diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 20 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.h | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 46 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 29 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.cpp | 11 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_manager.h | 8 |
8 files changed, 51 insertions, 91 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0f8227f7b..d93681813 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -323,8 +323,6 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) { | |||
| 323 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, | 323 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, |
| 324 | primitive_mode, current_texture_bindpoint); | 324 | primitive_mode, current_texture_bindpoint); |
| 325 | 325 | ||
| 326 | SetupAlphaTesting(shader); | ||
| 327 | |||
| 328 | // When VertexA is enabled, we have dual vertex shaders | 326 | // When VertexA is enabled, we have dual vertex shaders |
| 329 | if (program == Maxwell::ShaderProgram::VertexA) { | 327 | if (program == Maxwell::ShaderProgram::VertexA) { |
| 330 | // VertexB was combined with VertexA, so we skip the VertexB iteration | 328 | // VertexB was combined with VertexA, so we skip the VertexB iteration |
| @@ -882,19 +880,6 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, | |||
| 882 | return current_unit + static_cast<u32>(entries.size()); | 880 | return current_unit + static_cast<u32>(entries.size()); |
| 883 | } | 881 | } |
| 884 | 882 | ||
| 885 | void RasterizerOpenGL::SetupAlphaTesting(Shader& shader) { | ||
| 886 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | ||
| 887 | |||
| 888 | u32 func = static_cast<u32>(regs.alpha_test_func); | ||
| 889 | // Normalize the gl variants of opCompare to be the same as the normal variants | ||
| 890 | u32 op = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never); | ||
| 891 | if (func >= op) { | ||
| 892 | func = func - op + 1U; | ||
| 893 | } | ||
| 894 | |||
| 895 | shader->SetAlphaTesting(regs.alpha_test_enabled == 1, regs.alpha_test_ref, func); | ||
| 896 | } | ||
| 897 | |||
| 898 | void RasterizerOpenGL::SyncViewport() { | 883 | void RasterizerOpenGL::SyncViewport() { |
| 899 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; | 884 | const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; |
| 900 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; | 885 | const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[0].GetRect()}; |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 32a30e1b6..ece5cb2c4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -132,9 +132,6 @@ private: | |||
| 132 | u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, | 132 | u32 SetupTextures(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, |
| 133 | GLenum primitive_mode, u32 current_unit); | 133 | GLenum primitive_mode, u32 current_unit); |
| 134 | 134 | ||
| 135 | /// Syncs the alpha test state to match the guest state | ||
| 136 | void SetupAlphaTesting(Shader& shader); | ||
| 137 | |||
| 138 | /// Syncs the viewport to match the guest state | 135 | /// Syncs the viewport to match the guest state |
| 139 | void SyncViewport(); | 136 | void SyncViewport(); |
| 140 | 137 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index ccb8b4805..1a03a677f 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp | |||
| @@ -94,10 +94,6 @@ CachedShader::CachedShader(VAddr addr, Maxwell::ShaderProgram program_type) | |||
| 94 | // Store shader's code to lazily build it on draw | 94 | // Store shader's code to lazily build it on draw |
| 95 | geometry_programs.code = program_result.first; | 95 | geometry_programs.code = program_result.first; |
| 96 | } | 96 | } |
| 97 | |||
| 98 | if (program_type == Maxwell::ShaderProgram::Fragment) { | ||
| 99 | SaveAlphaTestingLocations(); | ||
| 100 | } | ||
| 101 | } | 97 | } |
| 102 | 98 | ||
| 103 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { | 99 | GLuint CachedShader::GetProgramResourceIndex(const GLShader::ConstBufferEntry& buffer) { |
| @@ -138,22 +134,6 @@ GLuint CachedShader::LazyGeometryProgram(OGLProgram& target_program, | |||
| 138 | return target_program.handle; | 134 | return target_program.handle; |
| 139 | }; | 135 | }; |
| 140 | 136 | ||
| 141 | void CachedShader::SetAlphaTesting(const bool enable, const float ref, const u32 func) { | ||
| 142 | if (program_type == Maxwell::ShaderProgram::Fragment) { | ||
| 143 | glProgramUniform1ui(program.handle, alpha_test.enable_loc, | ||
| 144 | (enable ? 1 : 0)); | ||
| 145 | glProgramUniform1f(program.handle, alpha_test.ref_loc, | ||
| 146 | ref); | ||
| 147 | glProgramUniform1ui(program.handle, alpha_test.func_loc, func); | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 151 | void CachedShader::SaveAlphaTestingLocations() { | ||
| 152 | alpha_test.enable_loc = glGetUniformLocation(program.handle, "alpha_testing_enable"); | ||
| 153 | alpha_test.ref_loc = glGetUniformLocation(program.handle, "alpha_testing_ref"); | ||
| 154 | alpha_test.func_loc = glGetUniformLocation(program.handle, "alpha_testing_func"); | ||
| 155 | } | ||
| 156 | |||
| 157 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { | 137 | Shader ShaderCacheOpenGL::GetStageProgram(Maxwell::ShaderProgram program) { |
| 158 | const VAddr program_addr{GetShaderAddress(program)}; | 138 | const VAddr program_addr{GetShaderAddress(program)}; |
| 159 | 139 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h index 7c80ee86b..a210f1731 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.h +++ b/src/video_core/renderer_opengl/gl_shader_cache.h | |||
| @@ -73,15 +73,11 @@ public: | |||
| 73 | /// Gets the GL uniform location for the specified resource, caching as needed | 73 | /// Gets the GL uniform location for the specified resource, caching as needed |
| 74 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); | 74 | GLint GetUniformLocation(const GLShader::SamplerEntry& sampler); |
| 75 | 75 | ||
| 76 | void SetAlphaTesting(const bool enable, const float ref, const u32 func); | ||
| 77 | |||
| 78 | private: | 76 | private: |
| 79 | /// Generates a geometry shader or returns one that already exists. | 77 | /// Generates a geometry shader or returns one that already exists. |
| 80 | GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, | 78 | GLuint LazyGeometryProgram(OGLProgram& target_program, const std::string& glsl_topology, |
| 81 | const std::string& debug_name); | 79 | const std::string& debug_name); |
| 82 | 80 | ||
| 83 | void SaveAlphaTestingLocations(); | ||
| 84 | |||
| 85 | VAddr addr; | 81 | VAddr addr; |
| 86 | Maxwell::ShaderProgram program_type; | 82 | Maxwell::ShaderProgram program_type; |
| 87 | GLShader::ShaderSetup setup; | 83 | GLShader::ShaderSetup setup; |
| @@ -102,12 +98,6 @@ private: | |||
| 102 | OGLProgram triangles_adjacency; | 98 | OGLProgram triangles_adjacency; |
| 103 | } geometry_programs; | 99 | } geometry_programs; |
| 104 | 100 | ||
| 105 | struct { | ||
| 106 | GLint enable_loc; | ||
| 107 | GLint ref_loc; | ||
| 108 | GLint func_loc; | ||
| 109 | } alpha_test; | ||
| 110 | |||
| 111 | std::map<u32, GLuint> resource_cache; | 101 | std::map<u32, GLuint> resource_cache; |
| 112 | std::map<u32, GLint> uniform_cache; | 102 | std::map<u32, GLint> uniform_cache; |
| 113 | }; | 103 | }; |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 7bd4d2d95..6fdfc742b 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -643,13 +643,6 @@ private: | |||
| 643 | ';'); | 643 | ';'); |
| 644 | } | 644 | } |
| 645 | declarations.AddNewLine(); | 645 | declarations.AddNewLine(); |
| 646 | |||
| 647 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { | ||
| 648 | declarations.AddLine("uniform bool alpha_testing_active;"); | ||
| 649 | declarations.AddLine("uniform float alpha_testing_ref;"); | ||
| 650 | declarations.AddLine("uniform uint alpha_testing_func;"); | ||
| 651 | } | ||
| 652 | declarations.AddNewLine(); | ||
| 653 | } | 646 | } |
| 654 | 647 | ||
| 655 | /// Generates declarations used for geometry shaders. | 648 | /// Generates declarations used for geometry shaders. |
| @@ -1271,17 +1264,20 @@ private: | |||
| 1271 | 1264 | ||
| 1272 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); | 1265 | ASSERT_MSG(header.ps.omap.sample_mask == 0, "Samplemask write is unimplemented"); |
| 1273 | 1266 | ||
| 1274 | shader.AddLine("if (alpha_testing_active) {"); | 1267 | shader.AddLine("if (alpha_test[0] != 0) {"); |
| 1275 | ++shader.scope; | 1268 | ++shader.scope; |
| 1269 | // We start on the register containing the alpha value in the first RT. | ||
| 1276 | u32 current_reg = 3; | 1270 | u32 current_reg = 3; |
| 1277 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; | 1271 | for (u32 render_target = 0; render_target < Maxwell3D::Regs::NumRenderTargets; |
| 1278 | ++render_target) { | 1272 | ++render_target) { |
| 1273 | // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when | ||
| 1274 | // multiple render targets are used. | ||
| 1279 | if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || | 1275 | if (header.ps.IsColorComponentOutputEnabled(render_target, 0) || |
| 1280 | header.ps.IsColorComponentOutputEnabled(render_target, 1) || | 1276 | header.ps.IsColorComponentOutputEnabled(render_target, 1) || |
| 1281 | header.ps.IsColorComponentOutputEnabled(render_target, 2) || | 1277 | header.ps.IsColorComponentOutputEnabled(render_target, 2) || |
| 1282 | header.ps.IsColorComponentOutputEnabled(render_target, 3)) { | 1278 | header.ps.IsColorComponentOutputEnabled(render_target, 3)) { |
| 1283 | shader.AddLine(fmt::format( | 1279 | shader.AddLine(fmt::format( |
| 1284 | "if (AlphaFunc({}, alpha_testing_ref, alpha_testing_func)) discard;", | 1280 | "if (AlphaFunc({})) discard;", |
| 1285 | regs.GetRegisterAsFloat(current_reg))); | 1281 | regs.GetRegisterAsFloat(current_reg))); |
| 1286 | current_reg += 4; | 1282 | current_reg += 4; |
| 1287 | } | 1283 | } |
| @@ -3506,38 +3502,6 @@ private: | |||
| 3506 | declarations.AddLine("bool " + pred + " = false;"); | 3502 | declarations.AddLine("bool " + pred + " = false;"); |
| 3507 | } | 3503 | } |
| 3508 | declarations.AddNewLine(); | 3504 | declarations.AddNewLine(); |
| 3509 | GenerateFunctionDeclarations(); | ||
| 3510 | } | ||
| 3511 | |||
| 3512 | void GenerateFunctionDeclarations() { | ||
| 3513 | if (stage == Maxwell3D::Regs::ShaderStage::Fragment) { | ||
| 3514 | declarations.AddLine("bool AlphaFunc(in float value, in float ref, in uint func) {"); | ||
| 3515 | declarations.scope++; | ||
| 3516 | declarations.AddLine("switch (func) {"); | ||
| 3517 | declarations.scope++; | ||
| 3518 | declarations.AddLine("case 1:"); | ||
| 3519 | declarations.AddLine("return false;"); | ||
| 3520 | declarations.AddLine("case 2:"); | ||
| 3521 | declarations.AddLine("return value < ref;"); | ||
| 3522 | declarations.AddLine("case 3:"); | ||
| 3523 | declarations.AddLine("return value == ref;"); | ||
| 3524 | declarations.AddLine("case 4:"); | ||
| 3525 | declarations.AddLine("return value <= ref;"); | ||
| 3526 | declarations.AddLine("case 5:"); | ||
| 3527 | declarations.AddLine("return value > ref;"); | ||
| 3528 | declarations.AddLine("case 6:"); | ||
| 3529 | declarations.AddLine("return value != ref;"); | ||
| 3530 | declarations.AddLine("case 7:"); | ||
| 3531 | declarations.AddLine("return value >= ref;"); | ||
| 3532 | declarations.AddLine("case 8:"); | ||
| 3533 | declarations.AddLine("return true;"); | ||
| 3534 | declarations.AddLine("default:"); | ||
| 3535 | declarations.AddLine("return false;"); | ||
| 3536 | declarations.scope--; | ||
| 3537 | declarations.AddLine('}'); | ||
| 3538 | declarations.scope--; | ||
| 3539 | declarations.AddLine('}'); | ||
| 3540 | } | ||
| 3541 | } | 3505 | } |
| 3542 | 3506 | ||
| 3543 | private: | 3507 | private: |
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index ecbc9d8ed..e883ffb1d 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp | |||
| @@ -29,6 +29,7 @@ layout(std140) uniform vs_config { | |||
| 29 | vec4 viewport_flip; | 29 | vec4 viewport_flip; |
| 30 | uvec4 instance_id; | 30 | uvec4 instance_id; |
| 31 | uvec4 flip_stage; | 31 | uvec4 flip_stage; |
| 32 | uvec4 alpha_test; | ||
| 32 | }; | 33 | }; |
| 33 | )"; | 34 | )"; |
| 34 | 35 | ||
| @@ -105,6 +106,7 @@ layout (std140) uniform gs_config { | |||
| 105 | vec4 viewport_flip; | 106 | vec4 viewport_flip; |
| 106 | uvec4 instance_id; | 107 | uvec4 instance_id; |
| 107 | uvec4 flip_stage; | 108 | uvec4 flip_stage; |
| 109 | uvec4 alpha_test; | ||
| 108 | }; | 110 | }; |
| 109 | 111 | ||
| 110 | void main() { | 112 | void main() { |
| @@ -142,8 +144,33 @@ layout (std140) uniform fs_config { | |||
| 142 | vec4 viewport_flip; | 144 | vec4 viewport_flip; |
| 143 | uvec4 instance_id; | 145 | uvec4 instance_id; |
| 144 | uvec4 flip_stage; | 146 | uvec4 flip_stage; |
| 147 | uvec4 alpha_test; | ||
| 145 | }; | 148 | }; |
| 146 | 149 | ||
| 150 | bool AlphaFunc(in float value) { | ||
| 151 | float ref = uintBitsToFloat(alpha_test[2]); | ||
| 152 | switch (alpha_test[1]) { | ||
| 153 | case 1: | ||
| 154 | return false; | ||
| 155 | case 2: | ||
| 156 | return value < ref; | ||
| 157 | case 3: | ||
| 158 | return value == ref; | ||
| 159 | case 4: | ||
| 160 | return value <= ref; | ||
| 161 | case 5: | ||
| 162 | return value > ref; | ||
| 163 | case 6: | ||
| 164 | return value != ref; | ||
| 165 | case 7: | ||
| 166 | return value >= ref; | ||
| 167 | case 8: | ||
| 168 | return true; | ||
| 169 | default: | ||
| 170 | return false; | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 147 | void main() { | 174 | void main() { |
| 148 | exec_fragment(); | 175 | exec_fragment(); |
| 149 | } | 176 | } |
| @@ -152,4 +179,4 @@ void main() { | |||
| 152 | out += program.first; | 179 | out += program.first; |
| 153 | return {out, program.second}; | 180 | return {out, program.second}; |
| 154 | } | 181 | } |
| 155 | } // namespace OpenGL::GLShader \ No newline at end of file | 182 | } // namespace OpenGL::GLShader |
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp index 010857ec6..8b8869ecb 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.cpp +++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp | |||
| @@ -16,6 +16,17 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D::State::ShaderStageInfo& sh | |||
| 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; | 16 | viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; |
| 17 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; | 17 | viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; |
| 18 | 18 | ||
| 19 | u32 func = static_cast<u32>(regs.alpha_test_func); | ||
| 20 | // Normalize the gl variants of opCompare to be the same as the normal variants | ||
| 21 | u32 op_gl_variant_base = static_cast<u32>(Tegra::Engines::Maxwell3D::Regs::ComparisonOp::Never); | ||
| 22 | if (func >= op_gl_variant_base) { | ||
| 23 | func = func - op_gl_variant_base + 1U; | ||
| 24 | } | ||
| 25 | |||
| 26 | alpha_test.enabled = regs.alpha_test_enabled; | ||
| 27 | alpha_test.func = func; | ||
| 28 | alpha_test.ref = regs.alpha_test_ref; | ||
| 29 | |||
| 19 | // We only assign the instance to the first component of the vector, the rest is just padding. | 30 | // We only assign the instance to the first component of the vector, the rest is just padding. |
| 20 | instance_id[0] = state.current_instance; | 31 | instance_id[0] = state.current_instance; |
| 21 | 32 | ||
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h index b3a191cf2..36fe1f04c 100644 --- a/src/video_core/renderer_opengl/gl_shader_manager.h +++ b/src/video_core/renderer_opengl/gl_shader_manager.h | |||
| @@ -22,8 +22,14 @@ struct MaxwellUniformData { | |||
| 22 | alignas(16) GLvec4 viewport_flip; | 22 | alignas(16) GLvec4 viewport_flip; |
| 23 | alignas(16) GLuvec4 instance_id; | 23 | alignas(16) GLuvec4 instance_id; |
| 24 | alignas(16) GLuvec4 flip_stage; | 24 | alignas(16) GLuvec4 flip_stage; |
| 25 | struct alignas(16) { | ||
| 26 | GLuint enabled; | ||
| 27 | GLuint func; | ||
| 28 | GLfloat ref; | ||
| 29 | GLuint padding; | ||
| 30 | } alpha_test; | ||
| 25 | }; | 31 | }; |
| 26 | static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); | 32 | static_assert(sizeof(MaxwellUniformData) == 64, "MaxwellUniformData structure size is incorrect"); |
| 27 | static_assert(sizeof(MaxwellUniformData) < 16384, | 33 | static_assert(sizeof(MaxwellUniformData) < 16384, |
| 28 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); | 34 | "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); |
| 29 | 35 | ||