From e0bbed0b3413eb58b0f992a3178d3d1d27b8a37d Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 17 Dec 2015 11:09:58 +0100 Subject: [PATCH] Pass shader specialization data to pipeline state (just data, not in UI) --- renderdoc/api/replay/vk_pipestate.h | 7 ++++- renderdoc/driver/vulkan/vk_info.cpp | 32 ++++++++++++++++++++++ renderdoc/driver/vulkan/vk_info.h | 9 ++++++ renderdoc/driver/vulkan/vk_replay.cpp | 7 +++++ renderdocui/Interop/VulkanPipelineState.cs | 10 +++++++ 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/renderdoc/api/replay/vk_pipestate.h b/renderdoc/api/replay/vk_pipestate.h index d13ab300f..30720923b 100644 --- a/renderdoc/api/replay/vk_pipestate.h +++ b/renderdoc/api/replay/vk_pipestate.h @@ -141,7 +141,12 @@ struct VulkanPipelineState ShaderStageType stage; - // VKTODOMED specialization info + struct SpecInfo + { + uint32_t specID; + rdctype::array data; + }; + rdctype::array specialization; } VS, TCS, TES, GS, FS, CS; struct Tessellation diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index efb8670a2..9af0d0e2b 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -93,6 +93,22 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); } + if(pCreateInfo->pStages[i].pSpecializationInfo) + { + shad.specdata.resize(pCreateInfo->pStages[i].pSpecializationInfo->dataSize); + memcpy(&shad.specdata[0], pCreateInfo->pStages[i].pSpecializationInfo->pData, shad.specdata.size()); + + const VkSpecializationMapEntry *maps = pCreateInfo->pStages[i].pSpecializationInfo->pMapEntries; + for(uint32_t s=0; s < pCreateInfo->pStages[i].pSpecializationInfo->mapEntryCount; s++) + { + Shader::SpecInfo spec; + spec.specID = maps[s].constantID; + spec.data = &shad.specdata[maps[s].offset]; + // ignore maps[s].size, assume it's enough for the type + shad.specialization.push_back(spec); + } + } + shad.refl = &reflData.refl; shad.mapping = &reflData.mapping; } @@ -224,6 +240,22 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk info.m_ShaderModule[id].spirv.MakeReflection(reflData.entryPoint, &reflData.refl, &reflData.mapping); } + if(pCreateInfo->stage.pSpecializationInfo) + { + shad.specdata.resize(pCreateInfo->stage.pSpecializationInfo->dataSize); + memcpy(&shad.specdata[0], pCreateInfo->stage.pSpecializationInfo->pData, shad.specdata.size()); + + const VkSpecializationMapEntry *maps = pCreateInfo->stage.pSpecializationInfo->pMapEntries; + for(uint32_t s=0; s < pCreateInfo->stage.pSpecializationInfo->mapEntryCount; s++) + { + Shader::SpecInfo spec; + spec.specID = maps[s].constantID; + spec.data = &shad.specdata[maps[s].offset]; + spec.size = maps[s].size; + shad.specialization.push_back(spec); + } + } + shad.refl = &reflData.refl; shad.mapping = &reflData.mapping; } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index f0ca5625c..5c9fb3348 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -74,6 +74,15 @@ struct VulkanCreationInfo string entryPoint; ShaderReflection *refl; ShaderBindpointMapping *mapping; + + vector specdata; + struct SpecInfo + { + uint32_t specID; + byte *data; + size_t size; + }; + vector specialization; }; Shader shaders[6]; diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index f766e7982..94cc26bb7 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -2710,6 +2710,13 @@ void VulkanReplay::SavePipelineState() stages[i]->stage = ShaderStageType(eShaderStage_Vertex + i); if(p.shaders[i].mapping) stages[i]->BindpointMapping = *p.shaders[i].mapping; + + create_array_uninit(stages[i]->specialization, p.shaders[i].specialization.size()); + for(size_t s=0; s < p.shaders[i].specialization.size(); s++) + { + stages[i]->specialization[s].specID = p.shaders[i].specialization[s].specID; + create_array_init(stages[i]->specialization[s].data, p.shaders[i].specialization[s].size, p.shaders[i].specialization[s].data); + } } // Tessellation diff --git a/renderdocui/Interop/VulkanPipelineState.cs b/renderdocui/Interop/VulkanPipelineState.cs index e13f349ca..c6d2d415e 100644 --- a/renderdocui/Interop/VulkanPipelineState.cs +++ b/renderdocui/Interop/VulkanPipelineState.cs @@ -182,6 +182,16 @@ namespace renderdoc public ShaderBindpointMapping BindpointMapping; public ShaderStageType stage; + + [StructLayout(LayoutKind.Sequential)] + struct SpecInfo + { + public UInt32 specID; + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + public byte[] data; + }; + [CustomMarshalAs(CustomUnmanagedType.TemplatedArray)] + SpecInfo[] specialization; }; [CustomMarshalAs(CustomUnmanagedType.CustomClass)] public ShaderStage VS, TCS, TES, GS, FS, CS;