diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index a258b5b6fc..068a0f6a2e 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -12,6 +12,7 @@ #endif gcmBuffer gcmBuffers[8]; +GLuint flipTex; int last_width = 0, last_height = 0, last_depth_format = 0; @@ -85,12 +86,15 @@ GLGSRender::GLGSRender() , m_context(nullptr) { m_frame = new GLGSFrame(); + + glGenTextures(1, &flipTex); } GLGSRender::~GLGSRender() { m_frame->Close(); delete m_context; + glDeleteTextures(1, &flipTex); } void GLGSRender::Enable(bool enable, const u32 cap) @@ -304,17 +308,39 @@ void GLGSRender::DisableVertexData() void GLGSRender::InitVertexData() { + GLfloat scaleOffsetMat[16] = {1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f}; + int l; + for(u32 i=0; i pixels; + pixels.SetCount(m_width * m_height * 4); + m_fbo.Bind(GL_READ_FRAMEBUFFER); + glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels.GetPtr()); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, flipTex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, pixels.GetPtr()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 1, 0, 1, 0, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + + m_program.UnUse(); + m_program.Use(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_ACCUM_BUFFER_BIT); + glBegin(GL_QUADS); + glTexCoord2i(0, 1); + glVertex2i(0, 0); + + glTexCoord2i(1, 1); + glVertex2i(1, 0); + + glTexCoord2i(1, 0); + glVertex2i(1, 1); + + glTexCoord2i(0, 0); + glVertex2i(0, 1); + glEnd(); + + /*GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); GLfbo::Blit( m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, - GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); + GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);*/ m_fbo.Bind(); } @@ -1072,4 +1139,39 @@ void GLGSRender::Flip() if(m_fbo.IsCreated()) m_fbo.Bind(); + + if(m_set_scissor_horizontal && m_set_scissor_vertical) + { + glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); + 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; } diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 8be6fc008c..d685271871 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -13,6 +13,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) @@ -51,9 +54,11 @@ public: case 1: return GL_REPEAT; case 2: return GL_MIRRORED_REPEAT; case 3: return GL_CLAMP_TO_EDGE; - case 4: return GL_TEXTURE_BORDER; - case 5: return GL_CLAMP_TO_EDGE;//GL_CLAMP; - //case 6: return GL_MIRROR_CLAMP_TO_EDGE_EXT; + case 4: return GL_CLAMP_TO_BORDER; + case 5: return GL_CLAMP_TO_EDGE; + case 6: return GL_MIRROR_CLAMP_TO_EDGE_EXT; + case 7: return GL_MIRROR_CLAMP_TO_BORDER_EXT; + case 8: return GL_MIRROR_CLAMP_EXT; } ConLog.Error("Texture wrap error: bad wrap (%d).", wrap); @@ -63,9 +68,9 @@ public: void Init(RSXTexture& tex) { Bind(); - if(!Memory.IsGoodAddr(tex.GetOffset())) + if(!Memory.IsGoodAddr(GetAddress(tex.GetOffset(), tex.GetLocation()))) { - ConLog.Error("Bad texture address=0x%x", tex.GetOffset()); + ConLog.Error("Bad texture address=0x%x", GetAddress(tex.GetOffset(), tex.GetLocation())); return; } //ConLog.Warning("texture addr = 0x%x, width = %d, height = %d, max_aniso=%d, mipmap=%d, remap=0x%x, zfunc=0x%x, wraps=0x%x, wrapt=0x%x, wrapr=0x%x, minlod=0x%x, maxlod=0x%x", @@ -77,12 +82,13 @@ public: bool is_swizzled = (tex.GetFormat() & 0x20) == 0; glPixelStorei(GL_PACK_ALIGNMENT, tex.m_pitch); - char* pixels = (char*)Memory.GetMemFromAddr(tex.GetOffset()); + char* pixels = (char*)Memory.GetMemFromAddr(GetAddress(tex.GetOffset(), tex.GetLocation())); + char* unswizzledPixels; switch(format) { case 0x81: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BLUE, GL_UNSIGNED_BYTE, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); @@ -94,39 +100,60 @@ public: break; case 0x85: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 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; case 0x86: { - u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 8; + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 8; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.m_width, tex.m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x87: { - u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16; + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.m_width, tex.m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x88: { - u32 size = ((tex.m_width + 3) / 4) * ((tex.m_height + 3) / 4) * 16; + u32 size = ((tex.GetWidth() + 3) / 4) * ((tex.GetHeight() + 3) / 4) * 16; - glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.m_width, tex.m_height, 0, size, pixels); + glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, tex.GetWidth(), tex.GetHeight(), 0, size, pixels); checkForGlError("GLTexture::Init() -> glCompressedTexImage2D"); } break; case 0x94: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_RED, GL_SHORT, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_SHORT, pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_ONE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ONE); @@ -135,30 +162,30 @@ public: break; case 0x9a: - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_HALF_FLOAT, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_HALF_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); break; case 0x9e: { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.m_width, tex.m_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE); } 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.m_mipmap - 1); - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.m_mipmap > 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.Getmipmap() - 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, tex.Getmipmap() > 1); if(format != 0x81 && format != 0x94) { - u8 remap_a = tex.m_remap & 0x3; - u8 remap_r = (tex.m_remap >> 2) & 0x3; - u8 remap_g = (tex.m_remap >> 4) & 0x3; - u8 remap_b = (tex.m_remap >> 6) & 0x3; + u8 remap_a = tex.GetRemap() & 0x3; + u8 remap_r = (tex.GetRemap() >> 2) & 0x3; + u8 remap_g = (tex.GetRemap() >> 4) & 0x3; + u8 remap_b = (tex.GetRemap() >> 6) & 0x3; static const int gl_remap[] = { @@ -174,6 +201,8 @@ public: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, gl_remap[remap_b]); } + checkForGlError("GLTexture::Init() -> remap"); + static const int gl_tex_zfunc[] = { GL_NEVER, @@ -186,14 +215,18 @@ public: GL_ALWAYS, }; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.m_wraps)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.m_wrapt)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GetGlWrap(tex.m_wrapr)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, gl_tex_zfunc[tex.m_zfunc]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GetGlWrap(tex.GetWrapS())); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GetGlWrap(tex.GetWrapT())); + 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"); - glTexEnvi(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, tex.m_bias); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, tex.m_minlod); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, tex.m_maxlod); + 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"); static const int gl_tex_filter[] = { @@ -207,20 +240,28 @@ 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"); + //Unbind(); + + if(is_swizzled && format == 0x85) + { + free(unswizzledPixels); + } } void Save(RSXTexture& tex, const wxString& name) { - if(!m_id || !tex.m_offset || !tex.m_width || !tex.m_height) return; + if(!m_id || !tex.GetOffset() || !tex.GetWidth() || !tex.GetHeight()) return; - u32* alldata = new u32[tex.m_width * tex.m_height]; + u32* alldata = new u32[tex.GetWidth() * tex.GetHeight()]; Bind(); - switch(tex.m_format & ~(0x20 | 0x40)) + switch(tex.GetFormat() & ~(0x20 | 0x40)) { case 0x81: glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, alldata); @@ -237,15 +278,15 @@ public: { wxFile f(name + ".raw", wxFile::write); - f.Write(alldata, tex.m_width * tex.m_height * 4); + f.Write(alldata, tex.GetWidth() * tex.GetHeight() * 4); } - u8* data = new u8[tex.m_width * tex.m_height * 3]; - u8* alpha = new u8[tex.m_width * tex.m_height]; + u8* data = new u8[tex.GetWidth() * tex.GetHeight() * 3]; + u8* alpha = new u8[tex.GetWidth() * tex.GetHeight()]; u8* src = (u8*)alldata; u8* dst_d = data; u8* dst_a = alpha; - for(u32 i=0; i> 2) & 0x1); +} + +u8 RSXTexture::GetBorderType() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 3) & 0x1); +} + +u8 RSXTexture::GetDimension() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 4) & 0xf); +} + +u8 RSXTexture::GetFormat() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 8) & 0xff); +} + +u16 RSXTexture::Getmipmap() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_FORMAT + (m_index*32)] >> 16) & 0xffff); +} + +u8 RSXTexture::GetWrapS() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)]) & 0xf); +} + +u8 RSXTexture::GetWrapT() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 8) & 0xf); +} + +u8 RSXTexture::GetWrapR() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 16) & 0xf); +} + +u8 RSXTexture::GetUnsignedRemap() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 12) & 0xf); +} + +u8 RSXTexture::GetZfunc() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 28) & 0xf); +} + +u8 RSXTexture::GetGamma() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 20) & 0xf); +} + +u8 RSXTexture::GetAnisoBias() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 4) & 0xf); +} + +u8 RSXTexture::GetSignedRemap() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_ADDRESS + (m_index*32)] >> 24) & 0xf); +} + +bool RSXTexture::IsEnabled() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 31) & 0x1); +} + +u16 RSXTexture::GetMinLOD() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 19) & 0xfff); +} + +u16 RSXTexture::GetMaxLOD() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 7) & 0xfff); +} + +u8 RSXTexture::GetMaxAniso() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 4) & 0x7); +} + +bool RSXTexture::IsAlphaKillEnabled() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_CONTROL0 + (m_index*32)] >> 2) & 0x1); +} + +u32 RSXTexture::GetRemap() const +{ + 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*32)] >> 16) & 0xffff); +} + +u16 RSXTexture::GetHeight() const +{ + return ((methodRegisters[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index*32)]) & 0xffff); +} + +void RSXTexture::SetControl3(u16 depth, u32 pitch) +{ + m_depth = depth; + m_pitch = pitch; +} \ No newline at end of file diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index bd9f4396df..9556370bf9 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -3,6 +3,21 @@ #define ARGS(x) (Memory.Read32(Memory.RSXIOMem.GetStartAddr() + re(m_ctrl->get) + (4*(x+1)))) +u32 methodRegisters[0xffff]; + +u32 GetAddress(u32 offset, u8 location) +{ + switch(location) + { + case CELL_GCM_LOCATION_LOCAL: return Memory.RSXFBMem.GetStartAddr() + offset; + case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset); + } + + ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location); + assert(0); + return 0; +} + RSXVertexData::RSXVertexData() : frequency(0) , stride(0) @@ -185,47 +200,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case_16(NV4097_SET_TEXTURE_OFFSET, 0x20): { - RSXTexture& tex = m_textures[index]; - const u32 offset = ARGS(0); - u32 a1 = ARGS(1); - u8 location = (a1 & 0x3) - 1; - const bool cubemap = (a1 >> 2) & 0x1; - const u8 dimension = (a1 >> 4) & 0xf; - const u8 format = (a1 >> 8) & 0xff; - const u16 mipmap = (a1 >> 16) & 0xffff; - CMD_LOG("index = %d, offset=0x%x, location=0x%x, cubemap=0x%x, dimension=0x%x, format=0x%x, mipmap=0x%x", - index, offset, location, cubemap, dimension, format, mipmap); - - if(location == 2) - { - ConLog.Error("Bad texture location."); - location = 1; - } - u32 tex_addr = GetAddress(offset, location); - if(!Memory.IsGoodAddr(tex_addr)) - ConLog.Error("Bad texture[%d] addr = 0x%x #offset = 0x%x, location=%d", index, tex_addr, offset, location); - //ConLog.Warning("texture addr = 0x%x #offset = 0x%x, location=%d", tex_addr, offset, location); - tex.SetOffset(tex_addr); - tex.SetFormat(cubemap, dimension, format, mipmap); - - if(!tex.m_width || !tex.m_height) - { - gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr); - if(!tex.m_width) tex.m_width = re(buffers[m_gcm_current_buffer].width); - if(!tex.m_height) tex.m_height = re(buffers[m_gcm_current_buffer].height); - } } break; case_16(NV4097_SET_TEXTURE_CONTROL0, 0x20): { - RSXTexture& tex = m_textures[index]; - u32 a0 = ARGS(0); - bool enable = a0 >> 31 ? true : false; - u16 minlod = (a0 >> 19) & 0xfff; - u16 maxlod = (a0 >> 7) & 0xfff; - u8 maxaniso = (a0 >> 2) & 0x7; - tex.SetControl0(enable, minlod, maxlod, maxaniso); } break; @@ -294,8 +273,6 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case_16(NV4097_SET_TEXTURE_CONTROL1, 0x20): { - RSXTexture& tex = m_textures[index]; - tex.SetControl1(ARGS(0)); } break; @@ -311,36 +288,11 @@ 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; case_16(NV4097_SET_TEXTURE_ADDRESS, 0x20): { - RSXTexture& tex = m_textures[index]; - - u32 a0 = ARGS(0); - u8 wraps = a0 & 0xf; - u8 aniso_bias = (a0 >> 4) & 0xf; - u8 wrapt = (a0 >> 8) & 0xf; - u8 unsigned_remap = (a0 >> 12) & 0xf; - u8 wrapr = (a0 >> 16) & 0xf; - u8 gamma = (a0 >> 20) & 0xf; - u8 signed_remap = (a0 >> 24) & 0xf; - u8 zfunc = a0 >> 28; - - tex.SetAddress(wraps, wrapt, wrapr, unsigned_remap, zfunc, gamma, aniso_bias, signed_remap); } break; @@ -350,26 +302,6 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case_16(NV4097_SET_TEXTURE_IMAGE_RECT, 32): { - RSXTexture& tex = m_textures[index]; - - u16 height = ARGS(0) & 0xffff; - u16 width = ARGS(0) >> 16; - CMD_LOG("width=%d, height=%d", width, height); - - if(!width || !height) - { - ConLog.Warning("Bad texture rect: %dx%d (%dx%d)", width, height, tex.m_width, tex.m_height); - for(int i=0; i::func(put, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, put)))); se_t::func(get, std::atomic_load((volatile std::atomic*)((u8*)m_ctrl + offsetof(CellGcmControl, get)))); @@ -1504,6 +1439,7 @@ void RSXThread::Task() if(cmd & CELL_GCM_METHOD_FLAG_NON_INCREMENT) { //ConLog.Warning("non increment cmd! 0x%x", cmd); + inc=0; } if(cmd == 0) @@ -1513,6 +1449,11 @@ void RSXThread::Task() continue; } + for(int i=0; iGetId()) SHOW_BUFFER(3); if (event.GetId() == p_buffer_tex->GetId()) { - if(Memory.IsGoodAddr(render.m_textures[m_cur_texture].m_offset) && render.m_textures[m_cur_texture].m_width && render.m_textures[m_cur_texture].m_height) + if(Memory.IsGoodAddr(GetAddress(render.m_textures[m_cur_texture].GetOffset(), render.m_textures[m_cur_texture].GetLocation())) && render.m_textures[m_cur_texture].GetWidth() && render.m_textures[m_cur_texture].GetHeight()) MemoryViewerPanel::ShowImage(this, - render.m_textures[m_cur_texture].m_offset, 0, - render.m_textures[m_cur_texture].m_width, - render.m_textures[m_cur_texture].m_height, false); + GetAddress(render.m_textures[m_cur_texture].GetOffset(), render.m_textures[m_cur_texture].GetLocation()), 1, + render.m_textures[m_cur_texture].GetWidth(), + render.m_textures[m_cur_texture].GetHeight(), false); } #undef SHOW_BUFFER @@ -417,15 +417,15 @@ void RSXDebugger::GetBuffers() } // Draw Texture - u32 TexBuffer_addr = render.m_textures[m_cur_texture].m_offset; + u32 TexBuffer_addr = GetAddress(render.m_textures[m_cur_texture].GetOffset(), render.m_textures[m_cur_texture].GetLocation()); if(!Memory.IsGoodAddr(TexBuffer_addr)) return; unsigned char* TexBuffer = (unsigned char*)Memory.VirtualToRealAddr(TexBuffer_addr); - u32 width = render.m_textures[m_cur_texture].m_width; - u32 height = render.m_textures[m_cur_texture].m_height; + u32 width = render.m_textures[m_cur_texture].GetWidth(); + u32 height = render.m_textures[m_cur_texture].GetHeight(); unsigned char* buffer = (unsigned char*)malloc(width * height * 3); memcpy(buffer, TexBuffer, width * height * 3); @@ -484,19 +484,22 @@ void RSXDebugger::GetTexture() for(uint i=0; iInsertItem(i, wxString::Format("%d", i)); - m_list_texture->SetItem(i, 1, wxString::Format("0x%x", render.m_textures[i].m_offset)); - m_list_texture->SetItem(i, 2, render.m_textures[i].m_cubemap ? "True" : "False"); - m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.m_textures[i].m_dimension)); - m_list_texture->SetItem(i, 4, render.m_textures[i].m_enabled ? "True" : "False"); - m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].m_format)); - m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].m_mipmap)); - m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch)); - m_list_texture->SetItem(i, 8, wxString::Format("%dx%d", - render.m_textures[i].m_width, - render.m_textures[i].m_height)); + if(render.m_textures[i].IsEnabled()) + { + m_list_texture->InsertItem(i, wxString::Format("%d", i)); + m_list_texture->SetItem(i, 1, wxString::Format("0x%x", GetAddress(render.m_textures[i].GetOffset(), render.m_textures[i].GetLocation()))); + m_list_texture->SetItem(i, 2, render.m_textures[i].isCubemap() ? "True" : "False"); + m_list_texture->SetItem(i, 3, wxString::Format("%dD", render.m_textures[i].GetDimension())); + m_list_texture->SetItem(i, 4, render.m_textures[i].IsEnabled() ? "True" : "False"); + m_list_texture->SetItem(i, 5, wxString::Format("0x%x", render.m_textures[i].GetFormat())); + m_list_texture->SetItem(i, 6, wxString::Format("0x%x", render.m_textures[i].Getmipmap())); + m_list_texture->SetItem(i, 7, wxString::Format("0x%x", render.m_textures[i].m_pitch)); + m_list_texture->SetItem(i, 8, wxString::Format("%dx%d", + render.m_textures[i].GetWidth(), + render.m_textures[i].GetHeight())); - m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White")); + m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White")); + } } } diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index d54859b8a4..05dbb2f58a 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -243,6 +243,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index a076af31e7..d7f9c7563c 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -394,7 +394,10 @@ Loader - + + Emu\GS + + Emu\SysCalls\Modules