Determine depth/stencil texture aspect based off of image swizzle

Required since we can't have a non-rt image with both a depth/stencil aspect at the same time according to vk spec.
This commit is contained in:
Billy Laws 2022-04-11 23:42:36 +01:00 committed by PixelyIon
parent 1878e582ad
commit 2c697ec36a
4 changed files with 31 additions and 6 deletions

View File

@ -268,6 +268,9 @@ namespace skyline::gpu::interconnect {
#undef FORMAT_SAME_NORM_INT_FLOAT_CASE #undef FORMAT_SAME_NORM_INT_FLOAT_CASE
}(); }();
if (renderTarget.guest.format)
renderTarget.guest.aspect = renderTarget.guest.format->vkAspect;
if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format) if (renderTarget.guest.tileConfig.mode == texture::TileMode::Linear && renderTarget.guest.format)
renderTarget.guest.dimensions.width = renderTarget.widthBytes / renderTarget.guest.format->bpb; renderTarget.guest.dimensions.width = renderTarget.widthBytes / renderTarget.guest.format->bpb;
@ -294,6 +297,9 @@ namespace skyline::gpu::interconnect {
} }
}(); }();
if (depthRenderTarget.guest.format)
depthRenderTarget.guest.aspect = depthRenderTarget.guest.format->vkAspect;
if (depthRenderTarget.guest.tileConfig.mode == texture::TileMode::Linear && depthRenderTarget.guest.format) if (depthRenderTarget.guest.tileConfig.mode == texture::TileMode::Linear && depthRenderTarget.guest.format)
depthRenderTarget.guest.dimensions.width = depthRenderTarget.widthBytes / depthRenderTarget.guest.format->bpb; depthRenderTarget.guest.dimensions.width = depthRenderTarget.widthBytes / depthRenderTarget.guest.format->bpb;
@ -1999,6 +2005,7 @@ namespace skyline::gpu::interconnect {
// If the entry didn't exist prior then we need to convert the TIC to a GuestTexture // If the entry didn't exist prior then we need to convert the TIC to a GuestTexture
auto &guest{poolTexture.guest}; auto &guest{poolTexture.guest};
guest.format = ConvertTicFormat(textureControl.formatWord, textureControl.isSrgb); guest.format = ConvertTicFormat(textureControl.formatWord, textureControl.isSrgb);
guest.aspect = guest.format->Aspect(textureControl.formatWord.swizzleX == TextureImageControl::ImageSwizzle::R);
if (guest.format->IsDepthOrStencil()) // G/R are equivalent for depth/stencil if (guest.format->IsDepthOrStencil()) // G/R are equivalent for depth/stencil
guest.swizzle = ConvertTicSwizzleMapping<true, false>(textureControl.formatWord); guest.swizzle = ConvertTicSwizzleMapping<true, false>(textureControl.formatWord);

View File

@ -143,7 +143,7 @@ namespace skyline::gpu::format {
}); });
FORMAT(S8UintD24Unorm, 32, eD24UnormS8Uint, .vkAspect = { FORMAT(S8UintD24Unorm, 32, eD24UnormS8Uint, .vkAspect = {
vka::eStencil | vka::eDepth vka::eStencil | vka::eDepth
}); // TODO: Swizzle Depth/Stencil }, .stencilFirst = true); // TODO: Swizzle Depth/Stencil
#undef FORMAT #undef FORMAT

View File

@ -69,6 +69,7 @@ namespace skyline::gpu {
u16 blockHeight{1}; //!< The height of a block in pixels u16 blockHeight{1}; //!< The height of a block in pixels
u16 blockWidth{1}; //!< The width of a block in pixels u16 blockWidth{1}; //!< The width of a block in pixels
bool swapRedBlue{}; //!< Swap the red and blue channels, ignored on depth formats bool swapRedBlue{}; //!< Swap the red and blue channels, ignored on depth formats
bool stencilFirst{}; //!< If the stencil channel is the first channel in the format
constexpr bool IsCompressed() const { constexpr bool IsCompressed() const {
return (blockHeight != 1) || (blockWidth != 1); return (blockHeight != 1) || (blockWidth != 1);
@ -115,7 +116,21 @@ namespace skyline::gpu {
} }
constexpr bool IsDepthOrStencil() const { constexpr bool IsDepthOrStencil() const {
return bool(vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)); return bool{vkAspect & (vk::ImageAspectFlagBits::eDepth | vk::ImageAspectFlagBits::eStencil)};
}
/**
* @brief Determines the image aspect to use based off of the format and the first swizzle component
*/
constexpr vk::ImageAspectFlags Aspect(bool first) const {
if (vkAspect & vk::ImageAspectFlagBits::eDepth && vkAspect & vk::ImageAspectFlagBits::eStencil) {
if (first)
return stencilFirst ? vk::ImageAspectFlagBits::eStencil : vk::ImageAspectFlagBits::eDepth;
else
return stencilFirst ? vk::ImageAspectFlagBits::eDepth : vk::ImageAspectFlagBits::eStencil;
} else {
return vkAspect;
}
} }
}; };
@ -226,6 +241,7 @@ namespace skyline::gpu {
u16 layerCount{}; u16 layerCount{};
u32 layerStride{}; //!< An optional hint regarding the size of a single layer, it will be set to 0 when not available, GetLayerSize() should be used to retrieve this value u32 layerStride{}; //!< An optional hint regarding the size of a single layer, it will be set to 0 when not available, GetLayerSize() should be used to retrieve this value
vk::ComponentMapping swizzle{}; //!< Component swizzle derived from format requirements and the guest supplied swizzle vk::ComponentMapping swizzle{}; //!< Component swizzle derived from format requirements and the guest supplied swizzle
vk::ImageAspectFlags aspect{};
GuestTexture() {} GuestTexture() {}
@ -237,7 +253,8 @@ namespace skyline::gpu {
type(type), type(type),
baseArrayLayer(baseArrayLayer), baseArrayLayer(baseArrayLayer),
layerCount(layerCount), layerCount(layerCount),
layerStride(layerStride) {} layerStride(layerStride),
aspect(format->vkAspect) {}
GuestTexture(span <u8> mapping, texture::Dimensions dimensions, texture::Format format, texture::TileConfig tileConfig, texture::TextureType type, u16 baseArrayLayer = 0, u16 layerCount = 1, u32 layerStride = 0) GuestTexture(span <u8> mapping, texture::Dimensions dimensions, texture::Format format, texture::TileConfig tileConfig, texture::TextureType type, u16 baseArrayLayer = 0, u16 layerCount = 1, u32 layerStride = 0)
: mappings(1, mapping), : mappings(1, mapping),
@ -247,7 +264,8 @@ namespace skyline::gpu {
type(type), type(type),
baseArrayLayer(baseArrayLayer), baseArrayLayer(baseArrayLayer),
layerCount(layerCount), layerCount(layerCount),
layerStride(layerStride) {} layerStride(layerStride),
aspect(format->vkAspect) {}
/** /**
* @note Requires `dimensions`, `format` and `tileConfig` to be filled in * @note Requires `dimensions`, `format` and `tileConfig` to be filled in

View File

@ -48,7 +48,7 @@ namespace skyline::gpu {
if (matchGuestTexture.format->IsCompatible(*guestTexture.format) && matchGuestTexture.dimensions == guestTexture.dimensions && matchGuestTexture.tileConfig == guestTexture.tileConfig) { if (matchGuestTexture.format->IsCompatible(*guestTexture.format) && matchGuestTexture.dimensions == guestTexture.dimensions && matchGuestTexture.tileConfig == guestTexture.tileConfig) {
auto &texture{hostMapping->texture}; auto &texture{hostMapping->texture};
return texture->GetView(static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{ return texture->GetView(static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{
.aspectMask = guestTexture.format->vkAspect, .aspectMask = guestTexture.aspect,
.levelCount = texture->mipLevels, .levelCount = texture->mipLevels,
.layerCount = texture->layerCount, .layerCount = texture->layerCount,
}, guestTexture.format, guestTexture.swizzle); }, guestTexture.format, guestTexture.swizzle);
@ -80,7 +80,7 @@ namespace skyline::gpu {
} }
return texture->GetView(static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{ return texture->GetView(static_cast<vk::ImageViewType>(guestTexture.type), vk::ImageSubresourceRange{
.aspectMask = guestTexture.format->vkAspect, .aspectMask = guestTexture.aspect,
.levelCount = texture->mipLevels, .levelCount = texture->mipLevels,
.layerCount = texture->layerCount, .layerCount = texture->layerCount,
}, guestTexture.format, guestTexture.swizzle); }, guestTexture.format, guestTexture.swizzle);