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<T>'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 <bclayton@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
Ben Clayton 2021-10-05 19:32:34 +00:00 committed by Dawn LUCI CQ
parent 01c6a44358
commit bc6d30a2f8
25 changed files with 224 additions and 276 deletions

View File

@ -64,7 +64,6 @@ To test against SwiftShader instead of the default Vulkan device, prefix `./src/
## Remaining work ## 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. - 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) - 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) - Hook up to presubmit bots (CQ / Kokoro)

View File

@ -328,6 +328,11 @@ namespace wgpu { namespace binding {
// vector -> raw pointer + count // vector -> raw pointer + count
template <typename OUT, typename IN> template <typename OUT, typename IN>
inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::vector<IN>& in) { inline bool Convert(OUT*& out_els, uint32_t& out_count, const std::vector<IN>& in) {
if (in.size() == 0) {
out_els = nullptr;
out_count = 0;
return true;
}
auto* els = Allocate<std::remove_const_t<OUT>>(in.size()); auto* els = Allocate<std::remove_const_t<OUT>>(in.size());
for (size_t i = 0; i < in.size(); i++) { for (size_t i = 0; i < in.size(); i++) {
if (!Convert(els[i], in[i])) { if (!Convert(els[i], in[i])) {

View File

@ -54,11 +54,11 @@ namespace wgpu { namespace binding {
interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> GPU::requestAdapter( interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> GPU::requestAdapter(
Napi::Env env, Napi::Env env,
std::optional<interop::GPURequestAdapterOptions> options) { interop::GPURequestAdapterOptions options) {
auto promise = auto promise =
interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>>(env); interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>>(env);
if (options.has_value() && options->forceFallbackAdapter) { if (options.forceFallbackAdapter) {
// Software adapters are not currently supported. // Software adapters are not currently supported.
promise.Resolve({}); promise.Resolve({});
return promise; return promise;

View File

@ -30,7 +30,7 @@ namespace wgpu { namespace binding {
// interop::GPU interface compliance // interop::GPU interface compliance
interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> requestAdapter( interop::Promise<std::optional<interop::Interface<interop::GPUAdapter>>> requestAdapter(
Napi::Env env, Napi::Env env,
std::optional<interop::GPURequestAdapterOptions> options) override; interop::GPURequestAdapterOptions options) override;
private: private:
dawn_native::Instance instance_; dawn_native::Instance instance_;

View File

@ -101,32 +101,30 @@ namespace wgpu { namespace binding {
interop::Promise<interop::Interface<interop::GPUDevice>> GPUAdapter::requestDevice( interop::Promise<interop::Interface<interop::GPUDevice>> GPUAdapter::requestDevice(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUDeviceDescriptor> descriptor) { interop::GPUDeviceDescriptor descriptor) {
dawn_native::DeviceDescriptor desc{}; // TODO(crbug.com/dawn/1133): Fill in. dawn_native::DeviceDescriptor desc{}; // TODO(crbug.com/dawn/1133): Fill in.
interop::Promise<interop::Interface<interop::GPUDevice>> promise(env); interop::Promise<interop::Interface<interop::GPUDevice>> promise(env);
if (descriptor.has_value()) { // See src/dawn_native/Features.cpp for enum <-> string mappings.
// See src/dawn_native/Features.cpp for enum <-> string mappings. for (auto required : descriptor.requiredFeatures) {
for (auto required : descriptor->requiredFeatures) { switch (required) {
switch (required) { case interop::GPUFeatureName::kDepthClamping:
case interop::GPUFeatureName::kDepthClamping: desc.requiredFeatures.emplace_back("depth_clamping");
desc.requiredFeatures.emplace_back("depth_clamping"); continue;
continue; case interop::GPUFeatureName::kPipelineStatisticsQuery:
case interop::GPUFeatureName::kPipelineStatisticsQuery: desc.requiredFeatures.emplace_back("pipeline_statistics_query");
desc.requiredFeatures.emplace_back("pipeline_statistics_query"); continue;
continue; case interop::GPUFeatureName::kTextureCompressionBc:
case interop::GPUFeatureName::kTextureCompressionBc: desc.requiredFeatures.emplace_back("texture_compression_bc");
desc.requiredFeatures.emplace_back("texture_compression_bc"); continue;
continue; case interop::GPUFeatureName::kTimestampQuery:
case interop::GPUFeatureName::kTimestampQuery: desc.requiredFeatures.emplace_back("timestamp_query");
desc.requiredFeatures.emplace_back("timestamp_query"); continue;
continue; case interop::GPUFeatureName::kDepth24UnormStencil8:
case interop::GPUFeatureName::kDepth24UnormStencil8: case interop::GPUFeatureName::kDepth32FloatStencil8:
case interop::GPUFeatureName::kDepth32FloatStencil8: continue; // TODO(crbug.com/dawn/1130)
continue; // TODO(crbug.com/dawn/1130)
}
UNIMPLEMENTED("required: ", required);
} }
UNIMPLEMENTED("required: ", required);
} }
auto wgpu_device = adapter_.CreateDevice(&desc); auto wgpu_device = adapter_.CreateDevice(&desc);

View File

@ -34,7 +34,7 @@ namespace wgpu { namespace binding {
bool getIsFallbackAdapter(Napi::Env) override; bool getIsFallbackAdapter(Napi::Env) override;
interop::Promise<interop::Interface<interop::GPUDevice>> requestDevice( interop::Promise<interop::Interface<interop::GPUDevice>> requestDevice(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUDeviceDescriptor> descriptor) override; interop::GPUDeviceDescriptor descriptor) override;
private: private:
dawn_native::Adapter adapter_; dawn_native::Adapter adapter_;

View File

@ -42,7 +42,7 @@ namespace wgpu { namespace binding {
interop::Promise<void> GPUBuffer::mapAsync(Napi::Env env, interop::Promise<void> GPUBuffer::mapAsync(Napi::Env env,
interop::GPUMapModeFlags mode, interop::GPUMapModeFlags mode,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
wgpu::MapMode md{}; wgpu::MapMode md{};
Converter conv(env); Converter conv(env);
@ -67,16 +67,14 @@ namespace wgpu { namespace binding {
auto ctx = new Context{env, interop::Promise<void>(env), async_, state_}; auto ctx = new Context{env, interop::Promise<void>(env), async_, state_};
auto promise = ctx->promise; auto promise = ctx->promise;
uint64_t o = offset.has_value() ? offset.value() : 0; uint64_t s = size.has_value() ? size.value() : (desc_.size - offset);
uint64_t s = size.has_value() ? size.value() : (desc_.size - o);
state_ = State::MappingPending; state_ = State::MappingPending;
buffer_.MapAsync( buffer_.MapAsync(
md, o, s, md, offset, s,
[](WGPUBufferMapAsyncStatus status, void* userdata) { [](WGPUBufferMapAsyncStatus status, void* userdata) {
auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata)); auto c = std::unique_ptr<Context>(static_cast<Context*>(userdata));
c->state = State::Unmapped; c->state = State::Unmapped;
switch (status) { switch (status) {
case WGPUBufferMapAsyncStatus_Force32: case WGPUBufferMapAsyncStatus_Force32:
@ -107,18 +105,17 @@ namespace wgpu { namespace binding {
} }
interop::ArrayBuffer GPUBuffer::getMappedRange(Napi::Env env, interop::ArrayBuffer GPUBuffer::getMappedRange(Napi::Env env,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
if (state_ != State::Mapped && state_ != State::MappedAtCreation) { if (state_ != State::Mapped && state_ != State::MappedAtCreation) {
Errors::OperationError(env).ThrowAsJavaScriptException(); Errors::OperationError(env).ThrowAsJavaScriptException();
return {}; return {};
} }
uint64_t o = offset.has_value() ? offset.value() : 0; uint64_t s = size.has_value() ? size.value() : (desc_.size - offset);
uint64_t s = size.has_value() ? size.value() : (desc_.size - o);
uint64_t start = o; uint64_t start = offset;
uint64_t end = o + s; uint64_t end = offset + s;
for (auto& mapping : mapped_) { for (auto& mapping : mapped_) {
if (mapping.Intersects(start, end)) { if (mapping.Intersects(start, end)) {
Errors::OperationError(env).ThrowAsJavaScriptException(); Errors::OperationError(env).ThrowAsJavaScriptException();
@ -127,8 +124,8 @@ namespace wgpu { namespace binding {
} }
auto* ptr = (desc_.usage & wgpu::BufferUsage::MapWrite) auto* ptr = (desc_.usage & wgpu::BufferUsage::MapWrite)
? buffer_.GetMappedRange(o, s) ? buffer_.GetMappedRange(offset, s)
: const_cast<void*>(buffer_.GetConstMappedRange(o, s)); : const_cast<void*>(buffer_.GetConstMappedRange(offset, s));
if (!ptr) { if (!ptr) {
Errors::OperationError(env).ThrowAsJavaScriptException(); Errors::OperationError(env).ThrowAsJavaScriptException();
return {}; return {};

View File

@ -44,10 +44,10 @@ namespace wgpu { namespace binding {
// interop::GPUBuffer interface compliance // interop::GPUBuffer interface compliance
interop::Promise<void> mapAsync(Napi::Env env, interop::Promise<void> mapAsync(Napi::Env env,
interop::GPUMapModeFlags mode, interop::GPUMapModeFlags mode,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
interop::ArrayBuffer getMappedRange(Napi::Env env, interop::ArrayBuffer getMappedRange(Napi::Env env,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void unmap(Napi::Env) override; void unmap(Napi::Env) override;
void destroy(Napi::Env) override; void destroy(Napi::Env) override;

View File

@ -50,7 +50,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUComputePassEncoder> GPUCommandEncoder::beginComputePass( interop::Interface<interop::GPUComputePassEncoder> GPUCommandEncoder::beginComputePass(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUComputePassDescriptor> descriptor) { interop::GPUComputePassDescriptor descriptor) {
wgpu::ComputePassDescriptor desc{}; wgpu::ComputePassDescriptor desc{};
return interop::GPUComputePassEncoder::Create<GPUComputePassEncoder>( return interop::GPUComputePassEncoder::Create<GPUComputePassEncoder>(
env, enc_.BeginComputePass(&desc)); env, enc_.BeginComputePass(&desc));
@ -180,7 +180,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUCommandBuffer> GPUCommandEncoder::finish( interop::Interface<interop::GPUCommandBuffer> GPUCommandEncoder::finish(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUCommandBufferDescriptor> descriptor) { interop::GPUCommandBufferDescriptor descriptor) {
wgpu::CommandBufferDescriptor desc{}; wgpu::CommandBufferDescriptor desc{};
return interop::GPUCommandBuffer::Create<GPUCommandBuffer>(env, enc_.Finish(&desc)); return interop::GPUCommandBuffer::Create<GPUCommandBuffer>(env, enc_.Finish(&desc));
} }

View File

@ -34,7 +34,7 @@ namespace wgpu { namespace binding {
interop::GPURenderPassDescriptor descriptor) override; interop::GPURenderPassDescriptor descriptor) override;
interop::Interface<interop::GPUComputePassEncoder> beginComputePass( interop::Interface<interop::GPUComputePassEncoder> beginComputePass(
Napi::Env, Napi::Env,
std::optional<interop::GPUComputePassDescriptor> descriptor) override; interop::GPUComputePassDescriptor descriptor) override;
void copyBufferToBuffer(Napi::Env, void copyBufferToBuffer(Napi::Env,
interop::Interface<interop::GPUBuffer> source, interop::Interface<interop::GPUBuffer> source,
interop::GPUSize64 sourceOffset, interop::GPUSize64 sourceOffset,
@ -67,7 +67,7 @@ namespace wgpu { namespace binding {
interop::GPUSize64 destinationOffset) override; interop::GPUSize64 destinationOffset) override;
interop::Interface<interop::GPUCommandBuffer> finish( interop::Interface<interop::GPUCommandBuffer> finish(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUCommandBufferDescriptor> descriptor) override; interop::GPUCommandBufferDescriptor descriptor) override;
std::optional<std::string> getLabel(Napi::Env) override; std::optional<std::string> getLabel(Napi::Env) override;
void setLabel(Napi::Env, std::optional<std::string> value) override; void setLabel(Napi::Env, std::optional<std::string> value) override;

View File

@ -38,9 +38,9 @@ namespace wgpu { namespace binding {
void GPUComputePassEncoder::dispatch(Napi::Env, void GPUComputePassEncoder::dispatch(Napi::Env,
interop::GPUSize32 x, interop::GPUSize32 x,
std::optional<interop::GPUSize32> y, interop::GPUSize32 y,
std::optional<interop::GPUSize32> z) { interop::GPUSize32 z) {
enc_.Dispatch(x, y.value_or(1), z.value_or(1)); enc_.Dispatch(x, y, z);
} }
void GPUComputePassEncoder::dispatchIndirect( void GPUComputePassEncoder::dispatchIndirect(
@ -82,29 +82,17 @@ namespace wgpu { namespace binding {
Napi::Env env, Napi::Env env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) { std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) {
Converter conv(env); Converter conv(env);
wgpu::BindGroup bg{}; 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; return;
} }
std::vector<uint32_t> offsets;
if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) { enc_.SetBindGroup(index, bg, num_offsets, offsets);
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);
}
} }
void GPUComputePassEncoder::setBindGroup(Napi::Env env, void GPUComputePassEncoder::setBindGroup(Napi::Env env,

View File

@ -38,8 +38,8 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUComputePipeline> pipeline) override; interop::Interface<interop::GPUComputePipeline> pipeline) override;
void dispatch(Napi::Env, void dispatch(Napi::Env,
interop::GPUSize32 x, interop::GPUSize32 x,
std::optional<interop::GPUSize32> y, interop::GPUSize32 y,
std::optional<interop::GPUSize32> z) override; interop::GPUSize32 z) override;
void dispatchIndirect(Napi::Env, void dispatchIndirect(Napi::Env,
interop::Interface<interop::GPUBuffer> indirectBuffer, interop::Interface<interop::GPUBuffer> indirectBuffer,
interop::GPUSize64 indirectOffset) override; interop::GPUSize64 indirectOffset) override;
@ -51,11 +51,10 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUQuerySet> querySet, interop::Interface<interop::GPUQuerySet> querySet,
interop::GPUSize32 queryIndex) override; interop::GPUSize32 queryIndex) override;
void endPass(Napi::Env) override; void endPass(Napi::Env) override;
void setBindGroup( void setBindGroup(Napi::Env,
Napi::Env, interop::GPUIndex32 index,
interop::GPUIndex32 index, interop::Interface<interop::GPUBindGroup> bindGroup,
interop::Interface<interop::GPUBindGroup> bindGroup, std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) override;
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) override;
void setBindGroup(Napi::Env, void setBindGroup(Napi::Env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,

View File

@ -172,28 +172,24 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUSampler> GPUDevice::createSampler( interop::Interface<interop::GPUSampler> GPUDevice::createSampler(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUSamplerDescriptor> descriptor) { interop::GPUSamplerDescriptor descriptor) {
Converter conv(env); Converter conv(env);
if (descriptor.has_value()) { wgpu::SamplerDescriptor desc{};
wgpu::SamplerDescriptor desc{}; if (!conv(desc.label, descriptor.label) || //
if (!conv(desc.label, descriptor->label) || // !conv(desc.addressModeU, descriptor.addressModeU) || //
!conv(desc.addressModeU, descriptor->addressModeU) || // !conv(desc.addressModeV, descriptor.addressModeV) || //
!conv(desc.addressModeV, descriptor->addressModeV) || // !conv(desc.addressModeW, descriptor.addressModeW) || //
!conv(desc.addressModeW, descriptor->addressModeW) || // !conv(desc.magFilter, descriptor.magFilter) || //
!conv(desc.magFilter, descriptor->magFilter) || // !conv(desc.minFilter, descriptor.minFilter) || //
!conv(desc.minFilter, descriptor->minFilter) || // !conv(desc.mipmapFilter, descriptor.mipmapFilter) || //
!conv(desc.mipmapFilter, descriptor->mipmapFilter) || // !conv(desc.lodMinClamp, descriptor.lodMinClamp) || //
!conv(desc.lodMinClamp, descriptor->lodMinClamp) || // !conv(desc.lodMaxClamp, descriptor.lodMaxClamp) || //
!conv(desc.lodMaxClamp, descriptor->lodMaxClamp) || // !conv(desc.compare, descriptor.compare) || //
!conv(desc.compare, descriptor->compare) || // !conv(desc.maxAnisotropy, descriptor.maxAnisotropy)) {
!conv(desc.maxAnisotropy, descriptor->maxAnisotropy)) { return {};
return {};
}
return interop::GPUSampler::Create<GPUSampler>(env, device_.CreateSampler(&desc));
} }
return interop::GPUSampler::Create<GPUSampler>(env, device_.CreateSampler(&desc));
return interop::GPUSampler::Create<GPUSampler>(env, device_.CreateSampler());
} }
interop::Interface<interop::GPUExternalTexture> GPUDevice::importExternalTexture( interop::Interface<interop::GPUExternalTexture> GPUDevice::importExternalTexture(
@ -374,7 +370,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUCommandEncoder> GPUDevice::createCommandEncoder( interop::Interface<interop::GPUCommandEncoder> GPUDevice::createCommandEncoder(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUCommandEncoderDescriptor> descriptor) { interop::GPUCommandEncoderDescriptor descriptor) {
wgpu::CommandEncoderDescriptor desc{}; wgpu::CommandEncoderDescriptor desc{};
return interop::GPUCommandEncoder::Create<GPUCommandEncoder>( return interop::GPUCommandEncoder::Create<GPUCommandEncoder>(
env, device_.CreateCommandEncoder(&desc)); env, device_.CreateCommandEncoder(&desc));

View File

@ -40,7 +40,7 @@ namespace wgpu { namespace binding {
interop::GPUTextureDescriptor descriptor) override; interop::GPUTextureDescriptor descriptor) override;
interop::Interface<interop::GPUSampler> createSampler( interop::Interface<interop::GPUSampler> createSampler(
Napi::Env, Napi::Env,
std::optional<interop::GPUSamplerDescriptor> descriptor) override; interop::GPUSamplerDescriptor descriptor) override;
interop::Interface<interop::GPUExternalTexture> importExternalTexture( interop::Interface<interop::GPUExternalTexture> importExternalTexture(
Napi::Env, Napi::Env,
interop::GPUExternalTextureDescriptor descriptor) override; interop::GPUExternalTextureDescriptor descriptor) override;
@ -70,7 +70,7 @@ namespace wgpu { namespace binding {
interop::GPURenderPipelineDescriptor descriptor) override; interop::GPURenderPipelineDescriptor descriptor) override;
interop::Interface<interop::GPUCommandEncoder> createCommandEncoder( interop::Interface<interop::GPUCommandEncoder> createCommandEncoder(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUCommandEncoderDescriptor> descriptor) override; interop::GPUCommandEncoderDescriptor descriptor) override;
interop::Interface<interop::GPURenderBundleEncoder> createRenderBundleEncoder( interop::Interface<interop::GPURenderBundleEncoder> createRenderBundleEncoder(
Napi::Env, Napi::Env,
interop::GPURenderBundleEncoderDescriptor descriptor) override; interop::GPURenderBundleEncoderDescriptor descriptor) override;

View File

@ -73,7 +73,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUSize64 bufferOffset, interop::GPUSize64 bufferOffset,
interop::BufferSource data, interop::BufferSource data,
std::optional<interop::GPUSize64> dataOffset, interop::GPUSize64 dataOffset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
wgpu::Buffer buf = *buffer.As<GPUBuffer>(); wgpu::Buffer buf = *buffer.As<GPUBuffer>();
Converter::BufferSource src{}; Converter::BufferSource src{};
@ -83,12 +83,10 @@ namespace wgpu { namespace binding {
} }
// TODO(crbug.com/dawn/1132): Bounds check // TODO(crbug.com/dawn/1132): Bounds check
if (dataOffset.has_value()) { if (src.data) {
if (src.data) { src.data = reinterpret_cast<uint8_t*>(src.data) + dataOffset;
src.data = reinterpret_cast<uint8_t*>(src.data) + dataOffset.value();
}
src.size -= dataOffset.value();
} }
src.size -= dataOffset;
if (size.has_value()) { if (size.has_value()) {
src.size = size.value(); src.size = size.value();
} }

View File

@ -37,7 +37,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUSize64 bufferOffset, interop::GPUSize64 bufferOffset,
interop::BufferSource data, interop::BufferSource data,
std::optional<interop::GPUSize64> dataOffset, interop::GPUSize64 dataOffset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void writeTexture(Napi::Env, void writeTexture(Napi::Env,
interop::GPUImageCopyTexture destination, interop::GPUImageCopyTexture destination,

View File

@ -32,7 +32,7 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPURenderBundle> GPURenderBundleEncoder::finish( interop::Interface<interop::GPURenderBundle> GPURenderBundleEncoder::finish(
Napi::Env env, Napi::Env env,
std::optional<interop::GPURenderBundleDescriptor> descriptor) { interop::GPURenderBundleDescriptor descriptor) {
wgpu::RenderBundleDescriptor desc{}; wgpu::RenderBundleDescriptor desc{};
return interop::GPURenderBundle::Create<GPURenderBundle>(env, enc_.Finish(&desc)); return interop::GPURenderBundle::Create<GPURenderBundle>(env, enc_.Finish(&desc));
@ -42,21 +42,17 @@ namespace wgpu { namespace binding {
Napi::Env env, Napi::Env env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) { std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) {
Converter conv(env); Converter conv(env);
wgpu::BindGroup bg{}; 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; return;
} }
uint32_t* offsets = nullptr;
uint32_t offset_count = 0; enc_.SetBindGroup(index, bg, num_offsets, offsets);
if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) {
if (!conv(offsets, offset_count, dynamicOffsets.value())) {
return;
}
}
enc_.SetBindGroup(index, bg, offset_count, offsets);
} }
void GPURenderBundleEncoder::setBindGroup(Napi::Env env, void GPURenderBundleEncoder::setBindGroup(Napi::Env env,
@ -104,14 +100,14 @@ namespace wgpu { namespace binding {
void GPURenderBundleEncoder::setIndexBuffer(Napi::Env env, void GPURenderBundleEncoder::setIndexBuffer(Napi::Env env,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUIndexFormat indexFormat, interop::GPUIndexFormat indexFormat,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
Converter conv(env); Converter conv(env);
wgpu::Buffer b{}; wgpu::Buffer b{};
wgpu::IndexFormat f{}; wgpu::IndexFormat f{};
uint64_t o = 0; uint64_t o = 0;
uint64_t s = 0; uint64_t s = wgpu::kWholeSize;
if (!conv(b, buffer) || // if (!conv(b, buffer) || //
!conv(f, indexFormat) || // !conv(f, indexFormat) || //
!conv(o, offset) || // !conv(o, offset) || //
@ -125,68 +121,33 @@ namespace wgpu { namespace binding {
void GPURenderBundleEncoder::setVertexBuffer(Napi::Env env, void GPURenderBundleEncoder::setVertexBuffer(Napi::Env env,
interop::GPUIndex32 slot, interop::GPUIndex32 slot,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
Converter conv(env); Converter conv(env);
uint32_t s = 0;
wgpu::Buffer b{}; wgpu::Buffer b{};
uint64_t o = 0; uint64_t s = wgpu::kWholeSize;
uint64_t sz = 0; if (!conv(b, buffer) || !conv(s, size)) {
if (!conv(s, slot) || //
!conv(b, buffer) || //
!conv(o, offset) || //
!conv(sz, size)) {
return; return;
} }
enc_.SetVertexBuffer(slot, b, offset, s);
enc_.SetVertexBuffer(s, b, o, sz);
} }
void GPURenderBundleEncoder::draw(Napi::Env env, void GPURenderBundleEncoder::draw(Napi::Env env,
interop::GPUSize32 vertexCount, interop::GPUSize32 vertexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstVertex, interop::GPUSize32 firstVertex,
std::optional<interop::GPUSize32> firstInstance) { interop::GPUSize32 firstInstance) {
Converter conv(env); enc_.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
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);
} }
void GPURenderBundleEncoder::drawIndexed(Napi::Env env, void GPURenderBundleEncoder::drawIndexed(Napi::Env env,
interop::GPUSize32 indexCount, interop::GPUSize32 indexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstIndex, interop::GPUSize32 firstIndex,
std::optional<interop::GPUSignedOffset32> baseVertex, interop::GPUSignedOffset32 baseVertex,
std::optional<interop::GPUSize32> firstInstance) { interop::GPUSize32 firstInstance) {
Converter conv(env); enc_.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
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);
} }
void GPURenderBundleEncoder::drawIndirect(Napi::Env env, void GPURenderBundleEncoder::drawIndirect(Napi::Env env,

View File

@ -31,12 +31,11 @@ namespace wgpu { namespace binding {
// interop::GPURenderBundleEncoder interface compliance // interop::GPURenderBundleEncoder interface compliance
interop::Interface<interop::GPURenderBundle> finish( interop::Interface<interop::GPURenderBundle> finish(
Napi::Env, Napi::Env,
std::optional<interop::GPURenderBundleDescriptor> descriptor) override; interop::GPURenderBundleDescriptor descriptor) override;
void setBindGroup( void setBindGroup(Napi::Env,
Napi::Env, interop::GPUIndex32 index,
interop::GPUIndex32 index, interop::Interface<interop::GPUBindGroup> bindGroup,
interop::Interface<interop::GPUBindGroup> bindGroup, std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) override;
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) override;
void setBindGroup(Napi::Env, void setBindGroup(Napi::Env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,
@ -51,24 +50,24 @@ namespace wgpu { namespace binding {
void setIndexBuffer(Napi::Env, void setIndexBuffer(Napi::Env,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUIndexFormat indexFormat, interop::GPUIndexFormat indexFormat,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void setVertexBuffer(Napi::Env, void setVertexBuffer(Napi::Env,
interop::GPUIndex32 slot, interop::GPUIndex32 slot,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void draw(Napi::Env, void draw(Napi::Env,
interop::GPUSize32 vertexCount, interop::GPUSize32 vertexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstVertex, interop::GPUSize32 firstVertex,
std::optional<interop::GPUSize32> firstInstance) override; interop::GPUSize32 firstInstance) override;
void drawIndexed(Napi::Env, void drawIndexed(Napi::Env,
interop::GPUSize32 indexCount, interop::GPUSize32 indexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstIndex, interop::GPUSize32 firstIndex,
std::optional<interop::GPUSignedOffset32> baseVertex, interop::GPUSignedOffset32 baseVertex,
std::optional<interop::GPUSize32> firstInstance) override; interop::GPUSize32 firstInstance) override;
void drawIndirect(Napi::Env, void drawIndirect(Napi::Env,
interop::Interface<interop::GPUBuffer> indirectBuffer, interop::Interface<interop::GPUBuffer> indirectBuffer,
interop::GPUSize64 indirectOffset) override; interop::GPUSize64 indirectOffset) override;

View File

@ -117,21 +117,17 @@ namespace wgpu { namespace binding {
Napi::Env env, Napi::Env env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) { std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) {
Converter conv(env); Converter conv(env);
wgpu::BindGroup bg{}; 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; return;
} }
uint32_t* offsets = nullptr;
uint32_t offset_count = 0; enc_.SetBindGroup(index, bg, num_offsets, offsets);
if (dynamicOffsets.has_value() && dynamicOffsets->size() > 0) {
if (!conv(offsets, offset_count, dynamicOffsets.value())) {
return;
}
}
enc_.SetBindGroup(index, bg, offset_count, offsets);
} }
void GPURenderPassEncoder::setBindGroup(Napi::Env env, void GPURenderPassEncoder::setBindGroup(Napi::Env env,
@ -177,85 +173,51 @@ namespace wgpu { namespace binding {
void GPURenderPassEncoder::setIndexBuffer(Napi::Env env, void GPURenderPassEncoder::setIndexBuffer(Napi::Env env,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUIndexFormat indexFormat, interop::GPUIndexFormat indexFormat,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
Converter conv(env); Converter conv(env);
wgpu::Buffer b{}; wgpu::Buffer b{};
wgpu::IndexFormat f; wgpu::IndexFormat f;
uint64_t o = 0;
uint64_t s = wgpu::kWholeSize; uint64_t s = wgpu::kWholeSize;
if (!conv(b, buffer) || // if (!conv(b, buffer) || //
!conv(f, indexFormat) || // !conv(f, indexFormat) || //
!conv(o, offset) || //
!conv(s, size)) { !conv(s, size)) {
return; return;
} }
enc_.SetIndexBuffer(b, f, o, s); enc_.SetIndexBuffer(b, f, offset, s);
} }
void GPURenderPassEncoder::setVertexBuffer(Napi::Env env, void GPURenderPassEncoder::setVertexBuffer(Napi::Env env,
interop::GPUIndex32 slot, interop::GPUIndex32 slot,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) { std::optional<interop::GPUSize64> size) {
Converter conv(env); Converter conv(env);
wgpu::Buffer b{}; wgpu::Buffer b{};
uint64_t o = 0;
uint64_t s = wgpu::kWholeSize; uint64_t s = wgpu::kWholeSize;
if (!conv(b, buffer) || // if (!conv(b, buffer) || !conv(s, size)) {
!conv(o, offset) || //
!conv(s, size)) {
return; return;
} }
enc_.SetVertexBuffer(slot, b, o, s); enc_.SetVertexBuffer(slot, b, offset, s);
} }
void GPURenderPassEncoder::draw(Napi::Env env, void GPURenderPassEncoder::draw(Napi::Env env,
interop::GPUSize32 vertexCount, interop::GPUSize32 vertexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstVertex, interop::GPUSize32 firstVertex,
std::optional<interop::GPUSize32> firstInstance) { interop::GPUSize32 firstInstance) {
Converter conv(env); enc_.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
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);
} }
void GPURenderPassEncoder::drawIndexed(Napi::Env env, void GPURenderPassEncoder::drawIndexed(Napi::Env env,
interop::GPUSize32 indexCount, interop::GPUSize32 indexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstIndex, interop::GPUSize32 firstIndex,
std::optional<interop::GPUSignedOffset32> baseVertex, interop::GPUSignedOffset32 baseVertex,
std::optional<interop::GPUSize32> firstInstance) { interop::GPUSize32 firstInstance) {
Converter conv(env); enc_.DrawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
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);
} }
void GPURenderPassEncoder::drawIndirect(Napi::Env env, void GPURenderPassEncoder::drawIndirect(Napi::Env env,

View File

@ -61,11 +61,10 @@ namespace wgpu { namespace binding {
Napi::Env, Napi::Env,
std::vector<interop::Interface<interop::GPURenderBundle>> bundles) override; std::vector<interop::Interface<interop::GPURenderBundle>> bundles) override;
void endPass(Napi::Env) override; void endPass(Napi::Env) override;
void setBindGroup( void setBindGroup(Napi::Env,
Napi::Env, interop::GPUIndex32 index,
interop::GPUIndex32 index, interop::Interface<interop::GPUBindGroup> bindGroup,
interop::Interface<interop::GPUBindGroup> bindGroup, std::vector<interop::GPUBufferDynamicOffset> dynamicOffsets) override;
std::optional<std::vector<interop::GPUBufferDynamicOffset>> dynamicOffsets) override;
void setBindGroup(Napi::Env, void setBindGroup(Napi::Env,
interop::GPUIndex32 index, interop::GPUIndex32 index,
interop::Interface<interop::GPUBindGroup> bindGroup, interop::Interface<interop::GPUBindGroup> bindGroup,
@ -80,24 +79,24 @@ namespace wgpu { namespace binding {
void setIndexBuffer(Napi::Env, void setIndexBuffer(Napi::Env,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
interop::GPUIndexFormat indexFormat, interop::GPUIndexFormat indexFormat,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void setVertexBuffer(Napi::Env, void setVertexBuffer(Napi::Env,
interop::GPUIndex32 slot, interop::GPUIndex32 slot,
interop::Interface<interop::GPUBuffer> buffer, interop::Interface<interop::GPUBuffer> buffer,
std::optional<interop::GPUSize64> offset, interop::GPUSize64 offset,
std::optional<interop::GPUSize64> size) override; std::optional<interop::GPUSize64> size) override;
void draw(Napi::Env, void draw(Napi::Env,
interop::GPUSize32 vertexCount, interop::GPUSize32 vertexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstVertex, interop::GPUSize32 firstVertex,
std::optional<interop::GPUSize32> firstInstance) override; interop::GPUSize32 firstInstance) override;
void drawIndexed(Napi::Env, void drawIndexed(Napi::Env,
interop::GPUSize32 indexCount, interop::GPUSize32 indexCount,
std::optional<interop::GPUSize32> instanceCount, interop::GPUSize32 instanceCount,
std::optional<interop::GPUSize32> firstIndex, interop::GPUSize32 firstIndex,
std::optional<interop::GPUSignedOffset32> baseVertex, interop::GPUSignedOffset32 baseVertex,
std::optional<interop::GPUSize32> firstInstance) override; interop::GPUSize32 firstInstance) override;
void drawIndirect(Napi::Env, void drawIndirect(Napi::Env,
interop::Interface<interop::GPUBuffer> indirectBuffer, interop::Interface<interop::GPUBuffer> indirectBuffer,
interop::GPUSize64 indirectOffset) override; interop::GPUSize64 indirectOffset) override;

View File

@ -29,28 +29,24 @@ namespace wgpu { namespace binding {
interop::Interface<interop::GPUTextureView> GPUTexture::createView( interop::Interface<interop::GPUTextureView> GPUTexture::createView(
Napi::Env env, Napi::Env env,
std::optional<interop::GPUTextureViewDescriptor> descriptor) { interop::GPUTextureViewDescriptor descriptor) {
if (!texture_) { if (!texture_) {
Errors::OperationError(env).ThrowAsJavaScriptException(); Errors::OperationError(env).ThrowAsJavaScriptException();
return {}; return {};
} }
if (descriptor.has_value()) { wgpu::TextureViewDescriptor desc{};
wgpu::TextureViewDescriptor desc{}; Converter conv(env);
Converter conv(env); if (!conv(desc.baseMipLevel, descriptor.baseMipLevel) || //
if (!conv(desc.baseMipLevel, descriptor->baseMipLevel) || !conv(desc.mipLevelCount, descriptor.mipLevelCount) || //
!conv(desc.mipLevelCount, descriptor->mipLevelCount) || !conv(desc.baseArrayLayer, descriptor.baseArrayLayer) || //
!conv(desc.baseArrayLayer, descriptor->baseArrayLayer) || !conv(desc.arrayLayerCount, descriptor.arrayLayerCount) || //
!conv(desc.arrayLayerCount, descriptor->arrayLayerCount) || !conv(desc.format, descriptor.format) || //
!conv(desc.format, descriptor->format) || !conv(desc.dimension, descriptor.dimension) || //
!conv(desc.dimension, descriptor->dimension) || !conv(desc.aspect, descriptor.aspect)) {
!conv(desc.aspect, descriptor->aspect)) { return {};
return {};
}
return interop::GPUTextureView::Create<GPUTextureView>(env, texture_.CreateView(&desc));
} }
return interop::GPUTextureView::Create<GPUTextureView>(env, texture_.CreateView(&desc));
return interop::GPUTextureView::Create<GPUTextureView>(env, texture_.CreateView());
} }
void GPUTexture::destroy(Napi::Env) { void GPUTexture::destroy(Napi::Env) {

View File

@ -35,7 +35,7 @@ namespace wgpu { namespace binding {
// interop::GPUTexture interface compliance // interop::GPUTexture interface compliance
interop::Interface<interop::GPUTextureView> createView( interop::Interface<interop::GPUTextureView> createView(
Napi::Env, Napi::Env,
std::optional<interop::GPUTextureViewDescriptor> descriptor) override; interop::GPUTextureViewDescriptor descriptor) override;
void destroy(Napi::Env) override; void destroy(Napi::Env) override;
std::optional<std::string> getLabel(Napi::Env) override; std::optional<std::string> getLabel(Napi::Env) override;
void setLabel(Napi::Env, std::optional<std::string> value) override; void setLabel(Napi::Env, std::optional<std::string> value) override;

View File

@ -550,16 +550,60 @@ namespace wgpu { namespace interop {
env, std::forward<T>(value)); env, std::forward<T>(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 <typename T>
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<T>::value is true iff T is of type DefaultedParameter.
template <typename T>
struct IsDefaultedParameter {
static constexpr bool value = false;
};
template <typename T>
struct IsDefaultedParameter<DefaultedParameter<T>> {
static constexpr bool value = true;
};
// FromJS() is a helper function for bulk converting the arguments of 'info'. // FromJS() is a helper function for bulk converting the arguments of 'info'.
// PARAM_TYPES is a std::tuple<> describing the C++ function parameter types. // 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. // Returns true on success, false on failure.
template <typename PARAM_TYPES, int BASE_INDEX = 0> template <typename PARAM_TYPES, int BASE_INDEX = 0>
inline bool FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) { inline bool FromJS(const Napi::CallbackInfo& info, PARAM_TYPES& args) {
if constexpr (BASE_INDEX < std::tuple_size_v<PARAM_TYPES>) { if constexpr (BASE_INDEX < std::tuple_size_v<PARAM_TYPES>) {
using T = std::tuple_element_t<BASE_INDEX, PARAM_TYPES>; using T = std::tuple_element_t<BASE_INDEX, PARAM_TYPES>;
if (!FromJS<T>(info.Env(), info[BASE_INDEX], std::get<BASE_INDEX>(args))) { auto& value = info[BASE_INDEX];
return false; auto& out = std::get<BASE_INDEX>(args);
if constexpr (IsDefaultedParameter<T>::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<PARAM_TYPES, BASE_INDEX + 1>(info, args); return FromJS<PARAM_TYPES, BASE_INDEX + 1>(info, args);
} else { } else {
return true; return true;

View File

@ -181,10 +181,18 @@ Wrappers* Wrappers::instance = nullptr;
std::tuple< std::tuple<
{{- range $i, $p := $o.Parameters}} {{- range $i, $p := $o.Parameters}}
{{- if $i}}, {{end}} {{- if $i}}, {{end}}
{{- if $p.Optional}}std::optional<{{template "Type" $p.Type}}> {{- if $p.Init }}DefaultedParameter<{{template "Type" $p.Type}}>
{{- else }}{{template "Type" $p.Type}} {{- else if $p.Optional}}std::optional<{{template "Type" $p.Type}}>
{{- else }}{{template "Type" $p.Type}}
{{- end}} {{- end}}
{{- end}}> args; {{- 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)) { if (FromJS(info, args)) {
{{/* indent */}}INTEROP_LOG( {{/* indent */}}INTEROP_LOG(
{{- range $i, $p := $o.Parameters}} {{- range $i, $p := $o.Parameters}}

View File

@ -275,9 +275,8 @@ std::ostream& operator<<(std::ostream& o, {{$.Name}});
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
*/ -}} */ -}}
{{- define "Parameter" -}} {{- define "Parameter" -}}
{{- if $.Optional -}} {{- if $.Init }}{{template "Type" $.Type}} {{$.Name}}
std::optional<{{template "Type" $.Type}}> {{$.Name}} {{- else if $.Optional}}std::optional<{{template "Type" $.Type}}> {{$.Name}}
{{- else}} {{- else }}{{template "Type" $.Type}} {{$.Name}}
{{- template "Type" $.Type}} {{$.Name}} {{- end }}
{{- end}}
{{- end}} {{- end}}