summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp4
-rw-r--r--src/video_core/engines/maxwell_3d.h26
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp33
-rw-r--r--src/video_core/renderer_opengl/gl_shader_manager.h1
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp67
-rw-r--r--src/video_core/renderer_opengl/gl_state.h22
6 files changed, 89 insertions, 64 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 6de07ea56..58b598c7f 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -34,8 +34,8 @@ void Maxwell3D::InitializeRegisterDefaults() {
34 // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is 34 // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is
35 // needed for ARMS. 35 // needed for ARMS.
36 for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) { 36 for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) {
37 regs.viewport[viewport].depth_range_near = 0.0f; 37 regs.viewports[viewport].depth_range_near = 0.0f;
38 regs.viewport[viewport].depth_range_far = 1.0f; 38 regs.viewports[viewport].depth_range_far = 1.0f;
39 } 39 }
40 // Doom and Bomberman seems to use the uninitialized registers and just enable blend 40 // Doom and Bomberman seems to use the uninitialized registers and just enable blend
41 // so initialize blend registers with sane values 41 // so initialize blend registers with sane values
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 91ca57883..32780fa9a 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -505,9 +505,9 @@ public:
505 505
506 INSERT_PADDING_WORDS(0x2E); 506 INSERT_PADDING_WORDS(0x2E);
507 507
508 RenderTargetConfig rt[NumRenderTargets]; 508 std::array<RenderTargetConfig, NumRenderTargets> rt;
509 509
510 struct { 510 struct ViewportTransform {
511 f32 scale_x; 511 f32 scale_x;
512 f32 scale_y; 512 f32 scale_y;
513 f32 scale_z; 513 f32 scale_z;
@@ -540,9 +540,11 @@ public:
540 s32 GetHeight() const { 540 s32 GetHeight() const {
541 return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY(); 541 return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY();
542 } 542 }
543 } viewport_transform[NumViewports]; 543 };
544 544
545 struct { 545 std::array<ViewportTransform, NumViewports> viewport_transform;
546
547 struct ViewPort {
546 union { 548 union {
547 BitField<0, 16, u32> x; 549 BitField<0, 16, u32> x;
548 BitField<16, 16, u32> width; 550 BitField<16, 16, u32> width;
@@ -553,7 +555,9 @@ public:
553 }; 555 };
554 float depth_range_near; 556 float depth_range_near;
555 float depth_range_far; 557 float depth_range_far;
556 } viewport[NumViewports]; 558 };
559
560 std::array<ViewPort, NumViewports> viewports;
557 561
558 INSERT_PADDING_WORDS(0x1D); 562 INSERT_PADDING_WORDS(0x1D);
559 563
@@ -571,7 +575,7 @@ public:
571 575
572 INSERT_PADDING_WORDS(0x17); 576 INSERT_PADDING_WORDS(0x17);
573 577
574 struct { 578 struct ScissorTest {
575 u32 enable; 579 u32 enable;
576 union { 580 union {
577 BitField<0, 16, u32> min_x; 581 BitField<0, 16, u32> min_x;
@@ -581,9 +585,11 @@ public:
581 BitField<0, 16, u32> min_y; 585 BitField<0, 16, u32> min_y;
582 BitField<16, 16, u32> max_y; 586 BitField<16, 16, u32> max_y;
583 }; 587 };
584 } scissor_test; 588 u32 fill;
589 };
590 std::array<ScissorTest, NumViewports> scissor_test;
585 591
586 INSERT_PADDING_WORDS(0x52); 592 INSERT_PADDING_WORDS(0x15);
587 593
588 s32 stencil_back_func_ref; 594 s32 stencil_back_func_ref;
589 u32 stencil_back_mask; 595 u32 stencil_back_mask;
@@ -1100,8 +1106,8 @@ private:
1100ASSERT_REG_POSITION(macros, 0x45); 1106ASSERT_REG_POSITION(macros, 0x45);
1101ASSERT_REG_POSITION(tfb_enabled, 0x1D1); 1107ASSERT_REG_POSITION(tfb_enabled, 0x1D1);
1102ASSERT_REG_POSITION(rt, 0x200); 1108ASSERT_REG_POSITION(rt, 0x200);
1103ASSERT_REG_POSITION(viewport_transform[0], 0x280); 1109ASSERT_REG_POSITION(viewport_transform, 0x280);
1104ASSERT_REG_POSITION(viewport, 0x300); 1110ASSERT_REG_POSITION(viewports, 0x300);
1105ASSERT_REG_POSITION(vertex_buffer, 0x35D); 1111ASSERT_REG_POSITION(vertex_buffer, 0x35D);
1106ASSERT_REG_POSITION(clear_color[0], 0x360); 1112ASSERT_REG_POSITION(clear_color[0], 0x360);
1107ASSERT_REG_POSITION(clear_depth, 0x364); 1113ASSERT_REG_POSITION(clear_depth, 0x364);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 54cc47a9b..0bf434b45 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -642,7 +642,7 @@ void RasterizerOpenGL::DrawArrays() {
642 params.DispatchDraw(); 642 params.DispatchDraw();
643 643
644 // Disable scissor test 644 // Disable scissor test
645 state.scissor.enabled = false; 645 state.viewports[0].scissor.enabled = false;
646 646
647 accelerate_draw = AccelDraw::Disabled; 647 accelerate_draw = AccelDraw::Disabled;
648 648
@@ -923,15 +923,15 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
923 923
924void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) { 924void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
925 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 925 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
926 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { 926 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
927 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()}; 927 const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
928 auto& viewport = current_state.viewports[i]; 928 auto& viewport = current_state.viewports[i];
929 viewport.x = viewport_rect.left; 929 viewport.x = viewport_rect.left;
930 viewport.y = viewport_rect.bottom; 930 viewport.y = viewport_rect.bottom;
931 viewport.width = static_cast<GLfloat>(viewport_rect.GetWidth()); 931 viewport.width = static_cast<GLfloat>(viewport_rect.GetWidth());
932 viewport.height = static_cast<GLfloat>(viewport_rect.GetHeight()); 932 viewport.height = static_cast<GLfloat>(viewport_rect.GetHeight());
933 viewport.depth_range_far = regs.viewport[i].depth_range_far; 933 viewport.depth_range_far = regs.viewports[i].depth_range_far;
934 viewport.depth_range_near = regs.viewport[i].depth_range_near; 934 viewport.depth_range_near = regs.viewports[i].depth_range_near;
935 } 935 }
936} 936}
937 937
@@ -1079,7 +1079,6 @@ void RasterizerOpenGL::SyncBlendState() {
1079void RasterizerOpenGL::SyncLogicOpState() { 1079void RasterizerOpenGL::SyncLogicOpState() {
1080 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1080 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
1081 1081
1082 // TODO(Subv): Support more than just render target 0.
1083 state.logic_op.enabled = regs.logic_op.enable != 0; 1082 state.logic_op.enabled = regs.logic_op.enable != 0;
1084 1083
1085 if (!state.logic_op.enabled) 1084 if (!state.logic_op.enabled)
@@ -1092,19 +1091,21 @@ void RasterizerOpenGL::SyncLogicOpState() {
1092} 1091}
1093 1092
1094void RasterizerOpenGL::SyncScissorTest() { 1093void RasterizerOpenGL::SyncScissorTest() {
1095 // TODO: what is the correct behavior here, a single scissor for all targets
1096 // or scissor disabled for the rest of the targets?
1097 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs; 1094 const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
1098 state.scissor.enabled = (regs.scissor_test.enable != 0); 1095 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
1099 if (regs.scissor_test.enable == 0) { 1096 const auto& src = regs.scissor_test[i];
1100 return; 1097 auto& dst = state.viewports[i].scissor;
1098 dst.enabled = (src.enable != 0);
1099 if (dst.enabled == 0) {
1100 return;
1101 }
1102 const u32 width = src.max_x - src.min_x;
1103 const u32 height = src.max_y - src.min_y;
1104 dst.x = src.min_x;
1105 dst.y = src.min_y;
1106 dst.width = width;
1107 dst.height = height;
1101 } 1108 }
1102 const u32 width = regs.scissor_test.max_x - regs.scissor_test.min_x;
1103 const u32 height = regs.scissor_test.max_y - regs.scissor_test.min_y;
1104 state.scissor.x = regs.scissor_test.min_x;
1105 state.scissor.y = regs.scissor_test.min_y;
1106 state.scissor.width = width;
1107 state.scissor.height = height;
1108} 1109}
1109 1110
1110void RasterizerOpenGL::SyncTransformFeedback() { 1111void RasterizerOpenGL::SyncTransformFeedback() {
diff --git a/src/video_core/renderer_opengl/gl_shader_manager.h b/src/video_core/renderer_opengl/gl_shader_manager.h
index 2a069cdd8..9a5d7e289 100644
--- a/src/video_core/renderer_opengl/gl_shader_manager.h
+++ b/src/video_core/renderer_opengl/gl_shader_manager.h
@@ -67,6 +67,7 @@ public:
67 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs); 67 glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs);
68 state.draw.shader_program = 0; 68 state.draw.shader_program = 0;
69 state.draw.program_pipeline = pipeline.handle; 69 state.draw.program_pipeline = pipeline.handle;
70 state.geometry_shaders.enabled = (gs != 0);
70 } 71 }
71 72
72private: 73private:
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index 98622a058..dd6d946e5 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -14,6 +14,7 @@ OpenGLState OpenGLState::cur_state;
14bool OpenGLState::s_rgb_used; 14bool OpenGLState::s_rgb_used;
15OpenGLState::OpenGLState() { 15OpenGLState::OpenGLState() {
16 // These all match default OpenGL values 16 // These all match default OpenGL values
17 geometry_shaders.enabled = false;
17 framebuffer_srgb.enabled = false; 18 framebuffer_srgb.enabled = false;
18 cull.enabled = false; 19 cull.enabled = false;
19 cull.mode = GL_BACK; 20 cull.mode = GL_BACK;
@@ -50,12 +51,12 @@ OpenGLState::OpenGLState() {
50 item.height = 0; 51 item.height = 0;
51 item.depth_range_near = 0.0f; 52 item.depth_range_near = 0.0f;
52 item.depth_range_far = 1.0f; 53 item.depth_range_far = 1.0f;
54 item.scissor.enabled = false;
55 item.scissor.x = 0;
56 item.scissor.y = 0;
57 item.scissor.width = 0;
58 item.scissor.height = 0;
53 } 59 }
54 scissor.enabled = false;
55 scissor.x = 0;
56 scissor.y = 0;
57 scissor.width = 0;
58 scissor.height = 0;
59 for (auto& item : blend) { 60 for (auto& item : blend) {
60 item.enabled = true; 61 item.enabled = true;
61 item.rgb_equation = GL_FUNC_ADD; 62 item.rgb_equation = GL_FUNC_ADD;
@@ -136,7 +137,7 @@ void OpenGLState::ApplyCulling() const {
136} 137}
137 138
138void OpenGLState::ApplyColorMask() const { 139void OpenGLState::ApplyColorMask() const {
139 if (GLAD_GL_ARB_viewport_array) { 140 if (GLAD_GL_ARB_viewport_array && independant_blend.enabled) {
140 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { 141 for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
141 const auto& updated = color_mask[i]; 142 const auto& updated = color_mask[i];
142 const auto& current = cur_state.color_mask[i]; 143 const auto& current = cur_state.color_mask[i];
@@ -230,26 +231,10 @@ void OpenGLState::ApplyStencilTest() const {
230 } 231 }
231} 232}
232 233
233void OpenGLState::ApplyScissor() const {
234 const bool scissor_changed = scissor.enabled != cur_state.scissor.enabled;
235 if (scissor_changed) {
236 if (scissor.enabled) {
237 glEnable(GL_SCISSOR_TEST);
238 } else {
239 glDisable(GL_SCISSOR_TEST);
240 }
241 }
242 if (scissor.enabled &&
243 (scissor_changed || scissor.x != cur_state.scissor.x || scissor.y != cur_state.scissor.y ||
244 scissor.width != cur_state.scissor.width || scissor.height != cur_state.scissor.height)) {
245 glScissor(scissor.x, scissor.y, scissor.width, scissor.height);
246 }
247}
248
249void OpenGLState::ApplyViewport() const { 234void OpenGLState::ApplyViewport() const {
250 if (GLAD_GL_ARB_viewport_array) { 235 if (GLAD_GL_ARB_viewport_array && geometry_shaders.enabled) {
251 for (GLuint i = 0; 236 for (GLuint i = 0; i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumViewports);
252 i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); i++) { 237 i++) {
253 const auto& current = cur_state.viewports[i]; 238 const auto& current = cur_state.viewports[i];
254 const auto& updated = viewports[i]; 239 const auto& updated = viewports[i];
255 if (updated.x != current.x || updated.y != current.y || 240 if (updated.x != current.x || updated.y != current.y ||
@@ -260,6 +245,22 @@ void OpenGLState::ApplyViewport() const {
260 updated.depth_range_far != current.depth_range_far) { 245 updated.depth_range_far != current.depth_range_far) {
261 glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far); 246 glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far);
262 } 247 }
248 const bool scissor_changed = updated.scissor.enabled != current.scissor.enabled;
249 if (scissor_changed) {
250 if (updated.scissor.enabled) {
251 glEnablei(GL_SCISSOR_TEST, i);
252 } else {
253 glDisablei(GL_SCISSOR_TEST, i);
254 }
255 }
256 if (updated.scissor.enabled &&
257 (scissor_changed || updated.scissor.x != current.scissor.x ||
258 updated.scissor.y != current.scissor.y ||
259 updated.scissor.width != current.scissor.width ||
260 updated.scissor.height != current.scissor.height)) {
261 glScissorIndexed(i, updated.scissor.x, updated.scissor.y, updated.scissor.width,
262 updated.scissor.height);
263 }
263 } 264 }
264 } else { 265 } else {
265 const auto& current = cur_state.viewports[0]; 266 const auto& current = cur_state.viewports[0];
@@ -273,6 +274,21 @@ void OpenGLState::ApplyViewport() const {
273 updated.depth_range_far != current.depth_range_far) { 274 updated.depth_range_far != current.depth_range_far) {
274 glDepthRange(updated.depth_range_near, updated.depth_range_far); 275 glDepthRange(updated.depth_range_near, updated.depth_range_far);
275 } 276 }
277 const bool scissor_changed = updated.scissor.enabled != current.scissor.enabled;
278 if (scissor_changed) {
279 if (updated.scissor.enabled) {
280 glEnable(GL_SCISSOR_TEST);
281 } else {
282 glDisable(GL_SCISSOR_TEST);
283 }
284 }
285 if (updated.scissor.enabled && (scissor_changed || updated.scissor.x != current.scissor.x ||
286 updated.scissor.y != current.scissor.y ||
287 updated.scissor.width != current.scissor.width ||
288 updated.scissor.height != current.scissor.height)) {
289 glScissor(updated.scissor.x, updated.scissor.y, updated.scissor.width,
290 updated.scissor.height);
291 }
276 } 292 }
277} 293}
278 294
@@ -483,7 +499,6 @@ void OpenGLState::Apply() const {
483 } 499 }
484 ApplyColorMask(); 500 ApplyColorMask();
485 ApplyViewport(); 501 ApplyViewport();
486 ApplyScissor();
487 ApplyStencilTest(); 502 ApplyStencilTest();
488 ApplySRgb(); 503 ApplySRgb();
489 ApplyCulling(); 504 ApplyCulling();
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index e5d1baae6..da487461f 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -40,6 +40,10 @@ public:
40 } framebuffer_srgb; 40 } framebuffer_srgb;
41 41
42 struct { 42 struct {
43 bool enabled; // viewports arrays are only supported when geometry shaders are enabled.
44 } geometry_shaders;
45
46 struct {
43 bool enabled; // GL_CULL_FACE 47 bool enabled; // GL_CULL_FACE
44 GLenum mode; // GL_CULL_FACE_MODE 48 GLenum mode; // GL_CULL_FACE_MODE
45 GLenum front_face; // GL_FRONT_FACE 49 GLenum front_face; // GL_FRONT_FACE
@@ -150,16 +154,15 @@ public:
150 GLfloat height; 154 GLfloat height;
151 GLfloat depth_range_near; // GL_DEPTH_RANGE 155 GLfloat depth_range_near; // GL_DEPTH_RANGE
152 GLfloat depth_range_far; // GL_DEPTH_RANGE 156 GLfloat depth_range_far; // GL_DEPTH_RANGE
157 struct {
158 bool enabled; // GL_SCISSOR_TEST
159 GLint x;
160 GLint y;
161 GLsizei width;
162 GLsizei height;
163 } scissor;
153 }; 164 };
154 std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> viewports; 165 std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
155
156 struct {
157 bool enabled; // GL_SCISSOR_TEST
158 GLint x;
159 GLint y;
160 GLsizei width;
161 GLsizei height;
162 } scissor;
163 166
164 struct { 167 struct {
165 float size; // GL_POINT_SIZE 168 float size; // GL_POINT_SIZE
@@ -214,7 +217,6 @@ private:
214 void ApplyLogicOp() const; 217 void ApplyLogicOp() const;
215 void ApplyTextures() const; 218 void ApplyTextures() const;
216 void ApplySamplers() const; 219 void ApplySamplers() const;
217 void ApplyScissor() const;
218}; 220};
219 221
220} // namespace OpenGL 222} // namespace OpenGL