Implement modern (130 and above) texturing. About 250 functions for 3.0, over 500 for 4.3, created programmatically. Handles all 3.0 functions, almost all 4.3 functions.

git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@20698 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
John Kessenich 2013-02-25 19:44:56 +00:00
parent 4774d5ca15
commit db6b9117a6
6 changed files with 405 additions and 9 deletions

59
Test/300.frag Normal file
View File

@ -0,0 +1,59 @@
#version 300 es
uniform sampler2D s2D;
uniform sampler3D s3D;
uniform samplerCube sCube;
uniform samplerCubeShadow sCubeShadow;
uniform sampler2DShadow s2DShadow;
uniform sampler2DArray s2DArray;
uniform sampler2DArrayShadow s2DArrayShadow;
uniform isampler2D is2D;
uniform isampler3D is3D;
uniform isamplerCube isCube;
uniform isampler2DArray is2DArray;
uniform usampler2D us2D;
uniform usampler3D us3D;
uniform usamplerCube usCube;
uniform usampler2DArray us2DArray;
in float c1D;
in vec2 c2D;
in vec3 c3D;
in vec4 c4D;
in int ic1D;
in ivec2 ic2D;
in ivec3 ic3D;
in ivec4 ic4D;
out vec4 FragData;
void main()
{
vec4 v = texture(s2D, c2D);
v += textureProj(s3D, c4D);
v += textureLod(s2DArray, c3D, 1.2);
v.y += textureOffset(s2DShadow, c3D, ic2D, c1D);
v += texelFetch(s3D, ic3D, ic1D);
v += texelFetchOffset(s2D, ic2D, 4, ic2D);
v.y += textureLodOffset(s2DShadow, c3D, c1D, ic2D);
v += textureProjLodOffset(s2D, c3D, c1D, ic2D);
v += textureGrad(sCube, c3D, c3D, c3D);
v.x += textureGradOffset(s2DArrayShadow, c4D, c2D, c2D, ic2D);
v += textureProjGrad(s3D, c4D, c3D, c3D);
v += textureProjGradOffset(s2D, c3D, c2D, c2D, ic2D);
ivec4 iv = texture(is2D, c2D);
iv += textureProjOffset(is2D, c4D, ic2D);
iv += textureProjLod(is2D, c3D, c1D);
iv += textureProjGrad(is2D, c3D, c2D, c2D);
iv += texture(is3D, c3D, 4.2);
iv += textureLod(isCube, c3D, c1D);
iv += texelFetch(is2DArray, ic3D, ic1D);
iv.xy += textureSize(sCubeShadow, 2);
FragData = v + vec4(iv);
}

View File

@ -9,4 +9,4 @@ while read t; do
b=`basename $t`
./StandAlone -i $t > $TARGETDIR/$b.out
diff $BASEDIR/$b.out $TARGETDIR/$b.out
done < testlist
done < localtestlist

View File

@ -120,7 +120,7 @@ struct TSampler {
case Esd2D: s.append("2D"); break;
case Esd3D: s.append("3D"); break;
case EsdCube: s.append("Cube"); break;
case EsdRect: s.append("Rect"); break;
case EsdRect: s.append("2DRect"); break;
case EsdBuffer: s.append("Buffer"); break;
}
if (ms)
@ -411,6 +411,7 @@ public:
case EbtFloat: return "float";
case EbtDouble: return "double";
case EbtInt: return "int";
case EbtUint: return "uint";
case EbtBool: return "bool";
case EbtSampler: return "sampler/image";
case EbtStruct: return "structure";

View File

