Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2013 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21.  * DEALINGS IN THE SOFTWARE.
  22.  */
  23. #include <gtest/gtest.h>
  24. #include "standalone_scaffolding.h"
  25. #include "main/compiler.h"
  26. #include "main/mtypes.h"
  27. #include "main/macros.h"
  28. #include "ir.h"
  29. #include "glsl_parser_extras.h"
  30. #include "glsl_symbol_table.h"
  31.  
  32. class common_builtin : public ::testing::Test {
  33. public:
  34.    common_builtin(GLenum shader_type)
  35.       : shader_type(shader_type)
  36.    {
  37.       /* empty */
  38.    }
  39.  
  40.    virtual void SetUp();
  41.    virtual void TearDown();
  42.  
  43.    void string_starts_with_prefix(const char *str, const char *prefix);
  44.    void names_start_with_gl();
  45.    void uniforms_and_system_values_dont_have_explicit_location();
  46.    void constants_are_constant();
  47.    void no_invalid_variable_modes();
  48.  
  49.    GLenum shader_type;
  50.    struct _mesa_glsl_parse_state *state;
  51.    struct gl_shader *shader;
  52.    void *mem_ctx;
  53.    gl_context ctx;
  54.    exec_list ir;
  55. };
  56.  
  57. void
  58. common_builtin::SetUp()
  59. {
  60.    this->mem_ctx = ralloc_context(NULL);
  61.    this->ir.make_empty();
  62.  
  63.    initialize_context_to_defaults(&this->ctx, API_OPENGL_COMPAT);
  64.  
  65.    this->shader = rzalloc(this->mem_ctx, gl_shader);
  66.    this->shader->Type = this->shader_type;
  67.    this->shader->Stage = _mesa_shader_enum_to_shader_stage(this->shader_type);
  68.  
  69.    this->state =
  70.       new(mem_ctx) _mesa_glsl_parse_state(&this->ctx, this->shader->Stage,
  71.                                           this->shader);
  72.  
  73.    _mesa_glsl_initialize_types(this->state);
  74.    _mesa_glsl_initialize_variables(&this->ir, this->state);
  75. }
  76.  
  77. void
  78. common_builtin::TearDown()
  79. {
  80.    ralloc_free(this->mem_ctx);
  81.    this->mem_ctx = NULL;
  82. }
  83.  
  84. void
  85. common_builtin::string_starts_with_prefix(const char *str, const char *prefix)
  86. {
  87.    const size_t len = strlen(prefix);
  88.    char *const name_prefix = new char[len + 1];
  89.  
  90.    strncpy(name_prefix, str, len);
  91.    name_prefix[len] = '\0';
  92.    EXPECT_STREQ(prefix, name_prefix) << "Bad name " << str;
  93.  
  94.    delete [] name_prefix;
  95. }
  96.  
  97. void
  98. common_builtin::names_start_with_gl()
  99. {
  100.    foreach_in_list(ir_instruction, node, &this->ir) {
  101.       ir_variable *const var = node->as_variable();
  102.  
  103.       string_starts_with_prefix(var->name, "gl_");
  104.    }
  105. }
  106.  
  107. void
  108. common_builtin::uniforms_and_system_values_dont_have_explicit_location()
  109. {
  110.    foreach_in_list(ir_instruction, node, &this->ir) {
  111.       ir_variable *const var = node->as_variable();
  112.  
  113.       if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_system_value)
  114.          continue;
  115.  
  116.       EXPECT_FALSE(var->data.explicit_location);
  117.       EXPECT_EQ(-1, var->data.location);
  118.    }
  119. }
  120.  
  121. void
  122. common_builtin::constants_are_constant()
  123. {
  124.    foreach_in_list(ir_instruction, node, &this->ir) {
  125.       ir_variable *const var = node->as_variable();
  126.  
  127.       if (var->data.mode != ir_var_auto)
  128.          continue;
  129.  
  130.       EXPECT_FALSE(var->data.explicit_location);
  131.       EXPECT_EQ(-1, var->data.location);
  132.       EXPECT_TRUE(var->data.read_only);
  133.    }
  134. }
  135.  
  136. void
  137. common_builtin::no_invalid_variable_modes()
  138. {
  139.    foreach_in_list(ir_instruction, node, &this->ir) {
  140.       ir_variable *const var = node->as_variable();
  141.  
  142.       switch (var->data.mode) {
  143.       case ir_var_auto:
  144.       case ir_var_uniform:
  145.       case ir_var_shader_in:
  146.       case ir_var_shader_out:
  147.       case ir_var_system_value:
  148.          break;
  149.  
  150.       default:
  151.          ADD_FAILURE() << "Built-in variable " << var->name
  152.                        << " has an invalid mode " << int(var->data.mode);
  153.          break;
  154.       }
  155.    }
  156. }
  157.  
  158. /************************************************************/
  159.  
  160. class vertex_builtin : public common_builtin {
  161. public:
  162.    vertex_builtin()
  163.       : common_builtin(GL_VERTEX_SHADER)
  164.    {
  165.       /* empty */
  166.    }
  167. };
  168.  
  169. TEST_F(vertex_builtin, names_start_with_gl)
  170. {
  171.    common_builtin::names_start_with_gl();
  172. }
  173.  
  174. TEST_F(vertex_builtin, inputs_have_explicit_location)
  175. {
  176.    foreach_in_list(ir_instruction, node, &this->ir) {
  177.       ir_variable *const var = node->as_variable();
  178.  
  179.       if (var->data.mode != ir_var_shader_in)
  180.          continue;
  181.  
  182.       EXPECT_TRUE(var->data.explicit_location);
  183.       EXPECT_NE(-1, var->data.location);
  184.       EXPECT_GT(VERT_ATTRIB_GENERIC0, var->data.location);
  185.       EXPECT_EQ(0u, var->data.location_frac);
  186.    }
  187. }
  188.  
  189. TEST_F(vertex_builtin, outputs_have_explicit_location)
  190. {
  191.    foreach_in_list(ir_instruction, node, &this->ir) {
  192.       ir_variable *const var = node->as_variable();
  193.  
  194.       if (var->data.mode != ir_var_shader_out)
  195.          continue;
  196.  
  197.       EXPECT_TRUE(var->data.explicit_location);
  198.       EXPECT_NE(-1, var->data.location);
  199.       EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
  200.       EXPECT_EQ(0u, var->data.location_frac);
  201.  
  202.       /* Several varyings only exist in the fragment shader.  Be sure that no
  203.        * outputs with these locations exist.
  204.        */
  205.       EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
  206.       EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
  207.       EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID, var->data.location);
  208.    }
  209. }
  210.  
  211. TEST_F(vertex_builtin, uniforms_and_system_values_dont_have_explicit_location)
  212. {
  213.    common_builtin::uniforms_and_system_values_dont_have_explicit_location();
  214. }
  215.  
  216. TEST_F(vertex_builtin, constants_are_constant)
  217. {
  218.    common_builtin::constants_are_constant();
  219. }
  220.  
  221. TEST_F(vertex_builtin, no_invalid_variable_modes)
  222. {
  223.    common_builtin::no_invalid_variable_modes();
  224. }
  225.  
  226. /********************************************************************/
  227.  
  228. class fragment_builtin : public common_builtin {
  229. public:
  230.    fragment_builtin()
  231.       : common_builtin(GL_FRAGMENT_SHADER)
  232.    {
  233.       /* empty */
  234.    }
  235. };
  236.  
  237. TEST_F(fragment_builtin, names_start_with_gl)
  238. {
  239.    common_builtin::names_start_with_gl();
  240. }
  241.  
  242. TEST_F(fragment_builtin, inputs_have_explicit_location)
  243. {
  244.    foreach_in_list(ir_instruction, node, &this->ir) {
  245.       ir_variable *const var = node->as_variable();
  246.  
  247.       if (var->data.mode != ir_var_shader_in)
  248.          continue;
  249.  
  250.       EXPECT_TRUE(var->data.explicit_location);
  251.       EXPECT_NE(-1, var->data.location);
  252.       EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
  253.       EXPECT_EQ(0u, var->data.location_frac);
  254.  
  255.       /* Several varyings only exist in the vertex / geometry shader.  Be sure
  256.        * that no inputs with these locations exist.
  257.        */
  258.       EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot) var->data.location));
  259.    }
  260. }
  261.  
  262. TEST_F(fragment_builtin, outputs_have_explicit_location)
  263. {
  264.    foreach_in_list(ir_instruction, node, &this->ir) {
  265.       ir_variable *const var = node->as_variable();
  266.  
  267.       if (var->data.mode != ir_var_shader_out)
  268.          continue;
  269.  
  270.       EXPECT_TRUE(var->data.explicit_location);
  271.       EXPECT_NE(-1, var->data.location);
  272.  
  273.       /* gl_FragData[] has location FRAG_RESULT_DATA0.  Locations beyond that
  274.        * are invalid.
  275.        */
  276.       EXPECT_GE(FRAG_RESULT_DATA0, var->data.location);
  277.  
  278.       EXPECT_EQ(0u, var->data.location_frac);
  279.    }
  280. }
  281.  
  282. TEST_F(fragment_builtin, uniforms_and_system_values_dont_have_explicit_location)
  283. {
  284.    common_builtin::uniforms_and_system_values_dont_have_explicit_location();
  285. }
  286.  
  287. TEST_F(fragment_builtin, constants_are_constant)
  288. {
  289.    common_builtin::constants_are_constant();
  290. }
  291.  
  292. TEST_F(fragment_builtin, no_invalid_variable_modes)
  293. {
  294.    common_builtin::no_invalid_variable_modes();
  295. }
  296.  
  297. /********************************************************************/
  298.  
  299. class geometry_builtin : public common_builtin {
  300. public:
  301.    geometry_builtin()
  302.       : common_builtin(GL_GEOMETRY_SHADER)
  303.    {
  304.       /* empty */
  305.    }
  306. };
  307.  
  308. TEST_F(geometry_builtin, names_start_with_gl)
  309. {
  310.    common_builtin::names_start_with_gl();
  311. }
  312.  
  313. TEST_F(geometry_builtin, inputs_have_explicit_location)
  314. {
  315.    foreach_in_list(ir_instruction, node, &this->ir) {
  316.       ir_variable *const var = node->as_variable();
  317.  
  318.       if (var->data.mode != ir_var_shader_in)
  319.          continue;
  320.  
  321.       if (var->is_interface_instance()) {
  322.          EXPECT_STREQ("gl_in", var->name);
  323.          EXPECT_FALSE(var->data.explicit_location);
  324.          EXPECT_EQ(-1, var->data.location);
  325.  
  326.          ASSERT_TRUE(var->type->is_array());
  327.  
  328.          const glsl_type *const instance_type = var->type->fields.array;
  329.  
  330.          for (unsigned i = 0; i < instance_type->length; i++) {
  331.             const glsl_struct_field *const input =
  332.                &instance_type->fields.structure[i];
  333.  
  334.             string_starts_with_prefix(input->name, "gl_");
  335.             EXPECT_NE(-1, input->location);
  336.             EXPECT_GT(VARYING_SLOT_VAR0, input->location);
  337.  
  338.             /* Several varyings only exist in the fragment shader.  Be sure
  339.              * that no inputs with these locations exist.
  340.              */
  341.             EXPECT_NE(VARYING_SLOT_PNTC, input->location);
  342.             EXPECT_NE(VARYING_SLOT_FACE, input->location);
  343.          }
  344.       } else {
  345.          EXPECT_TRUE(var->data.explicit_location);
  346.          EXPECT_NE(-1, var->data.location);
  347.          EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
  348.          EXPECT_EQ(0u, var->data.location_frac);
  349.       }
  350.  
  351.       /* Several varyings only exist in the fragment shader.  Be sure that no
  352.        * inputs with these locations exist.
  353.        */
  354.       EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
  355.       EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
  356.    }
  357. }
  358.  
  359. TEST_F(geometry_builtin, outputs_have_explicit_location)
  360. {
  361.    foreach_in_list(ir_instruction, node, &this->ir) {
  362.       ir_variable *const var = node->as_variable();
  363.  
  364.       if (var->data.mode != ir_var_shader_out)
  365.          continue;
  366.  
  367.       EXPECT_TRUE(var->data.explicit_location);
  368.       EXPECT_NE(-1, var->data.location);
  369.       EXPECT_GT(VARYING_SLOT_VAR0, var->data.location);
  370.       EXPECT_EQ(0u, var->data.location_frac);
  371.  
  372.       /* Several varyings only exist in the fragment shader.  Be sure that no
  373.        * outputs with these locations exist.
  374.        */
  375.       EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
  376.       EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
  377.    }
  378. }
  379.  
  380. TEST_F(geometry_builtin, uniforms_and_system_values_dont_have_explicit_location)
  381. {
  382.    common_builtin::uniforms_and_system_values_dont_have_explicit_location();
  383. }
  384.  
  385. TEST_F(geometry_builtin, constants_are_constant)
  386. {
  387.    common_builtin::constants_are_constant();
  388. }
  389.  
  390. TEST_F(geometry_builtin, no_invalid_variable_modes)
  391. {
  392.    common_builtin::no_invalid_variable_modes();
  393. }
  394.