Commit e24aa5ed by qining

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)`
parent d9952419
......@@ -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;
......
......@@ -1212,6 +1212,14 @@ Id Builder::createBinOp(Op opCode, Id typeId, Id left, Id right)
Id Builder::createTriOp(Op opCode, Id typeId, Id op1, Id op2, Id op3)
{
// Generate code for spec constants if in spec constant operation
// generation mode.
if (generatingOpCodeForSpecConst) {
std::vector<Id> operands(3);
operands[0] = op1; operands[1] = op2; operands[2] = op3;
return createSpecConstantOp(
opCode, typeId, operands, std::vector<Id>());
}
Instruction* op = new Instruction(getUniqueId(), typeId, opCode);
op->addIdOperand(op1);
op->addIdOperand(op2);
......
......@@ -10,9 +10,15 @@ layout(constant_id = 203) const int sp_sint = -10;
// Scalars
//
// Size convert
//const double float_to_double = double(sp_float);
//const float double_to_float = float(float_to_double);
// uint/int <-> bool conversion
const bool bool_from_int = bool(sp_int);
const bool bool_from_uint = bool(sp_uint);
const int int_from_bool = int(bool_from_int);
const uint uint_from_bool = uint(bool_from_int);
// uint <-> int
const uint sp_uint_from_sint = uint(sp_sint);
const int sp_sint_from_uint = int(sp_uint);
// Negate and Not
const int negate_int = -sp_int;
......@@ -54,9 +60,15 @@ const ivec4 iv = ivec4(20, 30, sp_int, sp_int);
const uvec4 uv = uvec4(sp_uint, sp_uint, -1, -2);
const vec4 fv = vec4(sp_float, 1.25, sp_float, 1.25);
// Size convert
//const dvec4 fv_to_dv = dvec4(fv);
//const vec4 dv_to_fv = vec4(fv_to_dv);
// uint/int <-> bool conversion
const bvec4 bv_from_iv = bvec4(iv);
const bvec4 bv_from_uv = bvec4(uv);
const ivec4 iv_from_bv = ivec4(bv_from_iv);
const uvec4 uv_from_bv = uvec4(bv_from_iv);
// uint <-> int
const uvec4 uv_from_iv = uvec4(iv);
const ivec4 iv_from_uv = ivec4(uv);
// Negate and Not
const ivec4 not_iv = ~iv;
......@@ -88,6 +100,9 @@ const ivec4 iv_yzxw = iv.yzxw;
int non_const_array_size_from_spec_const() {
int array[sp_int + 2];
for (int i = 0; i < sp_int + 2; i++) {
array[i] = 1023;
}
return array[sp_int + 1];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment