Skip to content

Commit 41bad61

Browse files
Sample app: Added WebGPU mode (close #168)
1 parent 98a9279 commit 41bad61

File tree

11 files changed

+129
-11
lines changed

11 files changed

+129
-11
lines changed

.github/workflows/build-emscripten.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ jobs:
88
matrix:
99
os: ["windows-latest", "ubuntu-20.04", "macos-14"]
1010
build_type: ["Debug", "Release"]
11+
cmake_args: ["-DDILIGENT_EMSCRIPTEN_STRIP_DEBUG_INFO=ON"]
1112
exclude:
1213
# Exclude MacOS-Release
1314
- os: "macos-14"
@@ -41,6 +42,7 @@ jobs:
4142
uses: DiligentGraphics/github-action/configure-cmake@v1
4243
with:
4344
build-type: ${{ matrix.build_type }}
45+
cmake-args: ${{ matrix.cmake_args }}
4446

4547
- name: Build
4648
if: success()

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ else()
99
set(DILIGENT_INSTALL_SAMPLES OFF)
1010
endif()
1111

12-
option(DILIGENT_BUILD_SAMPLE_BASE_ONLY "Build only SampleBase project" OFF)
12+
option(DILIGENT_BUILD_SAMPLE_BASE_ONLY "Build only SampleBase project" OFF)
13+
option(DILIGENT_EMSCRIPTEN_STRIP_DEBUG_INFO "Strip debug information from Emscripten build" OFF)
1314

1415
function(add_sample_app APP_NAME IDE_FOLDER SOURCE INCLUDE SHADERS ASSETS)
1516

SampleBase/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ if(PLATFORM_WIN32)
1818
src/Win32/resources/directx12-logo.bmp
1919
src/Win32/resources/vulkan-logo.bmp
2020
src/Win32/resources/opengl-logo.bmp
21+
src/Win32/resources/webgpu-logo.bmp
2122
src/Win32/resources/Win32AppResource.rc
2223
)
2324

@@ -129,7 +130,11 @@ elseif(PLATFORM_EMSCRIPTEN)
129130
set(HTML_TEMPLATE_FILE
130131
${SAMPLE_BASE_SOURCE_DIR}/src/Emscripten/resources/emscripten_template.html
131132
)
132-
target_link_options(${TARGET_NAME} PRIVATE "SHELL: --shell-file '${HTML_TEMPLATE_FILE}'")
133+
134+
target_link_options(${TARGET_NAME} PRIVATE "SHELL: --shell-file '${HTML_TEMPLATE_FILE}' -s WASM_BIGINT")
135+
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug" AND DILIGENT_EMSCRIPTEN_STRIP_DEBUG_INFO)
136+
target_link_options(${TARGET_NAME} PRIVATE "SHELL: -gseparate-dwarf -g0")
137+
endif()
133138
endfunction()
134139

135140
else()

SampleBase/src/Emscripten/SampleAppEmscripten.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525

2626
#include "SampleApp.hpp"
27-
#include "RenderDeviceGLES.h"
2827
#include "ImGuiImplEmscripten.hpp"
2928
#include <emscripten.h>
3029
#include <emscripten/html5.h>
@@ -38,7 +37,11 @@ class SampleAppEmscripten : public SampleApp
3837
public:
3938
SampleAppEmscripten()
4039
{
40+
#if WEBGPU_SUPPORTED
41+
m_DeviceType = RENDER_DEVICE_TYPE_WEBGPU;
42+
#else
4143
m_DeviceType = RENDER_DEVICE_TYPE_GLES;
44+
#endif
4245
}
4346

4447
void OnWindowCreated(const char* CanvasID, int32_t WindowWidth, int32_t WindowHeight) override

