Skip to content

Commit 2b01465

Browse files
tuxerrbaldurk
authored andcommitted
keep driver's pipelineCacheUUID valid and use it for replay
1 parent b400d4b commit 2b01465

File tree

2 files changed

+55
-103
lines changed

2 files changed

+55
-103
lines changed

renderdoc/driver/vulkan/wrappers/vk_get_funcs.cpp

Lines changed: 14 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,6 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevic
234234
{
235235
ObjDisp(physicalDevice)->GetPhysicalDeviceProperties(Unwrap(physicalDevice), pProperties);
236236

237-
MakeFakeUUID();
238-
239-
memcpy(pProperties->pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE);
240-
241237
ClampPhysDevAPIVersion(pProperties, physicalDevice);
242238
}
243239

@@ -639,57 +635,25 @@ void WrappedVulkan::vkGetRenderAreaGranularity(VkDevice device, VkRenderPass ren
639635
VkResult WrappedVulkan::vkGetPipelineCacheData(VkDevice device, VkPipelineCache pipelineCache,
640636
size_t *pDataSize, void *pData)
641637
{
642-
// required header and 4 NULL bytes
643-
size_t totalSize = sizeof(VkPipelineCacheHeaderVersionOne) + 4;
644-
645-
if(pDataSize && !pData)
646-
*pDataSize = totalSize;
647-
648-
if(pDataSize && pData)
649-
{
650-
if(*pDataSize < totalSize)
651-
{
652-
memset(pData, 0, *pDataSize);
653-
return VK_INCOMPLETE;
654-
}
655-
656-
VkPipelineCacheHeaderVersionOne *header = (VkPipelineCacheHeaderVersionOne *)pData;
657-
658-
RDCCOMPILE_ASSERT(sizeof(VkPipelineCacheHeaderVersionOne) == 16 + VK_UUID_SIZE,
659-
"Pipeline cache header size is wrong");
660-
661-
header->headerSize = sizeof(VkPipelineCacheHeaderVersionOne);
662-
header->headerVersion = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
663-
// just in case the user expects a valid vendorID/deviceID, write the real one
664-
// MULTIDEVICE need to get the right physical device for this device
665-
header->vendorID = m_PhysicalDeviceData.props.vendorID;
666-
header->deviceID = m_PhysicalDeviceData.props.deviceID;
667-
668-
MakeFakeUUID();
669-
670-
memcpy(header->pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE);
671-
672-
RDCCOMPILE_ASSERT(VK_UUID_SIZE == 16, "VK_UUID_SIZE has changed");
673-
674-
// empty bytes
675-
uint32_t *ptr = (uint32_t *)(header + 1);
676-
*ptr = 0;
677-
}
678-
679-
// we don't want the application to use pipeline caches at all, and especially
680-
// don't want to return any data for future use. We thus return a technically
681-
// valid but empty pipeline cache. Our UUID changes every run so in theory the
682-
// application should never provide an old cache, but just in case we will nop
683-
// it out in create pipeline cache
684-
return VK_SUCCESS;
638+
return ObjDisp(device)->GetPipelineCacheData(Unwrap(device), Unwrap(pipelineCache), pDataSize,
639+
pData);
685640
}
686641

687642
VkResult WrappedVulkan::vkMergePipelineCaches(VkDevice device, VkPipelineCache destCache,
688643
uint32_t srcCacheCount,
689644
const VkPipelineCache *pSrcCaches)
690645
{
691646
// do nothing, our pipeline caches are always dummies
692-
return VK_SUCCESS;
647+
rdcarray<VkPipelineCache> unwrappedPipelineCaches;
648+
649+
unwrappedPipelineCaches.reserve(srcCacheCount);
650+
for(uint32_t cacheIndex = 0; cacheIndex < srcCacheCount; cacheIndex++)
651+
{
652+
unwrappedPipelineCaches.push_back(Unwrap(pSrcCaches[cacheIndex]));
653+
}
654+
655+
return ObjDisp(device)->MergePipelineCaches(Unwrap(device), Unwrap(destCache), srcCacheCount,
656+
unwrappedPipelineCaches.data());
693657
}
694658

695659
VkResult WrappedVulkan::vkGetPhysicalDeviceExternalImageFormatPropertiesNV(
@@ -893,10 +857,6 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevi
893857
{
894858
ObjDisp(physicalDevice)->GetPhysicalDeviceProperties2(Unwrap(physicalDevice), pProperties);
895859

896-
MakeFakeUUID();
897-
898-
memcpy(pProperties->properties.pipelineCacheUUID, fakeRenderDocUUID, VK_UUID_SIZE);
899-
900860
ClampPhysDevAPIVersion(&pProperties->properties, physicalDevice);
901861

902862
// internal RenderDoc UUID for shader object binary
@@ -906,6 +866,8 @@ void WrappedVulkan::vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevi
906866

907867
if(shadObj)
908868
{
869+
MakeFakeUUID();
870+
909871
memcpy(shadObj->shaderBinaryUUID, fakeRenderDocUUID, VK_UUID_SIZE);
910872
}
911873
}

renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp

Lines changed: 41 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,22 @@
2929

3030
RDOC_EXTERN_CONFIG(bool, Replay_Debug_SingleThreadedCompilation);
3131

32-
static RDResult DeferredPipelineCompile(VkDevice device,
32+
RDOC_CONFIG(bool, Vulkan_Debug_UsePipelineCacheForReplay, true,
33+
"Use application-provided pipeline cache when compiling shaders on replay");
34+
35+
static RDResult DeferredPipelineCompile(VkDevice device, VkPipelineCache pipelineCache,
3336
const VkGraphicsPipelineCreateInfo &createInfo,
3437
WrappedVkPipeline *wrappedPipe)
3538
{
39+
if(!Vulkan_Debug_UsePipelineCacheForReplay())
40+
pipelineCache = VK_NULL_HANDLE;
41+
3642
byte *mem = AllocAlignedBuffer(GetNextPatchSize(&createInfo));
3743
VkGraphicsPipelineCreateInfo *unwrapped =
3844
UnwrapStructAndChain(CaptureState::LoadingReplaying, mem, &createInfo);
3945

4046
VkPipeline realPipe;
41-
VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), VK_NULL_HANDLE, 1,
47+
VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache), 1,
4248
unwrapped, NULL, &realPipe);
4349

4450
FreeAlignedBuffer((byte *)unwrapped);
@@ -54,16 +60,19 @@ static RDResult DeferredPipelineCompile(VkDevice device,
5460
return ResultCode::Succeeded;
5561
}
5662

57-
static RDResult DeferredPipelineCompile(VkDevice device,
63+
static RDResult DeferredPipelineCompile(VkDevice device, VkPipelineCache pipelineCache,
5864
const VkComputePipelineCreateInfo &createInfo,
5965
WrappedVkPipeline *wrappedPipe)
6066
{
67+
if(!Vulkan_Debug_UsePipelineCacheForReplay())
68+
pipelineCache = VK_NULL_HANDLE;
69+
6170
byte *mem = AllocAlignedBuffer(GetNextPatchSize(&createInfo));
6271
VkComputePipelineCreateInfo *unwrapped =
6372
UnwrapStructAndChain(CaptureState::LoadingReplaying, mem, &createInfo);
6473

6574
VkPipeline realPipe;
66-
VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), VK_NULL_HANDLE, 1,
75+
VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), 1,
6776
unwrapped, NULL, &realPipe);
6877

