Corentin Wallez 2ce1d927e9 SwapChainVk: handle mismatching size and usage with a blit
In Vulkan the swapchain can stop working if the window resizes and
doesn't match the size of the swapchain images anymore. WebGPU
applications might not handle resizes instantly, so if the swapchain
becomes incompatible we give them a temporary texture that we'll then
blit inside the real swapchain texture.

This also handles the case where the application requires more usages
than what the swapchain can support.

In addition, temporary checks are added that fail swapchain creation if
the VkSurface doesn't support BGRA8Unorm which is the only allowed
format for WebGPU swapchains at the moment.

SwapChainTests should now work on Vulkan and are enabled.

Bug: dawn:269

Change-Id: I812c0653125ed86d3a0f8f67347e961c7b207a98
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/30700
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
2020-10-22 17:07:49 +00:00

95 lines
3.2 KiB
C++

// Copyright 2018 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DAWNNATIVE_VULKAN_SWAPCHAINVK_H_
#define DAWNNATIVE_VULKAN_SWAPCHAINVK_H_
#include "dawn_native/SwapChain.h"
#include "common/vulkan_platform.h"
#include <vector>
namespace dawn_native { namespace vulkan {
class Device;
class Texture;
struct VulkanSurfaceInfo;
class OldSwapChain : public OldSwapChainBase {
public:
static OldSwapChain* Create(Device* device, const SwapChainDescriptor* descriptor);
protected:
OldSwapChain(Device* device, const SwapChainDescriptor* descriptor);
~OldSwapChain() override;
TextureBase* GetNextTextureImpl(const TextureDescriptor* descriptor) override;
MaybeError OnBeforePresent(TextureViewBase* texture) override;
private:
wgpu::TextureUsage mTextureUsage;
};
class SwapChain : public NewSwapChainBase {
public:
static ResultOrError<SwapChain*> Create(Device* device,
Surface* surface,
NewSwapChainBase* previousSwapChain,
const SwapChainDescriptor* descriptor);
~SwapChain() override;
private:
using NewSwapChainBase::NewSwapChainBase;
MaybeError Initialize(NewSwapChainBase* previousSwapChain);
struct Config {
// Information that's passed to vulkan swapchain creation.
VkPresentModeKHR presentMode;
VkExtent2D extent;
VkImageUsageFlags usage;
VkFormat format;
VkColorSpaceKHR colorSpace;
// Redundant information but as WebGPU enums to create the wgpu::Texture that
// encapsulates the native swapchain texture.
wgpu::TextureUsage wgpuUsage;
wgpu::TextureFormat wgpuFormat;
// Information about the blit workarounds we need to do (if any)
bool needsBlit = false;
};
ResultOrError<Config> ChooseConfig(const VulkanSurfaceInfo& surfaceInfo) const;
ResultOrError<TextureViewBase*> GetCurrentTextureViewInternal(bool isReentrant = false);
// NewSwapChainBase implementation
MaybeError PresentImpl() override;
ResultOrError<TextureViewBase*> GetCurrentTextureViewImpl() override;
void DetachFromSurfaceImpl() override;
Config mConfig;
VkSurfaceKHR mVkSurface = VK_NULL_HANDLE;
VkSwapchainKHR mSwapChain = VK_NULL_HANDLE;
std::vector<VkImage> mSwapChainImages;
uint32_t mLastImageIndex = 0;
Ref<Texture> mBlitTexture;
Ref<Texture> mTexture;
};
}} // namespace dawn_native::vulkan
#endif // DAWNNATIVE_VULKAN_SWAPCHAINVK_H_