renderer_vulkan: Implement depth uploads with blit

This commit is contained in:
emufan4568
2022-10-16 18:06:12 +03:00
parent b7fa091db0
commit 0223fa756c
3 changed files with 36 additions and 9 deletions

View File

@ -669,7 +669,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
auto surface = res_cache.GetTextureSurface(info);
const u32 binding = static_cast<u32>(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);

View File

@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <bit>
#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<u32>(ptr);
const u32 d24 = d24s8 >> 8;
mapped[stencil_offset] = static_cast<std::byte>(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

View File

@ -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;