Merge pull request #666 from cdavis5e/swapchain-colorspace

Support the VK_EXT_swapchain_colorspace extension.
This commit is contained in:
Bill Hollings 2019-07-16 15:37:06 -04:00 committed by GitHub
commit fe3b2fbd5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 9 deletions

View File

@ -257,6 +257,7 @@ In addition to the core *Vulkan* API, **MoltenVK** also supports the following
- `VK_EXT_metal_surface`
- `VK_EXT_shader_stencil_export` *(requires Mac GPU family 2 or iOS GPU family 5)*
- `VK_EXT_shader_viewport_index_layer`
- `VK_EXT_swapchain_colorspace` *(macOS)*
- `VK_EXT_vertex_attribute_divisor`
- `VK_EXTX_portability_subset`
- `VK_MVK_ios_surface` *(iOS) (Obsolete. Use `VK_EXT_metal_surface` instead.)*

View File

@ -466,22 +466,42 @@ VkResult MVKPhysicalDevice::getSurfaceFormats(MVKSurface* surface,
MTLPixelFormatRGBA16Float,
};
MVKVectorInline<VkColorSpaceKHR, 16> colorSpaces;
colorSpaces.push_back(VK_COLOR_SPACE_SRGB_NONLINEAR_KHR);
#if MVK_MACOS
if (getInstance()->_enabledExtensions.vk_EXT_swapchain_colorspace.enabled) {
// 10.11 supports some but not all of the color spaces specified by VK_EXT_swapchain_colorspace.
colorSpaces.push_back(VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT);
colorSpaces.push_back(VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT);
colorSpaces.push_back(VK_COLOR_SPACE_BT709_NONLINEAR_EXT);
colorSpaces.push_back(VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT);
colorSpaces.push_back(VK_COLOR_SPACE_PASS_THROUGH_EXT);
if (mvkOSVersion() >= 10.12) {
colorSpaces.push_back(VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT);
colorSpaces.push_back(VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT);
}
}
#endif
const uint mtlFmtsCnt = sizeof(mtlFormats) / sizeof(MTLPixelFormat);
const uint vkFmtsCnt = mtlFmtsCnt * (uint)colorSpaces.size();
// If properties aren't actually being requested yet, simply update the returned count
if ( !pSurfaceFormats ) {
*pCount = mtlFmtsCnt;
*pCount = vkFmtsCnt;
return VK_SUCCESS;
}
// Determine how many results we'll return, and return that number
VkResult result = (*pCount >= mtlFmtsCnt) ? VK_SUCCESS : VK_INCOMPLETE;
*pCount = min(*pCount, mtlFmtsCnt);
VkResult result = (*pCount >= vkFmtsCnt) ? VK_SUCCESS : VK_INCOMPLETE;
*pCount = min(*pCount, vkFmtsCnt);
// Now populate the supplied array
for (uint fmtIdx = 0; fmtIdx < *pCount; fmtIdx++) {
pSurfaceFormats[fmtIdx].format = mvkVkFormatFromMTLPixelFormat(mtlFormats[fmtIdx]);
pSurfaceFormats[fmtIdx].colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
for (uint csIdx = 0, idx = 0; idx < *pCount && csIdx < colorSpaces.size(); csIdx++) {
for (uint fmtIdx = 0; idx < *pCount && fmtIdx < mtlFmtsCnt; fmtIdx++, idx++) {
pSurfaceFormats[idx].format = mvkVkFormatFromMTLPixelFormat(mtlFormats[fmtIdx]);
pSurfaceFormats[idx].colorSpace = colorSpaces[csIdx];
}
}
return result;

View File

@ -224,12 +224,40 @@ void MVKSwapchain::initCAMetalLayer(const VkSwapchainCreateInfoKHR* pCreateInfo,
VK_IMAGE_USAGE_TRANSFER_DST_BIT |
VK_IMAGE_USAGE_SAMPLED_BIT |
VK_IMAGE_USAGE_STORAGE_BIT));
#if MVK_MACOS
switch (pCreateInfo->imageColorSpace) {
case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
break;
case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);
break;
case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB);
break;
case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceDCIP3);
break;
case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceITUR_709);
break;
case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceAdobeRGB1998);
break;
case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
_mtlLayer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedSRGB);
break;
case VK_COLOR_SPACE_PASS_THROUGH_EXT:
default:
// Nothing - the default is not to do color matching.
break;
}
#endif
_mtlLayerOrigDrawSize = _mtlLayer.updatedDrawableSizeMVK;
// TODO: set additional CAMetalLayer properties before extracting drawables:
// - presentsWithTransaction
// - drawsAsynchronously
// - colorspace (macOS only) Vulkan only supports sRGB colorspace for now.
// - wantsExtendedDynamicRangeContent (macOS only)
if ( [_mtlLayer.delegate isKindOfClass: [PLATFORM_VIEW_CLASS class]] ) {

View File

@ -61,6 +61,7 @@ MVK_EXTENSION(EXT_memory_budget, EXT_MEMORY_BUDGET)
MVK_EXTENSION(EXT_metal_surface, EXT_METAL_SURFACE)
MVK_EXTENSION(EXT_shader_stencil_export, EXT_SHADER_STENCIL_EXPORT)
MVK_EXTENSION(EXT_shader_viewport_index_layer, EXT_SHADER_VIEWPORT_INDEX_LAYER)
MVK_EXTENSION(EXT_swapchain_colorspace, EXT_SWAPCHAIN_COLOR_SPACE)
MVK_EXTENSION(EXT_vertex_attribute_divisor, EXT_VERTEX_ATTRIBUTE_DIVISOR)
MVK_EXTENSION(EXTX_portability_subset, EXTX_PORTABILITY_SUBSET)
MVK_EXTENSION(MVK_ios_surface, MVK_IOS_SURFACE)

View File

@ -46,7 +46,7 @@ static VkExtensionProperties kVkExtProps_ ##EXT = mvkMakeExtProps(VK_ ##EXT ##_E
// Returns whether the specified properties are valid for this platform
static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
#if !(MVK_IOS)
#if MVK_MACOS
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 10.13;
}
@ -56,7 +56,7 @@ static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
if (pProperties == &kVkExtProps_MVK_IOS_SURFACE) { return false; }
if (pProperties == &kVkExtProps_IMG_FORMAT_PVRTC) { return false; }
#endif
#if !(MVK_MACOS)
#if MVK_IOS
if (pProperties == &kVkExtProps_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE) { return false; }
if (pProperties == &kVkExtProps_EXT_MEMORY_BUDGET) {
return mvkOSVersion() >= 11.0;
@ -64,6 +64,7 @@ static bool mvkIsSupportedOnPlatform(VkExtensionProperties* pProperties) {
if (pProperties == &kVkExtProps_EXT_SHADER_STENCIL_EXPORT) {
return mvkOSVersion() >= 12.0;
}
if (pProperties == &kVkExtProps_EXT_SWAPCHAIN_COLOR_SPACE) { return false; }
if (pProperties == &kVkExtProps_MVK_MACOS_SURFACE) { return false; }
#endif