384 lines
8.8 KiB
C
384 lines
8.8 KiB
C
|
|
/*
|
|
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
|
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
|
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
|
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
|
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
|
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
|
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
|
**
|
|
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
|
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
|
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
|
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
|
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
|
** THE UNITED STATES.
|
|
**
|
|
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
|
**
|
|
** $Revision$
|
|
** $Date$
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
|
|
#include <3dfx.h>
|
|
#include <glide.h>
|
|
#include "texusint.h"
|
|
|
|
/*
|
|
* Allocate memory via Glide for a texture.
|
|
* Assumes that the passed image is already quantized to
|
|
* the format that you want to download.
|
|
*/
|
|
GrMipMapId_t txAllocateTexMemory( GrChipID_t tmu,
|
|
FxU8 odd_even_mask,
|
|
TxMip *texture,
|
|
GrMipMapMode_t mm_mode,
|
|
GrTextureClampMode_t s_clamp_mode,
|
|
GrTextureClampMode_t t_clamp_mode,
|
|
GrTextureFilterMode_t minfilter_mode,
|
|
GrTextureFilterMode_t magfilter_mode,
|
|
float lod_bias,
|
|
FxBool trilinear )
|
|
{
|
|
int aspect;
|
|
GrAspectRatio_t gr_aspect;
|
|
int longest_side;
|
|
GrLOD_t max_lod, min_lod;
|
|
int num_mipmap_levels = 0;
|
|
int i;
|
|
|
|
aspect = ( 8 * texture->width ) / texture->height;
|
|
|
|
#ifdef GLIDE3
|
|
switch( aspect )
|
|
{
|
|
case 64:
|
|
gr_aspect = GR_ASPECT_LOG2_8x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 32:
|
|
gr_aspect = GR_ASPECT_LOG2_4x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 16:
|
|
gr_aspect = GR_ASPECT_LOG2_2x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 8:
|
|
gr_aspect = GR_ASPECT_LOG2_1x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 4:
|
|
gr_aspect = GR_ASPECT_LOG2_1x2;
|
|
longest_side = texture->height;
|
|
break;
|
|
case 2:
|
|
gr_aspect = GR_ASPECT_LOG2_1x4;
|
|
longest_side = texture->height;
|
|
break;
|
|
case 1:
|
|
gr_aspect = GR_ASPECT_LOG2_1x8;
|
|
longest_side = texture->height;
|
|
break;
|
|
}
|
|
#else
|
|
switch( aspect )
|
|
{
|
|
case 64:
|
|
gr_aspect = GR_ASPECT_LOG2_8x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 32:
|
|
gr_aspect = GR_ASPECT_LOG2_4x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 16:
|
|
gr_aspect = GR_ASPECT_LOG2_2x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 8:
|
|
gr_aspect = GR_ASPECT_LOG2_1x1;
|
|
longest_side = texture->width;
|
|
break;
|
|
case 4:
|
|
gr_aspect = GR_ASPECT_LOG2_1x2;
|
|
longest_side = texture->height;
|
|
break;
|
|
case 2:
|
|
gr_aspect = GR_ASPECT_LOG2_1x4;
|
|
longest_side = texture->height;
|
|
break;
|
|
case 1:
|
|
gr_aspect = GR_ASPECT_LOG2_1x8;
|
|
longest_side = texture->height;
|
|
break;
|
|
}
|
|
#endif /* GLIDE3 */
|
|
|
|
/*
|
|
* How many mipmap levels are there?
|
|
*/
|
|
for( i = 0; i < 16; i++ )
|
|
{
|
|
if( texture->data[i] )
|
|
num_mipmap_levels++;
|
|
else
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Figure out the max lod.
|
|
*/
|
|
#ifdef GLIDE3
|
|
switch( longest_side )
|
|
{
|
|
case 256:
|
|
max_lod = GR_LOD_LOG2_256;
|
|
break;
|
|
case 128:
|
|
max_lod = GR_LOD_LOG2_128;
|
|
break;
|
|
case 64:
|
|
max_lod = GR_LOD_LOG2_64;
|
|
break;
|
|
case 32:
|
|
max_lod = GR_LOD_LOG2_32;
|
|
break;
|
|
case 16:
|
|
max_lod = GR_LOD_LOG2_16;
|
|
break;
|
|
case 8:
|
|
max_lod = GR_LOD_LOG2_8;
|
|
break;
|
|
case 4:
|
|
max_lod = GR_LOD_LOG2_4;
|
|
break;
|
|
case 2:
|
|
max_lod = GR_LOD_LOG2_2;
|
|
break;
|
|
case 1:
|
|
max_lod = GR_LOD_LOG2_1;
|
|
break;
|
|
}
|
|
#else
|
|
switch( longest_side )
|
|
{
|
|
case 256:
|
|
max_lod = GR_LOD_256;
|
|
break;
|
|
case 128:
|
|
max_lod = GR_LOD_128;
|
|
break;
|
|
case 64:
|
|
max_lod = GR_LOD_64;
|
|
break;
|
|
case 32:
|
|
max_lod = GR_LOD_32;
|
|
break;
|
|
case 16:
|
|
max_lod = GR_LOD_16;
|
|
break;
|
|
case 8:
|
|
max_lod = GR_LOD_8;
|
|
break;
|
|
case 4:
|
|
max_lod = GR_LOD_4;
|
|
break;
|
|
case 2:
|
|
max_lod = GR_LOD_2;
|
|
break;
|
|
case 1:
|
|
max_lod = GR_LOD_1;
|
|
break;
|
|
}
|
|
#endif /* GLIDE3 */
|
|
|
|
/*
|
|
* Figure out the minimum LOD.
|
|
*/
|
|
#ifdef GLIDE3
|
|
min_lod = max_lod - ( num_mipmap_levels - 1 );
|
|
#else
|
|
min_lod = max_lod + num_mipmap_levels - 1;
|
|
#endif
|
|
|
|
return grTexAllocateMemory( tmu, odd_even_mask,
|
|
#if 0
|
|
texture->width, texture->height,
|
|
#else
|
|
0, 0,
|
|
#endif
|
|
texture->format, mm_mode,
|
|
min_lod, max_lod,
|
|
gr_aspect,
|
|
s_clamp_mode, t_clamp_mode,
|
|
minfilter_mode, magfilter_mode,
|
|
lod_bias,
|
|
trilinear );
|
|
}
|
|
|
|
void txDownloadMipmap( GrMipMapId_t mmid, TxMip *texture )
|
|
{
|
|
int longest_side;
|
|
GrLOD_t lod;
|
|
int i;
|
|
|
|
if( texture->width > texture->height )
|
|
longest_side = texture->width;
|
|
else
|
|
longest_side = texture->height;
|
|
|
|
/*
|
|
* Figure out the max lod.
|
|
*/
|
|
#ifdef GLIDE3
|
|
switch( longest_side )
|
|
{
|
|
case 256:
|
|
lod = GR_LOD_LOG2_256;
|
|
break;
|
|
case 128:
|
|
lod = GR_LOD_LOG2_128;
|
|
break;
|
|
case 64:
|
|
lod = GR_LOD_LOG2_64;
|
|
break;
|
|
case 32:
|
|
lod = GR_LOD_LOG2_32;
|
|
break;
|
|
case 16:
|
|
lod = GR_LOD_LOG2_16;
|
|
break;
|
|
case 8:
|
|
lod = GR_LOD_LOG2_8;
|
|
break;
|
|
case 4:
|
|
lod = GR_LOD_LOG2_4;
|
|
break;
|
|
case 2:
|
|
lod = GR_LOD_LOG2_2;
|
|
break;
|
|
case 1:
|
|
lod = GR_LOD_LOG2_1;
|
|
break;
|
|
}
|
|
#else
|
|
switch( longest_side )
|
|
{
|
|
case 256:
|
|
lod = GR_LOD_256;
|
|
break;
|
|
case 128:
|
|
lod = GR_LOD_128;
|
|
break;
|
|
case 64:
|
|
lod = GR_LOD_64;
|
|
break;
|
|
case 32:
|
|
lod = GR_LOD_32;
|
|
break;
|
|
case 16:
|
|
lod = GR_LOD_16;
|
|
break;
|
|
case 8:
|
|
lod = GR_LOD_8;
|
|
break;
|
|
case 4:
|
|
lod = GR_LOD_4;
|
|
break;
|
|
case 2:
|
|
lod = GR_LOD_2;
|
|
break;
|
|
case 1:
|
|
lod = GR_LOD_1;
|
|
break;
|
|
}
|
|
#endif /* GLIDE3 */
|
|
|
|
for( i = 0; i < 16; i++ )
|
|
{
|
|
void *tmp;
|
|
|
|
if( !texture->data[i] )
|
|
break;
|
|
tmp = texture->data[i];
|
|
grTexDownloadMipMapLevel( mmid, lod, &tmp );
|
|
lod++;
|
|
}
|
|
|
|
if( ( texture->format == GR_TEXFMT_YIQ_422 ) ||
|
|
( texture->format == GR_TEXFMT_AYIQ_8422 ) )
|
|
{
|
|
int i, j;
|
|
GuNccTable ncc_table;
|
|
|
|
for( i = 0; i < 16; i++ )
|
|
{
|
|
ncc_table.yRGB[i] = ( FxU8 )texture->pal[i];
|
|
}
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
for( j = 0; j < 3; j++ )
|
|
{
|
|
ncc_table.iRGB[i][j] = ( FxI16 )( texture->pal[16 + 3 * i + j] );
|
|
ncc_table.qRGB[i][j] = ( FxI16 )( texture->pal[28 + 3 * i + j] );
|
|
}
|
|
}
|
|
|
|
/*
|
|
** pack the table Y entries
|
|
*/
|
|
for ( i = 0; i < 4; i++ )
|
|
{
|
|
FxU32 packedvalue;
|
|
|
|
packedvalue = ( ( FxU32 )( ncc_table.yRGB[i*4+0] & 0xff ) );
|
|
packedvalue |= ( ( FxU32 )( ncc_table.yRGB[i*4+1] & 0xff ) ) << 8;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.yRGB[i*4+2] & 0xff ) ) << 16;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.yRGB[i*4+3] & 0xff ) ) << 24;
|
|
|
|
ncc_table.packed_data[i] = packedvalue;
|
|
}
|
|
|
|
/*
|
|
** pack the table I entries
|
|
*/
|
|
for ( i = 0; i < 4; i++ )
|
|
{
|
|
FxU32 packedvalue;
|
|
|
|
packedvalue = ( ( FxU32 )( ncc_table.iRGB[i][0] & 0x1ff ) ) << 18;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.iRGB[i][1] & 0x1ff ) ) << 9;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.iRGB[i][2] & 0x1ff ) ) << 0;
|
|
|
|
ncc_table.packed_data[i+4] = packedvalue;
|
|
}
|
|
|
|
/*
|
|
** pack the table Q entries
|
|
*/
|
|
for ( i = 0; i < 4; i++ )
|
|
{
|
|
FxU32 packedvalue;
|
|
|
|
packedvalue = ( ( FxU32 )( ncc_table.qRGB[i][0] & 0x1ff ) ) << 18;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.qRGB[i][1] & 0x1ff ) ) << 9;;
|
|
packedvalue |= ( ( FxU32 )( ncc_table.qRGB[i][2] & 0x1ff ) ) << 0;
|
|
|
|
ncc_table.packed_data[i+8] = packedvalue;
|
|
}
|
|
|
|
#if 0
|
|
HackSetNCCTable( mmid, &ncc_table );
|
|
#endif
|
|
}
|
|
}
|