Commit 6b43d274 by steve-lunarg

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
parent e3aa654c
SamplerState g_sSamp : register(s0);
RWTexture1D <float4> g_tTex1df4 : register(t0);
RWTexture1D <int4> g_tTex1di4;
RWTexture1D <uint4> g_tTex1du4;
RWTexture2D <float4> g_tTex2df4;
RWTexture2D <int4> g_tTex2di4;
RWTexture2D <uint4> g_tTex2du4;
RWTexture3D <float4> g_tTex3df4;
RWTexture3D <int4> g_tTex3di4;
RWTexture3D <uint4> g_tTex3du4;
RWTexture1DArray <float4> g_tTex1df4a;
RWTexture1DArray <int4> g_tTex1di4a;
RWTexture1DArray <uint4> g_tTex1du4a;
RWTexture2DArray <float4> g_tTex2df4a;
RWTexture2DArray <int4> g_tTex2di4a;
RWTexture2DArray <uint4> g_tTex2du4a;
struct PS_OUTPUT
{
float4 Color : SV_Target0;
};
uniform int c1;
uniform int2 c2;
uniform int3 c3;
uniform int4 c4;
uniform int o1;
uniform int2 o2;
uniform int3 o3;
uniform int4 o4;
int4 Fn1(in int4 x) { return x; }
uint4 Fn1(in uint4 x) { return x; }
float4 Fn1(in float4 x) { return x; }
void Fn2(out int4 x) { x = int4(0); }
void Fn2(out uint4 x) { x = uint4(0); }
void Fn2(out float4 x) { x = float4(0); }
PS_OUTPUT main()
{
PS_OUTPUT psout;
// Test as R-values
// 1D
g_tTex1df4[c1];
float4 r00 = g_tTex1df4[c1];
int4 r01 = g_tTex1di4[c1];
uint4 r02 = g_tTex1du4[c1];
// 2D
float4 r10 = g_tTex2df4[c2];
int4 r11 = g_tTex2di4[c2];
uint4 r12 = g_tTex2du4[c2];
// 3D
float4 r20 = g_tTex3df4[c3];
int4 r21 = g_tTex3di4[c3];
uint4 r22 = g_tTex3du4[c3];
// // Test as L-values
// // 1D
// g_tTex1df4[c1] = float4(1,2,3,4);
// g_tTex1di4[c1] = int4(1,2,3,4);
// g_tTex1du4[c1] = uint4(1,2,3,4);
// // 2D
// g_tTex2df4[c2] = float4(1,2,3,4);
// g_tTex2di4[c2] = int4(1,2,3,4);
// g_tTex2du4[c2] = uint4(1,2,3,4);
// // 3D
// g_tTex3df4[c3] = float4(1,2,3,4);
// g_tTex3di4[c3] = int4(1,2,3,4);
// g_tTex3du4[c3] = uint4(1,2,3,4);
// // Test function calling
Fn1(g_tTex1df4[c1]); // in
Fn1(g_tTex1di4[c1]); // in
Fn1(g_tTex1du4[c1]); // in
// Fn2(g_tTex1df4[c1]); // out
// Fn2(g_tTex1di4[c1]); // out
// Fn2(g_tTex1du4[c1]); // out
// // Test increment operators
// g_tTex1df4[c1]++;
// g_tTex1di4[c1]++;
// g_tTex1du4[c1]++;
// g_tTex1df4[c1]--;
// g_tTex1di4[c1]--;
// g_tTex1du4[c1]--;
// ++g_tTex1df4[c1];
// ++g_tTex1di4[c1];
// ++g_tTex1du4[c1];
// --g_tTex1df4[c1];
// --g_tTex1di4[c1];
// --g_tTex1du4[c1];
psout.Color = 1.0;
return psout;
}
...@@ -147,6 +147,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -147,6 +147,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.pp.line.frag", "main"}, {"hlsl.pp.line.frag", "main"},
{"hlsl.precise.frag", "main"}, {"hlsl.precise.frag", "main"},
{"hlsl.promotions.frag", "main"}, {"hlsl.promotions.frag", "main"},
{"hlsl.rw.bracket.frag", "main"},
{"hlsl.sample.array.dx10.frag", "main"}, {"hlsl.sample.array.dx10.frag", "main"},
{"hlsl.sample.basic.dx10.frag", "main"}, {"hlsl.sample.basic.dx10.frag", "main"},
{"hlsl.sample.offset.dx10.frag", "main"}, {"hlsl.sample.offset.dx10.frag", "main"},
......
...@@ -298,11 +298,39 @@ TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, TSymbol* s ...@@ -298,11 +298,39 @@ TIntermTyped* HlslParseContext::handleVariable(const TSourceLoc& loc, TSymbol* s
} }
// //
// 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. // Handle seeing a base[index] dereference in the grammar.
// //
TIntermTyped* HlslParseContext::handleBracketDereference(const TSourceLoc& loc, TIntermTyped* base, TIntermTyped* index) 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; bool flattened = false;
int indexValue = 0; int indexValue = 0;
...@@ -425,10 +453,10 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt ...@@ -425,10 +453,10 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
field == "SampleLevel") { field == "SampleLevel") {
// If it's not a method on a sampler object, we fall through in case it is a struct member. // 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) { if (base->getType().getBasicType() == EbtSampler) {
const TSampler& texType = base->getType().getSampler(); const TSampler& sampler = base->getType().getSampler();
if (! texType.isPureSampler()) { if (! sampler.isPureSampler()) {
const int vecSize = texType.isShadow() ? 1 : 4; const int vecSize = sampler.isShadow() ? 1 : 4; // TODO: handle arbitrary sample return sizes
return intermediate.addMethod(base, TType(texType.type, EvqTemporary, vecSize), &field, loc); return intermediate.addMethod(base, TType(sampler.type, EvqTemporary, vecSize), &field, loc);
} }
} }
} }
...@@ -1261,7 +1289,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType ...@@ -1261,7 +1289,7 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
case Esd2D: numDims = 2; break; // W, H case Esd2D: numDims = 2; break; // W, H
case Esd3D: numDims = 3; break; // W, H, D case Esd3D: numDims = 3; break; // W, H, D
case EsdCube: numDims = 2; break; // W, H (cube) case EsdCube: numDims = 2; break; // W, H (cube)
case EsdBuffer: numDims = 1; break; // buffers case EsdBuffer: numDims = 1; break; // W (buffers)
default: default:
assert(0 && "unhandled texture dimension"); assert(0 && "unhandled texture dimension");
} }
......
...@@ -61,6 +61,7 @@ public: ...@@ -61,6 +61,7 @@ public:
void handlePragma(const TSourceLoc&, const TVector<TString>&); void handlePragma(const TSourceLoc&, const TVector<TString>&);
TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string); TIntermTyped* handleVariable(const TSourceLoc&, TSymbol* symbol, const TString* string);
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
TIntermTyped* handleBracketOperator(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void checkIndex(const TSourceLoc&, const TType&, int& index); void checkIndex(const TSourceLoc&, const TType&, int& index);
TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right); TIntermTyped* handleBinaryMath(const TSourceLoc&, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment