From d13705183361baa7353ae17a81aea39d567ca874 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Mon, 28 Mar 2022 20:10:50 +0100 Subject: [PATCH] Add basic support for 3d/cubemap textures These are mostly used in 3D games like SMO, support is still quite basic and synchronising block linear 3D texture will crash in most cases due to them being unimplemented. --- .../gpu/interconnect/graphics_context.h | 13 +++++----- .../main/cpp/skyline/gpu/texture/texture.cpp | 25 ++++++++----------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h index dab3ba2a..8c070849 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/graphics_context.h @@ -81,7 +81,8 @@ namespace skyline::gpu::interconnect { std::shared_ptr view; RenderTarget() { - guest.dimensions = texture::Dimensions(1, 1, 1); // We want the depth to be 1 by default (It cannot be set by the application) + guest.dimensions = texture::Dimensions(1, 1, 1); + guest.layerCount = 1; } }; @@ -301,7 +302,7 @@ namespace skyline::gpu::interconnect { } void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) { - renderTarget.guest.layerCount = mode.layerCount; + renderTarget.guest.dimensions.depth = mode.layerCount; renderTarget.view.reset(); } @@ -1917,7 +1918,7 @@ namespace skyline::gpu::interconnect { guest.layerCount = 1; break; case TicType::e1DArray: - guest.type = TexType::e1D; + guest.type = TexType::e1DArray; guest.layerCount = depth; break; case TicType::e1DBuffer: @@ -1929,7 +1930,7 @@ namespace skyline::gpu::interconnect { guest.layerCount = 1; break; case TicType::e2DArray: - guest.type = TexType::e2D; + guest.type = TexType::e2DArray; guest.layerCount = depth; break; @@ -1940,11 +1941,11 @@ namespace skyline::gpu::interconnect { break; case TicType::eCubemap: - guest.type = TexType::e2D; + guest.type = TexType::eCube; guest.layerCount = CubeFaceCount; break; case TicType::eCubeArray: - guest.type = TexType::e2D; + guest.type = TexType::eCubeArray; guest.layerCount = depth * CubeFaceCount; break; } diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index 31155aa8..d5553f16 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -28,20 +28,9 @@ namespace skyline::gpu { if (view) return **view; - auto viewType{[&]() { - switch (texture->dimensions.GetType()) { - case vk::ImageType::e1D: - return range.layerCount > 1 ? vk::ImageViewType::e1DArray : vk::ImageViewType::e1D; - case vk::ImageType::e2D: - return range.layerCount > 1 ? vk::ImageViewType::e2DArray : vk::ImageViewType::e2D; - case vk::ImageType::e3D: - return vk::ImageViewType::e3D; - } - }()}; - vk::ImageViewCreateInfo createInfo{ .image = texture->GetBacking(), - .viewType = viewType, + .viewType = type, .format = format ? *format : *texture->format, .components = mapping, .subresourceRange = range, @@ -135,7 +124,7 @@ namespace skyline::gpu { throw exception("Guest and host dimensions being different is not supported currently"); auto pointer{mirror.data()}; - auto size{format->GetSize(dimensions)}; + auto size{format->GetSize(dimensions) * layerCount}; WaitOnBacking(); @@ -306,8 +295,16 @@ namespace skyline::gpu { if (format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)) usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; + vk::ImageCreateFlags flags{gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat}; + + if (guest->dimensions.GetType() == vk::ImageType::e2D && dimensions.width == dimensions.height && layerCount >= 6) + flags |= vk::ImageCreateFlagBits::eCubeCompatible; + else if (guest->dimensions.GetType() == vk::ImageType::e3D) + flags |= vk::ImageCreateFlagBits::e2DArrayCompatible; + + vk::ImageCreateInfo imageCreateInfo{ - .flags = gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat, + .flags = flags, .imageType = guest->dimensions.GetType(), .format = *guest->format, .extent = guest->dimensions,