Commit 636b62db by John Kessenich

HLSL: Support vector 'cond ? :' -> EOpMix -> OpSelect.

parent 34718204
......@@ -6,8 +6,8 @@ float f;
float4 vectorCond()
{
return f4; // return (c4 ? t4 : f4) +
// (c4 ? t : f );
return (c4 ? t4 : f4) +
(c4 ? t : f );
}
float4 PixelShaderFunction(float4 input) : COLOR0
......
......@@ -1271,7 +1271,8 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
//
// For "?:" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are specified
// as separate parameters.
// as separate parameters. For vector 'cond', the true and false
// are not paths, but vectors to mix.
//
// Specialization constant operations include
// - The ternary operator ( ? : )
......@@ -1304,10 +1305,30 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
if (falseBlock->getType() != trueBlock->getType())
return nullptr;
//
// See if all the operands are constant, then fold it otherwise not.
//
// Handle a vector condition as a mix
if (!cond->getType().isScalarOrVec1()) {
TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
cond->getType().getVectorSize());
// smear true/false operations if needed
if (trueBlock->getType().isScalarOrVec1())
trueBlock = addShapeConversion(EOpAssign, targetVectorType, trueBlock);
if (falseBlock->getType().isScalarOrVec1())
falseBlock = addShapeConversion(EOpAssign, targetVectorType, falseBlock);
// make the mix operation
TIntermAggregate* mix = makeAggregate(loc);
mix = growAggregate(mix, falseBlock);
mix = growAggregate(mix, trueBlock);
mix = growAggregate(mix, cond);
mix->setType(targetVectorType);
mix->setOp(EOpMix);
return mix;
}
// Now have a scalar condition...
// Eliminate the selection when the condition is a scalar and all operands are constant.
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
return trueBlock;
......
......@@ -2536,7 +2536,7 @@ bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
if (! acceptTokenClass(EHTokQuestion))
return true;
node = parseContext.convertConditionalExpression(token.loc, node);
node = parseContext.convertConditionalExpression(token.loc, node, false);
if (node == nullptr)
return false;
......
......@@ -4529,9 +4529,9 @@ void HlslParseContext::handleRegister(const TSourceLoc& loc, TQualifier& qualifi
// Convert to a scalar boolean, or if not allowed by HLSL semantics,
// report an error and return nullptr.
TIntermTyped* HlslParseContext::convertConditionalExpression(const TSourceLoc& loc, TIntermTyped* condition)
TIntermTyped* HlslParseContext::convertConditionalExpression(const TSourceLoc& loc, TIntermTyped* condition, bool mustBeScalar)
{
if (!condition->getType().isScalarOrVec1()) {
if (mustBeScalar && !condition->getType().isScalarOrVec1()) {
error(loc, "requires a scalar", "conditional expression", "");
return nullptr;
}
......
......@@ -102,7 +102,7 @@ public:
const glslang::TString* component);
void handleRegister(const TSourceLoc&, TQualifier&, const glslang::TString* profile, const glslang::TString& desc,
int subComponent, const glslang::TString*);
TIntermTyped* convertConditionalExpression(const TSourceLoc&, TIntermTyped*);
TIntermTyped* convertConditionalExpression(const TSourceLoc&, TIntermTyped*, bool mustBeScalar = true);
TIntermAggregate* handleSamplerTextureCombine(const TSourceLoc& loc, TIntermTyped* argTex, TIntermTyped* argSampler);
bool parseMatrixSwizzleSelector(const TSourceLoc&, const TString&, int cols, int rows, TSwizzleSelectors<TMatrixSelector>&);
......
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