mirror of
https://github.com/citra-emu/citra.git
synced 2024-12-26 08:20:07 +00:00
vk_blit_helper: Add d24s8->rgba8 multi-sample blit
This commit is contained in:
parent
37c739603d
commit
4e8db844f2
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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),
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user