vk_blit_helper: Add d24s8->rgba8 multi-sample blit

This commit is contained in:
Wunkolo 2023-11-13 13:05:31 -08:00
parent 37c739603d
commit 4e8db844f2
4 changed files with 49 additions and 2 deletions

View file

@ -6,6 +6,7 @@ set(SHADER_FILES
format_reinterpreter/d24s8_to_rgba8.frag
format_reinterpreter/rgba4_to_rgb5a1.frag
format_reinterpreter/vulkan_d24s8_to_rgba8.comp
format_reinterpreter/vulkan_d24s8_to_rgba8_ms.comp
texture_filtering/bicubic.frag
texture_filtering/refine.frag
texture_filtering/scale_force.frag

View file

@ -0,0 +1,31 @@
// Copyright 2023 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#version 450 core
#extension GL_EXT_samplerless_texture_functions : require
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
layout(set = 0, binding = 0) uniform highp texture2DMS depth;
layout(set = 0, binding = 1) uniform lowp utexture2DMS stencil;
layout(set = 0, binding = 2, rgba8) uniform highp writeonly image2DMS color;
layout(push_constant, std140) uniform ComputeInfo {
mediump ivec2 src_offset;
mediump ivec2 dst_offset;
mediump ivec2 extent;
};
void main() {
int sample_count = textureSamples(depth);
ivec2 src_coord = src_offset + ivec2(gl_GlobalInvocationID.xy);
ivec2 dst_coord = dst_offset + ivec2(gl_GlobalInvocationID.xy);
for(int sample_index = 0; sample_index < sample_count; ++sample_index)
{
highp uint depth_val = uint(texelFetch(depth, src_coord, sample_index).x * (exp2(32.0) - 1.0));
lowp uint stencil_val = texelFetch(stencil, src_coord, sample_index).x;
highp uvec4 components = uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu);
imageStore(color, dst_coord, sample_index, vec4(components) / (exp2(8.0) - 1.0));
}
}

View file

@ -11,6 +11,7 @@
#include "video_core/renderer_vulkan/vk_texture_runtime.h"
#include "video_core/host_shaders/format_reinterpreter/vulkan_d24s8_to_rgba8_comp_spv.h"
#include "video_core/host_shaders/format_reinterpreter/vulkan_d24s8_to_rgba8_ms_comp_spv.h"
#include "video_core/host_shaders/full_screen_triangle_vert_spv.h"
#include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h"
#include "video_core/host_shaders/vulkan_depth_to_buffer_comp_spv.h"
@ -191,9 +192,12 @@ BlitHelper::BlitHelper(const Instance& instance_, Scheduler& scheduler_, Descrip
device.createPipelineLayout(PipelineLayoutCreateInfo(&two_textures_provider.Layout()))},
full_screen_vert{CompileSPV(FULL_SCREEN_TRIANGLE_VERT_SPV, device)},
d24s8_to_rgba8_comp{CompileSPV(VULKAN_D24S8_TO_RGBA8_COMP_SPV, device)},
d24s8_to_rgba8_ms_comp{CompileSPV(VULKAN_D24S8_TO_RGBA8_COMP_SPV, device)},
depth_to_buffer_comp{CompileSPV(VULKAN_DEPTH_TO_BUFFER_COMP_SPV, device)},
blit_depth_stencil_frag{CompileSPV(VULKAN_BLIT_DEPTH_STENCIL_FRAG_SPV, device)},
d24s8_to_rgba8_pipeline{MakeComputePipeline(d24s8_to_rgba8_comp, compute_pipeline_layout)},
d24s8_to_rgba8_ms_pipeline{
MakeComputePipeline(d24s8_to_rgba8_ms_comp, compute_pipeline_layout)},
depth_to_buffer_pipeline{
MakeComputePipeline(depth_to_buffer_comp, compute_buffer_pipeline_layout)},
depth_blit_pipeline{MakeDepthStencilBlitPipeline()},
@ -230,6 +234,7 @@ BlitHelper::~BlitHelper() {
device.destroyShaderModule(blit_depth_stencil_frag);
device.destroyPipeline(depth_to_buffer_pipeline);
device.destroyPipeline(d24s8_to_rgba8_pipeline);
device.destroyPipeline(d24s8_to_rgba8_ms_pipeline);
device.destroyPipeline(depth_blit_pipeline);
device.destroySampler(linear_sampler);
device.destroySampler(nearest_sampler);
@ -332,10 +337,18 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest,
.imageLayout = vk::ImageLayout::eGeneral,
};
if (dest.sample_count != source.sample_count) {
LOG_ERROR(Render_Vulkan, "Trying to bit DS24S8->RGBA8 with different sample counts");
return false;
}
const bool multisample = (source.sample_count > 1) && (dest.sample_count > 1);
const auto descriptor_set = compute_provider.Acquire(textures);
const auto pipeline = multisample ? d24s8_to_rgba8_ms_pipeline : d24s8_to_rgba8_pipeline;
renderpass_cache.EndRendering();
scheduler.Record([this, descriptor_set, copy, src_image = source.Image(),
scheduler.Record([this, pipeline, descriptor_set, copy, src_image = source.Image(),
dst_image = dest.Image()](vk::CommandBuffer cmdbuf) {
const std::array pre_barriers = {
vk::ImageMemoryBarrier{
@ -414,7 +427,7 @@ bool BlitHelper::ConvertDS24S8ToRGBA8(Surface& source, Surface& dest,
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eCompute, compute_pipeline_layout, 0,
descriptor_set, {});
cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, d24s8_to_rgba8_pipeline);
cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline);
const ComputeInfo info = {
.src_offset = Common::Vec2i{static_cast<int>(copy.src_offset.x),

View file

@ -55,10 +55,12 @@ private:
vk::ShaderModule full_screen_vert;
vk::ShaderModule d24s8_to_rgba8_comp;
vk::ShaderModule d24s8_to_rgba8_ms_comp;
vk::ShaderModule depth_to_buffer_comp;
vk::ShaderModule blit_depth_stencil_frag;
vk::Pipeline d24s8_to_rgba8_pipeline;
vk::Pipeline d24s8_to_rgba8_ms_pipeline;
vk::Pipeline depth_to_buffer_pipeline;
vk::Pipeline depth_blit_pipeline;
vk::Sampler linear_sampler;