Refactor MVKImageView::validateSwizzledMTLPixelFormat().
Move MVKImageView::validateSwizzledMTLPixelFormat() to MVKImageViewPlane::initSwizzledMTLPixelFormat(), make it non-static, and use instance member content instead of passing all the data as function arguments.
This commit is contained in:
parent
9534c3b9ef
commit
1748686d0d
@ -536,6 +536,7 @@ public:
|
||||
protected:
|
||||
void propagateDebugName();
|
||||
id<MTLTexture> newMTLTexture();
|
||||
VkResult initSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo);
|
||||
MVKImageViewPlane(MVKImageView* imageView, uint8_t planeIndex, MTLPixelFormat mtlPixFmt, const VkImageViewCreateInfo* pCreateInfo);
|
||||
|
||||
friend MVKImageView;
|
||||
@ -545,6 +546,7 @@ protected:
|
||||
uint32_t _packedSwizzle;
|
||||
id<MTLTexture> _mtlTexture;
|
||||
bool _useMTLTextureView;
|
||||
bool _useSwizzle;
|
||||
};
|
||||
|
||||
|
||||
@ -591,30 +593,6 @@ public:
|
||||
*/
|
||||
void populateMTLRenderPassAttachmentDescriptorResolve(MTLRenderPassAttachmentDescriptor* mtlAttDesc);
|
||||
|
||||
/**
|
||||
* Returns, in mtlPixFmt, a MTLPixelFormat, based on the MTLPixelFormat converted from
|
||||
* the VkFormat, but possibly modified by the swizzles defined in the VkComponentMapping
|
||||
* of the VkImageViewCreateInfo.
|
||||
*
|
||||
* Metal prior to version 3.0 does not support native per-texture swizzles, so if the swizzle
|
||||
* is not an identity swizzle, this function attempts to find an alternate MTLPixelFormat that
|
||||
* coincidentally matches the swizzled format.
|
||||
*
|
||||
* If a replacement MTLFormat was found, it is returned and useSwizzle is set to false.
|
||||
* If a replacement MTLFormat could not be found, the original MTLPixelFormat is returned,
|
||||
* and the useSwizzle is set to true, indicating that either native or shader swizzling
|
||||
* should be used for this image view.
|
||||
*
|
||||
* This is a static function that can be used to validate image view formats prior to creating one.
|
||||
*/
|
||||
static VkResult validateSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo,
|
||||
VkImageUsageFlags usage,
|
||||
MVKVulkanAPIObject* apiObject,
|
||||
bool hasNativeSwizzleSupport,
|
||||
bool hasShaderSwizzleSupport,
|
||||
MTLPixelFormat& mtlPixFmt,
|
||||
bool& useSwizzle);
|
||||
|
||||
|
||||
#pragma mark Construction
|
||||
|
||||
|
@ -1474,15 +1474,8 @@ MVKImageViewPlane::MVKImageViewPlane(MVKImageView* imageView,
|
||||
_mtlPixFmt = mtlPixFmt;
|
||||
_mtlTexture = nil;
|
||||
|
||||
bool useSwizzle;
|
||||
_imageView->setConfigurationResult(_imageView->validateSwizzledMTLPixelFormat(pCreateInfo,
|
||||
_imageView->_usage,
|
||||
_imageView,
|
||||
_device->_pMetalFeatures->nativeTextureSwizzle,
|
||||
mvkConfig().fullImageViewSwizzle,
|
||||
_mtlPixFmt,
|
||||
useSwizzle));
|
||||
_packedSwizzle = (useSwizzle) ? mvkPackSwizzle(pCreateInfo->components) : 0;
|
||||
getVulkanAPIObject()->setConfigurationResult(initSwizzledMTLPixelFormat(pCreateInfo));
|
||||
_packedSwizzle = _useSwizzle ? mvkPackSwizzle(pCreateInfo->components) : 0;
|
||||
|
||||
// Determine whether this image view should use a Metal texture view,
|
||||
// and set the _useMTLTextureView variable appropriately.
|
||||
@ -1503,6 +1496,177 @@ MVKImageViewPlane::MVKImageViewPlane(MVKImageView* imageView,
|
||||
}
|
||||
}
|
||||
|
||||
VkResult MVKImageViewPlane::initSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo) {
|
||||
|
||||
_useSwizzle = false;
|
||||
VkComponentMapping components = pCreateInfo->components;
|
||||
|
||||
#define SWIZZLE_MATCHES(R, G, B, A) mvkVkComponentMappingsMatch(components, {VK_COMPONENT_SWIZZLE_ ##R, VK_COMPONENT_SWIZZLE_ ##G, VK_COMPONENT_SWIZZLE_ ##B, VK_COMPONENT_SWIZZLE_ ##A} )
|
||||
#define VK_COMPONENT_SWIZZLE_ANY VK_COMPONENT_SWIZZLE_MAX_ENUM
|
||||
|
||||
// If we have an identity swizzle, we're all good.
|
||||
if (SWIZZLE_MATCHES(R, G, B, A)) {
|
||||
// Change to stencil-only format if only stencil aspect is requested
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
if (_mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8) {
|
||||
_mtlPixFmt = MTLPixelFormatX32_Stencil8;
|
||||
}
|
||||
#if MVK_MACOS
|
||||
else if (_mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8) {
|
||||
_mtlPixFmt = MTLPixelFormatX24_Stencil8;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (mvkIsAnyFlagEnabled(_imageView->_usage, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) {
|
||||
// Vulkan forbids using image views with non-identity swizzles as storage images or attachments.
|
||||
// Let's catch some cases which are essentially identity, but would still result in Metal restricting
|
||||
// the resulting texture's usage.
|
||||
|
||||
switch (_mtlPixFmt) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
#if MVK_APPLE_SILICON
|
||||
case MTLPixelFormatR8Unorm_sRGB:
|
||||
#endif
|
||||
case MTLPixelFormatR8Snorm:
|
||||
case MTLPixelFormatR8Uint:
|
||||
case MTLPixelFormatR8Sint:
|
||||
case MTLPixelFormatR16Unorm:
|
||||
case MTLPixelFormatR16Snorm:
|
||||
case MTLPixelFormatR16Uint:
|
||||
case MTLPixelFormatR16Sint:
|
||||
case MTLPixelFormatR16Float:
|
||||
case MTLPixelFormatR32Uint:
|
||||
case MTLPixelFormatR32Sint:
|
||||
case MTLPixelFormatR32Float:
|
||||
if (SWIZZLE_MATCHES(R, ZERO, ZERO, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRG8Unorm:
|
||||
#if MVK_APPLE_SILICON
|
||||
case MTLPixelFormatRG8Unorm_sRGB:
|
||||
#endif
|
||||
case MTLPixelFormatRG8Snorm:
|
||||
case MTLPixelFormatRG8Uint:
|
||||
case MTLPixelFormatRG8Sint:
|
||||
case MTLPixelFormatRG16Unorm:
|
||||
case MTLPixelFormatRG16Snorm:
|
||||
case MTLPixelFormatRG16Uint:
|
||||
case MTLPixelFormatRG16Sint:
|
||||
case MTLPixelFormatRG16Float:
|
||||
case MTLPixelFormatRG32Uint:
|
||||
case MTLPixelFormatRG32Sint:
|
||||
case MTLPixelFormatRG32Float:
|
||||
if (SWIZZLE_MATCHES(R, G, ZERO, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRG11B10Float:
|
||||
case MTLPixelFormatRGB9E5Float:
|
||||
if (SWIZZLE_MATCHES(R, G, B, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_mtlPixFmt) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {
|
||||
_mtlPixFmt = MTLPixelFormatA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatA8Unorm:
|
||||
if (SWIZZLE_MATCHES(A, ANY, ANY, ZERO)) {
|
||||
_mtlPixFmt = MTLPixelFormatR8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
_mtlPixFmt = MTLPixelFormatBGRA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
_mtlPixFmt = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
_mtlPixFmt = MTLPixelFormatRGBA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
_mtlPixFmt = MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
_mtlPixFmt = MTLPixelFormatX32_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if MVK_MACOS
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(_imageView->_usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
_mtlPixFmt = MTLPixelFormatX24_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// No format transformation swizzles were found, so we'll need to use either native or shader swizzling, if it is supported.
|
||||
if ( !(_device->_pMetalFeatures->nativeTextureSwizzle || mvkConfig().fullImageViewSwizzle) ) {
|
||||
return getVulkanAPIObject()->reportError(VK_ERROR_FEATURE_NOT_PRESENT,
|
||||
"The value of %s::components) (%s, %s, %s, %s), when applied to a VkImageView, requires full component swizzling to be enabled both at the"
|
||||
" time when the VkImageView is created and at the time any pipeline that uses that VkImageView is compiled. Full component swizzling can"
|
||||
" be enabled via the MVKConfiguration::fullImageViewSwizzle config parameter or MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE environment variable.",
|
||||
pCreateInfo->image ? "vkCreateImageView(VkImageViewCreateInfo" : "vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDeviceImageViewSupportEXTX",
|
||||
mvkVkComponentSwizzleName(components.r), mvkVkComponentSwizzleName(components.g),
|
||||
mvkVkComponentSwizzleName(components.b), mvkVkComponentSwizzleName(components.a));
|
||||
}
|
||||
|
||||
_useSwizzle = true;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
MVKImageViewPlane::~MVKImageViewPlane() {
|
||||
[_mtlTexture release];
|
||||
}
|
||||
@ -1635,180 +1799,6 @@ MVKImageView::MVKImageView(MVKDevice* device,
|
||||
}
|
||||
}
|
||||
|
||||
VkResult MVKImageView::validateSwizzledMTLPixelFormat(const VkImageViewCreateInfo* pCreateInfo,
|
||||
VkImageUsageFlags usage,
|
||||
MVKVulkanAPIObject* apiObject,
|
||||
bool hasNativeSwizzleSupport,
|
||||
bool hasShaderSwizzleSupport,
|
||||
MTLPixelFormat& mtlPixFmt,
|
||||
bool& useSwizzle) {
|
||||
useSwizzle = false;
|
||||
VkComponentMapping components = pCreateInfo->components;
|
||||
|
||||
#define SWIZZLE_MATCHES(R, G, B, A) mvkVkComponentMappingsMatch(components, {VK_COMPONENT_SWIZZLE_ ##R, VK_COMPONENT_SWIZZLE_ ##G, VK_COMPONENT_SWIZZLE_ ##B, VK_COMPONENT_SWIZZLE_ ##A} )
|
||||
#define VK_COMPONENT_SWIZZLE_ANY VK_COMPONENT_SWIZZLE_MAX_ENUM
|
||||
|
||||
// If we have an identity swizzle, we're all good.
|
||||
if (SWIZZLE_MATCHES(R, G, B, A)) {
|
||||
// Change to stencil-only format if only stencil aspect is requested
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
if (mtlPixFmt == MTLPixelFormatDepth32Float_Stencil8)
|
||||
mtlPixFmt = MTLPixelFormatX32_Stencil8;
|
||||
#if MVK_MACOS
|
||||
else if (mtlPixFmt == MTLPixelFormatDepth24Unorm_Stencil8)
|
||||
mtlPixFmt = MTLPixelFormatX24_Stencil8;
|
||||
#endif
|
||||
}
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
if (mvkIsAnyFlagEnabled(usage, VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) {
|
||||
// Vulkan forbids using image views with non-identity swizzles as storage images or attachments.
|
||||
// Let's catch some cases which are essentially identity, but would still result in Metal restricting
|
||||
// the resulting texture's usage.
|
||||
|
||||
switch (mtlPixFmt) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
#if MVK_APPLE_SILICON
|
||||
case MTLPixelFormatR8Unorm_sRGB:
|
||||
#endif
|
||||
case MTLPixelFormatR8Snorm:
|
||||
case MTLPixelFormatR8Uint:
|
||||
case MTLPixelFormatR8Sint:
|
||||
case MTLPixelFormatR16Unorm:
|
||||
case MTLPixelFormatR16Snorm:
|
||||
case MTLPixelFormatR16Uint:
|
||||
case MTLPixelFormatR16Sint:
|
||||
case MTLPixelFormatR16Float:
|
||||
case MTLPixelFormatR32Uint:
|
||||
case MTLPixelFormatR32Sint:
|
||||
case MTLPixelFormatR32Float:
|
||||
if (SWIZZLE_MATCHES(R, ZERO, ZERO, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRG8Unorm:
|
||||
#if MVK_APPLE_SILICON
|
||||
case MTLPixelFormatRG8Unorm_sRGB:
|
||||
#endif
|
||||
case MTLPixelFormatRG8Snorm:
|
||||
case MTLPixelFormatRG8Uint:
|
||||
case MTLPixelFormatRG8Sint:
|
||||
case MTLPixelFormatRG16Unorm:
|
||||
case MTLPixelFormatRG16Snorm:
|
||||
case MTLPixelFormatRG16Uint:
|
||||
case MTLPixelFormatRG16Sint:
|
||||
case MTLPixelFormatRG16Float:
|
||||
case MTLPixelFormatRG32Uint:
|
||||
case MTLPixelFormatRG32Sint:
|
||||
case MTLPixelFormatRG32Float:
|
||||
if (SWIZZLE_MATCHES(R, G, ZERO, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRG11B10Float:
|
||||
case MTLPixelFormatRGB9E5Float:
|
||||
if (SWIZZLE_MATCHES(R, G, B, ONE)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (mtlPixFmt) {
|
||||
case MTLPixelFormatR8Unorm:
|
||||
if (SWIZZLE_MATCHES(ZERO, ANY, ANY, R)) {
|
||||
mtlPixFmt = MTLPixelFormatA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatA8Unorm:
|
||||
if (SWIZZLE_MATCHES(A, ANY, ANY, ZERO)) {
|
||||
mtlPixFmt = MTLPixelFormatR8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
mtlPixFmt = MTLPixelFormatBGRA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatRGBA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
mtlPixFmt = MTLPixelFormatBGRA8Unorm_sRGB;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
mtlPixFmt = MTLPixelFormatRGBA8Unorm;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatBGRA8Unorm_sRGB:
|
||||
if (SWIZZLE_MATCHES(B, G, R, A)) {
|
||||
mtlPixFmt = MTLPixelFormatRGBA8Unorm_sRGB;
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTLPixelFormatDepth32Float_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
mtlPixFmt = MTLPixelFormatX32_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
#if MVK_MACOS
|
||||
case MTLPixelFormatDepth24Unorm_Stencil8:
|
||||
// If aspect mask looking only for stencil then change to stencil-only format even if shader swizzling is needed
|
||||
if (pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT &&
|
||||
mvkIsAnyFlagEnabled(usage, (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT))) {
|
||||
mtlPixFmt = MTLPixelFormatX24_Stencil8;
|
||||
if (SWIZZLE_MATCHES(R, ANY, ANY, ANY)) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// No format transformation swizzles were found, so we'll need to use either native or shader swizzling.
|
||||
useSwizzle = true;
|
||||
if (hasNativeSwizzleSupport || hasShaderSwizzleSupport ) {
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
// Oh, oh. Neither native or shader swizzling is supported.
|
||||
return apiObject->reportError(VK_ERROR_FEATURE_NOT_PRESENT,
|
||||
"The value of %s::components) (%s, %s, %s, %s), when applied to a VkImageView, requires full component swizzling to be enabled both at the"
|
||||
" time when the VkImageView is created and at the time any pipeline that uses that VkImageView is compiled. Full component swizzling can"
|
||||
" be enabled via the MVKConfiguration::fullImageViewSwizzle config parameter or MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE environment variable.",
|
||||
pCreateInfo->image ? "vkCreateImageView(VkImageViewCreateInfo" : "vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDeviceImageViewSupportEXTX",
|
||||
mvkVkComponentSwizzleName(components.r), mvkVkComponentSwizzleName(components.g),
|
||||
mvkVkComponentSwizzleName(components.b), mvkVkComponentSwizzleName(components.a));
|
||||
}
|
||||
|
||||
MVKImageView::~MVKImageView() {
|
||||
mvkDestroyContainerContents(_planes);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user