Rework Voodoo texture precalc to support non-split trilinear textures.
Fixes trilinear bugs on Voodoo 3.
This commit is contained in:
parent
b40cc2b87e
commit
826389a37a
1 changed files with 59 additions and 56 deletions
|
|
@ -22,6 +22,8 @@ void voodoo_recalc_tex(voodoo_t *voodoo, int tmu)
|
||||||
uint32_t base = voodoo->params.texBaseAddr[tmu];
|
uint32_t base = voodoo->params.texBaseAddr[tmu];
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
int tex_lod = 0;
|
int tex_lod = 0;
|
||||||
|
uint32_t offsets[LOD_MAX+3];
|
||||||
|
int widths[LOD_MAX+3], heights[LOD_MAX+3], shifts[LOD_MAX+3];
|
||||||
|
|
||||||
if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER)
|
if (voodoo->params.tLOD[tmu] & LOD_S_IS_WIDER)
|
||||||
height >>= aspect;
|
height >>= aspect;
|
||||||
|
|
@ -31,77 +33,78 @@ void voodoo_recalc_tex(voodoo_t *voodoo, int tmu)
|
||||||
shift -= aspect;
|
shift -= aspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((voodoo->params.tLOD[tmu] & LOD_SPLIT) && (voodoo->params.tLOD[tmu] & LOD_ODD))
|
for (lod = 0; lod <= LOD_MAX + 2; lod++)
|
||||||
{
|
{
|
||||||
width >>= 1;
|
offsets[lod] = offset;
|
||||||
height >>= 1;
|
widths[lod] = width >> lod;
|
||||||
shift--;
|
heights[lod] = height >> lod;
|
||||||
tex_lod++;
|
shifts[lod] = shift - lod;
|
||||||
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)
|
|
||||||
base = voodoo->params.texBaseAddr1[tmu];
|
if (!widths[lod])
|
||||||
|
widths[lod] = 1;
|
||||||
|
if (!heights[lod])
|
||||||
|
heights[lod] = 1;
|
||||||
|
if (shifts[lod] < 0)
|
||||||
|
shifts[lod] = 0;
|
||||||
|
|
||||||
|
if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) ||
|
||||||
|
((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) ||
|
||||||
|
(!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD)))
|
||||||
|
{
|
||||||
|
if (voodoo->params.tformat[tmu] & 8)
|
||||||
|
offset += (width >> lod) * (height >> lod) * 2;
|
||||||
|
else
|
||||||
|
offset += (width >> lod) * (height >> lod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) && (voodoo->params.tLOD[tmu] & LOD_ODD))
|
||||||
|
tex_lod++; /*Skip LOD 0*/
|
||||||
|
|
||||||
|
pclog("TMU %i: %08x\n", tmu, voodoo->params.textureMode[tmu]);
|
||||||
for (lod = 0; lod <= LOD_MAX+1; lod++)
|
for (lod = 0; lod <= LOD_MAX+1; lod++)
|
||||||
{
|
{
|
||||||
if (!width)
|
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)
|
||||||
width = 1;
|
{
|
||||||
if (!height)
|
switch (tex_lod)
|
||||||
height = 1;
|
{
|
||||||
if (shift < 0)
|
case 0:
|
||||||
shift = 0;
|
base = voodoo->params.texBaseAddr[tmu];
|
||||||
voodoo->params.tex_base[tmu][lod] = base + offset;
|
break;
|
||||||
|
case 1:
|
||||||
|
base = voodoo->params.texBaseAddr1[tmu];
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
base = voodoo->params.texBaseAddr2[tmu];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
base = voodoo->params.texBaseAddr38[tmu];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
voodoo->params.tex_base[tmu][lod] = base + offsets[tex_lod];
|
||||||
if (voodoo->params.tformat[tmu] & 8)
|
if (voodoo->params.tformat[tmu] & 8)
|
||||||
voodoo->params.tex_end[tmu][lod] = base + offset + (width * height * 2);
|
voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod] * 2);
|
||||||
else
|
else
|
||||||
voodoo->params.tex_end[tmu][lod] = base + offset + (width * height);
|
voodoo->params.tex_end[tmu][lod] = base + offsets[tex_lod] + (widths[tex_lod] * heights[tex_lod]);
|
||||||
voodoo->params.tex_w_mask[tmu][lod] = width - 1;
|
voodoo->params.tex_w_mask[tmu][lod] = widths[tex_lod] - 1;
|
||||||
voodoo->params.tex_w_nmask[tmu][lod] = ~(width - 1);
|
voodoo->params.tex_w_nmask[tmu][lod] = ~(widths[tex_lod] - 1);
|
||||||
voodoo->params.tex_h_mask[tmu][lod] = height - 1;
|
voodoo->params.tex_h_mask[tmu][lod] = heights[tex_lod] - 1;
|
||||||
voodoo->params.tex_shift[tmu][lod] = shift;
|
voodoo->params.tex_shift[tmu][lod] = shifts[tex_lod];
|
||||||
voodoo->params.tex_lod[tmu][lod] = tex_lod;
|
voodoo->params.tex_lod[tmu][lod] = tex_lod;
|
||||||
|
|
||||||
if (!(voodoo->params.tLOD[tmu] & LOD_SPLIT) || ((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) || (!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD)))
|
if (!(voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR) ||
|
||||||
|
((lod & 1) && (voodoo->params.tLOD[tmu] & LOD_ODD)) ||
|
||||||
|
(!(lod & 1) && !(voodoo->params.tLOD[tmu] & LOD_ODD)))
|
||||||
{
|
{
|
||||||
if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0)
|
if (!(voodoo->params.tLOD[tmu] & LOD_ODD) || lod != 0)
|
||||||
{
|
{
|
||||||
if (voodoo->params.tformat[tmu] & 8)
|
if (voodoo->params.textureMode[tmu] & TEXTUREMODE_TRILINEAR)
|
||||||
offset += width * height * 2;
|
|
||||||
else
|
|
||||||
offset += width * height;
|
|
||||||
|
|
||||||
if (voodoo->params.tLOD[tmu] & LOD_SPLIT)
|
|
||||||
{
|
|
||||||
width >>= 2;
|
|
||||||
height >>= 2;
|
|
||||||
shift -= 2;
|
|
||||||
tex_lod += 2;
|
tex_lod += 2;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
width >>= 1;
|
|
||||||
height >>= 1;
|
|
||||||
shift--;
|
|
||||||
tex_lod++;
|
tex_lod++;
|
||||||
}
|
|
||||||
|
|
||||||
if (voodoo->params.tLOD[tmu] & LOD_TMULTIBASEADDR)
|
|
||||||
{
|
|
||||||
switch (tex_lod)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
base = voodoo->params.texBaseAddr[tmu];
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
base = voodoo->params.texBaseAddr1[tmu];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
base = voodoo->params.texBaseAddr2[tmu];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
base = voodoo->params.texBaseAddr38[tmu];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue