Merge pull request #2067 from ReinUsesLisp/workaround-fb

gl_rasterizer: Workaround invalid zeta clears
This commit is contained in:
bunnei 2019-02-01 12:50:09 -05:00 committed by GitHub
commit 2d226ff8ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 14 deletions

View file

@ -477,9 +477,9 @@ void RasterizerOpenGL::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {
cached_pages.add({pages_interval, delta}); cached_pages.add({pages_interval, delta});
} }
void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool using_color_fb, std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
bool using_depth_fb, bool preserve_contents, OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
std::optional<std::size_t> single_color_target) { std::optional<std::size_t> single_color_target) {
MICROPROFILE_SCOPE(OpenGL_Framebuffer); MICROPROFILE_SCOPE(OpenGL_Framebuffer);
const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
const auto& regs = gpu.regs; const auto& regs = gpu.regs;
@ -491,7 +491,7 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
// Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or // Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
// single color targets). This is done because the guest registers may not change but the // single color targets). This is done because the guest registers may not change but the
// host framebuffer may contain different attachments // host framebuffer may contain different attachments
return; return current_depth_stencil_usage;
} }
current_framebuffer_config_state = fb_config_state; current_framebuffer_config_state = fb_config_state;
@ -561,12 +561,14 @@ void RasterizerOpenGL::ConfigureFramebuffers(OpenGLState& current_state, bool us
depth_surface->MarkAsModified(true, res_cache); depth_surface->MarkAsModified(true, res_cache);
fbkey.zeta = depth_surface->Texture().handle; fbkey.zeta = depth_surface->Texture().handle;
fbkey.stencil_enable = regs.stencil_enable; fbkey.stencil_enable = regs.stencil_enable &&
depth_surface->GetSurfaceParams().type == SurfaceType::DepthStencil;
} }
SetupCachedFramebuffer(fbkey, current_state); SetupCachedFramebuffer(fbkey, current_state);
SyncViewport(current_state); SyncViewport(current_state);
return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
} }
void RasterizerOpenGL::Clear() { void RasterizerOpenGL::Clear() {
@ -634,8 +636,8 @@ void RasterizerOpenGL::Clear() {
return; return;
} }
ConfigureFramebuffers(clear_state, use_color, use_depth || use_stencil, false, const auto [clear_depth, clear_stencil] = ConfigureFramebuffers(
regs.clear_buffers.RT.Value()); clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value());
if (regs.clear_flags.scissor) { if (regs.clear_flags.scissor) {
SyncScissorTest(clear_state); SyncScissorTest(clear_state);
} }
@ -650,11 +652,11 @@ void RasterizerOpenGL::Clear() {
glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color); glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
} }
if (use_depth && use_stencil) { if (clear_depth && clear_stencil) {
glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil); glClearBufferfi(GL_DEPTH_STENCIL, 0, regs.clear_depth, regs.clear_stencil);
} else if (use_depth) { } else if (clear_depth) {
glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth); glClearBufferfv(GL_DEPTH, 0, &regs.clear_depth);
} else if (use_stencil) { } else if (clear_stencil) {
glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil); glClearBufferiv(GL_STENCIL, 0, &regs.clear_stencil);
} }
} }

View file

@ -121,10 +121,12 @@ private:
* @param using_depth_fb If true, configure the depth/stencil framebuffer. * @param using_depth_fb If true, configure the depth/stencil framebuffer.
* @param preserve_contents If true, tries to preserve data from a previously used framebuffer. * @param preserve_contents If true, tries to preserve data from a previously used framebuffer.
* @param single_color_target Specifies if a single color buffer target should be used. * @param single_color_target Specifies if a single color buffer target should be used.
* @returns If depth (first) or stencil (second) are being stored in the bound zeta texture
* (requires using_depth_fb to be true)
*/ */
void ConfigureFramebuffers(OpenGLState& current_state, bool use_color_fb = true, std::pair<bool, bool> ConfigureFramebuffers(
bool using_depth_fb = true, bool preserve_contents = true, OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
std::optional<std::size_t> single_color_target = {}); bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
/// Configures the current constbuffers to use for the draw command. /// Configures the current constbuffers to use for the draw command.
void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader, void SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, const Shader& shader,
@ -213,6 +215,7 @@ private:
std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache; std::map<FramebufferCacheKey, OGLFramebuffer> framebuffer_cache;
FramebufferConfigState current_framebuffer_config_state; FramebufferConfigState current_framebuffer_config_state;
std::pair<bool, bool> current_depth_stencil_usage{};
std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers; std::array<SamplerInfo, Tegra::Engines::Maxwell3D::Regs::NumTextureSamplers> texture_samplers;