MacGLide/MacGLide/OpenGLide/PGUTexture.cpp

239 lines
7.5 KiB
C++

//**************************************************************
//* OpenGLide - Glide to OpenGL Wrapper
//* http://openglide.sourceforge.net
//*
//* implementation of the PGUexture class
//*
//* OpenGLide is OpenSource under LGPL license
//* Originaly made by Fabio Barros
//* Modified by Paul for Glidos (http://www.glidos.net)
//* Mac version and additional features by Jens-Olaf Hemprich
//**************************************************************
#include "PGTexture.h"
#include "PGUTexture.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
PGUTexture::PGUTexture( void )
{
for ( int i = 0; i < MAX_MM; i++ )
{
mm_info[ i ].valid = false;
}
m_free_mem = 0;
m_free_id = 0;
m_current_id = GR_NULL_MIPMAP_HANDLE;
}
PGUTexture::~PGUTexture( void )
{
}
GrMipMapId_t PGUTexture::AllocateMemory( GrChipID_t tmu, FxU8 odd_even_mask,
int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect,
GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minfilter_mode,
GrTextureFilterMode_t magfilter_mode,
float lod_bias, FxBool trilinear )
{
FxU32 size = 0;
GrLOD_t lod;
for ( lod = largest_lod; lod <= smallest_lod; lod++ )
{
size += PGTexture::MipMapMemRequired( lod, aspect, fmt );
}
size = ((size + 7) & ~7);
#ifdef OGL_UTEX
GlideMsg( "Allocate id = %d size = %d\n", m_free_id, size );
#endif
if ( ( m_free_id >= MAX_MM ) ||
( ( m_free_mem + size ) >= Textures->GetMemorySize( ) ) )
{
#ifdef OGL_UTEX
GlideMsg("Allocation failed\n");
#endif
return GR_NULL_MIPMAP_HANDLE;
}
mm_info[ m_free_id ].tmu = tmu;
mm_info[ m_free_id ].odd_even_mask = odd_even_mask;
mm_info[ m_free_id ].width = width;
mm_info[ m_free_id ].height = height;
mm_info[ m_free_id ].format = fmt;
mm_info[ m_free_id ].mipmap_mode = mm_mode;
mm_info[ m_free_id ].lod_min = smallest_lod;
mm_info[ m_free_id ].lod_max = largest_lod;
mm_info[ m_free_id ].aspect_ratio = aspect;
mm_info[ m_free_id ].s_clamp_mode = s_clamp_mode;
mm_info[ m_free_id ].t_clamp_mode = t_clamp_mode;
mm_info[ m_free_id ].minfilter_mode = minfilter_mode;
mm_info[ m_free_id ].magfilter_mode = magfilter_mode;
mm_info[ m_free_id ].lod_bias = lod_bias;
mm_info[ m_free_id ].trilinear = trilinear;
mm_info[ m_free_id ].valid = FXTRUE;
mm_start[ m_free_id ] = m_free_mem;
m_free_mem += size;
return m_free_id++;
}
void PGUTexture::DownloadMipMap( GrMipMapId_t mmid, const void *src, const GuNccTable *table )
{
#ifdef OGL_UTEX
GlideMsg("Download id = %d ", mmid);
#endif
if ( ( mmid >=0 ) && ( mmid < MAX_MM ) && ( mm_info[ mmid ].valid ) )
{
GrTexInfo info;
info.aspectRatio = mm_info[ mmid ].aspect_ratio;
info.format = mm_info[ mmid ].format;
info.largeLod = mm_info[ mmid ].lod_max;
info.smallLod = mm_info[ mmid ].lod_min;
info.data = (void *)src;
if (info.format == GR_TEXFMT_YIQ_422 ||
info.format == GR_TEXFMT_AYIQ_8422)
{
memcpy(&mm_info[ mmid ].ncc_table, table, sizeof(GuNccTable));
}
#ifdef OGL_UTEX
{
FxU32 size = 0;
for ( GrLOD_t lod = info.largeLod; lod <= info.smallLod; lod++ )
{
size += PGTexture::MipMapMemRequired( lod, info.aspectRatio, info.format );
}
GlideMsg( "size = %d\n", size );
}
#endif
grTexDownloadMipMap( mm_info[mmid].tmu, mm_start[ mmid ], mm_info[ mmid ].odd_even_mask, &info );
}
#ifdef OGL_UTEX
else
{
GlideMsg( "failed\n" );
}
#endif
}
void PGUTexture::DownloadMipMapLevel( GrMipMapId_t mmid, GrLOD_t lod, const void **src )
{
#ifdef OGL_NOTDONE
GlideMsg("PGUTexture::DownloadMipMapLevel(...)\n");
#endif
}
void PGUTexture::MemReset( void )
{
#ifdef OGL_UTEX
GlideMsg("Reset\n");
#endif
for ( int i = 0; i < MAX_MM; i++ )
{
mm_info[ i ].valid = false;
}
m_free_mem = 0;
m_free_id = 0;
m_current_id = GR_NULL_MIPMAP_HANDLE;
}
void PGUTexture::Source( GrMipMapId_t id )
{
if ( ( id >=0 ) && ( id < MAX_MM ) && ( mm_info[ id ].valid ) )
{
GrTexInfo info;
info.aspectRatio = mm_info[ id ].aspect_ratio;
info.format = mm_info[ id ].format;
info.largeLod = mm_info[ id ].lod_max;
info.smallLod = mm_info[ id ].lod_min;
int tmu = mm_info[ id ].tmu;
grTexSource( tmu, mm_start[ id ], mm_info[ id ].odd_even_mask, &info );
grTexFilterMode( tmu, mm_info[ id ].minfilter_mode, mm_info[ id ].magfilter_mode );
grTexMipMapMode( tmu, mm_info[ id ].mipmap_mode, mm_info[ id ].trilinear );
grTexClampMode( tmu, mm_info[ id ].s_clamp_mode, mm_info[ id ].t_clamp_mode );
grTexLodBiasValue( tmu, mm_info[ id ].lod_bias );
// Download the ncc table
// @todo: only necessary when the format uses the table?
if ((info.format == GR_TEXFMT_YIQ_422) ||
(info.format == GR_TEXFMT_AYIQ_8422))
{
// @todo: the linux driver utilises both tables and optimises downloads
// MacGLide only uses gr* functions whereas
// the linux driver has extra internal state for gu* functions
// -> No download, no texture recreation (see gutex.c)
// /* Which table should we use? */
// table = gc->tmu_state[tmu].next_ncc_table;
// /* Download NCC table */ // using internal function
// _grTexDownloadNccTable( tmu, table, &mminfo->ncc_table, 0, 11 );
// /* Set the mmid so we known it's down there */
// gc->tmu_state[tmu].ncc_mmids[table] = mmid;
// /* Set the state to know which table was the LRA */
// gc->tmu_state[tmu].next_ncc_table =
// (table == 0 ? 1 : 0);
grTexDownloadTable(tmu, GR_NCCTABLE_NCC0, &mm_info[ id ].ncc_table);
}
m_current_id = id;
}
#ifdef OGL_UTEX
else
{
GlideMsg( "TexSource failed\n" );
}
#endif
}
GrMipMapInfo *PGUTexture::GetMipMapInfo( GrMipMapId_t mmid )
{
return ( ( mmid >= 0 ) && ( mmid < MAX_MM ) &&
( mm_info[mmid].valid ) ? &( mm_info[ mmid ] ) : NULL );
}
FxBool PGUTexture::ChangeAttributes( GrMipMapId_t mmid, int width, int height,
GrTextureFormat_t fmt, GrMipMapMode_t mm_mode,
GrLOD_t smallest_lod, GrLOD_t largest_lod,
GrAspectRatio_t aspect, GrTextureClampMode_t s_clamp_mode,
GrTextureClampMode_t t_clamp_mode,
GrTextureFilterMode_t minFilterMode,
GrTextureFilterMode_t magFilterMode )
{
#ifdef OGL_NOTDONE
GlideMsg("PGUTexture::ChangeAttributes(...)\n");
#endif
return FXFALSE;
}
GrMipMapId_t PGUTexture::GetCurrentMipMap( GrChipID_t tmu ) const
{
return m_current_id;
}
FxU32 PGUTexture::MemQueryAvail( GrChipID_t tmu ) const
{
return Textures->GetMemorySize( ) - m_free_mem;
}