6978
FreeAlignedBuffer((byte *)unwrapped);
@@ -79,12 +88,15 @@ static RDResult DeferredPipelineCompile(VkDevice device,
7988
return ResultCode::Succeeded;
8089
}
8190

82-
static RDResult DeferredPipelineCompile(VkDevice device,
91+
static RDResult DeferredPipelineCompile(VkDevice device, VkPipelineCache pipelineCache,
8392
const VkRayTracingPipelineCreateInfoKHR &createInfo,
8493
const bytebuf &replayHandles,
8594
uint32_t captureReplayHandleSize,
8695
WrappedVkPipeline *wrappedPipe)
8796
{
97+
if(!Vulkan_Debug_UsePipelineCacheForReplay())
98+
pipelineCache = VK_NULL_HANDLE;
99+
88100
byte *mem = AllocAlignedBuffer(GetNextPatchSize(&createInfo));
89101
VkRayTracingPipelineCreateInfoKHR *unwrapped =
90102
UnwrapStructAndChain(CaptureState::LoadingReplaying, mem, &createInfo);
@@ -98,7 +110,7 @@ static RDResult DeferredPipelineCompile(VkDevice device,
98110

99111
VkPipeline realPipe;
100112
VkResult ret = ObjDisp(device)->CreateRayTracingPipelinesKHR(
101-
Unwrap(device), VK_NULL_HANDLE, VK_NULL_HANDLE, 1, unwrapped, NULL, &realPipe);
113+
Unwrap(device), VK_NULL_HANDLE, Unwrap(pipelineCache), 1, unwrapped, NULL, &realPipe);
102114

103115
FreeAlignedBuffer((byte *)unwrapped);
104116

@@ -660,18 +672,7 @@ VkResult WrappedVulkan::vkCreatePipelineCache(VkDevice device,
660672
const VkAllocationCallbacks *,
661673
VkPipelineCache *pPipelineCache)
662674
{
663-
// pretend the user didn't provide any cache data
664-
665675
VkPipelineCacheCreateInfo createInfo = *pCreateInfo;
666-
createInfo.initialDataSize = 0;
667-
createInfo.pInitialData = NULL;
668-
669-
if(pCreateInfo->initialDataSize > 0)
670-
{
671-
RDCWARN(
672-
"Application provided pipeline cache data! This is invalid, as RenderDoc reports "
673-
"incompatibility with previous caches");
674-
}
675676

676677
VkResult ret;
677678
SERIALISE_TIME_CALL(ret = ObjDisp(device)->CreatePipelineCache(Unwrap(device), &createInfo, NULL,
@@ -726,10 +727,6 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
726727
VkPipeline pipe = VK_NULL_HANDLE;
727728

728729
VkRenderPass origRP = CreateInfo.renderPass;
729-
VkPipelineCache origCache = pipelineCache;
730-
731-
// don't use pipeline caches on replay
732-
pipelineCache = VK_NULL_HANDLE;
733730

734731
// if we have pipeline executable properties, capture the data
735732
if(GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
@@ -852,8 +849,8 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
852849
}
853850

854851
DerivedResource(device, Pipeline);
855-
if(origCache != VK_NULL_HANDLE)
856-
DerivedResource(origCache, Pipeline);
852+
if(pipelineCache != VK_NULL_HANDLE)
853+
DerivedResource(pipelineCache, Pipeline);
857854
if(OrigCreateInfo.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT)
858855
{
859856
if(OrigCreateInfo.basePipelineHandle != VK_NULL_HANDLE)
@@ -887,8 +884,8 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
887884
{
888885
for(rdcpair<VkGraphicsPipelineCreateInfo, VkPipeline> &deferredPipe : pipelinesToCompile)
889886
{
890-
RDResult res =
891-
DeferredPipelineCompile(device, deferredPipe.first, GetWrapped(deferredPipe.second));
887+
RDResult res = DeferredPipelineCompile(device, pipelineCache, deferredPipe.first,
888+
GetWrapped(deferredPipe.second));
892889

893890
if(res != ResultCode::Succeeded)
894891
{
@@ -908,10 +905,11 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
908905
{
909906
WrappedVkPipeline *wrappedPipe = GetWrapped(deferredPipe.second);
910907
wrappedPipe->deferredJob = Threading::JobSystem::AddJob(
911-
[wrappedVulkan = this, device, createInfo = deferredPipe.first, wrappedPipe]() {
908+
[wrappedVulkan = this, device, pipelineCache, createInfo = deferredPipe.first,
909+
wrappedPipe]() {
912910
PerformanceTimer timer;
913911
wrappedVulkan->CheckDeferredResult(
914-
DeferredPipelineCompile(device, createInfo, wrappedPipe));
912+
DeferredPipelineCompile(device, pipelineCache, createInfo, wrappedPipe));
915913
wrappedVulkan->AddDeferredTime(timer.GetMilliseconds());
916914
},
917915
parents);
@@ -1074,11 +1072,6 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe
10741072
{
10751073
VkPipeline pipe = VK_NULL_HANDLE;
10761074

1077-
VkPipelineCache origCache = pipelineCache;
1078-
1079-
// don't use pipeline caches on replay
1080-
pipelineCache = VK_NULL_HANDLE;
1081-
10821075
// if we have pipeline executable properties, capture the data
10831076
if(GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
10841077
{
@@ -1152,7 +1145,7 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe
11521145

11531146
if(Replay_Debug_SingleThreadedCompilation())
11541147
{
1155-
RDResult res = DeferredPipelineCompile(device, OrigCreateInfo, GetWrapped(pipe));
1148+
RDResult res = DeferredPipelineCompile(device, pipelineCache, OrigCreateInfo, GetWrapped(pipe));
11561149
Deserialise(OrigCreateInfo);
11571150

11581151
if(res != ResultCode::Succeeded)
@@ -1164,20 +1157,20 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe
11641157
else
11651158
{
11661159
WrappedVkPipeline *wrappedPipe = GetWrapped(pipe);
1167-
wrappedPipe->deferredJob =
1168-
Threading::JobSystem::AddJob([wrappedVulkan = this, device, OrigCreateInfo, wrappedPipe]() {
1160+
wrappedPipe->deferredJob = Threading::JobSystem::AddJob(
1161+
[wrappedVulkan = this, device, pipelineCache, OrigCreateInfo, wrappedPipe]() {
11691162
PerformanceTimer timer;
11701163
wrappedVulkan->CheckDeferredResult(
1171-
DeferredPipelineCompile(device, OrigCreateInfo, wrappedPipe));
1164+
DeferredPipelineCompile(device, pipelineCache, OrigCreateInfo, wrappedPipe));
11721165
wrappedVulkan->AddDeferredTime(timer.GetMilliseconds());
11731166

11741167
Deserialise(OrigCreateInfo);
11751168
});
11761169
}
11771170

11781171
DerivedResource(device, Pipeline);
1179-
if(origCache != VK_NULL_HANDLE)
1180-
DerivedResource(origCache, Pipeline);
1172+
if(pipelineCache != VK_NULL_HANDLE)
1173+
DerivedResource(pipelineCache, Pipeline);
11811174
if(OrigCreateInfo.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT)
11821175
{
11831176
if(OrigCreateInfo.basePipelineHandle != VK_NULL_HANDLE)
@@ -1360,11 +1353,6 @@ bool WrappedVulkan::Serialise_vkCreateRayTracingPipelinesKHR(
13601353

13611354
VkPipeline pipe = VK_NULL_HANDLE;
13621355

1363-
VkPipelineCache origCache = pipelineCache;
1364-
1365-
// don't use pipeline caches on replay
1366-
pipelineCache = VK_NULL_HANDLE;
1367-
13681356
// don't fail when a compile is required because we don't currently replay caches so this will
13691357
// always happen. This still allows application to use this flag at runtime where it will be
13701358
// valid
@@ -1390,8 +1378,8 @@ bool WrappedVulkan::Serialise_vkCreateRayTracingPipelinesKHR(
13901378
pipeInfo.Init(GetResourceManager(), m_CreationInfo, live, &OrigCreateInfo);
13911379

13921380
DerivedResource(device, Pipeline);
1393-
if(origCache != VK_NULL_HANDLE)
1394-
DerivedResource(origCache, Pipeline);
1381+
if(pipelineCache != VK_NULL_HANDLE)
1382+
DerivedResource(pipelineCache, Pipeline);
13951383
if(OrigCreateInfo.flags & VK_PIPELINE_CREATE_DERIVATIVE_BIT)
13961384
{
13971385
if(OrigCreateInfo.basePipelineHandle != VK_NULL_HANDLE)
@@ -1418,8 +1406,9 @@ bool WrappedVulkan::Serialise_vkCreateRayTracingPipelinesKHR(
14181406

14191407
if(Replay_Debug_SingleThreadedCompilation())
14201408
{
1421-
RDResult res = DeferredPipelineCompile(device, OrigCreateInfo, *OrigReplayHandles,
1422-
captureReplayHandleSize, GetWrapped(pipe));
1409+
RDResult res =
1410+
DeferredPipelineCompile(device, pipelineCache, OrigCreateInfo, *OrigReplayHandles,
1411+
captureReplayHandleSize, GetWrapped(pipe));
14231412
if(res == ResultCode::APIHardwareUnsupported)
14241413
res.message = rdcstr(res.message) + "\n" + GetPhysDeviceCompatString(false, false);
14251414
Deserialise(OrigCreateInfo);
@@ -1435,11 +1424,12 @@ bool WrappedVulkan::Serialise_vkCreateRayTracingPipelinesKHR(
14351424
{
14361425
WrappedVkPipeline *wrappedPipe = GetWrapped(pipe);
14371426
wrappedPipe->deferredJob = Threading::JobSystem::AddJob(
1438-
[wrappedVulkan = this, device, OrigCreateInfo, OrigReplayHandles, captureReplayHandleSize,
1439-
wrappedPipe]() {
1427+
[wrappedVulkan = this, device, pipelineCache, OrigCreateInfo, OrigReplayHandles,
1428+
captureReplayHandleSize, wrappedPipe]() {
14401429
PerformanceTimer timer;
1441-
RDResult res = DeferredPipelineCompile(device, OrigCreateInfo, *OrigReplayHandles,
1442-
captureReplayHandleSize, wrappedPipe);
1430+
RDResult res =
1431+
DeferredPipelineCompile(device, pipelineCache, OrigCreateInfo, *OrigReplayHandles,
1432+
captureReplayHandleSize, wrappedPipe);
14431433
wrappedVulkan->AddDeferredTime(timer.GetMilliseconds());
14441434
if(res == ResultCode::APIHardwareUnsupported)
14451435
res.message = rdcstr(res.message) + "\n" +

0 commit comments

Comments
 (0)