summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp223
-rw-r--r--src/video_core/renderer_opengl/gl_state.h222
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
71void Enable(GLenum cap, bool& current_value, bool new_value) { 72void 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
76void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) { 78void 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
83OpenGLState::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; 86OpenGLState::OpenGLState() = default;
178 alpha_test.func = GL_ALWAYS;
179 alpha_test.ref = 0.0f;
180}
181 87
182void OpenGLState::SetDefaultViewports() { 88void 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
201void OpenGLState::ApplyDefaultState() { 95void 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
212void 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
221void OpenGLState::ApplyVertexArrayState() const { 104void 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
227void OpenGLState::ApplyShaderProgram() const { 110void 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
233void OpenGLState::ApplyProgramPipeline() const { 116void 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
239void OpenGLState::ApplyClipDistances() const { 122void 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
246void OpenGLState::ApplyPointSize() const { 129void 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
252void OpenGLState::ApplyFragmentColorClamp() const { 135void 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
259void OpenGLState::ApplyMultisample() const { 142void 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
266void OpenGLState::ApplyDepthClamp() const { 149void 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
279void OpenGLState::ApplySRgb() const { 162void 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
290void OpenGLState::ApplyCulling() const { 173void 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
302void OpenGLState::ApplyColorMask() const { 185void 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
317void OpenGLState::ApplyDepth() const { 205void 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
331void OpenGLState::ApplyPrimitiveRestart() const { 219void 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
340void OpenGLState::ApplyStencilTest() const { 228void 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
369void OpenGLState::ApplyViewport() const { 262void 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
406void OpenGLState::ApplyGlobalBlending() const { 299void 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
430void OpenGLState::ApplyTargetBlending(std::size_t target, bool force) const { 323void 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
454void OpenGLState::ApplyBlending() const { 347void 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
473void OpenGLState::ApplyLogicOp() const { 371void 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
481void OpenGLState::ApplyPolygonOffset() const { 379void 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
502void OpenGLState::ApplyAlphaTest() const { 405void 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
510void OpenGLState::ApplyTextures() const { 413void 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
516void OpenGLState::ApplySamplers() const { 419void 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
522void OpenGLState::ApplyImages() const { 425void 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
11namespace OpenGL { 12namespace OpenGL {
12 13
13namespace TextureUnits {
14
15struct TextureUnit {
16 GLint id;
17 constexpr GLenum Enum() const {
18 return static_cast<GLenum>(GL_TEXTURE0 + id);
19 }
20};
21
22constexpr TextureUnit MaxwellTexture(int unit) {
23 return TextureUnit{unit};
24}
25
26constexpr TextureUnit LightingLUT{3};
27constexpr TextureUnit FogLUT{4};
28constexpr TextureUnit ProcTexNoiseLUT{5};
29constexpr TextureUnit ProcTexColorMap{6};
30constexpr TextureUnit ProcTexAlphaMap{7};
31constexpr TextureUnit ProcTexLUT{8};
32constexpr TextureUnit ProcTexDiffLUT{9};
33
34} // namespace TextureUnits
35
36class OpenGLState { 14class OpenGLState {
37public: 15public:
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};
231static_assert(std::is_trivially_copyable_v<OpenGLState>);
256 232
257} // namespace OpenGL 233} // namespace OpenGL