rsx: Discard surface store contents once per frame (temp workaround)

Need to find the proper command issued to discard all surfaces
This commit is contained in:
kd-11 2017-06-14 01:36:41 +03:00
parent 110974af0b
commit db1a90d828
5 changed files with 74 additions and 44 deletions

View File

@ -115,7 +115,6 @@ 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);
@ -124,7 +123,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), address != previous_address);
Traits::prepare_ds_for_drawing(command_list, Traits::get(ds));
return Traits::get(ds);
}
invalidated_resources.push_back(std::move(ds));
@ -175,14 +174,13 @@ namespace rsx
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, old_zeta_address, std::forward<Args>(extra_params)...));
bind_address_as_depth_stencil(command_list, address_z, depth_format, clip_width, clip_height, std::forward<Args>(extra_params)...));
}
/**
@ -347,5 +345,18 @@ namespace rsx
Traits::unmap_downloaded_buffer(stencil_data, std::forward<Args&&>(args)...);
return result;
}
/**
* Invalidates cached surface data and marks surface contents as deleteable
* Called at the end of a frame (workaround, need to find the proper invalidate command)
*/
void invalidate_surface_cache_data(command_list_type command_list)
{
for (auto &rtt : m_render_targets_storage)
Traits::invalidate_rtt_surface_contents(command_list, Traits::get(std::get<1>(rtt)));
for (auto &ds : m_depth_stencil_storage)
Traits::invalidate_depth_surface_contents(command_list, Traits::get(std::get<1>(ds)));
}
};
}

View File

@ -100,12 +100,10 @@ struct render_target_traits
static
void prepare_ds_for_drawing(
gsl::not_null<ID3D12GraphicsCommandList*> command_list,
ID3D12Resource* ds, bool surface_changed)
ID3D12Resource* ds)
{
// 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
@ -116,6 +114,18 @@ struct render_target_traits
command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(ds, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
}
void invalidate_rtt_surface_contents(
gsl::not_null<ID3D12GraphicsCommandList*>,
ID3D12Resource*)
{}
void invalidate_depth_surface_contents(
gsl::not_null<ID3D12GraphicsCommandList*>,
ID3D12Resource*)
{
//TODO
}
static
bool rtt_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_color_format surface_color_format, size_t width, size_t height)
@ -125,7 +135,7 @@ struct render_target_traits
}
static
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_depth_format surface_depth_stencil_format, size_t width, size_t height)
bool ds_has_format_width_height(const ComPtr<ID3D12Resource> &rtt, surface_depth_format, size_t width, size_t height)
{
//TODO: Check format
return rtt->GetDesc().Width == width && rtt->GetDesc().Height == height;
@ -231,7 +241,7 @@ struct render_target_traits
static
gsl::span<const gsl::byte> map_downloaded_buffer(const std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE> &sync_data,
gsl::not_null<ID3D12Device*> device, gsl::not_null<ID3D12CommandQueue*> command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store)
gsl::not_null<ID3D12Device*>, gsl::not_null<ID3D12CommandQueue*>, d3d12_data_heap &readback_heap, resource_storage&)
{
size_t offset;
size_t buffer_size;
@ -247,8 +257,8 @@ struct render_target_traits
}
static
void unmap_downloaded_buffer(const std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE> &sync_data,
gsl::not_null<ID3D12Device*> device, gsl::not_null<ID3D12CommandQueue*> command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store)
void unmap_downloaded_buffer(const std::tuple<size_t, size_t, size_t, ComPtr<ID3D12Fence>, HANDLE> &,
gsl::not_null<ID3D12Device*>, gsl::not_null<ID3D12CommandQueue*>, d3d12_data_heap &readback_heap, resource_storage&)
{
readback_heap.unmap();
}

View File

@ -943,6 +943,7 @@ void GLGSRender::flip(int buffer)
}
m_rtts.invalidated_resources.clear();
m_rtts.invalidate_surface_cache_data(nullptr);
}

View File

