diff --git a/BUILD.gn b/BUILD.gn index 4375a36468..074e244009 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -124,6 +124,8 @@ source_set("libdawn_native_sources") { "src/dawn_native/CommandBufferStateTracker.h", "src/dawn_native/CommandEncoder.cpp", "src/dawn_native/CommandEncoder.h", + "src/dawn_native/CommandValidation.cpp", + "src/dawn_native/CommandValidation.h", "src/dawn_native/Commands.cpp", "src/dawn_native/Commands.h", "src/dawn_native/ComputePassEncoder.cpp", diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index 0fff02f92e..13bea8446f 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp @@ -19,6 +19,7 @@ #include "dawn_native/Buffer.h" #include "dawn_native/CommandBuffer.h" #include "dawn_native/CommandBufferStateTracker.h" +#include "dawn_native/CommandValidation.h" #include "dawn_native/Commands.h" #include "dawn_native/ComputePassEncoder.h" #include "dawn_native/Device.h" @@ -121,29 +122,6 @@ namespace dawn_native { return {}; } - inline MaybeError PushDebugMarkerStack(unsigned int* counter) { - *counter += 1; - return {}; - } - - inline MaybeError PopDebugMarkerStack(unsigned int* counter) { - if (*counter == 0) { - return DAWN_VALIDATION_ERROR("Pop must be balanced by a corresponding Push."); - } else { - *counter -= 1; - } - - return {}; - } - - inline MaybeError ValidateDebugGroups(const unsigned int counter) { - if (counter != 0) { - return DAWN_VALIDATION_ERROR("Each Push must be balanced by a corresponding Pop."); - } - - return {}; - } - MaybeError ValidateTextureSampleCountInCopyCommands(const TextureBase* texture) { if (texture->GetSampleCount() > 1) { return DAWN_VALIDATION_ERROR("The sample count of textures must be 1"); @@ -476,39 +454,6 @@ namespace dawn_native { return {}; } - void TrackBindGroupResourceUsage(BindGroupBase* group, PassResourceUsageTracker* tracker) { - const auto& layoutInfo = group->GetLayout()->GetBindingInfo(); - - for (uint32_t i : IterateBitSet(layoutInfo.mask)) { - dawn::BindingType type = layoutInfo.types[i]; - - switch (type) { - case dawn::BindingType::UniformBuffer: { - BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer; - tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Uniform); - } break; - - case dawn::BindingType::StorageBuffer: { - BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer; - tracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Storage); - } break; - - case dawn::BindingType::SampledTexture: { - TextureBase* texture = group->GetBindingAsTextureView(i)->GetTexture(); - tracker->TextureUsedAs(texture, dawn::TextureUsageBit::Sampled); - } break; - - case dawn::BindingType::Sampler: - break; - - case dawn::BindingType::StorageTexture: - case dawn::BindingType::ReadonlyStorageBuffer: - UNREACHABLE(); - break; - } - } - } - } // namespace CommandEncoderBase::CommandEncoderBase(DeviceBase* device, const CommandEncoderDescriptor*) @@ -749,12 +694,12 @@ namespace dawn_native { switch (type) { case Command::BeginComputePass: { commands->NextCommand(); - DAWN_TRY(ValidateComputePass(commands)); + DAWN_TRY(ValidateComputePass(commands, &mResourceUsages.perPass)); } break; case Command::BeginRenderPass: { BeginRenderPassCmd* cmd = commands->NextCommand(); - DAWN_TRY(ValidateRenderPass(commands, cmd)); + DAWN_TRY(ValidateRenderPass(commands, cmd, &mResourceUsages.perPass)); } break; case Command::CopyBufferToBuffer: { @@ -881,211 +826,4 @@ namespace dawn_native { return {}; } - MaybeError CommandEncoderBase::ValidateComputePass(CommandIterator* commands) { - PassResourceUsageTracker usageTracker; - CommandBufferStateTracker persistentState; - - Command type; - while (commands->NextCommandId(&type)) { - switch (type) { - case Command::EndComputePass: { - commands->NextCommand(); - - DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize)); - - DAWN_TRY(usageTracker.ValidateComputePassUsages()); - mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage()); - return {}; - } break; - - case Command::Dispatch: { - commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDispatch()); - } break; - - case Command::DispatchIndirect: { - DispatchIndirectCmd* cmd = commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDispatch()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - - case Command::InsertDebugMarker: { - InsertDebugMarkerCmd* cmd = commands->NextCommand(); - commands->NextData(cmd->length + 1); - } break; - - case Command::PopDebugGroup: { - commands->NextCommand(); - DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize)); - } break; - - case Command::PushDebugGroup: { - PushDebugGroupCmd* cmd = commands->NextCommand(); - commands->NextData(cmd->length + 1); - DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize)); - } break; - - case Command::SetComputePipeline: { - SetComputePipelineCmd* cmd = commands->NextCommand(); - ComputePipelineBase* pipeline = cmd->pipeline.Get(); - persistentState.SetComputePipeline(pipeline); - } break; - - case Command::SetBindGroup: { - SetBindGroupCmd* cmd = commands->NextCommand(); - if (cmd->dynamicOffsetCount > 0) { - commands->NextData(cmd->dynamicOffsetCount); - } - - TrackBindGroupResourceUsage(cmd->group.Get(), &usageTracker); - persistentState.SetBindGroup(cmd->index, cmd->group.Get()); - } break; - - default: - return DAWN_VALIDATION_ERROR("Command disallowed inside a compute pass"); - } - } - - UNREACHABLE(); - return DAWN_VALIDATION_ERROR("Unfinished compute pass"); - } - - MaybeError CommandEncoderBase::ValidateRenderPass(CommandIterator* commands, - BeginRenderPassCmd* renderPass) { - PassResourceUsageTracker usageTracker; - CommandBufferStateTracker persistentState; - - // Track usage of the render pass attachments - for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { - RenderPassColorAttachmentInfo* colorAttachment = &renderPass->colorAttachments[i]; - TextureBase* texture = colorAttachment->view->GetTexture(); - usageTracker.TextureUsedAs(texture, dawn::TextureUsageBit::OutputAttachment); - - TextureViewBase* resolveTarget = colorAttachment->resolveTarget.Get(); - if (resolveTarget != nullptr) { - usageTracker.TextureUsedAs(resolveTarget->GetTexture(), - dawn::TextureUsageBit::OutputAttachment); - } - } - - if (renderPass->attachmentState->HasDepthStencilAttachment()) { - TextureBase* texture = renderPass->depthStencilAttachment.view->GetTexture(); - usageTracker.TextureUsedAs(texture, dawn::TextureUsageBit::OutputAttachment); - } - - Command type; - while (commands->NextCommandId(&type)) { - switch (type) { - case Command::EndRenderPass: { - commands->NextCommand(); - - DAWN_TRY(ValidateDebugGroups(mDebugGroupStackSize)); - - DAWN_TRY(usageTracker.ValidateRenderPassUsages()); - mResourceUsages.perPass.push_back(usageTracker.AcquireResourceUsage()); - return {}; - } break; - - case Command::Draw: { - commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDraw()); - } break; - - case Command::DrawIndexed: { - commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDrawIndexed()); - } break; - - case Command::DrawIndirect: { - DrawIndirectCmd* cmd = commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDraw()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - - case Command::DrawIndexedIndirect: { - DrawIndexedIndirectCmd* cmd = commands->NextCommand(); - DAWN_TRY(persistentState.ValidateCanDrawIndexed()); - usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), - dawn::BufferUsageBit::Indirect); - } break; - - case Command::InsertDebugMarker: { - InsertDebugMarkerCmd* cmd = commands->NextCommand(); - commands->NextData(cmd->length + 1); - } break; - - case Command::PopDebugGroup: { - commands->NextCommand(); - DAWN_TRY(PopDebugMarkerStack(&mDebugGroupStackSize)); - } break; - - case Command::PushDebugGroup: { - PushDebugGroupCmd* cmd = commands->NextCommand(); - commands->NextData(cmd->length + 1); - DAWN_TRY(PushDebugMarkerStack(&mDebugGroupStackSize)); - } break; - - case Command::SetRenderPipeline: { - SetRenderPipelineCmd* cmd = commands->NextCommand(); - RenderPipelineBase* pipeline = cmd->pipeline.Get(); - - DAWN_TRY(pipeline->ValidateCompatibleWith(renderPass)); - persistentState.SetRenderPipeline(pipeline); - } break; - - case Command::SetStencilReference: { - commands->NextCommand(); - } break; - - case Command::SetBlendColor: { - commands->NextCommand(); - } break; - - case Command::SetViewport: { - commands->NextCommand(); - } break; - - case Command::SetScissorRect: { - commands->NextCommand(); - } break; - - case Command::SetBindGroup: { - SetBindGroupCmd* cmd = commands->NextCommand(); - if (cmd->dynamicOffsetCount > 0) { - commands->NextData(cmd->dynamicOffsetCount); - } - - TrackBindGroupResourceUsage(cmd->group.Get(), &usageTracker); - persistentState.SetBindGroup(cmd->index, cmd->group.Get()); - } break; - - case Command::SetIndexBuffer: { - SetIndexBufferCmd* cmd = commands->NextCommand(); - - usageTracker.BufferUsedAs(cmd->buffer.Get(), dawn::BufferUsageBit::Index); - persistentState.SetIndexBuffer(); - } break; - - case Command::SetVertexBuffers: { - SetVertexBuffersCmd* cmd = commands->NextCommand(); - auto buffers = commands->NextData>(cmd->count); - commands->NextData(cmd->count); - - for (uint32_t i = 0; i < cmd->count; ++i) { - usageTracker.BufferUsedAs(buffers[i].Get(), dawn::BufferUsageBit::Vertex); - } - persistentState.SetVertexBuffer(cmd->startSlot, cmd->count); - } break; - - default: - return DAWN_VALIDATION_ERROR("Command disallowed inside a render pass"); - } - } - - UNREACHABLE(); - return DAWN_VALIDATION_ERROR("Unfinished render pass"); - } - } // namespace dawn_native diff --git a/src/dawn_native/CommandEncoder.h b/src/dawn_native/CommandEncoder.h index 3a59e8e188..bcb1137014 100644 --- a/src/dawn_native/CommandEncoder.h +++ b/src/dawn_native/CommandEncoder.h @@ -56,15 +56,11 @@ namespace dawn_native { private: MaybeError ValidateFinish(const CommandBufferDescriptor* descriptor); - MaybeError ValidateComputePass(CommandIterator* commands); - MaybeError ValidateRenderPass(CommandIterator* commands, BeginRenderPassCmd* renderPass); EncodingContext mEncodingContext; bool mWereResourceUsagesAcquired = false; CommandBufferResourceUsage mResourceUsages; - - unsigned int mDebugGroupStackSize = 0; }; } // namespace dawn_native diff --git a/src/dawn_native/CommandValidation.cpp b/src/dawn_native/CommandValidation.cpp new file mode 100644 index 0000000000..9099a9e57c --- /dev/null +++ b/src/dawn_native/CommandValidation.cpp @@ -0,0 +1,321 @@ +// 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_native/CommandValidation.h" + +#include "common/BitSetIterator.h" +#include "dawn_native/BindGroup.h" +#include "dawn_native/CommandBufferStateTracker.h" +#include "dawn_native/Commands.h" +#include "dawn_native/PassResourceUsageTracker.h" +#include "dawn_native/RenderPipeline.h" + +namespace dawn_native { + + namespace { + + inline MaybeError PushDebugMarkerStack(unsigned int* counter) { + *counter += 1; + return {}; + } + + inline MaybeError PopDebugMarkerStack(unsigned int* counter) { + if (*counter == 0) { + return DAWN_VALIDATION_ERROR("Pop must be balanced by a corresponding Push."); + } else { + *counter -= 1; + } + + return {}; + } + + inline MaybeError ValidateDebugGroups(const unsigned int counter) { + if (counter != 0) { + return DAWN_VALIDATION_ERROR("Each Push must be balanced by a corresponding Pop."); + } + + return {}; + } + + void TrackBindGroupResourceUsage(BindGroupBase* group, + PassResourceUsageTracker* usageTracker) { + const auto& layoutInfo = group->GetLayout()->GetBindingInfo(); + + for (uint32_t i : IterateBitSet(layoutInfo.mask)) { + dawn::BindingType type = layoutInfo.types[i]; + + switch (type) { + case dawn::BindingType::UniformBuffer: { + BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer; + usageTracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Uniform); + } break; + + case dawn::BindingType::StorageBuffer: { + BufferBase* buffer = group->GetBindingAsBufferBinding(i).buffer; + usageTracker->BufferUsedAs(buffer, dawn::BufferUsageBit::Storage); + } break; + + case dawn::BindingType::SampledTexture: { + TextureBase* texture = group->GetBindingAsTextureView(i)->GetTexture(); + usageTracker->TextureUsedAs(texture, dawn::TextureUsageBit::Sampled); + } break; + + case dawn::BindingType::Sampler: + break; + + case dawn::BindingType::StorageTexture: + case dawn::BindingType::ReadonlyStorageBuffer: + UNREACHABLE(); + break; + } + } + } + + inline MaybeError ValidateRenderBundleCommand(CommandIterator* commands, + Command type, + PassResourceUsageTracker* usageTracker, + CommandBufferStateTracker* commandBufferState, + const AttachmentState* attachmentState, + unsigned int* debugGroupStackSize, + const char* disallowedMessage) { + switch (type) { + case Command::Draw: { + commands->NextCommand(); + DAWN_TRY(commandBufferState->ValidateCanDraw()); + } break; + + case Command::DrawIndexed: { + commands->NextCommand(); + DAWN_TRY(commandBufferState->ValidateCanDrawIndexed()); + } break; + + case Command::DrawIndirect: { + DrawIndirectCmd* cmd = commands->NextCommand(); + DAWN_TRY(commandBufferState->ValidateCanDraw()); + usageTracker->BufferUsedAs(cmd->indirectBuffer.Get(), + dawn::BufferUsageBit::Indirect); + } break; + + case Command::DrawIndexedIndirect: { + DrawIndexedIndirectCmd* cmd = commands->NextCommand(); + DAWN_TRY(commandBufferState->ValidateCanDrawIndexed()); + usageTracker->BufferUsedAs(cmd->indirectBuffer.Get(), + dawn::BufferUsageBit::Indirect); + } break; + + case Command::InsertDebugMarker: { + InsertDebugMarkerCmd* cmd = commands->NextCommand(); + commands->NextData(cmd->length + 1); + } break; + + case Command::PopDebugGroup: { + commands->NextCommand(); + DAWN_TRY(PopDebugMarkerStack(debugGroupStackSize)); + } break; + + case Command::PushDebugGroup: { + PushDebugGroupCmd* cmd = commands->NextCommand(); + commands->NextData(cmd->length + 1); + DAWN_TRY(PushDebugMarkerStack(debugGroupStackSize)); + } break; + + case Command::SetRenderPipeline: { + SetRenderPipelineCmd* cmd = commands->NextCommand(); + 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; + + case Command::SetBindGroup: { + SetBindGroupCmd* cmd = commands->NextCommand(); + if (cmd->dynamicOffsetCount > 0) { + commands->NextData(cmd->dynamicOffsetCount); + } + + TrackBindGroupResourceUsage(cmd->group.Get(), usageTracker); + commandBufferState->SetBindGroup(cmd->index, cmd->group.Get()); + } break; + + case Command::SetIndexBuffer: { + SetIndexBufferCmd* cmd = commands->NextCommand(); + + usageTracker->BufferUsedAs(cmd->buffer.Get(), dawn::BufferUsageBit::Index); + commandBufferState->SetIndexBuffer(); + } break; + + case Command::SetVertexBuffers: { + SetVertexBuffersCmd* cmd = commands->NextCommand(); + auto buffers = commands->NextData>(cmd->count); + commands->NextData(cmd->count); + + for (uint32_t i = 0; i < cmd->count; ++i) { + usageTracker->BufferUsedAs(buffers[i].Get(), dawn::BufferUsageBit::Vertex); + } + commandBufferState->SetVertexBuffer(cmd->startSlot, cmd->count); + } break; + + default: + return DAWN_VALIDATION_ERROR(disallowedMessage); + } + + return {}; + } + + } // namespace + + MaybeError ValidateRenderPass(CommandIterator* commands, + BeginRenderPassCmd* renderPass, + std::vector* perPassResourceUsages) { + PassResourceUsageTracker usageTracker; + CommandBufferStateTracker commandBufferState; + unsigned int debugGroupStackSize = 0; + + // Track usage of the render pass attachments + for (uint32_t i : IterateBitSet(renderPass->attachmentState->GetColorAttachmentsMask())) { + RenderPassColorAttachmentInfo* colorAttachment = &renderPass->colorAttachments[i]; + TextureBase* texture = colorAttachment->view->GetTexture(); + usageTracker.TextureUsedAs(texture, dawn::TextureUsageBit::OutputAttachment); + + TextureViewBase* resolveTarget = colorAttachment->resolveTarget.Get(); + if (resolveTarget != nullptr) { + usageTracker.TextureUsedAs(resolveTarget->GetTexture(), + dawn::TextureUsageBit::OutputAttachment); + } + } + + if (renderPass->attachmentState->HasDepthStencilAttachment()) { + TextureBase* texture = renderPass->depthStencilAttachment.view->GetTexture(); + usageTracker.TextureUsedAs(texture, dawn::TextureUsageBit::OutputAttachment); + } + + Command type; + while (commands->NextCommandId(&type)) { + switch (type) { + case Command::EndRenderPass: { + commands->NextCommand(); + + DAWN_TRY(ValidateDebugGroups(debugGroupStackSize)); + + DAWN_TRY(usageTracker.ValidateRenderPassUsages()); + ASSERT(perPassResourceUsages != nullptr); + perPassResourceUsages->push_back(usageTracker.AcquireResourceUsage()); + + return {}; + } break; + + case Command::SetStencilReference: { + commands->NextCommand(); + } break; + + case Command::SetBlendColor: { + commands->NextCommand(); + } break; + + case Command::SetViewport: { + commands->NextCommand(); + } break; + + case Command::SetScissorRect: { + commands->NextCommand(); + } break; + + default: + DAWN_TRY(ValidateRenderBundleCommand( + commands, type, &usageTracker, &commandBufferState, + renderPass->attachmentState.Get(), &debugGroupStackSize, + "Command disallowed inside a render pass")); + } + } + + UNREACHABLE(); + return DAWN_VALIDATION_ERROR("Unfinished render pass"); + } + + MaybeError ValidateComputePass(CommandIterator* commands, + std::vector* perPassResourceUsages) { + PassResourceUsageTracker usageTracker; + CommandBufferStateTracker commandBufferState; + unsigned int debugGroupStackSize = 0; + + Command type; + while (commands->NextCommandId(&type)) { + switch (type) { + case Command::EndComputePass: { + commands->NextCommand(); + + DAWN_TRY(ValidateDebugGroups(debugGroupStackSize)); + + DAWN_TRY(usageTracker.ValidateComputePassUsages()); + ASSERT(perPassResourceUsages != nullptr); + perPassResourceUsages->push_back(usageTracker.AcquireResourceUsage()); + return {}; + } break; + + case Command::Dispatch: { + commands->NextCommand(); + DAWN_TRY(commandBufferState.ValidateCanDispatch()); + } break; + + case Command::DispatchIndirect: { + DispatchIndirectCmd* cmd = commands->NextCommand(); + DAWN_TRY(commandBufferState.ValidateCanDispatch()); + usageTracker.BufferUsedAs(cmd->indirectBuffer.Get(), + dawn::BufferUsageBit::Indirect); + } break; + + case Command::InsertDebugMarker: { + InsertDebugMarkerCmd* cmd = commands->NextCommand(); + commands->NextData(cmd->length + 1); + } break; + + case Command::PopDebugGroup: { + commands->NextCommand(); + DAWN_TRY(PopDebugMarkerStack(&debugGroupStackSize)); + } break; + + case Command::PushDebugGroup: { + PushDebugGroupCmd* cmd = commands->NextCommand(); + commands->NextData(cmd->length + 1); + DAWN_TRY(PushDebugMarkerStack(&debugGroupStackSize)); + } break; + + case Command::SetComputePipeline: { + SetComputePipelineCmd* cmd = commands->NextCommand(); + ComputePipelineBase* pipeline = cmd->pipeline.Get(); + commandBufferState.SetComputePipeline(pipeline); + } break; + + case Command::SetBindGroup: { + SetBindGroupCmd* cmd = commands->NextCommand(); + if (cmd->dynamicOffsetCount > 0) { + commands->NextData(cmd->dynamicOffsetCount); + } + + TrackBindGroupResourceUsage(cmd->group.Get(), &usageTracker); + commandBufferState.SetBindGroup(cmd->index, cmd->group.Get()); + } break; + + default: + return DAWN_VALIDATION_ERROR("Command disallowed inside a compute pass"); + } + } + + UNREACHABLE(); + return DAWN_VALIDATION_ERROR("Unfinished compute pass"); + } + +} // namespace dawn_native diff --git a/src/dawn_native/CommandValidation.h b/src/dawn_native/CommandValidation.h new file mode 100644 index 0000000000..2d29cb3f95 --- /dev/null +++ b/src/dawn_native/CommandValidation.h @@ -0,0 +1,36 @@ +// 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. + +#ifndef DAWNNATIVE_COMMANDVALIDATION_H_ +#define DAWNNATIVE_COMMANDVALIDATION_H_ + +#include "dawn_native/CommandAllocator.h" +#include "dawn_native/Error.h" + +#include + +namespace dawn_native { + + struct BeginRenderPassCmd; + struct PassResourceUsage; + + MaybeError ValidateRenderPass(CommandIterator* commands, + BeginRenderPassCmd* renderPass, + std::vector* perPassResourceUsages); + MaybeError ValidateComputePass(CommandIterator* commands, + std::vector* perPassResourceUsages); + +} // namespace dawn_native + +#endif // DAWNNATIVE_COMMANDVALIDATION_H_ diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp index a9fd5d707d..6626c595fb 100644 --- a/src/dawn_native/RenderPipeline.cpp +++ b/src/dawn_native/RenderPipeline.cpp @@ -514,16 +514,10 @@ namespace dawn_native { return mAttachmentState->GetSampleCount(); } - MaybeError RenderPipelineBase::ValidateCompatibleWith( - const BeginRenderPassCmd* renderPass) const { + const AttachmentState* RenderPipelineBase::GetAttachmentState() const { ASSERT(!IsError()); - if (renderPass->attachmentState.Get() != mAttachmentState.Get()) { - return DAWN_VALIDATION_ERROR( - "Pipeline attachment state is not compatible with render pass"); - } - - return {}; + return mAttachmentState.Get(); } std::bitset RenderPipelineBase::GetAttributesUsingInput( diff --git a/src/dawn_native/RenderPipeline.h b/src/dawn_native/RenderPipeline.h index f8e884eb52..7a00e3adbb 100644 --- a/src/dawn_native/RenderPipeline.h +++ b/src/dawn_native/RenderPipeline.h @@ -78,9 +78,8 @@ namespace dawn_native { dawn::TextureFormat GetDepthStencilFormat() const; uint32_t GetSampleCount() const; - // A pipeline can be used in a render pass if its attachment info matches the actual - // attachments in the render pass. This returns whether it is the case. - MaybeError ValidateCompatibleWith(const BeginRenderPassCmd* renderPassCmd) const; + const AttachmentState* GetAttachmentState() const; + std::bitset GetAttributesUsingInput(uint32_t slot) const; std::array, kMaxVertexBuffers> attributesUsingInput;