gl_state: Remove framebuffer tracking
This commit is contained in:
parent
17a7fa751b
commit
5ccb07933a
|
@ -36,8 +36,7 @@ OGLFramebuffer FramebufferCacheOpenGL::CreateFramebuffer(const FramebufferCacheK
|
||||||
framebuffer.Create();
|
framebuffer.Create();
|
||||||
|
|
||||||
// TODO(Rodrigo): Use DSA here after Nvidia fixes their framebuffer DSA bugs.
|
// TODO(Rodrigo): Use DSA here after Nvidia fixes their framebuffer DSA bugs.
|
||||||
local_state.draw.draw_framebuffer = framebuffer.handle;
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer.handle);
|
||||||
local_state.ApplyFramebufferState();
|
|
||||||
|
|
||||||
if (key.zeta) {
|
if (key.zeta) {
|
||||||
const bool stencil = key.zeta->GetSurfaceParams().type == SurfaceType::DepthStencil;
|
const bool stencil = key.zeta->GetSurfaceParams().type == SurfaceType::DepthStencil;
|
||||||
|
|
|
@ -359,7 +359,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
|
||||||
|
|
||||||
texture_cache.GuardRenderTargets(false);
|
texture_cache.GuardRenderTargets(false);
|
||||||
|
|
||||||
state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, bool using_color_fb,
|
||||||
|
@ -384,8 +384,7 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(OpenGLState& current_state, boo
|
||||||
key.colors[0] = color_surface;
|
key.colors[0] = color_surface;
|
||||||
key.zeta = depth_surface;
|
key.zeta = depth_surface;
|
||||||
|
|
||||||
current_state.draw.draw_framebuffer = framebuffer_cache.GetFramebuffer(key);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
|
||||||
current_state.ApplyFramebufferState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::Clear() {
|
void RasterizerOpenGL::Clear() {
|
||||||
|
|
|
@ -20,7 +20,7 @@ void OGLRenderbuffer::Create() {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
|
MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
|
||||||
glGenRenderbuffers(1, &handle);
|
glCreateRenderbuffers(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OGLRenderbuffer::Release() {
|
void OGLRenderbuffer::Release() {
|
||||||
|
@ -29,7 +29,6 @@ void OGLRenderbuffer::Release() {
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
|
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
|
||||||
glDeleteRenderbuffers(1, &handle);
|
glDeleteRenderbuffers(1, &handle);
|
||||||
OpenGLState::GetCurState().ResetRenderbuffer(handle).Apply();
|
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +199,6 @@ void OGLFramebuffer::Release() {
|
||||||
|
|
||||||
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
|
MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
|
||||||
glDeleteFramebuffers(1, &handle);
|
glDeleteFramebuffers(1, &handle);
|
||||||
OpenGLState::GetCurState().ResetFramebuffer(handle).Apply();
|
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,15 +85,6 @@ void Enable(GLenum cap, GLuint index, bool& current_value, bool new_value) {
|
||||||
|
|
||||||
OpenGLState::OpenGLState() = default;
|
OpenGLState::OpenGLState() = default;
|
||||||
|
|
||||||
void OpenGLState::ApplyFramebufferState() {
|
|
||||||
if (UpdateValue(cur_state.draw.read_framebuffer, draw.read_framebuffer)) {
|
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, draw.read_framebuffer);
|
|
||||||
}
|
|
||||||
if (UpdateValue(cur_state.draw.draw_framebuffer, draw.draw_framebuffer)) {
|
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, draw.draw_framebuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLState::ApplyShaderProgram() {
|
void OpenGLState::ApplyShaderProgram() {
|
||||||
if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
|
if (UpdateValue(cur_state.draw.shader_program, draw.shader_program)) {
|
||||||
glUseProgram(draw.shader_program);
|
glUseProgram(draw.shader_program);
|
||||||
|
@ -106,19 +97,10 @@ void OpenGLState::ApplyProgramPipeline() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ApplyRenderBuffer() {
|
|
||||||
if (cur_state.renderbuffer != renderbuffer) {
|
|
||||||
cur_state.renderbuffer = renderbuffer;
|
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLState::Apply() {
|
void OpenGLState::Apply() {
|
||||||
MICROPROFILE_SCOPE(OpenGL_State);
|
MICROPROFILE_SCOPE(OpenGL_State);
|
||||||
ApplyFramebufferState();
|
|
||||||
ApplyShaderProgram();
|
ApplyShaderProgram();
|
||||||
ApplyProgramPipeline();
|
ApplyProgramPipeline();
|
||||||
ApplyRenderBuffer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLState& OpenGLState::ResetProgram(GLuint handle) {
|
OpenGLState& OpenGLState::ResetProgram(GLuint handle) {
|
||||||
|
@ -135,21 +117,4 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLState& OpenGLState::ResetFramebuffer(GLuint handle) {
|
|
||||||
if (draw.read_framebuffer == handle) {
|
|
||||||
draw.read_framebuffer = 0;
|
|
||||||
}
|
|
||||||
if (draw.draw_framebuffer == handle) {
|
|
||||||
draw.draw_framebuffer = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenGLState& OpenGLState::ResetRenderbuffer(GLuint handle) {
|
|
||||||
if (renderbuffer == handle) {
|
|
||||||
renderbuffer = 0;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -14,14 +14,10 @@ namespace OpenGL {
|
||||||
class OpenGLState {
|
class OpenGLState {
|
||||||
public:
|
public:
|
||||||
struct {
|
struct {
|
||||||
GLuint read_framebuffer = 0; // GL_READ_FRAMEBUFFER_BINDING
|
|
||||||
GLuint draw_framebuffer = 0; // GL_DRAW_FRAMEBUFFER_BINDING
|
|
||||||
GLuint shader_program = 0; // GL_CURRENT_PROGRAM
|
GLuint shader_program = 0; // GL_CURRENT_PROGRAM
|
||||||
GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
|
GLuint program_pipeline = 0; // GL_PROGRAM_PIPELINE_BINDING
|
||||||
} draw;
|
} draw;
|
||||||
|
|
||||||
GLuint renderbuffer{}; // GL_RENDERBUFFER_BINDING
|
|
||||||
|
|
||||||
OpenGLState();
|
OpenGLState();
|
||||||
|
|
||||||
/// Get the currently active OpenGL state
|
/// Get the currently active OpenGL state
|
||||||
|
@ -32,16 +28,12 @@ public:
|
||||||
/// Apply this state as the current OpenGL state
|
/// Apply this state as the current OpenGL state
|
||||||
void Apply();
|
void Apply();
|
||||||
|
|
||||||
void ApplyFramebufferState();
|
|
||||||
void ApplyShaderProgram();
|
void ApplyShaderProgram();
|
||||||
void ApplyProgramPipeline();
|
void ApplyProgramPipeline();
|
||||||
void ApplyRenderBuffer();
|
|
||||||
|
|
||||||
/// Resets any references to the given resource
|
/// Resets any references to the given resource
|
||||||
OpenGLState& ResetProgram(GLuint handle);
|
OpenGLState& ResetProgram(GLuint handle);
|
||||||
OpenGLState& ResetPipeline(GLuint handle);
|
OpenGLState& ResetPipeline(GLuint handle);
|
||||||
OpenGLState& ResetFramebuffer(GLuint handle);
|
|
||||||
OpenGLState& ResetRenderbuffer(GLuint handle);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static OpenGLState cur_state;
|
static OpenGLState cur_state;
|
||||||
|
|
|
@ -515,14 +515,8 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
|
||||||
const Tegra::Engines::Fermi2D::Config& copy_config) {
|
const Tegra::Engines::Fermi2D::Config& copy_config) {
|
||||||
const auto& src_params{src_view->GetSurfaceParams()};
|
const auto& src_params{src_view->GetSurfaceParams()};
|
||||||
const auto& dst_params{dst_view->GetSurfaceParams()};
|
const auto& dst_params{dst_view->GetSurfaceParams()};
|
||||||
|
UNIMPLEMENTED_IF(src_params.target == SurfaceTarget::Texture3D);
|
||||||
OpenGLState prev_state{OpenGLState::GetCurState()};
|
UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
|
||||||
SCOPE_EXIT({ prev_state.Apply(); });
|
|
||||||
|
|
||||||
OpenGLState state;
|
|
||||||
state.draw.read_framebuffer = src_framebuffer.handle;
|
|
||||||
state.draw.draw_framebuffer = dst_framebuffer.handle;
|
|
||||||
state.Apply();
|
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
if (dst_params.srgb_conversion) {
|
if (dst_params.srgb_conversion) {
|
||||||
|
@ -538,11 +532,10 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
|
||||||
glDisablei(GL_BLEND, 0);
|
glDisablei(GL_BLEND, 0);
|
||||||
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
|
||||||
|
|
||||||
u32 buffers{};
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, src_framebuffer.handle);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_framebuffer.handle);
|
||||||
UNIMPLEMENTED_IF(src_params.target == SurfaceTarget::Texture3D);
|
|
||||||
UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
|
|
||||||
|
|
||||||
|
GLenum buffers = 0;
|
||||||
if (src_params.type == SurfaceType::ColorTexture) {
|
if (src_params.type == SurfaceType::ColorTexture) {
|
||||||
src_view->Attach(GL_COLOR_ATTACHMENT0, GL_READ_FRAMEBUFFER);
|
src_view->Attach(GL_COLOR_ATTACHMENT0, GL_READ_FRAMEBUFFER);
|
||||||
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0,
|
||||||
|
|
|
@ -86,28 +86,22 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReloadRenderFrame(Frame* frame, u32 width, u32 height) {
|
void ReloadRenderFrame(Frame* frame, u32 width, u32 height) {
|
||||||
OpenGLState prev_state = OpenGLState::GetCurState();
|
|
||||||
OpenGLState state = OpenGLState::GetCurState();
|
|
||||||
|
|
||||||
// Recreate the color texture attachment
|
// Recreate the color texture attachment
|
||||||
frame->color.Release();
|
frame->color.Release();
|
||||||
frame->color.Create();
|
frame->color.Create();
|
||||||
state.renderbuffer = frame->color.handle;
|
const GLenum internal_format = frame->is_srgb ? GL_SRGB8 : GL_RGB8;
|
||||||
state.Apply();
|
glNamedRenderbufferStorage(frame->color.handle, internal_format, width, height);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, frame->is_srgb ? GL_SRGB8 : GL_RGB8, width, height);
|
|
||||||
|
|
||||||
// Recreate the FBO for the render target
|
// Recreate the FBO for the render target
|
||||||
frame->render.Release();
|
frame->render.Release();
|
||||||
frame->render.Create();
|
frame->render.Create();
|
||||||
state.draw.read_framebuffer = frame->render.handle;
|
glBindFramebuffer(GL_FRAMEBUFFER, frame->render.handle);
|
||||||
state.draw.draw_framebuffer = frame->render.handle;
|
|
||||||
state.Apply();
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
|
||||||
frame->color.handle);
|
frame->color.handle);
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
LOG_CRITICAL(Render_OpenGL, "Failed to recreate render FBO!");
|
LOG_CRITICAL(Render_OpenGL, "Failed to recreate render FBO!");
|
||||||
}
|
}
|
||||||
prev_state.Apply();
|
|
||||||
frame->width = width;
|
frame->width = width;
|
||||||
frame->height = height;
|
frame->height = height;
|
||||||
frame->color_reloaded = true;
|
frame->color_reloaded = true;
|
||||||
|
@ -353,8 +347,7 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
|
||||||
frame->is_srgb = screen_info.display_srgb;
|
frame->is_srgb = screen_info.display_srgb;
|
||||||
frame_mailbox->ReloadRenderFrame(frame, layout.width, layout.height);
|
frame_mailbox->ReloadRenderFrame(frame, layout.width, layout.height);
|
||||||
}
|
}
|
||||||
state.draw.draw_framebuffer = frame->render.handle;
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frame->render.handle);
|
||||||
state.Apply();
|
|
||||||
DrawScreen(layout);
|
DrawScreen(layout);
|
||||||
// Create a fence for the frontend to wait on and swap this frame to OffTex
|
// Create a fence for the frontend to wait on and swap this frame to OffTex
|
||||||
frame->render_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
frame->render_fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||||
|
@ -647,12 +640,14 @@ void RendererOpenGL::RenderScreenshot() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLint old_read_fb;
|
||||||
|
GLint old_draw_fb;
|
||||||
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fb);
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb);
|
||||||
|
|
||||||
// Draw the current frame to the screenshot framebuffer
|
// Draw the current frame to the screenshot framebuffer
|
||||||
screenshot_framebuffer.Create();
|
screenshot_framebuffer.Create();
|
||||||
GLuint old_read_fb = state.draw.read_framebuffer;
|
glBindFramebuffer(GL_FRAMEBUFFER, screenshot_framebuffer.handle);
|
||||||
GLuint old_draw_fb = state.draw.draw_framebuffer;
|
|
||||||
state.draw.read_framebuffer = state.draw.draw_framebuffer = screenshot_framebuffer.handle;
|
|
||||||
state.Apply();
|
|
||||||
|
|
||||||
Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
|
Layout::FramebufferLayout layout{renderer_settings.screenshot_framebuffer_layout};
|
||||||
|
|
||||||
|
@ -669,11 +664,11 @@ void RendererOpenGL::RenderScreenshot() {
|
||||||
renderer_settings.screenshot_bits);
|
renderer_settings.screenshot_bits);
|
||||||
|
|
||||||
screenshot_framebuffer.Release();
|
screenshot_framebuffer.Release();
|
||||||
state.draw.read_framebuffer = old_read_fb;
|
|
||||||
state.draw.draw_framebuffer = old_draw_fb;
|
|
||||||
state.Apply();
|
|
||||||
glDeleteRenderbuffers(1, &renderbuffer);
|
glDeleteRenderbuffers(1, &renderbuffer);
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb);
|
||||||
|
|
||||||
renderer_settings.screenshot_complete_callback();
|
renderer_settings.screenshot_complete_callback();
|
||||||
renderer_settings.screenshot_requested = false;
|
renderer_settings.screenshot_requested = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue