From ad4bd8ed744748baaba6b556fdc1866338007545 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 15 Sep 2013 21:39:28 -0700 Subject: [PATCH] softgpu: small optimization, precompute tex info. --- GPU/Directx9/TextureCacheDX9.cpp | 6 +++--- GPU/GLES/TextureCache.cpp | 8 ++++---- GPU/GPUState.h | 2 ++ GPU/Software/Rasterizer.cpp | 35 +++++++++++++++++++------------- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/GPU/Directx9/TextureCacheDX9.cpp b/GPU/Directx9/TextureCacheDX9.cpp index 869e6566b5..edafbabd3b 100644 --- a/GPU/Directx9/TextureCacheDX9.cpp +++ b/GPU/Directx9/TextureCacheDX9.cpp @@ -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); diff --git a/GPU/GLES/TextureCache.cpp b/GPU/GLES/TextureCache.cpp index ed64d839b6..5d802f627a 100644 --- a/GPU/GLES/TextureCache.cpp +++ b/GPU/GLES/TextureCache.cpp @@ -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; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 45c4dd1267..fd818e502c 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -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;} diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index cac7e23371..2d0befad9c 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -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 texcolor = Vec4::FromRGBA(SampleNearest(0, u, v)); + Vec4 texcolor = Vec4::FromRGBA(SampleNearest(texlevel, u, v, texptr, texbufwidthbits)); Vec4 out = GetTextureFunctionOutput(prim_color_rgb, prim_color_a, texcolor); prim_color_rgb = out.rgb(); prim_color_a = out.a();