diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/host_shaders/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_abgr8_to_d24s8.frag | 9 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag | 19 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_d24s8_to_abgr8.frag | 10 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_d24s8_to_b10g11r11.frag | 21 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_d24s8_to_r16g16.frag | 21 | ||||
| -rw-r--r-- | src/video_core/host_shaders/convert_r16g16_to_d24s8.frag | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.cpp | 98 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/blit_image.h | 25 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 44 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 96 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache_base.h | 3 | ||||
| -rw-r--r-- | src/video_core/texture_cache/util.cpp | 20 |
14 files changed, 168 insertions, 223 deletions
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 1c91999d7..fd3e41434 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -11,13 +11,9 @@ set(SHADER_FILES | |||
| 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 | 13 | convert_abgr8_to_d24s8.frag |
| 14 | convert_b10g11r11_to_d24s8.frag | ||
| 15 | convert_d24s8_to_abgr8.frag | 14 | convert_d24s8_to_abgr8.frag |
| 16 | convert_d24s8_to_b10g11r11.frag | ||
| 17 | convert_d24s8_to_r16g16.frag | ||
| 18 | convert_depth_to_float.frag | 15 | convert_depth_to_float.frag |
| 19 | convert_float_to_depth.frag | 16 | convert_float_to_depth.frag |
| 20 | convert_r16g16_to_d24s8.frag | ||
| 21 | full_screen_triangle.vert | 17 | full_screen_triangle.vert |
| 22 | fxaa.frag | 18 | fxaa.frag |
| 23 | fxaa.vert | 19 | fxaa.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 index 4e4ab6a26..ea055ddad 100644 --- a/src/video_core/host_shaders/convert_abgr8_to_d24s8.frag +++ b/src/video_core/host_shaders/convert_abgr8_to_d24s8.frag | |||
| @@ -9,9 +9,10 @@ layout(binding = 0) uniform sampler2D color_texture; | |||
| 9 | 9 | ||
| 10 | void main() { | 10 | void main() { |
| 11 | ivec2 coord = ivec2(gl_FragCoord.xy); | 11 | ivec2 coord = ivec2(gl_FragCoord.xy); |
| 12 | uvec4 color = uvec4(texelFetch(color_texture, coord, 0).rgba * (exp2(8) - 1.0f)); | 12 | uvec4 color = uvec4(texelFetch(color_texture, coord, 0).abgr * (exp2(8) - 1.0f)); |
| 13 | uint depth_unorm = (color.r << 16) | (color.g << 8) | color.b; | 13 | uvec4 bytes = color << uvec4(24, 16, 8, 0); |
| 14 | uint depth_stencil_unorm = bytes.x | bytes.y | bytes.z | bytes.w; | ||
| 14 | 15 | ||
| 15 | gl_FragDepth = float(depth_unorm) / (exp2(24.0) - 1.0f); | 16 | gl_FragDepth = float(depth_stencil_unorm & 0x00FFFFFFu) / (exp2(24.0) - 1.0f); |
| 16 | gl_FragStencilRefARB = int(color.a); | 17 | gl_FragStencilRefARB = int(depth_stencil_unorm >> 24); |
| 17 | } | 18 | } |
diff --git a/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag b/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag deleted file mode 100644 index 2999a84cf..000000000 --- a/src/video_core/host_shaders/convert_b10g11r11_to_d24s8.frag +++ /dev/null | |||
| @@ -1,19 +0,0 @@ | |||
| 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 | vec4 color = texelFetch(color_texture, coord, 0).rgba; | ||
| 13 | uint depth_stencil_unorm = (uint(color.b * (exp2(10) - 1.0f)) << 22) | ||
| 14 | | (uint(color.g * (exp2(11) - 1.0f)) << 11) | ||
| 15 | | (uint(color.r * (exp2(11) - 1.0f))); | ||
| 16 | |||
| 17 | gl_FragDepth = float(depth_stencil_unorm >> 8) / (exp2(24.0) - 1.0f); | ||
| 18 | gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FF); | ||
| 19 | } | ||
diff --git a/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag index ff3bf8209..94368fb59 100644 --- a/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag +++ b/src/video_core/host_shaders/convert_d24s8_to_abgr8.frag | |||
| @@ -14,8 +14,10 @@ void main() { | |||
| 14 | uint depth = uint(textureLod(depth_tex, coord, 0).r * (exp2(24.0) - 1.0f)); | 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); | 15 | uint stencil = uint(textureLod(stencil_tex, coord, 0).r); |
| 16 | 16 | ||
| 17 | color.r = float(depth >> 16) / (exp2(8) - 1.0); | 17 | highp uint depth_val = |
| 18 | color.g = float((depth >> 8) & 0x00FF) / (exp2(8) - 1.0); | 18 | uint(textureLod(depth_tex, coord, 0).r * (exp2(32.0) - 1.0)); |
| 19 | color.b = float(depth & 0x00FF) / (exp2(8) - 1.0); | 19 | lowp uint stencil_val = textureLod(stencil_tex, coord, 0).r; |
| 20 | color.a = float(stencil) / (exp2(8) - 1.0); | 20 | highp uvec4 components = |
| 21 | uvec4(stencil_val, (uvec3(depth_val) >> uvec3(24u, 16u, 8u)) & 0x000000FFu); | ||
| 22 | color.abgr = vec4(components) / (exp2(8.0) - 1.0); | ||
| 21 | } | 23 | } |
diff --git a/src/video_core/host_shaders/convert_d24s8_to_b10g11r11.frag b/src/video_core/host_shaders/convert_d24s8_to_b10g11r11.frag deleted file mode 100644 index c743d3a13..000000000 --- a/src/video_core/host_shaders/convert_d24s8_to_b10g11r11.frag +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 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.b = float(depth >> 22) / (exp2(10) - 1.0); | ||
| 18 | color.g = float((depth >> 11) & 0x00FF) / (exp2(11) - 1.0); | ||
| 19 | color.r = float(depth & 0x00FF) / (exp2(11) - 1.0); | ||
| 20 | color.a = 1.0f; | ||
| 21 | } | ||
diff --git a/src/video_core/host_shaders/convert_d24s8_to_r16g16.frag b/src/video_core/host_shaders/convert_d24s8_to_r16g16.frag deleted file mode 100644 index 2a9443d3d..000000000 --- a/src/video_core/host_shaders/convert_d24s8_to_r16g16.frag +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 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(16) - 1.0); | ||
| 18 | color.g = float((depth >> 16) & 0x00FF) / (exp2(16) - 1.0); | ||
| 19 | color.b = 0.0f; | ||
| 20 | color.a = 1.0f; | ||
| 21 | } | ||
diff --git a/src/video_core/host_shaders/convert_r16g16_to_d24s8.frag b/src/video_core/host_shaders/convert_r16g16_to_d24s8.frag deleted file mode 100644 index 3df70575e..000000000 --- a/src/video_core/host_shaders/convert_r16g16_to_d24s8.frag +++ /dev/null | |||
| @@ -1,18 +0,0 @@ | |||
| 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 | vec4 color = texelFetch(color_texture, coord, 0).rgba; | ||
| 13 | uint depth_stencil_unorm = (uint(color.r * (exp2(16) - 1.0f)) << 16) | ||
| 14 | | (uint(color.g * (exp2(16) - 1.0f)) << 16); | ||
| 15 | |||
| 16 | gl_FragDepth = float(depth_stencil_unorm >> 8) / (exp2(24.0) - 1.0f); | ||
| 17 | gl_FragStencilRefARB = int(depth_stencil_unorm & 0x00FF); | ||
| 18 | } | ||
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp index a63d4d222..9a38b6b34 100644 --- a/src/video_core/renderer_vulkan/blit_image.cpp +++ b/src/video_core/renderer_vulkan/blit_image.cpp | |||
| @@ -5,13 +5,9 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | 6 | ||
| 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" | 7 | #include "video_core/host_shaders/convert_abgr8_to_d24s8_frag_spv.h" |
| 8 | #include "video_core/host_shaders/convert_b10g11r11_to_d24s8_frag_spv.h" | ||
| 9 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" | 8 | #include "video_core/host_shaders/convert_d24s8_to_abgr8_frag_spv.h" |
| 10 | #include "video_core/host_shaders/convert_d24s8_to_b10g11r11_frag_spv.h" | ||
| 11 | #include "video_core/host_shaders/convert_d24s8_to_r16g16_frag_spv.h" | ||
| 12 | #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" |
| 13 | #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" |
| 14 | #include "video_core/host_shaders/convert_r16g16_to_d24s8_frag_spv.h" | ||
| 15 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" | 11 | #include "video_core/host_shaders/full_screen_triangle_vert_spv.h" |
| 16 | #include "video_core/host_shaders/vulkan_blit_color_float_frag_spv.h" | 12 | #include "video_core/host_shaders/vulkan_blit_color_float_frag_spv.h" |
| 17 | #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" | 13 | #include "video_core/host_shaders/vulkan_blit_depth_stencil_frag_spv.h" |
| @@ -361,11 +357,7 @@ BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, | |||
| 361 | 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)), |
| 362 | 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)), |
| 363 | convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), | 359 | convert_abgr8_to_d24s8_frag(BuildShader(device, CONVERT_ABGR8_TO_D24S8_FRAG_SPV)), |
| 364 | convert_b10g11r11_to_d24s8_frag(BuildShader(device, CONVERT_B10G11R11_TO_D24S8_FRAG_SPV)), | ||
| 365 | convert_r16g16_to_d24s8_frag(BuildShader(device, CONVERT_R16G16_TO_D24S8_FRAG_SPV)), | ||
| 366 | convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), | 360 | convert_d24s8_to_abgr8_frag(BuildShader(device, CONVERT_D24S8_TO_ABGR8_FRAG_SPV)), |
| 367 | convert_d24s8_to_b10g11r11_frag(BuildShader(device, CONVERT_D24S8_TO_B10G11R11_FRAG_SPV)), | ||
| 368 | convert_d24s8_to_r16g16_frag(BuildShader(device, CONVERT_D24S8_TO_R16G16_FRAG_SPV)), | ||
| 369 | linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)), | 361 | linear_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_LINEAR>)), |
| 370 | nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) { | 362 | nearest_sampler(device.GetLogical().CreateSampler(SAMPLER_CREATE_INFO<VK_FILTER_NEAREST>)) { |
| 371 | if (device.IsExtShaderStencilExportSupported()) { | 363 | if (device.IsExtShaderStencilExportSupported()) { |
| @@ -461,30 +453,11 @@ void BlitImageHelper::ConvertR16ToD16(const Framebuffer* dst_framebuffer, | |||
| 461 | } | 453 | } |
| 462 | 454 | ||
| 463 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, | 455 | void BlitImageHelper::ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, |
| 464 | const ImageView& src_image_view, u32 up_scale, | 456 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { |
| 465 | u32 down_shift) { | ||
| 466 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | 457 | ConvertPipelineDepthTargetEx(convert_abgr8_to_d24s8_pipeline, dst_framebuffer->RenderPass(), |
| 467 | convert_abgr8_to_d24s8_frag, true); | 458 | convert_abgr8_to_d24s8_frag, true); |
| 468 | Convert(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | 459 | ConvertColor(*convert_abgr8_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, |
| 469 | down_shift); | 460 | down_shift); |
| 470 | } | ||
| 471 | |||
| 472 | void BlitImageHelper::ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer, | ||
| 473 | const ImageView& src_image_view, u32 up_scale, | ||
| 474 | u32 down_shift) { | ||
| 475 | ConvertPipelineDepthTargetEx(convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | ||
| 476 | convert_b10g11r11_to_d24s8_frag, true); | ||
| 477 | Convert(*convert_b10g11r11_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | ||
| 478 | down_shift); | ||
| 479 | } | ||
| 480 | |||
| 481 | void BlitImageHelper::ConvertR16G16ToD24S8(const Framebuffer* dst_framebuffer, | ||
| 482 | const ImageView& src_image_view, u32 up_scale, | ||
| 483 | u32 down_shift) { | ||
| 484 | ConvertPipelineDepthTargetEx(convert_r16g16_to_d24s8_pipeline, dst_framebuffer->RenderPass(), | ||
| 485 | convert_r16g16_to_d24s8_frag, true); | ||
| 486 | Convert(*convert_r16g16_to_d24s8_pipeline, dst_framebuffer, src_image_view, up_scale, | ||
| 487 | down_shift); | ||
| 488 | } | 461 | } |
| 489 | 462 | ||
| 490 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | 463 | void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, |
| @@ -495,24 +468,6 @@ void BlitImageHelper::ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, | |||
| 495 | down_shift); | 468 | down_shift); |
| 496 | } | 469 | } |
| 497 | 470 | ||
| 498 | void BlitImageHelper::ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer, | ||
| 499 | ImageView& src_image_view, u32 up_scale, | ||
| 500 | u32 down_shift) { | ||
| 501 | ConvertPipelineColorTargetEx(convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer->RenderPass(), | ||
| 502 | convert_d24s8_to_b10g11r11_frag, false); | ||
| 503 | ConvertDepthStencil(*convert_d24s8_to_b10g11r11_pipeline, dst_framebuffer, src_image_view, | ||
| 504 | up_scale, down_shift); | ||
| 505 | } | ||
| 506 | |||
| 507 | void BlitImageHelper::ConvertD24S8ToR16G16(const Framebuffer* dst_framebuffer, | ||
| 508 | ImageView& src_image_view, u32 up_scale, | ||
| 509 | u32 down_shift) { | ||
| 510 | ConvertPipelineColorTargetEx(convert_d24s8_to_r16g16_pipeline, dst_framebuffer->RenderPass(), | ||
| 511 | convert_d24s8_to_r16g16_frag, false); | ||
| 512 | ConvertDepthStencil(*convert_d24s8_to_r16g16_pipeline, dst_framebuffer, src_image_view, | ||
| 513 | up_scale, down_shift); | ||
| 514 | } | ||
| 515 | |||
| 516 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 471 | void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 517 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 472 | const ImageView& src_image_view, u32 up_scale, u32 down_shift) { |
| 518 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | 473 | const VkPipelineLayout layout = *one_texture_pipeline_layout; |
| @@ -560,6 +515,53 @@ void BlitImageHelper::Convert(VkPipeline pipeline, const Framebuffer* dst_frameb | |||
| 560 | scheduler.InvalidateState(); | 515 | scheduler.InvalidateState(); |
| 561 | } | 516 | } |
| 562 | 517 | ||
| 518 | void BlitImageHelper::ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 519 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | ||
| 520 | const VkPipelineLayout layout = *one_texture_pipeline_layout; | ||
| 521 | const VkImageView src_view = src_image_view.ColorView(); | ||
| 522 | const VkSampler sampler = *nearest_sampler; | ||
| 523 | const VkExtent2D extent{ | ||
| 524 | .width = std::max((src_image_view.size.width * up_scale) >> down_shift, 1U), | ||
| 525 | .height = std::max((src_image_view.size.height * up_scale) >> down_shift, 1U), | ||
| 526 | }; | ||
| 527 | scheduler.RequestRenderpass(dst_framebuffer); | ||
| 528 | scheduler.Record([pipeline, layout, sampler, src_view, extent, up_scale, down_shift, | ||
| 529 | this](vk::CommandBuffer cmdbuf) { | ||
| 530 | const VkOffset2D offset{ | ||
| 531 | .x = 0, | ||
| 532 | .y = 0, | ||
| 533 | }; | ||
| 534 | const VkViewport viewport{ | ||
| 535 | .x = 0.0f, | ||
| 536 | .y = 0.0f, | ||
| 537 | .width = static_cast<float>(extent.width), | ||
| 538 | .height = static_cast<float>(extent.height), | ||
| 539 | .minDepth = 0.0f, | ||
| 540 | .maxDepth = 0.0f, | ||
| 541 | }; | ||
| 542 | const VkRect2D scissor{ | ||
| 543 | .offset = offset, | ||
| 544 | .extent = extent, | ||
| 545 | }; | ||
| 546 | const PushConstants push_constants{ | ||
| 547 | .tex_scale = {viewport.width, viewport.height}, | ||
| 548 | .tex_offset = {0.0f, 0.0f}, | ||
| 549 | }; | ||
| 550 | const VkDescriptorSet descriptor_set = one_texture_descriptor_allocator.Commit(); | ||
| 551 | UpdateOneTextureDescriptorSet(device, descriptor_set, sampler, src_view); | ||
| 552 | |||
| 553 | // TODO: Barriers | ||
| 554 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); | ||
| 555 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, descriptor_set, | ||
| 556 | nullptr); | ||
| 557 | cmdbuf.SetViewport(0, viewport); | ||
| 558 | cmdbuf.SetScissor(0, scissor); | ||
| 559 | cmdbuf.PushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT, push_constants); | ||
| 560 | cmdbuf.Draw(3, 1, 0, 0); | ||
| 561 | }); | ||
| 562 | scheduler.InvalidateState(); | ||
| 563 | } | ||
| 564 | |||
| 563 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 565 | void BlitImageHelper::ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 564 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { | 566 | ImageView& src_image_view, u32 up_scale, u32 down_shift) { |
| 565 | const VkPipelineLayout layout = *two_textures_pipeline_layout; | 567 | const VkPipelineLayout layout = *two_textures_pipeline_layout; |
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h index 3455c75f4..b1a717090 100644 --- a/src/video_core/renderer_vulkan/blit_image.h +++ b/src/video_core/renderer_vulkan/blit_image.h | |||
| @@ -56,28 +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, | 59 | void ConvertABGR8ToD24S8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, |
| 60 | u32 up_scale, u32 down_shift); | 60 | u32 up_scale, u32 down_shift); |
| 61 | 61 | ||
| 62 | void ConvertB10G11R11ToD24S8(const Framebuffer* dst_framebuffer, | ||
| 63 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); | ||
| 64 | |||
| 65 | void ConvertR16G16ToD24S8(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, | ||
| 66 | u32 up_scale, u32 down_shift); | ||
| 67 | |||
| 68 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | 62 | void ConvertD24S8ToABGR8(const Framebuffer* dst_framebuffer, ImageView& src_image_view, |
| 69 | u32 up_scale, u32 down_shift); | 63 | u32 up_scale, u32 down_shift); |
| 70 | 64 | ||
| 71 | void ConvertD24S8ToB10G11R11(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | ||
| 72 | u32 up_scale, u32 down_shift); | ||
| 73 | |||
| 74 | void ConvertD24S8ToR16G16(const Framebuffer* dst_framebuffer, ImageView& src_image_view, | ||
| 75 | u32 up_scale, u32 down_shift); | ||
| 76 | |||
| 77 | private: | 65 | private: |
| 78 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 66 | void Convert(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 79 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); | 67 | const ImageView& src_image_view, u32 up_scale, u32 down_shift); |
| 80 | 68 | ||
| 69 | void ConvertColor(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | ||
| 70 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | ||
| 71 | |||
| 81 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, | 72 | void ConvertDepthStencil(VkPipeline pipeline, const Framebuffer* dst_framebuffer, |
| 82 | ImageView& src_image_view, u32 up_scale, u32 down_shift); | 73 | ImageView& src_image_view, u32 up_scale, u32 down_shift); |
| 83 | 74 | ||
| @@ -114,11 +105,7 @@ private: | |||
| 114 | vk::ShaderModule convert_depth_to_float_frag; | 105 | vk::ShaderModule convert_depth_to_float_frag; |
| 115 | vk::ShaderModule convert_float_to_depth_frag; | 106 | vk::ShaderModule convert_float_to_depth_frag; |
| 116 | vk::ShaderModule convert_abgr8_to_d24s8_frag; | 107 | vk::ShaderModule convert_abgr8_to_d24s8_frag; |
| 117 | vk::ShaderModule convert_b10g11r11_to_d24s8_frag; | ||
| 118 | vk::ShaderModule convert_r16g16_to_d24s8_frag; | ||
| 119 | vk::ShaderModule convert_d24s8_to_abgr8_frag; | 108 | vk::ShaderModule convert_d24s8_to_abgr8_frag; |
| 120 | vk::ShaderModule convert_d24s8_to_b10g11r11_frag; | ||
| 121 | vk::ShaderModule convert_d24s8_to_r16g16_frag; | ||
| 122 | vk::Sampler linear_sampler; | 109 | vk::Sampler linear_sampler; |
| 123 | vk::Sampler nearest_sampler; | 110 | vk::Sampler nearest_sampler; |
| 124 | 111 | ||
| @@ -131,11 +118,7 @@ private: | |||
| 131 | vk::Pipeline convert_d16_to_r16_pipeline; | 118 | vk::Pipeline convert_d16_to_r16_pipeline; |
| 132 | vk::Pipeline convert_r16_to_d16_pipeline; | 119 | vk::Pipeline convert_r16_to_d16_pipeline; |
| 133 | vk::Pipeline convert_abgr8_to_d24s8_pipeline; | 120 | vk::Pipeline convert_abgr8_to_d24s8_pipeline; |
| 134 | vk::Pipeline convert_b10g11r11_to_d24s8_pipeline; | ||
| 135 | vk::Pipeline convert_r16g16_to_d24s8_pipeline; | ||
| 136 | vk::Pipeline convert_d24s8_to_abgr8_pipeline; | 121 | vk::Pipeline convert_d24s8_to_abgr8_pipeline; |
| 137 | vk::Pipeline convert_d24s8_to_b10g11r11_pipeline; | ||
| 138 | vk::Pipeline convert_d24s8_to_r16g16_pipeline; | ||
| 139 | }; | 122 | }; |
| 140 | 123 | ||
| 141 | } // namespace Vulkan | 124 | } // 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 c72f0c897..197cba8e3 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp | |||
| @@ -775,8 +775,18 @@ StagingBufferRef TextureCacheRuntime::DownloadStagingBuffer(size_t size) { | |||
| 775 | 775 | ||
| 776 | bool TextureCacheRuntime::ShouldReinterpret(Image& dst, Image& src) { | 776 | bool TextureCacheRuntime::ShouldReinterpret(Image& dst, Image& src) { |
| 777 | if (VideoCore::Surface::GetFormatType(dst.info.format) == | 777 | if (VideoCore::Surface::GetFormatType(dst.info.format) == |
| 778 | VideoCore::Surface::SurfaceType::DepthStencil) { | 778 | VideoCore::Surface::SurfaceType::DepthStencil && |
| 779 | return !device.IsExtShaderStencilExportSupported(); | 779 | !device.IsExtShaderStencilExportSupported()) { |
| 780 | return true; | ||
| 781 | } | ||
| 782 | if (VideoCore::Surface::GetFormatType(src.info.format) == | ||
| 783 | VideoCore::Surface::SurfaceType::DepthStencil && | ||
| 784 | !device.IsExtShaderStencilExportSupported()) { | ||
| 785 | return true; | ||
| 786 | } | ||
| 787 | if (dst.info.format == PixelFormat::D32_FLOAT_S8_UINT || | ||
| 788 | src.info.format == PixelFormat::D32_FLOAT_S8_UINT) { | ||
| 789 | return true; | ||
| 780 | } | 790 | } |
| 781 | return false; | 791 | return false; |
| 782 | } | 792 | } |
| @@ -1058,21 +1068,10 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 1058 | } | 1068 | } |
| 1059 | break; | 1069 | break; |
| 1060 | case PixelFormat::A8B8G8R8_UNORM: | 1070 | case PixelFormat::A8B8G8R8_UNORM: |
| 1061 | case PixelFormat::B8G8R8A8_UNORM: | ||
| 1062 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | 1071 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { |
| 1063 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); | 1072 | return blit_image_helper.ConvertD24S8ToABGR8(dst, src_view, up_scale, down_shift); |
| 1064 | } | 1073 | } |
| 1065 | break; | 1074 | break; |
| 1066 | case PixelFormat::B10G11R11_FLOAT: | ||
| 1067 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | ||
| 1068 | return blit_image_helper.ConvertD24S8ToB10G11R11(dst, src_view, up_scale, down_shift); | ||
| 1069 | } | ||
| 1070 | break; | ||
| 1071 | case PixelFormat::R16G16_UNORM: | ||
| 1072 | if (src_view.format == PixelFormat::S8_UINT_D24_UNORM) { | ||
| 1073 | return blit_image_helper.ConvertD24S8ToR16G16(dst, src_view, up_scale, down_shift); | ||
| 1074 | } | ||
| 1075 | break; | ||
| 1076 | case PixelFormat::R32_FLOAT: | 1075 | case PixelFormat::R32_FLOAT: |
| 1077 | if (src_view.format == PixelFormat::D32_FLOAT) { | 1076 | if (src_view.format == PixelFormat::D32_FLOAT) { |
| 1078 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); | 1077 | return blit_image_helper.ConvertD32ToR32(dst, src_view, up_scale, down_shift); |
| @@ -1084,16 +1083,7 @@ void TextureCacheRuntime::ConvertImage(Framebuffer* dst, ImageView& dst_view, Im | |||
| 1084 | } | 1083 | } |
| 1085 | break; | 1084 | break; |
| 1086 | case PixelFormat::S8_UINT_D24_UNORM: | 1085 | case PixelFormat::S8_UINT_D24_UNORM: |
| 1087 | if (src_view.format == PixelFormat::A8B8G8R8_UNORM || | 1086 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); |
| 1088 | src_view.format == PixelFormat::B8G8R8A8_UNORM) { | ||
| 1089 | return blit_image_helper.ConvertABGR8ToD24S8(dst, src_view, up_scale, down_shift); | ||
| 1090 | } | ||
| 1091 | if (src_view.format == PixelFormat::B10G11R11_FLOAT) { | ||
| 1092 | return blit_image_helper.ConvertB10G11R11ToD24S8(dst, src_view, up_scale, down_shift); | ||
| 1093 | } | ||
| 1094 | if (src_view.format == PixelFormat::R16G16_UNORM) { | ||
| 1095 | return blit_image_helper.ConvertR16G16ToD24S8(dst, src_view, up_scale, down_shift); | ||
| 1096 | } | ||
| 1097 | break; | 1087 | break; |
| 1098 | case PixelFormat::D32_FLOAT: | 1088 | case PixelFormat::D32_FLOAT: |
| 1099 | if (src_view.format == PixelFormat::R32_FLOAT) { | 1089 | if (src_view.format == PixelFormat::R32_FLOAT) { |
| @@ -1590,6 +1580,14 @@ VkImageView ImageView::StencilView() { | |||
| 1590 | return *stencil_view; | 1580 | return *stencil_view; |
| 1591 | } | 1581 | } |
| 1592 | 1582 | ||
| 1583 | VkImageView ImageView::ColorView() { | ||
| 1584 | if (color_view) { | ||
| 1585 | return *color_view; | ||
| 1586 | } | ||
| 1587 | color_view = MakeView(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT); | ||
| 1588 | return *color_view; | ||
| 1589 | } | ||
| 1590 | |||
| 1593 | VkImageView ImageView::StorageView(Shader::TextureType texture_type, | 1591 | VkImageView ImageView::StorageView(Shader::TextureType texture_type, |
| 1594 | Shader::ImageFormat image_format) { | 1592 | Shader::ImageFormat image_format) { |
| 1595 | if (image_format == Shader::ImageFormat::Typeless) { | 1593 | if (image_format == Shader::ImageFormat::Typeless) { |
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h index 44e9dcee4..753e3e8a1 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.h +++ b/src/video_core/renderer_vulkan/vk_texture_cache.h | |||
| @@ -184,6 +184,8 @@ public: | |||
| 184 | 184 | ||
| 185 | [[nodiscard]] VkImageView StencilView(); | 185 | [[nodiscard]] VkImageView StencilView(); |
| 186 | 186 | ||
| 187 | [[nodiscard]] VkImageView ColorView(); | ||
| 188 | |||
| 187 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, | 189 | [[nodiscard]] VkImageView StorageView(Shader::TextureType texture_type, |
| 188 | Shader::ImageFormat image_format); | 190 | Shader::ImageFormat image_format); |
| 189 | 191 | ||
| @@ -224,6 +226,7 @@ private: | |||
| 224 | std::unique_ptr<StorageViews> storage_views; | 226 | std::unique_ptr<StorageViews> storage_views; |
| 225 | vk::ImageView depth_view; | 227 | vk::ImageView depth_view; |
| 226 | vk::ImageView stencil_view; | 228 | vk::ImageView stencil_view; |
| 229 | vk::ImageView color_view; | ||
| 227 | VkImage image_handle = VK_NULL_HANDLE; | 230 | VkImage image_handle = VK_NULL_HANDLE; |
| 228 | VkImageView render_target = VK_NULL_HANDLE; | 231 | VkImageView render_target = VK_NULL_HANDLE; |
| 229 | VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; | 232 | VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 44a0d42ba..565b99254 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -472,7 +472,7 @@ template <class P> | |||
| 472 | void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, | 472 | void TextureCache<P>::BlitImage(const Tegra::Engines::Fermi2D::Surface& dst, |
| 473 | const Tegra::Engines::Fermi2D::Surface& src, | 473 | const Tegra::Engines::Fermi2D::Surface& src, |
| 474 | const Tegra::Engines::Fermi2D::Config& copy) { | 474 | const Tegra::Engines::Fermi2D::Config& copy) { |
| 475 | const BlitImages images = GetBlitImages(dst, src); | 475 | const BlitImages images = GetBlitImages(dst, src, copy); |
| 476 | const ImageId dst_id = images.dst_id; | 476 | const ImageId dst_id = images.dst_id; |
| 477 | const ImageId src_id = images.src_id; | 477 | const ImageId src_id = images.src_id; |
| 478 | 478 | ||
| @@ -762,12 +762,15 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, | |||
| 762 | const bool broken_views = | 762 | const bool broken_views = |
| 763 | runtime.HasBrokenTextureViewFormats() || True(options & RelaxedOptions::ForceBrokenViews); | 763 | runtime.HasBrokenTextureViewFormats() || True(options & RelaxedOptions::ForceBrokenViews); |
| 764 | const bool native_bgr = runtime.HasNativeBgr(); | 764 | const bool native_bgr = runtime.HasNativeBgr(); |
| 765 | ImageId image_id; | 765 | const bool flexible_formats = True(options & RelaxedOptions::Format); |
| 766 | ImageId image_id{}; | ||
| 767 | boost::container::small_vector<ImageId, 1> image_ids; | ||
| 766 | const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) { | 768 | const auto lambda = [&](ImageId existing_image_id, ImageBase& existing_image) { |
| 767 | if (True(existing_image.flags & ImageFlagBits::Remapped)) { | 769 | if (True(existing_image.flags & ImageFlagBits::Remapped)) { |
| 768 | return false; | 770 | return false; |
| 769 | } | 771 | } |
| 770 | if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) { | 772 | if (info.type == ImageType::Linear || existing_image.info.type == ImageType::Linear) |
| 773 | [[unlikely]] { | ||
| 771 | const bool strict_size = False(options & RelaxedOptions::Size) && | 774 | const bool strict_size = False(options & RelaxedOptions::Size) && |
| 772 | True(existing_image.flags & ImageFlagBits::Strong); | 775 | True(existing_image.flags & ImageFlagBits::Strong); |
| 773 | const ImageInfo& existing = existing_image.info; | 776 | const ImageInfo& existing = existing_image.info; |
| @@ -776,17 +779,27 @@ ImageId TextureCache<P>::FindImage(const ImageInfo& info, GPUVAddr gpu_addr, | |||
| 776 | IsPitchLinearSameSize(existing, info, strict_size) && | 779 | IsPitchLinearSameSize(existing, info, strict_size) && |
| 777 | IsViewCompatible(existing.format, info.format, broken_views, native_bgr)) { | 780 | IsViewCompatible(existing.format, info.format, broken_views, native_bgr)) { |
| 778 | image_id = existing_image_id; | 781 | image_id = existing_image_id; |
| 779 | return true; | 782 | image_ids.push_back(existing_image_id); |
| 783 | return !flexible_formats && existing.format == info.format; | ||
| 780 | } | 784 | } |
| 781 | } else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views, | 785 | } else if (IsSubresource(info, existing_image, gpu_addr, options, broken_views, |
| 782 | native_bgr)) { | 786 | native_bgr)) { |
| 783 | image_id = existing_image_id; | 787 | image_id = existing_image_id; |
| 784 | return true; | 788 | image_ids.push_back(existing_image_id); |
| 789 | return !flexible_formats && existing_image.info.format == info.format; | ||
| 785 | } | 790 | } |
| 786 | return false; | 791 | return false; |
| 787 | }; | 792 | }; |
| 788 | ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda); | 793 | ForEachImageInRegion(*cpu_addr, CalculateGuestSizeInBytes(info), lambda); |
| 789 | return image_id; | 794 | if (image_ids.size() <= 1) [[likely]] { |
| 795 | return image_id; | ||
| 796 | } | ||
| 797 | auto image_ids_compare = [this](ImageId a, ImageId b) { | ||
| 798 | auto& image_a = slot_images[a]; | ||
| 799 | auto& image_b = slot_images[b]; | ||
| 800 | return image_a.modification_tick < image_b.modification_tick; | ||
| 801 | }; | ||
| 802 | return *std::ranges::max_element(image_ids, image_ids_compare); | ||
| 790 | } | 803 | } |
| 791 | 804 | ||
| 792 | template <class P> | 805 | template <class P> |
| @@ -1078,32 +1091,58 @@ ImageId TextureCache<P>::JoinImages(const ImageInfo& info, GPUVAddr gpu_addr, VA | |||
| 1078 | 1091 | ||
| 1079 | template <class P> | 1092 | template <class P> |
| 1080 | typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages( | 1093 | typename TextureCache<P>::BlitImages TextureCache<P>::GetBlitImages( |
| 1081 | const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src) { | 1094 | const Tegra::Engines::Fermi2D::Surface& dst, const Tegra::Engines::Fermi2D::Surface& src, |
| 1082 | static constexpr auto FIND_OPTIONS = RelaxedOptions::Format | RelaxedOptions::Samples; | 1095 | const Tegra::Engines::Fermi2D::Config& copy) { |
| 1096 | |||
| 1097 | static constexpr auto FIND_OPTIONS = RelaxedOptions::Samples; | ||
| 1083 | const GPUVAddr dst_addr = dst.Address(); | 1098 | const GPUVAddr dst_addr = dst.Address(); |
| 1084 | const GPUVAddr src_addr = src.Address(); | 1099 | const GPUVAddr src_addr = src.Address(); |
| 1085 | ImageInfo dst_info(dst); | 1100 | ImageInfo dst_info(dst); |
| 1086 | ImageInfo src_info(src); | 1101 | ImageInfo src_info(src); |
| 1102 | const bool can_be_depth_blit = | ||
| 1103 | dst_info.format == src_info.format && copy.filter == Tegra::Engines::Fermi2D::Filter::Point; | ||
| 1087 | ImageId dst_id; | 1104 | ImageId dst_id; |
| 1088 | ImageId src_id; | 1105 | ImageId src_id; |
| 1106 | RelaxedOptions try_options = FIND_OPTIONS; | ||
| 1107 | if (can_be_depth_blit) { | ||
| 1108 | try_options |= RelaxedOptions::Format; | ||
| 1109 | } | ||
| 1089 | do { | 1110 | do { |
| 1090 | has_deleted_images = false; | 1111 | has_deleted_images = false; |
| 1091 | dst_id = FindImage(dst_info, dst_addr, FIND_OPTIONS); | 1112 | src_id = FindImage(src_info, src_addr, try_options); |
| 1092 | src_id = FindImage(src_info, src_addr, FIND_OPTIONS); | 1113 | dst_id = FindImage(dst_info, dst_addr, try_options); |
| 1093 | const ImageBase* const dst_image = dst_id ? &slot_images[dst_id] : nullptr; | ||
| 1094 | const ImageBase* const src_image = src_id ? &slot_images[src_id] : nullptr; | 1114 | const ImageBase* const src_image = src_id ? &slot_images[src_id] : nullptr; |
| 1095 | DeduceBlitImages(dst_info, src_info, dst_image, src_image); | 1115 | if (src_image && src_image->info.num_samples > 1) { |
| 1096 | if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) { | 1116 | RelaxedOptions find_options{FIND_OPTIONS | RelaxedOptions::ForceBrokenViews}; |
| 1097 | continue; | 1117 | src_id = FindOrInsertImage(src_info, src_addr, find_options); |
| 1118 | dst_id = FindOrInsertImage(dst_info, dst_addr, find_options); | ||
| 1119 | if (has_deleted_images) { | ||
| 1120 | continue; | ||
| 1121 | } | ||
| 1122 | break; | ||
| 1123 | } | ||
| 1124 | if (can_be_depth_blit) { | ||
| 1125 | const ImageBase* const dst_image = src_id ? &slot_images[src_id] : nullptr; | ||
| 1126 | DeduceBlitImages(dst_info, src_info, dst_image, src_image); | ||
| 1127 | if (GetFormatType(dst_info.format) != GetFormatType(src_info.format)) { | ||
| 1128 | continue; | ||
| 1129 | } | ||
| 1130 | } | ||
| 1131 | if (!src_id) { | ||
| 1132 | src_id = InsertImage(src_info, src_addr, RelaxedOptions{}); | ||
| 1098 | } | 1133 | } |
| 1099 | RelaxedOptions find_options{}; | 1134 | if (!dst_id) { |
| 1100 | if (src_info.num_samples > 1) { | 1135 | dst_id = InsertImage(dst_info, dst_addr, RelaxedOptions{}); |
| 1101 | // it's a resolve, we must enforce the same format. | ||
| 1102 | find_options = RelaxedOptions::ForceBrokenViews; | ||
| 1103 | } | 1136 | } |
| 1104 | src_id = FindOrInsertImage(src_info, src_addr, find_options); | ||
| 1105 | dst_id = FindOrInsertImage(dst_info, dst_addr, find_options); | ||
| 1106 | } while (has_deleted_images); | 1137 | } while (has_deleted_images); |
| 1138 | if (GetFormatType(dst_info.format) != SurfaceType::ColorTexture) { | ||
| 1139 | // Make sure the images are depth and/or stencil textures. | ||
| 1140 | do { | ||
| 1141 | has_deleted_images = false; | ||
| 1142 | src_id = FindOrInsertImage(src_info, src_addr, RelaxedOptions{}); | ||
| 1143 | dst_id = FindOrInsertImage(dst_info, dst_addr, RelaxedOptions{}); | ||
| 1144 | } while (has_deleted_images); | ||
| 1145 | } | ||
| 1107 | return BlitImages{ | 1146 | return BlitImages{ |
| 1108 | .dst_id = dst_id, | 1147 | .dst_id = dst_id, |
| 1109 | .src_id = src_id, | 1148 | .src_id = src_id, |
| @@ -1160,7 +1199,14 @@ template <class P> | |||
| 1160 | ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr, | 1199 | ImageViewId TextureCache<P>::FindRenderTargetView(const ImageInfo& info, GPUVAddr gpu_addr, |
| 1161 | bool is_clear) { | 1200 | bool is_clear) { |
| 1162 | const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{}; | 1201 | const auto options = is_clear ? RelaxedOptions::Samples : RelaxedOptions{}; |
| 1163 | const ImageId image_id = FindOrInsertImage(info, gpu_addr, options); | 1202 | ImageId image_id{}; |
| 1203 | bool delete_state = has_deleted_images; | ||
| 1204 | do { | ||
| 1205 | has_deleted_images = false; | ||
| 1206 | image_id = FindOrInsertImage(info, gpu_addr, options); | ||
| 1207 | delete_state |= has_deleted_images; | ||
| 1208 | } while (has_deleted_images); | ||
| 1209 | has_deleted_images = delete_state; | ||
| 1164 | if (!image_id) { | 1210 | if (!image_id) { |
| 1165 | return NULL_IMAGE_VIEW_ID; | 1211 | return NULL_IMAGE_VIEW_ID; |
| 1166 | } | 1212 | } |
| @@ -1783,7 +1829,13 @@ void TextureCache<P>::CopyImage(ImageId dst_id, ImageId src_id, std::vector<Imag | |||
| 1783 | const SubresourceExtent src_extent{.levels = 1, .layers = 1}; | 1829 | const SubresourceExtent src_extent{.levels = 1, .layers = 1}; |
| 1784 | const SubresourceRange dst_range{.base = dst_base, .extent = dst_extent}; | 1830 | const SubresourceRange dst_range{.base = dst_base, .extent = dst_extent}; |
| 1785 | const SubresourceRange src_range{.base = src_base, .extent = src_extent}; | 1831 | const SubresourceRange src_range{.base = src_base, .extent = src_extent}; |
| 1786 | const ImageViewInfo dst_view_info(ImageViewType::e2D, dst.info.format, dst_range); | 1832 | PixelFormat dst_format = dst.info.format; |
| 1833 | if (GetFormatType(src.info.format) == SurfaceType::DepthStencil && | ||
| 1834 | GetFormatType(dst_format) == SurfaceType::ColorTexture && | ||
| 1835 | BytesPerBlock(dst_format) == 4) { | ||
| 1836 | dst_format = PixelFormat::A8B8G8R8_UNORM; | ||
| 1837 | } | ||
| 1838 | const ImageViewInfo dst_view_info(ImageViewType::e2D, dst_format, dst_range); | ||
| 1787 | const ImageViewInfo src_view_info(ImageViewType::e2D, src.info.format, src_range); | 1839 | const ImageViewInfo src_view_info(ImageViewType::e2D, src.info.format, src_range); |
| 1788 | const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info); | 1840 | const auto [dst_framebuffer_id, dst_view_id] = RenderTargetFromImage(dst_id, dst_view_info); |
| 1789 | Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id]; | 1841 | Framebuffer* const dst_framebuffer = &slot_framebuffers[dst_framebuffer_id]; |
diff --git a/src/video_core/texture_cache/texture_cache_base.h b/src/video_core/texture_cache/texture_cache_base.h index 643ad811c..7107887a6 100644 --- a/src/video_core/texture_cache/texture_cache_base.h +++ b/src/video_core/texture_cache/texture_cache_base.h | |||
| @@ -252,7 +252,8 @@ private: | |||
| 252 | 252 | ||
| 253 | /// Return a blit image pair from the given guest blit parameters | 253 | /// Return a blit image pair from the given guest blit parameters |
| 254 | [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst, | 254 | [[nodiscard]] BlitImages GetBlitImages(const Tegra::Engines::Fermi2D::Surface& dst, |
| 255 | const Tegra::Engines::Fermi2D::Surface& src); | 255 | const Tegra::Engines::Fermi2D::Surface& src, |
| 256 | const Tegra::Engines::Fermi2D::Config& copy); | ||
| 256 | 257 | ||
| 257 | /// Find or create a sampler from a guest descriptor sampler | 258 | /// Find or create a sampler from a guest descriptor sampler |
| 258 | [[nodiscard]] SamplerId FindSampler(const TSCEntry& config); | 259 | [[nodiscard]] SamplerId FindSampler(const TSCEntry& config); |
diff --git a/src/video_core/texture_cache/util.cpp b/src/video_core/texture_cache/util.cpp index e4d82631e..7bd31b211 100644 --- a/src/video_core/texture_cache/util.cpp +++ b/src/video_core/texture_cache/util.cpp | |||
| @@ -1151,28 +1151,15 @@ bool IsSubresource(const ImageInfo& candidate, const ImageBase& image, GPUVAddr | |||
| 1151 | 1151 | ||
| 1152 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, | 1152 | void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* dst, |
| 1153 | const ImageBase* src) { | 1153 | const ImageBase* src) { |
| 1154 | bool is_resolve = false; | ||
| 1155 | const auto original_src_format = src_info.format; | ||
| 1156 | const auto original_dst_format = dst_info.format; | 1154 | const auto original_dst_format = dst_info.format; |
| 1157 | if (src) { | 1155 | if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) { |
| 1158 | if (GetFormatType(src->info.format) != SurfaceType::ColorTexture) { | 1156 | src_info.format = src->info.format; |
| 1159 | src_info.format = src->info.format; | ||
| 1160 | } | ||
| 1161 | is_resolve = src->info.num_samples > 1; | ||
| 1162 | src_info.num_samples = src->info.num_samples; | ||
| 1163 | src_info.size = src->info.size; | ||
| 1164 | } | 1157 | } |
| 1165 | if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { | 1158 | if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { |
| 1166 | dst_info.format = dst->info.format; | 1159 | dst_info.format = dst->info.format; |
| 1167 | } | 1160 | } |
| 1168 | if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) { | 1161 | if (src && GetFormatType(src->info.format) != SurfaceType::ColorTexture) { |
| 1169 | if (dst) { | 1162 | dst_info.format = src->info.format; |
| 1170 | if (GetFormatType(dst->info.format) == SurfaceType::ColorTexture) { | ||
| 1171 | src_info.format = original_src_format; | ||
| 1172 | } | ||
| 1173 | } else { | ||
| 1174 | dst_info.format = src->info.format; | ||
| 1175 | } | ||
| 1176 | } | 1163 | } |
| 1177 | if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { | 1164 | if (dst && GetFormatType(dst->info.format) != SurfaceType::ColorTexture) { |
| 1178 | if (src) { | 1165 | if (src) { |
| @@ -1183,7 +1170,6 @@ void DeduceBlitImages(ImageInfo& dst_info, ImageInfo& src_info, const ImageBase* | |||
| 1183 | src_info.format = dst->info.format; | 1170 | src_info.format = dst->info.format; |
| 1184 | } | 1171 | } |
| 1185 | } | 1172 | } |
| 1186 | ASSERT(!is_resolve || dst_info.format == src_info.format); | ||
| 1187 | } | 1173 | } |
| 1188 | 1174 | ||
| 1189 | u32 MapSizeBytes(const ImageBase& image) { | 1175 | u32 MapSizeBytes(const ImageBase& image) { |