From 41a36bbb2f95280589b91bfd60c10444238f9236 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Wed, 19 Jun 2013 05:41:25 +0000 Subject: [PATCH] Track separate precision defaults for each kind of sampler, give initial defaults as per spec. Also make fragment floats have no default. Modify/add tests to adapt to these changes. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22066 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- Test/300.frag | 36 ++++++++--------- Test/300block.frag | 8 ++-- Test/300layout.frag | 2 +- Test/300operations.frag | 2 +- Test/forwardRef.frag | 2 + Test/precision.frag | 2 +- Test/switch.frag | 2 +- Test/testlist | 1 + Test/uint.frag | 6 +-- Test/versionsClean.frag | 6 +-- glslang/MachineIndependent/ParseHelper.cpp | 46 +++++++++++++++++++++- glslang/MachineIndependent/ParseHelper.h | 5 +++ glslang/MachineIndependent/glslang.y | 7 +++- 13 files changed, 91 insertions(+), 34 deletions(-) diff --git a/Test/300.frag b/Test/300.frag index ad6cbe3db..4f22654ab 100644 --- a/Test/300.frag +++ b/Test/300.frag @@ -1,23 +1,23 @@ #version 300 es uniform sampler2D s2D; -uniform sampler3D s3D; +uniform lowp sampler3D s3D; uniform samplerCube sCube; -uniform samplerCubeShadow sCubeShadow; -uniform sampler2DShadow s2DShadow; -uniform sampler2DArray s2DArray; -uniform sampler2DArrayShadow s2DArrayShadow; +uniform lowp samplerCubeShadow sCubeShadow; +uniform lowp sampler2DShadow s2DShadow; +uniform lowp sampler2DArray s2DArray; +uniform lowp 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; +uniform lowp isampler2D is2D; +uniform lowp isampler3D is3D; +uniform lowp isamplerCube isCube; +uniform lowp isampler2DArray is2DArray; +uniform lowp usampler2D us2D; +uniform lowp usampler3D us3D; +uniform lowp usamplerCube usCube; +uniform lowp usampler2DArray us2DArray; +precision lowp float; in float c1D; in vec2 c2D; in vec3 c3D; @@ -28,15 +28,15 @@ flat in ivec2 ic2D; flat in ivec3 ic3D; flat in ivec4 ic4D; noperspective in vec4 badv; // ERROR -in sampler2D bads; // ERROR -precision lowp uint; // ERROR +in sampler2D bads; // ERROR +precision lowp uint; // ERROR struct s { int i; - sampler2D s; // ERROR + sampler2D s; }; -out s badout; // ERROR +out s badout; // ERROR void main() { diff --git a/Test/300block.frag b/Test/300block.frag index 8f88e1575..c6d9fcc8c 100644 --- a/Test/300block.frag +++ b/Test/300block.frag @@ -1,9 +1,11 @@ #version 300 es +precision mediump float; + struct S { vec4 u; uvec4 v; - isampler3D sampler; + lowp isampler3D sampler; vec3 w; struct T1 { // ERROR int a; @@ -15,7 +17,7 @@ uniform S s; uniform fooBlock { uvec4 bv; mat2 bm2; - isampler2D sampler; // ERROR + lowp isampler2D sampler; // ERROR struct T2 { // ERROR int a; } t; @@ -35,5 +37,5 @@ uniform barBlockArray { void main() { texture(s.sampler, vec3(inst.ni, bv.y, insts[2].nbv.z)); - insts[s.v.x]; // ERROR + insts[s.v.x]; // ERROR } diff --git a/Test/300layout.frag b/Test/300layout.frag index 7ba7f4adc..b4b0bba53 100644 --- a/Test/300layout.frag +++ b/Test/300layout.frag @@ -1,5 +1,5 @@ #version 300 es - +precision mediump float; in vec4 pos; layout (location = 2) in vec4 color; // ERROR diff --git a/Test/300operations.frag b/Test/300operations.frag index 3e7782c0e..f87142e1a 100644 --- a/Test/300operations.frag +++ b/Test/300operations.frag @@ -1,7 +1,7 @@ #version 300 es uniform block { - float f; + mediump float f; } instanceName; struct S { diff --git a/Test/forwardRef.frag b/Test/forwardRef.frag index c795369c3..49f3504ea 100644 --- a/Test/forwardRef.frag +++ b/Test/forwardRef.frag @@ -1,3 +1,5 @@ +#version 110 + uniform vec4 bigColor; varying vec4 BaseColor; uniform float d; diff --git a/Test/precision.frag b/Test/precision.frag index 37f3462b7..1f695c730 100644 --- a/Test/precision.frag +++ b/Test/precision.frag @@ -1,6 +1,6 @@ #version 100 -varying vec3 color; +varying vec3 color; // ERRROR, there is no default qualifier for float lowp vec2 foo(mediump vec3 mv3) { diff --git a/Test/switch.frag b/Test/switch.frag index 690562a26..ddd38f640 100644 --- a/Test/switch.frag +++ b/Test/switch.frag @@ -1,7 +1,7 @@ #version 300 es uniform int c, d; -in float x; +highp in float x; void main() { diff --git a/Test/testlist b/Test/testlist index 9c8932cc6..c549a3e7c 100644 --- a/Test/testlist +++ b/Test/testlist @@ -11,6 +11,7 @@ versionsErrors.vert 130.frag 140.frag precision.frag +precision.vert nonSquare.vert matrixError.vert cppSimple.vert diff --git a/Test/uint.frag b/Test/uint.frag index 22e5f33fd..6dd69ac9f 100644 --- a/Test/uint.frag +++ b/Test/uint.frag @@ -1,8 +1,8 @@ #version 300 es in uvec2 badu; // ERROR flat in uvec2 t; -in float f; -in vec2 tc; +in highp float f; +in highp vec2 tc; in bool bad; // ERROR uniform uvec4 v; uniform int i; @@ -10,7 +10,7 @@ uniform bool b; out uvec4 c; -uniform usampler2D usampler; +uniform lowp usampler2D usampler; void main() { diff --git a/Test/versionsClean.frag b/Test/versionsClean.frag index 5bf1baae5..6e19bf887 100644 --- a/Test/versionsClean.frag +++ b/Test/versionsClean.frag @@ -33,10 +33,10 @@ // #version 300 es -in vec3 color; -out vec4 foo; +in highp vec3 color; +out highp vec4 foo; -uniform sampler2DArrayShadow bar; +uniform highp sampler2DArrayShadow bar; void main() { diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 9d9ba5a42..9e3963403 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -51,7 +51,16 @@ TParseContext::TParseContext(TSymbolTable& symt, TIntermediate& interm, int v, E for (int type = 0; type < EbtNumTypes; ++type) defaultPrecision[type] = EpqNone; + for (int type = 0; type < maxSamplerIndex; ++type) + defaultSamplerPrecision[type] = EpqNone; + if (profile == EEsProfile) { + TSampler sampler; + sampler.set(EbtFloat, Esd2D); + defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; + sampler.set(EbtFloat, EsdCube); + defaultSamplerPrecision[computeSamplerTypeIndex(sampler)] = EpqLow; + switch (language) { case EShLangVertex: defaultPrecision[EbtInt] = EpqHigh; @@ -809,7 +818,13 @@ void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrec { TBasicType basicType = publicType.basicType; - if (basicType == EbtSampler || basicType == EbtInt || basicType == EbtFloat) { + if (basicType == EbtSampler) { + defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)] = qualifier; + + return; // all is well + } + + if (basicType == EbtInt || basicType == EbtFloat) { if (publicType.isScalar()) { defaultPrecision[basicType] = qualifier; if (basicType == EbtInt) @@ -822,6 +837,35 @@ void TParseContext::setDefaultPrecision(int line, TPublicType& publicType, TPrec error(line, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); } +// used to flatten the sampler type space into a single dimension +// correlates with the declaration of defaultSamplerPrecision[] +int TParseContext::computeSamplerTypeIndex(TSampler& sampler) +{ + int arrayIndex = sampler.arrayed ? 1 : 0; + int shadowIndex = sampler.shadow ? 1 : 0; + + return EsdNumDims * (EbtNumTypes * (2 * arrayIndex + shadowIndex) + sampler.type) + sampler.dim; +} + +TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType) +{ + if (publicType.basicType == EbtSampler) + return defaultSamplerPrecision[computeSamplerTypeIndex(publicType.sampler)]; + else + return defaultPrecision[publicType.basicType]; +} + +void TParseContext::precisionQualifierCheck(int line, TPublicType& publicType) +{ + if (profile != EEsProfile) + return; + + if (publicType.basicType == EbtFloat || publicType.basicType == EbtUint || publicType.basicType == EbtInt || publicType.basicType == EbtSampler) { + if (publicType.qualifier.precision == EpqNone) + error(line, "type requires declaration of default precision qualifier", TType::getBasicString(publicType.basicType), ""); + } +} + void TParseContext::parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type) { if ((qualifier == EvqOut || qualifier == EvqInOut) && type.getBasicType() != EbtStruct && type.getBasicType() == EbtSampler) diff --git a/glslang/MachineIndependent/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index d25d3c829..d5a215a2a 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -91,6 +91,8 @@ struct TParseContext { struct TPragma contextPragma; TPrecisionQualifier defaultPrecision[EbtNumTypes]; + static const int maxSamplerIndex = EsdNumDims * (EbtNumTypes * (2 * 2)); // see computeSamplerTypeIndex() + TPrecisionQualifier defaultSamplerPrecision[maxSamplerIndex]; TQualifier defaultGlobalQualification; TString HashErrMsg; bool AfterEOF; @@ -130,6 +132,9 @@ struct TParseContext { bool structQualifierErrorCheck(int line, const TPublicType& pType); void mergeQualifiers(int line, TPublicType& dst, const TPublicType& src, bool force); void setDefaultPrecision(int line, TPublicType&, TPrecisionQualifier); + int computeSamplerTypeIndex(TSampler&); + TPrecisionQualifier getDefaultPrecision(TPublicType&); + void precisionQualifierCheck(int line, TPublicType&); void parameterSamplerCheck(int line, TStorageQualifier qualifier, const TType& type); bool containsSampler(const TType& type); void nonInitConstCheck(int line, TString& identifier, TPublicType& type); diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index afc8e255c..a7995f94a 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -1484,6 +1484,7 @@ fully_specified_type $2.arraySizes = 0; parseContext.mergeQualifiers($2.line, $2, $1, true); + parseContext.precisionQualifierCheck($2.line, $2); $$ = $2; @@ -1724,11 +1725,11 @@ type_name_list type_specifier : type_specifier_nonarray { $$ = $1; - $$.qualifier.precision = parseContext.defaultPrecision[$$.basicType]; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); } | type_specifier_nonarray array_specifier { $$ = $1; - $$.qualifier.precision = parseContext.defaultPrecision[$$.basicType]; + $$.qualifier.precision = parseContext.getDefaultPrecision($$); $$.arraySizes = $2.arraySizes; } ; @@ -2466,6 +2467,7 @@ struct_declaration $$ = $2; parseContext.voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1); + parseContext.precisionQualifierCheck($1.line, $1); for (unsigned int i = 0; i < $$->size(); ++i) (*$$)[i].type->mergeType($1); @@ -2482,6 +2484,7 @@ struct_declaration parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2); parseContext.mergeQualifiers($2.line, $2, $1, true); + parseContext.precisionQualifierCheck($2.line, $2); for (unsigned int i = 0; i < $$->size(); ++i) (*$$)[i].type->mergeType($2);