Support composite types on vertex shader inputs, in vulkan PostVS fetch

This commit is contained in:
baldurk
2018-01-24 18:44:15 +00:00
parent 7636d370f4
commit 904511afb0
3 changed files with 55 additions and 14 deletions
@@ -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<uint32_t> 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<OutputAccess> outputs;
std::vector<InterfaceAccess> inputs;
std::vector<InterfaceAccess> outputs;
};
struct SPVModule
@@ -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<SPIRVPatchData::InterfaceAccess> 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<SPIRVPatchData::OutputAccess> outPatch = patchData.outputs;
std::vector<SPIRVPatchData::InterfaceAccess> outPatch = patchData.outputs;
for(size_t i = 0; i < outputs.size(); i++)
patchData.outputs[i] = outPatch[indices[i]];
}
+24 -2
View File
@@ -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<uint32_t> 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>((uint32_t)accessIdx);
words.push_back(idxs[accessIdx]);
}
ops.push_back(SPIRVOperation(spv::OpAccessChain, words));
ops.push_back(SPIRVOperation(spv::OpStore, {subElement, result}));
}
}
}