summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-05-21 20:28:09 -0300
committerGravatar ReinUsesLisp2019-05-30 13:21:01 -0300
commitb76df62c00c28244f2fdd657b809853907f0070f (patch)
treedfba6fc3c4fa662f9ee6825595597596811873ec /src
parentgl_rasterizer: Use GL_QUADS to emulate quads rendering (diff)
downloadyuzu-b76df62c00c28244f2fdd657b809853907f0070f.tar.gz
yuzu-b76df62c00c28244f2fdd657b809853907f0070f.tar.xz
yuzu-b76df62c00c28244f2fdd657b809853907f0070f.zip
gl_rasterizer: Move alpha testing to the OpenGL pipeline
Removes the alpha testing code from each fragment shader invocation.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp14
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp20
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp27
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.cpp11
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h8
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp13
-rw-r--r--src/video_core/renderer_opengl/gl_state.h7
8 files changed, 33 insertions, 71 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 5087d9406..ca410287a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -663,13 +663,10 @@ void RasterizerOpenGL::DrawArrays() {
663 SyncCullMode(); 663 SyncCullMode();
664 SyncPrimitiveRestart(); 664 SyncPrimitiveRestart();
665 SyncScissorTest(state); 665 SyncScissorTest(state);
666 // Alpha Testing is synced on shaders.
667 SyncTransformFeedback(); 666 SyncTransformFeedback();
668 SyncPointState(); 667 SyncPointState();
669 CheckAlphaTests();
670 SyncPolygonOffset(); 668 SyncPolygonOffset();
671 // TODO(bunnei): Sync framebuffer_scale uniform here 669 SyncAlphaTest();
672 // TODO(bunnei): Sync scissorbox uniform(s) here
673 670
674 // Draw the vertex batch 671 // Draw the vertex batch
675 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 672 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
@@ -1121,10 +1118,17 @@ void RasterizerOpenGL::SyncPolygonOffset() {
1121 state.polygon_offset.clamp = regs.polygon_offset_clamp; 1118 state.polygon_offset.clamp = regs.polygon_offset_clamp;
1122} 1119}
1123 1120
1124void RasterizerOpenGL::CheckAlphaTests() { 1121void RasterizerOpenGL::SyncAlphaTest() {
1125 const auto& regs = system.GPU().Maxwell3D().regs; 1122 const auto& regs = system.GPU().Maxwell3D().regs;
1126 UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1, 1123 UNIMPLEMENTED_IF_MSG(regs.alpha_test_enabled != 0 && regs.rt_control.count > 1,
1127 "Alpha Testing is enabled with more than one rendertarget"); 1124 "Alpha Testing is enabled with more than one rendertarget");
1125
1126 state.alpha_test.enabled = regs.alpha_test_enabled;
1127 if (!state.alpha_test.enabled) {
1128 return;
1129 }
1130 state.alpha_test.func = MaxwellToGL::ComparisonOp(regs.alpha_test_func);
1131 state.alpha_test.ref = regs.alpha_test_ref;
1128} 1132}
1129 1133
1130} // namespace OpenGL 1134} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index f2643f26f..2817f65c9 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -166,8 +166,8 @@ private:
166 /// Syncs the polygon offsets 166 /// Syncs the polygon offsets
167 void SyncPolygonOffset(); 167 void SyncPolygonOffset();
168 168
169 /// Check asserts for alpha testing. 169 /// Syncs the alpha test state to match the guest state
170 void CheckAlphaTests(); 170 void SyncAlphaTest();
171 171
172 /// Check for extension that are not strictly required 172 /// Check for extension that are not strictly required
173 /// but are needed for correct emulation 173 /// but are needed for correct emulation
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index e9f8d40db..ab75bb795 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1447,27 +1447,9 @@ private:
1447 1447
1448 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented"); 1448 UNIMPLEMENTED_IF_MSG(header.ps.omap.sample_mask != 0, "Sample mask write is unimplemented");
1449 1449
1450 code.AddLine("if (alpha_test[0] != 0) {{");
1451 ++code.scope;
1452 // We start on the register containing the alpha value in the first RT.
1453 u32 current_reg = 3;
1454 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
1455 // TODO(Blinkhawk): verify the behavior of alpha testing on hardware when
1456 // multiple render targets are used.
1457 if (header.ps.IsColorComponentOutputEnabled(render_target, 0) ||
1458 header.ps.IsColorComponentOutputEnabled(render_target, 1) ||
1459 header.ps.IsColorComponentOutputEnabled(render_target, 2) ||
1460 header.ps.IsColorComponentOutputEnabled(render_target, 3)) {
1461 code.AddLine("if (!AlphaFunc({})) discard;", SafeGetRegister(current_reg));
1462 current_reg += 4;
1463 }
1464 }
1465 --code.scope;
1466 code.AddLine("}}");
1467
1468 // Write the color outputs using the data in the shader registers, disabled 1450 // Write the color outputs using the data in the shader registers, disabled
1469 // rendertargets/components are skipped in the register assignment. 1451 // rendertargets/components are skipped in the register assignment.
1470 current_reg = 0; 1452 u32 current_reg = 0;
1471 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) { 1453 for (u32 render_target = 0; render_target < Maxwell::NumRenderTargets; ++render_target) {
1472 // TODO(Subv): Figure out how dual-source blending is configured in the Switch. 1454 // TODO(Subv): Figure out how dual-source blending is configured in the Switch.
1473 for (u32 component = 0; component < 4; ++component) { 1455 for (u32 component = 0; component < 4; ++component) {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index d2bb705a9..269dda122 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -28,7 +28,6 @@ layout (location = 0) out vec4 position;
28layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config { 28layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
29 vec4 viewport_flip; 29 vec4 viewport_flip;
30 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 30 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
31 uvec4 alpha_test;
32}; 31};
33 32
34)"; 33)";
@@ -91,7 +90,6 @@ layout (location = 0) out vec4 position;
91layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config { 90layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
92 vec4 viewport_flip; 91 vec4 viewport_flip;
93 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 92 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
94 uvec4 alpha_test;
95}; 93};
96 94
97)"; 95)";
@@ -129,33 +127,8 @@ layout (location = 0) in noperspective vec4 position;
129layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config { 127layout (std140, binding = EMULATION_UBO_BINDING) uniform fs_config {
130 vec4 viewport_flip; 128 vec4 viewport_flip;
131 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding 129 uvec4 config_pack; // instance_id, flip_stage, y_direction, padding
132 uvec4 alpha_test;
133}; 130};
134 131
135bool AlphaFunc(in float value) {
136 float ref = uintBitsToFloat(alpha_test[2]);
137 switch (alpha_test[1]) {
138 case 1:
139 return false;
140 case 2:
141 return value < ref;
142 case 3:
143 return value == ref;
144 case 4:
145 return value <= ref;
146 case 5:
147 return value > ref;
148 case 6:
149 return value != ref;
150 case 7:
151 return value >= ref;
152 case 8:
153 return true;
154 default:
155 return false;
156 }
157}
158
159)"; 132)";
160 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 133 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
161 ProgramResult program = 134 ProgramResult program =
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.cpp b/src/video_core/renderer_opengl/gl_shader_manager.cpp
index 05ab01dcb..b05f90f20 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_manager.cpp
@@ -48,17 +48,6 @@ void MaxwellUniformData::SetFromRegs(const Maxwell3D& maxwell, std::size_t shade
48 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f; 48 viewport_flip[0] = regs.viewport_transform[0].scale_x < 0.0 ? -1.0f : 1.0f;
49 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f; 49 viewport_flip[1] = regs.viewport_transform[0].scale_y < 0.0 ? -1.0f : 1.0f;
50 50
51 auto func{static_cast<u32>(regs.alpha_test_func)};
52 // Normalize the gl variants of opCompare to be the same as the normal variants
53 const u32 op_gl_variant_base = static_cast<u32>(Maxwell3D::Regs::ComparisonOp::Never);
54 if (func >= op_gl_variant_base) {
55 func = func - op_gl_variant_base + 1U;
56 }
57
58 alpha_test.enabled = regs.alpha_test_enabled;
59 alpha_test.func = func;
60 alpha_test.ref = regs.alpha_test_ref;
61
62 instance_id = state.current_instance; 51 instance_id = state.current_instance;
63 52
64 // Assign in which stage the position has to be flipped 53 // Assign in which stage the position has to be flipped
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index cec18a832..6961e702a 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -27,14 +27,8 @@ struct MaxwellUniformData {
27 GLuint flip_stage; 27 GLuint flip_stage;
28 GLfloat y_direction; 28 GLfloat y_direction;
29 }; 29 };
30 struct alignas(16) {
31 GLuint enabled;
32 GLuint func;
33 GLfloat ref;
34 GLuint padding;
35 } alpha_test;
36}; 30};
37static_assert(sizeof(MaxwellUniformData) == 48, "MaxwellUniformData structure size is incorrect"); 31static_assert(sizeof(MaxwellUniformData) == 32, "MaxwellUniformData structure size is incorrect");
38static_assert(sizeof(MaxwellUniformData) < 16384, 32static_assert(sizeof(MaxwellUniformData) < 16384,
39 "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec"); 33 "MaxwellUniformData structure must be less than 16kb as per the OpenGL spec");
40 34
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 7425fbe5d..d86e137ac 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -156,6 +156,10 @@ OpenGLState::OpenGLState() {
156 polygon_offset.factor = 0.0f; 156 polygon_offset.factor = 0.0f;
157 polygon_offset.units = 0.0f; 157 polygon_offset.units = 0.0f;
158 polygon_offset.clamp = 0.0f; 158 polygon_offset.clamp = 0.0f;
159
160 alpha_test.enabled = false;
161 alpha_test.func = GL_ALWAYS;
162 alpha_test.ref = 0.0f;
159} 163}
160 164
161void OpenGLState::ApplyDefaultState() { 165void OpenGLState::ApplyDefaultState() {
@@ -461,6 +465,14 @@ void OpenGLState::ApplyPolygonOffset() const {
461 } 465 }
462} 466}
463 467
468void OpenGLState::ApplyAlphaTest() const {
469 Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled);
470 if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref),
471 std::tie(alpha_test.func, alpha_test.ref))) {
472 glAlphaFunc(alpha_test.func, alpha_test.ref);
473 }
474}
475
464void OpenGLState::ApplyTextures() const { 476void OpenGLState::ApplyTextures() const {
465 bool has_delta{}; 477 bool has_delta{};
466 std::size_t first{}; 478 std::size_t first{};
@@ -533,6 +545,7 @@ void OpenGLState::Apply() const {
533 ApplyTextures(); 545 ApplyTextures();
534 ApplySamplers(); 546 ApplySamplers();
535 ApplyPolygonOffset(); 547 ApplyPolygonOffset();
548 ApplyAlphaTest();
536} 549}
537 550
538void OpenGLState::EmulateViewportWithScissor() { 551void OpenGLState::EmulateViewportWithScissor() {
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 41418a7b8..b0140495d 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -172,6 +172,12 @@ public:
172 GLfloat clamp; 172 GLfloat clamp;
173 } polygon_offset; 173 } polygon_offset;
174 174
175 struct {
176 bool enabled; // GL_ALPHA_TEST
177 GLenum func; // GL_ALPHA_TEST_FUNC
178 GLfloat ref; // GL_ALPHA_TEST_REF
179 } alpha_test;
180
175 std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE 181 std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE
176 182
177 OpenGLState(); 183 OpenGLState();
@@ -215,6 +221,7 @@ public:
215 void ApplySamplers() const; 221 void ApplySamplers() const;
216 void ApplyDepthClamp() const; 222 void ApplyDepthClamp() const;
217 void ApplyPolygonOffset() const; 223 void ApplyPolygonOffset() const;
224 void ApplyAlphaTest() const;
218 225
219 /// Set the initial OpenGL state 226 /// Set the initial OpenGL state
220 static void ApplyDefaultState(); 227 static void ApplyDefaultState();