Fixup: + getters, - redundant makecurrents/trackers
This commit is contained in:
parent
e2c74e8ea5
commit
d7cc5bdcc1
7 changed files with 170 additions and 97 deletions
|
@ -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() {
|
||||
|
|
|
@ -351,7 +351,6 @@ private:
|
|||
void SyncLightPosition(int light_index);
|
||||
|
||||
OpenGLState state;
|
||||
OpenGLState utility_state;
|
||||
|
||||
RasterizerCacheOpenGL res_cache;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue