1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "mozilla/dom/WebGPUBinding.h"
7 #include "ComputePassEncoder.h"
8 #include "BindGroup.h"
9 #include "ComputePipeline.h"
10 #include "CommandEncoder.h"
11 
12 #include "mozilla/webgpu/ffi/wgpu.h"
13 
14 namespace mozilla {
15 namespace webgpu {
16 
GPU_IMPL_CYCLE_COLLECTION(ComputePassEncoder,mParent,mUsedBindGroups,mUsedPipelines)17 GPU_IMPL_CYCLE_COLLECTION(ComputePassEncoder, mParent, mUsedBindGroups,
18                           mUsedPipelines)
19 GPU_IMPL_JS_WRAP(ComputePassEncoder)
20 
21 ffi::WGPUComputePass* ScopedFfiComputeTraits::empty() { return nullptr; }
22 
release(ffi::WGPUComputePass * raw)23 void ScopedFfiComputeTraits::release(ffi::WGPUComputePass* raw) {
24   if (raw) {
25     ffi::wgpu_compute_pass_destroy(raw);
26   }
27 }
28 
BeginComputePass(RawId aEncoderId,const dom::GPUComputePassDescriptor & aDesc)29 ffi::WGPUComputePass* BeginComputePass(
30     RawId aEncoderId, const dom::GPUComputePassDescriptor& aDesc) {
31   ffi::WGPUComputePassDescriptor desc = {};
32   Unused << aDesc;  // no useful fields
33   return ffi::wgpu_command_encoder_begin_compute_pass(aEncoderId, &desc);
34 }
35 
ComputePassEncoder(CommandEncoder * const aParent,const dom::GPUComputePassDescriptor & aDesc)36 ComputePassEncoder::ComputePassEncoder(
37     CommandEncoder* const aParent, const dom::GPUComputePassDescriptor& aDesc)
38     : ChildOf(aParent), mPass(BeginComputePass(aParent->mId, aDesc)) {}
39 
~ComputePassEncoder()40 ComputePassEncoder::~ComputePassEncoder() {
41   if (mValid) {
42     mValid = false;
43   }
44 }
45 
SetBindGroup(uint32_t aSlot,const BindGroup & aBindGroup,const dom::Sequence<uint32_t> & aDynamicOffsets)46 void ComputePassEncoder::SetBindGroup(
47     uint32_t aSlot, const BindGroup& aBindGroup,
48     const dom::Sequence<uint32_t>& aDynamicOffsets) {
49   if (mValid) {
50     mUsedBindGroups.AppendElement(&aBindGroup);
51     ffi::wgpu_compute_pass_set_bind_group(mPass, aSlot, aBindGroup.mId,
52                                           aDynamicOffsets.Elements(),
53                                           aDynamicOffsets.Length());
54   }
55 }
56 
SetPipeline(const ComputePipeline & aPipeline)57 void ComputePassEncoder::SetPipeline(const ComputePipeline& aPipeline) {
58   if (mValid) {
59     mUsedPipelines.AppendElement(&aPipeline);
60     ffi::wgpu_compute_pass_set_pipeline(mPass, aPipeline.mId);
61   }
62 }
63 
Dispatch(uint32_t x,uint32_t y,uint32_t z)64 void ComputePassEncoder::Dispatch(uint32_t x, uint32_t y, uint32_t z) {
65   if (mValid) {
66     ffi::wgpu_compute_pass_dispatch(mPass, x, y, z);
67   }
68 }
69 
DispatchIndirect(const Buffer & aIndirectBuffer,uint64_t aIndirectOffset)70 void ComputePassEncoder::DispatchIndirect(const Buffer& aIndirectBuffer,
71                                           uint64_t aIndirectOffset) {
72   if (mValid) {
73     ffi::wgpu_compute_pass_dispatch_indirect(mPass, aIndirectBuffer.mId,
74                                              aIndirectOffset);
75   }
76 }
77 
PushDebugGroup(const nsAString & aString)78 void ComputePassEncoder::PushDebugGroup(const nsAString& aString) {
79   if (mValid) {
80     const NS_ConvertUTF16toUTF8 utf8(aString);
81     ffi::wgpu_compute_pass_push_debug_group(mPass, utf8.get(), 0);
82   }
83 }
PopDebugGroup()84 void ComputePassEncoder::PopDebugGroup() {
85   if (mValid) {
86     ffi::wgpu_compute_pass_pop_debug_group(mPass);
87   }
88 }
InsertDebugMarker(const nsAString & aString)89 void ComputePassEncoder::InsertDebugMarker(const nsAString& aString) {
90   if (mValid) {
91     const NS_ConvertUTF16toUTF8 utf8(aString);
92     ffi::wgpu_compute_pass_insert_debug_marker(mPass, utf8.get(), 0);
93   }
94 }
95 
EndPass(ErrorResult & aRv)96 void ComputePassEncoder::EndPass(ErrorResult& aRv) {
97   if (mValid) {
98     mValid = false;
99     auto* pass = mPass.forget();
100     MOZ_ASSERT(pass);
101     mParent->EndComputePass(*pass, aRv);
102   }
103 }
104 
105 }  // namespace webgpu
106 }  // namespace mozilla
107