Make modifications of GL_EXT_spirv_intrinsics

1. spirv_execution_mode_id and spirv_decorate_id could support
   specialization constants. The original implementation always
   assume only normal frontend constants are valid. It is not true.

2. spirv_type donesn't support type_specifier as an option of
   spirv_type_parameter. At present, only constant_expression is the
   valid option.
This commit is contained in:
Rex Xu
2021-10-13 14:12:47 +08:00
parent b9ba4c5743
commit 07aec25f82
10 changed files with 2053 additions and 2041 deletions

View File

@@ -1830,10 +1830,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
std::vector<spv::Id> operandIds;
assert(!modeId.second.empty());
for (auto extraOperand : modeId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
if (extraOperand->getType().getQualifier().isSpecConstant())
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
else
operandIds.push_back(createSpvConstant(*extraOperand));
}
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
}
@@ -4150,58 +4150,48 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
std::vector<spv::Id> operands;
for (const auto& typeParam : spirvType.typeParams) {
if (typeParam.isConstant) {
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
operands.push_back(literal);
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
char ch = 0;
do {
ch = *(str++);
*(literalPtr++) = ch;
++charCount;
if (charCount == 4) {
operands.push_back(literal);
literalPtr = reinterpret_cast<char*>(&literal);
charCount = 0;
}
} else
assert(0); // Unexpected type
} else {
int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(
typeParam.constant->getType(), typeParam.constant->getConstArray(), nextConst, false);
operands.push_back(constant);
}
} else {
// Type specifier
spv::Id typeId = convertGlslangToSpvType(*typeParam.type);
operands.push_back(typeId);
}
} while (ch != 0);
// Partial literal is padded with 0
if (charCount > 0) {
for (; charCount < 4; ++charCount)
*(literalPtr++) = 0;
operands.push_back(literal);
}
} else
assert(0); // Unexpected type
} else
operands.push_back(createSpvConstant(*typeParam.constant));
}
if (spirvInst.set == "")
@@ -8847,12 +8837,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
std::vector<spv::Id> operandIds;
assert(!decorateId.second.empty());
for (auto extraOperand : decorateId.second) {
int nextConst = 0;
spv::Id operandId = createSpvConstantFromConstUnionArray(
extraOperand->getType(), extraOperand->getConstArray(), nextConst, false);
operandIds.push_back(operandId);
if (extraOperand->getQualifier().isSpecConstant())
operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode()));
else
operandIds.push_back(createSpvConstant(*extraOperand));
}
builder.addDecoration(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
builder.addDecorationId(id, static_cast<spv::Decoration>(decorateId.first), operandIds);
}
// Add spirv_decorate_string