mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-21 18:39:57 +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;
|
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 };
|
gl::command_context cmd{ gl_state };
|
||||||
const bool full_frame =
|
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 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));
|
u32 clear_depth = rsx::method_registers.z_clear_value(is_depth_stencil_format(surface_depth_format));
|
||||||
|
|
||||||
gl_state.depth_mask(GL_TRUE);
|
clear_cmd.clear_depth.value = f32(clear_depth) / max_depth_value;
|
||||||
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
clear_cmd.aspect_mask |= gl::image_aspect::depth;
|
||||||
mask |= GLenum(gl::buffers::depth);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_depth_stencil_format(surface_depth_format))
|
if (is_depth_stencil_format(surface_depth_format))
|
||||||
{
|
{
|
||||||
if (arg & RSX_GCM_CLEAR_STENCIL_BIT)
|
if (arg & RSX_GCM_CLEAR_STENCIL_BIT)
|
||||||
{
|
{
|
||||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
clear_cmd.clear_stencil.mask = rsx::method_registers.stencil_mask();
|
||||||
|
clear_cmd.clear_stencil.value = rsx::method_registers.stencil_clear_value();
|
||||||
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
|
clear_cmd.aspect_mask |= gl::image_aspect::stencil;
|
||||||
gl_state.clear_stencil(clear_stencil);
|
|
||||||
mask |= GLenum(gl::buffers::stencil);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto ds_mask = (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK);
|
if (const auto ds_mask = (arg & RSX_GCM_CLEAR_DEPTH_STENCIL_MASK);
|
||||||
ds_mask != RSX_GCM_CLEAR_DEPTH_STENCIL_MASK || !full_frame)
|
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
|
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
|
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)
|
if (ds_mask == RSX_GCM_CLEAR_DEPTH_BIT)
|
||||||
{
|
{
|
||||||
// Depth was cleared, initialize stencil
|
// Depth was cleared, initialize stencil
|
||||||
gl_state.stencil_mask(0xFF);
|
clear_cmd.clear_stencil.mask = 0xff;
|
||||||
gl_state.clear_stencil(0xFF);
|
clear_cmd.clear_stencil.value = 0xff;
|
||||||
mask |= GLenum(gl::buffers::stencil);
|
clear_cmd.aspect_mask |= gl::image_aspect::stencil;
|
||||||
}
|
}
|
||||||
else if (ds_mask == RSX_GCM_CLEAR_STENCIL_BIT)
|
else if (ds_mask == RSX_GCM_CLEAR_STENCIL_BIT)
|
||||||
{
|
{
|
||||||
// Stencil was cleared, initialize depth
|
// Stencil was cleared, initialize depth
|
||||||
gl_state.depth_mask(GL_TRUE);
|
clear_cmd.clear_depth.value = 1.f;
|
||||||
gl_state.clear_depth(1.f);
|
clear_cmd.aspect_mask |= gl::image_aspect::depth;
|
||||||
mask |= GLenum(gl::buffers::depth);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -612,7 +608,7 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask)
|
if (clear_cmd.aspect_mask)
|
||||||
{
|
{
|
||||||
// Memory has been initialized
|
// Memory has been initialized
|
||||||
update_z = true;
|
update_z = true;
|
||||||
@ -679,18 +675,20 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
|
|
||||||
if (colormask)
|
if (colormask)
|
||||||
{
|
{
|
||||||
gl_state.clear_color(clear_r, clear_g, clear_b, clear_a);
|
clear_cmd.clear_color.mask = colormask;
|
||||||
mask |= GLenum(gl::buffers::color);
|
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;
|
if (!full_frame)
|
||||||
for (const auto& index : m_rtts.m_bound_render_target_ids)
|
|
||||||
{
|
{
|
||||||
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);
|
m_rtts.m_bound_render_targets[index].second->write_barrier(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_state.color_maski(hw_index++, colormask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
update_color = true;
|
update_color = true;
|
||||||
@ -707,7 +705,7 @@ void GLGSRender::clear_surface(u32 arg)
|
|||||||
gl_state.enable(GL_SCISSOR_TEST);
|
gl_state.enable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
glClear(mask);
|
gl::clear_attachments(cmd, clear_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGSRender::load_program()
|
bool GLGSRender::load_program()
|
||||||
|
@ -1101,4 +1101,34 @@ namespace gl
|
|||||||
const coord3u dst_area = { {}, dst->size3D() };
|
const coord3u dst_area = { {}, dst->size3D() };
|
||||||
copy_typeless(cmd, dst, src, dst_area, src_area);
|
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;
|
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_target(rsx::texture_dimension_extended type);
|
||||||
GLenum get_sized_internal_format(u32 texture_format);
|
GLenum get_sized_internal_format(u32 texture_format);
|
||||||
std::tuple<GLenum, GLenum> get_format_type(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 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
|
namespace debug
|
||||||
{
|
{
|
||||||
extern std::unique_ptr<texture> g_vis_texture;
|
extern std::unique_ptr<texture> g_vis_texture;
|
||||||
|
@ -169,15 +169,6 @@ namespace gl
|
|||||||
glClear(static_cast<GLbitfield>(buffers_));
|
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
|
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);
|
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 draw_elements(const buffer& buffer, GLenum mode, GLsizei count, const GLuint* indices) const;
|
||||||
|
|
||||||
void clear(buffers buffers_) 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 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;
|
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