Dawn/Native: Support SetImmediateData() in Pass Encoders
This CL add SetImmediateData() API to support user upload
immediate data in pass encoders.
Bug:366291600
Change-Id: I6e1e3129383a602baf448790e7837bcf4b5b5671
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/224954
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Shaobo Yan <shaoboyan@microsoft.com>
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index 4f627f9..13c02da 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -1022,6 +1022,14 @@
"args": [
{"name": "label", "type": "string view"}
]
+ },
+ {
+ "name": "set immediate data",
+ "args": [
+ {"name": "offset", "type": "uint32_t"},
+ {"name": "data", "type": "void", "annotation": "const*", "length": "size"},
+ {"name": "size", "type": "size_t"}
+ ]
}
]
},
@@ -2882,6 +2890,14 @@
"args": [
{"name": "label", "type": "string view"}
]
+ },
+ {
+ "name": "set immediate data",
+ "args": [
+ {"name": "offset", "type": "uint32_t"},
+ {"name": "data", "type": "void", "annotation": "const*", "length": "size"},
+ {"name": "size", "type": "size_t"}
+ ]
}
]
},
@@ -3180,6 +3196,14 @@
"args": [
{"name": "label", "type": "string view"}
]
+ },
+ {
+ "name": "set immediate data",
+ "args": [
+ {"name": "offset", "type": "uint32_t"},
+ {"name": "data", "type": "void", "annotation": "const*", "length": "size"},
+ {"name": "size", "type": "size_t"}
+ ]
}
]
},
diff --git a/src/dawn/dawn_wire.json b/src/dawn/dawn_wire.json
index 73b104c..ed464e3 100644
--- a/src/dawn/dawn_wire.json
+++ b/src/dawn/dawn_wire.json
@@ -122,6 +122,24 @@
{ "name": "device object handle", "type": "ObjectHandle", "handle_type": "device"},
{ "name": "device lost future", "type": "future" },
{ "name": "descriptor", "type": "device descriptor", "annotation": "const*" }
+ ],
+ "render pass encoder set immediate data": [
+ { "name": "render pass encoder id", "type": "ObjectId", "id_type": "render pass encoder"},
+ {"name": "offset", "type": "uint32_t"},
+ { "name": "data", "type": "uint8_t", "annotation": "const*", "length": "size", "wire_is_data_only": true},
+ { "name": "size", "type": "size_t"}
+ ],
+ "render bundle encoder set immediate data": [
+ { "name": "render bundle encoder id", "type": "ObjectId", "id_type": "render bundle encoder"},
+ {"name": "offset", "type": "uint32_t"},
+ { "name": "data", "type": "uint8_t", "annotation": "const*", "length": "size", "wire_is_data_only": true},
+ { "name": "size", "type": "size_t"}
+ ],
+ "compute pass encoder set immediate data": [
+ { "name": "compute pass encoder id", "type": "ObjectId", "id_type": "compute pass encoder"},
+ {"name": "offset", "type": "uint32_t"},
+ { "name": "data", "type": "uint8_t", "annotation": "const*", "length": "size", "wire_is_data_only": true},
+ { "name": "size", "type": "size_t"}
]
},
"return commands": {
@@ -259,7 +277,10 @@
"TextureGetSampleCount",
"TextureGetDimension",
"TextureGetFormat",
- "TextureGetUsage"
+ "TextureGetUsage",
+ "RenderPassEncoderSetImmediateData",
+ "RenderBundleEncoderSetImmediateData",
+ "ComputePassEncoderSetImmediateData"
],
"client_handwritten_commands": [
"AdapterGetInstance",
@@ -285,7 +306,10 @@
"ShaderModule",
"Surface",
"SurfaceCapabilities",
- "Texture"
+ "Texture",
+ "RenderPassEncoder",
+ "RenderBundleEncoder",
+ "ComputePassEncoder"
],
"server_custom_pre_handler_commands": [
"BufferDestroy",
diff --git a/src/dawn/native/Commands.cpp b/src/dawn/native/Commands.cpp
index 009388b..4021792 100644
--- a/src/dawn/native/Commands.cpp
+++ b/src/dawn/native/Commands.cpp
@@ -216,6 +216,14 @@
cmd->~SetBindGroupCmd();
break;
}
+ case Command::SetImmediateData: {
+ SetImmediateDataCmd* cmd = commands->NextCommand<SetImmediateDataCmd>();
+ if (cmd->size > 0) {
+ commands->NextData<uint8_t>(cmd->size);
+ }
+ cmd->~SetImmediateDataCmd();
+ break;
+ }
case Command::SetIndexBuffer: {
SetIndexBufferCmd* cmd = commands->NextCommand<SetIndexBufferCmd>();
cmd->~SetIndexBufferCmd();
@@ -384,6 +392,14 @@
break;
}
+ case Command::SetImmediateData: {
+ SetImmediateDataCmd* cmd = commands->NextCommand<SetImmediateDataCmd>();
+ if (cmd->size > 0) {
+ commands->NextData<uint8_t>(cmd->size);
+ }
+ break;
+ }
+
case Command::SetIndexBuffer:
commands->NextCommand<SetIndexBufferCmd>();
break;
@@ -483,6 +499,9 @@
SetBindGroupCmd::SetBindGroupCmd() = default;
SetBindGroupCmd::~SetBindGroupCmd() = default;
+SetImmediateDataCmd::SetImmediateDataCmd() = default;
+SetImmediateDataCmd::~SetImmediateDataCmd() = default;
+
SetIndexBufferCmd::SetIndexBufferCmd() = default;
SetIndexBufferCmd::~SetIndexBufferCmd() = default;
diff --git a/src/dawn/native/Commands.h b/src/dawn/native/Commands.h
index 9b5edbe..b7edeeb 100644
--- a/src/dawn/native/Commands.h
+++ b/src/dawn/native/Commands.h
@@ -83,6 +83,7 @@
SetScissorRect,
SetBlendConstant,
SetBindGroup,
+ SetImmediateData,
SetIndexBuffer,
SetVertexBuffer,
WriteBuffer,
@@ -366,6 +367,14 @@
uint32_t dynamicOffsetCount;
};
+struct SetImmediateDataCmd {
+ SetImmediateDataCmd();
+ ~SetImmediateDataCmd();
+
+ uint64_t offset;
+ uint64_t size;
+};
+
struct SetIndexBufferCmd {
SetIndexBufferCmd();
~SetIndexBufferCmd();
diff --git a/src/dawn/native/ProgrammableEncoder.cpp b/src/dawn/native/ProgrammableEncoder.cpp
index 0956226..c7a2352 100644
--- a/src/dawn/native/ProgrammableEncoder.cpp
+++ b/src/dawn/native/ProgrammableEncoder.cpp
@@ -116,6 +116,51 @@
"encoding %s.PushDebugGroup(%s).", this, groupLabel);
}
+void ProgrammableEncoder::APISetImmediateData(uint32_t offset, const void* data, size_t size) {
+ mEncodingContext->TryEncode(
+ this,
+ [&](CommandAllocator* allocator) -> MaybeError {
+ DAWN_INVALID_IF(!GetDevice()->HasFeature(Feature::ChromiumExperimentalImmediateData),
+ "SetImmediateData() called without "
+ "Feature::ChromiumExperimentalImmediateData supported.");
+
+ if (IsValidationEnabled()) {
+ uint32_t maxImmediateDataRangeByteSize =
+ GetDevice()
+ ->GetLimits()
+ .experimentalImmediateDataLimits.maxImmediateDataRangeByteSize;
+ // Validate offset and size are aligned to 4 bytes.
+ DAWN_INVALID_IF(offset % 4 != 0, "offset (%u) is not a multiple of 4", offset);
+ DAWN_INVALID_IF(size % 4 != 0, "size (%u) is not a multiple of 4", size);
+
+ // Validate OOB
+ DAWN_INVALID_IF(offset > maxImmediateDataRangeByteSize,
+ "offset (%u) is larger than maxImmediateDataRangeByteSize (%u).",
+ offset, maxImmediateDataRangeByteSize);
+ DAWN_INVALID_IF(size > maxImmediateDataRangeByteSize,
+ "size (%u) is larger than maxImmediateDataRangeByteSize (%u).",
+ size, maxImmediateDataRangeByteSize);
+ DAWN_INVALID_IF(
+ size > maxImmediateDataRangeByteSize - offset,
+ "offset (%u) + size (%u): is larger than maxImmediateDataRangeByteSize (%u).",
+ offset, size, maxImmediateDataRangeByteSize);
+ }
+
+ SetImmediateDataCmd* cmd =
+ allocator->Allocate<SetImmediateDataCmd>(Command::SetImmediateData);
+ cmd->offset = offset;
+ cmd->size = size;
+
+ if (size > 0) {
+ uint8_t* immediateDatas = allocator->AllocateData<uint8_t>(cmd->size);
+ memcpy(immediateDatas, data, size);
+ }
+
+ return {};
+ },
+ "encoding %s.SetImmediateData(%u, %u, ...).", this, offset, size);
+}
+
MaybeError ProgrammableEncoder::ValidateSetBindGroup(BindGroupIndex index,
BindGroupBase* group,
uint32_t dynamicOffsetCountIn,
diff --git a/src/dawn/native/ProgrammableEncoder.h b/src/dawn/native/ProgrammableEncoder.h
index 600ac0e..9f37b0f 100644
--- a/src/dawn/native/ProgrammableEncoder.h
+++ b/src/dawn/native/ProgrammableEncoder.h
@@ -51,6 +51,7 @@
void APIInsertDebugMarker(StringView groupLabel);
void APIPopDebugGroup();
void APIPushDebugGroup(StringView groupLabel);
+ void APISetImmediateData(uint32_t offset, const void* data, size_t size);
protected:
bool IsValidationEnabled() const;
diff --git a/src/dawn/native/d3d11/CommandBufferD3D11.cpp b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
index d35d3ac..d9c8097 100644
--- a/src/dawn/native/d3d11/CommandBufferD3D11.cpp
+++ b/src/dawn/native/d3d11/CommandBufferD3D11.cpp
@@ -552,6 +552,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default:
DAWN_UNREACHABLE();
}
@@ -916,6 +919,9 @@
case Command::WriteTimestamp:
return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
DAWN_TRY(DoRenderBundleCommand(&mCommands, type));
}
diff --git a/src/dawn/native/d3d12/CommandBufferD3D12.cpp b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
index 1b99fcc..b0c1af7 100644
--- a/src/dawn/native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn/native/d3d12/CommandBufferD3D12.cpp
@@ -1344,6 +1344,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default:
DAWN_UNREACHABLE();
}
@@ -1870,6 +1873,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
DAWN_TRY(EncodeRenderBundleCommand(&mCommands, type));
break;
diff --git a/src/dawn/native/metal/CommandBufferMTL.mm b/src/dawn/native/metal/CommandBufferMTL.mm
index 749d007..b41d5e0 100644
--- a/src/dawn/native/metal/CommandBufferMTL.mm
+++ b/src/dawn/native/metal/CommandBufferMTL.mm
@@ -1454,6 +1454,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
DAWN_UNREACHABLE();
break;
@@ -1844,6 +1847,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
EncodeRenderBundleCommand(&mCommands, type);
break;
diff --git a/src/dawn/native/null/DeviceNull.cpp b/src/dawn/native/null/DeviceNull.cpp
index 9dd152c..f4d9059 100644
--- a/src/dawn/native/null/DeviceNull.cpp
+++ b/src/dawn/native/null/DeviceNull.cpp
@@ -92,7 +92,8 @@
// Set the subgroups limit, as DeviceNull should support subgroups feature.
limits->experimentalSubgroupLimits.minSubgroupSize = 4;
limits->experimentalSubgroupLimits.maxSubgroupSize = 128;
- limits->experimentalImmediateDataLimits.maxImmediateDataRangeByteSize = 16;
+ limits->experimentalImmediateDataLimits.maxImmediateDataRangeByteSize =
+ kMaxExternalImmediateConstantsPerPipeline * kImmediateConstantElementByteSize;
return {};
}
diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp
index b99934c..4aad721 100644
--- a/src/dawn/native/opengl/CommandBufferGL.cpp
+++ b/src/dawn/native/opengl/CommandBufferGL.cpp
@@ -1016,6 +1016,9 @@
return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default:
DAWN_UNREACHABLE();
}
@@ -1402,6 +1405,9 @@
case Command::WriteTimestamp:
return DAWN_UNIMPLEMENTED_ERROR("WriteTimestamp unimplemented");
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
DoRenderBundleCommand(&mCommands, type);
break;
diff --git a/src/dawn/native/vulkan/CommandBufferVk.cpp b/src/dawn/native/vulkan/CommandBufferVk.cpp
index 67d775f..f66d8a3 100644
--- a/src/dawn/native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn/native/vulkan/CommandBufferVk.cpp
@@ -1207,6 +1207,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default:
DAWN_UNREACHABLE();
}
@@ -1588,6 +1591,9 @@
break;
}
+ case Command::SetImmediateData:
+ return DAWN_UNIMPLEMENTED_ERROR("SetImmediateData unimplemented");
+
default: {
EncodeRenderBundleCommand(&mCommands, type);
break;
diff --git a/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp b/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
index 9e8dcde..f9bdefb 100644
--- a/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
+++ b/src/dawn/tests/unittests/validation/ImmediateDataTests.cpp
@@ -25,6 +25,7 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <cstdint>
#include <limits>
#include <string>
#include <vector>
@@ -36,7 +37,6 @@
namespace dawn {
namespace {
-class PixelLocalStorageDisabledTest : public ValidationTest {};
class ImmediateDataDisableTest : public ValidationTest {};
// Check that creating a PipelineLayout with non-zero immediateDataRangeByteSize is disallowed
@@ -105,5 +105,113 @@
}
}
+// Check that SetImmediateData offset and length must be aligned to 4 bytes.
+TEST_F(ImmediateDataTest, ValidateSetImmediateDataAlignment) {
+ DAWN_SKIP_TEST_IF(!device.HasFeature(wgpu::FeatureName::ChromiumExperimentalImmediateData));
+
+ // Success cases
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint32_t data = 0;
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(0, &data, 4);
+ computePass.End();
+ encoder.Finish();
+ }
+
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(4, nullptr, 0);
+ computePass.End();
+ encoder.Finish();
+ }
+
+ // Failed case with non-aligned offset bytes
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(2, nullptr, 0);
+ computePass.End();
+ ASSERT_DEVICE_ERROR(encoder.Finish());
+ }
+
+ // Failed cases with non-aligned size
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint8_t data = 0;
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(0, &data, 2);
+ computePass.End();
+ ASSERT_DEVICE_ERROR(encoder.Finish());
+ }
+}
+
+// Check that SetImmediateData offset + length must be in bound.
+TEST_F(ImmediateDataTest, ValidateSetImmediateDataOOB) {
+ DAWN_SKIP_TEST_IF(!device.HasFeature(wgpu::FeatureName::ChromiumExperimentalImmediateData));
+
+ uint32_t maxImmediateDataRangeByteSize = GetMaxImmediateDataRangeByteSize();
+
+ // Success cases
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ std::vector<uint32_t> data(maxImmediateDataRangeByteSize / 4, 0);
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(0, data.data(), maxImmediateDataRangeByteSize);
+ computePass.End();
+ encoder.Finish();
+ }
+
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(maxImmediateDataRangeByteSize, nullptr, 0);
+ computePass.End();
+ encoder.Finish();
+ }
+
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint32_t data = 0;
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(maxImmediateDataRangeByteSize - 4, &data, 4);
+ computePass.End();
+ encoder.Finish();
+ }
+
+ // Failed case with offset oob
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint32_t offset = maxImmediateDataRangeByteSize + 4;
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(offset, nullptr, 0);
+ computePass.End();
+ ASSERT_DEVICE_ERROR(encoder.Finish());
+ }
+
+ // Failed cases with size oob
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint32_t size = maxImmediateDataRangeByteSize + 4;
+ std::vector<uint32_t> data(size / 4, 0);
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(0, data.data(), size);
+ computePass.End();
+ ASSERT_DEVICE_ERROR(encoder.Finish());
+ }
+
+ // Failed cases with offset + size oob
+ {
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ uint32_t offset = maxImmediateDataRangeByteSize;
+ uint32_t data[] = {0};
+ wgpu::ComputePassEncoder computePass = encoder.BeginComputePass();
+ computePass.SetImmediateData(offset, data, 4);
+ computePass.End();
+ ASSERT_DEVICE_ERROR(encoder.Finish());
+ }
+}
+
} // anonymous namespace
} // namespace dawn
diff --git a/src/dawn/wire/BUILD.gn b/src/dawn/wire/BUILD.gn
index fd5c870..1fddb75 100644
--- a/src/dawn/wire/BUILD.gn
+++ b/src/dawn/wire/BUILD.gn
@@ -113,6 +113,8 @@
"client/Client.h",
"client/ClientDoers.cpp",
"client/ClientInlineMemoryTransferService.cpp",
+ "client/ComputePassEncoder.cpp",
+ "client/ComputePassEncoder.h",
"client/Device.cpp",
"client/Device.h",
"client/EventManager.cpp",
@@ -129,6 +131,10 @@
"client/QuerySet.h",
"client/Queue.cpp",
"client/Queue.h",
+ "client/RenderBundleEncoder.cpp",
+ "client/RenderBundleEncoder.h",
+ "client/RenderPassEncoder.cpp",
+ "client/RenderPassEncoder.h",
"client/ShaderModule.cpp",
"client/ShaderModule.h",
"client/Surface.cpp",
@@ -143,6 +149,7 @@
"server/ServerDevice.cpp",
"server/ServerInlineMemoryTransferService.cpp",
"server/ServerInstance.cpp",
+ "server/ServerProgrammableEncoder.cpp",
"server/ServerQueue.cpp",
"server/ServerShaderModule.cpp",
"server/ServerSurface.cpp",
diff --git a/src/dawn/wire/CMakeLists.txt b/src/dawn/wire/CMakeLists.txt
index a5c17bc..a652770 100644
--- a/src/dawn/wire/CMakeLists.txt
+++ b/src/dawn/wire/CMakeLists.txt
@@ -48,6 +48,7 @@
"client/Adapter.h"
"client/ApiObjects.h"
"client/Buffer.h"
+ "client/ComputePassEncoder.h"
"client/Client.h"
"client/Device.h"
"client/EventManager.h"
@@ -57,6 +58,8 @@
"client/ObjectStore.h"
"client/QuerySet.h"
"client/Queue.h"
+ "client/RenderBundleEncoder.h"
+ "client/RenderPassEncoder.h"
"client/ShaderModule.h"
"client/Surface.h"
"client/Texture.h"
@@ -74,6 +77,7 @@
"ChunkedCommandSerializer.cpp"
"client/Adapter.cpp"
"client/Buffer.cpp"
+ "client/ComputePassEncoder.cpp"
"client/Client.cpp"
"client/ClientDoers.cpp"
"client/ClientInlineMemoryTransferService.cpp"
@@ -85,6 +89,8 @@
"client/ObjectStore.cpp"
"client/QuerySet.cpp"
"client/Queue.cpp"
+ "client/RenderBundleEncoder.cpp"
+ "client/RenderPassEncoder.cpp"
"client/ShaderModule.cpp"
"client/Surface.cpp"
"client/Texture.cpp"
@@ -95,6 +101,7 @@
"server/ServerDevice.cpp"
"server/ServerInlineMemoryTransferService.cpp"
"server/ServerInstance.cpp"
+ "server/ServerProgrammableEncoder.cpp"
"server/ServerQueue.cpp"
"server/ServerShaderModule.cpp"
"server/ServerSurface.cpp"
diff --git a/src/dawn/wire/client/ApiObjects.h b/src/dawn/wire/client/ApiObjects.h
index 7a71269..4d939a6 100644
--- a/src/dawn/wire/client/ApiObjects.h
+++ b/src/dawn/wire/client/ApiObjects.h
@@ -32,10 +32,13 @@
#include "dawn/wire/client/Adapter.h"
#include "dawn/wire/client/Buffer.h"
+#include "dawn/wire/client/ComputePassEncoder.h"
#include "dawn/wire/client/Device.h"
#include "dawn/wire/client/Instance.h"
#include "dawn/wire/client/QuerySet.h"
#include "dawn/wire/client/Queue.h"
+#include "dawn/wire/client/RenderBundleEncoder.h"
+#include "dawn/wire/client/RenderPassEncoder.h"
#include "dawn/wire/client/ShaderModule.h"
#include "dawn/wire/client/Surface.h"
#include "dawn/wire/client/Texture.h"
diff --git a/src/dawn/wire/client/ComputePassEncoder.cpp b/src/dawn/wire/client/ComputePassEncoder.cpp
new file mode 100644
index 0000000..5681348
--- /dev/null
+++ b/src/dawn/wire/client/ComputePassEncoder.cpp
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/wire/client/ComputePassEncoder.h"
+
+#include "dawn/wire/WireCmd_autogen.h"
+#include "dawn/wire/client/Client.h"
+
+namespace dawn::wire::client {
+ComputePassEncoder::~ComputePassEncoder() = default;
+
+ObjectType ComputePassEncoder::GetObjectType() const {
+ return ObjectType::ComputePassEncoder;
+}
+
+void ComputePassEncoder::SetImmediateData(uint32_t offset, const void* data, size_t size) {
+ ComputePassEncoderSetImmediateDataCmd cmd;
+ cmd.computePassEncoderId = GetWireId();
+ cmd.offset = offset;
+ cmd.data = static_cast<const uint8_t*>(data);
+ cmd.size = size;
+
+ GetClient()->SerializeCommand(cmd);
+}
+
+} // namespace dawn::wire::client
diff --git a/src/dawn/wire/client/ComputePassEncoder.h b/src/dawn/wire/client/ComputePassEncoder.h
new file mode 100644
index 0000000..3563416
--- /dev/null
+++ b/src/dawn/wire/client/ComputePassEncoder.h
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_WIRE_CLIENT_COMPUTE_PASS_ENCODER_H_
+#define SRC_DAWN_WIRE_CLIENT_COMPUTE_PASS_ENCODER_H_
+
+#include <webgpu/webgpu.h>
+
+#include "dawn/wire/WireClient.h"
+#include "dawn/wire/client/ObjectBase.h"
+
+namespace dawn::wire::client {
+
+class ComputePassEncoder : public ObjectBase {
+ public:
+ using ObjectBase::ObjectBase;
+ ~ComputePassEncoder() override;
+ ObjectType GetObjectType() const override;
+
+ // DAWN API
+ void SetImmediateData(uint32_t offset, const void* data, size_t size);
+};
+
+} // namespace dawn::wire::client
+
+#endif // SRC_DAWN_WIRE_CLIENT_COMPUTE_PASS_ENCODER_H_
diff --git a/src/dawn/wire/client/RenderBundleEncoder.cpp b/src/dawn/wire/client/RenderBundleEncoder.cpp
new file mode 100644
index 0000000..54e6da0
--- /dev/null
+++ b/src/dawn/wire/client/RenderBundleEncoder.cpp
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/wire/client/RenderBundleEncoder.h"
+
+#include "dawn/wire/WireCmd_autogen.h"
+#include "dawn/wire/client/Client.h"
+
+namespace dawn::wire::client {
+RenderBundleEncoder::~RenderBundleEncoder() = default;
+
+ObjectType RenderBundleEncoder::GetObjectType() const {
+ return ObjectType::RenderBundleEncoder;
+}
+
+void RenderBundleEncoder::SetImmediateData(uint32_t offset, const void* data, size_t size) {
+ RenderBundleEncoderSetImmediateDataCmd cmd;
+ cmd.renderBundleEncoderId = GetWireId();
+ cmd.offset = offset;
+ cmd.data = static_cast<const uint8_t*>(data);
+ cmd.size = size;
+
+ GetClient()->SerializeCommand(cmd);
+}
+
+} // namespace dawn::wire::client
diff --git a/src/dawn/wire/client/RenderBundleEncoder.h b/src/dawn/wire/client/RenderBundleEncoder.h
new file mode 100644
index 0000000..7ce53b8
--- /dev/null
+++ b/src/dawn/wire/client/RenderBundleEncoder.h
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_WIRE_CLIENT_RENDER_BUNDLE_ENCODER_H_
+#define SRC_DAWN_WIRE_CLIENT_RENDER_BUNDLE_ENCODER_H_
+
+#include <webgpu/webgpu.h>
+
+#include "dawn/wire/WireClient.h"
+#include "dawn/wire/client/ObjectBase.h"
+
+namespace dawn::wire::client {
+
+class RenderBundleEncoder : public ObjectBase {
+ public:
+ using ObjectBase::ObjectBase;
+ ~RenderBundleEncoder() override;
+ ObjectType GetObjectType() const override;
+
+ // DAWN API
+ void SetImmediateData(uint32_t offset, const void* data, size_t size);
+};
+
+} // namespace dawn::wire::client
+
+#endif // SRC_DAWN_WIRE_CLIENT_RENDER_BUNDLE_ENCODER_H_
diff --git a/src/dawn/wire/client/RenderPassEncoder.cpp b/src/dawn/wire/client/RenderPassEncoder.cpp
new file mode 100644
index 0000000..4c9d61e
--- /dev/null
+++ b/src/dawn/wire/client/RenderPassEncoder.cpp
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "dawn/wire/client/RenderPassEncoder.h"
+
+#include "dawn/wire/WireCmd_autogen.h"
+#include "dawn/wire/client/Client.h"
+
+namespace dawn::wire::client {
+RenderPassEncoder::~RenderPassEncoder() = default;
+
+ObjectType RenderPassEncoder::GetObjectType() const {
+ return ObjectType::RenderPassEncoder;
+}
+
+void RenderPassEncoder::SetImmediateData(uint32_t offset, const void* data, size_t size) {
+ RenderPassEncoderSetImmediateDataCmd cmd;
+ cmd.renderPassEncoderId = GetWireId();
+ cmd.offset = offset;
+ cmd.data = static_cast<const uint8_t*>(data);
+ cmd.size = size;
+
+ GetClient()->SerializeCommand(cmd);
+}
+
+} // namespace dawn::wire::client
diff --git a/src/dawn/wire/client/RenderPassEncoder.h b/src/dawn/wire/client/RenderPassEncoder.h
new file mode 100644
index 0000000..e52ee42
--- /dev/null
+++ b/src/dawn/wire/client/RenderPassEncoder.h
@@ -0,0 +1,50 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_DAWN_WIRE_CLIENT_RENDER_PASS_ENCODER_H_
+#define SRC_DAWN_WIRE_CLIENT_RENDER_PASS_ENCODER_H_
+
+#include <webgpu/webgpu.h>
+
+#include "dawn/wire/WireClient.h"
+#include "dawn/wire/client/ObjectBase.h"
+
+namespace dawn::wire::client {
+
+class RenderPassEncoder : public ObjectBase {
+ public:
+ using ObjectBase::ObjectBase;
+ ~RenderPassEncoder() override;
+ ObjectType GetObjectType() const override;
+
+ // DAWN API
+ void SetImmediateData(uint32_t offset, const void* data, size_t size);
+};
+
+} // namespace dawn::wire::client
+
+#endif // SRC_DAWN_WIRE_CLIENT_RENDER_PASS_ENCODER_H_
diff --git a/src/dawn/wire/server/ServerProgrammableEncoder.cpp b/src/dawn/wire/server/ServerProgrammableEncoder.cpp
new file mode 100644
index 0000000..1d4cc55
--- /dev/null
+++ b/src/dawn/wire/server/ServerProgrammableEncoder.cpp
@@ -0,0 +1,65 @@
+// Copyright 2025 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <limits>
+
+#include "dawn/common/Assert.h"
+#include "dawn/wire/server/Server.h"
+
+namespace dawn::wire::server {
+
+WireResult Server::DoRenderPassEncoderSetImmediateData(
+ Known<WGPURenderPassEncoder> renderPassEncoder,
+ uint32_t immediateDataRangeOffsetBytes,
+ const uint8_t* data,
+ size_t size) {
+ mProcs.renderPassEncoderSetImmediateData(renderPassEncoder->handle,
+ immediateDataRangeOffsetBytes, data, size);
+ return WireResult::Success;
+}
+
+WireResult Server::DoRenderBundleEncoderSetImmediateData(
+ Known<WGPURenderBundleEncoder> renderBundleEncoder,
+ uint32_t immediateDataRangeOffsetBytes,
+ const uint8_t* data,
+ size_t size) {
+ mProcs.renderBundleEncoderSetImmediateData(renderBundleEncoder->handle,
+ immediateDataRangeOffsetBytes, data, size);
+ return WireResult::Success;
+}
+
+WireResult Server::DoComputePassEncoderSetImmediateData(
+ Known<WGPUComputePassEncoder> computePassEncoder,
+ uint32_t immediateDataRangeOffsetBytes,
+ const uint8_t* data,
+ size_t size) {
+ mProcs.computePassEncoderSetImmediateData(computePassEncoder->handle,
+ immediateDataRangeOffsetBytes, data, size);
+ return WireResult::Success;
+}
+
+} // namespace dawn::wire::server