Fixup: + getters, - redundant makecurrents/trackers

This commit is contained in:
tfarley 2016-05-02 20:02:30 -04:00
parent e2c74e8ea5
commit d7cc5bdcc1
7 changed files with 170 additions and 97 deletions

View file

@ -149,8 +149,6 @@ void RasterizerOpenGL::DrawTriangles() {
if (vertex_batch.empty())
return;
state.MakeCurrent();
const auto& regs = Pica::g_state.regs;
// Sync and bind the framebuffer surfaces
@ -247,8 +245,6 @@ void RasterizerOpenGL::DrawTriangles() {
void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) {
const auto& regs = Pica::g_state.regs;
state.MakeCurrent();
switch(id) {
// Culling
case PICA_REG_INDEX(cull_mode):
@ -612,17 +608,15 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
SurfaceType dst_type = CachedSurface::GetFormatType(dst_surface->pixel_format);
OpenGLState* old_state = OpenGLState::GetCurrentState();
utility_state.MakeCurrent();
utility_state.SetDrawFramebuffer(framebuffer.handle);
OpenGLState* cur_state = OpenGLState::GetCurrentState();
OpenGLState old_state = OpenGLState::ApplyTransferState(0, cur_state->GetReadFramebuffer(), dst_surface->texture.handle, framebuffer.handle);
if (dst_type == SurfaceType::Color || dst_type == SurfaceType::Texture) {
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dst_surface->texture.handle, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
@ -640,7 +634,7 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
color_values[2] = config.value_24bit_b / 255.0f;
break;
default:
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
} else if (config.fill_32bit) {
@ -654,7 +648,7 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
color_values[3] = (value & 0xFF) / 255.0f;
break;
default:
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
} else {
@ -694,12 +688,11 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
color_values[1] = (value_16bit & 0xFF) / 255.0f;
break;
default:
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
}
utility_state.SetColorMask(true, true, true, true);
glClearBufferfv(GL_COLOR, 0, color_values);
} else if (dst_type == SurfaceType::Depth) {
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
@ -707,7 +700,7 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
@ -718,26 +711,23 @@ bool RasterizerOpenGL::AccelerateFill(const GPU::Regs::MemoryFillConfig& config)
value_float = config.value_32bit / 16777215.0f; // 2^24 - 1
}
utility_state.SetDepthWriteMask(true);
glClearBufferfv(GL_DEPTH, 0, &value_float);
} else if (dst_type == SurfaceType::DepthStencil) {
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dst_surface->texture.handle, 0);
if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
GLfloat value_float = (config.value_32bit & 0xFFFFFF) / 16777215.0f; // 2^24 - 1
GLint value_int = (config.value_32bit >> 24);
utility_state.SetDepthWriteMask(true);
utility_state.SetStencilWriteMask(true);
glClearBufferfi(GL_DEPTH_STENCIL, 0, value_float, value_int);
}
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
dst_surface->dirty = true;
res_cache.FlushRegion(dst_surface->addr, dst_surface->size, dst_surface, true);
@ -821,8 +811,6 @@ void RasterizerOpenGL::SetShader() {
PicaShaderConfig config = PicaShaderConfig::CurrentConfig();
std::unique_ptr<PicaShader> shader = std::make_unique<PicaShader>();
state.MakeCurrent();
// Find (or generate) the GLSL shader for the current TEV state
auto cached_shader = shader_cache.find(config);
if (cached_shader != shader_cache.end()) {
@ -921,18 +909,20 @@ void RasterizerOpenGL::SyncBlendEnabled() {
void RasterizerOpenGL::SyncBlendFuncs() {
const auto& regs = Pica::g_state.regs;
state.SetBlendFunc(PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb),
state.SetBlendFunc(std::make_tuple<>(
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb),
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_rgb),
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_a),
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_a));
PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_a)));
}
void RasterizerOpenGL::SyncBlendColor() {
auto blend_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.output_merger.blend_const.raw);
state.SetBlendColor(blend_color[0],
state.SetBlendColor(std::make_tuple<>(
blend_color[0],
blend_color[1],
blend_color[2],
blend_color[3]);
blend_color[3]));
}
void RasterizerOpenGL::SyncAlphaTest() {
@ -954,10 +944,11 @@ void RasterizerOpenGL::SyncColorWriteMask() {
return (regs.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE : GL_FALSE;
};
state.SetColorMask(IsColorWriteEnabled(regs.output_merger.red_enable),
state.SetColorMask(std::make_tuple<>(
IsColorWriteEnabled(regs.output_merger.red_enable),
IsColorWriteEnabled(regs.output_merger.green_enable),
IsColorWriteEnabled(regs.output_merger.blue_enable),
IsColorWriteEnabled(regs.output_merger.alpha_enable));
IsColorWriteEnabled(regs.output_merger.alpha_enable)));
}
void RasterizerOpenGL::SyncStencilWriteMask() {
@ -977,12 +968,14 @@ void RasterizerOpenGL::SyncDepthWriteMask() {
void RasterizerOpenGL::SyncStencilTest() {
const auto& regs = Pica::g_state.regs;
state.SetStencilTestEnabled(regs.output_merger.stencil_test.enable && regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8);
state.SetStencilFunc(PicaToGL::CompareFunc(regs.output_merger.stencil_test.func),
state.SetStencilFunc(std::make_tuple<>(
PicaToGL::CompareFunc(regs.output_merger.stencil_test.func),
regs.output_merger.stencil_test.reference_value,
regs.output_merger.stencil_test.input_mask);
state.SetStencilOp(PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail),
regs.output_merger.stencil_test.input_mask));
state.SetStencilOp(std::make_tuple<>(
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail),
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail),
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass));
PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass)));
}
void RasterizerOpenGL::SyncDepthTest() {

View file

@ -351,7 +351,6 @@ private:
void SyncLightPosition(int light_index);
OpenGLState state;
OpenGLState utility_state;
RasterizerCacheOpenGL res_cache;

View file

@ -105,15 +105,7 @@ static void MortonCopyPixels(CachedSurface::PixelFormat pixel_format, u32 width,
bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedSurface::SurfaceType type, const MathUtil::Rectangle<int>& src_rect, const MathUtil::Rectangle<int>& dst_rect) {
using SurfaceType = CachedSurface::SurfaceType;
OpenGLState* old_state = OpenGLState::GetCurrentState();
utility_state.MakeCurrent();
// Make sure textures aren't bound to texture units, since going to bind them to framebuffer components
OpenGLState::ResetTexture(src_tex);
OpenGLState::ResetTexture(dst_tex);
utility_state.SetReadFramebuffer(transfer_framebuffers[0].handle);
utility_state.SetDrawFramebuffer(transfer_framebuffers[1].handle);
OpenGLState old_state = OpenGLState::ApplyTransferState(src_tex, transfer_framebuffers[0].handle, dst_tex, transfer_framebuffers[1].handle);
u32 buffers = 0;
@ -146,12 +138,12 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
}
if (OpenGLState::CheckBoundFBStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
if (OpenGLState::CheckBoundFBStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return false;
}
@ -159,7 +151,7 @@ bool RasterizerCacheOpenGL::BlitTextures(GLuint src_tex, GLuint dst_tex, CachedS
dst_rect.left, dst_rect.top, dst_rect.right, dst_rect.bottom,
buffers, buffers == GL_COLOR_BUFFER_BIT ? GL_LINEAR : GL_NEAREST);
old_state->MakeCurrent();
OpenGLState::UndoTransferState(old_state);
return true;
}
@ -178,11 +170,11 @@ void RasterizerCacheOpenGL::AllocateSurfaceTexture(GLuint texture, CachedSurface
// Allocate an uninitialized texture of appropriate size and format for the surface
using SurfaceType = CachedSurface::SurfaceType;
OpenGLState* old_state = OpenGLState::GetCurrentState();
utility_state.MakeCurrent();
utility_state.SetActiveTextureUnit(GL_TEXTURE0);
utility_state.SetTexture2D(texture);
OpenGLState* cur_state = OpenGLState::GetCurrentState();
GLenum old_active_texture = cur_state->GetActiveTextureUnit();
cur_state->SetActiveTextureUnit(GL_TEXTURE0);
GLuint old_texture = cur_state->GetTexture2D();
cur_state->SetTexture2D(texture);
SurfaceType type = CachedSurface::GetFormatType(pixel_format);
@ -206,7 +198,8 @@ void RasterizerCacheOpenGL::AllocateSurfaceTexture(GLuint texture, CachedSurface
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
old_state->MakeCurrent();
cur_state->SetTexture2D(old_texture);
cur_state->SetActiveTextureUnit(old_active_texture);
}
MICROPROFILE_DEFINE(OpenGL_SurfaceUpload, "OpenGL", "Surface Upload", MP_RGB(128, 64, 192));
@ -288,11 +281,11 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
Memory::RasterizerFlushRegion(params.addr, params_size);
// Load data from memory to the new surface
OpenGLState* old_state = OpenGLState::GetCurrentState();
utility_state.MakeCurrent();
utility_state.SetActiveTextureUnit(GL_TEXTURE0);
utility_state.SetTexture2D(new_surface->texture.handle);
OpenGLState* cur_state = OpenGLState::GetCurrentState();
GLenum old_active_texture = cur_state->GetActiveTextureUnit();
cur_state->SetActiveTextureUnit(GL_TEXTURE0);
GLuint old_texture = cur_state->GetTexture2D();
cur_state->SetTexture2D(new_surface->texture.handle);
glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)new_surface->stride);
if (!new_surface->is_tiled) {
@ -374,7 +367,8 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
old_state->MakeCurrent();
cur_state->SetTexture2D(old_texture);
cur_state->SetActiveTextureUnit(old_active_texture);
}
Memory::RasterizerMarkRegionCached(new_surface->addr, new_surface->size, 1);
@ -596,9 +590,6 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
return;
}
OpenGLState* old_state = OpenGLState::GetCurrentState();
utility_state.MakeCurrent();
OGLTexture unscaled_tex;
GLuint texture_to_flush = surface->texture.handle;
@ -614,8 +605,11 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
texture_to_flush = unscaled_tex.handle;
}
utility_state.SetActiveTextureUnit(GL_TEXTURE0);
utility_state.SetTexture2D(texture_to_flush);
OpenGLState* cur_state = OpenGLState::GetCurrentState();
GLenum old_active_texture = cur_state->GetActiveTextureUnit();
cur_state->SetActiveTextureUnit(GL_TEXTURE0);
GLuint old_texture = cur_state->GetTexture2D();
cur_state->SetTexture2D(texture_to_flush);
glPixelStorei(GL_PACK_ROW_LENGTH, (GLint)surface->stride);
if (!surface->is_tiled) {
@ -664,7 +658,8 @@ void RasterizerCacheOpenGL::FlushSurface(CachedSurface* surface) {
surface->dirty = false;
old_state->MakeCurrent();
cur_state->SetTexture2D(old_texture);
cur_state->SetActiveTextureUnit(old_active_texture);
}
void RasterizerCacheOpenGL::FlushRegion(PAddr addr, u32 size, const CachedSurface* skip_surface, bool invalidate) {

View file

@ -219,8 +219,6 @@ public:
private:
void AllocateSurfaceTexture(GLuint texture, CachedSurface::PixelFormat pixel_format, u32 width, u32 height);
OpenGLState utility_state;
SurfaceCache surface_cache;
OGLFramebuffer transfer_framebuffers[2];
};

View file

@ -82,26 +82,26 @@ void OpenGLState::MakeCurrent() {
return;
}
SetCullEnabled(cull.enabled);
SetCullMode(cull.mode);
SetCullFrontFace(cull.front_face);
SetCullEnabled(GetCullEnabled());
SetCullMode(GetCullMode());
SetCullFrontFace(GetCullFrontFace());
SetDepthTestEnabled(depth.test_enabled);
SetDepthFunc(depth.test_func);
SetDepthWriteMask(depth.write_mask);
SetDepthTestEnabled(GetDepthTestEnabled());
SetDepthFunc(GetDepthFunc());
SetDepthWriteMask(GetDepthWriteMask());
SetColorMask(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled);
SetColorMask(GetColorMask());
SetStencilTestEnabled(stencil.test_enabled);
SetStencilFunc(stencil.test_func, stencil.test_ref, stencil.test_mask);
SetStencilOp(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass);
SetStencilWriteMask(stencil.write_mask);
SetStencilTestEnabled(GetStencilTestEnabled());
SetStencilFunc(GetStencilFunc());
SetStencilOp(GetStencilOp());
SetStencilWriteMask(GetStencilWriteMask());
SetBlendEnabled(blend.enabled);
SetBlendFunc(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func);
SetBlendColor(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha);
SetBlendEnabled(GetBlendEnabled());
SetBlendFunc(GetBlendFunc());
SetBlendColor(GetBlendColor());
SetLogicOp(logic_op);
SetLogicOp(GetLogicOp());
GLenum prev_active_texture_unit = active_texture_unit;
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
@ -114,14 +114,14 @@ void OpenGLState::MakeCurrent() {
active_texture_unit = prev_active_texture_unit;
glActiveTexture(cur_state->active_texture_unit);
SetActiveTextureUnit(active_texture_unit);
SetActiveTextureUnit(GetActiveTextureUnit());
SetReadFramebuffer(draw.read_framebuffer);
SetDrawFramebuffer(draw.draw_framebuffer);
SetVertexArray(draw.vertex_array);
SetVertexBuffer(draw.vertex_buffer);
SetUniformBuffer(draw.uniform_buffer);
SetShaderProgram(draw.shader_program);
SetReadFramebuffer(GetReadFramebuffer());
SetDrawFramebuffer(GetDrawFramebuffer());
SetVertexArray(GetVertexArray());
SetVertexBuffer(GetVertexBuffer());
SetUniformBuffer(GetUniformBuffer());
SetShaderProgram(GetShaderProgram());
cur_state = this;
}
@ -176,7 +176,10 @@ void OpenGLState::SetDepthWriteMask(GLboolean n_write_mask) {
depth.write_mask = n_write_mask;
}
void OpenGLState::SetColorMask(GLboolean n_red_enabled, GLboolean n_green_enabled, GLboolean n_blue_enabled, GLboolean n_alpha_enabled) {
void OpenGLState::SetColorMask(std::tuple<GLboolean, GLboolean, GLboolean, GLboolean> n_rgba_enabled) {
GLboolean n_red_enabled, n_green_enabled, n_blue_enabled, n_alpha_enabled;
std::tie(n_red_enabled, n_green_enabled, n_blue_enabled, n_alpha_enabled) = n_rgba_enabled;
if (n_red_enabled != cur_state->color_mask.red_enabled ||
n_green_enabled != cur_state->color_mask.green_enabled ||
n_blue_enabled != cur_state->color_mask.blue_enabled ||
@ -201,7 +204,11 @@ void OpenGLState::SetStencilTestEnabled(bool n_test_enabled) {
stencil.test_enabled = n_test_enabled;
}
void OpenGLState::SetStencilFunc(GLenum n_test_func, GLint n_test_ref, GLuint n_test_mask) {
void OpenGLState::SetStencilFunc(std::tuple<GLenum, GLint, GLint> n_funcs) {
GLenum n_test_func;
GLint n_test_ref, n_test_mask;
std::tie(n_test_func, n_test_ref, n_test_mask) = n_funcs;
if (n_test_func != cur_state->stencil.test_func ||
n_test_ref != cur_state->stencil.test_ref ||
n_test_mask != cur_state->stencil.test_mask) {
@ -212,7 +219,10 @@ void OpenGLState::SetStencilFunc(GLenum n_test_func, GLint n_test_ref, GLuint n_
stencil.test_mask = n_test_mask;
}
void OpenGLState::SetStencilOp(GLenum n_action_stencil_fail, GLenum n_action_depth_fail, GLenum n_action_depth_pass) {
void OpenGLState::SetStencilOp(std::tuple<GLenum, GLenum, GLenum> n_actions) {
GLenum n_action_stencil_fail, n_action_depth_fail, n_action_depth_pass;
std::tie(n_action_stencil_fail, n_action_depth_fail, n_action_depth_pass) = n_actions;
if (n_action_stencil_fail != cur_state->stencil.action_stencil_fail ||
n_action_depth_fail != cur_state->stencil.action_depth_fail ||
n_action_depth_pass != cur_state->stencil.action_depth_pass) {
@ -245,7 +255,10 @@ void OpenGLState::SetBlendEnabled(bool n_enabled) {
blend.enabled = n_enabled;
}
void OpenGLState::SetBlendFunc(GLenum n_src_rgb_func, GLenum n_dst_rgb_func, GLenum n_src_a_func, GLenum n_dst_a_func) {
void OpenGLState::SetBlendFunc(std::tuple<GLenum, GLenum, GLenum, GLenum> n_funcs) {
GLenum n_src_rgb_func, n_dst_rgb_func, n_src_a_func, n_dst_a_func;
std::tie(n_src_rgb_func, n_dst_rgb_func, n_src_a_func, n_dst_a_func) = n_funcs;
if (n_src_rgb_func != cur_state->blend.src_rgb_func ||
n_dst_rgb_func != cur_state->blend.dst_rgb_func ||
n_src_a_func != cur_state->blend.src_a_func ||
@ -259,7 +272,10 @@ void OpenGLState::SetBlendFunc(GLenum n_src_rgb_func, GLenum n_dst_rgb_func, GLe
blend.dst_a_func = n_dst_a_func;
}
void OpenGLState::SetBlendColor(GLclampf n_red, GLclampf n_green, GLclampf n_blue, GLclampf n_alpha) {
void OpenGLState::SetBlendColor(std::tuple<GLclampf, GLclampf, GLclampf, GLclampf> n_color) {
GLclampf n_red, n_green, n_blue, n_alpha;
std::tie(n_red, n_green, n_blue, n_alpha) = n_color;
if (n_red != cur_state->blend.color.red ||
n_green != cur_state->blend.color.green ||
n_blue != cur_state->blend.color.blue ||
@ -477,3 +493,31 @@ GLenum OpenGLState::CheckBoundFBStatus(GLenum target) {
return fb_status;
}
OpenGLState OpenGLState::ApplyTransferState(GLuint src_tex, GLuint read_framebuffer, GLuint dst_tex, GLuint draw_framebuffer) {
OpenGLState old_state = *cur_state;
cur_state->SetColorMask(std::make_tuple<>(true, true, true, true));
cur_state->SetDepthWriteMask(true);
cur_state->SetStencilWriteMask(true);
if (src_tex != 0) {
cur_state->ResetTexture(src_tex);
}
cur_state->SetReadFramebuffer(read_framebuffer);
if (dst_tex != 0) {
cur_state->ResetTexture(dst_tex);
}
cur_state->SetDrawFramebuffer(draw_framebuffer);
return old_state;
}
void OpenGLState::UndoTransferState(OpenGLState &old_state) {
cur_state->SetColorMask(old_state.GetColorMask());
cur_state->SetDepthWriteMask(old_state.GetDepthWriteMask());
cur_state->SetStencilWriteMask(old_state.GetStencilWriteMask());
cur_state->SetReadFramebuffer(old_state.GetReadFramebuffer());
cur_state->SetDrawFramebuffer(old_state.GetDrawFramebuffer());
// NOTE: Textures that were reset in ApplyTransferState() are NOT restored
}

View file

@ -17,39 +17,74 @@ public:
/// Apply this state as the current OpenGL state
void MakeCurrent();
/// Setter functions for OpenGL state
/// Getter and setter functions for OpenGL state
inline bool GetCullEnabled() { return cull.enabled; }
void SetCullEnabled(bool n_enabled);
inline GLenum GetCullMode() { return cull.mode; }
void SetCullMode(GLenum n_mode);
inline GLenum GetCullFrontFace() { return cull.front_face; }
void SetCullFrontFace(GLenum n_front_face);
inline bool GetDepthTestEnabled() { return depth.test_enabled; }
void SetDepthTestEnabled(bool n_test_enabled);
inline GLenum GetDepthFunc() { return depth.test_func; }
void SetDepthFunc(GLenum n_test_func);
inline GLboolean GetDepthWriteMask() { return depth.write_mask; }
void SetDepthWriteMask(GLboolean n_write_mask);
void SetColorMask(GLboolean n_red_enabled, GLboolean n_green_enabled, GLboolean n_blue_enabled, GLboolean n_alpha_enabled);
inline std::tuple<GLboolean, GLboolean, GLboolean, GLboolean> GetColorMask() {
return std::make_tuple(color_mask.red_enabled, color_mask.green_enabled, color_mask.blue_enabled, color_mask.alpha_enabled);
}
void SetColorMask(std::tuple<GLboolean, GLboolean, GLboolean, GLboolean> n_rgba_enabled);
inline bool GetStencilTestEnabled() { return stencil.test_enabled; }
void SetStencilTestEnabled(bool n_test_enabled);
void SetStencilFunc(GLenum n_test_func, GLint n_test_ref, GLuint n_test_mask);
void SetStencilOp(GLenum n_action_stencil_fail, GLenum n_action_depth_fail, GLenum n_action_depth_pass);
inline std::tuple<GLenum, GLint, GLint> GetStencilFunc() {
return std::make_tuple(stencil.test_func, stencil.test_ref, stencil.test_mask);
}
void SetStencilFunc(std::tuple<GLenum, GLint, GLint> n_funcs);
inline std::tuple<GLenum, GLenum, GLenum> GetStencilOp() {
return std::make_tuple(stencil.action_stencil_fail, stencil.action_depth_fail, stencil.action_depth_pass);
}
void SetStencilOp(std::tuple<GLenum, GLenum, GLenum> n_actions);
inline GLuint GetStencilWriteMask() { return stencil.write_mask; }
void SetStencilWriteMask(GLuint n_write_mask);
inline bool GetBlendEnabled() { return blend.enabled; }
void SetBlendEnabled(bool n_enabled);
void SetBlendFunc(GLenum n_src_rgb_func, GLenum n_dst_rgb_func, GLenum n_src_a_func, GLenum n_dst_a_func);
void SetBlendColor(GLclampf n_red, GLclampf n_green, GLclampf n_blue, GLclampf n_alpha);
inline std::tuple<GLenum, GLenum, GLenum, GLenum> GetBlendFunc() {
return std::make_tuple(blend.src_rgb_func, blend.dst_rgb_func, blend.src_a_func, blend.dst_a_func);
}
void SetBlendFunc(std::tuple<GLenum, GLenum, GLenum, GLenum> n_funcs);
inline std::tuple<GLclampf, GLclampf, GLclampf, GLclampf> GetBlendColor() {
return std::make_tuple(blend.color.red, blend.color.green, blend.color.blue, blend.color.alpha);
}
void SetBlendColor(std::tuple<GLclampf, GLclampf, GLclampf, GLclampf> n_color);
inline GLenum GetLogicOp() { return logic_op; }
void SetLogicOp(GLenum n_logic_op);
inline GLuint GetTexture1D() { return texture_units[active_texture_unit - GL_TEXTURE0].texture_1d; }
void SetTexture1D(GLuint n_texture_1d);
inline GLuint GetTexture2D() { return texture_units[active_texture_unit - GL_TEXTURE0].texture_2d; }
void SetTexture2D(GLuint n_texture_2d);
inline GLuint GetSampler() { return texture_units[active_texture_unit - GL_TEXTURE0].sampler; }
void SetSampler(GLuint n_sampler);
inline GLenum GetActiveTextureUnit() { return active_texture_unit; }
void SetActiveTextureUnit(GLenum n_active_texture_unit);
inline GLuint GetReadFramebuffer() { return draw.read_framebuffer; }
void SetReadFramebuffer(GLuint n_read_framebuffer);
inline GLuint GetDrawFramebuffer() { return draw.draw_framebuffer; }
void SetDrawFramebuffer(GLuint n_draw_framebuffer);
inline GLuint GetVertexArray() { return draw.vertex_array; }
void SetVertexArray(GLuint n_vertex_array);
inline GLuint GetVertexBuffer() { return draw.vertex_buffer; }
void SetVertexBuffer(GLuint n_vertex_buffer);
inline GLuint GetUniformBuffer() { return draw.uniform_buffer; }
void SetUniformBuffer(GLuint n_uniform_buffer);
inline GLuint GetShaderProgram() { return draw.shader_program; }
void SetShaderProgram(GLuint n_shader_program);
/// Resets and unbinds any references to the given resource across all existing states
@ -63,6 +98,12 @@ public:
/// Check the status of the currently bound OpenGL read or draw framebuffer configuration
static GLenum CheckBoundFBStatus(GLenum target);
/// Manipulates the current state to prepare for pixel transfer, and returns a copy of the old state
static OpenGLState ApplyTransferState(GLuint src_tex, GLuint read_framebuffer, GLuint dst_tex, GLuint draw_framebuffer);
/// Returns the old state before transfer state changes were made
static void UndoTransferState(OpenGLState &old_state);
private:
struct {
bool enabled; // GL_CULL_FACE

View file

@ -108,6 +108,7 @@ RendererOpenGL::~RendererOpenGL() {
/// Swap buffers (render frame)
void RendererOpenGL::SwapBuffers() {
OpenGLState* old_state = OpenGLState::GetCurrentState();
state.MakeCurrent();
for (int i : {0, 1}) {
@ -157,6 +158,8 @@ void RendererOpenGL::SwapBuffers() {
profiler.BeginFrame();
old_state->MakeCurrent();
RefreshRasterizerSetting();
if (Pica::g_debug_context && Pica::g_debug_context->recorder) {