diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 1d514d70f..f7c9867f1 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -669,7 +669,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { auto surface = res_cache.GetTextureSurface(info); const u32 binding = static_cast(face); - if (surface != nullptr) { + if (surface) { pipeline_cache.BindStorageImage(binding, surface->GetImageView()); } else { pipeline_cache.BindStorageImage(binding, null_storage_surface.GetImageView()); @@ -775,8 +775,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) { .dst_layer = 0, .src_offset = VideoCore::Offset{0, 0}, .dst_offset = VideoCore::Offset{0, 0}, - .extent = VideoCore::Extent{temp.GetScaledWidth(), - temp.GetScaledHeight()}}; + .extent = VideoCore::Extent{temp.GetScaledWidth(), temp.GetScaledHeight()}}; runtime.CopyTextures(*color_surface, temp, copy); temp.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, temp.alloc.levels); diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index 5d1ed2eef..f5b5eae75 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "video_core/rasterizer_cache/morton_swizzle.h" #include "video_core/rasterizer_cache/utils.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_renderpass_cache.h" @@ -593,8 +594,8 @@ MICROPROFILE_DEFINE(Vulkan_Upload, "VulkanSurface", "Texture Upload", MP_RGB(128 void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingData& staging) { MICROPROFILE_SCOPE(Vulkan_Upload); - if (type == VideoCore::SurfaceType::DepthStencil) { - LOG_ERROR(Render_Vulkan, "Depth upload unimplemented, ignoring"); + if (type == VideoCore::SurfaceType::DepthStencil && !traits.blit_support) { + LOG_ERROR(Render_Vulkan, "Depth blit unsupported by hardware, ignoring"); return; } @@ -626,7 +627,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingDa copy_regions[region_count++] = copy_region; if (alloc.aspect & vk::ImageAspectFlagBits::eStencil) { - copy_region.bufferOffset += 4 * staging.size / 5; + copy_region.bufferOffset += UnpackDepthStencil(staging); copy_region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eStencil; copy_regions[region_count++] = copy_region; } @@ -813,4 +814,31 @@ void Surface::DepthStencilDownload(const VideoCore::BufferTextureCopy& download, r32_surface.Download(r32_download, staging); } +u32 Surface::UnpackDepthStencil(const StagingData& data) { + u32 depth_offset = 0; + u32 stencil_offset = 4 * data.size / 5; + const auto& mapped = data.mapped; + + switch (alloc.format) { + case vk::Format::eD24UnormS8Uint: { + for (; stencil_offset < data.size; depth_offset += 4) { + std::byte* ptr = mapped.data() + depth_offset; + const u32 d24s8 = VideoCore::MakeInt(ptr); + const u32 d24 = d24s8 >> 8; + mapped[stencil_offset] = static_cast(d24s8 & 0xFF); + std::memcpy(ptr, &d24, 4); + stencil_offset++; + } + break; + } + default: + LOG_ERROR(Render_Vulkan, "Unimplemtend convertion for depth format {}", + vk::to_string(alloc.format)); + UNREACHABLE(); + } + + ASSERT(depth_offset == 4 * data.size / 5); + return depth_offset; +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.h b/src/video_core/renderer_vulkan/vk_texture_runtime.h index a4e92948a..2af81d80c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.h +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.h @@ -172,9 +172,6 @@ public: TextureRuntime& runtime); ~Surface() override; - Surface(Surface&&) = default; - Surface& operator=(Surface&&) = default; - /// Transitions the mip level range of the surface to new_layout void Transition(vk::ImageLayout new_layout, u32 level, u32 level_count); @@ -223,6 +220,9 @@ private: void DepthStencilDownload(const VideoCore::BufferTextureCopy& download, const StagingData& staging); + /// Unpacks packed D24S8 data to facilitate depth upload + u32 UnpackDepthStencil(const StagingData& data); + private: TextureRuntime& runtime; const Instance& instance;