mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 07:20:15 +00:00
Fixup: all-state resets
This commit is contained in:
parent
6c42c2cd72
commit
e2c74e8ea5
@ -2,15 +2,18 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <set>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
|
||||||
#include "video_core/renderer_opengl/gl_state.h"
|
#include "video_core/renderer_opengl/gl_state.h"
|
||||||
|
|
||||||
static OpenGLState default_state;
|
std::set<OpenGLState*> states;
|
||||||
OpenGLState* OpenGLState::cur_state = &default_state;
|
OpenGLState default_state;
|
||||||
|
OpenGLState* cur_state = &default_state;
|
||||||
|
|
||||||
OpenGLState::OpenGLState() {
|
OpenGLState::OpenGLState() {
|
||||||
// These all match default OpenGL values
|
// These all match default OpenGL values
|
||||||
@ -62,6 +65,12 @@ OpenGLState::OpenGLState() {
|
|||||||
draw.vertex_buffer = 0;
|
draw.vertex_buffer = 0;
|
||||||
draw.uniform_buffer = 0;
|
draw.uniform_buffer = 0;
|
||||||
draw.shader_program = 0;
|
draw.shader_program = 0;
|
||||||
|
|
||||||
|
states.insert(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGLState::~OpenGLState() {
|
||||||
|
states.erase(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLState* OpenGLState::GetCurrentState() {
|
OpenGLState* OpenGLState::GetCurrentState() {
|
||||||
@ -94,12 +103,16 @@ void OpenGLState::MakeCurrent() {
|
|||||||
|
|
||||||
SetLogicOp(logic_op);
|
SetLogicOp(logic_op);
|
||||||
|
|
||||||
|
GLenum prev_active_texture_unit = active_texture_unit;
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
||||||
SetActiveTextureUnit(GL_TEXTURE0 + i);
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
active_texture_unit = GL_TEXTURE0 + i;
|
||||||
SetTexture1D(texture_units[i].texture_1d);
|
SetTexture1D(texture_units[i].texture_1d);
|
||||||
SetTexture2D(texture_units[i].texture_2d);
|
SetTexture2D(texture_units[i].texture_2d);
|
||||||
SetSampler(texture_units[i].sampler);
|
SetSampler(texture_units[i].sampler);
|
||||||
}
|
}
|
||||||
|
active_texture_unit = prev_active_texture_unit;
|
||||||
|
glActiveTexture(cur_state->active_texture_unit);
|
||||||
|
|
||||||
SetActiveTextureUnit(active_texture_unit);
|
SetActiveTextureUnit(active_texture_unit);
|
||||||
|
|
||||||
@ -347,61 +360,111 @@ void OpenGLState::SetShaderProgram(GLuint n_shader_program) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetTexture(GLuint handle) {
|
void OpenGLState::ResetTexture(GLuint handle) {
|
||||||
|
for (OpenGLState* state : states) {
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
||||||
if (cur_state->texture_units[i].texture_1d == handle) {
|
if (state->texture_units[i].texture_1d == handle) {
|
||||||
GLenum prev_active_texture_unit = cur_state->active_texture_unit;
|
if (state == cur_state) {
|
||||||
cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
GLenum prev_active_texture_unit = state->active_texture_unit;
|
||||||
cur_state->SetTexture1D(0);
|
state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
||||||
cur_state->SetActiveTextureUnit(prev_active_texture_unit);
|
state->SetTexture1D(0);
|
||||||
|
state->SetActiveTextureUnit(prev_active_texture_unit);
|
||||||
|
} else {
|
||||||
|
state->texture_units[i].texture_1d = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur_state->texture_units[i].texture_2d == handle) {
|
if (state->texture_units[i].texture_2d == handle) {
|
||||||
GLenum prev_active_texture_unit = cur_state->active_texture_unit;
|
if (state == cur_state) {
|
||||||
cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
GLenum prev_active_texture_unit = state->active_texture_unit;
|
||||||
cur_state->SetTexture2D(0);
|
state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
||||||
cur_state->SetActiveTextureUnit(prev_active_texture_unit);
|
state->SetTexture2D(0);
|
||||||
|
state->SetActiveTextureUnit(prev_active_texture_unit);
|
||||||
|
} else {
|
||||||
|
state->texture_units[i].texture_2d = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetSampler(GLuint handle) {
|
void OpenGLState::ResetSampler(GLuint handle) {
|
||||||
|
for (OpenGLState* state : states) {
|
||||||
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
||||||
if (cur_state->texture_units[i].sampler == handle) {
|
if (state->texture_units[i].sampler == handle) {
|
||||||
GLenum prev_active_texture_unit = cur_state->active_texture_unit;
|
if (state == cur_state) {
|
||||||
cur_state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
GLenum prev_active_texture_unit = state->active_texture_unit;
|
||||||
cur_state->SetSampler(0);
|
state->SetActiveTextureUnit(GL_TEXTURE0 + i);
|
||||||
cur_state->SetActiveTextureUnit(prev_active_texture_unit);
|
state->SetSampler(0);
|
||||||
|
state->SetActiveTextureUnit(prev_active_texture_unit);
|
||||||
|
} else {
|
||||||
|
state->texture_units[i].sampler = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetProgram(GLuint handle) {
|
void OpenGLState::ResetProgram(GLuint handle) {
|
||||||
if (cur_state->draw.shader_program == handle) {
|
for (OpenGLState* state : states) {
|
||||||
cur_state->SetShaderProgram(0);
|
if (state->draw.shader_program == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetShaderProgram(0);
|
||||||
|
} else {
|
||||||
|
state->draw.shader_program = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetBuffer(GLuint handle) {
|
void OpenGLState::ResetBuffer(GLuint handle) {
|
||||||
if (cur_state->draw.vertex_buffer == handle) {
|
for (OpenGLState* state : states) {
|
||||||
cur_state->SetVertexBuffer(0);
|
if (state->draw.vertex_buffer == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetVertexBuffer(0);
|
||||||
|
} else {
|
||||||
|
state->draw.vertex_buffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->draw.uniform_buffer == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetUniformBuffer(0);
|
||||||
|
} else {
|
||||||
|
state->draw.uniform_buffer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cur_state->draw.uniform_buffer == handle) {
|
|
||||||
cur_state->SetUniformBuffer(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetVertexArray(GLuint handle) {
|
void OpenGLState::ResetVertexArray(GLuint handle) {
|
||||||
if (cur_state->draw.vertex_array == handle) {
|
for (OpenGLState* state : states) {
|
||||||
cur_state->SetVertexArray(0);
|
if (state->draw.vertex_array == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetVertexArray(0);
|
||||||
|
} else {
|
||||||
|
state->draw.vertex_array = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLState::ResetFramebuffer(GLuint handle) {
|
void OpenGLState::ResetFramebuffer(GLuint handle) {
|
||||||
if (cur_state->draw.read_framebuffer == handle) {
|
for (OpenGLState* state : states) {
|
||||||
cur_state->SetReadFramebuffer(0);
|
if (state->draw.read_framebuffer == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetReadFramebuffer(0);
|
||||||
|
} else {
|
||||||
|
state->draw.read_framebuffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->draw.draw_framebuffer == handle) {
|
||||||
|
if (state == cur_state) {
|
||||||
|
state->SetDrawFramebuffer(0);
|
||||||
|
} else {
|
||||||
|
state->draw.draw_framebuffer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cur_state->draw.draw_framebuffer == handle) {
|
|
||||||
cur_state->SetDrawFramebuffer(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
class OpenGLState {
|
class OpenGLState {
|
||||||
public:
|
public:
|
||||||
OpenGLState();
|
OpenGLState();
|
||||||
|
~OpenGLState();
|
||||||
|
|
||||||
/// Get a pointer to the currently bound state tracker object
|
/// Get a pointer to the currently bound state tracker object
|
||||||
static OpenGLState* GetCurrentState();
|
static OpenGLState* GetCurrentState();
|
||||||
@ -51,7 +52,7 @@ public:
|
|||||||
void SetUniformBuffer(GLuint n_uniform_buffer);
|
void SetUniformBuffer(GLuint n_uniform_buffer);
|
||||||
void SetShaderProgram(GLuint n_shader_program);
|
void SetShaderProgram(GLuint n_shader_program);
|
||||||
|
|
||||||
/// Resets and unbinds any references to the given resource in the current OpenGL state
|
/// Resets and unbinds any references to the given resource across all existing states
|
||||||
static void ResetTexture(GLuint handle);
|
static void ResetTexture(GLuint handle);
|
||||||
static void ResetSampler(GLuint handle);
|
static void ResetSampler(GLuint handle);
|
||||||
static void ResetProgram(GLuint handle);
|
static void ResetProgram(GLuint handle);
|
||||||
@ -127,6 +128,4 @@ private:
|
|||||||
GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING
|
GLuint uniform_buffer; // GL_UNIFORM_BUFFER_BINDING
|
||||||
GLuint shader_program; // GL_CURRENT_PROGRAM
|
GLuint shader_program; // GL_CURRENT_PROGRAM
|
||||||
} draw;
|
} draw;
|
||||||
|
|
||||||
static OpenGLState* cur_state;
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user