Browse Source

WebGPU update (#2477)

* WebGPU: Update to latest changes + Fixes

* WebGPU: Fix RG11B10F format as framebuffer
Hugo Amnov 4 years ago
parent
commit
cf8ff18263
4 changed files with 226 additions and 180 deletions
  1. 2 1
      3rdparty/webgpu/webgpu_cpp.cpp
  2. 29 19
      scripts/bgfx.lua
  3. 188 150
      src/renderer_webgpu.cpp
  4. 7 10
      src/renderer_webgpu.h

+ 2 - 1
3rdparty/webgpu/webgpu_cpp.cpp

@@ -1,4 +1,5 @@
-#include "dawn/webgpu_cpp.h"
+
+#include "webgpu/webgpu_cpp.h"
 
 
 namespace wgpu {
 namespace wgpu {
 
 

+ 29 - 19
scripts/bgfx.lua

@@ -187,7 +187,7 @@ function bgfxProjectBase(_kind, _defines)
 			"BGFX_CONFIG_DEBUG_ANNOTATION=0", -- does not work
 			"BGFX_CONFIG_DEBUG_ANNOTATION=0", -- does not work
 		}
 		}
 
 
-		local generator = "out/Default"
+		local generator = "out/Cmake"
 
 
 		configuration { "wasm*" }
 		configuration { "wasm*" }
 			defines {
 			defines {
@@ -198,10 +198,13 @@ function bgfxProjectBase(_kind, _defines)
 		configuration { "not wasm*" }
 		configuration { "not wasm*" }
 			includedirs {
 			includedirs {
 				path.join(DAWN_DIR, "src/include"),
 				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"),
 				path.join(DAWN_DIR, generator, "gen/src/include"),
 			}
 			}
 
 
+			files {
+				path.join(DAWN_DIR, generator, "gen/src/dawn/webgpu_cpp.cpp"),
+			}
 		configuration { "vs*" }
 		configuration { "vs*" }
 			defines {
 			defines {
 				"NTDDI_VERSION=NTDDI_WIN10_RS2",
 				"NTDDI_VERSION=NTDDI_WIN10_RS2",
@@ -296,7 +299,7 @@ if _OPTIONS["with-webgpu"] then
 			}
 			}
 
 
 		configuration { "not wasm*" }
 		configuration { "not wasm*" }
-			local generator = "out/Default"
+			local generator = "out/Cmake"
 
 
 			includedirs {
 			includedirs {
 				path.join(DAWN_DIR, "src/include"),
 				path.join(DAWN_DIR, "src/include"),
@@ -305,27 +308,34 @@ if _OPTIONS["with-webgpu"] then
 
 
 			libdirs {
 			libdirs {
 				path.join(DAWN_DIR, generator),
 				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 {
 			links {
 				-- shared
 				-- shared
-				"dawn_proc_shared",
-				"dawn_native_shared",
-				"shaderc_spvc_shared",
+				--"dawn_proc_shared",
+				--"dawn_native_shared",
+				--"shaderc_spvc_shared",
 				-- static
 				-- 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",
 				--"spirv-cross-reflectd",
 			}
 			}
 
 

+ 188 - 150
src/renderer_webgpu.cpp

@@ -52,15 +52,15 @@ namespace bgfx { namespace webgpu
 	template <class T>
 	template <class T>
 	T defaultDescriptor() { return T(); }
 	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<wgpu::BlendDescriptor>(), defaultDescriptor<wgpu::BlendDescriptor>(), 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<wgpu::StencilStateFaceDescriptor>(), defaultDescriptor<wgpu::StencilStateFaceDescriptor>(), 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<wgpu::StencilFaceState>(), defaultDescriptor<wgpu::StencilFaceState>(), 0xff, 0xff }; }
 	template <> wgpu::PipelineLayoutDescriptor     defaultDescriptor() { return { NULL, "", 0, NULL }; }
 	template <> wgpu::PipelineLayoutDescriptor     defaultDescriptor() { return { NULL, "", 0, NULL }; }
 	template <> wgpu::TextureViewDescriptor        defaultDescriptor() { return {}; }
 	template <> wgpu::TextureViewDescriptor        defaultDescriptor() { return {}; }
 
 
@@ -86,49 +86,49 @@ namespace bgfx { namespace webgpu
 	{
 	{
 		for(uint32_t i = 0; i < kMaxVertexInputs; ++i)
 		for(uint32_t i = 0; i < kMaxVertexInputs; ++i)
 		{
 		{
-			vertexBuffers[i] = defaultDescriptor<wgpu::VertexBufferLayoutDescriptor>();
+			buffers[i] = defaultDescriptor<wgpu::VertexBufferLayout>();
 		}
 		}
 
 
 		for (uint32_t i = 0; i < kMaxVertexAttributes; ++i)
 		for (uint32_t i = 0; i < kMaxVertexAttributes; ++i)
 		{
 		{
-			attributes[i] = defaultDescriptor<wgpu::VertexAttributeDescriptor>();
+			attributes[i] = defaultDescriptor<wgpu::VertexAttribute>();
 		}
 		}
 
 
-		vertexBuffers[0].attributes = &attributes[0];
-		//vertexBuffers[0].attributeCount = numAttributes;
+		buffers[0].attributes = &attributes[0];
+		//buffers[0].attributeCount = numAttributes;
 
 
-		desc = defaultDescriptor<wgpu::VertexStateDescriptor>();
+		desc = defaultDescriptor<wgpu::VertexState>();
 
 
-		desc.vertexBuffers = vertexBuffers;
+		desc.buffers = buffers;
 		//desc.vertexBufferCount = numVertexBuffers;
 		//desc.vertexBufferCount = numVertexBuffers;
 	}
 	}
 
 
 	RenderPipelineDescriptor::RenderPipelineDescriptor()
 	RenderPipelineDescriptor::RenderPipelineDescriptor()
 	{
 	{
-		//vertexStage = defaultDescriptor<wgpu::ProgrammableStageDescriptor>();
-		fragmentStage = defaultDescriptor<wgpu::ProgrammableStageDescriptor>();
-		rasterizationState = defaultDescriptor<wgpu::RasterizationStateDescriptor>();
-		depthStencilState = defaultDescriptor<wgpu::DepthStencilStateDescriptor>();
+		//vertex = defaultDescriptor<wgpu::VertexState>();
+		fragment = defaultDescriptor<wgpu::FragmentState>();
+		depthStencil = defaultDescriptor<wgpu::DepthStencilState>();
 
 
 		for(uint32_t i = 0; i < kMaxColorAttachments; ++i)
 		for(uint32_t i = 0; i < kMaxColorAttachments; ++i)
 		{
 		{
-			colorStates[i] = defaultDescriptor<wgpu::ColorStateDescriptor>();
+			targets[i] = defaultDescriptor<wgpu::ColorTargetState>();
 		}
 		}
 
 
-		desc = defaultDescriptor<wgpu::RenderPipelineDescriptor>();
+		desc = defaultDescriptor<wgpu::RenderPipelineDescriptor2>();
 
 
-		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();
 		//wgpu::VertexStateDescriptor inputState = inputState.descriptor();
 
 
-		desc.vertexStage = defaultDescriptor<wgpu::ProgrammableStageDescriptor>();
-		desc.fragmentStage = &fragmentStage;
+		desc.vertex = defaultDescriptor<wgpu::VertexState>();
+		desc.fragment = NULL;
 		//desc.vertexState = &inputState;
 		//desc.vertexState = &inputState;
-		desc.rasterizationState = &rasterizationState;
-		desc.depthStencilState = NULL;
-		desc.colorStates = colorStates;
+		desc.primitive = defaultDescriptor<wgpu::PrimitiveState>();
+		desc.depthStencil = NULL;
 	}
 	}
 	// TODO (hugoam) cleanup (end)
 	// TODO (hugoam) cleanup (end)
 
 
@@ -163,34 +163,34 @@ namespace bgfx { namespace webgpu
 	static const wgpu::VertexFormat s_attribType[][4][2] =
 	static const wgpu::VertexFormat s_attribType[][4][2] =
 	{
 	{
 		{ // Uint8
 		{ // 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
 		{ // 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
 		{ // 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
 		{ // 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
 		{ // 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) );
 	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        },  // D16F
 		{ wgpu::TextureFormat::Undefined,           wgpu::TextureFormat::Undefined        },  // D24F
 		{ wgpu::TextureFormat::Undefined,           wgpu::TextureFormat::Undefined        },  // D24F
 		{ wgpu::TextureFormat::Depth32Float,        wgpu::TextureFormat::Undefined        },  // D32F
 		{ 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));
 	BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_textureFormat));
 
 
@@ -498,6 +498,7 @@ namespace bgfx { namespace webgpu
 			desc.forceEnabledToggles.push_back("use_dxc");
 			desc.forceEnabledToggles.push_back("use_dxc");
 #	endif
 #	endif
 
 
+			desc.forceDisabledToggles.push_back("disallow_unsafe_apis");
 
 
 			WGPUDevice backendDevice = backendAdapter.CreateDevice(&desc);
 			WGPUDevice backendDevice = backendAdapter.CreateDevice(&desc);
 			DawnProcTable backendProcs = dawn_native::GetProcs();
 			DawnProcTable backendProcs = dawn_native::GetProcs();
@@ -564,7 +565,7 @@ namespace bgfx { namespace webgpu
 				return false;
 				return false;
 			}
 			}
 
 
-			m_queue = m_device.GetDefaultQueue();
+			m_queue = m_device.GetQueue();
 
 
 			m_cmd.init(m_queue);
 			m_cmd.init(m_queue);
 			//BGFX_FATAL(NULL != m_cmd.m_commandQueue, Fatal::UnableToInitialize, "Unable to create Metal device.");
 			//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_OCCLUSION_QUERY
 				| BGFX_CAPS_SWAP_CHAIN
 				| BGFX_CAPS_SWAP_CHAIN
 				| BGFX_CAPS_TEXTURE_2D_ARRAY
 				| BGFX_CAPS_TEXTURE_2D_ARRAY
-			//	| BGFX_CAPS_TEXTURE_3D
+				| BGFX_CAPS_TEXTURE_3D
 				| BGFX_CAPS_TEXTURE_BLIT
 				| BGFX_CAPS_TEXTURE_BLIT
 				| BGFX_CAPS_TEXTURE_COMPARE_ALL
 				| BGFX_CAPS_TEXTURE_COMPARE_ALL
 				| BGFX_CAPS_TEXTURE_COMPARE_LEQUAL
 				| 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::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::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
 			// disable compressed formats
 			for (uint32_t ii = 0; ii < TextureFormat::Unknown; ++ii)
 			for (uint32_t ii = 0; ii < TextureFormat::Unknown; ++ii)
@@ -873,17 +875,17 @@ namespace bgfx { namespace webgpu
 				readback.m_buffer = m_device.CreateBuffer(&desc);
 				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 };
 			wgpu::Extent3D extent3D = { srcWidth, srcHeight, 1 };
-			getBlitCommandEncoder().CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &extent3D);
+			getBlitCommandEncoder().CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &extent3D);
 
 
 			auto finish = [](WGPUBufferMapAsyncStatus status, void* userdata)
 			auto finish = [](WGPUBufferMapAsyncStatus status, void* userdata)
 			{
 			{
@@ -1313,11 +1315,14 @@ namespace bgfx { namespace webgpu
 			bindState.numOffset = program.m_numUniforms;
 			bindState.numOffset = program.m_numUniforms;
 
 
 			// first two bindings are always uniform buffer (vertex/fragment)
 			// 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
 			if (NULL != program.m_fsh
 			&& 0 < program.m_fsh->m_gpuSize)
 			&& 0 < program.m_fsh->m_gpuSize)
@@ -1735,7 +1740,7 @@ namespace bgfx { namespace webgpu
 			m_rtMsaa = _msaa;
 			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 fstencil = unpackStencil(0, _stencil);
 			const uint32_t func = (_state&BGFX_STATE_DEPTH_TEST_MASK) >> BGFX_STATE_DEPTH_TEST_SHIFT;
 			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;
 			const uint32_t frontAndBack = bstencil != BGFX_STENCIL_NONE && bstencil != fstencil;
 			bstencil = frontAndBack ? bstencil : fstencil;
 			bstencil = frontAndBack ? bstencil : fstencil;
 
 
-			desc.stencilFront = defaultDescriptor<wgpu::StencilStateFaceDescriptor>();
-			desc.stencilBack = defaultDescriptor<wgpu::StencilStateFaceDescriptor>();
+			desc.stencilFront = defaultDescriptor<wgpu::StencilFaceState>();
+			desc.stencilBack = defaultDescriptor<wgpu::StencilFaceState>();
 
 
 			if (0 != _stencil)
 			if (0 != _stencil)
 			{
 			{
@@ -1869,9 +1874,9 @@ namespace bgfx { namespace webgpu
 						? swapChain.m_sampleCount
 						? swapChain.m_sampleCount
 						: 1
 						: 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
 				else
 				{
 				{
@@ -1884,16 +1889,16 @@ namespace bgfx { namespace webgpu
 							? texture.m_sampleCount
 							? texture.m_sampleCount
 							: 1
 							: 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) )
 					if (isValid(frameBuffer.m_depthHandle) )
 					{
 					{
 						const TextureWgpu& texture = m_textures[frameBuffer.m_depthHandle.idx];
 						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)
 				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))
 					if(!(BGFX_STATE_BLEND_MASK & _state))
 					{
 					{
-						drt.colorBlend = defaultDescriptor<wgpu::BlendDescriptor>();
-						drt.alphaBlend = defaultDescriptor<wgpu::BlendDescriptor>();
+						// useless
+						blend.color = defaultDescriptor<wgpu::BlendComponent>();
+						blend.alpha = defaultDescriptor<wgpu::BlendComponent>();
+
+						drt.blend = NULL;
 					}
 					}
 					else
 					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];
+
+						blend.alpha.srcFactor = s_blendFactor[srcA][1];
+						blend.alpha.dstFactor = s_blendFactor[dstA][1];
+						blend.alpha.operation = s_blendEquation[equA];
 
 
-						drt.alphaBlend.srcFactor = s_blendFactor[srcA][1];
-						drt.alphaBlend.dstFactor = s_blendFactor[dstA][1];
-						drt.alphaBlend.operation = s_blendEquation[equA];
+						drt.blend = &blend;
 					}
 					}
 
 
 					drt.writeMask = writeMask;
 					drt.writeMask = writeMask;
@@ -1941,7 +1952,8 @@ namespace bgfx { namespace webgpu
 				{
 				{
 					for (uint32_t ii = 1, rgba = _rgba; ii < frameBufferAttachment; ++ii, rgba >>= 11)
 					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);
 						//drt.blendingEnabled = 0 != (rgba&0x7ff);
 
 
@@ -1949,31 +1961,36 @@ namespace bgfx { namespace webgpu
 						const uint32_t dst           = (rgba>>4)&0xf;
 						const uint32_t dst           = (rgba>>4)&0xf;
 						const uint32_t equationIndex = (rgba>>8)&0x7;
 						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;
 						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;
+
+				if (NULL != program.m_fsh)
+				{
+					pd.fragment.module = program.m_fsh->m_module;
+					pd.desc.fragment = &pd.fragment;
+				}
 
 
-				setDepthStencilState(pd.depthStencilState, _state, _stencil);
+				setDepthStencilState(pd.depthStencil, _state, _stencil);
 
 
 				const uint64_t cull = _state & BGFX_STATE_CULL_MASK;
 				const uint64_t cull = _state & BGFX_STATE_CULL_MASK;
 				const uint8_t cullIndex = uint8_t(cull >> BGFX_STATE_CULL_SHIFT);
 				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 = m_renderPipelineDescriptor;
-				pd.desc.sampleCount = sampleCount;
+				pd.desc.multisample.count = sampleCount;
 
 
 				wgpu::PipelineLayoutDescriptor layout = defaultDescriptor<wgpu::PipelineLayoutDescriptor>();
 				wgpu::PipelineLayoutDescriptor layout = defaultDescriptor<wgpu::PipelineLayoutDescriptor>();
 				layout.bindGroupLayouts = &program.m_bindGroupLayout;
 				layout.bindGroupLayouts = &program.m_bindGroupLayout;
@@ -1990,17 +2007,18 @@ namespace bgfx { namespace webgpu
 				uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT);
 				uint8_t primIndex = uint8_t(primType >> BGFX_STATE_PT_SHIFT);
 
 
 				PrimInfo prim = s_primInfo[primIndex];
 				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)
 				auto fillVertexDecl = [&](const ShaderWgpu* _vsh, const VertexLayout& _decl)
 				{
 				{
-					input.desc.vertexBufferCount += 1;
+					vertex.desc.bufferCount += 1;
 
 
 					inputBinding->arrayStride = _decl.m_stride;
 					inputBinding->arrayStride = _decl.m_stride;
 					inputBinding->stepMode = wgpu::InputStepMode::Vertex;
 					inputBinding->stepMode = wgpu::InputStepMode::Vertex;
@@ -2079,14 +2097,14 @@ namespace bgfx { namespace webgpu
 					Attrib::Enum iiattr = Attrib::Enum(ii);
 					Attrib::Enum iiattr = Attrib::Enum(ii);
 					if (0 < unsettedAttr[ii])
 					if (0 < unsettedAttr[ii])
 					{
 					{
-					  //uint32_t numAttribs = input.vertexBuffers[stream].attributeCount;
+					  //uint32_t numAttribs = vertexs.buffers[stream].attributeCount;
 					  //uint32_t numAttribs = inputBinding->attributeCount;
 					  //uint32_t numAttribs = inputBinding->attributeCount;
-					  //wgpu::VertexBufferLayoutDescriptor* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
+					  //wgpu::VertexBufferLayout* inputAttrib = const_cast<VkVertexInputAttributeDescription*>(_vertexInputState.pVertexAttributeDescriptions + numAttribs);
 						inputAttrib->shaderLocation = program.m_vsh->m_attrRemap[ii];
 						inputAttrib->shaderLocation = program.m_vsh->m_attrRemap[ii];
 					  //inputAttrib->binding = 0;
 					  //inputAttrib->binding = 0;
 						inputAttrib->format = wgpu::VertexFormat::Float3; // VK_FORMAT_R32G32B32_SFLOAT;
 						inputAttrib->format = wgpu::VertexFormat::Float3; // VK_FORMAT_R32G32B32_SFLOAT;
 						inputAttrib->offset = 0;
 						inputAttrib->offset = 0;
-						input.vertexBuffers[stream-1].attributeCount++;
+						vertex.buffers[stream-1].attributeCount++;
 						++inputAttrib;
 						++inputAttrib;
 					}
 					}
 				}
 				}
@@ -2097,8 +2115,8 @@ namespace bgfx { namespace webgpu
 				//   - bind dummy attributes
 				//   - bind dummy attributes
 				if (0 < _numInstanceData)
 				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;
 					uint32_t numAttribs = firstAttrib;
 
 
 					inputBinding->arrayStride = _numInstanceData * 16;
 					inputBinding->arrayStride = _numInstanceData * 16;
@@ -2107,29 +2125,29 @@ namespace bgfx { namespace webgpu
 					for (uint32_t inst = 0; inst < _numInstanceData; ++inst)
 					for (uint32_t inst = 0; inst < _numInstanceData; ++inst)
 					{
 					{
 						inputAttrib->shaderLocation = numAttribs;
 						inputAttrib->shaderLocation = numAttribs;
-						inputAttrib->format = wgpu::VertexFormat::Float4;
+						inputAttrib->format = wgpu::VertexFormat::Float32x4;
 						inputAttrib->offset = inst * 16;
 						inputAttrib->offset = inst * 16;
 
 
 						++numAttribs;
 						++numAttribs;
 						++inputAttrib;
 						++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
 				bool isStrip = prim.m_type == wgpu::PrimitiveTopology::LineStrip
 				 			|| prim.m_type == wgpu::PrimitiveTopology::TriangleStrip;
 				 			|| prim.m_type == wgpu::PrimitiveTopology::TriangleStrip;
 				if (isStrip)
 				if (isStrip)
-					input.desc.indexFormat = _isIndex16 ? wgpu::IndexFormat::Uint16 : wgpu::IndexFormat::Uint32;
+					pd.desc.primitive.stripIndexFormat = _isIndex16 ? wgpu::IndexFormat::Uint16 : wgpu::IndexFormat::Uint32;
 				else
 				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());
 				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);
 				m_pipelineStateCache.add(hash, pso);
 			}
 			}
@@ -2590,8 +2608,8 @@ namespace bgfx { namespace webgpu
 						case TextureDimension::Dimension1D:        return wgpu::TextureViewDimension::e1D;
 						case TextureDimension::Dimension1D:        return wgpu::TextureViewDimension::e1D;
 						case TextureDimension::Dimension2D:        return wgpu::TextureViewDimension::e2D;
 						case TextureDimension::Dimension2D:        return wgpu::TextureViewDimension::e2D;
 						case TextureDimension::Dimension2DArray:   return wgpu::TextureViewDimension::e2DArray;
 						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;
 						case TextureDimension::Dimension3D:        return wgpu::TextureViewDimension::e3D;
 						default:                                   return wgpu::TextureViewDimension::Undefined;
 						default:                                   return wgpu::TextureViewDimension::Undefined;
 						}
 						}
@@ -2785,14 +2803,16 @@ namespace bgfx { namespace webgpu
 
 
 		uint8_t numBindings = 0;
 		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].binding = 48;
 			bindings[numBindings].visibility = wgpu::ShaderStage::Fragment;
 			bindings[numBindings].visibility = wgpu::ShaderStage::Fragment;
@@ -2841,13 +2861,28 @@ namespace bgfx { namespace webgpu
 
 
 		m_numSamplers = numSamplers;
 		m_numSamplers = numSamplers;
 
 
+		uint8_t numBuffers = 0;
+
 		for (uint32_t ii = 0; ii < _vsh->m_numBuffers; ++ii)
 		for (uint32_t ii = 0; ii < _vsh->m_numBuffers; ++ii)
 		{
 		{
 			m_buffers[ii] = _vsh->m_buffers[ii];
 			m_buffers[ii] = _vsh->m_buffers[ii];
 			bindings[numBindings++] = _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, "");
 		BX_ASSERT(m_numUniforms + m_numSamplers * 2 + m_numBuffers == numBindings, "");
 
 
@@ -3094,7 +3129,7 @@ namespace bgfx { namespace webgpu
 			desc.format = format;
 			desc.format = format;
 			desc.size.width  = m_width;
 			desc.size.width  = m_width;
 			desc.size.height = m_height;
 			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.mipLevelCount    = m_numMips;
 			desc.sampleCount      = 1;
 			desc.sampleCount      = 1;
 
 
@@ -3271,8 +3306,8 @@ namespace bgfx { namespace webgpu
 				stagingBuffer.Unmap();
 				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);
 			wgpu::Extent3D* textureCopySize = (wgpu::Extent3D*)BX_ALLOC(g_allocator, sizeof(wgpu::Extent3D) * numSrd);
 
 
 			uint64_t offset = 0;
 			uint64_t offset = 0;
@@ -3283,16 +3318,16 @@ namespace bgfx { namespace webgpu
 
 
 				uint32_t idealWidth  = bx::max<uint32_t>(1, m_width  >> imageInfos[ii].mipLevel);
 				uint32_t idealWidth  = bx::max<uint32_t>(1, m_width  >> imageInfos[ii].mipLevel);
 				uint32_t idealHeight = bx::max<uint32_t>(1, m_height >> imageInfos[ii].mipLevel);
 				uint32_t idealHeight = bx::max<uint32_t>(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)();
 				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 };
 				textureCopySize[ii] = { idealWidth, idealHeight, imageInfos[ii].depth };
 
 
 				offset += dstpitch * imageInfos[ii].height;
 				offset += dstpitch * imageInfos[ii].height;
@@ -3306,7 +3341,7 @@ namespace bgfx { namespace webgpu
 				//wgpu::CommandEncoder encoder = s_renderWgpu->m_cmd.m_encoder;
 				//wgpu::CommandEncoder encoder = s_renderWgpu->m_cmd.m_encoder;
 				for (uint32_t ii = 0; ii < numSrd; ++ii)
 				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
 			else
@@ -3325,8 +3360,8 @@ namespace bgfx { namespace webgpu
 			//vkFreeMemory(device, stagingDeviceMem, allocatorCb);
 			//vkFreeMemory(device, stagingDeviceMem, allocatorCb);
 			//vkDestroy(stagingBuffer);
 			//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);
 			BX_FREE(g_allocator, textureCopySize);
 			for (uint32_t ii = 0; ii < numSrd; ++ii)
 			for (uint32_t ii = 0; ii < numSrd; ++ii)
 			{
 			{
@@ -3385,12 +3420,12 @@ namespace bgfx { namespace webgpu
 
 
 		staging.Unmap();
 		staging.Unmap();
 
 
-		wgpu::BufferCopyView srcView;
+		wgpu::ImageCopyBuffer srcView;
 		srcView.buffer = staging;
 		srcView.buffer = staging;
 		srcView.layout.bytesPerRow = dstpitch;
 		srcView.layout.bytesPerRow = dstpitch;
 		srcView.layout.rowsPerImage = 0;
 		srcView.layout.rowsPerImage = 0;
 
 
-		wgpu::TextureCopyView destView;
+		wgpu::ImageCopyTexture destView;
 		destView.texture = m_ptr;
 		destView.texture = m_ptr;
 		destView.mipLevel = _mip;
 		destView.mipLevel = _mip;
 		destView.origin = { _rect.m_x, _rect.m_y, zz };
 		destView.origin = { _rect.m_x, _rect.m_y, zz };
@@ -3446,9 +3481,12 @@ namespace bgfx { namespace webgpu
 		auto ready = [](WGPUBufferMapAsyncStatus status, void* userdata)
 		auto ready = [](WGPUBufferMapAsyncStatus status, void* userdata)
 		{
 		{
 			StagingBufferWgpu* staging = static_cast<StagingBufferWgpu*>(userdata);
 			StagingBufferWgpu* staging = static_cast<StagingBufferWgpu*>(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)
 			if (status == WGPUBufferMapAsyncStatus_Success)
+			{
+				void* data = staging->m_buffer.GetMappedRange();
 				staging->mapped(data);
 				staging->mapped(data);
+			}
 		};
 		};
 
 
 		m_buffer.MapAsync(wgpu::MapMode::Write, 0, m_size, ready, this);
 		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.width  = _width;
 		desc.size.height = _height;
 		desc.size.height = _height;
-		desc.size.depth  = 1;
+		desc.size.depthOrArrayLayers = 1;
 		desc.mipLevelCount = 1;
 		desc.mipLevelCount = 1;
 		desc.sampleCount = sampleCount;
 		desc.sampleCount = sampleCount;
 		desc.usage = wgpu::TextureUsage::OutputAttachment;
 		desc.usage = wgpu::TextureUsage::OutputAttachment;
@@ -3995,12 +4033,12 @@ namespace bgfx { namespace webgpu
 
 
 			bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK);
 			bool readBack = !!(dst.m_flags & BGFX_TEXTURE_READ_BACK);
 
 
-			wgpu::TextureCopyView srcView;
+			wgpu::ImageCopyTexture srcView;
 			srcView.texture = src.m_ptr;
 			srcView.texture = src.m_ptr;
 			srcView.origin = { blit.m_srcX, blit.m_srcY, blit.m_srcZ };
 			srcView.origin = { blit.m_srcX, blit.m_srcY, blit.m_srcZ };
 			srcView.mipLevel = blit.m_srcMip;
 			srcView.mipLevel = blit.m_srcMip;
 
 
-			wgpu::TextureCopyView dstView;
+			wgpu::ImageCopyTexture dstView;
 			dstView.texture = dst.m_ptr;
 			dstView.texture = dst.m_ptr;
 			dstView.origin = { blit.m_dstX, blit.m_dstY, blit.m_dstZ };
 			dstView.origin = { blit.m_dstX, blit.m_dstY, blit.m_dstZ };
 			dstView.mipLevel = blit.m_dstMip;
 			dstView.mipLevel = blit.m_dstMip;
@@ -4307,11 +4345,11 @@ namespace bgfx { namespace webgpu
 
 
 					viewState.setPredefined<4>(this, view, program, _render, compute);
 					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)
 					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);
 					BindStateWgpu& bindState = allocAndFillBindState(program, bindStates, scratchBuffer, renderBind);

+ 7 - 10
src/renderer_webgpu.h

@@ -227,9 +227,9 @@ namespace bgfx { namespace webgpu
 	{
 	{
 		VertexStateDescriptor();
 		VertexStateDescriptor();
 
 
-		wgpu::VertexStateDescriptor desc;
+		wgpu::VertexState desc;
 
 
-		wgpu::VertexBufferLayoutDescriptor vertexBuffers[kMaxVertexInputs];
+		wgpu::VertexBufferLayoutDescriptor buffers[kMaxVertexInputs];
 		wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
 		wgpu::VertexAttributeDescriptor attributes[kMaxVertexAttributes];
 	};
 	};
 
 
@@ -237,16 +237,13 @@ namespace bgfx { namespace webgpu
 	{
 	{
 		RenderPipelineDescriptor();
 		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
 	struct BindingsWgpu