mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
rsx: Fix dirty flag reset after a partial attachment initialization
- D24S8 targets have 2 aspects that are dealt with separately; Forcefully initialize the remaining data if a partial init is done. Its 'free' anyway - It seems that the stencil mask matters when clearing unlike the depth mask and color mask
This commit is contained in:
parent
c80c7f06bb
commit
475cc99117
2 changed files with 85 additions and 37 deletions
|
@ -1119,29 +1119,56 @@ void GLGSRender::clear_surface(u32 arg)
|
|||
|
||||
rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
||||
|
||||
if (arg & 0x1)
|
||||
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); arg & 0x3)
|
||||
{
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8);
|
||||
|
||||
gl_state.depth_mask(GL_TRUE);
|
||||
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
|
||||
if (const auto address = std::get<0>(m_rtts.m_bound_depth_stencil))
|
||||
if (arg & 0x1)
|
||||
{
|
||||
m_rtts.on_write(address);
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8);
|
||||
|
||||
gl_state.depth_mask(GL_TRUE);
|
||||
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
}
|
||||
}
|
||||
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2))
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8)
|
||||
{
|
||||
if (arg & 0x2)
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
|
||||
gl_state.stencil_mask(0xFF);
|
||||
gl_state.clear_stencil(clear_stencil);
|
||||
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
|
||||
gl_state.clear_stencil(clear_stencil);
|
||||
mask |= GLenum(gl::buffers::stencil);
|
||||
}
|
||||
|
||||
mask |= GLenum(gl::buffers::stencil);
|
||||
if ((arg & 0x3) != 0x3 && ds->dirty)
|
||||
{
|
||||
verify(HERE), mask;
|
||||
|
||||
// Only one aspect was cleared. Make sure to memory intialize the other before removing dirty flag
|
||||
if (arg == 1)
|
||||
{
|
||||
// Depth was cleared, initialize stencil
|
||||
gl_state.stencil_mask(0xFF);
|
||||
gl_state.clear_stencil(0xFF);
|
||||
mask |= GLenum(gl::buffers::stencil);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stencil was cleared, initialize depth
|
||||
gl_state.depth_mask(GL_TRUE);
|
||||
gl_state.clear_depth(1.f);
|
||||
mask |= GLenum(gl::buffers::depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mask)
|
||||
{
|
||||
// Memory has been initialized
|
||||
m_rtts.on_write(std::get<0>(m_rtts.m_bound_depth_stencil));
|
||||
}
|
||||
}
|
||||
|
||||
if (auto colormask = (arg & 0xf0))
|
||||
|
|
|
@ -1901,28 +1901,49 @@ void VKGSRender::clear_surface(u32 mask)
|
|||
|
||||
auto surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
||||
|
||||
if (mask & 0x1)
|
||||
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); mask & 0x3)
|
||||
{
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
|
||||
u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8);
|
||||
float depth_clear = (float)clear_depth / max_depth_value;
|
||||
|
||||
depth_stencil_clear_values.depthStencil.depth = depth_clear;
|
||||
depth_stencil_clear_values.depthStencil.stencil = stencil_clear;
|
||||
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
|
||||
if (mask & 0x2)
|
||||
{
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 &&
|
||||
rsx::method_registers.stencil_mask() != 0)
|
||||
if (mask & 0x1)
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
depth_stencil_clear_values.depthStencil.stencil = clear_stencil;
|
||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
u32 clear_depth = rsx::method_registers.z_clear_value(surface_depth_format == rsx::surface_depth_format::z24s8);
|
||||
float depth_clear = (float)clear_depth / max_depth_value;
|
||||
|
||||
depth_stencil_clear_values.depthStencil.depth = depth_clear;
|
||||
depth_stencil_clear_values.depthStencil.stencil = stencil_clear;
|
||||
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
|
||||
if (surface_depth_format == rsx::surface_depth_format::z24s8)
|
||||
{
|
||||
if (mask & 0x2 && rsx::method_registers.stencil_mask() != 0)
|
||||
{
|
||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||
depth_stencil_clear_values.depthStencil.stencil = clear_stencil;
|
||||
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
|
||||
if ((mask & 0x3) != 0x3 && ds->dirty)
|
||||
{
|
||||
verify(HERE), depth_stencil_mask;
|
||||
|
||||
// Only one aspect was cleared. Make sure to memory intialize the other before removing dirty flag
|
||||
if (mask == 1)
|
||||
{
|
||||
// Depth was cleared, initialize stencil
|
||||
depth_stencil_clear_values.depthStencil.stencil = 0xFF;
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stencil was cleared, initialize depth
|
||||
depth_stencil_clear_values.depthStencil.depth = 1.f;
|
||||
depth_stencil_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2015,7 +2036,7 @@ void VKGSRender::clear_surface(u32 mask)
|
|||
}
|
||||
}
|
||||
|
||||
if (mask & 0x3)
|
||||
if (depth_stencil_mask)
|
||||
{
|
||||
if (const auto address = std::get<0>(m_rtts.m_bound_depth_stencil))
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue