diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.cpp | 223 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_state.h | 222 |
3 files changed, 156 insertions, 291 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 63cf4216b..6a4d2c83a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -68,8 +68,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind | |||
| 68 | ScreenInfo& info) | 68 | ScreenInfo& info) |
| 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, | 69 | : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device}, |
| 70 | system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { | 70 | system{system}, screen_info{info}, buffer_cache{*this, system, STREAM_BUFFER_SIZE} { |
| 71 | OpenGLState::ApplyDefaultState(); | ||
| 72 | |||
| 73 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 71 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| 74 | state.draw.shader_program = 0; | 72 | state.draw.shader_program = 0; |
| 75 | state.Apply(); | 73 | state.Apply(); |
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index bf86b5a0b..f25148362 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | ||
| 5 | #include <iterator> | 6 | #include <iterator> |
| 6 | #include <glad/glad.h> | 7 | #include <glad/glad.h> |
| 7 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| @@ -69,147 +70,29 @@ void Enable(GLenum cap, GLuint index, bool enable) { | |||
| 69 | } | 70 | } |
| 70 | 71 | ||
| 71 | void Enable(GLenum cap, bool& current_value, bool new_value) { | 72 | void Enable(GLenum cap, bool& current_value, bool new_value) { |
| 72 | if (UpdateValue(current_value, new_value)) | 73 | if (UpdateValue(current_value, new_value)) { |
| 73 | Enable(cap, new_value); | 74 | Enable(cap, new_value); |
| 75 | } | ||
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { | 78 | void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { |
| 77 | if (UpdateValue(current_value, new_value)) | 79 | if (UpdateValue(current_value, new_value)) { |
| 78 | Enable(cap, index, new_value); | 80 | Enable(cap, index, new_value); |
| 79 | } | ||
| 80 | |||
| 81 | } // namespace | ||
| 82 | |||
| 83 | OpenGLState::OpenGLState() { | ||
| 84 | // These all match default OpenGL values | ||
| 85 | framebuffer_srgb.enabled = false; | ||
| 86 | |||
| 87 | multisample_control.alpha_to_coverage = false; | ||
| 88 | multisample_control.alpha_to_one = false; | ||
| 89 | |||
| 90 | cull.enabled = false; | ||
| 91 | cull.mode = GL_BACK; | ||
| 92 | cull.front_face = GL_CCW; | ||
| 93 | |||
| 94 | depth.test_enabled = false; | ||
| 95 | depth.test_func = GL_LESS; | ||
| 96 | depth.write_mask = GL_TRUE; | ||
| 97 | |||
| 98 | primitive_restart.enabled = false; | ||
| 99 | primitive_restart.index = 0; | ||
| 100 | |||
| 101 | for (auto& item : color_mask) { | ||
| 102 | item.red_enabled = GL_TRUE; | ||
| 103 | item.green_enabled = GL_TRUE; | ||
| 104 | item.blue_enabled = GL_TRUE; | ||
| 105 | item.alpha_enabled = GL_TRUE; | ||
| 106 | } | 81 | } |
| 82 | } | ||
| 107 | 83 | ||
| 108 | const auto ResetStencil = [](auto& config) { | 84 | } // Anonymous namespace |
| 109 | config.test_func = GL_ALWAYS; | ||
| 110 | config.test_ref = 0; | ||
| 111 | config.test_mask = 0xFFFFFFFF; | ||
| 112 | config.write_mask = 0xFFFFFFFF; | ||
| 113 | config.action_depth_fail = GL_KEEP; | ||
| 114 | config.action_depth_pass = GL_KEEP; | ||
| 115 | config.action_stencil_fail = GL_KEEP; | ||
| 116 | }; | ||
| 117 | stencil.test_enabled = false; | ||
| 118 | ResetStencil(stencil.front); | ||
| 119 | ResetStencil(stencil.back); | ||
| 120 | |||
| 121 | for (auto& item : viewports) { | ||
| 122 | item.x = 0; | ||
| 123 | item.y = 0; | ||
| 124 | item.width = 0; | ||
| 125 | item.height = 0; | ||
| 126 | item.depth_range_near = 0.0f; | ||
| 127 | item.depth_range_far = 1.0f; | ||
| 128 | item.scissor.enabled = false; | ||
| 129 | item.scissor.x = 0; | ||
| 130 | item.scissor.y = 0; | ||
| 131 | item.scissor.width = 0; | ||
| 132 | item.scissor.height = 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | for (auto& item : blend) { | ||
| 136 | item.enabled = true; | ||
| 137 | item.rgb_equation = GL_FUNC_ADD; | ||
| 138 | item.a_equation = GL_FUNC_ADD; | ||
| 139 | item.src_rgb_func = GL_ONE; | ||
| 140 | item.dst_rgb_func = GL_ZERO; | ||
| 141 | item.src_a_func = GL_ONE; | ||
| 142 | item.dst_a_func = GL_ZERO; | ||
| 143 | } | ||
| 144 | |||
| 145 | independant_blend.enabled = false; | ||
| 146 | |||
| 147 | blend_color.red = 0.0f; | ||
| 148 | blend_color.green = 0.0f; | ||
| 149 | blend_color.blue = 0.0f; | ||
| 150 | blend_color.alpha = 0.0f; | ||
| 151 | |||
| 152 | logic_op.enabled = false; | ||
| 153 | logic_op.operation = GL_COPY; | ||
| 154 | |||
| 155 | draw.read_framebuffer = 0; | ||
| 156 | draw.draw_framebuffer = 0; | ||
| 157 | draw.vertex_array = 0; | ||
| 158 | draw.shader_program = 0; | ||
| 159 | draw.program_pipeline = 0; | ||
| 160 | |||
| 161 | clip_distance = {}; | ||
| 162 | |||
| 163 | point.size = 1; | ||
| 164 | |||
| 165 | fragment_color_clamp.enabled = false; | ||
| 166 | |||
| 167 | depth_clamp.far_plane = false; | ||
| 168 | depth_clamp.near_plane = false; | ||
| 169 | |||
| 170 | polygon_offset.fill_enable = false; | ||
| 171 | polygon_offset.line_enable = false; | ||
| 172 | polygon_offset.point_enable = false; | ||
| 173 | polygon_offset.factor = 0.0f; | ||
| 174 | polygon_offset.units = 0.0f; | ||
| 175 | polygon_offset.clamp = 0.0f; | ||
| 176 | 85 | ||
| 177 | alpha_test.enabled = false; | 86 | OpenGLState::OpenGLState() = default; |
| 178 | alpha_test.func = GL_ALWAYS; | ||
| 179 | alpha_test.ref = 0.0f; | ||
| 180 | } | ||
| 181 | 87 | ||
| 182 | void OpenGLState::SetDefaultViewports() { | 88 | void OpenGLState::SetDefaultViewports() { |
| 183 | for (auto& item : viewports) { | 89 | viewports.fill(Viewport{}); |
| 184 | item.x = 0; | ||
| 185 | item.y = 0; | ||
| 186 | item.width = 0; | ||
| 187 | item.height = 0; | ||
| 188 | item.depth_range_near = 0.0f; | ||
| 189 | item.depth_range_far = 1.0f; | ||
| 190 | item.scissor.enabled = false; | ||
| 191 | item.scissor.x = 0; | ||
| 192 | item.scissor.y = 0; | ||
| 193 | item.scissor.width = 0; | ||
| 194 | item.scissor.height = 0; | ||
| 195 | } | ||
| 196 | 90 | ||
| 197 | depth_clamp.far_plane = false; | 91 | depth_clamp.far_plane = false; |
| 198 | depth_clamp.near_plane = false; | 92 | depth_clamp.near_plane = false; |
| 199 | } | 93 | } |
| 200 | 94 | ||
| 201 | void OpenGLState::ApplyDefaultState() { | 95 | void OpenGLState::ApplyFramebufferState() { |
| 202 | glEnable(GL_BLEND); | ||
| 203 | glDisable(GL_FRAMEBUFFER_SRGB); | ||
| 204 | glDisable(GL_CULL_FACE); | ||
| 205 | glDisable(GL_DEPTH_TEST); | ||
| 206 | glDisable(GL_PRIMITIVE_RESTART); | ||
| 207 | glDisable(GL_STENCIL_TEST); | ||
| 208 | glDisable(GL_COLOR_LOGIC_OP); | ||
| 209 | glDisable(GL_SCISSOR_TEST); | ||
| 210 | } | ||
| 211 | |||
| 212 | void OpenGLState::ApplyFramebufferState() const { | ||
| 213 | if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { | 96 | if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) { |
| 214 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); | 97 | glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer); |
| 215 | } | 98 | } |
| @@ -218,52 +101,52 @@ void OpenGLState::ApplyFramebufferState() const { | |||
| 218 | } | 101 | } |
| 219 | } | 102 | } |
| 220 | 103 | ||
| 221 | void OpenGLState::ApplyVertexArrayState() const { | 104 | void OpenGLState::ApplyVertexArrayState() { |
| 222 | if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { | 105 | if (UpdateValue(cur_state.draw.vertex_array, draw.vertex_array)) { |
| 223 | glBindVertexArray(draw.vertex_array); | 106 | glBindVertexArray(draw.vertex_array); |
| 224 | } | 107 | } |
| 225 | } | 108 | } |
| 226 | 109 | ||
| 227 | void OpenGLState::ApplyShaderProgram() const { | 110 | void OpenGLState::ApplyShaderProgram() { |
| 228 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { | 111 | if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) { |
| 229 | glUseProgram(draw.shader_program); | 112 | glUseProgram(draw.shader_program); |
| 230 | } | 113 | } |
| 231 | } | 114 | } |
| 232 | 115 | ||
| 233 | void OpenGLState::ApplyProgramPipeline() const { | 116 | void OpenGLState::ApplyProgramPipeline() { |
| 234 | if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { | 117 | if (UpdateValue(cur_state.draw.program_pipeline, draw.program_pipeline)) { |
| 235 | glBindProgramPipeline(draw.program_pipeline); | 118 | glBindProgramPipeline(draw.program_pipeline); |
| 236 | } | 119 | } |
| 237 | } | 120 | } |
| 238 | 121 | ||
| 239 | void OpenGLState::ApplyClipDistances() const { | 122 | void OpenGLState::ApplyClipDistances() { |
| 240 | for (std::size_t i = 0; i < clip_distance.size(); ++i) { | 123 | for (std::size_t i = 0; i < clip_distance.size(); ++i) { |
| 241 | Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i], | 124 | Enable(GL_CLIP_DISTANCE0 + static_cast<GLenum>(i), cur_state.clip_distance[i], |
| 242 | clip_distance[i]); | 125 | clip_distance[i]); |
| 243 | } | 126 | } |
| 244 | } | 127 | } |
| 245 | 128 | ||
| 246 | void OpenGLState::ApplyPointSize() const { | 129 | void OpenGLState::ApplyPointSize() { |
| 247 | if (UpdateValue(cur_state.point.size, point.size)) { | 130 | if (UpdateValue(cur_state.point.size, point.size)) { |
| 248 | glPointSize(point.size); | 131 | glPointSize(point.size); |
| 249 | } | 132 | } |
| 250 | } | 133 | } |
| 251 | 134 | ||
| 252 | void OpenGLState::ApplyFragmentColorClamp() const { | 135 | void OpenGLState::ApplyFragmentColorClamp() { |
| 253 | if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) { | 136 | if (UpdateValue(cur_state.fragment_color_clamp.enabled, fragment_color_clamp.enabled)) { |
| 254 | glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, | 137 | glClampColor(GL_CLAMP_FRAGMENT_COLOR_ARB, |
| 255 | fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); | 138 | fragment_color_clamp.enabled ? GL_TRUE : GL_FALSE); |
| 256 | } | 139 | } |
| 257 | } | 140 | } |
| 258 | 141 | ||
| 259 | void OpenGLState::ApplyMultisample() const { | 142 | void OpenGLState::ApplyMultisample() { |
| 260 | Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage, | 143 | Enable(GL_SAMPLE_ALPHA_TO_COVERAGE, cur_state.multisample_control.alpha_to_coverage, |
| 261 | multisample_control.alpha_to_coverage); | 144 | multisample_control.alpha_to_coverage); |
| 262 | Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one, | 145 | Enable(GL_SAMPLE_ALPHA_TO_ONE, cur_state.multisample_control.alpha_to_one, |
| 263 | multisample_control.alpha_to_one); | 146 | multisample_control.alpha_to_one); |
| 264 | } | 147 | } |
| 265 | 148 | ||
| 266 | void OpenGLState::ApplyDepthClamp() const { | 149 | void OpenGLState::ApplyDepthClamp() { |
| 267 | if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && | 150 | if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && |
| 268 | depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { | 151 | depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { |
| 269 | return; | 152 | return; |
| @@ -276,7 +159,7 @@ void OpenGLState::ApplyDepthClamp() const { | |||
| 276 | Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane); | 159 | Enable(GL_DEPTH_CLAMP, depth_clamp.far_plane || depth_clamp.near_plane); |
| 277 | } | 160 | } |
| 278 | 161 | ||
| 279 | void OpenGLState::ApplySRgb() const { | 162 | void OpenGLState::ApplySRgb() { |
| 280 | if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled) | 163 | if (cur_state.framebuffer_srgb.enabled == framebuffer_srgb.enabled) |
| 281 | return; | 164 | return; |
| 282 | cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; | 165 | cur_state.framebuffer_srgb.enabled = framebuffer_srgb.enabled; |
| @@ -287,7 +170,7 @@ void OpenGLState::ApplySRgb() const { | |||
| 287 | } | 170 | } |
| 288 | } | 171 | } |
| 289 | 172 | ||
| 290 | void OpenGLState::ApplyCulling() const { | 173 | void OpenGLState::ApplyCulling() { |
| 291 | Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled); | 174 | Enable(GL_CULL_FACE, cur_state.cull.enabled, cull.enabled); |
| 292 | 175 | ||
| 293 | if (UpdateValue(cur_state.cull.mode, cull.mode)) { | 176 | if (UpdateValue(cur_state.cull.mode, cull.mode)) { |
| @@ -299,7 +182,12 @@ void OpenGLState::ApplyCulling() const { | |||
| 299 | } | 182 | } |
| 300 | } | 183 | } |
| 301 | 184 | ||
| 302 | void OpenGLState::ApplyColorMask() const { | 185 | void OpenGLState::ApplyColorMask() { |
| 186 | if (!dirty.color_mask) { | ||
| 187 | return; | ||
| 188 | } | ||
| 189 | dirty.color_mask = false; | ||
| 190 | |||
| 303 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { | 191 | for (std::size_t i = 0; i < Maxwell::NumRenderTargets; ++i) { |
| 304 | const auto& updated = color_mask[i]; | 192 | const auto& updated = color_mask[i]; |
| 305 | auto& current = cur_state.color_mask[i]; | 193 | auto& current = cur_state.color_mask[i]; |
| @@ -314,7 +202,7 @@ void OpenGLState::ApplyColorMask() const { | |||
| 314 | } | 202 | } |
| 315 | } | 203 | } |
| 316 | 204 | ||
| 317 | void OpenGLState::ApplyDepth() const { | 205 | void OpenGLState::ApplyDepth() { |
| 318 | Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled); | 206 | Enable(GL_DEPTH_TEST, cur_state.depth.test_enabled, depth.test_enabled); |
| 319 | 207 | ||
| 320 | if (cur_state.depth.test_func != depth.test_func) { | 208 | if (cur_state.depth.test_func != depth.test_func) { |
| @@ -328,7 +216,7 @@ void OpenGLState::ApplyDepth() const { | |||
| 328 | } | 216 | } |
| 329 | } | 217 | } |
| 330 | 218 | ||
| 331 | void OpenGLState::ApplyPrimitiveRestart() const { | 219 | void OpenGLState::ApplyPrimitiveRestart() { |
| 332 | Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled); | 220 | Enable(GL_PRIMITIVE_RESTART, cur_state.primitive_restart.enabled, primitive_restart.enabled); |
| 333 | 221 | ||
| 334 | if (cur_state.primitive_restart.index != primitive_restart.index) { | 222 | if (cur_state.primitive_restart.index != primitive_restart.index) { |
| @@ -337,7 +225,12 @@ void OpenGLState::ApplyPrimitiveRestart() const { | |||
| 337 | } | 225 | } |
| 338 | } | 226 | } |
| 339 | 227 | ||
| 340 | void OpenGLState::ApplyStencilTest() const { | 228 | void OpenGLState::ApplyStencilTest() { |
| 229 | if (!dirty.stencil_state) { | ||
| 230 | return; | ||
| 231 | } | ||
| 232 | dirty.stencil_state = false; | ||
| 233 | |||
| 341 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); | 234 | Enable(GL_STENCIL_TEST, cur_state.stencil.test_enabled, stencil.test_enabled); |
| 342 | 235 | ||
| 343 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { | 236 | const auto ConfigStencil = [](GLenum face, const auto& config, auto& current) { |
| @@ -366,7 +259,7 @@ void OpenGLState::ApplyStencilTest() const { | |||
| 366 | ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); | 259 | ConfigStencil(GL_BACK, stencil.back, cur_state.stencil.back); |
| 367 | } | 260 | } |
| 368 | 261 | ||
| 369 | void OpenGLState::ApplyViewport() const { | 262 | void OpenGLState::ApplyViewport() { |
| 370 | for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { | 263 | for (GLuint i = 0; i < static_cast<GLuint>(Maxwell::NumViewports); ++i) { |
| 371 | const auto& updated = viewports[i]; | 264 | const auto& updated = viewports[i]; |
| 372 | auto& current = cur_state.viewports[i]; | 265 | auto& current = cur_state.viewports[i]; |
| @@ -403,7 +296,7 @@ void OpenGLState::ApplyViewport() const { | |||
| 403 | } | 296 | } |
| 404 | } | 297 | } |
| 405 | 298 | ||
| 406 | void OpenGLState::ApplyGlobalBlending() const { | 299 | void OpenGLState::ApplyGlobalBlending() { |
| 407 | const Blend& updated = blend[0]; | 300 | const Blend& updated = blend[0]; |
| 408 | Blend& current = cur_state.blend[0]; | 301 | Blend& current = cur_state.blend[0]; |
| 409 | 302 | ||
| @@ -427,7 +320,7 @@ void OpenGLState::ApplyGlobalBlending() const { | |||
| 427 | } | 320 | } |
| 428 | } | 321 | } |
| 429 | 322 | ||
| 430 | void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { | 323 | void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) { |
| 431 | const Blend& updated = blend[target]; | 324 | const Blend& updated = blend[target]; |
| 432 | Blend& current = cur_state.blend[target]; | 325 | Blend& current = cur_state.blend[target]; |
| 433 | 326 | ||
| @@ -451,7 +344,12 @@ void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { | |||
| 451 | } | 344 | } |
| 452 | } | 345 | } |
| 453 | 346 | ||
| 454 | void OpenGLState::ApplyBlending() const { | 347 | void OpenGLState::ApplyBlending() { |
| 348 | if (!dirty.blend_state) { | ||
| 349 | return; | ||
| 350 | } | ||
| 351 | dirty.blend_state = false; | ||
| 352 | |||
| 455 | if (independant_blend.enabled) { | 353 | if (independant_blend.enabled) { |
| 456 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; | 354 | const bool force = independant_blend.enabled != cur_state.independant_blend.enabled; |
| 457 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { | 355 | for (std::size_t target = 0; target < Maxwell::NumRenderTargets; ++target) { |
| @@ -470,7 +368,7 @@ void OpenGLState::ApplyBlending() const { | |||
| 470 | } | 368 | } |
| 471 | } | 369 | } |
| 472 | 370 | ||
| 473 | void OpenGLState::ApplyLogicOp() const { | 371 | void OpenGLState::ApplyLogicOp() { |
| 474 | Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled); | 372 | Enable(GL_COLOR_LOGIC_OP, cur_state.logic_op.enabled, logic_op.enabled); |
| 475 | 373 | ||
| 476 | if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) { | 374 | if (UpdateValue(cur_state.logic_op.operation, logic_op.operation)) { |
| @@ -478,7 +376,12 @@ void OpenGLState::ApplyLogicOp() const { | |||
| 478 | } | 376 | } |
| 479 | } | 377 | } |
| 480 | 378 | ||
| 481 | void OpenGLState::ApplyPolygonOffset() const { | 379 | void OpenGLState::ApplyPolygonOffset() { |
| 380 | if (!dirty.polygon_offset) { | ||
| 381 | return; | ||
| 382 | } | ||
| 383 | dirty.polygon_offset = false; | ||
| 384 | |||
| 482 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, | 385 | Enable(GL_POLYGON_OFFSET_FILL, cur_state.polygon_offset.fill_enable, |
| 483 | polygon_offset.fill_enable); | 386 | polygon_offset.fill_enable); |
| 484 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, | 387 | Enable(GL_POLYGON_OFFSET_LINE, cur_state.polygon_offset.line_enable, |
| @@ -499,7 +402,7 @@ void OpenGLState::ApplyPolygonOffset() const { | |||
| 499 | } | 402 | } |
| 500 | } | 403 | } |
| 501 | 404 | ||
| 502 | void OpenGLState::ApplyAlphaTest() const { | 405 | void OpenGLState::ApplyAlphaTest() { |
| 503 | Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); | 406 | Enable(GL_ALPHA_TEST, cur_state.alpha_test.enabled, alpha_test.enabled); |
| 504 | if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), | 407 | if (UpdateTie(std::tie(cur_state.alpha_test.func, cur_state.alpha_test.ref), |
| 505 | std::tie(alpha_test.func, alpha_test.ref))) { | 408 | std::tie(alpha_test.func, alpha_test.ref))) { |
| @@ -507,19 +410,19 @@ void OpenGLState::ApplyAlphaTest() const { | |||
| 507 | } | 410 | } |
| 508 | } | 411 | } |
| 509 | 412 | ||
| 510 | void OpenGLState::ApplyTextures() const { | 413 | void OpenGLState::ApplyTextures() { |
| 511 | if (const auto update = UpdateArray(cur_state.textures, textures)) { | 414 | if (const auto update = UpdateArray(cur_state.textures, textures)) { |
| 512 | glBindTextures(update->first, update->second, textures.data() + update->first); | 415 | glBindTextures(update->first, update->second, textures.data() + update->first); |
| 513 | } | 416 | } |
| 514 | } | 417 | } |
| 515 | 418 | ||
| 516 | void OpenGLState::ApplySamplers() const { | 419 | void OpenGLState::ApplySamplers() { |
| 517 | if (const auto update = UpdateArray(cur_state.samplers, samplers)) { | 420 | if (const auto update = UpdateArray(cur_state.samplers, samplers)) { |
| 518 | glBindSamplers(update->first, update->second, samplers.data() + update->first); | 421 | glBindSamplers(update->first, update->second, samplers.data() + update->first); |
| 519 | } | 422 | } |
| 520 | } | 423 | } |
| 521 | 424 | ||
| 522 | void OpenGLState::ApplyImages() const { | 425 | void OpenGLState::ApplyImages() { |
| 523 | if (const auto update = UpdateArray(cur_state.images, images)) { | 426 | if (const auto update = UpdateArray(cur_state.images, images)) { |
| 524 | glBindImageTextures(update->first, update->second, images.data() + update->first); | 427 | glBindImageTextures(update->first, update->second, images.data() + update->first); |
| 525 | } | 428 | } |
| @@ -535,32 +438,20 @@ void OpenGLState::Apply() { | |||
| 535 | ApplyPointSize(); | 438 | ApplyPointSize(); |
| 536 | ApplyFragmentColorClamp(); | 439 | ApplyFragmentColorClamp(); |
| 537 | ApplyMultisample(); | 440 | ApplyMultisample(); |
| 538 | if (dirty.color_mask) { | 441 | ApplyColorMask(); |
| 539 | ApplyColorMask(); | ||
| 540 | dirty.color_mask = false; | ||
| 541 | } | ||
| 542 | ApplyDepthClamp(); | 442 | ApplyDepthClamp(); |
| 543 | ApplyViewport(); | 443 | ApplyViewport(); |
| 544 | if (dirty.stencil_state) { | 444 | ApplyStencilTest(); |
| 545 | ApplyStencilTest(); | ||
| 546 | dirty.stencil_state = false; | ||
| 547 | } | ||
| 548 | ApplySRgb(); | 445 | ApplySRgb(); |
| 549 | ApplyCulling(); | 446 | ApplyCulling(); |
| 550 | ApplyDepth(); | 447 | ApplyDepth(); |
| 551 | ApplyPrimitiveRestart(); | 448 | ApplyPrimitiveRestart(); |
| 552 | if (dirty.blend_state) { | 449 | ApplyBlending(); |
| 553 | ApplyBlending(); | ||
| 554 | dirty.blend_state = false; | ||
| 555 | } | ||
| 556 | ApplyLogicOp(); | 450 | ApplyLogicOp(); |
| 557 | ApplyTextures(); | 451 | ApplyTextures(); |
| 558 | ApplySamplers(); | 452 | ApplySamplers(); |
| 559 | ApplyImages(); | 453 | ApplyImages(); |
| 560 | if (dirty.polygon_offset) { | 454 | ApplyPolygonOffset(); |
| 561 | ApplyPolygonOffset(); | ||
| 562 | dirty.polygon_offset = false; | ||
| 563 | } | ||
| 564 | ApplyAlphaTest(); | 455 | ApplyAlphaTest(); |
| 565 | } | 456 | } |
| 566 | 457 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h index c358d3b38..cca25206b 100644 --- a/src/video_core/renderer_opengl/gl_state.h +++ b/src/video_core/renderer_opengl/gl_state.h | |||
| @@ -5,168 +5,146 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <type_traits> | ||
| 8 | #include <glad/glad.h> | 9 | #include <glad/glad.h> |
| 9 | #include "video_core/engines/maxwell_3d.h" | 10 | #include "video_core/engines/maxwell_3d.h" |
| 10 | 11 | ||
| 11 | namespace OpenGL { | 12 | namespace OpenGL { |
| 12 | 13 | ||
| 13 | namespace TextureUnits { | ||
| 14 | |||
| 15 | struct TextureUnit { | ||
| 16 | GLint id; | ||
| 17 | constexpr GLenum Enum() const { | ||
| 18 | return static_cast<GLenum>(GL_TEXTURE0 + id); | ||
| 19 | } | ||
| 20 | }; | ||
| 21 | |||
| 22 | constexpr TextureUnit MaxwellTexture(int unit) { | ||
| 23 | return TextureUnit{unit}; | ||
| 24 | } | ||
| 25 | |||
| 26 | constexpr TextureUnit LightingLUT{3}; | ||
| 27 | constexpr TextureUnit FogLUT{4}; | ||
| 28 | constexpr TextureUnit ProcTexNoiseLUT{5}; | ||
| 29 | constexpr TextureUnit ProcTexColorMap{6}; | ||
| 30 | constexpr TextureUnit ProcTexAlphaMap{7}; | ||
| 31 | constexpr TextureUnit ProcTexLUT{8}; | ||
| 32 | constexpr TextureUnit ProcTexDiffLUT{9}; | ||
| 33 | |||
| 34 | } // namespace TextureUnits | ||
| 35 | |||
| 36 | class OpenGLState { | 14 | class OpenGLState { |
| 37 | public: | 15 | public: |
| 38 | struct { | 16 | struct { |
| 39 | bool enabled; // GL_FRAMEBUFFER_SRGB | 17 | bool enabled = false; // GL_FRAMEBUFFER_SRGB |
| 40 | } framebuffer_srgb; | 18 | } framebuffer_srgb; |
| 41 | 19 | ||
| 42 | struct { | 20 | struct { |
| 43 | bool alpha_to_coverage; // GL_ALPHA_TO_COVERAGE | 21 | bool alpha_to_coverage = false; // GL_ALPHA_TO_COVERAGE |
| 44 | bool alpha_to_one; // GL_ALPHA_TO_ONE | 22 | bool alpha_to_one = false; // GL_ALPHA_TO_ONE |
| 45 | } multisample_control; | 23 | } multisample_control; |
| 46 | 24 | ||
| 47 | struct { | 25 | struct { |
| 48 | bool enabled; // GL_CLAMP_FRAGMENT_COLOR_ARB | 26 | bool enabled = false; // GL_CLAMP_FRAGMENT_COLOR_ARB |
| 49 | } fragment_color_clamp; | 27 | } fragment_color_clamp; |
| 50 | 28 | ||
| 51 | struct { | 29 | struct { |
| 52 | bool far_plane; | 30 | bool far_plane = false; |
| 53 | bool near_plane; | 31 | bool near_plane = false; |
| 54 | } depth_clamp; // GL_DEPTH_CLAMP | 32 | } depth_clamp; // GL_DEPTH_CLAMP |
| 55 | 33 | ||
| 56 | struct { | 34 | struct { |
| 57 | bool enabled; // GL_CULL_FACE | 35 | bool enabled = false; // GL_CULL_FACE |
| 58 | GLenum mode; // GL_CULL_FACE_MODE | 36 | GLenum mode = GL_BACK; // GL_CULL_FACE_MODE |
| 59 | GLenum front_face; // GL_FRONT_FACE | 37 | GLenum front_face = GL_CCW; // GL_FRONT_FACE |
| 60 | } cull; | 38 | } cull; |
| 61 | 39 | ||
| 62 | struct { | 40 | struct { |
| 63 | bool test_enabled; // GL_DEPTH_TEST | 41 | bool test_enabled = false; // GL_DEPTH_TEST |
| 64 | GLenum test_func; // GL_DEPTH_FUNC | 42 | GLboolean write_mask = GL_TRUE; // GL_DEPTH_WRITEMASK |
| 65 | GLboolean write_mask; // GL_DEPTH_WRITEMASK | 43 | GLenum test_func = GL_LESS; // GL_DEPTH_FUNC |
| 66 | } depth; | 44 | } depth; |
| 67 | 45 | ||
| 68 | struct { | 46 | struct { |
| 69 | bool enabled; | 47 | bool enabled = false; |
| 70 | GLuint index; | 48 | GLuint index = 0; |
| 71 | } primitive_restart; // GL_PRIMITIVE_RESTART | 49 | } primitive_restart; // GL_PRIMITIVE_RESTART |
| 72 | 50 | ||
| 73 | struct ColorMask { | 51 | struct ColorMask { |
| 74 | GLboolean red_enabled; | 52 | GLboolean red_enabled = GL_TRUE; |
| 75 | GLboolean green_enabled; | 53 | GLboolean green_enabled = GL_TRUE; |
| 76 | GLboolean blue_enabled; | 54 | GLboolean blue_enabled = GL_TRUE; |
| 77 | GLboolean alpha_enabled; | 55 | GLboolean alpha_enabled = GL_TRUE; |
| 78 | }; | 56 | }; |
| 79 | std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> | 57 | std::array<ColorMask, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> |
| 80 | color_mask; // GL_COLOR_WRITEMASK | 58 | color_mask; // GL_COLOR_WRITEMASK |
| 81 | struct { | 59 | struct { |
| 82 | bool test_enabled; // GL_STENCIL_TEST | 60 | bool test_enabled = false; // GL_STENCIL_TEST |
| 83 | struct { | 61 | struct { |
| 84 | GLenum test_func; // GL_STENCIL_FUNC | 62 | GLenum test_func = GL_ALWAYS; // GL_STENCIL_FUNC |
| 85 | GLint test_ref; // GL_STENCIL_REF | 63 | GLint test_ref = 0; // GL_STENCIL_REF |
| 86 | GLuint test_mask; // GL_STENCIL_VALUE_MASK | 64 | GLuint test_mask = 0xFFFFFFFF; // GL_STENCIL_VALUE_MASK |
| 87 | GLuint write_mask; // GL_STENCIL_WRITEMASK | 65 | GLuint write_mask = 0xFFFFFFFF; // GL_STENCIL_WRITEMASK |
| 88 | GLenum action_stencil_fail; // GL_STENCIL_FAIL | 66 | GLenum action_stencil_fail = GL_KEEP; // GL_STENCIL_FAIL |
| 89 | GLenum action_depth_fail; // GL_STENCIL_PASS_DEPTH_FAIL | 67 | GLenum action_depth_fail = GL_KEEP; // GL_STENCIL_PASS_DEPTH_FAIL |
| 90 | GLenum action_depth_pass; // GL_STENCIL_PASS_DEPTH_PASS | 68 | GLenum action_depth_pass = GL_KEEP; // GL_STENCIL_PASS_DEPTH_PASS |
| 91 | } front, back; | 69 | } front, back; |
| 92 | } stencil; | 70 | } stencil; |
| 93 | 71 | ||
| 94 | struct Blend { | 72 | struct Blend { |
| 95 | bool enabled; // GL_BLEND | 73 | bool enabled = false; // GL_BLEND |
| 96 | GLenum rgb_equation; // GL_BLEND_EQUATION_RGB | 74 | GLenum rgb_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_RGB |
| 97 | GLenum a_equation; // GL_BLEND_EQUATION_ALPHA | 75 | GLenum a_equation = GL_FUNC_ADD; // GL_BLEND_EQUATION_ALPHA |
| 98 | GLenum src_rgb_func; // GL_BLEND_SRC_RGB | 76 | GLenum src_rgb_func = GL_ONE; // GL_BLEND_SRC_RGB |
| 99 | GLenum dst_rgb_func; // GL_BLEND_DST_RGB | 77 | GLenum dst_rgb_func = GL_ZERO; // GL_BLEND_DST_RGB |
| 100 | GLenum src_a_func; // GL_BLEND_SRC_ALPHA | 78 | GLenum src_a_func = GL_ONE; // GL_BLEND_SRC_ALPHA |
| 101 | GLenum dst_a_func; // GL_BLEND_DST_ALPHA | 79 | GLenum dst_a_func = GL_ZERO; // GL_BLEND_DST_ALPHA |
| 102 | }; | 80 | }; |
| 103 | std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend; | 81 | std::array<Blend, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> blend; |
| 104 | 82 | ||
| 105 | struct { | 83 | struct { |
| 106 | bool enabled; | 84 | bool enabled = false; |
| 107 | } independant_blend; | 85 | } independant_blend; |
| 108 | 86 | ||
| 109 | struct { | 87 | struct { |
| 110 | GLclampf red; | 88 | GLclampf red = 0.0f; |
| 111 | GLclampf green; | 89 | GLclampf green = 0.0f; |
| 112 | GLclampf blue; | 90 | GLclampf blue = 0.0f; |
| 113 | GLclampf alpha; | 91 | GLclampf alpha = 0.0f; |
| 114 | } blend_color; // GL_BLEND_COLOR | 92 | } blend_color; // GL_BLEND_COLOR |
| 115 | 93 | ||
| 116 | struct { | 94 | struct { |
| 117 | bool enabled; // GL_LOGIC_OP_MODE | 95 | bool enabled = false; // GL_LOGIC_OP_MODE |
| 118 | GLenum operation; | 96 | GLenum operation = GL_COPY; |
| 119 | } logic_op; | 97 | } logic_op; |
| 120 | 98 | ||
| 121 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures{}; | 99 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> textures = {}; |
| 122 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers{}; | 100 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> samplers = {}; |
| 123 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images{}; | 101 | std::array<GLuint, Tegra::Engines::Maxwell3D::Regs::NumImages> images = {}; |
| 124 | 102 | ||
| 125 | struct { | 103 | struct { |
| 126 | GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING | 104 | GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING |
| 127 | GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING | 105 | GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING |
| 128 | GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING | 106 | GLuint vertex_array = 0; // GL_VERTEX_ARRAY_BINDING |
| 129 | GLuint shader_program; // GL_CURRENT_PROGRAM | 107 | GLuint shader_program = 0; // GL_CURRENT_PROGRAM |
| 130 | GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING | 108 | GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING |
| 131 | } draw; | 109 | } draw; |
| 132 | 110 | ||
| 133 | struct viewport { | 111 | struct Viewport { |
| 134 | GLint x; | 112 | GLint x = 0; |
| 135 | GLint y; | 113 | GLint y = 0; |
| 136 | GLint width; | 114 | GLint width = 0; |
| 137 | GLint height; | 115 | GLint height = 0; |
| 138 | GLfloat depth_range_near; // GL_DEPTH_RANGE | 116 | GLfloat depth_range_near = 0.0f; // GL_DEPTH_RANGE |
| 139 | GLfloat depth_range_far; // GL_DEPTH_RANGE | 117 | GLfloat depth_range_far = 1.0f; // GL_DEPTH_RANGE |
| 140 | struct { | 118 | struct { |
| 141 | bool enabled; // GL_SCISSOR_TEST | 119 | bool enabled = false; // GL_SCISSOR_TEST |
| 142 | GLint x; | 120 | GLint x = 0; |
| 143 | GLint y; | 121 | GLint y = 0; |
| 144 | GLsizei width; | 122 | GLsizei width = 0; |
| 145 | GLsizei height; | 123 | GLsizei height = 0; |
| 146 | } scissor; | 124 | } scissor; |
| 147 | }; | 125 | }; |
| 148 | std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; | 126 | std::array<Viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports; |
| 149 | 127 | ||
| 150 | struct { | 128 | struct { |
| 151 | float size; // GL_POINT_SIZE | 129 | float size = 1.0f; // GL_POINT_SIZE |
| 152 | } point; | 130 | } point; |
| 153 | 131 | ||
| 154 | struct { | 132 | struct { |
| 155 | bool point_enable; | 133 | bool point_enable = false; |
| 156 | bool line_enable; | 134 | bool line_enable = false; |
| 157 | bool fill_enable; | 135 | bool fill_enable = false; |
| 158 | GLfloat units; | 136 | GLfloat units = 0.0f; |
| 159 | GLfloat factor; | 137 | GLfloat factor = 0.0f; |
| 160 | GLfloat clamp; | 138 | GLfloat clamp = 0.0f; |
| 161 | } polygon_offset; | 139 | } polygon_offset; |
| 162 | 140 | ||
| 163 | struct { | 141 | struct { |
| 164 | bool enabled; // GL_ALPHA_TEST | 142 | bool enabled = false; // GL_ALPHA_TEST |
| 165 | GLenum func; // GL_ALPHA_TEST_FUNC | 143 | GLenum func = GL_ALWAYS; // GL_ALPHA_TEST_FUNC |
| 166 | GLfloat ref; // GL_ALPHA_TEST_REF | 144 | GLfloat ref = 0.0f; // GL_ALPHA_TEST_REF |
| 167 | } alpha_test; | 145 | } alpha_test; |
| 168 | 146 | ||
| 169 | std::array<bool, 8> clip_distance; // GL_CLIP_DISTANCE | 147 | std::array<bool, 8> clip_distance = {}; // GL_CLIP_DISTANCE |
| 170 | 148 | ||
| 171 | OpenGLState(); | 149 | OpenGLState(); |
| 172 | 150 | ||
| @@ -179,34 +157,31 @@ public: | |||
| 179 | /// Apply this state as the current OpenGL state | 157 | /// Apply this state as the current OpenGL state |
| 180 | void Apply(); | 158 | void Apply(); |
| 181 | 159 | ||
| 182 | void ApplyFramebufferState() const; | 160 | void ApplyFramebufferState(); |
| 183 | void ApplyVertexArrayState() const; | 161 | void ApplyVertexArrayState(); |
| 184 | void ApplyShaderProgram() const; | 162 | void ApplyShaderProgram(); |
| 185 | void ApplyProgramPipeline() const; | 163 | void ApplyProgramPipeline(); |
| 186 | void ApplyClipDistances() const; | 164 | void ApplyClipDistances(); |
| 187 | void ApplyPointSize() const; | 165 | void ApplyPointSize(); |
| 188 | void ApplyFragmentColorClamp() const; | 166 | void ApplyFragmentColorClamp(); |
| 189 | void ApplyMultisample() const; | 167 | void ApplyMultisample(); |
| 190 | void ApplySRgb() const; | 168 | void ApplySRgb(); |
| 191 | void ApplyCulling() const; | 169 | void ApplyCulling(); |
| 192 | void ApplyColorMask() const; | 170 | void ApplyColorMask(); |
| 193 | void ApplyDepth() const; | 171 | void ApplyDepth(); |
| 194 | void ApplyPrimitiveRestart() const; | 172 | void ApplyPrimitiveRestart(); |
| 195 | void ApplyStencilTest() const; | 173 | void ApplyStencilTest(); |
| 196 | void ApplyViewport() const; | 174 | void ApplyViewport(); |
| 197 | void ApplyTargetBlending(std::size_t target, bool force) const; | 175 | void ApplyTargetBlending(std::size_t target, bool force); |
| 198 | void ApplyGlobalBlending() const; | 176 | void ApplyGlobalBlending(); |
| 199 | void ApplyBlending() const; | 177 | void ApplyBlending(); |
| 200 | void ApplyLogicOp() const; | 178 | void ApplyLogicOp(); |
| 201 | void ApplyTextures() const; | 179 | void ApplyTextures(); |
| 202 | void ApplySamplers() const; | 180 | void ApplySamplers(); |
| 203 | void ApplyImages() const; | 181 | void ApplyImages(); |
| 204 | void ApplyDepthClamp() const; | 182 | void ApplyDepthClamp(); |
| 205 | void ApplyPolygonOffset() const; | 183 | void ApplyPolygonOffset(); |
| 206 | void ApplyAlphaTest() const; | 184 | void ApplyAlphaTest(); |
| 207 | |||
| 208 | /// Set the initial OpenGL state | ||
| 209 | static void ApplyDefaultState(); | ||
| 210 | 185 | ||
| 211 | /// Resets any references to the given resource | 186 | /// Resets any references to the given resource |
| 212 | OpenGLState& UnbindTexture(GLuint handle); | 187 | OpenGLState& UnbindTexture(GLuint handle); |
| @@ -253,5 +228,6 @@ private: | |||
| 253 | bool color_mask; | 228 | bool color_mask; |
| 254 | } dirty{}; | 229 | } dirty{}; |
| 255 | }; | 230 | }; |
| 231 | static_assert(std::is_trivially_copyable_v<OpenGLState>); | ||
| 256 | 232 | ||
| 257 | } // namespace OpenGL | 233 | } // namespace OpenGL |