Skip to content

Commit 617a582

Browse files
SwapChainWebGPU: improved handling of edge cases
1 parent e14f57c commit 617a582

File tree

3 files changed

+54
-39
lines changed

3 files changed

+54
-39
lines changed

Graphics/GraphicsEngineWebGPU/include/SwapChainWebGPUImpl.hpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@
3838
namespace Diligent
3939
{
4040

41-
class WebGPUSwapChainPresentCommand;
42-
4341
/// Swap chain implementation in WebGPU backend.
4442
class SwapChainWebGPUImpl final : public SwapChainBase<ISwapChainWebGPU>
4543
{
@@ -89,13 +87,15 @@ class SwapChainWebGPUImpl final : public SwapChainBase<ISwapChainWebGPU>
8987
void RecreateSwapChain();
9088

9189
private:
92-
NativeWindow m_NativeWindow;
93-
WebGPUSurfaceWrapper m_wgpuSurface;
94-
RefCntAutoPtr<ITextureViewWebGPU> m_pBackBufferRTV;
95-
RefCntAutoPtr<ITextureViewWebGPU> m_pBackBufferSRV;
96-
RefCntAutoPtr<ITextureViewWebGPU> m_pDepthBufferDSV;
97-
std::unique_ptr<WebGPUSwapChainPresentCommand> m_pCmdPresent;
98-
bool m_VSyncEnabled = true;
90+
class PresentCommand;
91+
92+
NativeWindow m_NativeWindow;
93+
WebGPUSurfaceWrapper m_wgpuSurface;
94+
RefCntAutoPtr<ITextureViewWebGPU> m_pBackBufferRTV;
95+
RefCntAutoPtr<ITextureViewWebGPU> m_pBackBufferSRV;
96+
RefCntAutoPtr<ITextureViewWebGPU> m_pDepthBufferDSV;
97+
std::unique_ptr<PresentCommand> m_pCmdPresent;
98+
bool m_VSyncEnabled = true;
9999
};
100100

101101
} // namespace Diligent

Graphics/GraphicsEngineWebGPU/include/WebGPUStubs.hpp

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,16 @@
2929
#if PLATFORM_EMSCRIPTEN
3030

3131
inline constexpr WGPUFeatureName WGPUFeatureName_ChromiumExperimentalTimestampQueryInsidePasses = static_cast<WGPUFeatureName>(0x000003EE);
32+
inline constexpr WGPUFeatureName WGPUFeatureName_Unorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FB);
33+
inline constexpr WGPUFeatureName WGPUFeatureName_Snorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FC);
3234

33-
inline constexpr WGPUFeatureName WGPUFeatureName_Unorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FB);
34-
35-
inline constexpr WGPUFeatureName WGPUFeatureName_Snorm16TextureFormats = static_cast<WGPUFeatureName>(0x000003FC);
36-
37-
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Unorm = static_cast<WGPUTextureFormat>(0x00000060);
38-
39-
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Snorm = static_cast<WGPUTextureFormat>(0x00000063);
40-
41-
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Unorm = static_cast<WGPUTextureFormat>(0x00000061);
42-
43-
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Snorm = static_cast<WGPUTextureFormat>(0x00000064);
44-
35+
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Unorm = static_cast<WGPUTextureFormat>(0x00000060);
36+
inline constexpr WGPUTextureFormat WGPUTextureFormat_R16Snorm = static_cast<WGPUTextureFormat>(0x00000063);
37+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Unorm = static_cast<WGPUTextureFormat>(0x00000061);
38+
inline constexpr WGPUTextureFormat WGPUTextureFormat_RG16Snorm = static_cast<WGPUTextureFormat>(0x00000064);
4539
inline constexpr WGPUTextureFormat WGPUTextureFormat_RGBA16Unorm = static_cast<WGPUTextureFormat>(0x00000062);
46-
4740
inline constexpr WGPUTextureFormat WGPUTextureFormat_RGBA16Snorm = static_cast<WGPUTextureFormat>(0x00000065);
4841

