mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-08-10 01:59:41 +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,6 +1119,8 @@ void GLGSRender::clear_surface(u32 arg)
|
||||||
|
|
||||||
rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
||||||
|
|
||||||
|
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); arg & 0x3)
|
||||||
|
{
|
||||||
if (arg & 0x1)
|
if (arg & 0x1)
|
||||||
{
|
{
|
||||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||||
|
@ -1127,23 +1129,48 @@ void GLGSRender::clear_surface(u32 arg)
|
||||||
gl_state.depth_mask(GL_TRUE);
|
gl_state.depth_mask(GL_TRUE);
|
||||||
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
gl_state.clear_depth(f32(clear_depth) / max_depth_value);
|
||||||
mask |= GLenum(gl::buffers::depth);
|
mask |= GLenum(gl::buffers::depth);
|
||||||
|
}
|
||||||
|
|
||||||
if (const auto address = std::get<0>(m_rtts.m_bound_depth_stencil))
|
if (surface_depth_format == rsx::surface_depth_format::z24s8)
|
||||||
{
|
{
|
||||||
m_rtts.on_write(address);
|
if (arg & 0x2)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2))
|
|
||||||
{
|
{
|
||||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||||
|
|
||||||
gl_state.stencil_mask(0xFF);
|
gl_state.stencil_mask(rsx::method_registers.stencil_mask());
|
||||||
gl_state.clear_stencil(clear_stencil);
|
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))
|
if (auto colormask = (arg & 0xf0))
|
||||||
{
|
{
|
||||||
switch (rsx::method_registers.surface_color())
|
switch (rsx::method_registers.surface_color())
|
||||||
|
|
|
@ -1901,6 +1901,8 @@ void VKGSRender::clear_surface(u32 mask)
|
||||||
|
|
||||||
auto surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
auto surface_depth_format = rsx::method_registers.surface_depth_fmt();
|
||||||
|
|
||||||
|
if (auto ds = std::get<1>(m_rtts.m_bound_depth_stencil); mask & 0x3)
|
||||||
|
{
|
||||||
if (mask & 0x1)
|
if (mask & 0x1)
|
||||||
{
|
{
|
||||||
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
u32 max_depth_value = get_max_depth_value(surface_depth_format);
|
||||||
|
@ -1914,16 +1916,35 @@ void VKGSRender::clear_surface(u32 mask)
|
||||||
depth_stencil_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
depth_stencil_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mask & 0x2)
|
if (surface_depth_format == rsx::surface_depth_format::z24s8)
|
||||||
{
|
{
|
||||||
if (surface_depth_format == rsx::surface_depth_format::z24s8 &&
|
if (mask & 0x2 && rsx::method_registers.stencil_mask() != 0)
|
||||||
rsx::method_registers.stencil_mask() != 0)
|
|
||||||
{
|
{
|
||||||
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
u8 clear_stencil = rsx::method_registers.stencil_clear_value();
|
||||||
depth_stencil_clear_values.depthStencil.stencil = clear_stencil;
|
depth_stencil_clear_values.depthStencil.stencil = clear_stencil;
|
||||||
|
|
||||||
depth_stencil_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto colormask = (mask & 0xF0))
|
if (auto colormask = (mask & 0xF0))
|
||||||
|
@ -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))
|
if (const auto address = std::get<0>(m_rtts.m_bound_depth_stencil))
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue