Browse Source

Updated glsl-optmizer.

Branimir Karadžić 10 years ago
parent
commit
c5ed5d3b00
28 changed files with 234 additions and 665 deletions
  1. 12 0
      3rdparty/glsl-optimizer/Changelog.md
  2. 0 1
      3rdparty/glsl-optimizer/autogen.sh
  3. 0 3
      3rdparty/glsl-optimizer/projects/vs2010/glsl_optimizer_lib.vcxproj.filters
  4. 0 4
      3rdparty/glsl-optimizer/projects/xcode5/glsl_optimizer_lib.xcodeproj/project.pbxproj
  5. 0 1
      3rdparty/glsl-optimizer/src/glsl/Makefile
  6. 8 6
      3rdparty/glsl-optimizer/src/glsl/glsl_optimizer.cpp
  7. 2 0
      3rdparty/glsl-optimizer/src/glsl/glsl_optimizer.h
  8. 0 8
      3rdparty/glsl-optimizer/src/glsl/ir_optimization.h
  9. 8 0
      3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp
  10. 4 2
      3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp
  11. 0 485
      3rdparty/glsl-optimizer/src/glsl/opt_vector_splitting.cpp
  12. 0 1
      3rdparty/glsl-optimizer/src/glsl_optimizer_lib.gyp
  13. 20 0
      3rdparty/glsl-optimizer/tests/fragment/tex2DArray-in.txt
  14. 19 0
      3rdparty/glsl-optimizer/tests/fragment/tex2DArray-inES3.txt
  15. 14 0
      3rdparty/glsl-optimizer/tests/fragment/tex2DArray-out.txt
  16. 33 0
      3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3.txt
  17. 42 0
      3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3Metal.txt
  18. 1 1
      3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-out.txt
  19. 1 1
      3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES.txt
  20. 1 1
      3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3.txt
  21. 1 1
      3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3Metal.txt
  22. 1 1
      3rdparty/glsl-optimizer/tests/fragment/texProj-outES.txt
  23. 1 1
      3rdparty/glsl-optimizer/tests/fragment/texProj-outES3.txt
  24. 1 1
      3rdparty/glsl-optimizer/tests/fragment/texProj-outES3Metal.txt
  25. 2 0
      3rdparty/glsl-optimizer/tests/glsl_optimizer_tests.cpp
  26. 22 50
      3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-out.txt
  27. 22 50
      3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3.txt
  28. 19 47
      3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3Metal.txt

+ 12 - 0
3rdparty/glsl-optimizer/Changelog.md

@@ -1,6 +1,18 @@
 GLSL optimizer Change Log
 =========================
 
+2015 08
+-------
+
+Changes:
+
+* 2D shadow and 2D array uniforms got their own glslopt_basic_type entries.
+
+Fixes:
+
+* Fixed translation of 2D texture arrays (GLSL with EXT_texture_array, GLES3 and Metal).
+
+
 2015 06
 -------
 

+ 0 - 1
3rdparty/glsl-optimizer/autogen.sh

@@ -317,7 +317,6 @@
     <ClCompile Include="..\..\src\glsl\opt_swizzle_swizzle.cpp" />
     <ClCompile Include="..\..\src\glsl\opt_tree_grafting.cpp" />
     <ClCompile Include="..\..\src\glsl\opt_vectorize.cpp" />
-    <ClCompile Include="..\..\src\glsl\opt_vector_splitting.cpp" />
     <ClCompile Include="..\..\src\glsl\s_expression.cpp" />
     <ClCompile Include="..\..\src\glsl\standalone_scaffolding.cpp" />
     <ClCompile Include="..\..\src\glsl\strtod.c" />

+ 0 - 3
3rdparty/glsl-optimizer/projects/vs2010/glsl_optimizer_lib.vcxproj.filters

@@ -491,9 +491,6 @@
     <ClCompile Include="..\..\src\glsl\ir_stats.cpp">
       <Filter>src\glsl</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\glsl\opt_vector_splitting.cpp">
-      <Filter>src\glsl</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\util\hash_table.c">
       <Filter>src\util</Filter>
     </ClCompile>

+ 0 - 4
3rdparty/glsl-optimizer/projects/xcode5/glsl_optimizer_lib.xcodeproj/project.pbxproj

@@ -126,7 +126,6 @@
 		2BA7E14617D0AEB200D5C475 /* lower_vector_insert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7E13C17D0AEB200D5C475 /* lower_vector_insert.cpp */; };
 		2BA7E14817D0AEB200D5C475 /* opt_dead_builtin_varyings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7E13D17D0AEB200D5C475 /* opt_dead_builtin_varyings.cpp */; };
 		2BA7E14A17D0AEB200D5C475 /* opt_flip_matrices.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA7E13E17D0AEB200D5C475 /* opt_flip_matrices.cpp */; };
-		2BA84CA619580C9D0021BE1D /* opt_vector_splitting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BA84CA519580C9D0021BE1D /* opt_vector_splitting.cpp */; };
 		2BB2F5B012B8F1580052C6B0 /* lower_discard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BB2F5AA12B8F1580052C6B0 /* lower_discard.cpp */; };
 		2BB2F5B112B8F1580052C6B0 /* lower_instructions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BB2F5AB12B8F1580052C6B0 /* lower_instructions.cpp */; };
 		2BB2F5B212B8F1580052C6B0 /* lower_vector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2BB2F5AC12B8F1580052C6B0 /* lower_vector.cpp */; };
@@ -292,7 +291,6 @@
 		2BA7E13C17D0AEB200D5C475 /* lower_vector_insert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lower_vector_insert.cpp; path = ../../src/glsl/lower_vector_insert.cpp; sourceTree = "<group>"; };
 		2BA7E13D17D0AEB200D5C475 /* opt_dead_builtin_varyings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = opt_dead_builtin_varyings.cpp; path = ../../src/glsl/opt_dead_builtin_varyings.cpp; sourceTree = "<group>"; };
 		2BA7E13E17D0AEB200D5C475 /* opt_flip_matrices.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = opt_flip_matrices.cpp; path = ../../src/glsl/opt_flip_matrices.cpp; sourceTree = "<group>"; };
-		2BA84CA519580C9D0021BE1D /* opt_vector_splitting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = opt_vector_splitting.cpp; path = ../../src/glsl/opt_vector_splitting.cpp; sourceTree = "<group>"; };
 		2BB2F5AA12B8F1580052C6B0 /* lower_discard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lower_discard.cpp; path = ../../src/glsl/lower_discard.cpp; sourceTree = SOURCE_ROOT; };
 		2BB2F5AB12B8F1580052C6B0 /* lower_instructions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lower_instructions.cpp; path = ../../src/glsl/lower_instructions.cpp; sourceTree = SOURCE_ROOT; };
 		2BB2F5AC12B8F1580052C6B0 /* lower_vector.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = lower_vector.cpp; path = ../../src/glsl/lower_vector.cpp; sourceTree = SOURCE_ROOT; };
@@ -543,7 +541,6 @@
 				2B38545B1293BE5000F3E692 /* opt_swizzle_swizzle.cpp */,
 				2B38545C1293BE5000F3E692 /* opt_tree_grafting.cpp */,
 				2B9F0A3C189664F3002FF617 /* opt_vectorize.cpp */,
-				2BA84CA519580C9D0021BE1D /* opt_vector_splitting.cpp */,
 				2BA55A991207FEA6002DC82D /* program.h */,
 				2BA55A9A1207FEA6002DC82D /* s_expression.cpp */,
 				2BA55A9B1207FEA6002DC82D /* s_expression.h */,
@@ -730,7 +727,6 @@
 				2B78C91D1858B052007F5D2A /* ir_equals.cpp in Sources */,
 				2B6A99F61223B1670059FBED /* glcpp-parse.c in Sources */,
 				2B6A99FB1223B1670059FBED /* pp.c in Sources */,
-				2BA84CA619580C9D0021BE1D /* opt_vector_splitting.cpp in Sources */,
 				2BBA49281254706A00D42573 /* glsl_symbol_table.cpp in Sources */,
 				2BBA492A1254706A00D42573 /* loop_analysis.cpp in Sources */,
 				2BBA492C1254706A00D42573 /* loop_controls.cpp in Sources */,

+ 0 - 1
3rdparty/glsl-optimizer/src/glsl/Makefile

@@ -103,7 +103,6 @@ SRC = ast_array_index.cpp \
 	opt_swizzle_swizzle.cpp \
 	opt_tree_grafting.cpp \
 	opt_vectorize.cpp \
-	opt_vector_splitting.cpp \
 	s_expression.cpp \
 	standalone_scaffolding.cpp \
 	strtod.c \

+ 8 - 6
3rdparty/glsl-optimizer/src/glsl/glsl_optimizer.cpp

@@ -454,10 +454,6 @@ static void do_optimization_passes(exec_list* ir, bool linked, _mesa_glsl_parse_
 		progress2 = propagate_precision (ir, state->metal_target); progress |= progress2; if (progress2) debug_print_ir ("After prec propagation", ir, state, mem_ctx);
 		progress2 = do_copy_propagation(ir); progress |= progress2; if (progress2) debug_print_ir ("After copy propagation", ir, state, mem_ctx);
 		progress2 = do_copy_propagation_elements(ir); progress |= progress2; if (progress2) debug_print_ir ("After copy propagation elems", ir, state, mem_ctx);
-		if (state->es_shader && linked)
-		{
-			progress2 = optimize_split_vectors(ir, linked, OPT_SPLIT_ONLY_LOOP_INDUCTORS); progress |= progress2; if (progress2) debug_print_ir("After split vectors", ir, state, mem_ctx);
-		}
 
 		if (linked)
 		{
@@ -488,7 +484,6 @@ static void do_optimization_passes(exec_list* ir, bool linked, _mesa_glsl_parse_
 		progress2 = do_swizzle_swizzle(ir); progress |= progress2; if (progress2) debug_print_ir ("After swizzle swizzle", ir, state, mem_ctx);
 		progress2 = do_noop_swizzle(ir); progress |= progress2; if (progress2) debug_print_ir ("After noop swizzle", ir, state, mem_ctx);
 		progress2 = optimize_split_arrays(ir, linked, state->metal_target && state->stage == MESA_SHADER_FRAGMENT); progress |= progress2; if (progress2) debug_print_ir ("After split arrays", ir, state, mem_ctx);
-		progress2 = optimize_split_vectors(ir, linked, OPT_SPLIT_ONLY_UNUSED); progress |= progress2; if (progress2) debug_print_ir("After split unused vectors", ir, state, mem_ctx);
 		progress2 = optimize_redundant_jumps(ir); progress |= progress2; if (progress2) debug_print_ir ("After redundant jumps", ir, state, mem_ctx);
 
 		// do loop stuff only when linked; otherwise causes duplicate loop induction variable
@@ -528,7 +523,14 @@ static void glsl_type_to_optimizer_desc(const glsl_type* type, glsl_precision pr
 	else if (type->is_sampler())
 	{
 		if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D)
-			out->type = kGlslTypeTex2D;
+		{
+			if (type->sampler_shadow)
+				out->type = kGlslTypeTex2DShadow;
+			else if (type->sampler_array)
+				out->type = kGlslTypeTex2DArray;
+			else
+				out->type = kGlslTypeTex2D;
+		}
 		else if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_3D)
 			out->type = kGlslTypeTex3D;
 		else if (type->sampler_dimensionality == GLSL_SAMPLER_DIM_CUBE)

+ 2 - 0
3rdparty/glsl-optimizer/src/glsl/glsl_optimizer.h

@@ -52,6 +52,8 @@ enum glslopt_basic_type {
 	kGlslTypeTex2D,
 	kGlslTypeTex3D,
 	kGlslTypeTexCube,
+	kGlslTypeTex2DShadow,
+	kGlslTypeTex2DArray,
 	kGlslTypeOther,
 	kGlslTypeCount
 };

+ 0 - 8
3rdparty/glsl-optimizer/src/glsl/ir_optimization.h

@@ -124,14 +124,6 @@ bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index);
 void lower_named_interface_blocks(void *mem_ctx, gl_shader *shader);
 bool optimize_redundant_jumps(exec_list *instructions);
 
-typedef enum {
-  OPT_SPLIT_ONLY_LOOP_INDUCTORS = 0, //< only split vectors that are used as loop inductors (and are not used by any vector operation)
-  OPT_SPLIT_ONLY_UNUSED = 1, //< only split vectors that have unused components (and are not used by any vector operation)
-  OPT_SPLIT_ANY_POSSIBLE = 2, //< Split all vectors that are only accessed by their components
-} glsl_vector_splitting_mode;
-
-bool optimize_split_vectors(exec_list *instructions, bool linked, glsl_vector_splitting_mode mode);
-
 bool optimize_split_arrays(exec_list *instructions, bool linked, bool split_shader_outputs);
 bool lower_offset_arrays(exec_list *instructions);
 void optimize_dead_builtin_variables(exec_list *instructions,

+ 8 - 0
3rdparty/glsl-optimizer/src/glsl/ir_print_glsl_visitor.cpp

@@ -254,6 +254,8 @@ _mesa_print_ir_glsl(exec_list *instructions,
 			str.asprintf_append ("#extension GL_EXT_shader_framebuffer_fetch : enable\n");
 		if (state->ARB_shader_bit_encoding_enable)
 			str.asprintf_append("#extension GL_ARB_shader_bit_encoding : enable\n");
+		if (state->EXT_texture_array_enable)
+			str.asprintf_append ("#extension GL_EXT_texture_array : enable\n");
 	}
 	
 	// remove unused struct declarations
@@ -822,11 +824,14 @@ void ir_print_glsl_visitor::visit(ir_texture *ir)
 {
 	glsl_sampler_dim sampler_dim = (glsl_sampler_dim)ir->sampler->type->sampler_dimensionality;
 	const bool is_shadow = ir->sampler->type->sampler_shadow;
+	const bool is_array = ir->sampler->type->sampler_array;
 	const glsl_type* uv_type = ir->coordinate->type;
 	const int uv_dim = uv_type->vector_elements;
 	int sampler_uv_dim = tex_sampler_dim_size[sampler_dim];
 	if (is_shadow)
 		sampler_uv_dim += 1;
+	if (is_array)
+		sampler_uv_dim += 1;
 	const bool is_proj = (uv_dim > sampler_uv_dim);
 	const bool is_lod = (ir->op == ir_txl);
 	
@@ -876,6 +881,9 @@ void ir_print_glsl_visitor::visit(ir_texture *ir)
         else
             buffer.asprintf_append ("texture");
     }
+
+	if (is_array && state->EXT_texture_array_enable)
+		buffer.asprintf_append ("Array");
 	
 	if (is_proj)
 		buffer.asprintf_append ("Proj");

+ 4 - 2
3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp

@@ -235,8 +235,10 @@ _mesa_print_ir_metal(exec_list *instructions,
 			// skip gl_ variables if they aren't used/assigned
 			if (strstr(var->name, "gl_") == var->name)
 			{
-				if (!var->data.used && !var->data.assigned)
-					continue;
+				if (NULL == strstr(var->name, "gl_FragData_") ) {
+					if (!var->data.used && !var->data.assigned)
+						continue;
+				}
 			}
 
 			//

+ 0 - 485
3rdparty/glsl-optimizer/src/glsl/opt_vector_splitting.cpp

@@ -1,485 +0,0 @@
-/*
- * Based on work Copyright © 2010 Intel Corporation, vector splitting
- * implemented by Copyright © 2014 Unity Technologies
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file opt_vector_splitting.cpp
- *
- * If a vector is always dereferenced only by its xyzw components separately,
- * and never accessed as a whole (or with swizzle mask with >1 bits set), then
- * split it apart into its elements, making it more amenable to other
- * optimization passes.
- *
- * This skips uniforms/varyings, which would need careful
- * handling due to their ir->location fields tying them to the GL API
- * and other shader stages.
- */
-
-#include "ir.h"
-#include "ir_visitor.h"
-#include "ir_rvalue_visitor.h"
-#include "glsl_types.h"
-#include "ir_optimization.h"
-#include "loop_analysis.h"
-
-static bool debug = false;
-
-namespace {
-	namespace opt_vector_splitting {
-
-		class variable_entry : public exec_node
-		{
-		public:
-			variable_entry(ir_variable *var)
-			{
-				this->var = var;
-				this->split = true;
-				this->use_mask = 0;
-				this->declaration = false;
-				this->components = NULL;
-				this->mem_ctx = NULL;
-			}
-
-			ir_variable *var; /* The key: the variable's pointer. */
-
-			/** Whether this array should be split or not. */
-			bool split;
-
-			/** bitmask for the components in the vector that actually get written to.
-			 * If multiple slots are written simultaneously, split gets set to false.*/
-			int use_mask;
-
-			/* If the variable had a decl we can work with in the instruction
-			 * stream.  We can't do splitting on function arguments, which
-			 * don't get this variable set.
-			 */
-			bool declaration;
-
-			ir_variable **components;
-
-			/** ralloc_parent(this->var) -- the shader's talloc context. */
-			void *mem_ctx;
-		};
-
-	} /* namespace */
-
-
-using namespace opt_vector_splitting;
-
-/**
- * This class does a walk over the tree, coming up with the set of
- * variables that could be split by looking to see if they are arrays
- * that are only ever constant-index dereferenced.
- */
-class ir_vector_reference_visitor : public ir_hierarchical_visitor {
-public:
-   ir_vector_reference_visitor(void)
-   {
-      this->mem_ctx = ralloc_context(NULL);
-      this->variable_list.make_empty();
-   }
-
-   ~ir_vector_reference_visitor(void)
-   {
-      ralloc_free(mem_ctx);
-   }
-
-   bool get_split_list(exec_list *instructions, bool linked, glsl_vector_splitting_mode mode);
-
-   virtual ir_visitor_status visit(ir_variable *);
-   virtual ir_visitor_status visit(ir_dereference_variable *);
-   virtual ir_visitor_status visit_enter(ir_swizzle *);
-   virtual ir_visitor_status visit_enter(ir_assignment *);
-   virtual ir_visitor_status visit_enter(ir_function_signature *);
-
-   variable_entry *get_variable_entry(ir_variable *var);
-
-   /* List of variable_entry */
-   exec_list variable_list;
-
-   /* Current split mode */
-   glsl_vector_splitting_mode mode;
-
-   loop_state *loopstate;
-
-   void *mem_ctx;
-};
-
-} /* namespace */
-
-variable_entry *
-ir_vector_reference_visitor::get_variable_entry(ir_variable *var)
-{
-   assert(var);
-
-   if (var->data.mode != ir_var_auto &&
-       var->data.mode != ir_var_temporary)
-      return NULL;
-
-   if (!var->type->is_vector())
-      return NULL;
-
-   // If mode is loop_inductors, allow only loop inductors to be stored.
-   if (mode == OPT_SPLIT_ONLY_LOOP_INDUCTORS && loopstate)
-   {
-	   loop_variable_state* inductor_state = loopstate->get_for_inductor(var);
-	   if (!inductor_state)
-	   {
-		   return NULL;
-	   }
-   }
-
-   foreach_in_list(variable_entry, entry, &this->variable_list) {
-      if (entry->var == var)
-	 return entry;
-   }
-
-
-   variable_entry *entry = new(mem_ctx) variable_entry(var);
-   this->variable_list.push_tail(entry);
-   return entry;
-}
-
-
-ir_visitor_status
-ir_vector_reference_visitor::visit(ir_variable *ir)
-{
-   variable_entry *entry = this->get_variable_entry(ir);
-
-   if (entry)
-      entry->declaration = true;
-
-   return visit_continue;
-}
-
-ir_visitor_status
-ir_vector_reference_visitor::visit(ir_dereference_variable *ir)
-{
-   variable_entry *entry = this->get_variable_entry(ir->var);
-
-   /* If we made it to here without seeing an ir_swizzle,
-    * then the dereference of this vector didn't have a swizzle in it
-    * (see the visit_continue_with_parent below), so we can't split
-    * the variable.
-    */
-   if (entry)
-      entry->split = false;
-
-   return visit_continue;
-}
-
-ir_visitor_status
-ir_vector_reference_visitor::visit_enter(ir_swizzle *ir)
-{
-	ir_variable *var = ir->variable_referenced();
-   if (!var)
-      return visit_continue;
-
-   variable_entry *entry = this->get_variable_entry(var);
-
-   if (entry)
-   {
-	   if (ir->mask.num_components > 1)
-	   {
-		   entry->split = false;
-	   }
-	   else
-	   {
-		   // Update the usemask
-		   entry->use_mask |= (1 << ir->mask.x);
-	   }
-   }
-
-	// Skip the rest of the swizzle IR tree, we're done here.
-   return visit_continue_with_parent;
-}
-
-ir_visitor_status
-ir_vector_reference_visitor::visit_enter(ir_assignment *ir)
-{
-	ir_dereference_variable *dest = ir->lhs->as_dereference_variable();
-	if (dest)
-	{
-		variable_entry *entry = this->get_variable_entry(dest->var);
-		if (entry)
-		{
-			// Count how many bits the write mask has
-			unsigned maskbitval = ir->write_mask; // count the number of bits set
-			int maskbitcount; // accumulates the total bits set
-			for ( maskbitcount = 0; maskbitval; maskbitcount++)
-			{
-				maskbitval &= maskbitval - 1; // clear the least significant bit set
-			}
-			if (maskbitcount > 1)
-			{
-				// Writing to more than one slot, cannot split.
-				entry->split = false;
-			}
-
-			// Update write mask
-			entry->use_mask |= ir->write_mask;
-		}
-	}
-
-	// Visit only the rhs, there may be swizzles and variable dereferences there as well
-	ir->rhs->accept(this);
-	return visit_continue_with_parent;
-
-}
-
-ir_visitor_status
-ir_vector_reference_visitor::visit_enter(ir_function_signature *ir)
-{
-   /* We don't have logic for array-splitting function arguments,
-    * so just look at the body instructions and not the parameter
-    * declarations.
-    */
-   visit_list_elements(this, &ir->body);
-   return visit_continue_with_parent;
-}
-
-bool
-ir_vector_reference_visitor::get_split_list(exec_list *instructions,
-					   bool linked,
-					   glsl_vector_splitting_mode _mode)
-{
-	mode = _mode;
-
-	if (linked)
-	{
-		loop_state* ls = analyze_loop_variables(instructions);
-		if (ls->loop_found)
-			set_loop_controls(instructions, ls);
-
-		loopstate = ls;
-	}
-	else
-	{
-		loopstate = NULL;
-	}
-
-	visit_list_elements(this, instructions);
-
-   /* If the shaders aren't linked yet, we can't mess with global
-    * declarations, which need to be matched by name across shaders.
-    */
-   if (!linked) {
-      foreach_in_list(ir_variable, var, instructions) {
-	 if (var) {
-	    variable_entry *entry = get_variable_entry(var);
-	    if (entry)
-	       entry->remove();
-	 }
-      }
-   }
-
-   /* Trim out variables we found that we can't split. */
-   foreach_in_list_safe(variable_entry, entry, &variable_list) {
-
-      if (debug) {
-	 printf("array %s@%p: decl %d, split %d\n",
-		entry->var->name, (void *) entry->var, entry->declaration,
-		entry->split);
-      }
-
-      if (!(entry->declaration && entry->split)) {
-	 entry->remove();
-      }
-	  else if (mode == OPT_SPLIT_ONLY_UNUSED)
-	  {
-		  /* Build mask of fully used vector (vec2 -> 0x3, vec3 -> 0x7, vec4 -> 0xe) */
-		  unsigned int fullmask = (1 << entry->var->type->vector_elements) - 1;
-		  if (entry->use_mask == fullmask)
-		  {
-			  entry->remove();
-		  }
-	  }
-   }
-
-   return !variable_list.is_empty();
-}
-
-/**
- * This class rewrites the dereferences of arrays that have been split
- * to use the newly created ir_variables for each component.
- */
-class ir_vector_splitting_visitor : public ir_rvalue_visitor {
-public:
-   ir_vector_splitting_visitor(exec_list *vars)
-   {
-      this->variable_list = vars;
-   }
-
-   virtual ~ir_vector_splitting_visitor()
-   {
-   }
-
-   virtual ir_visitor_status visit_leave(ir_assignment *);
-
-   void split_rvalue(ir_rvalue **rval);
-   void handle_rvalue(ir_rvalue **rvalue);
-   variable_entry *get_splitting_entry(ir_variable *var);
-
-   exec_list *variable_list;
-};
-
-variable_entry *
-ir_vector_splitting_visitor::get_splitting_entry(ir_variable *var)
-{
-   assert(var);
-
-   foreach_in_list(variable_entry, entry, this->variable_list) {
-      if (entry->var == var) {
-	 return entry;
-      }
-   }
-
-   return NULL;
-}
-
-void
-ir_vector_splitting_visitor::split_rvalue(ir_rvalue **rval)
-{
-	ir_swizzle *swizzle = (*rval)->as_swizzle();
-
-	if (!swizzle)
-		return;
-
-	ir_variable *var = swizzle->variable_referenced();
-	if (!var)
-		return;
-
-   variable_entry *entry = get_splitting_entry(var);
-   if (!entry)
-      return;
-
-   assert(swizzle->mask.num_components == 1);
-
-   *rval = new(entry->mem_ctx)
-	 ir_dereference_variable(entry->components[swizzle->mask.x]);
-}
-
-void
-ir_vector_splitting_visitor::handle_rvalue(ir_rvalue **rvalue)
-{
-   if (!*rvalue)
-      return;
-
-   ir_rvalue *v = *rvalue;
-   split_rvalue(&v);
-   *rvalue = v;
-}
-
-ir_visitor_status
-ir_vector_splitting_visitor::visit_leave(ir_assignment *ir)
-{
-   /* The normal rvalue visitor skips the LHS of assignments, but we
-    * need to process those just the same.
-    */
-   ir_rvalue *lhs = ir->lhs;
-
-   ir_dereference_variable *dest = ir->lhs->as_dereference_variable();
-   if (dest)
-   {
-	   variable_entry *entry = get_splitting_entry(dest->var);
-	   if (entry)
-	   {
-		   // Find the only set bit in writemask
-		   int component = 0;
-		   while (((ir->write_mask & (1 << component)) == 0) && (component < 4))
-		   {
-			   component++;
-		   }
-		   assert(ir->write_mask == (1 << component));
-
-		   ir_dereference_variable *newderef = new(entry->mem_ctx)
-			   ir_dereference_variable(entry->components[component]);
-
-		   ir->set_lhs(newderef);
-	   }
-   }
-   else
-   {
-	   ir->lhs = lhs->as_dereference();
-	   ir->lhs->accept(this);
-   }
-
-   handle_rvalue(&ir->rhs);
-   ir->rhs->accept(this);
-
-   if (ir->condition) {
-      handle_rvalue(&ir->condition);
-      ir->condition->accept(this);
-   }
-
-   return visit_continue;
-}
-
-bool
-optimize_split_vectors(exec_list *instructions, bool linked, glsl_vector_splitting_mode mode)
-{
-   ir_vector_reference_visitor refs;
-   if (!refs.get_split_list(instructions, linked, mode))
-      return false;
-
-   void *mem_ctx = ralloc_context(NULL);
-
-   /* Replace the decls of the vectors to be split with their split
-    * components.
-    */
-   foreach_in_list(variable_entry, entry, &refs.variable_list) {
-      const struct glsl_type *type = entry->var->type;
-      const struct glsl_type *subtype;
-      glsl_precision subprec = (glsl_precision)entry->var->data.precision;
-
-	  subtype = type->get_base_type();
-
-      entry->mem_ctx = ralloc_parent(entry->var);
-
-      entry->components = ralloc_array(mem_ctx,
-				       ir_variable *,
-				       type->vector_elements);
-
-      for (unsigned int i = 0; i < type->vector_elements; i++) {
-	 const char *name = ralloc_asprintf(mem_ctx, "%s_%c",
-					    entry->var->name, "xyzw"[i]);
-
-	 entry->components[i] =
-	    new(entry->mem_ctx) ir_variable(subtype, name, ir_var_temporary, subprec);
-	 entry->var->insert_before(entry->components[i]);
-      }
-
-      entry->var->remove();
-   }
-
-   ir_vector_splitting_visitor split(&refs.variable_list);
-   visit_list_elements(&split, instructions);
-
-   if (debug)
-      _mesa_print_ir(stdout, instructions, NULL);
-
-   ralloc_free(mem_ctx);
-
-   return true;
-
-}

+ 0 - 1
3rdparty/glsl-optimizer/src/glsl_optimizer_lib.gyp

@@ -135,7 +135,6 @@
         'glsl/opt_swizzle_swizzle.cpp',
         'glsl/opt_tree_grafting.cpp',
         'glsl/opt_vectorize.cpp',
-        'glsl/opt_vector_splitting.cpp',
         'glsl/opt_flip_matrices.cpp',
         'glsl/opt_dead_builtin_varyings.cpp',
         'glsl/program.h',

+ 20 - 0
3rdparty/glsl-optimizer/tests/fragment/tex2DArray-in.txt

@@ -0,0 +1,20 @@
+#extension GL_EXT_texture_array : require
+
+vec4 xll_tex2DArray(sampler2DArray s, vec3 coord) { return texture2DArray (s, coord); }
+vec4 xll_tex2DArrayBias(sampler2DArray s, vec4 coord) { return texture2DArray (s, coord.xyz, coord.w); }
+
+uniform sampler2DArray myarr;
+
+vec4 xlat_main( in vec4 uv ) {
+    vec4 s = xll_tex2DArray( myarr, uv.xyz);
+    vec4 sswiz = xll_tex2DArray( myarr, uv.xyw);
+    vec4 sbias = xll_tex2DArrayBias( myarr, vec4( uv.xyz, 1.5));
+    return s + sswiz + sbias;
+}
+
+varying vec4 uv;
+void main() {
+    vec4 xl_retval;
+    xl_retval = xlat_main(uv);
+    gl_FragData[0] = vec4(xl_retval);
+}

+ 19 - 0
3rdparty/glsl-optimizer/tests/fragment/tex2DArray-inES3.txt

@@ -0,0 +1,19 @@
+#version 300 es
+out lowp vec4 _fragData;
+
+vec4 xll_tex2DArray(sampler2DArray s, vec3 coord) { return texture (s, coord); }
+vec4 xll_tex2DArrayBias(sampler2DArray s, vec4 coord) { return texture (s, coord.xyz, coord.w); }
+
+uniform lowp sampler2DArray myarr;
+
+lowp vec4 xlat_main( in highp vec4 uv ) {
+    highp vec4 s = xll_tex2DArray( myarr, uv.xyz);
+    highp vec4 sswiz = xll_tex2DArray( myarr, uv.xyw);
+    highp vec4 sbias = xll_tex2DArrayBias( myarr, vec4( uv.xyz, 1.5));
+    highp vec4 slod = textureLod(myarr, uv.xyz, 2.5);
+    return (((s + sswiz) + sbias) + slod);
+}
+in highp vec4 uv;
+void main() {
+    _fragData = xlat_main(uv);
+}

+ 14 - 0
3rdparty/glsl-optimizer/tests/fragment/tex2DArray-out.txt

@@ -0,0 +1,14 @@
+#extension GL_EXT_texture_array : enable
+uniform sampler2DArray myarr;
+varying vec4 uv;
+void main ()
+{
+  gl_FragData[0] = ((texture2DArray (myarr, uv.xyz) + texture2DArray (myarr, uv.xyw)) + texture2DArray (myarr, uv.xyz, 1.5));
+}
+
+
+// stats: 2 alu 3 tex 0 flow
+// inputs: 1
+//  #0: uv (high float) 4x1 [-1]
+// textures: 1
+//  #0: myarr (high 2darray) 0x0 [-1]

+ 33 - 0
3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3.txt

@@ -0,0 +1,33 @@
+#version 300 es
+out lowp vec4 _fragData;
+uniform sampler2DArray myarr;
+in highp vec4 uv;
+void main ()
+{
+  lowp vec4 tmpvar_1;
+  highp vec4 slod_2;
+  lowp vec4 tmpvar_3;
+  tmpvar_3 = texture (myarr, uv.xyz);
+  highp vec4 tmpvar_4;
+  tmpvar_4 = tmpvar_3;
+  lowp vec4 tmpvar_5;
+  tmpvar_5 = texture (myarr, uv.xyw);
+  highp vec4 tmpvar_6;
+  tmpvar_6 = tmpvar_5;
+  lowp vec4 tmpvar_7;
+  tmpvar_7 = texture (myarr, uv.xyz, 1.5);
+  highp vec4 tmpvar_8;
+  tmpvar_8 = tmpvar_7;
+  lowp vec4 tmpvar_9;
+  tmpvar_9 = textureLod (myarr, uv.xyz, 2.5);
+  slod_2 = tmpvar_9;
+  tmpvar_1 = ((tmpvar_4 + tmpvar_6) + (tmpvar_8 + slod_2));
+  _fragData = tmpvar_1;
+}
+
+
+// stats: 3 alu 4 tex 0 flow
+// inputs: 1
+//  #0: uv (high float) 4x1 [-1]
+// textures: 1
+//  #0: myarr (low 2darray) 0x0 [-1]

+ 42 - 0
3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3Metal.txt

@@ -0,0 +1,42 @@
+#include <metal_stdlib>
+using namespace metal;
+struct xlatMtlShaderInput {
+  float4 uv;
+};
+struct xlatMtlShaderOutput {
+  half4 _fragData [[color(0)]];
+};
+struct xlatMtlShaderUniform {
+};
+fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]]
+  ,   texture2d_array<half> myarr [[texture(0)]], sampler _mtlsmp_myarr [[sampler(0)]])
+{
+  xlatMtlShaderOutput _mtl_o;
+  half4 tmpvar_1;
+  float4 slod_2;
+  half4 tmpvar_3;
+  tmpvar_3 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyz).xy), (uint)((_mtl_i.uv.xyz).z));
+  float4 tmpvar_4;
+  tmpvar_4 = float4(tmpvar_3);
+  half4 tmpvar_5;
+  tmpvar_5 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyw).xy), (uint)((_mtl_i.uv.xyw).z));
+  float4 tmpvar_6;
+  tmpvar_6 = float4(tmpvar_5);
+  half4 tmpvar_7;
+  tmpvar_7 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyz).xy), (uint)((_mtl_i.uv.xyz).z), bias(1.5));
+  float4 tmpvar_8;
+  tmpvar_8 = float4(tmpvar_7);
+  half4 tmpvar_9;
+  tmpvar_9 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyz).xy), (uint)((_mtl_i.uv.xyz).z), level(2.5));
+  slod_2 = float4(tmpvar_9);
+  tmpvar_1 = half4(((tmpvar_4 + tmpvar_6) + (tmpvar_8 + slod_2)));
+  _mtl_o._fragData = tmpvar_1;
+  return _mtl_o;
+}
+
+
+// stats: 3 alu 4 tex 0 flow
+// inputs: 1
+//  #0: uv (high float) 4x1 [-1]
+// textures: 1
+//  #0: myarr (low 2darray) 0x0 [-1] loc 0

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-out.txt

