diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 4ea5f4db7a..9d02e706f6 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -1107,3 +1107,32 @@ void GLGSRender::Flip() checkForGlError("glScissor"); } } + +uint32_t LinearToSwizzleAddress( + uint32_t x, uint32_t y, uint32_t z, + uint32_t log2_width, uint32_t log2_height, uint32_t log2_depth) +{ + uint32_t offset = 0; + uint32_t shift_count = 0; + while(log2_width | log2_height | log2_depth){ + if(log2_width){ + offset |= (x & 0x01) << shift_count; + x >>= 1; + ++shift_count; + --log2_width; + } + if(log2_height){ + offset |= (y & 0x01) << shift_count; + y >>= 1; + ++shift_count; + --log2_height; + } + if(log2_depth){ + offset |= (z & 0x01) << shift_count; + z >>= 1; + ++shift_count; + --log2_depth; + } + } + return offset; +} \ No newline at end of file diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index ef46141163..97e9d36882 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -14,6 +14,9 @@ extern GLenum g_last_gl_error; void printGlError(GLenum err, const char* situation); +uint32_t LinearToSwizzleAddress( + uint32_t x, uint32_t y, uint32_t z, + uint32_t log2_width, uint32_t log2_height, uint32_t log2_depth); #if RSX_DEBUG #define checkForGlError(sit) if((g_last_gl_error = glGetError()) != GL_NO_ERROR) printGlError(g_last_gl_error, sit) @@ -81,6 +84,7 @@ public: glPixelStorei(GL_PACK_ALIGNMENT, tex.m_pitch); char* pixels = (char*)Memory.GetMemFromAddr(GetAddress(tex.GetOffset(), tex.GetLocation())); + char* unswizzledPixels; switch(format) { @@ -97,7 +101,28 @@ public: break; case 0x85: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + if(is_swizzled) + { + uint32_t *src, *dst; + uint32_t log2width, log2height; + + unswizzledPixels = (char*)malloc(tex.GetWidth() * tex.GetHeight() * 4); + src = (uint32_t*)pixels; + dst = (uint32_t*)unswizzledPixels; + + log2width = log(tex.GetWidth())/log(2); + log2height = log(tex.GetHeight())/log(2); + + for(int i=0; i glTexImage2D"); break; @@ -150,7 +175,7 @@ public: } break; - default: ConLog.Error("Init tex error: Bad tex format (0x%x | 0x%x | 0x%x)", format, tex.GetFormat() & 0x20, tex.GetFormat() & 0x40); break; + default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, is_swizzled ? "swizzled" : "linear", tex.GetFormat() & 0x40); break; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.Getmipmap() - 1); @@ -177,7 +202,7 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, gl_remap[remap_b]); } - checkForGlError("GLTexture::Init() -> remap"); + checkForGlError("GLTexture::Init() -> remap"); static const int gl_tex_zfunc[] = { @@ -196,13 +221,13 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.GetWrapR())); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.GetZfunc()]); - checkForGlError("GLTexture::Init() -> parameters1"); + checkForGlError("GLTexture::Init() -> parameters1"); - glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.m_bias); + glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.GetBias()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, (tex.GetMinLOD() >> 8)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, (tex.GetMaxLOD() >> 8)); - checkForGlError("GLTexture::Init() -> parameters2"); + checkForGlError("GLTexture::Init() -> parameters2"); static const int gl_tex_filter[] = { @@ -216,12 +241,17 @@ public: GL_NEAREST, }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[tex.m_min_filter]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[tex.m_mag_filter]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_tex_filter[tex.GetMinFilter()]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_tex_filter[tex.GetMagFilter()]); - checkForGlError("GLTexture::Init() -> filters"); + checkForGlError("GLTexture::Init() -> filters"); //Unbind(); + + if(is_swizzled && format == 0x85) + { + free(unswizzledPixels); + } } void Save(RSXTexture& tex, const wxString& name) diff --git a/rpcs3/Emu/GS/RSXTexture.cpp b/rpcs3/Emu/GS/RSXTexture.cpp index 16b470e319..8db5499a02 100644 --- a/rpcs3/Emu/GS/RSXTexture.cpp +++ b/rpcs3/Emu/GS/RSXTexture.cpp @@ -2,17 +2,11 @@ #include "RSXThread.h" RSXTexture::RSXTexture() - : m_bias(0) - , m_min_filter(1) - , m_mag_filter(2) { m_index = 0; } RSXTexture::RSXTexture(u8 index) - : m_bias(0) - , m_min_filter(1) - , m_mag_filter(2) { m_index = index; } @@ -20,153 +14,189 @@ RSXTexture::RSXTexture(u8 index) void RSXTexture::Init() { // Offset - methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*4)] = 0; + methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*32)] = 0; // Format - methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] = 0; + methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] = 0; // Address - methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] = + methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] = ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | ((/*wrapr*/2) << 16) | ((/*gamma*/0) << 20) |((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); // Control0 - methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] = + methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] = (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); + // Control1 + methodRegisters[NV4097_SET_TEXTURE_CONTROL1 + (m_index*32)] = 0xE4; + + // Filter + methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] = + ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) + | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31) ); + // Image Rect - methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*4)] = (/*height*/1) | ((/*width*/1) << 16); + methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] = (/*height*/1) | ((/*width*/1) << 16); } u32 RSXTexture::GetOffset() const { - return methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*4)]; + return methodRegisters[NV4097_SET_TEXTURE_OFFSET + (m_index*32)]; } u8 RSXTexture::GetLocation() const { - return (methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] & 0x3) - 1; + return (methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] & 0x3) - 1; } bool RSXTexture::isCubemap() const { - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] >> 2) & 0x1); + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 2) & 0x1); } u8 RSXTexture::GetBorderType() const { - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] >> 3) & 0x1); + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 3) & 0x1); } u8 RSXTexture::GetDimension() const { - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] >> 4) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 4) & 0xf); } u8 RSXTexture::GetFormat() const { - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] >> 8) & 0xff); + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 8) & 0xff); } u16 RSXTexture::Getmipmap() const { - return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*4)] >> 16) & 0xffff); + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 16) & 0xffff); } u8 RSXTexture::GetWrapS() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)]) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)]) & 0xf); } u8 RSXTexture::GetWrapT() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 8) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 8) & 0xf); } u8 RSXTexture::GetWrapR() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 16) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 16) & 0xf); } u8 RSXTexture::GetUnsignedRemap() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 12) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 12) & 0xf); } u8 RSXTexture::GetZfunc() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 28) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 28) & 0xf); } u8 RSXTexture::GetGamma() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 20) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 20) & 0xf); } u8 RSXTexture::GetAnisoBias() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 4) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 4) & 0xf); } u8 RSXTexture::GetSignedRemap() const { - return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*4)] >> 24) & 0xf); + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 24) & 0xf); } bool RSXTexture::IsEnabled() const { - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] >> 31) & 0x1); + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 31) & 0x1); } u16 RSXTexture::GetMinLOD() const { - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] >> 19) & 0xfff); + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 19) & 0xfff); } u16 RSXTexture::GetMaxLOD() const { - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] >> 7) & 0xfff); + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 7) & 0xfff); } u8 RSXTexture::GetMaxAniso() const { - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] >> 4) & 0x7); + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 4) & 0x7); } bool RSXTexture::IsAlphaKillEnabled() const { - return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*4)] >> 2) & 0x1); + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 2) & 0x1); } u32 RSXTexture::GetRemap() const { - return (methodRegisters[NV4097_SET_TEXTURE_CONTROL1 + (m_index*4)]); + return (methodRegisters[NV4097_SET_TEXTURE_CONTROL1 + (m_index*32)]); +} + +u16 RSXTexture::GetBias() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)]) & 0x1fff); +} + +u8 RSXTexture::GetMinFilter() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 16) & 0x7); +} + +u8 RSXTexture::GetMagFilter() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 24) & 0x7); +} + +u8 RSXTexture::GetConvolutionFilter() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 13) & 0xf); +} + +bool RSXTexture::isASigned() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 28) & 0x1); +} + +bool RSXTexture::isRSigned() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 29) & 0x1); +} + +bool RSXTexture::isGSigned() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 30) & 0x1); +} + +bool RSXTexture::isBSigned() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FILTER + (m_index*32)] >> 31) & 0x1); } u16 RSXTexture::GetWidth() const { - return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*4)] >> 16) & 0xffff); + return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)] >> 16) & 0xffff); } u16 RSXTexture::GetHeight() const { - return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*4)]) & 0xffff); + return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)]) & 0xffff); } void RSXTexture::SetControl3(u16 depth, u32 pitch) { m_depth = depth; m_pitch = pitch; -} - -void RSXTexture::SetFilter(u16 bias, u8 min, u8 mag, u8 conv, u8 a_signed, u8 r_signed, u8 g_signed, u8 b_signed) -{ - m_bias = bias; - m_min_filter = min; - m_mag_filter = mag; - m_conv = conv; - m_a_signed = a_signed; - m_r_signed = r_signed; - m_g_signed = g_signed; - m_b_signed = b_signed; } \ No newline at end of file diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 4dea573808..9556370bf9 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -288,18 +288,6 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case_16(NV4097_SET_TEXTURE_FILTER, 0x20): { - RSXTexture& tex = m_textures[index]; - u32 a0 = ARGS(0); - u16 bias = a0 & 0x1fff; - u8 conv = (a0 >> 13) & 0xf; - u8 min = (a0 >> 16) & 0x7; - u8 mag = (a0 >> 24) & 0x7; - u8 a_signed = (a0 >> 28) & 0x1; - u8 r_signed = (a0 >> 29) & 0x1; - u8 g_signed = (a0 >> 30) & 0x1; - u8 b_signed = (a0 >> 31) & 0x1; - - tex.SetFilter(bias, min, mag, conv, a_signed, r_signed, g_signed, b_signed); } break; diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index b8e93153a9..fd96f49817 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -22,15 +22,6 @@ public: u32 m_pitch; u16 m_depth; - u16 m_bias; - u8 m_min_filter; - u8 m_mag_filter; - u8 m_conv; - u8 m_a_signed; - u8 m_r_signed; - u8 m_g_signed; - u8 m_b_signed; - public: RSXTexture(); RSXTexture(u8 index); @@ -67,12 +58,21 @@ public: // Control1 u32 GetRemap() const; + // Filter + u16 GetBias() const; + u8 GetMinFilter() const; + u8 GetMagFilter() const; + u8 GetConvolutionFilter() const; + bool isASigned() const; + bool isRSigned() const; + bool isGSigned() const; + bool isBSigned() const; + // Image Rect u16 GetWidth() const; u16 GetHeight() const; void SetControl3(u16 depth, u32 pitch); - void SetFilter(u16 bias, u8 min, u8 mag, u8 conv, u8 a_signed, u8 r_signed, u8 g_signed, u8 b_signed); }; struct RSXVertexData