CommandBufferResourceUsage: track render and compute separately. This change is a preparation for making the compute pass track the synchronization scope usages per dispatch instead of for the whole pass. - Split the tracking of render and compute passes usages. - Rename PassTextureUsage to TextureSubresourceUsage since is it not per-pass - Add SyncScopeResourceUsage as a subclass of PassResourceUsage to start modifying some of the code to work with synchronization scopes (even if syncscope == pass at the moment). There are no functional changes. Bug: dawn:632 Change-Id: Ieeb6d70a44dc1c726f26989eebcd87e63e732785 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/49883 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/dawn_native/Buffer.cpp b/src/dawn_native/Buffer.cpp index e8bb23f..3ddb72b 100644 --- a/src/dawn_native/Buffer.cpp +++ b/src/dawn_native/Buffer.cpp
@@ -133,8 +133,7 @@ mUsage(descriptor->usage), mState(BufferState::Unmapped) { // Add readonly storage usage if the buffer has a storage usage. The validation rules in - // ValidatePassResourceUsage will make sure we don't use both at the same - // time. + // ValidateSyncScopeResourceUsage will make sure we don't use both at the same time. if (mUsage & wgpu::BufferUsage::Storage) { mUsage |= kReadOnlyStorageBuffer; }
diff --git a/src/dawn_native/CommandEncoder.cpp b/src/dawn_native/CommandEncoder.cpp index 97f7320..21060e4 100644 --- a/src/dawn_native/CommandEncoder.cpp +++ b/src/dawn_native/CommandEncoder.cpp
@@ -470,9 +470,9 @@ } CommandBufferResourceUsage CommandEncoder::AcquireResourceUsages() { - return CommandBufferResourceUsage{mEncodingContext.AcquirePassUsages(), - std::move(mTopLevelBuffers), std::move(mTopLevelTextures), - std::move(mUsedQuerySets)}; + return CommandBufferResourceUsage{ + mEncodingContext.AcquireRenderPassUsages(), mEncodingContext.AcquireComputePassUsages(), + std::move(mTopLevelBuffers), std::move(mTopLevelTextures), std::move(mUsedQuerySets)}; } CommandIterator CommandEncoder::AcquireCommands() { @@ -936,21 +936,21 @@ DAWN_TRY(device->ValidateIsAlive()); if (device->IsValidationEnabled()) { - DAWN_TRY( - ValidateFinish(mEncodingContext.GetIterator(), mEncodingContext.GetPassUsages())); + DAWN_TRY(ValidateFinish()); } return device->CreateCommandBuffer(this, descriptor); } // Implementation of the command buffer validation that can be precomputed before submit - MaybeError CommandEncoder::ValidateFinish(CommandIterator* commands, - const PerPassUsages& perPassUsages) const { + MaybeError CommandEncoder::ValidateFinish() const { TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "CommandEncoder::ValidateFinish"); DAWN_TRY(GetDevice()->ValidateObject(this)); - for (const PassResourceUsage& passUsage : perPassUsages) { - DAWN_TRY(ValidatePassResourceUsage(passUsage)); + for (const PassResourceUsage& passUsage : mEncodingContext.GetRenderPassUsages()) { + DAWN_TRY(ValidateSyncScopeResourceUsage(passUsage)); } + // TODO(dawn:632): The synchronization scopes of compute passes should be validated here + // once they are tracked per-dispatch. if (mDebugGroupStackSize != 0) { return DAWN_VALIDATION_ERROR("Each Push must be balanced by a corresponding Pop.");
diff --git a/src/dawn_native/CommandEncoder.h b/src/dawn_native/CommandEncoder.h index a8bf6a0..13678f1 100644 --- a/src/dawn_native/CommandEncoder.h +++ b/src/dawn_native/CommandEncoder.h
@@ -73,8 +73,7 @@ ResultOrError<Ref<CommandBufferBase>> FinishInternal( const CommandBufferDescriptor* descriptor); - MaybeError ValidateFinish(CommandIterator* commands, - const PerPassUsages& perPassUsages) const; + MaybeError ValidateFinish() const; EncodingContext mEncodingContext; std::set<BufferBase*> mTopLevelBuffers;
diff --git a/src/dawn_native/CommandValidation.cpp b/src/dawn_native/CommandValidation.cpp index 1e2fc38..05e3a9e 100644 --- a/src/dawn_native/CommandValidation.cpp +++ b/src/dawn_native/CommandValidation.cpp
@@ -28,20 +28,10 @@ namespace dawn_native { - // Performs the per-pass usage validation checks - // This will eventually need to differentiate between render and compute passes. - // It will be valid to use a buffer both as uniform and storage in the same compute pass. - // TODO(yunchao.he@intel.com): add read/write usage tracking for compute - MaybeError ValidatePassResourceUsage(const PassResourceUsage& pass) { - // TODO(cwallez@chromium.org): Remove this special casing once the PassResourceUsage is a - // SyncScopeResourceUsage. - if (pass.passType != PassType::Render) { - return {}; - } - + // Performs validation of the "synchronization scope" rules of WebGPU. + MaybeError ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& scope) { // Buffers can only be used as single-write or multiple read. - for (size_t i = 0; i < pass.buffers.size(); ++i) { - wgpu::BufferUsage usage = pass.bufferUsages[i]; + for (wgpu::BufferUsage usage : scope.bufferUsages) { bool readOnly = IsSubset(usage, kReadOnlyBufferUsages); bool singleUse = wgpu::HasZeroOrOneBits(usage); @@ -53,7 +43,7 @@ // Check that every single subresource is used as either a single-write usage or a // combination of readonly usages. - for (const PassTextureUsage& textureUsage : pass.textureUsages) { + for (const TextureSubresourceUsage& textureUsage : scope.textureUsages) { MaybeError error = {}; textureUsage.Iterate([&](const SubresourceRange&, const wgpu::TextureUsage& usage) { bool readOnly = IsSubset(usage, kReadOnlyTextureUsages);
diff --git a/src/dawn_native/CommandValidation.h b/src/dawn_native/CommandValidation.h index 9c8a42f..7b5fce2 100644 --- a/src/dawn_native/CommandValidation.h +++ b/src/dawn_native/CommandValidation.h
@@ -24,10 +24,10 @@ namespace dawn_native { class QuerySetBase; - struct PassResourceUsage; + struct SyncScopeResourceUsage; struct TexelBlockInfo; - MaybeError ValidatePassResourceUsage(const PassResourceUsage& usage); + MaybeError ValidateSyncScopeResourceUsage(const SyncScopeResourceUsage& usage); MaybeError ValidateTimestampQuery(QuerySetBase* querySet, uint32_t queryIndex);
diff --git a/src/dawn_native/ComputePassEncoder.cpp b/src/dawn_native/ComputePassEncoder.cpp index 04bb8ff..666235e 100644 --- a/src/dawn_native/ComputePassEncoder.cpp +++ b/src/dawn_native/ComputePassEncoder.cpp
@@ -55,7 +55,8 @@ return {}; })) { - mEncodingContext->ExitPass(this, mUsageTracker.AcquireResourceUsage()); + mEncodingContext->ExitPass(this, mUsageTracker.AcquireResourceUsage(), + PassType::Compute); } }
diff --git a/src/dawn_native/EncodingContext.cpp b/src/dawn_native/EncodingContext.cpp index 39b5d4c..acdecd7 100644 --- a/src/dawn_native/EncodingContext.cpp +++ b/src/dawn_native/EncodingContext.cpp
@@ -76,25 +76,43 @@ mCurrentEncoder = passEncoder; } - void EncodingContext::ExitPass(const ObjectBase* passEncoder, PassResourceUsage passUsage) { + void EncodingContext::ExitPass(const ObjectBase* passEncoder, + PassResourceUsage passUsage, + PassType type) { // Assert we're not at the top level. ASSERT(mCurrentEncoder != mTopLevelEncoder); // Assert the pass encoder is current. ASSERT(mCurrentEncoder == passEncoder); mCurrentEncoder = mTopLevelEncoder; - mPassUsages.push_back(std::move(passUsage)); + + if (type == PassType::Render) { + mRenderPassUsages.push_back(std::move(passUsage)); + } else { + mComputePassUsages.push_back(std::move(passUsage)); + } } - const PerPassUsages& EncodingContext::GetPassUsages() const { - ASSERT(!mWerePassUsagesAcquired); - return mPassUsages; + const RenderPassUsages& EncodingContext::GetRenderPassUsages() const { + ASSERT(!mWereRenderPassUsagesAcquired); + return mRenderPassUsages; } - PerPassUsages EncodingContext::AcquirePassUsages() { - ASSERT(!mWerePassUsagesAcquired); - mWerePassUsagesAcquired = true; - return std::move(mPassUsages); + RenderPassUsages EncodingContext::AcquireRenderPassUsages() { + ASSERT(!mWereRenderPassUsagesAcquired); + mWereRenderPassUsagesAcquired = true; + return std::move(mRenderPassUsages); + } + + const ComputePassUsages& EncodingContext::GetComputePassUsages() const { + ASSERT(!mWereComputePassUsagesAcquired); + return mComputePassUsages; + } + + ComputePassUsages EncodingContext::AcquireComputePassUsages() { + ASSERT(!mWereComputePassUsagesAcquired); + mWereComputePassUsagesAcquired = true; + return std::move(mComputePassUsages); } MaybeError EncodingContext::Finish() {
diff --git a/src/dawn_native/EncodingContext.h b/src/dawn_native/EncodingContext.h index e74819a..f181e57 100644 --- a/src/dawn_native/EncodingContext.h +++ b/src/dawn_native/EncodingContext.h
@@ -79,11 +79,13 @@ // Functions to set current encoder state void EnterPass(const ObjectBase* passEncoder); - void ExitPass(const ObjectBase* passEncoder, PassResourceUsage passUsages); + void ExitPass(const ObjectBase* passEncoder, PassResourceUsage passUsages, PassType type); MaybeError Finish(); - const PerPassUsages& GetPassUsages() const; - PerPassUsages AcquirePassUsages(); + const RenderPassUsages& GetRenderPassUsages() const; + const ComputePassUsages& GetComputePassUsages() const; + RenderPassUsages AcquireRenderPassUsages(); + ComputePassUsages AcquireComputePassUsages(); private: bool IsFinished() const; @@ -101,8 +103,10 @@ // CommandEncoder::Begin/EndPass. const ObjectBase* mCurrentEncoder; - PerPassUsages mPassUsages; - bool mWerePassUsagesAcquired = false; + RenderPassUsages mRenderPassUsages; + bool mWereRenderPassUsagesAcquired = false; + ComputePassUsages mComputePassUsages; + bool mWereComputePassUsagesAcquired = false; CommandAllocator mAllocator; CommandIterator mIterator;
diff --git a/src/dawn_native/PassResourceUsage.h b/src/dawn_native/PassResourceUsage.h index 772f8c2..0f64346 100644 --- a/src/dawn_native/PassResourceUsage.h +++ b/src/dawn_native/PassResourceUsage.h
@@ -30,27 +30,31 @@ enum class PassType { Render, Compute }; // The texture usage inside passes must be tracked per-subresource. - using PassTextureUsage = SubresourceStorage<wgpu::TextureUsage>; + using TextureSubresourceUsage = SubresourceStorage<wgpu::TextureUsage>; - // Which resources are used by pass and how they are used. The command buffer validation - // pre-computes this information so that backends with explicit barriers don't have to - // re-compute it. - struct PassResourceUsage { - PassType passType; + // Which resources are used by a synchronization scope and how they are used. The command + // buffer validation pre-computes this information so that backends with explicit barriers + // don't have to re-compute it. + struct SyncScopeResourceUsage { std::vector<BufferBase*> buffers; std::vector<wgpu::BufferUsage> bufferUsages; std::vector<TextureBase*> textures; - std::vector<PassTextureUsage> textureUsages; + std::vector<TextureSubresourceUsage> textureUsages; + }; + // Additional data tracked per-pass. + struct PassResourceUsage : public SyncScopeResourceUsage { std::vector<QuerySetBase*> querySets; std::vector<std::vector<bool>> queryAvailabilities; }; - using PerPassUsages = std::vector<PassResourceUsage>; + using RenderPassUsages = std::vector<PassResourceUsage>; + using ComputePassUsages = std::vector<PassResourceUsage>; struct CommandBufferResourceUsage { - PerPassUsages perPass; + RenderPassUsages renderPasses; + ComputePassUsages computePasses; std::set<BufferBase*> topLevelBuffers; std::set<TextureBase*> topLevelTextures; std::set<QuerySetBase*> usedQuerySets;
diff --git a/src/dawn_native/PassResourceUsageTracker.cpp b/src/dawn_native/PassResourceUsageTracker.cpp index 81d72ed..806d40b 100644 --- a/src/dawn_native/PassResourceUsageTracker.cpp +++ b/src/dawn_native/PassResourceUsageTracker.cpp
@@ -37,13 +37,13 @@ TextureBase* texture = view->GetTexture(); const SubresourceRange& range = view->GetSubresourceRange(); - // Get or create a new PassTextureUsage for that texture (initially filled with + // Get or create a new TextureSubresourceUsage for that texture (initially filled with // wgpu::TextureUsage::None) auto it = mTextureUsages.emplace( std::piecewise_construct, std::forward_as_tuple(texture), std::forward_as_tuple(texture->GetFormat().aspects, texture->GetArrayLayers(), texture->GetNumMipLevels(), wgpu::TextureUsage::None)); - PassTextureUsage& textureUsage = it.first->second; + TextureSubresourceUsage& textureUsage = it.first->second; textureUsage.Update(range, [usage](const SubresourceRange&, wgpu::TextureUsage* storedUsage) { @@ -52,14 +52,14 @@ } void PassResourceUsageTracker::AddTextureUsage(TextureBase* texture, - const PassTextureUsage& textureUsage) { - // Get or create a new PassTextureUsage for that texture (initially filled with + const TextureSubresourceUsage& textureUsage) { + // Get or create a new TextureSubresourceUsage for that texture (initially filled with // wgpu::TextureUsage::None) auto it = mTextureUsages.emplace( std::piecewise_construct, std::forward_as_tuple(texture), std::forward_as_tuple(texture->GetFormat().aspects, texture->GetArrayLayers(), texture->GetNumMipLevels(), wgpu::TextureUsage::None)); - PassTextureUsage* passTextureUsage = &it.first->second; + TextureSubresourceUsage* passTextureUsage = &it.first->second; passTextureUsage->Merge( textureUsage, [](const SubresourceRange&, wgpu::TextureUsage* storedUsage, @@ -86,7 +86,6 @@ // Returns the per-pass usage for use by backends for APIs with explicit barriers. PassResourceUsage PassResourceUsageTracker::AcquireResourceUsage() { PassResourceUsage result; - result.passType = mPassType; result.buffers.reserve(mBufferUsages.size()); result.bufferUsages.reserve(mBufferUsages.size()); result.textures.reserve(mTextureUsages.size());
diff --git a/src/dawn_native/PassResourceUsageTracker.h b/src/dawn_native/PassResourceUsageTracker.h index cd54f8c..d56d724 100644 --- a/src/dawn_native/PassResourceUsageTracker.h +++ b/src/dawn_native/PassResourceUsageTracker.h
@@ -38,7 +38,7 @@ PassResourceUsageTracker(PassType passType); void BufferUsedAs(BufferBase* buffer, wgpu::BufferUsage usage); void TextureViewUsedAs(TextureViewBase* texture, wgpu::TextureUsage usage); - void AddTextureUsage(TextureBase* texture, const PassTextureUsage& textureUsage); + void AddTextureUsage(TextureBase* texture, const TextureSubresourceUsage& textureUsage); void TrackQueryAvailability(QuerySetBase* querySet, uint32_t queryIndex); const QueryAvailabilityMap& GetQueryAvailabilityMap() const; @@ -48,7 +48,7 @@ private: PassType mPassType; std::map<BufferBase*, wgpu::BufferUsage> mBufferUsages; - std::map<TextureBase*, PassTextureUsage> mTextureUsages; + std::map<TextureBase*, TextureSubresourceUsage> mTextureUsages; // Dedicated to track the availability of the queries used on render pass. The same query // cannot be written twice in same render pass, so each render pass also need to have its // own query availability map for validation.
diff --git a/src/dawn_native/Queue.cpp b/src/dawn_native/Queue.cpp index c113c1e..c555d99 100644 --- a/src/dawn_native/Queue.cpp +++ b/src/dawn_native/Queue.cpp
@@ -37,6 +37,18 @@ namespace { + MaybeError ValidateSyncScopeUsedInSubmit(const SyncScopeResourceUsage& scope) { + for (const BufferBase* buffer : scope.buffers) { + DAWN_TRY(buffer->ValidateCanUseOnQueueNow()); + } + + for (const TextureBase* texture : scope.textures) { + DAWN_TRY(texture->ValidateCanUseInSubmitNow()); + } + + return {}; + } + void CopyTextureData(uint8_t* dstPointer, const uint8_t* srcPointer, uint32_t depth, @@ -410,13 +422,11 @@ const CommandBufferResourceUsage& usages = commands[i]->GetResourceUsages(); - for (const PassResourceUsage& passUsages : usages.perPass) { - for (const BufferBase* buffer : passUsages.buffers) { - DAWN_TRY(buffer->ValidateCanUseOnQueueNow()); - } - for (const TextureBase* texture : passUsages.textures) { - DAWN_TRY(texture->ValidateCanUseInSubmitNow()); - } + for (const SyncScopeResourceUsage& scope : usages.renderPasses) { + DAWN_TRY(ValidateSyncScopeUsedInSubmit(scope)); + } + for (const SyncScopeResourceUsage& scope : usages.computePasses) { + DAWN_TRY(ValidateSyncScopeUsedInSubmit(scope)); } for (const BufferBase* buffer : usages.topLevelBuffers) {
diff --git a/src/dawn_native/RenderBundleEncoder.cpp b/src/dawn_native/RenderBundleEncoder.cpp index 45647a4..8afcd32 100644 --- a/src/dawn_native/RenderBundleEncoder.cpp +++ b/src/dawn_native/RenderBundleEncoder.cpp
@@ -137,7 +137,7 @@ const PassResourceUsage& usages) const { TRACE_EVENT0(GetDevice()->GetPlatform(), Validation, "RenderBundleEncoder::ValidateFinish"); DAWN_TRY(GetDevice()->ValidateObject(this)); - DAWN_TRY(ValidatePassResourceUsage(usages)); + DAWN_TRY(ValidateSyncScopeResourceUsage(usages)); return {}; }
diff --git a/src/dawn_native/RenderPassEncoder.cpp b/src/dawn_native/RenderPassEncoder.cpp index 1ab9023..c5c52e4 100644 --- a/src/dawn_native/RenderPassEncoder.cpp +++ b/src/dawn_native/RenderPassEncoder.cpp
@@ -101,7 +101,8 @@ allocator->Allocate<EndRenderPassCmd>(Command::EndRenderPass); return {}; })) { - mEncodingContext->ExitPass(this, mUsageTracker.AcquireResourceUsage()); + mEncodingContext->ExitPass(this, mUsageTracker.AcquireResourceUsage(), + PassType::Render); } }
diff --git a/src/dawn_native/Texture.cpp b/src/dawn_native/Texture.cpp index 2e6eafb..f0ea858 100644 --- a/src/dawn_native/Texture.cpp +++ b/src/dawn_native/Texture.cpp
@@ -441,7 +441,7 @@ mIsSubresourceContentInitializedAtIndex = std::vector<bool>(subresourceCount, false); // Add readonly storage usage if the texture has a storage usage. The validation rules in - // ValidatePassResourceUsage will make sure we don't use both at the same time. + // ValidateSyncScopeResourceUsage will make sure we don't use both at the same time. if (mUsage & wgpu::TextureUsage::Storage) { mUsage |= kReadOnlyStorageTexture; }
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 9e575a6..9d7f96d 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -682,8 +682,8 @@ } }; - const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass; - uint32_t nextPassNumber = 0; + size_t nextComputePassNumber = 0; + size_t nextRenderPassNumber = 0; Command type; while (mCommands.NextCommandId(&type)) { @@ -691,12 +691,12 @@ case Command::BeginComputePass: { mCommands.NextCommand<BeginComputePassCmd>(); - PrepareResourcesForComputePass(commandContext, - passResourceUsages[nextPassNumber]); + PrepareResourcesForComputePass( + commandContext, GetResourceUsages().computePasses[nextComputePassNumber]); bindingTracker.SetInComputePass(true); DAWN_TRY(RecordComputePass(commandContext, &bindingTracker)); - nextPassNumber++; + nextComputePassNumber++; break; } @@ -705,14 +705,14 @@ mCommands.NextCommand<BeginRenderPassCmd>(); const bool passHasUAV = PrepareResourcesForRenderPass( - commandContext, passResourceUsages[nextPassNumber]); + commandContext, GetResourceUsages().renderPasses[nextRenderPassNumber]); bindingTracker.SetInComputePass(false); LazyClearRenderPassAttachments(beginRenderPassCmd); DAWN_TRY(RecordRenderPass(commandContext, &bindingTracker, beginRenderPassCmd, passHasUAV)); - nextPassNumber++; + nextRenderPassNumber++; break; }
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp index 6274801..11d9048 100644 --- a/src/dawn_native/d3d12/TextureD3D12.cpp +++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -776,7 +776,7 @@ void Texture::TrackUsageAndGetResourceBarrierForPass( CommandRecordingContext* commandContext, std::vector<D3D12_RESOURCE_BARRIER>* barriers, - const PassTextureUsage& textureUsages) { + const TextureSubresourceUsage& textureUsages) { if (mResourceAllocation.GetInfo().mMethod != AllocationMethod::kExternal) { // Track the underlying heap to ensure residency. Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h index 528dd21..c7a652d 100644 --- a/src/dawn_native/d3d12/TextureD3D12.h +++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -64,7 +64,7 @@ void TrackUsageAndGetResourceBarrierForPass(CommandRecordingContext* commandContext, std::vector<D3D12_RESOURCE_BARRIER>* barrier, - const PassTextureUsage& textureUsages); + const TextureSubresourceUsage& textureUsages); void TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext, std::vector<D3D12_RESOURCE_BARRIER>* barrier, wgpu::TextureUsage usage,
diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm index f93737d..0793f97 100644 --- a/src/dawn_native/metal/CommandBufferMTL.mm +++ b/src/dawn_native/metal/CommandBufferMTL.mm
@@ -551,25 +551,25 @@ } MaybeError CommandBuffer::FillCommands(CommandRecordingContext* commandContext) { - const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass; - size_t nextPassNumber = 0; + size_t nextComputePassNumber = 0; + size_t nextRenderPassNumber = 0; - auto LazyClearForPass = [](const PassResourceUsage& usages, + auto LazyClearForPass = [](const SyncScopeResourceUsage& scope, CommandRecordingContext* commandContext) { - for (size_t i = 0; i < usages.textures.size(); ++i) { - Texture* texture = ToBackend(usages.textures[i]); + for (size_t i = 0; i < scope.textures.size(); ++i) { + Texture* texture = ToBackend(scope.textures[i]); // Clear subresources that are not render attachments. Render attachments will be // cleared in RecordBeginRenderPass by setting the loadop to clear when the texture // subresource has not been initialized before the render pass. - usages.textureUsages[i].Iterate( + scope.textureUsages[i].Iterate( [&](const SubresourceRange& range, wgpu::TextureUsage usage) { if (usage & ~wgpu::TextureUsage::RenderAttachment) { texture->EnsureSubresourceContentInitialized(range); } }); } - for (BufferBase* bufferBase : usages.buffers) { + for (BufferBase* bufferBase : scope.buffers) { ToBackend(bufferBase)->EnsureDataInitialized(commandContext); } }; @@ -580,19 +580,21 @@ case Command::BeginComputePass: { mCommands.NextCommand<BeginComputePassCmd>(); - LazyClearForPass(passResourceUsages[nextPassNumber], commandContext); + LazyClearForPass(GetResourceUsages().computePasses[nextComputePassNumber], + commandContext); commandContext->EndBlit(); DAWN_TRY(EncodeComputePass(commandContext)); - nextPassNumber++; + nextComputePassNumber++; break; } case Command::BeginRenderPass: { BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); - LazyClearForPass(passResourceUsages[nextPassNumber], commandContext); + LazyClearForPass(GetResourceUsages().renderPasses[nextRenderPassNumber], + commandContext); commandContext->EndBlit(); LazyClearRenderPassAttachments(cmd); @@ -600,7 +602,7 @@ DAWN_TRY(EncodeRenderPass(commandContext, descriptor.Get(), cmd->width, cmd->height)); - nextPassNumber++; + nextRenderPassNumber++; break; }
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index afb15a2..54687a0 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -536,14 +536,14 @@ MaybeError CommandBuffer::Execute() { const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; - auto TransitionForPass = [](const PassResourceUsage& usages) { - for (size_t i = 0; i < usages.textures.size(); i++) { - Texture* texture = ToBackend(usages.textures[i]); + auto LazyClearForPass = [](const SyncScopeResourceUsage& scope) { + for (size_t i = 0; i < scope.textures.size(); i++) { + Texture* texture = ToBackend(scope.textures[i]); // Clear subresources that are not render attachments. Render attachments will be // cleared in RecordBeginRenderPass by setting the loadop to clear when the texture // subresource has not been initialized before the render pass. - usages.textureUsages[i].Iterate( + scope.textureUsages[i].Iterate( [&](const SubresourceRange& range, wgpu::TextureUsage usage) { if (usage & ~wgpu::TextureUsage::RenderAttachment) { texture->EnsureSubresourceContentInitialized(range); @@ -551,34 +551,33 @@ }); } - for (BufferBase* bufferBase : usages.buffers) { + for (BufferBase* bufferBase : scope.buffers) { ToBackend(bufferBase)->EnsureDataInitialized(); } }; - const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass; - uint32_t nextPassNumber = 0; + size_t nextComputePassNumber = 0; + size_t nextRenderPassNumber = 0; Command type; while (mCommands.NextCommandId(&type)) { switch (type) { case Command::BeginComputePass: { mCommands.NextCommand<BeginComputePassCmd>(); - TransitionForPass(passResourceUsages[nextPassNumber]); + LazyClearForPass(GetResourceUsages().computePasses[nextComputePassNumber]); DAWN_TRY(ExecuteComputePass()); - nextPassNumber++; + nextComputePassNumber++; break; } case Command::BeginRenderPass: { auto* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); - TransitionForPass(passResourceUsages[nextPassNumber]); - + LazyClearForPass(GetResourceUsages().renderPasses[nextRenderPassNumber]); LazyClearRenderPassAttachments(cmd); DAWN_TRY(ExecuteRenderPass(cmd)); - nextPassNumber++; + nextRenderPassNumber++; break; }
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp index d154026..c014c85 100644 --- a/src/dawn_native/vulkan/CommandBufferVk.cpp +++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -596,8 +596,8 @@ } }; - const std::vector<PassResourceUsage>& passResourceUsages = GetResourceUsages().perPass; - size_t nextPassNumber = 0; + size_t nextComputePassNumber = 0; + size_t nextRenderPassNumber = 0; Command type; while (mCommands.NextCommandId(&type)) { @@ -774,24 +774,26 @@ case Command::BeginRenderPass: { BeginRenderPassCmd* cmd = mCommands.NextCommand<BeginRenderPassCmd>(); - PrepareResourcesForRenderPass(device, recordingContext, - passResourceUsages[nextPassNumber]); + PrepareResourcesForRenderPass( + device, recordingContext, + GetResourceUsages().renderPasses[nextRenderPassNumber]); LazyClearRenderPassAttachments(cmd); DAWN_TRY(RecordRenderPass(recordingContext, cmd)); - nextPassNumber++; + nextRenderPassNumber++; break; } case Command::BeginComputePass: { mCommands.NextCommand<BeginComputePassCmd>(); - PrepareResourcesForComputePass(device, recordingContext, - passResourceUsages[nextPassNumber]); + PrepareResourcesForComputePass( + device, recordingContext, + GetResourceUsages().computePasses[nextComputePassNumber]); DAWN_TRY(RecordComputePass(recordingContext)); - nextPassNumber++; + nextComputePassNumber++; break; }
diff --git a/src/dawn_native/vulkan/TextureVk.cpp b/src/dawn_native/vulkan/TextureVk.cpp index 59e753f..90f85f3 100644 --- a/src/dawn_native/vulkan/TextureVk.cpp +++ b/src/dawn_native/vulkan/TextureVk.cpp
@@ -863,7 +863,7 @@ } void Texture::TransitionUsageForPass(CommandRecordingContext* recordingContext, - const PassTextureUsage& textureUsages, + const TextureSubresourceUsage& textureUsages, std::vector<VkImageMemoryBarrier>* imageBarriers, VkPipelineStageFlags* srcStages, VkPipelineStageFlags* dstStages) {
diff --git a/src/dawn_native/vulkan/TextureVk.h b/src/dawn_native/vulkan/TextureVk.h index 013a3b6..908e468 100644 --- a/src/dawn_native/vulkan/TextureVk.h +++ b/src/dawn_native/vulkan/TextureVk.h
@@ -78,7 +78,7 @@ VkPipelineStageFlags* srcStages, VkPipelineStageFlags* dstStages); void TransitionUsageForPass(CommandRecordingContext* recordingContext, - const PassTextureUsage& textureUsages, + const TextureSubresourceUsage& textureUsages, std::vector<VkImageMemoryBarrier>* imageBarriers, VkPipelineStageFlags* srcStages, VkPipelineStageFlags* dstStages);