@@ -10,4 +10,4 @@ void main ()
 // inputs: 1
 //  #0: xlv_TEXCOORD0 (high float) 4x1 [-1]
 // textures: 1
-//  #0: shadowmap (high 2d) 0x0 [-1]
+//  #0: shadowmap (high 2dshadow) 0x0 [-1]

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES.txt

@@ -13,4 +13,4 @@ void main ()
 // inputs: 1
 //  #0: xlv_TEXCOORD0 (high float) 4x1 [-1]
 // textures: 1
-//  #0: shadowmap (low 2d) 0x0 [-1]
+//  #0: shadowmap (low 2dshadow) 0x0 [-1]

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3.txt

@@ -20,4 +20,4 @@ void main ()
 //  #0: uvHi (high float) 4x1 [-1]
 //  #1: uvMed (medium float) 4x1 [-1]
 // textures: 1
-//  #0: shadowmap (low 2d) 0x0 [-1]
+//  #0: shadowmap (low 2dshadow) 0x0 [-1]

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3Metal.txt

@@ -30,4 +30,4 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
 //  #0: uvHi (high float) 4x1 [-1]
 //  #1: uvMed (medium float) 4x1 [-1]
 // textures: 1
-//  #0: shadowmap (low 2d) 0x0 [-1] loc 0
+//  #0: shadowmap (low 2dshadow) 0x0 [-1] loc 0

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/texProj-outES.txt

