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.
This commit is contained in:
Billy Laws 2022-03-28 20:10:50 +01:00 committed by PixelyIon
parent bcc00216b7
commit d137051833
2 changed files with 18 additions and 20 deletions

View File

@ -81,7 +81,8 @@ namespace skyline::gpu::interconnect {
std::shared_ptr<TextureView> view; std::shared_ptr<TextureView> view;
RenderTarget() { 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) { void SetRenderTargetArrayMode(RenderTarget &renderTarget, maxwell3d::RenderTargetArrayMode mode) {
renderTarget.guest.layerCount = mode.layerCount; renderTarget.guest.dimensions.depth = mode.layerCount;
renderTarget.view.reset(); renderTarget.view.reset();
} }
@ -1917,7 +1918,7 @@ namespace skyline::gpu::interconnect {
guest.layerCount = 1; guest.layerCount = 1;
break; break;
case TicType::e1DArray: case TicType::e1DArray:
guest.type = TexType::e1D; guest.type = TexType::e1DArray;
guest.layerCount = depth; guest.layerCount = depth;
break; break;
case TicType::e1DBuffer: case TicType::e1DBuffer:
@ -1929,7 +1930,7 @@ namespace skyline::gpu::interconnect {
guest.layerCount = 1; guest.layerCount = 1;
break; break;
case TicType::e2DArray: case TicType::e2DArray:
guest.type = TexType::e2D; guest.type = TexType::e2DArray;
guest.layerCount = depth; guest.layerCount = depth;
break; break;
@ -1940,11 +1941,11 @@ namespace skyline::gpu::interconnect {
break; break;
case TicType::eCubemap: case TicType::eCubemap:
guest.type = TexType::e2D; guest.type = TexType::eCube;
guest.layerCount = CubeFaceCount; guest.layerCount = CubeFaceCount;
break; break;
case TicType::eCubeArray: case TicType::eCubeArray:
guest.type = TexType::e2D; guest.type = TexType::eCubeArray;
guest.layerCount = depth * CubeFaceCount; guest.layerCount = depth * CubeFaceCount;
break; break;
} }

View File

@ -28,20 +28,9 @@ namespace skyline::gpu {
if (view) if (view)
return **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{ vk::ImageViewCreateInfo createInfo{
.image = texture->GetBacking(), .image = texture->GetBacking(),
.viewType = viewType, .viewType = type,
.format = format ? *format : *texture->format, .format = format ? *format : *texture->format,
.components = mapping, .components = mapping,
.subresourceRange = range, .subresourceRange = range,
@ -135,7 +124,7 @@ namespace skyline::gpu {
throw exception("Guest and host dimensions being different is not supported currently"); throw exception("Guest and host dimensions being different is not supported currently");
auto pointer{mirror.data()}; auto pointer{mirror.data()};
auto size{format->GetSize(dimensions)}; auto size{format->GetSize(dimensions) * layerCount};
WaitOnBacking(); WaitOnBacking();
@ -306,8 +295,16 @@ namespace skyline::gpu {
if (format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)) if (format->vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil))
usage |= vk::ImageUsageFlagBits::eDepthStencilAttachment; 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{ vk::ImageCreateInfo imageCreateInfo{
.flags = gpu.traits.quirks.vkImageMutableFormatCostly ? vk::ImageCreateFlags{} : vk::ImageCreateFlagBits::eMutableFormat, .flags = flags,
.imageType = guest->dimensions.GetType(), .imageType = guest->dimensions.GetType(),
.format = *guest->format, .format = *guest->format,
.extent = guest->dimensions, .extent = guest->dimensions,