dawn_native: Do attachment state validation at encoding time.
The overarching goal with this CL is to do validation at encoding time
which will help produce SyncScopeResourceUsage in the frontend for
dispatch() calls so that they can be reused by the backends.
Bug: dawn:635
Change-Id: Ifb8b7883abe18089dc3d632baebbcc79b3f324f7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38843
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp
index 5ccfdc3d..d6d2de1 100644
--- a/src/dawn_native/CommandEncoder.cpp
+++ b/src/dawn_native/CommandEncoder.cpp
@@ -503,6 +503,7 @@
uint32_t width = 0;
uint32_t height = 0;
+ Ref<AttachmentState> attachmentState;
bool success =
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
uint32_t sampleCount = 0;
@@ -516,6 +517,7 @@
allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
+ attachmentState = cmd->attachmentState;
for (ColorAttachmentIndex index :
IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
@@ -565,9 +567,9 @@
});
if (success) {
- RenderPassEncoder* passEncoder =
- new RenderPassEncoder(device, this, &mEncodingContext, std::move(usageTracker),
- descriptor->occlusionQuerySet, width, height);
+ RenderPassEncoder* passEncoder = new RenderPassEncoder(
+ device, this, &mEncodingContext, std::move(usageTracker),
+ std::move(attachmentState), descriptor->occlusionQuerySet, width, height);
mEncodingContext.EnterPass(passEncoder);
return passEncoder;
}
diff --git a/src/dawn_native/CommandValidation.cpp b/src/dawn_native/CommandValidation.cpp
index d28bf2c..e461382 100644
--- a/src/dawn_native/CommandValidation.cpp
+++ b/src/dawn_native/CommandValidation.cpp
@@ -32,7 +32,6 @@
inline MaybeError ValidateRenderBundleCommand(CommandIterator* commands,
Command type,
CommandBufferStateTracker* commandBufferState,
- const AttachmentState* attachmentState,
const char* disallowedMessage) {
switch (type) {
case Command::Draw: {
@@ -79,10 +78,6 @@
case Command::SetRenderPipeline: {
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
RenderPipelineBase* pipeline = cmd->pipeline.Get();
-
- if (DAWN_UNLIKELY(pipeline->GetAttachmentState() != attachmentState)) {
- return DAWN_VALIDATION_ERROR("Pipeline attachment state is not compatible");
- }
commandBufferState->SetRenderPipeline(pipeline);
break;
}
@@ -118,13 +113,11 @@
} // namespace
- MaybeError ValidateRenderBundle(CommandIterator* commands,
- const AttachmentState* attachmentState) {
+ MaybeError ValidateRenderBundle(CommandIterator* commands) {
CommandBufferStateTracker commandBufferState;
Command type;
while (commands->NextCommandId(&type)) {
DAWN_TRY(ValidateRenderBundleCommand(commands, type, &commandBufferState,
- attachmentState,
"Command disallowed inside a render bundle"));
}
@@ -153,14 +146,7 @@
case Command::ExecuteBundles: {
ExecuteBundlesCmd* cmd = commands->NextCommand<ExecuteBundlesCmd>();
- auto bundles = commands->NextData<Ref<RenderBundleBase>>(cmd->count);
- for (uint32_t i = 0; i < cmd->count; ++i) {
- if (DAWN_UNLIKELY(renderPass->attachmentState.Get() !=
- bundles[i]->GetAttachmentState())) {
- return DAWN_VALIDATION_ERROR(
- "Render bundle is not compatible with render pass");
- }
- }
+ commands->NextData<Ref<RenderBundleBase>>(cmd->count);
if (cmd->count > 0) {
// Reset state. It is invalidated after render bundle execution.
@@ -196,9 +182,9 @@
}
default:
- DAWN_TRY(ValidateRenderBundleCommand(
- commands, type, &commandBufferState, renderPass->attachmentState.Get(),
- "Command disallowed inside a render pass"));
+ DAWN_TRY(
+ ValidateRenderBundleCommand(commands, type, &commandBufferState,
+ "Command disallowed inside a render pass"));
}
}
diff --git a/src/dawn_native/CommandValidation.h b/src/dawn_native/CommandValidation.h
index d1deed4..26db8b4 100644
--- a/src/dawn_native/CommandValidation.h
+++ b/src/dawn_native/CommandValidation.h
@@ -29,8 +29,7 @@
struct PassResourceUsage;
struct TexelBlockInfo;
- MaybeError ValidateRenderBundle(CommandIterator* commands,
- const AttachmentState* attachmentState);
+ MaybeError ValidateRenderBundle(CommandIterator* commands);
MaybeError ValidateRenderPass(CommandIterator* commands, const BeginRenderPassCmd* renderPass);
MaybeError ValidateComputePass(CommandIterator* commands);
diff --git a/src/dawn_native/RenderBundle.cpp b/src/dawn_native/RenderBundle.cpp
index b347886..930eb6e 100644
--- a/src/dawn_native/RenderBundle.cpp
+++ b/src/dawn_native/RenderBundle.cpp
@@ -23,11 +23,11 @@
RenderBundleBase::RenderBundleBase(RenderBundleEncoder* encoder,
const RenderBundleDescriptor* descriptor,
- AttachmentState* attachmentState,
+ Ref<AttachmentState> attachmentState,
PassResourceUsage resourceUsage)
: ObjectBase(encoder->GetDevice()),
mCommands(encoder->AcquireCommands()),
- mAttachmentState(attachmentState),
+ mAttachmentState(std::move(attachmentState)),
mResourceUsage(std::move(resourceUsage)) {
}
diff --git a/src/dawn_native/RenderBundle.h b/src/dawn_native/RenderBundle.h
index ed80c69..312954e 100644
--- a/src/dawn_native/RenderBundle.h
+++ b/src/dawn_native/RenderBundle.h
@@ -36,7 +36,7 @@
public:
RenderBundleBase(RenderBundleEncoder* encoder,
const RenderBundleDescriptor* descriptor,
- AttachmentState* attachmentState,
+ Ref<AttachmentState> attachmentState,
PassResourceUsage resourceUsage);
static RenderBundleBase* MakeError(DeviceBase* device);
diff --git a/src/dawn_native/RenderBundleEncoder.cpp b/src/dawn_native/RenderBundleEncoder.cpp
index aedcfff..fbc03d3 100644
--- a/src/dawn_native/RenderBundleEncoder.cpp
+++ b/src/dawn_native/RenderBundleEncoder.cpp
@@ -79,9 +79,10 @@
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device,
const RenderBundleEncoderDescriptor* descriptor)
- : RenderEncoderBase(device, &mBundleEncodingContext),
- mBundleEncodingContext(device, this),
- mAttachmentState(device->GetOrCreateAttachmentState(descriptor)) {
+ : RenderEncoderBase(device,
+ &mBundleEncodingContext,
+ device->GetOrCreateAttachmentState(descriptor)),
+ mBundleEncodingContext(device, this) {
}
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag)
@@ -94,10 +95,6 @@
return new RenderBundleEncoder(device, ObjectBase::kError);
}
- const AttachmentState* RenderBundleEncoder::GetAttachmentState() const {
- return mAttachmentState.Get();
- }
-
CommandIterator RenderBundleEncoder::AcquireCommands() {
return mBundleEncodingContext.AcquireCommands();
}
@@ -126,7 +123,7 @@
DAWN_TRY(ValidateFinish(mBundleEncodingContext.GetIterator(), usages));
}
- return new RenderBundleBase(this, descriptor, mAttachmentState.Get(), std::move(usages));
+ return new RenderBundleBase(this, descriptor, AcquireAttachmentState(), std::move(usages));
}
MaybeError RenderBundleEncoder::ValidateFinish(CommandIterator* commands,
@@ -134,7 +131,7 @@
TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "RenderBundleEncoder::ValidateFinish");
DAWN_TRY(GetDevice()->ValidateObject(this));
DAWN_TRY(ValidatePassResourceUsage(usages));
- DAWN_TRY(ValidateRenderBundle(commands, mAttachmentState.Get()));
+ DAWN_TRY(ValidateRenderBundle(commands));
return {};
}
diff --git a/src/dawn_native/RenderBundleEncoder.h b/src/dawn_native/RenderBundleEncoder.h
index bc9aaac..0bd63fb 100644
--- a/src/dawn_native/RenderBundleEncoder.h
+++ b/src/dawn_native/RenderBundleEncoder.h
@@ -15,7 +15,6 @@
#ifndef DAWNNATIVE_RENDERBUNDLEENCODER_H_
#define DAWNNATIVE_RENDERBUNDLEENCODER_H_
-#include "dawn_native/AttachmentState.h"
#include "dawn_native/EncodingContext.h"
#include "dawn_native/Error.h"
#include "dawn_native/RenderBundle.h"
@@ -33,8 +32,6 @@
static RenderBundleEncoder* MakeError(DeviceBase* device);
- const AttachmentState* GetAttachmentState() const;
-
RenderBundleBase* Finish(const RenderBundleDescriptor* descriptor);
CommandIterator AcquireCommands();
@@ -46,7 +43,6 @@
MaybeError ValidateFinish(CommandIterator* commands, const PassResourceUsage& usages) const;
EncodingContext mBundleEncodingContext;
- Ref<AttachmentState> mAttachmentState;
};
} // namespace dawn_native
diff --git a/src/dawn_native/RenderEncoderBase.cpp b/src/dawn_native/RenderEncoderBase.cpp
index 5d029ae..18d587c 100644
--- a/src/dawn_native/RenderEncoderBase.cpp
+++ b/src/dawn_native/RenderEncoderBase.cpp
@@ -28,8 +28,11 @@
namespace dawn_native {
- RenderEncoderBase::RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext)
+ RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
+ EncodingContext* encodingContext,
+ Ref<AttachmentState> attachmentState)
: ProgrammablePassEncoder(device, encodingContext, PassType::Render),
+ mAttachmentState(std::move(attachmentState)),
mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
}
@@ -42,6 +45,16 @@
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
}
+ const AttachmentState* RenderEncoderBase::GetAttachmentState() const {
+ ASSERT(!IsError());
+ ASSERT(mAttachmentState != nullptr);
+ return mAttachmentState.Get();
+ }
+
+ Ref<AttachmentState> RenderEncoderBase::AcquireAttachmentState() {
+ return std::move(mAttachmentState);
+ }
+
void RenderEncoderBase::Draw(uint32_t vertexCount,
uint32_t instanceCount,
uint32_t firstVertex,
@@ -157,6 +170,12 @@
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
if (IsValidationEnabled()) {
DAWN_TRY(GetDevice()->ValidateObject(pipeline));
+
+ if (pipeline->GetAttachmentState() != mAttachmentState.Get()) {
+ return DAWN_VALIDATION_ERROR(
+ "Pipeline attachment state is not compatible with render encoder "
+ "attachment state");
+ }
}
SetRenderPipelineCmd* cmd =
diff --git a/src/dawn_native/RenderEncoderBase.h b/src/dawn_native/RenderEncoderBase.h
index 9e21740..8025f74 100644
--- a/src/dawn_native/RenderEncoderBase.h
+++ b/src/dawn_native/RenderEncoderBase.h
@@ -15,6 +15,7 @@
#ifndef DAWNNATIVE_RENDERENCODERBASE_H_
#define DAWNNATIVE_RENDERENCODERBASE_H_
+#include "dawn_native/AttachmentState.h"
#include "dawn_native/Error.h"
#include "dawn_native/ProgrammablePassEncoder.h"
@@ -22,7 +23,9 @@
class RenderEncoderBase : public ProgrammablePassEncoder {
public:
- RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext);
+ RenderEncoderBase(DeviceBase* device,
+ EncodingContext* encodingContext,
+ Ref<AttachmentState> attachmentState);
void Draw(uint32_t vertexCount,
uint32_t instanceCount = 1,
@@ -47,11 +50,15 @@
void SetIndexBufferWithFormat(BufferBase* buffer, wgpu::IndexFormat format, uint64_t offset,
uint64_t size);
+ const AttachmentState* GetAttachmentState() const;
+ Ref<AttachmentState> AcquireAttachmentState();
+
protected:
// Construct an "error" render encoder base.
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext, ErrorTag errorTag);
private:
+ Ref<AttachmentState> mAttachmentState;
const bool mDisableBaseVertex;
const bool mDisableBaseInstance;
};
diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp
index d7f168e..dbc0463 100644
--- a/src/dawn_native/RenderPassEncoder.cpp
+++ b/src/dawn_native/RenderPassEncoder.cpp
@@ -52,10 +52,11 @@
CommandEncoder* commandEncoder,
EncodingContext* encodingContext,
PassResourceUsageTracker usageTracker,
+ Ref<AttachmentState> attachmentState,
QuerySetBase* occlusionQuerySet,
uint32_t renderTargetWidth,
uint32_t renderTargetHeight)
- : RenderEncoderBase(device, encodingContext),
+ : RenderEncoderBase(device, encodingContext, std::move(attachmentState)),
mCommandEncoder(commandEncoder),
mRenderTargetWidth(renderTargetWidth),
mRenderTargetHeight(renderTargetHeight),
@@ -198,6 +199,12 @@
if (IsValidationEnabled()) {
for (uint32_t i = 0; i < count; ++i) {
DAWN_TRY(GetDevice()->ValidateObject(renderBundles[i]));
+
+ if (GetAttachmentState() != renderBundles[i]->GetAttachmentState()) {
+ return DAWN_VALIDATION_ERROR(
+ "Render bundle attachment state is not compatible with render pass "
+ "attachment state");
+ }
}
}
diff --git a/src/dawn_native/RenderPassEncoder.h b/src/dawn_native/RenderPassEncoder.h
index 289990a..abae193 100644
--- a/src/dawn_native/RenderPassEncoder.h
+++ b/src/dawn_native/RenderPassEncoder.h
@@ -28,6 +28,7 @@
CommandEncoder* commandEncoder,
EncodingContext* encodingContext,
PassResourceUsageTracker usageTracker,
+ Ref<AttachmentState> attachmentState,
QuerySetBase* occlusionQuerySet,
uint32_t renderTargetWidth,
uint32_t renderTargetHeight);