mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-09 20:10:06 +00:00
HLSL: Fix #846: support mixed ternary types.
Vector conditions properly convert the true/false expression types to same width vector as the condition. Scalar conditions make the true/false expressions convert to each other.
This commit is contained in:
parent
0603a383c1
commit
32a385e9d7
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,14 @@ float4 vectorCond()
|
|||||||
{
|
{
|
||||||
return (c4 ? t4 : f4) +
|
return (c4 ? t4 : f4) +
|
||||||
(c4 ? t : f ) +
|
(c4 ? t : f ) +
|
||||||
(t4 < f4 ? t4 : f4);
|
(t4 < f4 ? t4 : f4) +
|
||||||
|
(c4 ? t : f4);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 scalarCond()
|
||||||
|
{
|
||||||
|
float4 ret = t != f ? t * f4 : 1;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
float2 fbSelect(bool2 cnd, float2 src0, float2 src1)
|
float2 fbSelect(bool2 cnd, float2 src0, float2 src1)
|
||||||
@ -30,6 +37,6 @@ float4 PixelShaderFunction(float4 input) : COLOR0
|
|||||||
e = a = b ? c = d : 10, b = a ? d = c : 11;
|
e = a = b ? c = d : 10, b = a ? d = c : 11;
|
||||||
float4 f;
|
float4 f;
|
||||||
f = ret.x < input.y ? c * input : d * input;
|
f = ret.x < input.y ? c * input : d * input;
|
||||||
return e * ret + f + vectorCond() +
|
return e * ret + f + vectorCond() + scalarCond() +
|
||||||
float4(fbSelect(bool2(true, false), float2(1.0, 2.0), float2(3.0, 4.0)), 10.0, 10.0);
|
float4(fbSelect(bool2(true, false), float2(1.0, 2.0), float2(3.0, 4.0)), 10.0, 10.0);
|
||||||
}
|
}
|
||||||
|
@ -836,6 +836,9 @@ TIntermTyped* TIntermediate::addUniShapeConversion(TOperator op, const TType& ty
|
|||||||
case EOpAssign:
|
case EOpAssign:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EOpMix:
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -911,6 +914,8 @@ void TIntermediate::addBiShapeConversion(TOperator op, TIntermTyped*& lhsNode, T
|
|||||||
case EOpAnd:
|
case EOpAnd:
|
||||||
case EOpInclusiveOr:
|
case EOpInclusiveOr:
|
||||||
case EOpExclusiveOr:
|
case EOpExclusiveOr:
|
||||||
|
|
||||||
|
case EOpMix:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1422,19 +1427,17 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// After conversion, types have to match.
|
|
||||||
if (falseBlock->getType() != trueBlock->getType())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// Handle a vector condition as a mix
|
// Handle a vector condition as a mix
|
||||||
if (!cond->getType().isScalarOrVec1()) {
|
if (!cond->getType().isScalarOrVec1()) {
|
||||||
TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
|
TType targetVectorType(trueBlock->getType().getBasicType(), EvqTemporary,
|
||||||
cond->getType().getVectorSize());
|
cond->getType().getVectorSize());
|
||||||
// smear true/false operations if needed
|
// smear true/false operands as needed
|
||||||
if (trueBlock->getType().isScalarOrVec1())
|
trueBlock = addUniShapeConversion(EOpMix, targetVectorType, trueBlock);
|
||||||
trueBlock = addShapeConversion(targetVectorType, trueBlock);
|
falseBlock = addUniShapeConversion(EOpMix, targetVectorType, falseBlock);
|
||||||
if (falseBlock->getType().isScalarOrVec1())
|
|
||||||
falseBlock = addShapeConversion(targetVectorType, falseBlock);
|
// After conversion, types have to match.
|
||||||
|
if (falseBlock->getType() != trueBlock->getType())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// make the mix operation
|
// make the mix operation
|
||||||
TIntermAggregate* mix = makeAggregate(loc);
|
TIntermAggregate* mix = makeAggregate(loc);
|
||||||
@ -1449,6 +1452,13 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
|
|||||||
|
|
||||||
// Now have a scalar condition...
|
// Now have a scalar condition...
|
||||||
|
|
||||||
|
// Convert true and false expressions to matching types
|
||||||
|
addBiShapeConversion(EOpMix, trueBlock, falseBlock);
|
||||||
|
|
||||||
|
// After conversion, types have to match.
|
||||||
|
if (falseBlock->getType() != trueBlock->getType())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
// Eliminate the selection when the condition is a scalar and all operands are constant.
|
// Eliminate the selection when the condition is a scalar and all operands are constant.
|
||||||
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
|
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
|
||||||
if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
|
if (cond->getAsConstantUnion()->getConstArray()[0].getBConst())
|
||||||
|
Loading…
Reference in New Issue
Block a user