From db6b9117a64ea2342c608a6b8cf3d63b1c480ca4 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Mon, 25 Feb 2013 19:44:56 +0000 Subject: [PATCH] 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 --- Test/300.frag | 59 ++++++ Test/runtests | 2 +- glslang/Include/Types.h | 3 +- glslang/MachineIndependent/Initialize.cpp | 327 +++++++++++++++++++++++++++++- glslang/MachineIndependent/Initialize.h | 13 ++ glslang/MachineIndependent/glslang.l | 10 +- 6 files changed, 405 insertions(+), 9 deletions(-) create mode 100644 Test/300.frag diff --git a/Test/300.frag b/Test/300.frag new file mode 100644 index 0000000..4a5422d --- /dev/null +++ b/Test/300.frag @@ -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); +} diff --git a/Test/runtests b/Test/runtests index c3e1746..4f78333 100644 --- a/Test/runtests +++ b/Test/runtests @@ -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 diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 9f61329..0f19eca 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -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"; diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 2bd39d8..1b405c2 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -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) diff --git a/glslang/MachineIndependent/Initialize.h b/glslang/MachineIndependent/Initialize.h index 58cf647..b341b61 100644 --- a/glslang/MachineIndependent/Initialize.h +++ b/glslang/MachineIndependent/Initialize.h @@ -48,11 +48,24 @@ typedef TVector 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&); diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index 3609907..1b3f34c 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -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); } -- 2.7.4