From bc6d30a2f85443ad76e379c4dcd697660a5dcc9a Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 5 Oct 2021 19:32:34 +0000 Subject: [PATCH] dawn_node: Use IDL default parameter values If the IDL provides a default value for a interface method parameter, then use that default value if no argument is provided. Removes a bunch of std::optional's from the C++ interfaces, and simplifies binding implementations. Also fix some defaults of buffer size from 0 to kWholeSize. This was partially done in an earlier CL, but it seems I missed a few. Bug: dawn:1143 Change-Id: Ifc1bb29a5e7ead42dd015d2333c743165f2459a6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/65663 Commit-Queue: Ben Clayton Reviewed-by: Antonio Maiorano Reviewed-by: Austin Eng --- src/dawn_node/README.md | 1 - src/dawn_node/binding/Converter.h | 5 ++ src/dawn_node/binding/GPU.cpp | 4 +- src/dawn_node/binding/GPU.h | 2 +- src/dawn_node/binding/GPUAdapter.cpp | 42 +++++----- src/dawn_node/binding/GPUAdapter.h | 2 +- src/dawn_node/binding/GPUBuffer.cpp | 21 ++--- src/dawn_node/binding/GPUBuffer.h | 4 +- src/dawn_node/binding/GPUCommandEncoder.cpp | 4 +- src/dawn_node/binding/GPUCommandEncoder.h | 4 +- .../binding/GPUComputePassEncoder.cpp | 30 ++----- src/dawn_node/binding/GPUComputePassEncoder.h | 13 ++- src/dawn_node/binding/GPUDevice.cpp | 36 ++++---- src/dawn_node/binding/GPUDevice.h | 4 +- src/dawn_node/binding/GPUQueue.cpp | 10 +-- src/dawn_node/binding/GPUQueue.h | 2 +- .../binding/GPURenderBundleEncoder.cpp | 83 +++++-------------- .../binding/GPURenderBundleEncoder.h | 29 ++++--- .../binding/GPURenderPassEncoder.cpp | 78 +++++------------ src/dawn_node/binding/GPURenderPassEncoder.h | 27 +++--- src/dawn_node/binding/GPUTexture.cpp | 28 +++---- src/dawn_node/binding/GPUTexture.h | 2 +- src/dawn_node/interop/Core.h | 48 ++++++++++- src/dawn_node/interop/WebGPU.cpp.tmpl | 12 ++- src/dawn_node/interop/WebGPU.h.tmpl | 9 +- 25 files changed, 224 insertions(+), 276 deletions(-) diff --git a/src/dawn_node/README.md b/src/dawn_node/README.md index 1273c85f7c..fe2b6f18e3 100644 --- a/src/dawn_node/README.md +++ b/src/dawn_node/README.md @@ -64,7 +64,6 @@ To test against SwiftShader instead of the default Vulkan device, prefix `./src/ ## Remaining work -- Have the IDL interop generator produce default values for parameters (instead of std::optional). [discussion](https://dawn-review.googlesource.com/c/dawn/+/64912/5/src/dawn_node/binding/GPURenderBundleEncoder.cpp#166) - Investigate CTS failures that are not expected to fail. - Generated includes live in `src/` for `dawn_node`, but outside for Dawn. [discussion](https://dawn-review.googlesource.com/c/dawn/+/64903/9/src/dawn_node/interop/CMakeLists.txt#56) - Hook up to presubmit bots (CQ / Kokoro) diff --git a/src/dawn_node/binding/Converter.h b/src/dawn_node/binding/Converter.h index 812d405590..e499e4fa93 100644 --- a/src/dawn_node/binding/Converter.h +++ b/src/dawn_node/binding/Converter.h @@ -328,6 +328,11 @@ namespace wgpu { namespace binding { // vector -> raw pointer + count template inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::vector& in) { + if (in.size() == 0) { + out_els = nullptr; + out_count = 0; + return true; + } auto* els = Allocate>(in.size()); for (size_t i = 0; i < in.size(); i++) { if (!Convert(els[i], in[i])) { diff --git a/src/dawn_node/binding/GPU.cpp b/src/dawn_node/binding/GPU.cpp index cf22465ec3..2f649786af 100644 --- a/src/dawn_node/binding/GPU.cpp +++ b/src/dawn_node/binding/GPU.cpp @@ -54,11 +54,11 @@ namespace wgpu { namespace binding { interop::Promise>> GPU::requestAdapter( Napi::Env env, - std::optional options) { + interop::GPURequestAdapterOptions options) { auto promise = interop::Promise>>(env); - if (options.has_value() && options->forceFallbackAdapter) { + if (options.forceFallbackAdapter) { // Software adapters are not currently supported. promise.Resolve({}); return promise; diff --git a/src/dawn_node/binding/GPU.h b/src/dawn_node/binding/GPU.h index 55264b24f0..131ce42ad9 100644 --- a/src/dawn_node/binding/GPU.h +++ b/src/dawn_node/binding/GPU.h @@ -30,7 +30,7 @@ namespace wgpu { namespace binding { // interop::GPU interface compliance interop::Promise>> requestAdapter( Napi::Env env, - std::optional options) override; + interop::GPURequestAdapterOptions options) override; private: dawn_native::Instance instance_; diff --git a/src/dawn_node/binding/GPUAdapter.cpp b/src/dawn_node/binding/GPUAdapter.cpp index 81a95e16ee..d7b1d14ce2 100644 --- a/src/dawn_node/binding/GPUAdapter.cpp +++ b/src/dawn_node/binding/GPUAdapter.cpp @@ -101,32 +101,30 @@ namespace wgpu { namespace binding { interop::Promise> GPUAdapter::requestDevice( Napi::Env env, - std::optional descriptor) { + interop::GPUDeviceDescriptor descriptor) { dawn_native::DeviceDescriptor desc{}; // TODO(crbug.com/dawn/1133): Fill in. interop::Promise> promise(env); - if (descriptor.has_value()) { - // See src/dawn_native/Features.cpp for enum <-> string mappings. - for (auto required : descriptor->requiredFeatures) { - switch (required) { - case interop::GPUFeatureName::kDepthClamping: - desc.requiredFeatures.emplace_back("depth_clamping"); - continue; - case interop::GPUFeatureName::kPipelineStatisticsQuery: - desc.requiredFeatures.emplace_back("pipeline_statistics_query"); - continue; - case interop::GPUFeatureName::kTextureCompressionBc: - desc.requiredFeatures.emplace_back("texture_compression_bc"); - continue; - case interop::GPUFeatureName::kTimestampQuery: - desc.requiredFeatures.emplace_back("timestamp_query"); - continue; - case interop::GPUFeatureName::kDepth24UnormStencil8: - case interop::GPUFeatureName::kDepth32FloatStencil8: - continue; // TODO(crbug.com/dawn/1130) - } - UNIMPLEMENTED("required: ", required); + // See src/dawn_native/Features.cpp for enum <-> string mappings. + for (auto required : descriptor.requiredFeatures) { + switch (required) { + case interop::GPUFeatureName::kDepthClamping: + desc.requiredFeatures.emplace_back("depth_clamping"); + continue; + case interop::GPUFeatureName::kPipelineStatisticsQuery: + desc.requiredFeatures.emplace_back("pipeline_statistics_query"); + continue; + case interop::GPUFeatureName::kTextureCompressionBc: + desc.requiredFeatures.emplace_back("texture_compression_bc"); + continue; + case interop::GPUFeatureName::kTimestampQuery: + desc.requiredFeatures.emplace_back("timestamp_query"); + continue; + case interop::GPUFeatureName::kDepth24UnormStencil8: + case interop::GPUFeatureName::kDepth32FloatStencil8: + continue; // TODO(crbug.com/dawn/1130) } + UNIMPLEMENTED("required: ", required); } auto wgpu_device = adapter_.CreateDevice(&desc); diff --git a/src/dawn_node/binding/GPUAdapter.h b/src/dawn_node/binding/GPUAdapter.h index 3140ff8718..1b44f57993 100644 --- a/src/dawn_node/binding/GPUAdapter.h +++ b/src/dawn_node/binding/GPUAdapter.h @@ -34,7 +34,7 @@ namespace wgpu { namespace binding { bool getIsFallbackAdapter(Napi::Env) override; interop::Promise> requestDevice( Napi::Env env, - std::optional descriptor) override; + interop::GPUDeviceDescriptor descriptor) override; private: dawn_native::Adapter adapter_; diff --git a/src/dawn_node/binding/GPUBuffer.cpp b/src/dawn_node/binding/GPUBuffer.cpp index 9921b7280a..ac5ae544b4 100644 --- a/src/dawn_node/binding/GPUBuffer.cpp +++ b/src/dawn_node/binding/GPUBuffer.cpp @@ -42,7 +42,7 @@ namespace wgpu { namespace binding { interop::Promise GPUBuffer::mapAsync(Napi::Env env, interop::GPUMapModeFlags mode, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { wgpu::MapMode md{}; Converter conv(env); @@ -67,16 +67,14 @@ namespace wgpu { namespace binding { auto ctx = new Context{env, interop::Promise(env), async_, state_}; auto promise = ctx->promise; - uint64_t o = offset.has_value() ? offset.value() : 0; - uint64_t s = size.has_value() ? size.value() : (desc_.size - o); + uint64_t s = size.has_value() ? size.value() : (desc_.size - offset); state_ = State::MappingPending; buffer_.MapAsync( - md, o, s, + md, offset, s, [](WGPUBufferMapAsyncStatus status, void* userdata) { auto c = std::unique_ptr(static_cast(userdata)); - c->state = State::Unmapped; switch (status) { case WGPUBufferMapAsyncStatus_Force32: @@ -107,18 +105,17 @@ namespace wgpu { namespace binding { } interop::ArrayBuffer GPUBuffer::getMappedRange(Napi::Env env, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { if (state_ != State::Mapped && state_ != State::MappedAtCreation) { Errors::OperationError(env).ThrowAsJavaScriptException(); return {}; } - uint64_t o = offset.has_value() ? offset.value() : 0; - uint64_t s = size.has_value() ? size.value() : (desc_.size - o); + uint64_t s = size.has_value() ? size.value() : (desc_.size - offset); - uint64_t start = o; - uint64_t end = o + s; + uint64_t start = offset; + uint64_t end = offset + s; for (auto& mapping : mapped_) { if (mapping.Intersects(start, end)) { Errors::OperationError(env).ThrowAsJavaScriptException(); @@ -127,8 +124,8 @@ namespace wgpu { namespace binding { } auto* ptr = (desc_.usage & wgpu::BufferUsage::MapWrite) - ? buffer_.GetMappedRange(o, s) - : const_cast(buffer_.GetConstMappedRange(o, s)); + ? buffer_.GetMappedRange(offset, s) + : const_cast(buffer_.GetConstMappedRange(offset, s)); if (!ptr) { Errors::OperationError(env).ThrowAsJavaScriptException(); return {}; diff --git a/src/dawn_node/binding/GPUBuffer.h b/src/dawn_node/binding/GPUBuffer.h index 0c4d17c8c4..c3d8b03198 100644 --- a/src/dawn_node/binding/GPUBuffer.h +++ b/src/dawn_node/binding/GPUBuffer.h @@ -44,10 +44,10 @@ namespace wgpu { namespace binding { // interop::GPUBuffer interface compliance interop::Promise mapAsync(Napi::Env env, interop::GPUMapModeFlags mode, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; interop::ArrayBuffer getMappedRange(Napi::Env env, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; void unmap(Napi::Env) override; void destroy(Napi::Env) override; diff --git a/src/dawn_node/binding/GPUCommandEncoder.cpp b/src/dawn_node/binding/GPUCommandEncoder.cpp index 533ed21dc9..cf3925c268 100644 --- a/src/dawn_node/binding/GPUCommandEncoder.cpp +++ b/src/dawn_node/binding/GPUCommandEncoder.cpp @@ -50,7 +50,7 @@ namespace wgpu { namespace binding { interop::Interface GPUCommandEncoder::beginComputePass( Napi::Env env, - std::optional descriptor) { + interop::GPUComputePassDescriptor descriptor) { wgpu::ComputePassDescriptor desc{}; return interop::GPUComputePassEncoder::Create( env, enc_.BeginComputePass(&desc)); @@ -180,7 +180,7 @@ namespace wgpu { namespace binding { interop::Interface GPUCommandEncoder::finish( Napi::Env env, - std::optional descriptor) { + interop::GPUCommandBufferDescriptor descriptor) { wgpu::CommandBufferDescriptor desc{}; return interop::GPUCommandBuffer::Create(env, enc_.Finish(&desc)); } diff --git a/src/dawn_node/binding/GPUCommandEncoder.h b/src/dawn_node/binding/GPUCommandEncoder.h index 081032a154..f23e281234 100644 --- a/src/dawn_node/binding/GPUCommandEncoder.h +++ b/src/dawn_node/binding/GPUCommandEncoder.h @@ -34,7 +34,7 @@ namespace wgpu { namespace binding { interop::GPURenderPassDescriptor descriptor) override; interop::Interface beginComputePass( Napi::Env, - std::optional descriptor) override; + interop::GPUComputePassDescriptor descriptor) override; void copyBufferToBuffer(Napi::Env, interop::Interface source, interop::GPUSize64 sourceOffset, @@ -67,7 +67,7 @@ namespace wgpu { namespace binding { interop::GPUSize64 destinationOffset) override; interop::Interface finish( Napi::Env env, - std::optional descriptor) override; + interop::GPUCommandBufferDescriptor descriptor) override; std::optional getLabel(Napi::Env) override; void setLabel(Napi::Env, std::optional value) override; diff --git a/src/dawn_node/binding/GPUComputePassEncoder.cpp b/src/dawn_node/binding/GPUComputePassEncoder.cpp index 4cf3caff48..6edc467ccf 100644 --- a/src/dawn_node/binding/GPUComputePassEncoder.cpp +++ b/src/dawn_node/binding/GPUComputePassEncoder.cpp @@ -38,9 +38,9 @@ namespace wgpu { namespace binding { void GPUComputePassEncoder::dispatch(Napi::Env, interop::GPUSize32 x, - std::optional y, - std::optional z) { - enc_.Dispatch(x, y.value_or(1), z.value_or(1)); + interop::GPUSize32 y, + interop::GPUSize32 z) { + enc_.Dispatch(x, y, z); } void GPUComputePassEncoder::dispatchIndirect( @@ -82,29 +82,17 @@ namespace wgpu { namespace binding { Napi::Env env, interop::GPUIndex32 index, interop::Interface bindGroup, - std::optional> dynamicOffsets) { + std::vector dynamicOffsets) { Converter conv(env); wgpu::BindGroup bg{}; - if (!conv(bg, bindGroup)) { + uint32_t* offsets = nullptr; + uint32_t num_offsets = 0; + if (!conv(bg, bindGroup) || !conv(offsets, num_offsets, dynamicOffsets)) { return; } - std::vector offsets; - if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) { - offsets.resize(dynamicOffsets->size()); - for (size_t i = 0; i < offsets.size(); i++) { - if (!conv(offsets[i], dynamicOffsets.value()[i])) { - return; - } - } - uint32_t offsets_size; - if (!conv(offsets_size, offsets.size())) { - return; - } - enc_.SetBindGroup(index, bg, offsets_size, offsets.data()); - } else { - enc_.SetBindGroup(index, bg); - } + + enc_.SetBindGroup(index, bg, num_offsets, offsets); } void GPUComputePassEncoder::setBindGroup(Napi::Env env, diff --git a/src/dawn_node/binding/GPUComputePassEncoder.h b/src/dawn_node/binding/GPUComputePassEncoder.h index f387ca01f9..9c7064be99 100644 --- a/src/dawn_node/binding/GPUComputePassEncoder.h +++ b/src/dawn_node/binding/GPUComputePassEncoder.h @@ -38,8 +38,8 @@ namespace wgpu { namespace binding { interop::Interface pipeline) override; void dispatch(Napi::Env, interop::GPUSize32 x, - std::optional y, - std::optional z) override; + interop::GPUSize32 y, + interop::GPUSize32 z) override; void dispatchIndirect(Napi::Env, interop::Interface indirectBuffer, interop::GPUSize64 indirectOffset) override; @@ -51,11 +51,10 @@ namespace wgpu { namespace binding { interop::Interface querySet, interop::GPUSize32 queryIndex) override; void endPass(Napi::Env) override; - void setBindGroup( - Napi::Env, - interop::GPUIndex32 index, - interop::Interface bindGroup, - std::optional> dynamicOffsets) override; + void setBindGroup(Napi::Env, + interop::GPUIndex32 index, + interop::Interface bindGroup, + std::vector dynamicOffsets) override; void setBindGroup(Napi::Env, interop::GPUIndex32 index, interop::Interface bindGroup, diff --git a/src/dawn_node/binding/GPUDevice.cpp b/src/dawn_node/binding/GPUDevice.cpp index 21cd40dd8b..73b5e18f4e 100644 --- a/src/dawn_node/binding/GPUDevice.cpp +++ b/src/dawn_node/binding/GPUDevice.cpp @@ -172,28 +172,24 @@ namespace wgpu { namespace binding { interop::Interface GPUDevice::createSampler( Napi::Env env, - std::optional descriptor) { + interop::GPUSamplerDescriptor descriptor) { Converter conv(env); - if (descriptor.has_value()) { - wgpu::SamplerDescriptor desc{}; - if (!conv(desc.label, descriptor->label) || // - !conv(desc.addressModeU, descriptor->addressModeU) || // - !conv(desc.addressModeV, descriptor->addressModeV) || // - !conv(desc.addressModeW, descriptor->addressModeW) || // - !conv(desc.magFilter, descriptor->magFilter) || // - !conv(desc.minFilter, descriptor->minFilter) || // - !conv(desc.mipmapFilter, descriptor->mipmapFilter) || // - !conv(desc.lodMinClamp, descriptor->lodMinClamp) || // - !conv(desc.lodMaxClamp, descriptor->lodMaxClamp) || // - !conv(desc.compare, descriptor->compare) || // - !conv(desc.maxAnisotropy, descriptor->maxAnisotropy)) { - return {}; - } - return interop::GPUSampler::Create(env, device_.CreateSampler(&desc)); + wgpu::SamplerDescriptor desc{}; + if (!conv(desc.label, descriptor.label) || // + !conv(desc.addressModeU, descriptor.addressModeU) || // + !conv(desc.addressModeV, descriptor.addressModeV) || // + !conv(desc.addressModeW, descriptor.addressModeW) || // + !conv(desc.magFilter, descriptor.magFilter) || // + !conv(desc.minFilter, descriptor.minFilter) || // + !conv(desc.mipmapFilter, descriptor.mipmapFilter) || // + !conv(desc.lodMinClamp, descriptor.lodMinClamp) || // + !conv(desc.lodMaxClamp, descriptor.lodMaxClamp) || // + !conv(desc.compare, descriptor.compare) || // + !conv(desc.maxAnisotropy, descriptor.maxAnisotropy)) { + return {}; } - - return interop::GPUSampler::Create(env, device_.CreateSampler()); + return interop::GPUSampler::Create(env, device_.CreateSampler(&desc)); } interop::Interface GPUDevice::importExternalTexture( @@ -374,7 +370,7 @@ namespace wgpu { namespace binding { interop::Interface GPUDevice::createCommandEncoder( Napi::Env env, - std::optional descriptor) { + interop::GPUCommandEncoderDescriptor descriptor) { wgpu::CommandEncoderDescriptor desc{}; return interop::GPUCommandEncoder::Create( env, device_.CreateCommandEncoder(&desc)); diff --git a/src/dawn_node/binding/GPUDevice.h b/src/dawn_node/binding/GPUDevice.h index f04fba8def..a3c5dce31d 100644 --- a/src/dawn_node/binding/GPUDevice.h +++ b/src/dawn_node/binding/GPUDevice.h @@ -40,7 +40,7 @@ namespace wgpu { namespace binding { interop::GPUTextureDescriptor descriptor) override; interop::Interface createSampler( Napi::Env, - std::optional descriptor) override; + interop::GPUSamplerDescriptor descriptor) override; interop::Interface importExternalTexture( Napi::Env, interop::GPUExternalTextureDescriptor descriptor) override; @@ -70,7 +70,7 @@ namespace wgpu { namespace binding { interop::GPURenderPipelineDescriptor descriptor) override; interop::Interface createCommandEncoder( Napi::Env env, - std::optional descriptor) override; + interop::GPUCommandEncoderDescriptor descriptor) override; interop::Interface createRenderBundleEncoder( Napi::Env, interop::GPURenderBundleEncoderDescriptor descriptor) override; diff --git a/src/dawn_node/binding/GPUQueue.cpp b/src/dawn_node/binding/GPUQueue.cpp index 92ad948e7d..c8e39fe23e 100644 --- a/src/dawn_node/binding/GPUQueue.cpp +++ b/src/dawn_node/binding/GPUQueue.cpp @@ -73,7 +73,7 @@ namespace wgpu { namespace binding { interop::Interface buffer, interop::GPUSize64 bufferOffset, interop::BufferSource data, - std::optional dataOffset, + interop::GPUSize64 dataOffset, std::optional size) { wgpu::Buffer buf = *buffer.As(); Converter::BufferSource src{}; @@ -83,12 +83,10 @@ namespace wgpu { namespace binding { } // TODO(crbug.com/dawn/1132): Bounds check - if (dataOffset.has_value()) { - if (src.data) { - src.data = reinterpret_cast(src.data) + dataOffset.value(); - } - src.size -= dataOffset.value(); + if (src.data) { + src.data = reinterpret_cast(src.data) + dataOffset; } + src.size -= dataOffset; if (size.has_value()) { src.size = size.value(); } diff --git a/src/dawn_node/binding/GPUQueue.h b/src/dawn_node/binding/GPUQueue.h index 53751205d4..69952c6dd4 100644 --- a/src/dawn_node/binding/GPUQueue.h +++ b/src/dawn_node/binding/GPUQueue.h @@ -37,7 +37,7 @@ namespace wgpu { namespace binding { interop::Interface buffer, interop::GPUSize64 bufferOffset, interop::BufferSource data, - std::optional dataOffset, + interop::GPUSize64 dataOffset, std::optional size) override; void writeTexture(Napi::Env, interop::GPUImageCopyTexture destination, diff --git a/src/dawn_node/binding/GPURenderBundleEncoder.cpp b/src/dawn_node/binding/GPURenderBundleEncoder.cpp index 796f84bd52..123741d6c4 100644 --- a/src/dawn_node/binding/GPURenderBundleEncoder.cpp +++ b/src/dawn_node/binding/GPURenderBundleEncoder.cpp @@ -32,7 +32,7 @@ namespace wgpu { namespace binding { interop::Interface GPURenderBundleEncoder::finish( Napi::Env env, - std::optional descriptor) { + interop::GPURenderBundleDescriptor descriptor) { wgpu::RenderBundleDescriptor desc{}; return interop::GPURenderBundle::Create(env, enc_.Finish(&desc)); @@ -42,21 +42,17 @@ namespace wgpu { namespace binding { Napi::Env env, interop::GPUIndex32 index, interop::Interface bindGroup, - std::optional> dynamicOffsets) { + std::vector dynamicOffsets) { Converter conv(env); wgpu::BindGroup bg{}; - if (!conv(bg, bindGroup)) { + uint32_t* offsets = nullptr; + uint32_t num_offsets = 0; + if (!conv(bg, bindGroup) || !conv(offsets, num_offsets, dynamicOffsets)) { return; } - uint32_t* offsets = nullptr; - uint32_t offset_count = 0; - if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) { - if (!conv(offsets, offset_count, dynamicOffsets.value())) { - return; - } - } - enc_.SetBindGroup(index, bg, offset_count, offsets); + + enc_.SetBindGroup(index, bg, num_offsets, offsets); } void GPURenderBundleEncoder::setBindGroup(Napi::Env env, @@ -104,14 +100,14 @@ namespace wgpu { namespace binding { void GPURenderBundleEncoder::setIndexBuffer(Napi::Env env, interop::Interface buffer, interop::GPUIndexFormat indexFormat, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { Converter conv(env); wgpu::Buffer b{}; wgpu::IndexFormat f{}; uint64_t o = 0; - uint64_t s = 0; + uint64_t s = wgpu::kWholeSize; if (!conv(b, buffer) || // !conv(f, indexFormat) || // !conv(o, offset) || // @@ -125,68 +121,33 @@ namespace wgpu { namespace binding { void GPURenderBundleEncoder::setVertexBuffer(Napi::Env env, interop::GPUIndex32 slot, interop::Interface buffer, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { Converter conv(env); - uint32_t s = 0; wgpu::Buffer b{}; - uint64_t o = 0; - uint64_t sz = 0; - if (!conv(s, slot) || // - !conv(b, buffer) || // - !conv(o, offset) || // - !conv(sz, size)) { + uint64_t s = wgpu::kWholeSize; + if (!conv(b, buffer) || !conv(s, size)) { return; } - - enc_.SetVertexBuffer(s, b, o, sz); + enc_.SetVertexBuffer(slot, b, offset, s); } void GPURenderBundleEncoder::draw(Napi::Env env, interop::GPUSize32 vertexCount, - std::optional instanceCount, - std::optional firstVertex, - std::optional firstInstance) { - Converter conv(env); - - uint32_t vc = 0; - uint32_t ic = 1; - uint32_t fv = 0; - uint32_t fi = 0; - if (!conv(vc, vertexCount) || // - !conv(ic, instanceCount) || // - !conv(fv, firstVertex) || // - !conv(fi, firstInstance)) { - return; - } - - enc_.Draw(vc, ic, fv, fi); + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstVertex, + interop::GPUSize32 firstInstance) { + enc_.Draw(vertexCount, instanceCount, firstVertex, firstInstance); } void GPURenderBundleEncoder::drawIndexed(Napi::Env env, interop::GPUSize32 indexCount, - std::optional instanceCount, - std::optional firstIndex, - std::optional baseVertex, - std::optional firstInstance) { - Converter conv(env); - - uint32_t idx_c = 0; - uint32_t ins_c = 1; - uint32_t f_idx = 0; - int32_t bv = 0; - uint32_t f_ins = 0; - - if (!conv(idx_c, indexCount) || // - !conv(ins_c, instanceCount) || // - !conv(f_idx, firstIndex) || // - !conv(bv, baseVertex) || // - !conv(f_ins, firstInstance)) { - return; - } - - enc_.DrawIndexed(idx_c, ins_c, f_idx, bv, f_ins); + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstIndex, + interop::GPUSignedOffset32 baseVertex, + interop::GPUSize32 firstInstance) { + enc_.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance); } void GPURenderBundleEncoder::drawIndirect(Napi::Env env, diff --git a/src/dawn_node/binding/GPURenderBundleEncoder.h b/src/dawn_node/binding/GPURenderBundleEncoder.h index e9ee6b2ae8..3d11e330e4 100644 --- a/src/dawn_node/binding/GPURenderBundleEncoder.h +++ b/src/dawn_node/binding/GPURenderBundleEncoder.h @@ -31,12 +31,11 @@ namespace wgpu { namespace binding { // interop::GPURenderBundleEncoder interface compliance interop::Interface finish( Napi::Env, - std::optional descriptor) override; - void setBindGroup( - Napi::Env, - interop::GPUIndex32 index, - interop::Interface bindGroup, - std::optional> dynamicOffsets) override; + interop::GPURenderBundleDescriptor descriptor) override; + void setBindGroup(Napi::Env, + interop::GPUIndex32 index, + interop::Interface bindGroup, + std::vector dynamicOffsets) override; void setBindGroup(Napi::Env, interop::GPUIndex32 index, interop::Interface bindGroup, @@ -51,24 +50,24 @@ namespace wgpu { namespace binding { void setIndexBuffer(Napi::Env, interop::Interface buffer, interop::GPUIndexFormat indexFormat, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; void setVertexBuffer(Napi::Env, interop::GPUIndex32 slot, interop::Interface buffer, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; void draw(Napi::Env, interop::GPUSize32 vertexCount, - std::optional instanceCount, - std::optional firstVertex, - std::optional firstInstance) override; + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstVertex, + interop::GPUSize32 firstInstance) override; void drawIndexed(Napi::Env, interop::GPUSize32 indexCount, - std::optional instanceCount, - std::optional firstIndex, - std::optional baseVertex, - std::optional firstInstance) override; + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstIndex, + interop::GPUSignedOffset32 baseVertex, + interop::GPUSize32 firstInstance) override; void drawIndirect(Napi::Env, interop::Interface indirectBuffer, interop::GPUSize64 indirectOffset) override; diff --git a/src/dawn_node/binding/GPURenderPassEncoder.cpp b/src/dawn_node/binding/GPURenderPassEncoder.cpp index 4e504ae4cc..5dce4f2389 100644 --- a/src/dawn_node/binding/GPURenderPassEncoder.cpp +++ b/src/dawn_node/binding/GPURenderPassEncoder.cpp @@ -117,21 +117,17 @@ namespace wgpu { namespace binding { Napi::Env env, interop::GPUIndex32 index, interop::Interface bindGroup, - std::optional> dynamicOffsets) { + std::vector dynamicOffsets) { Converter conv(env); wgpu::BindGroup bg{}; - if (!conv(bg, bindGroup)) { + uint32_t* offsets = nullptr; + uint32_t num_offsets = 0; + if (!conv(bg, bindGroup) || !conv(offsets, num_offsets, dynamicOffsets)) { return; } - uint32_t* offsets = nullptr; - uint32_t offset_count = 0; - if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) { - if (!conv(offsets, offset_count, dynamicOffsets.value())) { - return; - } - } - enc_.SetBindGroup(index, bg, offset_count, offsets); + + enc_.SetBindGroup(index, bg, num_offsets, offsets); } void GPURenderPassEncoder::setBindGroup(Napi::Env env, @@ -177,85 +173,51 @@ namespace wgpu { namespace binding { void GPURenderPassEncoder::setIndexBuffer(Napi::Env env, interop::Interface buffer, interop::GPUIndexFormat indexFormat, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { Converter conv(env); wgpu::Buffer b{}; wgpu::IndexFormat f; - uint64_t o = 0; uint64_t s = wgpu::kWholeSize; if (!conv(b, buffer) || // !conv(f, indexFormat) || // - !conv(o, offset) || // !conv(s, size)) { return; } - enc_.SetIndexBuffer(b, f, o, s); + enc_.SetIndexBuffer(b, f, offset, s); } void GPURenderPassEncoder::setVertexBuffer(Napi::Env env, interop::GPUIndex32 slot, interop::Interface buffer, - std::optional offset, + interop::GPUSize64 offset, std::optional size) { Converter conv(env); wgpu::Buffer b{}; - uint64_t o = 0; uint64_t s = wgpu::kWholeSize; - if (!conv(b, buffer) || // - !conv(o, offset) || // - !conv(s, size)) { + if (!conv(b, buffer) || !conv(s, size)) { return; } - enc_.SetVertexBuffer(slot, b, o, s); + enc_.SetVertexBuffer(slot, b, offset, s); } void GPURenderPassEncoder::draw(Napi::Env env, interop::GPUSize32 vertexCount, - std::optional instanceCount, - std::optional firstVertex, - std::optional firstInstance) { - Converter conv(env); - - uint32_t vc = 0; - uint32_t ic = 1; - uint32_t fv = 0; - uint32_t fi = 0; - if (!conv(vc, vertexCount) || // - !conv(ic, instanceCount) || // - !conv(fv, firstVertex) || // - !conv(fi, firstInstance)) { - return; - } - - enc_.Draw(vc, ic, fv, fi); + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstVertex, + interop::GPUSize32 firstInstance) { + enc_.Draw(vertexCount, instanceCount, firstVertex, firstInstance); } void GPURenderPassEncoder::drawIndexed(Napi::Env env, interop::GPUSize32 indexCount, - std::optional instanceCount, - std::optional firstIndex, - std::optional baseVertex, - std::optional firstInstance) { - Converter conv(env); - - uint32_t idx_c = 0; - uint32_t ins_c = 1; - uint32_t f_idx = 0; - int32_t bv = 0; - uint32_t f_ins = 0; - - if (!conv(idx_c, indexCount) || // - !conv(ins_c, instanceCount) || // - !conv(f_idx, firstIndex) || // - !conv(bv, baseVertex) || // - !conv(f_ins, firstInstance)) { - return; - } - - enc_.DrawIndexed(idx_c, ins_c, f_idx, bv, f_ins); + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstIndex, + interop::GPUSignedOffset32 baseVertex, + interop::GPUSize32 firstInstance) { + enc_.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance); } void GPURenderPassEncoder::drawIndirect(Napi::Env env, diff --git a/src/dawn_node/binding/GPURenderPassEncoder.h b/src/dawn_node/binding/GPURenderPassEncoder.h index adde06274f..866aaab822 100644 --- a/src/dawn_node/binding/GPURenderPassEncoder.h +++ b/src/dawn_node/binding/GPURenderPassEncoder.h @@ -61,11 +61,10 @@ namespace wgpu { namespace binding { Napi::Env, std::vector> bundles) override; void endPass(Napi::Env) override; - void setBindGroup( - Napi::Env, - interop::GPUIndex32 index, - interop::Interface bindGroup, - std::optional> dynamicOffsets) override; + void setBindGroup(Napi::Env, + interop::GPUIndex32 index, + interop::Interface bindGroup, + std::vector dynamicOffsets) override; void setBindGroup(Napi::Env, interop::GPUIndex32 index, interop::Interface bindGroup, @@ -80,24 +79,24 @@ namespace wgpu { namespace binding { void setIndexBuffer(Napi::Env, interop::Interface buffer, interop::GPUIndexFormat indexFormat, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; void setVertexBuffer(Napi::Env, interop::GPUIndex32 slot, interop::Interface buffer, - std::optional offset, + interop::GPUSize64 offset, std::optional size) override; void draw(Napi::Env, interop::GPUSize32 vertexCount, - std::optional instanceCount, - std::optional firstVertex, - std::optional firstInstance) override; + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstVertex, + interop::GPUSize32 firstInstance) override; void drawIndexed(Napi::Env, interop::GPUSize32 indexCount, - std::optional instanceCount, - std::optional firstIndex, - std::optional baseVertex, - std::optional firstInstance) override; + interop::GPUSize32 instanceCount, + interop::GPUSize32 firstIndex, + interop::GPUSignedOffset32 baseVertex, + interop::GPUSize32 firstInstance) override; void drawIndirect(Napi::Env, interop::Interface indirectBuffer, interop::GPUSize64 indirectOffset) override; diff --git a/src/dawn_node/binding/GPUTexture.cpp b/src/dawn_node/binding/GPUTexture.cpp index 2ebb7850b6..284cd8a91f 100644 --- a/src/dawn_node/binding/GPUTexture.cpp +++ b/src/dawn_node/binding/GPUTexture.cpp @@ -29,28 +29,24 @@ namespace wgpu { namespace binding { interop::Interface GPUTexture::createView( Napi::Env env, - std::optional descriptor) { + interop::GPUTextureViewDescriptor descriptor) { if (!texture_) { Errors::OperationError(env).ThrowAsJavaScriptException(); return {}; } - if (descriptor.has_value()) { - wgpu::TextureViewDescriptor desc{}; - Converter conv(env); - if (!conv(desc.baseMipLevel, descriptor->baseMipLevel) || - !conv(desc.mipLevelCount, descriptor->mipLevelCount) || - !conv(desc.baseArrayLayer, descriptor->baseArrayLayer) || - !conv(desc.arrayLayerCount, descriptor->arrayLayerCount) || - !conv(desc.format, descriptor->format) || - !conv(desc.dimension, descriptor->dimension) || - !conv(desc.aspect, descriptor->aspect)) { - return {}; - } - return interop::GPUTextureView::Create(env, texture_.CreateView(&desc)); + wgpu::TextureViewDescriptor desc{}; + Converter conv(env); + if (!conv(desc.baseMipLevel, descriptor.baseMipLevel) || // + !conv(desc.mipLevelCount, descriptor.mipLevelCount) || // + !conv(desc.baseArrayLayer, descriptor.baseArrayLayer) || // + !conv(desc.arrayLayerCount, descriptor.arrayLayerCount) || // + !conv(desc.format, descriptor.format) || // + !conv(desc.dimension, descriptor.dimension) || // + !conv(desc.aspect, descriptor.aspect)) { + return {}; } - - return interop::GPUTextureView::Create(env, texture_.CreateView()); + return interop::GPUTextureView::Create(env, texture_.CreateView(&desc)); } void GPUTexture::destroy(Napi::Env) { diff --git a/src/dawn_node/binding/GPUTexture.h b/src/dawn_node/binding/GPUTexture.h index 0058d878fb..f5a2a47392 100644 --- a/src/dawn_node/binding/GPUTexture.h +++ b/src/dawn_node/binding/GPUTexture.h @@ -35,7 +35,7 @@ namespace wgpu { namespace binding { // interop::GPUTexture interface compliance interop::Interface createView( Napi::Env, - std::optional descriptor) override; + interop::GPUTextureViewDescriptor descriptor) override; void destroy(Napi::Env) override; std::optional getLabel(Napi::Env) override; void setLabel(Napi::Env, std::optional value) override; diff --git a/src/dawn_node/interop/Core.h b/src/dawn_node/interop/Core.h index 4460f9fdde..e05f0b19b8 100644 --- a/src/dawn_node/interop/Core.h +++ b/src/dawn_node/interop/Core.h @@ -550,16 +550,60 @@ namespace wgpu { namespace interop { env, std::forward(value)); } + // DefaultedParameter can be used in the tuple parameter types passed to + // FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args), for parameters + // that have a default value. If the argument is omitted in the call, then + // DefaultedParameter::default_value will be assigned to + // DefaultedParameter::value. + template + struct DefaultedParameter { + T value; // The argument value assigned by FromJS() + T default_value; // The default value if no argument supplied + + // Implicit conversion operator. Returns value. + inline operator const T&() const { + return value; + } + }; + + // IsDefaultedParameter::value is true iff T is of type DefaultedParameter. + template + struct IsDefaultedParameter { + static constexpr bool value = false; + }; + template + struct IsDefaultedParameter> { + static constexpr bool value = true; + }; + // FromJS() is a helper function for bulk converting the arguments of 'info'. // PARAM_TYPES is a std::tuple<> describing the C++ function parameter types. + // Parameters may be of the templated DefaultedParameter type, in which case + // the parameter will default to the default-value if omitted. // Returns true on success, false on failure. template inline bool FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) { if constexpr (BASE_INDEX < std::tuple_size_v) { using T = std::tuple_element_t; - if (!FromJS(info.Env(), info[BASE_INDEX], std::get(args))) { - return false; + auto& value = info[BASE_INDEX]; + auto& out = std::get(args); + if constexpr (IsDefaultedParameter::value) { + // Parameter has a default value. + // Check whether the argument was provided. + if (value.IsNull() || value.IsUndefined()) { + // Use default value for this parameter + out.value = out.default_value; + } else if (!FromJS(info.Env(), value, out.value)) { + // Argument was provided, but failed to convert. + return false; + } + } else { + // Parameter does not have a default value. + if (!FromJS(info.Env(), value, out)) { + return false; + } } + // Convert the rest of the arguments return FromJS(info, args); } else { return true; diff --git a/src/dawn_node/interop/WebGPU.cpp.tmpl b/src/dawn_node/interop/WebGPU.cpp.tmpl index 0c0dc3fd4a..9ec75c0a7d 100644 --- a/src/dawn_node/interop/WebGPU.cpp.tmpl +++ b/src/dawn_node/interop/WebGPU.cpp.tmpl @@ -181,10 +181,18 @@ Wrappers* Wrappers::instance = nullptr; std::tuple< {{- range $i, $p := $o.Parameters}} {{- if $i}}, {{end}} -{{- if $p.Optional}}std::optional<{{template "Type" $p.Type}}> -{{- else }}{{template "Type" $p.Type}} +{{- if $p.Init }}DefaultedParameter<{{template "Type" $p.Type}}> +{{- else if $p.Optional}}std::optional<{{template "Type" $p.Type}}> +{{- else }}{{template "Type" $p.Type}} {{- end}} {{- end}}> args; + +{{- range $i, $p := $o.Parameters}} +{{- if $p.Init}} + std::get<{{$i}} /* {{$p.Name}} */>(args).default_value = {{Eval "Literal" "Value" $p.Init "Type" $p.Type}}; +{{- end}} +{{- end}} + if (FromJS(info, args)) { {{/* indent */}}INTEROP_LOG( {{- range $i, $p := $o.Parameters}} diff --git a/src/dawn_node/interop/WebGPU.h.tmpl b/src/dawn_node/interop/WebGPU.h.tmpl index 883f33f0bc..e23be0cd49 100644 --- a/src/dawn_node/interop/WebGPU.h.tmpl +++ b/src/dawn_node/interop/WebGPU.h.tmpl @@ -275,9 +275,8 @@ std::ostream& operator<<(std::ostream& o, {{$.Name}}); -------------------------------------------------------------------------------- */ -}} {{- define "Parameter" -}} -{{- if $.Optional -}} -std::optional<{{template "Type" $.Type}}> {{$.Name}} -{{- else}} -{{- template "Type" $.Type}} {{$.Name}} -{{- end}} +{{- if $.Init }}{{template "Type" $.Type}} {{$.Name}} +{{- else if $.Optional}}std::optional<{{template "Type" $.Type}}> {{$.Name}} +{{- else }}{{template "Type" $.Type}} {{$.Name}} +{{- end }} {{- end}}