Skip to content

Commit

Permalink
Merge branch 'OGRECave:master' into patch-3
Browse files Browse the repository at this point in the history
  • Loading branch information
mosfet80 authored Sep 11, 2024
2 parents 8a82f29 + 6df7138 commit c0b498b
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 2 deletions.
26 changes: 26 additions & 0 deletions OgreMain/include/OgreRenderSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -1547,6 +1547,32 @@ namespace Ogre

BarrierSolver &getBarrierSolver() { return mBarrierSolver; }

/** Loads the pipeline cache from disk.
@param stream The source stream, optional, starts with struct PipelineCachePrefixHeader
*/
virtual void loadPipelineCache( DataStreamPtr stream );
/** Saves the pipeline cache to disk.
@param stream The destination stream
*/
virtual void savePipelineCache( DataStreamPtr stream ) const;

/// When serializing pipeline cache data to the file, we use a header that is filled with
/// enough information to be able to validate the data, with the pipeline cache data following
/// immediately afterwards. https://zeux.io/2019/07/17/serializing-pipeline-cache/#fn:1
struct PipelineCachePrefixHeader
{
uint32_t magic; // an arbitrary magic header to make sure this is actually our file
uint32_t dataSize; // equal to *pDataSize returned by vkGetPipelineCacheData
uint64_t dataHash; // a hash of pipeline cache data, including the header

uint32_t vendorID; // equal to VkPhysicalDeviceProperties::vendorID
uint32_t deviceID; // equal to VkPhysicalDeviceProperties::deviceID
uint32_t driverVersion; // equal to VkPhysicalDeviceProperties::driverVersion
uint32_t driverABI; // equal to sizeof(void*)

uint8_t uuid[16]; // equal to VkPhysicalDeviceProperties::pipelineCacheUUID
};

protected:
void destroyAllRenderPassDescriptors();

Expand Down
4 changes: 4 additions & 0 deletions OgreMain/src/OgreRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1373,6 +1373,10 @@ namespace Ogre
mGlobalInstanceVertexBufferVertexDeclaration = val;
}
//---------------------------------------------------------------------
void RenderSystem::loadPipelineCache( DataStreamPtr stream ) {}
//---------------------------------------------------------------------
void RenderSystem::savePipelineCache( DataStreamPtr stream ) const {}
//---------------------------------------------------------------------
bool RenderSystem::startGpuDebuggerFrameCapture( Window *window )
{
if( !mRenderDocApi )
Expand Down
1 change: 1 addition & 0 deletions RenderSystems/Vulkan/include/OgreVulkanDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ namespace Ogre
VkInstance mInstance;
VkPhysicalDevice mPhysicalDevice;
VkDevice mDevice;
VkPipelineCache mPipelineCache;

VkQueue mPresentQueue;
/// Graphics queue is *guaranteed by spec* to also be able to run compute and transfer
Expand Down
2 changes: 2 additions & 0 deletions RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ namespace Ogre
const char *getPriorityConfigOption( size_t idx ) const override;
size_t getNumPriorityConfigOptions() const override;
bool supportsMultithreadedShaderCompilation() const override;
void loadPipelineCache( DataStreamPtr stream ) override;
void savePipelineCache( DataStreamPtr stream ) const override;

HardwareOcclusionQuery *createHardwareOcclusionQuery() override;

Expand Down
14 changes: 14 additions & 0 deletions RenderSystems/Vulkan/src/OgreVulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace Ogre
mInstance( instance ),
mPhysicalDevice( 0 ),
mDevice( 0 ),
mPipelineCache( 0 ),
mPresentQueue( 0 ),
mVaoManager( 0 ),
mRenderSystem( renderSystem ),
Expand All @@ -69,6 +70,7 @@ namespace Ogre
mInstance( instance ),
mPhysicalDevice( externalDevice.physicalDevice ),
mDevice( externalDevice.device ),
mPipelineCache( 0 ),
mPresentQueue( 0 ),
mVaoManager( 0 ),
mRenderSystem( renderSystem ),
Expand Down Expand Up @@ -208,6 +210,12 @@ namespace Ogre
destroyQueues( mComputeQueues );
destroyQueues( mTransferQueues );

if( mPipelineCache )
{
vkDestroyPipelineCache( mDevice, mPipelineCache, nullptr );
mPipelineCache = 0;
}

// Must be done externally (this' destructor has yet to free more Vulkan stuff)
// vkDestroyDevice( mDevice, 0 );
mDevice = 0;
Expand Down Expand Up @@ -620,6 +628,12 @@ namespace Ogre
VkResult result = vkCreateDevice( mPhysicalDevice, &createInfo, NULL, &mDevice );
checkVkResult( result, "vkCreateDevice" );

VkPipelineCacheCreateInfo pipelineCacheCreateInfo;
makeVkStruct( pipelineCacheCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO );

result = vkCreatePipelineCache( mDevice, &pipelineCacheCreateInfo, nullptr, &mPipelineCache );
checkVkResult( result, "vkCreatePipelineCache" );

initUtils( mDevice );
}
//-------------------------------------------------------------------------
Expand Down
112 changes: 110 additions & 2 deletions RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ THE SOFTWARE.

