Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ macros before including pcreader.hpp.
The PC Writer utility performs dynamic memory allocations using the standard `new`
and `delete` array operators.

It also makes use of the `assert` and `memcpy` standard library functions.
It also makes use of the `assert`, `memcpy`, and `memcmp` standard library functions.
If a user of the library wishes to disable asserts or provide an alternative memcpy
implementation this can be done by setting the `VKSC_ASSERT` and `VKSC_MEMCPY`
macros before including pcwriter.hpp.
and memcmp implementations this can be done by setting the `VKSC_ASSERT`, `VKSC_MEMCPY`,
and `VKSC_MEMCMP` macros before including pcwriter.hpp.
39 changes: 38 additions & 1 deletion pcwriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include <cstring>
#define VKSC_MEMCPY memcpy
#endif // VKSC_MEMCPY
#ifndef VKSC_MEMCMP
#include <cstring>
#define VKSC_MEMCMP memcmp
#endif // VKSC_MEMCPY

#include <vulkan/vulkan_sc_core.hpp>

Expand Down Expand Up @@ -145,6 +149,12 @@ class VKSCPipelineEntry
VKSCPipelineEntry& operator=(VKSCPipelineEntry const& rhs) = delete; // copy assignment
VKSCPipelineEntry& operator=(VKSCPipelineEntry&& rhs) = delete; // move assignment

// equality operator -- determined soley by equality of pipeline <identifier>
bool operator==(VKSCPipelineEntry const& rhs)
{
return (VKSC_MEMCMP(m_Identifier, rhs.m_Identifier, VK_UUID_SIZE) == 0);
}

// destructor - delete any memory this class allocated
~VKSCPipelineEntry()
{
Expand Down Expand Up @@ -446,7 +456,8 @@ class VKSCPipelineCacheHeaderWriter
// write the Pipeline Index and all associated data at mPipelineIndexOffset bytes into <data>
// param: <size> is the amount of memory in bytes for the pipeline cache memory
// param: <data> is pointer to the beginning of the pipeline cache memory
// returns the offset in bytes into <data> which immediately follows the written information
// return: the offset in bytes into <data> which immediately follows the written information
// return: 0 if the pipeline cache contains duplicate identifiers, no data is written
// precondition: the memory at [data,data+size) is writeable for the pipeline cache
// No implementation-specific per-pipeline or per-stage metadata is written, but space is reserved if
// setPipelineIndexStride and/or setStageIndexStride were called appropriately.
Expand All @@ -456,6 +467,13 @@ class VKSCPipelineCacheHeaderWriter
uint64_t extraOffset = m_PipelineIndexOffset + indexSize;
VKSC_ASSERT(size > extraOffset);

// cowardly refuse to create a pipeline cache with duplicate identifiers
if (checkDuplicatePipelineIdentifiers())
{
//VKSC_ASSERT(0 && "pipeline contains duplicates");
return 0;
}

uint64_t currentOffset = m_PipelineIndexOffset;
for (uint32_t i = 0U; i < m_PipelineCount; ++i)
{
Expand All @@ -466,6 +484,25 @@ class VKSCPipelineCacheHeaderWriter
return extraOffset;
}

// A valid pipeline cache cannot contain duplicate pipeline identifiers, as it would be
// undefined which one would be used at runtime. It would also waste pipeline cache storage
// space, since they are presumably identical.
bool checkDuplicatePipelineIdentifiers() const
{
for (uint32_t i = 0U; i < m_PipelineCount; i++)
{
for (uint32_t j = i + 1U; j < m_PipelineCount; j++)
{
if (*m_PipelineIndex[i] == *m_PipelineIndex[j])
{
std::cerr << "ERROR: pipelines " << i << " and " << j << " have identical pipeline identifiers." << std::endl;
return true;
}
}
}
return false;
}

// return: the amount of space in bytes required for the pipeline index and all associated data.
// includes pipeline index and all associated pipeline entry data (json, stage index, stage code).
// Does NOT include the size of the initial VkPipelineCacheHeaderVersionSafetyCriticalOne header.
Expand Down
2 changes: 2 additions & 0 deletions pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ int main(void)

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

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