diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 71b292ab81..154464ab18 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -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(extra_params)...)); + bind_address_as_depth_stencil(command_list, address_z, depth_format, clip_width, clip_height, std::forward(extra_params)...)); } /** @@ -347,5 +345,18 @@ namespace rsx Traits::unmap_downloaded_buffer(stencil_data, std::forward(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))); + } }; } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h index a937c4bcec..363d245005 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.h @@ -100,12 +100,10 @@ struct render_target_traits static void prepare_ds_for_drawing( gsl::not_null 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, + ID3D12Resource*) + {} + + void invalidate_depth_surface_contents( + gsl::not_null, + ID3D12Resource*) + { + //TODO + } + static bool rtt_has_format_width_height(const ComPtr &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 &rtt, surface_depth_format surface_depth_stencil_format, size_t width, size_t height) + bool ds_has_format_width_height(const ComPtr &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 map_downloaded_buffer(const std::tuple, HANDLE> &sync_data, - gsl::not_null device, gsl::not_null command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store) + gsl::not_null, gsl::not_null, 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, HANDLE> &sync_data, - gsl::not_null device, gsl::not_null command_queue, d3d12_data_heap &readback_heap, resource_storage &res_store) + void unmap_downloaded_buffer(const std::tuple, HANDLE> &, + gsl::not_null, gsl::not_null, d3d12_data_heap &readback_heap, resource_storage&) { readback_heap.unmap(); } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index ae3eb11970..7924b52d44 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -943,6 +943,7 @@ void GLGSRender::flip(int buffer) } m_rtts.invalidated_resources.clear(); + m_rtts.invalidate_surface_cache_data(nullptr); } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index aebd1c4728..1877e8c8d8 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -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 &rtt, rsx::surface_color_format surface_color_format, size_t width, size_t height) { diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index efa5e50105..f5f625a31f 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -42,7 +42,7 @@ namespace rsx using command_list_type = vk::command_buffer*; using download_buffer_object = void*; - static std::unique_ptr 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 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 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 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 &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 &ds, surface_depth_format format, size_t width, size_t height) + static bool ds_has_format_width_height(const std::unique_ptr &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; }