Add support for VK_KHR_pipeline_executable_properties

This commit is contained in:
baldurk
2019-08-15 13:05:06 +01:00
parent 715c18b591
commit 0522a636ad
12 changed files with 574 additions and 28 deletions
+17 -3
View File
@@ -793,6 +793,7 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryProperties2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMultiviewFeatures);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMultiviewProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePCIBusInfoPropertiesEXT);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR);
DECLARE_REFLECTION_STRUCT(VkPhysicalDevicePointClippingProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProperties2);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProtectedMemoryFeatures);
@@ -829,6 +830,11 @@ DECLARE_REFLECTION_STRUCT(VkPipelineCreationFeedbackCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineDepthStencilStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineDiscardRectangleStateCreateInfoEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineDynamicStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineExecutableInfoKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineExecutableInternalRepresentationKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineExecutablePropertiesKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineExecutableStatisticKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineInfoKHR);
DECLARE_REFLECTION_STRUCT(VkPipelineInputAssemblyStateCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineLayoutCreateInfo);
DECLARE_REFLECTION_STRUCT(VkPipelineMultisampleStateCreateInfo);
@@ -1039,6 +1045,7 @@ DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMemoryProperties2);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMultiviewFeatures);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceMultiviewProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePCIBusInfoPropertiesEXT);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR);
DECLARE_DESERIALISE_TYPE(VkPhysicalDevicePointClippingProperties);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProperties2);
DECLARE_DESERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryFeatures);
@@ -1075,6 +1082,11 @@ DECLARE_DESERIALISE_TYPE(VkPipelineCreationFeedbackCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
DECLARE_DESERIALISE_TYPE(VkPipelineDynamicStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineExecutableInfoKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineExecutableInternalRepresentationKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineExecutablePropertiesKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineExecutableStatisticKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineInfoKHR);
DECLARE_DESERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineLayoutCreateInfo);
DECLARE_DESERIALISE_TYPE(VkPipelineMultisampleStateCreateInfo);
@@ -1183,8 +1195,9 @@ DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceLimits);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceMemoryProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceProperties);
DECLARE_REFLECTION_STRUCT(VkPhysicalDeviceSparseProperties);
DECLARE_REFLECTION_STRUCT(VkPipelineCreationFeedbackEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineColorBlendAttachmentState);
DECLARE_REFLECTION_STRUCT(VkPipelineCreationFeedbackEXT);
DECLARE_REFLECTION_STRUCT(VkPipelineExecutableStatisticValueKHR);
DECLARE_REFLECTION_STRUCT(VkPresentRegionKHR);
DECLARE_REFLECTION_STRUCT(VkPushConstantRange);
DECLARE_REFLECTION_STRUCT(VkQueueFamilyProperties);
@@ -1333,6 +1346,8 @@ DECLARE_REFLECTION_ENUM(VkPhysicalDeviceType);
DECLARE_REFLECTION_ENUM(VkPipelineBindPoint);
DECLARE_REFLECTION_ENUM(VkPipelineCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkPipelineCreationFeedbackFlagBitsEXT);
DECLARE_REFLECTION_ENUM(VkPipelineExecutableStatisticFormatKHR);
DECLARE_REFLECTION_ENUM(VkPipelineShaderStageCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkPipelineStageFlagBits);
DECLARE_REFLECTION_ENUM(VkPointClippingBehavior);
DECLARE_REFLECTION_ENUM(VkPolygonMode);
@@ -1344,7 +1359,6 @@ DECLARE_REFLECTION_ENUM(VkQueryResultFlagBits);
DECLARE_REFLECTION_ENUM(VkQueryType);
DECLARE_REFLECTION_ENUM(VkQueueFlagBits);
DECLARE_REFLECTION_ENUM(VkQueueGlobalPriorityEXT);
DECLARE_REFLECTION_ENUM(VkPipelineShaderStageCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkRenderPassCreateFlagBits);
DECLARE_REFLECTION_ENUM(VkResolveModeFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkResult);
@@ -1374,8 +1388,8 @@ DECLARE_REFLECTION_ENUM(VkSwapchainCreateFlagBitsKHR);
DECLARE_REFLECTION_ENUM(VkTessellationDomainOrigin);
DECLARE_REFLECTION_ENUM(VkTimeDomainEXT);
DECLARE_REFLECTION_ENUM(VkValidationCheckEXT);
DECLARE_REFLECTION_ENUM(VkValidationFeatureEnableEXT);
DECLARE_REFLECTION_ENUM(VkValidationFeatureDisableEXT);
DECLARE_REFLECTION_ENUM(VkValidationFeatureEnableEXT);
DECLARE_REFLECTION_ENUM(VkVertexInputRate);
// win32 only enums
+4
View File
@@ -936,6 +936,10 @@ static const VkExtensionProperties supportedExtensions[] = {
{
VK_KHR_MULTIVIEW_EXTENSION_NAME, VK_KHR_MULTIVIEW_SPEC_VERSION,
},
{
VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME,
VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_SPEC_VERSION,
},
{
VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, VK_KHR_PUSH_DESCRIPTOR_SPEC_VERSION,
},
+17
View File
@@ -2104,8 +2104,25 @@ public:
IMPLEMENT_FUNCTION_SERIALISED(VkResult, vkReleaseFullScreenExclusiveModeEXT, VkDevice device,
VkSwapchainKHR swapchain);
// VK_EXT_headless_surface
VkResult vkCreateHeadlessSurfaceEXT(VkInstance instance,
const VkHeadlessSurfaceCreateInfoEXT *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
VkSurfaceKHR *pSurface);
// VK_KHR_pipeline_executable_properties
VkResult vkGetPipelineExecutablePropertiesKHR(VkDevice device,
const VkPipelineInfoKHR *pPipelineInfo,
uint32_t *pExecutableCount,
VkPipelineExecutablePropertiesKHR *pProperties);
VkResult vkGetPipelineExecutableStatisticsKHR(VkDevice device,
const VkPipelineExecutableInfoKHR *pExecutableInfo,
uint32_t *pStatisticCount,
VkPipelineExecutableStatisticKHR *pStatistics);
VkResult vkGetPipelineExecutableInternalRepresentationsKHR(
VkDevice device, const VkPipelineExecutableInfoKHR *pExecutableInfo,
uint32_t *pInternalRepresentationCount,
VkPipelineExecutableInternalRepresentationKHR *pInternalRepresentations);
};
+18 -2
View File
@@ -387,7 +387,8 @@
DeclExt(EXT_buffer_device_address); \
DeclExt(EXT_full_screen_exclusive); \
DeclExt(EXT_hdr_metadata); \
DeclExt(AMD_display_native_hdr);
DeclExt(AMD_display_native_hdr); \
DeclExt(KHR_pipeline_executable_properties);
// for simplicity and since the check itself is platform agnostic,
// these aren't protected in platform defines
@@ -465,7 +466,8 @@
CheckExt(EXT_host_query_reset, VKXX); \
CheckExt(EXT_buffer_device_address, VKXX); \
CheckExt(EXT_hdr_metadata, VKXX); \
CheckExt(AMD_display_native_hdr, VKXX);
CheckExt(AMD_display_native_hdr, VKXX); \
CheckExt(KHR_pipeline_executable_properties, VKXX);
#define HookInitVulkanInstanceExts() \
HookInitExtension(KHR_surface, DestroySurfaceKHR); \
@@ -604,6 +606,10 @@
HookInitExtension(EXT_buffer_device_address, GetBufferDeviceAddressEXT); \
HookInitExtension(EXT_hdr_metadata, SetHdrMetadataEXT); \
HookInitExtension(AMD_display_native_hdr, SetLocalDimmingAMD); \
HookInitExtension(KHR_pipeline_executable_properties, GetPipelineExecutablePropertiesKHR); \
HookInitExtension(KHR_pipeline_executable_properties, GetPipelineExecutableStatisticsKHR); \
HookInitExtension(KHR_pipeline_executable_properties, \
GetPipelineExecutableInternalRepresentationsKHR); \
HookInitDevice_PlatformSpecific()
#define DefineHooks() \
@@ -1183,4 +1189,14 @@
HookDefine4(VkResult, vkCreateHeadlessSurfaceEXT, VkInstance, instance, \
const VkHeadlessSurfaceCreateInfoEXT *, pCreateInfo, const VkAllocationCallbacks *, \
pAllocator, VkSurfaceKHR *, pSurface); \
HookDefine4(VkResult, vkGetPipelineExecutablePropertiesKHR, VkDevice, device, \
const VkPipelineInfoKHR *, pPipelineInfo, uint32_t *, pExecutableCount, \
VkPipelineExecutablePropertiesKHR *, pProperties); \
HookDefine4(VkResult, vkGetPipelineExecutableStatisticsKHR, VkDevice, device, \
const VkPipelineExecutableInfoKHR *, pExecutableInfo, uint32_t *, pStatisticCount, \
VkPipelineExecutableStatisticKHR *, pStatistics); \
HookDefine4(VkResult, vkGetPipelineExecutableInternalRepresentationsKHR, VkDevice, device, \
const VkPipelineExecutableInfoKHR *, pExecutableInfo, uint32_t *, \
pInternalRepresentationCount, VkPipelineExecutableInternalRepresentationKHR *, \
pInternalRepresentations); \
HookDefine_PlatformSpecific()
+11 -6
View File
@@ -224,6 +224,8 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPhysicalDeviceMultiviewProperties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT, \
VkPhysicalDevicePCIBusInfoPropertiesEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, \
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES, \
VkPhysicalDevicePointClippingProperties); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, VkPhysicalDeviceProperties2); \
@@ -292,6 +294,11 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
VkPipelineDiscardRectangleStateCreateInfoEXT); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, \
VkPipelineDynamicStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR, \
VkPipelineExecutablePropertiesKHR) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR, VkPipelineExecutableStatisticKHR) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR, \
VkPipelineExecutableInternalRepresentationKHR) \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, \
VkPipelineInputAssemblyStateCreateInfo); \
COPY_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, \
@@ -427,6 +434,10 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
UnwrapInPlace(out->memory)); \
UNWRAP_STRUCT(VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, VkMemoryDedicatedAllocateInfo, \
UnwrapInPlace(out->buffer), UnwrapInPlace(out->image)); \
UNWRAP_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, VkPipelineInfoKHR, \
UnwrapInPlace(out->pipeline)); \
UNWRAP_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, VkPipelineExecutableInfoKHR, \
UnwrapInPlace(out->pipeline)); \
UNWRAP_STRUCT(VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, VkRenderPassBeginInfo, \
UnwrapInPlace(out->renderPass), UnwrapInPlace(out->framebuffer)); \
UNWRAP_STRUCT(VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, VkSamplerYcbcrConversionInfo, \
@@ -535,7 +546,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD: \
@@ -550,11 +560,6 @@ static void AppendModifiedChainedStruct(byte *&tempMem, VkStruct *outputStruct,
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_REDUCTION_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV: \
case VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR: \
case VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR: \
case VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR: \
case VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR: \
case VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR: \
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT: \
case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD: \
case VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV: \
+229 -8
View File
@@ -40,7 +40,8 @@
#include "data/glsl/glsl_ubos_cpp.h"
static const char *SPIRVDisassemblyTarget = "SPIR-V (RenderDoc)";
static const char *LiveDriverDisassemblyTarget = "Live driver disassembly";
static const char *AMDShaderInfoTarget = "AMD_shader_info disassembly";
static const char *KHRExecutablePropertiesTarget = "KHR_pipeline_executable_properties";
VulkanReplay::VulkanReplay()
{
@@ -350,11 +351,11 @@ std::vector<std::string> VulkanReplay::GetDisassemblyTargets()
{
std::vector<std::string> ret;
VkDevice dev = m_pDriver->GetDev();
const VkDevDispatchTable *vt = ObjDisp(dev);
if(m_pDriver->GetExtensions(NULL).ext_AMD_shader_info)
ret.push_back(AMDShaderInfoTarget);
if(vt->GetShaderInfoAMD)
ret.push_back(LiveDriverDisassemblyTarget);
if(m_pDriver->GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
ret.push_back(KHRExecutablePropertiesTarget);
// default is always first
ret.insert(ret.begin(), SPIRVDisassemblyTarget);
@@ -365,6 +366,79 @@ std::vector<std::string> VulkanReplay::GetDisassemblyTargets()
return ret;
}
void VulkanReplay::CachePipelineExecutables(ResourceId pipeline)
{
auto it = m_PipelineExecutables.insert({pipeline, rdcarray<PipelineExecutables>()});
if(!it.second)
return;
rdcarray<PipelineExecutables> &data = it.first->second;
VkPipeline pipe = m_pDriver->GetResourceManager()->GetLiveHandle<VkPipeline>(pipeline);
VkPipelineInfoKHR pipeInfo = {
VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, NULL, Unwrap(pipe),
};
VkDevice dev = m_pDriver->GetDev();
const VkDevDispatchTable *vt = ObjDisp(dev);
uint32_t execCount = 0;
vt->GetPipelineExecutablePropertiesKHR(Unwrap(dev), &pipeInfo, &execCount, NULL);
rdcarray<VkPipelineExecutablePropertiesKHR> executables;
executables.resize(execCount);
data.resize(execCount);
vt->GetPipelineExecutablePropertiesKHR(Unwrap(dev), &pipeInfo, &execCount, executables.data());
for(uint32_t i = 0; i < execCount; i++)
{
const VkPipelineExecutablePropertiesKHR &exec = executables[i];
PipelineExecutables &out = data[i];
out.name = exec.name;
out.description = exec.description;
out.stages = exec.stages;
out.subgroupSize = exec.subgroupSize;
rdcarray<VkPipelineExecutableStatisticKHR> &stats = out.statistics;
rdcarray<VkPipelineExecutableInternalRepresentationKHR> &irs = out.representations;
VkPipelineExecutableInfoKHR pipeExecInfo = {
VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, NULL, Unwrap(pipe), i,
};
// enumerate statistics
uint32_t statCount = 0;
vt->GetPipelineExecutableStatisticsKHR(Unwrap(dev), &pipeExecInfo, &statCount, NULL);
stats.resize(statCount);
for(uint32_t s = 0; s < statCount; s++)
stats[s].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR;
vt->GetPipelineExecutableStatisticsKHR(Unwrap(dev), &pipeExecInfo, &statCount, stats.data());
// enumerate internal representations
uint32_t irCount = 0;
vt->GetPipelineExecutableInternalRepresentationsKHR(Unwrap(dev), &pipeExecInfo, &irCount, NULL);
irs.resize(irCount);
for(uint32_t ir = 0; ir < irCount; ir++)
irs[ir].sType = VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR;
vt->GetPipelineExecutableInternalRepresentationsKHR(Unwrap(dev), &pipeExecInfo, &irCount,
irs.data());
// need to now allocate space, and try again
out.irbytes.resize(irCount);
for(uint32_t ir = 0; ir < irCount; ir++)
{
out.irbytes[ir].resize(irs[ir].dataSize);
irs[ir].pData = out.irbytes[ir].data();
}
vt->GetPipelineExecutableInternalRepresentationsKHR(Unwrap(dev), &pipeExecInfo, &irCount,
irs.data());
}
}
std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderReflection *refl,
const std::string &target)
{
@@ -387,12 +461,12 @@ std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderRef
VkDevice dev = m_pDriver->GetDev();
const VkDevDispatchTable *vt = ObjDisp(dev);
if(target == LiveDriverDisassemblyTarget && vt->GetShaderInfoAMD)
if(target == AMDShaderInfoTarget && vt->GetShaderInfoAMD)
{
if(pipeline == ResourceId())
{
return "; No pipeline specified, live driver disassembly is not available\n"
"; Shader must be disassembled with a specific pipeline to get live driver assembly.";
return "; No pipeline specified, VK_AMD_shader_info disassembly is not available\n"
"; Shader must be disassembled with a specific pipeline.";
}
VkPipeline pipe = m_pDriver->GetResourceManager()->GetLiveHandle<VkPipeline>(pipeline);
@@ -412,6 +486,139 @@ std::string VulkanReplay::DisassembleShader(ResourceId pipeline, const ShaderRef
return disasm;
}
if(target == KHRExecutablePropertiesTarget && vt->GetPipelineExecutablePropertiesKHR)
{
if(pipeline == ResourceId())
{
return "; No pipeline specified, VK_KHR_pipeline_executable_properties disassembly is not "
"available\n"
"; Shader must be disassembled with a specific pipeline.";
}
CachePipelineExecutables(pipeline);
VkShaderStageFlagBits stageBit =
VkShaderStageFlagBits(1 << it->second.m_Reflections[refl->entryPoint.c_str()].stageIndex);
const rdcarray<PipelineExecutables> &executables = m_PipelineExecutables[pipeline];
std::string disasm;
for(const PipelineExecutables &exec : executables)
{
// if this executable is associated with our stage, definitely include it. If this executable
// is associated with *no* stages, then also include it (since we don't know what it
// corresponds to)
if((exec.stages & stageBit) || exec.stages == 0)
{
disasm += "======== " + exec.name + " ========\n\n";
disasm += exec.description + "\n\n";
// statistics first
disasm += StringFormat::Fmt(
"==== Statistics ====\n\n"
"Subgroup Size: %u"
" // the subgroup size with which this executable is dispatched.\n",
exec.subgroupSize);
for(const VkPipelineExecutableStatisticKHR &stat : exec.statistics)
{
std::string value;
switch(stat.format)
{
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR:
value = stat.value.b32 ? "true" : "false";
break;
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR:
value = ToStr(stat.value.i64);
break;
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR:
value = ToStr(stat.value.u64);
break;
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR:
value = ToStr(stat.value.f64);
break;
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_RANGE_SIZE_KHR:
case VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_MAX_ENUM_KHR: value = "???"; break;
}
disasm +=
StringFormat::Fmt("%s: %s // %s\n", stat.name, value.c_str(), stat.description);
}
// then IRs
if(!exec.representations.empty())
disasm += "\n\n==== Internal Representations ====\n\n";
for(const VkPipelineExecutableInternalRepresentationKHR &ir : exec.representations)
{
disasm += "---- " + std::string(ir.name) + " ----\n\n";
disasm += "; " + std::string(ir.description) + "\n\n";
if(ir.isText)
{
char *str = (char *)ir.pData;
// should already be NULL terminated but let's be sure
str[ir.dataSize - 1] = 0;
disasm += str;
}
else
{
// canonical hexdump display
size_t bytesRemaining = ir.dataSize;
size_t offset = 0;
const byte *src = (const byte *)ir.pData;
while(bytesRemaining > 0)
{
uint8_t row[16];
const size_t copySize = RDCMIN(sizeof(row), bytesRemaining);
memcpy(row, src + offset, copySize);
disasm += StringFormat::Fmt("%08zx ", offset);
for(size_t b = 0; b < 16; b++)
{
if(b < bytesRemaining)
disasm += StringFormat::Fmt("%02hhx ", row[b]);
else
disasm += " ";
if(b == 7 || b == 15)
disasm += " ";
}
disasm += "|";
for(size_t b = 0; b < 16; b++)
{
if(b < bytesRemaining)
{
char c = (char)row[b];
if(isprint(c))
disasm.push_back(c);
else
disasm.push_back('.');
}
}
disasm += "|";
disasm += "\n";
offset += copySize;
bytesRemaining -= copySize;
}
disasm += StringFormat::Fmt("%08zx", offset);
}
}
}
}
return disasm;
}
return StringFormat::Fmt("; Invalid disassembly target %s", target.c_str());
}
@@ -3633,6 +3840,13 @@ void VulkanReplay::ReplaceResource(ResourceId from, ResourceId to)
sh.module = dstShaderModule;
}
// if we have pipeline executable properties, capture the data
if(m_pDriver->GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
{
pipeCreateInfo.flags |= (VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR |
VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
}
// create the new graphics pipeline
VkResult vkr = m_pDriver->vkCreateGraphicsPipelines(dev, VK_NULL_HANDLE, 1, &pipeCreateInfo,
NULL, &pipe);
@@ -3648,6 +3862,13 @@ void VulkanReplay::ReplaceResource(ResourceId from, ResourceId to)
RDCASSERT(sh.module == srcShaderModule);
sh.module = dstShaderModule;
// if we have pipeline executable properties, capture the data
if(m_pDriver->GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
{
pipeCreateInfo.flags |= (VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR |
VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
}
// create the new compute pipeline
VkResult vkr = m_pDriver->vkCreateComputePipelines(dev, VK_NULL_HANDLE, 1, &pipeCreateInfo,
NULL, &pipe);
+16
View File
@@ -676,6 +676,22 @@ private:
DriverInformation m_DriverInfo;
struct PipelineExecutables
{
VkShaderStageFlags stages;
rdcstr name, description;
uint32_t subgroupSize;
rdcarray<VkPipelineExecutableStatisticKHR> statistics;
rdcarray<VkPipelineExecutableInternalRepresentationKHR> representations;
// internal data, pointed to from representations above
rdcarray<bytebuf> irbytes;
};
std::map<ResourceId, rdcarray<PipelineExecutables>> m_PipelineExecutables;
void CachePipelineExecutables(ResourceId pipeline);
void CreateTexImageView(VkImage liveIm, const VulkanCreationInfo::Image &iminfo,
CompType typeHint, TextureDisplayViews &views);
+139 -9
View File
@@ -809,6 +809,17 @@ SERIALISE_VK_HANDLES();
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES, \
VkPhysicalDeviceMultiviewProperties) \
\
/* VK_KHR_pipeline_executable_properties */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR, \
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR, VkPipelineInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR, \
VkPipelineExecutablePropertiesKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR, VkPipelineExecutableInfoKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR, VkPipelineExecutableStatisticKHR) \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR, \
VkPipelineExecutableInternalRepresentationKHR) \
\
/* VK_KHR_push_descriptor */ \
PNEXT_STRUCT(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR, \
VkPhysicalDevicePushDescriptorPropertiesKHR) \
@@ -969,14 +980,6 @@ SERIALISE_VK_HANDLES();
/* VK_INTEL_shader_integer_functions2 */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_INTEGER_FUNCTIONS_2_FEATURES_INTEL) \
\
/* VK_KHR_pipeline_executable_properties */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR) \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR) \
\
/* VK_NV_clip_space_w_scaling */ \
PNEXT_UNSUPPORTED(VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV) \
\
@@ -4202,6 +4205,126 @@ void Deserialise(const VkPhysicalDeviceMultiviewProperties &el)
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(pipelineExecutableInfo);
}
template <>
void Deserialise(const VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(pipeline);
}
template <>
void Deserialise(const VkPipelineInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineExecutablePropertiesKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_PROPERTIES_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER_VKFLAGS(VkShaderStageFlags, stages);
SERIALISE_MEMBER(name);
SERIALISE_MEMBER(description);
SERIALISE_MEMBER(subgroupSize);
}
template <>
void Deserialise(const VkPipelineExecutablePropertiesKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineExecutableInfoKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INFO_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(pipeline);
SERIALISE_MEMBER(executableIndex);
}
template <>
void Deserialise(const VkPipelineExecutableInfoKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineExecutableStatisticValueKHR &el)
{
SERIALISE_MEMBER(b32);
SERIALISE_MEMBER(i64);
SERIALISE_MEMBER(u64);
SERIALISE_MEMBER(f64);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineExecutableStatisticKHR &el)
{
RDCASSERT(ser.IsReading() || el.sType == VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_STATISTIC_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(name);
SERIALISE_MEMBER(description);
SERIALISE_MEMBER(format);
SERIALISE_MEMBER(value);
}
template <>
void Deserialise(const VkPipelineExecutableStatisticKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPipelineExecutableInternalRepresentationKHR &el)
{
RDCASSERT(ser.IsReading() ||
el.sType == VK_STRUCTURE_TYPE_PIPELINE_EXECUTABLE_INTERNAL_REPRESENTATION_KHR);
SerialiseNext(ser, el.sType, el.pNext);
SERIALISE_MEMBER(name);
SERIALISE_MEMBER(description);
SERIALISE_MEMBER(isText);
// don't serialise size_t, otherwise capture/replay between different bit-ness won't work
{
uint64_t dataSize = el.dataSize;
ser.Serialise("dataSize"_lit, dataSize);
if(ser.IsReading())
el.dataSize = (size_t)dataSize;
}
SERIALISE_MEMBER_ARRAY(pData, dataSize);
}
template <>
void Deserialise(const VkPipelineExecutableInternalRepresentationKHR &el)
{
DeserialiseNext(el.pNext);
}
template <typename SerialiserType>
void DoSerialise(SerialiserType &ser, VkPhysicalDevicePushDescriptorPropertiesKHR &el)
{
@@ -7148,6 +7271,7 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryProperties2);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMultiviewFeatures);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMultiviewProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePCIBusInfoPropertiesEXT);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDevicePointClippingProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProperties2);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProtectedMemoryFeatures);
@@ -7182,6 +7306,11 @@ INSTANTIATE_SERIALISE_TYPE(VkPipelineCreationFeedbackCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineDepthStencilStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineDiscardRectangleStateCreateInfoEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineDynamicStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableInternalRepresentationKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutablePropertiesKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableStatisticKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineInfoKHR);
INSTANTIATE_SERIALISE_TYPE(VkPipelineInputAssemblyStateCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineLayoutCreateInfo);
INSTANTIATE_SERIALISE_TYPE(VkPipelineMultisampleStateCreateInfo);
@@ -7289,8 +7418,9 @@ INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceLimits);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceMemoryProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceProperties);
INSTANTIATE_SERIALISE_TYPE(VkPhysicalDeviceSparseProperties);
INSTANTIATE_SERIALISE_TYPE(VkPipelineCreationFeedbackEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineColorBlendAttachmentState);
INSTANTIATE_SERIALISE_TYPE(VkPipelineCreationFeedbackEXT);
INSTANTIATE_SERIALISE_TYPE(VkPipelineExecutableStatisticValueKHR);
INSTANTIATE_SERIALISE_TYPE(VkPresentRegionKHR);
INSTANTIATE_SERIALISE_TYPE(VkPushConstantRange);
INSTANTIATE_SERIALISE_TYPE(VkQueueFamilyProperties);
+13
View File
@@ -2572,6 +2572,19 @@ rdcstr DoStringise(const VkShaderFloatControlsIndependenceKHR &el)
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const VkPipelineExecutableStatisticFormatKHR &el)
{
BEGIN_ENUM_STRINGISE(VkPipelineExecutableStatisticFormatKHR);
{
STRINGISE_ENUM(VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_BOOL32_KHR);
STRINGISE_ENUM(VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_INT64_KHR);
STRINGISE_ENUM(VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_UINT64_KHR);
STRINGISE_ENUM(VK_PIPELINE_EXECUTABLE_STATISTIC_FORMAT_FLOAT64_KHR);
}
END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const VkExtent3D &el)
{
@@ -1427,6 +1427,18 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
RDCLOG("Enabling VK_KHR_driver_properties");
}
bool pipeExec = false;
// enable VK_KHR_pipeline_executable_properties if it's available, to fetch disassembly and
// statistics
if(supportedExtensions.find(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME) !=
supportedExtensions.end())
{
pipeExec = true;
Extensions.push_back(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME);
RDCLOG("Enabling VK_KHR_pipeline_executable_properties");
}
bool xfb = false;
// enable VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME if it's available, to fetch mesh output in
@@ -2127,6 +2139,14 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
CHECK_PHYS_EXT_FEATURE(computeFullSubgroups);
}
END_PHYS_EXT_CHECK();
BEGIN_PHYS_EXT_CHECK(
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR);
{
CHECK_PHYS_EXT_FEATURE(pipelineExecutableInfo);
}
END_PHYS_EXT_CHECK();
}
if(availFeatures.depthClamp)
@@ -2243,6 +2263,51 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
SAFE_DELETE_ARRAY(exts);
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR pipeExecFeatures = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR,
};
if(pipeExec)
{
VkPhysicalDeviceFeatures2 availBase = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2};
availBase.pNext = &pipeExecFeatures;
ObjDisp(physicalDevice)->GetPhysicalDeviceFeatures2(Unwrap(physicalDevice), &availBase);
if(pipeExecFeatures.pipelineExecutableInfo)
{
// see if there's an existing struct
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *existing =
(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)FindNextStruct(
&createInfo,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR);
if(existing)
{
// if so, make sure the feature is enabled
existing->pipelineExecutableInfo = VK_TRUE;
}
else
{
// otherwise, add our own, and push it onto the pNext array
pipeExecFeatures.pipelineExecutableInfo = VK_TRUE;
pipeExecFeatures.pNext = (void *)createInfo.pNext;
createInfo.pNext = &pipeExecFeatures;
}
}
else
{
RDCWARN(
"VK_KHR_pipeline_executable_properties is available, but the physical device feature "
"is not. Disabling");
auto it = std::find(Extensions.begin(), Extensions.end(),
VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME);
RDCASSERT(it != Extensions.end());
Extensions.erase(it);
}
}
VkPhysicalDeviceTransformFeedbackFeaturesEXT xfbFeatures = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT,
};
@@ -728,4 +728,35 @@ VkDeviceAddress WrappedVulkan::vkGetBufferDeviceAddressEXT(VkDevice device,
VkBufferDeviceAddressInfoEXT unwrappedInfo = *pInfo;
unwrappedInfo.buffer = Unwrap(unwrappedInfo.buffer);
return ObjDisp(device)->GetBufferDeviceAddressEXT(Unwrap(device), &unwrappedInfo);
}
VkResult WrappedVulkan::vkGetPipelineExecutablePropertiesKHR(
VkDevice device, const VkPipelineInfoKHR *pPipelineInfo, uint32_t *pExecutableCount,
VkPipelineExecutablePropertiesKHR *pProperties)
{
VkPipelineInfoKHR unwrappedInfo = *pPipelineInfo;
unwrappedInfo.pipeline = Unwrap(unwrappedInfo.pipeline);
return ObjDisp(device)->GetPipelineExecutablePropertiesKHR(Unwrap(device), &unwrappedInfo,
pExecutableCount, pProperties);
}
VkResult WrappedVulkan::vkGetPipelineExecutableStatisticsKHR(
VkDevice device, const VkPipelineExecutableInfoKHR *pExecutableInfo, uint32_t *pStatisticCount,
VkPipelineExecutableStatisticKHR *pStatistics)
{
VkPipelineExecutableInfoKHR unwrappedInfo = *pExecutableInfo;
unwrappedInfo.pipeline = Unwrap(unwrappedInfo.pipeline);
return ObjDisp(device)->GetPipelineExecutableStatisticsKHR(Unwrap(device), &unwrappedInfo,
pStatisticCount, pStatistics);
}
VkResult WrappedVulkan::vkGetPipelineExecutableInternalRepresentationsKHR(
VkDevice device, const VkPipelineExecutableInfoKHR *pExecutableInfo,
uint32_t *pInternalRepresentationCount,
VkPipelineExecutableInternalRepresentationKHR *pInternalRepresentations)
{
VkPipelineExecutableInfoKHR unwrappedInfo = *pExecutableInfo;
unwrappedInfo.pipeline = Unwrap(unwrappedInfo.pipeline);
return ObjDisp(device)->GetPipelineExecutableInternalRepresentationsKHR(
Unwrap(device), &unwrappedInfo, pInternalRepresentationCount, pInternalRepresentations);
}
@@ -421,6 +421,13 @@ bool WrappedVulkan::Serialise_vkCreateGraphicsPipelines(
// don't use pipeline caches on replay
pipelineCache = VK_NULL_HANDLE;
// if we have pipeline executable properties, capture the data
if(GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
{
CreateInfo.flags |= (VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR |
VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
}
VkGraphicsPipelineCreateInfo *unwrapped = UnwrapInfos(&CreateInfo, 1);
VkResult ret = ObjDisp(device)->CreateGraphicsPipelines(Unwrap(device), Unwrap(pipelineCache),
1, unwrapped, NULL, &pipe);
@@ -614,6 +621,13 @@ bool WrappedVulkan::Serialise_vkCreateComputePipelines(SerialiserType &ser, VkDe
// don't use pipeline caches on replay
pipelineCache = VK_NULL_HANDLE;
// if we have pipeline executable properties, capture the data
if(GetExtensions(NULL).ext_KHR_pipeline_executable_properties)
{
CreateInfo.flags |= (VK_PIPELINE_CREATE_CAPTURE_STATISTICS_BIT_KHR |
VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
}
VkComputePipelineCreateInfo *unwrapped = UnwrapInfos(&CreateInfo, 1);
VkResult ret = ObjDisp(device)->CreateComputePipelines(Unwrap(device), Unwrap(pipelineCache), 1,
unwrapped, NULL, &pipe);