Skip to content

Commit 5c304e3

Browse files
committed
Add duplicate pipeline error check
Refuse to write the pipeline index if there are duplicate pipeline identifiers.
1 parent f6b81d1 commit 5c304e3

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

pcwriter.hpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include <cstring>
3030
#define VKSC_MEMCPY memcpy
3131
#endif // VKSC_MEMCPY
32+
#ifndef VKSC_MEMCMP
33+
#include <cstring>
34+
#define VKSC_MEMCMP memcmp
35+
#endif // VKSC_MEMCPY
3236

3337
#include <vulkan/vulkan_sc_core.hpp>
3438

@@ -145,6 +149,12 @@ class VKSCPipelineEntry
145149
VKSCPipelineEntry& operator=(VKSCPipelineEntry const& rhs) = delete; // copy assignment
146150
VKSCPipelineEntry& operator=(VKSCPipelineEntry&& rhs) = delete; // move assignment
147151

152+
// equality operator -- determined soley by equality of pipeline <identifier>
153+
bool operator==(VKSCPipelineEntry const& rhs)
154+
{
155+
return (VKSC_MEMCMP(m_Identifier, rhs.m_Identifier, VK_UUID_SIZE) == 0);
156+
}
157+
148158
// destructor - delete any memory this class allocated
149159
~VKSCPipelineEntry()
150160
{
@@ -446,7 +456,8 @@ class VKSCPipelineCacheHeaderWriter
446456
// write the Pipeline Index and all associated data at mPipelineIndexOffset bytes into <data>
447457
// param: <size> is the amount of memory in bytes for the pipeline cache memory
448458
// param: <data> is pointer to the beginning of the pipeline cache memory
449-
// returns the offset in bytes into <data> which immediately follows the written information
459+
// return: the offset in bytes into <data> which immediately follows the written information
460+
// return: 0 if the pipeline cache contains duplicate identifiers, no data is written
450461
// precondition: the memory at [data,data+size) is writeable for the pipeline cache
451462
// No implementation-specific per-pipeline or per-stage metadata is written, but space is reserved if
452463
// setPipelineIndexStride and/or setStageIndexStride were called appropriately.
@@ -456,6 +467,13 @@ class VKSCPipelineCacheHeaderWriter
456467
uint64_t extraOffset = m_PipelineIndexOffset + indexSize;
457468
VKSC_ASSERT(size > extraOffset);
458469

470+
// cowardly refuse to create a pipeline cache with duplicate identifiers
471+
if (checkDuplicatePipelineIdentifiers())
472+
{
473+
//VKSC_ASSERT(0 && "pipeline contains duplicates");
474+
return 0;
475+
}
476+
459477
uint64_t currentOffset = m_PipelineIndexOffset;
460478
for (uint32_t i = 0U; i < m_PipelineCount; ++i)
461479
{
@@ -466,6 +484,25 @@ class VKSCPipelineCacheHeaderWriter
466484
return extraOffset;
467485
}
468486

487+
// A valid pipeline cache cannot contain duplicate pipeline identifiers, as it would be
488+
// undefined which one would be used at runtime. It would also waste pipeline cache storage
489+
// space, since they are presumably identical.
490+
bool checkDuplicatePipelineIdentifiers() const
491+
{
492+
for (uint32_t i = 0U; i < m_PipelineCount; i++)
493+
{
494+
for (uint32_t j = i + 1U; j < m_PipelineCount; j++)
495+
{
496+
if (*m_PipelineIndex[i] == *m_PipelineIndex[j])
497+
{
498+
std::cerr << "ERROR: pipelines " << i << " and " << j << " have identical pipeline identifiers." << std::endl;
499+
return true;
500+
}
501+
}
502+
}
503+
return false;
504+
}
505+
469506
// return: the amount of space in bytes required for the pipeline index and all associated data.
470507
// includes pipeline index and all associated pipeline entry data (json, stage index, stage code).
471508
// Does NOT include the size of the initial VkPipelineCacheHeaderVersionSafetyCriticalOne header.

pipeline.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ int main(void)
193193

194194
pcw.writeHeaderSafetyCriticalOne(cacheSize, cache.data());
195195
uint64_t end = pcw.writePipelineIndex(cacheSize, cache.data());
196+
if (end == 0) std::cout << "pipeline write aborted due to duplicates" << std::endl;
196197
uint64_t pipelineIndexSize = pcw.getPipelineIndexSize();
197198

198199
for (auto& entry : pipeStore)
@@ -238,6 +239,7 @@ int main(void)
238239
std::cout << "pie " << id << ": " << *pie << std::endl;
239240
} else {
240241
std::cout << "pie " << id << ": not found" << std::endl;
242+
continue;
241243
}
242244
char const *jsonPtr = reinterpret_cast<char const *>(pcr.getJson(*pie));
243245
if (nullptr != jsonPtr)

0 commit comments

Comments
 (0)