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, command_list_type command_list,
u32 address, u32 address,
surface_depth_format depth_format, size_t width, size_t height, surface_depth_format depth_format, size_t width, size_t height,
u32 previous_address,
Args&&... extra_params) Args&&... extra_params)
{ {
auto It = m_depth_stencil_storage.find(address); auto It = m_depth_stencil_storage.find(address);
@ -123,7 +124,7 @@ namespace rsx
surface_storage_type &ds = It->second; surface_storage_type &ds = It->second;
if (Traits::ds_has_format_width_height(ds, depth_format, width, height)) 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); return Traits::get(ds);
} }
invalidated_resources.push_back(std::move(ds)); invalidated_resources.push_back(std::move(ds));
@ -173,11 +174,15 @@ namespace rsx
// Same for depth buffer // Same for depth buffer
if (std::get<1>(m_bound_depth_stencil) != nullptr) if (std::get<1>(m_bound_depth_stencil) != nullptr)
Traits::prepare_ds_for_sampling(command_list, std::get<1>(m_bound_depth_stencil)); 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); m_bound_depth_stencil = std::make_tuple(0, nullptr);
if (!address_z) if (!address_z)
return; return;
m_bound_depth_stencil = std::make_tuple(address_z, 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 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 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 static
ComPtr<ID3D12Resource> create_new_surface( ComPtr<ID3D12Resource> create_new_surface(
u32 address, u32 address,
@ -97,10 +100,12 @@ struct render_target_traits
static static
void prepare_ds_for_drawing( void prepare_ds_for_drawing(
gsl::not_null<ID3D12GraphicsCommandList*> command_list, gsl::not_null<ID3D12GraphicsCommandList*> command_list,
ID3D12Resource* ds) ID3D12Resource* ds, bool surface_changed)
{ {
// set the resource as depth write // 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)); 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 static

View file

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

View file

@ -65,9 +65,9 @@ namespace gl
render_target() {} render_target() {}
void set_cleared() void set_cleared(bool clear=true)
{ {
is_cleared = true; is_cleared = clear;
} }
bool cleared() const 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_drawing(void *, gl::render_target*) {}
static void prepare_rtt_for_sampling(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 void prepare_ds_for_sampling(void *, gl::render_target*) {}
static static

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); 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); VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
if (!surface_changed)
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range); 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) static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)