SwapChainVK: Handle transform, imageCount, alphaMode.

This removes outstanding TODOs in the creation of the VkSwapChain
by correctly handling imageCount and validation that the surface
supports identity transform and opaque alpha mode.

Bug: dawn:269

Change-Id: Ifbc30a9832a6853731be0460928ddcd4966a1e6a
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/31560
Reviewed-by: Stephen White <senorblanco@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-11-06 16:41:20 +00:00 committed by Commit Bot service account
parent 16036cf206
commit a701961ad3
2 changed files with 44 additions and 6 deletions

View File

@ -166,6 +166,18 @@ namespace dawn_native { namespace vulkan {
} }
} }
uint32_t MinImageCountForPresentMode(VkPresentModeKHR mode) {
switch (mode) {
case VK_PRESENT_MODE_FIFO_KHR:
case VK_PRESENT_MODE_IMMEDIATE_KHR:
return 2;
case VK_PRESENT_MODE_MAILBOX_KHR:
return 3;
default:
UNREACHABLE();
}
}
} // anonymous namespace } // anonymous namespace
// static // static
@ -242,7 +254,7 @@ namespace dawn_native { namespace vulkan {
createInfo.pNext = nullptr; createInfo.pNext = nullptr;
createInfo.flags = 0; createInfo.flags = 0;
createInfo.surface = mVkSurface; createInfo.surface = mVkSurface;
createInfo.minImageCount = 3; // TODO createInfo.minImageCount = mConfig.targetImageCount;
createInfo.imageFormat = mConfig.format; createInfo.imageFormat = mConfig.format;
createInfo.imageColorSpace = mConfig.colorSpace; createInfo.imageColorSpace = mConfig.colorSpace;
createInfo.imageExtent = mConfig.extent; createInfo.imageExtent = mConfig.extent;
@ -251,8 +263,8 @@ namespace dawn_native { namespace vulkan {
createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; createInfo.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE;
createInfo.queueFamilyIndexCount = 0; createInfo.queueFamilyIndexCount = 0;
createInfo.pQueueFamilyIndices = nullptr; createInfo.pQueueFamilyIndices = nullptr;
createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; // TODO createInfo.preTransform = mConfig.transform;
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; // TODO createInfo.compositeAlpha = mConfig.alphaMode;
createInfo.presentMode = mConfig.presentMode; createInfo.presentMode = mConfig.presentMode;
createInfo.clipped = false; createInfo.clipped = false;
createInfo.oldSwapchain = previousVkSwapChain; createInfo.oldSwapchain = previousVkSwapChain;
@ -268,9 +280,6 @@ namespace dawn_native { namespace vulkan {
device->fn.GetSwapchainImagesKHR(device->GetVkDevice(), mSwapChain, &count, nullptr), device->fn.GetSwapchainImagesKHR(device->GetVkDevice(), mSwapChain, &count, nullptr),
"GetSwapChainImages1")); "GetSwapChainImages1"));
// TODO(cwallez@chromium.org): Figure out if we can only have more swapchain images, or also
// less than requested (and what should happen in that case).
ASSERT(count >= 3);
mSwapChainImages.resize(count); mSwapChainImages.resize(count);
DAWN_TRY(CheckVkSuccess( DAWN_TRY(CheckVkSuccess(
device->fn.GetSwapchainImagesKHR(device->GetVkDevice(), mSwapChain, &count, device->fn.GetSwapchainImagesKHR(device->GetVkDevice(), mSwapChain, &count,
@ -355,6 +364,32 @@ namespace dawn_native { namespace vulkan {
config.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR; config.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
config.wgpuFormat = wgpu::TextureFormat::BGRA8Unorm; config.wgpuFormat = wgpu::TextureFormat::BGRA8Unorm;
// Only the identity transform with opaque alpha is supported for now.
if ((surfaceInfo.capabilities.supportedTransforms &
VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) == 0) {
return DAWN_VALIDATION_ERROR("Vulkan swapchain must support the identity transform");
}
config.transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
if ((surfaceInfo.capabilities.supportedCompositeAlpha &
VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR) == 0) {
return DAWN_VALIDATION_ERROR("Vulkan swapchain must support opaque alpha");
}
config.alphaMode = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
// Choose the number of images for the swapchain= and clamp it to the min and max from the
// surface capabilities. maxImageCount = 0 means there is no limit.
ASSERT(surfaceInfo.capabilities.maxImageCount == 0 ||
surfaceInfo.capabilities.minImageCount <= surfaceInfo.capabilities.maxImageCount);
uint32_t targetCount = MinImageCountForPresentMode(config.presentMode);
targetCount = std::max(targetCount, surfaceInfo.capabilities.minImageCount);
if (surfaceInfo.capabilities.maxImageCount != 0) {
targetCount = std::min(targetCount, surfaceInfo.capabilities.maxImageCount);
}
config.targetImageCount = targetCount;
// Choose a valid config for the swapchain texture that will receive the blit. // Choose a valid config for the swapchain texture that will receive the blit.
if (config.needsBlit) { if (config.needsBlit) {
// Vulkan has provisions to have surfaces that adapt to the swapchain size. If that's // Vulkan has provisions to have surfaces that adapt to the swapchain size. If that's

View File

@ -61,6 +61,9 @@ namespace dawn_native { namespace vulkan {
VkImageUsageFlags usage; VkImageUsageFlags usage;
VkFormat format; VkFormat format;
VkColorSpaceKHR colorSpace; VkColorSpaceKHR colorSpace;
uint32_t targetImageCount;
VkSurfaceTransformFlagBitsKHR transform;
VkCompositeAlphaFlagBitsKHR alphaMode;
// Redundant information but as WebGPU enums to create the wgpu::Texture that // Redundant information but as WebGPU enums to create the wgpu::Texture that
// encapsulates the native swapchain texture. // encapsulates the native swapchain texture.