summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/rasterizer_interface.h7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp52
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp9
4 files changed, 37 insertions, 35 deletions
diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index 71df233b5..8ef7e74c7 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -42,11 +42,16 @@ public:
/// and invalidated
virtual void FlushAndInvalidateRegion(PAddr addr, u32 size) = 0;
- /// Attempt to use a faster method to perform a display transfer
+ /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
virtual bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) {
return false;
}
+ /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1
+ virtual bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) {
+ return false;
+ }
+
/// Attempt to use a faster method to fill a region
virtual bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) {
return false;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 60c9d9180..7cc3b407a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -211,6 +211,27 @@ void RasterizerOpenGL::DrawTriangles() {
uniform_block_data.dirty = true;
}
+ // Scissor checks are window-, not viewport-relative, which means that if the cached texture
+ // sub-rect changes, the scissor bounds also need to be updated.
+ GLint scissor_x1 = rect.left + regs.scissor_test.x1 * color_surface->res_scale_width;
+ GLint scissor_y1 = rect.bottom + regs.scissor_test.y1 * color_surface->res_scale_height;
+ // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when
+ // scaling or doing multisampling.
+ GLint scissor_x2 = rect.left + (regs.scissor_test.x2 + 1) * color_surface->res_scale_width;
+ GLint scissor_y2 = rect.bottom + (regs.scissor_test.y2 + 1) * color_surface->res_scale_height;
+
+ if (uniform_block_data.data.scissor_x1 != scissor_x1 ||
+ uniform_block_data.data.scissor_x2 != scissor_x2 ||
+ uniform_block_data.data.scissor_y1 != scissor_y1 ||
+ uniform_block_data.data.scissor_y2 != scissor_y2) {
+
+ uniform_block_data.data.scissor_x1 = scissor_x1;
+ uniform_block_data.data.scissor_x2 = scissor_x2;
+ uniform_block_data.data.scissor_y1 = scissor_y1;
+ uniform_block_data.data.scissor_y2 = scissor_y2;
+ uniform_block_data.dirty = true;
+ }
+
// Sync and bind the texture surfaces
const auto pica_textures = regs.GetTextures();
for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) {
@@ -374,10 +395,6 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
case PICA_REG_INDEX(scissor_test.mode):
shader_dirty = true;
break;
- case PICA_REG_INDEX(scissor_test.x1): // and y1
- case PICA_REG_INDEX(scissor_test.x2): // and y2
- SyncScissorTest();
- break;
// Logic op
case PICA_REG_INDEX(output_merger.logic_op):
@@ -692,11 +709,6 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe
using PixelFormat = CachedSurface::PixelFormat;
using SurfaceType = CachedSurface::SurfaceType;
- if (config.is_texture_copy) {
- // TODO(tfarley): Try to hardware accelerate this
- return false;
- }
-
CachedSurface src_params;
src_params.addr = config.GetPhysicalInputAddress();
src_params.width = config.output_width;
@@ -751,6 +763,11 @@ bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransfe
return true;
}
+bool RasterizerOpenGL::AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) {
+ // TODO(tfarley): Try to hardware accelerate this
+ return false;
+}
+
bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config) {
using PixelFormat = CachedSurface::PixelFormat;
using SurfaceType = CachedSurface::SurfaceType;
@@ -1061,7 +1078,6 @@ void RasterizerOpenGL::SetShader() {
SyncDepthOffset();
SyncAlphaTest();
SyncCombinerColor();
- SyncScissorTest();
auto& tev_stages = Pica::g_state.regs.GetTevStages();
for (int index = 0; index < tev_stages.size(); ++index)
SyncTevConstColor(index, tev_stages[index]);
@@ -1236,22 +1252,6 @@ void RasterizerOpenGL::SyncDepthTest() {
: GL_ALWAYS;
}
-void RasterizerOpenGL::SyncScissorTest() {
- const auto& regs = Pica::g_state.regs;
-
- if (uniform_block_data.data.scissor_x1 != regs.scissor_test.x1 ||
- uniform_block_data.data.scissor_y1 != regs.scissor_test.y1 ||
- uniform_block_data.data.scissor_x2 != regs.scissor_test.x2 ||
- uniform_block_data.data.scissor_y2 != regs.scissor_test.y2) {
-
- uniform_block_data.data.scissor_x1 = regs.scissor_test.x1;
- uniform_block_data.data.scissor_y1 = regs.scissor_test.y1;
- uniform_block_data.data.scissor_x2 = regs.scissor_test.x2;
- uniform_block_data.data.scissor_y2 = regs.scissor_test.y2;
- uniform_block_data.dirty = true;
- }
-}
-
void RasterizerOpenGL::SyncCombinerColor() {
auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw);
if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 24fefed1b..e1a9cb361 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -238,6 +238,7 @@ public:
void FlushRegion(PAddr addr, u32 size) override;
void FlushAndInvalidateRegion(PAddr addr, u32 size) override;
bool AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) override;
+ bool AccelerateTextureCopy(const GPU::Regs::DisplayTransferConfig& config) override;
bool AccelerateFill(const GPU::Regs::MemoryFillConfig& config) override;
bool AccelerateDisplay(const GPU::Regs::FramebufferConfig& config, PAddr framebuffer_addr,
u32 pixel_stride, ScreenInfo& screen_info) override;
@@ -393,9 +394,6 @@ private:
/// Syncs the depth test states to match the PICA register
void SyncDepthTest();
- /// Syncs the scissor test state to match the PICA register
- void SyncScissorTest();
-
/// Syncs the TEV combiner color buffer to match the PICA register
void SyncCombinerColor();
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 1808ee0a9..8f278722d 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -645,11 +645,10 @@ vec4 secondary_fragment_color = vec4(0.0);
// Negate the condition if we have to keep only the pixels outside the scissor box
if (state.scissor_test_mode == Regs::ScissorMode::Include)
out += "!";
- // x2,y2 have +1 added to cover the entire pixel area
- out += "(gl_FragCoord.x >= scissor_x1 * framebuffer_scale.x && "
- "gl_FragCoord.y >= scissor_y1 * framebuffer_scale.y && "
- "gl_FragCoord.x < (scissor_x2 + 1) * framebuffer_scale.x && "
- "gl_FragCoord.y < (scissor_y2 + 1) * framebuffer_scale.y)) discard;\n";
+ out += "(gl_FragCoord.x >= scissor_x1 && "
+ "gl_FragCoord.y >= scissor_y1 && "
+ "gl_FragCoord.x < scissor_x2 && "
+ "gl_FragCoord.y < scissor_y2)) discard;\n";
}
out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n";