diff --git a/renderdoc/driver/vulkan/vk_core.h b/renderdoc/driver/vulkan/vk_core.h index 0990d4e4f..1dd614ebb 100644 --- a/renderdoc/driver/vulkan/vk_core.h +++ b/renderdoc/driver/vulkan/vk_core.h @@ -36,8 +36,6 @@ #include "vk_manager.h" #include "vk_replay.h" -#include "driver/shaders/spirv/spirv_common.h" - using std::vector; using std::list; @@ -372,34 +370,21 @@ private: vector currentBindings; }; - struct ShaderModuleInfo - { - SPVModule spirv; - ShaderReflection reflTemplate; - ShaderBindpointMapping mapping; - }; - - struct ShaderInfo - { - ResourceId module; - ShaderReflection refl; - ShaderBindpointMapping mapping; - }; - // VKTODO all these m_*Info things need to be locked and ensure we only access // them in slow path functions like creation, or just moved elsewhere like inside // the wrapped objects // VKTODOHIGH all of these need to be locked map m_MemoryInfo; map m_ImageInfo; - map m_BufferMemBinds; - map m_ObjectNames; map m_CmdBufferInfo; map m_SwapChainInfo; - map m_DescriptorSetInfo; - map m_ShaderModuleInfo; - map m_ShaderInfo; + // READING only + map m_BufferMemBinds; + map m_ObjectNames; + map m_DescriptorSetInfo; + + // only used in replay side, so doesn't need to be thread protected VulkanCreationInfo m_CreationInfo; static const char *GetChunkName(uint32_t idx); diff --git a/renderdoc/driver/vulkan/vk_info.cpp b/renderdoc/driver/vulkan/vk_info.cpp index caf423205..c0fc2ea1f 100644 --- a/renderdoc/driver/vulkan/vk_info.cpp +++ b/renderdoc/driver/vulkan/vk_info.cpp @@ -24,6 +24,35 @@ #include "vk_info.h" +void DescSetLayout::Init(const VkDescriptorSetLayoutCreateInfo* pCreateInfo) +{ + bindings.resize(pCreateInfo->count); + for(uint32_t i=0; i < pCreateInfo->count; i++) + { + bindings[i].arraySize = pCreateInfo->pBinding[i].arraySize; + bindings[i].descriptorType = pCreateInfo->pBinding[i].descriptorType; + bindings[i].stageFlags = pCreateInfo->pBinding[i].stageFlags; + + if(pCreateInfo->pBinding[i].pImmutableSamplers) + { + bindings[i].immutableSampler = new ResourceId[bindings[i].arraySize]; + + for(uint32_t s=0; s < bindings[i].arraySize; s++) + bindings[i].immutableSampler[s] = VKMGR()->GetNonDispWrapper(pCreateInfo->pBinding[i].pImmutableSamplers[s])->id; + } + } +} + +void DescSetLayout::CreateBindingsArray(vector &descBindings) +{ + descBindings.resize(bindings.size()); + for(size_t i=0; i < bindings.size(); i++) + { + descBindings[i] = new VkDescriptorInfo[bindings[i].arraySize]; + memset(descBindings[i], 0, sizeof(VkDescriptorInfo)*bindings[i].arraySize); + } +} + void VulkanCreationInfo::Pipeline::Init(const VkGraphicsPipelineCreateInfo* pCreateInfo) { flags = pCreateInfo->flags; @@ -224,31 +253,20 @@ void VulkanCreationInfo::ImageView::Init(const VkImageViewCreateInfo* pCreateInf image = VKMGR()->GetNonDispWrapper(pCreateInfo->image)->id; } -void VulkanCreationInfo::DescSetLayout::Init(const VkDescriptorSetLayoutCreateInfo* pCreateInfo) +void VulkanCreationInfo::ShaderModule::Init(const VkShaderModuleCreateInfo* pCreateInfo) { - bindings.resize(pCreateInfo->count); - for(uint32_t i=0; i < pCreateInfo->count; i++) - { - bindings[i].arraySize = pCreateInfo->pBinding[i].arraySize; - bindings[i].descriptorType = pCreateInfo->pBinding[i].descriptorType; - bindings[i].stageFlags = pCreateInfo->pBinding[i].stageFlags; + RDCASSERT(pCreateInfo->codeSize % sizeof(uint32_t) == 0); + ParseSPIRV((uint32_t *)pCreateInfo->pCode, pCreateInfo->codeSize/sizeof(uint32_t), spirv); - if(pCreateInfo->pBinding[i].pImmutableSamplers) - { - bindings[i].immutableSampler = new ResourceId[bindings[i].arraySize]; - - for(uint32_t s=0; s < bindings[i].arraySize; s++) - bindings[i].immutableSampler[s] = VKMGR()->GetNonDispWrapper(pCreateInfo->pBinding[i].pImmutableSamplers[s])->id; - } - } + spirv.MakeReflection(&reflTemplate, &mapping); } -void VulkanCreationInfo::DescSetLayout::CreateBindingsArray(vector &descBindings) +void VulkanCreationInfo::Shader::Init(const VkShaderCreateInfo* pCreateInfo, VulkanCreationInfo::ShaderModule &moduleinfo) { - descBindings.resize(bindings.size()); - for(size_t i=0; i < bindings.size(); i++) - { - descBindings[i] = new VkDescriptorInfo[bindings[i].arraySize]; - memset(descBindings[i], 0, sizeof(VkDescriptorInfo)*bindings[i].arraySize); - } + module = VKMGR()->GetNonDispWrapper(pCreateInfo->module)->id; + mapping = moduleinfo.mapping; + refl = moduleinfo.reflTemplate; + refl.DebugInfo.entryFunc = pCreateInfo->pName; + // VKTODOLOW set this properly + refl.DebugInfo.entryFile = 0; } diff --git a/renderdoc/driver/vulkan/vk_info.h b/renderdoc/driver/vulkan/vk_info.h index 8a8342f40..4383835e0 100644 --- a/renderdoc/driver/vulkan/vk_info.h +++ b/renderdoc/driver/vulkan/vk_info.h @@ -27,6 +27,26 @@ #include "vk_common.h" #include "vk_manager.h" +#include "driver/shaders/spirv/spirv_common.h" + +struct DescSetLayout +{ + void Init(const VkDescriptorSetLayoutCreateInfo* pCreateInfo); + + void CreateBindingsArray(vector &descBindings); + + struct Binding + { + Binding() : immutableSampler(NULL) {} + ~Binding() { SAFE_DELETE_ARRAY(immutableSampler); } + + VkDescriptorType descriptorType; + uint32_t arraySize; + VkShaderStageFlags stageFlags; + ResourceId *immutableSampler; + }; + vector bindings; +}; struct VulkanCreationInfo { struct Pipeline @@ -168,23 +188,25 @@ struct VulkanCreationInfo }; map m_ImageView; - struct DescSetLayout - { - void Init(const VkDescriptorSetLayoutCreateInfo* pCreateInfo); - - void CreateBindingsArray(vector &descBindings); - - struct Binding - { - Binding() : immutableSampler(NULL) {} - ~Binding() { SAFE_DELETE_ARRAY(immutableSampler); } - - VkDescriptorType descriptorType; - uint32_t arraySize; - VkShaderStageFlags stageFlags; - ResourceId *immutableSampler; - }; - vector bindings; - }; map m_DescSetLayout; + + struct ShaderModule + { + void Init(const VkShaderModuleCreateInfo* pCreateInfo); + + SPVModule spirv; + ShaderReflection reflTemplate; + ShaderBindpointMapping mapping; + }; + map m_ShaderModule; + + struct Shader + { + void Init(const VkShaderCreateInfo* pCreateInfo, VulkanCreationInfo::ShaderModule &moduleinfo); + + ResourceId module; + ShaderReflection refl; + ShaderBindpointMapping mapping; + }; + map m_Shader; }; diff --git a/renderdoc/driver/vulkan/vk_initstate.cpp b/renderdoc/driver/vulkan/vk_initstate.cpp index 48b11c232..f9e75ba20 100644 --- a/renderdoc/driver/vulkan/vk_initstate.cpp +++ b/renderdoc/driver/vulkan/vk_initstate.cpp @@ -33,7 +33,8 @@ bool WrappedVulkan::Prepare_InitialState(WrappedVkRes *res) if(type == eResDescriptorSet) { VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[record->layout]; + RDCASSERT(record->layout); + const DescSetLayout &layout = *record->layout; uint32_t numElems = 0; for(size_t i=0; i < layout.bindings.size(); i++) @@ -173,7 +174,8 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) if(type == eResDescriptorSet) { VkResourceRecord *record = GetResourceManager()->GetResourceRecord(id); - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[record->layout]; + RDCASSERT(record->layout); + const DescSetLayout &layout = *record->layout; VkDescriptorInfo *info = (VkDescriptorInfo *)initContents.blob; @@ -212,7 +214,7 @@ bool WrappedVulkan::Serialise_InitialState(WrappedVkRes *res) m_pSerialiser->SerialiseComplexArray("Bindings", bindings, numElems); - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[ m_DescriptorSetInfo[id].layout ]; + const DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[ m_DescriptorSetInfo[id].layout ]; uint32_t numBinds = (uint32_t)layout.bindings.size(); diff --git a/renderdoc/driver/vulkan/vk_replay.cpp b/renderdoc/driver/vulkan/vk_replay.cpp index 94dfcd085..ab5cef1cb 100644 --- a/renderdoc/driver/vulkan/vk_replay.cpp +++ b/renderdoc/driver/vulkan/vk_replay.cpp @@ -1392,24 +1392,26 @@ FetchBuffer VulkanReplay::GetBuffer(ResourceId id) ShaderReflection *VulkanReplay::GetShader(ResourceId id) { - auto it = m_pDriver->m_ShaderInfo.find(id); + auto shad = m_pDriver->m_CreationInfo.m_Shader.find(m_pDriver->GetResourceManager()->GetOriginalID(id)); - if(it == m_pDriver->m_ShaderInfo.end()) + if(shad == m_pDriver->m_CreationInfo.m_Shader.end()) { RDCERR("Can't get shader details"); return NULL; } // disassemble lazily on demand - if(it->second.refl.Disassembly.count == 0) + if(shad->second.refl.Disassembly.count == 0) { - if(m_pDriver->m_ShaderModuleInfo[it->second.module].spirv.m_Disassembly.empty()) - m_pDriver->m_ShaderModuleInfo[it->second.module].spirv.Disassemble(); + auto &shadmod = m_pDriver->m_CreationInfo.m_ShaderModule[m_pDriver->GetResourceManager()->GetOriginalID(shad->second.module)]; - it->second.refl.Disassembly = m_pDriver->m_ShaderModuleInfo[it->second.module].spirv.m_Disassembly; + if(shadmod.spirv.m_Disassembly.empty()) + shadmod.spirv.Disassemble(); + + shad->second.refl.Disassembly = shadmod.spirv.m_Disassembly; } - return &it->second.refl; + return &shad->second.refl; } void VulkanReplay::SavePipelineState() @@ -1484,7 +1486,7 @@ void VulkanReplay::SavePipelineState() stages[i]->customName = false; stages[i]->ShaderName = StringFormat::Fmt("Shader %llu", stages[i]->Shader); stages[i]->stage = ShaderStageType(eShaderStage_Vertex + i); - stages[i]->BindpointMapping = m_pDriver->m_ShaderInfo[p.shaders[i]].mapping; + stages[i]->BindpointMapping = m_pDriver->m_CreationInfo.m_Shader[stages[i]->Shader].mapping; } // Descriptor sets @@ -1515,7 +1517,7 @@ void VulkanReplay::SavePipelineState() for(size_t b=0; b < m_pDriver->m_DescriptorSetInfo[src].currentBindings.size(); b++) { VkDescriptorInfo *info = m_pDriver->m_DescriptorSetInfo[src].currentBindings[b]; - const VulkanCreationInfo::DescSetLayout::Binding &layoutBind = c.m_DescSetLayout[dst.layout].bindings[b]; + const DescSetLayout::Binding &layoutBind = c.m_DescSetLayout[dst.layout].bindings[b]; dst.bindings[b].arraySize = layoutBind.arraySize; dst.bindings[b].stageFlags = (ShaderStageBits)layoutBind.stageFlags; @@ -1957,9 +1959,9 @@ void VulkanReplay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, ve // Correct SPIR-V will ultimately need to set explicit layout information for each type. // For now, just assume D3D11 packing (float4 alignment on float4s, float3s, matrices, arrays and structures) - auto it = m_pDriver->m_ShaderInfo.find(shader); + auto it = m_pDriver->m_CreationInfo.m_Shader.find(m_pDriver->GetResourceManager()->GetOriginalID(shader)); - if(it == m_pDriver->m_ShaderInfo.end()) + if(it == m_pDriver->m_CreationInfo.m_Shader.end()) { RDCERR("Can't get shader details"); return; diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 2e672a4b7..847a2ee4f 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -23,6 +23,7 @@ ******************************************************************************/ #include "vk_resources.h" +#include "vk_info.h" WRAPPED_POOL_INST(WrappedVkInstance) WRAPPED_POOL_INST(WrappedVkPhysicalDevice) @@ -477,3 +478,12 @@ uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat F return ret; } + +VkResourceRecord::~VkResourceRecord() +{ + for(size_t i=0; i < descBindings.size(); i++) + delete[] descBindings[i]; + descBindings.clear(); + + SAFE_DELETE(layout); +} diff --git a/renderdoc/driver/vulkan/vk_resources.h b/renderdoc/driver/vulkan/vk_resources.h index ffe37c034..afd5a3c0c 100644 --- a/renderdoc/driver/vulkan/vk_resources.h +++ b/renderdoc/driver/vulkan/vk_resources.h @@ -549,6 +549,8 @@ inline bool operator <(const VkDescriptorSet a, const VkDescriptorSet b) return a.handle < b.handle; } +struct DescSetLayout; + struct VkResourceRecord : public ResourceRecord { public: @@ -558,16 +560,12 @@ struct VkResourceRecord : public ResourceRecord ResourceRecord(id, true), bakedCommands(NULL), pool(NULL), - memory(NULL) + memory(NULL), + layout(NULL) { } - ~VkResourceRecord() - { - for(size_t i=0; i < descBindings.size(); i++) - delete[] descBindings[i]; - descBindings.clear(); - } + ~VkResourceRecord(); void Bake() { @@ -651,7 +649,7 @@ struct VkResourceRecord : public ResourceRecord // descriptor set bindings for this descriptor set. Filled out on // create from the layout. - ResourceId layout; + DescSetLayout *layout; vector descBindings; // contains the framerefs (ref counted) for the bound resources diff --git a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp index d4ca55f36..123bb650d 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_cmd_funcs.cpp @@ -926,7 +926,7 @@ bool WrappedVulkan::Serialise_vkCmdBindDescriptorSets( // and in array element order within a binding for(uint32_t i=0; i < numSets; i++) { - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[descriptorIDs[i]]; + const DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[descriptorIDs[i]]; for(size_t b=0; b < layout.bindings.size(); b++) { diff --git a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp index 6fdc39dbf..e1b55bddf 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_descriptor_funcs.cpp @@ -102,15 +102,13 @@ bool WrappedVulkan::Serialise_vkCreateDescriptorSetLayout( SERIALISE_ELEMENT(VkDescriptorSetLayoutCreateInfo, info, *pCreateInfo); SERIALISE_ELEMENT(ResourceId, id, GetResID(*pSetLayout)); - // this creation info is needed at capture time (for creating/updating descriptor set bindings) - // uses original ID in replay - m_CreationInfo.m_DescSetLayout[id].Init(&info); - if(m_State == READING) { VkDescriptorSetLayout layout = VK_NULL_HANDLE; device = GetResourceManager()->GetLiveHandle(devId); + + m_CreationInfo.m_DescSetLayout[id].Init(&info); VkResult ret = ObjDisp(device)->CreateDescriptorSetLayout(Unwrap(device), &info, &layout); @@ -180,6 +178,9 @@ VkResult WrappedVulkan::vkCreateDescriptorSetLayout( VkResourceRecord *record = GetResourceManager()->AddResourceRecord(*pSetLayout); record->AddChunk(chunk); + + record->layout = new DescSetLayout(); + record->layout->Init(pCreateInfo); } else { @@ -268,6 +269,7 @@ VkResult WrappedVulkan::vkAllocDescriptorSets( record->AddChunk(chunk); ResourceId layoutID = GetResID(pSetLayouts[i]); + VkResourceRecord *layoutRecord = GetRecord(pSetLayouts[i]); VkResourceRecord *poolrecord = GetRecord(descriptorPool); @@ -291,8 +293,9 @@ VkResult WrappedVulkan::vkAllocDescriptorSets( GetResourceManager()->MarkPendingDirty(id); } - record->layout = layoutID; - m_CreationInfo.m_DescSetLayout[layoutID].CreateBindingsArray(record->descBindings); + record->layout = new DescSetLayout(); + *record->layout = *layoutRecord->layout; + record->layout->CreateBindingsArray(record->descBindings); } else { @@ -563,7 +566,8 @@ void WrappedVulkan::vkUpdateDescriptorSets( for(uint32_t i=0; i < writeCount; i++) { VkResourceRecord *record = GetRecord(pDescriptorWrites[i].destSet); - const VulkanCreationInfo::DescSetLayout &layout = m_CreationInfo.m_DescSetLayout[record->layout]; + RDCASSERT(record->layout); + const DescSetLayout &layout = *record->layout; RDCASSERT(pDescriptorWrites[i].destBinding < record->descBindings.size()); diff --git a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp index 686565146..b921fbd83 100644 --- a/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp +++ b/renderdoc/driver/vulkan/wrappers/vk_shader_funcs.cpp @@ -122,6 +122,8 @@ bool WrappedVulkan::Serialise_vkCreateShaderModule( device = GetResourceManager()->GetLiveHandle(devId); VkShaderModule sh = VK_NULL_HANDLE; + m_CreationInfo.m_ShaderModule[id].Init(&info); + VkResult ret = ObjDisp(device)->CreateShaderModule(Unwrap(device), &info, &sh); if(ret != VK_SUCCESS) @@ -132,11 +134,6 @@ bool WrappedVulkan::Serialise_vkCreateShaderModule( { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), sh); GetResourceManager()->AddLiveResource(id, sh); - - RDCASSERT(info.codeSize % sizeof(uint32_t) == 0); - ParseSPIRV((uint32_t *)info.pCode, info.codeSize/sizeof(uint32_t), m_ShaderModuleInfo[live].spirv); - - m_ShaderModuleInfo[live].spirv.MakeReflection(&m_ShaderModuleInfo[live].reflTemplate, &m_ShaderModuleInfo[live].mapping); } } @@ -196,6 +193,9 @@ bool WrappedVulkan::Serialise_vkCreateShader( VkResult ret = ObjDisp(device)->CreateShader(Unwrap(device), &info, &sh); + ResourceId moduleid = GetResourceManager()->GetNonDispWrapper(info.module)->id; + m_CreationInfo.m_Shader[id].Init(&info, m_CreationInfo.m_ShaderModule[GetResourceManager()->GetOriginalID(moduleid)]); + if(ret != VK_SUCCESS) { RDCERR("Failed on resource serialise-creation, VkResult: 0x%08x", ret); @@ -204,13 +204,6 @@ bool WrappedVulkan::Serialise_vkCreateShader( { ResourceId live = GetResourceManager()->WrapResource(Unwrap(device), sh); GetResourceManager()->AddLiveResource(id, sh); - - m_ShaderInfo[live].module = GetResourceManager()->GetNonDispWrapper(info.module)->id; - m_ShaderInfo[live].mapping = m_ShaderModuleInfo[m_ShaderInfo[live].module].mapping; - m_ShaderInfo[live].refl = m_ShaderModuleInfo[m_ShaderInfo[live].module].reflTemplate; - m_ShaderInfo[live].refl.DebugInfo.entryFunc = info.pName; - // VKTODOLOW set this properly - m_ShaderInfo[live].refl.DebugInfo.entryFile = 0; } }