Revert "dawn_native: Indirect draw/dispatch" This reverts commit 7eb6be186be60a536a9f529b514bb5c5fd79293d. Reason for revert: This change is breaking Clusterfuzz bots. crbug.com/972358 Bug: chromium:972358 Original change's description: > dawn_native: Indirect draw/dispatch > > Adds indirect draw and dispatch for all backends (without validation). > > Tests for opengl negative offset are skipped since there is no easy > way to add the index buffer offset. Current idea is to use a compute > shader to modify the indirect draw buffer. > > Change-Id: I1d3eec7c699b211423f4b911769cca17bfbcd045 > Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7481 > Commit-Queue: Idan Raiter <idanr@google.com> > Reviewed-by: Kai Ninomiya <kainino@chromium.org> TBR=cwallez@chromium.org,kainino@chromium.org,idanr@google.com # Not skipping CQ checks because original CL landed > 1 day ago. Change-Id: I9b7b63de0900e20c4da8561ceb9b2dece77c3885 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7960 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn index 7b3e78a..b66d807 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -568,11 +568,9 @@ "src/tests/unittests/validation/BindGroupValidationTests.cpp", "src/tests/unittests/validation/BufferValidationTests.cpp", "src/tests/unittests/validation/CommandBufferValidationTests.cpp", - "src/tests/unittests/validation/ComputeIndirectValidationTests.cpp", "src/tests/unittests/validation/ComputeValidationTests.cpp", "src/tests/unittests/validation/CopyCommandsValidationTests.cpp", "src/tests/unittests/validation/DebugMarkerValidationTests.cpp", - "src/tests/unittests/validation/DrawIndirectValidationTests.cpp", "src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp", "src/tests/unittests/validation/FenceValidationTests.cpp", "src/tests/unittests/validation/QueueSubmitValidationTests.cpp", @@ -634,15 +632,12 @@ "src/tests/end2end/ClipSpaceTests.cpp", "src/tests/end2end/ColorStateTests.cpp", "src/tests/end2end/ComputeCopyStorageBufferTests.cpp", - "src/tests/end2end/ComputeIndirectTests.cpp", "src/tests/end2end/ComputeSharedMemoryTests.cpp", "src/tests/end2end/CopyTests.cpp", "src/tests/end2end/DebugMarkerTests.cpp", "src/tests/end2end/DepthStencilStateTests.cpp", "src/tests/end2end/DestroyTests.cpp", - "src/tests/end2end/DrawIndexedIndirectTests.cpp", "src/tests/end2end/DrawIndexedTests.cpp", - "src/tests/end2end/DrawIndirectTests.cpp", "src/tests/end2end/DrawTests.cpp", "src/tests/end2end/DynamicBufferOffsetTests.cpp", "src/tests/end2end/FenceTests.cpp",
diff --git a/dawn.json b/dawn.json index a0fa36b..8ed7ed5 100644 --- a/dawn.json +++ b/dawn.json
@@ -204,8 +204,7 @@ {"value": 16, "name": "index"}, {"value": 32, "name": "vertex"}, {"value": 64, "name": "uniform"}, - {"value": 128, "name": "storage"}, - {"value": 256, "name": "indirect"} + {"value": 128, "name": "storage"} ] }, "char": { @@ -355,13 +354,6 @@ ] }, { - "name": "dispatch indirect", - "args": [ - {"name": "indirect buffer", "type": "buffer"}, - {"name": "indirect offset", "type": "uint64_t"} - ] - }, - { "name": "end pass", "TODO": "This returns the top-level encoder in the WebGPU IDL" } @@ -773,20 +765,6 @@ ] }, { - "name": "draw indirect", - "args": [ - {"name": "indirect buffer", "type": "buffer"}, - {"name": "indirect offset", "type": "uint64_t"} - ] - }, - { - "name": "draw indexed indirect", - "args": [ - {"name": "indirect buffer", "type": "buffer"}, - {"name": "indirect offset", "type": "uint64_t"} - ] - }, - { "name": "insert debug marker", "args": [ {"name": "group label", "type": "char", "annotation": "const*", "length": "strlen"}
diff --git a/src/common/Constants.h b/src/common/Constants.h index c2fa5c2..7924a70 100644 --- a/src/common/Constants.h +++ b/src/common/Constants.h
@@ -35,10 +35,6 @@ static constexpr uint32_t kTextureRowPitchAlignment = 256u; // Dynamic buffer offsets require offset to be divisible by 256 static constexpr uint64_t kMinDynamicBufferOffsetAlignment = 256u; -// Indirect command sizes -static constexpr uint64_t kDispatchIndirectSize = 3 * sizeof(uint32_t); -static constexpr uint64_t kDrawIndirectSize = 4 * sizeof(uint32_t); -static constexpr uint64_t kDrawIndexedIndirectSize = 5 * sizeof(uint32_t); // Non spec defined constants. static constexpr float kLodMin = 0.0;
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index acb17d3..f2d4269 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp
@@ -999,13 +999,6 @@ DAWN_TRY(persistentState.ValidateCanDispatch()); } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* cmd = mIterator.NextCommand<DispatchIndirectCmd>(); - DAWN_TRY(persistentState.ValidateCanDispatch()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - case Command::InsertDebugMarker: { InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>(); mIterator.NextData<char>(cmd->length + 1); @@ -1092,20 +1085,6 @@ DAWN_TRY(persistentState.ValidateCanDrawIndexed()); } break; - case Command::DrawIndirect: { - DrawIndirectCmd* cmd = mIterator.NextCommand<DrawIndirectCmd>(); - DAWN_TRY(persistentState.ValidateCanDraw()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - - case Command::DrawIndexedIndirect: { - DrawIndexedIndirectCmd* cmd = mIterator.NextCommand<DrawIndexedIndirectCmd>(); - DAWN_TRY(persistentState.ValidateCanDrawIndexed()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - case Command::InsertDebugMarker: { InsertDebugMarkerCmd* cmd = mIterator.NextCommand<InsertDebugMarkerCmd>(); mIterator.NextData<char>(cmd->length + 1);
diff --git a/src/dawn_native/Commands.cpp b/src/dawn_native/Commands.cpp index 93f7ddf..512e7e4 100644 --- a/src/dawn_native/Commands.cpp +++ b/src/dawn_native/Commands.cpp
@@ -58,10 +58,6 @@ DispatchCmd* dispatch = commands->NextCommand<DispatchCmd>(); dispatch->~DispatchCmd(); } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* dispatch = commands->NextCommand<DispatchIndirectCmd>(); - dispatch->~DispatchIndirectCmd(); - } break; case Command::Draw: { DrawCmd* draw = commands->NextCommand<DrawCmd>(); draw->~DrawCmd(); @@ -70,14 +66,6 @@ DrawIndexedCmd* draw = commands->NextCommand<DrawIndexedCmd>(); draw->~DrawIndexedCmd(); } break; - case Command::DrawIndirect: { - DrawIndirectCmd* draw = commands->NextCommand<DrawIndirectCmd>(); - draw->~DrawIndirectCmd(); - } break; - case Command::DrawIndexedIndirect: { - DrawIndexedIndirectCmd* draw = commands->NextCommand<DrawIndexedIndirectCmd>(); - draw->~DrawIndexedIndirectCmd(); - } break; case Command::EndComputePass: { EndComputePassCmd* cmd = commands->NextCommand<EndComputePassCmd>(); cmd->~EndComputePassCmd(); @@ -175,10 +163,6 @@ commands->NextCommand<DispatchCmd>(); break; - case Command::DispatchIndirect: - commands->NextCommand<DispatchIndirectCmd>(); - break; - case Command::Draw: commands->NextCommand<DrawCmd>(); break; @@ -187,14 +171,6 @@ commands->NextCommand<DrawIndexedCmd>(); break; - case Command::DrawIndirect: - commands->NextCommand<DrawIndirectCmd>(); - break; - - case Command::DrawIndexedIndirect: - commands->NextCommand<DrawIndexedIndirectCmd>(); - break; - case Command::EndComputePass: commands->NextCommand<EndComputePassCmd>(); break;
diff --git a/src/dawn_native/Commands.h b/src/dawn_native/Commands.h index 04ae7f5..53d6047 100644 --- a/src/dawn_native/Commands.h +++ b/src/dawn_native/Commands.h
@@ -38,11 +38,8 @@ CopyTextureToBuffer, CopyTextureToTexture, Dispatch, - DispatchIndirect, Draw, DrawIndexed, - DrawIndirect, - DrawIndexedIndirect, EndComputePass, EndRenderPass, InsertDebugMarker, @@ -136,11 +133,6 @@ uint32_t z; }; - struct DispatchIndirectCmd { - Ref<BufferBase> indirectBuffer; - uint64_t indirectOffset; - }; - struct DrawCmd { uint32_t vertexCount; uint32_t instanceCount; @@ -156,16 +148,6 @@ uint32_t firstInstance; }; - struct DrawIndirectCmd { - Ref<BufferBase> indirectBuffer; - uint64_t indirectOffset; - }; - - struct DrawIndexedIndirectCmd { - Ref<BufferBase> indirectBuffer; - uint64_t indirectOffset; - }; - struct EndComputePassCmd {}; struct EndRenderPassCmd {};
diff --git a/src/dawn_native/ComputePassEncoder.cpp b/src/dawn_native/ComputePassEncoder.cpp index 708b2cb..1217b92 100644 --- a/src/dawn_native/ComputePassEncoder.cpp +++ b/src/dawn_native/ComputePassEncoder.cpp
@@ -14,7 +14,6 @@ #include "dawn_native/ComputePassEncoder.h" -#include "dawn_native/Buffer.h" #include "dawn_native/CommandEncoder.h" #include "dawn_native/Commands.h" #include "dawn_native/ComputePipeline.h" @@ -50,25 +49,6 @@ dispatch->z = z; } - void ComputePassEncoderBase::DispatchIndirect(BufferBase* indirectBuffer, - uint64_t indirectOffset) { - if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || - mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(indirectBuffer))) { - return; - } - - if (indirectOffset >= indirectBuffer->GetSize() || - indirectOffset + kDispatchIndirectSize > indirectBuffer->GetSize()) { - mTopLevelEncoder->HandleError("Indirect offset out of bounds"); - return; - } - - DispatchIndirectCmd* dispatch = - mAllocator->Allocate<DispatchIndirectCmd>(Command::DispatchIndirect); - dispatch->indirectBuffer = indirectBuffer; - dispatch->indirectOffset = indirectOffset; - } - void ComputePassEncoderBase::SetPipeline(ComputePipelineBase* pipeline) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(pipeline))) {
diff --git a/src/dawn_native/ComputePassEncoder.h b/src/dawn_native/ComputePassEncoder.h index 36a7e31..a45dad5 100644 --- a/src/dawn_native/ComputePassEncoder.h +++ b/src/dawn_native/ComputePassEncoder.h
@@ -34,7 +34,6 @@ CommandEncoderBase* topLevelEncoder); void Dispatch(uint32_t x, uint32_t y, uint32_t z); - void DispatchIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset); void SetPipeline(ComputePipelineBase* pipeline); protected:
diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp index c3820d0..c83666b 100644 --- a/src/dawn_native/RenderPassEncoder.cpp +++ b/src/dawn_native/RenderPassEncoder.cpp
@@ -14,7 +14,6 @@ #include "dawn_native/RenderPassEncoder.h" -#include "common/Constants.h" #include "dawn_native/Buffer.h" #include "dawn_native/CommandEncoder.h" #include "dawn_native/Commands.h" @@ -74,42 +73,6 @@ draw->firstInstance = firstInstance; } - void RenderPassEncoderBase::DrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset) { - if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || - mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(indirectBuffer))) { - return; - } - - if (indirectOffset >= indirectBuffer->GetSize() || - indirectOffset + kDrawIndirectSize > indirectBuffer->GetSize()) { - mTopLevelEncoder->HandleError("Indirect offset out of bounds"); - return; - } - - DrawIndirectCmd* cmd = mAllocator->Allocate<DrawIndirectCmd>(Command::DrawIndirect); - cmd->indirectBuffer = indirectBuffer; - cmd->indirectOffset = indirectOffset; - } - - void RenderPassEncoderBase::DrawIndexedIndirect(BufferBase* indirectBuffer, - uint64_t indirectOffset) { - if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || - mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(indirectBuffer))) { - return; - } - - if (indirectOffset >= indirectBuffer->GetSize() || - indirectOffset + kDrawIndexedIndirectSize > indirectBuffer->GetSize()) { - mTopLevelEncoder->HandleError("Indirect offset out of bounds"); - return; - } - - DrawIndexedIndirectCmd* cmd = - mAllocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect); - cmd->indirectBuffer = indirectBuffer; - cmd->indirectOffset = indirectOffset; - } - void RenderPassEncoderBase::SetPipeline(RenderPipelineBase* pipeline) { if (mTopLevelEncoder->ConsumedError(ValidateCanRecordCommands()) || mTopLevelEncoder->ConsumedError(GetDevice()->ValidateObject(pipeline))) {
diff --git a/src/dawn_native/RenderPassEncoder.h b/src/dawn_native/RenderPassEncoder.h index c6029c5..dc7b54f 100644 --- a/src/dawn_native/RenderPassEncoder.h +++ b/src/dawn_native/RenderPassEncoder.h
@@ -43,9 +43,6 @@ int32_t baseVertex, uint32_t firstInstance); - void DrawIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset); - void DrawIndexedIndirect(BufferBase* indirectBuffer, uint64_t indirectOffset); - void SetPipeline(RenderPipelineBase* pipeline); void SetStencilReference(uint32_t reference);
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 98afe26..eed3963 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -684,17 +684,6 @@ commandList->Dispatch(dispatch->x, dispatch->y, dispatch->z); } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>(); - - Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get()); - ComPtr<ID3D12CommandSignature> signature = - ToBackend(GetDevice())->GetDispatchIndirectSignature(); - commandList->ExecuteIndirect(signature.Get(), 1, - buffer->GetD3D12Resource().Get(), - dispatch->indirectOffset, nullptr, 0); - } break; - case Command::EndComputePass: { mCommands.NextCommand<EndComputePassCmd>(); return; @@ -829,30 +818,6 @@ draw->firstInstance); } break; - case Command::DrawIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - - FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline); - Buffer* buffer = ToBackend(draw->indirectBuffer.Get()); - ComPtr<ID3D12CommandSignature> signature = - ToBackend(GetDevice())->GetDrawIndirectSignature(); - commandList->ExecuteIndirect(signature.Get(), 1, - buffer->GetD3D12Resource().Get(), - draw->indirectOffset, nullptr, 0); - } break; - - case Command::DrawIndexedIndirect: { - DrawIndexedIndirectCmd* draw = mCommands.NextCommand<DrawIndexedIndirectCmd>(); - - FlushSetVertexBuffers(commandList, &vertexBuffersInfo, lastPipeline); - Buffer* buffer = ToBackend(draw->indirectBuffer.Get()); - ComPtr<ID3D12CommandSignature> signature = - ToBackend(GetDevice())->GetDrawIndexedIndirectSignature(); - commandList->ExecuteIndirect(signature.Get(), 1, - buffer->GetD3D12Resource().Get(), - draw->indirectOffset, nullptr, 0); - } break; - case Command::InsertDebugMarker: { InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>(); const char* label = mCommands.NextData<char>(cmd->length + 1);
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp index 651323e..a13f5b5 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.cpp +++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -68,34 +68,6 @@ mResourceAllocator = std::make_unique<ResourceAllocator>(this); NextSerial(); - - // Initialize indirect commands - D3D12_INDIRECT_ARGUMENT_DESC argumentDesc = {}; - argumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH; - - D3D12_COMMAND_SIGNATURE_DESC programDesc = {}; - programDesc.ByteStride = 3 * sizeof(uint32_t); - programDesc.NumArgumentDescs = 1; - programDesc.pArgumentDescs = &argumentDesc; - - ToBackend(GetDevice()) - ->GetD3D12Device() - ->CreateCommandSignature(&programDesc, NULL, IID_PPV_ARGS(&mDispatchIndirectSignature)); - - argumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW; - programDesc.ByteStride = 4 * sizeof(uint32_t); - - ToBackend(GetDevice()) - ->GetD3D12Device() - ->CreateCommandSignature(&programDesc, NULL, IID_PPV_ARGS(&mDrawIndirectSignature)); - - argumentDesc.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED; - programDesc.ByteStride = 5 * sizeof(uint32_t); - - ToBackend(GetDevice()) - ->GetD3D12Device() - ->CreateCommandSignature(&programDesc, NULL, - IID_PPV_ARGS(&mDrawIndexedIndirectSignature)); } Device::~Device() { @@ -129,18 +101,6 @@ return mCommandQueue; } - ComPtr<ID3D12CommandSignature> Device::GetDispatchIndirectSignature() const { - return mDispatchIndirectSignature; - } - - ComPtr<ID3D12CommandSignature> Device::GetDrawIndirectSignature() const { - return mDrawIndirectSignature; - } - - ComPtr<ID3D12CommandSignature> Device::GetDrawIndexedIndirectSignature() const { - return mDrawIndexedIndirectSignature; - } - DescriptorHeapAllocator* Device::GetDescriptorHeapAllocator() const { return mDescriptorHeapAllocator.get(); }
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h index 18efaab..5287588 100644 --- a/src/dawn_native/d3d12/DeviceD3D12.h +++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -51,10 +51,6 @@ ComPtr<ID3D12Device> GetD3D12Device() const; ComPtr<ID3D12CommandQueue> GetCommandQueue() const; - ComPtr<ID3D12CommandSignature> GetDispatchIndirectSignature() const; - ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const; - ComPtr<ID3D12CommandSignature> GetDrawIndexedIndirectSignature() const; - DescriptorHeapAllocator* GetDescriptorHeapAllocator() const; MapRequestTracker* GetMapRequestTracker() const; ResourceAllocator* GetResourceAllocator() const; @@ -111,10 +107,6 @@ ComPtr<ID3D12Device> mD3d12Device; ComPtr<ID3D12CommandQueue> mCommandQueue; - ComPtr<ID3D12CommandSignature> mDispatchIndirectSignature; - ComPtr<ID3D12CommandSignature> mDrawIndirectSignature; - ComPtr<ID3D12CommandSignature> mDrawIndexedIndirectSignature; - struct PendingCommandList { ComPtr<ID3D12GraphicsCommandList> commandList; bool open = false;
diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm index 65cf726..7cc8897 100644 --- a/src/dawn_native/metal/CommandBufferMTL.mm +++ b/src/dawn_native/metal/CommandBufferMTL.mm
@@ -645,17 +645,6 @@ threadsPerThreadgroup:lastPipeline->GetLocalWorkGroupSize()]; } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>(); - - Buffer* buffer = ToBackend(dispatch->indirectBuffer.Get()); - id<MTLBuffer> indirectBuffer = buffer->GetMTLBuffer(); - [encoder dispatchThreadgroupsWithIndirectBuffer:indirectBuffer - indirectBufferOffset:dispatch->indirectOffset - threadsPerThreadgroup:lastPipeline - ->GetLocalWorkGroupSize()]; - } break; - case Command::SetComputePipeline: { SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>(); lastPipeline = ToBackend(cmd->pipeline).Get(); @@ -828,29 +817,6 @@ } } break; - case Command::DrawIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - - Buffer* buffer = ToBackend(draw->indirectBuffer.Get()); - id<MTLBuffer> indirectBuffer = buffer->GetMTLBuffer(); - [encoder drawPrimitives:lastPipeline->GetMTLPrimitiveTopology() - indirectBuffer:indirectBuffer - indirectBufferOffset:draw->indirectOffset]; - } break; - - case Command::DrawIndexedIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - - Buffer* buffer = ToBackend(draw->indirectBuffer.Get()); - id<MTLBuffer> indirectBuffer = buffer->GetMTLBuffer(); - [encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology() - indexType:lastPipeline->GetMTLIndexType() - indexBuffer:indexBuffer - indexBufferOffset:indexBufferBaseOffset - indirectBuffer:indirectBuffer - indirectBufferOffset:draw->indirectOffset]; - } break; - case Command::InsertDebugMarker: { InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>(); auto label = mCommands.NextData<char>(cmd->length + 1);
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index 8c93a82..7c5a8dc 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -499,19 +499,6 @@ glMemoryBarrier(GL_ALL_BARRIER_BITS); } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* dispatch = mCommands.NextCommand<DispatchIndirectCmd>(); - - uint64_t indirectBufferOffset = dispatch->indirectOffset; - Buffer* indirectBuffer = ToBackend(dispatch->indirectBuffer.Get()); - - glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, indirectBuffer->GetHandle()); - glDispatchComputeIndirect( - reinterpret_cast<GLintptr>(static_cast<intptr_t>(indirectBufferOffset))); - // TODO(cwallez@chromium.org): add barriers to the API - glMemoryBarrier(GL_ALL_BARRIER_BITS); - } break; - case Command::SetComputePipeline: { SetComputePipelineCmd* cmd = mCommands.NextCommand<SetComputePipelineCmd>(); lastPipeline = ToBackend(cmd->pipeline).Get(); @@ -719,36 +706,6 @@ } } break; - case Command::DrawIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - inputBuffers.Apply(); - - uint64_t indirectBufferOffset = draw->indirectOffset; - Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get()); - - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle()); - glDrawArraysIndirect( - lastPipeline->GetGLPrimitiveTopology(), - reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset))); - } break; - - case Command::DrawIndexedIndirect: { - DrawIndexedIndirectCmd* draw = mCommands.NextCommand<DrawIndexedIndirectCmd>(); - inputBuffers.Apply(); - - dawn::IndexFormat indexFormat = - lastPipeline->GetVertexInputDescriptor()->indexFormat; - GLenum formatType = IndexFormatType(indexFormat); - - uint64_t indirectBufferOffset = draw->indirectOffset; - Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get()); - - glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle()); - glDrawElementsIndirect( - lastPipeline->GetGLPrimitiveTopology(), formatType, - reinterpret_cast<void*>(static_cast<intptr_t>(indirectBufferOffset))); - } break; - case Command::InsertDebugMarker: case Command::PopDebugGroup: case Command::PushDebugGroup: {
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index 73c7a4f..a04bec7 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -425,16 +425,6 @@ device->fn.CmdDispatch(commands, dispatch->x, dispatch->y, dispatch->z); } break; - case Command::DispatchIndirect: { - DispatchIndirectCmd* Dispatch = mCommands.NextCommand<DispatchIndirectCmd>(); - VkBuffer indirectBuffer = ToBackend(Dispatch->indirectBuffer)->GetHandle(); - - descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_COMPUTE); - device->fn.CmdDispatchIndirect( - commands, indirectBuffer, - static_cast<VkDeviceSize>(Dispatch->indirectOffset)); - } break; - case Command::SetBindGroup: { SetBindGroupCmd* cmd = mCommands.NextCommand<SetBindGroupCmd>(); VkDescriptorSet set = ToBackend(cmd->group.Get())->GetHandle(); @@ -531,26 +521,6 @@ draw->firstInstance); } break; - case Command::DrawIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle(); - - descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS); - device->fn.CmdDrawIndirect(commands, indirectBuffer, - static_cast<VkDeviceSize>(draw->indirectOffset), 1, - 0); - } break; - - case Command::DrawIndexedIndirect: { - DrawIndirectCmd* draw = mCommands.NextCommand<DrawIndirectCmd>(); - VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle(); - - descriptorSets.Flush(device, commands, VK_PIPELINE_BIND_POINT_GRAPHICS); - device->fn.CmdDrawIndexedIndirect( - commands, indirectBuffer, static_cast<VkDeviceSize>(draw->indirectOffset), - 1, 0); - } break; - case Command::InsertDebugMarker: { if (device->GetDeviceInfo().debugMarker) { InsertDebugMarkerCmd* cmd = mCommands.NextCommand<InsertDebugMarkerCmd>();
diff --git a/src/tests/end2end/ComputeIndirectTests.cpp b/src/tests/end2end/ComputeIndirectTests.cpp deleted file mode 100644 index 5dea851..0000000 --- a/src/tests/end2end/ComputeIndirectTests.cpp +++ /dev/null
@@ -1,131 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "dawn/dawncpp.h" -#include "tests/DawnTest.h" - -#include "utils/DawnHelpers.h" - -#include <array> -#include <initializer_list> - -class ComputeIndirectTests : public DawnTest { - public: - // Write into the output buffer if we saw the biggest dispatch - // This is a workaround since D3D12 doesn't have gl_NumWorkGroups - const char* shaderSource = R"( - #version 450 - layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in; - layout(std140, set = 0, binding = 0) uniform inputBuf { - uvec3 expectedDispatch; - }; - layout(std140, set = 0, binding = 1) buffer outputBuf { - uvec3 workGroups; - }; - - void main() { - if (gl_GlobalInvocationID == expectedDispatch - uvec3(1, 1, 1)) { - workGroups = expectedDispatch; - } - })"; - - void BasicTest(std::initializer_list<uint32_t> buffer, uint64_t indirectOffset); -}; - -void ComputeIndirectTests::BasicTest(std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset) { - dawn::BindGroupLayout bgl = utils::MakeBindGroupLayout( - device, { - {0, dawn::ShaderStageBit::Compute, dawn::BindingType::UniformBuffer}, - {1, dawn::ShaderStageBit::Compute, dawn::BindingType::StorageBuffer}, - }); - - // Set up shader and pipeline - dawn::ShaderModule module = - utils::CreateShaderModule(device, dawn::ShaderStage::Compute, shaderSource); - dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, &bgl); - - dawn::ComputePipelineDescriptor csDesc; - csDesc.layout = pl; - - dawn::PipelineStageDescriptor computeStage; - computeStage.module = module; - computeStage.entryPoint = "main"; - csDesc.computeStage = &computeStage; - - dawn::ComputePipeline pipeline = device.CreateComputePipeline(&csDesc); - - // Set up dst storage buffer to contain dispatch x, y, z - dawn::Buffer dst = utils::CreateBufferFromData<uint32_t>(device, - dawn::BufferUsageBit::Storage | - dawn::BufferUsageBit::TransferSrc | - dawn::BufferUsageBit::TransferDst, - {0, 0, 0}); - - std::vector<uint32_t> indirectBufferData = bufferList; - - dawn::Buffer indirectBuffer = - utils::CreateBufferFromData<uint32_t>(device, dawn::BufferUsageBit::Indirect, bufferList); - - dawn::Buffer expectedBuffer = - utils::CreateBufferFromData(device, &indirectBufferData[indirectOffset / sizeof(uint32_t)], - 3 * sizeof(uint32_t), dawn::BufferUsageBit::Uniform); - - // Set up bind group and issue dispatch - dawn::BindGroup bindGroup = - utils::MakeBindGroup(device, bgl, - { - {0, expectedBuffer, 0, 3 * sizeof(uint32_t)}, - {1, dst, 0, 3 * sizeof(uint32_t)}, - }); - - dawn::CommandBuffer commands; - { - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - dawn::ComputePassEncoder pass = encoder.BeginComputePass(); - pass.SetPipeline(pipeline); - pass.SetBindGroup(0, bindGroup, 0, nullptr); - pass.DispatchIndirect(indirectBuffer, indirectOffset); - pass.EndPass(); - - commands = encoder.Finish(); - } - - queue.Submit(1, &commands); - - // Verify the dispatch got called with group counts in indirect buffer - EXPECT_BUFFER_U32_RANGE_EQ(&indirectBufferData[indirectOffset / sizeof(uint32_t)], dst, 0, 3); -} - -// Test basic indirect -TEST_P(ComputeIndirectTests, Basic) { - // See https://bugs.chromium.org/p/dawn/issues/detail?id=159 - DAWN_SKIP_TEST_IF(IsD3D12() && IsNvidia()); - - BasicTest({2, 3, 4}, 0); -} - -// Test indirect with buffer offset -TEST_P(ComputeIndirectTests, IndirectOffset) { - // See https://bugs.chromium.org/p/dawn/issues/detail?id=159 - DAWN_SKIP_TEST_IF(IsD3D12() && IsNvidia()); - - BasicTest({0, 0, 0, 2, 3, 4}, 3 * sizeof(uint32_t)); -} - -DAWN_INSTANTIATE_TEST(ComputeIndirectTests, - D3D12Backend, - MetalBackend, - OpenGLBackend, - VulkanBackend);
diff --git a/src/tests/end2end/DrawIndexedIndirectTests.cpp b/src/tests/end2end/DrawIndexedIndirectTests.cpp deleted file mode 100644 index c525735..0000000 --- a/src/tests/end2end/DrawIndexedIndirectTests.cpp +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright 2018 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "tests/DawnTest.h" - -#include "utils/ComboRenderPipelineDescriptor.h" -#include "utils/DawnHelpers.h" - -constexpr uint32_t kRTSize = 4; - -class DrawIndexedIndirectTest : public DawnTest { - protected: - void SetUp() override { - DawnTest::SetUp(); - - renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - - dawn::ShaderModule vsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( - #version 450 - layout(location = 0) in vec4 pos; - void main() { - gl_Position = pos; - })"); - - dawn::ShaderModule fsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( - #version 450 - layout(location = 0) out vec4 fragColor; - void main() { - fragColor = vec4(0.0, 1.0, 0.0, 1.0); - })"); - - utils::ComboRenderPipelineDescriptor descriptor(device); - descriptor.cVertexStage.module = vsModule; - descriptor.cFragmentStage.module = fsModule; - descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; - descriptor.cVertexInput.bufferCount = 1; - descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float); - descriptor.cVertexInput.cBuffers[0].attributeCount = 1; - descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4; - descriptor.cColorStates[0]->format = renderPass.colorFormat; - - pipeline = device.CreateRenderPipeline(&descriptor); - - vertexBuffer = utils::CreateBufferFromData<float>( - device, dawn::BufferUsageBit::Vertex, - {// First quad: the first 3 vertices represent the bottom left triangle - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, - 0.0f, 1.0f, - - // Second quad: the first 3 vertices represent the top right triangle - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, - 0.0f, 1.0f}); - indexBuffer = utils::CreateBufferFromData<uint32_t>( - device, dawn::BufferUsageBit::Index, - {0, 1, 2, 0, 3, 1, - // The indices below are added to test negatve baseVertex - 0 + 4, 1 + 4, 2 + 4, 0 + 4, 3 + 4, 1 + 4}); - } - - utils::BasicRenderPass renderPass; - dawn::RenderPipeline pipeline; - dawn::Buffer vertexBuffer; - dawn::Buffer indexBuffer; - - void Test(std::initializer_list<uint32_t> bufferList, - uint64_t indexOffset, - uint64_t indirectOffset, - RGBA8 bottomLeftExpected, - RGBA8 topRightExpected) { - dawn::Buffer indirectBuffer = utils::CreateBufferFromData<uint32_t>( - device, dawn::BufferUsageBit::Indirect, bufferList); - - uint64_t zeroOffset = 0; - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - { - dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); - pass.SetPipeline(pipeline); - pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); - pass.SetIndexBuffer(indexBuffer, indexOffset); - pass.DrawIndexedIndirect(indirectBuffer, indirectOffset); - pass.EndPass(); - } - - dawn::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - - EXPECT_PIXEL_RGBA8_EQ(bottomLeftExpected, renderPass.color, 1, 3); - EXPECT_PIXEL_RGBA8_EQ(topRightExpected, renderPass.color, 3, 1); - } -}; - -// The most basic DrawIndexed triangle draw. -TEST_P(DrawIndexedIndirectTest, Uint32) { - RGBA8 filled(0, 255, 0, 255); - RGBA8 notFilled(0, 0, 0, 0); - - // Test a draw with no indices. - Test({0, 0, 0, 0, 0}, 0, 0, notFilled, notFilled); - - // Test a draw with only the first 3 indices of the first quad (bottom left triangle) - Test({3, 1, 0, 0, 0}, 0, 0, filled, notFilled); - - // Test a draw with only the last 3 indices of the first quad (top right triangle) - Test({3, 1, 3, 0, 0}, 0, 0, notFilled, filled); - - // Test a draw with all 6 indices (both triangles). - Test({6, 1, 0, 0, 0}, 0, 0, filled, filled); -} - -// Test the parameter 'baseVertex' of DrawIndexed() works. -TEST_P(DrawIndexedIndirectTest, BaseVertex) { - // TODO(crbug.com/dawn/161): add workaround for OpenGL index buffer offset (could be compute - // shader that adds it to the draw calls) - DAWN_SKIP_TEST_IF(IsOpenGL()); - - RGBA8 filled(0, 255, 0, 255); - RGBA8 notFilled(0, 0, 0, 0); - - // Test a draw with only the first 3 indices of the second quad (top right triangle) - Test({3, 1, 0, 4, 0}, 0, 0, notFilled, filled); - - // Test a draw with only the last 3 indices of the second quad (bottom left triangle) - Test({3, 1, 3, 4, 0}, 0, 0, filled, notFilled); - - // Test negative baseVertex - // Test a draw with only the first 3 indices of the first quad (bottom left triangle) - Test({3, 1, 0, -4, 0}, 6 * sizeof(uint32_t), 0, filled, notFilled); - - // Test a draw with only the last 3 indices of the first quad (top right triangle) - Test({3, 1, 3, -4, 0}, 6 * sizeof(uint32_t), 0, notFilled, filled); -} - -TEST_P(DrawIndexedIndirectTest, IndirectOffset) { - RGBA8 filled(0, 255, 0, 255); - RGBA8 notFilled(0, 0, 0, 0); - - // Test an offset draw call, with indirect buffer containing 2 calls: - // 1) first 3 indices of the second quad (top right triangle) - // 2) last 3 indices of the second quad - - // Test #1 (no offset) - Test({3, 1, 0, 4, 0, 3, 1, 3, 4, 0}, 0, 0, notFilled, filled); - - // Offset to draw #2 - Test({3, 1, 0, 4, 0, 3, 1, 3, 4, 0}, 0, 5 * sizeof(uint32_t), filled, notFilled); -} - -DAWN_INSTANTIATE_TEST(DrawIndexedIndirectTest, - D3D12Backend, - MetalBackend, - OpenGLBackend, - VulkanBackend);
diff --git a/src/tests/end2end/DrawIndirectTests.cpp b/src/tests/end2end/DrawIndirectTests.cpp deleted file mode 100644 index a27aac9..0000000 --- a/src/tests/end2end/DrawIndirectTests.cpp +++ /dev/null
@@ -1,128 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "tests/DawnTest.h" - -#include "utils/ComboRenderPipelineDescriptor.h" -#include "utils/DawnHelpers.h" - -constexpr uint32_t kRTSize = 4; - -class DrawIndirectTest : public DawnTest { - protected: - void SetUp() override { - DawnTest::SetUp(); - - renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - - dawn::ShaderModule vsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( - #version 450 - layout(location = 0) in vec4 pos; - void main() { - gl_Position = pos; - })"); - - dawn::ShaderModule fsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( - #version 450 - layout(location = 0) out vec4 fragColor; - void main() { - fragColor = vec4(0.0, 1.0, 0.0, 1.0); - })"); - - utils::ComboRenderPipelineDescriptor descriptor(device); - descriptor.cVertexStage.module = vsModule; - descriptor.cFragmentStage.module = fsModule; - descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; - descriptor.cVertexInput.bufferCount = 1; - descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float); - descriptor.cVertexInput.cBuffers[0].attributeCount = 1; - descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4; - descriptor.cColorStates[0]->format = renderPass.colorFormat; - - pipeline = device.CreateRenderPipeline(&descriptor); - - vertexBuffer = utils::CreateBufferFromData<float>( - device, dawn::BufferUsageBit::Vertex, - {// The bottom left triangle - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, - - // The top right triangle - -1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f}); - } - - utils::BasicRenderPass renderPass; - dawn::RenderPipeline pipeline; - dawn::Buffer vertexBuffer; - - void Test(std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset, - RGBA8 bottomLeftExpected, - RGBA8 topRightExpected) { - dawn::Buffer indirectBuffer = utils::CreateBufferFromData<uint32_t>( - device, dawn::BufferUsageBit::Indirect, bufferList); - - uint64_t zeroOffset = 0; - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - { - dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo); - pass.SetPipeline(pipeline); - pass.SetVertexBuffers(0, 1, &vertexBuffer, &zeroOffset); - pass.DrawIndirect(indirectBuffer, indirectOffset); - pass.EndPass(); - } - - dawn::CommandBuffer commands = encoder.Finish(); - queue.Submit(1, &commands); - - EXPECT_PIXEL_RGBA8_EQ(bottomLeftExpected, renderPass.color, 1, 3); - EXPECT_PIXEL_RGBA8_EQ(topRightExpected, renderPass.color, 3, 1); - } -}; - -// The basic triangle draw. -TEST_P(DrawIndirectTest, Uint32) { - RGBA8 filled(0, 255, 0, 255); - RGBA8 notFilled(0, 0, 0, 0); - - // Test a draw with no indices. - Test({0, 0, 0, 0}, 0, notFilled, notFilled); - - // Test a draw with only the first 3 indices (bottom left triangle) - Test({3, 1, 0, 0}, 0, filled, notFilled); - - // Test a draw with only the last 3 indices (top right triangle) - Test({3, 1, 3, 0}, 0, notFilled, filled); - - // Test a draw with all 6 indices (both triangles). - Test({6, 1, 0, 0}, 0, filled, filled); -} - -TEST_P(DrawIndirectTest, IndirectOffset) { - RGBA8 filled(0, 255, 0, 255); - RGBA8 notFilled(0, 0, 0, 0); - - // Test an offset draw call, with indirect buffer containing 2 calls: - // 1) only the first 3 indices (bottom left triangle) - // 2) only the last 3 indices (top right triangle) - - // Test #1 (no offset) - Test({3, 1, 0, 0, 3, 1, 3, 0}, 0, filled, notFilled); - - // Offset to draw #2 - Test({3, 1, 0, 0, 3, 1, 3, 0}, 4 * sizeof(uint32_t), notFilled, filled); -} - -DAWN_INSTANTIATE_TEST(DrawIndirectTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
diff --git a/src/tests/unittests/validation/ComputeIndirectValidationTests.cpp b/src/tests/unittests/validation/ComputeIndirectValidationTests.cpp deleted file mode 100644 index 294b5b1..0000000 --- a/src/tests/unittests/validation/ComputeIndirectValidationTests.cpp +++ /dev/null
@@ -1,90 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <initializer_list> -#include <limits> -#include "tests/unittests/validation/ValidationTest.h" -#include "utils/DawnHelpers.h" - -class ComputeIndirectValidationTest : public ValidationTest { - protected: - void SetUp() override { - ValidationTest::SetUp(); - - dawn::ShaderModule computeModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Compute, R"( - #version 450 - layout(local_size_x = 1) in; - void main() { - })"); - - // Set up compute pipeline - dawn::PipelineLayout pl = utils::MakeBasicPipelineLayout(device, nullptr); - - dawn::ComputePipelineDescriptor csDesc; - csDesc.layout = pl; - - dawn::PipelineStageDescriptor computeStage; - computeStage.module = computeModule; - computeStage.entryPoint = "main"; - csDesc.computeStage = &computeStage; - - pipeline = device.CreateComputePipeline(&csDesc); - } - - void ValidateExpectation(dawn::CommandEncoder encoder, utils::Expectation expectation) { - if (expectation == utils::Expectation::Success) { - encoder.Finish(); - } else { - ASSERT_DEVICE_ERROR(encoder.Finish()); - } - } - - void TestIndirectOffset(utils::Expectation expectation, - std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset) { - dawn::Buffer indirectBuffer = utils::CreateBufferFromData<uint32_t>( - device, dawn::BufferUsageBit::Indirect, bufferList); - - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - dawn::ComputePassEncoder pass = encoder.BeginComputePass(); - pass.SetPipeline(pipeline); - pass.DispatchIndirect(indirectBuffer, indirectOffset); - pass.EndPass(); - - ValidateExpectation(encoder, expectation); - } - - dawn::ComputePipeline pipeline; -}; - -// Verify out of bounds indirect dispatch calls are caught early -TEST_F(ComputeIndirectValidationTest, IndirectOffsetBounds) { - // In bounds - TestIndirectOffset(utils::Expectation::Success, {1, 2, 3}, 0); - // In bounds, bigger buffer - TestIndirectOffset(utils::Expectation::Success, {1, 2, 3, 4, 5, 6}, 0); - // In bounds, bigger buffer, positive offset - TestIndirectOffset(utils::Expectation::Success, {1, 2, 3, 4, 5, 6}, 3 * sizeof(uint32_t)); - - // Out of bounds, buffer too small - TestIndirectOffset(utils::Expectation::Failure, {1, 2}, 0); - // Out of bounds, index too big - TestIndirectOffset(utils::Expectation::Failure, {1, 2, 3}, 1 * sizeof(uint32_t)); - // Out of bounds, index past buffer - TestIndirectOffset(utils::Expectation::Failure, {1, 2, 3}, 4 * sizeof(uint32_t)); - // Out of bounds, index + size of command overflows - uint64_t offset = std::numeric_limits<uint64_t>::max(); - TestIndirectOffset(utils::Expectation::Failure, {1, 2, 3, 4, 5, 6}, offset); -}
diff --git a/src/tests/unittests/validation/DrawIndirectValidationTests.cpp b/src/tests/unittests/validation/DrawIndirectValidationTests.cpp deleted file mode 100644 index de3a3bb..0000000 --- a/src/tests/unittests/validation/DrawIndirectValidationTests.cpp +++ /dev/null
@@ -1,143 +0,0 @@ -// Copyright 2019 The Dawn Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include <initializer_list> -#include <limits> -#include "tests/unittests/validation/ValidationTest.h" -#include "utils/ComboRenderPipelineDescriptor.h" -#include "utils/DawnHelpers.h" - -class DrawIndirectValidationTest : public ValidationTest { - protected: - void SetUp() override { - ValidationTest::SetUp(); - - dawn::ShaderModule vsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( - #version 450 - void main() { - gl_Position = vec4(0.0); - })"); - - dawn::ShaderModule fsModule = - utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"( - #version 450 - layout(location = 0) out vec4 fragColor; - void main() { - fragColor = vec4(0.0); - })"); - - // Set up render pipeline - dawn::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, nullptr); - - utils::ComboRenderPipelineDescriptor descriptor(device); - descriptor.layout = pipelineLayout; - descriptor.cVertexStage.module = vsModule; - descriptor.cFragmentStage.module = fsModule; - - pipeline = device.CreateRenderPipeline(&descriptor); - } - - void ValidateExpectation(dawn::CommandEncoder encoder, utils::Expectation expectation) { - if (expectation == utils::Expectation::Success) { - encoder.Finish(); - } else { - ASSERT_DEVICE_ERROR(encoder.Finish()); - } - } - - void TestIndirectOffsetDrawIndexed(utils::Expectation expectation, - std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset) { - TestIndirectOffset(expectation, bufferList, indirectOffset, true); - } - - void TestIndirectOffsetDraw(utils::Expectation expectation, - std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset) { - TestIndirectOffset(expectation, bufferList, indirectOffset, false); - } - - void TestIndirectOffset(utils::Expectation expectation, - std::initializer_list<uint32_t> bufferList, - uint64_t indirectOffset, - bool indexed) { - dawn::Buffer indirectBuffer = utils::CreateBufferFromData<uint32_t>( - device, dawn::BufferUsageBit::Indirect, bufferList); - - DummyRenderPass renderPass(device); - dawn::CommandEncoder encoder = device.CreateCommandEncoder(); - dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass); - pass.SetPipeline(pipeline); - if (indexed) { - uint32_t zeros[100] = {}; - dawn::Buffer indexBuffer = utils::CreateBufferFromData(device, zeros, sizeof(zeros), - dawn::BufferUsageBit::Index); - pass.SetIndexBuffer(indexBuffer, 0); - pass.DrawIndexedIndirect(indirectBuffer, indirectOffset); - } else { - pass.DrawIndirect(indirectBuffer, indirectOffset); - } - pass.EndPass(); - - ValidateExpectation(encoder, expectation); - } - - dawn::RenderPipeline pipeline; -}; - -// Verify out of bounds indirect draw calls are caught early -TEST_F(DrawIndirectValidationTest, DrawIndirectOffsetBounds) { - // In bounds - TestIndirectOffsetDraw(utils::Expectation::Success, {1, 2, 3, 4}, 0); - // In bounds, bigger buffer - TestIndirectOffsetDraw(utils::Expectation::Success, {1, 2, 3, 4, 5, 6, 7}, 0); - // In bounds, bigger buffer, positive offset - TestIndirectOffsetDraw(utils::Expectation::Success, {1, 2, 3, 4, 5, 6, 7, 8}, - 4 * sizeof(uint32_t)); - - // Out of bounds, buffer too small - TestIndirectOffsetDraw(utils::Expectation::Failure, {1, 2, 3}, 0); - // Out of bounds, index too big - TestIndirectOffsetDraw(utils::Expectation::Failure, {1, 2, 3, 4}, 1 * sizeof(uint32_t)); - // Out of bounds, index past buffer - TestIndirectOffsetDraw(utils::Expectation::Failure, {1, 2, 3, 4}, 5 * sizeof(uint32_t)); - // Out of bounds, index + size of command overflows - uint64_t offset = std::numeric_limits<uint64_t>::max(); - TestIndirectOffsetDraw(utils::Expectation::Failure, {1, 2, 3, 4, 5, 6, 7}, offset); -} - -// Verify out of bounds indirect draw indexed calls are caught early -TEST_F(DrawIndirectValidationTest, DrawIndexedIndirectOffsetBounds) { - // In bounds - TestIndirectOffsetDrawIndexed(utils::Expectation::Success, {1, 2, 3, 4, 5}, 0); - // In bounds, bigger buffer - TestIndirectOffsetDrawIndexed(utils::Expectation::Success, {1, 2, 3, 4, 5, 6, 7, 8, 9}, 0); - // In bounds, bigger buffer, positive offset - TestIndirectOffsetDrawIndexed(utils::Expectation::Success, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, - 5 * sizeof(uint32_t)); - - // Out of bounds, buffer too small - TestIndirectOffsetDrawIndexed(utils::Expectation::Failure, {1, 2, 3, 4}, 0); - // Out of bounds, index too big - TestIndirectOffsetDrawIndexed(utils::Expectation::Failure, {1, 2, 3, 4, 5}, - 1 * sizeof(uint32_t)); - // Out of bounds, index past buffer - TestIndirectOffsetDrawIndexed(utils::Expectation::Failure, {1, 2, 3, 4, 5}, - 5 * sizeof(uint32_t)); - // Out of bounds, index + size of command overflows - uint64_t offset = std::numeric_limits<uint64_t>::max(); - TestIndirectOffsetDrawIndexed(utils::Expectation::Failure, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, - offset); -}