Non-functional: correctly do GL_EXT_buffer_reference2 semantic checking
See #2366 for detail.
This commit is contained in:
parent
6c37bbbb03
commit
d8daeb4323
8 changed files with 1253 additions and 1240 deletions
|
|
@ -120,7 +120,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
return nullptr;
|
||||
|
||||
// Convert "reference +/- int" and "reference - reference" to integer math
|
||||
if ((op == EOpAdd || op == EOpSub) && extensionRequested(E_GL_EXT_buffer_reference2)) {
|
||||
if (op == EOpAdd || op == EOpSub) {
|
||||
|
||||
// No addressing math on struct with unsized array.
|
||||
if ((left->isReference() && left->getType().getReferentType()->containsUnsizedArray()) ||
|
||||
|
|
@ -140,41 +140,42 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
|
|||
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
|
||||
const TType& referenceType = right->getType();
|
||||
TIntermConstantUnion* size = addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
|
||||
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
||||
|
||||
left = createConversion(EbtInt64, left);
|
||||
left = addBinaryMath(EOpMul, left, size, loc);
|
||||
|
||||
TIntermTyped *node = addBinaryMath(op, left, right, loc);
|
||||
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (op == EOpSub && left->isReference() && right->isReference()) {
|
||||
TIntermConstantUnion* size = addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
|
||||
|
||||
left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
|
||||
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
||||
|
||||
left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64));
|
||||
right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64));
|
||||
|
||||
left = addBinaryMath(EOpSub, left, right, loc);
|
||||
|
||||
TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
|
||||
return node;
|
||||
}
|
||||
|
||||
// No other math operators supported on references
|
||||
if (left->isReference() || right->isReference()) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (op == EOpAdd && right->isReference() && isTypeInt(left->getBasicType())) {
|
||||
const TType& referenceType = right->getType();
|
||||
TIntermConstantUnion* size =
|
||||
addConstantUnion((unsigned long long)computeBufferReferenceTypeSize(right->getType()), loc, true);
|
||||
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
||||
|
||||
left = createConversion(EbtInt64, left);
|
||||
left = addBinaryMath(EOpMul, left, size, loc);
|
||||
|
||||
TIntermTyped *node = addBinaryMath(op, left, right, loc);
|
||||
node = addBuiltInFunctionCall(loc, EOpConvUint64ToPtr, true, node, referenceType);
|
||||
return node;
|
||||
}
|
||||
|
||||
if (op == EOpSub && left->isReference() && right->isReference()) {
|
||||
TIntermConstantUnion* size =
|
||||
addConstantUnion((long long)computeBufferReferenceTypeSize(left->getType()), loc, true);
|
||||
|
||||
left = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, left, TType(EbtUint64));
|
||||
right = addBuiltInFunctionCall(loc, EOpConvPtrToUint64, true, right, TType(EbtUint64));
|
||||
|
||||
left = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, left, TType(EbtInt64));
|
||||
right = addBuiltInFunctionCall(loc, EOpConvUint64ToInt64, true, right, TType(EbtInt64));
|
||||
|
||||
left = addBinaryMath(EOpSub, left, right, loc);
|
||||
|
||||
TIntermTyped *node = addBinaryMath(EOpDiv, left, size, loc);
|
||||
return node;
|
||||
}
|
||||
|
||||
// No other math operators supported on references
|
||||
if (left->isReference() || right->isReference())
|
||||
return nullptr;
|
||||
|
||||
// Try converting the children's base types to compatible types.
|
||||
auto children = addConversion(op, left, right);
|
||||
left = std::get<0>(children);
|
||||
|
|
@ -290,9 +291,7 @@ TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TInterm
|
|||
// Convert "reference += int" to "reference = reference + int". We need this because the
|
||||
// "reference + int" calculation involves a cast back to the original type, which makes it
|
||||
// not an lvalue.
|
||||
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference() &&
|
||||
extensionRequested(E_GL_EXT_buffer_reference2)) {
|
||||
|
||||
if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) {
|
||||
if (!(right->getType().isScalar() && right->getType().isIntegerDomain()))
|
||||
return nullptr;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue