mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Add Webgpu backend (#2132)
* WebGPU first draft (shaderc bin version 8) * WebGPU scripts
This commit is contained in:
144
3rdparty/webgpu/include/webgpu/EnumClassBitmasks.h
vendored
Normal file
144
3rdparty/webgpu/include/webgpu/EnumClassBitmasks.h
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright 2017 The Dawn Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef DAWN_ENUM_CLASS_BITMASKS_H_
|
||||
#define DAWN_ENUM_CLASS_BITMASKS_H_
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace wgpu {
|
||||
|
||||
template <typename T>
|
||||
struct IsDawnBitmask {
|
||||
static constexpr bool enable = false;
|
||||
};
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct LowerBitmask {
|
||||
static constexpr bool enable = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct LowerBitmask<T, typename std::enable_if<IsDawnBitmask<T>::enable>::type> {
|
||||
static constexpr bool enable = true;
|
||||
using type = T;
|
||||
constexpr static T Lower(T t) {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct BoolConvertible {
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
|
||||
constexpr BoolConvertible(Integral value) : value(value) {
|
||||
}
|
||||
constexpr operator bool() const {
|
||||
return value != 0;
|
||||
}
|
||||
constexpr operator T() const {
|
||||
return static_cast<T>(value);
|
||||
}
|
||||
|
||||
Integral value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct LowerBitmask<BoolConvertible<T>> {
|
||||
static constexpr bool enable = true;
|
||||
using type = T;
|
||||
static constexpr type Lower(BoolConvertible<T> t) {
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T1,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<LowerBitmask<T1>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator|(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) |
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
}
|
||||
|
||||
template <typename T1,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<LowerBitmask<T1>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator&(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) &
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
}
|
||||
|
||||
template <typename T1,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<LowerBitmask<T1>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator^(T1 left, T2 right) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return static_cast<Integral>(LowerBitmask<T1>::Lower(left)) ^
|
||||
static_cast<Integral>(LowerBitmask<T2>::Lower(right));
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
constexpr BoolConvertible<typename LowerBitmask<T1>::type> operator~(T1 t) {
|
||||
using T = typename LowerBitmask<T1>::type;
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return ~static_cast<Integral>(LowerBitmask<T1>::Lower(t));
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<IsDawnBitmask<T>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr T& operator&=(T& l, T2 right) {
|
||||
T r = LowerBitmask<T2>::Lower(right);
|
||||
l = l & r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<IsDawnBitmask<T>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr T& operator|=(T& l, T2 right) {
|
||||
T r = LowerBitmask<T2>::Lower(right);
|
||||
l = l | r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template <typename T,
|
||||
typename T2,
|
||||
typename = typename std::enable_if<IsDawnBitmask<T>::enable &&
|
||||
LowerBitmask<T2>::enable>::type>
|
||||
constexpr T& operator^=(T& l, T2 right) {
|
||||
T r = LowerBitmask<T2>::Lower(right);
|
||||
l = l ^ r;
|
||||
return l;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr bool HasZeroOrOneBits(T value) {
|
||||
using Integral = typename std::underlying_type<T>::type;
|
||||
return (static_cast<Integral>(value) & (static_cast<Integral>(value) - 1)) == 0;
|
||||
}
|
||||
|
||||
} // namespace wgpu
|
||||
|
||||
#endif // DAWN_ENUM_CLASS_BITMASKS_H_
|
||||
1207
3rdparty/webgpu/include/webgpu/webgpu.h
vendored
Normal file
1207
3rdparty/webgpu/include/webgpu/webgpu.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1273
3rdparty/webgpu/include/webgpu/webgpu_cpp.h
vendored
Normal file
1273
3rdparty/webgpu/include/webgpu/webgpu_cpp.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1762
3rdparty/webgpu/webgpu_cpp.cpp
vendored
Normal file
1762
3rdparty/webgpu/webgpu_cpp.cpp
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1371,6 +1371,11 @@ public static partial class bgfx
|
||||
/// </summary>
|
||||
Vulkan,
|
||||
|
||||
/// <summary>
|
||||
/// WebGPU
|
||||
/// </summary>
|
||||
WebGPU,
|
||||
|
||||
Count
|
||||
}
|
||||
|
||||
|
||||
@@ -435,6 +435,7 @@ enum bgfx_renderer_type_t
|
||||
BGFX_RENDERER_TYPE_OPENGLES, /// OpenGL ES 2.0+
|
||||
BGFX_RENDERER_TYPE_OPENGL, /// OpenGL 2.1+
|
||||
BGFX_RENDERER_TYPE_VULKAN, /// Vulkan
|
||||
BGFX_RENDERER_TYPE_WEBGPU, /// WebGPU
|
||||
|
||||
BGFX_RENDERER_TYPE_COUNT
|
||||
}
|
||||
|
||||
@@ -483,7 +483,11 @@ public:
|
||||
gbufferAt[1].init(m_gbufferTex[1]);
|
||||
}
|
||||
|
||||
m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, bgfx::TextureFormat::D24S8, BGFX_TEXTURE_RT | tsFlags);
|
||||
bgfx::TextureFormat::Enum depthFormat = bgfx::getRendererType() == bgfx::RendererType::WebGPU
|
||||
? bgfx::TextureFormat::D32F // WebGPU only supports sampling those for now
|
||||
: bgfx::TextureFormat::D24S8;
|
||||
|
||||
m_gbufferTex[2] = bgfx::createTexture2D(uint16_t(m_width), uint16_t(m_height), false, 1, depthFormat, BGFX_TEXTURE_RT | tsFlags);
|
||||
gbufferAt[2].init(m_gbufferTex[2]);
|
||||
|
||||
m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(gbufferAt), gbufferAt, true);
|
||||
|
||||
@@ -312,9 +312,13 @@ public:
|
||||
;
|
||||
|
||||
// Make gbuffer and related textures
|
||||
bgfx::TextureFormat::Enum depthFormat = bgfx::getRendererType() == bgfx::RendererType::WebGPU
|
||||
? bgfx::TextureFormat::D32F
|
||||
: bgfx::TextureFormat::D24;
|
||||
|
||||
m_gbufferTex[GBUFFER_RT_NORMAL] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
|
||||
m_gbufferTex[GBUFFER_RT_COLOR] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, false, 1, bgfx::TextureFormat::BGRA8, tsFlags);
|
||||
m_gbufferTex[GBUFFER_RT_DEPTH] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, false, 1, bgfx::TextureFormat::D24, tsFlags);
|
||||
m_gbufferTex[GBUFFER_RT_DEPTH] = bgfx::createTexture2D(bgfx::BackbufferRatio::Equal, false, 1, depthFormat, tsFlags);
|
||||
m_gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(m_gbufferTex), m_gbufferTex, true);
|
||||
|
||||
// Make light buffer
|
||||
|
||||
@@ -114,6 +114,7 @@ static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name
|
||||
case bgfx::RendererType::OpenGL: shaderPath = "shaders/glsl/"; break;
|
||||
case bgfx::RendererType::OpenGLES: shaderPath = "shaders/essl/"; break;
|
||||
case bgfx::RendererType::Vulkan: shaderPath = "shaders/spirv/"; break;
|
||||
case bgfx::RendererType::WebGPU: shaderPath = "shaders/spirv/"; break;
|
||||
|
||||
case bgfx::RendererType::Count:
|
||||
BX_CHECK(false, "You should not be here!");
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace bgfx
|
||||
OpenGLES, //!< OpenGL ES 2.0+
|
||||
OpenGL, //!< OpenGL 2.1+
|
||||
Vulkan, //!< Vulkan
|
||||
WebGPU, //!< WebGPU
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
@@ -90,6 +90,7 @@ typedef enum bgfx_renderer_type
|
||||
BGFX_RENDERER_TYPE_OPENGLES, /** ( 7) OpenGL ES 2.0+ */
|
||||
BGFX_RENDERER_TYPE_OPENGL, /** ( 8) OpenGL 2.1+ */
|
||||
BGFX_RENDERER_TYPE_VULKAN, /** ( 9) Vulkan */
|
||||
BGFX_RENDERER_TYPE_WEBGPU, /** (10) WebGPU */
|
||||
|
||||
BGFX_RENDERER_TYPE_COUNT
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
)
|
||||
#define BGFX_PLATFORM_SUPPORTS_SPIRV (0 \
|
||||
|| BX_PLATFORM_ANDROID \
|
||||
|| BX_PLATFORM_EMSCRIPTEN \
|
||||
|| BX_PLATFORM_LINUX \
|
||||
|| BX_PLATFORM_WINDOWS \
|
||||
|| BX_PLATFORM_OSX \
|
||||
@@ -113,6 +114,7 @@
|
||||
BGFX_EMBEDDED_SHADER_ESSL (bgfx::RendererType::OpenGLES, _name) \
|
||||
BGFX_EMBEDDED_SHADER_GLSL (bgfx::RendererType::OpenGL, _name) \
|
||||
BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::Vulkan, _name) \
|
||||
BGFX_EMBEDDED_SHADER_SPIRV(bgfx::RendererType::WebGPU, _name) \
|
||||
{ bgfx::RendererType::Noop, (const uint8_t*)"VSH\x5\x0\x0\x0\x0\x0\x0", 10 }, \
|
||||
{ bgfx::RendererType::Count, NULL, 0 } \
|
||||
} \
|
||||
|
||||
@@ -458,6 +458,7 @@ enum.RendererType { comment = "Renderer types:" }
|
||||
.OpenGLES --- OpenGL ES 2.0+
|
||||
.OpenGL --- OpenGL 2.1+
|
||||
.Vulkan --- Vulkan
|
||||
.WebGPU --- WebGPU
|
||||
()
|
||||
|
||||
--- Access mode enum.
|
||||
|
||||
@@ -163,6 +163,43 @@ function bgfxProjectBase(_kind, _defines)
|
||||
path.join(BGFX_DIR, "src/renderer_nvn.h"),
|
||||
})
|
||||
|
||||
if _OPTIONS["webgpu"] then
|
||||
defines {
|
||||
"BGFX_CONFIG_RENDERER_WEBGPU=1",
|
||||
}
|
||||
|
||||
configuration { "asmjs" }
|
||||
defines {
|
||||
"BGFX_CONFIG_RENDERER_OPENGL=0",
|
||||
"BGFX_CONFIG_RENDERER_OPENGLES=0",
|
||||
}
|
||||
|
||||
configuration { "not asmjs" }
|
||||
--local generator = "out/Default"
|
||||
local generator = "out/VS2019"
|
||||
|
||||
includedirs {
|
||||
path.join(DAWN_DIR, "src"),
|
||||
path.join(DAWN_DIR, "src/include"),
|
||||
path.join(DAWN_DIR, "third_party/vulkan-headers/include"),
|
||||
path.join(DAWN_DIR, generator, "gen/src"),
|
||||
path.join(DAWN_DIR, generator, "gen/src/include"),
|
||||
}
|
||||
|
||||
configuration { "vs*" }
|
||||
defines {
|
||||
"NTDDI_VERSION=NTDDI_WIN10_RS2",
|
||||
|
||||
-- We can't say `=_WIN32_WINNT_WIN10` here because some files do
|
||||
-- `#if WINVER < 0x0600` without including windows.h before,
|
||||
-- and then _WIN32_WINNT_WIN10 isn't yet known to be 0x0A00.
|
||||
"_WIN32_WINNT=0x0A00",
|
||||
"WINVER=0x0A00",
|
||||
}
|
||||
|
||||
configuration {}
|
||||
end
|
||||
|
||||
if _OPTIONS["with-amalgamated"] then
|
||||
excludes {
|
||||
path.join(BGFX_DIR, "src/bgfx.cpp"),
|
||||
@@ -234,3 +271,59 @@ function bgfxProject(_name, _kind, _defines)
|
||||
|
||||
copyLib()
|
||||
end
|
||||
|
||||
if _OPTIONS["webgpu"] then
|
||||
function usesWebGPU()
|
||||
configuration { "asmjs" }
|
||||
linkoptions {
|
||||
"-s USE_WEBGPU=1",
|
||||
}
|
||||
|
||||
configuration { "not asmjs" }
|
||||
--local generator = "out/Default"
|
||||
local generator = "out/VS2019"
|
||||
|
||||
includedirs {
|
||||
path.join(DAWN_DIR, "src"),
|
||||
path.join(DAWN_DIR, "src/include"),
|
||||
path.join(DAWN_DIR, generator, "gen/src"),
|
||||
path.join(DAWN_DIR, generator, "gen/src/include"),
|
||||
}
|
||||
|
||||
libdirs {
|
||||
path.join(DAWN_DIR, generator),
|
||||
path.join(DAWN_DIR, generator, "lib/Debug"),
|
||||
}
|
||||
|
||||
files {
|
||||
path.join(DAWN_DIR, generator, "gen/src/dawn/webgpu_cpp.cpp"),
|
||||
}
|
||||
|
||||
links {
|
||||
-- shared
|
||||
"dawn_proc_shared",
|
||||
"dawn_native_shared",
|
||||
"shaderc_spvc_shared",
|
||||
-- static
|
||||
--"dawn_common",
|
||||
--"dawn_proc",
|
||||
--"dawn_native",
|
||||
--"dawn_platform",
|
||||
------"shaderc",
|
||||
--"shaderc_spvc",
|
||||
--"SPIRV-tools",
|
||||
--"SPIRV-tools-opt",
|
||||
--"spirv-cross-cored",
|
||||
--"spirv-cross-hlsld",
|
||||
--"spirv-cross-glsld",
|
||||
--"spirv-cross-msld",
|
||||
--"spirv-cross-reflectd",
|
||||
}
|
||||
|
||||
removeflags {
|
||||
"FatalWarnings",
|
||||
}
|
||||
|
||||
configuration {}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
-- License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
--
|
||||
|
||||
newoption {
|
||||
trigger = "webgpu",
|
||||
description = "Enable webgpu experimental renderer.",
|
||||
}
|
||||
|
||||
newoption {
|
||||
trigger = "with-amalgamated",
|
||||
description = "Enable amalgamated build.",
|
||||
@@ -162,6 +167,12 @@ if not os.isdir(BX_DIR) or not os.isdir(BIMG_DIR) then
|
||||
os.exit()
|
||||
end
|
||||
|
||||
if _OPTIONS["webgpu"] then
|
||||
DAWN_DIR = os.getenv("DAWN_DIR")
|
||||
|
||||
_OPTIONS["with-windows"] = "10.0"
|
||||
end
|
||||
|
||||
dofile (path.join(BX_DIR, "scripts/toolchain.lua"))
|
||||
if not toolchain(BGFX_BUILD_DIR, BGFX_THIRD_PARTY_DIR) then
|
||||
return -- no action specified
|
||||
@@ -214,6 +225,10 @@ function exampleProjectDefaults()
|
||||
"bx",
|
||||
}
|
||||
|
||||
if _OPTIONS["webgpu"] then
|
||||
usesWebGPU()
|
||||
end
|
||||
|
||||
if _OPTIONS["with-sdl"] then
|
||||
defines { "ENTRY_CONFIG_USE_SDL=1" }
|
||||
links { "SDL2" }
|
||||
|
||||
@@ -597,6 +597,7 @@ project "shaderc"
|
||||
path.join(BIMG_DIR, "include"),
|
||||
path.join(BGFX_DIR, "include"),
|
||||
|
||||
path.join(BGFX_DIR, "3rdparty/webgpu/include"),
|
||||
path.join(BGFX_DIR, "3rdparty/dxsdk/include"),
|
||||
|
||||
FCPP_DIR,
|
||||
|
||||
33
src/bgfx.cpp
33
src/bgfx.cpp
@@ -679,6 +679,8 @@ namespace bgfx
|
||||
ShaderHandle vsh = createEmbeddedShader(s_embeddedShaders, g_caps.rendererType, "vs_debugfont");
|
||||
ShaderHandle fsh = createEmbeddedShader(s_embeddedShaders, g_caps.rendererType, "fs_debugfont");
|
||||
|
||||
BX_CHECK(isValid(vsh) && isValid(fsh), "Failed to create embedded blit shaders");
|
||||
|
||||
m_program = createProgram(vsh, fsh, true);
|
||||
|
||||
m_vb = s_ctx->createTransientVertexBuffer(numBatchVertices*m_layout.m_stride, &m_layout);
|
||||
@@ -849,12 +851,14 @@ namespace bgfx
|
||||
.end();
|
||||
|
||||
ShaderHandle vsh = createEmbeddedShader(s_embeddedShaders, g_caps.rendererType, "vs_clear");
|
||||
BX_CHECK(isValid(vsh), "Failed to create clear quad embedded vertex shader \"vs_clear\"");
|
||||
|
||||
for (uint32_t ii = 0, num = g_caps.limits.maxFBAttachments; ii < num; ++ii)
|
||||
{
|
||||
char name[32];
|
||||
bx::snprintf(name, BX_COUNTOF(name), "fs_clear%d", ii);
|
||||
ShaderHandle fsh = createEmbeddedShader(s_embeddedShaders, g_caps.rendererType, name);
|
||||
BX_CHECK(isValid(fsh), "Failed to create clear quad embedded fragment shader \"%s\"", name);
|
||||
|
||||
m_program[ii] = createProgram(vsh, fsh);
|
||||
BX_CHECK(isValid(m_program[ii]), "Failed to create clear quad program.");
|
||||
@@ -1707,6 +1711,11 @@ namespace bgfx
|
||||
return s_ctx->m_uniformRef[_handle.idx].m_name.getPtr();
|
||||
}
|
||||
|
||||
const char* getName(ShaderHandle _handle)
|
||||
{
|
||||
return s_ctx->m_shaderRef[_handle.idx].m_name.getPtr();
|
||||
}
|
||||
|
||||
static const char* s_topologyName[] =
|
||||
{
|
||||
"Triangles",
|
||||
@@ -2476,6 +2485,7 @@ namespace bgfx
|
||||
BGFX_RENDERER_CONTEXT(nvn);
|
||||
BGFX_RENDERER_CONTEXT(gl);
|
||||
BGFX_RENDERER_CONTEXT(vk);
|
||||
BGFX_RENDERER_CONTEXT(webgpu);
|
||||
|
||||
#undef BGFX_RENDERER_CONTEXT
|
||||
|
||||
@@ -2489,20 +2499,21 @@ namespace bgfx
|
||||
|
||||
static RendererCreator s_rendererCreator[] =
|
||||
{
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, true }, // Noop
|
||||
{ d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
|
||||
{ d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
|
||||
{ d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
|
||||
{ gnm::rendererCreate, gnm::rendererDestroy, BGFX_RENDERER_GNM_NAME, !!BGFX_CONFIG_RENDERER_GNM }, // GNM
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, true }, // Noop
|
||||
{ d3d9::rendererCreate, d3d9::rendererDestroy, BGFX_RENDERER_DIRECT3D9_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D9 }, // Direct3D9
|
||||
{ d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
|
||||
{ d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
|
||||
{ gnm::rendererCreate, gnm::rendererDestroy, BGFX_RENDERER_GNM_NAME, !!BGFX_CONFIG_RENDERER_GNM }, // GNM
|
||||
#if BX_PLATFORM_OSX || BX_PLATFORM_IOS
|
||||
{ mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal
|
||||
{ mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal
|
||||
#else
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, false }, // Noop
|
||||
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, false }, // Noop
|
||||
#endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS
|
||||
{ nvn::rendererCreate, nvn::rendererDestroy, BGFX_RENDERER_NVN_NAME, !!BGFX_CONFIG_RENDERER_NVN }, // NVN
|
||||
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES
|
||||
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL
|
||||
{ vk::rendererCreate, vk::rendererDestroy, BGFX_RENDERER_VULKAN_NAME, !!BGFX_CONFIG_RENDERER_VULKAN }, // Vulkan
|
||||
{ nvn::rendererCreate, nvn::rendererDestroy, BGFX_RENDERER_NVN_NAME, !!BGFX_CONFIG_RENDERER_NVN }, // NVN
|
||||
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES
|
||||
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL
|
||||
{ vk::rendererCreate, vk::rendererDestroy, BGFX_RENDERER_VULKAN_NAME, !!BGFX_CONFIG_RENDERER_VULKAN }, // Vulkan
|
||||
{ webgpu::rendererCreate, webgpu::rendererDestroy, BGFX_RENDERER_WEBGPU_NAME, !!BGFX_CONFIG_RENDERER_WEBGPU }, // WebGPU
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_rendererCreator) == RendererType::Count);
|
||||
|
||||
|
||||
12
src/bgfx_p.h
12
src/bgfx_p.h
@@ -225,6 +225,7 @@ namespace stl = std;
|
||||
#define BGFX_RENDERER_METAL_NAME "Metal"
|
||||
#define BGFX_RENDERER_NVN_NAME "NVN"
|
||||
#define BGFX_RENDERER_VULKAN_NAME "Vulkan"
|
||||
#define BGFX_RENDERER_WEBGPU_NAME "WebGPU"
|
||||
#define BGFX_RENDERER_NOOP_NAME "Noop"
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
@@ -491,6 +492,7 @@ namespace bgfx
|
||||
TextureFormat::Enum getViableTextureFormat(const bimg::ImageContainer& _imageContainer);
|
||||
const char* getName(TextureFormat::Enum _fmt);
|
||||
const char* getName(UniformHandle _handle);
|
||||
const char* getName(ShaderHandle _handle);
|
||||
const char* getName(Topology::Enum _topology);
|
||||
|
||||
template<typename Ty>
|
||||
@@ -1326,7 +1328,9 @@ constexpr uint64_t kSortKeyComputeProgramMask = uint64_t(BGFX_CONFIG_MAX_PROGRA
|
||||
|
||||
#define BGFX_UNIFORM_FRAGMENTBIT UINT8_C(0x10)
|
||||
#define BGFX_UNIFORM_SAMPLERBIT UINT8_C(0x20)
|
||||
#define BGFX_UNIFORM_MASK (BGFX_UNIFORM_FRAGMENTBIT|BGFX_UNIFORM_SAMPLERBIT)
|
||||
#define BGFX_UNIFORM_READONLYBIT UINT8_C(0x40)
|
||||
#define BGFX_UNIFORM_COMPAREBIT UINT8_C(0x80)
|
||||
#define BGFX_UNIFORM_MASK (BGFX_UNIFORM_FRAGMENTBIT|BGFX_UNIFORM_SAMPLERBIT|BGFX_UNIFORM_READONLYBIT|BGFX_UNIFORM_COMPAREBIT)
|
||||
|
||||
class UniformBuffer
|
||||
{
|
||||
@@ -3872,6 +3876,12 @@ constexpr uint64_t kSortKeyComputeProgramMask = uint64_t(BGFX_CONFIG_MAX_PROGRA
|
||||
uint16_t regCount;
|
||||
bx::read(&reader, regCount, &err);
|
||||
|
||||
if (!isShaderVerLess(magic, 8))
|
||||
{
|
||||
uint16_t texInfo;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
|
||||
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
|
||||
if (PredefinedUniform::Count == predefined && UniformType::End != UniformType::Enum(type))
|
||||
{
|
||||
|
||||
@@ -137,6 +137,10 @@
|
||||
# ifndef BGFX_CONFIG_RENDERER_VULKAN
|
||||
# define BGFX_CONFIG_RENDERER_VULKAN 0
|
||||
# endif // BGFX_CONFIG_RENDERER_VULKAN
|
||||
|
||||
# ifndef BGFX_CONFIG_RENDERER_WEBGPU
|
||||
# define BGFX_CONFIG_RENDERER_WEBGPU 0
|
||||
# endif // BGFX_CONFIG_RENDERER_VULKAN
|
||||
#endif // !defined...
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL && BGFX_CONFIG_RENDERER_OPENGL < 21
|
||||
|
||||
@@ -3938,6 +3938,12 @@ namespace bgfx { namespace d3d11
|
||||
uint16_t regCount = 0;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
|
||||
const char* kind = "invalid";
|
||||
|
||||
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
|
||||
|
||||
@@ -4535,6 +4535,12 @@ namespace bgfx { namespace d3d12
|
||||
uint16_t regCount = 0;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
|
||||
const char* kind = "invalid";
|
||||
|
||||
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
|
||||
|
||||
@@ -2449,6 +2449,12 @@ namespace bgfx { namespace d3d9
|
||||
uint16_t regCount = 0;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
|
||||
const char* kind = "invalid";
|
||||
|
||||
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
|
||||
|
||||
@@ -5905,6 +5905,12 @@ namespace bgfx { namespace gl
|
||||
|
||||
uint16_t regCount;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t shaderSize;
|
||||
|
||||
@@ -2459,6 +2459,12 @@ namespace bgfx { namespace mtl
|
||||
|
||||
uint16_t regCount;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (isShaderType(magic, 'C'))
|
||||
|
||||
@@ -4816,6 +4816,11 @@ VK_DESTROY
|
||||
uint16_t regCount;
|
||||
bx::read(&reader, regCount);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo = 0;
|
||||
bx::read(&reader, texInfo);
|
||||
}
|
||||
const char* kind = "invalid";
|
||||
|
||||
PredefinedUniform::Enum predefined = nameToPredefinedUniformEnum(name);
|
||||
|
||||
4898
src/renderer_webgpu.cpp
Normal file
4898
src/renderer_webgpu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
4775
src/renderer_webgpu.cpp~RF2c45ef4.TMP
Normal file
4775
src/renderer_webgpu.cpp~RF2c45ef4.TMP
Normal file
File diff suppressed because it is too large
Load Diff
568
src/renderer_webgpu.h
Normal file
568
src/renderer_webgpu.h
Normal file
@@ -0,0 +1,568 @@
|
||||
/*
|
||||
* Copyright 2011-2019 Branimir Karadzic. All rights reserved.
|
||||
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
|
||||
*/
|
||||
|
||||
#ifndef BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
|
||||
#define BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
|
||||
|
||||
#include "bgfx_p.h"
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_WEBGPU
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
#include <dawn/webgpu_cpp.h>
|
||||
#include <dawn/dawn_wsi.h>
|
||||
#else
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
#endif
|
||||
|
||||
#define BGFX_WEBGPU_PROFILER_BEGIN(_view, _abgr) \
|
||||
BX_MACRO_BLOCK_BEGIN \
|
||||
BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
|
||||
BX_MACRO_BLOCK_END
|
||||
|
||||
#define BGFX_WEBGPU_PROFILER_BEGIN_LITERAL(_name, _abgr) \
|
||||
BX_MACRO_BLOCK_BEGIN \
|
||||
BGFX_PROFILER_BEGIN_LITERAL("" # _name, _abgr); \
|
||||
BX_MACRO_BLOCK_END
|
||||
|
||||
#define BGFX_WEBGPU_PROFILER_END() \
|
||||
BX_MACRO_BLOCK_BEGIN \
|
||||
BGFX_PROFILER_END(); \
|
||||
BX_MACRO_BLOCK_END
|
||||
|
||||
#define WEBGPU_MAX_FRAMES_IN_FLIGHT 3
|
||||
#define WEBGPU_NUM_UNIFORM_BUFFERS 8
|
||||
|
||||
namespace bgfx {
|
||||
namespace webgpu
|
||||
{
|
||||
|
||||
template <typename Ty>
|
||||
class StateCacheT
|
||||
{
|
||||
public:
|
||||
void add(uint64_t _id, Ty _item)
|
||||
{
|
||||
invalidate(_id);
|
||||
m_hashMap.insert(stl::make_pair(_id, _item));
|
||||
}
|
||||
|
||||
Ty find(uint64_t _id)
|
||||
{
|
||||
typename HashMap::iterator it = m_hashMap.find(_id);
|
||||
if(it != m_hashMap.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void invalidate(uint64_t _id)
|
||||
{
|
||||
typename HashMap::iterator it = m_hashMap.find(_id);
|
||||
if(it != m_hashMap.end())
|
||||
{
|
||||
release(it->second);
|
||||
m_hashMap.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
for(typename HashMap::iterator it = m_hashMap.begin(), itEnd = m_hashMap.end(); it != itEnd; ++it)
|
||||
{
|
||||
release(it->second);
|
||||
}
|
||||
|
||||
m_hashMap.clear();
|
||||
}
|
||||
|
||||
uint32_t getCount() const
|
||||
{
|
||||
return uint32_t(m_hashMap.size());
|
||||
}
|
||||
|
||||
private:
|
||||
typedef stl::unordered_map<uint64_t, Ty> HashMap;
|
||||
HashMap m_hashMap;
|
||||
};
|
||||
|
||||
struct BufferWgpu
|
||||
{
|
||||
void create(uint32_t _size, void* _data, uint16_t _flags, uint16_t _stride = 0, bool _vertex = false);
|
||||
void update(uint32_t _offset, uint32_t _size, void* _data, bool _discard = false);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_ptr.Destroy();
|
||||
|
||||
if(NULL != m_dynamic)
|
||||
{
|
||||
BX_DELETE(g_allocator, m_dynamic);
|
||||
m_dynamic = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t m_size;
|
||||
uint16_t m_flags = BGFX_BUFFER_NONE;
|
||||
bool m_vertex;
|
||||
|
||||
String m_label;
|
||||
wgpu::Buffer m_ptr;
|
||||
uint8_t* m_dynamic = NULL;
|
||||
};
|
||||
|
||||
typedef BufferWgpu IndexBufferWgpu;
|
||||
|
||||
struct VertexBufferWgpu : public BufferWgpu
|
||||
{
|
||||
void create(uint32_t _size, void* _data, VertexLayoutHandle _declHandle, uint16_t _flags);
|
||||
|
||||
VertexLayoutHandle m_layoutHandle;
|
||||
};
|
||||
|
||||
struct BindInfo
|
||||
{
|
||||
uint32_t m_index = UINT32_MAX;
|
||||
uint32_t m_binding = UINT32_MAX;
|
||||
UniformHandle m_uniform = BGFX_INVALID_HANDLE;
|
||||
};
|
||||
|
||||
struct ShaderWgpu
|
||||
{
|
||||
void create(ShaderHandle _handle, const Memory* _mem);
|
||||
void destroy()
|
||||
{
|
||||
if (NULL != m_constantBuffer)
|
||||
{
|
||||
UniformBuffer::destroy(m_constantBuffer);
|
||||
m_constantBuffer = NULL;
|
||||
}
|
||||
|
||||
m_module = nullptr;
|
||||
}
|
||||
|
||||
const char* name() const { return getName(m_handle); }
|
||||
|
||||
ShaderHandle m_handle;
|
||||
String m_label;
|
||||
|
||||
wgpu::ShaderStage m_stage;
|
||||
wgpu::ShaderModule m_module;
|
||||
|
||||
uint32_t* m_code = nullptr;
|
||||
size_t m_codeSize = 0;
|
||||
|
||||
UniformBuffer* m_constantBuffer = nullptr;
|
||||
|
||||
PredefinedUniform m_predefined[PredefinedUniform::Count];
|
||||
uint16_t m_attrMask[Attrib::Count];
|
||||
uint8_t m_attrRemap[Attrib::Count];
|
||||
|
||||
uint32_t m_hash = 0;
|
||||
uint16_t m_numUniforms = 0;
|
||||
uint16_t m_size = 0;
|
||||
uint16_t m_gpuSize = 0;
|
||||
uint8_t m_numPredefined = 0;
|
||||
uint8_t m_numAttrs = 0;
|
||||
|
||||
BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
uint8_t m_numSamplers = 0;
|
||||
wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
uint32_t m_numBuffers = 0;
|
||||
};
|
||||
|
||||
struct PipelineStateWgpu;
|
||||
|
||||
struct ProgramWgpu
|
||||
{
|
||||
void create(const ShaderWgpu* _vsh, const ShaderWgpu* _fsh);
|
||||
void destroy();
|
||||
|
||||
const ShaderWgpu* m_vsh = NULL;
|
||||
const ShaderWgpu* m_fsh = NULL;
|
||||
|
||||
PredefinedUniform m_predefined[PredefinedUniform::Count * 2];
|
||||
uint8_t m_numPredefined;
|
||||
|
||||
PipelineStateWgpu* m_computePS = NULL;
|
||||
|
||||
wgpu::BindGroupLayout m_bindGroupLayout;
|
||||
uint16_t m_gpuSize = 0;
|
||||
uint32_t m_numUniforms;
|
||||
uint32_t m_bindGroupLayoutHash;
|
||||
|
||||
BindInfo m_bindInfo[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
wgpu::BindGroupLayoutEntry m_samplers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
wgpu::BindGroupLayoutEntry m_textures[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
uint32_t m_numSamplers = 0;
|
||||
wgpu::BindGroupLayoutEntry m_buffers[BGFX_CONFIG_MAX_TEXTURE_SAMPLERS];
|
||||
uint32_t m_numBuffers = 0;
|
||||
};
|
||||
|
||||
constexpr size_t kMaxVertexInputs = 16;
|
||||
constexpr size_t kMaxVertexAttributes = 16;
|
||||
constexpr size_t kMaxColorAttachments = BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS;
|
||||
|
||||
constexpr uint32_t kMinBufferOffsetAlignment = 256;
|
||||
|
||||
struct RenderPassDescriptor
|
||||
{
|
||||
RenderPassDescriptor();
|
||||
|
||||
wgpu::RenderPassDescriptor desc;
|
||||
|
||||
wgpu::RenderPassColorAttachmentDescriptor colorAttachments[kMaxColorAttachments];
|
||||
wgpu::RenderPassDepthStencilAttachmentDescriptor depthStencilAttachment;
|
||||
};
|
||||
|
||||
struct VertexStateDescriptor
|
||||
{
|
||||
VertexStateDescriptor();
|
||||
|
||||
wgpu::VertexStateDescriptor desc;
|
||||
|
||||
wgpu::VertexBufferLayoutDescriptor vertexBuffers[kMaxVertexInputs];
|
||||
wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
|
||||
};
|
||||
|
||||
struct RenderPipelineDescriptor
|
||||
{
|
||||
RenderPipelineDescriptor();
|
||||
|
||||
wgpu::RenderPipelineDescriptor desc;
|
||||
|
||||
//wgpu::ProgrammableStageDescriptor vertexStage;
|
||||
wgpu::ProgrammableStageDescriptor fragmentStage;
|
||||
|
||||
wgpu::VertexStateDescriptor inputState;
|
||||
|
||||
wgpu::RasterizationStateDescriptor rasterizationState;
|
||||
wgpu::DepthStencilStateDescriptor depthStencilState;
|
||||
wgpu::ColorStateDescriptor colorStates[kMaxColorAttachments];
|
||||
};
|
||||
|
||||
struct BindingsWgpu
|
||||
{
|
||||
uint32_t numEntries = 0;
|
||||
wgpu::BindGroupEntry m_entries[2 + BGFX_CONFIG_MAX_TEXTURE_SAMPLERS*3];
|
||||
};
|
||||
|
||||
struct BindStateWgpu
|
||||
{
|
||||
void clear();
|
||||
|
||||
uint32_t numOffset;
|
||||
|
||||
wgpu::BindGroup m_bindGroup;
|
||||
};
|
||||
|
||||
struct RenderPassStateWgpu
|
||||
{
|
||||
RenderPassDescriptor m_rpd;
|
||||
};
|
||||
|
||||
struct PipelineStateWgpu
|
||||
{
|
||||
RenderPipelineDescriptor m_rpd;
|
||||
|
||||
wgpu::PipelineLayout m_layout;
|
||||
|
||||
wgpu::RenderPipeline m_rps;
|
||||
wgpu::ComputePipeline m_cps;
|
||||
};
|
||||
|
||||
void release(RenderPassStateWgpu* _ptr)
|
||||
{
|
||||
BX_DELETE(g_allocator, _ptr);
|
||||
}
|
||||
|
||||
void release(PipelineStateWgpu* _ptr)
|
||||
{
|
||||
BX_DELETE(g_allocator, _ptr);
|
||||
}
|
||||
|
||||
class StagingBufferWgpu
|
||||
{
|
||||
public:
|
||||
void create(uint32_t _size, bool mapped);
|
||||
void map();
|
||||
void unmap();
|
||||
void destroy();
|
||||
|
||||
void mapped(void* _data, uint64_t _size);
|
||||
|
||||
wgpu::Buffer m_buffer;
|
||||
void* m_data = nullptr;
|
||||
uint64_t m_size = 0;
|
||||
};
|
||||
|
||||
class ScratchBufferWgpu
|
||||
{
|
||||
public:
|
||||
void create(uint32_t _size); // , uint32_t _maxBindGroups);
|
||||
void destroy();
|
||||
void begin();
|
||||
uint32_t write(void* data, uint64_t _size, uint64_t _offset);
|
||||
uint32_t write(void* data, uint64_t _size);
|
||||
void submit();
|
||||
void release();
|
||||
|
||||
StagingBufferWgpu* m_staging = nullptr;
|
||||
wgpu::Buffer m_stagingAlloc;
|
||||
wgpu::Buffer m_buffer;
|
||||
uint32_t m_offset;
|
||||
uint32_t m_size;
|
||||
};
|
||||
|
||||
class BindStateCacheWgpu
|
||||
{
|
||||
public:
|
||||
void create(); // , uint32_t _maxBindGroups);
|
||||
void destroy();
|
||||
void reset();
|
||||
|
||||
BindStateWgpu m_bindStates[1024] = {};
|
||||
uint32_t m_currentBindState;
|
||||
//uint32_t m_maxBindStates;
|
||||
};
|
||||
|
||||
struct ReadbackWgpu
|
||||
{
|
||||
void create(TextureHandle _texture) { m_texture = _texture; }
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_buffer.Destroy();
|
||||
}
|
||||
|
||||
void readback(void const* data, uint64_t size)
|
||||
{
|
||||
bx::memCopy(m_data, data, m_size < size ? m_size : size);
|
||||
m_buffer.Unmap();
|
||||
m_mapped = false;
|
||||
}
|
||||
|
||||
TextureHandle m_texture;
|
||||
wgpu::Buffer m_buffer;
|
||||
uint32_t m_mip = 0;
|
||||
bool m_mapped = false;
|
||||
void* m_data = NULL;
|
||||
size_t m_size = 0;
|
||||
};
|
||||
|
||||
struct TextureWgpu
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Texture2D,
|
||||
Texture3D,
|
||||
TextureCube,
|
||||
};
|
||||
|
||||
void create(TextureHandle _handle, const Memory* _mem, uint64_t _flags, uint8_t _skip);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_ptr.Destroy();
|
||||
}
|
||||
|
||||
void update(
|
||||
uint8_t _side
|
||||
, uint8_t _mip
|
||||
, const Rect& _rect
|
||||
, uint16_t _z
|
||||
, uint16_t _depth
|
||||
, uint16_t _pitch
|
||||
, const Memory* _mem
|
||||
);
|
||||
|
||||
TextureHandle m_handle;
|
||||
String m_label;
|
||||
|
||||
wgpu::TextureView m_view;
|
||||
wgpu::TextureView getTextureMipLevel(int _mip);
|
||||
|
||||
wgpu::Texture m_ptr;
|
||||
wgpu::Texture m_ptrMsaa;
|
||||
wgpu::TextureView m_ptrMips[14] = {};
|
||||
wgpu::Sampler m_sampler;
|
||||
uint64_t m_flags = 0;
|
||||
uint32_t m_width = 0;
|
||||
uint32_t m_height = 0;
|
||||
uint32_t m_depth = 0;
|
||||
uint8_t m_type;
|
||||
TextureFormat::Enum m_requestedFormat;
|
||||
TextureFormat::Enum m_textureFormat;
|
||||
uint8_t m_numMips = 0;
|
||||
uint8_t m_numLayers;
|
||||
uint32_t m_numSides;
|
||||
uint8_t m_sampleCount;
|
||||
|
||||
ReadbackWgpu m_readback;
|
||||
};
|
||||
|
||||
struct SamplerStateWgpu
|
||||
{
|
||||
wgpu::Sampler m_sampler;
|
||||
};
|
||||
|
||||
void release(SamplerStateWgpu* _ptr)
|
||||
{
|
||||
BX_DELETE(g_allocator, _ptr);
|
||||
}
|
||||
|
||||
struct FrameBufferWgpu;
|
||||
|
||||
struct SwapChainWgpu
|
||||
{
|
||||
void init(wgpu::Device _device, void* _nwh, uint32_t _width, uint32_t _height);
|
||||
void resize(FrameBufferWgpu& _frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags);
|
||||
|
||||
void flip();
|
||||
|
||||
wgpu::TextureView current();
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
DawnSwapChainImplementation m_impl;
|
||||
#endif
|
||||
|
||||
wgpu::SwapChain m_swapChain;
|
||||
|
||||
wgpu::TextureView m_drawable;
|
||||
|
||||
wgpu::Texture m_backBufferColorMsaa;
|
||||
wgpu::Texture m_backBufferDepth;
|
||||
|
||||
wgpu::TextureFormat m_colorFormat;
|
||||
wgpu::TextureFormat m_depthFormat;
|
||||
|
||||
uint32_t m_maxAnisotropy = 0;
|
||||
uint8_t m_sampleCount;
|
||||
};
|
||||
|
||||
struct FrameBufferWgpu
|
||||
{
|
||||
void create(uint8_t _num, const Attachment* _attachment);
|
||||
bool create(
|
||||
uint16_t _denseIdx
|
||||
, void* _nwh
|
||||
, uint32_t _width
|
||||
, uint32_t _height
|
||||
, TextureFormat::Enum _format
|
||||
, TextureFormat::Enum _depthFormat
|
||||
);
|
||||
void postReset();
|
||||
uint16_t destroy();
|
||||
|
||||
SwapChainWgpu* m_swapChain = NULL;
|
||||
void* m_nwh = NULL;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint16_t m_denseIdx = UINT16_MAX;
|
||||
|
||||
uint32_t m_pixelFormatHash = 0;
|
||||
|
||||
TextureHandle m_colorHandle[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
|
||||
TextureHandle m_depthHandle = { kInvalidHandle };
|
||||
Attachment m_colorAttachment[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS - 1];
|
||||
Attachment m_depthAttachment;
|
||||
uint8_t m_num = 0; // number of color handles
|
||||
};
|
||||
|
||||
struct CommandQueueWgpu
|
||||
{
|
||||
void init(wgpu::Queue _queue);
|
||||
void shutdown();
|
||||
void begin();
|
||||
void kick(bool _endFrame, bool _waitForFinish = false);
|
||||
void finish(bool _finishAll = false);
|
||||
void release(wgpu::Buffer _buffer);
|
||||
void consume();
|
||||
|
||||
#if BGFX_CONFIG_MULTITHREADED
|
||||
//bx::Semaphore m_framesSemaphore;
|
||||
#endif
|
||||
|
||||
wgpu::Queue m_queue;
|
||||
wgpu::CommandEncoder m_encoder;
|
||||
|
||||
int m_releaseWriteIndex = 0;
|
||||
int m_releaseReadIndex = 0;
|
||||
|
||||
typedef stl::vector<wgpu::Buffer> ResourceArray;
|
||||
ResourceArray m_release[WEBGPU_MAX_FRAMES_IN_FLIGHT];
|
||||
};
|
||||
|
||||
struct TimerQueryWgpu
|
||||
{
|
||||
TimerQueryWgpu()
|
||||
: m_control(4)
|
||||
{
|
||||
}
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
uint32_t begin(uint32_t _resultIdx);
|
||||
void end(uint32_t _idx);
|
||||
void addHandlers(wgpu::CommandBuffer& _commandBuffer);
|
||||
bool get();
|
||||
|
||||
struct Result
|
||||
{
|
||||
void reset()
|
||||
{
|
||||
m_begin = 0;
|
||||
m_end = 0;
|
||||
m_pending = 0;
|
||||
}
|
||||
|
||||
uint64_t m_begin;
|
||||
uint64_t m_end;
|
||||
uint32_t m_pending;
|
||||
};
|
||||
|
||||
uint64_t m_begin;
|
||||
uint64_t m_end;
|
||||
uint64_t m_elapsed;
|
||||
uint64_t m_frequency;
|
||||
|
||||
Result m_result[4 * 2];
|
||||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
struct OcclusionQueryWgpu
|
||||
{
|
||||
OcclusionQueryWgpu()
|
||||
: m_control(BX_COUNTOF(m_query))
|
||||
{
|
||||
}
|
||||
|
||||
void postReset();
|
||||
void preReset();
|
||||
void begin(wgpu::RenderPassEncoder& _rce, Frame* _render, OcclusionQueryHandle _handle);
|
||||
void end(wgpu::RenderPassEncoder& _rce);
|
||||
void resolve(Frame* _render, bool _wait = false);
|
||||
void invalidate(OcclusionQueryHandle _handle);
|
||||
|
||||
struct Query
|
||||
{
|
||||
OcclusionQueryHandle m_handle;
|
||||
};
|
||||
|
||||
wgpu::Buffer m_buffer;
|
||||
Query m_query[BGFX_CONFIG_MAX_OCCLUSION_QUERIES];
|
||||
bx::RingBufferControl m_control;
|
||||
};
|
||||
|
||||
} /* namespace metal */
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_CONFIG_RENDERER_WEBGPU
|
||||
|
||||
#endif // BGFX_RENDERER_WEBGPU_H_HEADER_GUARD
|
||||
@@ -120,6 +120,12 @@ namespace bgfx
|
||||
|
||||
uint16_t regCount;
|
||||
bx::read(_reader, regCount, _err);
|
||||
|
||||
if (!isShaderVerLess(magic, 8) )
|
||||
{
|
||||
uint16_t texInfo;
|
||||
bx::read(_reader, texInfo, _err);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t shaderSize;
|
||||
|
||||
@@ -53,6 +53,7 @@ namespace bgfx
|
||||
&s_attribTypeSizeGl, // OpenGLES
|
||||
&s_attribTypeSizeGl, // OpenGL
|
||||
&s_attribTypeSizeD3D1x, // Vulkan
|
||||
&s_attribTypeSizeD3D1x, // WebGPU
|
||||
&s_attribTypeSizeD3D9, // Count
|
||||
};
|
||||
BX_STATIC_ASSERT(BX_COUNTOF(s_attribTypeSize) == RendererType::Count+1);
|
||||
|
||||
@@ -13,7 +13,7 @@ extern "C"
|
||||
#include <fpp.h>
|
||||
} // extern "C"
|
||||
|
||||
#define BGFX_SHADER_BIN_VERSION 6
|
||||
#define BGFX_SHADER_BIN_VERSION 8
|
||||
#define BGFX_CHUNK_MAGIC_CSH BX_MAKEFOURCC('C', 'S', 'H', BGFX_SHADER_BIN_VERSION)
|
||||
#define BGFX_CHUNK_MAGIC_FSH BX_MAKEFOURCC('F', 'S', 'H', BGFX_SHADER_BIN_VERSION)
|
||||
#define BGFX_CHUNK_MAGIC_VSH BX_MAKEFOURCC('V', 'S', 'H', BGFX_SHADER_BIN_VERSION)
|
||||
|
||||
@@ -109,7 +109,9 @@ namespace bgfx
|
||||
|
||||
#define BGFX_UNIFORM_FRAGMENTBIT UINT8_C(0x10)
|
||||
#define BGFX_UNIFORM_SAMPLERBIT UINT8_C(0x20)
|
||||
#define BGFX_UNIFORM_MASK (BGFX_UNIFORM_FRAGMENTBIT|BGFX_UNIFORM_SAMPLERBIT)
|
||||
#define BGFX_UNIFORM_READONLYBIT UINT8_C(0x40)
|
||||
#define BGFX_UNIFORM_COMPAREBIT UINT8_C(0x80)
|
||||
#define BGFX_UNIFORM_MASK (BGFX_UNIFORM_FRAGMENTBIT|BGFX_UNIFORM_SAMPLERBIT|BGFX_UNIFORM_READONLYBIT|BGFX_UNIFORM_COMPAREBIT)
|
||||
|
||||
const char* getUniformTypeName(UniformType::Enum _enum);
|
||||
UniformType::Enum nameToUniformTypeEnum(const char* _name);
|
||||
@@ -121,6 +123,8 @@ namespace bgfx
|
||||
uint8_t num;
|
||||
uint16_t regIndex;
|
||||
uint16_t regCount;
|
||||
uint8_t texComponent;
|
||||
uint8_t texDimension;
|
||||
};
|
||||
|
||||
struct Options
|
||||
|
||||
@@ -339,6 +339,8 @@ namespace bgfx { namespace glsl
|
||||
bx::write(_writer, un.num);
|
||||
bx::write(_writer, un.regIndex);
|
||||
bx::write(_writer, un.regCount);
|
||||
bx::write(_writer, un.texComponent);
|
||||
bx::write(_writer, un.texDimension);
|
||||
|
||||
BX_TRACE("%s, %s, %d, %d, %d"
|
||||
, un.name.c_str()
|
||||
|
||||
@@ -736,6 +736,8 @@ namespace bgfx { namespace hlsl
|
||||
bx::write(_writer, un.num);
|
||||
bx::write(_writer, un.regIndex);
|
||||
bx::write(_writer, un.regCount);
|
||||
bx::write(_writer, un.texComponent);
|
||||
bx::write(_writer, un.texDimension);
|
||||
|
||||
BX_TRACE("%s, %s, %d, %d, %d"
|
||||
, un.name.c_str()
|
||||
|
||||
@@ -602,6 +602,8 @@ namespace bgfx { namespace metal
|
||||
bx::write(_writer, un.num);
|
||||
bx::write(_writer, un.regIndex);
|
||||
bx::write(_writer, un.regCount);
|
||||
bx::write(_writer, un.texComponent);
|
||||
bx::write(_writer, un.texDimension);
|
||||
|
||||
BX_TRACE("%s, %s, %d, %d, %d"
|
||||
, un.name.c_str()
|
||||
|
||||
@@ -14,6 +14,7 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow") // warning: declaration of 'u
|
||||
#include <ResourceLimits.h>
|
||||
#include <SPIRV/SPVRemapper.h>
|
||||
#include <SPIRV/GlslangToSpv.h>
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
#define SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
|
||||
#include <spirv_msl.hpp>
|
||||
#include <spirv_reflect.hpp>
|
||||
@@ -175,6 +176,42 @@ namespace bgfx { namespace spirv
|
||||
return true;
|
||||
}
|
||||
|
||||
wgpu::TextureComponentType SpirvCrossBaseTypeToFormatType(spirv_cross::SPIRType::BaseType spirvBaseType)
|
||||
{
|
||||
switch (spirvBaseType)
|
||||
{
|
||||
case spirv_cross::SPIRType::Float:
|
||||
return wgpu::TextureComponentType::Float;
|
||||
case spirv_cross::SPIRType::Int:
|
||||
return wgpu::TextureComponentType::Sint;
|
||||
case spirv_cross::SPIRType::UInt:
|
||||
return wgpu::TextureComponentType::Uint;
|
||||
default:
|
||||
return wgpu::TextureComponentType::Float;
|
||||
}
|
||||
}
|
||||
|
||||
wgpu::TextureViewDimension SpirvDimToTextureViewDimension(spv::Dim dim, bool arrayed)
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
case spv::Dim::Dim1D:
|
||||
return wgpu::TextureViewDimension::e1D;
|
||||
case spv::Dim::Dim2D:
|
||||
return arrayed
|
||||
? wgpu::TextureViewDimension::e2DArray
|
||||
: wgpu::TextureViewDimension::e2D;
|
||||
case spv::Dim::Dim3D:
|
||||
return wgpu::TextureViewDimension::e3D;
|
||||
case spv::Dim::DimCube:
|
||||
return arrayed
|
||||
? wgpu::TextureViewDimension::CubeArray
|
||||
: wgpu::TextureViewDimension::Cube;
|
||||
default:
|
||||
return wgpu::TextureViewDimension::Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
struct SpvReflection
|
||||
{
|
||||
struct TypeId
|
||||
@@ -619,6 +656,8 @@ namespace bgfx { namespace spirv
|
||||
bx::write(_writer, un.num);
|
||||
bx::write(_writer, un.regIndex);
|
||||
bx::write(_writer, un.regCount);
|
||||
bx::write(_writer, un.texComponent);
|
||||
bx::write(_writer, un.texDimension);
|
||||
|
||||
BX_TRACE("%s, %s, %d, %d, %d"
|
||||
, un.name.c_str()
|
||||
@@ -938,15 +977,32 @@ namespace bgfx { namespace spirv
|
||||
if (name.size() > 7
|
||||
&& 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") )
|
||||
{
|
||||
auto uniform_name = name.substr(0, name.length() - 7);
|
||||
std::string uniform_name = name.substr(0, name.length() - 7);
|
||||
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
|
||||
|
||||
auto imageType = refl.get_type(resource.base_type_id).image;
|
||||
auto componentType = refl.get_type(imageType.type).basetype;
|
||||
|
||||
bool isCompareSampler = false;
|
||||
for (auto& sampler : resourcesrefl.separate_samplers)
|
||||
{
|
||||
if (binding_index + 16 == refl.get_decoration(sampler.id, spv::Decoration::DecorationBinding))
|
||||
{
|
||||
std::string samplerName = refl.get_name(sampler.id);
|
||||
isCompareSampler = refl.variable_is_depth_or_compare(sampler.id) || samplerName.find("Comparison") != std::string::npos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Uniform un;
|
||||
un.name = uniform_name;
|
||||
un.type = UniformType::Enum(BGFX_UNIFORM_SAMPLERBIT | UniformType::Sampler);
|
||||
if (isCompareSampler)
|
||||
un.type = UniformType::Enum(BGFX_UNIFORM_SAMPLERBIT | BGFX_UNIFORM_COMPAREBIT | UniformType::Sampler);
|
||||
else
|
||||
un.type = UniformType::Enum(BGFX_UNIFORM_SAMPLERBIT | UniformType::Sampler);
|
||||
|
||||
const uint32_t binding = refl.get_decoration(resource.id, spv::DecorationBinding);
|
||||
|
||||
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
|
||||
un.texComponent = uint8_t(SpirvCrossBaseTypeToFormatType(componentType));
|
||||
un.texDimension = uint8_t(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed));
|
||||
|
||||
un.regIndex = binding_index;
|
||||
un.regCount = 0; // unused
|
||||
@@ -963,13 +1019,24 @@ namespace bgfx { namespace spirv
|
||||
if (name.size() > 7
|
||||
&& 0 == bx::strCmp(name.c_str() + name.length() - 7, "Texture") )
|
||||
{
|
||||
auto uniform_name = name.substr(0, name.length() - 7);
|
||||
std::string uniform_name = name.substr(0, name.length() - 7);
|
||||
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
|
||||
std::string sampler_name = uniform_name + "Sampler";
|
||||
|
||||
auto imageType = refl.get_type(resource.base_type_id).image;
|
||||
auto componentType = refl.get_type(imageType.type).basetype;
|
||||
|
||||
spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id);
|
||||
UniformType::Enum type = flags.get(spv::DecorationNonWritable)
|
||||
? UniformType::Enum(BGFX_UNIFORM_READONLYBIT | UniformType::End)
|
||||
: UniformType::End;
|
||||
|
||||
Uniform un;
|
||||
un.name = uniform_name;
|
||||
un.type = UniformType::End;
|
||||
un.type = type;
|
||||
|
||||
un.texComponent = uint8_t(SpirvCrossBaseTypeToFormatType(componentType));
|
||||
un.texDimension = uint8_t(SpirvDimToTextureViewDimension(imageType.dim, imageType.arrayed));
|
||||
|
||||
un.regIndex = binding_index;
|
||||
un.regCount = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE; // for descriptor type
|
||||
|
||||
@@ -986,6 +1053,11 @@ namespace bgfx { namespace spirv
|
||||
{
|
||||
if (!bx::strFind(uniform.name.c_str(), name.c_str()).isEmpty())
|
||||
{
|
||||
spirv_cross::Bitset flags = refl.get_buffer_block_flags(resource.id);
|
||||
UniformType::Enum type = flags.get(spv::DecorationNonWritable)
|
||||
? UniformType::Enum(BGFX_UNIFORM_READONLYBIT | UniformType::End)
|
||||
: UniformType::End;
|
||||
|
||||
uint32_t binding_index = refl.get_decoration(resource.id, spv::Decoration::DecorationBinding);
|
||||
uniform.name = name;
|
||||
uniform.type = UniformType::End;
|
||||
|
||||
Reference in New Issue
Block a user