42+
inline constexpr WGPUSurfaceGetCurrentTextureStatus WGPUSurfaceGetCurrentTextureStatus_Error = static_cast<WGPUSurfaceGetCurrentTextureStatus>(0x00000007);
43+
4944
#endif

Graphics/GraphicsEngineWebGPU/src/SwapChainWebGPUImpl.cpp

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "DeviceContextWebGPUImpl.hpp"
3232
#include "TextureViewWebGPU.h"
3333
#include "WebGPUTypeConversions.hpp"
34+
#include "WebGPUStubs.hpp"
3435

3536
#ifdef PLATFORM_WIN32
3637
# include <Windows.h>
@@ -116,10 +117,10 @@ WGPUTextureFormat WGPUConvertUnormToSRGB(WGPUTextureFormat Format)
116117

117118
} // namespace
118119

119-
class WebGPUSwapChainPresentCommand
120+
class SwapChainWebGPUImpl::PresentCommand
120121
{
121122
public:
122-
WebGPUSwapChainPresentCommand(IRenderDeviceWebGPU* pRenderDevice) :
123+
PresentCommand(IRenderDeviceWebGPU* pRenderDevice) :
123124
m_pRenderDevice{pRenderDevice}
124125
{
125126
}
@@ -220,30 +221,43 @@ class WebGPUSwapChainPresentCommand
220221
return true;
221222
}
222223

223-
void Execute(ITextureViewWebGPU* pTexture, ISwapChainWebGPU* pSwapChain, IDeviceContextWebGPU* pDeviceContext)
224+
WGPUSurfaceGetCurrentTextureStatus Execute(ITextureViewWebGPU* pTexture, ISwapChainWebGPU* pSwapChain, IDeviceContextWebGPU* pDeviceContext)
224225
{
225226
WGPUSurfaceTexture wgpuSurfaceTexture{};
226227
wgpuSurfaceGetCurrentTexture(pSwapChain->GetWebGPUSurface(), &wgpuSurfaceTexture);
228+
WebGPUTextureWrapper wgpuTexture{wgpuSurfaceTexture.texture};
227229

228230
switch (wgpuSurfaceTexture.status)
229231
{
230232
case WGPUSurfaceGetCurrentTextureStatus_Success:
233+
case WGPUSurfaceGetCurrentTextureStatus_Outdated:
231234
break;
232235

233236
case WGPUSurfaceGetCurrentTextureStatus_Timeout:
234-
case WGPUSurfaceGetCurrentTextureStatus_Outdated:
235-
case WGPUSurfaceGetCurrentTextureStatus_Lost:
236237
break;
237238

239+
case WGPUSurfaceGetCurrentTextureStatus_Lost:
240+
LOG_WARNING_MESSAGE("Unable to present: swap chain surface is lost");
241+
return wgpuSurfaceTexture.status;
242+
238243
case WGPUSurfaceGetCurrentTextureStatus_OutOfMemory:
244+
LOG_ERROR_MESSAGE("Unable to present: out of memory");
245+
return wgpuSurfaceTexture.status;
246+
239247
case WGPUSurfaceGetCurrentTextureStatus_DeviceLost:
240-
LOG_ERROR_MESSAGE("Failed to acquire next frame");
241-
break;
248+
LOG_ERROR_MESSAGE("Unable to present: device is lost");
249+
return wgpuSurfaceTexture.status;
250+
251+
case WGPUSurfaceGetCurrentTextureStatus_Error:
252+
LOG_ERROR_MESSAGE("Unable to present: unknown error");
253+
return wgpuSurfaceTexture.status;
254+
242255
default:
243-
break;
256+
UNEXPECTED("Unexpected status");
257+
return wgpuSurfaceTexture.status;
244258
}
245259

246-
WGPUTextureFormat ViewFormat = wgpuTextureGetFormat(wgpuSurfaceTexture.texture);
260+
WGPUTextureFormat ViewFormat = wgpuTextureGetFormat(wgpuTexture);
247261

248262
// Simplify this code once the bug for sRGB texture view is fixed in Dawn
249263
bool ConvertToGamma = false;
@@ -254,7 +268,7 @@ class WebGPUSwapChainPresentCommand
254268
ConvertToGamma = IsSRGBFormat(pSwapChain->GetDesc().ColorBufferFormat);
255269
#endif
256270
if (!InitializePipelineState(ViewFormat, ConvertToGamma))
257-
return;
271+
return WGPUSurfaceGetCurrentTextureStatus_Error;
258272

259273
WGPUTextureViewDescriptor wgpuTextureViewDesc;
260274
wgpuTextureViewDesc.nextInChain = nullptr;
@@ -267,9 +281,12 @@ class WebGPUSwapChainPresentCommand
267281
wgpuTextureViewDesc.arrayLayerCount = 1;
268282
wgpuTextureViewDesc.aspect = WGPUTextureAspect_All;
269283

270-
WebGPUTextureViewWrapper wgpuTextureView{wgpuTextureCreateView(wgpuSurfaceTexture.texture, &wgpuTextureViewDesc)};
284+
WebGPUTextureViewWrapper wgpuTextureView{wgpuTextureCreateView(wgpuTexture, &wgpuTextureViewDesc)};
271285
if (!wgpuTextureView)
272-
LOG_ERROR_MESSAGE("Failed to acquire next frame");
286+
{
287+
LOG_ERROR_MESSAGE("Failed to create texture view for WGPU surface texture");
288+
return WGPUSurfaceGetCurrentTextureStatus_Error;
289+
}
273290

274291
WGPUBindGroupEntry wgpuBindGroupEntries[1]{};
275292
wgpuBindGroupEntries[0].binding = 0;
@@ -312,7 +329,8 @@ class WebGPUSwapChainPresentCommand
312329
#else
313330
wgpuSurfacePresent(pSwapChain->GetWebGPUSurface());
314331
#endif
315-
wgpuTextureRelease(wgpuSurfaceTexture.texture);
332+
333+
return wgpuSurfaceTexture.status;
316334
}
317335

