<div dir="ltr">On 22 October 2013 13:00, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 10/18/2013 01:14 PM, Paul Berry wrote:<br>
> On 11 October 2013 11:18, Ian Romanick <<a href="mailto:idr@freedesktop.org">idr@freedesktop.org</a><br>
</div><div class="im">> <mailto:<a href="mailto:idr@freedesktop.org">idr@freedesktop.org</a>>> wrote:<br>
><br>
>     From: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a><br>
</div>>     <mailto:<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a>>><br>
<div class="im">><br>
>     Checks that the variables generated meet certain criteria.<br>
><br>
>      - Vertex shader inputs have an explicit location.<br>
><br>
>      - Vertex shader outputs have an explicit location.<br>
><br>
>      - Fragment shader-only varying locations are not used.<br>
><br>
>      - Vertex shader uniforms and system values don't have an explicit<br>
>        location.<br>
><br>
>      - Vertex shader constants don't have an explicit location and are<br>
>        read-only.<br>
><br>
>      - No other kinds of vertex variables exist.<br>
><br>
>     It does not verify that an specific variables exist.<br>
><br>
>     Signed-off-by: Ian Romanick <<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a><br>
</div>>     <mailto:<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a>>><br>
<div><div class="h5">>     ---<br>
>      src/glsl/Makefile.am                     |   1 +<br>
>      src/glsl/tests/builtin_variable_test.cpp | 235<br>
>     +++++++++++++++++++++++++++++++<br>
>      2 files changed, 236 insertions(+)<br>
>      create mode 100644 src/glsl/tests/builtin_variable_test.cpp<br>
><br>
>     diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am<br>
>     index f43f49d..80949fb 100644<br>
>     --- a/src/glsl/Makefile.am<br>
>     +++ b/src/glsl/Makefile.am<br>
>     @@ -59,6 +59,7 @@ tests_general_ir_test_SOURCES =               \<br>
>             $(top_srcdir)/src/mesa/program/prog_hash_table.c\<br>
>             $(top_srcdir)/src/mesa/program/symbol_table.c   \<br>
>             $(GLSL_SRCDIR)/standalone_scaffolding.cpp \<br>
>     +       tests/builtin_variable_test.cpp                 \<br>
>             tests/general_ir_test.cpp<br>
>      tests_general_ir_test_CFLAGS =                         \<br>
>             $(PTHREAD_CFLAGS)<br>
>     diff --git a/src/glsl/tests/builtin_variable_test.cpp<br>
>     b/src/glsl/tests/builtin_variable_test.cpp<br>
>     new file mode 100644<br>
>     index 0000000..c4711ab<br>
>     --- /dev/null<br>
>     +++ b/src/glsl/tests/builtin_variable_test.cpp<br>
>     @@ -0,0 +1,235 @@<br>
>     +/*<br>
>     + * Copyright © 2013 Intel Corporation<br>
>     + *<br>
>     + * Permission is hereby granted, free of charge, to any person<br>
>     obtaining a<br>
>     + * copy of this software and associated documentation files (the<br>
>     "Software"),<br>
>     + * to deal in the Software without restriction, including without<br>
>     limitation<br>
>     + * the rights to use, copy, modify, merge, publish, distribute,<br>
>     sublicense,<br>
>     + * and/or sell copies of the Software, and to permit persons to<br>
>     whom the<br>
>     + * Software is furnished to do so, subject to the following conditions:<br>
>     + *<br>
>     + * The above copyright notice and this permission notice (including<br>
>     the next<br>
>     + * paragraph) shall be included in all copies or substantial<br>
>     portions of the<br>
>     + * Software.<br>
>     + *<br>
>     + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,<br>
>     EXPRESS OR<br>
>     + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<br>
>     MERCHANTABILITY,<br>
>     + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO<br>
>     EVENT SHALL<br>
>     + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,<br>
>     DAMAGES OR OTHER<br>
>     + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
>     ARISING<br>
>     + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
>     + * DEALINGS IN THE SOFTWARE.<br>
>     + */<br>
>     +#include <gtest/gtest.h><br>
>     +#include "standalone_scaffolding.h"<br>
>     +#include "main/compiler.h"<br>
>     +#include "main/mtypes.h"<br>
>     +#include "main/macros.h"<br>
>     +#include "ralloc.h"<br>
>     +#include "ir.h"<br>
>     +#include "glsl_parser_extras.h"<br>
>     +#include "glsl_symbol_table.h"<br>
>     +<br>
>     +class common_builtin : public ::testing::Test {<br>
>     +public:<br>
>     +   common_builtin(GLenum shader_type)<br>
>     +      : shader_type(shader_type)<br>
>     +   {<br>
>     +      /* empty */<br>
>     +   }<br>
>     +<br>
>     +   virtual void SetUp();<br>
>     +   virtual void TearDown();<br>
>     +<br>
>     +   void string_starts_with_prefix(const char *str, const char *prefix);<br>
>     +   void names_start_with_gl();<br>
>     +   void uniforms_and_system_values_dont_have_explicit_location();<br>
>     +   void constants_are_constant();<br>
>     +   void no_invalid_variable_modes();<br>
>     +<br>
>     +   GLenum shader_type;<br>
>     +   struct _mesa_glsl_parse_state *state;<br>
>     +   struct gl_shader *shader;<br>
>     +   void *mem_ctx;<br>
>     +   gl_context ctx;<br>
>     +   exec_list ir;<br>
>     +};<br>
>     +<br>
>     +void<br>
>     +common_builtin::SetUp()<br>
>     +{<br>
>     +   this->mem_ctx = ralloc_context(NULL);<br>
>     +   this->ir.make_empty();<br>
>     +<br>
>     +   initialize_context_to_defaults(&this->ctx, API_OPENGL_COMPAT);<br>
>     +<br>
>     +   this->shader = rzalloc(this->mem_ctx, gl_shader);<br>
>     +   this->shader->Type = this->shader_type;<br>
>     +<br>
>     +   this->state =<br>
>     +      new(mem_ctx) _mesa_glsl_parse_state(&this->ctx,<br>
>     this->shader->Type,<br>
>     +                                          this->shader);<br>
>     +<br>
>     +   _mesa_glsl_initialize_types(this->state);<br>
>     +   _mesa_glsl_initialize_variables(&this->ir, this->state);<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::TearDown()<br>
>     +{<br>
>     +   ralloc_free(this->mem_ctx);<br>
>     +   this->mem_ctx = NULL;<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::string_starts_with_prefix(const char *str, const<br>
>     char *prefix)<br>
>     +{<br>
>     +   const size_t len = strlen(prefix);<br>
>     +   char *const name_prefix = new char[len];<br>
><br>
><br>
> This needs to be new char[len + 1], since you assign to its len'th<br>
> element below.<br>
<br>
</div></div>Yes... and I forgot to release the memory when I was done.  Strong work.<br>
:(  I'll fix both of those issues.<br>
<div><div class="h5"><br>
>     +<br>
>     +   strncpy(name_prefix, str, len);<br>
>     +   name_prefix[len] = '\0';<br>
>     +   EXPECT_STREQ(prefix, name_prefix) << "Bad name " << str;<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::names_start_with_gl()<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      string_starts_with_prefix(var->name, "gl_");<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::uniforms_and_system_values_dont_have_explicit_location()<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      if (var->mode != ir_var_uniform && var->mode !=<br>
>     ir_var_system_value)<br>
>     +         continue;<br>
>     +<br>
>     +      EXPECT_FALSE(var->explicit_location);<br>
>     +      EXPECT_EQ(-1, var->location);<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::constants_are_constant()<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      if (var->mode != ir_var_auto)<br>
>     +         continue;<br>
>     +<br>
>     +      EXPECT_FALSE(var->explicit_location);<br>
>     +      EXPECT_EQ(-1, var->location);<br>
>     +      EXPECT_TRUE(var->read_only);<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +void<br>
>     +common_builtin::no_invalid_variable_modes()<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      switch (var->mode) {<br>
>     +      case ir_var_auto:<br>
>     +      case ir_var_uniform:<br>
>     +      case ir_var_shader_in:<br>
>     +      case ir_var_shader_out:<br>
>     +      case ir_var_system_value:<br>
>     +         break;<br>
>     +<br>
>     +      /* Invalid modes that we know. */<br>
>     +      case ir_var_function_in:<br>
>     +      case ir_var_function_out:<br>
>     +      case ir_var_function_inout:<br>
>     +      case ir_var_const_in:<br>
>     +      case ir_var_temporary:<br>
>     +         EXPECT_NE(ir_var_function_in, var->mode);<br>
>     +         EXPECT_NE(ir_var_function_out, var->mode);<br>
>     +         EXPECT_NE(ir_var_function_inout, var->mode);<br>
>     +         EXPECT_NE(ir_var_const_in, var->mode);<br>
>     +         EXPECT_NE(ir_var_temporary, var->mode);<br>
>     +         break;<br>
><br>
><br>
> This block seems really strange to me.  All of these invalid modes are<br>
> adequately covered by the default case, which is easier to read.<br>
<br>
</div></div>I did that so that when a failure was encountered a more reasonable<br>
message would be logged.  However, it occurs to me that isn't very<br>
useful because you still don't know which variable failed.  I've deleted<br>
this block and changed the default case to:<br>
<br>
      default:<br>
         ADD_FAILURE() << "Built-in variable " << var->name<br>
                       << " has an invalid mode " << int(var->mode);<br>
         break;<br>
<br>
That should make it easier to track down failures.<br></blockquote><div><br></div><div>That sounds reasonable.  Thanks.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="im"><br>
> With those two things fixed, this patch is:<br>
><br>
> Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a><br>
</div>> <mailto:<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>>><br>
<div><div class="h5">><br>
><br>
>     +<br>
>     +      /* Invalid modes that we don't know. */<br>
>     +      default:<br>
>     +         EXPECT_TRUE(false) << "invalid mode " << int(var->mode);<br>
>     +         break;<br>
>     +      }<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +/************************************************************/<br>
>     +<br>
>     +class vertex_builtin : public common_builtin {<br>
>     +public:<br>
>     +   vertex_builtin()<br>
>     +      : common_builtin(GL_VERTEX_SHADER)<br>
>     +   {<br>
>     +      /* empty */<br>
>     +   }<br>
>     +};<br>
>     +<br>
>     +TEST_F(vertex_builtin, names_start_with_gl)<br>
>     +{<br>
>     +   common_builtin::names_start_with_gl();<br>
>     +}<br>
>     +<br>
>     +TEST_F(vertex_builtin, inputs_have_explicit_location)<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      if (var->mode != ir_var_shader_in)<br>
>     +         continue;<br>
>     +<br>
>     +      EXPECT_TRUE(var->explicit_location);<br>
>     +      EXPECT_NE(-1, var->location);<br>
>     +      EXPECT_GT(VERT_ATTRIB_GENERIC0, var->location);<br>
>     +      EXPECT_EQ(0u, var->location_frac);<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +TEST_F(vertex_builtin, outputs_have_explicit_location)<br>
>     +{<br>
>     +   foreach_list(node, &this->ir) {<br>
>     +      ir_variable *const var = ((ir_instruction *)<br>
>     node)->as_variable();<br>
>     +<br>
>     +      if (var->mode != ir_var_shader_out)<br>
>     +         continue;<br>
>     +<br>
>     +      EXPECT_TRUE(var->explicit_location);<br>
>     +      EXPECT_NE(-1, var->location);<br>
>     +      EXPECT_GT(VARYING_SLOT_VAR0, var->location);<br>
>     +      EXPECT_EQ(0u, var->location_frac);<br>
>     +<br>
>     +      /* Several varyings only exist in the fragment shader.  Be<br>
>     sure that no<br>
>     +       * outputs with these locations exist.<br>
>     +       */<br>
>     +      EXPECT_NE(VARYING_SLOT_PNTC, var->location);<br>
>     +      EXPECT_NE(VARYING_SLOT_FACE, var->location);<br>
>     +      EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID, var->location);<br>
>     +   }<br>
>     +}<br>
>     +<br>
>     +TEST_F(vertex_builtin,<br>
>     uniforms_and_system_values_dont_have_explicit_location)<br>
>     +{<br>
>     +<br>
>     common_builtin::uniforms_and_system_values_dont_have_explicit_location();<br>
>     +}<br>
>     +<br>
>     +TEST_F(vertex_builtin, constants_are_constant)<br>
>     +{<br>
>     +   common_builtin::constants_are_constant();<br>
>     +}<br>
>     +<br>
>     +TEST_F(vertex_builtin, no_invalid_variable_modes)<br>
>     +{<br>
>     +   common_builtin::no_invalid_variable_modes();<br>
>     +}<br>
>     --<br>
>     1.8.1.4<br>
><br>
>     _______________________________________________<br>
>     mesa-dev mailing list<br>
</div></div>>     <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a> <mailto:<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a>><br>
>     <a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
<br>
</blockquote></div><br></div></div>