Skip to content

Commit

Permalink
[preliminary] GL_EXT_spirv_intrinsics: allow spirv_type with Id operands
Browse files Browse the repository at this point in the history
Some types may use Ids to refer to constant operands instead of literals.
OpTypeArray is precedent.

This change is preliminary and should not yet be merged upstream since it
is not supported by the extension spec.

Change-Id: Iaddd07979a5aa638f4da4653f8e8e9e0785bfc46
  • Loading branch information
nhaehnle committed Oct 15, 2021
1 parent 07aec25 commit 99ad9a7
Show file tree
Hide file tree
Showing 9 changed files with 3,955 additions and 3,813 deletions.
29 changes: 16 additions & 13 deletions SPIRV/GlslangToSpv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4151,22 +4151,26 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
std::vector<spv::Id> operands;
for (const auto& typeParam : spirvType.typeParams) {
// Constant expression
if (typeParam.constant->isLiteral()) {
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
if (typeParam.spirvId) {
operands.push_back(createSpvConstant(*typeParam.constant));
} else {
const glslang::TIntermConstantUnion* constant = typeParam.constant->getAsConstantUnion();
assert(constant->isLiteral());
if (constant->getBasicType() == glslang::EbtFloat) {
float floatValue = static_cast<float>(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();
} else if (constant->getBasicType() == glslang::EbtInt) {
unsigned literal = constant->getConstArray()[0].getIConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
} else if (constant->getBasicType() == glslang::EbtUint) {
unsigned literal = constant->getConstArray()[0].getUConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
} else if (constant->getBasicType() == glslang::EbtBool) {
unsigned literal = constant->getConstArray()[0].getBConst();
operands.push_back(literal);
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
} else if (constant->getBasicType() == glslang::EbtString) {
auto str = constant->getConstArray()[0].getSConst()->c_str();
unsigned literal = 0;
char* literalPtr = reinterpret_cast<char*>(&literal);
unsigned charCount = 0;
Expand All @@ -4190,8 +4194,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
}
} else
assert(0); // Unexpected type
} else
operands.push_back(createSpvConstant(*typeParam.constant));
}
}

if (spirvInst.set == "")
Expand Down
10 changes: 7 additions & 3 deletions glslang/Include/SpirvIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,16 @@ struct TSpirvInstruction {
struct TSpirvTypeParameter {
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())

TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; }
TSpirvTypeParameter(const TIntermTyped* arg, bool argSpirvId) { constant = arg; spirvId = argSpirvId; }

bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; }
bool operator==(const TSpirvTypeParameter& rhs) const
{
return constant == rhs.constant && spirvId == rhs.spirvId;
}
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }

const TIntermConstantUnion* constant;
const TIntermTyped* constant;
bool spirvId = false;
};

typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
Expand Down
3 changes: 2 additions & 1 deletion glslang/MachineIndependent/ParseHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,8 @@ class TParseContext : public TParseContextBase {
const TIntermAggregate* extensions, const TIntermAggregate* capabilities);
TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1,
TSpirvRequirement* spirvReq2);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant);
TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermTyped* constant,
bool spirvId);
TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1,
TSpirvTypeParameters* spirvTypeParams2);
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value);
Expand Down
2 changes: 2 additions & 0 deletions glslang/MachineIndependent/Scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,7 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS;
(*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE;
(*KeywordMap)["spirv_literal"] = SPIRV_LITERAL;
(*KeywordMap)["spirv_id"] = SPIRV_ID;
#endif

(*KeywordMap)["sampler2D"] = SAMPLER2D;
Expand Down Expand Up @@ -1770,6 +1771,7 @@ int TScanContext::tokenizeIdentifier()
case SPIRV_STORAGE_CLASS:
case SPIRV_BY_REFERENCE:
case SPIRV_LITERAL:
case SPIRV_ID:
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
return keyword;
Expand Down
4 changes: 2 additions & 2 deletions glslang/MachineIndependent/SpirvIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ void TPublicType::setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvT
spirvType->typeParams = *typeParams;
}

TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant)
TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermTyped* constant, bool spirvId)
{
TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters;
if (constant->getBasicType() != EbtFloat &&
Expand All @@ -286,7 +286,7 @@ TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& l
error(loc, "this type not allowed", constant->getType().getBasicString(), "");
else {
assert(constant);
spirvTypeParams->push_back(TSpirvTypeParameter(constant));
spirvTypeParams->push_back(TSpirvTypeParameter(constant, spirvId));
}

return spirvTypeParams;
Expand Down
10 changes: 8 additions & 2 deletions glslang/MachineIndependent/glslang.m4
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ GLSLANG_WEB_EXCLUDE_ON
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
%token <lex> SPIRV_ID

GLSLANG_WEB_EXCLUDE_OFF

Expand Down Expand Up @@ -4364,8 +4365,13 @@ spirv_type_parameter_list
}

spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
: SPIRV_ID constant_expression {
$$ = parseContext.makeSpirvTypeParameters($2->getLoc(), $2, true);
}
| constant_expression {
if (!$1->getAsConstantUnion() || !$1->getAsConstantUnion()->isLiteral())
parseContext.error($1->getLoc(), "expected a literal constant (did you mean to use 'spirv_id'?)", "", "");
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1, false);
}

spirv_instruction_qualifier
Expand Down
10 changes: 8 additions & 2 deletions glslang/MachineIndependent/glslang.y
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> SPIRV_INSTRUCTION SPIRV_EXECUTION_MODE SPIRV_EXECUTION_MODE_ID
%token <lex> SPIRV_DECORATE SPIRV_DECORATE_ID SPIRV_DECORATE_STRING
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
%token <lex> SPIRV_ID



Expand Down Expand Up @@ -4364,8 +4365,13 @@ spirv_type_parameter_list
}

spirv_type_parameter
: constant_expression {
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1->getAsConstantUnion());
: SPIRV_ID constant_expression {
$$ = parseContext.makeSpirvTypeParameters($2->getLoc(), $2, true);
}
| constant_expression {
if (!$1->getAsConstantUnion() || !$1->getAsConstantUnion()->isLiteral())
parseContext.error($1->getLoc(), "expected a literal constant (did you mean to use 'spirv_id'?)", "", "");
$$ = parseContext.makeSpirvTypeParameters($1->getLoc(), $1, false);
}

spirv_instruction_qualifier
Expand Down
Loading

0 comments on commit 99ad9a7

Please sign in to comment.