tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ComputePassEncoder.cpp (5689B)


      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 "ComputePassEncoder.h"
      7 
      8 #include "BindGroup.h"
      9 #include "CommandEncoder.h"
     10 #include "ComputePipeline.h"
     11 #include "ExternalTexture.h"
     12 #include "Utility.h"
     13 #include "mozilla/dom/WebGPUBinding.h"
     14 #include "mozilla/webgpu/ffi/wgpu.h"
     15 
     16 namespace mozilla::webgpu {
     17 
     18 GPU_IMPL_CYCLE_COLLECTION(ComputePassEncoder, mParent, mUsedBindGroups,
     19                          mUsedBuffers, mUsedPipelines)
     20 GPU_IMPL_JS_WRAP(ComputePassEncoder)
     21 
     22 void ffiWGPUComputePassDeleter::operator()(ffi::WGPURecordedComputePass* raw) {
     23  if (raw) {
     24    ffi::wgpu_compute_pass_destroy(raw);
     25  }
     26 }
     27 
     28 ffi::WGPURecordedComputePass* BeginComputePass(
     29    RawId aEncoderId, const dom::GPUComputePassDescriptor& aDesc) {
     30  MOZ_RELEASE_ASSERT(aEncoderId);
     31  ffi::WGPUComputePassDescriptor desc = {};
     32 
     33  webgpu::StringHelper label(aDesc.mLabel);
     34  desc.label = label.Get();
     35 
     36  ffi::WGPUPassTimestampWrites passTimestampWrites = {};
     37  if (aDesc.mTimestampWrites.WasPassed()) {
     38    AssignPassTimestampWrites(aDesc.mTimestampWrites.Value(),
     39                              passTimestampWrites);
     40    desc.timestamp_writes = &passTimestampWrites;
     41  }
     42 
     43  return ffi::wgpu_command_encoder_begin_compute_pass(&desc);
     44 }
     45 
     46 ComputePassEncoder::ComputePassEncoder(
     47    CommandEncoder* const aParent, RawId aId,
     48    const dom::GPUComputePassDescriptor& aDesc)
     49    : ObjectBase(aParent->GetChild(), aId,
     50                 ffi::wgpu_client_drop_compute_pass_encoder),
     51      ChildOf(aParent),
     52      mPass(BeginComputePass(aParent->GetId(), aDesc)) {}
     53 
     54 ComputePassEncoder::~ComputePassEncoder() = default;
     55 
     56 void ComputePassEncoder::SetBindGroup(uint32_t aSlot,
     57                                      BindGroup* const aBindGroup,
     58                                      const uint32_t* aDynamicOffsets,
     59                                      size_t aDynamicOffsetsLength) {
     60  RawId bindGroup = 0;
     61  if (aBindGroup) {
     62    mUsedBindGroups.AppendElement(aBindGroup);
     63    mUsedCanvasContexts.AppendElements(aBindGroup->GetCanvasContexts());
     64    bindGroup = aBindGroup->GetId();
     65  }
     66  ffi::wgpu_recorded_compute_pass_set_bind_group(
     67      mPass.get(), aSlot, bindGroup, {aDynamicOffsets, aDynamicOffsetsLength});
     68 }
     69 
     70 void ComputePassEncoder::SetBindGroup(
     71    uint32_t aSlot, BindGroup* const aBindGroup,
     72    const dom::Sequence<uint32_t>& aDynamicOffsets, ErrorResult& aRv) {
     73  if (!mValid) {
     74    return;
     75  }
     76  this->SetBindGroup(aSlot, aBindGroup, aDynamicOffsets.Elements(),
     77                     aDynamicOffsets.Length());
     78 }
     79 
     80 void ComputePassEncoder::SetBindGroup(
     81    uint32_t aSlot, BindGroup* const aBindGroup,
     82    const dom::Uint32Array& aDynamicOffsetsData,
     83    uint64_t aDynamicOffsetsDataStart, uint64_t aDynamicOffsetsDataLength,
     84    ErrorResult& aRv) {
     85  if (!mValid) {
     86    return;
     87  }
     88 
     89  auto dynamicOffsets =
     90      GetDynamicOffsetsFromArray(aDynamicOffsetsData, aDynamicOffsetsDataStart,
     91                                 aDynamicOffsetsDataLength, aRv);
     92 
     93  if (dynamicOffsets.isSome()) {
     94    this->SetBindGroup(aSlot, aBindGroup, dynamicOffsets->Elements(),
     95                       dynamicOffsets->Length());
     96  }
     97 }
     98 
     99 void ComputePassEncoder::SetPipeline(const ComputePipeline& aPipeline) {
    100  if (!mValid) {
    101    return;
    102  }
    103  mUsedPipelines.AppendElement(&aPipeline);
    104  ffi::wgpu_recorded_compute_pass_set_pipeline(mPass.get(), aPipeline.GetId());
    105 }
    106 
    107 void ComputePassEncoder::DispatchWorkgroups(uint32_t workgroupCountX,
    108                                            uint32_t workgroupCountY,
    109                                            uint32_t workgroupCountZ) {
    110  if (!mValid) {
    111    return;
    112  }
    113  ffi::wgpu_recorded_compute_pass_dispatch_workgroups(
    114      mPass.get(), workgroupCountX, workgroupCountY, workgroupCountZ);
    115 }
    116 
    117 void ComputePassEncoder::DispatchWorkgroupsIndirect(
    118    const Buffer& aIndirectBuffer, uint64_t aIndirectOffset) {
    119  if (!mValid) {
    120    return;
    121  }
    122  mUsedBuffers.AppendElement(&aIndirectBuffer);
    123  ffi::wgpu_recorded_compute_pass_dispatch_workgroups_indirect(
    124      mPass.get(), aIndirectBuffer.GetId(), aIndirectOffset);
    125 }
    126 
    127 void ComputePassEncoder::PushDebugGroup(const nsAString& aString) {
    128  if (!mValid) {
    129    return;
    130  }
    131  const NS_ConvertUTF16toUTF8 utf8(aString);
    132  ffi::wgpu_recorded_compute_pass_push_debug_group(mPass.get(), utf8.get(), 0);
    133 }
    134 void ComputePassEncoder::PopDebugGroup() {
    135  if (!mValid) {
    136    return;
    137  }
    138  ffi::wgpu_recorded_compute_pass_pop_debug_group(mPass.get());
    139 }
    140 void ComputePassEncoder::InsertDebugMarker(const nsAString& aString) {
    141  if (!mValid) {
    142    return;
    143  }
    144  const NS_ConvertUTF16toUTF8 utf8(aString);
    145  ffi::wgpu_recorded_compute_pass_insert_debug_marker(mPass.get(), utf8.get(),
    146                                                      0);
    147 }
    148 
    149 void ComputePassEncoder::End() {
    150  if (mParent->GetState() != CommandEncoderState::Locked) {
    151    const auto* message = "Encoding must not have ended";
    152    ffi::wgpu_report_validation_error(GetClient(),
    153                                      mParent->GetDevice()->GetId(), message);
    154  }
    155  if (!mValid) {
    156    return;
    157  }
    158  nsTArray<RefPtr<ExternalTexture>> externalTextures;
    159  for (const auto& bindGroup : mUsedBindGroups) {
    160    externalTextures.AppendElements(bindGroup->GetExternalTextures());
    161  }
    162  MOZ_ASSERT(!!mPass);
    163  mParent->EndComputePass(*mPass, mUsedCanvasContexts, externalTextures);
    164 
    165  mValid = false;
    166  mPass.release();
    167  mUsedBindGroups.Clear();
    168  mUsedBuffers.Clear();
    169  mUsedPipelines.Clear();
    170 }
    171 
    172 }  // namespace mozilla::webgpu