HLSL: phase 2a: add r-value operator[] for RWTexture/RWBuffer

This commit adds r-value support for RW textures and buffers.
Supported is:

- Function in parameter conversions
- conversion of rvalue use to imageLoad
This commit is contained in:
steve-lunarg
2016-10-06 20:12:24 -06:00
parent e3aa654c4b
commit 6b43d274e7
5 changed files with 869 additions and 6 deletions

View File

@@ -297,12 +297,40 @@ TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, TSymbol* s
return node;
}
//
// Handle operator[] on any objects it applies to. Currently:
// Textures
// Buffers
//
TIntermTyped* HlslParseContext::handleBracketOperator(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{
// handle r-value operator[] on textures and images. l-values will be processed later.
if (base->getType().getBasicType() == EbtSampler && !base->isArray()) {
const TSampler& sampler = base->getType().getSampler();
if (sampler.isImage() || sampler.isTexture()) {
const int vecSize = 4; // TODO: handle arbitrary sizes (get from qualifier)
TIntermAggregate* load = new TIntermAggregate(EOpImageLoad);
load->setType(TType(sampler.type, EvqTemporary, vecSize));
load->setLoc(loc);
load->getSequence().push_back(base);
load->getSequence().push_back(index);
return load;
}
}
return nullptr;
}
//
// Handle seeing a base[index] dereference in the grammar.
//
TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index)
{
TIntermTyped* result = nullptr;
TIntermTyped* result = handleBracketOperator(loc, base, index);
if (result != nullptr)
return result; // it was handled as an operator[]
bool flattened = false;
int indexValue = 0;
@@ -425,10 +453,10 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
field == "SampleLevel") {
// If it's not a method on a sampler object, we fall through in case it is a struct member.
if (base->getType().getBasicType() == EbtSampler) {
const TSampler& texType = base->getType().getSampler();
if (! texType.isPureSampler()) {
const int vecSize = texType.isShadow() ? 1 : 4;
return intermediate.addMethod(base, TType(texType.type, EvqTemporary, vecSize), &field, loc);
const TSampler& sampler = base->getType().getSampler();
if (! sampler.isPureSampler()) {
const int vecSize = sampler.isShadow() ? 1 : 4; // TODO: handle arbitrary sample return sizes
return intermediate.addMethod(base, TType(sampler.type, EvqTemporary, vecSize), &field, loc);
}
}
}
@@ -1261,7 +1289,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
case Esd2D: numDims = 2; break; // W, H
case Esd3D: numDims = 3; break; // W, H, D
case EsdCube: numDims = 2; break; // W, H (cube)
case EsdBuffer: numDims = 1; break; // buffers
case EsdBuffer: numDims = 1; break; // W (buffers)
default:
assert(0 && "unhandled texture dimension");
}

View File

@@ -61,6 +61,7 @@ public:
void handlePragma(const TSourceLoc&, const TVector<TString>&);
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
TIntermTyped* handleBracketOperator(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(const TSourceLoc&, const TType&, int& index);
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);