The encoder classes already have strong references to the resources they rely upon. That is enough to prevent those resources from being released before the encoder. That's all we need! Including the resources in cycle checking is just making it possible for the resource and the encoder to be unlinked in the same cycle, in arbitrary order. That's dangerous because it's the same outcome as if the encoder didn't have a strong reference to the resource at all. Differential Revision: https://phabricator.services.mozilla.com/D225914
123 lines
3.6 KiB
C++
123 lines
3.6 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)
|
|
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() {
|
|
if (mValid) {
|
|
End();
|
|
}
|
|
}
|
|
|
|
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) {
|
|
mValid = false;
|
|
auto* pass = mPass.release();
|
|
MOZ_ASSERT(pass);
|
|
mParent->EndComputePass(*pass);
|
|
}
|
|
}
|
|
|
|
} // namespace mozilla::webgpu
|