#define TODO_addVpCount_to_passpso

#if OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32
# define OGRE_HASH128_FUNC MurmurHash3_x86_128
#else
# define OGRE_HASH128_FUNC MurmurHash3_x64_128
#endif

namespace Ogre
{
/*static bool checkLayers( const FastArray<layer_properties> &layer_props,
Expand Down Expand Up @@ -467,6 +473,108 @@ namespace Ogre
#endif
}
//-------------------------------------------------------------------------
void VulkanRenderSystem::loadPipelineCache( DataStreamPtr stream )
{
if( stream && stream->size() > sizeof( PipelineCachePrefixHeader ) )
{
std::vector<unsigned char> buf; // PipelineCachePrefixHeader + payload
buf.resize( stream->size() );
stream->read( buf.data(), buf.size() );

// validate blob
VkResult result = VK_ERROR_FORMAT_NOT_SUPPORTED;
auto &hdr = *(PipelineCachePrefixHeader *)buf.data();
if( hdr.magic == ( 'V' | ( 'K' << 8 ) | ( 'P' << 16 ) | ( 'C' << 24 ) ) &&
hdr.dataSize == buf.size() - sizeof( PipelineCachePrefixHeader ) &&
hdr.vendorID == mActiveDevice->mDeviceProperties.vendorID &&
hdr.deviceID == mActiveDevice->mDeviceProperties.deviceID &&
hdr.driverVersion == mActiveDevice->mDeviceProperties.driverVersion &&
hdr.driverABI == sizeof( void * ) &&
0 == memcmp( hdr.uuid, mActiveDevice->mDeviceProperties.pipelineCacheUUID,
VK_UUID_SIZE ) )
{
auto dataHash = hdr.dataHash;
hdr.dataHash = 0;
uint64 hashResult[2] = {};
OGRE_HASH128_FUNC( buf.data(), (int)buf.size(), IdString::Seed, hashResult );
if( dataHash == hashResult[0] )
result = VK_SUCCESS;
}

if( result != VK_SUCCESS )
LogManager::getSingleton().logMessage( "[Vulkan] Pipeline cache outdated, not loaded." );
else
{
VkPipelineCacheCreateInfo pipelineCacheCreateInfo;
makeVkStruct( pipelineCacheCreateInfo, VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO );
pipelineCacheCreateInfo.initialDataSize =
buf.size() - sizeof( PipelineCachePrefixHeader );
pipelineCacheCreateInfo.pInitialData = buf.data() + sizeof( PipelineCachePrefixHeader );

VkPipelineCache pipelineCache{};
result = vkCreatePipelineCache( mActiveDevice->mDevice, &pipelineCacheCreateInfo,
nullptr, &pipelineCache );
if( VK_SUCCESS == result && pipelineCache != 0 )
std::swap( mActiveDevice->mPipelineCache, pipelineCache );
else
LogManager::getSingleton().logMessage(
"[Vulkan] Pipeline cache loading failed. VkResult = " +
vkResultToString( result ) );
if( pipelineCache != 0 )
vkDestroyPipelineCache( mActiveDevice->mDevice, pipelineCache, nullptr );
}
}
}
//-------------------------------------------------------------------------
void VulkanRenderSystem::savePipelineCache( DataStreamPtr stream ) const
{
static_assert( sizeof( PipelineCachePrefixHeader ) == 48 );
if( mActiveDevice->mPipelineCache )
{
size_t size{};
VkResult result = vkGetPipelineCacheData( mActiveDevice->mDevice,
mActiveDevice->mPipelineCache, &size, nullptr );
if( result == VK_SUCCESS && size > 0 && size <= 0x7FFFFFFF )
{
std::vector<unsigned char> buf; // PipelineCachePrefixHeader + payload
do
{
buf.resize( sizeof( PipelineCachePrefixHeader ) + size );
result = vkGetPipelineCacheData( mActiveDevice->mDevice,
mActiveDevice->mPipelineCache, &size,
buf.data() + sizeof( PipelineCachePrefixHeader ) );
} while( result == VK_INCOMPLETE );

if( result == VK_SUCCESS && size > 0 && size <= 0x7FFFFFFF )
{
if( sizeof( PipelineCachePrefixHeader ) + size < buf.size() )
buf.resize( sizeof( PipelineCachePrefixHeader ) + size );

auto &hdr = *(PipelineCachePrefixHeader *)buf.data();
hdr.magic = 'V' | ( 'K' << 8 ) | ( 'P' << 16 ) | ( 'C' << 24 );
hdr.dataSize = (uint32_t)size;
hdr.dataHash = 0;
hdr.vendorID = mActiveDevice->mDeviceProperties.vendorID;
hdr.deviceID = mActiveDevice->mDeviceProperties.deviceID;
hdr.driverVersion = mActiveDevice->mDeviceProperties.driverVersion;
hdr.driverABI = sizeof( void * );
memcpy( hdr.uuid, mActiveDevice->mDeviceProperties.pipelineCacheUUID, VK_UUID_SIZE );
static_assert( VK_UUID_SIZE == 16 );

uint64 hashResult[2] = {};
OGRE_HASH128_FUNC( buf.data(), (int)buf.size(), IdString::Seed, hashResult );
hdr.dataHash = hashResult[0];

stream->write( buf.data(), buf.size() );
LogManager::getSingleton().logMessage( "[Vulkan] Pipeline cache saved." );
}
}
if( result != VK_SUCCESS )
LogManager::getSingleton().logMessage( "[Vulkan] Pipeline cache not saved. VkResult = " +
vkResultToString( result ) );
}
}
//-------------------------------------------------------------------------
String VulkanRenderSystem::validateConfigOptions()
{
return mVulkanSupport->validateConfigOptions();
Expand Down Expand Up @@ -3531,8 +3639,8 @@ namespace Ogre
#endif

VkPipeline vulkanPso = 0;
VkResult result = vkCreateGraphicsPipelines( mActiveDevice->mDevice, VK_NULL_HANDLE, 1u,
&pipeline, 0, &vulkanPso );
VkResult result = vkCreateGraphicsPipelines(
mActiveDevice->mDevice, mActiveDevice->mPipelineCache, 1u, &pipeline, 0, &vulkanPso );
checkVkResult( result, "vkCreateGraphicsPipelines" );

#if OGRE_DEBUG_MODE >= OGRE_DEBUG_MEDIUM
Expand Down
17 changes: 17 additions & 0 deletions Samples/2.0/Common/src/GraphicsSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,16 @@ namespace Demo
Ogre::Archive *rwAccessFolderArchive =
archiveManager.load( mWriteAccessFolder, "FileSystem", true );

if( mUseMicrocodeCache /* mUsePipelineCache */ )
{
const Ogre::String filename = "pipelineCache.cache";
if( rwAccessFolderArchive->exists( filename ) )
{
Ogre::DataStreamPtr pipelineCacheFile = rwAccessFolderArchive->open( filename );
mRoot->getRenderSystem()->loadPipelineCache( pipelineCacheFile );
}
}

if( mUseMicrocodeCache )
{
// Make sure the microcode cache is enabled.
Expand Down Expand Up @@ -687,6 +697,13 @@ namespace Demo
Ogre::GpuProgramManager::getSingleton().saveMicrocodeCache( shaderCacheFile );
}

if( mUseMicrocodeCache /* mUsePipelineCache */ )
{
const Ogre::String filename = "pipelineCache.cache";
Ogre::DataStreamPtr shaderCacheFile = rwAccessFolderArchive->create( filename );
mRoot->getRenderSystem()->savePipelineCache( shaderCacheFile );
}

archiveManager.unload( mWriteAccessFolder );
}
}
Expand Down

0 comments on commit c0b498b

Please sign in to comment.