mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-20 15:40:23 +00:00
gl: Refactor attachment clear logic
- Make the whole thing a standalone command to avoid unnecessary state meddling.
This commit is contained in:
parent
b86ecf7441
commit
fdfcc6c5ea
@ -546,7 +546,7 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
|
||||
if (!m_graphics_state.test(rsx::rtt_config_valid)) return;
|
||||
|
||||
GLbitfield mask = 0;
|
||||
gl::clear_cmd_info clear_cmd{};
|
||||
|
||||
gl::command_context cmd{ gl_state };
|
||||
const bool full_frame =
|
||||
@ -565,26 +565,23 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
u32 clear_depth = rsx::method_registers.z_clear_value(is_depth_stencil_format(surface_depth_format));
|
||||
|
||||
gl_state.depth_mask(GL_TRUE);
|
||||
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
clear_cmd.clear_depth.value = f32(clear_depth) / max_depth_value;
|
||||
clear_cmd.aspect_mask |= gl::image_aspect::depth;
|
||||
}
|
||||
|
||||
if (is_depth_stencil_format(surface_depth_format))
|
||||
{
|
||||
if (arg & RSX_GCM_CLEAR_STENCIL_BIT)
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
|
||||
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
|
||||
gl_state.clear_stencil(clear_stencil);
|
||||
mask |= GLenum(gl::buffers::stencil);
|
||||
clear_cmd.clear_stencil.mask = rsx::method_registers.stencil_mask();
|
||||
clear_cmd.clear_stencil.value = rsx::method_registers.stencil_clear_value();
|
||||
clear_cmd.aspect_mask |= gl::image_aspect::stencil;
|
||||
}
|
||||
|
||||
if (const auto ds_mask = (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK);
|
||||
ds_mask != RSX_GCM_CLEAR_DEPTH_STENCIL_MASK || !full_frame)
|
||||
{
|
||||
ensure(mask);
|
||||
ensure(clear_cmd.aspect_mask);
|
||||
|
||||
if (ds->state_flags & rsx::surface_state_flags::erase_bkgnd && // Needs initialization
|
||||
ds->old_contents.empty() && !g_cfg.video.read_depth_buffer) // No way to load data from memory, so no initialization given
|
||||
@ -593,16 +590,15 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
if (ds_mask == RSX_GCM_CLEAR_DEPTH_BIT)
|
||||
{
|
||||
// Depth was cleared, initialize stencil
|
||||
gl_state.stencil_mask(0xFF);
|
||||
gl_state.clear_stencil(0xFF);
|
||||
mask |= GLenum(gl::buffers::stencil);
|
||||
clear_cmd.clear_stencil.mask = 0xff;
|
||||
clear_cmd.clear_stencil.value = 0xff;
|
||||
clear_cmd.aspect_mask |= gl::image_aspect::stencil;
|
||||
}
|
||||
else if (ds_mask == RSX_GCM_CLEAR_STENCIL_BIT)
|
||||
{
|
||||
// Stencil was cleared, initialize depth
|
||||
gl_state.depth_mask(GL_TRUE);
|
||||
gl_state.clear_depth(1.f);
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
clear_cmd.clear_depth.value = 1.f;
|
||||
clear_cmd.aspect_mask |= gl::image_aspect::depth;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -612,7 +608,7 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
}
|
||||
}
|
||||
|
||||
if (mask)
|
||||
if (clear_cmd.aspect_mask)
|
||||
{
|
||||
// Memory has been initialized
|
||||
update_z = true;
|
||||
@ -679,18 +675,20 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
|
||||
if (colormask)
|
||||
{
|
||||
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
|
||||
mask |= GLenum(gl::buffers::color);
|
||||
clear_cmd.clear_color.mask = colormask;
|
||||
clear_cmd.clear_color.attachment_count = static_cast<u8>(m_rtts.m_bound_render_target_ids.size());
|
||||
clear_cmd.clear_color.r = clear_r;
|
||||
clear_cmd.clear_color.g = clear_g;
|
||||
clear_cmd.clear_color.b = clear_b;
|
||||
clear_cmd.clear_color.a = clear_a;
|
||||
clear_cmd.aspect_mask |= gl::image_aspect::color;
|
||||
|
||||
int hw_index = 0;
|
||||
for (const auto& index : m_rtts.m_bound_render_target_ids)
|
||||
if (!full_frame)
|
||||
{
|
||||
if (!full_frame)
|
||||
for (const auto& index : m_rtts.m_bound_render_target_ids)
|
||||
{
|
||||
m_rtts.m_bound_render_targets[index].second->write_barrier(cmd);
|
||||
}
|
||||
|
||||
gl_state.color_maski(hw_index++, colormask);
|
||||
}
|
||||
|
||||
update_color = true;
|
||||
@ -707,7 +705,7 @@ void GLGSRender::clear_surface(u32 arg)
|
||||
gl_state.enable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
glClear(mask);
|
||||
gl::clear_attachments(cmd, clear_cmd);
|
||||
}
|
||||
|
||||
bool GLGSRender::load_program()
|
||||
|
@ -1101,4 +1101,34 @@ namespace gl
|
||||
const coord3u dst_area = { {}, dst->size3D() };
|
||||
copy_typeless(cmd, dst, src, dst_area, src_area);
|
||||
}
|
||||
|
||||
void clear_attachments(gl::command_context& cmd, const clear_cmd_info& info)
|
||||
{
|
||||
// Compile the clear command at the end. Other intervening operations will
|
||||
GLbitfield clear_mask = 0;
|
||||
if (info.aspect_mask & gl::image_aspect::color)
|
||||
{
|
||||
for (u32 buffer_id = 0; buffer_id < info.clear_color.attachment_count; ++buffer_id)
|
||||
{
|
||||
cmd->color_maski(buffer_id, info.clear_color.mask);
|
||||
}
|
||||
|
||||
cmd->clear_color(info.clear_color.r, info.clear_color.g, info.clear_color.b, info.clear_color.a);
|
||||
clear_mask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if (info.aspect_mask & gl::image_aspect::depth)
|
||||
{
|
||||
cmd->depth_mask(GL_TRUE);
|
||||
cmd->clear_depth(info.clear_depth.value);
|
||||
clear_mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
if (info.aspect_mask & gl::image_aspect::stencil)
|
||||
{
|
||||
cmd->stencil_mask(info.clear_stencil.mask);
|
||||
cmd->clear_stencil(info.clear_stencil.value);
|
||||
clear_mask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(clear_mask);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,34 @@ namespace gl
|
||||
u64 memory_required;
|
||||
};
|
||||
|
||||
struct clear_cmd_info
|
||||
{
|
||||
GLbitfield aspect_mask = 0;
|
||||
|
||||
struct
|
||||
{
|
||||
f32 value = 0;
|
||||
}
|
||||
clear_depth;
|
||||
|
||||
struct
|
||||
{
|
||||
u8 mask = 0;
|
||||
u8 value = 0;
|
||||
}
|
||||
clear_stencil;
|
||||
|
||||
struct {
|
||||
u32 mask = 0;
|
||||
u8 attachment_count = 0;
|
||||
u8 r = 0;
|
||||
u8 g = 0;
|
||||
u8 b = 0;
|
||||
u8 a = 0;
|
||||
}
|
||||
clear_color;
|
||||
};
|
||||
|
||||
GLenum get_target(rsx::texture_dimension_extended type);
|
||||
GLenum get_sized_internal_format(u32 texture_format);
|
||||
std::tuple<GLenum, GLenum> get_format_type(u32 texture_format);
|
||||
@ -51,6 +79,8 @@ namespace gl
|
||||
|
||||
void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector<rsx::subresource_layout>& subresources_layout);
|
||||
|
||||
void clear_attachments(gl::command_context& cmd, const clear_cmd_info& info);
|
||||
|
||||
namespace debug
|
||||
{
|
||||
extern std::unique_ptr<texture> g_vis_texture;
|
||||
|
@ -169,15 +169,6 @@ namespace gl
|
||||
glClear(static_cast<GLbitfield>(buffers_));
|
||||
}
|
||||
|
||||
void fbo::clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const
|
||||
{
|
||||
save_binding_state save(*this);
|
||||
glClearColor(color_value.r, color_value.g, color_value.b, color_value.a);
|
||||
glClearDepth(depth_value);
|
||||
glClearStencil(stencil_value);
|
||||
clear(buffers_);
|
||||
}
|
||||
|
||||
void fbo::copy_from(const void* pixels, const sizei& size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings) const
|
||||
{
|
||||
save_binding_state save(*this);
|
||||
|
@ -211,7 +211,6 @@ namespace gl
|
||||
void draw_elements(const buffer& buffer, GLenum mode, GLsizei count, const GLuint* indices) const;
|
||||
|
||||
void clear(buffers buffers_) const;
|
||||
void clear(buffers buffers_, color4f color_value, double depth_value, u8 stencil_value) const;
|
||||
|
||||
void copy_from(const void* pixels, const sizei& size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const;
|
||||
void copy_from(const buffer& buf, const sizei& size, gl::texture::format format_, gl::texture::type type_, class pixel_unpack_settings pixel_settings = pixel_unpack_settings()) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user