@ -1,4 +1,5 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-License-Identifier: GPL-2.0-or-later
# include <algorithm>
# include <algorithm>
@ -28,6 +29,7 @@
# include "video_core/surface.h"
# include "video_core/surface.h"
# include "video_core/vulkan_common/vulkan_device.h"
# include "video_core/vulkan_common/vulkan_device.h"
# include "video_core/vulkan_common/vulkan_wrapper.h"
# include "video_core/vulkan_common/vulkan_wrapper.h"
# include "video_core/host_shaders/convert_abgr8_srgb_to_d24s8_frag_spv.h"
namespace Vulkan {
namespace Vulkan {
@ -439,6 +441,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, Scheduler& scheduler_,
convert_d32f_to_abgr8_frag ( BuildShader ( device , CONVERT_D32F_TO_ABGR8_FRAG_SPV ) ) ,
convert_d32f_to_abgr8_frag ( BuildShader ( device , CONVERT_D32F_TO_ABGR8_FRAG_SPV ) ) ,
convert_d24s8_to_abgr8_frag ( BuildShader ( device , CONVERT_D24S8_TO_ABGR8_FRAG_SPV ) ) ,
convert_d24s8_to_abgr8_frag ( BuildShader ( device , CONVERT_D24S8_TO_ABGR8_FRAG_SPV ) ) ,
convert_s8d24_to_abgr8_frag ( BuildShader ( device , CONVERT_S8D24_TO_ABGR8_FRAG_SPV ) ) ,
convert_s8d24_to_abgr8_frag ( BuildShader ( device , CONVERT_S8D24_TO_ABGR8_FRAG_SPV ) ) ,
convert_abgr8_srgb_to_d24s8_frag ( BuildShader ( device , CONVERT_ABGR8_SRGB_TO_D24S8_FRAG_SPV ) ) ,
linear_sampler ( device . GetLogical ( ) . CreateSampler ( SAMPLER_CREATE_INFO < VK_FILTER_LINEAR > ) ) ,
linear_sampler ( device . GetLogical ( ) . CreateSampler ( SAMPLER_CREATE_INFO < VK_FILTER_LINEAR > ) ) ,
nearest_sampler ( device . GetLogical ( ) . CreateSampler ( SAMPLER_CREATE_INFO < VK_FILTER_NEAREST > ) ) { }
nearest_sampler ( device . GetLogical ( ) . CreateSampler ( SAMPLER_CREATE_INFO < VK_FILTER_NEAREST > ) ) { }
@ -589,6 +592,14 @@ void BlitImageHelper::ConvertS8D24ToABGR8(const Framebuffer* dst_framebuffer,
ConvertDepthStencil ( * convert_s8d24_to_abgr8_pipeline , dst_framebuffer , src_image_view ) ;
ConvertDepthStencil ( * convert_s8d24_to_abgr8_pipeline , dst_framebuffer , src_image_view ) ;
}
}
void BlitImageHelper : : ConvertABGR8SRGBToD24S8 ( const Framebuffer * dst_framebuffer ,
const ImageView & src_image_view ) {
ConvertPipelineDepthTargetEx ( convert_abgr8_srgb_to_d24s8_pipeline ,
dst_framebuffer - > RenderPass ( ) ,
convert_abgr8_srgb_to_d24s8_frag ) ;
Convert ( * convert_abgr8_srgb_to_d24s8_pipeline , dst_framebuffer , src_image_view ) ;
}
void BlitImageHelper : : ClearColor ( const Framebuffer * dst_framebuffer , u8 color_mask ,
void BlitImageHelper : : ClearColor ( const Framebuffer * dst_framebuffer , u8 color_mask ,
const std : : array < f32 , 4 > & clear_color ,
const std : : array < f32 , 4 > & clear_color ,
const Region2D & dst_region ) {
const Region2D & dst_region ) {
@ -919,13 +930,11 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
return * clear_stencil_pipelines . back ( ) ;
return * clear_stencil_pipelines . back ( ) ;
}
}
void BlitImageHelper : : ConvertPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ,
bool is_target_depth ) {
void BlitImageHelper : : ConvertDepthToColorPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ) {
if ( pipeline ) {
if ( pipeline ) {
return ;
return ;
}
}
VkShaderModule frag_shader =
is_target_depth ? * convert_float_to_depth_frag : * convert_depth_to_float_frag ;
VkShaderModule frag_shader = * convert_float_to_depth_frag ;
const std : : array stages = MakeStages ( * full_screen_vert , frag_shader ) ;
const std : : array stages = MakeStages ( * full_screen_vert , frag_shader ) ;
pipeline = device . GetLogical ( ) . CreateGraphicsPipeline ( {
pipeline = device . GetLogical ( ) . CreateGraphicsPipeline ( {
. sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO ,
. sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO ,
@ -939,9 +948,8 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende
. pViewportState = & PIPELINE_VIEWPORT_STATE_CREATE_INFO ,
. pViewportState = & PIPELINE_VIEWPORT_STATE_CREATE_INFO ,
. pRasterizationState = & PIPELINE_RASTERIZATION_STATE_CREATE_INFO ,
. pRasterizationState = & PIPELINE_RASTERIZATION_STATE_CREATE_INFO ,
. pMultisampleState = & PIPELINE_MULTISAMPLE_STATE_CREATE_INFO ,
. pMultisampleState = & PIPELINE_MULTISAMPLE_STATE_CREATE_INFO ,
. pDepthStencilState = is_target_depth ? & PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr ,
. pColorBlendState = is_target_depth ? & PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
: & PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO ,
. pDepthStencilState = & PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO ,
. pColorBlendState = & PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO ,
. pDynamicState = & PIPELINE_DYNAMIC_STATE_CREATE_INFO ,
. pDynamicState = & PIPELINE_DYNAMIC_STATE_CREATE_INFO ,
. layout = * one_texture_pipeline_layout ,
. layout = * one_texture_pipeline_layout ,
. renderPass = renderpass ,
. renderPass = renderpass ,
@ -951,12 +959,33 @@ void BlitImageHelper::ConvertPipeline(vk::Pipeline& pipeline, VkRenderPass rende
} ) ;
} ) ;
}
}
void BlitImageHelper : : ConvertDepthToColorPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ) {
ConvertPipeline ( pipeline , renderpass , false ) ;
}
void BlitImageHelper : : ConvertColorToDepthPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ) {
void BlitImageHelper : : ConvertColorToDepthPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ) {
ConvertPipeline ( pipeline , renderpass , true ) ;
if ( pipeline ) {
return ;
}
VkShaderModule frag_shader = * convert_depth_to_float_frag ;
const std : : array stages = MakeStages ( * full_screen_vert , frag_shader ) ;
pipeline = device . GetLogical ( ) . CreateGraphicsPipeline ( {
. sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO ,
. pNext = nullptr ,
. flags = 0 ,
. stageCount = static_cast < u32 > ( stages . size ( ) ) ,
. pStages = stages . data ( ) ,
. pVertexInputState = & PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO ,
. pInputAssemblyState = & PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO ,
. pTessellationState = nullptr ,
. pViewportState = & PIPELINE_VIEWPORT_STATE_CREATE_INFO ,
. pRasterizationState = & PIPELINE_RASTERIZATION_STATE_CREATE_INFO ,
. pMultisampleState = & PIPELINE_MULTISAMPLE_STATE_CREATE_INFO ,
. pDepthStencilState = & PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO ,
. pColorBlendState = & PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO ,
. pDynamicState = & PIPELINE_DYNAMIC_STATE_CREATE_INFO ,
. layout = * one_texture_pipeline_layout ,
. renderPass = renderpass ,
. subpass = 0 ,
. basePipelineHandle = VK_NULL_HANDLE ,
. basePipelineIndex = 0 ,
} ) ;
}
}
void BlitImageHelper : : ConvertPipelineEx ( vk : : Pipeline & pipeline , VkRenderPass renderpass ,
void BlitImageHelper : : ConvertPipelineEx ( vk : : Pipeline & pipeline , VkRenderPass renderpass ,
@ -999,4 +1028,36 @@ void BlitImageHelper::ConvertPipelineDepthTargetEx(vk::Pipeline& pipeline, VkRen
ConvertPipelineEx ( pipeline , renderpass , module , true , true ) ;
ConvertPipelineEx ( pipeline , renderpass , module , true , true ) ;
}
}
void BlitImageHelper : : ConvertPipeline ( vk : : Pipeline & pipeline , VkRenderPass renderpass ,
bool is_target_depth ) {
if ( pipeline ) {
return ;
}
VkShaderModule frag_shader =
is_target_depth ? * convert_float_to_depth_frag : * convert_depth_to_float_frag ;
const std : : array stages = MakeStages ( * full_screen_vert , frag_shader ) ;
pipeline = device . GetLogical ( ) . CreateGraphicsPipeline ( {
. sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO ,
. pNext = nullptr ,
. flags = 0 ,
. stageCount = static_cast < u32 > ( stages . size ( ) ) ,
. pStages = stages . data ( ) ,
. pVertexInputState = & PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO ,
. pInputAssemblyState = & PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO ,
. pTessellationState = nullptr ,
. pViewportState = & PIPELINE_VIEWPORT_STATE_CREATE_INFO ,
. pRasterizationState = & PIPELINE_RASTERIZATION_STATE_CREATE_INFO ,
. pMultisampleState = & PIPELINE_MULTISAMPLE_STATE_CREATE_INFO ,
. pDepthStencilState = is_target_depth ? & PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO : nullptr ,
. pColorBlendState = is_target_depth ? & PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO
: & PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO ,
. pDynamicState = & PIPELINE_DYNAMIC_STATE_CREATE_INFO ,
. layout = * one_texture_pipeline_layout ,
. renderPass = renderpass ,
. subpass = 0 ,
. basePipelineHandle = VK_NULL_HANDLE ,
. basePipelineIndex = 0 ,
} ) ;
}
} // namespace Vulkan
} // namespace Vulkan