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>
This commit is contained in:
parent
3b49f247b0
commit
95ff834028
|
@ -503,6 +503,7 @@ namespace dawn_native {
|
|||
|
||||
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 @@ namespace dawn_native {
|
|||
allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
|
||||
|
||||
cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
|
||||
attachmentState = cmd->attachmentState;
|
||||
|
||||
for (ColorAttachmentIndex index :
|
||||
IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
|
||||
|
@ -565,9 +567,9 @@ namespace dawn_native {
|
|||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace dawn_native {
|
|||
inline MaybeError ValidateRenderBundleCommand(CommandIterator* commands,
|
||||
Command type,
|
||||
CommandBufferStateTracker* commandBufferState,
|
||||
const AttachmentState* attachmentState,
|
||||
const char* disallowedMessage) {
|
||||
switch (type) {
|
||||
case Command::Draw: {
|
||||
|
@ -79,10 +78,6 @@ namespace dawn_native {
|
|||
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 dawn_native {
|
|||
|
||||
} // 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 @@ namespace dawn_native {
|
|||
|
||||
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 @@ namespace dawn_native {
|
|||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,7 @@ namespace dawn_native {
|
|||
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);
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ namespace dawn_native {
|
|||
|
||||
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)) {
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ namespace dawn_native {
|
|||
public:
|
||||
RenderBundleBase(RenderBundleEncoder* encoder,
|
||||
const RenderBundleDescriptor* descriptor,
|
||||
AttachmentState* attachmentState,
|
||||
Ref<AttachmentState> attachmentState,
|
||||
PassResourceUsage resourceUsage);
|
||||
|
||||
static RenderBundleBase* MakeError(DeviceBase* device);
|
||||
|
|
|
@ -79,9 +79,10 @@ namespace dawn_native {
|
|||
|
||||
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 @@ namespace dawn_native {
|
|||
return new RenderBundleEncoder(device, ObjectBase::kError);
|
||||
}
|
||||
|
||||
const AttachmentState* RenderBundleEncoder::GetAttachmentState() const {
|
||||
return mAttachmentState.Get();
|
||||
}
|
||||
|
||||
CommandIterator RenderBundleEncoder::AcquireCommands() {
|
||||
return mBundleEncodingContext.AcquireCommands();
|
||||
}
|
||||
|
@ -126,7 +123,7 @@ namespace dawn_native {
|
|||
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 @@ namespace dawn_native {
|
|||
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 {};
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ namespace dawn_native {
|
|||
|
||||
static RenderBundleEncoder* MakeError(DeviceBase* device);
|
||||
|
||||
const AttachmentState* GetAttachmentState() const;
|
||||
|
||||
RenderBundleBase* Finish(const RenderBundleDescriptor* descriptor);
|
||||
|
||||
CommandIterator AcquireCommands();
|
||||
|
@ -46,7 +43,6 @@ namespace dawn_native {
|
|||
MaybeError ValidateFinish(CommandIterator* commands, const PassResourceUsage& usages) const;
|
||||
|
||||
EncodingContext mBundleEncodingContext;
|
||||
Ref<AttachmentState> mAttachmentState;
|
||||
};
|
||||
} // namespace dawn_native
|
||||
|
||||
|
|
|
@ -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 @@ namespace dawn_native {
|
|||
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 @@ namespace dawn_native {
|
|||
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 =
|
||||
|
|
|
@ -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 @@ namespace dawn_native {
|
|||
|
||||
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 @@ namespace dawn_native {
|
|||
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;
|
||||
};
|
||||
|
|
|
@ -52,10 +52,11 @@ namespace dawn_native {
|
|||
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 @@ namespace dawn_native {
|
|||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ namespace dawn_native {
|
|||
CommandEncoder* commandEncoder,
|
||||
EncodingContext* encodingContext,
|
||||
PassResourceUsageTracker usageTracker,
|
||||
Ref<AttachmentState> attachmentState,
|
||||
QuerySetBase* occlusionQuerySet,
|
||||
uint32_t renderTargetWidth,
|
||||
uint32_t renderTargetHeight);
|
||||
|
|
Loading…
Reference in New Issue