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.
0 commit comments