@ -45,8 +45,32 @@
const int FirstProfileVersion = 150;
TBuiltIns::TBuiltIns()
{
prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u";
postfixes[2] = "2";
postfixes[3] = "3";
postfixes[4] = "4";
dimMap[Esd1D] = 1;
dimMap[Esd2D] = 2;
dimMap[EsdRect] = 2;
dimMap[Esd3D] = 3;
dimMap[EsdCube] = 3;
dimMap[EsdBuffer] = 1;
}
TBuiltIns::~TBuiltIns()
{
}
void TBuiltIns::initialize(int version, EProfile profile)
{
// TODO: Performance/Memory: consider an extra outer scope for built-ins common across all stages
//
// Initialize all the built-in strings for parsing.
//
@ -389,7 +413,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
s.append(TString("\n"));
//
// Original style texture Functions existing in both stages.
// Original-style texture Functions existing in both stages.
// (Per-stage functions below.)
//
if (profile != EEsProfile || version == 100) {
@ -464,7 +488,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
s.append(TString("vec4 ftransform();"));
//
// Texture Functions with lod.
// Original-style texture Functions with lod.
//
if (profile != EEsProfile || version == 100) {
s.append(TString("vec4 texture2DLod(sampler2D, vec2, float);"));
@ -495,7 +519,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
TString& s = BuiltInFunctionsFragment;
//
// Texture Functions with bias.
// Original-style texture Functions with bias.
//
if (profile != EEsProfile || version == 100) {
s.append(TString("vec4 texture2D(sampler2D, vec2, float);"));
@ -770,7 +794,7 @@ void TBuiltIns::initialize(int version, EProfile profile)
}
}
builtInStrings[EShLangFragment].push_back(BuiltInFunctions.c_str());
builtInStrings[EShLangFragment].push_back(BuiltInFunctions);
builtInStrings[EShLangFragment].push_back(BuiltInFunctionsFragment);
builtInStrings[EShLangFragment].push_back(StandardUniforms);
builtInStrings[EShLangFragment].push_back(StandardFragmentVaryings);
@ -780,6 +804,301 @@ void TBuiltIns::initialize(int version, EProfile profile)
builtInStrings[EShLangVertex].push_back(StandardVertexVaryings);
builtInStrings[EShLangVertex].push_back(StandardVertexAttributes);
builtInStrings[EShLangVertex].push_back(StandardUniforms);
if (version >= 130)
add2ndGenerationSamplingImaging(version, profile);
#ifdef TEST_MODE
printf("VERTEX SYMBOLS \n");
for (unsigned int i = 0; i < builtInStrings[EShLangVertex].size(); ++i)
printf("%s", builtInStrings[EShLangVertex][i].c_str());
printf("FRAGMENT SYMBOLS \n");
for (unsigned int i = 0; i < builtInStrings[EShLangFragment].size(); ++i)
printf("%s", builtInStrings[EShLangFragment][i].c_str());
#endif
}
void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile)
{
TBasicType bTypes[3] = { EbtFloat, EbtInt, EbtUint };
// enumerate all the types
for (int image = 0; image <= 1; ++image) { // loop over "bool" image vs sampler
if (image > 0 && version < 420)
continue;
for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
for (int ms = 0; ms <=1; ++ms) {
if ((ms || image) && shadow)
continue;
if (ms && (profile == EEsProfile || version < 150))
continue;
for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not
for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, 2D, ..., buffer
if ((dim == Esd1D || dim == EsdRect) && profile == EEsProfile)
continue;
if (dim != Esd2D && ms)
continue;
if ((dim == Esd3D || dim == EsdRect) && arrayed)
continue;
if (dim == Esd3D && shadow)
continue;
if (dim == EsdCube && arrayed && version < 400)
continue;
if (dim == EsdBuffer && (profile == EEsProfile || version < 140))
continue;
if (dim == EsdBuffer && (shadow || arrayed || ms))
continue;
for (int bType = 0; bType < 3; ++bType) { // float, int, uint results
if (shadow && bType > 0)
continue;
//
// Now, make all the function prototypes for the type we just built...
//
TSampler sampler;
sampler.set(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false,
shadow ? true : false,
ms ? true : false);
if (image)
sampler.image = true;
TString typeName = sampler.getString();
addQueryFunctions(sampler, typeName, version, profile);
if (image)
addImageFunctions(sampler, typeName, version, profile);
else
addSamplingFunctions(sampler, typeName, version, profile);
}
}
}
}
}
}
}
void TBuiltIns::addQueryFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
{
//
// textureSize
//
if (version < 430 && sampler.image)
return;
TString s;
if (profile == EEsProfile)
s.append("highp ");
int dims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0);
if (dims == 1)
s.append("int");
else {
s.append("ivec");
s.append(postfixes[dims]);
}
if (sampler.image)
s.append(" imageSize(");
else
s.append(" textureSize(");
s.append(typeName);
if (! sampler.image && sampler.dim != EsdRect && sampler.dim != EsdBuffer && ! sampler.ms)
s.append(",int);\n");
else
s.append(");\n");
builtInStrings[EShLangFragment].push_back(s);
builtInStrings[EShLangVertex].push_back(s);
// TODO: Functionality: version 420 imaging functions
}
void TBuiltIns::addImageFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
{
// TODO: Functionality: version 420 imaging functions
}
void TBuiltIns::addSamplingFunctions(TSampler sampler, TString& typeName, int version, EProfile profile)
{
// make one string per stage to contain all functions of the passed-in type for that stage
TString functions[EShLangCount];
//
// texturing
//
for (int proj = 0; proj <= 1; ++proj) { // loop over "bool" projective or not
if (proj && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.arrayed || sampler.ms))
continue;
for (int lod = 0; lod <= 1; ++lod) {
if (lod && (sampler.dim == EsdBuffer || sampler.dim == EsdRect || sampler.ms))
continue;
if (lod && sampler.dim == Esd2D && sampler.arrayed && sampler.shadow)
continue;
if (lod && sampler.dim == EsdCube && sampler.shadow)
continue;
for (int bias = 0; bias <= 1; ++bias) {
if (bias && (lod || sampler.ms))
continue;
if (bias && sampler.dim == Esd2D && sampler.shadow && sampler.arrayed)
continue;
if (bias && (sampler.dim == EsdRect || sampler.dim == EsdBuffer))
continue;
for (int offset = 0; offset <= 1; ++offset) { // loop over "bool" offset or not
if (proj + offset + bias + lod > 3)
continue;
if (offset && (sampler.dim == EsdCube || sampler.dim == EsdBuffer || sampler.ms))
continue;
for (int fetch = 0; fetch <= 1; ++fetch) { // loop over "bool" fetch or not
if (proj + offset + fetch + bias + lod > 3)
continue;
if (fetch && (lod || bias))
continue;
if (fetch && (sampler.shadow || sampler.dim == EsdCube))
continue;
if (fetch == 0 && (sampler.ms || sampler.dim == EsdBuffer))
continue;
for (int grad = 0; grad <= 1; ++grad) { // loop over "bool" grad or not
if (grad && (lod || bias || sampler.ms))
continue;
if (grad && sampler.dim == EsdBuffer)
continue;
if (proj + offset + fetch + grad + bias + lod > 3)
continue;
for (int extraProj = 0; extraProj <= 1; ++extraProj) {
bool compare = false;
int totalDims = dimMap[sampler.dim] + proj + (sampler.arrayed ? 1 : 0) + (sampler.shadow ? 1 : 0);
if (totalDims > 4 && sampler.shadow) {
compare = true;
totalDims = 4;
}
assert(totalDims <= 4);
if (extraProj && ! proj)
continue;
if (extraProj && (sampler.dim == Esd3D || sampler.shadow))
continue;
TString s;
// return type
if (sampler.shadow)
s.append("float ");
else {
s.append(prefixes[sampler.type]);
s.append("vec4 ");
}
// name
if (fetch)
s.append("texel");
else
s.append("texture");
if (proj)
s.append("Proj");
if (lod)
s.append("Lod");
if (grad)
s.append("Grad");
if (fetch)
s.append("Fetch");
if (offset)
s.append("Offset");
s.append("(");
// sampler type
s.append(typeName);
// P coordinate
if (extraProj)
s.append(",vec4");
else {
s.append(",");
TBasicType t = fetch ? EbtInt : EbtFloat;
if (totalDims == 1)
s.append(TType::getBasicString(t));
else {
s.append(prefixes[t]);
s.append("vec");
s.append(postfixes[totalDims]);
}
}
if (bias && compare)
continue;
// non-optional lod argument (lod that's not driven by lod loop)
if (fetch && sampler.dim != EsdBuffer && !sampler.ms)
s.append(",int");
// non-optional lod
if (lod)
s.append(",float");
// gradient arguments
if (grad) {
if (dimMap[sampler.dim] == 1)
s.append(",float,float");
else {
s.append(",vec");
s.append(postfixes[dimMap[sampler.dim]]);
s.append(",vec");
s.append(postfixes[dimMap[sampler.dim]]);
}
}
// offset
if (offset) {
if (dimMap[sampler.dim] == 1)
s.append(",int");
else {
s.append(",ivec");
s.append(postfixes[dimMap[sampler.dim]]);
}
}
// optional bias or non-optional compare
if (bias || compare)
s.append(",float");
s.append(");\n");
// Add to the per-language set of built-ins
if (! bias) {
functions[EShLangVertex].append(s);
// all stages other than fragment get this here too
}
functions[EShLangFragment].append(s);
}
}
}
}
}
}
}
builtInStrings[EShLangVertex].push_back(functions[EShLangVertex]);
builtInStrings[EShLangFragment].push_back(functions[EShLangFragment]);
}
void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, EShLanguage language)

