From 0f664ef89d68bb008c386680a7b1d747d50ac698 Mon Sep 17 00:00:00 2001 From: wwylele Date: Wed, 3 May 2017 19:59:48 +0300 Subject: [PATCH 1/2] pica: use correct coordinates for texture 2 --- src/video_core/regs_texturing.h | 4 ++++ .../renderer_opengl/gl_shader_gen.cpp | 17 ++++++++++++++--- src/video_core/renderer_opengl/gl_shader_gen.h | 1 + src/video_core/swrasterizer/rasterizer.cpp | 5 +++-- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/video_core/regs_texturing.h b/src/video_core/regs_texturing.h index 0b62da1457..515848bd69 100644 --- a/src/video_core/regs_texturing.h +++ b/src/video_core/regs_texturing.h @@ -122,6 +122,10 @@ struct TexturingRegs { BitField<0, 1, u32> texture0_enable; BitField<1, 1, u32> texture1_enable; BitField<2, 1, u32> texture2_enable; + BitField<8, 2, u32> texture3_coordinates; // TODO: unimplemented + BitField<10, 1, u32> texture3_enable; // TODO: unimplemented + BitField<13, 1, u32> texture2_use_coord1; + BitField<16, 1, u32> clear_texture_cache; // TODO: unimplemented }; TextureConfig texture0; INSERT_PADDING_WORDS(0x8); diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 0f889b1725..5077e38b7e 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -40,6 +40,8 @@ PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) { state.texture0_type = regs.texturing.texture0.type; + state.texture2_use_coord1 = regs.texturing.texture2_use_coord1 != 0; + // Copy relevant tev stages fields. // We don't sync const_color here because of the high variance, it is a // shader uniform instead. @@ -126,6 +128,15 @@ static bool IsPassThroughTevStage(const TevStageConfig& stage) { stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); } +static std::string TexCoord(const PicaShaderConfig& config, int texture_unit) { + if (texture_unit == 2 && config.state.texture2_use_coord1) { + return "texcoord[1]"; + } + // TODO: if texture unit 3 (procedural texture) implementation also uses this function, + // config.state.texture3_coordinates should be repected here. + return "texcoord[" + std::to_string(texture_unit) + "]"; +} + /// Writes the specified TEV stage source component(s) static void AppendSource(std::string& out, const PicaShaderConfig& config, TevStageConfig::Source source, const std::string& index_name) { @@ -162,7 +173,7 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, out += "texture(tex[1], texcoord[1])"; break; case Source::Texture2: - out += "texture(tex[2], texcoord[2])"; + out += "texture(tex[2], " + TexCoord(config, 2) + ")"; break; case Source::PreviousBuffer: out += "combiner_buffer"; @@ -473,8 +484,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // Bump mapping is enabled using a normal map, read perturbation vector from the selected // texture std::string bump_selector = std::to_string(lighting.bump_selector); - out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], texcoord[" + - bump_selector + "]).rgb - 1.0;\n"; + out += "vec3 surface_normal = 2.0 * texture(tex[" + bump_selector + "], " + + TexCoord(config, lighting.bump_selector) + ").rgb - 1.0;\n"; // Recompute Z-component of perturbation if 'renorm' is enabled, this provides a higher // precision result diff --git a/src/video_core/renderer_opengl/gl_shader_gen.h b/src/video_core/renderer_opengl/gl_shader_gen.h index 921d976a10..3fb046b76e 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.h +++ b/src/video_core/renderer_opengl/gl_shader_gen.h @@ -79,6 +79,7 @@ union PicaShaderConfig { Pica::FramebufferRegs::CompareFunc alpha_test_func; Pica::RasterizerRegs::ScissorMode scissor_test_mode; Pica::TexturingRegs::TextureConfig::TextureType texture0_type; + bool texture2_use_coord1; std::array tev_stages; u8 combiner_buffer_input; diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index cb1b90a817..fa8377f80e 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -276,8 +276,9 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve DEBUG_ASSERT(0 != texture.config.address); - float24 u = uv[i].u(); - float24 v = uv[i].v(); + int coordinate_i = (i == 2 && regs.texturing.texture2_use_coord1) ? 1 : i; + float24 u = uv[coordinate_i].u(); + float24 v = uv[coordinate_i].v(); // Only unit 0 respects the texturing type (according to 3DBrew) // TODO: Refactor so cubemaps and shadowmaps can be handled From 039b2930928c34c011fcc236d7f8c32599077ad0 Mon Sep 17 00:00:00 2001 From: wwylele Date: Fri, 5 May 2017 15:29:35 +0300 Subject: [PATCH 2/2] pica: shader_dirty if texture2 coord changed --- src/video_core/regs.h | 2 +- src/video_core/regs_texturing.h | 8 ++++---- src/video_core/renderer_opengl/gl_rasterizer.cpp | 4 ++++ src/video_core/renderer_opengl/gl_shader_gen.cpp | 2 +- src/video_core/swrasterizer/rasterizer.cpp | 3 ++- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/video_core/regs.h b/src/video_core/regs.h index 86826088b0..1776dad89b 100644 --- a/src/video_core/regs.h +++ b/src/video_core/regs.h @@ -93,7 +93,7 @@ ASSERT_REG_POSITION(rasterizer.viewport_corner, 0x68); ASSERT_REG_POSITION(rasterizer.depthmap_enable, 0x6D); ASSERT_REG_POSITION(texturing, 0x80); -ASSERT_REG_POSITION(texturing.texture0_enable, 0x80); +ASSERT_REG_POSITION(texturing.main_config, 0x80); ASSERT_REG_POSITION(texturing.texture0, 0x81); ASSERT_REG_POSITION(texturing.texture0_format, 0x8e); ASSERT_REG_POSITION(texturing.fragment_lighting_enable, 0x8f); diff --git a/src/video_core/regs_texturing.h b/src/video_core/regs_texturing.h index 515848bd69..8a7c6efe4e 100644 --- a/src/video_core/regs_texturing.h +++ b/src/video_core/regs_texturing.h @@ -126,7 +126,7 @@ struct TexturingRegs { BitField<10, 1, u32> texture3_enable; // TODO: unimplemented BitField<13, 1, u32> texture2_use_coord1; BitField<16, 1, u32> clear_texture_cache; // TODO: unimplemented - }; + } main_config; TextureConfig texture0; INSERT_PADDING_WORDS(0x8); BitField<0, 4, TextureFormat> texture0_format; @@ -146,9 +146,9 @@ struct TexturingRegs { }; const std::array GetTextures() const { return {{ - {texture0_enable.ToBool(), texture0, texture0_format}, - {texture1_enable.ToBool(), texture1, texture1_format}, - {texture2_enable.ToBool(), texture2, texture2_format}, + {main_config.texture0_enable.ToBool(), texture0, texture0_format}, + {main_config.texture1_enable.ToBool(), texture1, texture1_format}, + {main_config.texture2_enable.ToBool(), texture2, texture2_format}, }}; } diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index a473070991..12ac9bbd97 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -402,6 +402,10 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { SyncLogicOp(); break; + case PICA_REG_INDEX(texturing.main_config): + shader_dirty = true; + break; + // Texture 0 type case PICA_REG_INDEX(texturing.texture0.type): shader_dirty = true; diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 5077e38b7e..7b44dade81 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -40,7 +40,7 @@ PicaShaderConfig PicaShaderConfig::BuildFromRegs(const Pica::Regs& regs) { state.texture0_type = regs.texturing.texture0.type; - state.texture2_use_coord1 = regs.texturing.texture2_use_coord1 != 0; + state.texture2_use_coord1 = regs.texturing.main_config.texture2_use_coord1 != 0; // Copy relevant tev stages fields. // We don't sync const_color here because of the high variance, it is a diff --git a/src/video_core/swrasterizer/rasterizer.cpp b/src/video_core/swrasterizer/rasterizer.cpp index fa8377f80e..20addf0bdb 100644 --- a/src/video_core/swrasterizer/rasterizer.cpp +++ b/src/video_core/swrasterizer/rasterizer.cpp @@ -276,7 +276,8 @@ static void ProcessTriangleInternal(const Vertex& v0, const Vertex& v1, const Ve DEBUG_ASSERT(0 != texture.config.address); - int coordinate_i = (i == 2 && regs.texturing.texture2_use_coord1) ? 1 : i; + int coordinate_i = + (i == 2 && regs.texturing.main_config.texture2_use_coord1) ? 1 : i; float24 u = uv[coordinate_i].u(); float24 v = uv[coordinate_i].v();