renderer_vulkan: Implement depth uploads with blit
This commit is contained in:
@ -669,7 +669,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
auto surface = res_cache.GetTextureSurface(info);
|
auto surface = res_cache.GetTextureSurface(info);
|
||||||
|
|
||||||
const u32 binding = static_cast<u32>(face);
|
const u32 binding = static_cast<u32>(face);
|
||||||
if (surface != nullptr) {
|
if (surface) {
|
||||||
pipeline_cache.BindStorageImage(binding, surface->GetImageView());
|
pipeline_cache.BindStorageImage(binding, surface->GetImageView());
|
||||||
} else {
|
} else {
|
||||||
pipeline_cache.BindStorageImage(binding, null_storage_surface.GetImageView());
|
pipeline_cache.BindStorageImage(binding, null_storage_surface.GetImageView());
|
||||||
@ -775,8 +775,7 @@ bool RasterizerVulkan::Draw(bool accelerate, bool is_indexed) {
|
|||||||
.dst_layer = 0,
|
.dst_layer = 0,
|
||||||
.src_offset = VideoCore::Offset{0, 0},
|
.src_offset = VideoCore::Offset{0, 0},
|
||||||
.dst_offset = VideoCore::Offset{0, 0},
|
.dst_offset = VideoCore::Offset{0, 0},
|
||||||
.extent = VideoCore::Extent{temp.GetScaledWidth(),
|
.extent = VideoCore::Extent{temp.GetScaledWidth(), temp.GetScaledHeight()}};
|
||||||
temp.GetScaledHeight()}};
|
|
||||||
|
|
||||||
runtime.CopyTextures(*color_surface, temp, copy);
|
runtime.CopyTextures(*color_surface, temp, copy);
|
||||||
temp.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, temp.alloc.levels);
|
temp.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, temp.alloc.levels);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
#include "video_core/rasterizer_cache/morton_swizzle.h"
|
||||||
#include "video_core/rasterizer_cache/utils.h"
|
#include "video_core/rasterizer_cache/utils.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_renderpass_cache.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) {
|
void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingData& staging) {
|
||||||
MICROPROFILE_SCOPE(Vulkan_Upload);
|
MICROPROFILE_SCOPE(Vulkan_Upload);
|
||||||
|
|
||||||
if (type == VideoCore::SurfaceType::DepthStencil) {
|
if (type == VideoCore::SurfaceType::DepthStencil && !traits.blit_support) {
|
||||||
LOG_ERROR(Render_Vulkan, "Depth upload unimplemented, ignoring");
|
LOG_ERROR(Render_Vulkan, "Depth blit unsupported by hardware, ignoring");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +627,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingDa
|
|||||||
copy_regions[region_count++] = copy_region;
|
copy_regions[region_count++] = copy_region;
|
||||||
|
|
||||||
if (alloc.aspect & vk::ImageAspectFlagBits::eStencil) {
|
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_region.imageSubresource.aspectMask = vk::ImageAspectFlagBits::eStencil;
|
||||||
copy_regions[region_count++] = copy_region;
|
copy_regions[region_count++] = copy_region;
|
||||||
}
|
}
|
||||||
@ -813,4 +814,31 @@ void Surface::DepthStencilDownload(const VideoCore::BufferTextureCopy& download,
|
|||||||
r32_surface.Download(r32_download, staging);
|
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
|
} // namespace Vulkan
|
||||||
|
@ -172,9 +172,6 @@ public:
|
|||||||
TextureRuntime& runtime);
|
TextureRuntime& runtime);
|
||||||
~Surface() override;
|
~Surface() override;
|
||||||
|
|
||||||
Surface(Surface&&) = default;
|
|
||||||
Surface& operator=(Surface&&) = default;
|
|
||||||
|
|
||||||
/// Transitions the mip level range of the surface to new_layout
|
/// Transitions the mip level range of the surface to new_layout
|
||||||
void Transition(vk::ImageLayout new_layout, u32 level, u32 level_count);
|
void Transition(vk::ImageLayout new_layout, u32 level, u32 level_count);
|
||||||
|
|
||||||
@ -223,6 +220,9 @@ private:
|
|||||||
void DepthStencilDownload(const VideoCore::BufferTextureCopy& download,
|
void DepthStencilDownload(const VideoCore::BufferTextureCopy& download,
|
||||||
const StagingData& staging);
|
const StagingData& staging);
|
||||||
|
|
||||||
|
/// Unpacks packed D24S8 data to facilitate depth upload
|
||||||
|
u32 UnpackDepthStencil(const StagingData& data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextureRuntime& runtime;
|
TextureRuntime& runtime;
|
||||||
const Instance& instance;
|
const Instance& instance;
|
||||||
|
Reference in New Issue
Block a user