Files
firefox/dom/webgpu/ComputePassEncoder.cpp
T
Brad Werth f3e24d843c Bug 1925398 Part 1: Restore WebGPU encoder cycle collection, fix Cleanup(). r=teoxoy
Cleanup() should not call End(), because doing so exposes us to timing
dependencies on the cycle collection. Specifically, as noted in the
patches for Bug 1907457, cycle collection of encoders and their
resources could result in the resource getting destructed before the
encoder. Bug 1907457 "fixed" that by allowing cycles. This patch instead
fixes it by changing encoder Cleanup() to just tidy up resources and not
attempt to complete the work of the encoder by passing it to wgpu.

This also removes mUsedTextureViews from the RenderBundleEncoder, as it
is unused. RenderBundleEncoders have no reliance on TextureViews.

Differential Revision: https://phabricator.services.mozilla.com/D226200
2024-10-23 22:15:23 +00:00

125 lines
3.7 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/WebGPUBinding.h"
#include "ComputePassEncoder.h"
#include "BindGroup.h"
#include "ComputePipeline.h"
#include "CommandEncoder.h"
#include "mozilla/webgpu/ffi/wgpu.h"
namespace mozilla::webgpu {
GPU_IMPL_CYCLE_COLLECTION(ComputePassEncoder, mParent, mUsedBindGroups,
mUsedPipelines)
GPU_IMPL_JS_WRAP(ComputePassEncoder)
void ffiWGPUComputePassDeleter::operator()(ffi::WGPURecordedComputePass* raw) {
if (raw) {
ffi::wgpu_compute_pass_destroy(raw);
}
}
ffi::WGPURecordedComputePass* BeginComputePass(
RawId aEncoderId, const dom::GPUComputePassDescriptor& aDesc) {
MOZ_RELEASE_ASSERT(aEncoderId);
ffi::WGPUComputePassDescriptor desc = {};
webgpu::StringHelper label(aDesc.mLabel);
desc.label = label.Get();
return ffi::wgpu_command_encoder_begin_compute_pass(&desc);
}
ComputePassEncoder::ComputePassEncoder(
CommandEncoder* const aParent, const dom::GPUComputePassDescriptor& aDesc)
: ChildOf(aParent), mPass(BeginComputePass(aParent->mId, aDesc)) {}
ComputePassEncoder::~ComputePassEncoder() { Cleanup(); }
void ComputePassEncoder::Cleanup() {
mValid = false;
mPass.release();
mUsedBindGroups.Clear();
mUsedPipelines.Clear();
}
void ComputePassEncoder::SetBindGroup(
uint32_t aSlot, BindGroup* const aBindGroup,
const dom::Sequence<uint32_t>& aDynamicOffsets) {
if (!mValid) {
return;
}
RawId bindGroup = 0;
if (aBindGroup) {
mUsedBindGroups.AppendElement(aBindGroup);
bindGroup = aBindGroup->mId;
}
ffi::wgpu_recorded_compute_pass_set_bind_group(mPass.get(), aSlot, bindGroup,
aDynamicOffsets.Elements(),
aDynamicOffsets.Length());
}
void ComputePassEncoder::SetPipeline(const ComputePipeline& aPipeline) {
if (!mValid) {
return;
}
mUsedPipelines.AppendElement(&aPipeline);
ffi::wgpu_recorded_compute_pass_set_pipeline(mPass.get(), aPipeline.mId);
}
void ComputePassEncoder::DispatchWorkgroups(uint32_t workgroupCountX,
uint32_t workgroupCountY,
uint32_t workgroupCountZ) {
if (!mValid) {
return;
}
ffi::wgpu_recorded_compute_pass_dispatch_workgroups(
mPass.get(), workgroupCountX, workgroupCountY, workgroupCountZ);
}
void ComputePassEncoder::DispatchWorkgroupsIndirect(
const Buffer& aIndirectBuffer, uint64_t aIndirectOffset) {
if (!mValid) {
return;
}
ffi::wgpu_recorded_compute_pass_dispatch_workgroups_indirect(
mPass.get(), aIndirectBuffer.mId, aIndirectOffset);
}
void ComputePassEncoder::PushDebugGroup(const nsAString& aString) {
if (!mValid) {
return;
}
const NS_ConvertUTF16toUTF8 utf8(aString);
ffi::wgpu_recorded_compute_pass_push_debug_group(mPass.get(), utf8.get(), 0);
}
void ComputePassEncoder::PopDebugGroup() {
if (!mValid) {
return;
}
ffi::wgpu_recorded_compute_pass_pop_debug_group(mPass.get());
}
void ComputePassEncoder::InsertDebugMarker(const nsAString& aString) {
if (!mValid) {
return;
}
const NS_ConvertUTF16toUTF8 utf8(aString);
ffi::wgpu_recorded_compute_pass_insert_debug_marker(mPass.get(), utf8.get(),
0);
}
void ComputePassEncoder::End() {
if (!mValid) {
return;
}
MOZ_ASSERT(!!mPass);
mParent->EndComputePass(*mPass);
Cleanup();
}
} // namespace mozilla::webgpu