Merge SPIRVVoid into SPIRVScalar, add image types, reduce copy-paste

* We use templates to reduce copy-paste between the different types
  since it's the same operation of "look up a map, if not found then
  declare and add to map", just with a different typed map.
This commit is contained in:
baldurk
2018-01-16 16:54:32 +00:00
parent 75c31a9775
commit 50b34a2bb7
3 changed files with 190 additions and 123 deletions
+83 -98
View File
@@ -37,7 +37,7 @@ SPIRVScalar::SPIRVScalar(SPIRVIterator it)
{
type = it.opcode();
if(type != spv::OpTypeBool)
if(type == spv::OpTypeInt || type == spv::OpTypeFloat)
width = it.word(2);
else
width = 0;
@@ -48,6 +48,44 @@ SPIRVScalar::SPIRVScalar(SPIRVIterator it)
signedness = false;
}
SPIRVOperation SPIRVVector::decl(SPIRVEditor &editor) const
{
return SPIRVOperation(spv::OpTypeVector, {0U, editor.DeclareType(scalar), count});
}
SPIRVOperation SPIRVMatrix::decl(SPIRVEditor &editor) const
{
return SPIRVOperation(spv::OpTypeMatrix, {0U, editor.DeclareType(vector), count});
}
SPIRVOperation SPIRVPointer::decl(SPIRVEditor &editor) const
{
return SPIRVOperation(spv::OpTypePointer, {0U, (uint32_t)storage, baseId});
}
SPIRVOperation SPIRVImage::decl(SPIRVEditor &editor) const
{
return SPIRVOperation(spv::OpTypeImage, {0U, editor.DeclareType(retType), (uint32_t)dim, depth,
arrayed, ms, sampled, (uint32_t)format});
}
SPIRVOperation SPIRVSampledImage::decl(SPIRVEditor &editor) const
{
return SPIRVOperation(spv::OpTypeSampledImage, {0U, baseId});
}
SPIRVOperation SPIRVFunction::decl(SPIRVEditor &editor) const
{
std::vector<uint32_t> words;
words.push_back(0U);
words.push_back(returnId);
for(SPIRVId id : argumentIds)
words.push_back(id);
return SPIRVOperation(spv::OpTypeFunction, words);
}
SPIRVEditor::SPIRVEditor(std::vector<uint32_t> &spirvWords) : spirv(spirvWords)
{
if(spirv.size() < 5 || spirv[0] != spv::MagicNumber)
@@ -140,7 +178,8 @@ SPIRVEditor::SPIRVEditor(std::vector<uint32_t> &spirvWords) : spirv(spirvWords)
}
// identify declared scalar/vector/matrix types
if(opcode == spv::OpTypeBool || opcode == spv::OpTypeInt || opcode == spv::OpTypeFloat)
if(opcode == spv::OpTypeVoid || opcode == spv::OpTypeBool || opcode == spv::OpTypeInt ||
opcode == spv::OpTypeFloat)
{
uint32_t id = it.word(1);
idOffsets[id] = it.offset;
@@ -204,12 +243,6 @@ SPIRVEditor::SPIRVEditor(std::vector<uint32_t> &spirvWords) : spirv(spirvWords)
functionTypes[SPIRVFunction(it.word(2), args)] = id;
}
if(opcode == spv::OpTypeVoid)
{
voidType = it.word(1);
idOffsets[voidType] = it.offset;
}
}
}
@@ -348,96 +381,6 @@ SPIRVIterator SPIRVEditor::EndTypes()
return SPIRVIterator(spirv, typeVarSection.endOffset);
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVVoid &)
{
if(voidType)
return voidType;
voidType = MakeId();
AddType(SPIRVOperation(spv::OpTypeVoid, {voidType}));
return voidType;
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVScalar &scalar)
{
auto it = scalarTypes.lower_bound(scalar);
if(it != scalarTypes.end() && it->first == scalar)
return it->second;
SPIRVOperation decl = scalar.decl();
SPIRVId id = decl[1] = MakeId();
AddType(decl);
scalarTypes.insert(it, std::make_pair(scalar, id));
return id;
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVVector &vector)
{
auto it = vectorTypes.lower_bound(vector);
if(it != vectorTypes.end() && it->first == vector)
return it->second;
SPIRVId id = MakeId();
AddType(SPIRVOperation(spv::OpTypeVector, {id, DeclareType(vector.scalar), vector.count}));
vectorTypes.insert(it, std::make_pair(vector, id));
return id;
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVMatrix &matrix)
{
auto it = matrixTypes.lower_bound(matrix);
if(it != matrixTypes.end() && it->first == matrix)
return it->second;
SPIRVId id = MakeId();
AddType(SPIRVOperation(spv::OpTypeVector, {id, DeclareType(matrix.vector), matrix.count}));
matrixTypes.insert(it, std::make_pair(matrix, id));
return id;
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVPointer &pointer)
{
auto it = pointerTypes.lower_bound(pointer);
if(it != pointerTypes.end() && it->first == pointer)
return it->second;
SPIRVId id = MakeId();
AddType(SPIRVOperation(spv::OpTypePointer, {id, (uint32_t)pointer.storage, pointer.baseId}));
pointerTypes.insert(it, std::make_pair(pointer, id));
return id;
}
SPIRVId SPIRVEditor::DeclareType(const SPIRVFunction &func)
{
auto it = functionTypes.lower_bound(func);
if(it != functionTypes.end() && it->first == func)
return it->second;
SPIRVId id = MakeId();
std::vector<uint32_t> words;
words.push_back(id);
words.push_back(func.returnId);
for(SPIRVId id : func.argumentIds)
words.push_back(id);
AddType(SPIRVOperation(spv::OpTypeFunction, words));
functionTypes.insert(it, std::make_pair(func, id));
return id;
}
SPIRVId SPIRVEditor::DeclareStructType(std::vector<uint32_t> members)
{
SPIRVId typeId = MakeId();
@@ -487,3 +430,45 @@ void SPIRVEditor::addWords(size_t offs, int32_t num)
if(o >= offs)
o += num;
}
template <>
std::map<SPIRVScalar, SPIRVId> &SPIRVEditor::GetTable<SPIRVScalar>()
{
return scalarTypes;
}
template <>
std::map<SPIRVVector, SPIRVId> &SPIRVEditor::GetTable<SPIRVVector>()
{
return vectorTypes;
}
template <>
std::map<SPIRVMatrix, SPIRVId> &SPIRVEditor::GetTable<SPIRVMatrix>()
{
return matrixTypes;
}
template <>
std::map<SPIRVPointer, SPIRVId> &SPIRVEditor::GetTable<SPIRVPointer>()
{
return pointerTypes;
}
template <>
std::map<SPIRVImage, SPIRVId> &SPIRVEditor::GetTable<SPIRVImage>()
{
return imageTypes;
}
template <>
std::map<SPIRVSampledImage, SPIRVId> &SPIRVEditor::GetTable<SPIRVSampledImage>()
{
return sampledImageTypes;
}
template <>
std::map<SPIRVFunction, SPIRVId> &SPIRVEditor::GetTable<SPIRVFunction>()
{
return functionTypes;
}
+106 -24
View File
@@ -172,10 +172,6 @@ struct SPIRVEntry
std::string name;
};
struct SPIRVVoid
{
};
struct SPIRVScalar
{
constexpr SPIRVScalar(spv::Op t, uint32_t w, bool s) : type(t), width(w), signedness(s) {}
@@ -200,16 +196,18 @@ struct SPIRVScalar
return type == o.type && width == o.width && signedness == o.signedness;
}
inline SPIRVOperation decl() const
SPIRVOperation decl(SPIRVEditor &editor) const
{
if(type == spv::Op::OpTypeBool)
if(type == spv::OpTypeVoid)
return SPIRVOperation(type, {0});
else if(type == spv::Op::OpTypeFloat)
else if(type == spv::OpTypeBool)
return SPIRVOperation(type, {0});
else if(type == spv::OpTypeFloat)
return SPIRVOperation(type, {0, width});
else if(type == spv::Op::OpTypeInt)
else if(type == spv::OpTypeInt)
return SPIRVOperation(type, {0, width, signedness ? 1U : 0U});
else
return SPIRVOperation(spv::Op::OpNop, {0});
return SPIRVOperation(spv::OpNop, {0});
}
};
@@ -224,13 +222,14 @@ inline constexpr SPIRVScalar scalar();
return SPIRVScalar(op, width, sign); \
}
SCALAR_TYPE(bool, spv::Op::OpTypeBool, 0, false);
SCALAR_TYPE(uint16_t, spv::Op::OpTypeInt, 16, false);
SCALAR_TYPE(uint32_t, spv::Op::OpTypeInt, 32, false);
SCALAR_TYPE(int16_t, spv::Op::OpTypeInt, 16, true);
SCALAR_TYPE(int32_t, spv::Op::OpTypeInt, 32, true);
SCALAR_TYPE(float, spv::Op::OpTypeFloat, 32, false);
SCALAR_TYPE(double, spv::Op::OpTypeFloat, 64, false);
SCALAR_TYPE(void, spv::OpTypeVoid, 0, false);
SCALAR_TYPE(bool, spv::OpTypeBool, 0, false);
SCALAR_TYPE(uint16_t, spv::OpTypeInt, 16, false);
SCALAR_TYPE(uint32_t, spv::OpTypeInt, 32, false);
SCALAR_TYPE(int16_t, spv::OpTypeInt, 16, true);
SCALAR_TYPE(int32_t, spv::OpTypeInt, 32, true);
SCALAR_TYPE(float, spv::OpTypeFloat, 32, false);
SCALAR_TYPE(double, spv::OpTypeFloat, 64, false);
struct SPIRVVector
{
@@ -247,6 +246,7 @@ struct SPIRVVector
bool operator!=(const SPIRVVector &o) const { return !operator==(o); }
bool operator==(const SPIRVVector &o) const { return scalar == o.scalar && count == o.count; }
SPIRVOperation decl(SPIRVEditor &editor) const;
};
struct SPIRVMatrix
@@ -264,6 +264,7 @@ struct SPIRVMatrix
bool operator!=(const SPIRVMatrix &o) const { return !operator==(o); }
bool operator==(const SPIRVMatrix &o) const { return vector == o.vector && count == o.count; }
SPIRVOperation decl(SPIRVEditor &editor) const;
};
struct SPIRVPointer
@@ -284,6 +285,59 @@ struct SPIRVPointer
{
return baseId == o.baseId && storage == o.storage;
}
SPIRVOperation decl(SPIRVEditor &editor) const;
};
struct SPIRVImage
{
SPIRVImage(SPIRVScalar ret, spv::Dim d, uint32_t dp, uint32_t ar, uint32_t m, uint32_t samp,
spv::ImageFormat f)
: retType(ret), dim(d), depth(dp), arrayed(ar), ms(m), sampled(samp), format(f)
{
}
SPIRVScalar retType;
spv::Dim dim;
uint32_t depth;
uint32_t arrayed;
uint32_t ms;
uint32_t sampled;
spv::ImageFormat format;
bool operator<(const SPIRVImage &o) const
{
if(retType != o.retType)
return retType < o.retType;
if(dim != o.dim)
return dim < o.dim;
if(depth != o.depth)
return depth < o.depth;
if(arrayed != o.arrayed)
return arrayed < o.arrayed;
if(ms != o.ms)
return ms < o.ms;
if(sampled != o.sampled)
return sampled < o.sampled;
return format < o.format;
}
bool operator!=(const SPIRVImage &o) const { return !operator==(o); }
bool operator==(const SPIRVImage &o) const
{
return retType == o.retType && dim == o.dim && depth == o.depth && arrayed == o.arrayed &&
ms == o.ms && sampled == o.sampled && format == o.format;
}
SPIRVOperation decl(SPIRVEditor &editor) const;
};
struct SPIRVSampledImage
{
SPIRVSampledImage(SPIRVId b) : baseId(b) {}
SPIRVId baseId;
bool operator<(const SPIRVSampledImage &o) const { return baseId < o.baseId; }
bool operator!=(const SPIRVSampledImage &o) const { return !operator==(o); }
bool operator==(const SPIRVSampledImage &o) const { return baseId == o.baseId; }
SPIRVOperation decl(SPIRVEditor &editor) const;
};
struct SPIRVFunction
@@ -304,6 +358,7 @@ struct SPIRVFunction
{
return returnId == o.returnId && argumentIds == o.argumentIds;
}
SPIRVOperation decl(SPIRVEditor &editor) const;
};
class SPIRVEditor
@@ -337,12 +392,35 @@ public:
// fetches the id of this type. If it exists already the old ID will be returned, otherwise it
// will be declared and the new ID returned
SPIRVId DeclareType(const SPIRVVoid &);
SPIRVId DeclareType(const SPIRVScalar &scalar);
SPIRVId DeclareType(const SPIRVVector &vector);
SPIRVId DeclareType(const SPIRVMatrix &matrix);
SPIRVId DeclareType(const SPIRVPointer &pointer);
SPIRVId DeclareType(const SPIRVFunction &func);
template <typename SPIRVType>
SPIRVId DeclareType(const SPIRVType &t)
{
std::map<SPIRVType, SPIRVId> &table = GetTable<SPIRVType>();
auto it = table.lower_bound(t);
if(it != table.end() && it->first == t)
return it->second;
SPIRVOperation decl = t.decl(*this);
SPIRVId id = decl[1] = MakeId();
AddType(decl);
table.insert(it, std::make_pair(t, id));
return id;
}
template <typename SPIRVType>
SPIRVId GetType(const SPIRVType &t)
{
std::map<SPIRVType, SPIRVId> &table = GetTable<SPIRVType>();
auto it = table.find(t);
if(it != table.end())
return it->second;
return SPIRVId();
}
SPIRVId DeclareStructType(std::vector<uint32_t> members);
@@ -397,8 +475,12 @@ private:
std::map<SPIRVVector, SPIRVId> vectorTypes;
std::map<SPIRVMatrix, SPIRVId> matrixTypes;
std::map<SPIRVPointer, SPIRVId> pointerTypes;
std::map<SPIRVImage, SPIRVId> imageTypes;
std::map<SPIRVSampledImage, SPIRVId> sampledImageTypes;
std::map<SPIRVFunction, SPIRVId> functionTypes;
SPIRVId voidType;
template <typename SPIRVType>
std::map<SPIRVType, SPIRVId> &GetTable();
std::vector<uint32_t> &spirv;
};
};
+1 -1
View File
@@ -242,7 +242,7 @@ static void AddOutputDumping(const ShaderReflection &refl, const SPIRVPatchData
{
std::vector<SPIRVOperation> ops;
SPIRVId voidType = editor.DeclareType(SPIRVVoid());
SPIRVId voidType = editor.DeclareType(scalar<void>());
SPIRVId funcType = editor.DeclareType(SPIRVFunction(voidType, {}));
ops.push_back(SPIRVOperation(spv::OpFunction,