HLSL: cast non-int types to uint on Load/Store indexes
Some texture and SB operations can take non-integer indexes, which should be cast to integers before use if they are not already. This adds makeIntegerIndex() for the purpose. Int types are left alone. (This was done before for operator[], but needs to apply to some other things too, hence its extraction into common function now)
This commit is contained in:
@@ -712,28 +712,39 @@ TIntermTyped* HlslParseContext::handleBracketOperator(const TSourceLoc& loc, TIn
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Cast index value to a uint if it isn't already (for operator[], load indexes, etc)
|
||||
TIntermTyped* HlslParseContext::makeIntegerIndex(TIntermTyped* index)
|
||||
{
|
||||
const TBasicType indexBasicType = index->getType().getBasicType();
|
||||
const int vecSize = index->getType().getVectorSize();
|
||||
|
||||
// We can use int types directly as the index
|
||||
if (indexBasicType == EbtInt || indexBasicType == EbtUint ||
|
||||
indexBasicType == EbtInt64 || indexBasicType == EbtUint64)
|
||||
return index;
|
||||
|
||||
// Cast index to unsigned integer if it isn't one.
|
||||
return intermediate.addConversion(EOpConstructUint, TType(EbtUint, EvqTemporary, vecSize), index);
|
||||
}
|
||||
|
||||
//
|
||||
// Handle seeing a base[index] dereference in the grammar.
|
||||
//
|
||||
TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
|
||||
{
|
||||
TIntermTyped* result = handleBracketOperator(loc, base, index);
|
||||
|
||||
if (result != nullptr)
|
||||
return result; // it was handled as an operator[]
|
||||
|
||||
const TBasicType indexBasicType = index->getType().getBasicType();
|
||||
|
||||
// Cast index to unsigned integer if it isn't one.
|
||||
if (indexBasicType != EbtInt && indexBasicType != EbtUint &&
|
||||
indexBasicType != EbtInt64 && indexBasicType != EbtUint64)
|
||||
index = intermediate.addConversion(EOpConstructUint, TType(EbtUint), index);
|
||||
index = makeIntegerIndex(index);
|
||||
|
||||
if (index == nullptr) {
|
||||
error(loc, " unknown undex type ", "", "");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TIntermTyped* result = handleBracketOperator(loc, base, index);
|
||||
|
||||
if (result != nullptr)
|
||||
return result; // it was handled as an operator[]
|
||||
|
||||
bool flattened = false;
|
||||
int indexValue = 0;
|
||||
if (index->getQualifier().storage == EvqConst) {
|
||||
@@ -2570,7 +2581,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
|
||||
switch (op) {
|
||||
case EOpMethodLoad:
|
||||
{
|
||||
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // index
|
||||
TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
|
||||
|
||||
// Byte address buffers index in bytes (only multiples of 4 permitted... not so much a byte address
|
||||
// buffer then, but that's what it calls itself.
|
||||
@@ -2596,7 +2607,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
|
||||
case EOpMethodLoad3:
|
||||
case EOpMethodLoad4:
|
||||
{
|
||||
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // index
|
||||
TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
|
||||
|
||||
TOperator constructOp = EOpNull;
|
||||
int size = 0;
|
||||
@@ -2654,7 +2665,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
|
||||
case EOpMethodStore3:
|
||||
case EOpMethodStore4:
|
||||
{
|
||||
TIntermTyped* argIndex = argAggregate->getSequence()[1]->getAsTyped(); // address
|
||||
TIntermTyped* argIndex = makeIntegerIndex(argAggregate->getSequence()[1]->getAsTyped()); // index
|
||||
TIntermTyped* argValue = argAggregate->getSequence()[2]->getAsTyped(); // value
|
||||
|
||||
// Index into the array to find the item being loaded.
|
||||
@@ -2761,7 +2772,7 @@ void HlslParseContext::decomposeStructBufferMethods(const TSourceLoc& loc, TInte
|
||||
|
||||
TIntermSequence& sequence = argAggregate->getSequence();
|
||||
|
||||
TIntermTyped* argIndex = sequence[1]->getAsTyped(); // index
|
||||
TIntermTyped* argIndex = makeIntegerIndex(sequence[1]->getAsTyped()); // index
|
||||
argIndex = intermediate.addBinaryNode(EOpRightShift, argIndex, intermediate.addConstantUnion(2, loc, true),
|
||||
loc, TType(EbtInt));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user