From cf8ff1826345c33c550a65e4f0fe9adb57d128ea Mon Sep 17 00:00:00 2001 From: Hugo Amnov Date: Sun, 18 Apr 2021 20:39:52 +0200 Subject: [PATCH] WebGPU update (#2477) * WebGPU: Update to latest changes + Fixes * WebGPU: Fix RG11B10F format as framebuffer --- 3rdparty/webgpu/webgpu_cpp.cpp | 3 +- scripts/bgfx.lua | 48 +++-- src/renderer_webgpu.cpp | 338 ++++++++++++++++++--------------- src/renderer_webgpu.h | 17 +- 4 files changed, 226 insertions(+), 180 deletions(-) diff --git a/3rdparty/webgpu/webgpu_cpp.cpp b/3rdparty/webgpu/webgpu_cpp.cpp index 60dd5060c..ad9c22a26 100644 --- a/3rdparty/webgpu/webgpu_cpp.cpp +++ b/3rdparty/webgpu/webgpu_cpp.cpp @@ -1,4 +1,5 @@ -#include "dawn/webgpu_cpp.h" + +#include "webgpu/webgpu_cpp.h" namespace wgpu { diff --git a/scripts/bgfx.lua b/scripts/bgfx.lua index a911bc47e..0fba9be0a 100644 --- a/scripts/bgfx.lua +++ b/scripts/bgfx.lua @@ -187,7 +187,7 @@ function bgfxProjectBase(_kind, _defines) "BGFX_CONFIG_DEBUG_ANNOTATION=0", -- does not work } - local generator = "out/Default" + local generator = "out/Cmake" configuration { "wasm*" } defines { @@ -198,10 +198,13 @@ function bgfxProjectBase(_kind, _defines) configuration { "not wasm*" } includedirs { path.join(DAWN_DIR, "src/include"), - path.join(DAWN_DIR, "third_party/vulkan-headers/include"), + path.join(DAWN_DIR, "third_party/vulkan-deps/vulkan-headers/src/include"), path.join(DAWN_DIR, generator, "gen/src/include"), } + files { + path.join(DAWN_DIR, generator, "gen/src/dawn/webgpu_cpp.cpp"), + } configuration { "vs*" } defines { "NTDDI_VERSION=NTDDI_WIN10_RS2", @@ -296,7 +299,7 @@ if _OPTIONS["with-webgpu"] then } configuration { "not wasm*" } - local generator = "out/Default" + local generator = "out/Cmake" includedirs { path.join(DAWN_DIR, "src/include"), @@ -305,27 +308,34 @@ if _OPTIONS["with-webgpu"] then libdirs { path.join(DAWN_DIR, generator), - path.join(DAWN_DIR, generator, "lib/Debug"), + path.join(DAWN_DIR, generator, "src/common/Debug"), + path.join(DAWN_DIR, generator, "src/dawn/Debug"), + path.join(DAWN_DIR, generator, "src/dawn_native/Debug"), + path.join(DAWN_DIR, generator, "src/dawn_platform/Debug"), + path.join(DAWN_DIR, generator, "third_party/tint/src/Debug"), + path.join(DAWN_DIR, generator, "third_party/vulkan-deps/spirv-tools/src/source/Debug"), + path.join(DAWN_DIR, generator, "third_party/vulkan-deps/spirv-tools/src/source/opt/Debug"), + path.join(DAWN_DIR, generator, "third_party/vulkan-deps/spirv-cross/src/Debug"), } links { -- shared - "dawn_proc_shared", - "dawn_native_shared", - "shaderc_spvc_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", + "dawn_common", + "dawn_proc", + "dawn_native", + "dawn_platform", + ----"shaderc", + "tint", + "SPIRV-Tools", + "SPIRV-Tools-opt", + "spirv-cross-cored", + "spirv-cross-hlsld", + "spirv-cross-glsld", + "spirv-cross-msld", --"spirv-cross-reflectd", } diff --git a/src/renderer_webgpu.cpp b/src/renderer_webgpu.cpp index 5728412d4..485b7b9d2 100644 --- a/src/renderer_webgpu.cpp +++ b/src/renderer_webgpu.cpp @@ -52,15 +52,15 @@ namespace bgfx { namespace webgpu template T defaultDescriptor() { return T(); } - template <> wgpu::BlendDescriptor defaultDescriptor() { return { wgpu::BlendOperation::Add, wgpu::BlendFactor::One, wgpu::BlendFactor::Zero }; } - template <> wgpu::ColorStateDescriptor defaultDescriptor() { return { NULL, wgpu::TextureFormat::RGBA8Unorm, defaultDescriptor(), defaultDescriptor(), wgpu::ColorWriteMask::All }; } - template <> wgpu::StencilStateFaceDescriptor defaultDescriptor() { return { wgpu::CompareFunction::Always, wgpu::StencilOperation::Keep, wgpu::StencilOperation::Keep, wgpu::StencilOperation::Keep }; } - template <> wgpu::VertexStateDescriptor defaultDescriptor() { return { NULL, wgpu::IndexFormat::Undefined, 0, NULL }; } - template <> wgpu::VertexBufferLayoutDescriptor defaultDescriptor() { return { 0, wgpu::InputStepMode::Vertex, 0, NULL }; } - template <> wgpu::VertexAttributeDescriptor defaultDescriptor() { return { wgpu::VertexFormat::Float, 0, 0 }; } - template <> wgpu::RasterizationStateDescriptor defaultDescriptor() { return { NULL, wgpu::FrontFace::CCW, wgpu::CullMode::None, 0, 0.f, 0.f }; } - template <> wgpu::ProgrammableStageDescriptor defaultDescriptor() { return { NULL, {}, "main" }; } - template <> wgpu::DepthStencilStateDescriptor defaultDescriptor() { return { NULL, wgpu::TextureFormat::Depth24PlusStencil8, false, wgpu::CompareFunction::Always, defaultDescriptor(), defaultDescriptor(), 0xff, 0xff }; } + template <> wgpu::BlendComponent defaultDescriptor() { return { wgpu::BlendOperation::Add, wgpu::BlendFactor::One, wgpu::BlendFactor::Zero }; } + template <> wgpu::ColorTargetState defaultDescriptor() { return { NULL, wgpu::TextureFormat::RGBA8Unorm, NULL, wgpu::ColorWriteMask::All }; } + template <> wgpu::StencilFaceState defaultDescriptor() { return { wgpu::CompareFunction::Always, wgpu::StencilOperation::Keep, wgpu::StencilOperation::Keep, wgpu::StencilOperation::Keep }; } + template <> wgpu::VertexState defaultDescriptor() { return { NULL, {}, "main", 0, NULL }; } + template <> wgpu::FragmentState defaultDescriptor() { return { NULL, {}, "main", 0, NULL }; } + template <> wgpu::VertexBufferLayout defaultDescriptor() { return { 0, wgpu::InputStepMode::Vertex, 0, NULL }; } + template <> wgpu::VertexAttribute defaultDescriptor() { return { wgpu::VertexFormat::Float, 0, 0 }; } + template <> wgpu::PrimitiveState defaultDescriptor() { return { NULL, wgpu::PrimitiveTopology::TriangleList, wgpu::IndexFormat::Undefined, wgpu::FrontFace::CCW, wgpu::CullMode::None }; } + template <> wgpu::DepthStencilState defaultDescriptor() { return { NULL, wgpu::TextureFormat::Depth24PlusStencil8, false, wgpu::CompareFunction::Always, defaultDescriptor(), defaultDescriptor(), 0xff, 0xff }; } template <> wgpu::PipelineLayoutDescriptor defaultDescriptor() { return { NULL, "", 0, NULL }; } template <> wgpu::TextureViewDescriptor defaultDescriptor() { return {}; } @@ -86,49 +86,49 @@ namespace bgfx { namespace webgpu { for(uint32_t i = 0; i < kMaxVertexInputs; ++i) { - vertexBuffers[i] = defaultDescriptor(); + buffers[i] = defaultDescriptor(); } for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) { - attributes[i] = defaultDescriptor(); + attributes[i] = defaultDescriptor(); } - vertexBuffers[0].attributes = &attributes[0]; - //vertexBuffers[0].attributeCount = numAttributes; + buffers[0].attributes = &attributes[0]; + //buffers[0].attributeCount = numAttributes; - desc = defaultDescriptor(); + desc = defaultDescriptor(); - desc.vertexBuffers = vertexBuffers; + desc.buffers = buffers; //desc.vertexBufferCount = numVertexBuffers; } RenderPipelineDescriptor::RenderPipelineDescriptor() { - //vertexStage = defaultDescriptor(); - fragmentStage = defaultDescriptor(); - rasterizationState = defaultDescriptor(); - depthStencilState = defaultDescriptor(); + //vertex = defaultDescriptor(); + fragment = defaultDescriptor(); + depthStencil = defaultDescriptor(); for(uint32_t i = 0; i < kMaxColorAttachments; ++i) { - colorStates[i] = defaultDescriptor(); + targets[i] = defaultDescriptor(); } - desc = defaultDescriptor(); + desc = defaultDescriptor(); - desc.primitiveTopology = wgpu::PrimitiveTopology::TriangleList; - desc.sampleCount = 1; - desc.colorStateCount = 1; + desc.primitive.topology = wgpu::PrimitiveTopology::TriangleList; + desc.multisample.count = 1; + + fragment.targetCount = 1; + fragment.targets = targets; //wgpu::VertexStateDescriptor inputState = inputState.descriptor(); - desc.vertexStage = defaultDescriptor(); - desc.fragmentStage = &fragmentStage; + desc.vertex = defaultDescriptor(); + desc.fragment = NULL; //desc.vertexState = &inputState; - desc.rasterizationState = &rasterizationState; - desc.depthStencilState = NULL; - desc.colorStates = colorStates; + desc.primitive = defaultDescriptor(); + desc.depthStencil = NULL; } // TODO (hugoam) cleanup (end) @@ -163,34 +163,34 @@ namespace bgfx { namespace webgpu static const wgpu::VertexFormat s_attribType[][4][2] = { { // Uint8 - { wgpu::VertexFormat::UChar2, wgpu::VertexFormat::UChar2Norm }, - { wgpu::VertexFormat::UChar2, wgpu::VertexFormat::UChar2Norm }, - { wgpu::VertexFormat::UChar4, wgpu::VertexFormat::UChar4Norm }, - { wgpu::VertexFormat::UChar4, wgpu::VertexFormat::UChar4Norm }, + { wgpu::VertexFormat::Uint8x2, wgpu::VertexFormat::Unorm8x2 }, + { wgpu::VertexFormat::Uint8x2, wgpu::VertexFormat::Unorm8x2 }, + { wgpu::VertexFormat::Uint8x4, wgpu::VertexFormat::Unorm8x4 }, + { wgpu::VertexFormat::Uint8x4, wgpu::VertexFormat::Unorm8x4 }, }, { // Uint10 - { wgpu::VertexFormat::UShort2, wgpu::VertexFormat::UShort2Norm }, - { wgpu::VertexFormat::UShort2, wgpu::VertexFormat::UShort2Norm }, - { wgpu::VertexFormat::UShort4, wgpu::VertexFormat::UShort4Norm }, - { wgpu::VertexFormat::UShort4, wgpu::VertexFormat::UShort4Norm }, + { wgpu::VertexFormat::Uint16x2, wgpu::VertexFormat::Unorm16x2 }, + { wgpu::VertexFormat::Uint16x2, wgpu::VertexFormat::Unorm16x2 }, + { wgpu::VertexFormat::Uint16x4, wgpu::VertexFormat::Unorm16x4 }, + { wgpu::VertexFormat::Uint16x4, wgpu::VertexFormat::Unorm16x4 }, }, { // Int16 - { wgpu::VertexFormat::Short2, wgpu::VertexFormat::Short2Norm }, - { wgpu::VertexFormat::Short2, wgpu::VertexFormat::Short2Norm }, - { wgpu::VertexFormat::Short4, wgpu::VertexFormat::Short4Norm }, - { wgpu::VertexFormat::Short4, wgpu::VertexFormat::Short4Norm }, + { wgpu::VertexFormat::Sint16x2, wgpu::VertexFormat::Snorm16x2 }, + { wgpu::VertexFormat::Sint16x2, wgpu::VertexFormat::Snorm16x2 }, + { wgpu::VertexFormat::Sint16x4, wgpu::VertexFormat::Snorm16x4 }, + { wgpu::VertexFormat::Sint16x4, wgpu::VertexFormat::Snorm16x4 }, }, { // Half - { wgpu::VertexFormat::Half2, wgpu::VertexFormat::Half2 }, - { wgpu::VertexFormat::Half2, wgpu::VertexFormat::Half2 }, - { wgpu::VertexFormat::Half4, wgpu::VertexFormat::Half4 }, - { wgpu::VertexFormat::Half4, wgpu::VertexFormat::Half4 }, + { wgpu::VertexFormat::Float16x2, wgpu::VertexFormat::Float16x2 }, + { wgpu::VertexFormat::Float16x2, wgpu::VertexFormat::Float16x2 }, + { wgpu::VertexFormat::Float16x4, wgpu::VertexFormat::Float16x4 }, + { wgpu::VertexFormat::Float16x4, wgpu::VertexFormat::Float16x4 }, }, { // Float - { wgpu::VertexFormat::Float, wgpu::VertexFormat::Float }, - { wgpu::VertexFormat::Float2, wgpu::VertexFormat::Float2 }, - { wgpu::VertexFormat::Float3, wgpu::VertexFormat::Float3 }, - { wgpu::VertexFormat::Float4, wgpu::VertexFormat::Float4 }, + { wgpu::VertexFormat::Float32, wgpu::VertexFormat::Float32 }, + { wgpu::VertexFormat::Float32x2, wgpu::VertexFormat::Float32x2 }, + { wgpu::VertexFormat::Float32x3, wgpu::VertexFormat::Float32x3 }, + { wgpu::VertexFormat::Float32x4, wgpu::VertexFormat::Float32x4 }, }, }; BX_STATIC_ASSERT(AttribType::Count == BX_COUNTOF(s_attribType) ); @@ -368,7 +368,7 @@ namespace bgfx { namespace webgpu { wgpu::TextureFormat::Undefined, wgpu::TextureFormat::Undefined }, // D16F { wgpu::TextureFormat::Undefined, wgpu::TextureFormat::Undefined }, // D24F { wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Undefined }, // D32F - { wgpu::TextureFormat::Undefined, wgpu::TextureFormat::Undefined }, // D0S8 + { wgpu::TextureFormat::Stencil8, wgpu::TextureFormat::Undefined }, // D0S8 }; BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat)); @@ -498,6 +498,7 @@ namespace bgfx { namespace webgpu desc.forceEnabledToggles.push_back("use_dxc"); # endif + desc.forceDisabledToggles.push_back("disallow_unsafe_apis"); WGPUDevice backendDevice = backendAdapter.CreateDevice(&desc); DawnProcTable backendProcs = dawn_native::GetProcs(); @@ -564,7 +565,7 @@ namespace bgfx { namespace webgpu return false; } - m_queue = m_device.GetDefaultQueue(); + m_queue = m_device.GetQueue(); m_cmd.init(m_queue); //BGFX_FATAL(NULL != m_cmd.m_commandQueue, Fatal::UnableToInitialize, "Unable to create Metal device."); @@ -591,7 +592,7 @@ namespace bgfx { namespace webgpu // | BGFX_CAPS_OCCLUSION_QUERY | BGFX_CAPS_SWAP_CHAIN | BGFX_CAPS_TEXTURE_2D_ARRAY - // | BGFX_CAPS_TEXTURE_3D + | BGFX_CAPS_TEXTURE_3D | BGFX_CAPS_TEXTURE_BLIT | BGFX_CAPS_TEXTURE_COMPARE_ALL | BGFX_CAPS_TEXTURE_COMPARE_LEQUAL @@ -661,6 +662,7 @@ namespace bgfx { namespace webgpu g_caps.formats[TextureFormat::RGB5A1] = BGFX_CAPS_FORMAT_TEXTURE_NONE; g_caps.formats[TextureFormat::RGB9E5F] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); + g_caps.formats[TextureFormat::RG11B10F] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER | BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); // disable compressed formats for (uint32_t ii = 0; ii < TextureFormat::Unknown; ++ii) @@ -873,17 +875,17 @@ namespace bgfx { namespace webgpu readback.m_buffer = m_device.CreateBuffer(&desc); } - wgpu::TextureCopyView textureCopyView; - textureCopyView.texture = texture.m_ptr; - textureCopyView.origin = { 0, 0, 0 }; + wgpu::ImageCopyTexture imageCopyTexture; + imageCopyTexture.texture = texture.m_ptr; + imageCopyTexture.origin = { 0, 0, 0 }; - wgpu::BufferCopyView bufferCopyView; - bufferCopyView.buffer = readback.m_buffer; - bufferCopyView.layout.bytesPerRow = dstpitch; - bufferCopyView.layout.rowsPerImage = srcHeight; + wgpu::ImageCopyBuffer imageCopyBuffer; + imageCopyBuffer.buffer = readback.m_buffer; + imageCopyBuffer.layout.bytesPerRow = dstpitch; + imageCopyBuffer.layout.rowsPerImage = srcHeight; wgpu::Extent3D extent3D = { srcWidth, srcHeight, 1 }; - getBlitCommandEncoder().CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &extent3D); + getBlitCommandEncoder().CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &extent3D); auto finish = [](WGPUBufferMapAsyncStatus status, void* userdata) { @@ -1313,11 +1315,14 @@ namespace bgfx { namespace webgpu bindState.numOffset = program.m_numUniforms; // first two bindings are always uniform buffer (vertex/fragment) - bindings.m_entries[0].binding = 0; - bindings.m_entries[0].offset = 0; - bindings.m_entries[0].size = program.m_vsh->m_gpuSize; - bindings.m_entries[0].buffer = scratchBuffer.m_buffer; - bindings.numEntries++; + if (0 < program.m_vsh->m_gpuSize) + { + bindings.m_entries[0].binding = 0; + bindings.m_entries[0].offset = 0; + bindings.m_entries[0].size = program.m_vsh->m_gpuSize; + bindings.m_entries[0].buffer = scratchBuffer.m_buffer; + bindings.numEntries++; + } if (NULL != program.m_fsh && 0 < program.m_fsh->m_gpuSize) @@ -1735,7 +1740,7 @@ namespace bgfx { namespace webgpu m_rtMsaa = _msaa; } - void setDepthStencilState(wgpu::DepthStencilStateDescriptor& desc, uint64_t _state, uint64_t _stencil = 0) + void setDepthStencilState(wgpu::DepthStencilState& desc, uint64_t _state, uint64_t _stencil = 0) { const uint32_t fstencil = unpackStencil(0, _stencil); const uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK) >> BGFX_STATE_DEPTH_TEST_SHIFT; @@ -1747,8 +1752,8 @@ namespace bgfx { namespace webgpu const uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil; bstencil = frontAndBack ? bstencil : fstencil; - desc.stencilFront = defaultDescriptor(); - desc.stencilBack = defaultDescriptor(); + desc.stencilFront = defaultDescriptor(); + desc.stencilBack = defaultDescriptor(); if (0 != _stencil) { @@ -1869,9 +1874,9 @@ namespace bgfx { namespace webgpu ? swapChain.m_sampleCount : 1 ; - pd.colorStates[0].format = swapChain.m_colorFormat; - pd.depthStencilState.format = swapChain.m_depthFormat; - pd.desc.depthStencilState = &pd.depthStencilState; + pd.targets[0].format = swapChain.m_colorFormat; + pd.depthStencil.format = swapChain.m_depthFormat; + pd.desc.depthStencil = &pd.depthStencil; } else { @@ -1884,16 +1889,16 @@ namespace bgfx { namespace webgpu ? texture.m_sampleCount : 1 ; - pd.colorStates[ii].format = s_textureFormat[texture.m_textureFormat].m_fmt; + pd.targets[ii].format = s_textureFormat[texture.m_textureFormat].m_fmt; } - pd.desc.colorStateCount = frameBuffer.m_num; + pd.fragment.targetCount = frameBuffer.m_num; if (isValid(frameBuffer.m_depthHandle) ) { const TextureWgpu& texture = m_textures[frameBuffer.m_depthHandle.idx]; - pd.depthStencilState.format = s_textureFormat[texture.m_textureFormat].m_fmt; - pd.desc.depthStencilState = &pd.depthStencilState; + pd.depthStencil.format = s_textureFormat[texture.m_textureFormat].m_fmt; + pd.desc.depthStencil = &pd.depthStencil; } } @@ -1916,22 +1921,28 @@ namespace bgfx { namespace webgpu for (uint32_t ii = 0; ii < (independentBlendEnable ? 1 : frameBufferAttachment); ++ii) { - wgpu::ColorStateDescriptor& drt = pd.colorStates[ii]; // = pd.colorAttachments[ii]; + wgpu::ColorTargetState& drt = pd.targets[ii]; + wgpu::BlendState& blend = pd.blends[ii]; if(!(BGFX_STATE_BLEND_MASK & _state)) { - drt.colorBlend = defaultDescriptor(); - drt.alphaBlend = defaultDescriptor(); + // useless + blend.color = defaultDescriptor(); + blend.alpha = defaultDescriptor(); + + drt.blend = NULL; } else { - drt.colorBlend.srcFactor = s_blendFactor[srcRGB][0]; - drt.colorBlend.dstFactor = s_blendFactor[dstRGB][0]; - drt.colorBlend.operation = s_blendEquation[equRGB]; + blend.color.srcFactor = s_blendFactor[srcRGB][0]; + blend.color.dstFactor = s_blendFactor[dstRGB][0]; + blend.color.operation = s_blendEquation[equRGB]; - drt.alphaBlend.srcFactor = s_blendFactor[srcA][1]; - drt.alphaBlend.dstFactor = s_blendFactor[dstA][1]; - drt.alphaBlend.operation = s_blendEquation[equA]; + blend.alpha.srcFactor = s_blendFactor[srcA][1]; + blend.alpha.dstFactor = s_blendFactor[dstA][1]; + blend.alpha.operation = s_blendEquation[equA]; + + drt.blend = &blend; } drt.writeMask = writeMask; @@ -1941,7 +1952,8 @@ namespace bgfx { namespace webgpu { for (uint32_t ii = 1, rgba = _rgba; ii < frameBufferAttachment; ++ii, rgba >>= 11) { - wgpu::ColorStateDescriptor drt = pd.colorStates[ii]; // = pd.colorAttachments[ii]; + wgpu::ColorTargetState& drt = pd.targets[ii]; + wgpu::BlendState& blend = pd.blends[ii]; //drt.blendingEnabled = 0 != (rgba&0x7ff); @@ -1949,31 +1961,36 @@ namespace bgfx { namespace webgpu const uint32_t dst = (rgba>>4)&0xf; const uint32_t equationIndex = (rgba>>8)&0x7; - drt.colorBlend.srcFactor = s_blendFactor[src][0]; - drt.colorBlend.dstFactor = s_blendFactor[dst][0]; - drt.colorBlend.operation = s_blendEquation[equationIndex]; + blend.color.srcFactor = s_blendFactor[src][0]; + blend.color.dstFactor = s_blendFactor[dst][0]; + blend.color.operation = s_blendEquation[equationIndex]; - drt.alphaBlend.srcFactor = s_blendFactor[src][1]; - drt.alphaBlend.dstFactor = s_blendFactor[dst][1]; - drt.alphaBlend.operation = s_blendEquation[equationIndex]; + blend.alpha.srcFactor = s_blendFactor[src][1]; + blend.alpha.dstFactor = s_blendFactor[dst][1]; + blend.alpha.operation = s_blendEquation[equationIndex]; drt.writeMask = writeMask; } } - pd.desc.vertexStage.module = program.m_vsh->m_module; - pd.fragmentStage.module = program.m_fsh != NULL ? program.m_fsh->m_module : wgpu::ShaderModule(); + pd.desc.vertex.module = program.m_vsh->m_module; - setDepthStencilState(pd.depthStencilState, _state, _stencil); + if (NULL != program.m_fsh) + { + pd.fragment.module = program.m_fsh->m_module; + pd.desc.fragment = &pd.fragment; + } + + setDepthStencilState(pd.depthStencil, _state, _stencil); const uint64_t cull = _state & BGFX_STATE_CULL_MASK; const uint8_t cullIndex = uint8_t(cull >> BGFX_STATE_CULL_SHIFT); - pd.rasterizationState.cullMode = s_cullMode[cullIndex]; + pd.desc.primitive.cullMode = s_cullMode[cullIndex]; - pd.rasterizationState.frontFace = (_state & BGFX_STATE_FRONT_CCW) ? wgpu::FrontFace::CCW : wgpu::FrontFace::CW; + pd.desc.primitive.frontFace = (_state & BGFX_STATE_FRONT_CCW) ? wgpu::FrontFace::CCW : wgpu::FrontFace::CW; // pd.desc = m_renderPipelineDescriptor; - pd.desc.sampleCount = sampleCount; + pd.desc.multisample.count = sampleCount; wgpu::PipelineLayoutDescriptor layout = defaultDescriptor(); layout.bindGroupLayouts = &program.m_bindGroupLayout; @@ -1990,17 +2007,18 @@ namespace bgfx { namespace webgpu uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT); PrimInfo prim = s_primInfo[primIndex]; - pd.desc.primitiveTopology = prim.m_type; + pd.desc.primitive.topology = prim.m_type; - VertexStateDescriptor input; - input.desc.vertexBufferCount = 0; + VertexStateDescriptor vertex; + vertex.desc.module = program.m_vsh->m_module; + vertex.desc.bufferCount = 0; - wgpu::VertexBufferLayoutDescriptor* inputBinding = input.vertexBuffers; - wgpu::VertexAttributeDescriptor* inputAttrib = input.attributes; + wgpu::VertexBufferLayout* inputBinding = vertex.buffers; + wgpu::VertexAttribute* inputAttrib = vertex.attributes; auto fillVertexDecl = [&](const ShaderWgpu* _vsh, const VertexLayout& _decl) { - input.desc.vertexBufferCount += 1; + vertex.desc.bufferCount += 1; inputBinding->arrayStride = _decl.m_stride; inputBinding->stepMode = wgpu::InputStepMode::Vertex; @@ -2079,14 +2097,14 @@ namespace bgfx { namespace webgpu Attrib::Enum iiattr = Attrib::Enum(ii); if (0 < unsettedAttr[ii]) { - //uint32_t numAttribs = input.vertexBuffers[stream].attributeCount; + //uint32_t numAttribs = vertexs.buffers[stream].attributeCount; //uint32_t numAttribs = inputBinding->attributeCount; - //wgpu::VertexBufferLayoutDescriptor* inputAttrib = const_cast(_vertexInputState.pVertexAttributeDescriptions + numAttribs); + //wgpu::VertexBufferLayout* inputAttrib = const_cast(_vertexInputState.pVertexAttributeDescriptions + numAttribs); inputAttrib->shaderLocation = program.m_vsh->m_attrRemap[ii]; //inputAttrib->binding = 0; inputAttrib->format = wgpu::VertexFormat::Float3; // VK_FORMAT_R32G32B32_SFLOAT; inputAttrib->offset = 0; - input.vertexBuffers[stream-1].attributeCount++; + vertex.buffers[stream-1].attributeCount++; ++inputAttrib; } } @@ -2097,8 +2115,8 @@ namespace bgfx { namespace webgpu // - bind dummy attributes if (0 < _numInstanceData) { - uint32_t numBindings = input.desc.vertexBufferCount; // == stream+1 // .vertexBindingDescriptionCount; - uint32_t firstAttrib = input.vertexBuffers[stream-1].attributeCount; + uint32_t numBindings = vertex.desc.bufferCount; // == stream+1 // .vertexBindingDescriptionCount; + uint32_t firstAttrib = vertex.buffers[stream-1].attributeCount; uint32_t numAttribs = firstAttrib; inputBinding->arrayStride = _numInstanceData * 16; @@ -2107,29 +2125,29 @@ namespace bgfx { namespace webgpu for (uint32_t inst = 0; inst < _numInstanceData; ++inst) { inputAttrib->shaderLocation = numAttribs; - inputAttrib->format = wgpu::VertexFormat::Float4; + inputAttrib->format = wgpu::VertexFormat::Float32x4; inputAttrib->offset = inst * 16; ++numAttribs; ++inputAttrib; } - input.desc.vertexBufferCount = numBindings + 1; - input.vertexBuffers[stream].attributeCount = numAttribs - firstAttrib; - input.vertexBuffers[stream].attributes = &input.attributes[firstAttrib]; + vertex.desc.bufferCount = numBindings + 1; + vertex.buffers[stream].attributeCount = numAttribs - firstAttrib; + vertex.buffers[stream].attributes = &vertex.attributes[firstAttrib]; } bool isStrip = prim.m_type == wgpu::PrimitiveTopology::LineStrip || prim.m_type == wgpu::PrimitiveTopology::TriangleStrip; if (isStrip) - input.desc.indexFormat = _isIndex16 ? wgpu::IndexFormat::Uint16 : wgpu::IndexFormat::Uint32; + pd.desc.primitive.stripIndexFormat = _isIndex16 ? wgpu::IndexFormat::Uint16 : wgpu::IndexFormat::Uint32; else - input.desc.indexFormat = wgpu::IndexFormat::Undefined; + pd.desc.primitive.stripIndexFormat = wgpu::IndexFormat::Undefined; - pd.desc.vertexState = &input.desc; + pd.desc.vertex = vertex.desc; BX_TRACE("Creating WebGPU render pipeline state for program %s", program.m_vsh->name()); - pso->m_rps = m_device.CreateRenderPipeline(&pd.desc); + pso->m_rps = m_device.CreateRenderPipeline2(&pd.desc); m_pipelineStateCache.add(hash, pso); } @@ -2590,8 +2608,8 @@ namespace bgfx { namespace webgpu case TextureDimension::Dimension1D: return wgpu::TextureViewDimension::e1D; case TextureDimension::Dimension2D: return wgpu::TextureViewDimension::e2D; case TextureDimension::Dimension2DArray: return wgpu::TextureViewDimension::e2DArray; - case TextureDimension::DimensionCube: return wgpu::TextureViewDimension::eCube; - case TextureDimension::DimensionCubeArray: return wgpu::TextureViewDimension::eCubeArray; + case TextureDimension::DimensionCube: return wgpu::TextureViewDimension::Cube; + case TextureDimension::DimensionCubeArray: return wgpu::TextureViewDimension::CubeArray; case TextureDimension::Dimension3D: return wgpu::TextureViewDimension::e3D; default: return wgpu::TextureViewDimension::Undefined; } @@ -2785,14 +2803,16 @@ namespace bgfx { namespace webgpu uint8_t numBindings = 0; - // bind uniform buffer at slot 0 - bindings[numBindings].binding = 0; - bindings[numBindings].visibility = _vsh->m_stage; - bindings[numBindings].buffer.type = wgpu::BufferBindingType::Uniform; - bindings[numBindings].buffer.hasDynamicOffset = true; - numBindings++; + if (_vsh->m_size > 0) + { + bindings[numBindings].binding = 0; + bindings[numBindings].visibility = _vsh->m_stage; + bindings[numBindings].buffer.type = wgpu::BufferBindingType::Uniform; + bindings[numBindings].buffer.hasDynamicOffset = true; + numBindings++; + } - if (m_numUniforms > 1) + if (NULL != _fsh && _fsh->m_size > 0) { bindings[numBindings].binding = 48; bindings[numBindings].visibility = wgpu::ShaderStage::Fragment; @@ -2841,13 +2861,28 @@ namespace bgfx { namespace webgpu m_numSamplers = numSamplers; + uint8_t numBuffers = 0; + for (uint32_t ii = 0; ii < _vsh->m_numBuffers; ++ii) { m_buffers[ii] = _vsh->m_buffers[ii]; bindings[numBindings++] = _vsh->m_buffers[ii]; } - m_numBuffers = _vsh->m_numBuffers; + numBuffers += _vsh->m_numBuffers; + + if (NULL != _fsh) + { + for (uint32_t ii = 0; ii < _fsh->m_numBuffers; ++ii) + { + m_buffers[numBuffers + ii] = _fsh->m_buffers[ii]; + bindings[numBindings++] = _fsh->m_buffers[ii]; + } + + numBuffers += _fsh->m_numBuffers; + } + + m_numBuffers = numBuffers; BX_ASSERT(m_numUniforms + m_numSamplers * 2 + m_numBuffers == numBindings, ""); @@ -3094,7 +3129,7 @@ namespace bgfx { namespace webgpu desc.format = format; desc.size.width = m_width; desc.size.height = m_height; - desc.size.depth = m_numSides * bx::uint32_max(1,imageContainer.m_depth); + desc.size.depthOrArrayLayers = m_numSides * bx::uint32_max(1,imageContainer.m_depth); desc.mipLevelCount = m_numMips; desc.sampleCount = 1; @@ -3271,8 +3306,8 @@ namespace bgfx { namespace webgpu stagingBuffer.Unmap(); } - wgpu::BufferCopyView* bufferCopyView = (wgpu::BufferCopyView*)BX_ALLOC(g_allocator, sizeof(wgpu::BufferCopyView) * numSrd); - wgpu::TextureCopyView* textureCopyView = (wgpu::TextureCopyView*)BX_ALLOC(g_allocator, sizeof(wgpu::TextureCopyView) * numSrd); + wgpu::ImageCopyBuffer* imageCopyBuffer = (wgpu::ImageCopyBuffer*)BX_ALLOC(g_allocator, sizeof(wgpu::ImageCopyBuffer) * numSrd); + wgpu::ImageCopyTexture* imageCopyTexture = (wgpu::ImageCopyTexture*)BX_ALLOC(g_allocator, sizeof(wgpu::ImageCopyTexture) * numSrd); wgpu::Extent3D* textureCopySize = (wgpu::Extent3D*)BX_ALLOC(g_allocator, sizeof(wgpu::Extent3D) * numSrd); uint64_t offset = 0; @@ -3283,16 +3318,16 @@ namespace bgfx { namespace webgpu uint32_t idealWidth = bx::max(1, m_width >> imageInfos[ii].mipLevel); uint32_t idealHeight = bx::max(1, m_height >> imageInfos[ii].mipLevel); - BX_PLACEMENT_NEW(&bufferCopyView[ii], wgpu::BufferCopyView)(); - BX_PLACEMENT_NEW(&textureCopyView[ii], wgpu::TextureCopyView)(); + BX_PLACEMENT_NEW(&imageCopyBuffer[ii], wgpu::ImageCopyBuffer)(); + BX_PLACEMENT_NEW(&imageCopyTexture[ii], wgpu::ImageCopyTexture)(); BX_PLACEMENT_NEW(&textureCopySize[ii], wgpu::Extent3D)(); - bufferCopyView[ii].buffer = stagingBuffer; - bufferCopyView[ii].layout.offset = offset; - bufferCopyView[ii].layout.bytesPerRow = dstpitch; // assume that image data are tightly aligned - bufferCopyView[ii].layout.rowsPerImage = 0; // assume that image data are tightly aligned - textureCopyView[ii].texture = m_ptr; - textureCopyView[ii].mipLevel = imageInfos[ii].mipLevel; - textureCopyView[ii].origin = { 0, 0, imageInfos[ii].layer }; + imageCopyBuffer[ii].buffer = stagingBuffer; + imageCopyBuffer[ii].layout.offset = offset; + imageCopyBuffer[ii].layout.bytesPerRow = dstpitch; // assume that image data are tightly aligned + imageCopyBuffer[ii].layout.rowsPerImage = 0; // assume that image data are tightly aligned + imageCopyTexture[ii].texture = m_ptr; + imageCopyTexture[ii].mipLevel = imageInfos[ii].mipLevel; + imageCopyTexture[ii].origin = { 0, 0, imageInfos[ii].layer }; textureCopySize[ii] = { idealWidth, idealHeight, imageInfos[ii].depth }; offset += dstpitch * imageInfos[ii].height; @@ -3306,7 +3341,7 @@ namespace bgfx { namespace webgpu //wgpu::CommandEncoder encoder = s_renderWgpu->m_cmd.m_encoder; for (uint32_t ii = 0; ii < numSrd; ++ii) { - encoder.CopyBufferToTexture(&bufferCopyView[ii], &textureCopyView[ii], &textureCopySize[ii]); + encoder.CopyBufferToTexture(&imageCopyBuffer[ii], &imageCopyTexture[ii], &textureCopySize[ii]); } } else @@ -3325,8 +3360,8 @@ namespace bgfx { namespace webgpu //vkFreeMemory(device, stagingDeviceMem, allocatorCb); //vkDestroy(stagingBuffer); - BX_FREE(g_allocator, bufferCopyView); - BX_FREE(g_allocator, textureCopyView); + BX_FREE(g_allocator, imageCopyBuffer); + BX_FREE(g_allocator, imageCopyTexture); BX_FREE(g_allocator, textureCopySize); for (uint32_t ii = 0; ii < numSrd; ++ii) { @@ -3385,12 +3420,12 @@ namespace bgfx { namespace webgpu staging.Unmap(); - wgpu::BufferCopyView srcView; + wgpu::ImageCopyBuffer srcView; srcView.buffer = staging; srcView.layout.bytesPerRow = dstpitch; srcView.layout.rowsPerImage = 0; - wgpu::TextureCopyView destView; + wgpu::ImageCopyTexture destView; destView.texture = m_ptr; destView.mipLevel = _mip; destView.origin = { _rect.m_x, _rect.m_y, zz }; @@ -3446,9 +3481,12 @@ namespace bgfx { namespace webgpu auto ready = [](WGPUBufferMapAsyncStatus status, void* userdata) { StagingBufferWgpu* staging = static_cast(userdata); - void* data = staging->m_buffer.GetMappedRange(); + BX_WARN(status == WGPUBufferMapAsyncStatus_Success, "Failed mapping staging buffer (size %d) for writing with error %d", staging->m_size, status); if (status == WGPUBufferMapAsyncStatus_Success) + { + void* data = staging->m_buffer.GetMappedRange(); staging->mapped(data); + } }; m_buffer.MapAsync(wgpu::MapMode::Write, 0, m_size, ready, this); @@ -3664,7 +3702,7 @@ namespace bgfx { namespace webgpu desc.size.width = _width; desc.size.height = _height; - desc.size.depth = 1; + desc.size.depthOrArrayLayers = 1; desc.mipLevelCount = 1; desc.sampleCount = sampleCount; desc.usage = wgpu::TextureUsage::OutputAttachment; @@ -3995,12 +4033,12 @@ namespace bgfx { namespace webgpu bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK); - wgpu::TextureCopyView srcView; + wgpu::ImageCopyTexture srcView; srcView.texture = src.m_ptr; srcView.origin = { blit.m_srcX, blit.m_srcY, blit.m_srcZ }; srcView.mipLevel = blit.m_srcMip; - wgpu::TextureCopyView dstView; + wgpu::ImageCopyTexture dstView; dstView.texture = dst.m_ptr; dstView.origin = { blit.m_dstX, blit.m_dstY, blit.m_dstZ }; dstView.mipLevel = blit.m_dstMip; @@ -4307,11 +4345,11 @@ namespace bgfx { namespace webgpu viewState.setPredefined<4>(this, view, program, _render, compute); - uint32_t numOffset = 1; - uint32_t offsets[2] = { scratchBuffer.m_offset, 0 }; + uint32_t numOffset = 0; + uint32_t offsets[2] = { 0, 0 }; if (program.m_vsh->m_size > 0) { - scratchBuffer.write(m_vsScratch, program.m_vsh->m_gpuSize); + offsets[numOffset++] = scratchBuffer.write(m_vsScratch, program.m_vsh->m_gpuSize); } BindStateWgpu& bindState = allocAndFillBindState(program, bindStates, scratchBuffer, renderBind); diff --git a/src/renderer_webgpu.h b/src/renderer_webgpu.h index 0790031b2..ed91a702e 100644 --- a/src/renderer_webgpu.h +++ b/src/renderer_webgpu.h @@ -227,9 +227,9 @@ namespace bgfx { namespace webgpu { VertexStateDescriptor(); - wgpu::VertexStateDescriptor desc; + wgpu::VertexState desc; - wgpu::VertexBufferLayoutDescriptor vertexBuffers[kMaxVertexInputs]; + wgpu::VertexBufferLayoutDescriptor buffers[kMaxVertexInputs]; wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes]; }; @@ -237,16 +237,13 @@ namespace bgfx { namespace webgpu { RenderPipelineDescriptor(); - wgpu::RenderPipelineDescriptor desc; + wgpu::RenderPipelineDescriptor2 desc; - //wgpu::ProgrammableStageDescriptor vertexStage; - wgpu::ProgrammableStageDescriptor fragmentStage; + wgpu::FragmentState fragment; + wgpu::DepthStencilState depthStencil; - wgpu::VertexStateDescriptor inputState; - - wgpu::RasterizationStateDescriptor rasterizationState; - wgpu::DepthStencilStateDescriptor depthStencilState; - wgpu::ColorStateDescriptor colorStates[kMaxColorAttachments]; + wgpu::ColorTargetState targets[kMaxColorAttachments]; + wgpu::BlendState blends[kMaxColorAttachments]; }; struct BindingsWgpu