mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-21 10:49:14 +00:00
Implement the webgpu.h swapchains in the frontend and Null backend.
The state-tracking of the webgpu.h swapchain is a bit complicated because contrary to implementation-based swapchains, they have more guarantees and a "replacing mechanism". For example instead of hoping the implementation-based swapchain resize automatically, the surface-based swapchain needs to be replaced by a new swapchain and invalidated. This mechanism of invalidation also needs to be triggered when the last reference to the surface is lost because we don't want to risk the application destroying the window from under us. Adds tests for all the cases of invalidation I could think of apart from device loss. Bug: dawn:269 Change-Id: Id515dbb640e13c6e30bb1f1e93b8e54f1e2bba4b Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/15400 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
0df4753ba6
commit
d26ee85fba
@@ -15,6 +15,7 @@
|
||||
#include "dawn_native/SwapChain.h"
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "dawn_native/Adapter.h"
|
||||
#include "dawn_native/Device.h"
|
||||
#include "dawn_native/Surface.h"
|
||||
#include "dawn_native/Texture.h"
|
||||
@@ -96,6 +97,19 @@ namespace dawn_native {
|
||||
return {};
|
||||
}
|
||||
|
||||
TextureDescriptor GetSwapChainBaseTextureDescriptor(NewSwapChainBase* swapChain) {
|
||||
TextureDescriptor desc;
|
||||
desc.usage = swapChain->GetUsage();
|
||||
desc.dimension = wgpu::TextureDimension::e2D;
|
||||
desc.size = {swapChain->GetWidth(), swapChain->GetHeight(), 1};
|
||||
desc.arrayLayerCount = 1;
|
||||
desc.format = swapChain->GetFormat();
|
||||
desc.mipLevelCount = 1;
|
||||
desc.sampleCount = 1;
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
// SwapChainBase
|
||||
|
||||
SwapChainBase::SwapChainBase(DeviceBase* device) : ObjectBase(device) {
|
||||
@@ -246,6 +260,7 @@ namespace dawn_native {
|
||||
Surface* surface,
|
||||
const SwapChainDescriptor* descriptor)
|
||||
: SwapChainBase(device),
|
||||
mAttached(true),
|
||||
mWidth(descriptor->width),
|
||||
mHeight(descriptor->height),
|
||||
mFormat(descriptor->format),
|
||||
@@ -253,6 +268,25 @@ namespace dawn_native {
|
||||
mSurface(surface) {
|
||||
}
|
||||
|
||||
NewSwapChainBase::~NewSwapChainBase() {
|
||||
if (mCurrentTextureView.Get() != nullptr) {
|
||||
ASSERT(mCurrentTextureView->GetTexture()->GetTextureState() ==
|
||||
TextureBase::TextureState::Destroyed);
|
||||
}
|
||||
|
||||
ASSERT(!mAttached);
|
||||
ASSERT(mSurface == nullptr);
|
||||
}
|
||||
|
||||
void NewSwapChainBase::DetachFromSurface() {
|
||||
if (mAttached) {
|
||||
DetachFromSurfaceImpl();
|
||||
GetSurface()->SetAttachedSwapChain(nullptr);
|
||||
mSurface = nullptr;
|
||||
mAttached = false;
|
||||
}
|
||||
}
|
||||
|
||||
void NewSwapChainBase::Configure(wgpu::TextureFormat format,
|
||||
wgpu::TextureUsage allowedUsage,
|
||||
uint32_t width,
|
||||
@@ -262,14 +296,48 @@ namespace dawn_native {
|
||||
}
|
||||
|
||||
TextureViewBase* NewSwapChainBase::GetCurrentTextureView() {
|
||||
GetDevice()->ConsumedError(DAWN_VALIDATION_ERROR(
|
||||
"GetCurrentTextureView not implemented yet for surface-based swapchains"));
|
||||
return TextureViewBase::MakeError(GetDevice());
|
||||
if (GetDevice()->ConsumedError(ValidateGetCurrentTextureView())) {
|
||||
return TextureViewBase::MakeError(GetDevice());
|
||||
}
|
||||
|
||||
if (mCurrentTextureView.Get() != nullptr) {
|
||||
// Calling GetCurrentTextureView always returns a new reference so add it even when
|
||||
// reusing the existing texture view.
|
||||
mCurrentTextureView->Reference();
|
||||
return mCurrentTextureView.Get();
|
||||
}
|
||||
|
||||
TextureViewBase* view = nullptr;
|
||||
if (GetDevice()->ConsumedError(GetCurrentTextureViewImpl(), &view)) {
|
||||
return TextureViewBase::MakeError(GetDevice());
|
||||
}
|
||||
|
||||
// Check that the return texture view matches exactly what was given for this descriptor.
|
||||
ASSERT(view->GetTexture()->GetFormat().format == mFormat);
|
||||
ASSERT((view->GetTexture()->GetUsage() & mUsage) == mUsage);
|
||||
ASSERT(view->GetLevelCount() == 1);
|
||||
ASSERT(view->GetLayerCount() == 1);
|
||||
ASSERT(view->GetDimension() == wgpu::TextureViewDimension::e2D);
|
||||
ASSERT(view->GetTexture()->GetMipLevelVirtualSize(view->GetBaseMipLevel()).width == mWidth);
|
||||
ASSERT(view->GetTexture()->GetMipLevelVirtualSize(view->GetBaseMipLevel()).height ==
|
||||
mHeight);
|
||||
|
||||
mCurrentTextureView = view;
|
||||
return view;
|
||||
}
|
||||
|
||||
void NewSwapChainBase::Present() {
|
||||
GetDevice()->ConsumedError(
|
||||
DAWN_VALIDATION_ERROR("Present not implemented yet for surface-based swapchains"));
|
||||
if (GetDevice()->ConsumedError(ValidatePresent())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetDevice()->ConsumedError(PresentImpl())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(mCurrentTextureView->GetTexture()->GetTextureState() ==
|
||||
TextureBase::TextureState::Destroyed);
|
||||
mCurrentTextureView = nullptr;
|
||||
}
|
||||
|
||||
uint32_t NewSwapChainBase::GetWidth() const {
|
||||
@@ -289,7 +357,41 @@ namespace dawn_native {
|
||||
}
|
||||
|
||||
Surface* NewSwapChainBase::GetSurface() {
|
||||
return mSurface.Get();
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
bool NewSwapChainBase::IsAttached() const {
|
||||
return mAttached;
|
||||
}
|
||||
|
||||
wgpu::BackendType NewSwapChainBase::GetBackendType() const {
|
||||
return GetDevice()->GetAdapter()->GetBackendType();
|
||||
}
|
||||
|
||||
MaybeError NewSwapChainBase::ValidatePresent() const {
|
||||
DAWN_TRY(GetDevice()->ValidateIsAlive());
|
||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||
|
||||
if (!mAttached) {
|
||||
return DAWN_VALIDATION_ERROR("Presenting on detached swapchain");
|
||||
}
|
||||
|
||||
if (mCurrentTextureView.Get() == nullptr) {
|
||||
return DAWN_VALIDATION_ERROR("Presenting without prior GetCurrentTextureView");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
MaybeError NewSwapChainBase::ValidateGetCurrentTextureView() const {
|
||||
DAWN_TRY(GetDevice()->ValidateIsAlive());
|
||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||
|
||||
if (!mAttached) {
|
||||
return DAWN_VALIDATION_ERROR("Getting view on detached swapchain");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
||||
Reference in New Issue
Block a user