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 width = 0;
|
||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
|
Ref<AttachmentState> attachmentState;
|
||||||
bool success =
|
bool success =
|
||||||
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
mEncodingContext.TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
||||||
uint32_t sampleCount = 0;
|
uint32_t sampleCount = 0;
|
||||||
|
@ -516,6 +517,7 @@ namespace dawn_native {
|
||||||
allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
|
allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
|
||||||
|
|
||||||
cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
|
cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
|
||||||
|
attachmentState = cmd->attachmentState;
|
||||||
|
|
||||||
for (ColorAttachmentIndex index :
|
for (ColorAttachmentIndex index :
|
||||||
IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
|
IterateBitSet(cmd->attachmentState->GetColorAttachmentsMask())) {
|
||||||
|
@ -565,9 +567,9 @@ namespace dawn_native {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
RenderPassEncoder* passEncoder =
|
RenderPassEncoder* passEncoder = new RenderPassEncoder(
|
||||||
new RenderPassEncoder(device, this, &mEncodingContext, std::move(usageTracker),
|
device, this, &mEncodingContext, std::move(usageTracker),
|
||||||
descriptor->occlusionQuerySet, width, height);
|
std::move(attachmentState), descriptor->occlusionQuerySet, width, height);
|
||||||
mEncodingContext.EnterPass(passEncoder);
|
mEncodingContext.EnterPass(passEncoder);
|
||||||
return passEncoder;
|
return passEncoder;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,6 @@ namespace dawn_native {
|
||||||
inline MaybeError ValidateRenderBundleCommand(CommandIterator* commands,
|
inline MaybeError ValidateRenderBundleCommand(CommandIterator* commands,
|
||||||
Command type,
|
Command type,
|
||||||
CommandBufferStateTracker* commandBufferState,
|
CommandBufferStateTracker* commandBufferState,
|
||||||
const AttachmentState* attachmentState,
|
|
||||||
const char* disallowedMessage) {
|
const char* disallowedMessage) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
|
@ -79,10 +78,6 @@ namespace dawn_native {
|
||||||
case Command::SetRenderPipeline: {
|
case Command::SetRenderPipeline: {
|
||||||
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = commands->NextCommand<SetRenderPipelineCmd>();
|
||||||
RenderPipelineBase* pipeline = cmd->pipeline.Get();
|
RenderPipelineBase* pipeline = cmd->pipeline.Get();
|
||||||
|
|
||||||
if (DAWN_UNLIKELY(pipeline->GetAttachmentState() != attachmentState)) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Pipeline attachment state is not compatible");
|
|
||||||
}
|
|
||||||
commandBufferState->SetRenderPipeline(pipeline);
|
commandBufferState->SetRenderPipeline(pipeline);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -118,13 +113,11 @@ namespace dawn_native {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MaybeError ValidateRenderBundle(CommandIterator* commands,
|
MaybeError ValidateRenderBundle(CommandIterator* commands) {
|
||||||
const AttachmentState* attachmentState) {
|
|
||||||
CommandBufferStateTracker commandBufferState;
|
CommandBufferStateTracker commandBufferState;
|
||||||
Command type;
|
Command type;
|
||||||
while (commands->NextCommandId(&type)) {
|
while (commands->NextCommandId(&type)) {
|
||||||
DAWN_TRY(ValidateRenderBundleCommand(commands, type, &commandBufferState,
|
DAWN_TRY(ValidateRenderBundleCommand(commands, type, &commandBufferState,
|
||||||
attachmentState,
|
|
||||||
"Command disallowed inside a render bundle"));
|
"Command disallowed inside a render bundle"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,14 +146,7 @@ namespace dawn_native {
|
||||||
|
|
||||||
case Command::ExecuteBundles: {
|
case Command::ExecuteBundles: {
|
||||||
ExecuteBundlesCmd* cmd = commands->NextCommand<ExecuteBundlesCmd>();
|
ExecuteBundlesCmd* cmd = commands->NextCommand<ExecuteBundlesCmd>();
|
||||||
auto bundles = commands->NextData<Ref<RenderBundleBase>>(cmd->count);
|
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cmd->count > 0) {
|
if (cmd->count > 0) {
|
||||||
// Reset state. It is invalidated after render bundle execution.
|
// Reset state. It is invalidated after render bundle execution.
|
||||||
|
@ -196,9 +182,9 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DAWN_TRY(ValidateRenderBundleCommand(
|
DAWN_TRY(
|
||||||
commands, type, &commandBufferState, renderPass->attachmentState.Get(),
|
ValidateRenderBundleCommand(commands, type, &commandBufferState,
|
||||||
"Command disallowed inside a render pass"));
|
"Command disallowed inside a render pass"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,7 @@ namespace dawn_native {
|
||||||
struct PassResourceUsage;
|
struct PassResourceUsage;
|
||||||
struct TexelBlockInfo;
|
struct TexelBlockInfo;
|
||||||
|
|
||||||
MaybeError ValidateRenderBundle(CommandIterator* commands,
|
MaybeError ValidateRenderBundle(CommandIterator* commands);
|
||||||
const AttachmentState* attachmentState);
|
|
||||||
MaybeError ValidateRenderPass(CommandIterator* commands, const BeginRenderPassCmd* renderPass);
|
MaybeError ValidateRenderPass(CommandIterator* commands, const BeginRenderPassCmd* renderPass);
|
||||||
MaybeError ValidateComputePass(CommandIterator* commands);
|
MaybeError ValidateComputePass(CommandIterator* commands);
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,11 @@ namespace dawn_native {
|
||||||
|
|
||||||
RenderBundleBase::RenderBundleBase(RenderBundleEncoder* encoder,
|
RenderBundleBase::RenderBundleBase(RenderBundleEncoder* encoder,
|
||||||
const RenderBundleDescriptor* descriptor,
|
const RenderBundleDescriptor* descriptor,
|
||||||
AttachmentState* attachmentState,
|
Ref<AttachmentState> attachmentState,
|
||||||
PassResourceUsage resourceUsage)
|
PassResourceUsage resourceUsage)
|
||||||
: ObjectBase(encoder->GetDevice()),
|
: ObjectBase(encoder->GetDevice()),
|
||||||
mCommands(encoder->AcquireCommands()),
|
mCommands(encoder->AcquireCommands()),
|
||||||
mAttachmentState(attachmentState),
|
mAttachmentState(std::move(attachmentState)),
|
||||||
mResourceUsage(std::move(resourceUsage)) {
|
mResourceUsage(std::move(resourceUsage)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace dawn_native {
|
||||||
public:
|
public:
|
||||||
RenderBundleBase(RenderBundleEncoder* encoder,
|
RenderBundleBase(RenderBundleEncoder* encoder,
|
||||||
const RenderBundleDescriptor* descriptor,
|
const RenderBundleDescriptor* descriptor,
|
||||||
AttachmentState* attachmentState,
|
Ref<AttachmentState> attachmentState,
|
||||||
PassResourceUsage resourceUsage);
|
PassResourceUsage resourceUsage);
|
||||||
|
|
||||||
static RenderBundleBase* MakeError(DeviceBase* device);
|
static RenderBundleBase* MakeError(DeviceBase* device);
|
||||||
|
|
|
@ -79,9 +79,10 @@ namespace dawn_native {
|
||||||
|
|
||||||
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device,
|
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device,
|
||||||
const RenderBundleEncoderDescriptor* descriptor)
|
const RenderBundleEncoderDescriptor* descriptor)
|
||||||
: RenderEncoderBase(device, &mBundleEncodingContext),
|
: RenderEncoderBase(device,
|
||||||
mBundleEncodingContext(device, this),
|
&mBundleEncodingContext,
|
||||||
mAttachmentState(device->GetOrCreateAttachmentState(descriptor)) {
|
device->GetOrCreateAttachmentState(descriptor)),
|
||||||
|
mBundleEncodingContext(device, this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag)
|
RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag)
|
||||||
|
@ -94,10 +95,6 @@ namespace dawn_native {
|
||||||
return new RenderBundleEncoder(device, ObjectBase::kError);
|
return new RenderBundleEncoder(device, ObjectBase::kError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AttachmentState* RenderBundleEncoder::GetAttachmentState() const {
|
|
||||||
return mAttachmentState.Get();
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandIterator RenderBundleEncoder::AcquireCommands() {
|
CommandIterator RenderBundleEncoder::AcquireCommands() {
|
||||||
return mBundleEncodingContext.AcquireCommands();
|
return mBundleEncodingContext.AcquireCommands();
|
||||||
}
|
}
|
||||||
|
@ -126,7 +123,7 @@ namespace dawn_native {
|
||||||
DAWN_TRY(ValidateFinish(mBundleEncodingContext.GetIterator(), usages));
|
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,
|
MaybeError RenderBundleEncoder::ValidateFinish(CommandIterator* commands,
|
||||||
|
@ -134,7 +131,7 @@ namespace dawn_native {
|
||||||
TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "RenderBundleEncoder::ValidateFinish");
|
TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "RenderBundleEncoder::ValidateFinish");
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(this));
|
DAWN_TRY(GetDevice()->ValidateObject(this));
|
||||||
DAWN_TRY(ValidatePassResourceUsage(usages));
|
DAWN_TRY(ValidatePassResourceUsage(usages));
|
||||||
DAWN_TRY(ValidateRenderBundle(commands, mAttachmentState.Get()));
|
DAWN_TRY(ValidateRenderBundle(commands));
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#ifndef DAWNNATIVE_RENDERBUNDLEENCODER_H_
|
#ifndef DAWNNATIVE_RENDERBUNDLEENCODER_H_
|
||||||
#define DAWNNATIVE_RENDERBUNDLEENCODER_H_
|
#define DAWNNATIVE_RENDERBUNDLEENCODER_H_
|
||||||
|
|
||||||
#include "dawn_native/AttachmentState.h"
|
|
||||||
#include "dawn_native/EncodingContext.h"
|
#include "dawn_native/EncodingContext.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/RenderBundle.h"
|
#include "dawn_native/RenderBundle.h"
|
||||||
|
@ -33,8 +32,6 @@ namespace dawn_native {
|
||||||
|
|
||||||
static RenderBundleEncoder* MakeError(DeviceBase* device);
|
static RenderBundleEncoder* MakeError(DeviceBase* device);
|
||||||
|
|
||||||
const AttachmentState* GetAttachmentState() const;
|
|
||||||
|
|
||||||
RenderBundleBase* Finish(const RenderBundleDescriptor* descriptor);
|
RenderBundleBase* Finish(const RenderBundleDescriptor* descriptor);
|
||||||
|
|
||||||
CommandIterator AcquireCommands();
|
CommandIterator AcquireCommands();
|
||||||
|
@ -46,7 +43,6 @@ namespace dawn_native {
|
||||||
MaybeError ValidateFinish(CommandIterator* commands, const PassResourceUsage& usages) const;
|
MaybeError ValidateFinish(CommandIterator* commands, const PassResourceUsage& usages) const;
|
||||||
|
|
||||||
EncodingContext mBundleEncodingContext;
|
EncodingContext mBundleEncodingContext;
|
||||||
Ref<AttachmentState> mAttachmentState;
|
|
||||||
};
|
};
|
||||||
} // namespace dawn_native
|
} // namespace dawn_native
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,11 @@
|
||||||
|
|
||||||
namespace dawn_native {
|
namespace dawn_native {
|
||||||
|
|
||||||
RenderEncoderBase::RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext)
|
RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
|
||||||
|
EncodingContext* encodingContext,
|
||||||
|
Ref<AttachmentState> attachmentState)
|
||||||
: ProgrammablePassEncoder(device, encodingContext, PassType::Render),
|
: ProgrammablePassEncoder(device, encodingContext, PassType::Render),
|
||||||
|
mAttachmentState(std::move(attachmentState)),
|
||||||
mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
|
mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
|
||||||
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
|
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
|
||||||
}
|
}
|
||||||
|
@ -42,6 +45,16 @@ namespace dawn_native {
|
||||||
mDisableBaseInstance(device->IsToggleEnabled(Toggle::DisableBaseInstance)) {
|
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,
|
void RenderEncoderBase::Draw(uint32_t vertexCount,
|
||||||
uint32_t instanceCount,
|
uint32_t instanceCount,
|
||||||
uint32_t firstVertex,
|
uint32_t firstVertex,
|
||||||
|
@ -157,6 +170,12 @@ namespace dawn_native {
|
||||||
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
mEncodingContext->TryEncode(this, [&](CommandAllocator* allocator) -> MaybeError {
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(pipeline));
|
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 =
|
SetRenderPipelineCmd* cmd =
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#ifndef DAWNNATIVE_RENDERENCODERBASE_H_
|
#ifndef DAWNNATIVE_RENDERENCODERBASE_H_
|
||||||
#define DAWNNATIVE_RENDERENCODERBASE_H_
|
#define DAWNNATIVE_RENDERENCODERBASE_H_
|
||||||
|
|
||||||
|
#include "dawn_native/AttachmentState.h"
|
||||||
#include "dawn_native/Error.h"
|
#include "dawn_native/Error.h"
|
||||||
#include "dawn_native/ProgrammablePassEncoder.h"
|
#include "dawn_native/ProgrammablePassEncoder.h"
|
||||||
|
|
||||||
|
@ -22,7 +23,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
class RenderEncoderBase : public ProgrammablePassEncoder {
|
class RenderEncoderBase : public ProgrammablePassEncoder {
|
||||||
public:
|
public:
|
||||||
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext);
|
RenderEncoderBase(DeviceBase* device,
|
||||||
|
EncodingContext* encodingContext,
|
||||||
|
Ref<AttachmentState> attachmentState);
|
||||||
|
|
||||||
void Draw(uint32_t vertexCount,
|
void Draw(uint32_t vertexCount,
|
||||||
uint32_t instanceCount = 1,
|
uint32_t instanceCount = 1,
|
||||||
|
@ -47,11 +50,15 @@ namespace dawn_native {
|
||||||
void SetIndexBufferWithFormat(BufferBase* buffer, wgpu::IndexFormat format, uint64_t offset,
|
void SetIndexBufferWithFormat(BufferBase* buffer, wgpu::IndexFormat format, uint64_t offset,
|
||||||
uint64_t size);
|
uint64_t size);
|
||||||
|
|
||||||
|
const AttachmentState* GetAttachmentState() const;
|
||||||
|
Ref<AttachmentState> AcquireAttachmentState();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Construct an "error" render encoder base.
|
// Construct an "error" render encoder base.
|
||||||
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext, ErrorTag errorTag);
|
RenderEncoderBase(DeviceBase* device, EncodingContext* encodingContext, ErrorTag errorTag);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Ref<AttachmentState> mAttachmentState;
|
||||||
const bool mDisableBaseVertex;
|
const bool mDisableBaseVertex;
|
||||||
const bool mDisableBaseInstance;
|
const bool mDisableBaseInstance;
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,10 +52,11 @@ namespace dawn_native {
|
||||||
CommandEncoder* commandEncoder,
|
CommandEncoder* commandEncoder,
|
||||||
EncodingContext* encodingContext,
|
EncodingContext* encodingContext,
|
||||||
PassResourceUsageTracker usageTracker,
|
PassResourceUsageTracker usageTracker,
|
||||||
|
Ref<AttachmentState> attachmentState,
|
||||||
QuerySetBase* occlusionQuerySet,
|
QuerySetBase* occlusionQuerySet,
|
||||||
uint32_t renderTargetWidth,
|
uint32_t renderTargetWidth,
|
||||||
uint32_t renderTargetHeight)
|
uint32_t renderTargetHeight)
|
||||||
: RenderEncoderBase(device, encodingContext),
|
: RenderEncoderBase(device, encodingContext, std::move(attachmentState)),
|
||||||
mCommandEncoder(commandEncoder),
|
mCommandEncoder(commandEncoder),
|
||||||
mRenderTargetWidth(renderTargetWidth),
|
mRenderTargetWidth(renderTargetWidth),
|
||||||
mRenderTargetHeight(renderTargetHeight),
|
mRenderTargetHeight(renderTargetHeight),
|
||||||
|
@ -198,6 +199,12 @@ namespace dawn_native {
|
||||||
if (IsValidationEnabled()) {
|
if (IsValidationEnabled()) {
|
||||||
for (uint32_t i = 0; i < count; ++i) {
|
for (uint32_t i = 0; i < count; ++i) {
|
||||||
DAWN_TRY(GetDevice()->ValidateObject(renderBundles[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,
|
CommandEncoder* commandEncoder,
|
||||||
EncodingContext* encodingContext,
|
EncodingContext* encodingContext,
|
||||||
PassResourceUsageTracker usageTracker,
|
PassResourceUsageTracker usageTracker,
|
||||||
|
Ref<AttachmentState> attachmentState,
|
||||||
QuerySetBase* occlusionQuerySet,
|
QuerySetBase* occlusionQuerySet,
|
||||||
uint32_t renderTargetWidth,
|
uint32_t renderTargetWidth,
|
||||||
uint32_t renderTargetHeight);
|
uint32_t renderTargetHeight);
|
||||||
|
|
Loading…
Reference in New Issue