mirror of https://git.suyu.dev/suyu/suyu
GL_Rasterizer: Rework RenderTarget/DepthBuffer clearing
This commit is contained in:
parent
a081dea8ab
commit
fec32fed18
|
@ -568,7 +568,6 @@ void Maxwell3D::FinishCBData() {
|
||||||
|
|
||||||
const u32 id = cb_data_state.id;
|
const u32 id = cb_data_state.id;
|
||||||
memory_manager.WriteBlock(address, cb_data_state.buff[id].data(), size);
|
memory_manager.WriteBlock(address, cb_data_state.buff[id].data(), size);
|
||||||
dirty.ResetRenderTargets();
|
|
||||||
|
|
||||||
cb_data_state.id = null_cb_data;
|
cb_data_state.id = null_cb_data;
|
||||||
cb_data_state.current = null_cb_data;
|
cb_data_state.current = null_cb_data;
|
||||||
|
|
|
@ -105,6 +105,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind
|
||||||
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
|
shader_program_manager = std::make_unique<GLShader::ProgramManager>();
|
||||||
state.draw.shader_program = 0;
|
state.draw.shader_program = 0;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
clear_framebuffer.Create();
|
||||||
|
|
||||||
LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
|
LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here");
|
||||||
CheckExtensions();
|
CheckExtensions();
|
||||||
|
@ -546,12 +547,63 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||||
return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
|
return current_depth_stencil_usage = {static_cast<bool>(depth_surface), fbkey.stencil_enable};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
||||||
|
bool using_depth_fb, bool using_stencil_fb) {
|
||||||
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
|
texture_cache.GuardRenderTargets(true);
|
||||||
|
View color_surface{};
|
||||||
|
if (using_color_fb) {
|
||||||
|
color_surface = texture_cache.GetColorBufferSurface(regs.clear_buffers.RT, false);
|
||||||
|
}
|
||||||
|
View depth_surface{};
|
||||||
|
if (using_depth_fb || using_stencil_fb) {
|
||||||
|
depth_surface = texture_cache.GetDepthBufferSurface(false);
|
||||||
|
}
|
||||||
|
texture_cache.GuardRenderTargets(false);
|
||||||
|
|
||||||
|
current_state.draw.draw_framebuffer = clear_framebuffer.handle;
|
||||||
|
current_state.ApplyFramebufferState();
|
||||||
|
|
||||||
|
if (color_surface) {
|
||||||
|
color_surface->Attach(GL_COLOR_ATTACHMENT0, GL_DRAW_FRAMEBUFFER);
|
||||||
|
} else {
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (depth_surface) {
|
||||||
|
const auto& params = depth_surface->GetSurfaceParams();
|
||||||
|
switch (params.type) {
|
||||||
|
case VideoCore::Surface::SurfaceType::Depth: {
|
||||||
|
depth_surface->Attach(GL_DEPTH_ATTACHMENT, GL_DRAW_FRAMEBUFFER);
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VideoCore::Surface::SurfaceType::DepthStencil: {
|
||||||
|
depth_surface->Attach(GL_DEPTH_ATTACHMENT, GL_DRAW_FRAMEBUFFER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: { UNIMPLEMENTED(); }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::Clear() {
|
void RasterizerOpenGL::Clear() {
|
||||||
const auto& regs = system.GPU().Maxwell3D().regs;
|
const auto& regs = system.GPU().Maxwell3D().regs;
|
||||||
bool use_color{};
|
bool use_color{};
|
||||||
bool use_depth{};
|
bool use_depth{};
|
||||||
bool use_stencil{};
|
bool use_stencil{};
|
||||||
|
|
||||||
|
OpenGLState prev_state{OpenGLState::GetCurState()};
|
||||||
|
SCOPE_EXIT({
|
||||||
|
prev_state.AllDirty();
|
||||||
|
prev_state.Apply();
|
||||||
|
});
|
||||||
|
|
||||||
OpenGLState clear_state;
|
OpenGLState clear_state;
|
||||||
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
|
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B ||
|
||||||
regs.clear_buffers.A) {
|
regs.clear_buffers.A) {
|
||||||
|
@ -608,8 +660,8 @@ void RasterizerOpenGL::Clear() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto [clear_depth, clear_stencil] = ConfigureFramebuffers(
|
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil);
|
||||||
clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value());
|
SyncViewport(clear_state);
|
||||||
if (regs.clear_flags.scissor) {
|
if (regs.clear_flags.scissor) {
|
||||||
SyncScissorTest(clear_state);
|
SyncScissorTest(clear_state);
|
||||||
}
|
}
|
||||||
|
@ -625,14 +677,14 @@ void RasterizerOpenGL::Clear() {
|
||||||
clear_state.ApplyFramebufferState();
|
clear_state.ApplyFramebufferState();
|
||||||
|
|
||||||
if (use_color) {
|
if (use_color) {
|
||||||
glClearBufferfv(GL_COLOR, regs.clear_buffers.RT, regs.clear_color);
|
glClearBufferfv(GL_COLOR, 0, regs.clear_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_depth && clear_stencil) {
|
if (use_depth && use_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 (clear_depth) {
|
} else if (use_depth) {
|
||||||
glClearBufferfv(GL_DEPTH, 0, ®s.clear_depth);
|
glClearBufferfv(GL_DEPTH, 0, ®s.clear_depth);
|
||||||
} else if (clear_stencil) {
|
} else if (use_stencil) {
|
||||||
glClearBufferiv(GL_STENCIL, 0, ®s.clear_stencil);
|
glClearBufferiv(GL_STENCIL, 0, ®s.clear_stencil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,6 +108,9 @@ private:
|
||||||
OpenGLState& current_state, bool using_color_fb = true, bool using_depth_fb = true,
|
OpenGLState& current_state, bool using_color_fb = true, bool using_depth_fb = true,
|
||||||
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
|
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
|
||||||
|
|
||||||
|
void ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
||||||
|
bool using_depth_fb, bool using_stencil_fb);
|
||||||
|
|
||||||
/// Configures the current constbuffers to use for the draw command.
|
/// Configures the current constbuffers to use for the draw command.
|
||||||
void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
|
void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
|
||||||
const Shader& shader);
|
const Shader& shader);
|
||||||
|
@ -227,6 +230,8 @@ private:
|
||||||
enum class AccelDraw { Disabled, Arrays, Indexed };
|
enum class AccelDraw { Disabled, Arrays, Indexed };
|
||||||
AccelDraw accelerate_draw = AccelDraw::Disabled;
|
AccelDraw accelerate_draw = AccelDraw::Disabled;
|
||||||
|
|
||||||
|
OGLFramebuffer clear_framebuffer;
|
||||||
|
|
||||||
using CachedPageMap = boost::icl::interval_map<u64, int>;
|
using CachedPageMap = boost::icl::interval_map<u64, int>;
|
||||||
CachedPageMap cached_pages;
|
CachedPageMap cached_pages;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue