From 904511afb09a74604ac118cf0f416a79d1a7139e Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 24 Jan 2018 18:44:15 +0000 Subject: [PATCH] Support composite types on vertex shader inputs, in vulkan PostVS fetch --- renderdoc/driver/shaders/spirv/spirv_common.h | 11 ++++--- .../shaders/spirv/spirv_disassemble.cpp | 32 +++++++++++++++---- renderdoc/driver/vulkan/vk_postvs.cpp | 26 +++++++++++++-- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/renderdoc/driver/shaders/spirv/spirv_common.h b/renderdoc/driver/shaders/spirv/spirv_common.h index a9eeee2b5..3f6bdf1a9 100644 --- a/renderdoc/driver/shaders/spirv/spirv_common.h +++ b/renderdoc/driver/shaders/spirv/spirv_common.h @@ -78,21 +78,22 @@ ShaderBuiltin BuiltInToSystemAttribute(ShaderStage stage, const spv::BuiltIn el) // patching struct SPIRVPatchData { - struct OutputAccess + struct InterfaceAccess { - // ID of the base output variable + // ID of the base variable uint32_t ID; // the access chain of indices std::vector accessChain; - // is this output part of a matrix + // is this input/output part of a matrix bool isMatrix = false; }; - // matches the output signature array, with details of where to fetch the output from in the + // matches the input/output signature array, with details of where to fetch the output from in the // SPIR-V. - std::vector outputs; + std::vector inputs; + std::vector outputs; }; struct SPVModule diff --git a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp index 21ad498f3..1d215ae6b 100644 --- a/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp +++ b/renderdoc/driver/shaders/spirv/spirv_disassemble.cpp @@ -3710,7 +3710,7 @@ void AddSignatureParameter(bool isInput, ShaderStage stage, uint32_t id, uint32_ sig.needSemanticIndex = false; - SPIRVPatchData::OutputAccess patch; + SPIRVPatchData::InterfaceAccess patch; patch.accessChain = accessChain; patch.ID = id; @@ -3843,7 +3843,9 @@ void AddSignatureParameter(bool isInput, ShaderStage stage, uint32_t id, uint32_ regIndex++; - if(!isInput) + if(isInput) + patchData.inputs.push_back(patch); + else patchData.outputs.push_back(patch); } else @@ -3862,7 +3864,9 @@ void AddSignatureParameter(bool isInput, ShaderStage stage, uint32_t id, uint32_ sigarray.push_back(s); - if(!isInput) + if(isInput) + patchData.inputs.push_back(patch); + else patchData.outputs.push_back(patch); regIndex++; @@ -4012,8 +4016,16 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint, { sigarray->pop_back(); - if(patchData.outputs.size() > sigarray->size()) - patchData.outputs.pop_back(); + if(isInput) + { + if(patchData.inputs.size() > sigarray->size()) + patchData.inputs.pop_back(); + } + else + { + if(patchData.outputs.size() > sigarray->size()) + patchData.outputs.pop_back(); + } } } @@ -4086,7 +4098,9 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint, if((*sigarray)[s].systemValue == attr) { sigarray->erase(sigarray->begin() + s); - if(!isInput) + if(isInput) + patchData.inputs.erase(patchData.inputs.begin() + s); + else patchData.outputs.erase(patchData.outputs.begin() + s); break; } @@ -4435,6 +4449,10 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint, reflection.inputSignature.reserve(inputs.size()); for(size_t i = 0; i < inputs.size(); i++) reflection.inputSignature.push_back(inputs[indices[i]]); + + std::vector inPatch = patchData.inputs; + for(size_t i = 0; i < inputs.size(); i++) + patchData.inputs[i] = inPatch[indices[i]]; } { @@ -4448,7 +4466,7 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint, for(size_t i = 0; i < outputs.size(); i++) reflection.outputSignature.push_back(outputs[indices[i]]); - std::vector outPatch = patchData.outputs; + std::vector outPatch = patchData.outputs; for(size_t i = 0; i < outputs.size(); i++) patchData.outputs[i] = outPatch[indices[i]]; } diff --git a/renderdoc/driver/vulkan/vk_postvs.cpp b/renderdoc/driver/vulkan/vk_postvs.cpp index 180dfe31b..aaf8e9ff3 100644 --- a/renderdoc/driver/vulkan/vk_postvs.cpp +++ b/renderdoc/driver/vulkan/vk_postvs.cpp @@ -860,8 +860,30 @@ static void ConvertToMeshOutputCompute(const ShaderReflection &refl, const SPIRV ops.push_back(SPIRVOperation(spv::OpVectorShuffle, words)); } - // *global = value - ops.push_back(SPIRVOperation(spv::OpStore, {ins[i].variableID, result})); + // not a composite type, we can store directly + if(patchData.inputs[i].accessChain.empty()) + { + // *global = value + ops.push_back(SPIRVOperation(spv::OpStore, {ins[i].variableID, result})); + } + else + { + // for composite types we need to access chain first + uint32_t subElement = editor.MakeId(); + std::vector words = {ins[i].privatePtrID, subElement, patchData.inputs[i].ID}; + + for(uint32_t accessIdx : patchData.inputs[i].accessChain) + { + if(idxs[accessIdx] == 0) + idxs[accessIdx] = editor.AddConstantImmediate((uint32_t)accessIdx); + + words.push_back(idxs[accessIdx]); + } + + ops.push_back(SPIRVOperation(spv::OpAccessChain, words)); + + ops.push_back(SPIRVOperation(spv::OpStore, {subElement, result})); + } } }