SpecOp bool->uint/int and uint<->int conversion

Bool -> uint/int with OpSpecConstantOp OpSelect instruction.

uint <-> int conversion with OpSpecConstantOp OpIAdd instruction.

Note, implicit conversion: `const uint = an_int_spec_constant` is not
supported. Explicit type casting is required: `const uint =
uint(an_int_spec_constant)`
This commit is contained in:
qining
2016-04-07 15:40:27 -04:00
parent d99524197f
commit e24aa5edbb
4 changed files with 188 additions and 103 deletions

View File

@@ -1960,7 +1960,6 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim);
if (specNode != nullptr) {
builder.clearAccessChain();
// SpecConstantOpModeGuard set_to_spec_const_mode(&builder);
specNode->traverse(this);
return accessChainLoad(specNode->getAsTyped()->getType());
}
@@ -3307,7 +3306,27 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Dec
break;
case glslang::EOpConvUintToInt:
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd to do the conversion when
// generating for OpSpecConstantOp instruction.
zero = builder.makeIntConstant(0);
zero = makeSmearedConstant(zero, vectorSize);
}
// Don't 'break' here as this case should be grouped together with
// EOpConvIntToUint when generating normal run-time conversion
// instruction.
case glslang::EOpConvIntToUint:
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd.
if (zero == 0) {
zero = builder.makeUintConstant(0);
zero = makeSmearedConstant(zero, vectorSize);
}
// Use OpIAdd, instead of OpBitcast to do the conversion when
// generating for OpSpecConstantOp instruction.
return builder.createBinOp(spv::OpIAdd, destType, operand, zero);
}
// For normal run-time conversion instruction, use OpBitcast.
convOp = spv::OpBitcast;
break;