rsx/wip: Fix depth surface reuse and clearing (fixes shadows)

This commit is contained in:
kd-11 2017-06-12 01:27:27 +03:00
parent 701728ecd7
commit 5f66d0b996
5 changed files with 41 additions and 11 deletions

View File

@ -115,6 +115,7 @@ namespace rsx
command_list_type command_list,
u32 address,
surface_depth_format depth_format, size_t width, size_t height,
u32 previous_address,
Args&&... extra_params)
{
auto It = m_depth_stencil_storage.find(address);
@ -123,7 +124,7 @@ namespace rsx
surface_storage_type &ds = It->second;
if (Traits::ds_has_format_width_height(ds, depth_format, width, height))
{
Traits::prepare_ds_for_drawing(command_list, Traits::get(ds));
Traits::prepare_ds_for_drawing(command_list, Traits::get(ds), address != previous_address);
return Traits::get(ds);
}
invalidated_resources.push_back(std::move(ds));
@ -173,11 +174,15 @@ namespace rsx
// Same for depth buffer
if (std::get<1>(m_bound_depth_stencil) != nullptr)
Traits::prepare_ds_for_sampling(command_list, std::get<1>(m_bound_depth_stencil));
const u32 old_zeta_address = std::get<0>(m_bound_depth_stencil);
m_bound_depth_stencil = std::make_tuple(0, nullptr);
if (!address_z)
return;
m_bound_depth_stencil = std::make_tuple(address_z,
bind_address_as_depth_stencil(command_list, address_z, depth_format, clip_width, clip_height, std::forward<Args>(extra_params)...));
bind_address_as_depth_stencil(command_list, address_z, depth_format, clip_width, clip_height, old_zeta_address, std::forward<Args>(extra_params)...));
}
/**

View File

@ -18,6 +18,9 @@ struct render_target_traits
using command_list_type = gsl::not_null<ID3D12GraphicsCommandList*>;
using download_buffer_object = std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE>; // heap offset, size, last_put_pos, fence, handle
//TODO: Move this somewhere else
bool depth_is_dirty = false;
static
ComPtr<ID3D12Resource> create_new_surface(
u32 address,
@ -97,10 +100,12 @@ struct render_target_traits
static
void prepare_ds_for_drawing(
gsl::not_null<ID3D12GraphicsCommandList*> command_list,
ID3D12Resource* ds)
ID3D12Resource* ds, bool surface_changed)
{
// set the resource as depth write
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_DEPTH_WRITE));
//TODO: Clear this surface if the depth address changed (Requires a partial rewrite)
}
static

View File

@ -349,11 +349,17 @@ void GLGSRender::end()
gl::render_target *ds = std::get<1>(m_rtts.m_bound_depth_stencil);
if (ds && !ds->cleared())
{
//Temporarily disable pixel tests
glDisable(GL_SCISSOR_TEST);
glDepthMask(GL_TRUE);
glClearDepth(1.f);
glClearDepth(1.0);
glClearStencil(0);
glClear(GL_DEPTH_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDepthMask(rsx::method_registers.depth_write_enabled());
glEnable(GL_SCISSOR_TEST);
ds->set_cleared();
}

View File

@ -65,9 +65,9 @@ namespace gl
render_target() {}
void set_cleared()
void set_cleared(bool clear=true)
{
is_cleared = true;
is_cleared = clear;
}
bool cleared() const
@ -227,7 +227,8 @@ struct gl_render_target_traits
static void prepare_rtt_for_drawing(void *, gl::render_target*) {}
static void prepare_rtt_for_sampling(void *, gl::render_target*) {}
static void prepare_ds_for_drawing(void *, gl::render_target*) {}
static void prepare_ds_for_drawing(void *, gl::render_target *ds, bool surface_changed) { if (surface_changed) ds->set_cleared(false); }
static void prepare_ds_for_sampling(void *, gl::render_target*) {}
static
@ -238,7 +239,7 @@ struct gl_render_target_traits
}
static
bool ds_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_depth_format surface_depth_stencil_format, size_t width, size_t height)
bool ds_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_depth_format surface_depth_stencil_format, size_t width, size_t height)
{
// TODO: check format
return rtt->width() == width && rtt->height() == height;

View File

@ -128,10 +128,23 @@ namespace rsx
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
}
static void prepare_ds_for_drawing(vk::command_buffer* pcmd, vk::render_target *surface)
static void prepare_ds_for_drawing(vk::command_buffer* pcmd, vk::render_target *surface, bool surface_changed)
{
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
if (!surface_changed)
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
else
{
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, range);
//Clear the surface before drawing on it
VkClearDepthStencilValue clear_depth = {};
clear_depth.depth = 1.f;
clear_depth.stencil = 0;
vkCmdClearDepthStencilImage(*pcmd, surface->value, VK_IMAGE_LAYOUT_GENERAL, &clear_depth, 1, &range);
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
}
}
static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)