From 1f3f5df6810adfd8c37ce25fb3c22c92a4e9bf02 Mon Sep 17 00:00:00 2001 From: Jiawei Shao Date: Fri, 6 Sep 2024 00:59:21 +0000 Subject: [PATCH] Support validating buffer usage with usage validation mode This patch adds `UsageValidationMode` as the third parameter of `ValidateCanUseAs` with a buffer as input to align with the format of the function `ValidateCanUseAs` with a texture as input. This patch also updates the test `InternalStorageBufferBindingTests` by using classes in `native::` instead of the `wgpu::` to better test the `internal usage` of the buffers. Bug: chromium:42240463 Test: dawn_unittests Change-Id: I2db2c922555ded050949da20828be17c95499152 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/204914 Commit-Queue: Jiawei Shao Reviewed-by: Corentin Wallez --- src/dawn/native/BindGroup.cpp | 10 +- src/dawn/native/CommandEncoder.cpp | 37 ++++--- src/dawn/native/CommandValidation.cpp | 31 +++--- src/dawn/native/CommandValidation.h | 8 +- src/dawn/native/ComputePassEncoder.cpp | 5 +- .../native/IndirectDrawValidationEncoder.cpp | 6 +- src/dawn/native/Queue.cpp | 3 +- src/dawn/native/RenderEncoderBase.cpp | 48 +++++++-- .../InternalStorageBufferBindingTests.cpp | 98 ++++++++++--------- 9 files changed, 152 insertions(+), 94 deletions(-) diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp index b397bf454e0..2f31c8b1615 100644 --- a/src/dawn/native/BindGroup.cpp +++ b/src/dawn/native/BindGroup.cpp @@ -51,7 +51,8 @@ namespace { MaybeError ValidateBufferBinding(const DeviceBase* device, const BindGroupEntry& entry, - const BufferBindingInfo& layout) { + const BufferBindingInfo& layout, + UsageValidationMode mode) { DAWN_INVALID_IF(entry.buffer == nullptr, "Binding entry buffer not set."); DAWN_INVALID_IF(entry.sampler != nullptr || entry.textureView != nullptr, @@ -115,9 +116,7 @@ MaybeError ValidateBufferBinding(const DeviceBase* device, "Offset (%u) of %s does not satisfy the minimum %s alignment (%u).", entry.offset, entry.buffer, layout.type, requiredBindingAlignment); - DAWN_INVALID_IF(!(entry.buffer->GetInternalUsage() & requiredUsage), - "Binding usage (%s) of %s doesn't match expected usage (%s).", - entry.buffer->GetUsage(), entry.buffer, requiredUsage); + DAWN_TRY(ValidateCanUseAs(entry.buffer, requiredUsage, mode)); DAWN_INVALID_IF(bindingSize < layout.minBindingSize, "Binding size (%u) of %s is smaller than the minimum binding size (%u).", @@ -376,8 +375,7 @@ MaybeError ValidateBindGroupDescriptor(DeviceBase* device, DAWN_TRY(MatchVariant( bindingInfo.bindingLayout, [&](const BufferBindingInfo& layout) -> MaybeError { - // TODO(dawn:1485): Validate buffer binding with usage validation mode. - DAWN_TRY_CONTEXT(ValidateBufferBinding(device, entry, layout), + DAWN_TRY_CONTEXT(ValidateBufferBinding(device, entry, layout, mode), "validating entries[%u] as a Buffer." "\nExpected entry layout: %s", i, layout); diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp index 3ded74ad756..468268b3565 100644 --- a/src/dawn/native/CommandEncoder.cpp +++ b/src/dawn/native/CommandEncoder.cpp @@ -1452,10 +1452,12 @@ void CommandEncoder::APICopyBufferToBuffer(BufferBase* source, "validating destination %s copy size.", destination); DAWN_TRY(ValidateB2BCopyAlignment(size, sourceOffset, destinationOffset)); - DAWN_TRY_CONTEXT(ValidateCanUseAs(source, wgpu::BufferUsage::CopySrc), - "validating source %s usage.", source); - DAWN_TRY_CONTEXT(ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst), - "validating destination %s usage.", destination); + DAWN_TRY_CONTEXT( + ValidateCanUseAs(source, wgpu::BufferUsage::CopySrc, mUsageValidationMode), + "validating source %s usage.", source); + DAWN_TRY_CONTEXT( + ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst, mUsageValidationMode), + "validating destination %s usage.", destination); } mTopLevelBuffers.insert(source); @@ -1501,10 +1503,12 @@ void CommandEncoder::InternalCopyBufferToBufferWithAllocatedSize(BufferBase* sou destination); DAWN_TRY(ValidateB2BCopyAlignment(size, sourceOffset, destinationOffset)); - DAWN_TRY_CONTEXT(ValidateCanUseAsInternal( - source, wgpu::BufferUsage::CopySrc | kInternalCopySrcBuffer), - "validating source %s usage.", source); - DAWN_TRY_CONTEXT(ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst), + DAWN_TRY_CONTEXT( + ValidateCanUseAs(source, wgpu::BufferUsage::CopySrc | kInternalCopySrcBuffer, + UsageValidationMode::Internal), + "validating source %s usage.", source); + DAWN_TRY_CONTEXT(ValidateCanUseAs(destination, wgpu::BufferUsage::CopyDst, + UsageValidationMode::Internal), "validating destination %s usage.", destination); } @@ -1535,7 +1539,8 @@ void CommandEncoder::APICopyBufferToTexture(const ImageCopyBuffer* source, [&](CommandAllocator* allocator) -> MaybeError { if (GetDevice()->IsValidationEnabled()) { DAWN_TRY(ValidateImageCopyBuffer(GetDevice(), *source)); - DAWN_TRY_CONTEXT(ValidateCanUseAs(source->buffer, wgpu::BufferUsage::CopySrc), + DAWN_TRY_CONTEXT(ValidateCanUseAs(source->buffer, wgpu::BufferUsage::CopySrc, + mUsageValidationMode), "validating source %s usage.", source->buffer); DAWN_TRY(ValidateImageCopyTexture(GetDevice(), destination, *copySize)); @@ -1631,7 +1636,8 @@ void CommandEncoder::APICopyTextureToBuffer(const ImageCopyTexture* sourceOrig, DAWN_TRY(ValidateTextureDepthStencilToBufferCopyRestrictions(source)); DAWN_TRY(ValidateImageCopyBuffer(GetDevice(), *destination)); - DAWN_TRY_CONTEXT(ValidateCanUseAs(destination->buffer, wgpu::BufferUsage::CopyDst), + DAWN_TRY_CONTEXT(ValidateCanUseAs(destination->buffer, wgpu::BufferUsage::CopyDst, + mUsageValidationMode), "validating destination %s usage.", destination->buffer); // We validate texture copy range before validating linear texture data, @@ -1862,8 +1868,9 @@ void CommandEncoder::APIClearBuffer(BufferBase* buffer, uint64_t offset, uint64_ offset, size, bufferSize, buffer); } - DAWN_TRY_CONTEXT(ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst), - "validating buffer %s usage.", buffer); + DAWN_TRY_CONTEXT( + ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst, mUsageValidationMode), + "validating buffer %s usage.", buffer); // Size must be a multiple of 4 bytes on macOS. DAWN_INVALID_IF(size % 4 != 0, "Fill size (%u) is not a multiple of 4 bytes.", @@ -1967,7 +1974,8 @@ void CommandEncoder::APIResolveQuerySet(QuerySetBase* querySet, DAWN_TRY(ValidateQuerySetResolve(querySet, firstQuery, queryCount, destination, destinationOffset)); - DAWN_TRY(ValidateCanUseAs(destination, wgpu::BufferUsage::QueryResolve)); + DAWN_TRY(ValidateCanUseAs(destination, wgpu::BufferUsage::QueryResolve, + mUsageValidationMode)); TrackUsedQuerySet(querySet); } @@ -2008,7 +2016,8 @@ void CommandEncoder::APIWriteBuffer(BufferBase* buffer, this, [&](CommandAllocator* allocator) -> MaybeError { if (GetDevice()->IsValidationEnabled()) { - DAWN_TRY(ValidateWriteBuffer(GetDevice(), buffer, bufferOffset, size)); + DAWN_TRY(ValidateWriteBuffer(GetDevice(), buffer, bufferOffset, size, + mUsageValidationMode)); } WriteBufferCmd* cmd = allocator->Allocate(Command::WriteBuffer); diff --git a/src/dawn/native/CommandValidation.cpp b/src/dawn/native/CommandValidation.cpp index 7bd537ad1b1..d9c6f995ace 100644 --- a/src/dawn/native/CommandValidation.cpp +++ b/src/dawn/native/CommandValidation.cpp @@ -223,7 +223,8 @@ MaybeError ValidatePassTimestampWrites(const DeviceBase* device, MaybeError ValidateWriteBuffer(const DeviceBase* device, const BufferBase* buffer, uint64_t bufferOffset, - uint64_t size) { + uint64_t size, + UsageValidationMode mode) { DAWN_TRY(device->ValidateObject(buffer)); DAWN_INVALID_IF(bufferOffset % 4 != 0, "BufferOffset (%u) is not a multiple of 4.", @@ -236,7 +237,7 @@ MaybeError ValidateWriteBuffer(const DeviceBase* device, "Write range (bufferOffset: %u, size: %u) does not fit in %s size (%u).", bufferOffset, size, buffer, bufferSize); - DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst)); + DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::CopyDst, mode)); return {}; } @@ -648,17 +649,21 @@ MaybeError ValidateCanUseAs(const TextureBase* texture, return {}; } -MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage) { - DAWN_ASSERT(wgpu::HasZeroOrOneBits(usage)); - DAWN_INVALID_IF(!(buffer->GetUsage() & usage), "%s usage (%s) doesn't include %s.", buffer, - buffer->GetUsage(), usage); - return {}; -} - -MaybeError ValidateCanUseAsInternal(const BufferBase* buffer, wgpu::BufferUsage usage) { - DAWN_INVALID_IF(!(buffer->GetInternalUsage() & usage), - "%s internal usage (%s) doesn't include %s.", buffer, - buffer->GetInternalUsage(), usage); +MaybeError ValidateCanUseAs(const BufferBase* buffer, + wgpu::BufferUsage usage, + UsageValidationMode mode) { + switch (mode) { + case UsageValidationMode::Default: + DAWN_ASSERT(wgpu::HasZeroOrOneBits(usage)); + DAWN_INVALID_IF(!(buffer->GetUsage() & usage), "%s usage (%s) doesn't include %s.", + buffer, buffer->GetUsage(), usage); + break; + case UsageValidationMode::Internal: + DAWN_INVALID_IF(!(buffer->GetInternalUsage() & usage), + "%s internal usage (%s) doesn't include %s.", buffer, + buffer->GetInternalUsage(), usage); + break; + } return {}; } diff --git a/src/dawn/native/CommandValidation.h b/src/dawn/native/CommandValidation.h index 36e737ff24e..3afd684d939 100644 --- a/src/dawn/native/CommandValidation.h +++ b/src/dawn/native/CommandValidation.h @@ -61,7 +61,8 @@ MaybeError ValidatePassTimestampWrites(const DeviceBase* device, MaybeError ValidateWriteBuffer(const DeviceBase* device, const BufferBase* buffer, uint64_t bufferOffset, - uint64_t size); + uint64_t size, + UsageValidationMode mode); template DAWN_FORCE_INLINE uint64_t Safe32x32(A a, B b) { @@ -113,8 +114,9 @@ MaybeError ValidateTextureToTextureCopyRestrictions(DeviceBase const* device, MaybeError ValidateCanUseAs(const TextureBase* texture, wgpu::TextureUsage usage, UsageValidationMode mode); -MaybeError ValidateCanUseAs(const BufferBase* buffer, wgpu::BufferUsage usage); -MaybeError ValidateCanUseAsInternal(const BufferBase* buffer, wgpu::BufferUsage usage); +MaybeError ValidateCanUseAs(const BufferBase* buffer, + wgpu::BufferUsage usage, + UsageValidationMode mode); using ColorAttachmentFormats = absl::InlinedVector; MaybeError ValidateColorAttachmentBytesPerSample(DeviceBase* device, diff --git a/src/dawn/native/ComputePassEncoder.cpp b/src/dawn/native/ComputePassEncoder.cpp index fb76d7f835b..f25767bd7ba 100644 --- a/src/dawn/native/ComputePassEncoder.cpp +++ b/src/dawn/native/ComputePassEncoder.cpp @@ -352,7 +352,10 @@ void ComputePassEncoder::APIDispatchWorkgroupsIndirect(BufferBase* indirectBuffe [&](CommandAllocator* allocator) -> MaybeError { if (IsValidationEnabled()) { DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); - DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with the usage validation + // mode of mCommandEncoder + DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_TRY(mCommandBufferState.ValidateCanDispatch()); DAWN_INVALID_IF(indirectOffset % 4 != 0, diff --git a/src/dawn/native/IndirectDrawValidationEncoder.cpp b/src/dawn/native/IndirectDrawValidationEncoder.cpp index e373d9c3dd6..b9c4c5f53ea 100644 --- a/src/dawn/native/IndirectDrawValidationEncoder.cpp +++ b/src/dawn/native/IndirectDrawValidationEncoder.cpp @@ -722,7 +722,8 @@ MaybeError EncodeIndirectDrawValidationCommands(DeviceBase* device, outputParamsBinding.size = batch.outputParamsSize; Ref bindGroup; - DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bindGroupDescriptor)); + DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bindGroupDescriptor, + UsageValidationMode::Internal)); const uint32_t numDrawsRoundedUp = (batch.batchInfo->numDraws + kWorkgroupSize - 1) / kWorkgroupSize; @@ -846,7 +847,8 @@ MaybeError EncodeIndirectDrawValidationCommands(DeviceBase* device, } Ref bindGroup; - DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bindGroupDescriptor)); + DAWN_TRY_ASSIGN(bindGroup, device->CreateBindGroup(&bindGroupDescriptor, + UsageValidationMode::Internal)); commandEncoder->APIWriteBuffer(drawConstantsBuffer.GetBuffer(), 0, reinterpret_cast(&drawConstants), diff --git a/src/dawn/native/Queue.cpp b/src/dawn/native/Queue.cpp index a8197d24eeb..d87847eaf1d 100644 --- a/src/dawn/native/Queue.cpp +++ b/src/dawn/native/Queue.cpp @@ -448,7 +448,8 @@ MaybeError QueueBase::WriteBuffer(BufferBase* buffer, size_t size) { DAWN_TRY(GetDevice()->ValidateIsAlive()); DAWN_TRY(GetDevice()->ValidateObject(this)); - DAWN_TRY(ValidateWriteBuffer(GetDevice(), buffer, bufferOffset, size)); + DAWN_TRY( + ValidateWriteBuffer(GetDevice(), buffer, bufferOffset, size, UsageValidationMode::Default)); DAWN_TRY(buffer->ValidateCanUseOnQueueNow()); return WriteBufferImpl(buffer, bufferOffset, data, size); } diff --git a/src/dawn/native/RenderEncoderBase.cpp b/src/dawn/native/RenderEncoderBase.cpp index 67af801fd1e..6cafa624fd5 100644 --- a/src/dawn/native/RenderEncoderBase.cpp +++ b/src/dawn/native/RenderEncoderBase.cpp @@ -202,7 +202,11 @@ void RenderEncoderBase::APIDrawIndirect(BufferBase* indirectBuffer, uint64_t ind [&](CommandAllocator* allocator) -> MaybeError { if (IsValidationEnabled()) { DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); - DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_TRY(mCommandBufferState.ValidateCanDraw()); if (GetDevice()->IsCompatibilityMode()) { DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture()); @@ -261,7 +265,11 @@ void RenderEncoderBase::APIDrawIndexedIndirect(BufferBase* indirectBuffer, [&](CommandAllocator* allocator) -> MaybeError { if (IsValidationEnabled()) { DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); - DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_TRY(mCommandBufferState.ValidateCanDrawIndexed()); if (GetDevice()->IsCompatibilityMode()) { DAWN_TRY(mCommandBufferState.ValidateNoDifferentTextureViewsOnSameTexture()); @@ -332,7 +340,11 @@ void RenderEncoderBase::APIMultiDrawIndirect(BufferBase* indirectBuffer, "%s is not enabled.", wgpu::FeatureName::MultiDrawIndirect); DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); - DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_INVALID_IF(indirectOffset % 4 != 0, "Indirect offset (%u) is not a multiple of 4.", indirectOffset); @@ -353,7 +365,11 @@ void RenderEncoderBase::APIMultiDrawIndirect(BufferBase* indirectBuffer, // draw count buffer is optional if (drawCountBuffer != nullptr) { DAWN_TRY(GetDevice()->ValidateObject(drawCountBuffer)); - DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_INVALID_IF(drawCountBufferOffset % 4 != 0, "Draw count buffer offset (%u) is not a multiple of 4.", @@ -435,7 +451,11 @@ void RenderEncoderBase::APIMultiDrawIndexedIndirect(BufferBase* indirectBuffer, "%s is not enabled.", wgpu::FeatureName::MultiDrawIndirect); DAWN_TRY(GetDevice()->ValidateObject(indirectBuffer)); - DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(indirectBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_INVALID_IF(indirectOffset % 4 != 0, "Indirect offset (%u) is not a multiple of 4.", indirectOffset); @@ -457,7 +477,11 @@ void RenderEncoderBase::APIMultiDrawIndexedIndirect(BufferBase* indirectBuffer, // draw count buffer is optional if (drawCountBuffer != nullptr) { DAWN_TRY(GetDevice()->ValidateObject(drawCountBuffer)); - DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(drawCountBuffer, wgpu::BufferUsage::Indirect, + UsageValidationMode::Default)); DAWN_INVALID_IF(drawCountBufferOffset % 4 != 0, "Draw count buffer offset (%u) is not a multiple of 4.", @@ -571,7 +595,11 @@ void RenderEncoderBase::APISetIndexBuffer(BufferBase* buffer, [&](CommandAllocator* allocator) -> MaybeError { if (IsValidationEnabled()) { DAWN_TRY(GetDevice()->ValidateObject(buffer)); - DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Index, + UsageValidationMode::Default)); DAWN_TRY(ValidateIndexFormat(format)); @@ -641,7 +669,11 @@ void RenderEncoderBase::APISetVertexBuffer(uint32_t slot, "Size (%u) must be either 0 or wgpu::kWholeSize if buffer is null", size); } else { DAWN_TRY(GetDevice()->ValidateObject(buffer)); - DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex)); + // TODO(chromium:42240463): validate indirectBuffer usage with internal usage + // validation mode when we support creating RenderBundle with internal usage + // validation mode + DAWN_TRY(ValidateCanUseAs(buffer, wgpu::BufferUsage::Vertex, + UsageValidationMode::Default)); DAWN_INVALID_IF(offset % 4 != 0, "Vertex buffer offset (%u) is not a multiple of 4", offset); diff --git a/src/dawn/tests/white_box/InternalStorageBufferBindingTests.cpp b/src/dawn/tests/white_box/InternalStorageBufferBindingTests.cpp index 4060a58476d..373aa322819 100644 --- a/src/dawn/tests/white_box/InternalStorageBufferBindingTests.cpp +++ b/src/dawn/tests/white_box/InternalStorageBufferBindingTests.cpp @@ -28,11 +28,18 @@ #include #include +#include "dawn/native/BindGroup.h" #include "dawn/native/BindGroupLayout.h" +#include "dawn/native/CommandBuffer.h" +#include "dawn/native/CommandEncoder.h" +#include "dawn/native/ComputePassEncoder.h" +#include "dawn/native/ComputePipeline.h" #include "dawn/native/Device.h" +#include "dawn/native/PipelineLayout.h" +#include "dawn/native/Queue.h" #include "dawn/native/dawn_platform.h" +#include "dawn/native/utils/WGPUHelpers.h" #include "dawn/tests/DawnTest.h" -#include "dawn/utils/WGPUHelpers.h" namespace dawn { namespace { @@ -47,8 +54,11 @@ class InternalStorageBufferBindingTests : public DawnTest { DAWN_TEST_UNSUPPORTED_IF(UsesWire()); } - wgpu::ComputePipeline CreateComputePipelineWithInternalStorage() { - wgpu::ShaderModule module = utils::CreateShaderModule(device, R"( + Ref CreateComputePipelineWithInternalStorage() { + native::DeviceBase* nativeDevice = native::FromAPI(device.Get()); + + Ref shaderModule = + native::utils::CreateShaderModule(nativeDevice, R"( struct Buf { data : array } @@ -59,37 +69,24 @@ class InternalStorageBufferBindingTests : public DawnTest { fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3u) { buf.data[GlobalInvocationID.x] = buf.data[GlobalInvocationID.x] + 0x1234u; } - )"); + )") + .AcquireSuccess(); // Create binding group layout with internal storage buffer binding type - native::BindGroupLayoutEntry bglEntry; - bglEntry.binding = 0; - bglEntry.buffer.type = native::kInternalStorageBufferBinding; - bglEntry.visibility = wgpu::ShaderStage::Compute; - - native::BindGroupLayoutDescriptor bglDesc; - bglDesc.entryCount = 1; - bglDesc.entries = &bglEntry; - - native::DeviceBase* nativeDevice = native::FromAPI(device.Get()); - Ref bglRef = - nativeDevice->CreateBindGroupLayout(&bglDesc, true).AcquireSuccess(); - - wgpu::BindGroupLayout bgl = - wgpu::BindGroupLayout::Acquire(native::ToAPI(ReturnToAPI(std::move(bglRef)))); + native::utils::MakeBindGroupLayout( + nativeDevice, + {{0, wgpu::ShaderStage::Compute, native::kInternalStorageBufferBinding}}, true) + .AcquireSuccess(); // Create pipeline layout - wgpu::PipelineLayoutDescriptor plDesc; - plDesc.bindGroupLayoutCount = 1; - plDesc.bindGroupLayouts = &bgl; - wgpu::PipelineLayout layout = device.CreatePipelineLayout(&plDesc); - - wgpu::ComputePipelineDescriptor pipelineDesc = {}; - pipelineDesc.layout = layout; - pipelineDesc.compute.module = module; + Ref layout = + native::utils::MakeBasicPipelineLayout(nativeDevice, bglRef).AcquireSuccess(); - return device.CreateComputePipeline(&pipelineDesc); + native::ComputePipelineDescriptor pipelineDesc = {}; + pipelineDesc.compute.module = shaderModule.Get(); + pipelineDesc.layout = layout.Get(); + return nativeDevice->CreateComputePipeline(&pipelineDesc).AcquireSuccess(); } }; @@ -99,28 +96,37 @@ TEST_P(InternalStorageBufferBindingTests, QueryResolveBufferBoundAsInternalStora std::vector data(kNumValues, 0); std::vector expected(kNumValues, 0x1234u * kIterations); - uint64_t bufferSize = static_cast(data.size() * sizeof(uint32_t)); - wgpu::Buffer buffer = - utils::CreateBufferFromData(device, data.data(), bufferSize, - wgpu::BufferUsage::QueryResolve | wgpu::BufferUsage::CopySrc); - - wgpu::ComputePipeline pipeline = CreateComputePipelineWithInternalStorage(); - - wgpu::BindGroup bindGroup = - utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, buffer, 0, bufferSize}}); + native::DeviceBase* nativeDevice = native::FromAPI(device.Get()); - wgpu::CommandEncoder encoder = device.CreateCommandEncoder(); - wgpu::ComputePassEncoder pass = encoder.BeginComputePass(); - pass.SetPipeline(pipeline); - pass.SetBindGroup(0, bindGroup); + uint64_t bufferSize = static_cast(data.size() * sizeof(uint32_t)); + Ref buffer = + native::utils::CreateBufferFromData(nativeDevice, + wgpu::BufferUsage::QueryResolve | + wgpu::BufferUsage::CopySrc | + wgpu::BufferUsage::CopyDst, + data.data(), bufferSize) + .AcquireSuccess(); + + Ref pipeline = CreateComputePipelineWithInternalStorage(); + Ref bindGroupLayout = + pipeline->GetBindGroupLayout(0).AcquireSuccess(); + Ref bindGroup = + native::utils::MakeBindGroup(nativeDevice, bindGroupLayout, {{0, buffer.Get()}}, + native::UsageValidationMode::Internal) + .AcquireSuccess(); + + Ref encoder = nativeDevice->CreateCommandEncoder().AcquireSuccess(); + Ref pass = encoder->BeginComputePass(); + pass->APISetPipeline(pipeline.Get()); + pass->APISetBindGroup(0, bindGroup.Get()); for (uint32_t i = 0; i < kIterations; ++i) { - pass.DispatchWorkgroups(kNumValues); + pass->APIDispatchWorkgroups(kNumValues); } - pass.End(); - wgpu::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); + pass->APIEnd(); + Ref commandBuffer = encoder->Finish().AcquireSuccess(); + nativeDevice->GetQueue()->APISubmit(1, &commandBuffer.Get()); - EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), buffer, 0, kNumValues); + EXPECT_BUFFER_U32_RANGE_EQ(expected.data(), native::ToAPI(buffer.Get()), 0, kNumValues); } DAWN_INSTANTIATE_TEST(InternalStorageBufferBindingTests,