summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
authorRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2018-11-14 00:13:16 +0100
committerRodolfo Bogado <rodolfoosvaldobogado@gmail.com>2018-11-17 23:59:32 +0100
commit1881e86c434edfc17f78f68f07443bef1120cda1 (patch)
tree3694a8acdc510e4d17e124b0c4285c99c14ccfd4 /src/video_core
parentMerge pull request #1722 from MysticExile/enable-applictation-crash-report (diff)
downloadyuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar.gz
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar.bz2
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar.lz
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar.xz
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.tar.zst
yuzu-1881e86c434edfc17f78f68f07443bef1120cda1.zip
Diffstat (limited to 'src/video_core')
-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() {
// Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is
// needed for ARMS.
for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) {
- regs.viewport[viewport].depth_range_near = 0.0f;
- regs.viewport[viewport].depth_range_far = 1.0f;
+ regs.viewports[viewport].depth_range_near = 0.0f;
+ regs.viewports[viewport].depth_range_far = 1.0f;
}
// Doom and Bomberman seems to use the uninitialized registers and just enable blend
// 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:
INSERT_PADDING_WORDS(0x2E);
- RenderTargetConfig rt[NumRenderTargets];
+ std::array<RenderTargetConfig, NumRenderTargets> rt;
- struct {
+ struct ViewportTransform {
f32 scale_x;
f32 scale_y;
f32 scale_z;
@@ -540,9 +540,11 @@ public:
s32 GetHeight() const {
return static_cast<s32>(translate_y + std::fabs(scale_y)) - GetY();
}
- } viewport_transform[NumViewports];
+ };
- struct {
+ std::array<ViewportTransform, NumViewports> viewport_transform;
+
+ struct ViewPort {
union {
BitField<0, 16, u32> x;
BitField<16, 16, u32> width;
@@ -553,7 +555,9 @@ public:
};
float depth_range_near;
float depth_range_far;
- } viewport[NumViewports];
+ };
+
+ std::array<ViewPort, NumViewports> viewports;
INSERT_PADDING_WORDS(0x1D);
@@ -571,7 +575,7 @@ public:
INSERT_PADDING_WORDS(0x17);
- struct {
+ struct ScissorTest {
u32 enable;
union {
BitField<0, 16, u32> min_x;
@@ -581,9 +585,11 @@ public:
BitField<0, 16, u32> min_y;
BitField<16, 16, u32> max_y;
};
- } scissor_test;
+ u32 fill;
+ };
+ std::array<ScissorTest, NumViewports> scissor_test;
- INSERT_PADDING_WORDS(0x52);
+ INSERT_PADDING_WORDS(0x15);
s32 stencil_back_func_ref;
u32 stencil_back_mask;
@@ -1100,8 +1106,8 @@ private:
ASSERT_REG_POSITION(macros, 0x45);
ASSERT_REG_POSITION(tfb_enabled, 0x1D1);
ASSERT_REG_POSITION(rt, 0x200);
-ASSERT_REG_POSITION(viewport_transform[0], 0x280);
-ASSERT_REG_POSITION(viewport, 0x300);
+ASSERT_REG_POSITION(viewport_transform, 0x280);
+ASSERT_REG_POSITION(viewports, 0x300);
ASSERT_REG_POSITION(vertex_buffer, 0x35D);
ASSERT_REG_POSITION(clear_color[0], 0x360);
ASSERT_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() {
params.DispatchDraw();
// Disable scissor test
- state.scissor.enabled = false;
+ state.viewports[0].scissor.enabled = false;
accelerate_draw = AccelDraw::Disabled;
@@ -923,15 +923,15 @@ u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader,
void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
+ for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
const MathUtil::Rectangle<s32> viewport_rect{regs.viewport_transform[i].GetRect()};
auto& viewport = current_state.viewports[i];
viewport.x = viewport_rect.left;
viewport.y = viewport_rect.bottom;
viewport.width = static_cast<GLfloat>(viewport_rect.GetWidth());
viewport.height = static_cast<GLfloat>(viewport_rect.GetHeight());
- viewport.depth_range_far = regs.viewport[i].depth_range_far;
- viewport.depth_range_near = regs.viewport[i].depth_range_near;
+ viewport.depth_range_far = regs.viewports[i].depth_range_far;
+ viewport.depth_range_near = regs.viewports[i].depth_range_near;
}
}
@@ -1079,7 +1079,6 @@ void RasterizerOpenGL::SyncBlendState() {
void RasterizerOpenGL::SyncLogicOpState() {
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- // TODO(Subv): Support more than just render target 0.
state.logic_op.enabled = regs.logic_op.enable != 0;
if (!state.logic_op.enabled)
@@ -1092,19 +1091,21 @@ void RasterizerOpenGL::SyncLogicOpState() {
}
void RasterizerOpenGL::SyncScissorTest() {
- // TODO: what is the correct behavior here, a single scissor for all targets
- // or scissor disabled for the rest of the targets?
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- state.scissor.enabled = (regs.scissor_test.enable != 0);
- if (regs.scissor_test.enable == 0) {
- return;
+ for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumViewports; i++) {
+ const auto& src = regs.scissor_test[i];
+ auto& dst = state.viewports[i].scissor;
+ dst.enabled = (src.enable != 0);
+ if (dst.enabled == 0) {
+ return;
+ }
+ const u32 width = src.max_x - src.min_x;
+ const u32 height = src.max_y - src.min_y;
+ dst.x = src.min_x;
+ dst.y = src.min_y;
+ dst.width = width;
+ dst.height = height;
}
- const u32 width = regs.scissor_test.max_x - regs.scissor_test.min_x;
- const u32 height = regs.scissor_test.max_y - regs.scissor_test.min_y;
- state.scissor.x = regs.scissor_test.min_x;
- state.scissor.y = regs.scissor_test.min_y;
- state.scissor.width = width;
- state.scissor.height = height;
}
void 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:
glUseProgramStages(pipeline.handle, GL_FRAGMENT_SHADER_BIT, fs);
state.draw.shader_program = 0;
state.draw.program_pipeline = pipeline.handle;
+ state.geometry_shaders.enabled = (gs != 0);
}
private:
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;
bool OpenGLState::s_rgb_used;
OpenGLState::OpenGLState() {
// These all match default OpenGL values
+ geometry_shaders.enabled = false;
framebuffer_srgb.enabled = false;
cull.enabled = false;
cull.mode = GL_BACK;
@@ -50,12 +51,12 @@ OpenGLState::OpenGLState() {
item.height = 0;
item.depth_range_near = 0.0f;
item.depth_range_far = 1.0f;
+ item.scissor.enabled = false;
+ item.scissor.x = 0;
+ item.scissor.y = 0;
+ item.scissor.width = 0;
+ item.scissor.height = 0;
}
- scissor.enabled = false;
- scissor.x = 0;
- scissor.y = 0;
- scissor.width = 0;
- scissor.height = 0;
for (auto& item : blend) {
item.enabled = true;
item.rgb_equation = GL_FUNC_ADD;
@@ -136,7 +137,7 @@ void OpenGLState::ApplyCulling() const {
}
void OpenGLState::ApplyColorMask() const {
- if (GLAD_GL_ARB_viewport_array) {
+ if (GLAD_GL_ARB_viewport_array && independant_blend.enabled) {
for (size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) {
const auto& updated = color_mask[i];
const auto& current = cur_state.color_mask[i];
@@ -230,26 +231,10 @@ void OpenGLState::ApplyStencilTest() const {
}
}
-void OpenGLState::ApplyScissor() const {
- const bool scissor_changed = scissor.enabled != cur_state.scissor.enabled;
- if (scissor_changed) {
- if (scissor.enabled) {
- glEnable(GL_SCISSOR_TEST);
- } else {
- glDisable(GL_SCISSOR_TEST);
- }
- }
- if (scissor.enabled &&
- (scissor_changed || scissor.x != cur_state.scissor.x || scissor.y != cur_state.scissor.y ||
- scissor.width != cur_state.scissor.width || scissor.height != cur_state.scissor.height)) {
- glScissor(scissor.x, scissor.y, scissor.width, scissor.height);
- }
-}
-
void OpenGLState::ApplyViewport() const {
- if (GLAD_GL_ARB_viewport_array) {
- for (GLuint i = 0;
- i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); i++) {
+ if (GLAD_GL_ARB_viewport_array && geometry_shaders.enabled) {
+ for (GLuint i = 0; i < static_cast<GLuint>(Tegra::Engines::Maxwell3D::Regs::NumViewports);
+ i++) {
const auto& current = cur_state.viewports[i];
const auto& updated = viewports[i];
if (updated.x != current.x || updated.y != current.y ||
@@ -260,6 +245,22 @@ void OpenGLState::ApplyViewport() const {
updated.depth_range_far != current.depth_range_far) {
glDepthRangeIndexed(i, updated.depth_range_near, updated.depth_range_far);
}
+ const bool scissor_changed = updated.scissor.enabled != current.scissor.enabled;
+ if (scissor_changed) {
+ if (updated.scissor.enabled) {
+ glEnablei(GL_SCISSOR_TEST, i);
+ } else {
+ glDisablei(GL_SCISSOR_TEST, i);
+ }
+ }
+ if (updated.scissor.enabled &&
+ (scissor_changed || updated.scissor.x != current.scissor.x ||
+ updated.scissor.y != current.scissor.y ||
+ updated.scissor.width != current.scissor.width ||
+ updated.scissor.height != current.scissor.height)) {
+ glScissorIndexed(i, updated.scissor.x, updated.scissor.y, updated.scissor.width,
+ updated.scissor.height);
+ }
}
} else {
const auto& current = cur_state.viewports[0];
@@ -273,6 +274,21 @@ void OpenGLState::ApplyViewport() const {
updated.depth_range_far != current.depth_range_far) {
glDepthRange(updated.depth_range_near, updated.depth_range_far);
}
+ const bool scissor_changed = updated.scissor.enabled != current.scissor.enabled;
+ if (scissor_changed) {
+ if (updated.scissor.enabled) {
+ glEnable(GL_SCISSOR_TEST);
+ } else {
+ glDisable(GL_SCISSOR_TEST);
+ }
+ }
+ if (updated.scissor.enabled && (scissor_changed || updated.scissor.x != current.scissor.x ||
+ updated.scissor.y != current.scissor.y ||
+ updated.scissor.width != current.scissor.width ||
+ updated.scissor.height != current.scissor.height)) {
+ glScissor(updated.scissor.x, updated.scissor.y, updated.scissor.width,
+ updated.scissor.height);
+ }
}
}
@@ -483,7 +499,6 @@ void OpenGLState::Apply() const {
}
ApplyColorMask();
ApplyViewport();
- ApplyScissor();
ApplyStencilTest();
ApplySRgb();
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:
} framebuffer_srgb;
struct {
+ bool enabled; // viewports arrays are only supported when geometry shaders are enabled.
+ } geometry_shaders;
+
+ struct {
bool enabled; // GL_CULL_FACE
GLenum mode; // GL_CULL_FACE_MODE
GLenum front_face; // GL_FRONT_FACE
@@ -150,16 +154,15 @@ public:
GLfloat height;
GLfloat depth_range_near; // GL_DEPTH_RANGE
GLfloat depth_range_far; // GL_DEPTH_RANGE
+ struct {
+ bool enabled; // GL_SCISSOR_TEST
+ GLint x;
+ GLint y;
+ GLsizei width;
+ GLsizei height;
+ } scissor;
};
- std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumRenderTargets> viewports;
-
- struct {
- bool enabled; // GL_SCISSOR_TEST
- GLint x;
- GLint y;
- GLsizei width;
- GLsizei height;
- } scissor;
+ std::array<viewport, Tegra::Engines::Maxwell3D::Regs::NumViewports> viewports;
struct {
float size; // GL_POINT_SIZE
@@ -214,7 +217,6 @@ private:
void ApplyLogicOp() const;
void ApplyTextures() const;
void ApplySamplers() const;
- void ApplyScissor() const;
};
} // namespace OpenGL