|
|
|
@ -105,6 +105,7 @@ RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWind |
|
|
|
shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
|
|
|
state.draw.shader_program = 0; |
|
|
|
state.Apply(); |
|
|
|
clear_framebuffer.Create(); |
|
|
|
|
|
|
|
LOG_DEBUG(Render_OpenGL, "Sync fixed function OpenGL state here"); |
|
|
|
CheckExtensions(); |
|
|
|
@ -546,12 +547,63 @@ std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers( |
|
|
|
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() { |
|
|
|
const auto& regs = system.GPU().Maxwell3D().regs; |
|
|
|
bool use_color{}; |
|
|
|
bool use_depth{}; |
|
|
|
bool use_stencil{}; |
|
|
|
|
|
|
|
OpenGLState prev_state{OpenGLState::GetCurState()}; |
|
|
|
SCOPE_EXIT({ |
|
|
|
prev_state.AllDirty(); |
|
|
|
prev_state.Apply(); |
|
|
|
}); |
|
|
|
|
|
|
|
OpenGLState clear_state; |
|
|
|
if (regs.clear_buffers.R || regs.clear_buffers.G || regs.clear_buffers.B || |
|
|
|
regs.clear_buffers.A) { |
|
|
|
@ -608,8 +660,8 @@ void RasterizerOpenGL::Clear() { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const auto [clear_depth, clear_stencil] = ConfigureFramebuffers( |
|
|
|
clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value()); |
|
|
|
ConfigureClearFramebuffer(clear_state, use_color, use_depth, use_stencil); |
|
|
|
SyncViewport(clear_state); |
|
|
|
if (regs.clear_flags.scissor) { |
|
|
|
SyncScissorTest(clear_state); |
|
|
|
} |
|
|
|
@ -625,14 +677,14 @@ void RasterizerOpenGL::Clear() { |
|
|
|
clear_state.ApplyFramebufferState(); |
|
|
|
|
|
|
|
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); |
|
|
|
} else if (clear_depth) { |
|
|
|
} else if (use_depth) { |
|
|
|
glClearBufferfv(GL_DEPTH, 0, ®s.clear_depth); |
|
|
|
} else if (clear_stencil) { |
|
|
|
} else if (use_stencil) { |
|
|
|
glClearBufferiv(GL_STENCIL, 0, ®s.clear_stencil); |
|
|
|
} |
|
|
|
} |
|
|
|
|