3232#include " TextureViewWebGPU.h"
3333#include " WebGPUTypeConversions.hpp"
3434#include " WebGPUStubs.hpp"
35+ #include " webgpu/webgpu.h"
36+ #include < cstdint>
3537
3638#ifdef PLATFORM_WIN32
3739# include < Windows.h>
@@ -117,6 +119,7 @@ WGPUTextureFormat WGPUConvertUnormToSRGB(WGPUTextureFormat Format)
117119
118120} // namespace
119121
122+ /*
120123class SwapChainWebGPUImpl::PresentCommand
121124{
122125public:
@@ -318,11 +321,7 @@ class SwapChainWebGPUImpl::PresentCommand
318321
319322 wgpuQueueSubmit(pDeviceContext->GetWebGPUQueue(), 1, &wgpuCmdBuffer.Get());
320323
321- #if PLATFORM_WEB
322- emscripten_request_animation_frame ([](double Time, void * pUserData) -> EM_BOOL { return EM_FALSE; }, nullptr );
323- #else
324- wgpuSurfacePresent (pSwapChain->GetWebGPUSurface ());
325- #endif
324+
326325
327326 return wgpuSurfaceTexture.status;
328327 }
@@ -339,6 +338,7 @@ class SwapChainWebGPUImpl::PresentCommand
339338 WebGPUPipelineLayoutWrapper m_wgpuPipelineLayout;
340339 WebGPURenderPipelineWrapper m_wgpuRenderPipeline;
341340};
341+ */
342342
343343SwapChainWebGPUImpl::SwapChainWebGPUImpl (IReferenceCounters* pRefCounters,
344344 const SwapChainDesc& SCDesc,
@@ -353,8 +353,7 @@ SwapChainWebGPUImpl::SwapChainWebGPUImpl(IReferenceCounters* pRefCounters,
353353 pDeviceContext,
354354 SCDesc
355355 },
356- m_NativeWindow{Window},
357- m_pCmdPresent{std::make_unique<PresentCommand>(pRenderDevice)}
356+ m_NativeWindow{Window}
358357// clang-format on
359358{
360359 if (m_DesiredPreTransform != SURFACE_TRANSFORM_OPTIMAL && m_DesiredPreTransform != SURFACE_TRANSFORM_IDENTITY)
@@ -368,7 +367,14 @@ SwapChainWebGPUImpl::SwapChainWebGPUImpl(IReferenceCounters* pRefCounters,
368367
369368 CreateSurface ();
370369 ConfigureSurface ();
371- CreateBuffersAndViews ();
370+ CreateDepthBufferView ();
371+
372+ WGPUSurfaceGetCurrentTextureStatus wgpuStatus = AcquireSurfaceTexture ();
373+ if (wgpuStatus != WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal &&
374+ wgpuStatus != WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal)
375+ {
376+ LOG_ERROR_MESSAGE (" Failed to acquire the initial swap chain surface texture" );
377+ }
372378}
373379
374380SwapChainWebGPUImpl::~SwapChainWebGPUImpl () = default ;
@@ -387,9 +393,15 @@ void SwapChainWebGPUImpl::Present(Uint32 SyncInterval)
387393 }
388394
389395 DeviceContextWebGPUImpl* pImmediateCtxWebGPU = pDeviceContext.RawPtr <DeviceContextWebGPUImpl>();
390-
391396 pImmediateCtxWebGPU->Flush ();
392- WGPUSurfaceGetCurrentTextureStatus SurfaceStatus = m_pCmdPresent->Execute (m_pBackBufferSRV, this , pImmediateCtxWebGPU);
397+
398+ #if PLATFORM_WEB
399+ emscripten_request_animation_frame ([](double Time, void * pUserData) -> EM_BOOL { return EM_FALSE; }, nullptr );
400+ #else
401+ wgpuSurfacePresent (m_wgpuSurface);
402+ #endif
403+
404+ WGPUSurfaceGetCurrentTextureStatus wgpuStatus = AcquireSurfaceTexture ();
393405
394406 if (m_SwapChainDesc.IsPrimary )
395407 {
@@ -398,8 +410,8 @@ void SwapChainWebGPUImpl::Present(Uint32 SyncInterval)
398410 }
399411
400412 const bool EnableVSync = SyncInterval != 0 ;
401- if (SurfaceStatus == WGPUSurfaceGetCurrentTextureStatus_Outdated ||
402- SurfaceStatus == WGPUSurfaceGetCurrentTextureStatus_Lost ||
413+ if (wgpuStatus == WGPUSurfaceGetCurrentTextureStatus_Outdated ||
414+ wgpuStatus == WGPUSurfaceGetCurrentTextureStatus_Lost ||
403415 m_VSyncEnabled != EnableVSync)
404416 {
405417 m_VSyncEnabled = EnableVSync;
@@ -436,9 +448,9 @@ void SwapChainWebGPUImpl::CreateSurface()
436448 wgpuSurfaceNativeDesc.hinstance = GetModuleHandle (nullptr );
437449#elif PLATFORM_LINUX
438450 WGPUSurfaceSourceXCBWindow wgpuSurfaceNativeDesc{};
439- wgpuSurfaceNativeDesc.chain = {nullptr , WGPUSType_SurfaceSourceXCBWindow};
451+ wgpuSurfaceNativeDesc.chain = {nullptr , WGPUSType_SurfaceSourceXCBWindow};
440452 wgpuSurfaceNativeDesc.connection = m_NativeWindow.pXCBConnection ;
441- wgpuSurfaceNativeDesc.window = m_NativeWindow.WindowId ;
453+ wgpuSurfaceNativeDesc.window = m_NativeWindow.WindowId ;
442454#elif PLATFROM_MACOS
443455 WGPUSurfaceSourceMetalLayer wgpuSurfaceNativeDesc{};
444456 wgpuSurfaceNativeDesc.chain = {nullptr , WGPUSType_SurfaceSourceMetalLayer};
@@ -512,6 +524,23 @@ void SwapChainWebGPUImpl::ConfigureSurface()
512524 return Result;
513525 };
514526
527+ auto SelectFormat = [&](TEXTURE_FORMAT Format) {
528+ WGPUTextureFormat wgpuFormat = TextureFormatToWGPUFormat (SRGBFormatToUnorm (Format));
529+
530+ const WGPUTextureFormat* FindBegin = wgpuSurfaceCapabilities.formats ;
531+ const WGPUTextureFormat* FindEnd = wgpuSurfaceCapabilities.formats + wgpuSurfaceCapabilities.formatCount ;
532+
533+ if (std::find (FindBegin, FindEnd, wgpuFormat) != FindEnd)
534+ {
535+ return wgpuFormat;
536+ }
537+ else
538+ {
539+ LOG_ERROR_MESSAGE (" Failed to find the requested format in the surface capabilities. Using the first available format instead." );
540+ return wgpuSurfaceCapabilities.formats [0 ];
541+ }
542+ };
543+
515544 if (m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0 )
516545 {
517546#if PLATFORM_WIN32
@@ -521,64 +550,96 @@ void SwapChainWebGPUImpl::ConfigureSurface()
521550 m_SwapChainDesc.Width = WindowRect.right - WindowRect.left ;
522551 m_SwapChainDesc.Height = WindowRect.bottom - WindowRect.top ;
523552#elif PLATFORM_WEB
524- int32_t CanvasWidth = 0 ;
553+ int32_t CanvasWidth = 0 ;
525554 int32_t CanvasHeight = 0 ;
526555 emscripten_get_canvas_element_size (m_NativeWindow.pCanvasId , &CanvasWidth, &CanvasHeight);
527556
528- m_SwapChainDesc.Width = static_cast <Uint32>(CanvasWidth);
557+ m_SwapChainDesc.Width = static_cast <Uint32>(CanvasWidth);
529558 m_SwapChainDesc.Height = static_cast <Uint32>(CanvasHeight);
530559#endif
531560
532561 m_SwapChainDesc.Width = (std::max)(m_SwapChainDesc.Width , 1u );
533562 m_SwapChainDesc.Height = (std::max)(m_SwapChainDesc.Height , 1u );
534563 }
535564
536- const WGPUTextureFormat wgpuPreferredFormat = wgpuSurfaceCapabilities. formats [ 0 ] ;
565+ const WGPUTextureFormat wgpuPreferredFormat = SelectFormat (m_SwapChainDesc. ColorBufferFormat ) ;
537566
538- WGPUTextureFormat wgpuRTVFormats[] = {
539- wgpuPreferredFormat,
540- WGPUConvertUnormToSRGB (wgpuPreferredFormat),
541- };
567+ std::vector<WGPUTextureFormat> wgpuRTVFormats;
568+ wgpuRTVFormats.push_back (wgpuPreferredFormat);
569+ if (IsSRGBFormat (m_SwapChainDesc.ColorBufferFormat ))
570+ wgpuRTVFormats.push_back (WGPUConvertUnormToSRGB (wgpuPreferredFormat));
571+
572+ WGPUSurfaceColorManagement wgpuColorManagement{};
573+ wgpuColorManagement.chain .sType = WGPUSType_SurfaceColorManagement;
574+ wgpuColorManagement.colorSpace = WGPUPredefinedColorSpace_DisplayP3;
575+ wgpuColorManagement.toneMappingMode = WGPUToneMappingMode_Extended;
542576
543577 WGPUSurfaceConfiguration wgpuSurfaceConfig{};
544- wgpuSurfaceConfig.nextInChain = nullptr ;
578+ wgpuSurfaceConfig.nextInChain = &wgpuColorManagement. chain ;
545579 wgpuSurfaceConfig.device = pRenderDeviceWebGPU->GetWebGPUDevice ();
546580 wgpuSurfaceConfig.usage = SelectUsage (m_SwapChainDesc.Usage );
547581 wgpuSurfaceConfig.width = m_SwapChainDesc.Width ;
548582 wgpuSurfaceConfig.height = m_SwapChainDesc.Height ;
549583 wgpuSurfaceConfig.format = wgpuPreferredFormat;
550584 wgpuSurfaceConfig.presentMode = SelectPresentMode (m_VSyncEnabled);
551585 wgpuSurfaceConfig.alphaMode = WGPUCompositeAlphaMode_Auto;
552- wgpuSurfaceConfig.viewFormats = wgpuRTVFormats;
553- wgpuSurfaceConfig.viewFormatCount = _countof (wgpuRTVFormats);
586+ wgpuSurfaceConfig.viewFormats = wgpuRTVFormats. data () ;
587+ wgpuSurfaceConfig.viewFormatCount = static_cast < uint32_t > (wgpuRTVFormats. size () );
554588
555589 wgpuSurfaceConfigure (m_wgpuSurface, &wgpuSurfaceConfig);
556590 wgpuSurfaceCapabilitiesFreeMembers (wgpuSurfaceCapabilities);
557591}
558592
559- void SwapChainWebGPUImpl::CreateBuffersAndViews ()
593+ WGPUSurfaceGetCurrentTextureStatus SwapChainWebGPUImpl::AcquireSurfaceTexture ()
560594{
595+ m_pBackBufferRTV.Release ();
596+
597+ WGPUSurfaceTexture wgpuSurfaceTexture{};
598+ wgpuSurfaceGetCurrentTexture (m_wgpuSurface, &wgpuSurfaceTexture);
599+
600+ WGPUTextureFormat wgpuFormat = wgpuTextureGetFormat (wgpuSurfaceTexture.texture );
601+ uint32_t wgpuSurfaceWidth = wgpuTextureGetWidth (wgpuSurfaceTexture.texture );
602+ uint32_t wgpuSurfaceHeight = wgpuTextureGetHeight (wgpuSurfaceTexture.texture );
603+
561604 TextureDesc BackBufferDesc{};
605+ BackBufferDesc.Name = " Main back buffer" ;
562606 BackBufferDesc.Type = RESOURCE_DIM_TEX_2D;
563- BackBufferDesc.Width = m_SwapChainDesc.Width ;
564- BackBufferDesc.Height = m_SwapChainDesc.Height ;
565- BackBufferDesc.Format = m_SwapChainDesc.ColorBufferFormat ;
566- BackBufferDesc.SampleCount = 1 ;
607+ BackBufferDesc.Width = wgpuSurfaceWidth;
608+ BackBufferDesc.Height = wgpuSurfaceHeight;
609+ BackBufferDesc.Format = WGPUFormatToTextureFormat (wgpuFormat);
567610 BackBufferDesc.Usage = USAGE_DEFAULT;
568- BackBufferDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET;
569- BackBufferDesc.Name = " Main back buffer" ;
611+ BackBufferDesc.BindFlags = BIND_RENDER_TARGET;
570612
571- RefCntAutoPtr<ITexture> pBackBufferTex;
572- m_pRenderDevice->CreateTexture (BackBufferDesc, nullptr , &pBackBufferTex);
573- m_pBackBufferRTV = RefCntAutoPtr<ITextureViewWebGPU>{pBackBufferTex->GetDefaultView (TEXTURE_VIEW_RENDER_TARGET), IID_TextureViewWebGPU};
574- m_pBackBufferSRV = RefCntAutoPtr<ITextureViewWebGPU>{pBackBufferTex->GetDefaultView (TEXTURE_VIEW_SHADER_RESOURCE), IID_TextureViewWebGPU};
613+ RefCntAutoPtr<ITexture> pBackBufferTexture;
614+ m_pRenderDevice.RawPtr <RenderDeviceWebGPUImpl>()->CreateTextureFromWebGPUTexture (wgpuSurfaceTexture.texture , BackBufferDesc, RESOURCE_STATE_UNDEFINED, &pBackBufferTexture);
575615
616+ if (IsSRGBFormat (m_SwapChainDesc.ColorBufferFormat ))
617+ {
618+ TextureViewDesc BackBufferRTVDesc{};
619+ BackBufferRTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
620+ BackBufferRTVDesc.Format = m_SwapChainDesc.ColorBufferFormat ;
621+
622+ RefCntAutoPtr<ITextureView> pBackBufferRTV;
623+ pBackBufferTexture->CreateView (BackBufferRTVDesc, &pBackBufferRTV);
624+ m_pBackBufferRTV = RefCntAutoPtr<ITextureViewWebGPU>{pBackBufferRTV, IID_TextureViewWebGPU};
625+ }
626+ else
627+ {
628+ m_pBackBufferRTV = RefCntAutoPtr<ITextureViewWebGPU>{pBackBufferTexture->GetDefaultView (TEXTURE_VIEW_RENDER_TARGET), IID_TextureViewWebGPU};
629+ }
630+
631+ return wgpuSurfaceTexture.status ;
632+ }
633+
634+ void SwapChainWebGPUImpl::CreateDepthBufferView ()
635+ {
576636 if (m_SwapChainDesc.DepthBufferFormat != TEX_FORMAT_UNKNOWN)
577637 {
578638 TextureDesc DepthBufferDesc{};
639+ DepthBufferDesc.Name = " Main depth buffer" ;
579640 DepthBufferDesc.Type = RESOURCE_DIM_TEX_2D;
580- DepthBufferDesc.Width = BackBufferDesc .Width ;
581- DepthBufferDesc.Height = BackBufferDesc .Height ;
641+ DepthBufferDesc.Width = m_SwapChainDesc .Width ;
642+ DepthBufferDesc.Height = m_SwapChainDesc .Height ;
582643 DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat ;
583644 DepthBufferDesc.SampleCount = 1 ;
584645 DepthBufferDesc.Usage = USAGE_DEFAULT;
@@ -587,7 +648,7 @@ void SwapChainWebGPUImpl::CreateBuffersAndViews()
587648 DepthBufferDesc.ClearValue .Format = DepthBufferDesc.Format ;
588649 DepthBufferDesc.ClearValue .DepthStencil .Depth = m_SwapChainDesc.DefaultDepthValue ;
589650 DepthBufferDesc.ClearValue .DepthStencil .Stencil = m_SwapChainDesc.DefaultStencilValue ;
590- DepthBufferDesc. Name = " Main depth buffer " ;
651+
591652 RefCntAutoPtr<ITexture> pDepthBufferTex;
592653 m_pRenderDevice->CreateTexture (DepthBufferDesc, nullptr , &pDepthBufferTex);
593654 m_pDepthBufferDSV = RefCntAutoPtr<ITextureViewWebGPU>{pDepthBufferTex->GetDefaultView (TEXTURE_VIEW_DEPTH_STENCIL), IID_TextureViewWebGPU};
@@ -599,8 +660,6 @@ void SwapChainWebGPUImpl::ReleaseSwapChainResources()
599660 if (!m_wgpuSurface)
600661 return ;
601662
602- m_pCmdPresent->ReleaseSwapChainResources ();
603- m_pBackBufferSRV.Release ();
604663 m_pBackBufferRTV.Release ();
605664 m_pDepthBufferDSV.Release ();
606665}
@@ -611,7 +670,7 @@ void SwapChainWebGPUImpl::RecreateSwapChain()
611670 {
612671 ReleaseSwapChainResources ();
613672 ConfigureSurface ();
614- CreateBuffersAndViews ();
673+ CreateDepthBufferView ();
615674 }
616675 catch (const std::runtime_error&)
617676 {
0 commit comments