318336
private:
@@ -335,8 +353,8 @@ SwapChainWebGPUImpl::SwapChainWebGPUImpl(IReferenceCounters* pRefCounters,
335353
pDeviceContext,
336354
SCDesc
337355
},
338-
m_NativeWindow(Window),
339-
m_pCmdPresent(std::make_unique<WebGPUSwapChainPresentCommand>(pRenderDevice))
356+
m_NativeWindow{Window},
357+
m_pCmdPresent{std::make_unique<PresentCommand>(pRenderDevice)}
340358
// clang-format on
341359
{
342360
if (m_DesiredPreTransform != SURFACE_TRANSFORM_OPTIMAL && m_DesiredPreTransform != SURFACE_TRANSFORM_IDENTITY)
@@ -371,7 +389,7 @@ void SwapChainWebGPUImpl::Present(Uint32 SyncInterval)
371389
DeviceContextWebGPUImpl* pImmediateCtxWebGPU = pDeviceContext.RawPtr<DeviceContextWebGPUImpl>();
372390

373391
pImmediateCtxWebGPU->Flush();
374-
m_pCmdPresent->Execute(m_pBackBufferSRV, this, pImmediateCtxWebGPU);
392+
WGPUSurfaceGetCurrentTextureStatus SurfaceStatus = m_pCmdPresent->Execute(m_pBackBufferSRV, this, pImmediateCtxWebGPU);
375393

376394
if (m_SwapChainDesc.IsPrimary)
377395
{
@@ -380,7 +398,9 @@ void SwapChainWebGPUImpl::Present(Uint32 SyncInterval)
380398
}
381399

382400
const bool EnableVSync = SyncInterval != 0;
383-
if (m_VSyncEnabled != EnableVSync)
401+
if (SurfaceStatus == WGPUSurfaceGetCurrentTextureStatus_Outdated ||
402+
SurfaceStatus == WGPUSurfaceGetCurrentTextureStatus_Lost ||
403+
m_VSyncEnabled != EnableVSync)
384404
{
385405
m_VSyncEnabled = EnableVSync;
386406
RecreateSwapChain();

0 commit comments

Comments
 (0)