Commit 4886f697 by LoopDawg

HLSL: Sampler/texture declarations, method syntax, partial Sample method

parent d8509b33
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
*.so *.so
*.exe *.exe
tags tags
TAGS
build/ build/
Test/localResults/ Test/localResults/
Test/multiThread.out Test/multiThread.out
......
SamplerState g_sSamp : register(s0);
uniform sampler2D g_sSamp2d
{
AddressU = MIRROR;
AddressV = WRAP;
MinLOD = 0;
MaxLOD = 10;
MaxAnisotropy = 2;
MipLodBias = 0.2;
}, g_sSamp2D_b;
Texture1D g_tTex1df4a : register(t1);
uniform Texture1D <float4> g_tTex1df4 : register(t0);
Texture1D <int4> g_tTex1di4;
Texture1D <uint4> g_tTex1du4;
Texture2D <float4> g_tTex2df4;
Texture2D <int4> g_tTex2di4;
Texture2D <uint4> g_tTex2du4;
Texture3D <float4> g_tTex3df4;
Texture3D <int4> g_tTex3di4;
Texture3D <uint4> g_tTex3du4;
TextureCube <float4> g_tTexcdf4;
TextureCube <int4> g_tTexcdi4;
TextureCube <uint4> g_tTexcdu4;
struct MemberTest
{
int Sample; // in HLSL, method names are valid struct members.
int CalculateLevelOfDetail; // ...
int CalculateLevelOfDetailUnclamped; // ...
int Gather; // ...
int GetDimensions; // ...
int GetSamplePosition; // ...
int Load; // ...
int SampleBias; // ...
int SampleCmp; // ...
int SampleCmpLevelZero; // ...
int SampleGrad; // ...
int SampleLevel; // ...
};
struct PS_OUTPUT
{
float4 Color : SV_Target0;
float Depth : SV_Depth;
};
PS_OUTPUT main()
{
PS_OUTPUT psout;
MemberTest mtest;
mtest.CalculateLevelOfDetail = 1; // in HLSL, method names are valid struct members.
mtest.CalculateLevelOfDetailUnclamped = 1; // ...
mtest.Gather = 1; // ...
mtest.GetDimensions = 1; // ...
mtest.GetSamplePosition = 1; // ...
mtest.Load = 1; // ...
mtest.Sample = 1; // ...
mtest.SampleBias = 1; // ...
mtest.SampleCmp = 1; // ...
mtest.SampleCmpLevelZero = 1; // ...
mtest.SampleGrad = 1; // ...
mtest.SampleLevel = 1; // ...
float4 txval10 = g_tTex1df4 . Sample(g_sSamp, 0.1);
int4 txval11 = g_tTex1di4 . Sample(g_sSamp, 0.2);
uint4 txval12 = g_tTex1du4 . Sample(g_sSamp, 0.3);
float4 txval20 = g_tTex2df4 . Sample(g_sSamp, float2(0.1, 0.2));
int4 txval21 = g_tTex2di4 . Sample(g_sSamp, float2(0.3, 0.4));
uint4 txval22 = g_tTex2du4 . Sample(g_sSamp, float2(0.5, 0.6));
float4 txval30 = g_tTex3df4 . Sample(g_sSamp, float3(0.1, 0.2, 0.3));
int4 txval31 = g_tTex3di4 . Sample(g_sSamp, float3(0.4, 0.5, 0.6));
uint4 txval32 = g_tTex3du4 . Sample(g_sSamp, float3(0.7, 0.8, 0.9));
float4 txval40 = g_tTexcdf4 . Sample(g_sSamp, float3(0.1, 0.2, 0.3));
int4 txval41 = g_tTexcdi4 . Sample(g_sSamp, float3(0.4, 0.5, 0.6));
uint4 txval42 = g_tTexcdu4 . Sample(g_sSamp, float3(0.7, 0.8, 0.9));
psout.Color = 1.0;
psout.Depth = 1.0;
return psout;
}
...@@ -84,6 +84,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler, ...@@ -84,6 +84,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool isCombined() const { return combined; } bool isCombined() const { return combined; }
bool isPureSampler() const { return sampler; } bool isPureSampler() const { return sampler; }
bool isTexture() const { return !sampler && !image; } bool isTexture() const { return !sampler && !image; }
bool isShadow() const { return shadow; }
void clear() void clear()
{ {
...@@ -1080,6 +1081,15 @@ public: ...@@ -1080,6 +1081,15 @@ public:
typeName = NewPoolTString(p.userDef->getTypeName().c_str()); typeName = NewPoolTString(p.userDef->getTypeName().c_str());
} }
} }
// for construction of sampler types
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler)
{
qualifier.clear();
qualifier.storage = q;
}
// to efficiently make a dereferenced type // to efficiently make a dereferenced type
// without ever duplicating the outer structure that will be thrown away // without ever duplicating the outer structure that will be thrown away
// and using only shallow copy // and using only shallow copy
......
...@@ -525,6 +525,8 @@ enum TOperator { ...@@ -525,6 +525,8 @@ enum TOperator {
EOpLit, // HLSL lighting coefficient vector EOpLit, // HLSL lighting coefficient vector
EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture EOpTextureBias, // HLSL texture bias: will be lowered to EOpTexture
EOpAsDouble, // slightly different from EOpUint64BitsToDouble EOpAsDouble, // slightly different from EOpUint64BitsToDouble
EOpMethodSample,
}; };
class TIntermTraverser; class TIntermTraverser;
......
...@@ -93,6 +93,7 @@ INSTANTIATE_TEST_CASE_P( ...@@ -93,6 +93,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"}, {"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"}, {"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
{"hlsl.sample.basicdx10.frag", "main"},
{"hlsl.intrinsics.vert", "VertexShaderFunction"}, {"hlsl.intrinsics.vert", "VertexShaderFunction"},
{"hlsl.matType.frag", "PixelShaderFunction"}, {"hlsl.matType.frag", "PixelShaderFunction"},
{"hlsl.max.frag", "PixelShaderFunction"}, {"hlsl.max.frag", "PixelShaderFunction"},
......
...@@ -59,16 +59,21 @@ namespace glslang { ...@@ -59,16 +59,21 @@ namespace glslang {
HlslGrammar& operator=(const HlslGrammar&); HlslGrammar& operator=(const HlslGrammar&);
void expected(const char*); void expected(const char*);
void unimplemented(const char*);
bool acceptIdentifier(HlslToken&); bool acceptIdentifier(HlslToken&);
bool acceptCompilationUnit(); bool acceptCompilationUnit();
bool acceptDeclaration(TIntermNode*& node); bool acceptDeclaration(TIntermNode*& node);
bool acceptControlDeclaration(TIntermNode*& node); bool acceptControlDeclaration(TIntermNode*& node);
bool acceptSamplerDeclarationDX9(TType&);
bool acceptSamplerState();
bool acceptFullySpecifiedType(TType&); bool acceptFullySpecifiedType(TType&);
void acceptQualifier(TQualifier&); void acceptQualifier(TQualifier&);
bool acceptType(TType&); bool acceptType(TType&);
bool acceptTemplateType(TBasicType&); bool acceptTemplateType(TBasicType&);
bool acceptVectorTemplateType(TType&); bool acceptVectorTemplateType(TType&);
bool acceptMatrixTemplateType(TType&); bool acceptMatrixTemplateType(TType&);
bool acceptSamplerType(TType&);
bool acceptTextureType(TType&);
bool acceptStruct(TType&); bool acceptStruct(TType&);
bool acceptStructDeclarationList(TTypeList*&); bool acceptStructDeclarationList(TTypeList*&);
bool acceptFunctionParameters(TFunction&); bool acceptFunctionParameters(TFunction&);
...@@ -82,7 +87,7 @@ namespace glslang { ...@@ -82,7 +87,7 @@ namespace glslang {
bool acceptUnaryExpression(TIntermTyped*&); bool acceptUnaryExpression(TIntermTyped*&);
bool acceptPostfixExpression(TIntermTyped*&); bool acceptPostfixExpression(TIntermTyped*&);
bool acceptConstructor(TIntermTyped*&); bool acceptConstructor(TIntermTyped*&);
bool acceptFunctionCall(HlslToken, TIntermTyped*&); bool acceptFunctionCall(HlslToken, TIntermTyped*&, TIntermTyped* base = nullptr);
bool acceptArguments(TFunction*, TIntermTyped*&); bool acceptArguments(TFunction*, TIntermTyped*&);
bool acceptLiteral(TIntermTyped*&); bool acceptLiteral(TIntermTyped*&);
bool acceptCompoundStatement(TIntermNode*&); bool acceptCompoundStatement(TIntermNode*&);
......
...@@ -564,12 +564,32 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt ...@@ -564,12 +564,32 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
variableCheck(base); variableCheck(base);
// //
// .length() can't be resolved until we later see the function-calling syntax. // methods can't be resolved until we later see the function-calling syntax.
// Save away the name in the AST for now. Processing is completed in // Save away the name in the AST for now. Processing is completed in
// handleLengthMethod(). // handleLengthMethod(), etc.
// //
if (field == "length") { if (field == "length") {
return intermediate.addMethod(base, TType(EbtInt), &field, loc); return intermediate.addMethod(base, TType(EbtInt), &field, loc);
} else if (field == "CalculateLevelOfDetail" ||
field == "CalculateLevelOfDetailUnclamped" ||
field == "Gather" ||
field == "GetDimensions" ||
field == "GetSamplePosition" ||
field == "Load" ||
field == "Sample" ||
field == "SampleBias" ||
field == "SampleCmp" ||
field == "SampleCmpLevelZero" ||
field == "SampleGrad" ||
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);
}
}
} }
// It's not .length() if we get to here. // It's not .length() if we get to here.
...@@ -1006,9 +1026,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*& ...@@ -1006,9 +1026,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
TIntermTyped* arg0 = argAggregate->getSequence()[0]->getAsTyped(); TIntermTyped* arg0 = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* arg1 = argAggregate->getSequence()[1]->getAsTyped(); TIntermTyped* arg1 = argAggregate->getSequence()[1]->getAsTyped();
TBasicType type0 = arg0->getBasicType();
TIntermTyped* x = intermediate.addConstantUnion(0, loc, true);
TIntermTyped* y = intermediate.addConstantUnion(1, loc, true); TIntermTyped* y = intermediate.addConstantUnion(1, loc, true);
TIntermTyped* z = intermediate.addConstantUnion(2, loc, true); TIntermTyped* z = intermediate.addConstantUnion(2, loc, true);
TIntermTyped* w = intermediate.addConstantUnion(3, loc, true); TIntermTyped* w = intermediate.addConstantUnion(3, loc, true);
...@@ -1205,6 +1223,49 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*& ...@@ -1205,6 +1223,49 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
} }
// //
// Decompose sample methods into AST
//
void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments)
{
if (!node || !node->getAsOperator())
return;
const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr;
const TOperator op = node->getAsOperator()->getOp();
switch (op) {
case EOpMethodSample:
{
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
TIntermTyped* argSamp = argAggregate->getSequence()[1]->getAsTyped();
TIntermTyped* argCoord = argAggregate->getSequence()[2]->getAsTyped();
TIntermAggregate* txcombine = new TIntermAggregate(EOpConstructTextureSampler);
txcombine->getSequence().push_back(argTex);
txcombine->getSequence().push_back(argSamp);
TSampler samplerType = argTex->getType().getSampler();
samplerType.combined = true;
txcombine->setType(TType(samplerType, EvqTemporary));
txcombine->setLoc(loc);
TIntermAggregate* txsample = new TIntermAggregate(EOpTexture);
txsample->getSequence().push_back(txcombine);
txsample->getSequence().push_back(argCoord);
txsample->setType(node->getType());
txsample->setLoc(loc);
node = txsample;
break;
}
default:
break; // most pass through unchanged
}
}
//
// Handle seeing function call syntax in the grammar, which could be any of // Handle seeing function call syntax in the grammar, which could be any of
// - .length() method // - .length() method
// - constructor // - constructor
...@@ -1307,8 +1368,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct ...@@ -1307,8 +1368,9 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate()); result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
} }
decomposeIntrinsic(loc, result, arguments); decomposeIntrinsic(loc, result, arguments); // HLSL->AST intrinsic decompositions
textureParameters(loc, result, arguments); decomposeSampleMethods(loc, result, arguments); // HLSL->AST sample method decompositions
textureParameters(loc, result, arguments); // HLSL->AST texture intrinsics
} }
} }
......
...@@ -87,6 +87,7 @@ public: ...@@ -87,6 +87,7 @@ public:
void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg); void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void textureParameters(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments); void textureParameters(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*); TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const; void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
......
// //
//Copyright (C) 2016 Google, Inc. //Copyright (C) 2016 Google, Inc.
//Copyright (C) 2016 LunarG, Inc.
// //
//All rights reserved. //All rights reserved.
// //
...@@ -249,6 +250,9 @@ void HlslScanContext::fillInKeywordMap() ...@@ -249,6 +250,9 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["Texture2DArray"] = EHTokTexture2darray; (*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
(*KeywordMap)["Texture3D"] = EHTokTexture3d; (*KeywordMap)["Texture3D"] = EHTokTexture3d;
(*KeywordMap)["TextureCube"] = EHTokTextureCube; (*KeywordMap)["TextureCube"] = EHTokTextureCube;
(*KeywordMap)["TextureCubeArray"] = EHTokTextureCubearray;
(*KeywordMap)["Texture2DMS"] = EHTokTexture2DMS;
(*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
(*KeywordMap)["struct"] = EHTokStruct; (*KeywordMap)["struct"] = EHTokStruct;
(*KeywordMap)["typedef"] = EHTokTypedef; (*KeywordMap)["typedef"] = EHTokTypedef;
...@@ -556,6 +560,9 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() ...@@ -556,6 +560,9 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
case EHTokTexture2darray: case EHTokTexture2darray:
case EHTokTexture3d: case EHTokTexture3d:
case EHTokTextureCube: case EHTokTextureCube:
case EHTokTextureCubearray:
case EHTokTexture2DMS:
case EHTokTexture2DMSarray:
return keyword; return keyword;
// variable, user type, ... // variable, user type, ...
......
// //
//Copyright (C) 2016 Google, Inc. //Copyright (C) 2016 Google, Inc.
//Copyright (C) 2016 LunarG, Inc.
// //
//All rights reserved. //All rights reserved.
// //
...@@ -200,6 +201,9 @@ enum EHlslTokenClass { ...@@ -200,6 +201,9 @@ enum EHlslTokenClass {
EHTokTexture2darray, EHTokTexture2darray,
EHTokTexture3d, EHTokTexture3d,
EHTokTextureCube, EHTokTextureCube,
EHTokTextureCubearray,
EHTokTexture2DMS,
EHTokTexture2DMSarray,
// variable, user type, ... // variable, user type, ...
EHTokIdentifier, EHTokIdentifier,
...@@ -278,4 +282,4 @@ enum EHlslTokenClass { ...@@ -278,4 +282,4 @@ enum EHlslTokenClass {
} // end namespace glslang } // end namespace glslang
#endif // EHLSLTOKENS_H_ #endif // EHLSLTOKENS_H_
\ No newline at end of file
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