diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index a75c7caf..94e37e8f 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -93,6 +93,7 @@ protected: spv::Id getSampledType(const glslang::TSampler&); spv::Id convertGlslangToSpvType(const glslang::TType& type); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&); + spv::Id accessChainLoad(const glslang::TType& type); glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const; int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix); int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix); @@ -234,7 +235,6 @@ spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type) switch (type.getQualifier().precision) { case glslang::EpqLow: return spv::DecorationRelaxedPrecision; case glslang::EpqMedium: return spv::DecorationRelaxedPrecision; - case glslang::EpqHigh: return spv::NoPrecision; default: return spv::NoPrecision; } @@ -709,12 +709,12 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // evaluate the right builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id rValue = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); + spv::Id rValue = accessChainLoad(node->getRight()->getType()); if (node->getOp() != glslang::EOpAssign) { // the left is also an r-value builder.setAccessChain(lValue); - spv::Id leftRValue = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType())); + spv::Id leftRValue = accessChainLoad(node->getLeft()->getType()); // do the operation rValue = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), @@ -782,7 +782,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // compute the next index in the chain builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id index = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); + spv::Id index = accessChainLoad(node->getRight()->getType()); // restore the saved access chain builder.setAccessChain(partial); @@ -824,21 +824,20 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // Assume generic binary op... - // Get the operands + // get right operand builder.clearAccessChain(); node->getLeft()->traverse(this); - spv::Id left = builder.accessChainLoad(convertGlslangToSpvType(node->getLeft()->getType())); + spv::Id left = accessChainLoad(node->getLeft()->getType()); + // get left operand builder.clearAccessChain(); node->getRight()->traverse(this); - spv::Id right = builder.accessChainLoad(convertGlslangToSpvType(node->getRight()->getType())); + spv::Id right = accessChainLoad(node->getRight()->getType()); - spv::Id result; - spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); - - result = createBinaryOperation(node->getOp(), precision, - convertGlslangToSpvType(node->getType()), left, right, - node->getLeft()->getType().getBasicType()); + // get result + spv::Id result = createBinaryOperation(node->getOp(), TranslatePrecisionDecoration(node->getType()), + convertGlslangToSpvType(node->getType()), left, right, + node->getLeft()->getType().getBasicType()); builder.clearAccessChain(); if (! result) { @@ -896,7 +895,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI node->getOp() == glslang::EOpInterpolateAtCentroid) operand = builder.accessChainGetLValue(); // Special case l-value operands else - operand = builder.accessChainLoad(convertGlslangToSpvType(node->getOperand()->getType())); + operand = accessChainLoad(node->getOperand()->getType()); spv::Decoration precision = TranslatePrecisionDecoration(node->getType()); @@ -1208,11 +1207,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.clearAccessChain(); left->traverse(this); - spv::Id leftId = builder.accessChainLoad(convertGlslangToSpvType(left->getType())); + spv::Id leftId = accessChainLoad(left->getType()); builder.clearAccessChain(); right->traverse(this); - spv::Id rightId = builder.accessChainLoad(convertGlslangToSpvType(right->getType())); + spv::Id rightId = accessChainLoad(right->getType()); result = createBinaryOperation(binOp, precision, convertGlslangToSpvType(node->getType()), leftId, rightId, @@ -1275,7 +1274,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (lvalue) operands.push_back(builder.accessChainGetLValue()); else - operands.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangOperands[arg]->getAsTyped()->getType()))); + operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); } if (atomic) { @@ -1325,13 +1324,13 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang node->getCondition()->traverse(this); // make an "if" based on the value created by the condition - spv::Builder::If ifBuilder(builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getType())), builder); + spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), builder); if (node->getTrueBlock()) { // emit the "then" statement node->getTrueBlock()->traverse(this); if (result) - builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getTrueBlock()->getAsTyped()->getType())), result); + builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result); } if (node->getFalseBlock()) { @@ -1339,7 +1338,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // emit the "else" statement node->getFalseBlock()->traverse(this); if (result) - builder.createStore(builder.accessChainLoad(convertGlslangToSpvType(node->getFalseBlock()->getAsTyped()->getType())), result); + builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result); } ifBuilder.makeEndIf(); @@ -1360,7 +1359,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T { // emit and get the condition before doing anything with switch node->getCondition()->traverse(this); - spv::Id selector = builder.accessChainLoad(convertGlslangToSpvType(node->getCondition()->getAsTyped()->getType())); + spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType()); // browse the children to sort out code segments int defaultSegment = -1; @@ -1433,7 +1432,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn builder.setBuildPoint(&test); node->getTest()->traverse(this); spv::Id condition = - builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); + accessChainLoad(node->getTest()->getType()); builder.createConditionalBranch(condition, &blocks.body, &blocks.merge); builder.setBuildPoint(&blocks.body); @@ -1463,7 +1462,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn if (node->getTest()) { node->getTest()->traverse(this); spv::Id condition = - builder.accessChainLoad(convertGlslangToSpvType(node->getTest()->getType())); + accessChainLoad(node->getTest()->getType()); builder.createConditionalBranch(condition, &blocks.head, &blocks.merge); } else { // TODO: unless there was a break/return/discard instruction @@ -1497,7 +1496,7 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T break; case glslang::EOpReturn: if (node->getExpression()) - builder.makeReturn(false, builder.accessChainLoad(convertGlslangToSpvType(node->getExpression()->getType()))); + builder.makeReturn(false, accessChainLoad(node->getExpression()->getType())); else builder.makeReturn(false); @@ -1765,6 +1764,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty return spvType; } +spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) +{ + return builder.accessChainLoad(TranslatePrecisionDecoration(type), convertGlslangToSpvType(type)); +} + // Decide whether or not this type should be // decorated with offsets and strides, and if so // whether std140 or std430 rules should be applied. @@ -1885,6 +1889,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF // copy-in/copy-out semantics. They can be handled though with a pointer to a copy. std::vector paramTypes; + std::vector paramPrecisions; glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); for (int p = 0; p < (int)parameters.size(); ++p) { @@ -1894,12 +1899,14 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF typeId = builder.makePointer(spv::StorageClassFunction, typeId); else constReadOnlyParameters.insert(parameters[p]->getAsSymbolNode()->getId()); + paramPrecisions.push_back(TranslatePrecisionDecoration(paramType)); paramTypes.push_back(typeId); } spv::Block* functionBlock; - spv::Function *function = builder.makeFunctionEntry(convertGlslangToSpvType(glslFunction->getType()), glslFunction->getName().c_str(), - paramTypes, &functionBlock); + spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()), + convertGlslangToSpvType(glslFunction->getType()), + glslFunction->getName().c_str(), paramTypes, paramPrecisions, &functionBlock); // Track function to emit/call later functionMap[glslFunction->getName().c_str()] = function; @@ -2028,7 +2035,7 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if (lvalue) arguments.push_back(builder.accessChainGetLValue()); else - arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(glslangArguments[i]->getAsTyped()->getType()))); + arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); } } @@ -2036,7 +2043,7 @@ void TGlslangToSpvTraverser::translateArguments(glslang::TIntermUnary& node, std { builder.clearAccessChain(); node.getOperand()->traverse(this); - arguments.push_back(builder.accessChainLoad(convertGlslangToSpvType(node.getOperand()->getType()))); + arguments.push_back(accessChainLoad(node.getOperand()->getType())); } spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermOperator* node) @@ -2241,19 +2248,19 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg // 1. Evaluate the arguments std::vector lValues; std::vector rValues; - std::vector argTypes; + std::vector argTypes; for (int a = 0; a < (int)glslangArgs.size(); ++a) { // build l-value builder.clearAccessChain(); glslangArgs[a]->traverse(this); - argTypes.push_back(convertGlslangToSpvType(glslangArgs[a]->getAsTyped()->getType())); + argTypes.push_back(&glslangArgs[a]->getAsTyped()->getType()); // keep outputs as l-values, evaluate input-only as r-values if (qualifiers[a] != glslang::EvqConstReadOnly) { // save l-value lValues.push_back(builder.getAccessChain()); } else { // process r-value - rValues.push_back(builder.accessChainLoad(argTypes.back())); + rValues.push_back(accessChainLoad(*argTypes.back())); } } @@ -2273,7 +2280,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg if (qualifiers[a] == glslang::EvqIn || qualifiers[a] == glslang::EvqInOut) { // need to copy the input into output space builder.setAccessChain(lValues[lValueCount]); - spv::Id copy = builder.accessChainLoad(argTypes[a]); + spv::Id copy = accessChainLoad(*argTypes[a]); builder.createStore(copy, arg); } ++lValueCount; @@ -2286,6 +2293,7 @@ spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAgg // 3. Make the call. spv::Id result = builder.createFunctionCall(function, spvArgs); + builder.setPrecision(result, TranslatePrecisionDecoration(node->getType())); // 4. Copy back out an "out" arguments. lValueCount = 0; @@ -2446,10 +2454,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv if (needMatchingVectors) builder.promoteScalar(precision, left, right); - spv::Id id = builder.createBinOp(binOp, typeId, left, right); - builder.setPrecision(id, precision); - - return id; + return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision); } if (! comparison) @@ -2514,12 +2519,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv break; } - if (binOp != spv::OpNop) { - spv::Id id = builder.createBinOp(binOp, typeId, left, right); - builder.setPrecision(id, precision); - - return id; - } + if (binOp != spv::OpNop) + return builder.setPrecision(builder.createBinOp(binOp, typeId, left, right), precision); return 0; } @@ -2574,12 +2575,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec break; } - if (firstClass) { - spv::Id id = builder.createBinOp(op, typeId, left, right); - builder.setPrecision(id, precision); - - return id; - } + if (firstClass) + return builder.setPrecision(builder.createBinOp(op, typeId, left, right), precision); // Handle component-wise +, -, *, and / for all combinations of type. // The result type of all of them is the same type as the (a) matrix operand. @@ -2619,9 +2616,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec } // put the pieces together - spv::Id id = builder.createCompositeConstruct(typeId, results); - builder.setPrecision(id, precision); - return id; + return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision); } default: assert(0); @@ -2899,13 +2894,11 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv: if (libCall >= 0) { std::vector args; args.push_back(operand); - id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, args); + id = builder.createBuiltinCall(typeId, stdBuiltins, libCall, args); } else id = builder.createUnaryOp(unaryOp, typeId, operand); - builder.setPrecision(id, precision); - - return id; + return builder.setPrecision(id, precision); } // Create a unary operation on a matrix @@ -2935,10 +2928,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Deco } // put the pieces together - spv::Id id = builder.createCompositeConstruct(typeId, results); - builder.setPrecision(id, precision); - - return id; + return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision); } spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destType, spv::Id operand) @@ -3031,9 +3021,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Dec } else result = builder.createUnaryOp(convOp, destType, operand); - builder.setPrecision(result, precision); - - return result; + return builder.setPrecision(result, precision); } spv::Id TGlslangToSpvTraverser::makeSmearedConstant(spv::Id constant, int vectorSize) @@ -3277,7 +3265,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: // Construct the call arguments, without modifying the original operands vector. // We might need the remaining arguments, e.g. in the EOpFrexp case. std::vector callArguments(operands.begin(), operands.begin() + consumedOperands); - id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, callArguments); + id = builder.createBuiltinCall(typeId, stdBuiltins, libCall, callArguments); } else { switch (consumedOperands) { case 0: @@ -3320,9 +3308,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: break; } - builder.setPrecision(id, precision); - - return id; + return builder.setPrecision(id, precision); } // Intrinsics with no arguments, no return value, and no precision. @@ -3644,7 +3630,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan // emit left operand builder.clearAccessChain(); left.traverse(this); - spv::Id leftId = builder.accessChainLoad(boolTypeId); + spv::Id leftId = builder.accessChainLoad(spv::NoPrecision, boolTypeId); // Operands to accumulate OpPhi operands std::vector phiOperands; @@ -3667,7 +3653,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan // emit right operand as the "then" part of the "if" builder.clearAccessChain(); right.traverse(this); - spv::Id rightId = builder.accessChainLoad(boolTypeId); + spv::Id rightId = builder.accessChainLoad(spv::NoPrecision, boolTypeId); // accumulate left operand's phi information phiOperands.push_back(rightId); diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 237496e3..1594da31 100755 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -192,7 +192,7 @@ Id Builder::makeFloatType(int width) // See makeStructResultType() for non-decorated structs // needed as the result of some instructions, which does // check for duplicates. -Id Builder::makeStructType(std::vector& members, const char* name) +Id Builder::makeStructType(const std::vector& members, const char* name) { // Don't look for previous one, because in the general case, // structs can be duplicated except for decorations. @@ -321,7 +321,7 @@ Id Builder::makeRuntimeArray(Id element) return type->getResultId(); } -Id Builder::makeFunctionType(Id returnType, std::vector& paramTypes) +Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) { // try to find it Instruction* type; @@ -805,19 +805,28 @@ Function* Builder::makeMain() Block* entry; std::vector params; + std::vector precisions; - mainFunction = makeFunctionEntry(makeVoidType(), "main", params, &entry); + mainFunction = makeFunctionEntry(NoPrecision, makeVoidType(), "main", params, precisions, &entry); return mainFunction; } // Comments in header -Function* Builder::makeFunctionEntry(Id returnType, const char* name, std::vector& paramTypes, Block **entry) +Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, + const std::vector& paramTypes, const std::vector& precisions, Block **entry) { + // Make the function and initial instructions in it Id typeId = makeFunctionType(returnType, paramTypes); Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size()); Function* function = new Function(getUniqueId(), returnType, typeId, firstParamId, module); + // Set up the precisions + setPrecision(function->getId(), precision); + for (unsigned p = 0; p < (unsigned)precisions.size(); ++p) + setPrecision(firstParamId + p, precisions[p]); + + // CFG if (entry) { *entry = new Block(getUniqueId(), *function); function->addBlock(*entry); @@ -1117,10 +1126,10 @@ Id Builder::createFunctionCall(spv::Function* function, std::vector& ar } // Comments in header -Id Builder::createRvalueSwizzle(Id typeId, Id source, std::vector& channels) +Id Builder::createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector& channels) { if (channels.size() == 1) - return createCompositeExtract(source, typeId, channels.front()); + return setPrecision(createCompositeExtract(source, typeId, channels.front()), precision); Instruction* swizzle = new Instruction(getUniqueId(), typeId, OpVectorShuffle); assert(isVector(source)); @@ -1130,7 +1139,7 @@ Id Builder::createRvalueSwizzle(Id typeId, Id source, std::vector& cha swizzle->addImmediateOperand(channels[i]); buildPoint->addInstruction(std::unique_ptr(swizzle)); - return swizzle->getResultId(); + return setPrecision(swizzle->getResultId(), precision); } // Comments in header @@ -1178,7 +1187,7 @@ void Builder::promoteScalar(Decoration precision, Id& left, Id& right) } // Comments in header -Id Builder::smearScalar(Decoration /*precision*/, Id scalar, Id vectorType) +Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType) { assert(getNumComponents(scalar) == 1); assert(getTypeId(scalar) == getScalarTypeId(vectorType)); @@ -1192,11 +1201,11 @@ Id Builder::smearScalar(Decoration /*precision*/, Id scalar, Id vectorType) smear->addIdOperand(scalar); buildPoint->addInstruction(std::unique_ptr(smear)); - return smear->getResultId(); + return setPrecision(smear->getResultId(), precision); } // Comments in header -Id Builder::createBuiltinCall(Decoration /*precision*/, Id resultType, Id builtins, int entryPoint, std::vector& args) +Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::vector& args) { Instruction* inst = new Instruction(getUniqueId(), resultType, OpExtInst); inst->addIdOperand(builtins); @@ -1205,6 +1214,7 @@ Id Builder::createBuiltinCall(Decoration /*precision*/, Id resultType, Id builti inst->addIdOperand(args[arg]); buildPoint->addInstruction(std::unique_ptr(inst)); + return inst->getResultId(); } @@ -1386,6 +1396,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // Decode the return type that was a special structure createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut); resultId = createCompositeExtract(resultId, typeId0, 0); + setPrecision(resultId, precision); } else { // When a smear is needed, do it, as per what was computed // above when resultType was changed to a scalar type. @@ -1492,7 +1503,6 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b if (isScalarType(valueType)) { // scalar resultId = createBinOp(op, boolType, value1, value2); - setPrecision(resultId, precision); } else { // vector resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2); @@ -1501,7 +1511,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b resultId = createUnaryOp(equal ? OpAll : OpAny, boolType, resultId); } - return resultId; + return setPrecision(resultId, precision); } // Only structs, arrays, and matrices should be left. @@ -1521,7 +1531,7 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b if (constituent == 0) resultId = subResultId; else - resultId = createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId); + resultId = setPrecision(createBinOp(equal ? OpLogicalAnd : OpLogicalOr, boolType, resultId, subResultId), precision); } return resultId; @@ -1543,7 +1553,7 @@ Id Builder::createCompositeConstruct(Id typeId, std::vector& constituents) // Vector or scalar constructor Id Builder::createConstructor(Decoration precision, const std::vector& sources, Id resultTypeId) { - Id result = 0; + Id result = NoResult; unsigned int numTargetComponents = getNumTypeComponents(resultTypeId); unsigned int targetComponent = 0; @@ -1566,7 +1576,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc if (sourceSize > 1) { std::vector swiz; swiz.push_back(s); - arg = createRvalueSwizzle(scalarTypeId, arg, swiz); + arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz); } if (numTargetComponents > 1) @@ -1583,9 +1593,7 @@ Id Builder::createConstructor(Decoration precision, const std::vector& sourc if (constituents.size() > 0) result = createCompositeConstruct(resultTypeId, constituents); - setPrecision(result, precision); - - return result; + return setPrecision(result, precision); } // Comments in header @@ -1666,11 +1674,13 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& std::vector vectorComponents; for (int row = 0; row < numRows; ++row) vectorComponents.push_back(ids[col][row]); - matrixColumns.push_back(createCompositeConstruct(columnTypeId, vectorComponents)); + Id column = createCompositeConstruct(columnTypeId, vectorComponents); + setPrecision(column, precision); + matrixColumns.push_back(column); } // make the matrix - return createCompositeConstruct(resultTypeId, matrixColumns); + return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision); } // Comments in header @@ -1895,7 +1905,7 @@ void Builder::accessChainStore(Id rvalue) } // Comments in header -Id Builder::accessChainLoad(Id resultType) +Id Builder::accessChainLoad(Decoration precision, Id resultType) { Id id; @@ -1904,7 +1914,7 @@ Id Builder::accessChainLoad(Id resultType) transferAccessChainSwizzle(false); if (accessChain.indexChain.size() > 0) { Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType; - + // if all the accesses are constants, we can use OpCompositeExtract std::vector indexes; bool constant = true; @@ -1933,12 +1943,14 @@ Id Builder::accessChainLoad(Id resultType) // load through the access chain id = createLoad(collapseAccessChain()); } + setPrecision(id, precision); } else - id = accessChain.base; + id = accessChain.base; // no precision, it was set when this was defined } else { transferAccessChainSwizzle(true); // load through the access chain id = createLoad(collapseAccessChain()); + setPrecision(id, precision); } // Done, unless there are swizzles to do @@ -1952,12 +1964,12 @@ Id Builder::accessChainLoad(Id resultType) Id swizzledType = getScalarTypeId(getTypeId(id)); if (accessChain.swizzle.size() > 1) swizzledType = makeVectorType(swizzledType, (int)accessChain.swizzle.size()); - id = createRvalueSwizzle(swizzledType, id, accessChain.swizzle); + id = createRvalueSwizzle(precision, swizzledType, id, accessChain.swizzle); } // dynamic single-component selection if (accessChain.component != NoResult) - id = createVectorExtractDynamic(id, resultType, accessChain.component); + id = setPrecision(createVectorExtractDynamic(id, resultType, accessChain.component), precision); return id; } diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h index fbfbfad0..00516c82 100755 --- a/SPIRV/SpvBuilder.h +++ b/SPIRV/SpvBuilder.h @@ -100,13 +100,13 @@ public: Id makeIntType(int width) { return makeIntegerType(width, true); } Id makeUintType(int width) { return makeIntegerType(width, false); } Id makeFloatType(int width); - Id makeStructType(std::vector& members, const char*); + Id makeStructType(const std::vector& members, const char*); Id makeStructResultType(Id type0, Id type1); Id makeVectorType(Id component, int size); Id makeMatrixType(Id component, int cols, int rows); Id makeArrayType(Id element, unsigned size, int stride); // 0 means no stride decoration Id makeRuntimeArray(Id element); - Id makeFunctionType(Id returnType, std::vector& paramTypes); + Id makeFunctionType(Id returnType, const std::vector& paramTypes); Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format); Id makeSamplerType(); Id makeSampledImageType(Id imageType); @@ -210,7 +210,8 @@ public: // Make a shader-style function, and create its entry block if entry is non-zero. // Return the function, pass back the entry. // The returned pointer is only valid for the lifetime of this builder. - Function* makeFunctionEntry(Id returnType, const char* name, std::vector& paramTypes, Block **entry = 0); + Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector& paramTypes, + const std::vector& precisions, Block **entry = 0); // Create a return. An 'implicit' return is one not appearing in the source // code. In the case of an implicit return, no post-return block is inserted. @@ -225,7 +226,7 @@ public: // Create a global or function local or IO variable. Id createVariable(StorageClass, Id type, const char* name = 0); - // Create an imtermediate with an undefined value. + // Create an intermediate with an undefined value. Id createUndefined(Id type); // Store into an Id and return the l-value @@ -262,7 +263,7 @@ public: // Take an rvalue (source) and a set of channels to extract from it to // make a new rvalue, which is returned. - Id createRvalueSwizzle(Id typeId, Id source, std::vector& channels); + Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, std::vector& channels); // Take a copy of an lvalue (target) and a source of components, and set the // source components into the lvalue where the 'channels' say to put them. @@ -270,13 +271,15 @@ public: // (No true lvalue or stores are used.) Id createLvalueSwizzle(Id typeId, Id target, Id source, std::vector& channels); - // If the value passed in is an instruction and the precision is not NoPrecision, - // it gets tagged with the requested precision. - void setPrecision(Id /* value */, Decoration precision) + // If both the id and precision are valid, the id + // gets tagged with the requested precision. + // The passed in id is always the returned id, to simplify use patterns. + Id setPrecision(Id id, Decoration precision) { - if (precision != NoPrecision) { - ;// TODO - } + if (precision != NoPrecision && id != NoResult) + addDecoration(id, precision); + + return id; } // Can smear a scalar to a vector for the following forms: @@ -299,7 +302,7 @@ public: Id smearScalar(Decoration precision, Id scalarVal, Id vectorType); // Create a call to a built-in function. - Id createBuiltinCall(Decoration precision, Id resultType, Id builtins, int entryPoint, std::vector& args); + Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, std::vector& args); // List of parameters used to create a texture operation struct TextureParameters { @@ -330,7 +333,7 @@ public: Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned); Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id); - // Reduction comparision for composites: For equal and not-equal resulting in a scalar. + // Reduction comparison for composites: For equal and not-equal resulting in a scalar. Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */); // OpCompositeConstruct @@ -498,7 +501,7 @@ public: void accessChainStore(Id rvalue); // use accessChain and swizzle to load an r-value - Id accessChainLoad(Id ResultType); + Id accessChainLoad(Decoration precision, Id ResultType); // get the direct pointer for an l-value Id accessChainGetLValue(); diff --git a/Test/baseResults/spv.100ops.frag.out b/Test/baseResults/spv.100ops.frag.out index 82342324..1d00037c 100755 --- a/Test/baseResults/spv.100ops.frag.out +++ b/Test/baseResults/spv.100ops.frag.out @@ -23,12 +23,28 @@ Linked fragment stage: Name 21 "low" Name 26 "high" Name 36 "Color" + Decorate 8(foo() RelaxedPrecision Decorate 11(face1) RelaxedPrecision Decorate 13(face2) RelaxedPrecision Decorate 17(z) RelaxedPrecision Decorate 21(low) RelaxedPrecision + Decorate 22 RelaxedPrecision + Decorate 23 RelaxedPrecision + Decorate 25 RelaxedPrecision Decorate 26(high) RelaxedPrecision + Decorate 27 RelaxedPrecision + Decorate 32 RelaxedPrecision + Decorate 33 RelaxedPrecision Decorate 36(Color) RelaxedPrecision + Decorate 37 RelaxedPrecision + Decorate 38 RelaxedPrecision + Decorate 39 RelaxedPrecision + Decorate 40 RelaxedPrecision + Decorate 41 RelaxedPrecision + Decorate 42 RelaxedPrecision + Decorate 43 RelaxedPrecision + Decorate 44 RelaxedPrecision + Decorate 45 RelaxedPrecision 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/spv.300BuiltIns.vert.out b/Test/baseResults/spv.300BuiltIns.vert.out index dbe9fa1d..a8dd6221 100755 --- a/Test/baseResults/spv.300BuiltIns.vert.out +++ b/Test/baseResults/spv.300BuiltIns.vert.out @@ -32,6 +32,10 @@ Linked vertex stage: MemberDecorate 22(gl_PerVertex) 1 BuiltIn PointSize Decorate 22(gl_PerVertex) Block Decorate 27(ps) RelaxedPrecision + Decorate 28 RelaxedPrecision + Decorate 32 RelaxedPrecision + Decorate 39 RelaxedPrecision + Decorate 42 RelaxedPrecision Decorate 48(gl_InstanceID) BuiltIn InstanceId 2: TypeVoid 3: TypeFunction 2 diff --git a/Test/baseResults/spv.300layout.frag.out b/Test/baseResults/spv.300layout.frag.out index 2876822e..ed39d5a6 100755 --- a/Test/baseResults/spv.300layout.frag.out +++ b/Test/baseResults/spv.300layout.frag.out @@ -27,11 +27,17 @@ Linked fragment stage: Decorate 9(c) RelaxedPrecision Decorate 9(c) Location 7 Decorate 11(color) RelaxedPrecision + Decorate 12 RelaxedPrecision MemberDecorate 13(S) 0 RelaxedPrecision MemberDecorate 13(S) 1 RelaxedPrecision + Decorate 19 RelaxedPrecision + Decorate 20 RelaxedPrecision Decorate 26(p) RelaxedPrecision Decorate 26(p) Location 3 Decorate 29(pos) RelaxedPrecision + Decorate 30 RelaxedPrecision + Decorate 33 RelaxedPrecision + Decorate 34 RelaxedPrecision 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/spv.intOps.vert.out b/Test/baseResults/spv.intOps.vert.out index 799d4cf4..86a52190 100644 --- a/Test/baseResults/spv.intOps.vert.out +++ b/Test/baseResults/spv.intOps.vert.out @@ -46,6 +46,8 @@ Linked vertex stage: Name 247 "v4" Name 268 "gl_VertexID" Name 269 "gl_InstanceID" + Decorate 261 RelaxedPrecision + Decorate 265 RelaxedPrecision Decorate 268(gl_VertexID) BuiltIn VertexId Decorate 269(gl_InstanceID) BuiltIn InstanceId 2: TypeVoid diff --git a/Test/baseResults/spv.precision.frag.out b/Test/baseResults/spv.precision.frag.out index 27e48f1e..f454b857 100755 --- a/Test/baseResults/spv.precision.frag.out +++ b/Test/baseResults/spv.precision.frag.out @@ -7,12 +7,12 @@ Linked fragment stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 114 +// Id's are bound by 127 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Fragment 4 "main" 23 59 61 73 + EntryPoint Fragment 4 "main" 23 59 61 73 116 ExecutionMode 4 OriginLowerLeft Source ESSL 310 Name 4 "main" @@ -35,15 +35,58 @@ Linked fragment stage: Name 73 "mediumfout" Name 104 "ub2" Name 105 "param" + Name 114 "S" + MemberName 114(S) 0 "a" + MemberName 114(S) 1 "b" + Name 116 "s" + Decorate 12(foo(vf3;) RelaxedPrecision + Decorate 11(mv3) RelaxedPrecision Decorate 38(sum) RelaxedPrecision Decorate 40(uniform_medium) RelaxedPrecision + Decorate 41 RelaxedPrecision + Decorate 46 RelaxedPrecision Decorate 48(uniform_low) RelaxedPrecision + Decorate 49 RelaxedPrecision + Decorate 50 RelaxedPrecision + Decorate 51 RelaxedPrecision Decorate 53(arg1) RelaxedPrecision Decorate 55(arg2) RelaxedPrecision Decorate 57(d) RelaxedPrecision Decorate 59(lowfin) RelaxedPrecision + Decorate 60 RelaxedPrecision Decorate 61(mediumfin) RelaxedPrecision + Decorate 62 RelaxedPrecision + Decorate 63 RelaxedPrecision Decorate 73(mediumfout) RelaxedPrecision + Decorate 74 RelaxedPrecision + Decorate 75 RelaxedPrecision + Decorate 76 RelaxedPrecision + Decorate 77 RelaxedPrecision + Decorate 78 RelaxedPrecision + Decorate 79 RelaxedPrecision + Decorate 83 RelaxedPrecision + Decorate 85 RelaxedPrecision + Decorate 87 RelaxedPrecision + Decorate 88 RelaxedPrecision + Decorate 90 RelaxedPrecision + Decorate 91 RelaxedPrecision + Decorate 94 RelaxedPrecision + Decorate 95 RelaxedPrecision + Decorate 96 RelaxedPrecision + Decorate 97 RelaxedPrecision + Decorate 98 RelaxedPrecision + Decorate 99 RelaxedPrecision + Decorate 100 RelaxedPrecision + Decorate 101 RelaxedPrecision + Decorate 102 RelaxedPrecision + Decorate 110 RelaxedPrecision + Decorate 112 RelaxedPrecision + Decorate 113 RelaxedPrecision + MemberDecorate 114(S) 1 RelaxedPrecision + Decorate 120 RelaxedPrecision + Decorate 124 RelaxedPrecision + Decorate 125 RelaxedPrecision + Decorate 126 RelaxedPrecision 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -85,6 +128,11 @@ Linked fragment stage: 103: TypePointer UniformConstant 15(bvec2) 104(ub2): 103(ptr) Variable UniformConstant 111: 6(float) Constant 1065353216 + 114(S): TypeStruct 6(float) 6(float) + 115: TypePointer Input 114(S) + 116(s): 115(ptr) Variable Input + 117: 36(int) Constant 0 + 122: 36(int) Constant 1 4(main): 2 Function None 3 5: Label 38(sum): 37(ptr) Variable Function @@ -157,6 +205,16 @@ Linked fragment stage: Store 73(mediumfout) 113 Branch 109 109: Label + 118: 58(ptr) AccessChain 116(s) 117 + 119: 6(float) Load 118 + 120: 21(fvec4) Load 73(mediumfout) + 121: 21(fvec4) VectorTimesScalar 120 119 + Store 73(mediumfout) 121 + 123: 58(ptr) AccessChain 116(s) 122 + 124: 6(float) Load 123 + 125: 21(fvec4) Load 73(mediumfout) + 126: 21(fvec4) VectorTimesScalar 125 124 + Store 73(mediumfout) 126 Return FunctionEnd 12(foo(vf3;): 9(fvec2) Function None 10 diff --git a/Test/baseResults/spv.switch.frag.out b/Test/baseResults/spv.switch.frag.out index 74f4463a..f96ec88f 100755 --- a/Test/baseResults/spv.switch.frag.out +++ b/Test/baseResults/spv.switch.frag.out @@ -42,15 +42,137 @@ Linked fragment stage: Name 246 "param" Name 248 "param" Name 250 "param" + Decorate 15(foo1(vf4;vf4;i1;) RelaxedPrecision + Decorate 12(v1) RelaxedPrecision + Decorate 13(v2) RelaxedPrecision + Decorate 14(i1) RelaxedPrecision + Decorate 20(foo2(vf4;vf4;i1;) RelaxedPrecision + Decorate 17(v1) RelaxedPrecision + Decorate 18(v2) RelaxedPrecision + Decorate 19(i1) RelaxedPrecision + Decorate 22 RelaxedPrecision + Decorate 27 RelaxedPrecision + Decorate 29 RelaxedPrecision + Decorate 31 RelaxedPrecision + Decorate 32 RelaxedPrecision + Decorate 33 RelaxedPrecision + Decorate 40 RelaxedPrecision + Decorate 46 RelaxedPrecision + Decorate 51 RelaxedPrecision + Decorate 53 RelaxedPrecision + Decorate 54 RelaxedPrecision + Decorate 55 RelaxedPrecision Decorate 60(local) RelaxedPrecision Decorate 62(c) RelaxedPrecision + Decorate 63 RelaxedPrecision + Decorate 64 RelaxedPrecision + Decorate 66 RelaxedPrecision + Decorate 67 RelaxedPrecision Decorate 73(f) RelaxedPrecision Decorate 75(x) RelaxedPrecision + Decorate 76 RelaxedPrecision + Decorate 77 RelaxedPrecision + Decorate 79 RelaxedPrecision + Decorate 80 RelaxedPrecision + Decorate 82 RelaxedPrecision + Decorate 83 RelaxedPrecision + Decorate 85 RelaxedPrecision + Decorate 90 RelaxedPrecision + Decorate 91 RelaxedPrecision + Decorate 92 RelaxedPrecision + Decorate 93 RelaxedPrecision + Decorate 94 RelaxedPrecision + Decorate 95 RelaxedPrecision + Decorate 96 RelaxedPrecision + Decorate 97 RelaxedPrecision + Decorate 99 RelaxedPrecision + Decorate 100 RelaxedPrecision + Decorate 101 RelaxedPrecision + Decorate 102 RelaxedPrecision + Decorate 104 RelaxedPrecision + Decorate 108 RelaxedPrecision + Decorate 109 RelaxedPrecision + Decorate 110 RelaxedPrecision + Decorate 111 RelaxedPrecision + Decorate 113 RelaxedPrecision + Decorate 114 RelaxedPrecision + Decorate 115 RelaxedPrecision + Decorate 116 RelaxedPrecision + Decorate 119 RelaxedPrecision + Decorate 124 RelaxedPrecision + Decorate 125 RelaxedPrecision + Decorate 126 RelaxedPrecision + Decorate 127 RelaxedPrecision Decorate 129(d) RelaxedPrecision + Decorate 130 RelaxedPrecision + Decorate 134 RelaxedPrecision + Decorate 135 RelaxedPrecision + Decorate 136 RelaxedPrecision + Decorate 137 RelaxedPrecision + Decorate 138 RelaxedPrecision + Decorate 139 RelaxedPrecision + Decorate 140 RelaxedPrecision + Decorate 142 RelaxedPrecision + Decorate 143 RelaxedPrecision + Decorate 144 RelaxedPrecision + Decorate 145 RelaxedPrecision + Decorate 146 RelaxedPrecision + Decorate 150 RelaxedPrecision + Decorate 151 RelaxedPrecision + Decorate 152 RelaxedPrecision + Decorate 153 RelaxedPrecision Decorate 155(i) RelaxedPrecision + Decorate 162 RelaxedPrecision + Decorate 166 RelaxedPrecision + Decorate 171 RelaxedPrecision + Decorate 172 RelaxedPrecision + Decorate 173 RelaxedPrecision + Decorate 174 RelaxedPrecision Decorate 175(j) RelaxedPrecision + Decorate 182 RelaxedPrecision + Decorate 185 RelaxedPrecision + Decorate 186 RelaxedPrecision + Decorate 187 RelaxedPrecision + Decorate 193 RelaxedPrecision + Decorate 194 RelaxedPrecision + Decorate 196 RelaxedPrecision + Decorate 197 RelaxedPrecision + Decorate 198 RelaxedPrecision + Decorate 199 RelaxedPrecision + Decorate 202 RelaxedPrecision + Decorate 203 RelaxedPrecision + Decorate 204 RelaxedPrecision + Decorate 205 RelaxedPrecision + Decorate 207 RelaxedPrecision + Decorate 213 RelaxedPrecision + Decorate 214 RelaxedPrecision + Decorate 215 RelaxedPrecision + Decorate 219 RelaxedPrecision + Decorate 220 RelaxedPrecision + Decorate 221 RelaxedPrecision + Decorate 222 RelaxedPrecision Decorate 227(color) RelaxedPrecision + Decorate 228 RelaxedPrecision + Decorate 229 RelaxedPrecision + Decorate 230 RelaxedPrecision + Decorate 231 RelaxedPrecision Decorate 233(v) RelaxedPrecision + Decorate 235 RelaxedPrecision + Decorate 237 RelaxedPrecision + Decorate 239 RelaxedPrecision + Decorate 240 RelaxedPrecision + Decorate 243 RelaxedPrecision + Decorate 244 RelaxedPrecision + Decorate 245 RelaxedPrecision + Decorate 247 RelaxedPrecision + Decorate 249 RelaxedPrecision + Decorate 251 RelaxedPrecision + Decorate 252 RelaxedPrecision + Decorate 254 RelaxedPrecision + Decorate 255 RelaxedPrecision + Decorate 256 RelaxedPrecision + Decorate 257 RelaxedPrecision + Decorate 264 RelaxedPrecision 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/spv.uint.frag.out b/Test/baseResults/spv.uint.frag.out index 8c732dc8..4ac9c58f 100755 --- a/Test/baseResults/spv.uint.frag.out +++ b/Test/baseResults/spv.uint.frag.out @@ -41,19 +41,102 @@ Linked fragment stage: Decorate 12(u) RelaxedPrecision Decorate 15(t) RelaxedPrecision Decorate 15(t) Flat + Decorate 19 RelaxedPrecision + Decorate 21 RelaxedPrecision + Decorate 27 RelaxedPrecision + Decorate 28 RelaxedPrecision + Decorate 32 RelaxedPrecision + Decorate 33 RelaxedPrecision + Decorate 38 RelaxedPrecision + Decorate 39 RelaxedPrecision + Decorate 43 RelaxedPrecision + Decorate 44 RelaxedPrecision + Decorate 48 RelaxedPrecision + Decorate 49 RelaxedPrecision + Decorate 53 RelaxedPrecision + Decorate 54 RelaxedPrecision Decorate 55(shiftedii) RelaxedPrecision Decorate 57(shiftedui) RelaxedPrecision Decorate 59(shiftediu) RelaxedPrecision Decorate 60(shifteduu) RelaxedPrecision + Decorate 61 RelaxedPrecision + Decorate 62 RelaxedPrecision Decorate 68(c) RelaxedPrecision Decorate 72(usampler) RelaxedPrecision + Decorate 73 RelaxedPrecision Decorate 77(tc) RelaxedPrecision + Decorate 78 RelaxedPrecision + Decorate 79 RelaxedPrecision + Decorate 80 RelaxedPrecision + Decorate 81 RelaxedPrecision + Decorate 85 RelaxedPrecision + Decorate 86 RelaxedPrecision + Decorate 88 RelaxedPrecision + Decorate 89 RelaxedPrecision + Decorate 90 RelaxedPrecision + Decorate 91 RelaxedPrecision + Decorate 92 RelaxedPrecision + Decorate 97 RelaxedPrecision + Decorate 98 RelaxedPrecision + Decorate 101 RelaxedPrecision + Decorate 102 RelaxedPrecision + Decorate 105 RelaxedPrecision Decorate 111(af) RelaxedPrecision + Decorate 112 RelaxedPrecision + Decorate 113 RelaxedPrecision + Decorate 116 RelaxedPrecision Decorate 118(ai) RelaxedPrecision + Decorate 119 RelaxedPrecision + Decorate 120 RelaxedPrecision + Decorate 121 RelaxedPrecision + Decorate 122 RelaxedPrecision + Decorate 124 RelaxedPrecision + Decorate 125 RelaxedPrecision + Decorate 126 RelaxedPrecision + Decorate 127 RelaxedPrecision + Decorate 128 RelaxedPrecision + Decorate 129 RelaxedPrecision + Decorate 130 RelaxedPrecision + Decorate 131 RelaxedPrecision + Decorate 135 RelaxedPrecision + Decorate 136 RelaxedPrecision + Decorate 140 RelaxedPrecision + Decorate 141 RelaxedPrecision + Decorate 145 RelaxedPrecision + Decorate 146 RelaxedPrecision + Decorate 150 RelaxedPrecision + Decorate 151 RelaxedPrecision Decorate 152(mask1) RelaxedPrecision Decorate 154(mask2) RelaxedPrecision Decorate 156(mask3) RelaxedPrecision + Decorate 157 RelaxedPrecision + Decorate 159 RelaxedPrecision Decorate 160(mask4) RelaxedPrecision + Decorate 162 RelaxedPrecision + Decorate 163 RelaxedPrecision + Decorate 167 RelaxedPrecision + Decorate 168 RelaxedPrecision + Decorate 169 RelaxedPrecision + Decorate 170 RelaxedPrecision + Decorate 171 RelaxedPrecision + Decorate 175 RelaxedPrecision + Decorate 176 RelaxedPrecision + Decorate 177 RelaxedPrecision + Decorate 178 RelaxedPrecision + Decorate 179 RelaxedPrecision + Decorate 180 RelaxedPrecision + Decorate 184 RelaxedPrecision + Decorate 185 RelaxedPrecision + Decorate 186 RelaxedPrecision + Decorate 187 RelaxedPrecision + Decorate 188 RelaxedPrecision + Decorate 192 RelaxedPrecision + Decorate 193 RelaxedPrecision + Decorate 194 RelaxedPrecision + Decorate 195 RelaxedPrecision + Decorate 196 RelaxedPrecision + Decorate 197 RelaxedPrecision + Decorate 198 RelaxedPrecision Decorate 200(f) RelaxedPrecision Decorate 202(v) RelaxedPrecision Decorate 204(i) RelaxedPrecision diff --git a/Test/spv.precision.frag b/Test/spv.precision.frag index 40f790a2..997e4ead 100644 --- a/Test/spv.precision.frag +++ b/Test/spv.precision.frag @@ -23,6 +23,13 @@ bool boolfun(bvec2 bv2) return bv2 == bvec2(false, true); } +struct S { + highp float a; + lowp float b; +}; + +in S s; + void main() { lowp int sum = uniform_medium + uniform_high; @@ -47,4 +54,7 @@ void main() if (boolfun(ub2)) ++mediumfout; + + mediumfout *= s.a; + mediumfout *= s.b; }