diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/host_shaders/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_abgr8_to_d24s8.frag | 17 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_d24s8_to_abgr8.frag | 21 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.cpp | 98 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 12 |
6 files changed, 166 insertions, 0 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index d779a967a..fd3e41434 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -10,6 +10,8 @@ set(SHADER_FILES | |||
| 10 | astc_decoder.comp | 10 | astc_decoder.comp |
| 11 | block_linear_unswizzle_2d.comp | 11 | block_linear_unswizzle_2d.comp |
| 12 | block_linear_unswizzle_3d.comp | 12 | block_linear_unswizzle_3d.comp |
| 13 | convert_abgr8_to_d24s8.frag | ||
| 14 | convert_d24s8_to_abgr8.frag | ||
| 13 | convert_depth_to_float.frag | 15 | convert_depth_to_float.frag |
| 14 | convert_float_to_depth.frag | 16 | convert_float_to_depth.frag |
| 15 | full_screen_triangle.vert | 17 | full_screen_triangle.vert |
diff --git a/src/video_core/host_shaders/convert_abgr8_to_d24s8.frag b/src/video_core/host_shaders/convert_abgr8_to_d24s8.frag new file mode 100644 index 000000000..f7657e50a --- /dev/null +++ b/src/video_core/host_shaders/convert_abgr8_to_d24s8.frag | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #version 450 | ||
| 6 | // #extension GL_ARB_shader_stencil_export : require | ||
| 7 | |||
| 8 | layout(binding = 0) uniform sampler2D color_texture; | ||
| 9 | |||
| 10 | void main() { | ||
| 11 | ivec2 coord = ivec2(gl_FragCoord.xy); | ||
| 12 | uvec4 color = uvec4(texelFetch(color_texture, coord, 0).rgba * (exp2(8) - 1.0f)); | ||
| 13 | uint depth_unorm = (color.r << 16) | (color.g << 8) | color.b; | ||
| 14 | |||
| 15 | gl_FragDepth = float(depth_unorm) / (exp2(24.0) - 1.0f); | ||
| 16 | // gl_FragStencilRefARB = int(color.a); | ||
| 17 | } | ||
diff --git a/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag new file mode 100644 index 000000000..ff3bf8209 --- /dev/null +++ b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #version 450 | ||
| 6 | |||
| 7 | layout(binding = 0) uniform sampler2D depth_tex; | ||
| 8 | layout(binding = 1) uniform isampler2D stencil_tex; | ||
| 9 | |||
| 10 | layout(location = 0) out vec4 color; | ||
| 11 | |||
| 12 | void main() { | ||
| 13 | ivec2 coord = ivec2(gl_FragCoord.xy); | ||
| 14 | uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f)); | ||
| 15 | uint stencil = uint(textureLod(stencil_tex, coord, 0).r); | ||
| 16 | |||
| 17 | color.r = float(depth >> 16) / (exp2(8) - 1.0); | ||
| 18 | color.g = float((depth >> 8) & 0x00FF) / (exp2(8) - 1.0); | ||
| 19 | color.b = float(depth & 0x00FF) / (exp2(8) - 1.0); | ||
| 20 | color.a = float(stencil) / (exp2(8) - 1.0); | ||
| 21 | } | ||
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index b3884a4f5..01535d0c0 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | ||
| 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | ||
| 8 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | ||
| 7 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" | 9 | #include "video_core/host_shaders/convert_depth_to_float_frag_spv.h" |
| 8 | #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" | 10 | #include "video_core/host_shaders/convert_float_to_depth_frag_spv.h" |
| 9 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" | 11 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" |
| @@ -354,6 +356,8 @@ BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | |||
| 354 | blit_color_to_color_frag(BuildShader(device, VULKAN_BLIT_COLOR_FLOAT_FRAG_SPV)), | 356 | blit_color_to_color_frag(BuildShader(device, VULKAN_BLIT_COLOR_FLOAT_FRAG_SPV)), |
| 355 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), | 357 | convert_depth_to_float_frag(BuildShader(device, CONVERT_DEPTH_TO_FLOAT_FRAG_SPV)), |
| 356 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), | 358 | convert_float_to_depth_frag(BuildShader(device, CONVERT_FLOAT_TO_DEPTH_FRAG_SPV)), |
| 359 | convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), | ||
| 360 | convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), | ||
| 357 | linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)), | 361 | linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)), |
| 358 | nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) { | 362 | nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) { |
| 359 | if (device.IsExtShaderStencilExportSupported()) { | 363 | if (device.IsExtShaderStencilExportSupported()) { |
| @@ -448,6 +452,23 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, | |||
| 448 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); | 452 | Convert(*convert_r16_to_d16_pipeline, dst_framebuffer, src_image_view, up_scale, down_shift); |
| 449 | } | 453 | } |
| 450 | 454 | ||
| 455 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | ||
| 456 | const ImageView& src_image_view, u32 up_scale, | ||
| 457 | u32 down_shift) { | ||
| 458 | ConvertPipelineEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | ||
| 459 | convert_abgr8_to_d24s8_frag, true); | ||
| 460 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | ||
| 461 | down_shift); | ||
| 462 | } | ||
| 463 | |||
| 464 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | ||
| 465 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | ||
| 466 | ConvertPipelineEx(convert_d24s8_to_abgr8_pipeline, dst_framebuffer->RenderPass(), | ||
| 467 | convert_d24s8_to_abgr8_frag, false); | ||
| 468 | ConvertDepthStencil(*convert_d24s8_to_abgr8_pipeline, dst_framebuffer, src_image_view, up_scale, | ||
| 469 | down_shift); | ||
| 470 | } | ||
| 471 | |||
| 451 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 472 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 452 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 473 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { |
| 453 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | 474 | const VkPipelineLayout layout = *one_texture_pipeline_layout; |
| @@ -495,6 +516,54 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb | |||
| 495 | scheduler.InvalidateState(); | 516 | scheduler.InvalidateState(); |
| 496 | } | 517 | } |
| 497 | 518 | ||
| 519 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 520 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | ||
| 521 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | ||
| 522 | const VkImageView src_depth_view = src_image_view.DepthView(); | ||
| 523 | const VkImageView src_stencil_view = src_image_view.StencilView(); | ||
| 524 | const VkSampler sampler = *nearest_sampler; | ||
| 525 | const VkExtent2D extent{ | ||
| 526 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | ||
| 527 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 528 | }; | ||
| 529 | scheduler.RequestRenderpass(dst_framebuffer); | ||
| 530 | scheduler.Record([pipeline, layout, sampler, src_depth_view, src_stencil_view, extent, up_scale, | ||
| 531 | down_shift, this](vk::CommandBuffer cmdbuf) { | ||
| 532 | const VkOffset2D offset{ | ||
| 533 | .x = 0, | ||
| 534 | .y = 0, | ||
| 535 | }; | ||
| 536 | const VkViewport viewport{ | ||
| 537 | .x = 0.0f, | ||
| 538 | .y = 0.0f, | ||
| 539 | .width = static_cast<float>(extent.width), | ||
| 540 | .height = static_cast<float>(extent.height), | ||
| 541 | .minDepth = 0.0f, | ||
| 542 | .maxDepth = 0.0f, | ||
| 543 | }; | ||
| 544 | const VkRect2D scissor{ | ||
| 545 | .offset = offset, | ||
| 546 | .extent = extent, | ||
| 547 | }; | ||
| 548 | const PushConstants push_constants{ | ||
| 549 | .tex_scale = {viewport.width, viewport.height}, | ||
| 550 | .tex_offset = {0.0f, 0.0f}, | ||
| 551 | }; | ||
| 552 | const VkDescriptorSet descriptor_set = two_textures_descriptor_allocator.Commit(); | ||
| 553 | UpdateTwoTexturesDescriptorSet(device, descriptor_set, sampler, src_depth_view, | ||
| 554 | src_stencil_view); | ||
| 555 | // TODO: Barriers | ||
| 556 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); | ||
| 557 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, | ||
| 558 | nullptr); | ||
| 559 | cmdbuf.SetViewport(0, viewport); | ||
| 560 | cmdbuf.SetScissor(0, scissor); | ||
| 561 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); | ||
| 562 | cmdbuf.Draw(3, 1, 0, 0); | ||
| 563 | }); | ||
| 564 | scheduler.InvalidateState(); | ||
| 565 | } | ||
| 566 | |||
| 498 | VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key) { | 567 | VkPipeline BlitImageHelper::FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key) { |
| 499 | const auto it = std::ranges::find(blit_color_keys, key); | 568 | const auto it = std::ranges::find(blit_color_keys, key); |
| 500 | if (it != blit_color_keys.end()) { | 569 | if (it != blit_color_keys.end()) { |
| @@ -636,4 +705,33 @@ void BlitImageHelper::ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRend | |||
| 636 | }); | 705 | }); |
| 637 | } | 706 | } |
| 638 | 707 | ||
| 708 | void BlitImageHelper::ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | ||
| 709 | vk::ShaderModule& module, bool single_texture) { | ||
| 710 | if (pipeline) { | ||
| 711 | return; | ||
| 712 | } | ||
| 713 | const std::array stages = MakeStages(*full_screen_vert, *module); | ||
| 714 | pipeline = device.GetLogical().CreateGraphicsPipeline({ | ||
| 715 | .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, | ||
| 716 | .pNext = nullptr, | ||
| 717 | .flags = 0, | ||
| 718 | .stageCount = static_cast<u32>(stages.size()), | ||
| 719 | .pStages = stages.data(), | ||
| 720 | .pVertexInputState = &PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, | ||
| 721 | .pInputAssemblyState = &PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, | ||
| 722 | .pTessellationState = nullptr, | ||
| 723 | .pViewportState = &PIPELINE_VIEWPORT_STATE_CREATE_INFO, | ||
| 724 | .pRasterizationState = &PIPELINE_RASTERIZATION_STATE_CREATE_INFO, | ||
| 725 | .pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, | ||
| 726 | .pDepthStencilState = &PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, | ||
| 727 | .pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_EMPTY_CREATE_INFO, | ||
| 728 | .pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO, | ||
| 729 | .layout = single_texture ? *one_texture_pipeline_layout : *two_textures_pipeline_layout, | ||
| 730 | .renderPass = renderpass, | ||
| 731 | .subpass = 0, | ||
| 732 | .basePipelineHandle = VK_NULL_HANDLE, | ||
| 733 | .basePipelineIndex = 0, | ||
| 734 | }); | ||
| 735 | } | ||
| 736 | |||
| 639 | } // namespace Vulkan | 737 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index d77f76678..f754a7294 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -56,10 +56,19 @@ public: | |||
| 56 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | 56 | void ConvertR16ToD16(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, |
| 57 | u32 up_scale, u32 down_shift); | 57 | u32 up_scale, u32 down_shift); |
| 58 | 58 | ||
| 59 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | ||
| 60 | u32 up_scale, u32 down_shift); | ||
| 61 | |||
| 62 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | ||
| 63 | u32 up_scale, u32 down_shift); | ||
| 64 | |||
| 59 | private: | 65 | private: |
| 60 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 66 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 61 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); | 67 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); |
| 62 | 68 | ||
| 69 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 70 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | ||
| 71 | |||
| 63 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); | 72 | [[nodiscard]] VkPipeline FindOrEmplaceColorPipeline(const BlitImagePipelineKey& key); |
| 64 | 73 | ||
| 65 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); | 74 | [[nodiscard]] VkPipeline FindOrEmplaceDepthStencilPipeline(const BlitImagePipelineKey& key); |
| @@ -68,6 +77,9 @@ private: | |||
| 68 | 77 | ||
| 69 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); | 78 | void ConvertColorToDepthPipeline(vk::Pipeline& pipeline, VkRenderPass renderpass); |
| 70 | 79 | ||
| 80 | void ConvertPipelineEx(vk::Pipeline& pipeline, VkRenderPass renderpass, | ||
| 81 | vk::ShaderModule& module, bool single_texture); | ||
| 82 | |||
| 71 | const Device& device; | 83 | const Device& device; |
| 72 | VKScheduler& scheduler; | 84 | VKScheduler& scheduler; |
| 73 | StateTracker& state_tracker; | 85 | StateTracker& state_tracker; |
| @@ -83,6 +95,8 @@ private: | |||
| 83 | vk::ShaderModule blit_depth_stencil_frag; | 95 | vk::ShaderModule blit_depth_stencil_frag; |
| 84 | vk::ShaderModule convert_depth_to_float_frag; | 96 | vk::ShaderModule convert_depth_to_float_frag; |
| 85 | vk::ShaderModule convert_float_to_depth_frag; | 97 | vk::ShaderModule convert_float_to_depth_frag; |
| 98 | vk::ShaderModule convert_abgr8_to_d24s8_frag; | ||
| 99 | vk::ShaderModule convert_d24s8_to_abgr8_frag; | ||
| 86 | vk::Sampler linear_sampler; | 100 | vk::Sampler linear_sampler; |
| 87 | vk::Sampler nearest_sampler; | 101 | vk::Sampler nearest_sampler; |
| 88 | 102 | ||
| @@ -94,6 +108,8 @@ private: | |||
| 94 | vk::Pipeline convert_r32_to_d32_pipeline; | 108 | vk::Pipeline convert_r32_to_d32_pipeline; |
| 95 | vk::Pipeline convert_d16_to_r16_pipeline; | 109 | vk::Pipeline convert_d16_to_r16_pipeline; |
| 96 | vk::Pipeline convert_r16_to_d16_pipeline; | 110 | vk::Pipeline convert_r16_to_d16_pipeline; |
| 111 | vk::Pipeline convert_abgr8_to_d24s8_pipeline; | ||
| 112 | vk::Pipeline convert_d24s8_to_abgr8_pipeline; | ||
| 97 | }; | 113 | }; |
| 98 | 114 | ||
| 99 | } // namespace Vulkan | 115 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 407fd2a15..6dfd45f31 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -881,6 +881,12 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 881 | return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift); | 881 | return blit_image_helper.ConvertD16ToR16(dst, src_view, up_scale, down_shift); |
| 882 | } | 882 | } |
| 883 | break; | 883 | break; |
| 884 | case PixelFormat::A8B8G8R8_UNORM: | ||
| 885 | case PixelFormat::B8G8R8A8_UNORM: | ||
| 886 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | ||
| 887 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); | ||
| 888 | } | ||
| 889 | break; | ||
| 884 | case PixelFormat::R32_FLOAT: | 890 | case PixelFormat::R32_FLOAT: |
| 885 | if (src_view.format == PixelFormat::D32_FLOAT) { | 891 | if (src_view.format == PixelFormat::D32_FLOAT) { |
| 886 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); | 892 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); |
| @@ -891,6 +897,12 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 891 | return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift); | 897 | return blit_image_helper.ConvertR16ToD16(dst, src_view, up_scale, down_shift); |
| 892 | } | 898 | } |
| 893 | break; | 899 | break; |
| 900 | case PixelFormat::S8_UINT_D24_UNORM: | ||
| 901 | if (src_view.format == PixelFormat::A8B8G8R8_UNORM || | ||
| 902 | src_view.format == PixelFormat::B8G8R8A8_UNORM) { | ||
| 903 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); | ||
| 904 | } | ||
| 905 | break; | ||
| 894 | case PixelFormat::D32_FLOAT: | 906 | case PixelFormat::D32_FLOAT: |
| 895 | if (src_view.format == PixelFormat::R32_FLOAT) { | 907 | if (src_view.format == PixelFormat::R32_FLOAT) { |
| 896 | return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift); | 908 | return blit_image_helper.ConvertR32ToD32(dst, src_view, up_scale, down_shift); |