@@ -38,4 +38,4 @@ void main ()
 //  #0: uv (high float) 4x1 [-1]
 // textures: 2
 //  #0: tex (low 2d) 0x0 [-1]
-//  #1: shadowmap (low 2d) 0x0 [-1]
+//  #1: shadowmap (low 2dshadow) 0x0 [-1]

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/texProj-outES3.txt

@@ -20,4 +20,4 @@ void main ()
 //  #0: uv (high float) 4x1 [-1]
 // textures: 2
 //  #0: tex (low 2d) 0x0 [-1]
-//  #1: shadowmap (low 2d) 0x0 [-1]
+//  #1: shadowmap (low 2dshadow) 0x0 [-1]

+ 1 - 1
3rdparty/glsl-optimizer/tests/fragment/texProj-outES3Metal.txt

@@ -30,4 +30,4 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
 //  #0: uv (high float) 4x1 [-1]
 // textures: 2
 //  #0: tex (low 2d) 0x0 [-1] loc 0
-//  #1: shadowmap (low 2d) 0x0 [-1] loc 1
+//  #1: shadowmap (low 2dshadow) 0x0 [-1] loc 1

+ 2 - 0
3rdparty/glsl-optimizer/tests/glsl_optimizer_tests.cpp

@@ -460,6 +460,8 @@ static const char* kGlslTypeNames[kGlslTypeCount] = {
 	"2d",
 	"3d",
 	"cube",
+	"2dshadow",
+	"2darray",
 	"other",
 };
 static const char* kGlslPrecNames[kGlslPrecCount] = {

+ 22 - 50
3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-out.txt

@@ -40,14 +40,14 @@ vec4 Temp_0;
 vec4 Temp_1;
 vec4 Temp_2;
 vec4 Temp_3;
-int tmpvar_1;
+ivec4 Temp_int_0;
 void main ()
 {
   Temp_0 = (dcl_Input0_POSITION0.yyyy * glstate_matrix_mvp[1]);
   Temp_0 = ((glstate_matrix_mvp[0] * dcl_Input0_POSITION0.xxxx) + Temp_0);
   Temp_0 = ((glstate_matrix_mvp[2] * dcl_Input0_POSITION0.zzzz) + Temp_0);
-  vec4 tmpvar_2;
-  tmpvar_2 = ((glstate_matrix_mvp[3] * dcl_Input0_POSITION0.wwww) + Temp_0);
+  vec4 tmpvar_1;
+  tmpvar_1 = ((glstate_matrix_mvp[3] * dcl_Input0_POSITION0.wwww) + Temp_0);
   VtxGeoOutput1_TEXCOORD0.xy = ((dcl_Input2_TEXCOORD0.xyxx * _MainTex_ST.xyxx) + _MainTex_ST.zwzz).xy;
   Temp_0.xyz = (dcl_Input0_POSITION0.yyyy * glstate_matrix_modelview0[1].xyzx).xyz;
   Temp_0.xyz = ((glstate_matrix_modelview0[0].xyzx * dcl_Input0_POSITION0.xxxx) + Temp_0.xyzx).xyz;
@@ -60,58 +60,30 @@ void main ()
   Temp_0.w = inversesqrt(Temp_0.w);
   Temp_1.xyz = (Temp_0.wwww * Temp_1.xyzx).xyz;
   Temp_2.xyz = glstate_lightmodel_ambient.xyz;
-  tmpvar_1 = 0;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + glstate_lightmodel_ambient.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
+  Temp_int_0.w = 0;
+  while (true) {
+    if ((Temp_int_0.w >= 4)) {
+      break;
+    };
+    Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[Temp_int_0.w].wwww) + unity_LightPosition[Temp_int_0.w].xyzx).xyz;
+    Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
+    Temp_2.w = ((Temp_1.w * unity_LightAtten[Temp_int_0.w].z) + 1.0);
+    Temp_2.w = (1.0/(Temp_2.w));
+    Temp_1.w = inversesqrt(Temp_1.w);
+    Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
+    Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
+    Temp_1.w = max (Temp_1.w, 0.0);
+    Temp_1.w = (Temp_1.w * Temp_2.w);
+    Temp_2.xyz = ((unity_LightColor[Temp_int_0.w].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
+    Temp_int_0.w = (Temp_int_0.w + 1);
+  };
   VtxGeoOutput2_COLOR0.xyz = (Temp_2.xyzx + Temp_2.xyzx).xyz;
   VtxGeoOutput2_COLOR0.w = 1.0;
-  gl_Position = tmpvar_2;
+  gl_Position = tmpvar_1;
 }
 
 
-// stats: 87 alu 0 tex 0 flow
+// stats: 43 alu 0 tex 2 flow
 // inputs: 3
 //  #0: dcl_Input0_POSITION0 (high float) 4x1 [-1]
 //  #1: dcl_Input1_NORMAL0 (high float) 4x1 [-1]

+ 22 - 50
3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3.txt

@@ -40,14 +40,14 @@ vec4 Temp_0;
 vec4 Temp_1;
 vec4 Temp_2;
 vec4 Temp_3;
-highp int tmpvar_1;
+highp ivec4 Temp_int_0;
 void main ()
 {
   Temp_0 = (dcl_Input0_POSITION0.yyyy * glstate_matrix_mvp[1]);
   Temp_0 = ((glstate_matrix_mvp[0] * dcl_Input0_POSITION0.xxxx) + Temp_0);
   Temp_0 = ((glstate_matrix_mvp[2] * dcl_Input0_POSITION0.zzzz) + Temp_0);
-  highp vec4 tmpvar_2;
-  tmpvar_2 = ((glstate_matrix_mvp[3] * dcl_Input0_POSITION0.wwww) + Temp_0);
+  highp vec4 tmpvar_1;
+  tmpvar_1 = ((glstate_matrix_mvp[3] * dcl_Input0_POSITION0.wwww) + Temp_0);
   VtxGeoOutput1_TEXCOORD0.xy = ((dcl_Input2_TEXCOORD0.xyxx * _MainTex_ST.xyxx) + _MainTex_ST.zwzz).xy;
   Temp_0.xyz = (dcl_Input0_POSITION0.yyyy * glstate_matrix_modelview0[1].xyzx).xyz;
   Temp_0.xyz = ((glstate_matrix_modelview0[0].xyzx * dcl_Input0_POSITION0.xxxx) + Temp_0.xyzx).xyz;
@@ -60,58 +60,30 @@ void main ()
   Temp_0.w = inversesqrt(Temp_0.w);
   Temp_1.xyz = (Temp_0.wwww * Temp_1.xyzx).xyz;
   Temp_2.xyz = glstate_lightmodel_ambient.xyz;
-  tmpvar_1 = 0;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + glstate_lightmodel_ambient.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
-  Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[tmpvar_1].wwww) + unity_LightPosition[tmpvar_1].xyzx).xyz;
-  Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
-  Temp_2.w = ((Temp_1.w * unity_LightAtten[tmpvar_1].z) + 1.0);
-  Temp_2.w = (1.0/(Temp_2.w));
-  Temp_1.w = inversesqrt(Temp_1.w);
-  Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
-  Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
-  Temp_1.w = max (Temp_1.w, 0.0);
-  Temp_1.w = (Temp_1.w * Temp_2.w);
-  Temp_2.xyz = ((unity_LightColor[tmpvar_1].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
-  tmpvar_1++;
+  Temp_int_0.w = 0;
+  while (true) {
+    if ((Temp_int_0.w >= 4)) {
+      break;
+    };
+    Temp_3.xyz = ((-(Temp_0.xyzx) * unity_LightPosition[Temp_int_0.w].wwww) + unity_LightPosition[Temp_int_0.w].xyzx).xyz;
+    Temp_1.w = dot (Temp_3.xyz, Temp_3.xyz);
+    Temp_2.w = ((Temp_1.w * unity_LightAtten[Temp_int_0.w].z) + 1.0);
+    Temp_2.w = (1.0/(Temp_2.w));
+    Temp_1.w = inversesqrt(Temp_1.w);
+    Temp_3.xyz = (Temp_1.wwww * Temp_3.xyzx).xyz;
+    Temp_1.w = dot (Temp_1.xyz, Temp_3.xyz);
+    Temp_1.w = max (Temp_1.w, 0.0);
+    Temp_1.w = (Temp_1.w * Temp_2.w);
+    Temp_2.xyz = ((unity_LightColor[Temp_int_0.w].xyzx * Temp_1.wwww) + Temp_2.xyzx).xyz;
+    Temp_int_0.w = (Temp_int_0.w + 1);
+  };
   VtxGeoOutput2_COLOR0.xyz = (Temp_2.xyzx + Temp_2.xyzx).xyz;
   VtxGeoOutput2_COLOR0.w = 1.0;
-  gl_Position = tmpvar_2;
+  gl_Position = tmpvar_1;
 }
 
 
-// stats: 87 alu 0 tex 0 flow
+// stats: 43 alu 0 tex 2 flow
 // inputs: 3
 //  #0: dcl_Input0_POSITION0 (high float) 4x1 [-1]
 //  #1: dcl_Input1_NORMAL0 (high float) 4x1 [-1]

+ 19 - 47
3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3Metal.txt

@@ -52,7 +52,7 @@ float4 Temp_0_2;
 float4 Temp_1_3;
 float4 Temp_2_4;
 float4 Temp_3_5;
-int tmpvar_6;
+int4 Temp_int_0_6;
   Temp_0_2 = (_mtl_i.dcl_Input0_POSITION0.yyyy * _mtl_u.glstate_matrix_mvp[1]);
   Temp_0_2 = ((_mtl_u.glstate_matrix_mvp[0] * _mtl_i.dcl_Input0_POSITION0.xxxx) + Temp_0_2);
   Temp_0_2 = ((_mtl_u.glstate_matrix_mvp[2] * _mtl_i.dcl_Input0_POSITION0.zzzz) + Temp_0_2);
@@ -69,51 +69,23 @@ int tmpvar_6;
   Temp_0_2.w = rsqrt(Temp_0_2.w);
   Temp_1_3.xyz = (Temp_0_2.wwww * Temp_1_3.xyzx).xyz;
   Temp_2_4.xyz = _mtl_u.glstate_lightmodel_ambient.xyz;
-  tmpvar_6 = 0;
-  Temp_3_5.xyz = ((-(Temp_0_2.xyzx) * _mtl_u.unity_LightPosition[tmpvar_6].wwww) + _mtl_u.unity_LightPosition[tmpvar_6].xyzx).xyz;
-  Temp_1_3.w = dot (Temp_3_5.xyz, Temp_3_5.xyz);
-  Temp_2_4.w = ((Temp_1_3.w * _mtl_u.unity_LightAtten[tmpvar_6].z) + 1.0);
-  Temp_2_4.w = (1.0/(Temp_2_4.w));
-  Temp_1_3.w = rsqrt(Temp_1_3.w);
-  Temp_3_5.xyz = (Temp_1_3.wwww * Temp_3_5.xyzx).xyz;
-  Temp_1_3.w = dot (Temp_1_3.xyz, Temp_3_5.xyz);
-  Temp_1_3.w = max (Temp_1_3.w, 0.0);
-  Temp_1_3.w = (Temp_1_3.w * Temp_2_4.w);
-  Temp_2_4.xyz = ((_mtl_u.unity_LightColor[tmpvar_6].xyzx * Temp_1_3.wwww) + _mtl_u.glstate_lightmodel_ambient.xyzx).xyz;
-  tmpvar_6++;
-  Temp_3_5.xyz = ((-(Temp_0_2.xyzx) * _mtl_u.unity_LightPosition[tmpvar_6].wwww) + _mtl_u.unity_LightPosition[tmpvar_6].xyzx).xyz;
-  Temp_1_3.w = dot (Temp_3_5.xyz, Temp_3_5.xyz);
-  Temp_2_4.w = ((Temp_1_3.w * _mtl_u.unity_LightAtten[tmpvar_6].z) + 1.0);
-  Temp_2_4.w = (1.0/(Temp_2_4.w));
-  Temp_1_3.w = rsqrt(Temp_1_3.w);
-  Temp_3_5.xyz = (Temp_1_3.wwww * Temp_3_5.xyzx).xyz;
-  Temp_1_3.w = dot (Temp_1_3.xyz, Temp_3_5.xyz);
-  Temp_1_3.w = max (Temp_1_3.w, 0.0);
-  Temp_1_3.w = (Temp_1_3.w * Temp_2_4.w);
-  Temp_2_4.xyz = ((_mtl_u.unity_LightColor[tmpvar_6].xyzx * Temp_1_3.wwww) + Temp_2_4.xyzx).xyz;
-  tmpvar_6++;
-  Temp_3_5.xyz = ((-(Temp_0_2.xyzx) * _mtl_u.unity_LightPosition[tmpvar_6].wwww) + _mtl_u.unity_LightPosition[tmpvar_6].xyzx).xyz;
-  Temp_1_3.w = dot (Temp_3_5.xyz, Temp_3_5.xyz);
-  Temp_2_4.w = ((Temp_1_3.w * _mtl_u.unity_LightAtten[tmpvar_6].z) + 1.0);
-  Temp_2_4.w = (1.0/(Temp_2_4.w));
-  Temp_1_3.w = rsqrt(Temp_1_3.w);
-  Temp_3_5.xyz = (Temp_1_3.wwww * Temp_3_5.xyzx).xyz;
-  Temp_1_3.w = dot (Temp_1_3.xyz, Temp_3_5.xyz);
-  Temp_1_3.w = max (Temp_1_3.w, 0.0);
-  Temp_1_3.w = (Temp_1_3.w * Temp_2_4.w);
-  Temp_2_4.xyz = ((_mtl_u.unity_LightColor[tmpvar_6].xyzx * Temp_1_3.wwww) + Temp_2_4.xyzx).xyz;
-  tmpvar_6++;
-  Temp_3_5.xyz = ((-(Temp_0_2.xyzx) * _mtl_u.unity_LightPosition[tmpvar_6].wwww) + _mtl_u.unity_LightPosition[tmpvar_6].xyzx).xyz;
-  Temp_1_3.w = dot (Temp_3_5.xyz, Temp_3_5.xyz);
-  Temp_2_4.w = ((Temp_1_3.w * _mtl_u.unity_LightAtten[tmpvar_6].z) + 1.0);
-  Temp_2_4.w = (1.0/(Temp_2_4.w));
-  Temp_1_3.w = rsqrt(Temp_1_3.w);
-  Temp_3_5.xyz = (Temp_1_3.wwww * Temp_3_5.xyzx).xyz;
-  Temp_1_3.w = dot (Temp_1_3.xyz, Temp_3_5.xyz);
-  Temp_1_3.w = max (Temp_1_3.w, 0.0);
-  Temp_1_3.w = (Temp_1_3.w * Temp_2_4.w);
-  Temp_2_4.xyz = ((_mtl_u.unity_LightColor[tmpvar_6].xyzx * Temp_1_3.wwww) + Temp_2_4.xyzx).xyz;
-  tmpvar_6++;
+  Temp_int_0_6.w = 0;
+  while (true) {
+    if ((Temp_int_0_6.w >= 4)) {
+      break;
+    };
+    Temp_3_5.xyz = ((-(Temp_0_2.xyzx) * _mtl_u.unity_LightPosition[Temp_int_0_6.w].wwww) + _mtl_u.unity_LightPosition[Temp_int_0_6.w].xyzx).xyz;
+    Temp_1_3.w = dot (Temp_3_5.xyz, Temp_3_5.xyz);
+    Temp_2_4.w = ((Temp_1_3.w * _mtl_u.unity_LightAtten[Temp_int_0_6.w].z) + 1.0);
+    Temp_2_4.w = (1.0/(Temp_2_4.w));
+    Temp_1_3.w = rsqrt(Temp_1_3.w);
+    Temp_3_5.xyz = (Temp_1_3.wwww * Temp_3_5.xyzx).xyz;
+    Temp_1_3.w = dot (Temp_1_3.xyz, Temp_3_5.xyz);
+    Temp_1_3.w = max (Temp_1_3.w, 0.0);
+    Temp_1_3.w = (Temp_1_3.w * Temp_2_4.w);
+    Temp_2_4.xyz = ((_mtl_u.unity_LightColor[Temp_int_0_6.w].xyzx * Temp_1_3.wwww) + Temp_2_4.xyzx).xyz;
+    Temp_int_0_6.w = (Temp_int_0_6.w + 1);
+  };
   _mtl_o.VtxGeoOutput2_COLOR0.xyz = (Temp_2_4.xyzx + Temp_2_4.xyzx).xyz;
   _mtl_o.VtxGeoOutput2_COLOR0.w = 1.0;
   _mtl_o.gl_Position = phase0_Output0_1;
@@ -121,7 +93,7 @@ int tmpvar_6;
 }
 
 
-// stats: 87 alu 0 tex 0 flow
+// stats: 43 alu 0 tex 2 flow
 // inputs: 3
 //  #0: dcl_Input0_POSITION0 (high float) 4x1 [-1] loc 0
 //  #1: dcl_Input1_NORMAL0 (high float) 4x1 [-1] loc 1