summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/gl_rasterizer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/gl_rasterizer.cpp')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp50
1 files changed, 25 insertions, 25 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index a44bbfae8..9e93bd609 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -88,19 +88,6 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo
state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
}
- GLint ext_num;
- glGetIntegerv(GL_NUM_EXTENSIONS, &ext_num);
- for (GLint i = 0; i < ext_num; i++) {
- const std::string_view extension{
- reinterpret_cast<const char*>(glGetStringi(GL_EXTENSIONS, i))};
-
- if (extension == "GL_ARB_direct_state_access") {
- has_ARB_direct_state_access = true;
- } else if (extension == "GL_ARB_multi_bind") {
- has_ARB_multi_bind = true;
- }
- }
-
OpenGLState::ApplyDefaultState();
// Create render framebuffer
@@ -295,6 +282,7 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
// shaders. The constbuffer bindpoint starts after the shader stage configuration bind points.
u32 current_constbuffer_bindpoint = Tegra::Engines::Maxwell3D::Regs::MaxShaderStage;
u32 current_texture_bindpoint = 0;
+ std::array<bool, Maxwell::NumClipDistances> clip_distances{};
for (std::size_t index = 0; index < Maxwell::MaxShaderProgram; ++index) {
const auto& shader_config = gpu.regs.shader_config[index];
@@ -355,12 +343,22 @@ void RasterizerOpenGL::SetupShaders(GLenum primitive_mode) {
current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader,
primitive_mode, current_texture_bindpoint);
+ // Workaround for Intel drivers.
+ // When a clip distance is enabled but not set in the shader it crops parts of the screen
+ // (sometimes it's half the screen, sometimes three quarters). To avoid this, enable the
+ // clip distances only when it's written by a shader stage.
+ for (std::size_t i = 0; i < Maxwell::NumClipDistances; ++i) {
+ clip_distances[i] |= shader->GetShaderEntries().clip_distances[i];
+ }
+
// When VertexA is enabled, we have dual vertex shaders
if (program == Maxwell::ShaderProgram::VertexA) {
// VertexB was combined with VertexA, so we skip the VertexB iteration
index++;
}
}
+
+ SyncClipEnabled(clip_distances);
}
std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
@@ -443,7 +441,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
// TODO(bunnei): Figure out how the below register works. According to envytools, this should be
// used to enable multiple render targets. However, it is left unset on all games that I have
// tested.
- ASSERT_MSG(regs.rt_separate_frag_data == 0, "Unimplemented");
+ UNIMPLEMENTED_IF(regs.rt_separate_frag_data != 0);
// Bind the framebuffer surfaces
current_state.draw.draw_framebuffer = framebuffer.handle;
@@ -642,7 +640,6 @@ void RasterizerOpenGL::DrawArrays() {
SyncCullMode();
SyncPrimitiveRestart();
SyncScissorTest(state);
- SyncClipEnabled();
// Alpha Testing is synced on shaders.
SyncTransformFeedback();
SyncPointState();
@@ -1019,20 +1016,23 @@ void RasterizerOpenGL::SyncViewport(OpenGLState& current_state) {
state.depth_clamp.near_plane = regs.view_volume_clip_control.depth_clamp_near != 0;
}
-void RasterizerOpenGL::SyncClipEnabled() {
+void RasterizerOpenGL::SyncClipEnabled(
+ const std::array<bool, Maxwell::Regs::NumClipDistances>& clip_mask) {
+
const auto& regs = Core::System::GetInstance().GPU().Maxwell3D().regs;
- state.clip_distance[0] = regs.clip_distance_enabled.c0 != 0;
- state.clip_distance[1] = regs.clip_distance_enabled.c1 != 0;
- state.clip_distance[2] = regs.clip_distance_enabled.c2 != 0;
- state.clip_distance[3] = regs.clip_distance_enabled.c3 != 0;
- state.clip_distance[4] = regs.clip_distance_enabled.c4 != 0;
- state.clip_distance[5] = regs.clip_distance_enabled.c5 != 0;
- state.clip_distance[6] = regs.clip_distance_enabled.c6 != 0;
- state.clip_distance[7] = regs.clip_distance_enabled.c7 != 0;
+ const std::array<bool, Maxwell::Regs::NumClipDistances> reg_state{
+ regs.clip_distance_enabled.c0 != 0, regs.clip_distance_enabled.c1 != 0,
+ regs.clip_distance_enabled.c2 != 0, regs.clip_distance_enabled.c3 != 0,
+ regs.clip_distance_enabled.c4 != 0, regs.clip_distance_enabled.c5 != 0,
+ regs.clip_distance_enabled.c6 != 0, regs.clip_distance_enabled.c7 != 0};
+
+ for (std::size_t i = 0; i < Maxwell::Regs::NumClipDistances; ++i) {
+ state.clip_distance[i] = reg_state[i] && clip_mask[i];
+ }
}
void RasterizerOpenGL::SyncClipCoef() {
- UNREACHABLE();
+ UNIMPLEMENTED();
}
void RasterizerOpenGL::SyncCullMode() {