@@ -938,7 +938,8 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
938938 BindGroup::ShaderStageArray<BindGroupLayout::ArgumentIndices> argumentIndices;
939939 for (ShaderStage stage : stages) {
940940 auto encodedLength = bindGroupLayout->encodedLength (stage);
941- argumentBuffer[stage] = encodedLength ? safeCreateBuffer (encodedLength, MTLStorageModeShared ) : nil ;
941+ if (encodedLength)
942+ argumentBuffer[stage] = safeCreateBuffer (encodedLength, MTLStorageModeShared );
942943 [argumentEncoder[stage] setArgumentBuffer: argumentBuffer[stage] offset: 0 ];
943944 argumentIndices[stage] = bindGroupLayout->argumentIndices (stage);
944945 }
@@ -998,7 +999,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
998999 bool isDestroyed = apiBuffer->isDestroyed ();
9991000 if (isDestroyed && stage != ShaderStage::Undefined) {
10001001 argumentEncoder[stage] = nil ;
1001- argumentBuffer[stage] = nil ;
1002+ argumentBuffer[stage] = { } ;
10021003 }
10031004
10041005 auto entryOffset = isDestroyed ? 0 : entry.offset ;
@@ -1142,7 +1143,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
11421143 }
11431144 } else if (stage != ShaderStage::Undefined) {
11441145 argumentEncoder[stage] = nil ;
1145- argumentBuffer[stage] = nil ;
1146+ argumentBuffer[stage] = { } ;
11461147 }
11471148
11481149 if (stage != ShaderStage::Undefined) {
@@ -1235,7 +1236,13 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
12351236 std::sort (dynamicBuffers.begin (), dynamicBuffers.end (), [](const BindGroup::BufferAndType& a, const BindGroup::BufferAndType& b) {
12361237 return a.bindingIndex < b.bindingIndex ;
12371238 });
1238- return BindGroup::create (argumentBuffer[ShaderStage::Vertex], argumentBuffer[ShaderStage::Fragment], argumentBuffer[ShaderStage::Compute], WTFMove (resources), bindGroupLayout, WTFMove (dynamicBuffers), WTFMove (samplersSet), WTFMove (externalTextureIndices), *this );
1239+
1240+ if (m_bindGroupId == std::numeric_limits<decltype (m_bindGroupId)>::max ()) {
1241+ loseTheDevice (WGPUDeviceLostReason_Undefined);
1242+ return BindGroup::createInvalid (*this );
1243+ }
1244+
1245+ return BindGroup::create (argumentBuffer[ShaderStage::Vertex], argumentBuffer[ShaderStage::Fragment], argumentBuffer[ShaderStage::Compute], WTFMove (resources), bindGroupLayout, WTFMove (dynamicBuffers), WTFMove (samplersSet), WTFMove (externalTextureIndices), ++m_bindGroupId, *this );
12391246#undef VALIDATION_ERROR
12401247#undef INTERNAL_ERROR_STRING
12411248}
@@ -1245,7 +1252,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
12451252 return !!bindGroupLayout ();
12461253}
12471254
1248- BindGroup::BindGroup (id <MTLBuffer > vertexArgumentBuffer, id <MTLBuffer > fragmentArgumentBuffer, id <MTLBuffer > computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, SamplersContainer&& samplers, ShaderStageArray<ExternalTextureIndices>&& externalTextureIndices, Device& device)
1255+ BindGroup::BindGroup (id <MTLBuffer > vertexArgumentBuffer, id <MTLBuffer > fragmentArgumentBuffer, id <MTLBuffer > computeArgumentBuffer, Vector<BindableResources>&& resources, const BindGroupLayout& bindGroupLayout, DynamicBuffersContainer&& dynamicBuffers, SamplersContainer&& samplers, ShaderStageArray<ExternalTextureIndices>&& externalTextureIndices, uint32_t uniqueIdentifier, Device& device)
12491256 : m_vertexArgumentBuffer(vertexArgumentBuffer)
12501257 , m_fragmentArgumentBuffer(fragmentArgumentBuffer)
12511258 , m_computeArgumentBuffer(computeArgumentBuffer)
@@ -1255,6 +1262,7 @@ static BindGroupEntryUsageData makeBindGroupEntryUsageData(BindGroupEntryUsage u
12551262 , m_dynamicBuffers(WTFMove(dynamicBuffers))
12561263 , m_samplers(WTFMove(samplers))
12571264 , m_externalTextureIndices(WTFMove(externalTextureIndices))
1265+ , m_uniqueIdentifier(uniqueIdentifier)
12581266{
12591267 for (size_t index = 0 , maxIndex = m_dynamicBuffers.size (); index < maxIndex; ++index)
12601268 m_dynamicOffsetsIndices.add (m_dynamicBuffers[index].bindingIndex , index);
@@ -1443,6 +1451,23 @@ static bool WARN_UNUSED_RETURN setArgumentBuffer(id<MTLArgumentEncoder> encoder,
14431451 return true ;
14441452}
14451453
1454+ static uint64_t makePipelineBindGroupKey (uint32_t groupIndex, uint64_t pipelineIndex)
1455+ {
1456+ return static_cast <uint64_t >(groupIndex) | (pipelineIndex << Device::maxBindGroups);
1457+ }
1458+
1459+ void BindGroup::validatedSuccessfully (uint32_t groupIndex, uint64_t pipelineIndex, uint32_t maxOffset) const
1460+ {
1461+ auto it = m_validatedBindGroup.add (makePipelineBindGroupKey (groupIndex, pipelineIndex), maxOffset).iterator ;
1462+ it->value = std::max (it->value , maxOffset);
1463+ }
1464+
1465+ bool BindGroup::previouslyValidatedBindGroup (uint32_t groupIndex, uint64_t pipelineIndex, uint32_t maxOffset) const
1466+ {
1467+ auto it = m_validatedBindGroup.find (makePipelineBindGroupKey (groupIndex, pipelineIndex));
1468+ return it != m_validatedBindGroup.end () && it->value >= maxOffset;
1469+ }
1470+
14461471} // namespace WebGPU
14471472
14481473#pragma mark WGPU Stubs
0 commit comments