Merge pull request #842 from steve-lunarg/sb-cast

HLSL: cast non-int types to uint on Load/Store indexes
This commit is contained in:
John Kessenich
2017-04-20 20:35:09 -06:00
committed by GitHub
6 changed files with 453 additions and 91 deletions

View File

@@ -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));

View File

@@ -250,6 +250,7 @@ protected:
TVariable* getSplitIoVar(int id) const;
void addInterstageIoToLinkage();
void addPatchConstantInvocation();
TIntermTyped* makeIntegerIndex(TIntermTyped*);
void fixBuiltInIoType(TType&);