Remove deferred BufferLocation updates for drawIndexedIndirect
Instead of using BufferLocation as another layer of indirection, the indirectBuffer can be set directly on the indirect command. This makes the indirect validation a bit simpler, but introduces additional lifetime dependencies in that the indirect draw validation MUST be encoded while the DrawIndexedIndirectCmds it references are still valid. Bug: dawn:809 Change-Id: I1ef084622d8737ad5ec1b0247bf9062712e35008 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/67241 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
d4b9cda056
commit
6abf1a1adb
|
@ -205,8 +205,6 @@ source_set("dawn_native_sources") {
|
||||||
"BuddyMemoryAllocator.h",
|
"BuddyMemoryAllocator.h",
|
||||||
"Buffer.cpp",
|
"Buffer.cpp",
|
||||||
"Buffer.h",
|
"Buffer.h",
|
||||||
"BufferLocation.cpp",
|
|
||||||
"BufferLocation.h",
|
|
||||||
"CachedObject.cpp",
|
"CachedObject.cpp",
|
||||||
"CachedObject.h",
|
"CachedObject.h",
|
||||||
"CallbackTaskManager.cpp",
|
"CallbackTaskManager.cpp",
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
// Copyright 2021 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_native/BufferLocation.h"
|
|
||||||
|
|
||||||
namespace dawn_native {
|
|
||||||
|
|
||||||
BufferLocation::BufferLocation() = default;
|
|
||||||
|
|
||||||
BufferLocation::BufferLocation(BufferBase* buffer, uint64_t offset)
|
|
||||||
: mBuffer(buffer), mOffset(offset) {
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferLocation::~BufferLocation() = default;
|
|
||||||
|
|
||||||
// static
|
|
||||||
Ref<BufferLocation> BufferLocation::New() {
|
|
||||||
return AcquireRef(new BufferLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
Ref<BufferLocation> BufferLocation::New(BufferBase* buffer, uint64_t offset) {
|
|
||||||
return AcquireRef(new BufferLocation(buffer, offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BufferLocation::IsNull() const {
|
|
||||||
return mBuffer.Get() == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferBase* BufferLocation::GetBuffer() const {
|
|
||||||
return mBuffer.Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t BufferLocation::GetOffset() const {
|
|
||||||
return mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BufferLocation::Set(BufferBase* buffer, uint64_t offset) {
|
|
||||||
mBuffer = buffer;
|
|
||||||
mOffset = offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dawn_native
|
|
|
@ -1,49 +0,0 @@
|
||||||
// Copyright 2021 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.
|
|
||||||
|
|
||||||
#ifndef DAWNNATIVE_BUFFERLOCATION_H_
|
|
||||||
#define DAWNNATIVE_BUFFERLOCATION_H_
|
|
||||||
|
|
||||||
#include "common/RefCounted.h"
|
|
||||||
#include "dawn_native/Buffer.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace dawn_native {
|
|
||||||
|
|
||||||
// A ref-counted wrapper around a Buffer ref and an offset into the buffer.
|
|
||||||
class BufferLocation : public RefCounted {
|
|
||||||
public:
|
|
||||||
BufferLocation();
|
|
||||||
BufferLocation(BufferBase* buffer, uint64_t offset = 0);
|
|
||||||
~BufferLocation();
|
|
||||||
|
|
||||||
static Ref<BufferLocation> New();
|
|
||||||
static Ref<BufferLocation> New(BufferBase* buffer, uint64_t offset = 0);
|
|
||||||
|
|
||||||
bool IsNull() const;
|
|
||||||
|
|
||||||
BufferBase* GetBuffer() const;
|
|
||||||
uint64_t GetOffset() const;
|
|
||||||
|
|
||||||
void Set(BufferBase* buffer, uint64_t offset);
|
|
||||||
|
|
||||||
private:
|
|
||||||
Ref<BufferBase> mBuffer;
|
|
||||||
uint64_t mOffset = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dawn_native
|
|
||||||
|
|
||||||
#endif // DAWNNATIVE_BUFFERLOCATION_H_
|
|
|
@ -50,8 +50,6 @@ target_sources(dawn_native PRIVATE
|
||||||
"BuddyMemoryAllocator.h"
|
"BuddyMemoryAllocator.h"
|
||||||
"Buffer.cpp"
|
"Buffer.cpp"
|
||||||
"Buffer.h"
|
"Buffer.h"
|
||||||
"BufferLocation.cpp"
|
|
||||||
"BufferLocation.h"
|
|
||||||
"CachedObject.cpp"
|
"CachedObject.cpp"
|
||||||
"CachedObject.h"
|
"CachedObject.h"
|
||||||
"CallbackTaskManager.cpp"
|
"CallbackTaskManager.cpp"
|
||||||
|
|
|
@ -39,14 +39,6 @@ namespace dawn_native {
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferBase::DoNextSetValidatedBufferLocationsInternal() {
|
|
||||||
SetValidatedBufferLocationsInternalCmd* cmd =
|
|
||||||
mCommands.NextCommand<SetValidatedBufferLocationsInternalCmd>();
|
|
||||||
for (const DeferredBufferLocationUpdate& update : cmd->updates) {
|
|
||||||
update.location->Set(update.buffer.Get(), update.offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
CommandBufferBase* CommandBufferBase::MakeError(DeviceBase* device) {
|
CommandBufferBase* CommandBufferBase::MakeError(DeviceBase* device) {
|
||||||
return new CommandBufferBase(device, ObjectBase::kError);
|
return new CommandBufferBase(device, ObjectBase::kError);
|
||||||
|
|
|
@ -48,8 +48,6 @@ namespace dawn_native {
|
||||||
protected:
|
protected:
|
||||||
~CommandBufferBase() override;
|
~CommandBufferBase() override;
|
||||||
|
|
||||||
void DoNextSetValidatedBufferLocationsInternal();
|
|
||||||
|
|
||||||
CommandIterator mCommands;
|
CommandIterator mCommands;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1018,18 +1018,6 @@ namespace dawn_native {
|
||||||
return commandBuffer.Detach();
|
return commandBuffer.Detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandEncoder::EncodeSetValidatedBufferLocationsInternal(
|
|
||||||
std::vector<DeferredBufferLocationUpdate> updates) {
|
|
||||||
ASSERT(GetDevice()->IsValidationEnabled());
|
|
||||||
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
|
||||||
SetValidatedBufferLocationsInternalCmd* cmd =
|
|
||||||
allocator->Allocate<SetValidatedBufferLocationsInternalCmd>(
|
|
||||||
Command::SetValidatedBufferLocationsInternal);
|
|
||||||
cmd->updates = std::move(updates);
|
|
||||||
return {};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultOrError<Ref<CommandBufferBase>> CommandEncoder::FinishInternal(
|
ResultOrError<Ref<CommandBufferBase>> CommandEncoder::FinishInternal(
|
||||||
const CommandBufferDescriptor* descriptor) {
|
const CommandBufferDescriptor* descriptor) {
|
||||||
DeviceBase* device = GetDevice();
|
DeviceBase* device = GetDevice();
|
||||||
|
|
|
@ -78,9 +78,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
CommandBufferBase* APIFinish(const CommandBufferDescriptor* descriptor = nullptr);
|
CommandBufferBase* APIFinish(const CommandBufferDescriptor* descriptor = nullptr);
|
||||||
|
|
||||||
void EncodeSetValidatedBufferLocationsInternal(
|
|
||||||
std::vector<DeferredBufferLocationUpdate> updates);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ResultOrError<Ref<CommandBufferBase>> FinishInternal(
|
ResultOrError<Ref<CommandBufferBase>> FinishInternal(
|
||||||
const CommandBufferDescriptor* descriptor);
|
const CommandBufferDescriptor* descriptor);
|
||||||
|
|
|
@ -158,12 +158,6 @@ namespace dawn_native {
|
||||||
cmd->~SetStencilReferenceCmd();
|
cmd->~SetStencilReferenceCmd();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Command::SetValidatedBufferLocationsInternal: {
|
|
||||||
SetValidatedBufferLocationsInternalCmd* cmd =
|
|
||||||
commands->NextCommand<SetValidatedBufferLocationsInternalCmd>();
|
|
||||||
cmd->~SetValidatedBufferLocationsInternalCmd();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Command::SetViewport: {
|
case Command::SetViewport: {
|
||||||
SetViewportCmd* cmd = commands->NextCommand<SetViewportCmd>();
|
SetViewportCmd* cmd = commands->NextCommand<SetViewportCmd>();
|
||||||
cmd->~SetViewportCmd();
|
cmd->~SetViewportCmd();
|
||||||
|
@ -319,10 +313,6 @@ namespace dawn_native {
|
||||||
commands->NextCommand<SetStencilReferenceCmd>();
|
commands->NextCommand<SetStencilReferenceCmd>();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::SetValidatedBufferLocationsInternal:
|
|
||||||
commands->NextCommand<SetValidatedBufferLocationsInternalCmd>();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::SetViewport:
|
case Command::SetViewport:
|
||||||
commands->NextCommand<SetViewportCmd>();
|
commands->NextCommand<SetViewportCmd>();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
#include "dawn_native/AttachmentState.h"
|
#include "dawn_native/AttachmentState.h"
|
||||||
#include "dawn_native/BindingInfo.h"
|
#include "dawn_native/BindingInfo.h"
|
||||||
#include "dawn_native/BufferLocation.h"
|
|
||||||
#include "dawn_native/Texture.h"
|
#include "dawn_native/Texture.h"
|
||||||
|
|
||||||
#include "dawn_native/dawn_platform.h"
|
#include "dawn_native/dawn_platform.h"
|
||||||
|
@ -63,7 +62,6 @@ namespace dawn_native {
|
||||||
SetBlendConstant,
|
SetBlendConstant,
|
||||||
SetBindGroup,
|
SetBindGroup,
|
||||||
SetIndexBuffer,
|
SetIndexBuffer,
|
||||||
SetValidatedBufferLocationsInternal,
|
|
||||||
SetVertexBuffer,
|
SetVertexBuffer,
|
||||||
WriteBuffer,
|
WriteBuffer,
|
||||||
WriteTimestamp,
|
WriteTimestamp,
|
||||||
|
@ -179,7 +177,8 @@ namespace dawn_native {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DrawIndexedIndirectCmd {
|
struct DrawIndexedIndirectCmd {
|
||||||
Ref<BufferLocation> indirectBufferLocation;
|
Ref<BufferBase> indirectBuffer;
|
||||||
|
uint64_t indirectOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EndComputePassCmd {};
|
struct EndComputePassCmd {};
|
||||||
|
@ -225,16 +224,6 @@ namespace dawn_native {
|
||||||
uint32_t reference;
|
uint32_t reference;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeferredBufferLocationUpdate {
|
|
||||||
Ref<BufferLocation> location;
|
|
||||||
Ref<BufferBase> buffer;
|
|
||||||
uint64_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SetValidatedBufferLocationsInternalCmd {
|
|
||||||
std::vector<DeferredBufferLocationUpdate> updates;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SetViewportCmd {
|
struct SetViewportCmd {
|
||||||
float x, y, width, height, minDepth, maxDepth;
|
float x, y, width, height, minDepth, maxDepth;
|
||||||
};
|
};
|
||||||
|
|
|
@ -159,12 +159,11 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IndirectDrawMetadata::AddIndexedIndirectDraw(
|
void IndirectDrawMetadata::AddIndexedIndirectDraw(wgpu::IndexFormat indexFormat,
|
||||||
wgpu::IndexFormat indexFormat,
|
|
||||||
uint64_t indexBufferSize,
|
uint64_t indexBufferSize,
|
||||||
BufferBase* indirectBuffer,
|
BufferBase* indirectBuffer,
|
||||||
uint64_t indirectOffset,
|
uint64_t indirectOffset,
|
||||||
BufferLocation* drawCmdIndirectBufferLocation) {
|
DrawIndexedIndirectCmd* cmd) {
|
||||||
uint64_t numIndexBufferElements;
|
uint64_t numIndexBufferElements;
|
||||||
switch (indexFormat) {
|
switch (indexFormat) {
|
||||||
case wgpu::IndexFormat::Uint16:
|
case wgpu::IndexFormat::Uint16:
|
||||||
|
@ -187,7 +186,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
IndexedIndirectDraw draw;
|
IndexedIndirectDraw draw;
|
||||||
draw.clientBufferOffset = indirectOffset;
|
draw.clientBufferOffset = indirectOffset;
|
||||||
draw.bufferLocation = drawCmdIndirectBufferLocation;
|
draw.cmd = cmd;
|
||||||
it->second.AddIndexedIndirectDraw(mMaxDrawCallsPerBatch, mMaxBatchOffsetRange,
|
it->second.AddIndexedIndirectDraw(mMaxDrawCallsPerBatch, mMaxBatchOffsetRange,
|
||||||
std::move(draw));
|
std::move(draw));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "common/NonCopyable.h"
|
#include "common/NonCopyable.h"
|
||||||
#include "common/RefCounted.h"
|
#include "common/RefCounted.h"
|
||||||
#include "dawn_native/Buffer.h"
|
#include "dawn_native/Buffer.h"
|
||||||
#include "dawn_native/BufferLocation.h"
|
|
||||||
#include "dawn_native/CommandBufferStateTracker.h"
|
#include "dawn_native/CommandBufferStateTracker.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
|
||||||
|
@ -45,7 +44,10 @@ namespace dawn_native {
|
||||||
public:
|
public:
|
||||||
struct IndexedIndirectDraw {
|
struct IndexedIndirectDraw {
|
||||||
uint64_t clientBufferOffset;
|
uint64_t clientBufferOffset;
|
||||||
Ref<BufferLocation> bufferLocation;
|
// This is a pointer to the command that should be populated with the validated
|
||||||
|
// indirect scratch buffer. It is only valid up until the encoded command buffer
|
||||||
|
// is submitted.
|
||||||
|
DrawIndexedIndirectCmd* cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IndexedIndirectValidationBatch {
|
struct IndexedIndirectValidationBatch {
|
||||||
|
@ -109,7 +111,7 @@ namespace dawn_native {
|
||||||
uint64_t indexBufferSize,
|
uint64_t indexBufferSize,
|
||||||
BufferBase* indirectBuffer,
|
BufferBase* indirectBuffer,
|
||||||
uint64_t indirectOffset,
|
uint64_t indirectOffset,
|
||||||
BufferLocation* drawCmdIndirectBufferLocation);
|
DrawIndexedIndirectCmd* cmd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IndexedIndirectBufferValidationInfoMap mIndexedIndirectBufferValidationInfo;
|
IndexedIndirectBufferValidationInfoMap mIndexedIndirectBufferValidationInfo;
|
||||||
|
|
|
@ -226,7 +226,6 @@ namespace dawn_native {
|
||||||
// single pass as possible. Batches can be grouped together as long as they're validating
|
// single pass as possible. Batches can be grouped together as long as they're validating
|
||||||
// data from the same indirect buffer, but they may still be split into multiple passes if
|
// data from the same indirect buffer, but they may still be split into multiple passes if
|
||||||
// the number of draw calls in a pass would exceed some (very high) upper bound.
|
// the number of draw calls in a pass would exceed some (very high) upper bound.
|
||||||
uint64_t numTotalDrawCalls = 0;
|
|
||||||
size_t validatedParamsSize = 0;
|
size_t validatedParamsSize = 0;
|
||||||
std::vector<Pass> passes;
|
std::vector<Pass> passes;
|
||||||
IndirectDrawMetadata::IndexedIndirectBufferValidationInfoMap& bufferInfoMap =
|
IndirectDrawMetadata::IndexedIndirectBufferValidationInfoMap& bufferInfoMap =
|
||||||
|
@ -257,7 +256,6 @@ namespace dawn_native {
|
||||||
newBatch.clientIndirectOffset = minOffsetAlignedDown;
|
newBatch.clientIndirectOffset = minOffsetAlignedDown;
|
||||||
newBatch.clientIndirectSize =
|
newBatch.clientIndirectSize =
|
||||||
batch.maxOffset + kDrawIndexedIndirectSize - minOffsetAlignedDown;
|
batch.maxOffset + kDrawIndexedIndirectSize - minOffsetAlignedDown;
|
||||||
numTotalDrawCalls += batch.draws.size();
|
|
||||||
|
|
||||||
newBatch.validatedParamsSize = batch.draws.size() * kDrawIndexedIndirectSize;
|
newBatch.validatedParamsSize = batch.draws.size() * kDrawIndexedIndirectSize;
|
||||||
newBatch.validatedParamsOffset =
|
newBatch.validatedParamsOffset =
|
||||||
|
@ -306,10 +304,7 @@ namespace dawn_native {
|
||||||
DAWN_TRY(validatedParamsBuffer.EnsureCapacity(validatedParamsSize));
|
DAWN_TRY(validatedParamsBuffer.EnsureCapacity(validatedParamsSize));
|
||||||
usageTracker->BufferUsedAs(validatedParamsBuffer.GetBuffer(), wgpu::BufferUsage::Indirect);
|
usageTracker->BufferUsedAs(validatedParamsBuffer.GetBuffer(), wgpu::BufferUsage::Indirect);
|
||||||
|
|
||||||
// Now we allocate and populate host-side batch data to be copied to the GPU, and prepare to
|
// Now we allocate and populate host-side batch data to be copied to the GPU.
|
||||||
// update all DrawIndexedIndirectCmd buffer references.
|
|
||||||
std::vector<DeferredBufferLocationUpdate> deferredBufferLocationUpdates;
|
|
||||||
deferredBufferLocationUpdates.reserve(numTotalDrawCalls);
|
|
||||||
for (Pass& pass : passes) {
|
for (Pass& pass : passes) {
|
||||||
// We use std::malloc here because it guarantees maximal scalar alignment.
|
// We use std::malloc here because it guarantees maximal scalar alignment.
|
||||||
pass.batchData = {std::malloc(pass.batchDataSize), std::free};
|
pass.batchData = {std::malloc(pass.batchDataSize), std::free};
|
||||||
|
@ -322,16 +317,13 @@ namespace dawn_native {
|
||||||
|
|
||||||
uint32_t* indirectOffsets = reinterpret_cast<uint32_t*>(batch.batchInfo + 1);
|
uint32_t* indirectOffsets = reinterpret_cast<uint32_t*>(batch.batchInfo + 1);
|
||||||
uint64_t validatedParamsOffset = batch.validatedParamsOffset;
|
uint64_t validatedParamsOffset = batch.validatedParamsOffset;
|
||||||
for (const auto& draw : batch.metadata->draws) {
|
for (auto& draw : batch.metadata->draws) {
|
||||||
// The shader uses this to index an array of u32, hence the division by 4 bytes.
|
// The shader uses this to index an array of u32, hence the division by 4 bytes.
|
||||||
*indirectOffsets++ = static_cast<uint32_t>(
|
*indirectOffsets++ = static_cast<uint32_t>(
|
||||||
(draw.clientBufferOffset - batch.clientIndirectOffset) / 4);
|
(draw.clientBufferOffset - batch.clientIndirectOffset) / 4);
|
||||||
|
|
||||||
DeferredBufferLocationUpdate deferredUpdate;
|
draw.cmd->indirectBuffer = validatedParamsBuffer.GetBuffer();
|
||||||
deferredUpdate.location = draw.bufferLocation;
|
draw.cmd->indirectOffset = validatedParamsOffset;
|
||||||
deferredUpdate.buffer = validatedParamsBuffer.GetBuffer();
|
|
||||||
deferredUpdate.offset = validatedParamsOffset;
|
|
||||||
deferredBufferLocationUpdates.push_back(std::move(deferredUpdate));
|
|
||||||
|
|
||||||
validatedParamsOffset += kDrawIndexedIndirectSize;
|
validatedParamsOffset += kDrawIndexedIndirectSize;
|
||||||
}
|
}
|
||||||
|
@ -364,8 +356,6 @@ namespace dawn_native {
|
||||||
// Finally, we can now encode our validation passes. Each pass first does a single
|
// Finally, we can now encode our validation passes. Each pass first does a single
|
||||||
// WriteBuffer to get batch data over to the GPU, followed by a single compute pass. The
|
// WriteBuffer to get batch data over to the GPU, followed by a single compute pass. The
|
||||||
// compute pass encodes a separate SetBindGroup and Dispatch command for each batch.
|
// compute pass encodes a separate SetBindGroup and Dispatch command for each batch.
|
||||||
commandEncoder->EncodeSetValidatedBufferLocationsInternal(
|
|
||||||
std::move(deferredBufferLocationUpdates));
|
|
||||||
for (const Pass& pass : passes) {
|
for (const Pass& pass : passes) {
|
||||||
commandEncoder->APIWriteBuffer(batchDataBuffer.GetBuffer(), 0,
|
commandEncoder->APIWriteBuffer(batchDataBuffer.GetBuffer(), 0,
|
||||||
static_cast<const uint8_t*>(pass.batchData.get()),
|
static_cast<const uint8_t*>(pass.batchData.get()),
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
#include "common/Log.h"
|
#include "common/Log.h"
|
||||||
#include "dawn_native/Buffer.h"
|
#include "dawn_native/Buffer.h"
|
||||||
#include "dawn_native/BufferLocation.h"
|
|
||||||
#include "dawn_native/CommandEncoder.h"
|
#include "dawn_native/CommandEncoder.h"
|
||||||
#include "dawn_native/CommandValidation.h"
|
#include "dawn_native/CommandValidation.h"
|
||||||
#include "dawn_native/Commands.h"
|
#include "dawn_native/Commands.h"
|
||||||
|
@ -198,14 +197,20 @@ namespace dawn_native {
|
||||||
DrawIndexedIndirectCmd* cmd =
|
DrawIndexedIndirectCmd* cmd =
|
||||||
allocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect);
|
allocator->Allocate<DrawIndexedIndirectCmd>(Command::DrawIndexedIndirect);
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
cmd->indirectBufferLocation = BufferLocation::New();
|
// Later, EncodeIndirectDrawValidationCommands will allocate a scratch storage
|
||||||
|
// buffer which will store the validated indirect data. The buffer and offset
|
||||||
|
// will be updated to point to it.
|
||||||
|
// |EncodeIndirectDrawValidationCommands| is called at the end of encoding the
|
||||||
|
// render pass, while the |cmd| pointer is still valid.
|
||||||
|
cmd->indirectBuffer = nullptr;
|
||||||
|
|
||||||
mIndirectDrawMetadata.AddIndexedIndirectDraw(
|
mIndirectDrawMetadata.AddIndexedIndirectDraw(
|
||||||
mCommandBufferState.GetIndexFormat(),
|
mCommandBufferState.GetIndexFormat(),
|
||||||
mCommandBufferState.GetIndexBufferSize(), indirectBuffer, indirectOffset,
|
mCommandBufferState.GetIndexBufferSize(), indirectBuffer, indirectOffset,
|
||||||
cmd->indirectBufferLocation.Get());
|
cmd);
|
||||||
} else {
|
} else {
|
||||||
cmd->indirectBufferLocation =
|
cmd->indirectBuffer = indirectBuffer;
|
||||||
BufferLocation::New(indirectBuffer, indirectOffset);
|
cmd->indirectOffset = indirectOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(crbug.com/dawn/1166): Adding the indirectBuffer is needed for correct usage
|
// TODO(crbug.com/dawn/1166): Adding the indirectBuffer is needed for correct usage
|
||||||
|
|
|
@ -993,10 +993,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::SetValidatedBufferLocationsInternal:
|
|
||||||
DoNextSetValidatedBufferLocationsInternal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::WriteBuffer: {
|
case Command::WriteBuffer: {
|
||||||
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
||||||
const uint64_t offset = write->offset;
|
const uint64_t offset = write->offset;
|
||||||
|
@ -1414,7 +1410,6 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
ASSERT(!draw->indirectBufferLocation->IsNull());
|
|
||||||
|
|
||||||
DAWN_TRY(bindingTracker->Apply(commandContext));
|
DAWN_TRY(bindingTracker->Apply(commandContext));
|
||||||
vertexBufferTracker.Apply(commandList, lastPipeline);
|
vertexBufferTracker.Apply(commandList, lastPipeline);
|
||||||
|
@ -1423,12 +1418,13 @@ namespace dawn_native { namespace d3d12 {
|
||||||
// Zero the index offset values to avoid reusing values from the previous draw
|
// Zero the index offset values to avoid reusing values from the previous draw
|
||||||
RecordFirstIndexOffset(commandList, lastPipeline, 0, 0);
|
RecordFirstIndexOffset(commandList, lastPipeline, 0, 0);
|
||||||
|
|
||||||
Buffer* buffer = ToBackend(draw->indirectBufferLocation->GetBuffer());
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
|
ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
ComPtr<ID3D12CommandSignature> signature =
|
ComPtr<ID3D12CommandSignature> signature =
|
||||||
ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
|
ToBackend(GetDevice())->GetDrawIndexedIndirectSignature();
|
||||||
commandList->ExecuteIndirect(signature.Get(), 1, buffer->GetD3D12Resource(),
|
commandList->ExecuteIndirect(signature.Get(), 1, buffer->GetD3D12Resource(),
|
||||||
draw->indirectBufferLocation->GetOffset(), nullptr,
|
draw->indirectOffset, nullptr, 0);
|
||||||
0);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -986,10 +986,6 @@ namespace dawn_native { namespace metal {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::SetValidatedBufferLocationsInternal:
|
|
||||||
DoNextSetValidatedBufferLocationsInternal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::WriteBuffer: {
|
case Command::WriteBuffer: {
|
||||||
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
||||||
const uint64_t offset = write->offset;
|
const uint64_t offset = write->offset;
|
||||||
|
@ -1341,15 +1337,16 @@ namespace dawn_native { namespace metal {
|
||||||
bindGroups.Apply(encoder);
|
bindGroups.Apply(encoder);
|
||||||
storageBufferLengths.Apply(encoder, lastPipeline, enableVertexPulling);
|
storageBufferLengths.Apply(encoder, lastPipeline, enableVertexPulling);
|
||||||
|
|
||||||
ASSERT(!draw->indirectBufferLocation->IsNull());
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
Buffer* buffer = ToBackend(draw->indirectBufferLocation->GetBuffer());
|
ASSERT(buffer != nullptr);
|
||||||
|
|
||||||
id<MTLBuffer> indirectBuffer = buffer->GetMTLBuffer();
|
id<MTLBuffer> indirectBuffer = buffer->GetMTLBuffer();
|
||||||
[encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
[encoder drawIndexedPrimitives:lastPipeline->GetMTLPrimitiveTopology()
|
||||||
indexType:indexBufferType
|
indexType:indexBufferType
|
||||||
indexBuffer:indexBuffer
|
indexBuffer:indexBuffer
|
||||||
indexBufferOffset:indexBufferBaseOffset
|
indexBufferOffset:indexBufferBaseOffset
|
||||||
indirectBuffer:indirectBuffer
|
indirectBuffer:indirectBuffer
|
||||||
indirectBufferOffset:draw->indirectBufferLocation->GetOffset()];
|
indirectBufferOffset:draw->indirectOffset];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -844,10 +844,6 @@ namespace dawn_native { namespace opengl {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::SetValidatedBufferLocationsInternal:
|
|
||||||
DoNextSetValidatedBufferLocationsInternal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::WriteBuffer: {
|
case Command::WriteBuffer: {
|
||||||
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
||||||
uint64_t offset = write->offset;
|
uint64_t offset = write->offset;
|
||||||
|
@ -1187,17 +1183,17 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
ASSERT(!draw->indirectBufferLocation->IsNull());
|
|
||||||
|
|
||||||
vertexStateBufferBindingTracker.Apply(gl);
|
vertexStateBufferBindingTracker.Apply(gl);
|
||||||
bindGroupTracker.Apply(gl);
|
bindGroupTracker.Apply(gl);
|
||||||
|
|
||||||
Buffer* indirectBuffer = ToBackend(draw->indirectBufferLocation->GetBuffer());
|
Buffer* indirectBuffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
|
ASSERT(indirectBuffer != nullptr);
|
||||||
|
|
||||||
gl.BindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle());
|
gl.BindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer->GetHandle());
|
||||||
gl.DrawElementsIndirect(
|
gl.DrawElementsIndirect(
|
||||||
lastPipeline->GetGLPrimitiveTopology(), indexBufferFormat,
|
lastPipeline->GetGLPrimitiveTopology(), indexBufferFormat,
|
||||||
reinterpret_cast<void*>(
|
reinterpret_cast<void*>(static_cast<intptr_t>(draw->indirectOffset)));
|
||||||
static_cast<intptr_t>(draw->indirectBufferLocation->GetOffset())));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -826,10 +826,6 @@ namespace dawn_native { namespace vulkan {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Command::SetValidatedBufferLocationsInternal:
|
|
||||||
DoNextSetValidatedBufferLocationsInternal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Command::WriteBuffer: {
|
case Command::WriteBuffer: {
|
||||||
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
WriteBufferCmd* write = mCommands.NextCommand<WriteBufferCmd>();
|
||||||
const uint64_t offset = write->offset;
|
const uint64_t offset = write->offset;
|
||||||
|
@ -1075,10 +1071,10 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
VkBuffer indirectBuffer = ToBackend(draw->indirectBuffer)->GetHandle();
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
|
|
||||||
descriptorSets.Apply(device, recordingContext, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Apply(device, recordingContext, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
device->fn.CmdDrawIndirect(commands, indirectBuffer,
|
device->fn.CmdDrawIndirect(commands, buffer->GetHandle(),
|
||||||
static_cast<VkDeviceSize>(draw->indirectOffset), 1,
|
static_cast<VkDeviceSize>(draw->indirectOffset), 1,
|
||||||
0);
|
0);
|
||||||
break;
|
break;
|
||||||
|
@ -1086,14 +1082,13 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
ASSERT(!draw->indirectBufferLocation->IsNull());
|
Buffer* buffer = ToBackend(draw->indirectBuffer.Get());
|
||||||
VkBuffer indirectBuffer =
|
ASSERT(buffer != nullptr);
|
||||||
ToBackend(draw->indirectBufferLocation->GetBuffer())->GetHandle();
|
|
||||||
|
|
||||||
descriptorSets.Apply(device, recordingContext, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
descriptorSets.Apply(device, recordingContext, VK_PIPELINE_BIND_POINT_GRAPHICS);
|
||||||
device->fn.CmdDrawIndexedIndirect(
|
device->fn.CmdDrawIndexedIndirect(
|
||||||
commands, indirectBuffer,
|
commands, buffer->GetHandle(),
|
||||||
static_cast<VkDeviceSize>(draw->indirectBufferLocation->GetOffset()), 1, 0);
|
static_cast<VkDeviceSize>(draw->indirectOffset), 1, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue