mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-16 14:05:28 +00:00
WebGPU: enable emscripten support (#3780)
This commit is contained in:
4
3rdparty/dawn/include/webgpu/webgpu.h
vendored
4
3rdparty/dawn/include/webgpu/webgpu.h
vendored
@@ -27,10 +27,6 @@
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#error "Do not include this header. Emscripten already provides headers needed for WebGPU."
|
||||
#endif
|
||||
|
||||
#ifndef WEBGPU_H_
|
||||
#define WEBGPU_H_
|
||||
|
||||
|
||||
@@ -90,6 +90,7 @@
|
||||
|
||||
#ifndef BGFX_PLATFORM_SUPPORTS_WGSL
|
||||
# define BGFX_PLATFORM_SUPPORTS_WGSL (0 \
|
||||
|| BX_PLATFORM_EMSCRIPTEN \
|
||||
|| BX_PLATFORM_LINUX \
|
||||
|| BX_PLATFORM_WINDOWS \
|
||||
|| BX_PLATFORM_OSX \
|
||||
|
||||
@@ -887,6 +887,12 @@ WGPU_IMPORT
|
||||
renderCtx->m_device = _device;
|
||||
}
|
||||
|
||||
WGPUWaitStatus waitForFuture(WGPUFutureWaitInfo& _fwi)
|
||||
{
|
||||
wgpuInstanceProcessEvents(m_instance);
|
||||
return wgpuInstanceWaitAny(m_instance, 1, &_fwi, UINT64_MAX);
|
||||
}
|
||||
|
||||
bool init(const Init& _init)
|
||||
{
|
||||
struct ErrorState
|
||||
@@ -923,6 +929,7 @@ WGPU_IMPORT
|
||||
|
||||
bool imported = true;
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
m_webgpuDll = bx::dlopen(
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
"webgpu_dawn.dll"
|
||||
@@ -970,12 +977,21 @@ WGPU_IMPORT
|
||||
goto error;
|
||||
}
|
||||
|
||||
#else // BX_PLATFORM_EMSCRIPTEN
|
||||
BX_TRACE("Emscripten: Using statically linked WebGPU.");
|
||||
m_webgpuDll = NULL;
|
||||
errorState = ErrorState::LoadedWebGPU;
|
||||
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
{
|
||||
{
|
||||
WGPUInstanceFeatureName requiredFeatures[] =
|
||||
{
|
||||
WGPUInstanceFeatureName_TimedWaitAny,
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
WGPUInstanceFeatureName_ShaderSourceSPIRV,
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
};
|
||||
|
||||
WGPUInstanceDescriptor instanceDesc =
|
||||
@@ -1021,7 +1037,7 @@ WGPU_IMPORT
|
||||
.completed = false,
|
||||
};
|
||||
|
||||
WGPUWaitStatus waitStatus = wgpuInstanceWaitAny(m_instance, 1, &fwi, UINT64_MAX);
|
||||
WGPUWaitStatus waitStatus = waitForFuture(fwi);
|
||||
|
||||
if (WGPUWaitStatus_Success != waitStatus
|
||||
|| NULL == m_adapter)
|
||||
@@ -1157,15 +1173,18 @@ WGPU_IMPORT
|
||||
|
||||
if (WGPUStatus_Success == status)
|
||||
{
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
requiredLimits.maxComputeWorkgroupSizeX = 1024;
|
||||
requiredLimits.maxComputeWorkgroupSizeY = 1024;
|
||||
requiredLimits.maxComputeWorkgroupSizeZ = 64;
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
}
|
||||
|
||||
static constexpr uint32_t kMaxEnabledTogles = 10;
|
||||
const char* enabledToggles[kMaxEnabledTogles];
|
||||
uint32_t enabledTogglesCount = 0;
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
enabledToggles[enabledTogglesCount++] = "allow_unsafe_apis"; // TimestampWrite requires this.
|
||||
|
||||
if (_init.debug)
|
||||
@@ -1207,10 +1226,15 @@ WGPU_IMPORT
|
||||
.disabledToggleCount = 0,
|
||||
.disabledToggles = NULL,
|
||||
};
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
WGPUDeviceDescriptor deviceDesc =
|
||||
{
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
.nextInChain = &dawnTogglesDescriptor.chain,
|
||||
#else
|
||||
.nextInChain = NULL,
|
||||
#endif
|
||||
.label = WGPU_STRING_VIEW_INIT,
|
||||
.requiredFeatureCount = requiredFeatureCount,
|
||||
.requiredFeatures = requiredFeatures,
|
||||
@@ -1219,7 +1243,7 @@ WGPU_IMPORT
|
||||
.deviceLostCallbackInfo =
|
||||
{
|
||||
.nextInChain = NULL,
|
||||
.mode = WGPUCallbackMode_WaitAnyOnly,
|
||||
.mode = WGPUCallbackMode_AllowSpontaneous,
|
||||
.callback = deviceLostCb,
|
||||
.userdata1 = this,
|
||||
.userdata2 = NULL,
|
||||
@@ -1246,7 +1270,7 @@ WGPU_IMPORT
|
||||
.completed = false,
|
||||
};
|
||||
|
||||
WGPUWaitStatus waitStatus = wgpuInstanceWaitAny(m_instance, 1, &fwi, UINT64_MAX);
|
||||
WGPUWaitStatus waitStatus = waitForFuture(fwi);
|
||||
|
||||
if (WGPUWaitStatus_Success != waitStatus
|
||||
|| NULL == m_device)
|
||||
@@ -4337,7 +4361,7 @@ WGPU_IMPORT
|
||||
{
|
||||
m_resolution = _resolution;
|
||||
|
||||
WGPUSurfaceCapabilities surfaceCaps;
|
||||
WGPUSurfaceCapabilities surfaceCaps = WGPU_SURFACE_CAPABILITIES_INIT;
|
||||
WGPUStatus status = WGPU_CHECK(wgpuSurfaceGetCapabilities(m_surface, s_renderWGPU->m_adapter, &surfaceCaps) );
|
||||
|
||||
if (WGPUStatus_Success != status)
|
||||
@@ -4361,6 +4385,24 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
}
|
||||
}
|
||||
|
||||
#if BX_PLATFORM_EMSCRIPTEN
|
||||
if (WGPUTextureFormat_Undefined != format
|
||||
&& surfaceCaps.formatCount > 0
|
||||
&& format != surfaceCaps.formats[0])
|
||||
{
|
||||
format = surfaceCaps.formats[0];
|
||||
|
||||
if (WGPUTextureFormat_BGRA8Unorm == format)
|
||||
{
|
||||
m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
}
|
||||
else if (WGPUTextureFormat_RGBA8Unorm == format)
|
||||
{
|
||||
m_resolution.formatColor = TextureFormat::RGBA8;
|
||||
}
|
||||
}
|
||||
#endif // BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
BX_ASSERT(WGPUTextureFormat_Undefined != format, "SwapChain surface format is not available!");
|
||||
|
||||
m_surfaceConfig =
|
||||
@@ -4386,6 +4428,9 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
|
||||
const uint32_t msaa = s_msaa[(_resolution.reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT];
|
||||
|
||||
wgpuRelease(m_depthStencilView);
|
||||
wgpuRelease(m_msaaTextureView);
|
||||
|
||||
if (bimg::isDepth(bimg::TextureFormat::Enum(m_resolution.formatDepthStencil) ) )
|
||||
{
|
||||
WGPUTextureDescriptor textureDesc =
|
||||
@@ -4471,6 +4516,7 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
};
|
||||
|
||||
m_msaaTextureView = WGPU_CHECK(wgpuTextureCreateView(texture, &textureViewDesc) );
|
||||
wgpuRelease(texture);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4642,6 +4688,26 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
.layer = toMetalLayer(m_nwh),
|
||||
};
|
||||
|
||||
surfaceDesc =
|
||||
{
|
||||
.nextInChain = &surfaceSource.chain,
|
||||
.label = toWGPUStringView("SwapChainWGPU"),
|
||||
};
|
||||
#elif BX_PLATFORM_EMSCRIPTEN
|
||||
WGPUEmscriptenSurfaceSourceCanvasHTMLSelector surfaceSource =
|
||||
{
|
||||
.chain =
|
||||
{
|
||||
.next = NULL,
|
||||
.sType = WGPUSType_EmscriptenSurfaceSourceCanvasHTMLSelector,
|
||||
},
|
||||
.selector =
|
||||
{
|
||||
.data = static_cast<const char*>(m_nwh),
|
||||
.length = uint32_t(bx::strLen(static_cast<const char*>(m_nwh))),
|
||||
},
|
||||
};
|
||||
|
||||
surfaceDesc =
|
||||
{
|
||||
.nextInChain = &surfaceSource.chain,
|
||||
@@ -4659,7 +4725,9 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
void SwapChainWGPU::present()
|
||||
{
|
||||
wgpuRelease(m_textureView);
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
WGPU_CHECK(wgpuSurfacePresent(m_surface) );
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
WGPUSurfaceTexture surfaceTexture = WGPU_SURFACE_TEXTURE_INIT;
|
||||
wgpuSurfaceGetCurrentTexture(m_surface, &surfaceTexture);
|
||||
@@ -4874,30 +4942,42 @@ m_resolution.formatColor = TextureFormat::BGRA8;
|
||||
WGPUCommandBuffer commandBuffer = WGPU_CHECK(wgpuCommandEncoderFinish(m_commandEncoder, NULL) );
|
||||
|
||||
WGPU_CHECK(wgpuQueueSubmit(m_queue, 1, &commandBuffer) );
|
||||
WGPU_CHECK(wgpuQueueOnSubmittedWorkDone(
|
||||
m_queue
|
||||
m_future = wgpuQueueOnSubmittedWorkDone(
|
||||
m_queue
|
||||
, {
|
||||
.nextInChain = NULL,
|
||||
.mode = WGPUCallbackMode_AllowProcessEvents,
|
||||
.callback = queueWorkDoneCb,
|
||||
.userdata1 = (void*)uintptr_t(m_counter),
|
||||
.userdata2 = NULL,
|
||||
}) );
|
||||
});
|
||||
wgpuRelease(commandBuffer);
|
||||
wgpuRelease(m_commandEncoder);
|
||||
++m_counter;
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
WGPU_CHECK(wgpuInstanceProcessEvents(s_renderWGPU->m_instance) );
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
m_commandEncoder = WGPU_CHECK(wgpuDeviceCreateCommandEncoder(s_renderWGPU->m_device, NULL) );
|
||||
}
|
||||
|
||||
void CommandQueueWGPU::wait()
|
||||
{
|
||||
#if BX_PLATFORM_EMSCRIPTEN
|
||||
wgpuInstanceProcessEvents(s_renderWGPU->m_instance);
|
||||
#else
|
||||
while (0 < m_counter)
|
||||
{
|
||||
WGPU_CHECK(wgpuInstanceProcessEvents(s_renderWGPU->m_instance) );
|
||||
WGPUFutureWaitInfo fwi =
|
||||
{
|
||||
.future = m_future,
|
||||
.completed = false,
|
||||
};
|
||||
|
||||
wgpuInstanceWaitAny(s_renderWGPU->m_instance, 1, &fwi, 1000000);
|
||||
}
|
||||
#endif // BX_PLATFORM_EMSCRIPTEN
|
||||
}
|
||||
|
||||
void CommandQueueWGPU::frame()
|
||||
|
||||
@@ -24,7 +24,9 @@
|
||||
# define WGPU_CHECK(_call) _call
|
||||
#endif // BGFX_CONFIG_DEBUG
|
||||
|
||||
#define WGPU_SKIP_DECLARATIONS
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
# define WGPU_SKIP_DECLARATIONS
|
||||
#endif // !BX_PLATFORM_EMSCRIPTEN
|
||||
#include <dawn/include/webgpu/webgpu.h>
|
||||
|
||||
#if USE_WEBGPU_DYNAMIC_LIB
|
||||
@@ -307,11 +309,11 @@
|
||||
WGPU_IGNORE_____(false, TextureGetDepthOrArrayLayers); \
|
||||
WGPU_IGNORE_____(false, TextureGetDimension); \
|
||||
WGPU_IGNORE_____(false, TextureGetFormat); \
|
||||
WGPU_IGNORE_____(false, TextureGetHeight); \
|
||||
WGPU_IMPORT_FUNC(false, TextureGetHeight); \
|
||||
WGPU_IGNORE_____(false, TextureGetMipLevelCount); \
|
||||
WGPU_IGNORE_____(false, TextureGetSampleCount); \
|
||||
WGPU_IGNORE_____(false, TextureGetUsage); \
|
||||
WGPU_IGNORE_____(false, TextureGetWidth); \
|
||||
WGPU_IMPORT_FUNC(false, TextureGetWidth); \
|
||||
WGPU_IGNORE_____(false, TexturePin); \
|
||||
WGPU_IMPORT_FUNC(false, TextureSetLabel); \
|
||||
WGPU_IGNORE_____(false, TextureUnpin); \
|
||||
@@ -744,6 +746,7 @@ namespace wgpu {
|
||||
: m_queue(NULL)
|
||||
, m_commandEncoder(NULL)
|
||||
, m_counter(0)
|
||||
, m_future(WGPU_FUTURE_INIT)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -767,6 +770,7 @@ namespace wgpu {
|
||||
WGPUCommandEncoder m_commandEncoder;
|
||||
uint32_t m_currentFrameInFlight;
|
||||
uint32_t m_counter;
|
||||
WGPUFuture m_future;
|
||||
};
|
||||
|
||||
struct TimerQueryWGPU
|
||||
|
||||
Reference in New Issue
Block a user