diff --git a/src/backend/Builder.cpp b/src/backend/Builder.cpp index 35a94ffa37..83ebf2c82f 100644 --- a/src/backend/Builder.cpp +++ b/src/backend/Builder.cpp @@ -17,6 +17,8 @@ #include "backend/Device.h" #include "common/Assert.h" +#include + namespace backend { bool BuilderBase::CanBeUsed() const { @@ -76,6 +78,8 @@ namespace backend { result->Release(); result = nullptr; } + + if (!callback) std::cout << storedMessage << std::endl; } else { ASSERT(storedStatus == nxt::BuilderErrorStatus::Success); ASSERT(storedMessage.empty()); diff --git a/src/backend/CommandBufferStateTracker.cpp b/src/backend/CommandBufferStateTracker.cpp index cd438a4d64..e23deaa14d 100644 --- a/src/backend/CommandBufferStateTracker.cpp +++ b/src/backend/CommandBufferStateTracker.cpp @@ -520,23 +520,16 @@ namespace backend { return true; } - bool CommandBufferStateTracker::SetPipelineCommon(PipelineBase* pipeline) { PipelineLayoutBase* layout = pipeline->GetLayout(); aspects.reset(VALIDATION_ASPECT_BIND_GROUPS); + // Reset bindgroups but mark unused bindgroups as valid bindgroupsSet = ~layout->GetBindGroupsLayoutMask(); // Only bindgroups that were not the same layout in the last pipeline need to be set again. if (lastPipeline) { - PipelineLayoutBase* lastLayout = lastPipeline->GetLayout(); - for (uint32_t i = 0; i < kMaxBindGroups; ++i) { - if (lastLayout->GetBindGroupLayout(i) == layout->GetBindGroupLayout(i)) { - bindgroupsSet |= uint64_t(1) << i; - } else { - break; - } - } + bindgroupsSet |= layout->InheritedGroupsMask(lastPipeline->GetLayout()); } lastPipeline = pipeline; diff --git a/src/backend/PipelineLayout.cpp b/src/backend/PipelineLayout.cpp index 9d0ac5066c..45b66983e0 100644 --- a/src/backend/PipelineLayout.cpp +++ b/src/backend/PipelineLayout.cpp @@ -35,6 +35,19 @@ namespace backend { return mask; } + std::bitset PipelineLayoutBase::InheritedGroupsMask(const PipelineLayoutBase* other) const { + return { GroupsInheritUpTo(other) - 1 }; + } + + uint32_t PipelineLayoutBase::GroupsInheritUpTo(const PipelineLayoutBase* other) const { + for (uint32_t i = 0; i < kMaxBindGroups; ++i) { + if (!mask[i] || bindGroupLayouts[i].Get() != other->bindGroupLayouts[i].Get()) { + return i; + } + } + return kMaxBindGroups + 1; + } + // PipelineLayoutBuilder PipelineLayoutBuilder::PipelineLayoutBuilder(DeviceBase* device) : Builder(device) { diff --git a/src/backend/PipelineLayout.h b/src/backend/PipelineLayout.h index 6ad1d568f3..2e3f4cd288 100644 --- a/src/backend/PipelineLayout.h +++ b/src/backend/PipelineLayout.h @@ -36,6 +36,13 @@ namespace backend { const BindGroupLayoutBase* GetBindGroupLayout(size_t group) const; const std::bitset GetBindGroupsLayoutMask() const; + // Utility functions to compute inherited bind groups. + // Returns the inherited bind groups as a mask + std::bitset InheritedGroupsMask(const PipelineLayoutBase* other) const; + + // Returns the index of the first incompatible bind group (in the range [1, kMaxBindGroups + 1]) + uint32_t GroupsInheritUpTo(const PipelineLayoutBase* other) const; + protected: BindGroupLayoutArray bindGroupLayouts; std::bitset mask; diff --git a/src/backend/d3d12/CommandBufferD3D12.cpp b/src/backend/d3d12/CommandBufferD3D12.cpp index 849d0e316b..0d0ad0a7d4 100644 --- a/src/backend/d3d12/CommandBufferD3D12.cpp +++ b/src/backend/d3d12/CommandBufferD3D12.cpp @@ -81,18 +81,9 @@ namespace d3d12 { return; } - auto mask = newLayout->GetBindGroupsLayoutMask(); - for (uint32_t i = 0; i < kMaxBindGroups; ++i) { - // matching bind groups are inherited until they differ - if (mask[i] && oldLayout->GetBindGroupLayout(i) == newLayout->GetBindGroupLayout(i)) { - BindGroup* group = bindGroups[i]; - if (group != nullptr) { - TrackSetBindGroup(group, i); - } - } - else { - break; - } + uint32_t inheritUntil = oldLayout->GroupsInheritUpTo(newLayout); + for (uint32_t i = 0; i < inheritUntil; ++i) { + TrackSetBindGroup(bindGroups[i], i); } } @@ -130,18 +121,10 @@ namespace d3d12 { if (oldLayout == nullptr) { return; } - auto mask = newLayout->GetBindGroupsLayoutMask(); - for (uint32_t i = 0; i < kMaxBindGroups; ++i) { - // matching bind groups are inherited until they differ - if (mask[i] && oldLayout->GetBindGroupLayout(i) == oldLayout->GetBindGroupLayout(i)) { - BindGroup* group = bindGroups[i]; - if (group != nullptr) { - SetBindGroup(commandList, newLayout, group, i, true); - } - } - else { - break; - } + + uint32_t inheritUntil = oldLayout->GroupsInheritUpTo(newLayout); + for (uint32_t i = 0; i < inheritUntil; ++i) { + SetBindGroup(commandList, newLayout, bindGroups[i], i, true); } }