View File

@ -48,11 +48,24 @@ typedef TVector<TString> TBuiltInStrings;
class TBuiltIns {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TBuiltIns();
virtual ~TBuiltIns();
void initialize(int version, EProfile);
void initialize(const TBuiltInResource& resources, int version, EProfile, EShLanguage);
TBuiltInStrings* getBuiltInStrings() { return builtInStrings; }
protected:
void add2ndGenerationSamplingImaging(int version, EProfile profile);
void addQueryFunctions(TSampler, TString& typeName, int version, EProfile profile);
void addImageFunctions(TSampler, TString& typeName, int version, EProfile profile);
void addSamplingFunctions(TSampler, TString& typeName, int version, EProfile profile);
TBuiltInStrings builtInStrings[EShLangCount];
// Helpers for making text
const char* postfixes[5];
const char* prefixes[EbtNumTypes];
int dimMap[EsdNumDims];
};
void IdentifyBuiltIns(int version, EProfile profile, EShLanguage, TSymbolTable&);

View File

@ -231,18 +231,22 @@ int yy_input(char* buf, int max_size);
"samplerCubeShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBESHADOW; }
"sampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DARRAY; }
"sampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DARRAY; }
"samplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBEARRAY; }
"sampler1DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DARRAYSHADOW; }
"sampler2DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DARRAYSHADOW; }
"samplerCubeArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBEARRAYSHADOW; }
"isampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER1D; }
"isampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER2D; }
"isampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER3D; }
"isamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLERCUBE; }
"isamplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLERCUBEARRAY; }
"isampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER1DARRAY; }
"isampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER2DARRAY; }
"usampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER1D; }
"usampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER2D; }
"usampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER3D; }
"usamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLERCUBE; }
"usamplerCubeArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLERCUBEARRAY; }
"usampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER1DARRAY; }
"usampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER2DARRAY; }
@ -252,9 +256,9 @@ int yy_input(char* buf, int max_size);
"sampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLER2DMS); }
"isampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLER2DMS); }
"usampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLER2DMS); }
"sampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLER2DMSARRAY); }
"isampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLER2DMSARRAY); }
"usampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLER2DMSARRAY); }
"sampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLER2DMSARRAY); }
"isampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLER2DMSARRAY); }
"usampler2DMSArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLER2DMSARRAY); }
"image1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1D); }
"iimage1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1D); }
"uimage1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1D); }