blob: d75e217a9881c3fc97ba4ed76d4d0d4c54e8e005 [file] [log] [blame] [edit]
// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/dawn_node/binding/Converter.h"
#include "src/dawn_node/binding/GPUBuffer.h"
#include "src/dawn_node/binding/GPUPipelineLayout.h"
#include "src/dawn_node/binding/GPUSampler.h"
#include "src/dawn_node/binding/GPUShaderModule.h"
#include "src/dawn_node/binding/GPUTexture.h"
#include "src/dawn_node/binding/GPUTextureView.h"
#include "src/dawn_node/utils/Debug.h"
namespace wgpu { namespace binding {
Converter::~Converter() {
for (auto& free : free_) {
free();
}
}
bool Converter::Convert(wgpu::Extent3D& out, const interop::GPUExtent3D& in) {
out = {};
if (auto* dict = std::get_if<interop::GPUExtent3DDict>(&in)) {
out.depthOrArrayLayers = dict->depthOrArrayLayers;
out.width = dict->width;
out.height = dict->height;
return true;
}
if (auto* vec = std::get_if<std::vector<interop::GPUIntegerCoordinate>>(&in)) {
switch (vec->size()) {
default:
case 3:
out.depthOrArrayLayers = (*vec)[2];
case 2: // fallthrough
out.height = (*vec)[1];
case 1: // fallthrough
out.width = (*vec)[0];
return true;
case 0:
break;
}
}
Napi::Error::New(env, "invalid value for GPUExtent3D").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::Origin3D& out, const interop::GPUOrigin3DDict& in) {
out = {};
out.x = in.x;
out.y = in.y;
out.z = in.z;
return true;
}
bool Converter::Convert(wgpu::Color& out, const interop::GPUColor& in) {
out = {};
if (auto* dict = std::get_if<interop::GPUColorDict>(&in)) {
out.r = dict->r;
out.g = dict->g;
out.b = dict->b;
out.a = dict->a;
return true;
}
if (auto* vec = std::get_if<std::vector<double>>(&in)) {
switch (vec->size()) {
default:
case 4:
out.a = (*vec)[3];
case 3: // fallthrough
out.b = (*vec)[2];
case 2: // fallthrough
out.g = (*vec)[1];
case 1: // fallthrough
out.r = (*vec)[0];
return true;
case 0:
break;
}
}
Napi::Error::New(env, "invalid value for GPUColor").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::Origin3D& out,
const std::vector<interop::GPUIntegerCoordinate>& in) {
out = {};
switch (in.size()) {
default:
case 3:
out.z = in[2];
case 2: // fallthrough
out.y = in[1];
case 1: // fallthrough
out.x = in[0];
case 0:
break;
}
return true;
}
bool Converter::Convert(wgpu::TextureAspect& out, const interop::GPUTextureAspect& in) {
out = wgpu::TextureAspect::All;
switch (in) {
case interop::GPUTextureAspect::kAll:
out = wgpu::TextureAspect::All;
return true;
case interop::GPUTextureAspect::kStencilOnly:
out = wgpu::TextureAspect::StencilOnly;
return true;
case interop::GPUTextureAspect::kDepthOnly:
out = wgpu::TextureAspect::DepthOnly;
return true;
}
Napi::Error::New(env, "invalid value for GPUTextureAspect").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::ImageCopyTexture& out, const interop::GPUImageCopyTexture& in) {
out = {};
return Convert(out.texture, in.texture) && Convert(out.mipLevel, in.mipLevel) &&
Convert(out.origin, in.origin) && Convert(out.aspect, in.aspect);
}
bool Converter::Convert(wgpu::ImageCopyBuffer& out, const interop::GPUImageCopyBuffer& in) {
out = {};
out.buffer = *in.buffer.As<GPUBuffer>();
return Convert(out.layout.offset, in.offset) &&
Convert(out.layout.bytesPerRow, in.bytesPerRow) &&
Convert(out.layout.rowsPerImage, in.rowsPerImage);
}
bool Converter::Convert(BufferSource& out, interop::BufferSource in) {
out = {};
if (auto* view = std::get_if<interop::ArrayBufferView>(&in)) {
std::visit(
[&](auto&& v) {
auto arr = v.ArrayBuffer();
out.data = arr.Data();
out.size = arr.ByteLength();
},
*view);
return true;
}
if (auto* arr = std::get_if<interop::ArrayBuffer>(&in)) {
out.data = arr->Data();
out.size = arr->ByteLength();
return true;
}
Napi::Error::New(env, "invalid value for BufferSource").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::TextureDataLayout& out, const interop::GPUImageDataLayout& in) {
out = {};
return Convert(out.bytesPerRow, in.bytesPerRow) && Convert(out.offset, in.offset) &&
Convert(out.rowsPerImage, in.rowsPerImage);
}
bool Converter::Convert(wgpu::TextureFormat& out, const interop::GPUTextureFormat& in) {
out = wgpu::TextureFormat::Undefined;
switch (in) {
case interop::GPUTextureFormat::kR8Unorm:
out = wgpu::TextureFormat::R8Unorm;
return true;
case interop::GPUTextureFormat::kR8Snorm:
out = wgpu::TextureFormat::R8Snorm;
return true;
case interop::GPUTextureFormat::kR8Uint:
out = wgpu::TextureFormat::R8Uint;
return true;
case interop::GPUTextureFormat::kR8Sint:
out = wgpu::TextureFormat::R8Sint;
return true;
case interop::GPUTextureFormat::kR16Uint:
out = wgpu::TextureFormat::R16Uint;
return true;
case interop::GPUTextureFormat::kR16Sint:
out = wgpu::TextureFormat::R16Sint;
return true;
case interop::GPUTextureFormat::kR16Float:
out = wgpu::TextureFormat::R16Float;
return true;
case interop::GPUTextureFormat::kRg8Unorm:
out = wgpu::TextureFormat::RG8Unorm;
return true;
case interop::GPUTextureFormat::kRg8Snorm:
out = wgpu::TextureFormat::RG8Snorm;
return true;
case interop::GPUTextureFormat::kRg8Uint:
out = wgpu::TextureFormat::RG8Uint;
return true;
case interop::GPUTextureFormat::kRg8Sint:
out = wgpu::TextureFormat::RG8Sint;
return true;
case interop::GPUTextureFormat::kR32Uint:
out = wgpu::TextureFormat::R32Uint;
return true;
case interop::GPUTextureFormat::kR32Sint:
out = wgpu::TextureFormat::R32Sint;
return true;
case interop::GPUTextureFormat::kR32Float:
out = wgpu::TextureFormat::R32Float;
return true;
case interop::GPUTextureFormat::kRg16Uint:
out = wgpu::TextureFormat::RG16Uint;
return true;
case interop::GPUTextureFormat::kRg16Sint:
out = wgpu::TextureFormat::RG16Sint;
return true;
case interop::GPUTextureFormat::kRg16Float:
out = wgpu::TextureFormat::RG16Float;
return true;
case interop::GPUTextureFormat::kRgba8Unorm:
out = wgpu::TextureFormat::RGBA8Unorm;
return true;
case interop::GPUTextureFormat::kRgba8UnormSrgb:
out = wgpu::TextureFormat::RGBA8UnormSrgb;
return true;
case interop::GPUTextureFormat::kRgba8Snorm:
out = wgpu::TextureFormat::RGBA8Snorm;
return true;
case interop::GPUTextureFormat::kRgba8Uint:
out = wgpu::TextureFormat::RGBA8Uint;
return true;
case interop::GPUTextureFormat::kRgba8Sint:
out = wgpu::TextureFormat::RGBA8Sint;
return true;
case interop::GPUTextureFormat::kBgra8Unorm:
out = wgpu::TextureFormat::BGRA8Unorm;
return true;
case interop::GPUTextureFormat::kBgra8UnormSrgb:
out = wgpu::TextureFormat::BGRA8UnormSrgb;
return true;
case interop::GPUTextureFormat::kRgb9E5Ufloat:
out = wgpu::TextureFormat::RGB9E5Ufloat;
return true;
case interop::GPUTextureFormat::kRgb10A2Unorm:
out = wgpu::TextureFormat::RGB10A2Unorm;
return true;
case interop::GPUTextureFormat::kRg11B10Ufloat:
out = wgpu::TextureFormat::RG11B10Ufloat;
return true;
case interop::GPUTextureFormat::kRg32Uint:
out = wgpu::TextureFormat::RG32Uint;
return true;
case interop::GPUTextureFormat::kRg32Sint:
out = wgpu::TextureFormat::RG32Sint;
return true;
case interop::GPUTextureFormat::kRg32Float:
out = wgpu::TextureFormat::RG32Float;
return true;
case interop::GPUTextureFormat::kRgba16Uint:
out = wgpu::TextureFormat::RGBA16Uint;
return true;
case interop::GPUTextureFormat::kRgba16Sint:
out = wgpu::TextureFormat::RGBA16Sint;
return true;
case interop::GPUTextureFormat::kRgba16Float:
out = wgpu::TextureFormat::RGBA16Float;
return true;
case interop::GPUTextureFormat::kRgba32Uint:
out = wgpu::TextureFormat::RGBA32Uint;
return true;
case interop::GPUTextureFormat::kRgba32Sint:
out = wgpu::TextureFormat::RGBA32Sint;
return true;
case interop::GPUTextureFormat::kRgba32Float:
out = wgpu::TextureFormat::RGBA32Float;
return true;
case interop::GPUTextureFormat::kStencil8:
out = wgpu::TextureFormat::Stencil8;
return true;
case interop::GPUTextureFormat::kDepth16Unorm:
break; // TODO(crbug.com/dawn/1130): Unsupported.
case interop::GPUTextureFormat::kDepth24Plus:
out = wgpu::TextureFormat::Depth24Plus;
return true;
case interop::GPUTextureFormat::kDepth24PlusStencil8:
out = wgpu::TextureFormat::Depth24PlusStencil8;
return true;
case interop::GPUTextureFormat::kDepth32Float:
out = wgpu::TextureFormat::Depth32Float;
return true;
case interop::GPUTextureFormat::kBc1RgbaUnorm:
out = wgpu::TextureFormat::BC1RGBAUnorm;
return true;
case interop::GPUTextureFormat::kBc1RgbaUnormSrgb:
out = wgpu::TextureFormat::BC1RGBAUnormSrgb;
return true;
case interop::GPUTextureFormat::kBc2RgbaUnorm:
out = wgpu::TextureFormat::BC2RGBAUnorm;
return true;
case interop::GPUTextureFormat::kBc2RgbaUnormSrgb:
out = wgpu::TextureFormat::BC2RGBAUnormSrgb;
return true;
case interop::GPUTextureFormat::kBc3RgbaUnorm:
out = wgpu::TextureFormat::BC3RGBAUnorm;
return true;
case interop::GPUTextureFormat::kBc3RgbaUnormSrgb:
out = wgpu::TextureFormat::BC3RGBAUnormSrgb;
return true;
case interop::GPUTextureFormat::kBc4RUnorm:
out = wgpu::TextureFormat::BC4RUnorm;
return true;
case interop::GPUTextureFormat::kBc4RSnorm:
out = wgpu::TextureFormat::BC4RSnorm;
return true;
case interop::GPUTextureFormat::kBc5RgUnorm:
out = wgpu::TextureFormat::BC5RGUnorm;
return true;
case interop::GPUTextureFormat::kBc5RgSnorm:
out = wgpu::TextureFormat::BC5RGSnorm;
return true;
case interop::GPUTextureFormat::kBc6HRgbUfloat:
out = wgpu::TextureFormat::BC6HRGBUfloat;
return true;
case interop::GPUTextureFormat::kBc6HRgbFloat:
out = wgpu::TextureFormat::BC6HRGBFloat;
return true;
case interop::GPUTextureFormat::kBc7RgbaUnorm:
out = wgpu::TextureFormat::BC7RGBAUnorm;
return true;
case interop::GPUTextureFormat::kBc7RgbaUnormSrgb:
out = wgpu::TextureFormat::BC7RGBAUnormSrgb;
return true;
case interop::GPUTextureFormat::kDepth24UnormStencil8:
break; // TODO(crbug.com/dawn/1130): Unsupported.
case interop::GPUTextureFormat::kDepth32FloatStencil8:
break; // TODO(crbug.com/dawn/1130): Unsupported.
}
// TODO(crbug.com/dawn/1130): Add ASTC and ETC formats.
Napi::Error::New(env, "invalid value for GPUTextureFormat").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::TextureUsage& out, const interop::GPUTextureUsageFlags& in) {
out = static_cast<wgpu::TextureUsage>(in);
return true;
}
bool Converter::Convert(wgpu::ColorWriteMask& out, const interop::GPUColorWriteFlags& in) {
out = static_cast<wgpu::ColorWriteMask>(in);
return true;
}
bool Converter::Convert(wgpu::BufferUsage& out, const interop::GPUBufferUsageFlags& in) {
out = static_cast<wgpu::BufferUsage>(in);
return true;
}
bool Converter::Convert(wgpu::MapMode& out, const interop::GPUMapModeFlags& in) {
out = static_cast<wgpu::MapMode>(in);
return true;
}
bool Converter::Convert(wgpu::ShaderStage& out, const interop::GPUShaderStageFlags& in) {
out = static_cast<wgpu::ShaderStage>(in);
return true;
}
bool Converter::Convert(wgpu::TextureDimension& out, const interop::GPUTextureDimension& in) {
out = wgpu::TextureDimension::e1D;
switch (in) {
case interop::GPUTextureDimension::k1D:
out = wgpu::TextureDimension::e1D;
return true;
case interop::GPUTextureDimension::k2D:
out = wgpu::TextureDimension::e2D;
return true;
case interop::GPUTextureDimension::k3D:
out = wgpu::TextureDimension::e3D;
return true;
}
Napi::Error::New(env, "invalid value for GPUTextureDimension").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::TextureViewDimension& out,
const interop::GPUTextureViewDimension& in) {
out = wgpu::TextureViewDimension::Undefined;
switch (in) {
case interop::GPUTextureViewDimension::k1D:
out = wgpu::TextureViewDimension::e1D;
return true;
case interop::GPUTextureViewDimension::k2D:
out = wgpu::TextureViewDimension::e2D;
return true;
case interop::GPUTextureViewDimension::k2DArray:
out = wgpu::TextureViewDimension::e2DArray;
return true;
case interop::GPUTextureViewDimension::kCube:
out = wgpu::TextureViewDimension::Cube;
return true;
case interop::GPUTextureViewDimension::kCubeArray:
out = wgpu::TextureViewDimension::CubeArray;
return true;
case interop::GPUTextureViewDimension::k3D:
out = wgpu::TextureViewDimension::e3D;
return true;
default:
break;
}
Napi::Error::New(env, "invalid value for GPUTextureViewDimension")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::ProgrammableStageDescriptor& out,
const interop::GPUProgrammableStage& in) {
out = {};
out.entryPoint = in.entryPoint.c_str();
out.module = *in.module.As<GPUShaderModule>();
return Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::ConstantEntry& out,
const std::string& in_name,
wgpu::interop::GPUPipelineConstantValue in_value) {
out.key = in_name.c_str();
out.value = in_value;
return true;
}
bool Converter::Convert(wgpu::BlendComponent& out, const interop::GPUBlendComponent& in) {
out = {};
return Convert(out.operation, in.operation) && Convert(out.dstFactor, in.dstFactor) &&
Convert(out.srcFactor, in.srcFactor);
}
bool Converter::Convert(wgpu::BlendFactor& out, const interop::GPUBlendFactor& in) {
out = wgpu::BlendFactor::Zero;
switch (in) {
case interop::GPUBlendFactor::kZero:
out = wgpu::BlendFactor::Zero;
return true;
case interop::GPUBlendFactor::kOne:
out = wgpu::BlendFactor::One;
return true;
case interop::GPUBlendFactor::kSrc:
out = wgpu::BlendFactor::Src;
return true;
case interop::GPUBlendFactor::kOneMinusSrc:
out = wgpu::BlendFactor::OneMinusSrc;
return true;
case interop::GPUBlendFactor::kSrcAlpha:
out = wgpu::BlendFactor::SrcAlpha;
return true;
case interop::GPUBlendFactor::kOneMinusSrcAlpha:
out = wgpu::BlendFactor::OneMinusSrcAlpha;
return true;
case interop::GPUBlendFactor::kDst:
out = wgpu::BlendFactor::Dst;
return true;
case interop::GPUBlendFactor::kOneMinusDst:
out = wgpu::BlendFactor::OneMinusDst;
return true;
case interop::GPUBlendFactor::kDstAlpha:
out = wgpu::BlendFactor::DstAlpha;
return true;
case interop::GPUBlendFactor::kOneMinusDstAlpha:
out = wgpu::BlendFactor::OneMinusDstAlpha;
return true;
case interop::GPUBlendFactor::kSrcAlphaSaturated:
out = wgpu::BlendFactor::SrcAlphaSaturated;
return true;
case interop::GPUBlendFactor::kConstant:
out = wgpu::BlendFactor::Constant;
return true;
case interop::GPUBlendFactor::kOneMinusConstant:
out = wgpu::BlendFactor::OneMinusConstant;
return true;
default:
break;
}
Napi::Error::New(env, "invalid value for GPUBlendFactor").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::BlendOperation& out, const interop::GPUBlendOperation& in) {
out = wgpu::BlendOperation::Add;
switch (in) {
case interop::GPUBlendOperation::kAdd:
out = wgpu::BlendOperation::Add;
return true;
case interop::GPUBlendOperation::kSubtract:
out = wgpu::BlendOperation::Subtract;
return true;
case interop::GPUBlendOperation::kReverseSubtract:
out = wgpu::BlendOperation::ReverseSubtract;
return true;
case interop::GPUBlendOperation::kMin:
out = wgpu::BlendOperation::Min;
return true;
case interop::GPUBlendOperation::kMax:
out = wgpu::BlendOperation::Max;
return true;
default:
break;
}
Napi::Error::New(env, "invalid value for GPUBlendOperation").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::BlendState& out, const interop::GPUBlendState& in) {
out = {};
return Convert(out.alpha, in.alpha) && Convert(out.color, in.color);
}
bool Converter::Convert(wgpu::PrimitiveState& out, const interop::GPUPrimitiveState& in) {
out = {};
return Convert(out.topology, in.topology) &&
Convert(out.stripIndexFormat, in.stripIndexFormat) &&
Convert(out.frontFace, in.frontFace) && Convert(out.cullMode, in.cullMode);
}
bool Converter::Convert(wgpu::ColorTargetState& out, const interop::GPUColorTargetState& in) {
out = {};
return Convert(out.format, in.format) && Convert(out.blend, in.blend) &&
Convert(out.writeMask, in.writeMask);
}
bool Converter::Convert(wgpu::DepthStencilState& out, const interop::GPUDepthStencilState& in) {
out = {};
return Convert(out.format, in.format) &&
Convert(out.depthWriteEnabled, in.depthWriteEnabled) &&
Convert(out.depthCompare, in.depthCompare) &&
Convert(out.stencilFront, in.stencilFront) &&
Convert(out.stencilBack, in.stencilBack) &&
Convert(out.stencilReadMask, in.stencilReadMask) &&
Convert(out.stencilWriteMask, in.stencilWriteMask) &&
Convert(out.depthBias, in.depthBias) &&
Convert(out.depthBiasSlopeScale, in.depthBiasSlopeScale) &&
Convert(out.depthBiasClamp, in.depthBiasClamp);
}
bool Converter::Convert(wgpu::MultisampleState& out, const interop::GPUMultisampleState& in) {
out = {};
return Convert(out.count, in.count) && Convert(out.mask, in.mask) &&
Convert(out.alphaToCoverageEnabled, in.alphaToCoverageEnabled);
}
bool Converter::Convert(wgpu::FragmentState& out, const interop::GPUFragmentState& in) {
out = {};
return Convert(out.targets, out.targetCount, in.targets) && //
Convert(out.module, in.module) && //
Convert(out.entryPoint, in.entryPoint) && //
Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::PrimitiveTopology& out, const interop::GPUPrimitiveTopology& in) {
out = wgpu::PrimitiveTopology::LineList;
switch (in) {
case interop::GPUPrimitiveTopology::kPointList:
out = wgpu::PrimitiveTopology::PointList;
return true;
case interop::GPUPrimitiveTopology::kLineList:
out = wgpu::PrimitiveTopology::LineList;
return true;
case interop::GPUPrimitiveTopology::kLineStrip:
out = wgpu::PrimitiveTopology::LineStrip;
return true;
case interop::GPUPrimitiveTopology::kTriangleList:
out = wgpu::PrimitiveTopology::TriangleList;
return true;
case interop::GPUPrimitiveTopology::kTriangleStrip:
out = wgpu::PrimitiveTopology::TriangleStrip;
return true;
}
Napi::Error::New(env, "invalid value for GPUPrimitiveTopology")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::FrontFace& out, const interop::GPUFrontFace& in) {
out = wgpu::FrontFace::CW;
switch (in) {
case interop::GPUFrontFace::kCw:
out = wgpu::FrontFace::CW;
return true;
case interop::GPUFrontFace::kCcw:
out = wgpu::FrontFace::CCW;
return true;
}
Napi::Error::New(env, "invalid value for GPUFrontFace").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::CullMode& out, const interop::GPUCullMode& in) {
out = wgpu::CullMode::None;
switch (in) {
case interop::GPUCullMode::kNone:
out = wgpu::CullMode::None;
return true;
case interop::GPUCullMode::kFront:
out = wgpu::CullMode::Front;
return true;
case interop::GPUCullMode::kBack:
out = wgpu::CullMode::Back;
return true;
}
Napi::Error::New(env, "invalid value for GPUCullMode").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::CompareFunction& out, const interop::GPUCompareFunction& in) {
out = wgpu::CompareFunction::Undefined;
switch (in) {
case interop::GPUCompareFunction::kNever:
out = wgpu::CompareFunction::Never;
return true;
case interop::GPUCompareFunction::kLess:
out = wgpu::CompareFunction::Less;
return true;
case interop::GPUCompareFunction::kLessEqual:
out = wgpu::CompareFunction::LessEqual;
return true;
case interop::GPUCompareFunction::kGreater:
out = wgpu::CompareFunction::Greater;
return true;
case interop::GPUCompareFunction::kGreaterEqual:
out = wgpu::CompareFunction::GreaterEqual;
return true;
case interop::GPUCompareFunction::kEqual:
out = wgpu::CompareFunction::Equal;
return true;
case interop::GPUCompareFunction::kNotEqual:
out = wgpu::CompareFunction::NotEqual;
return true;
case interop::GPUCompareFunction::kAlways:
out = wgpu::CompareFunction::Always;
return true;
}
Napi::Error::New(env, "invalid value for GPUCompareFunction").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::IndexFormat& out, const interop::GPUIndexFormat& in) {
out = wgpu::IndexFormat::Undefined;
switch (in) {
case interop::GPUIndexFormat::kUint16:
out = wgpu::IndexFormat::Uint16;
return true;
case interop::GPUIndexFormat::kUint32:
out = wgpu::IndexFormat::Uint32;
return true;
}
Napi::Error::New(env, "invalid value for GPUIndexFormat").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::StencilOperation& out, const interop::GPUStencilOperation& in) {
out = wgpu::StencilOperation::Zero;
switch (in) {
case interop::GPUStencilOperation::kKeep:
out = wgpu::StencilOperation::Keep;
return true;
case interop::GPUStencilOperation::kZero:
out = wgpu::StencilOperation::Zero;
return true;
case interop::GPUStencilOperation::kReplace:
out = wgpu::StencilOperation::Replace;
return true;
case interop::GPUStencilOperation::kInvert:
out = wgpu::StencilOperation::Invert;
return true;
case interop::GPUStencilOperation::kIncrementClamp:
out = wgpu::StencilOperation::IncrementClamp;
return true;
case interop::GPUStencilOperation::kDecrementClamp:
out = wgpu::StencilOperation::DecrementClamp;
return true;
case interop::GPUStencilOperation::kIncrementWrap:
out = wgpu::StencilOperation::IncrementWrap;
return true;
case interop::GPUStencilOperation::kDecrementWrap:
out = wgpu::StencilOperation::DecrementWrap;
return true;
}
Napi::Error::New(env, "invalid value for GPUStencilOperation").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::StencilFaceState& out, const interop::GPUStencilFaceState& in) {
return Convert(out.compare, in.compare) && Convert(out.failOp, in.failOp) &&
Convert(out.depthFailOp, in.depthFailOp) && Convert(out.passOp, in.passOp);
}
bool Converter::Convert(wgpu::VertexBufferLayout& out,
const interop::GPUVertexBufferLayout& in) {
out = {};
return Convert(out.attributes, out.attributeCount, in.attributes) &&
Convert(out.arrayStride, in.arrayStride) && Convert(out.stepMode, in.stepMode);
}
bool Converter::Convert(wgpu::VertexState& out, const interop::GPUVertexState& in) {
out = {};
return Convert(out.module, in.module) &&
Convert(out.buffers, out.bufferCount, in.buffers) &&
Convert(out.entryPoint, in.entryPoint) &&
Convert(out.constants, out.constantCount, in.constants);
}
bool Converter::Convert(wgpu::VertexStepMode& out, const interop::GPUVertexStepMode& in) {
out = wgpu::VertexStepMode::Instance;
switch (in) {
case interop::GPUVertexStepMode::kInstance:
out = wgpu::VertexStepMode::Instance;
return true;
case interop::GPUVertexStepMode::kVertex:
out = wgpu::VertexStepMode::Vertex;
return true;
default:
break;
}
Napi::Error::New(env, "invalid value for GPUVertexStepMode").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::VertexAttribute& out, const interop::GPUVertexAttribute& in) {
return Convert(out.format, in.format) && Convert(out.offset, in.offset) &&
Convert(out.shaderLocation, in.shaderLocation);
}
bool Converter::Convert(wgpu::VertexFormat& out, const interop::GPUVertexFormat& in) {
out = wgpu::VertexFormat::Undefined;
switch (in) {
case interop::GPUVertexFormat::kUint8X2:
out = wgpu::VertexFormat::Uint8x2;
return true;
case interop::GPUVertexFormat::kUint8X4:
out = wgpu::VertexFormat::Uint8x4;
return true;
case interop::GPUVertexFormat::kSint8X2:
out = wgpu::VertexFormat::Sint8x2;
return true;
case interop::GPUVertexFormat::kSint8X4:
out = wgpu::VertexFormat::Sint8x4;
return true;
case interop::GPUVertexFormat::kUnorm8X2:
out = wgpu::VertexFormat::Unorm8x2;
return true;
case interop::GPUVertexFormat::kUnorm8X4:
out = wgpu::VertexFormat::Unorm8x4;
return true;
case interop::GPUVertexFormat::kSnorm8X2:
out = wgpu::VertexFormat::Snorm8x2;
return true;
case interop::GPUVertexFormat::kSnorm8X4:
out = wgpu::VertexFormat::Snorm8x4;
return true;
case interop::GPUVertexFormat::kUint16X2:
out = wgpu::VertexFormat::Uint16x2;
return true;
case interop::GPUVertexFormat::kUint16X4:
out = wgpu::VertexFormat::Uint16x4;
return true;
case interop::GPUVertexFormat::kSint16X2:
out = wgpu::VertexFormat::Sint16x2;
return true;
case interop::GPUVertexFormat::kSint16X4:
out = wgpu::VertexFormat::Sint16x4;
return true;
case interop::GPUVertexFormat::kUnorm16X2:
out = wgpu::VertexFormat::Unorm16x2;
return true;
case interop::GPUVertexFormat::kUnorm16X4:
out = wgpu::VertexFormat::Unorm16x4;
return true;
case interop::GPUVertexFormat::kSnorm16X2:
out = wgpu::VertexFormat::Snorm16x2;
return true;
case interop::GPUVertexFormat::kSnorm16X4:
out = wgpu::VertexFormat::Snorm16x4;
return true;
case interop::GPUVertexFormat::kFloat16X2:
out = wgpu::VertexFormat::Float16x2;
return true;
case interop::GPUVertexFormat::kFloat16X4:
out = wgpu::VertexFormat::Float16x4;
return true;
case interop::GPUVertexFormat::kFloat32:
out = wgpu::VertexFormat::Float32;
return true;
case interop::GPUVertexFormat::kFloat32X2:
out = wgpu::VertexFormat::Float32x2;
return true;
case interop::GPUVertexFormat::kFloat32X3:
out = wgpu::VertexFormat::Float32x3;
return true;
case interop::GPUVertexFormat::kFloat32X4:
out = wgpu::VertexFormat::Float32x4;
return true;
case interop::GPUVertexFormat::kUint32:
out = wgpu::VertexFormat::Uint32;
return true;
case interop::GPUVertexFormat::kUint32X2:
out = wgpu::VertexFormat::Uint32x2;
return true;
case interop::GPUVertexFormat::kUint32X3:
out = wgpu::VertexFormat::Uint32x3;
return true;
case interop::GPUVertexFormat::kUint32X4:
out = wgpu::VertexFormat::Uint32x4;
return true;
case interop::GPUVertexFormat::kSint32:
out = wgpu::VertexFormat::Sint32;
return true;
case interop::GPUVertexFormat::kSint32X2:
out = wgpu::VertexFormat::Sint32x2;
return true;
case interop::GPUVertexFormat::kSint32X3:
out = wgpu::VertexFormat::Sint32x3;
return true;
case interop::GPUVertexFormat::kSint32X4:
out = wgpu::VertexFormat::Sint32x4;
return true;
default:
break;
}
Napi::Error::New(env, "invalid value for GPUVertexFormat").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::RenderPassColorAttachment& out,
const interop::GPURenderPassColorAttachment& in) {
out = {};
if (auto* op = std::get_if<interop::GPULoadOp>(&in.loadValue)) {
if (!Convert(out.loadOp, *op)) {
return false;
}
} else if (auto* color = std::get_if<interop::GPUColor>(&in.loadValue)) {
out.loadOp = wgpu::LoadOp::Clear;
if (!Convert(out.clearColor, *color)) {
return false;
}
} else {
Napi::Error::New(env, "invalid value for GPURenderPassColorAttachment.loadValue")
.ThrowAsJavaScriptException();
return false;
}
return Convert(out.view, in.view) && Convert(out.resolveTarget, in.resolveTarget) &&
Convert(out.storeOp, in.storeOp);
}
bool Converter::Convert(wgpu::RenderPassDepthStencilAttachment& out,
const interop::GPURenderPassDepthStencilAttachment& in) {
out = {};
if (auto* op = std::get_if<interop::GPULoadOp>(&in.depthLoadValue)) {
if (!Convert(out.depthLoadOp, *op)) {
return false;
}
} else if (auto* value = std::get_if<float>(&in.depthLoadValue)) {
out.stencilLoadOp = wgpu::LoadOp::Clear;
if (!Convert(out.clearDepth, *value)) {
return false;
}
} else {
Napi::Error::New(env,
"invalid value for GPURenderPassDepthStencilAttachment.depthLoadValue")
.ThrowAsJavaScriptException();
return false;
}
if (auto* op = std::get_if<interop::GPULoadOp>(&in.stencilLoadValue)) {
if (!Convert(out.stencilLoadOp, *op)) {
return false;
}
} else if (auto* value = std::get_if<interop::GPUStencilValue>(&in.stencilLoadValue)) {
if (!Convert(out.clearStencil, *value)) {
return false;
}
} else {
Napi::Error::New(env,
"invalid value for "
"GPURenderPassDepthStencilAttachment.stencilLoadValue")
.ThrowAsJavaScriptException();
return false;
}
return Convert(out.view, in.view) && Convert(out.depthStoreOp, in.depthStoreOp) &&
Convert(out.depthReadOnly, in.depthReadOnly) &&
Convert(out.stencilStoreOp, in.stencilStoreOp) &&
Convert(out.stencilReadOnly, in.stencilReadOnly);
}
bool Converter::Convert(wgpu::LoadOp& out, const interop::GPULoadOp& in) {
out = wgpu::LoadOp::Clear;
switch (in) {
case interop::GPULoadOp::kLoad:
out = wgpu::LoadOp::Load;
return true;
}
Napi::Error::New(env, "invalid value for GPULoadOp").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::StoreOp& out, const interop::GPUStoreOp& in) {
out = wgpu::StoreOp::Store;
switch (in) {
case interop::GPUStoreOp::kStore:
out = wgpu::StoreOp::Store;
return true;
case interop::GPUStoreOp::kDiscard:
out = wgpu::StoreOp::Discard;
return true;
}
Napi::Error::New(env, "invalid value for GPUStoreOp").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::BindGroupEntry& out, const interop::GPUBindGroupEntry& in) {
out = {};
if (!Convert(out.binding, in.binding)) {
return false;
}
if (auto* res = std::get_if<interop::Interface<interop::GPUSampler>>(&in.resource)) {
return Convert(out.sampler, *res);
}
if (auto* res = std::get_if<interop::Interface<interop::GPUTextureView>>(&in.resource)) {
return Convert(out.textureView, *res);
}
if (auto* res = std::get_if<interop::GPUBufferBinding>(&in.resource)) {
auto buffer = res->buffer.As<GPUBuffer>();
out.size = wgpu::kWholeSize;
if (!buffer || !Convert(out.offset, res->offset) || !Convert(out.size, res->size)) {
return false;
}
out.buffer = *buffer;
return true;
}
if (auto* res =
std::get_if<interop::Interface<interop::GPUExternalTexture>>(&in.resource)) {
// TODO(crbug.com/dawn/1129): External textures
UNIMPLEMENTED();
}
Napi::Error::New(env, "invalid value for GPUBindGroupEntry.resource")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::BindGroupLayoutEntry& out,
const interop::GPUBindGroupLayoutEntry& in) {
// TODO(crbug.com/dawn/1129): External textures
return Convert(out.binding, in.binding) && Convert(out.visibility, in.visibility) &&
Convert(out.buffer, in.buffer) && Convert(out.sampler, in.sampler) &&
Convert(out.texture, in.texture) && Convert(out.storageTexture, in.storageTexture);
}
bool Converter::Convert(wgpu::BufferBindingLayout& out,
const interop::GPUBufferBindingLayout& in) {
return Convert(out.type, in.type) && Convert(out.hasDynamicOffset, in.hasDynamicOffset) &&
Convert(out.minBindingSize, in.minBindingSize);
}
bool Converter::Convert(wgpu::SamplerBindingLayout& out,
const interop::GPUSamplerBindingLayout& in) {
return Convert(out.type, in.type);
}
bool Converter::Convert(wgpu::TextureBindingLayout& out,
const interop::GPUTextureBindingLayout& in) {
return Convert(out.sampleType, in.sampleType) &&
Convert(out.viewDimension, in.viewDimension) &&
Convert(out.multisampled, in.multisampled);
}
bool Converter::Convert(wgpu::StorageTextureBindingLayout& out,
const interop::GPUStorageTextureBindingLayout& in) {
return Convert(out.access, in.access) && Convert(out.format, in.format) &&
Convert(out.viewDimension, in.viewDimension);
}
bool Converter::Convert(wgpu::BufferBindingType& out, const interop::GPUBufferBindingType& in) {
out = wgpu::BufferBindingType::Undefined;
switch (in) {
case interop::GPUBufferBindingType::kUniform:
out = wgpu::BufferBindingType::Uniform;
return true;
case interop::GPUBufferBindingType::kStorage:
out = wgpu::BufferBindingType::Storage;
return true;
case interop::GPUBufferBindingType::kReadOnlyStorage:
out = wgpu::BufferBindingType::ReadOnlyStorage;
return true;
}
Napi::Error::New(env, "invalid value for GPUBufferBindingType")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::TextureSampleType& out, const interop::GPUTextureSampleType& in) {
out = wgpu::TextureSampleType::Undefined;
switch (in) {
case interop::GPUTextureSampleType::kFloat:
out = wgpu::TextureSampleType::Float;
return true;
case interop::GPUTextureSampleType::kUnfilterableFloat:
out = wgpu::TextureSampleType::UnfilterableFloat;
return true;
case interop::GPUTextureSampleType::kDepth:
out = wgpu::TextureSampleType::Depth;
return true;
case interop::GPUTextureSampleType::kSint:
out = wgpu::TextureSampleType::Sint;
return true;
case interop::GPUTextureSampleType::kUint:
out = wgpu::TextureSampleType::Uint;
return true;
}
Napi::Error::New(env, "invalid value for GPUTextureSampleType")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::SamplerBindingType& out,
const interop::GPUSamplerBindingType& in) {
out = wgpu::SamplerBindingType::Undefined;
switch (in) {
case interop::GPUSamplerBindingType::kFiltering:
out = wgpu::SamplerBindingType::Filtering;
return true;
case interop::GPUSamplerBindingType::kNonFiltering:
out = wgpu::SamplerBindingType::NonFiltering;
return true;
case interop::GPUSamplerBindingType::kComparison:
out = wgpu::SamplerBindingType::Comparison;
return true;
}
Napi::Error::New(env, "invalid value for GPUSamplerBindingType")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::StorageTextureAccess& out,
const interop::GPUStorageTextureAccess& in) {
out = wgpu::StorageTextureAccess::Undefined;
switch (in) {
case interop::GPUStorageTextureAccess::kWriteOnly:
out = wgpu::StorageTextureAccess::WriteOnly;
return true;
}
Napi::Error::New(env, "invalid value for GPUStorageTextureAccess")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::QueryType& out, const interop::GPUQueryType& in) {
out = wgpu::QueryType::Occlusion;
switch (in) {
case interop::GPUQueryType::kOcclusion:
out = wgpu::QueryType::Occlusion;
return true;
case interop::GPUQueryType::kPipelineStatistics:
out = wgpu::QueryType::PipelineStatistics;
return true;
case interop::GPUQueryType::kTimestamp:
out = wgpu::QueryType::Timestamp;
return true;
}
Napi::Error::New(env, "invalid value for GPUQueryType").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::PipelineStatisticName& out,
const interop::GPUPipelineStatisticName& in) {
out = wgpu::PipelineStatisticName::VertexShaderInvocations;
switch (in) {
case interop::GPUPipelineStatisticName::kVertexShaderInvocations:
out = wgpu::PipelineStatisticName::VertexShaderInvocations;
return true;
case interop::GPUPipelineStatisticName::kClipperInvocations:
out = wgpu::PipelineStatisticName::ClipperInvocations;
return true;
case interop::GPUPipelineStatisticName::kClipperPrimitivesOut:
out = wgpu::PipelineStatisticName::ClipperPrimitivesOut;
return true;
case interop::GPUPipelineStatisticName::kFragmentShaderInvocations:
out = wgpu::PipelineStatisticName::FragmentShaderInvocations;
return true;
case interop::GPUPipelineStatisticName::kComputeShaderInvocations:
out = wgpu::PipelineStatisticName::ComputeShaderInvocations;
return true;
}
Napi::Error::New(env, "invalid value for GPUPipelineStatisticName")
.ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::AddressMode& out, const interop::GPUAddressMode& in) {
out = wgpu::AddressMode::Repeat;
switch (in) {
case interop::GPUAddressMode::kClampToEdge:
out = wgpu::AddressMode::ClampToEdge;
return true;
case interop::GPUAddressMode::kRepeat:
out = wgpu::AddressMode::Repeat;
return true;
case interop::GPUAddressMode::kMirrorRepeat:
out = wgpu::AddressMode::MirrorRepeat;
return true;
}
Napi::Error::New(env, "invalid value for GPUAddressMode").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::FilterMode& out, const interop::GPUFilterMode& in) {
out = wgpu::FilterMode::Nearest;
switch (in) {
case interop::GPUFilterMode::kNearest:
out = wgpu::FilterMode::Nearest;
return true;
case interop::GPUFilterMode::kLinear:
out = wgpu::FilterMode::Linear;
return true;
}
Napi::Error::New(env, "invalid value for GPUFilterMode").ThrowAsJavaScriptException();
return false;
}
bool Converter::Convert(wgpu::ComputePipelineDescriptor& out,
const interop::GPUComputePipelineDescriptor& in) {
return Convert(out.label, in.label) && //
Convert(out.layout, in.layout) && //
Convert(out.compute, in.compute);
}
bool Converter::Convert(wgpu::RenderPipelineDescriptor& out,
const interop::GPURenderPipelineDescriptor& in) {
wgpu::RenderPipelineDescriptor desc{};
return Convert(out.label, in.label) && //
Convert(out.layout, in.layout) && //
Convert(out.vertex, in.vertex) && //
Convert(out.primitive, in.primitive) && //
Convert(out.depthStencil, in.depthStencil) && //
Convert(out.multisample, in.multisample) && //
Convert(out.fragment, in.fragment);
}
}} // namespace wgpu::binding