SampleBase/src/Emscripten/resources/emscripten_template.html

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
<body>
3535
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()" tabindex=-1></canvas>
3636
<script type='text/javascript'>
37-
var Module = {
37+
var Module;
38+
(async() => {
39+
Module= {
3840
preRun: [],
3941
postRun: function() {
4042
var canvas = document.getElementById('canvas');
@@ -69,9 +71,30 @@
6971
// no run dependencies to log
7072
}
7173
};
74+
7275
window.onerror = function () {
7376
console.log("onerror: " + event);
7477
};
78+
79+
{
80+
const requiredFeatures = [
81+
"depth-clip-control",
82+
"depth32float-stencil8",
83+
"texture-compression-bc",
84+
"indirect-first-instance",
85+
"shader-f16",
86+
"rg11b10ufloat-renderable",
87+
"bgra8unorm-storage",
88+
"float32-filterable",
89+
];
90+
91+
const adapter = await navigator.gpu.requestAdapter();
92+
const device = await adapter.requestDevice({
93+
requiredFeatures: requiredFeatures.filter(feature => adapter.features.has(feature)),
94+
});
95+
Module.preinitializedWebGPUDevice = device;
96+
}
97+
})();
7598
</script>
7699
{{{ SCRIPT }}}
77100
</body>

SampleBase/src/SampleApp.cpp

Lines changed: 64 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,18 @@
6060
# include "EngineFactoryMtl.h"
6161
#endif
6262

63+
#if WEBGPU_SUPPORTED
64+
# include "EngineFactoryWebGPU.h"
65+
#endif
66+
6367
#include "imgui.h"
6468
#include "ImGuiImplDiligent.hpp"
6569
#include "ImGuiUtils.hpp"
6670

71+
#if PLATFORM_EMSCRIPTEN
72+
# include <emscripten/html5_webgpu.h>
73+
#endif
74+
6775
namespace Diligent
6876
{
6977

@@ -136,7 +144,7 @@ void SampleApp::InitializeDiligentEngine(const NativeWindow* pWindow)
136144

137145
Uint32 NumImmediateContexts = 0;
138146

139-
#if D3D11_SUPPORTED || D3D12_SUPPORTED || VULKAN_SUPPORTED
147+
#if D3D11_SUPPORTED || D3D12_SUPPORTED || VULKAN_SUPPORTED || WEBGPU_SUPPORTED
140148
auto FindAdapter = [this](auto* pFactory, Version GraphicsAPIVersion, GraphicsAdapterInfo& AdapterAttribs) {
141149
Uint32 NumAdapters = 0;
142150
pFactory->EnumerateAdapters(GraphicsAPIVersion, NumAdapters, nullptr);
@@ -414,7 +422,6 @@ void SampleApp::InitializeDiligentEngine(const NativeWindow* pWindow)
414422
break;
415423
#endif
416424

417-
418425
#if METAL_SUPPORTED
419426
case RENDER_DEVICE_TYPE_METAL:
420427
{
@@ -442,6 +449,50 @@ void SampleApp::InitializeDiligentEngine(const NativeWindow* pWindow)
442449
break;
443450
#endif
444451

452+
#if WEBGPU_SUPPORTED
453+
case RENDER_DEVICE_TYPE_WEBGPU:
454+
{
455+
# if EXPLICITLY_LOAD_ENGINE_WEBGPU_DLL
456+
// Load the dll and import LoadGraphicsEngineWebGPU() function
457+
auto GetEngineFactoryWebGPU = LoadGraphicsEngineWebGPU();
458+
# endif
459+
EngineWebGPUCreateInfo EngineCI;
460+
if (m_ValidationLevel >= 0)
461+
EngineCI.SetValidationLevel(static_cast<VALIDATION_LEVEL>(m_ValidationLevel));
462+
463+
auto* pFactoryWebGPU = GetEngineFactoryWebGPU();
464+
m_pEngineFactory = pFactoryWebGPU;
465+
466+
NumImmediateContexts = std::max(1u, EngineCI.NumImmediateContexts);
467+
ppContexts.resize(NumImmediateContexts + EngineCI.NumDeferredContexts);
468+
m_TheSample->ModifyEngineInitInfo({pFactoryWebGPU, m_DeviceType, EngineCI, m_SwapChainInitDesc});
469+
470+
if (EngineCI.NumDeferredContexts != 0)
471+
{
472+
LOG_WARNING_MESSAGE("Deferred contexts are not supported in WebGPU mode");
473+
EngineCI.NumDeferredContexts = 0;
474+
}
475+
476+
# if PLATFORM_EMSCRIPTEN
477+
(void)FindAdapter;
478+
WGPUDevice wgpuDevice = emscripten_webgpu_get_device();
479+
WGPUInstance wgpuInstance = wgpuCreateInstance(nullptr);
480+
pFactoryWebGPU->AttachToWebGPUDevice(wgpuInstance, nullptr, wgpuDevice, EngineCI, &m_pDevice, ppContexts.data());
481+
# else
482+
EngineCI.AdapterId = FindAdapter(pFactoryWebGPU, EngineCI.GraphicsAPIVersion, m_AdapterAttribs);
483+
pFactoryWebGPU->CreateDeviceAndContextsWebGPU(EngineCI, &m_pDevice, ppContexts.data());
484+
# endif
485+
if (!m_pDevice)
486+
{
487+
LOG_ERROR_AND_THROW("Unable to initialize Diligent Engine in WebGPU mode. The API may not be available, "
488+
"or required features may not be supported by this GPU/driver/OS version.");
489+
}
490+
491+
if (!m_pSwapChain && pWindow != nullptr)
492+
pFactoryWebGPU->CreateSwapChainWebGPU(m_pDevice, ppContexts[0], m_SwapChainInitDesc, *pWindow, &m_pSwapChain);
493+
}
494+
break;
495+
#endif
445496
default:
446497
LOG_ERROR_AND_THROW("Unknown device type");
447498
break;
@@ -664,7 +715,8 @@ SampleApp::CommandLineStatus SampleApp::ProcessCommandLine(int argc, const char*
664715
{"gl", RENDER_DEVICE_TYPE_GL},
665716
{"gles", RENDER_DEVICE_TYPE_GLES},
666717
{"vk", RENDER_DEVICE_TYPE_VULKAN},
667-
{"mtl", RENDER_DEVICE_TYPE_METAL} //
718+
{"mtl", RENDER_DEVICE_TYPE_METAL},
719+
{"wgpu", RENDER_DEVICE_TYPE_WEBGPU} //
668720
};
669721
return ArgsParser.ParseEnum("mode", 'm', DeviceTypeEnumVals, m_DeviceType);
670722
});
@@ -711,6 +763,13 @@ SampleApp::CommandLineStatus SampleApp::ProcessCommandLine(int argc, const char*
711763
LOG_ERROR_MESSAGE("Metal is not supported. Please select another device type");
712764
}
713765
#endif
766+
#if !WEBGPU_SUPPORTED
767+
if (m_DeviceType == RENDER_DEVICE_TYPE_WEBGPU)
768+
{
769+
m_DeviceType = RENDER_DEVICE_TYPE_UNDEFINED;
770+
LOG_ERROR_MESSAGE("WebGPU is not supported. Please select another device type");
771+
}
772+
#endif
714773

715774
if (ArgsParser.Parse("capture_path", m_ScreenCaptureInfo.Directory))
716775
m_ScreenCaptureInfo.AllowCapture = true;
@@ -784,6 +843,8 @@ SampleApp::CommandLineStatus SampleApp::ProcessCommandLine(int argc, const char*
784843
m_DeviceType = RENDER_DEVICE_TYPE_D3D11;
785844
#elif GL_SUPPORTED || GLES_SUPPORTED
786845
m_DeviceType = RENDER_DEVICE_TYPE_GL;
846+
#elif WEBGPU_SUPPORTED
847+
m_DeviceType = RENDER_DEVICE_TYPE_WEBGPU;
787848
#endif
788849
}
789850
}

SampleBase/src/SampleBase.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ void SampleBase::ModifyEngineInitInfo(const ModifyEngineInitInfoAttribs& Attribs
9595
break;
9696
#endif
9797

98+
#if WEBGPU_SUPPORTED
99+
case RENDER_DEVICE_TYPE_WEBGPU:
100+
{
101+
// Nothing to do
102+
}
103+
break;
104+
#endif
98105
default:
99106
LOG_ERROR_AND_THROW("Unknown device type");
100107
break;

SampleBase/src/Win32/SampleAppWin32.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ INT_PTR CALLBACK SelectDeviceTypeDialogProc(HWND hwndDlg,
7373
g_DeviceType = Diligent::RENDER_DEVICE_TYPE_VULKAN;
7474
EndDialog(hwndDlg, wParam);
7575
return TRUE;
76+
case ID_WEBGPU:
77+
g_DeviceType = Diligent::RENDER_DEVICE_TYPE_WEBGPU;
78+
EndDialog(hwndDlg, wParam);
79+
return TRUE;
7680
}
7781
break;
7882

@@ -105,6 +109,13 @@ INT_PTR CALLBACK SelectDeviceTypeDialogProc(HWND hwndDlg,
105109
BOOL VulkanSupported = FALSE;
106110
#endif
107111
SetButtonImage(hwndDlg, ID_VULKAN, IDB_VULKAN_LOGO, VulkanSupported);
112+
113+
#if WEBGPU_SUPPORTED
114+
BOOL WebGPUSupported = TRUE;
115+
#else
116+
BOOL WebGPUSupported = FALSE;
117+
#endif
118+
SetButtonImage(hwndDlg, ID_WEBGPU, IDB_WEBGPU_LOGO, WebGPUSupported);
108119
}
109120
break;
110121
}

SampleBase/src/Win32/resources/Win32AppResource.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
#define IDB_VULKAN_LOGO 103
88
#define IDB_DIRECTX11_LOGO 104
99
#define IDB_DIRECTX12_LOGO 105
10+
#define IDB_WEBGPU_LOGO 106
1011
#define ID_VULKAN 1001
1112
#define ID_OPENGL 1002
1213
#define ID_DIRECT3D11 1003
1314
#define ID_DIRECT3D12 1004
15+
#define ID_WEBGPU 1005
1416

1517
// Next default values for new objects
1618
//
1719
#ifdef APSTUDIO_INVOKED
1820
#ifndef APSTUDIO_READONLY_SYMBOLS
19-
#define _APS_NEXT_RESOURCE_VALUE 106
21+
#define _APS_NEXT_RESOURCE_VALUE 108
2022
#define _APS_NEXT_COMMAND_VALUE 40001
21-
#define _APS_NEXT_CONTROL_VALUE 1005
23+
#define _APS_NEXT_CONTROL_VALUE 1006
2224
#define _APS_NEXT_SYMED_VALUE 101
2325
#endif
2426
#endif

SampleBase/src/Win32/resources/Win32AppResource.rc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ END
5252
// Dialog
5353
//
5454

55-
IDD_DEVICE_TYPE_SELECTION_DIALOG DIALOGEX 0, 0, 198, 213
55+
IDD_DEVICE_TYPE_SELECTION_DIALOG DIALOGEX 0, 0, 198, 265
5656
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION
5757
CAPTION "Please select rendering backend"
5858
FONT 12, "MS Shell Dlg", 400, 0, 0xCC
@@ -61,6 +61,7 @@ BEGIN
6161
DEFPUSHBUTTON "Direct3D12",ID_DIRECT3D12,47,61,103,43,BS_BITMAP,WS_EX_CLIENTEDGE
6262
DEFPUSHBUTTON "OpenGL",ID_OPENGL,47,109,103,43,BS_BITMAP,WS_EX_CLIENTEDGE
6363
DEFPUSHBUTTON "Vulkan",ID_VULKAN,47,157,103,43,BS_BITMAP,WS_EX_CLIENTEDGE
64+
DEFPUSHBUTTON "WebGPU",ID_WEBGPU,47,205,104,43,BS_BITMAP,WS_EX_CLIENTEDGE
6465
END
6566

6667

@@ -77,7 +78,7 @@ BEGIN
7778
LEFTMARGIN, 7
7879
RIGHTMARGIN, 187
7980
TOPMARGIN, 7
80-
BOTTOMMARGIN, 201
81+
BOTTOMMARGIN, 253
8182
END
8283
END
8384
#endif // APSTUDIO_INVOKED
@@ -107,6 +108,8 @@ IDB_DIRECTX11_LOGO BITMAP "directx11-logo.bmp"
107108

108109
IDB_DIRECTX12_LOGO BITMAP "directx12-logo.bmp"
109110

111+
IDB_WEBGPU_LOGO BITMAP "webgpu-logo.bmp"
112+
110113
#endif // English (United States) resources
111114
/////////////////////////////////////////////////////////////////////////////
112115

0 commit comments

Comments
 (0)