blob: 53c04faf29da7329355a5fb262802a37e54a25bf [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle_encoder.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_descriptor.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_render_bundle_encoder_descriptor.h"
#include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_bind_group.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_buffer.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_device.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_render_bundle.h"
#include "third_party/blink/renderer/modules/webgpu/gpu_render_pipeline.h"
#include "third_party/blink/renderer/platform/heap/heap.h"
namespace blink {
// static
GPURenderBundleEncoder* GPURenderBundleEncoder::Create(
GPUDevice* device,
const GPURenderBundleEncoderDescriptor* webgpu_desc) {
uint32_t color_formats_count =
static_cast<uint32_t>(webgpu_desc->colorFormats().size());
std::unique_ptr<WGPUTextureFormat[]> color_formats =
AsDawnEnum<WGPUTextureFormat>(webgpu_desc->colorFormats());
WGPUTextureFormat depth_stencil_format = WGPUTextureFormat_Undefined;
if (webgpu_desc->hasDepthStencilFormat()) {
depth_stencil_format =
AsDawnEnum<WGPUTextureFormat>(webgpu_desc->depthStencilFormat());
}
std::string label;
WGPURenderBundleEncoderDescriptor dawn_desc = {};
dawn_desc.nextInChain = nullptr;
dawn_desc.colorFormatsCount = color_formats_count;
dawn_desc.colorFormats = color_formats.get();
dawn_desc.depthStencilFormat = depth_stencil_format;
dawn_desc.sampleCount = webgpu_desc->sampleCount();
if (webgpu_desc->hasLabel()) {
label = webgpu_desc->label().Utf8();
dawn_desc.label = label.c_str();
}
GPURenderBundleEncoder* encoder =
MakeGarbageCollected<GPURenderBundleEncoder>(
device, device->GetProcs().deviceCreateRenderBundleEncoder(
device->GetHandle(), &dawn_desc));
encoder->setLabel(webgpu_desc->label());
return encoder;
}
GPURenderBundleEncoder::GPURenderBundleEncoder(
GPUDevice* device,
WGPURenderBundleEncoder render_bundle_encoder)
: DawnObject<WGPURenderBundleEncoder>(device, render_bundle_encoder) {}
void GPURenderBundleEncoder::setBindGroup(uint32_t index,
GPUBindGroup* bindGroup) {
GetProcs().renderBundleEncoderSetBindGroup(
GetHandle(), index, bindGroup->GetHandle(), 0, nullptr);
}
void GPURenderBundleEncoder::setBindGroup(
uint32_t index,
GPUBindGroup* bindGroup,
const Vector<uint32_t>& dynamicOffsets) {
GetProcs().renderBundleEncoderSetBindGroup(
GetHandle(), index, bindGroup->GetHandle(), dynamicOffsets.size(),
dynamicOffsets.data());
}
void GPURenderBundleEncoder::setBindGroup(
uint32_t index,
GPUBindGroup* bind_group,
const FlexibleUint32Array& dynamic_offsets_data,
uint64_t dynamic_offsets_data_start,
uint32_t dynamic_offsets_data_length,
ExceptionState& exception_state) {
if (!ValidateSetBindGroupDynamicOffsets(
dynamic_offsets_data, dynamic_offsets_data_start,
dynamic_offsets_data_length, exception_state)) {
return;
}
const uint32_t* data =
dynamic_offsets_data.DataMaybeOnStack() + dynamic_offsets_data_start;
GetProcs().renderBundleEncoderSetBindGroup(GetHandle(), index,
bind_group->GetHandle(),
dynamic_offsets_data_length, data);
}
void GPURenderBundleEncoder::pushDebugGroup(String groupLabel) {
std::string label = groupLabel.Utf8();
GetProcs().renderBundleEncoderPushDebugGroup(GetHandle(), label.c_str());
}
void GPURenderBundleEncoder::popDebugGroup() {
GetProcs().renderBundleEncoderPopDebugGroup(GetHandle());
}
void GPURenderBundleEncoder::insertDebugMarker(String markerLabel) {
std::string label = markerLabel.Utf8();
GetProcs().renderBundleEncoderInsertDebugMarker(GetHandle(), label.c_str());
}
void GPURenderBundleEncoder::setPipeline(GPURenderPipeline* pipeline) {
GetProcs().renderBundleEncoderSetPipeline(GetHandle(), pipeline->GetHandle());
}
void GPURenderBundleEncoder::setIndexBuffer(GPUBuffer* buffer,
const V8GPUIndexFormat& format,
uint64_t offset,
uint64_t size) {
GetProcs().renderBundleEncoderSetIndexBufferWithFormat(
GetHandle(), buffer->GetHandle(), AsDawnEnum(format), offset, size);
}
void GPURenderBundleEncoder::setVertexBuffer(uint32_t slot,
const GPUBuffer* buffer,
uint64_t offset,
uint64_t size) {
GetProcs().renderBundleEncoderSetVertexBuffer(
GetHandle(), slot, buffer->GetHandle(), offset, size);
}
void GPURenderBundleEncoder::draw(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance) {
GetProcs().renderBundleEncoderDraw(GetHandle(), vertexCount, instanceCount,
firstVertex, firstInstance);
}
void GPURenderBundleEncoder::draw(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
uint32_t firstInstance,
v8::FastApiCallbackOptions& options) {
draw(vertexCount, instanceCount, firstVertex, firstInstance);
}
void GPURenderBundleEncoder::drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t baseVertex,
uint32_t firstInstance) {
GetProcs().renderBundleEncoderDrawIndexed(GetHandle(), indexCount,
instanceCount, firstIndex,
baseVertex, firstInstance);
}
void GPURenderBundleEncoder::drawIndexed(uint32_t indexCount,
uint32_t instanceCount,
uint32_t firstIndex,
int32_t baseVertex,
uint32_t firstInstance,
v8::FastApiCallbackOptions& options) {
drawIndexed(indexCount, instanceCount, firstIndex, baseVertex, firstInstance);
}
void GPURenderBundleEncoder::drawIndirect(GPUBuffer* indirectBuffer,
uint64_t indirectOffset) {
GetProcs().renderBundleEncoderDrawIndirect(
GetHandle(), indirectBuffer->GetHandle(), indirectOffset);
}
void GPURenderBundleEncoder::drawIndexedIndirect(GPUBuffer* indirectBuffer,
uint64_t indirectOffset) {
GetProcs().renderBundleEncoderDrawIndexedIndirect(
GetHandle(), indirectBuffer->GetHandle(), indirectOffset);
}
GPURenderBundle* GPURenderBundleEncoder::finish(
const GPURenderBundleDescriptor* webgpu_desc) {
std::string label;
WGPURenderBundleDescriptor dawn_desc = {};
dawn_desc.nextInChain = nullptr;
if (webgpu_desc->hasLabel()) {
label = webgpu_desc->label().Utf8();
dawn_desc.label = label.c_str();
}
WGPURenderBundle render_bundle =
GetProcs().renderBundleEncoderFinish(GetHandle(), &dawn_desc);
return MakeGarbageCollected<GPURenderBundle>(device_, render_bundle);
}
} // namespace blink