softgpu: small optimization, precompute tex info.

This commit is contained in:
Unknown W. Brackets 2013-09-15 21:39:28 -07:00
parent f43997a47f
commit ad4bd8ed74
4 changed files with 30 additions and 21 deletions

View file

@ -1027,7 +1027,7 @@ void TextureCacheDX9::SetTexture() {
}
#endif
u32 texaddr = (gstate.texaddr[0] & 0xFFFFF0) | ((gstate.texbufwidth[0]<<8) & 0x0F000000);
u32 texaddr = gstate.getTextureAddress(0);
if (!Memory::IsValidAddress(texaddr)) {
// Bind a null texture and return.
pD3Ddevice->SetTexture(0, NULL);
@ -1249,7 +1249,7 @@ void TextureCacheDX9::SetTexture() {
// Adjust maxLevel to actually present levels..
for (int i = 0; i <= maxLevel; i++) {
// If encountering levels pointing to nothing, adjust max level.
u32 levelTexaddr = (gstate.texaddr[i] & 0xFFFFF0) | ((gstate.texbufwidth[i] << 8) & 0x0F000000);
u32 levelTexaddr = gstate.getTextureAddress(i);
if (!Memory::IsValidAddress(levelTexaddr)) {
maxLevel = i - 1;
break;
@ -1273,7 +1273,7 @@ void TextureCacheDX9::SetTexture() {
void *TextureCacheDX9::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat clutformat, int level, u32 &texByteAlign, u32 &dstFmt) {
void *finalBuf = NULL;
u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000);
u32 texaddr = gstate.getTextureAddress(level);
int bufw = GetTextureBufw(level, texaddr, format);

View file

@ -982,7 +982,7 @@ void TextureCache::SetTexture() {
}
#endif
u32 texaddr = (gstate.texaddr[0] & 0xFFFFF0) | ((gstate.texbufwidth[0]<<8) & 0x0F000000);
u32 texaddr = gstate.getTextureAddress(0);
if (!Memory::IsValidAddress(texaddr)) {
// Bind a null texture and return.
glBindTexture(GL_TEXTURE_2D, 0);
@ -1210,7 +1210,7 @@ void TextureCache::SetTexture() {
// Adjust maxLevel to actually present levels..
for (int i = 0; i <= maxLevel; i++) {
// If encountering levels pointing to nothing, adjust max level.
u32 levelTexaddr = (gstate.texaddr[i] & 0xFFFFF0) | ((gstate.texbufwidth[i] << 8) & 0x0F000000);
u32 levelTexaddr = gstate.getTextureAddress(i);
if (!Memory::IsValidAddress(levelTexaddr)) {
maxLevel = i - 1;
break;
@ -1261,7 +1261,7 @@ void TextureCache::SetTexture() {
void *TextureCache::DecodeTextureLevel(GETextureFormat format, GEPaletteFormat clutformat, int level, u32 &texByteAlign, GLenum &dstFmt) {
void *finalBuf = NULL;
u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000);
u32 texaddr = gstate.getTextureAddress(level);
int bufw = GetTextureBufw(level, texaddr, format);
int w = gstate.getTextureWidth(level);
@ -1615,7 +1615,7 @@ bool TextureCache::DecodeTexture(u8* output, GPUgstate state)
GPUgstate oldState = gstate;
gstate = state;
u32 texaddr = (gstate.texaddr[0] & 0xFFFFF0) | ((gstate.texbufwidth[0]<<8) & 0x0F000000);
u32 texaddr = gstate.getTextureAddress(0);
if (!Memory::IsValidAddress(texaddr)) {
return false;

View file

@ -276,6 +276,8 @@ struct GPUgstate
u32 getColorTestMask() const { return colormask & 0xFFFFFF; }
// Texturing
// TODO: Verify getTextureAddress() alignment?
u32 getTextureAddress(int level) const { return (texaddr[level] & 0xFFFFF0) | ((texbufwidth[level] << 8) & 0x0F000000); }
int getTextureWidth(int level) const { return 1 << (texsize[level] & 0xf);}
int getTextureHeight(int level) const { return 1 << ((texsize[level] >> 8) & 0xf);}
u16 getTextureDimension(int level) const { return texsize[level] & 0xf0f;}

View file

@ -166,54 +166,50 @@ static inline void GetTextureCoordinates(const VertexData& v0, const VertexData&
}
}
static inline u32 SampleNearest(int level, unsigned int u, unsigned int v)
static inline u32 SampleNearest(int level, unsigned int u, unsigned int v, u8 *srcptr, int texbufwidthbits)
{
GETextureFormat texfmt = gstate.getTextureFormat();
u32 texaddr = (gstate.texaddr[level] & 0xFFFFF0) | ((gstate.texbufwidth[level] << 8) & 0x0F000000);
u8* srcptr = (u8*)Memory::GetPointer(texaddr); // TODO: not sure if this is the right place to load from...?
int texbufwidth = GetTextureBufw(level, texaddr, texfmt);
// TODO: Should probably check if textures are aligned properly...
switch (texfmt) {
case GE_TFMT_4444:
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(16, texbufwidthbits, u, v);
return DecodeRGBA4444(*(u16*)srcptr);
case GE_TFMT_5551:
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(16, texbufwidthbits, u, v);
return DecodeRGBA5551(*(u16*)srcptr);
case GE_TFMT_5650:
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(16, texbufwidthbits, u, v);
return DecodeRGB565(*(u16*)srcptr);
case GE_TFMT_8888:
srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(32, texbufwidthbits, u, v);
return DecodeRGBA8888(*(u32*)srcptr);
case GE_TFMT_CLUT32:
{
srcptr += GetPixelDataOffset(32, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(32, texbufwidthbits, u, v);
u32 val = srcptr[0] + (srcptr[1] << 8) + (srcptr[2] << 16) + (srcptr[3] << 24);
return LookupColor(gstate.transformClutIndex(val), level);
}
case GE_TFMT_CLUT16:
{
srcptr += GetPixelDataOffset(16, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(16, texbufwidthbits, u, v);
u16 val = srcptr[0] + (srcptr[1] << 8);
return LookupColor(gstate.transformClutIndex(val), level);
}
case GE_TFMT_CLUT8:
{
srcptr += GetPixelDataOffset(8, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(8, texbufwidthbits, u, v);
u8 val = *srcptr;
return LookupColor(gstate.transformClutIndex(val), level);
}
case GE_TFMT_CLUT4:
{
srcptr += GetPixelDataOffset(4, texbufwidth*8, u, v);
srcptr += GetPixelDataOffset(4, texbufwidthbits, u, v);
u8 val = (u & 1) ? (srcptr[0] >> 4) : (srcptr[0] & 0xF);
return LookupColor(gstate.transformClutIndex(val), level);
}
@ -750,6 +746,17 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
int bias1 = IsRightSideOrFlatBottomLine(v1.screenpos.xy(), v2.screenpos.xy(), v0.screenpos.xy()) ? -1 : 0;
int bias2 = IsRightSideOrFlatBottomLine(v2.screenpos.xy(), v0.screenpos.xy(), v1.screenpos.xy()) ? -1 : 0;
int texlevel = 0;
int texbufwidthbits = 0;
u8 *texptr = NULL;
if (gstate.isTextureMapEnabled() && !gstate.isModeClear()) {
// TODO: Always using level 0.
GETextureFormat texfmt = gstate.getTextureFormat();
u32 texaddr = gstate.getTextureAddress(texlevel);
texbufwidthbits = GetTextureBufw(texlevel, texaddr, texfmt) * 8;
texptr = Memory::GetPointer(texaddr);
}
ScreenCoords pprime(minX, minY, 0);
int w0_base = orient2d(v1.screenpos, v2.screenpos, pprime);
int w1_base = orient2d(v2.screenpos, v0.screenpos, pprime);
@ -806,7 +813,7 @@ void DrawTriangle(const VertexData& v0, const VertexData& v1, const VertexData&
GetTexelCoordinates(0, s, t, u, v);
}
Vec4<int> texcolor = Vec4<int>::FromRGBA(SampleNearest(0, u, v));
Vec4<int> texcolor = Vec4<int>::FromRGBA(SampleNearest(texlevel, u, v, texptr, texbufwidthbits));
Vec4<int> out = GetTextureFunctionOutput(prim_color_rgb, prim_color_a, texcolor);
prim_color_rgb = out.rgb();
prim_color_a = out.a();