summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-05-24 17:57:54 -0300
committerGravatar ReinUsesLisp2020-05-26 17:44:50 -0300
commit8bba84a4014e1bf204089ff7dbcaa73917f84738 (patch)
tree2775c6a219a18ff4ceed45e4954f6707d7fafd8b /src/video_core/renderer_vulkan
parentMerge pull request #3978 from ReinUsesLisp/write-rz (diff)
downloadyuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.tar.gz
yuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.tar.xz
yuzu-8bba84a4014e1bf204089ff7dbcaa73917f84738.zip
texture_cache: Implement depth stencil texture swizzles
Stop ignoring image swizzles on depth and stencil images. This doesn't fix a known issue on Xenoblade Chronicles 2 where an OpenGL texture changes swizzles twice before being used. A proper fix would be having a small texture view cache for this like we do on Vulkan.
Diffstat (limited to 'src/video_core/renderer_vulkan')
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp29
1 files changed, 13 insertions, 16 deletions
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 55f43e61b..2f1d5021d 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -354,26 +354,23 @@ CachedSurfaceView::~CachedSurfaceView() = default;
354 354
355VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y_source, 355VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y_source,
356 SwizzleSource z_source, SwizzleSource w_source) { 356 SwizzleSource z_source, SwizzleSource w_source) {
357 const u32 swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source); 357 const u32 new_swizzle = EncodeSwizzle(x_source, y_source, z_source, w_source);
358 if (last_image_view && last_swizzle == swizzle) { 358 if (last_image_view && last_swizzle == new_swizzle) {
359 return last_image_view; 359 return last_image_view;
360 } 360 }
361 last_swizzle = swizzle; 361 last_swizzle = new_swizzle;
362 362
363 const auto [entry, is_cache_miss] = view_cache.try_emplace(swizzle); 363 const auto [entry, is_cache_miss] = view_cache.try_emplace(new_swizzle);
364 auto& image_view = entry->second; 364 auto& image_view = entry->second;
365 if (!is_cache_miss) { 365 if (!is_cache_miss) {
366 return last_image_view = *image_view; 366 return last_image_view = *image_view;
367 } 367 }
368 368
369 auto swizzle_x = MaxwellToVK::SwizzleSource(x_source); 369 std::array swizzle{MaxwellToVK::SwizzleSource(x_source), MaxwellToVK::SwizzleSource(y_source),
370 auto swizzle_y = MaxwellToVK::SwizzleSource(y_source); 370 MaxwellToVK::SwizzleSource(z_source), MaxwellToVK::SwizzleSource(w_source)};
371 auto swizzle_z = MaxwellToVK::SwizzleSource(z_source);
372 auto swizzle_w = MaxwellToVK::SwizzleSource(w_source);
373
374 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) { 371 if (params.pixel_format == VideoCore::Surface::PixelFormat::A1B5G5R5U) {
375 // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here. 372 // A1B5G5R5 is implemented as A1R5G5B5, we have to change the swizzle here.
376 std::swap(swizzle_x, swizzle_z); 373 std::swap(swizzle[0], swizzle[2]);
377 } 374 }
378 375
379 // Games can sample depth or stencil values on textures. This is decided by the swizzle value on 376 // Games can sample depth or stencil values on textures. This is decided by the swizzle value on
@@ -395,11 +392,11 @@ VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y
395 UNIMPLEMENTED(); 392 UNIMPLEMENTED();
396 } 393 }
397 394
398 // Vulkan doesn't seem to understand swizzling of a depth stencil image, use identity 395 // Make sure we sample the first component
399 swizzle_x = VK_COMPONENT_SWIZZLE_R; 396 std::transform(
400 swizzle_y = VK_COMPONENT_SWIZZLE_G; 397 swizzle.begin(), swizzle.end(), swizzle.begin(), [](VkComponentSwizzle component) {
401 swizzle_z = VK_COMPONENT_SWIZZLE_B; 398 return component == VK_COMPONENT_SWIZZLE_G ? VK_COMPONENT_SWIZZLE_R : component;
402 swizzle_w = VK_COMPONENT_SWIZZLE_A; 399 });
403 } 400 }
404 401
405 VkImageViewCreateInfo ci; 402 VkImageViewCreateInfo ci;
@@ -409,7 +406,7 @@ VkImageView CachedSurfaceView::GetHandle(SwizzleSource x_source, SwizzleSource y
409 ci.image = surface.GetImageHandle(); 406 ci.image = surface.GetImageHandle();
410 ci.viewType = image_view_type; 407 ci.viewType = image_view_type;
411 ci.format = surface.GetImage().GetFormat(); 408 ci.format = surface.GetImage().GetFormat();
412 ci.components = {swizzle_x, swizzle_y, swizzle_z, swizzle_w}; 409 ci.components = {swizzle[0], swizzle[1], swizzle[2], swizzle[3]};
413 ci.subresourceRange.aspectMask = aspect; 410 ci.subresourceRange.aspectMask = aspect;
414 ci.subresourceRange.baseMipLevel = base_level; 411 ci.subresourceRange.baseMipLevel = base_level;
415 ci.subresourceRange.levelCount = num_levels; 412 ci.subresourceRange.levelCount = num_levels;