@ -215,7 +215,7 @@ struct gl_render_target_traits
__glcheck result->pixel_pack_settings().aligment(1);
__glcheck result->pixel_unpack_settings().aligment(1);
u16 native_pitch = width * 2;
u16 native_pitch = (u16)width * 2;
if (surface_depth_format == rsx::surface_depth_format::z24s8)
native_pitch *= 2;
@ -228,9 +228,12 @@ 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 *ds, bool surface_changed) { if (surface_changed) ds->set_cleared(false); }
static void prepare_ds_for_drawing(void *, gl::render_target *ds) {}
static void prepare_ds_for_sampling(void *, gl::render_target*) {}
static void invalidate_rtt_surface_contents(void *, gl::render_target *ds) {}
static void invalidate_depth_surface_contents(void *, gl::render_target *ds) { ds->set_cleared(false); }
static
bool rtt_has_format_width_height(const std::unique_ptr<gl::render_target> &rtt, rsx::surface_color_format surface_color_format, size_t width, size_t height)
{

View File

@ -42,7 +42,7 @@ namespace rsx
using command_list_type = vk::command_buffer*;
using download_buffer_object = void*;
static std::unique_ptr<vk::render_target> create_new_surface(u32 address, surface_color_format format, size_t width, size_t height, vk::render_device &device, vk::command_buffer *cmd, const vk::gpu_formats_support &support, const vk::memory_type_mapping &mem_mapping)
static std::unique_ptr<vk::render_target> create_new_surface(u32, surface_color_format format, size_t width, size_t height, vk::render_device &device, vk::command_buffer *cmd, const vk::gpu_formats_support &, const vk::memory_type_mapping &mem_mapping)
{
auto fmt = vk::get_compatible_surface_format(format);
VkFormat requested_format = fmt.first;
@ -58,7 +58,7 @@ namespace rsx
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
0));
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
change_image_layout(*cmd, rtt.get(), VK_IMAGE_LAYOUT_GENERAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
//Clear new surface
VkClearColorValue clear_color;
VkImageSubresourceRange range = vk::get_image_subresource_range(0,0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT);
@ -69,14 +69,14 @@ namespace rsx
clear_color.float32[3] = 0.f;
vkCmdClearColorImage(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range);
change_image_layout(*cmd, rtt->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
change_image_layout(*cmd, rtt.get(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
rtt->native_layout = fmt.second;
rtt->native_pitch = width * get_format_block_size_in_bytes(format);
rtt->native_component_map = fmt.second;
rtt->native_pitch = (u16)width * get_format_block_size_in_bytes(format);
return rtt;
}
static std::unique_ptr<vk::render_target> create_new_surface(u32 address, surface_depth_format format, size_t width, size_t height, vk::render_device &device, vk::command_buffer *cmd, const vk::gpu_formats_support &support, const vk::memory_type_mapping &mem_mapping)
static std::unique_ptr<vk::render_target> create_new_surface(u32, surface_depth_format format, size_t width, size_t height, vk::render_device &device, vk::command_buffer *cmd, const vk::gpu_formats_support &support, const vk::memory_type_mapping &mem_mapping)
{
VkFormat requested_format = vk::get_compatible_depth_surface_format(support, format);
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_DEPTH_BIT);
@ -93,10 +93,11 @@ namespace rsx
VK_SAMPLE_COUNT_1_BIT,
VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0));
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT| VK_IMAGE_USAGE_TRANSFER_SRC_BIT| VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT,
0));
ds->native_layout = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R };
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, range);
ds->native_component_map = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R };
change_image_layout(*cmd, ds.get(), VK_IMAGE_LAYOUT_GENERAL, range);
//Clear new surface..
VkClearDepthStencilValue clear_depth = {};
@ -105,9 +106,9 @@ namespace rsx
clear_depth.stencil = 0;
vkCmdClearDepthStencilImage(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, &clear_depth, 1, &range);
change_image_layout(*cmd, ds->value, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
change_image_layout(*cmd, ds.get(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
ds->native_pitch = width * 2;
ds->native_pitch = (u16)width * 2;
if (format == rsx::surface_depth_format::z24s8)
ds->native_pitch *= 2;
@ -119,38 +120,42 @@ namespace rsx
static void prepare_rtt_for_drawing(vk::command_buffer* pcmd, vk::render_target *surface)
{
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_COLOR_ATTACHMENT_OPTIMAL, range);
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, range);
}
static void prepare_rtt_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
{
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
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, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
}
static void prepare_ds_for_drawing(vk::command_buffer* pcmd, vk::render_target *surface, bool surface_changed)
static void prepare_ds_for_drawing(vk::command_buffer* pcmd, vk::render_target *surface)
{
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);
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);
}
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, range);
}
static void prepare_ds_for_sampling(vk::command_buffer* pcmd, vk::render_target *surface)
{
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, surface->attachment_aspect_flag);
change_image_layout(*pcmd, surface->value, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
change_image_layout(*pcmd, surface, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, range);
}
static void invalidate_rtt_surface_contents(vk::command_buffer*, vk::render_target*) {}
static void invalidate_depth_surface_contents(vk::command_buffer* pcmd, vk::render_target *ds)
{
VkImageLayout old_layout = ds->current_layout;
VkImageSubresourceRange range = vk::get_image_subresource_range(0, 0, 1, 1, ds->attachment_aspect_flag);
change_image_layout(*pcmd, ds, 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, ds->value, VK_IMAGE_LAYOUT_GENERAL, &clear_depth, 1, &range);
change_image_layout(*pcmd, ds, old_layout, range);
}
static bool rtt_has_format_width_height(const std::unique_ptr<vk::render_target> &rtt, surface_color_format format, size_t width, size_t height)
@ -165,7 +170,7 @@ namespace rsx
return false;
}
static bool ds_has_format_width_height(const std::unique_ptr<vk::render_target> &ds, surface_depth_format format, size_t width, size_t height)
static bool ds_has_format_width_height(const std::unique_ptr<vk::render_target> &ds, surface_depth_format, size_t width, size_t height)
{
// TODO: check format
//VkFormat fmt = vk::get_compatible_depth_surface_format(format);
@ -178,7 +183,7 @@ namespace rsx
return false;
}
static download_buffer_object issue_download_command(surface_type, surface_color_format color_format, size_t width, size_t height, ...)
static download_buffer_object issue_download_command(surface_type, surface_color_format color_format, size_t width, size_t, ...)
{
return nullptr;
}