| // Copyright 2025 The Dawn & Tint Authors | |
| // | |
| // Redistribution and use in source and binary forms, with or without | |
| // modification, are permitted provided that the following conditions are met: | |
| // | |
| // 1. Redistributions of source code must retain the above copyright notice, this | |
| // list of conditions and the following disclaimer. | |
| // | |
| // 2. Redistributions in binary form must reproduce the above copyright notice, | |
| // this list of conditions and the following disclaimer in the documentation | |
| // and/or other materials provided with the distribution. | |
| // | |
| // 3. Neither the name of the copyright holder nor the names of its | |
| // contributors may be used to endorse or promote products derived from | |
| // this software without specific prior written permission. | |
| // | |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
| // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
| // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| #include "src/dawn/native/webgpu/ToWGPU.h" | |
| #include "dawn/native/dawn_platform_autogen.h" | |
| #include "src/dawn/common/Math.h" | |
| #include "src/dawn/common/StringViewUtils.h" | |
| #include "src/dawn/native/BlockInfo.h" | |
| #include "src/dawn/native/Commands.h" | |
| #include "src/dawn/native/webgpu/BufferWGPU.h" | |
| #include "src/dawn/native/webgpu/Forward.h" | |
| #include "src/dawn/native/webgpu/QuerySetWGPU.h" | |
| #include "src/dawn/native/webgpu/TextureWGPU.h" | |
| namespace dawn::native::webgpu { | |
| WGPUExtent3D ToWGPU(const TexelExtent3D& extent) { | |
| return { | |
| .width = dchecked_cast<uint32_t>(extent.width), | |
| .height = dchecked_cast<uint32_t>(extent.height), | |
| .depthOrArrayLayers = dchecked_cast<uint32_t>(extent.depthOrArrayLayers), | |
| }; | |
| } | |
| WGPUOrigin3D ToWGPU(const TexelOrigin3D& origin) { | |
| return { | |
| .x = dchecked_cast<uint32_t>(origin.x), | |
| .y = dchecked_cast<uint32_t>(origin.y), | |
| .z = dchecked_cast<uint32_t>(origin.z), | |
| }; | |
| } | |
| WGPUOrigin2D ToWGPU(const Origin2D& origin) { | |
| return { | |
| .x = static_cast<uint32_t>(origin.x), | |
| .y = static_cast<uint32_t>(origin.y), | |
| }; | |
| } | |
| WGPUExtent2D ToWGPU(const Extent2D& extent) { | |
| return { | |
| .width = static_cast<uint32_t>(extent.width), | |
| .height = static_cast<uint32_t>(extent.height), | |
| }; | |
| } | |
| WGPUColor ToWGPU(const dawn::native::Color& color) { | |
| return { | |
| .r = color.r, | |
| .g = color.g, | |
| .b = color.b, | |
| .a = color.a, | |
| }; | |
| } | |
| WGPUTexelCopyBufferLayout ToWGPU(const TexelCopyBufferLayout& copy) { | |
| return { | |
| .offset = copy.offset, | |
| .bytesPerRow = copy.bytesPerRow, | |
| .rowsPerImage = copy.rowsPerImage, | |
| }; | |
| } | |
| WGPUTexelCopyBufferInfo ToWGPU(const BufferCopy& copy, const TypedTexelBlockInfo& blockInfo) { | |
| return { | |
| .layout = | |
| { | |
| .offset = copy.offset, | |
| .bytesPerRow = static_cast<uint32_t>(blockInfo.ToBytes(copy.blocksPerRow)), | |
| .rowsPerImage = dchecked_cast<uint32_t>(copy.rowsPerImage), | |
| }, | |
| .buffer = ToBackend(copy.buffer)->GetInnerHandle(), | |
| }; | |
| } | |
| WGPUTexelCopyBufferInfo ToWGPU(const TexelCopyBufferLayout& copy, const BufferBase* buffer) { | |
| return { | |
| .layout = ToWGPU(copy), | |
| .buffer = ToBackend(buffer)->GetInnerHandle(), | |
| }; | |
| } | |
| WGPUTextureAspect ToWGPU(const Aspect aspect) { | |
| switch (aspect) { | |
| case Aspect::Depth: | |
| return WGPUTextureAspect_DepthOnly; | |
| case Aspect::Stencil: | |
| return WGPUTextureAspect_StencilOnly; | |
| case Aspect::Plane0: | |
| return WGPUTextureAspect_Plane0Only; | |
| case Aspect::Plane1: | |
| return WGPUTextureAspect_Plane1Only; | |
| case Aspect::Plane2: | |
| return WGPUTextureAspect_Plane2Only; | |
| default: | |
| return WGPUTextureAspect_All; | |
| } | |
| } | |
| WGPULoadOp ToWGPU(const wgpu::LoadOp op) { | |
| switch (op) { | |
| case wgpu::LoadOp::Load: | |
| return WGPULoadOp_Load; | |
| case wgpu::LoadOp::Clear: | |
| return WGPULoadOp_Clear; | |
| case wgpu::LoadOp::ExpandResolveTexture: | |
| return WGPULoadOp_ExpandResolveTexture; | |
| default: | |
| return WGPULoadOp_Undefined; | |
| } | |
| } | |
| WGPUStoreOp ToWGPU(const wgpu::StoreOp op) { | |
| switch (op) { | |
| case wgpu::StoreOp::Store: | |
| return WGPUStoreOp_Store; | |
| case wgpu::StoreOp::Discard: | |
| return WGPUStoreOp_Discard; | |
| default: | |
| return WGPUStoreOp_Undefined; | |
| } | |
| } | |
| WGPUIndexFormat ToWGPU(const wgpu::IndexFormat format) { | |
| switch (format) { | |
| case wgpu::IndexFormat::Uint16: | |
| return WGPUIndexFormat_Uint16; | |
| case wgpu::IndexFormat::Uint32: | |
| return WGPUIndexFormat_Uint32; | |
| default: | |
| return WGPUIndexFormat_Undefined; | |
| } | |
| } | |
| WGPUPassTimestampWrites ToWGPU(const TimestampWrites& writes) { | |
| return { | |
| .nextInChain = nullptr, | |
| .querySet = ToBackend(writes.querySet)->GetInnerHandle(), | |
| .beginningOfPassWriteIndex = uint32_t{writes.beginningOfPassWriteIndex}, | |
| .endOfPassWriteIndex = uint32_t{writes.endOfPassWriteIndex}, | |
| }; | |
| } | |
| WGPUTexelCopyTextureInfo ToWGPU(const TextureCopy& copy) { | |
| return { | |
| .texture = ToBackend(copy.texture)->GetInnerHandle(), | |
| .mipLevel = copy.mipLevel, | |
| .origin = ToWGPU(copy.origin), | |
| .aspect = ToWGPU(copy.aspect), | |
| }; | |
| } | |
| WGPURenderPassColorAttachment ToWGPU(const RenderPassColorAttachmentInfo& info) { | |
| return { | |
| .nextInChain = nullptr, | |
| .view = ToBackend(info.view)->GetInnerHandle(), | |
| // depthSlice is set to 0 for undefined in native::CommandEncoder. | |
| .depthSlice = | |
| info.depthSlice == 0 && info.view->GetDimension() != wgpu::TextureViewDimension::e3D | |
| ? WGPU_DEPTH_SLICE_UNDEFINED | |
| : info.depthSlice, | |
| .resolveTarget = info.resolveTarget == nullptr | |
| ? nullptr | |
| : ToBackend(info.resolveTarget)->GetInnerHandle(), | |
| .loadOp = ToWGPU(info.loadOp), | |
| .storeOp = ToWGPU(info.storeOp), | |
| .clearValue = ToWGPU(info.clearColor), | |
| }; | |
| } | |
| WGPURenderPassDepthStencilAttachment ToWGPU(const RenderPassDepthStencilAttachmentInfo& info) { | |
| // Depth and stencil op in info is set to default value is not explicitly assigned. | |
| // Avoid setting them if there's no such aspect or the aspect is read only. | |
| bool setDepthOp = !info.depthReadOnly && IsSubset(Aspect::Depth, info.view->GetAspects()); | |
| bool setStencilOp = !info.stencilReadOnly && IsSubset(Aspect::Stencil, info.view->GetAspects()); | |
| return { | |
| .nextInChain = nullptr, | |
| .view = info.view == nullptr ? nullptr : ToBackend(info.view)->GetInnerHandle(), | |
| .depthLoadOp = setDepthOp ? ToWGPU(info.depthLoadOp) : WGPULoadOp_Undefined, | |
| .depthStoreOp = setDepthOp ? ToWGPU(info.depthStoreOp) : WGPUStoreOp_Undefined, | |
| .depthClearValue = info.clearDepth, | |
| .depthReadOnly = info.depthReadOnly, | |
| .stencilLoadOp = setStencilOp ? ToWGPU(info.stencilLoadOp) : WGPULoadOp_Undefined, | |
| .stencilStoreOp = setStencilOp ? ToWGPU(info.stencilStoreOp) : WGPUStoreOp_Undefined, | |
| .stencilClearValue = info.clearStencil, | |
| .stencilReadOnly = info.stencilReadOnly, | |
| }; | |
| } | |
| WGPUStencilFaceState ToWGPU(const StencilFaceState* desc) { | |
| return { | |
| .compare = ToAPI(desc->compare), | |
| .failOp = ToAPI(desc->failOp), | |
| .depthFailOp = ToAPI(desc->depthFailOp), | |
| .passOp = ToAPI(desc->passOp), | |
| }; | |
| } | |
| WGPUDepthStencilState ToWGPU(const DepthStencilState* desc) { | |
| return { | |
| .nextInChain = nullptr, | |
| .format = ToAPI(desc->format), | |
| .depthWriteEnabled = desc->depthWriteEnabled, | |
| .depthCompare = ToAPI(desc->depthCompare), | |
| .stencilFront = ToWGPU(&desc->stencilFront), | |
| .stencilBack = ToWGPU(&desc->stencilBack), | |
| .stencilReadMask = desc->stencilReadMask, | |
| .stencilWriteMask = desc->stencilWriteMask, | |
| .depthBias = desc->depthBias, | |
| .depthBiasSlopeScale = desc->depthBiasSlopeScale, | |
| .depthBiasClamp = desc->depthBiasClamp, | |
| }; | |
| } | |
| WGPUPrimitiveState ToWGPU(const PrimitiveState* desc) { | |
| return { | |
| .nextInChain = nullptr, | |
| .topology = ToAPI(desc->topology), | |
| .stripIndexFormat = ToAPI(desc->stripIndexFormat), | |
| .frontFace = ToAPI(desc->frontFace), | |
| .cullMode = ToAPI(desc->cullMode), | |
| .unclippedDepth = desc->unclippedDepth, | |
| }; | |
| } | |
| WGPUMultisampleState ToWGPU(const MultisampleState* desc) { | |
| return { | |
| .nextInChain = nullptr, | |
| .count = desc->count, | |
| .mask = desc->mask, | |
| .alphaToCoverageEnabled = desc->alphaToCoverageEnabled, | |
| }; | |
| } | |
| WGPUBlendState ToWGPU(const BlendState* desc) { | |
| return { | |
| .color = | |
| { | |
| .operation = ToAPI(desc->color.operation), | |
| .srcFactor = ToAPI(desc->color.srcFactor), | |
| .dstFactor = ToAPI(desc->color.dstFactor), | |
| }, | |
| .alpha = | |
| { | |
| .operation = ToAPI(desc->alpha.operation), | |
| .srcFactor = ToAPI(desc->alpha.srcFactor), | |
| .dstFactor = ToAPI(desc->alpha.dstFactor), | |
| }, | |
| }; | |
| } | |
| void PopulateWGPUConstants(std::vector<WGPUConstantEntry>* constants, | |
| std::vector<std::string>* keys, | |
| const PipelineConstantEntries& entries) { | |
| keys->reserve(entries.size()); | |
| constants->reserve(entries.size()); | |
| for (const auto& [key, value] : entries) { | |
| keys->push_back(key); | |
| constants->push_back(WGPUConstantEntry{ | |
| .nextInChain = nullptr, | |
| .key = ToOutputStringView(keys->back()), | |
| .value = value, | |
| }); | |
| } | |
| } | |
| } // namespace dawn::native::webgpu |