Browse Source

added support for textures bigger than HW can support (SW rescaling)

tags/R300_DRIVER_0
Daniel Borca 22 years ago
parent
commit
09a4fcb592
3 changed files with 96 additions and 2 deletions
  1. 13
    2
      src/mesa/drivers/glide/fxdd.c
  2. 1
    0
      src/mesa/drivers/glide/fxdrv.h
  3. 82
    0
      src/mesa/drivers/glide/fxsetup.c

+ 13
- 2
src/mesa/drivers/glide/fxdd.c View File

@@ -797,6 +797,7 @@ fxDDReadPixels565 (GLcontext * ctx,
GrLfbInfo_t info;

BEGIN_BOARD_LOCK();
info.size = sizeof(info);
if (grLfbLock(GR_LFB_READ_ONLY,
fxMesa->currentFB,
GR_LFBWRITEMODE_ANY,
@@ -909,6 +910,7 @@ fxDDReadPixels555 (GLcontext * ctx,
GrLfbInfo_t info;

BEGIN_BOARD_LOCK();
info.size = sizeof(info);
if (grLfbLock(GR_LFB_READ_ONLY,
fxMesa->currentFB,
GR_LFBWRITEMODE_ANY,
@@ -1021,6 +1023,7 @@ fxDDReadPixels8888 (GLcontext * ctx,
GrLfbInfo_t info;

BEGIN_BOARD_LOCK();
info.size = sizeof(info);
if (grLfbLock(GR_LFB_READ_ONLY,
fxMesa->currentFB,
GR_LFBWRITEMODE_ANY,
@@ -1338,17 +1341,25 @@ fxDDInitFxMesaContext(fxMesaContext fxMesa)
fxMesa->textureAlign = FX_grGetInteger(GR_TEXTURE_ALIGN);
/* [koolsmoky] */
{
char *env;
int textureLevels = 0;
int textureSize = FX_grGetInteger(GR_MAX_TEXTURE_SIZE);
do {
textureLevels++;
} while ((textureSize >>= 0x1) & 0x7ff);
fxMesa->textureMaxLod = textureLevels - 1;
ctx->Const.MaxTextureLevels = textureLevels;
if ((env = getenv("MESA_FX_MAXLOD")) != NULL) {
int maxLevels = atoi(env) + 1;
if ((maxLevels <= MAX_TEXTURE_LEVELS) && (maxLevels > textureLevels)) {
ctx->Const.MaxTextureLevels = maxLevels;
}
}
}
ctx->Const.MaxTextureCoordUnits = fxMesa->haveTwoTMUs ? 2 : 1;
ctx->Const.MaxTextureCoordUnits =
ctx->Const.MaxTextureImageUnits = fxMesa->haveTwoTMUs ? 2 : 1;
ctx->Const.MaxTextureUnits = MAX2(ctx->Const.MaxTextureImageUnits, ctx->Const.MaxTextureCoordUnits);

fxMesa->new_state = _NEW_ALL;
if (!fxMesa->haveHwStencil) {
/* don't touch stencil if there is none */

+ 1
- 0
src/mesa/drivers/glide/fxdrv.h View File

@@ -462,6 +462,7 @@ struct tfxMesaContext
GLfloat fogStart, fogEnd;
GrFog_t *fogTable;
GLint textureAlign;
GLint textureMaxLod;

/* Vertex building and storage:
*/

+ 82
- 0
src/mesa/drivers/glide/fxsetup.c View File

@@ -65,6 +65,88 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj)
minl = ti->minLevel = tObj->BaseLevel;
maxl = ti->maxLevel = MIN2(tObj->MaxLevel, tObj->Image[0]->MaxLog2);

#if 1||FX_RESCALE_BIG_TEXURES
{
extern void _mesa_rescale_teximage2d( GLuint bytesPerPixel,
GLuint dstRowStride,
GLint srcWidth, GLint srcHeight,
GLint dstWidth, GLint dstHeight,
const GLvoid *srcImage, GLvoid *dstImage );
fxMesaContext fxMesa = FX_CONTEXT(ctx);
if (maxl - minl > fxMesa->textureMaxLod) {
/* [dBorca]
* Ooooooook! Here's a(nother) long story.
* We get here because we need to handle a texture larger
* than hardware can support. Two cases:
* 1) we have mipmaps. Then we just push up to the first supported
* LOD. A possible drawback is that Mesa will ignore the skipped
* LODs on further texture handling (including memory freeing).
* Will this interfere with GL_TEXTURE_[MIN|BASE]_LEVEL? How?
* 2) we don't have mipmaps. We need to rescale texture; two ways:
* a) create a new LOD and push up ti->minLevel and tObj->BaseLevel
* but this means we need to rescale on both axes, which
* yield unnecessary ugly texture. Also, same issues as 1)
* b) rescale the biggest LOD in place and go two ways:
* - update texImage->Width and texImage->Height, then
* decrease maxLevel, so we won't rescale again on the
* next validation. Changing texImage-> parameters is
* not quite legal here (see convolution), but...
* - leaving texImage-> parameters alone, while rescaling
* texture and decreasing maxLevel makes Mesa puke. Also
* this approach requires that mml->[wh]Scale go below 1,
* otherwise bad ju-ju will be in our future (see fetch_texel)
* Will this interfere with GL_TEXTURE_MAX_LEVEL? How?
* The above approach is somehow dumb! we might have rescaled
* once in TexImage2D to accomodate aspect ratio, and now we
* are rescaling again. The thing is, in TexImage2D we don't
* know whether we'll hit 1) or 2) by the time of validation.
* NB: we could handle mml->[wh]Scale nicely, using (biased) shifts.
*
* Which brings me to another issue. How can we handle NPOT textures?
* - rescaling NPOT to the next bigger POT (mml->[wh]Scale can't shift)
* - upping the max LOD to the next power-of-two, in fxTexGetInfo; then
* choosing non-power-of-two values for ti->[st]Scale... Anyhow, we
* still need to align mipmaps correctly in texture memory!
*/
if ((tObj->MinFilter == GL_NEAREST) || (tObj->MinFilter == GL_LINEAR)) {
/* no mipmaps! need to rescale */
struct gl_texture_image *texImage = tObj->Image[minl];
tfxMipMapLevel *mml = FX_MIPMAP_DATA(texImage);
GLint texelBytes = texImage->TexFormat->TexelBytes;
GLvoid *texImage_Data = texImage->Data;
GLint _w = MIN2(mml->width, 1 << fxMesa->textureMaxLod);
GLint _h = MIN2(mml->height, 1 << fxMesa->textureMaxLod);
if (TDFX_DEBUG & VERBOSE_TEXTURE) {
fprintf(stderr, "fxTexValidate: rescaling %d x %d -> %d x %d\n",
mml->width, mml->height,
_w, _h);
}
fxTexGetInfo(_w, _h, NULL, NULL, NULL, NULL,
&(mml->wScale), &(mml->hScale));
texImage->Width = _w / mml->wScale;
texImage->Height = _h / mml->hScale;
texImage->Data = MESA_PBUFFER_ALLOC(_w * _h * texelBytes);
_mesa_rescale_teximage2d(texelBytes,
_w * texelBytes, /* dst stride */
mml->width, mml->height, /* src */
_w, _h, /* dst */
texImage_Data /*src*/, texImage->Data /*dst*/ );
MESA_PBUFFER_FREE(texImage_Data);
mml->width = _w;
mml->height = _h;
maxl = ti->maxLevel = tObj->Image[0]->MaxLog2 = minl + fxMesa->textureMaxLod;
} else {
/* skip a certain number of LODs */
minl += maxl - fxMesa->textureMaxLod;
if (TDFX_DEBUG & VERBOSE_TEXTURE) {
fprintf(stderr, "fxTexValidate: skipping %d LODs\n", minl - ti->minLevel);
}
ti->minLevel = tObj->BaseLevel = minl;
}
}
}
#endif

fxTexGetInfo(tObj->Image[minl]->Width, tObj->Image[minl]->Height,
&(FX_largeLodLog2(ti->info)), &(FX_aspectRatioLog2(ti->info)),
&(ti->sScale), &(ti->tScale),

Loading…
Cancel
Save