mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 02:32:36 +01:00
gl: Minor optimization around test..set patterns in the state tracker
This commit is contained in:
parent
bd1fb86492
commit
81fa3da101
@ -165,21 +165,21 @@ void GLGSRender::update_draw_state()
|
||||
|
||||
if (gl_state.enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST))
|
||||
{
|
||||
glStencilFunc(gl::comparison_op(rsx::method_registers.stencil_func()),
|
||||
gl_state.stencil_func(gl::comparison_op(rsx::method_registers.stencil_func()),
|
||||
rsx::method_registers.stencil_func_ref(),
|
||||
rsx::method_registers.stencil_func_mask());
|
||||
|
||||
glStencilOp(gl::stencil_op(rsx::method_registers.stencil_op_fail()), gl::stencil_op(rsx::method_registers.stencil_op_zfail()),
|
||||
gl_state.stencil_op(gl::stencil_op(rsx::method_registers.stencil_op_fail()), gl::stencil_op(rsx::method_registers.stencil_op_zfail()),
|
||||
gl::stencil_op(rsx::method_registers.stencil_op_zpass()));
|
||||
|
||||
if (rsx::method_registers.two_sided_stencil_test_enabled())
|
||||
{
|
||||
glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask());
|
||||
gl_state.stencil_back_mask(rsx::method_registers.back_stencil_mask());
|
||||
|
||||
glStencilFuncSeparate(GL_BACK, gl::comparison_op(rsx::method_registers.back_stencil_func()),
|
||||
gl_state.stencil_back_func(gl::comparison_op(rsx::method_registers.back_stencil_func()),
|
||||
rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask());
|
||||
|
||||
glStencilOpSeparate(GL_BACK, gl::stencil_op(rsx::method_registers.back_stencil_op_fail()),
|
||||
gl_state.stencil_back_op(gl::stencil_op(rsx::method_registers.back_stencil_op_fail()),
|
||||
gl::stencil_op(rsx::method_registers.back_stencil_op_zfail()), gl::stencil_op(rsx::method_registers.back_stencil_op_zpass()));
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ namespace gl
|
||||
glBindVertexArray(old_vao);
|
||||
}
|
||||
|
||||
void overlay_pass::run(gl::command_context& cmd, const areau& region, GLuint target_texture, GLuint image_aspect_bits, bool use_blending)
|
||||
void overlay_pass::run(gl::command_context& cmd, const areau& region, GLuint target_texture, GLuint image_aspect_bits, bool enable_blending)
|
||||
{
|
||||
if (!compiled)
|
||||
{
|
||||
@ -116,6 +116,9 @@ namespace gl
|
||||
default:
|
||||
fmt::throw_exception("Unsupported image aspect combination 0x%x", image_aspect_bits);
|
||||
}
|
||||
|
||||
enable_depth_writes = (image_aspect_bits & m_write_aspect_mask) & gl::image_aspect::depth;
|
||||
enable_stencil_writes = (image_aspect_bits & m_write_aspect_mask) & gl::image_aspect::stencil;
|
||||
}
|
||||
|
||||
if (!target_texture || fbo.check())
|
||||
@ -128,15 +131,34 @@ namespace gl
|
||||
cmd->color_maski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
cmd->depth_mask(image_aspect_bits == gl::image_aspect::color ? GL_FALSE : GL_TRUE);
|
||||
|
||||
// Disabling depth test will also disable depth writes which is not desired
|
||||
cmd->depth_func(GL_ALWAYS);
|
||||
cmd->enable(GL_DEPTH_TEST);
|
||||
|
||||
cmd->disable(GL_SCISSOR_TEST);
|
||||
cmd->disable(GL_CULL_FACE);
|
||||
cmd->disable(GL_STENCIL_TEST);
|
||||
cmd->disable(GL_SCISSOR_TEST);
|
||||
|
||||
if (use_blending)
|
||||
if (enable_depth_writes)
|
||||
{
|
||||
// Disabling depth test will also disable depth writes which is not desired
|
||||
cmd->depth_func(GL_ALWAYS);
|
||||
cmd->enable(GL_DEPTH_TEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->disable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
if (enable_stencil_writes)
|
||||
{
|
||||
// Disabling stencil test also disables stencil writes.
|
||||
cmd->enable(GL_STENCIL_TEST);
|
||||
cmd->stencil_mask(0xFF);
|
||||
cmd->stencil_func(GL_ALWAYS, 0xFF, 0xFF);
|
||||
cmd->stencil_op(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd->disable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
if (enable_blending)
|
||||
{
|
||||
cmd->enablei(GL_BLEND, 0);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
@ -605,15 +627,21 @@ namespace gl
|
||||
#include "../Program/GLSLSnippets/CopyBufferToGenericImage.glsl"
|
||||
;
|
||||
|
||||
const bool stencil_export_supported = gl::get_driver_caps().ARB_shader_stencil_export_supported;
|
||||
std::pair<std::string_view, std::string> repl_list[] =
|
||||
{
|
||||
{ "%set, ", "" },
|
||||
{ "%loc", std::to_string(GL_COMPUTE_BUFFER_SLOT(0)) },
|
||||
{ "%push_block", fmt::format("binding=%d, std140", GL_COMPUTE_BUFFER_SLOT(1)) },
|
||||
{ "%stencil_export_supported", gl::get_driver_caps().ARB_shader_stencil_export_supported ? "1" : "0" }
|
||||
{ "%stencil_export_supported", stencil_export_supported ? "1" : "0" }
|
||||
};
|
||||
|
||||
fs_src = fmt::replace_all(fs_src, repl_list);
|
||||
|
||||
if (stencil_export_supported)
|
||||
{
|
||||
m_write_aspect_mask |= gl::image_aspect::stencil;
|
||||
}
|
||||
}
|
||||
|
||||
void rp_ssbo_to_generic_texture::run(gl::command_context& cmd,
|
||||
|
@ -35,6 +35,10 @@ namespace gl
|
||||
GLenum primitives = GL_TRIANGLE_STRIP;
|
||||
GLenum input_filter = GL_NEAREST;
|
||||
|
||||
u32 m_write_aspect_mask = gl::image_aspect::color | gl::image_aspect::depth;
|
||||
bool enable_depth_writes = false;
|
||||
bool enable_stencil_writes = false;
|
||||
|
||||
void create();
|
||||
void destroy();
|
||||
|
||||
@ -52,7 +56,7 @@ namespace gl
|
||||
|
||||
virtual void emit_geometry();
|
||||
|
||||
void run(gl::command_context& cmd, const areau& region, GLuint target_texture, GLuint image_aspect_bits, bool use_blending = false);
|
||||
void run(gl::command_context& cmd, const areau& region, GLuint target_texture, GLuint image_aspect_bits, bool enable_blending = false);
|
||||
};
|
||||
|
||||
struct ui_overlay_renderer : public overlay_pass
|
||||
|
@ -7,12 +7,17 @@
|
||||
|
||||
namespace gl
|
||||
{
|
||||
struct driver_state
|
||||
class driver_state
|
||||
{
|
||||
const u32 DEPTH_BOUNDS_MIN = 0xFFFF0001;
|
||||
const u32 DEPTH_BOUNDS_MAX = 0xFFFF0002;
|
||||
const u32 DEPTH_RANGE_MIN = 0xFFFF0003;
|
||||
const u32 DEPTH_RANGE_MAX = 0xFFFF0004;
|
||||
const u32 DEPTH_BOUNDS_MIN = 0xFFFF0001;
|
||||
const u32 DEPTH_BOUNDS_MAX = 0xFFFF0002;
|
||||
const u32 DEPTH_RANGE_MIN = 0xFFFF0003;
|
||||
const u32 DEPTH_RANGE_MAX = 0xFFFF0004;
|
||||
const u32 STENCIL_FRONT_FUNC = 0xFFFF0005;
|
||||
const u32 STENCIL_BACK_FUNC = 0xFFFF0006;
|
||||
const u32 STENCIL_FRONT_OP = 0xFFFF0007;
|
||||
const u32 STENCIL_BACK_OP = 0xFFFF0008;
|
||||
const u32 STENCIL_BACK_MASK = 0xFFFF0009;
|
||||
|
||||
std::unordered_map<GLenum, u32> properties = {};
|
||||
std::unordered_map<GLenum, std::array<u32, 4>> indexed_properties = {};
|
||||
@ -20,6 +25,36 @@ namespace gl
|
||||
GLuint current_program = GL_NONE;
|
||||
std::array<std::unordered_map<GLenum, GLuint>, 48> bound_textures{ {} };
|
||||
|
||||
bool test_and_set_property(GLenum property, u32 test)
|
||||
{
|
||||
auto found = properties.find(property);
|
||||
if (found != properties.end() && found->second == test)
|
||||
return true;
|
||||
|
||||
properties[property] = test;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool test_and_set_property(GLenum property, u32 test, GLint index)
|
||||
{
|
||||
auto found = indexed_properties.find(property);
|
||||
if (found != indexed_properties.end())
|
||||
{
|
||||
if (found->second[index] == test)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
found->second[index] = test;
|
||||
return false;
|
||||
}
|
||||
|
||||
indexed_properties[property][index] = test;
|
||||
return false;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool enable(u32 test, GLenum cap)
|
||||
{
|
||||
auto found = properties.find(cap);
|
||||
@ -82,77 +117,97 @@ namespace gl
|
||||
return enablei(GL_FALSE, cap, index);
|
||||
}
|
||||
|
||||
inline bool test_property(GLenum property, u32 test) const
|
||||
{
|
||||
auto found = properties.find(property);
|
||||
if (found == properties.end())
|
||||
return false;
|
||||
|
||||
return (found->second == test);
|
||||
}
|
||||
|
||||
inline bool test_propertyi(GLenum property, u32 test, GLint index) const
|
||||
{
|
||||
auto found = indexed_properties.find(property);
|
||||
if (found == indexed_properties.end())
|
||||
return false;
|
||||
|
||||
return found->second[index] == test;
|
||||
}
|
||||
|
||||
void depth_func(GLenum func)
|
||||
{
|
||||
if (!test_property(GL_DEPTH_FUNC, func))
|
||||
if (!test_and_set_property(GL_DEPTH_FUNC, func))
|
||||
{
|
||||
glDepthFunc(func);
|
||||
properties[GL_DEPTH_FUNC] = func;
|
||||
}
|
||||
}
|
||||
|
||||
void depth_mask(GLboolean mask)
|
||||
{
|
||||
if (!test_property(GL_DEPTH_WRITEMASK, mask))
|
||||
if (!test_and_set_property(GL_DEPTH_WRITEMASK, mask))
|
||||
{
|
||||
glDepthMask(mask);
|
||||
properties[GL_DEPTH_WRITEMASK] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
void clear_depth(GLfloat depth)
|
||||
{
|
||||
u32 value = std::bit_cast<u32>(depth);
|
||||
if (!test_property(GL_DEPTH_CLEAR_VALUE, value))
|
||||
if (!test_and_set_property(GL_DEPTH_CLEAR_VALUE, value))
|
||||
{
|
||||
glClearDepth(depth);
|
||||
properties[GL_DEPTH_CLEAR_VALUE] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_mask(GLuint mask)
|
||||
{
|
||||
if (!test_property(GL_STENCIL_WRITEMASK, mask))
|
||||
if (!test_and_set_property(GL_STENCIL_WRITEMASK, mask))
|
||||
{
|
||||
glStencilMask(mask);
|
||||
properties[GL_STENCIL_WRITEMASK] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_back_mask(GLuint mask)
|
||||
{
|
||||
if (!test_and_set_property(STENCIL_BACK_MASK, mask))
|
||||
{
|
||||
glStencilMaskSeparate(GL_BACK, mask);
|
||||
}
|
||||
}
|
||||
|
||||
void clear_stencil(GLint stencil)
|
||||
{
|
||||
u32 value = std::bit_cast<u32>(stencil);
|
||||
if (!test_property(GL_STENCIL_CLEAR_VALUE, value))
|
||||
const u32 value = std::bit_cast<u32>(stencil);
|
||||
if (!test_and_set_property(GL_STENCIL_CLEAR_VALUE, value))
|
||||
{
|
||||
glClearStencil(stencil);
|
||||
properties[GL_STENCIL_CLEAR_VALUE] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_func(GLenum func, GLint ref, GLuint mask)
|
||||
{
|
||||
const u32 value = func | ref << 16u | mask << 24;
|
||||
if (!test_and_set_property(STENCIL_FRONT_FUNC, value))
|
||||
{
|
||||
glStencilFunc(func, ref, mask);
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_back_func(GLenum func, GLint ref, GLuint mask)
|
||||
{
|
||||
const u32 value = func | ref << 16u | mask << 24;
|
||||
if (!test_and_set_property(STENCIL_BACK_FUNC, value))
|
||||
{
|
||||
glStencilFunc(func, ref, mask);
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_op(GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
const u32 value = (fail & 0xFF) << 16 | (zfail & 0xFF) << 8 | (zpass & 0xFF);
|
||||
if (!test_and_set_property(STENCIL_FRONT_OP, value))
|
||||
{
|
||||
glStencilOp(fail, zfail, zpass);
|
||||
}
|
||||
}
|
||||
|
||||
void stencil_back_op(GLenum fail, GLenum zfail, GLenum zpass)
|
||||
{
|
||||
const u32 value = (fail & 0xFF) << 16 | (zfail & 0xFF) << 8 | (zpass & 0xFF);
|
||||
if (!test_and_set_property(STENCIL_FRONT_OP, value))
|
||||
{
|
||||
glStencilOpSeparate(GL_BACK, fail, zfail, zpass);
|
||||
}
|
||||
}
|
||||
|
||||
void color_maski(GLint index, u32 mask)
|
||||
{
|
||||
if (!test_propertyi(GL_COLOR_WRITEMASK, mask, index))
|
||||
if (!test_and_set_property(GL_COLOR_WRITEMASK, mask, index))
|
||||
{
|
||||
glColorMaski(index, ((mask & 0x10) ? 1 : 0), ((mask & 0x20) ? 1 : 0), ((mask & 0x40) ? 1 : 0), ((mask & 0x80) ? 1 : 0));
|
||||
indexed_properties[GL_COLOR_WRITEMASK][index] = mask;
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,10 +225,9 @@ namespace gl
|
||||
void clear_color(u8 r, u8 g, u8 b, u8 a)
|
||||
{
|
||||
u32 value = u32{ r } | u32{ g } << 8 | u32{ b } << 16 | u32{ a } << 24;
|
||||
if (!test_property(GL_COLOR_CLEAR_VALUE, value))
|
||||
if (!test_and_set_property(GL_COLOR_CLEAR_VALUE, value))
|
||||
{
|
||||
glClearColor(r / 255.f, g / 255.f, b / 255.f, a / 255.f);
|
||||
properties[GL_COLOR_CLEAR_VALUE] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,7 +241,7 @@ namespace gl
|
||||
u32 depth_min = std::bit_cast<u32>(min);
|
||||
u32 depth_max = std::bit_cast<u32>(max);
|
||||
|
||||
if (!test_property(DEPTH_BOUNDS_MIN, depth_min) || !test_property(DEPTH_BOUNDS_MAX, depth_max))
|
||||
if (!test_and_set_property(DEPTH_BOUNDS_MIN, depth_min) || !test_and_set_property(DEPTH_BOUNDS_MAX, depth_max))
|
||||
{
|
||||
if (get_driver_caps().NV_depth_buffer_float_supported)
|
||||
{
|
||||
@ -197,9 +251,6 @@ namespace gl
|
||||
{
|
||||
glDepthBoundsEXT(min, max);
|
||||
}
|
||||
|
||||
properties[DEPTH_BOUNDS_MIN] = depth_min;
|
||||
properties[DEPTH_BOUNDS_MAX] = depth_max;
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,7 +259,7 @@ namespace gl
|
||||
u32 depth_min = std::bit_cast<u32>(min);
|
||||
u32 depth_max = std::bit_cast<u32>(max);
|
||||
|
||||
if (!test_property(DEPTH_RANGE_MIN, depth_min) || !test_property(DEPTH_RANGE_MAX, depth_max))
|
||||
if (!test_and_set_property(DEPTH_RANGE_MIN, depth_min) || !test_and_set_property(DEPTH_RANGE_MAX, depth_max))
|
||||
{
|
||||
if (get_driver_caps().NV_depth_buffer_float_supported)
|
||||
{
|
||||
@ -218,18 +269,14 @@ namespace gl
|
||||
{
|
||||
glDepthRange(min, max);
|
||||
}
|
||||
|
||||
properties[DEPTH_RANGE_MIN] = depth_min;
|
||||
properties[DEPTH_RANGE_MAX] = depth_max;
|
||||
}
|
||||
}
|
||||
|
||||
void logic_op(GLenum op)
|
||||
{
|
||||
if (!test_property(GL_COLOR_LOGIC_OP, op))
|
||||
if (!test_and_set_property(GL_COLOR_LOGIC_OP, op))
|
||||
{
|
||||
glLogicOp(op);
|
||||
properties[GL_COLOR_LOGIC_OP] = op;
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,28 +284,25 @@ namespace gl
|
||||
{
|
||||
u32 value = std::bit_cast<u32>(width);
|
||||
|
||||
if (!test_property(GL_LINE_WIDTH, value))
|
||||
if (!test_and_set_property(GL_LINE_WIDTH, value))
|
||||
{
|
||||
glLineWidth(width);
|
||||
properties[GL_LINE_WIDTH] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void front_face(GLenum face)
|
||||
{
|
||||
if (!test_property(GL_FRONT_FACE, face))
|
||||
if (!test_and_set_property(GL_FRONT_FACE, face))
|
||||
{
|
||||
glFrontFace(face);
|
||||
properties[GL_FRONT_FACE] = face;
|
||||
}
|
||||
}
|
||||
|
||||
void cull_face(GLenum mode)
|
||||
{
|
||||
if (!test_property(GL_CULL_FACE_MODE, mode))
|
||||
if (!test_and_set_property(GL_CULL_FACE_MODE, mode))
|
||||
{
|
||||
glCullFace(mode);
|
||||
properties[GL_CULL_FACE_MODE] = mode;
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,12 +311,9 @@ namespace gl
|
||||
u32 _units = std::bit_cast<u32>(units);
|
||||
u32 _factor = std::bit_cast<u32>(factor);
|
||||
|
||||
if (!test_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_property(GL_POLYGON_OFFSET_FACTOR, _factor))
|
||||
if (!test_and_set_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_and_set_property(GL_POLYGON_OFFSET_FACTOR, _factor))
|
||||
{
|
||||
glPolygonOffset(factor, units);
|
||||
|
||||
properties[GL_POLYGON_OFFSET_UNITS] = _units;
|
||||
properties[GL_POLYGON_OFFSET_FACTOR] = _factor;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user