Home | History | Annotate | Download | only in compiler_tests
      1 //
      2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 // CollectVariables_test.cpp:
      7 //   Some tests for shader inspection
      8 //
      9 
     10 #include "angle_gl.h"
     11 #include "gtest/gtest.h"
     12 #include "GLSLANG/ShaderLang.h"
     13 #include "compiler/translator/TranslatorGLSL.h"
     14 
     15 #define EXPECT_GLENUM_EQ(expected, actual) \
     16     EXPECT_EQ(static_cast<GLenum>(expected), static_cast<GLenum>(actual))
     17 
     18 class CollectVariablesTest : public testing::Test
     19 {
     20   public:
     21     CollectVariablesTest(GLenum shaderType)
     22         : mShaderType(shaderType)
     23     {}
     24 
     25   protected:
     26     virtual void SetUp()
     27     {
     28         ShBuiltInResources resources;
     29         ShInitBuiltInResources(&resources);
     30         resources.MaxDrawBuffers = 8;
     31 
     32         mTranslator = new TranslatorGLSL(mShaderType, SH_GLES2_SPEC);
     33         ASSERT_TRUE(mTranslator->Init(resources));
     34     }
     35 
     36     virtual void TearDown()
     37     {
     38         delete mTranslator;
     39     }
     40 
     41     GLenum mShaderType;
     42     TranslatorGLSL *mTranslator;
     43 };
     44 
     45 class CollectVertexVariablesTest : public CollectVariablesTest
     46 {
     47   public:
     48     CollectVertexVariablesTest() : CollectVariablesTest(GL_VERTEX_SHADER) {}
     49 };
     50 
     51 class CollectFragmentVariablesTest : public CollectVariablesTest
     52 {
     53   public:
     54       CollectFragmentVariablesTest() : CollectVariablesTest(GL_FRAGMENT_SHADER) {}
     55 };
     56 
     57 TEST_F(CollectFragmentVariablesTest, SimpleOutputVar)
     58 {
     59     const std::string &shaderString =
     60         "#version 300 es\n"
     61         "precision mediump float;\n"
     62         "out vec4 out_fragColor;\n"
     63         "void main() {\n"
     64         "   out_fragColor = vec4(1.0);\n"
     65         "}\n";
     66 
     67     const char *shaderStrings[] = { shaderString.c_str() };
     68     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
     69 
     70     const std::vector<sh::Attribute> &outputVariables = mTranslator->getOutputVariables();
     71     ASSERT_EQ(1u, outputVariables.size());
     72 
     73     const sh::Attribute &outputVariable = outputVariables[0];
     74 
     75     EXPECT_EQ(0u, outputVariable.arraySize);
     76     EXPECT_EQ(-1, outputVariable.location);
     77     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
     78     EXPECT_TRUE(outputVariable.staticUse);
     79     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
     80     EXPECT_EQ("out_fragColor", outputVariable.name);
     81 }
     82 
     83 TEST_F(CollectFragmentVariablesTest, LocationOutputVar)
     84 {
     85     const std::string &shaderString =
     86         "#version 300 es\n"
     87         "precision mediump float;\n"
     88         "layout(location=5) out vec4 out_fragColor;\n"
     89         "void main() {\n"
     90         "   out_fragColor = vec4(1.0);\n"
     91         "}\n";
     92 
     93     const char *shaderStrings[] = { shaderString.c_str() };
     94     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
     95 
     96     const std::vector<sh::Attribute> &outputVariables = mTranslator->getOutputVariables();
     97     ASSERT_EQ(1u, outputVariables.size());
     98 
     99     const sh::Attribute &outputVariable = outputVariables[0];
    100 
    101     EXPECT_EQ(0u, outputVariable.arraySize);
    102     EXPECT_EQ(5, outputVariable.location);
    103     EXPECT_GLENUM_EQ(GL_MEDIUM_FLOAT, outputVariable.precision);
    104     EXPECT_TRUE(outputVariable.staticUse);
    105     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, outputVariable.type);
    106     EXPECT_EQ("out_fragColor", outputVariable.name);
    107 }
    108 
    109 TEST_F(CollectVertexVariablesTest, LocationAttribute)
    110 {
    111     const std::string &shaderString =
    112         "#version 300 es\n"
    113         "layout(location=5) in vec4 in_Position;\n"
    114         "void main() {\n"
    115         "   gl_Position = in_Position;\n"
    116         "}\n";
    117 
    118     const char *shaderStrings[] = { shaderString.c_str() };
    119     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    120 
    121     const std::vector<sh::Attribute> &attributes = mTranslator->getAttributes();
    122     ASSERT_EQ(1u, attributes.size());
    123 
    124     const sh::Attribute &attribute = attributes[0];
    125 
    126     EXPECT_EQ(0u, attribute.arraySize);
    127     EXPECT_EQ(5, attribute.location);
    128     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, attribute.precision);
    129     EXPECT_TRUE(attribute.staticUse);
    130     EXPECT_GLENUM_EQ(GL_FLOAT_VEC4, attribute.type);
    131     EXPECT_EQ("in_Position", attribute.name);
    132 }
    133 
    134 TEST_F(CollectVertexVariablesTest, SimpleInterfaceBlock)
    135 {
    136     const std::string &shaderString =
    137         "#version 300 es\n"
    138         "uniform b {\n"
    139         "  float f;\n"
    140         "};"
    141         "void main() {\n"
    142         "   gl_Position = vec4(f, 0.0, 0.0, 1.0);\n"
    143         "}\n";
    144 
    145     const char *shaderStrings[] = { shaderString.c_str() };
    146     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    147 
    148     const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
    149     ASSERT_EQ(1u, interfaceBlocks.size());
    150 
    151     const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
    152 
    153     EXPECT_EQ(0u, interfaceBlock.arraySize);
    154     EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
    155     EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
    156     EXPECT_EQ("b", interfaceBlock.name);
    157     EXPECT_TRUE(interfaceBlock.staticUse);
    158 
    159     ASSERT_EQ(1u, interfaceBlock.fields.size());
    160 
    161     const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
    162 
    163     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
    164     EXPECT_TRUE(field.staticUse);
    165     EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
    166     EXPECT_EQ("f", field.name);
    167     EXPECT_FALSE(field.isRowMajorLayout);
    168     EXPECT_TRUE(field.fields.empty());
    169 }
    170 
    171 TEST_F(CollectVertexVariablesTest, SimpleInstancedInterfaceBlock)
    172 {
    173     const std::string &shaderString =
    174         "#version 300 es\n"
    175         "uniform b {\n"
    176         "  float f;\n"
    177         "} blockInstance;"
    178         "void main() {\n"
    179         "   gl_Position = vec4(blockInstance.f, 0.0, 0.0, 1.0);\n"
    180         "}\n";
    181 
    182     const char *shaderStrings[] = { shaderString.c_str() };
    183     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    184 
    185     const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
    186     ASSERT_EQ(1u, interfaceBlocks.size());
    187 
    188     const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
    189 
    190     EXPECT_EQ(0u, interfaceBlock.arraySize);
    191     EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
    192     EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
    193     EXPECT_EQ("b", interfaceBlock.name);
    194     EXPECT_TRUE(interfaceBlock.staticUse);
    195 
    196     ASSERT_EQ(1u, interfaceBlock.fields.size());
    197 
    198     const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
    199 
    200     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, field.precision);
    201     EXPECT_TRUE(field.staticUse);
    202     EXPECT_GLENUM_EQ(GL_FLOAT, field.type);
    203     EXPECT_EQ("b.f", field.name);
    204     EXPECT_FALSE(field.isRowMajorLayout);
    205     EXPECT_TRUE(field.fields.empty());
    206 }
    207 
    208 TEST_F(CollectVertexVariablesTest, StructInterfaceBlock)
    209 {
    210     const std::string &shaderString =
    211         "#version 300 es\n"
    212         "struct st { float f; };"
    213         "uniform b {\n"
    214         "  st s;\n"
    215         "};"
    216         "void main() {\n"
    217         "   gl_Position = vec4(s.f, 0.0, 0.0, 1.0);\n"
    218         "}\n";
    219 
    220     const char *shaderStrings[] = { shaderString.c_str() };
    221     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    222 
    223     const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
    224     ASSERT_EQ(1u, interfaceBlocks.size());
    225 
    226     const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
    227 
    228     EXPECT_EQ(0u, interfaceBlock.arraySize);
    229     EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
    230     EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
    231     EXPECT_EQ("b", interfaceBlock.name);
    232     EXPECT_TRUE(interfaceBlock.staticUse);
    233 
    234     ASSERT_EQ(1u, interfaceBlock.fields.size());
    235 
    236     const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
    237 
    238     EXPECT_TRUE(field.isStruct());
    239     EXPECT_TRUE(field.staticUse);
    240     EXPECT_EQ("s", field.name);
    241     EXPECT_FALSE(field.isRowMajorLayout);
    242 
    243     const sh::ShaderVariable &member = field.fields[0];
    244 
    245     // NOTE: we don't currently mark struct members as statically used or not
    246     EXPECT_FALSE(member.isStruct());
    247     EXPECT_EQ("f", member.name);
    248     EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
    249     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
    250 }
    251 
    252 TEST_F(CollectVertexVariablesTest, StructInstancedInterfaceBlock)
    253 {
    254     const std::string &shaderString =
    255         "#version 300 es\n"
    256         "struct st { float f; };"
    257         "uniform b {\n"
    258         "  st s;\n"
    259         "} instanceName;"
    260         "void main() {\n"
    261         "   gl_Position = vec4(instanceName.s.f, 0.0, 0.0, 1.0);\n"
    262         "}\n";
    263 
    264     const char *shaderStrings[] = { shaderString.c_str() };
    265     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    266 
    267     const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
    268     ASSERT_EQ(1u, interfaceBlocks.size());
    269 
    270     const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
    271 
    272     EXPECT_EQ(0u, interfaceBlock.arraySize);
    273     EXPECT_FALSE(interfaceBlock.isRowMajorLayout);
    274     EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
    275     EXPECT_EQ("b", interfaceBlock.name);
    276     EXPECT_TRUE(interfaceBlock.staticUse);
    277 
    278     ASSERT_EQ(1u, interfaceBlock.fields.size());
    279 
    280     const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
    281 
    282     EXPECT_TRUE(field.isStruct());
    283     EXPECT_TRUE(field.staticUse);
    284     EXPECT_EQ("b.s", field.name);
    285     EXPECT_FALSE(field.isRowMajorLayout);
    286 
    287     const sh::ShaderVariable &member = field.fields[0];
    288 
    289     // NOTE: we don't currently mark struct members as statically used or not
    290     EXPECT_FALSE(member.isStruct());
    291     EXPECT_EQ("f", member.name);
    292     EXPECT_GLENUM_EQ(GL_FLOAT, member.type);
    293     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
    294 }
    295 
    296 TEST_F(CollectVertexVariablesTest, NestedStructRowMajorInterfaceBlock)
    297 {
    298     const std::string &shaderString =
    299         "#version 300 es\n"
    300         "struct st { mat2 m; };"
    301         "layout(row_major) uniform b {\n"
    302         "  st s;\n"
    303         "};"
    304         "void main() {\n"
    305         "   gl_Position = vec4(s.m);\n"
    306         "}\n";
    307 
    308     const char *shaderStrings[] = { shaderString.c_str() };
    309     ASSERT_TRUE(mTranslator->compile(shaderStrings, 1, SH_VARIABLES));
    310 
    311     const std::vector<sh::InterfaceBlock> &interfaceBlocks = mTranslator->getInterfaceBlocks();
    312     ASSERT_EQ(1u, interfaceBlocks.size());
    313 
    314     const sh::InterfaceBlock &interfaceBlock = interfaceBlocks[0];
    315 
    316     EXPECT_EQ(0u, interfaceBlock.arraySize);
    317     EXPECT_TRUE(interfaceBlock.isRowMajorLayout);
    318     EXPECT_EQ(sh::BLOCKLAYOUT_SHARED, interfaceBlock.layout);
    319     EXPECT_EQ("b", interfaceBlock.name);
    320     EXPECT_TRUE(interfaceBlock.staticUse);
    321 
    322     ASSERT_EQ(1u, interfaceBlock.fields.size());
    323 
    324     const sh::InterfaceBlockField &field = interfaceBlock.fields[0];
    325 
    326     EXPECT_TRUE(field.isStruct());
    327     EXPECT_TRUE(field.staticUse);
    328     EXPECT_EQ("s", field.name);
    329     EXPECT_TRUE(field.isRowMajorLayout);
    330 
    331     const sh::ShaderVariable &member = field.fields[0];
    332 
    333     // NOTE: we don't currently mark struct members as statically used or not
    334     EXPECT_FALSE(member.isStruct());
    335     EXPECT_EQ("m", member.name);
    336     EXPECT_GLENUM_EQ(GL_FLOAT_MAT2, member.type);
    337     EXPECT_GLENUM_EQ(GL_HIGH_FLOAT, member.precision);
    338 }
    339