forked from suyu/suyu
Merge pull request #1023 from yuriks/gl-state-bugs
OpenGL: Fix state tracking in situations with reused object handles
This commit is contained in:
commit
93f607f549
6 changed files with 48 additions and 26 deletions
|
@ -99,7 +99,6 @@ void RasterizerOpenGL::InitObjects() {
|
||||||
fb_color_texture.texture.Create();
|
fb_color_texture.texture.Create();
|
||||||
ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1);
|
ReconfigureColorTexture(fb_color_texture, Pica::Regs::ColorFormat::RGBA8, 1, 1);
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -115,7 +114,6 @@ void RasterizerOpenGL::InitObjects() {
|
||||||
fb_depth_texture.texture.Create();
|
fb_depth_texture.texture.Create();
|
||||||
ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
|
ReconfigureDepthTexture(fb_depth_texture, Pica::Regs::DepthFormat::D16, 1, 1);
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -493,7 +491,6 @@ void RasterizerOpenGL::ReconfigureColorTexture(TextureInfo& texture, Pica::Regs:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.texture.handle;
|
state.texture_units[0].texture_2d = texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -537,7 +534,6 @@ void RasterizerOpenGL::ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.texture.handle;
|
state.texture_units[0].texture_2d = texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -766,10 +762,9 @@ void RasterizerOpenGL::SyncDrawState() {
|
||||||
const auto& texture = pica_textures[texture_index];
|
const auto& texture = pica_textures[texture_index];
|
||||||
|
|
||||||
if (texture.enabled) {
|
if (texture.enabled) {
|
||||||
state.texture_units[texture_index].enabled_2d = true;
|
|
||||||
res_cache.LoadAndBindTexture(state, texture_index, texture);
|
res_cache.LoadAndBindTexture(state, texture_index, texture);
|
||||||
} else {
|
} else {
|
||||||
state.texture_units[texture_index].enabled_2d = false;
|
state.texture_units[texture_index].texture_2d = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,7 +799,6 @@ void RasterizerOpenGL::ReloadColorBuffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -862,7 +856,6 @@ void RasterizerOpenGL::ReloadDepthBuffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -887,7 +880,6 @@ void RasterizerOpenGL::CommitColorBuffer() {
|
||||||
|
|
||||||
std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
std::unique_ptr<u8[]> temp_gl_color_buffer(new u8[fb_color_texture.width * fb_color_texture.height * bytes_per_pixel]);
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_color_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -927,7 +919,6 @@ void RasterizerOpenGL::CommitDepthBuffer() {
|
||||||
|
|
||||||
std::unique_ptr<u8[]> temp_gl_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]);
|
std::unique_ptr<u8[]> temp_gl_depth_buffer(new u8[fb_depth_texture.width * fb_depth_texture.height * gl_bpp]);
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
state.texture_units[0].texture_2d = fb_depth_texture.texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ void RasterizerCacheOpenGL::LoadAndBindTexture(OpenGLState &state, unsigned text
|
||||||
new_texture->texture.Create();
|
new_texture->texture.Create();
|
||||||
state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
|
state.texture_units[texture_unit].texture_2d = new_texture->texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
glActiveTexture(GL_TEXTURE0 + texture_unit);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, PicaToGL::TextureFilterMode(config.config.mag_filter));
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter));
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, PicaToGL::TextureFilterMode(config.config.min_filter));
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include "video_core/renderer_opengl/generated/gl_3_2_core.h"
|
#include "video_core/renderer_opengl/generated/gl_3_2_core.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_util.h"
|
#include "video_core/renderer_opengl/gl_shader_util.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state.h"
|
||||||
|
|
||||||
class OGLTexture : private NonCopyable {
|
class OGLTexture : private NonCopyable {
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +29,7 @@ public:
|
||||||
void Release() {
|
void Release() {
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
glDeleteTextures(1, &handle);
|
glDeleteTextures(1, &handle);
|
||||||
|
OpenGLState::ResetTexture(handle);
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,6 +53,7 @@ public:
|
||||||
void Release() {
|
void Release() {
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
glDeleteProgram(handle);
|
glDeleteProgram(handle);
|
||||||
|
OpenGLState::ResetProgram(handle);
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +77,7 @@ public:
|
||||||
void Release() {
|
void Release() {
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
glDeleteBuffers(1, &handle);
|
glDeleteBuffers(1, &handle);
|
||||||
|
OpenGLState::ResetBuffer(handle);
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +101,7 @@ public:
|
||||||
void Release() {
|
void Release() {
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
glDeleteVertexArrays(1, &handle);
|
glDeleteVertexArrays(1, &handle);
|
||||||
|
OpenGLState::ResetVertexArray(handle);
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +125,7 @@ public:
|
||||||
void Release() {
|
void Release() {
|
||||||
if (handle == 0) return;
|
if (handle == 0) return;
|
||||||
glDeleteFramebuffers(1, &handle);
|
glDeleteFramebuffers(1, &handle);
|
||||||
|
OpenGLState::ResetFramebuffer(handle);
|
||||||
handle = 0;
|
handle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,6 @@ OpenGLState::OpenGLState() {
|
||||||
logic_op = GL_COPY;
|
logic_op = GL_COPY;
|
||||||
|
|
||||||
for (auto& texture_unit : texture_units) {
|
for (auto& texture_unit : texture_units) {
|
||||||
texture_unit.enabled_2d = false;
|
|
||||||
texture_unit.texture_2d = 0;
|
texture_unit.texture_2d = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,16 +146,9 @@ void OpenGLState::Apply() {
|
||||||
|
|
||||||
// Textures
|
// Textures
|
||||||
for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
|
for (unsigned texture_index = 0; texture_index < ARRAY_SIZE(texture_units); ++texture_index) {
|
||||||
if (texture_units[texture_index].enabled_2d != cur_state.texture_units[texture_index].enabled_2d ||
|
if (texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
|
||||||
texture_units[texture_index].texture_2d != cur_state.texture_units[texture_index].texture_2d) {
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + texture_index);
|
glActiveTexture(GL_TEXTURE0 + texture_index);
|
||||||
|
|
||||||
if (texture_units[texture_index].enabled_2d) {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
|
glBindTexture(GL_TEXTURE_2D, texture_units[texture_index].texture_2d);
|
||||||
} else {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,3 +174,35 @@ void OpenGLState::Apply() {
|
||||||
|
|
||||||
cur_state = *this;
|
cur_state = *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLState::ResetTexture(GLuint id) {
|
||||||
|
for (auto& unit : cur_state.texture_units) {
|
||||||
|
if (unit.texture_2d == id) {
|
||||||
|
unit.texture_2d = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLState::ResetProgram(GLuint id) {
|
||||||
|
if (cur_state.draw.shader_program == id) {
|
||||||
|
cur_state.draw.shader_program = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLState::ResetBuffer(GLuint id) {
|
||||||
|
if (cur_state.draw.vertex_buffer == id) {
|
||||||
|
cur_state.draw.vertex_buffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLState::ResetVertexArray(GLuint id) {
|
||||||
|
if (cur_state.draw.vertex_array == id) {
|
||||||
|
cur_state.draw.vertex_array = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLState::ResetFramebuffer(GLuint id) {
|
||||||
|
if (cur_state.draw.framebuffer == id) {
|
||||||
|
cur_state.draw.framebuffer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -53,7 +53,6 @@ public:
|
||||||
|
|
||||||
// 3 texture units - one for each that is used in PICA fragment shader emulation
|
// 3 texture units - one for each that is used in PICA fragment shader emulation
|
||||||
struct {
|
struct {
|
||||||
bool enabled_2d; // GL_TEXTURE_2D
|
|
||||||
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
GLuint texture_2d; // GL_TEXTURE_BINDING_2D
|
||||||
} texture_units[3];
|
} texture_units[3];
|
||||||
|
|
||||||
|
@ -74,6 +73,12 @@ public:
|
||||||
/// Apply this state as the current OpenGL state
|
/// Apply this state as the current OpenGL state
|
||||||
void Apply();
|
void Apply();
|
||||||
|
|
||||||
|
static void ResetTexture(GLuint id);
|
||||||
|
static void ResetProgram(GLuint id);
|
||||||
|
static void ResetBuffer(GLuint id);
|
||||||
|
static void ResetVertexArray(GLuint id);
|
||||||
|
static void ResetFramebuffer(GLuint id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static OpenGLState cur_state;
|
static OpenGLState cur_state;
|
||||||
};
|
};
|
||||||
|
|
|
@ -163,7 +163,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
|
||||||
// only allows rows to have a memory alignement of 4.
|
// only allows rows to have a memory alignement of 4.
|
||||||
ASSERT(pixel_stride % 4 == 0);
|
ASSERT(pixel_stride % 4 == 0);
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.handle;
|
state.texture_units[0].texture_2d = texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -191,7 +190,6 @@ void RendererOpenGL::LoadFBToActiveGLTexture(const GPU::Regs::FramebufferConfig&
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
|
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b,
|
||||||
const TextureInfo& texture) {
|
const TextureInfo& texture) {
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.handle;
|
state.texture_units[0].texture_2d = texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -239,7 +237,6 @@ void RendererOpenGL::InitOpenGLObjects() {
|
||||||
// Allocation of storage is deferred until the first frame, when we
|
// Allocation of storage is deferred until the first frame, when we
|
||||||
// know the framebuffer size.
|
// know the framebuffer size.
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.handle;
|
state.texture_units[0].texture_2d = texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -305,7 +302,6 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.handle;
|
state.texture_units[0].texture_2d = texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
@ -325,7 +321,6 @@ void RendererOpenGL::DrawSingleScreenRotated(const TextureInfo& texture, float x
|
||||||
ScreenRectVertex(x+w, y+h, 0.f, 1.f),
|
ScreenRectVertex(x+w, y+h, 0.f, 1.f),
|
||||||
};
|
};
|
||||||
|
|
||||||
state.texture_units[0].enabled_2d = true;
|
|
||||||
state.texture_units[0].texture_2d = texture.handle;
|
state.texture_units[0].texture_2d = texture.handle;
|
||||||
state.Apply();
|
state.Apply();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue