Add proper support for mesh dumping with nested struct outputs

* Instead of hacking in some data in unused fields in the output sig we
  side-band the data we need to form the access chain.
* We also fix some issues with the SPIR-V generation for mesh dumping
  that were caught by validation.
This commit is contained in:
baldurk
2017-06-02 14:54:17 +01:00
parent 162325dbd5
commit 2706f2e04b
5 changed files with 230 additions and 133 deletions
+20 -2
View File
@@ -53,6 +53,24 @@ enum class ShaderStage : uint32_t;
struct ShaderReflection;
struct ShaderBindpointMapping;
// extra information that goes along with a ShaderReflection that has extra information for SPIR-V
// patching
struct SPIRVPatchData
{
struct OutputAccess
{
// ID of the base output variable
uint32_t ID;
// the access chain of indices
std::vector<uint32_t> accessChain;
};
// matches the output signature array, with details of where to fetch the output from in the
// SPIR-V.
std::vector<OutputAccess> outputs;
};
struct SPVModule
{
SPVModule();
@@ -90,8 +108,8 @@ struct SPVModule
SPVInstruction *GetByID(uint32_t id);
string Disassemble(const string &entryPoint);
void MakeReflection(ShaderStage stage, const string &entryPoint, ShaderReflection *reflection,
ShaderBindpointMapping *mapping);
void MakeReflection(ShaderStage stage, const string &entryPoint, ShaderReflection &reflection,
ShaderBindpointMapping &mapping, SPIRVPatchData &patchData);
};
string CompileSPIRV(SPIRVShaderStage shadType, const vector<string> &sources,
@@ -3695,19 +3695,18 @@ struct bindpair
typedef bindpair<ConstantBlock> cblockpair;
typedef bindpair<ShaderResource> shaderrespair;
void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, string varName,
SPVTypeData *type, const vector<SPVDecoration> &decorations,
vector<SigParameter> &sigarray)
void AddSignatureParameter(bool isInput, ShaderStage stage, uint32_t id,
std::vector<uint32_t> accessChain, string varName, SPVTypeData *type,
const vector<SPVDecoration> &decorations, vector<SigParameter> &sigarray,
SPIRVPatchData &patchData)
{
SigParameter sig;
sig.needSemanticIndex = false;
// this is super cheeky, but useful to pick up when doing output dumping and
// these properties won't be used elsewhere. We should really share the data
// in a better way though.
sig.semanticIdxName = StringFormat::Fmt("%u", id);
sig.semanticIndex = childIdx;
SPIRVPatchData::OutputAccess patch;
patch.accessChain = accessChain;
patch.ID = id;
bool rowmajor = true;
@@ -3742,9 +3741,6 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
if(type->type == SPVTypeData::eStruct)
{
// we don't support nested structs yet
RDCASSERT(childIdx == ~0U);
// it's invalid to include built-in and 'normal' outputs in the same struct. One
// way this can happen is if a SPIR-V generator incorrectly puts in legacy elements
// into an implicit gl_PerVertex struct, but they don't have a builtin to associate
@@ -3766,6 +3762,8 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
for(uint32_t a = 0; a < arraySize; a++)
{
patch.accessChain.push_back(0U);
for(size_t c = 0; c < type->children.size(); c++)
{
// if this struct has builtins, see if this child is a builtin
@@ -3789,8 +3787,11 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
string baseName = isArray ? StringFormat::Fmt("%s[%u]", varName.c_str(), a) : varName;
AddSignatureParameter(stage, id, (uint32_t)c, baseName + "." + type->children[c].second,
type->children[c].first, type->childDecorations[c], sigarray);
AddSignatureParameter(isInput, stage, id, patch.accessChain,
baseName + "." + type->children[c].second, type->children[c].first,
type->childDecorations[c], sigarray, patchData);
patch.accessChain.back()++;
}
}
@@ -3818,6 +3819,10 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
{
string n = varName;
// arrays will need an extra access chain index
if(arraySize > 1)
patch.accessChain.push_back(0U);
if(isArray)
{
n = StringFormat::Fmt("%s[%u]", varName.c_str(), a);
@@ -3829,6 +3834,9 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
if(type->matrixSize == 1)
{
sigarray.push_back(sig);
if(!isInput)
patchData.outputs.push_back(patch);
}
else
{
@@ -3841,15 +3849,21 @@ void AddSignatureParameter(ShaderStage stage, uint32_t id, uint32_t childIdx, st
RDCASSERT(s.regIndex < 16);
sigarray.push_back(s);
if(!isInput)
patchData.outputs.push_back(patch);
}
}
sig.regIndex += RDCMAX(1U, type->matrixSize);
if(arraySize > 1)
patch.accessChain.back()++;
}
}
void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
ShaderReflection *reflection, ShaderBindpointMapping *mapping)
ShaderReflection &reflection, ShaderBindpointMapping &mapping,
SPIRVPatchData &patchData)
{
vector<SigParameter> inputs;
vector<SigParameter> outputs;
@@ -3859,24 +3873,24 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
// VKTODOLOW filter to only functions/resources used by entryPoint
// VKTODOLOW set this properly
reflection->DebugInfo.entryFile = 0;
reflection->DebugInfo.entryFunc = entryPoint;
reflection.DebugInfo.entryFile = 0;
reflection.DebugInfo.entryFunc = entryPoint;
if(!sourceFiles.empty())
{
create_array_uninit(reflection->DebugInfo.files, sourceFiles.size());
create_array_uninit(reflection.DebugInfo.files, sourceFiles.size());
for(size_t i = 0; i < sourceFiles.size(); i++)
{
reflection->DebugInfo.files[i].first = sourceFiles[i].first;
reflection->DebugInfo.files[i].second = sourceFiles[i].second;
reflection.DebugInfo.files[i].first = sourceFiles[i].first;
reflection.DebugInfo.files[i].second = sourceFiles[i].second;
}
}
// TODO need to fetch these
reflection->DispatchThreadsDimension[0] = 0;
reflection->DispatchThreadsDimension[1] = 0;
reflection->DispatchThreadsDimension[2] = 0;
reflection.DispatchThreadsDimension[0] = 0;
reflection.DispatchThreadsDimension[1] = 0;
reflection.DispatchThreadsDimension[2] = 0;
for(size_t i = 0; i < globals.size(); i++)
{
@@ -3898,7 +3912,8 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
else
nm = StringFormat::Fmt("sig%u", inst->id);
AddSignatureParameter(stage, inst->id, ~0U, nm, inst->var->type, inst->decorations, *sigarray);
AddSignatureParameter(isInput, stage, inst->id, std::vector<uint32_t>(), nm, inst->var->type,
inst->decorations, *sigarray, patchData);
// eliminate any members of gl_PerVertex that are actually unused and just came along
// for the ride (usually with gl_Position, but maybe declared globally and still unused)
@@ -3942,8 +3957,10 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
if(eliminate)
{
// variable must be the last one added, just remove it
sigarray->pop_back();
if(patchData.outputs.size() > sigarray->size())
patchData.outputs.pop_back();
}
}
@@ -4009,12 +4026,15 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
if(eliminate)
{
ShaderBuiltin attr = BuiltInToSystemAttribute(stage, checkBuiltin);
// find this builtin in the array, and remove
for(auto it = sigarray->begin(); it != sigarray->end(); ++it)
for(size_t s = 0; s < sigarray->size(); s++)
{
if(it->systemValue == attr)
if((*sigarray)[s].systemValue == attr)
{
sigarray->erase(it);
sigarray->erase(sigarray->begin() + s);
if(!isInput)
patchData.outputs.erase(patchData.outputs.begin() + s);
break;
}
}
@@ -4326,8 +4346,14 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
// sort system value semantics to the start of the list
struct sig_param_sort
{
bool operator()(const SigParameter &a, const SigParameter &b)
sig_param_sort(const vector<SigParameter> &arr) : sigArray(arr) {}
const vector<SigParameter> &sigArray;
bool operator()(const size_t idxA, const size_t idxB)
{
const SigParameter &a = sigArray[idxA];
const SigParameter &b = sigArray[idxB];
if(a.systemValue == b.systemValue)
{
if(a.regIndex != b.regIndex)
@@ -4344,73 +4370,96 @@ void SPVModule::MakeReflection(ShaderStage stage, const string &entryPoint,
}
};
std::sort(inputs.begin(), inputs.end(), sig_param_sort());
std::sort(outputs.begin(), outputs.end(), sig_param_sort());
std::vector<size_t> indices;
{
indices.resize(inputs.size());
for(size_t i = 0; i < inputs.size(); i++)
indices[i] = i;
std::sort(indices.begin(), indices.end(), sig_param_sort(inputs));
create_array_uninit(reflection.InputSig, inputs.size());
for(size_t i = 0; i < inputs.size(); i++)
reflection.InputSig[i] = inputs[indices[i]];
}
{
indices.resize(outputs.size());
for(size_t i = 0; i < outputs.size(); i++)
indices[i] = i;
std::sort(indices.begin(), indices.end(), sig_param_sort(outputs));
create_array_uninit(reflection.OutputSig, outputs.size());
for(size_t i = 0; i < outputs.size(); i++)
reflection.OutputSig[i] = outputs[indices[i]];
std::vector<SPIRVPatchData::OutputAccess> outPatch = patchData.outputs;
for(size_t i = 0; i < outputs.size(); i++)
patchData.outputs[i] = outPatch[indices[i]];
}
size_t numInputs = 16;
for(size_t i = 0; i < inputs.size(); i++)
if(inputs[i].systemValue == ShaderBuiltin::Undefined)
numInputs = RDCMAX(numInputs, (size_t)inputs[i].regIndex + 1);
for(size_t i = 0; i < reflection.InputSig.size(); i++)
if(reflection.InputSig[i].systemValue == ShaderBuiltin::Undefined)
numInputs = RDCMAX(numInputs, (size_t)reflection.InputSig[i].regIndex + 1);
create_array_uninit(mapping->InputAttributes, numInputs);
create_array_uninit(mapping.InputAttributes, numInputs);
for(size_t i = 0; i < numInputs; i++)
mapping->InputAttributes[i] = -1;
mapping.InputAttributes[i] = -1;
for(size_t i = 0; i < inputs.size(); i++)
if(inputs[i].systemValue == ShaderBuiltin::Undefined)
mapping->InputAttributes[inputs[i].regIndex] = (int32_t)i;
reflection->InputSig = inputs;
reflection->OutputSig = outputs;
for(size_t i = 0; i < reflection.InputSig.size(); i++)
if(reflection.InputSig[i].systemValue == ShaderBuiltin::Undefined)
mapping.InputAttributes[reflection.InputSig[i].regIndex] = (int32_t)i;
std::sort(cblocks.begin(), cblocks.end());
std::sort(roresources.begin(), roresources.end());
std::sort(rwresources.begin(), rwresources.end());
create_array_uninit(mapping->ConstantBlocks, cblocks.size());
create_array_uninit(reflection->ConstantBlocks, cblocks.size());
create_array_uninit(mapping.ConstantBlocks, cblocks.size());
create_array_uninit(reflection.ConstantBlocks, cblocks.size());
create_array_uninit(mapping->ReadOnlyResources, roresources.size());
create_array_uninit(reflection->ReadOnlyResources, roresources.size());
create_array_uninit(mapping.ReadOnlyResources, roresources.size());
create_array_uninit(reflection.ReadOnlyResources, roresources.size());
create_array_uninit(mapping->ReadWriteResources, rwresources.size());
create_array_uninit(reflection->ReadWriteResources, rwresources.size());
create_array_uninit(mapping.ReadWriteResources, rwresources.size());
create_array_uninit(reflection.ReadWriteResources, rwresources.size());
for(size_t i = 0; i < cblocks.size(); i++)
{
mapping->ConstantBlocks[i] = cblocks[i].map;
mapping.ConstantBlocks[i] = cblocks[i].map;
// fix up any bind points marked with -1. They were sorted to the end
// but from here on we want to just be able to index with the bind point
// without any special casing.
if(mapping->ConstantBlocks[i].bind == -1)
mapping->ConstantBlocks[i].bind = 0;
reflection->ConstantBlocks[i] = cblocks[i].bindres;
reflection->ConstantBlocks[i].bindPoint = (int32_t)i;
if(mapping.ConstantBlocks[i].bind == -1)
mapping.ConstantBlocks[i].bind = 0;
reflection.ConstantBlocks[i] = cblocks[i].bindres;
reflection.ConstantBlocks[i].bindPoint = (int32_t)i;
}
for(size_t i = 0; i < roresources.size(); i++)
{
mapping->ReadOnlyResources[i] = roresources[i].map;
mapping.ReadOnlyResources[i] = roresources[i].map;
// fix up any bind points marked with -1. They were sorted to the end
// but from here on we want to just be able to index with the bind point
// without any special casing.
if(mapping->ReadOnlyResources[i].bind == -1)
mapping->ReadOnlyResources[i].bind = 0;
reflection->ReadOnlyResources[i] = roresources[i].bindres;
reflection->ReadOnlyResources[i].bindPoint = (int32_t)i;
if(mapping.ReadOnlyResources[i].bind == -1)
mapping.ReadOnlyResources[i].bind = 0;
reflection.ReadOnlyResources[i] = roresources[i].bindres;
reflection.ReadOnlyResources[i].bindPoint = (int32_t)i;
}
for(size_t i = 0; i < rwresources.size(); i++)
{
mapping->ReadWriteResources[i] = rwresources[i].map;
mapping.ReadWriteResources[i] = rwresources[i].map;
// fix up any bind points marked with -1. They were sorted to the end
// but from here on we want to just be able to index with the bind point
// without any special casing.
if(mapping->ReadWriteResources[i].bind == -1)
mapping->ReadWriteResources[i].bind = 0;
reflection->ReadWriteResources[i] = rwresources[i].bindres;
reflection->ReadWriteResources[i].bindPoint = (int32_t)i;
if(mapping.ReadWriteResources[i].bind == -1)
mapping.ReadWriteResources[i].bind = 0;
reflection.ReadWriteResources[i] = rwresources[i].bindres;
reflection.ReadWriteResources[i].bindPoint = (int32_t)i;
}
}
+90 -66
View File
@@ -7087,9 +7087,10 @@ inline uint32_t MakeSPIRVOp(spv::Op op, uint32_t WordCount)
return (uint32_t(op) & spv::OpCodeMask) | (WordCount << spv::WordCountShift);
}
static void AddOutputDumping(const ShaderReflection &refl, const char *entryName, uint32_t descSet,
uint32_t vertexIndexOffset, uint32_t instanceIndexOffset,
uint32_t numVerts, vector<uint32_t> &modSpirv, uint32_t &bufStride)
static void AddOutputDumping(const ShaderReflection &refl, const SPIRVPatchData &patchData,
const char *entryName, uint32_t descSet, uint32_t vertexIndexOffset,
uint32_t instanceIndexOffset, uint32_t numVerts,
vector<uint32_t> &modSpirv, uint32_t &bufStride)
{
uint32_t *spirv = &modSpirv[0];
size_t spirvLength = modSpirv.size();
@@ -7138,10 +7139,7 @@ static void AddOutputDumping(const ShaderReflection &refl, const char *entryName
uint32_t constID; // constant ID for the index of this output
uint32_t basetypeID; // the type ID for this output. Must be present already by definition!
uint32_t uniformPtrID; // Uniform Pointer ID for this output. Used to write the output data
uint32_t varID; // we get this from the output signature, ID of actual variable
uint32_t
childIdx; // if the output variable is a struct, this is the member idx of this output
uint32_t outputPtrID; // Output Pointer ID for this output. Used to read the output data
};
outputIDs outs[100] = {};
@@ -7196,30 +7194,54 @@ static void AddOutputDumping(const ShaderReflection &refl, const char *entryName
outs[i].constID = spirv[it + 2];
}
if(refl.OutputSig[i].compCount > 1 && opcode == spv::OpTypeVector)
if(outs[i].basetypeID == 0)
{
uint32_t baseID = 0;
if(refl.OutputSig[i].compCount > 1 && opcode == spv::OpTypeVector)
{
uint32_t baseID = 0;
if(refl.OutputSig[i].compType == CompType::UInt)
baseID = uint32ID;
else if(refl.OutputSig[i].compType == CompType::SInt)
baseID = sint32ID;
else if(refl.OutputSig[i].compType == CompType::Float)
baseID = floatID;
else if(refl.OutputSig[i].compType == CompType::Double)
baseID = doubleID;
else
RDCERR("Unexpected component type for output signature element");
if(refl.OutputSig[i].compType == CompType::UInt)
baseID = uint32ID;
else if(refl.OutputSig[i].compType == CompType::SInt)
baseID = sint32ID;
else if(refl.OutputSig[i].compType == CompType::Float)
baseID = floatID;
else if(refl.OutputSig[i].compType == CompType::Double)
baseID = doubleID;
else
RDCERR("Unexpected component type for output signature element");
// if we have the base type, see if this is the right sized vector of that type
if(baseID != 0 && spirv[it + 2] == baseID && spirv[it + 3] == refl.OutputSig[i].compCount)
outs[i].basetypeID = spirv[it + 1];
// if we have the base type, see if this is the right sized vector of that type
if(baseID != 0 && spirv[it + 2] == baseID && spirv[it + 3] == refl.OutputSig[i].compCount)
outs[i].basetypeID = spirv[it + 1];
}
// handle non-vectors
if(refl.OutputSig[i].compCount == 1)
{
if(refl.OutputSig[i].compType == CompType::UInt)
outs[i].basetypeID = uint32ID;
else if(refl.OutputSig[i].compType == CompType::SInt)
outs[i].basetypeID = sint32ID;
else if(refl.OutputSig[i].compType == CompType::Float)
outs[i].basetypeID = floatID;
else if(refl.OutputSig[i].compType == CompType::Double)
outs[i].basetypeID = doubleID;
}
}
// if we've found the base type, try and identify uniform pointers to that type
// if we've found the base type, try and identify pointers to that type
if(outs[i].basetypeID != 0 && opcode == spv::OpTypePointer &&
spirv[it + 2] == spv::StorageClassUniform && spirv[it + 3] == outs[i].basetypeID)
{
outs[i].uniformPtrID = spirv[it + 1];
}
if(outs[i].basetypeID != 0 && opcode == spv::OpTypePointer &&
spirv[it + 2] == spv::StorageClassOutput && spirv[it + 3] == outs[i].basetypeID)
{
outs[i].outputPtrID = spirv[it + 1];
}
}
if(opcode == spv::OpEntryPoint)
@@ -7259,27 +7281,8 @@ static void AddOutputDumping(const ShaderReflection &refl, const char *entryName
for(int i = 0; i < numOutputs; i++)
{
// handle non-vectors once here
if(refl.OutputSig[i].compCount == 1)
{
if(refl.OutputSig[i].compType == CompType::UInt)
outs[i].basetypeID = uint32ID;
else if(refl.OutputSig[i].compType == CompType::SInt)
outs[i].basetypeID = sint32ID;
else if(refl.OutputSig[i].compType == CompType::Float)
outs[i].basetypeID = floatID;
else if(refl.OutputSig[i].compType == CompType::Double)
outs[i].basetypeID = doubleID;
else
RDCERR("Unexpected component type for output signature element");
}
// must have at least found the base type, or something has gone seriously wrong
RDCASSERT(outs[i].basetypeID != 0);
// bit of a hack, these were stored from SPIR-V disassembly
outs[i].varID = atoi(refl.OutputSig[i].semanticIdxName.elems);
outs[i].childIdx = refl.OutputSig[i].semanticIndex;
}
// if needed add new ID for sint32 type
@@ -7474,6 +7477,39 @@ static void AddOutputDumping(const ShaderReflection &refl, const char *entryName
}
}
}
// it would be very strange to have no output pointer ID, since the original SPIR-V would have
// had to use some other mechanism to write to the output variable. But just to be safe we
// ensure that we have it here too.
if(outs[i].outputPtrID == 0)
{
RDCERR("No output pointer ID found for output %d: %s (%u %u)", i,
refl.OutputSig[i].varName.c_str(), refl.OutputSig[i].compType,
refl.OutputSig[i].compCount);
outs[i].outputPtrID = idBound++;
uint32_t typeOp[] = {
MakeSPIRVOp(spv::OpTypePointer, 4), outs[i].outputPtrID, spv::StorageClassOutput,
outs[i].basetypeID,
};
// insert at the end of the types/variables/constants section
modSpirv.insert(modSpirv.begin() + typeVarOffset, typeOp, typeOp + ARRAY_COUNT(typeOp));
// update offsets to account for inserted op
typeVarOffset += ARRAY_COUNT(typeOp);
// update subsequent outputs of identical type
for(int j = i + 1; j < numOutputs; j++)
{
if(outs[i].basetypeID == outs[j].basetypeID)
{
RDCASSERT(outs[j].outputPtrID == 0);
outs[j].outputPtrID = outs[i].outputPtrID;
}
}
}
}
uint32_t outBufferVarID = 0;
@@ -7735,42 +7771,29 @@ static void AddOutputDumping(const ShaderReflection &refl, const char *entryName
uint32_t loaded = 0;
// not a structure member or array child, can load directly
if(outs[o].childIdx == ~0U && refl.OutputSig[o].arrayIndex == ~0U)
if(patchData.outputs[o].accessChain.empty())
{
loaded = idBound++;
dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4));
dumpCode.push_back(outs[o].basetypeID);
dumpCode.push_back(loaded);
dumpCode.push_back(outs[o].varID);
dumpCode.push_back(patchData.outputs[o].ID);
}
else
{
uint32_t readPtr = idBound++;
loaded = idBound++;
uint32_t chainLength = 1;
if(outs[o].childIdx != ~0U && refl.OutputSig[o].arrayIndex != ~0U)
chainLength = 2;
// structure member, need to access chain first
dumpCode.push_back(MakeSPIRVOp(spv::OpAccessChain, 4 + chainLength));
dumpCode.push_back(outs[o].uniformPtrID);
dumpCode.push_back(readPtr); // readPtr =
dumpCode.push_back(outs[o].varID); // outStructWhatever
dumpCode.push_back(
MakeSPIRVOp(spv::OpAccessChain, 4 + (uint32_t)patchData.outputs[o].accessChain.size()));
dumpCode.push_back(outs[o].outputPtrID);
dumpCode.push_back(readPtr); // readPtr =
dumpCode.push_back(patchData.outputs[o].ID); // outStructWhatever
if(outs[o].childIdx != ~0U)
{
RDCASSERT(outs[o].childIdx < (uint32_t)numOutputs);
dumpCode.push_back(outs[outs[o].childIdx].constID); // .actualOut
}
if(refl.OutputSig[o].arrayIndex != ~0U)
{
RDCASSERT(refl.OutputSig[o].arrayIndex < (uint32_t)numOutputs);
dumpCode.push_back(outs[refl.OutputSig[o].arrayIndex].constID); // [element]
}
for(uint32_t idx : patchData.outputs[o].accessChain)
dumpCode.push_back(outs[idx].constID);
dumpCode.push_back(MakeSPIRVOp(spv::OpLoad, 4));
dumpCode.push_back(outs[o].basetypeID);
@@ -8130,8 +8153,9 @@ void VulkanDebugManager::InitPostVSBuffers(uint32_t eventID)
uint32_t bufStride = 0;
vector<uint32_t> modSpirv = moduleInfo.spirv.spirv;
AddOutputDumping(*refl, pipeInfo.shaders[0].entryPoint.c_str(), descSet, vertexIndexOffset,
drawcall->instanceOffset, numVerts, modSpirv, bufStride);
AddOutputDumping(*refl, *pipeInfo.shaders[0].patchData, pipeInfo.shaders[0].entryPoint.c_str(),
descSet, vertexIndexOffset, drawcall->instanceOffset, numVerts, modSpirv,
bufStride);
// create vertex shader with modified code
VkShaderModuleCreateInfo moduleCreateInfo = {
+6 -2
View File
@@ -112,7 +112,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
reflData.entryPoint = shad.entryPoint;
reflData.stage = stageIndex;
info.m_ShaderModule[id].spirv.MakeReflection(ShaderStage(reflData.stage), reflData.entryPoint,
&reflData.refl, &reflData.mapping);
reflData.refl, reflData.mapping,
reflData.patchData);
}
if(pCreateInfo->pStages[i].pSpecializationInfo)
@@ -135,6 +136,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
shad.refl = &reflData.refl;
shad.mapping = &reflData.mapping;
shad.patchData = &reflData.patchData;
}
if(pCreateInfo->pVertexInputState)
@@ -326,7 +328,8 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
{
reflData.entryPoint = shad.entryPoint;
info.m_ShaderModule[id].spirv.MakeReflection(ShaderStage::Compute, reflData.entryPoint,
&reflData.refl, &reflData.mapping);
reflData.refl, reflData.mapping,
reflData.patchData);
}
if(pCreateInfo->stage.pSpecializationInfo)
@@ -347,6 +350,7 @@ void VulkanCreationInfo::Pipeline::Init(VulkanResourceManager *resourceMan, Vulk
shad.refl = &reflData.refl;
shad.mapping = &reflData.mapping;
shad.patchData = &reflData.patchData;
}
topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+3 -1
View File
@@ -92,11 +92,12 @@ struct VulkanCreationInfo
// VkPipelineShaderStageCreateInfo
struct Shader
{
Shader() : refl(NULL), mapping(NULL) {}
Shader() : refl(NULL), mapping(NULL), patchData(NULL) {}
ResourceId module;
string entryPoint;
ShaderReflection *refl;
ShaderBindpointMapping *mapping;
SPIRVPatchData *patchData;
vector<byte> specdata;
struct SpecInfo
@@ -346,6 +347,7 @@ struct VulkanCreationInfo
string entryPoint;
ShaderReflection refl;
ShaderBindpointMapping mapping;
SPIRVPatchData patchData;
};
map<string, Reflection> m_Reflections;
};