Daniele Bartolini 9 лет назад
Родитель
Сommit
756fbb40c2
100 измененных файлов с 5556 добавлено и 1970 удалено
  1. 4 4
      third/bgfx/3rdparty/dxsdk/include/d3dcompiler.h
  2. 24 0
      third/bgfx/3rdparty/glsl-optimizer/Changelog.md
  3. 11 0
      third/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp
  4. 2 2
      third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp
  5. 1 1
      third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h
  6. 2 1
      third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp
  7. 35 9
      third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp
  8. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/array-const-outES3Metal.txt
  9. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/array-constconst-outES3Metal.txt
  10. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ast-outES3Metal.txt
  11. 32 32
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-loop-undeclaredinductor-outES3Metal.txt
  12. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-sampler-highp-outES3Metal.txt
  13. 39 39
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-sampler-highpfull-outES3Metal.txt
  14. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/builtin-vars-outES3Metal.txt
  15. 41 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-inES3.txt
  16. 34 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3.txt
  17. 46 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3Metal.txt
  18. 3 3
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/framebuffer_fetch-outES3Metal.txt
  19. 685 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-inES3.txt
  20. 187 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3.txt
  21. 199 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3Metal.txt
  22. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/glsl120-basic-outES3Metal.txt
  23. 57 57
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/intrinsics-outES3Metal.txt
  24. 4 4
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/loop-for-outES3Metal.txt
  25. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/loop-forafterdiscard-outES3Metal.txt
  26. 19 19
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/matrix-cast-types-outES3Metal.txt
  27. 6 6
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/matrix-ops-outES3Metal.txt
  28. 3 3
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/mrt-unused-outES3Metal.txt
  29. 3 3
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/opt-grafting-precision-outES3Metal.txt
  30. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/prec-expressions-outES3Metal.txt
  31. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/prec-matrix-constr-outES3Metal.txt
  32. 7 7
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/sampler-precision-outES3Metal.txt
  33. 10 10
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ternary-outES3Metal.txt
  34. 32 32
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ternary-vec4-outES3Metal.txt
  35. 9 9
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3Metal.txt
  36. 4 4
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dgrad-outES3Metal.txt
  37. 3 3
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dlod-outES3Metal.txt
  38. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3Metal.txt
  39. 2 2
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texCubeShadow-outES3Metal.txt
  40. 1 1
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texOffset-outES3Metal.txt
  41. 4 4
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texProj-outES3Metal.txt
  42. 44 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-inES3.txt
  43. 32 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-outES3.txt
  44. 42 0
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-outES3Metal.txt
  45. 13 13
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-DirLMBasis-outES3Metal.txt
  46. 34 34
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-LightShaftsCoord-outES3Metal.txt
  47. 15 15
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-alphabumpspec-outES3Metal.txt
  48. 20 20
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-collectshadows-outES3Metal.txt
  49. 97 97
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-fxaa-preset3-outES3Metal.txt
  50. 56 56
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-prepasslight-outES3Metal.txt
  51. 9 9
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-tonemap-usercurve-outES3Metal.txt
  52. 18 18
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-treeleafloop-outES3Metal.txt
  53. 71 71
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-unishader-dirlm-outES3Metal.txt
  54. 21 21
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-unity-spot-outES3Metal.txt
  55. 11 11
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/zun-MobileBumpSpec-outES3Metal.txt
  56. 24 24
      third/bgfx/3rdparty/glsl-optimizer/tests/fragment/zun-SSAO24-outES3Metal.txt
  57. 32 32
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/MF-GodRays-outES3Metal.txt
  58. 15 15
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/bug-swizzle-lhs-cast-outES3Metal.txt
  59. 2 2
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/builtin-vars-outES3Metal.txt
  60. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/inputs-outES3Metal.txt
  61. 6 6
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3Metal.txt
  62. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4inductorW-outES3Metal.txt
  63. 15 15
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-forlimitbreak-outES3Metal.txt
  64. 19 19
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-forvarious-outES3Metal.txt
  65. 3 3
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/matrix-casts-outES3Metal.txt
  66. 15 15
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/opt-matrix-transpose-mul-outES3Metal.txt
  67. 2 2
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/swizzle-casts-outES3Metal.txt
  68. 2 2
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/types-outES3Metal.txt
  69. 22 22
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/uniforms-arrays-outES3Metal.txt
  70. 67 67
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-NichsHybridLightVectorInsertBug-outES3Metal.txt
  71. 5 5
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-prepasslight-outES3Metal.txt
  72. 30 30
      third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-treeleaf-outES3Metal.txt
  73. 232 174
      third/bgfx/3rdparty/ocornut-imgui/imgui.cpp
  74. 59 62
      third/bgfx/3rdparty/ocornut-imgui/imgui.h
  75. 103 21
      third/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp
  76. 48 33
      third/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp
  77. 37 22
      third/bgfx/3rdparty/ocornut-imgui/imgui_internal.h
  78. 1 0
      third/bgfx/3rdparty/ocornut-imgui/imgui_user.h
  79. 1 0
      third/bgfx/3rdparty/ocornut-imgui/imgui_user.inl
  80. 10 3
      third/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp
  81. 5 0
      third/bgfx/3rdparty/ocornut-imgui/widgets/file_list.inl
  82. 156 0
      third/bgfx/3rdparty/ocornut-imgui/widgets/gizmo.h
  83. 1489 0
      third/bgfx/3rdparty/ocornut-imgui/widgets/gizmo.inl
  84. 266 88
      third/bgfx/3rdparty/remotery/lib/Remotery.c
  85. 23 18
      third/bgfx/3rdparty/remotery/lib/Remotery.h
  86. 2 2
      third/bgfx/3rdparty/remotery/readme.md
  87. 15 3
      third/bgfx/3rdparty/remotery/sample/sample.c
  88. 82 7
      third/bgfx/3rdparty/remotery/vis/Code/Console.js
  89. 3 0
      third/bgfx/3rdparty/remotery/vis/Code/Remotery.js
  90. 1 0
      third/bgfx/3rdparty/remotery/vis/Styles/Remotery.css
  91. 13 11
      third/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js
  92. 1 0
      third/bgfx/3rdparty/remotery/vis/index.html
  93. 369 290
      third/bgfx/3rdparty/renderdoc/renderdoc_app.h
  94. 44 40
      third/bgfx/3rdparty/stb/stb_textedit.h
  95. 19 2
      third/bgfx/README.md
  96. 182 39
      third/bgfx/include/bgfx/bgfx.h
  97. 26 22
      third/bgfx/include/bgfx/bgfxdefines.h
  98. 2 193
      third/bgfx/include/bgfx/bgfxplatform.h
  99. 69 17
      third/bgfx/include/bgfx/c99/bgfx.h
  100. 11 8
      third/bgfx/include/bgfx/c99/bgfxplatform.h

+ 4 - 4
third/bgfx/3rdparty/dxsdk/include/d3dcompiler.h

@@ -303,9 +303,9 @@ D3DReflect(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
 
 HRESULT WINAPI
 D3DReflectLibrary(__in_bcount(SrcDataSize) LPCVOID pSrcData,
-                  __in SIZE_T SrcDataSize,
-	              __in REFIID riid,
-                  __out LPVOID * ppReflector);
+                  SIZE_T SrcDataSize,
+	              REFIID riid,
+                  LPVOID * ppReflector);
 
 //----------------------------------------------------------------------------
 // D3DDisassemble:
@@ -350,7 +350,7 @@ D3DDisassembleRegion(_In_reads_bytes_(SrcDataSize) LPCVOID pSrcData,
 // Shader linking and Function Linking Graph (FLG) APIs
 //----------------------------------------------------------------------------
 HRESULT WINAPI
-D3DCreateLinker(__out interface ID3D11Linker ** ppLinker);
+D3DCreateLinker(interface ID3D11Linker ** ppLinker);
 
 HRESULT WINAPI
 D3DLoadModule(_In_ LPCVOID pSrcData,

+ 24 - 0
third/bgfx/3rdparty/glsl-optimizer/Changelog.md

@@ -1,6 +1,30 @@
 GLSL optimizer Change Log
 =========================
 
+2016 09
+-------
+
+* Metal: Fixed constant precision propagation in some cases.
+* Metal: Fixed shadowmap sampling when reference Z value is outside of 0..1 range (now clamps to match GLES specs).
+
+
+2016 06
+-------
+
+Fixed:
+
+* Fixed Metal translation in some cases having wrong precision on constants or constant arrays.
+
+
+2016 05
+-------
+
+Fixed:
+
+* Fixed Metal translation in some cases having wrong precision on struct members.
+* Fixed Metal translation in some cases emitting struct declarations vs. constant initializers in wrong order.
+
+
 2016 03
 -------
 

+ 11 - 0
third/bgfx/3rdparty/glsl-optimizer/src/glsl/ast_to_hir.cpp

@@ -3042,6 +3042,17 @@ process_initializer(ir_variable *var, ast_declaration *decl,
    ir_dereference *const lhs = new(state) ir_dereference_variable(var);
    ir_rvalue *rhs = decl->initializer->hir(initializer_instructions, state);
 
+   /* Propagate precision qualifier for constant value */
+   if (type->qualifier.flags.q.constant) {
+      ir_constant *constant_value = rhs->constant_expression_value();
+      constant_value->set_precision((glsl_precision)type->qualifier.precision);
+      if (constant_value->type->is_array()) {
+         for (unsigned i = 0; i < constant_value->type->length; i++) {
+            constant_value->get_array_element(i)->set_precision((glsl_precision)type->qualifier.precision);
+         }
+      }
+   }
+	
    /* Calculate the constant value if this is a const or uniform
     * declaration.
     */

+ 2 - 2
third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.cpp

@@ -647,8 +647,8 @@ ir_constant::ir_constant()
 }
 
 ir_constant::ir_constant(const struct glsl_type *type,
-			 const ir_constant_data *data)
-   : ir_rvalue(ir_type_constant, glsl_precision_undefined)
+			 const ir_constant_data *data, glsl_precision precision)
+   : ir_rvalue(ir_type_constant, precision)
 {
    assert((type->base_type >= GLSL_TYPE_UINT)
 	  && (type->base_type <= GLSL_TYPE_BOOL));

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir.h

@@ -2161,7 +2161,7 @@ union ir_constant_data {
 
 class ir_constant : public ir_rvalue {
 public:
-   ir_constant(const struct glsl_type *type, const ir_constant_data *data);
+   ir_constant(const struct glsl_type *type, const ir_constant_data *data, glsl_precision precision = glsl_precision_undefined);
    ir_constant(bool b, unsigned vector_elements=1);
    ir_constant(unsigned int u, unsigned vector_elements=1);
    ir_constant(int i, unsigned vector_elements=1);

+ 2 - 1
third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_clone.cpp

@@ -330,7 +330,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
    case GLSL_TYPE_INT:
    case GLSL_TYPE_FLOAT:
    case GLSL_TYPE_BOOL:
-      return new(mem_ctx) ir_constant(this->type, &this->value);
+      return new(mem_ctx) ir_constant(this->type, &this->value, this->precision);
 
    case GLSL_TYPE_STRUCT: {
       ir_constant *c = new(mem_ctx) ir_constant;
@@ -351,6 +351,7 @@ ir_constant::clone(void *mem_ctx, struct hash_table *ht) const
       ir_constant *c = new(mem_ctx) ir_constant;
 
       c->type = this->type;
+      c->set_precision(this->get_precision());
       c->array_elements = ralloc_array(c, ir_constant *, this->type->length);
       for (unsigned i = 0; i < this->type->length; i++) {
 	 c->array_elements[i] = this->array_elements[i]->clone(mem_ctx, NULL);

+ 35 - 9
third/bgfx/3rdparty/glsl-optimizer/src/glsl/ir_print_metal_visitor.cpp

@@ -99,6 +99,7 @@ struct metal_print_context
 	, inoutStr(ralloc_strdup(buffer, ""))
 	, uniformStr(ralloc_strdup(buffer, ""))
 	, paramsStr(ralloc_strdup(buffer, ""))
+	, typedeclStr(ralloc_strdup(buffer, ""))
 	, writingParams(false)
 	, matrixCastsDone(false)
 	, matrixConstructorsDone(false)
@@ -117,6 +118,7 @@ struct metal_print_context
 	string_buffer inoutStr;
 	string_buffer uniformStr;
 	string_buffer paramsStr;
+	string_buffer typedeclStr;
 	bool writingParams;
 	bool matrixCastsDone;
 	bool matrixConstructorsDone;
@@ -267,7 +269,10 @@ _mesa_print_ir_metal(exec_list *instructions,
 			if (var->data.mode == ir_var_shader_inout)
 				strOut = &ctx.inoutStr;
 		}
-
+		
+		if (ir->ir_type == ir_type_typedecl) {
+			strOut = &ctx.typedeclStr;
+		}
 
 		ir_print_metal_visitor v (ctx, *strOut, &gtracker, mode, state);
 		v.loopstate = ls;
@@ -293,6 +298,8 @@ _mesa_print_ir_metal(exec_list *instructions,
 	ctx.uniformStr.asprintf_append("};\n");
 
 	// emit global array/struct constants
+	
+	ctx.prefixStr.asprintf_append("%s", ctx.typedeclStr.c_str());
 	foreach_in_list_safe(gconst_entry_metal, node, &gtracker.global_constants)
 	{
 		ir_constant* c = node->ir;
@@ -670,6 +677,20 @@ void ir_print_metal_visitor::visit(ir_variable *ir)
 		buffer.asprintf_append (" = ");
 		visit (ir->constant_value);
 	}
+
+	if ((ir->data.mode == ir_var_auto || ir->data.mode == ir_var_temporary) && (ir->type->matrix_columns == 1)) {
+		switch (ir->type->base_type) {
+			case GLSL_TYPE_INT:
+			case GLSL_TYPE_FLOAT:
+				buffer.asprintf_append (" = 0");
+				break;
+			case GLSL_TYPE_BOOL:
+				buffer.asprintf_append (" = false");
+				break;
+			default:
+				break;
+		}
+	}
 }
 
 
@@ -1103,9 +1124,10 @@ void ir_print_metal_visitor::visit(ir_expression *ir)
 			else if (op0cast)
 			{
 				print_cast (buffer, arg_prec, ir->operands[0]);
+				buffer.asprintf_append ("(");
 			}
 			ir->operands[0]->accept(this);
-			if (op0castTo1)
+			if (op0castTo1 || op0cast)
 			{
 				buffer.asprintf_append (")");
 			}
@@ -1124,9 +1146,10 @@ void ir_print_metal_visitor::visit(ir_expression *ir)
 			else if (op1cast)
 			{
 				print_cast (buffer, arg_prec, ir->operands[1]);
+				buffer.asprintf_append ("(");
 			}
 			ir->operands[1]->accept(this);
-			if (op1castTo0)
+			if (op1castTo0 || op1cast)
 			{
 				buffer.asprintf_append (")");
 			}
@@ -1207,14 +1230,17 @@ static void print_texture_uv (ir_print_metal_visitor* vis, ir_texture* ir, bool
 	}
 	else if (is_shadow)
 	{
+		// Note that on metal sample_compare works differently than shadow2DEXT on GLES:
+		// it does not clamp neither the pixel value nor compare value to the [0.0, 1.0] range. To
+		// preserve same behavior we're clamping the argument explicitly.
 		if (!is_proj)
 		{
 			// regular shadow
 			vis->buffer.asprintf_append (uv_dim == 4 ? "(float3)(" : "(float2)(");
 			ir->coordinate->accept(vis);
-			vis->buffer.asprintf_append (uv_dim == 4 ? ").xyz, (" : ").xy, (float)(");
+			vis->buffer.asprintf_append (uv_dim == 4 ? ").xyz, (" : ").xy, saturate((float)(");
 			ir->coordinate->accept(vis);
-			vis->buffer.asprintf_append (uv_dim == 4 ? ").w" : ").z");
+			vis->buffer.asprintf_append (uv_dim == 4 ? ").w" : ").z)");
 		}
 		else
 		{
@@ -1223,11 +1249,11 @@ static void print_texture_uv (ir_print_metal_visitor* vis, ir_texture* ir, bool
 			ir->coordinate->accept(vis);
 			vis->buffer.asprintf_append (").xy / (float)(");
 			ir->coordinate->accept(vis);
-			vis->buffer.asprintf_append (").w, (float)(");
+			vis->buffer.asprintf_append (").w, saturate((float)(");
 			ir->coordinate->accept(vis);
 			vis->buffer.asprintf_append (").z / (float)(");
 			ir->coordinate->accept(vis);
-			vis->buffer.asprintf_append (").w");
+			vis->buffer.asprintf_append (").w)");
 		}
 	}
 }
@@ -1251,7 +1277,7 @@ void ir_print_metal_visitor::visit(ir_texture *ir)
 		// For shadow sampling, Metal right now needs a hardcoded sampler state :|
 		if (!ctx.shadowSamplerDone)
 		{
-			ctx.prefixStr.asprintf_append("constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less);\n");
+			ctx.prefixStr.asprintf_append("constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less_equal);\n");
 			ctx.shadowSamplerDone = true;
 		}
 		buffer.asprintf_append (".sample_compare(_mtl_xl_shadow_sampler");
@@ -1968,7 +1994,7 @@ ir_print_metal_visitor::visit(ir_typedecl_statement *ir)
 		buffer.asprintf_append ("  ");
 		//if (state->es_shader)
 		//	buffer.asprintf_append ("%s", get_precision_string(s->fields.structure[j].precision)); //@TODO
-		print_type(buffer, ir, s->fields.structure[j].type, false);
+		print_type_precision(buffer, s->fields.structure[j].type, s->fields.structure[j].precision, false);
 		buffer.asprintf_append (" %s", s->fields.structure[j].name);
 		print_type_post(buffer, s->fields.structure[j].type, false);
 		buffer.asprintf_append (";\n");

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/array-const-outES3Metal.txt

@@ -11,7 +11,7 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1.zw = half2(float2(0.0, 0.0));
   c_1.xy = half2(float2(-0.3441301, 0.05004501));
   _mtl_o._fragData = c_1;

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/array-constconst-outES3Metal.txt

@@ -11,7 +11,7 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1.zw = half2(float2(0.0, 0.0));
   c_1.xy = half2(float2(-0.3441301, 0.05004501));
   _mtl_o._fragData = c_1;

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ast-outES3Metal.txt

@@ -12,7 +12,7 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float a_2;
+  float a_2 = 0;
   if ((_mtl_i.gl_FragCoord.x == 1.0)) {
     discard_fragment();
   };

+ 32 - 32
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-loop-undeclaredinductor-outES3Metal.txt

@@ -18,57 +18,57 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(0)]], sampler _mtlsmp__MainTex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 t_1;
-  half4 tmpvar_2;
+  half4 t_1 = 0;
+  half4 tmpvar_2 = 0;
   tmpvar_2 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
   t_1 = tmpvar_2;
-  if ((_mtl_u._NumPasses > (half)0.0)) {
-    half passes_3;
+  if ((_mtl_u._NumPasses > (half)(0.0))) {
+    half passes_3 = 0;
     passes_3 = _mtl_u._NumPasses;
-    float i_4;
-    half3 res_5;
+    float i_4 = 0;
+    half3 res_5 = 0;
     res_5 = tmpvar_2.xyz;
     i_4 = 0.0;
     while (true) {
       if ((i_4 >= 4.0)) {
         break;
       };
-      if ((i_4 == (float)passes_3)) {
+      if ((i_4 == (float)(passes_3))) {
         break;
       };
       if ((i_4 == 0.0)) {
-        half3 tmpvar_6;
-        half val_7;
-        val_7 = ((_mtl_u._ContrastShift.x * (half)3.0) + (half)12.0);
-        half tmpvar_8;
-        tmpvar_8 = pow ((cos(val_7) + (half)1.0), val_7);
-        tmpvar_6 = ((res_5 - (half)0.5) * tmpvar_8);
+        half3 tmpvar_6 = 0;
+        half val_7 = 0;
+        val_7 = ((_mtl_u._ContrastShift.x * (half)(3.0)) + (half)(12.0));
+        half tmpvar_8 = 0;
+        tmpvar_8 = pow ((cos(val_7) + (half)(1.0)), val_7);
+        tmpvar_6 = ((res_5 - (half)(0.5)) * tmpvar_8);
         res_5 = tmpvar_6;
       } else {
         if ((i_4 == 1.0)) {
-          half3 tmpvar_9;
-          half val_10;
-          val_10 = ((_mtl_u._SaturationShift.y * (half)3.0) + (half)12.0);
-          half tmpvar_11;
-          tmpvar_11 = pow ((cos(val_10) + (half)1.0), val_10);
-          tmpvar_9 = ((res_5 - (half)0.5) * tmpvar_11);
+          half3 tmpvar_9 = 0;
+          half val_10 = 0;
+          val_10 = ((_mtl_u._SaturationShift.y * (half)(3.0)) + (half)(12.0));
+          half tmpvar_11 = 0;
+          tmpvar_11 = pow ((cos(val_10) + (half)(1.0)), val_10);
+          tmpvar_9 = ((res_5 - (half)(0.5)) * tmpvar_11);
           res_5 = tmpvar_9;
         } else {
           if ((i_4 == 2.0)) {
-            half3 tmpvar_12;
-            half val_13;
-            val_13 = ((_mtl_u._HueShift.z * (half)3.0) + (half)12.0);
-            half tmpvar_14;
-            tmpvar_14 = pow ((cos(val_13) + (half)1.0), val_13);
-            tmpvar_12 = ((res_5 - (half)0.5) * tmpvar_14);
+            half3 tmpvar_12 = 0;
+            half val_13 = 0;
+            val_13 = ((_mtl_u._HueShift.z * (half)(3.0)) + (half)(12.0));
+            half tmpvar_14 = 0;
+            tmpvar_14 = pow ((cos(val_13) + (half)(1.0)), val_13);
+            tmpvar_12 = ((res_5 - (half)(0.5)) * tmpvar_14);
             res_5 = tmpvar_12;
           } else {
-            half3 tmpvar_15;
-            half val_16;
-            val_16 = ((_mtl_u._LuminosityShift.x * (half)3.0) + (half)12.0);
-            half tmpvar_17;
-            tmpvar_17 = pow ((cos(val_16) + (half)1.0), val_16);
-            tmpvar_15 = ((res_5 - (half)0.5) * tmpvar_17);
+            half3 tmpvar_15 = 0;
+            half val_16 = 0;
+            val_16 = ((_mtl_u._LuminosityShift.x * (half)(3.0)) + (half)(12.0));
+            half tmpvar_17 = 0;
+            tmpvar_17 = pow ((cos(val_16) + (half)(1.0)), val_16);
+            tmpvar_15 = ((res_5 - (half)(0.5)) * tmpvar_17);
             res_5 = tmpvar_15;
           };
         };
@@ -77,7 +77,7 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     };
     t_1.xyz = res_5;
   };
-  half4 tmpvar_18;
+  half4 tmpvar_18 = 0;
   tmpvar_18.w = half(1.0);
   tmpvar_18.xyz = t_1.xyz;
   _mtl_o._fragData = tmpvar_18;

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-sampler-highp-outES3Metal.txt

@@ -13,7 +13,7 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<float> _CameraDepthTexture [[texture(0)]], sampler _mtlsmp__CameraDepthTexture [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float4 tmpvar_1;
+  float4 tmpvar_1 = 0;
   tmpvar_1 = _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(_mtl_i.varUV), level(0.0)).xxxx;
   _mtl_o._fragData = half4(tmpvar_1);
   return _mtl_o;

+ 39 - 39
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/bug-sampler-highpfull-outES3Metal.txt

@@ -23,48 +23,48 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _NoiseTex [[texture(4)]], sampler _mtlsmp__NoiseTex [[sampler(4)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float2 tmpvar_1;
+  float2 tmpvar_1 = 0;
   tmpvar_1 = _mtl_i.xlv_TEXCOORD0;
-  float4 jitteredDir_3;
-  float4 sum_4;
-  float weight_5;
-  float zx_6;
-  float2 vx_7;
-  float2 x_8;
-  float2 xf_9;
+  float4 jitteredDir_3 = 0;
+  float4 sum_4 = 0;
+  float weight_5 = 0;
+  float zx_6 = 0;
+  float2 vx_7 = 0;
+  float2 x_8 = 0;
+  float2 xf_9 = 0;
   xf_9 = _mtl_i.xlv_TEXCOORD0;
   x_8 = _mtl_i.xlv_TEXCOORD0;
   if ((_mtl_u._MainTex_TexelSize.y < 0.0)) {
     xf_9.y = (1.0 - _mtl_i.xlv_TEXCOORD0.y);
   };
-  half4 tmpvar_10;
+  half4 tmpvar_10 = 0;
   tmpvar_10 = _NeighbourMaxTex.sample(_mtlsmp__NeighbourMaxTex, (float2)(xf_9), level(0.0));
-  float2 tmpvar_11;
+  float2 tmpvar_11 = 0;
   tmpvar_11 = float2(tmpvar_10.xy);
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0), level(0.0));
-  float4 tmpvar_13;
+  float4 tmpvar_13 = 0;
   tmpvar_13 = float4(tmpvar_12);
-  half4 tmpvar_14;
+  half4 tmpvar_14 = 0;
   tmpvar_14 = _VelTex.sample(_mtlsmp__VelTex, (float2)(xf_9), level(0.0));
-  float2 tmpvar_15;
+  float2 tmpvar_15 = 0;
   tmpvar_15 = float2(tmpvar_14.xy);
   vx_7 = tmpvar_15;
-  float4 tmpvar_16;
+  float4 tmpvar_16 = 0;
   tmpvar_16.zw = float2(0.0, 0.0);
   tmpvar_16.xy = _mtl_i.xlv_TEXCOORD0;
-  float4 coord_17;
+  float4 coord_17 = 0;
   coord_17 = (tmpvar_16 * 11.0);
-  half4 tmpvar_18;
+  half4 tmpvar_18 = 0;
   tmpvar_18 = _NoiseTex.sample(_mtlsmp__NoiseTex, (float2)(coord_17.xy), level(coord_17.w));
-  float4 tmpvar_19;
-  tmpvar_19 = float4(((tmpvar_18 * (half)2.0) - (half)1.0));
+  float4 tmpvar_19 = 0;
+  tmpvar_19 = float4(((tmpvar_18 * (half)(2.0)) - (half)(1.0)));
   zx_6 = -((1.0/((
     (_mtl_u._ZBufferParams.x * _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(_mtl_i.xlv_TEXCOORD0), level(0.0)).x)
    + _mtl_u._ZBufferParams.y))));
   weight_5 = 1.0;
   sum_4 = tmpvar_13;
-  float4 tmpvar_20;
+  float4 tmpvar_20 = 0;
   tmpvar_20 = (tmpvar_11.xyxy + (tmpvar_19 * (_mtl_u._MainTex_TexelSize.xyxy * _mtl_u._Jitter)).xyyz);
   jitteredDir_3 = ((max (
     abs(tmpvar_20.xyxy)
@@ -72,50 +72,50 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     ((_mtl_u._MainTex_TexelSize.xyxy * _mtl_u._MaxVelocity) * 0.15)
   ) * sign(tmpvar_20.xyxy)) * float4(1.0, 1.0, -1.0, -1.0));
   for (int l_2 = 0; l_2 < 12; l_2++) {
-    float zy_21;
-    float4 yf_22;
-    float4 tmpvar_23;
+    float zy_21 = 0;
+    float4 yf_22 = 0;
+    float4 tmpvar_23 = 0;
     tmpvar_23 = (tmpvar_1.xyxy + ((jitteredDir_3.xyxy * _xlat_mtl_const1[l_2].xyxy) * float4(1.0, 1.0, -1.0, -1.0)));
     yf_22 = tmpvar_23;
     if ((_mtl_u._MainTex_TexelSize.y < 0.0)) {
       yf_22.yw = (1.0 - tmpvar_23.yw);
     };
-    half4 tmpvar_24;
+    half4 tmpvar_24 = 0;
     tmpvar_24 = _VelTex.sample(_mtlsmp__VelTex, (float2)(yf_22.xy), level(0.0));
-    float2 tmpvar_25;
+    float2 tmpvar_25 = 0;
     tmpvar_25 = float2(tmpvar_24.xy);
     zy_21 = -((1.0/((
       (_mtl_u._ZBufferParams.x * _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(tmpvar_23.xy), level(0.0)).x)
      + _mtl_u._ZBufferParams.y))));
-    float2 x_26;
+    float2 x_26 = 0;
     x_26 = (x_8 - tmpvar_23.xy);
-    float2 x_27;
+    float2 x_27 = 0;
     x_27 = (tmpvar_23.xy - x_8);
-    float tmpvar_28;
+    float tmpvar_28 = 0;
     tmpvar_28 = sqrt(dot (tmpvar_25, tmpvar_25));
-    float2 x_29;
+    float2 x_29 = 0;
     x_29 = (tmpvar_23.xy - x_8);
-    float edge0_30;
+    float edge0_30 = 0;
     edge0_30 = (0.95 * tmpvar_28);
-    float tmpvar_31;
+    float tmpvar_31 = 0;
     tmpvar_31 = clamp (((
       sqrt(dot (x_29, x_29))
      - edge0_30) / (
       (1.05 * tmpvar_28)
      - edge0_30)), 0.0, 1.0);
-    float tmpvar_32;
+    float tmpvar_32 = 0;
     tmpvar_32 = sqrt(dot (vx_7, vx_7));
-    float2 x_33;
+    float2 x_33 = 0;
     x_33 = (x_8 - tmpvar_23.xy);
-    float edge0_34;
+    float edge0_34 = 0;
     edge0_34 = (0.95 * tmpvar_32);
-    float tmpvar_35;
+    float tmpvar_35 = 0;
     tmpvar_35 = clamp (((
       sqrt(dot (x_33, x_33))
      - edge0_34) / (
       (1.05 * tmpvar_32)
      - edge0_34)), 0.0, 1.0);
-    float tmpvar_36;
+    float tmpvar_36 = 0;
     tmpvar_36 = (((
       clamp ((1.0 - ((zy_21 - zx_6) / _mtl_u._SoftZDistance)), 0.0, 1.0)
      * 
@@ -141,14 +141,14 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
         (2.0 * tmpvar_35)
       ))))
     ) * 2.0));
-    half4 tmpvar_37;
+    half4 tmpvar_37 = 0;
     tmpvar_37 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_23.xy), level(0.0));
-    float4 tmpvar_38;
+    float4 tmpvar_38 = 0;
     tmpvar_38 = float4(tmpvar_37);
     sum_4 = (sum_4 + (tmpvar_38 * tmpvar_36));
     weight_5 = (weight_5 + tmpvar_36);
   };
-  float4 tmpvar_39;
+  float4 tmpvar_39 = 0;
   tmpvar_39 = (sum_4 / weight_5);
   _mtl_o._fragData = half4(tmpvar_39);
   return _mtl_o;

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/builtin-vars-outES3Metal.txt

@@ -15,16 +15,16 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  c_1 = half4(((float4)_mtl_i.uv + _mtl_i.gl_FragCoord));
-  float tmpvar_2;
+  half4 c_1 = 0;
+  c_1 = half4(((float4)(_mtl_i.uv) + _mtl_i.gl_FragCoord));
+  float tmpvar_2 = 0;
   if (_mtl_i.gl_FrontFacing) {
     tmpvar_2 = 1.0;
   } else {
     tmpvar_2 = 0.0;
   };
-  c_1.x = (c_1.x + (half)tmpvar_2);
-  c_1.xy = half2(((float2)c_1.xy + _mtl_i.gl_PointCoord));
+  c_1.x = (c_1.x + (half)(tmpvar_2));
+  c_1.xy = half2(((float2)(c_1.xy) + _mtl_i.gl_PointCoord));
   _mtl_o._fragData = c_1;
   return _mtl_o;
 }

+ 41 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-inES3.txt

@@ -0,0 +1,41 @@
+#version 300 es
+#define gl_FragData _glesFragData
+layout(location = 0) out mediump vec4 _glesFragData[1];
+
+struct v2f {
+    highp vec4 pos;
+    mediump vec2 uv;
+};
+
+struct u2v {
+    highp vec4 vertex;
+    mediump vec2 texcoord;
+};
+
+const mediump vec3[3] ha = vec3[3]( vec3( 1.0, 2.0, 3.0), vec3( 4.0, 5.0, 6.0), vec3( 7.0, 8.0, 9.0));
+const highp vec3[3] fa = vec3[3]( vec3( 11.0, 12.0, 13.0), vec3( 14.0, 15.0, 16.0), vec3( 17.0, 18.0, 19.0));
+
+mediump vec4 frag( in v2f i ) {
+    mediump vec3 h = vec3( 0.0);
+    highp vec3 f = vec3( 0.0);
+    highp vec3 p = vec3( i.uv.xy, 1.0);
+    highp int j = 0;
+    for ( ; (j < int((i.uv.x * 3.0))); (j++)) {
+        h += ha[j];
+        f += fa[j];
+        f += (p * ha[0]);
+		f += (ha[1] * p);
+    }
+    return vec4( h.xy, f.xy);
+}
+
+in mediump vec2 xlv_TEXCOORD0;
+void main() {
+    mediump vec4 xl_retval;
+    v2f xlt_i;
+    xlt_i.pos = vec4(0.0);
+    xlt_i.uv = vec2(xlv_TEXCOORD0);
+    xl_retval = frag( xlt_i);
+    gl_FragData[0] = vec4(xl_retval);
+}
+

+ 34 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3.txt

@@ -0,0 +1,34 @@
+#version 300 es
+layout(location=0) out mediump vec4 _glesFragData[1];
+in mediump vec2 xlv_TEXCOORD0;
+void main ()
+{
+  mediump vec4 tmpvar_1;
+  mediump vec2 tmpvar_2;
+  tmpvar_2 = xlv_TEXCOORD0;
+  highp vec3 p_4;
+  highp vec3 f_5;
+  mediump vec3 h_6;
+  h_6 = vec3(0.0, 0.0, 0.0);
+  f_5 = vec3(0.0, 0.0, 0.0);
+  mediump vec3 tmpvar_7;
+  tmpvar_7.z = 1.0;
+  tmpvar_7.xy = xlv_TEXCOORD0;
+  p_4 = tmpvar_7;
+  for (highp int j_3 = 0; j_3 < int((tmpvar_2.x * 3.0)); j_3++) {
+    h_6 = (h_6 + vec3[3](vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0), vec3(7.0, 8.0, 9.0))[j_3]);
+    f_5 = (f_5 + vec3[3](vec3(11.0, 12.0, 13.0), vec3(14.0, 15.0, 16.0), vec3(17.0, 18.0, 19.0))[j_3]);
+    f_5 = (f_5 + (p_4 * vec3(1.0, 2.0, 3.0)));
+    f_5 = (f_5 + (vec3(4.0, 5.0, 6.0) * p_4));
+  };
+  highp vec4 tmpvar_8;
+  tmpvar_8.xy = h_6.xy;
+  tmpvar_8.zw = f_5.xy;
+  tmpvar_1 = tmpvar_8;
+  _glesFragData[0] = tmpvar_1;
+}
+
+
+// stats: 14 alu 0 tex 2 flow
+// inputs: 1
+//  #0: xlv_TEXCOORD0 (medium float) 2x1 [-1]

+ 46 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/const-precision-outES3Metal.txt

@@ -0,0 +1,46 @@
+#include <metal_stdlib>
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+using namespace metal;
+constant half3 _xlat_mtl_const1[3] = {half3(1.0, 2.0, 3.0), half3(4.0, 5.0, 6.0), half3(7.0, 8.0, 9.0)};
+constant float3 _xlat_mtl_const2[3] = {float3(11.0, 12.0, 13.0), float3(14.0, 15.0, 16.0), float3(17.0, 18.0, 19.0)};
+struct xlatMtlShaderInput {
+  half2 xlv_TEXCOORD0;
+};
+struct xlatMtlShaderOutput {
+  half4 _glesFragData_0 [[color(0)]];
+};
+struct xlatMtlShaderUniform {
+};
+fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
+{
+  xlatMtlShaderOutput _mtl_o;
+  half4 tmpvar_1 = 0;
+  half2 tmpvar_2 = 0;
+  tmpvar_2 = _mtl_i.xlv_TEXCOORD0;
+  float3 p_4 = 0;
+  float3 f_5 = 0;
+  half3 h_6 = 0;
+  h_6 = half3(float3(0.0, 0.0, 0.0));
+  f_5 = float3(0.0, 0.0, 0.0);
+  half3 tmpvar_7 = 0;
+  tmpvar_7.z = half(1.0);
+  tmpvar_7.xy = _mtl_i.xlv_TEXCOORD0;
+  p_4 = float3(tmpvar_7);
+  for (int j_3 = 0; j_3 < short((tmpvar_2.x * (half)(3.0))); j_3++) {
+    h_6 = (h_6 + _xlat_mtl_const1[j_3]);
+    f_5 = (f_5 + _xlat_mtl_const2[j_3]);
+    f_5 = (f_5 + (p_4 * (float3)(half3(1.0, 2.0, 3.0))));
+    f_5 = (f_5 + ((float3)(half3(4.0, 5.0, 6.0)) * p_4));
+  };
+  float4 tmpvar_8 = 0;
+  tmpvar_8.xy = float2(h_6.xy);
+  tmpvar_8.zw = f_5.xy;
+  tmpvar_1 = half4(tmpvar_8);
+  _mtl_o._glesFragData_0 = tmpvar_1;
+  return _mtl_o;
+}
+
+
+// stats: 14 alu 0 tex 2 flow
+// inputs: 1
+//  #0: xlv_TEXCOORD0 (medium float) 2x1 [-1]

+ 3 - 3
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/framebuffer_fetch-outES3Metal.txt

@@ -13,12 +13,12 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 xlt_ocol_1;
+  half4 xlt_ocol_1 = 0;
   xlt_ocol_1 = _mtl_i._glesFragData_0;
-  half4 ocol_2;
+  half4 ocol_2 = 0;
   ocol_2.w = xlt_ocol_1.w;
   ocol_2.xy = _mtl_i.xlv_TEXCOORD0.xy;
-  ocol_2.z = (xlt_ocol_1.z * (half)2.0);
+  ocol_2.z = (xlt_ocol_1.z * (half)(2.0));
   xlt_ocol_1 = ocol_2;
   _mtl_o._glesFragData_0 = ocol_2;
   return _mtl_o;

+ 685 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-inES3.txt

@@ -0,0 +1,685 @@
+#version 300 es
+vec4 xll_texCUBElod(samplerCube s, vec4 coord) {
+  return textureLod( s, coord.xyz, coord.w);
+}
+float xll_shadow2D(mediump sampler2DShadow s, vec3 coord) { return texture (s, coord); }
+float xll_saturate_f( float x) {
+  return clamp( x, 0.0, 1.0);
+}
+vec2 xll_saturate_vf2( vec2 x) {
+  return clamp( x, 0.0, 1.0);
+}
+vec3 xll_saturate_vf3( vec3 x) {
+  return clamp( x, 0.0, 1.0); 
+}
+vec4 xll_saturate_vf4( vec4 x) {
+  return clamp( x, 0.0, 1.0);
+}
+mat2 xll_saturate_mf2x2(mat2 m) {
+  return mat2( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0));
+}
+mat3 xll_saturate_mf3x3(mat3 m) {
+  return mat3( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0), clamp(m[2], 0.0, 1.0));
+}
+mat4 xll_saturate_mf4x4(mat4 m) {
+  return mat4( clamp(m[0], 0.0, 1.0), clamp(m[1], 0.0, 1.0), clamp(m[2], 0.0, 1.0), clamp(m[3], 0.0, 1.0));
+}
+
+struct v2f_vertex_lit {
+    highp vec2 uv;
+    lowp vec4 diff;
+    lowp vec4 spec;
+};
+
+struct v2f_img {
+    highp vec4 pos;
+    mediump vec2 uv;
+};
+
+struct appdata_img {
+    highp vec4 vertex;
+    mediump vec2 texcoord;
+};
+
+struct Unity_GlossyEnvironmentData {
+    mediump float roughness;
+    mediump vec3 reflUVW;
+};
+
+struct UnityLight {
+    mediump vec3 color;
+    mediump vec3 dir;
+    mediump float ndotl;
+};
+
+struct UnityIndirect {
+    mediump vec3 diffuse;
+    mediump vec3 specular;
+};
+
+struct UnityGI {
+    UnityLight light;
+    UnityIndirect indirect;
+};
+
+struct UnityGIInput {
+    UnityLight light;
+    highp vec3 worldPos;
+    mediump vec3 worldViewDir;
+    mediump float atten;
+    mediump vec3 ambient;
+    mediump vec4 lightmapUV;
+    highp vec4 boxMax[2];
+    highp vec4 boxMin[2];
+    highp vec4 probePosition[2];
+    highp vec4 probeHDR[2];
+};
+
+struct SurfaceOutputStandard {
+    lowp vec3 Albedo;
+    lowp vec3 Normal;
+    mediump vec3 Emission;
+    mediump float Metallic;
+    mediump float Smoothness;
+    mediump float Occlusion;
+    lowp float Alpha;
+};
+
+struct SurfaceOutputStandardSpecular {
+    lowp vec3 Albedo;
+    lowp vec3 Specular;
+    lowp vec3 Normal;
+    mediump vec3 Emission;
+    mediump float Smoothness;
+    mediump float Occlusion;
+    lowp float Alpha;
+};
+
+struct VertexInput {
+    highp vec4 vertex;
+    mediump vec3 normal;
+    highp vec2 uv0;
+    highp vec2 uv1;
+};
+
+struct FragmentCommonData {
+    mediump vec3 diffColor;
+    mediump vec3 specColor;
+    mediump float oneMinusReflectivity;
+    mediump float oneMinusRoughness;
+    mediump vec3 normalWorld;
+    mediump vec3 eyeVec;
+    mediump vec3 posWorld;
+    mediump float alpha;
+};
+
+struct VertexOutputForwardBase {
+    highp vec4 pos;
+    highp vec4 tex;
+    mediump vec3 eyeVec;
+    mediump vec4 tangentToWorldAndParallax[3];
+    mediump vec4 ambientOrLightmapUV;
+    mediump vec4 _ShadowCoord;
+};
+
+struct VertexOutputForwardAdd {
+    highp vec4 pos;
+    highp vec4 tex;
+    mediump vec3 eyeVec;
+    mediump vec4 tangentToWorldAndLightDir[3];
+    mediump vec4 _ShadowCoord;
+};
+
+struct VertexOutputDeferred {
+    highp vec4 pos;
+    highp vec4 tex;
+    mediump vec3 eyeVec;
+    mediump vec4 tangentToWorldAndParallax[3];
+    mediump vec4 ambientOrLightmapUV;
+};
+
+struct VertexInput_VC {
+    highp vec4 vertex;
+    lowp vec4 color;
+    mediump vec3 normal;
+    highp vec2 uv0;
+    highp vec2 uv1;
+};
+
+struct VertexOutputForwardBase_VC {
+    highp vec4 pos;
+    highp vec4 tex;
+    mediump vec3 eyeVec;
+    mediump vec4 tangentToWorldAndParallax[3];
+    mediump vec4 ambientOrLightmapUV;
+    mediump vec4 _ShadowCoord;
+    lowp vec4 color;
+};
+
+struct VertexOutputDeferred_VC {
+    highp vec4 pos;
+    lowp vec4 color;
+    highp vec4 tex;
+    mediump vec3 eyeVec;
+    mediump vec4 tangentToWorldAndParallax[3];
+    mediump vec4 ambientOrLightmapUV;
+};
+
+uniform highp vec4 _Time;
+uniform highp vec4 _SinTime;
+uniform highp vec4 _CosTime;
+uniform highp vec4 unity_DeltaTime;
+
+uniform highp vec3 _WorldSpaceCameraPos;
+
+uniform highp vec4 _ProjectionParams;
+
+uniform highp vec4 _ScreenParams;
+
+uniform highp vec4 _ZBufferParams;
+
+uniform highp vec4 unity_OrthoParams;
+
+uniform highp vec4 unity_CameraWorldClipPlanes[6];
+
+uniform highp mat4 unity_CameraProjection;
+uniform highp mat4 unity_CameraInvProjection;
+
+uniform mediump vec4 _WorldSpaceLightPos0;
+
+uniform highp vec4 _LightPositionRange;
+uniform highp vec4 unity_4LightPosX0;
+uniform highp vec4 unity_4LightPosY0;
+
+uniform highp vec4 unity_4LightPosZ0;
+uniform mediump vec4 unity_4LightAtten0;
+uniform mediump vec4 unity_LightColor[8];
+
+uniform highp vec4 unity_LightPosition[8];
+
+uniform mediump vec4 unity_LightAtten[8];
+uniform highp vec4 unity_SpotDirection[8];
+
+uniform mediump vec4 unity_SHAr;
+uniform mediump vec4 unity_SHAg;
+uniform mediump vec4 unity_SHAb;
+uniform mediump vec4 unity_SHBr;
+
+uniform mediump vec4 unity_SHBg;
+uniform mediump vec4 unity_SHBb;
+uniform mediump vec4 unity_SHC;
+
+uniform mediump vec3 unity_LightColor0;
+uniform mediump vec3 unity_LightColor1;
+uniform mediump vec3 unity_LightColor2;
+uniform mediump vec3 unity_LightColor3;
+
+uniform highp vec4 unity_ShadowSplitSpheres[4];
+uniform highp vec4 unity_ShadowSplitSqRadii;
+uniform highp vec4 unity_LightShadowBias;
+uniform highp vec4 _LightSplitsNear;
+
+uniform highp vec4 _LightSplitsFar;
+uniform highp mat4 unity_World2Shadow[4];
+uniform mediump vec4 _LightShadowData;
+uniform highp vec4 unity_ShadowFadeCenterAndType;
+
+uniform highp mat4 glstate_matrix_mvp;
+uniform highp mat4 glstate_matrix_modelview0;
+uniform highp mat4 glstate_matrix_invtrans_modelview0;
+
+uniform highp mat4 _Object2World;
+uniform highp mat4 _World2Object;
+uniform highp vec4 unity_LODFade;
+uniform highp vec4 unity_WorldTransformParams;
+
+uniform highp mat4 glstate_matrix_transpose_modelview0;
+
+uniform highp mat4 glstate_matrix_projection;
+uniform lowp vec4 glstate_lightmodel_ambient;
+
+uniform highp mat4 unity_MatrixV;
+uniform highp mat4 unity_MatrixVP;
+
+uniform lowp vec4 unity_AmbientSky;
+uniform lowp vec4 unity_AmbientEquator;
+uniform lowp vec4 unity_AmbientGround;
+
+uniform lowp vec4 unity_FogColor;
+
+uniform highp vec4 unity_FogParams;
+
+uniform sampler2D unity_Lightmap;
+uniform sampler2D unity_LightmapInd;
+
+uniform sampler2D unity_DynamicLightmap;
+uniform sampler2D unity_DynamicDirectionality;
+uniform sampler2D unity_DynamicNormal;
+
+uniform highp vec4 unity_LightmapST;
+uniform highp vec4 unity_DynamicLightmapST;
+
+uniform samplerCube unity_SpecCube0;
+uniform samplerCube unity_SpecCube1;
+
+uniform highp vec4 unity_SpecCube0_BoxMax;
+uniform highp vec4 unity_SpecCube0_BoxMin;
+uniform highp vec4 unity_SpecCube0_ProbePosition;
+uniform mediump vec4 unity_SpecCube0_HDR;
+
+uniform highp vec4 unity_SpecCube1_BoxMax;
+uniform highp vec4 unity_SpecCube1_BoxMin;
+uniform highp vec4 unity_SpecCube1_ProbePosition;
+uniform mediump vec4 unity_SpecCube1_HDR;
+
+uniform lowp vec4 unity_ColorSpaceGrey;
+uniform lowp vec4 unity_ColorSpaceDouble;
+uniform mediump vec4 unity_ColorSpaceDielectricSpec;
+uniform mediump vec4 unity_ColorSpaceLuminance;
+
+uniform mediump vec4 unity_Lightmap_HDR;
+
+uniform mediump vec4 unity_DynamicLightmap_HDR;
+
+uniform lowp vec4 _LightColor0;
+uniform lowp vec4 _SpecColor;
+
+uniform sampler2D unity_NHxRoughness;
+
+uniform mediump vec4 _Color;
+uniform mediump float _Cutoff;
+uniform sampler2D _MainTex;
+
+uniform highp vec4 _MainTex_ST;
+uniform sampler2D _DetailAlbedoMap;
+uniform highp vec4 _DetailAlbedoMap_ST;
+
+uniform sampler2D _BumpMap;
+uniform mediump float _BumpScale;
+uniform sampler2D _DetailMask;
+
+uniform sampler2D _DetailNormalMap;
+uniform mediump float _DetailNormalMapScale;
+uniform sampler2D _SpecGlossMap;
+
+uniform sampler2D _MetallicGlossMap;
+uniform mediump float _Metallic;
+uniform mediump float _Glossiness;
+
+uniform sampler2D _OcclusionMap;
+uniform mediump float _OcclusionStrength;
+uniform sampler2D _ParallaxMap;
+
+uniform mediump float _Parallax;
+uniform mediump float _UVSec;
+uniform mediump vec4 _EmissionColor;
+
+uniform sampler2D _EmissionMap;
+
+uniform lowp sampler2DShadow _ShadowMapTexture;
+
+mediump float DotClamped( in mediump vec3 a, in mediump vec3 b ) {    
+    return max( 0.0, dot( a, b));
+}
+
+mediump float BlinnTerm( in mediump vec3 normal, in mediump vec3 halfDir ) {
+    return DotClamped( normal, halfDir);
+}
+
+mediump float Pow4( in mediump float x ) {
+    return (((x * x) * x) * x);
+}
+
+mediump vec3 FresnelLerpFast( in mediump vec3 F0, in mediump vec3 F90, in mediump float cosA ) {
+    mediump float t = Pow4( (1.0 - cosA));
+    return mix( F0, F90, vec3( t));
+}
+
+bool IsGammaSpace(  ) {
+    return true;
+}
+
+mediump float RoughnessToSpecPower( in mediump float roughness ) {
+    
+    mediump float m = max( 0.0001, (roughness * roughness));
+    mediump float n = ((2.0 / (m * m)) - 2.0);
+    n = max( n, 0.0001);
+    
+    return n;
+}
+
+mediump vec3 Unity_SafeNormalize( in mediump vec3 inVec ) {
+    mediump float dp3 = max( 0.001, dot( inVec, inVec));
+    return (inVec * inversesqrt(dp3));
+}
+
+mediump vec4 BRDF2_Unity_PBS( in mediump vec3 diffColor, in mediump vec3 specColor, in mediump float oneMinusReflectivity, in mediump float oneMinusRoughness, in mediump vec3 normal, in mediump vec3 viewDir, in UnityLight light, in UnityIndirect gi ) {
+    mediump vec3 halfDir = Unity_SafeNormalize( (light.dir + viewDir));
+    
+    mediump float nl = light.ndotl;
+    mediump float nh = BlinnTerm( normal, halfDir);
+    mediump float nv = DotClamped( normal, viewDir);
+    mediump float lh = DotClamped( light.dir, halfDir);
+    
+    mediump float roughness = (1.0 - oneMinusRoughness);
+    mediump float specularPower = RoughnessToSpecPower( roughness);
+    
+    mediump float invV = (((lh * lh) * oneMinusRoughness) + (roughness * roughness));
+    mediump float invF = lh;
+    mediump float specular = (((specularPower + 1.0) * pow( nh, specularPower)) / (((8.0 * invV) * invF) + 0.0001));
+    if (IsGammaSpace( )){
+        specular = sqrt(max( 0.0001, specular));
+    }
+    
+    mediump float realRoughness = (roughness * roughness);
+    mediump float surfaceReduction = (( IsGammaSpace( ) ) ? ( 0.28 ) : ( (0.6 - (0.08 * roughness)) ));
+    
+    surfaceReduction = (1.0 - ((realRoughness * roughness) * surfaceReduction));
+    
+    mediump float grazingTerm = xll_saturate_f((oneMinusRoughness + (1.0 - oneMinusReflectivity)));
+    mediump vec3 color = (((((diffColor + (specular * specColor)) * light.color) * nl) + (gi.diffuse * diffColor)) + ((surfaceReduction * gi.specular) * FresnelLerpFast( specColor, vec3( grazingTerm), nv)));
+    
+    return vec4( color, 1.0);
+}
+
+mediump vec3 BRDF_Unity_Indirect( in mediump vec3 baseColor, in mediump vec3 specColor, in mediump float oneMinusReflectivity, in mediump float oneMinusRoughness, in mediump vec3 normal, in mediump vec3 viewDir, in mediump float occlusion, in UnityGI gi ) {
+    mediump vec3 c = vec3( 0.0);
+    
+    return c;
+}
+
+mediump vec3 Emission( in highp vec2 uv ) {
+    return vec3( 0.0);
+}
+
+void ResetUnityLight( out UnityLight outLight ) {
+    
+    outLight.color = vec3( 0.0);
+    outLight.dir = vec3( 0.0);
+    outLight.ndotl = 0.0;
+}
+
+void ResetUnityGI( out UnityGI outGI ) {
+    ResetUnityLight( outGI.light);
+    
+    outGI.indirect.diffuse = vec3( 0.0);
+    outGI.indirect.specular = vec3( 0.0);
+}
+
+mediump vec3 LinearToGammaSpace( in mediump vec3 linRGB ) {
+    linRGB = max( linRGB, vec3( 0.0, 0.0, 0.0));
+    
+    return max( ((1.055 * pow( linRGB, vec3( 0.4166667))) - 0.055), vec3( 0.0));
+}
+
+mediump vec3 SHEvalLinearL0L1( in mediump vec4 normal ) {
+    mediump vec3 x;
+    
+    x.x = dot( unity_SHAr, normal);
+    x.y = dot( unity_SHAg, normal);
+    x.z = dot( unity_SHAb, normal);
+    
+    return x;
+}
+
+mediump vec3 ShadeSHPerPixel( in mediump vec3 normal, in mediump vec3 ambient ) {
+    
+    mediump vec3 ambient_contrib = vec3( 0.0);
+    
+    ambient_contrib = SHEvalLinearL0L1( vec4( normal, 1.0));
+    ambient = max( vec3( 0.0, 0.0, 0.0), (ambient + ambient_contrib));
+    if (IsGammaSpace( )){
+        ambient = LinearToGammaSpace( ambient);
+    }
+    
+    return ambient;
+}
+
+UnityGI UnityGI_Base( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld ) {
+    UnityGI o_gi;
+    ResetUnityGI( o_gi);
+    
+    o_gi.light = data.light;
+    o_gi.light.color *= data.atten;
+    
+    o_gi.indirect.diffuse = ShadeSHPerPixel( normalWorld, data.ambient);
+    
+    o_gi.indirect.diffuse *= occlusion;
+    return o_gi;
+}
+
+UnityGI UnityGlobalIllumination( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld ) {
+    return UnityGI_Base( data, occlusion, normalWorld);
+}
+
+mediump vec3 DecodeHDR( in mediump vec4 data, in mediump vec4 decodeInstructions ) {
+    return ((decodeInstructions.x * data.w) * data.xyz);
+}
+
+mediump vec3 DecodeHDR_NoLinearSupportInSM2( in mediump vec4 data, in mediump vec4 decodeInstructions ) {    
+    return DecodeHDR( data, decodeInstructions);
+}
+
+mediump vec3 Unity_GlossyEnvironment( in samplerCube tex, in mediump vec4 hdr, in Unity_GlossyEnvironmentData glossIn ) {
+    
+    mediump float roughness = glossIn.roughness;
+    
+    roughness = (roughness * (1.7 - (0.7 * roughness)));
+    
+    mediump float mip = (roughness * 6.0);
+    mediump vec4 rgbm = xll_texCUBElod( tex, vec4( glossIn.reflUVW, mip));
+    return DecodeHDR_NoLinearSupportInSM2( rgbm, hdr);
+}
+
+mediump vec3 UnityGI_IndirectSpecular( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld, in Unity_GlossyEnvironmentData glossIn ) {
+    mediump vec3 specular;
+    mediump vec3 env0 = Unity_GlossyEnvironment( unity_SpecCube0, data.probeHDR[0], glossIn);
+    specular = env0;
+    return (specular * occlusion);
+}
+
+UnityGI UnityGlobalIllumination( in UnityGIInput data, in mediump float occlusion, in mediump vec3 normalWorld, in Unity_GlossyEnvironmentData glossIn ) {
+    UnityGI o_gi = UnityGI_Base( data, occlusion, normalWorld);
+    o_gi.indirect.specular = UnityGI_IndirectSpecular( data, occlusion, normalWorld, glossIn);    
+    return o_gi;
+}
+
+UnityGI FragmentGI( in FragmentCommonData s, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in UnityLight light, in bool reflections ) {
+    UnityGIInput d;
+    d.light = light;
+    
+    d.worldPos = s.posWorld;
+    d.worldViewDir = (-s.eyeVec);
+    d.atten = atten;
+    
+    d.ambient = i_ambientOrLightmapUV.xyz;
+    d.lightmapUV = vec4( 0.0);
+    d.boxMax[0] = unity_SpecCube0_BoxMax;
+    
+    d.boxMin[0] = unity_SpecCube0_BoxMin;
+    d.probePosition[0] = unity_SpecCube0_ProbePosition;
+    d.probeHDR[0] = unity_SpecCube0_HDR;
+    
+    d.boxMax[1] = unity_SpecCube1_BoxMax;
+    d.boxMin[1] = unity_SpecCube1_BoxMin;
+    d.probePosition[1] = unity_SpecCube1_ProbePosition;
+    d.probeHDR[1] = unity_SpecCube1_HDR;
+    
+    if (reflections){
+        Unity_GlossyEnvironmentData g;
+        g.roughness = (1.0 - s.oneMinusRoughness);
+        
+        g.reflUVW = reflect( s.eyeVec, s.normalWorld);
+        return UnityGlobalIllumination( d, occlusion, s.normalWorld, g);
+    }
+    else{
+        return UnityGlobalIllumination( d, occlusion, s.normalWorld);
+    }
+}
+
+UnityGI FragmentGI( in highp vec3 posWorld, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in mediump float oneMinusRoughness, in mediump vec3 normalWorld, in mediump vec3 eyeVec, in UnityLight light, in bool reflections ) {
+    FragmentCommonData s = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0);
+    s.oneMinusRoughness = oneMinusRoughness;
+    s.normalWorld = normalWorld;
+    s.eyeVec = eyeVec;
+    s.posWorld = posWorld;
+    return FragmentGI( s, occlusion, i_ambientOrLightmapUV, atten, light, reflections);
+}
+
+UnityGI FragmentGI( in highp vec3 posWorld, in mediump float occlusion, in mediump vec4 i_ambientOrLightmapUV, in mediump float atten, in mediump float oneMinusRoughness, in mediump vec3 normalWorld, in mediump vec3 eyeVec, in UnityLight light ) {
+    return FragmentGI( posWorld, occlusion, i_ambientOrLightmapUV, atten, oneMinusRoughness, normalWorld, eyeVec, light, true);
+}
+
+mediump float Alpha( in highp vec2 uv ) {
+    return (texture( _MainTex, uv).w * _Color.w);
+}
+
+mediump vec3 Albedo( in highp vec4 texcoords ) {
+    mediump vec3 albedo = (_Color.xyz * texture( _MainTex, texcoords.xy).xyz);
+    return albedo;
+}
+
+mediump float OneMinusReflectivityFromMetallic( in mediump float metallic ) {
+    mediump float oneMinusDielectricSpec = unity_ColorSpaceDielectricSpec.w;
+    return (oneMinusDielectricSpec - (metallic * oneMinusDielectricSpec));
+}
+
+mediump vec3 DiffuseAndSpecularFromMetallic( in mediump vec3 albedo, in mediump float metallic, out mediump vec3 specColor, out mediump float oneMinusReflectivity ) {
+    specColor = mix( unity_ColorSpaceDielectricSpec.xyz, albedo, vec3( metallic));
+    oneMinusReflectivity = OneMinusReflectivityFromMetallic( metallic);
+    
+    return (albedo * oneMinusReflectivity);
+}
+
+mediump vec2 MetallicGloss( in highp vec2 uv ) {
+    mediump vec2 mg;
+    
+    mg = vec2( _Metallic, _Glossiness);
+    return mg;
+}
+
+FragmentCommonData MetallicSetup( in highp vec4 i_tex ) {
+    mediump vec2 metallicGloss = MetallicGloss( i_tex.xy);
+    mediump float metallic = metallicGloss.x;
+    
+    mediump float oneMinusRoughness = metallicGloss.y;
+    mediump float oneMinusReflectivity;
+    mediump vec3 specColor;
+    
+    mediump vec3 diffColor = DiffuseAndSpecularFromMetallic( Albedo( i_tex), metallic, specColor, oneMinusReflectivity);
+    FragmentCommonData o = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0);
+    o.diffColor = diffColor;
+    
+    o.specColor = specColor;
+    o.oneMinusReflectivity = oneMinusReflectivity;
+    o.oneMinusRoughness = oneMinusRoughness;
+    return o;
+}
+
+mediump vec3 NormalizePerPixelNormal( in mediump vec3 n ) {
+    return normalize(n);
+}
+
+highp vec4 Parallax( in highp vec4 texcoords, in mediump vec3 viewDir ) {
+    return texcoords;
+}
+
+mediump vec3 PerPixelWorldNormal( in highp vec4 i_tex, in mediump vec4 tangentToWorld[3] ) {
+    mediump vec3 normalWorld = normalize(tangentToWorld[2].xyz);
+    return normalWorld;
+}
+
+mediump vec3 PreMultiplyAlpha( in mediump vec3 diffColor, in mediump float alpha, in mediump float oneMinusReflectivity, out mediump float outModifiedAlpha ) {
+    outModifiedAlpha = alpha;
+    return diffColor;
+}
+
+FragmentCommonData FragmentSetup( in highp vec4 i_tex, in mediump vec3 i_eyeVec, in mediump vec3 i_viewDirForParallax, in mediump vec4 tangentToWorld[3], in mediump vec3 i_posWorld ) {
+    i_tex = Parallax( i_tex, i_viewDirForParallax);
+    
+    mediump float alpha = Alpha( i_tex.xy);
+    
+    FragmentCommonData o = MetallicSetup( i_tex);
+    o.normalWorld = PerPixelWorldNormal( i_tex, tangentToWorld);
+    o.eyeVec = NormalizePerPixelNormal( i_eyeVec);
+    o.posWorld = i_posWorld;
+    
+    o.diffColor = PreMultiplyAlpha( o.diffColor, alpha, o.oneMinusReflectivity, o.alpha);
+    return o;
+}
+
+mediump float LambertTerm( in mediump vec3 normal, in mediump vec3 lightDir ) {
+    return DotClamped( normal, lightDir);
+}
+
+UnityLight MainLight( in mediump vec3 normalWorld ) {
+    UnityLight l;
+    
+    l.color = _LightColor0.xyz;
+    l.dir = _WorldSpaceLightPos0.xyz;
+    l.ndotl = LambertTerm( normalWorld, l.dir);
+    
+    return l;
+}
+
+mediump float LerpOneTo( in mediump float b, in mediump float t ) {
+    mediump float oneMinusT = (1.0 - t);
+    return (oneMinusT + (b * t));
+}
+
+mediump float Occlusion( in highp vec2 uv ) {    
+    mediump float occ = texture( _OcclusionMap, uv).y;
+    return LerpOneTo( occ, _OcclusionStrength);
+}
+
+mediump vec4 OutputForward( in mediump vec4 xlat_varoutput, in mediump float alphaFromSurface ) {
+    xlat_varoutput.w = 1.0;
+    return xlat_varoutput;
+}
+
+lowp float unitySampleShadow( in mediump vec4 shadowCoord ) {    
+    lowp float shadow = xll_shadow2D( _ShadowMapTexture, shadowCoord.xyz.xyz);
+    shadow = (_LightShadowData.x + (shadow * (1.0 - _LightShadowData.x)));
+    return shadow;
+}
+
+mediump vec4 fragForwardBase_VC( in VertexOutputForwardBase_VC i ) {
+    FragmentCommonData s = FragmentSetup( i.tex, i.eyeVec, vec3( 0.0, 0.0, 0.0), i.tangentToWorldAndParallax, vec3( 0.0, 0.0, 0.0));
+    UnityLight mainLight = MainLight( s.normalWorld);
+    
+    mediump float atten = unitySampleShadow( i._ShadowCoord);
+    mediump float occlusion = Occlusion( i.tex.xy);
+    UnityGI gi = FragmentGI( s.posWorld, occlusion, i.ambientOrLightmapUV, atten, s.oneMinusRoughness, s.normalWorld, s.eyeVec, mainLight);
+    
+    mediump vec4 c = BRDF2_Unity_PBS( s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, (-s.eyeVec), gi.light, gi.indirect);
+    c *= i.color;
+    
+    c.xyz += BRDF_Unity_Indirect( s.diffColor, s.specColor, s.oneMinusReflectivity, s.oneMinusRoughness, s.normalWorld, (-s.eyeVec), occlusion, gi);
+    c.xyz += Emission( i.tex.xy);
+    
+    return OutputForward( c, (s.alpha * i.color.w));
+}
+in highp vec4 xlv_TEXCOORD0;
+in mediump vec3 xlv_TEXCOORD1;
+in mediump vec4 xlv_TEXCOORD2;
+in mediump vec4 xlv_TEXCOORD2_1;
+in mediump vec4 xlv_TEXCOORD2_2;
+in mediump vec4 xlv_TEXCOORD5;
+in mediump vec4 xlv_TEXCOORD6;
+in lowp vec4 xlv_COLOR;
+out lowp vec4 FragData [1];
+void main() {
+    mediump vec4 xl_retval;
+    VertexOutputForwardBase_VC xlt_i;
+    xlt_i.pos = vec4(0.0);
+    xlt_i.tex = vec4(xlv_TEXCOORD0);
+    xlt_i.eyeVec = vec3(xlv_TEXCOORD1);
+    xlt_i.tangentToWorldAndParallax[0] = vec4(xlv_TEXCOORD2);
+    xlt_i.tangentToWorldAndParallax[1] = vec4(xlv_TEXCOORD2_1);
+    xlt_i.tangentToWorldAndParallax[2] = vec4(xlv_TEXCOORD2_2);
+    xlt_i.ambientOrLightmapUV = vec4(xlv_TEXCOORD5);
+    xlt_i._ShadowCoord = vec4(xlv_TEXCOORD6);
+    xlt_i.color = vec4(xlv_COLOR);
+    xl_retval = fragForwardBase_VC( xlt_i);
+    FragData[0] = vec4(xl_retval);
+}

+ 187 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3.txt

@@ -0,0 +1,187 @@
+#version 300 es
+struct FragmentCommonData {
+  mediump vec3 diffColor;
+  mediump vec3 specColor;
+  mediump float oneMinusReflectivity;
+  mediump float oneMinusRoughness;
+  mediump vec3 normalWorld;
+  mediump vec3 eyeVec;
+  mediump vec3 posWorld;
+  mediump float alpha;
+};
+uniform mediump vec4 _WorldSpaceLightPos0;
+uniform mediump vec4 unity_SHAr;
+uniform mediump vec4 unity_SHAg;
+uniform mediump vec4 unity_SHAb;
+uniform mediump vec4 _LightShadowData;
+uniform lowp samplerCube unity_SpecCube0;
+uniform mediump vec4 unity_SpecCube0_HDR;
+uniform mediump vec4 unity_ColorSpaceDielectricSpec;
+uniform lowp vec4 _LightColor0;
+uniform mediump vec4 _Color;
+uniform sampler2D _MainTex;
+uniform mediump float _Metallic;
+uniform mediump float _Glossiness;
+uniform sampler2D _OcclusionMap;
+uniform mediump float _OcclusionStrength;
+uniform lowp sampler2DShadow _ShadowMapTexture;
+in highp vec4 xlv_TEXCOORD0;
+in mediump vec3 xlv_TEXCOORD1;
+in mediump vec4 xlv_TEXCOORD2_2;
+in mediump vec4 xlv_TEXCOORD5;
+in mediump vec4 xlv_TEXCOORD6;
+in lowp vec4 xlv_COLOR;
+out lowp vec4 FragData[1];
+void main ()
+{
+  mediump vec4 c_1;
+  mediump float atten_2;
+  lowp vec4 tmpvar_3;
+  tmpvar_3 = texture (_MainTex, xlv_TEXCOORD0.xy);
+  mediump vec2 tmpvar_4;
+  tmpvar_4.x = _Metallic;
+  tmpvar_4.y = _Glossiness;
+  mediump vec3 tmpvar_5;
+  tmpvar_5 = (_Color.xyz * tmpvar_3.xyz);
+  mediump vec3 tmpvar_6;
+  mediump vec3 tmpvar_7;
+  tmpvar_7 = mix (unity_ColorSpaceDielectricSpec.xyz, tmpvar_5, vec3(_Metallic));
+  mediump float tmpvar_8;
+  tmpvar_8 = (unity_ColorSpaceDielectricSpec.w - (_Metallic * unity_ColorSpaceDielectricSpec.w));
+  tmpvar_6 = (tmpvar_5 * tmpvar_8);
+  mediump vec3 tmpvar_9;
+  tmpvar_9 = normalize(xlv_TEXCOORD2_2.xyz);
+  mediump vec3 tmpvar_10;
+  tmpvar_10 = normalize(xlv_TEXCOORD1);
+  mediump vec3 tmpvar_11;
+  tmpvar_11 = _LightColor0.xyz;
+  lowp float shadow_12;
+  mediump float tmpvar_13;
+  tmpvar_13 = texture (_ShadowMapTexture, xlv_TEXCOORD6.xyz);
+  lowp float tmpvar_14;
+  tmpvar_14 = tmpvar_13;
+  shadow_12 = (_LightShadowData.x + (tmpvar_14 * (1.0 - _LightShadowData.x)));
+  atten_2 = shadow_12;
+  mediump float occ_15;
+  lowp float tmpvar_16;
+  tmpvar_16 = texture (_OcclusionMap, xlv_TEXCOORD0.xy).y;
+  occ_15 = tmpvar_16;
+  mediump float tmpvar_17;
+  tmpvar_17 = ((1.0 - _OcclusionStrength) + (occ_15 * _OcclusionStrength));
+  FragmentCommonData s_18;
+  s_18 = FragmentCommonData(vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0, 0.0, vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), vec3(0.0, 0.0, 0.0), 0.0);
+  s_18.oneMinusRoughness = tmpvar_4.y;
+  s_18.normalWorld = tmpvar_9;
+  s_18.eyeVec = tmpvar_10;
+  s_18.posWorld = vec3(0.0, 0.0, 0.0);
+  mediump vec3 tmpvar_19;
+  mediump vec3 tmpvar_20;
+  tmpvar_19 = s_18.normalWorld;
+  tmpvar_20 = s_18.eyeVec;
+  highp vec4 tmpvar_21;
+  tmpvar_21 = unity_SpecCube0_HDR;
+  mediump float tmpvar_22;
+  tmpvar_22 = (1.0 - s_18.oneMinusRoughness);
+  mediump vec3 tmpvar_23;
+  tmpvar_23 = (tmpvar_20 - (2.0 * (
+    dot (tmpvar_19, tmpvar_20)
+   * tmpvar_19)));
+  mediump vec4 tmpvar_24;
+  tmpvar_24.w = 1.0;
+  tmpvar_24.xyz = tmpvar_19;
+  mediump vec3 x_25;
+  x_25.x = dot (unity_SHAr, tmpvar_24);
+  x_25.y = dot (unity_SHAg, tmpvar_24);
+  x_25.z = dot (unity_SHAb, tmpvar_24);
+  mediump vec4 hdr_26;
+  hdr_26 = tmpvar_21;
+  mediump vec4 tmpvar_27;
+  tmpvar_27.xyz = tmpvar_23;
+  tmpvar_27.w = ((tmpvar_22 * (1.7 - 
+    (0.7 * tmpvar_22)
+  )) * 6.0);
+  lowp vec4 tmpvar_28;
+  tmpvar_28 = textureLod (unity_SpecCube0, tmpvar_23, tmpvar_27.w);
+  mediump vec4 tmpvar_29;
+  tmpvar_29 = tmpvar_28;
+  mediump vec3 viewDir_30;
+  viewDir_30 = -(tmpvar_10);
+  mediump vec3 tmpvar_31;
+  mediump vec3 inVec_32;
+  inVec_32 = (_WorldSpaceLightPos0.xyz + viewDir_30);
+  tmpvar_31 = (inVec_32 * inversesqrt(max (0.001, 
+    dot (inVec_32, inVec_32)
+  )));
+  mediump float tmpvar_33;
+  tmpvar_33 = max (0.0, dot (_WorldSpaceLightPos0.xyz, tmpvar_31));
+  mediump float tmpvar_34;
+  tmpvar_34 = (1.0 - _Glossiness);
+  mediump float tmpvar_35;
+  tmpvar_35 = max (0.0001, (tmpvar_34 * tmpvar_34));
+  mediump float tmpvar_36;
+  tmpvar_36 = max (((2.0 / 
+    (tmpvar_35 * tmpvar_35)
+  ) - 2.0), 0.0001);
+  mediump float x_37;
+  x_37 = (1.0 - max (0.0, dot (tmpvar_9, viewDir_30)));
+  mediump vec4 tmpvar_38;
+  tmpvar_38.w = 1.0;
+  tmpvar_38.xyz = (((
+    ((tmpvar_6 + (sqrt(
+      max (0.0001, (((tmpvar_36 + 1.0) * pow (
+        max (0.0, dot (tmpvar_9, tmpvar_31))
+      , tmpvar_36)) / ((
+        (8.0 * (((tmpvar_33 * tmpvar_33) * _Glossiness) + (tmpvar_34 * tmpvar_34)))
+       * tmpvar_33) + 0.0001)))
+    ) * tmpvar_7)) * (tmpvar_11 * atten_2))
+   * 
+    max (0.0, dot (tmpvar_9, _WorldSpaceLightPos0.xyz))
+  ) + (
+    (max (((1.055 * 
+      pow (max (vec3(0.0, 0.0, 0.0), (xlv_TEXCOORD5.xyz + x_25)), vec3(0.4166667, 0.4166667, 0.4166667))
+    ) - 0.055), vec3(0.0, 0.0, 0.0)) * tmpvar_17)
+   * tmpvar_6)) + ((
+    (1.0 - ((tmpvar_34 * tmpvar_34) * (tmpvar_34 * 0.28)))
+   * 
+    (((hdr_26.x * tmpvar_29.w) * tmpvar_29.xyz) * tmpvar_17)
+  ) * mix (tmpvar_7, vec3(
+    clamp ((_Glossiness + (1.0 - tmpvar_8)), 0.0, 1.0)
+  ), vec3(
+    ((x_37 * x_37) * (x_37 * x_37))
+  ))));
+  c_1 = (tmpvar_38 * xlv_COLOR);
+  c_1.xyz = c_1.xyz;
+  c_1.xyz = c_1.xyz;
+  mediump vec4 xlat_varoutput_39;
+  xlat_varoutput_39.xyz = c_1.xyz;
+  xlat_varoutput_39.w = 1.0;
+  FragData[0] = xlat_varoutput_39;
+}
+
+
+// stats: 97 alu 4 tex 0 flow
+// inputs: 6
+//  #0: xlv_TEXCOORD0 (high float) 4x1 [-1]
+//  #1: xlv_TEXCOORD1 (medium float) 3x1 [-1]
+//  #2: xlv_TEXCOORD2_2 (medium float) 4x1 [-1]
+//  #3: xlv_TEXCOORD5 (medium float) 4x1 [-1]
+//  #4: xlv_TEXCOORD6 (medium float) 4x1 [-1]
+//  #5: xlv_COLOR (low float) 4x1 [-1]
+// uniforms: 12 (total size: 0)
+//  #0: _WorldSpaceLightPos0 (medium float) 4x1 [-1]
+//  #1: unity_SHAr (medium float) 4x1 [-1]
+//  #2: unity_SHAg (medium float) 4x1 [-1]
+//  #3: unity_SHAb (medium float) 4x1 [-1]
+//  #4: _LightShadowData (medium float) 4x1 [-1]
+//  #5: unity_SpecCube0_HDR (medium float) 4x1 [-1]
+//  #6: unity_ColorSpaceDielectricSpec (medium float) 4x1 [-1]
+//  #7: _LightColor0 (low float) 4x1 [-1]
+//  #8: _Color (medium float) 4x1 [-1]
+//  #9: _Metallic (medium float) 1x1 [-1]
+//  #10: _Glossiness (medium float) 1x1 [-1]
+//  #11: _OcclusionStrength (medium float) 1x1 [-1]
+// textures: 4
+//  #0: unity_SpecCube0 (low cube) 0x0 [-1]
+//  #1: _MainTex (low 2d) 0x0 [-1]
+//  #2: _OcclusionMap (low 2d) 0x0 [-1]
+//  #3: _ShadowMapTexture (low 2dshadow) 0x0 [-1]

+ 199 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/global-struct-constant-init-metal-outES3Metal.txt

@@ -0,0 +1,199 @@
+#include <metal_stdlib>
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+using namespace metal;
+constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less_equal);
+struct FragmentCommonData {
+  half3 diffColor;
+  half3 specColor;
+  half oneMinusReflectivity;
+  half oneMinusRoughness;
+  half3 normalWorld;
+  half3 eyeVec;
+  half3 posWorld;
+  half alpha;
+};
+constant FragmentCommonData _xlat_mtl_const1 = {float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), 0.0, 0.0, float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), 0.0};
+struct xlatMtlShaderInput {
+  float4 xlv_TEXCOORD0;
+  half3 xlv_TEXCOORD1;
+  half4 xlv_TEXCOORD2_2;
+  half4 xlv_TEXCOORD5;
+  half4 xlv_TEXCOORD6;
+  half4 xlv_COLOR;
+};
+struct xlatMtlShaderOutput {
+  half4 FragData_0 [[color(0)]];
+};
+struct xlatMtlShaderUniform {
+  half4 _WorldSpaceLightPos0;
+  half4 unity_SHAr;
+  half4 unity_SHAg;
+  half4 unity_SHAb;
+  half4 _LightShadowData;
+  half4 unity_SpecCube0_HDR;
+  half4 unity_ColorSpaceDielectricSpec;
+  half4 _LightColor0;
+  half4 _Color;
+  half _Metallic;
+  half _Glossiness;
+  half _OcclusionStrength;
+};
+fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]]
+  ,   texturecube<half> unity_SpecCube0 [[texture(0)]], sampler _mtlsmp_unity_SpecCube0 [[sampler(0)]]
+  ,   texture2d<half> _MainTex [[texture(1)]], sampler _mtlsmp__MainTex [[sampler(1)]]
+  ,   texture2d<half> _OcclusionMap [[texture(2)]], sampler _mtlsmp__OcclusionMap [[sampler(2)]]
+  ,   depth2d<float> _ShadowMapTexture [[texture(3)]], sampler _mtlsmp__ShadowMapTexture [[sampler(3)]])
+{
+  xlatMtlShaderOutput _mtl_o;
+  half4 c_1 = 0;
+  half atten_2 = 0;
+  half4 tmpvar_3 = 0;
+  tmpvar_3 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0.xy));
+  half2 tmpvar_4 = 0;
+  tmpvar_4.x = _mtl_u._Metallic;
+  tmpvar_4.y = _mtl_u._Glossiness;
+  half3 tmpvar_5 = 0;
+  tmpvar_5 = (_mtl_u._Color.xyz * tmpvar_3.xyz);
+  half3 tmpvar_6 = 0;
+  half3 tmpvar_7 = 0;
+  tmpvar_7 = mix (_mtl_u.unity_ColorSpaceDielectricSpec.xyz, tmpvar_5, half3(_mtl_u._Metallic));
+  half tmpvar_8 = 0;
+  tmpvar_8 = (_mtl_u.unity_ColorSpaceDielectricSpec.w - (_mtl_u._Metallic * _mtl_u.unity_ColorSpaceDielectricSpec.w));
+  tmpvar_6 = (tmpvar_5 * tmpvar_8);
+  half3 tmpvar_9 = 0;
+  tmpvar_9 = normalize(_mtl_i.xlv_TEXCOORD2_2.xyz);
+  half3 tmpvar_10 = 0;
+  tmpvar_10 = normalize(_mtl_i.xlv_TEXCOORD1);
+  half3 tmpvar_11 = 0;
+  tmpvar_11 = _mtl_u._LightColor0.xyz;
+  half shadow_12 = 0;
+  half tmpvar_13 = 0;
+  tmpvar_13 = _ShadowMapTexture.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.xlv_TEXCOORD6.xyz).xy, (float)(_mtl_i.xlv_TEXCOORD6.xyz).z);
+  half tmpvar_14 = 0;
+  tmpvar_14 = tmpvar_13;
+  shadow_12 = (_mtl_u._LightShadowData.x + (tmpvar_14 * ((half)(1.0) - _mtl_u._LightShadowData.x)));
+  atten_2 = shadow_12;
+  half occ_15 = 0;
+  half tmpvar_16 = 0;
+  tmpvar_16 = _OcclusionMap.sample(_mtlsmp__OcclusionMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).y;
+  occ_15 = tmpvar_16;
+  half tmpvar_17 = 0;
+  tmpvar_17 = (((half)(1.0) - _mtl_u._OcclusionStrength) + (occ_15 * _mtl_u._OcclusionStrength));
+  FragmentCommonData s_18;
+  s_18 = _xlat_mtl_const1;
+  s_18.oneMinusRoughness = tmpvar_4.y;
+  s_18.normalWorld = tmpvar_9;
+  s_18.eyeVec = tmpvar_10;
+  s_18.posWorld = half3(float3(0.0, 0.0, 0.0));
+  half3 tmpvar_19 = 0;
+  half3 tmpvar_20 = 0;
+  tmpvar_19 = s_18.normalWorld;
+  tmpvar_20 = s_18.eyeVec;
+  float4 tmpvar_21 = 0;
+  tmpvar_21 = float4(_mtl_u.unity_SpecCube0_HDR);
+  half tmpvar_22 = 0;
+  tmpvar_22 = ((half)(1.0) - s_18.oneMinusRoughness);
+  half3 tmpvar_23 = 0;
+  tmpvar_23 = (tmpvar_20 - ((half)(2.0) * (
+    dot (tmpvar_19, tmpvar_20)
+   * tmpvar_19)));
+  half4 tmpvar_24 = 0;
+  tmpvar_24.w = half(1.0);
+  tmpvar_24.xyz = tmpvar_19;
+  half3 x_25 = 0;
+  x_25.x = dot (_mtl_u.unity_SHAr, tmpvar_24);
+  x_25.y = dot (_mtl_u.unity_SHAg, tmpvar_24);
+  x_25.z = dot (_mtl_u.unity_SHAb, tmpvar_24);
+  half4 hdr_26 = 0;
+  hdr_26 = half4(tmpvar_21);
+  half4 tmpvar_27 = 0;
+  tmpvar_27.xyz = tmpvar_23;
+  tmpvar_27.w = ((tmpvar_22 * ((half)(1.7) - 
+    ((half)(0.7) * tmpvar_22)
+  )) * (half)(6.0));
+  half4 tmpvar_28 = 0;
+  tmpvar_28 = unity_SpecCube0.sample(_mtlsmp_unity_SpecCube0, (float3)(tmpvar_23), level(tmpvar_27.w));
+  half4 tmpvar_29 = 0;
+  tmpvar_29 = tmpvar_28;
+  half3 viewDir_30 = 0;
+  viewDir_30 = -(tmpvar_10);
+  half3 tmpvar_31 = 0;
+  half3 inVec_32 = 0;
+  inVec_32 = (_mtl_u._WorldSpaceLightPos0.xyz + viewDir_30);
+  tmpvar_31 = (inVec_32 * rsqrt(max ((half)0.001, 
+    dot (inVec_32, inVec_32)
+  )));
+  half tmpvar_33 = 0;
+  tmpvar_33 = max ((half)0.0, dot (_mtl_u._WorldSpaceLightPos0.xyz, tmpvar_31));
+  half tmpvar_34 = 0;
+  tmpvar_34 = ((half)(1.0) - _mtl_u._Glossiness);
+  half tmpvar_35 = 0;
+  tmpvar_35 = max ((half)0.0001, (tmpvar_34 * tmpvar_34));
+  half tmpvar_36 = 0;
+  tmpvar_36 = max ((((half)(2.0) / 
+    (tmpvar_35 * tmpvar_35)
+  ) - (half)(2.0)), (half)0.0001);
+  half x_37 = 0;
+  x_37 = ((half)(1.0) - max ((half)0.0, dot (tmpvar_9, viewDir_30)));
+  half4 tmpvar_38 = 0;
+  tmpvar_38.w = half(1.0);
+  tmpvar_38.xyz = (((
+    ((tmpvar_6 + (sqrt(
+      max ((half)0.0001, (((tmpvar_36 + (half)(1.0)) * pow (
+        max ((half)0.0, dot (tmpvar_9, tmpvar_31))
+      , tmpvar_36)) / ((
+        ((half)(8.0) * (((tmpvar_33 * tmpvar_33) * _mtl_u._Glossiness) + (tmpvar_34 * tmpvar_34)))
+       * tmpvar_33) + (half)(0.0001))))
+    ) * tmpvar_7)) * (tmpvar_11 * atten_2))
+   * 
+    max ((half)0.0, dot (tmpvar_9, _mtl_u._WorldSpaceLightPos0.xyz))
+  ) + (
+    (max ((((half)(1.055) * 
+      pow (max ((half3)float3(0.0, 0.0, 0.0), (_mtl_i.xlv_TEXCOORD5.xyz + x_25)), (half3)float3(0.4166667, 0.4166667, 0.4166667))
+    ) - (half)(0.055)), (half3)float3(0.0, 0.0, 0.0)) * tmpvar_17)
+   * tmpvar_6)) + ((
+    ((half)(1.0) - ((tmpvar_34 * tmpvar_34) * (tmpvar_34 * (half)(0.28))))
+   * 
+    (((hdr_26.x * tmpvar_29.w) * tmpvar_29.xyz) * tmpvar_17)
+  ) * mix (tmpvar_7, half3(
+    clamp ((_mtl_u._Glossiness + ((half)(1.0) - tmpvar_8)), (half)0.0, (half)1.0)
+  ), half3(
+    ((x_37 * x_37) * (x_37 * x_37))
+  ))));
+  c_1 = (tmpvar_38 * _mtl_i.xlv_COLOR);
+  c_1.xyz = c_1.xyz;
+  c_1.xyz = c_1.xyz;
+  half4 xlat_varoutput_39 = 0;
+  xlat_varoutput_39.xyz = c_1.xyz;
+  xlat_varoutput_39.w = half(1.0);
+  _mtl_o.FragData_0 = xlat_varoutput_39;
+  return _mtl_o;
+}
+
+
+// stats: 97 alu 4 tex 0 flow
+// inputs: 6
+//  #0: xlv_TEXCOORD0 (high float) 4x1 [-1]
+//  #1: xlv_TEXCOORD1 (medium float) 3x1 [-1]
+//  #2: xlv_TEXCOORD2_2 (medium float) 4x1 [-1]
+//  #3: xlv_TEXCOORD5 (medium float) 4x1 [-1]
+//  #4: xlv_TEXCOORD6 (medium float) 4x1 [-1]
+//  #5: xlv_COLOR (low float) 4x1 [-1]
+// uniforms: 12 (total size: 78)
+//  #0: _WorldSpaceLightPos0 (medium float) 4x1 [-1] loc 0
+//  #1: unity_SHAr (medium float) 4x1 [-1] loc 8
+//  #2: unity_SHAg (medium float) 4x1 [-1] loc 16
+//  #3: unity_SHAb (medium float) 4x1 [-1] loc 24
+//  #4: _LightShadowData (medium float) 4x1 [-1] loc 32
+//  #5: unity_SpecCube0_HDR (medium float) 4x1 [-1] loc 40
+//  #6: unity_ColorSpaceDielectricSpec (medium float) 4x1 [-1] loc 48
+//  #7: _LightColor0 (low float) 4x1 [-1] loc 56
+//  #8: _Color (medium float) 4x1 [-1] loc 64
+//  #9: _Metallic (medium float) 1x1 [-1] loc 72
+//  #10: _Glossiness (medium float) 1x1 [-1] loc 74
+//  #11: _OcclusionStrength (medium float) 1x1 [-1] loc 76
+// textures: 4
+//  #0: unity_SpecCube0 (low cube) 0x0 [-1] loc 0
+//  #1: _MainTex (low 2d) 0x0 [-1] loc 1
+//  #2: _OcclusionMap (low 2d) 0x0 [-1] loc 2
+//  #3: _ShadowMapTexture (low 2dshadow) 0x0 [-1] loc 3

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/glsl120-basic-outES3Metal.txt

@@ -12,7 +12,7 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 v_1;
+  half4 v_1 = 0;
   v_1.w = half(-1.0);
   v_1.x = ((half)(1.2 + _mtl_u.nonSqMat[0].x));
   v_1.y = half(6.0);

+ 57 - 57
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/intrinsics-outES3Metal.txt

@@ -12,148 +12,148 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1 = half4(float4(0.0, 0.0, 0.0, 0.0));
-  float tmpvar_2;
+  float tmpvar_2 = 0;
   tmpvar_2 = (_mtl_i.xlv_TEXCOORD0.x / 2.0);
-  float tmpvar_3;
+  float tmpvar_3 = 0;
   tmpvar_3 = (fract(abs(tmpvar_2)) * 2.0);
-  float tmpvar_4;
+  float tmpvar_4 = 0;
   if ((tmpvar_2 >= 0.0)) {
     tmpvar_4 = tmpvar_3;
   } else {
     tmpvar_4 = -(tmpvar_3);
   };
   c_1.x = half(tmpvar_4);
-  float2 tmpvar_5;
+  float2 tmpvar_5 = 0;
   tmpvar_5 = (_mtl_i.xlv_TEXCOORD0.xy / float2(2.0, 2.0));
-  float2 tmpvar_6;
+  float2 tmpvar_6 = 0;
   tmpvar_6 = (fract(abs(tmpvar_5)) * float2(2.0, 2.0));
-  float tmpvar_7;
+  float tmpvar_7 = 0;
   if ((tmpvar_5.x >= 0.0)) {
     tmpvar_7 = tmpvar_6.x;
   } else {
     tmpvar_7 = -(tmpvar_6.x);
   };
-  float tmpvar_8;
+  float tmpvar_8 = 0;
   if ((tmpvar_5.y >= 0.0)) {
     tmpvar_8 = tmpvar_6.y;
   } else {
     tmpvar_8 = -(tmpvar_6.y);
   };
-  float2 tmpvar_9;
+  float2 tmpvar_9 = 0;
   tmpvar_9.x = tmpvar_7;
   tmpvar_9.y = tmpvar_8;
-  c_1.xy = ((half2)((float2)c_1.xy + tmpvar_9));
-  float3 tmpvar_10;
+  c_1.xy = ((half2)((float2)(c_1.xy) + tmpvar_9));
+  float3 tmpvar_10 = 0;
   tmpvar_10 = (_mtl_i.xlv_TEXCOORD0.xyz / float3(2.0, 2.0, 2.0));
-  float3 tmpvar_11;
+  float3 tmpvar_11 = 0;
   tmpvar_11 = (fract(abs(tmpvar_10)) * float3(2.0, 2.0, 2.0));
-  float tmpvar_12;
+  float tmpvar_12 = 0;
   if ((tmpvar_10.x >= 0.0)) {
     tmpvar_12 = tmpvar_11.x;
   } else {
     tmpvar_12 = -(tmpvar_11.x);
   };
-  float tmpvar_13;
+  float tmpvar_13 = 0;
   if ((tmpvar_10.y >= 0.0)) {
     tmpvar_13 = tmpvar_11.y;
   } else {
     tmpvar_13 = -(tmpvar_11.y);
   };
-  float tmpvar_14;
+  float tmpvar_14 = 0;
   if ((tmpvar_10.z >= 0.0)) {
     tmpvar_14 = tmpvar_11.z;
   } else {
     tmpvar_14 = -(tmpvar_11.z);
   };
-  float3 tmpvar_15;
+  float3 tmpvar_15 = 0;
   tmpvar_15.x = tmpvar_12;
   tmpvar_15.y = tmpvar_13;
   tmpvar_15.z = tmpvar_14;
-  c_1.xyz = ((half3)((float3)c_1.xyz + tmpvar_15));
-  float4 tmpvar_16;
+  c_1.xyz = ((half3)((float3)(c_1.xyz) + tmpvar_15));
+  float4 tmpvar_16 = 0;
   tmpvar_16 = (_mtl_i.xlv_TEXCOORD0 / float4(2.0, 2.0, 2.0, 2.0));
-  float4 tmpvar_17;
+  float4 tmpvar_17 = 0;
   tmpvar_17 = (fract(abs(tmpvar_16)) * float4(2.0, 2.0, 2.0, 2.0));
-  float tmpvar_18;
+  float tmpvar_18 = 0;
   if ((tmpvar_16.x >= 0.0)) {
     tmpvar_18 = tmpvar_17.x;
   } else {
     tmpvar_18 = -(tmpvar_17.x);
   };
-  float tmpvar_19;
+  float tmpvar_19 = 0;
   if ((tmpvar_16.y >= 0.0)) {
     tmpvar_19 = tmpvar_17.y;
   } else {
     tmpvar_19 = -(tmpvar_17.y);
   };
-  float tmpvar_20;
+  float tmpvar_20 = 0;
   if ((tmpvar_16.z >= 0.0)) {
     tmpvar_20 = tmpvar_17.z;
   } else {
     tmpvar_20 = -(tmpvar_17.z);
   };
-  float tmpvar_21;
+  float tmpvar_21 = 0;
   if ((tmpvar_16.w >= 0.0)) {
     tmpvar_21 = tmpvar_17.w;
   } else {
     tmpvar_21 = -(tmpvar_17.w);
   };
-  float4 tmpvar_22;
+  float4 tmpvar_22 = 0;
   tmpvar_22.x = tmpvar_18;
   tmpvar_22.y = tmpvar_19;
   tmpvar_22.z = tmpvar_20;
   tmpvar_22.w = tmpvar_21;
-  c_1 = ((half4)((float4)c_1 + tmpvar_22));
-  float tmpvar_23;
-  half ip_24;
-  int tmpvar_25;
+  c_1 = ((half4)((float4)(c_1) + tmpvar_22));
+  float tmpvar_23 = 0;
+  half ip_24 = 0;
+  int tmpvar_25 = 0;
   tmpvar_25 = int(_mtl_i.xlv_TEXCOORD0.x);
   ip_24 = half(float(tmpvar_25));
-  tmpvar_23 = (_mtl_i.xlv_TEXCOORD0.x - (float)ip_24);
-  c_1.x = ((half)((float)c_1.x + tmpvar_23));
-  float2 tmpvar_26;
-  int2 tmpvar_27;
+  tmpvar_23 = (_mtl_i.xlv_TEXCOORD0.x - (float)(ip_24));
+  c_1.x = ((half)((float)(c_1.x) + tmpvar_23));
+  float2 tmpvar_26 = 0;
+  int2 tmpvar_27 = 0;
   tmpvar_27 = int2(_mtl_i.xlv_TEXCOORD0.xy);
-  half2 tmpvar_28;
+  half2 tmpvar_28 = 0;
   tmpvar_28 = half2(float2(tmpvar_27));
-  tmpvar_26 = (_mtl_i.xlv_TEXCOORD0.xy - (float2)tmpvar_28);
-  c_1.xy = ((half2)((float2)c_1.xy + tmpvar_26));
-  float3 tmpvar_29;
-  int3 tmpvar_30;
+  tmpvar_26 = (_mtl_i.xlv_TEXCOORD0.xy - (float2)(tmpvar_28));
+  c_1.xy = ((half2)((float2)(c_1.xy) + tmpvar_26));
+  float3 tmpvar_29 = 0;
+  int3 tmpvar_30 = 0;
   tmpvar_30 = int3(_mtl_i.xlv_TEXCOORD0.xyz);
-  half3 tmpvar_31;
+  half3 tmpvar_31 = 0;
   tmpvar_31 = half3(float3(tmpvar_30));
-  tmpvar_29 = (_mtl_i.xlv_TEXCOORD0.xyz - (float3)tmpvar_31);
-  c_1.xyz = ((half3)((float3)c_1.xyz + tmpvar_29));
-  float4 tmpvar_32;
-  int4 tmpvar_33;
+  tmpvar_29 = (_mtl_i.xlv_TEXCOORD0.xyz - (float3)(tmpvar_31));
+  c_1.xyz = ((half3)((float3)(c_1.xyz) + tmpvar_29));
+  float4 tmpvar_32 = 0;
+  int4 tmpvar_33 = 0;
   tmpvar_33 = int4(_mtl_i.xlv_TEXCOORD0);
-  half4 tmpvar_34;
+  half4 tmpvar_34 = 0;
   tmpvar_34 = half4(float4(tmpvar_33));
-  tmpvar_32 = (_mtl_i.xlv_TEXCOORD0 - (float4)tmpvar_34);
-  c_1 = ((half4)((float4)c_1 + tmpvar_32));
-  float tmpvar_35;
+  tmpvar_32 = (_mtl_i.xlv_TEXCOORD0 - (float4)(tmpvar_34));
+  c_1 = ((half4)((float4)(c_1) + tmpvar_32));
+  float tmpvar_35 = 0;
   tmpvar_35 = (float(fmod (_mtl_i.xlv_TEXCOORD0.x, (float)tmpvar_34.x)));
-  c_1.x = half(((float)c_1.x + tmpvar_35));
-  float2 tmpvar_36;
+  c_1.x = half(((float)(c_1.x) + tmpvar_35));
+  float2 tmpvar_36 = 0;
   tmpvar_36 = (float2(fmod (_mtl_i.xlv_TEXCOORD0.xy, (float2)tmpvar_34.xy)));
-  c_1.xy = half2(((float2)c_1.xy + tmpvar_36));
-  float3 tmpvar_37;
+  c_1.xy = half2(((float2)(c_1.xy) + tmpvar_36));
+  float3 tmpvar_37 = 0;
   tmpvar_37 = (float3(fmod (_mtl_i.xlv_TEXCOORD0.xyz, (float3)tmpvar_34.xyz)));
-  c_1.xyz = half3(((float3)c_1.xyz + tmpvar_37));
-  float tmpvar_38;
+  c_1.xyz = half3(((float3)(c_1.xyz) + tmpvar_37));
+  float tmpvar_38 = 0;
   tmpvar_38 = (1.0/(_mtl_i.xlv_TEXCOORD0.x));
-  c_1.x = half(((float)c_1.x + tmpvar_38));
-  float tmpvar_39;
+  c_1.x = half(((float)(c_1.x) + tmpvar_38));
+  float tmpvar_39 = 0;
   tmpvar_39 = max (0.0, tmpvar_38);
-  c_1.x = half(((float)c_1.x + tmpvar_39));
+  c_1.x = half(((float)(c_1.x) + tmpvar_39));
   c_1.y = (c_1.y + ((half)1.0/(c_1.z)));
   c_1.y = (c_1.y + max ((half)0.0, ((half)1.0/(c_1.w))));
-  float tmpvar_40;
+  float tmpvar_40 = 0;
   tmpvar_40 = max (_mtl_i.xlv_TEXCOORD0.x, (float)c_1.z);
-  c_1.x = half(((float)c_1.x + tmpvar_40));
+  c_1.x = half(((float)(c_1.x) + tmpvar_40));
   _mtl_o._fragData = c_1;
   return _mtl_o;
 }

+ 4 - 4
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/loop-for-outES3Metal.txt

@@ -15,14 +15,14 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(0)]], sampler _mtlsmp__MainTex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  half3 light_2;
-  half4 col_3;
+  half4 tmpvar_1 = 0;
+  half3 light_2 = 0;
+  half4 col_3 = 0;
   col_3 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_uv));
   light_2 = ((col_3.xyz * _mtl_i.xlv_nl.x) * _mtl_u._TerrainTreeLightColors[0].xyz);
   light_2 = (light_2 + ((col_3.xyz * _mtl_i.xlv_nl.y) * _mtl_u._TerrainTreeLightColors[1].xyz));
   light_2 = (light_2 + ((col_3.xyz * _mtl_i.xlv_nl.z) * _mtl_u._TerrainTreeLightColors[2].xyz));
-  half4 tmpvar_4;
+  half4 tmpvar_4 = 0;
   tmpvar_4.w = half(1.0);
   tmpvar_4.xyz = light_2;
   tmpvar_1 = tmpvar_4;

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/loop-forafterdiscard-outES3Metal.txt

@@ -15,17 +15,17 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(0)]], sampler _mtlsmp__MainTex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  half3 light_2;
-  half4 tmpvar_3;
+  half4 tmpvar_1 = 0;
+  half3 light_2 = 0;
+  half4 tmpvar_3 = 0;
   tmpvar_3 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_uv));
-  if ((tmpvar_3.w < (half)0.5)) {
+  if ((tmpvar_3.w < (half)(0.5))) {
     discard_fragment();
   };
   light_2 = ((tmpvar_3.xyz * _mtl_i.xlv_nl.x) * _mtl_u._TerrainTreeLightColors[0].xyz);
   light_2 = (light_2 + ((tmpvar_3.xyz * _mtl_i.xlv_nl.y) * _mtl_u._TerrainTreeLightColors[1].xyz));
   light_2 = (light_2 + ((tmpvar_3.xyz * _mtl_i.xlv_nl.z) * _mtl_u._TerrainTreeLightColors[2].xyz));
-  half4 tmpvar_4;
+  half4 tmpvar_4 = 0;
   tmpvar_4.w = half(1.0);
   tmpvar_4.xyz = light_2;
   tmpvar_1 = tmpvar_4;

+ 19 - 19
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/matrix-cast-types-outES3Metal.txt

@@ -23,18 +23,18 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _DecalNorm [[texture(1)]], sampler _mtlsmp__DecalNorm [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 res_1;
-  half3 worldN_2;
-  half3 combinedNormal_3;
-  half3 tmpvar_4;
-  tmpvar_4 = ((_DecalNorm.sample(_mtlsmp__DecalNorm, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).xyz * (half)2.0) - (half)1.0);
-  half3 tmpvar_5;
-  tmpvar_5 = ((_PanelNorm.sample(_mtlsmp__PanelNorm, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz * (half)2.0) - (half)1.0);
-  half3 tmpvar_6;
+  half4 res_1 = 0;
+  half3 worldN_2 = 0;
+  half3 combinedNormal_3 = 0;
+  half3 tmpvar_4 = 0;
+  tmpvar_4 = ((_DecalNorm.sample(_mtlsmp__DecalNorm, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).xyz * (half)(2.0)) - (half)(1.0));
+  half3 tmpvar_5 = 0;
+  tmpvar_5 = ((_PanelNorm.sample(_mtlsmp__PanelNorm, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz * (half)(2.0)) - (half)(1.0));
+  half3 tmpvar_6 = 0;
   tmpvar_6.x = tmpvar_4.z;
   tmpvar_6.y = tmpvar_4.y;
   tmpvar_6.z = -(tmpvar_4.x);
-  half3 tmpvar_7;
+  half3 tmpvar_7 = 0;
   tmpvar_7.x = tmpvar_4.x;
   tmpvar_7.y = tmpvar_4.z;
   tmpvar_7.z = -(tmpvar_4.y);
@@ -50,33 +50,33 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   tmpvar_9[2].y = tmpvar_7.z;
   tmpvar_9[2].z = tmpvar_4.z;
   tmpvar_8 = _xlcast_float3x3(tmpvar_9);
-  float3 v_10;
+  float3 v_10 = 0;
   v_10.x = tmpvar_8[0].x;
   v_10.y = tmpvar_8[1].x;
   v_10.z = tmpvar_8[2].x;
-  float3 v_11;
+  float3 v_11 = 0;
   v_11.x = tmpvar_8[0].y;
   v_11.y = tmpvar_8[1].y;
   v_11.z = tmpvar_8[2].y;
-  float3 v_12;
+  float3 v_12 = 0;
   v_12.x = tmpvar_8[0].z;
   v_12.y = tmpvar_8[1].z;
   v_12.z = tmpvar_8[2].z;
   combinedNormal_3 = normalize(((
-    ((half3)((float)tmpvar_5.x * v_10))
+    ((half3)((float)(tmpvar_5.x) * v_10))
    + 
-    ((half3)((float)tmpvar_5.y * v_11))
-  ) + ((half3)((float)tmpvar_5.z * v_12))));
-  float tmpvar_13;
+    ((half3)((float)(tmpvar_5.y) * v_11))
+  ) + ((half3)((float)(tmpvar_5.z) * v_12))));
+  float tmpvar_13 = 0;
   tmpvar_13 = dot (_mtl_i.xlv_TEXCOORD1.xyz, (float3)combinedNormal_3);
   worldN_2.x = half(tmpvar_13);
-  float tmpvar_14;
+  float tmpvar_14 = 0;
   tmpvar_14 = dot (_mtl_i.xlv_TEXCOORD2.xyz, (float3)combinedNormal_3);
   worldN_2.y = half(tmpvar_14);
-  float tmpvar_15;
+  float tmpvar_15 = 0;
   tmpvar_15 = dot (_mtl_i.xlv_TEXCOORD3.xyz, (float3)combinedNormal_3);
   worldN_2.z = half(tmpvar_15);
-  res_1.xyz = ((worldN_2 * (half)0.5) + (half)0.5);
+  res_1.xyz = ((worldN_2 * (half)(0.5)) + (half)(0.5));
   res_1.w = half(0.0);
   _mtl_o._fragData = res_1;
   return _mtl_o;

+ 6 - 6
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/matrix-ops-outES3Metal.txt

@@ -28,11 +28,11 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   xlatMtlShaderOutput _mtl_o;
   half2x2 halfMatrix_1;
   float2x2 rotationMatrix_2;
-  float tmpvar_3;
-  float tmpvar_4;
+  float tmpvar_3 = 0;
+  float tmpvar_4 = 0;
   tmpvar_4 = (_mtl_u._Speed * _mtl_u._Time.x);
   tmpvar_3 = sin(tmpvar_4);
-  float tmpvar_5;
+  float tmpvar_5 = 0;
   tmpvar_5 = cos(tmpvar_4);
   float2x2 tmpvar_6;
   tmpvar_6[0].x = tmpvar_5;
@@ -50,14 +50,14 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   tmpvar_7[1].x = -(tmpvar_3);
   tmpvar_7[1].y = tmpvar_5;
   halfMatrix_1 = _xlcast_half2x2(tmpvar_7);
-  halfMatrix_1 = (halfMatrix_1 * (half)2.0);
+  halfMatrix_1 = (halfMatrix_1 * (half)(2.0));
   halfMatrix_1 = (halfMatrix_1 - _xlinit_half2x2(1.0));
   halfMatrix_1 = _xlcast_half2x2(((float2x2)(_xlinit_half2x2(tmpvar_3) - halfMatrix_1)));
   halfMatrix_1 = _xlcast_half2x2(((float2x2)(_xlinit_half2x2(tmpvar_5) + halfMatrix_1)));
   halfMatrix_1 = _xlcast_half2x2(((float2x2)(halfMatrix_1 * (1.0h/half(tmpvar_3)))));
-  float4 tmpvar_8;
+  float4 tmpvar_8 = 0;
   tmpvar_8.xy = (rotationMatrix_2 * _mtl_i.uv);
-  tmpvar_8.zw = ((float2)(halfMatrix_1 * (half2)_mtl_i.uv));
+  tmpvar_8.zw = ((float2)(halfMatrix_1 * (half2)(_mtl_i.uv)));
   _mtl_o._fragData = half4(tmpvar_8);
   return _mtl_o;
 }

+ 3 - 3
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/mrt-unused-outES3Metal.txt

@@ -13,9 +13,9 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  float4 tmpvar_2;
-  tmpvar_2 = ((float4)_mtl_i.xlv_COLOR0 * _mtl_u._Color);
+  half4 c_1 = 0;
+  float4 tmpvar_2 = 0;
+  tmpvar_2 = ((float4)(_mtl_i.xlv_COLOR0) * _mtl_u._Color);
   c_1 = half4(tmpvar_2);
   _mtl_o._glesFragData_0 = c_1;
   return _mtl_o;

+ 3 - 3
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/opt-grafting-precision-outES3Metal.txt

@@ -14,10 +14,10 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half tmpvar_2;
+  half4 c_1 = 0;
+  half tmpvar_2 = 0;
   tmpvar_2 = dot (_mtl_i.normal, _mtl_i.halfDir);
-  half4 tmpvar_3;
+  half4 tmpvar_3 = 0;
   tmpvar_3 = half4(pow (tmpvar_2, _mtl_u.specPower));
   c_1 = tmpvar_3;
   _mtl_o._fragData = c_1;

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/prec-expressions-outES3Metal.txt

@@ -13,13 +13,13 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 r_1;
-  half3 lightCoord_2;
-  float4 tmpvar_3;
+  half4 r_1 = 0;
+  half3 lightCoord_2 = 0;
+  float4 tmpvar_3 = 0;
   tmpvar_3.w = 1.0;
   tmpvar_3.xyz = _mtl_u._WorldPos;
-  float3 tmpvar_4;
-  tmpvar_4 = ((float4)(_mtl_u._LightMatrix * (half4)tmpvar_3)).xyz;
+  float3 tmpvar_4 = 0;
+  tmpvar_4 = ((float4)(_mtl_u._LightMatrix * (half4)(tmpvar_3))).xyz;
   lightCoord_2 = half3(tmpvar_4);
   r_1.xyz = lightCoord_2;
   r_1.w = half(1.0);

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/prec-matrix-constr-outES3Metal.txt

@@ -12,7 +12,7 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   half3x3 tmpvar_2;
   tmpvar_2[0].x = half(0.8164966);
   tmpvar_2[0].y = half(-0.4082483);

+ 7 - 7
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/sampler-precision-outES3Metal.txt

@@ -18,21 +18,21 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texturecube<float> cubehigh [[texture(5)]], sampler _mtlsmp_cubehigh [[sampler(5)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half4 tmpvar_2;
+  half4 c_1 = 0;
+  half4 tmpvar_2 = 0;
   tmpvar_2 = texlow.sample(_mtlsmp_texlow, (float2)(_mtl_i.varUV.xy));
   c_1 = tmpvar_2;
   c_1 = (c_1 + texmed.sample(_mtlsmp_texmed, (float2)(_mtl_i.varUV.xy)));
-  float4 tmpvar_3;
+  float4 tmpvar_3 = 0;
   tmpvar_3 = texhigh.sample(_mtlsmp_texhigh, (float2)(_mtl_i.varUV.xy));
-  c_1 = half4(((float4)c_1 + tmpvar_3));
-  half4 tmpvar_4;
+  c_1 = half4(((float4)(c_1) + tmpvar_3));
+  half4 tmpvar_4 = 0;
   tmpvar_4 = cubelow.sample(_mtlsmp_cubelow, (float3)(_mtl_i.varUV.xyz));
   c_1 = (c_1 + tmpvar_4);
   c_1 = (c_1 + cubemed.sample(_mtlsmp_cubemed, (float3)(_mtl_i.varUV.xyz)));
-  float4 tmpvar_5;
+  float4 tmpvar_5 = 0;
   tmpvar_5 = cubehigh.sample(_mtlsmp_cubehigh, (float3)(_mtl_i.varUV.xyz));
-  c_1 = half4(((float4)c_1 + tmpvar_5));
+  c_1 = half4(((float4)(c_1) + tmpvar_5));
   _mtl_o._fragData = c_1;
   return _mtl_o;
 }

+ 10 - 10
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ternary-outES3Metal.txt

@@ -12,45 +12,45 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1 = half4(float4(0.0, 0.0, 0.0, 0.0));
-  float tmpvar_2;
+  float tmpvar_2 = 0;
   if ((_mtl_i.xlv_TEXCOORD0.x > 0.5)) {
     tmpvar_2 = 0.9;
   } else {
     tmpvar_2 = 0.1;
   };
   c_1 = half4(float4(tmpvar_2));
-  float4 tmpvar_3;
+  float4 tmpvar_3 = 0;
   if ((_mtl_i.xlv_TEXCOORD0.x > 0.5)) {
     tmpvar_3 = float4(0.9, 0.9, 0.9, 0.9);
   } else {
     tmpvar_3 = float4(0.1, 0.1, 0.1, 0.1);
   };
   c_1 = ((half4)(float4(tmpvar_2) + tmpvar_3));
-  float3 tmpvar_4;
+  float3 tmpvar_4 = 0;
   if ((_mtl_i.xlv_TEXCOORD0.x > 0.5)) {
     tmpvar_4 = float3(0.9, 0.9, 0.9);
   } else {
     tmpvar_4 = float3(0.1, 0.1, 0.1);
   };
-  c_1.xyz = (c_1.xyz + (half3)tmpvar_4);
-  float2 tmpvar_5;
+  c_1.xyz = (c_1.xyz + (half3)(tmpvar_4));
+  float2 tmpvar_5 = 0;
   if ((_mtl_i.xlv_TEXCOORD0.x > 0.5)) {
     tmpvar_5 = float2(0.9, 0.9);
   } else {
     tmpvar_5 = float2(0.1, 0.1);
   };
-  c_1.xy = (c_1.xy + (half2)tmpvar_5);
-  float tmpvar_6;
+  c_1.xy = (c_1.xy + (half2)(tmpvar_5));
+  float tmpvar_6 = 0;
   tmpvar_6 = fract(_mtl_i.xlv_TEXCOORD0.x);
-  float tmpvar_7;
+  float tmpvar_7 = 0;
   if (bool(tmpvar_6)) {
     tmpvar_7 = 0.9;
   } else {
     tmpvar_7 = 0.1;
   };
-  c_1.x = (c_1.x + (half)tmpvar_7);
+  c_1.x = (c_1.x + (half)(tmpvar_7));
   _mtl_o._fragData = c_1;
   return _mtl_o;
 }

+ 32 - 32
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/ternary-vec4-outES3Metal.txt

@@ -12,164 +12,164 @@ struct xlatMtlShaderUniform {
 fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  float4 a_2;
+  half4 tmpvar_1 = 0;
+  float4 a_2 = 0;
   a_2 = float4(0.0, 0.0, 0.0, 0.0);
-  bool4 tmpvar_3;
+  bool4 tmpvar_3 = false;
   tmpvar_3 = bool4((_mtl_i.xlv_TEXCOORD0 > float4(0.5, 0.5, 0.5, 0.5)));
-  float tmpvar_4;
+  float tmpvar_4 = 0;
   if (tmpvar_3.x) {
     tmpvar_4 = 1.0;
   } else {
     tmpvar_4 = 5.0;
   };
-  float tmpvar_5;
+  float tmpvar_5 = 0;
   if (tmpvar_3.y) {
     tmpvar_5 = 2.0;
   } else {
     tmpvar_5 = 6.0;
   };
-  float tmpvar_6;
+  float tmpvar_6 = 0;
   if (tmpvar_3.z) {
     tmpvar_6 = 3.0;
   } else {
     tmpvar_6 = 7.0;
   };
-  float tmpvar_7;
+  float tmpvar_7 = 0;
   if (tmpvar_3.w) {
     tmpvar_7 = 4.0;
   } else {
     tmpvar_7 = 8.0;
   };
-  float4 tmpvar_8;
+  float4 tmpvar_8 = 0;
   tmpvar_8.x = tmpvar_4;
   tmpvar_8.y = tmpvar_5;
   tmpvar_8.z = tmpvar_6;
   tmpvar_8.w = tmpvar_7;
   a_2 = tmpvar_8;
-  bool4 tmpvar_9;
+  bool4 tmpvar_9 = false;
   tmpvar_9 = bool4((_mtl_i.xlv_TEXCOORD0 > float4(0.5, 0.5, 0.5, 0.5)));
-  float tmpvar_10;
+  float tmpvar_10 = 0;
   if (tmpvar_9.x) {
     tmpvar_10 = 1.0;
   } else {
     tmpvar_10 = 5.0;
   };
-  float tmpvar_11;
+  float tmpvar_11 = 0;
   if (tmpvar_9.y) {
     tmpvar_11 = 2.0;
   } else {
     tmpvar_11 = 6.0;
   };
-  float tmpvar_12;
+  float tmpvar_12 = 0;
   if (tmpvar_9.z) {
     tmpvar_12 = 3.0;
   } else {
     tmpvar_12 = 7.0;
   };
-  float tmpvar_13;
+  float tmpvar_13 = 0;
   if (tmpvar_9.w) {
     tmpvar_13 = 4.0;
   } else {
     tmpvar_13 = 8.0;
   };
-  float4 tmpvar_14;
+  float4 tmpvar_14 = 0;
   tmpvar_14.x = tmpvar_10;
   tmpvar_14.y = tmpvar_11;
   tmpvar_14.z = tmpvar_12;
   tmpvar_14.w = tmpvar_13;
   a_2 = (tmpvar_8 + tmpvar_14);
-  bool4 tmpvar_15;
+  bool4 tmpvar_15 = false;
   tmpvar_15 = bool4((_mtl_i.xlv_TEXCOORD0 > float4(0.5, 0.5, 0.5, 0.5)));
-  float tmpvar_16;
+  float tmpvar_16 = 0;
   if (tmpvar_15.x) {
     tmpvar_16 = 1.0;
   } else {
     tmpvar_16 = 2.0;
   };
-  float tmpvar_17;
+  float tmpvar_17 = 0;
   if (tmpvar_15.y) {
     tmpvar_17 = 1.0;
   } else {
     tmpvar_17 = 2.0;
   };
-  float tmpvar_18;
+  float tmpvar_18 = 0;
   if (tmpvar_15.z) {
     tmpvar_18 = 1.0;
   } else {
     tmpvar_18 = 2.0;
   };
-  float tmpvar_19;
+  float tmpvar_19 = 0;
   if (tmpvar_15.w) {
     tmpvar_19 = 1.0;
   } else {
     tmpvar_19 = 2.0;
   };
-  float4 tmpvar_20;
+  float4 tmpvar_20 = 0;
   tmpvar_20.x = tmpvar_16;
   tmpvar_20.y = tmpvar_17;
   tmpvar_20.z = tmpvar_18;
   tmpvar_20.w = tmpvar_19;
   a_2 = (a_2 + tmpvar_20);
-  bool4 tmpvar_21;
+  bool4 tmpvar_21 = false;
   tmpvar_21 = bool4((_mtl_i.xlv_TEXCOORD0 > float4(0.5, 0.5, 0.5, 0.5)));
-  float tmpvar_22;
+  float tmpvar_22 = 0;
   if (tmpvar_21.x) {
     tmpvar_22 = 1.0;
   } else {
     tmpvar_22 = 2.0;
   };
-  float tmpvar_23;
+  float tmpvar_23 = 0;
   if (tmpvar_21.y) {
     tmpvar_23 = 1.0;
   } else {
     tmpvar_23 = 2.0;
   };
-  float tmpvar_24;
+  float tmpvar_24 = 0;
   if (tmpvar_21.z) {
     tmpvar_24 = 1.0;
   } else {
     tmpvar_24 = 2.0;
   };
-  float tmpvar_25;
+  float tmpvar_25 = 0;
   if (tmpvar_21.w) {
     tmpvar_25 = 1.0;
   } else {
     tmpvar_25 = 2.0;
   };
-  float4 tmpvar_26;
+  float4 tmpvar_26 = 0;
   tmpvar_26.x = tmpvar_22;
   tmpvar_26.y = tmpvar_23;
   tmpvar_26.z = tmpvar_24;
   tmpvar_26.w = tmpvar_25;
   a_2 = (a_2 + tmpvar_26);
-  bool4 tmpvar_27;
+  bool4 tmpvar_27 = false;
   tmpvar_27 = bool4(fract(_mtl_i.xlv_TEXCOORD0));
-  float tmpvar_28;
+  float tmpvar_28 = 0;
   if (tmpvar_27.x) {
     tmpvar_28 = 1.0;
   } else {
     tmpvar_28 = 2.0;
   };
-  float tmpvar_29;
+  float tmpvar_29 = 0;
   if (tmpvar_27.y) {
     tmpvar_29 = 1.0;
   } else {
     tmpvar_29 = 2.0;
   };
-  float tmpvar_30;
+  float tmpvar_30 = 0;
   if (tmpvar_27.z) {
     tmpvar_30 = 1.0;
   } else {
     tmpvar_30 = 2.0;
   };
-  float tmpvar_31;
+  float tmpvar_31 = 0;
   if (tmpvar_27.w) {
     tmpvar_31 = 1.0;
   } else {
     tmpvar_31 = 2.0;
   };
-  float4 tmpvar_32;
+  float4 tmpvar_32 = 0;
   tmpvar_32.x = tmpvar_28;
   tmpvar_32.y = tmpvar_29;
   tmpvar_32.z = tmpvar_30;

+ 9 - 9
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2DArray-outES3Metal.txt

@@ -13,21 +13,21 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d_array<half> myarr [[texture(0)]], sampler _mtlsmp_myarr [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  float4 slod_2;
-  half4 tmpvar_3;
+  half4 tmpvar_1 = 0;
+  float4 slod_2 = 0;
+  half4 tmpvar_3 = 0;
   tmpvar_3 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyz).xy), (uint)((_mtl_i.uv.xyz).z));
-  float4 tmpvar_4;
+  float4 tmpvar_4 = 0;
   tmpvar_4 = float4(tmpvar_3);
-  half4 tmpvar_5;
+  half4 tmpvar_5 = 0;
   tmpvar_5 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyw).xy), (uint)((_mtl_i.uv.xyw).z));
-  float4 tmpvar_6;
+  float4 tmpvar_6 = 0;
   tmpvar_6 = float4(tmpvar_5);
-  half4 tmpvar_7;
+  half4 tmpvar_7 = 0;
   tmpvar_7 = myarr.sample(_mtlsmp_myarr, (float2)((_mtl_i.uv.xyz).xy), (uint)((_mtl_i.uv.xyz).z), bias(1.5));
-  float4 tmpvar_8;
+  float4 tmpvar_8 = 0;
   tmpvar_8 = float4(tmpvar_7);
-  half4 tmpvar_9;
+  half4 tmpvar_9 = 0;
   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)));

+ 4 - 4
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dgrad-outES3Metal.txt

@@ -15,13 +15,13 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> tex [[texture(0)]], sampler _mtlsmp_tex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half2 tmpvar_1;
+  half2 tmpvar_1 = 0;
   tmpvar_1 = dfdx(_mtl_i.uv1.xy);
-  half2 tmpvar_2;
+  half2 tmpvar_2 = 0;
   tmpvar_2 = dfdy(_mtl_i.uv1.xy);
-  float2 tmpvar_3;
+  float2 tmpvar_3 = 0;
   tmpvar_3 = dfdx(_mtl_i.uv2.xy);
-  float2 tmpvar_4;
+  float2 tmpvar_4 = 0;
   tmpvar_4 = dfdy(_mtl_i.uv2.xy);
   _mtl_o._fragColor = ((tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uv1.xy), gradient2d((float2)(tmpvar_1), (float2)(tmpvar_2))) + tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uv2.xy), gradient2d((float2)(tmpvar_3), (float2)(tmpvar_4)))) + tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uv2.xy), gradient2d((float2)(_mtl_i.uv1.xy), (float2)(_mtl_i.uv1.xy))));
   return _mtl_o;

+ 3 - 3
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dlod-outES3Metal.txt

@@ -15,11 +15,11 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> tex [[texture(0)]], sampler _mtlsmp_tex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  half4 tmpvar_2;
+  half4 tmpvar_1 = 0;
+  half4 tmpvar_2 = 0;
   tmpvar_2 = tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uvHi.xy), level(0.0));
   tmpvar_1 = tmpvar_2;
-  half4 tmpvar_3;
+  half4 tmpvar_3 = 0;
   tmpvar_3 = tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uvMed.xy), level(_mtl_i.uvMed.z));
   _mtl_o._fragColor = (tmpvar_1 + tmpvar_3);
   return _mtl_o;

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/tex2dshadow-outES3Metal.txt

@@ -1,7 +1,7 @@
 #include <metal_stdlib>
 #pragma clang diagnostic ignored "-Wparentheses-equality"
 using namespace metal;
-constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less);
+constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less_equal);
 struct xlatMtlShaderInput {
   float4 uvHi;
   half4 uvMed;
@@ -16,11 +16,11 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   depth2d<float> shadowmap [[texture(0)]], sampler _mtlsmp_shadowmap [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 r_1;
-  half4 tmpvar_2;
-  tmpvar_2 = half4((shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvHi.xyz).xy, (float)(_mtl_i.uvHi.xyz).z) + shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvHi).xy / (float)(_mtl_i.uvHi).w, (float)(_mtl_i.uvHi).z / (float)(_mtl_i.uvHi).w)));
+  half4 r_1 = 0;
+  half4 tmpvar_2 = 0;
+  tmpvar_2 = half4((shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvHi.xyz).xy, saturate((float)(_mtl_i.uvHi.xyz).z)) + shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvHi).xy / (float)(_mtl_i.uvHi).w, saturate((float)(_mtl_i.uvHi).z / (float)(_mtl_i.uvHi).w))));
   r_1.yzw = tmpvar_2.yzw;
-  r_1.x = (tmpvar_2.x + shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvMed.xyz).xy, (float)(_mtl_i.uvMed.xyz).z));
+  r_1.x = (tmpvar_2.x + shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uvMed.xyz).xy, saturate((float)(_mtl_i.uvMed.xyz).z)));
   _mtl_o._fragColor = r_1;
   return _mtl_o;
 }

+ 2 - 2
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texCubeShadow-outES3Metal.txt

@@ -1,7 +1,7 @@
 #include <metal_stdlib>
 #pragma clang diagnostic ignored "-Wparentheses-equality"
 using namespace metal;
-constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less);
+constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less_equal);
 struct xlatMtlShaderInput {
   half4 uv;
 };
@@ -15,7 +15,7 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   depthcube<float> shadowmap [[texture(0)]], sampler _mtlsmp_shadowmap [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
+  half4 tmpvar_1 = 0;
   tmpvar_1 = half4(shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float3)(_mtl_i.uv).xyz, (_mtl_i.uv).w));
   _mtl_o._fragColor = tmpvar_1;
   return _mtl_o;

+ 1 - 1
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texOffset-outES3Metal.txt

@@ -14,7 +14,7 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture3d<half> vol [[texture(1)]], sampler _mtlsmp_vol [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1 = (tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uv.xy)) + tex.sample(_mtlsmp_tex, (float2)(_mtl_i.uv.xy), bias(0.5)));
   c_1 = (c_1 + vol.sample(_mtlsmp_vol, (float3)(_mtl_i.uv)));
   c_1 = (c_1 + vol.sample(_mtlsmp_vol, (float3)(_mtl_i.uv), bias(-0.5)));

+ 4 - 4
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/texProj-outES3Metal.txt

@@ -1,7 +1,7 @@
 #include <metal_stdlib>
 #pragma clang diagnostic ignored "-Wparentheses-equality"
 using namespace metal;
-constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less);
+constexpr sampler _mtl_xl_shadow_sampler(address::clamp_to_edge, filter::linear, compare_func::less_equal);
 struct xlatMtlShaderInput {
   float4 uv;
 };
@@ -15,12 +15,12 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   depth2d<float> shadowmap [[texture(1)]], sampler _mtlsmp_shadowmap [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
+  half4 c_1 = 0;
   c_1 = (tex.sample(_mtlsmp_tex, ((float2)(_mtl_i.uv).xy / (float)(_mtl_i.uv).w)) + tex.sample(_mtlsmp_tex, ((float2)(_mtl_i.uv.xyz).xy / (float)(_mtl_i.uv.xyz).z)));
   c_1 = (c_1 + tex.sample(_mtlsmp_tex, ((float2)(_mtl_i.uv).xy / (float)(_mtl_i.uv).w), level(1.0)));
   c_1 = (c_1 + tex.sample(_mtlsmp_tex, ((float2)(_mtl_i.uv.xyz).xy / (float)(_mtl_i.uv.xyz).z), level(1.0)));
-  c_1 = (c_1 + half4(shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uv.xyz).xy, (float)(_mtl_i.uv.xyz).z)));
-  c_1 = (c_1 + half4(shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uv).xy / (float)(_mtl_i.uv).w, (float)(_mtl_i.uv).z / (float)(_mtl_i.uv).w)));
+  c_1 = (c_1 + half4(shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uv.xyz).xy, saturate((float)(_mtl_i.uv.xyz).z))));
+  c_1 = (c_1 + half4(shadowmap.sample_compare(_mtl_xl_shadow_sampler, (float2)(_mtl_i.uv).xy / (float)(_mtl_i.uv).w, saturate((float)(_mtl_i.uv).z / (float)(_mtl_i.uv).w))));
   _mtl_o._fragData = c_1;
   return _mtl_o;
 }

+ 44 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-inES3.txt

@@ -0,0 +1,44 @@
+#version 300 es
+#define gl_FragData _glesFragData
+layout(location = 0) out mediump vec4 _glesFragData[1];
+
+uniform sampler2D _MainTex;
+
+struct u2v {
+	vec4 pos;
+	vec2 uv;
+};
+
+struct v2f {
+	vec4 pos;
+	vec2 uv;
+};
+
+v2f vert (u2v v) {
+	v2f o;
+	o.pos = v.pos;
+	o.uv = v.uv;
+	return o;
+}
+
+vec4 frag (in v2f i) {
+	vec4 foo;
+	bool bar;
+	mat4 mat;
+	vec4 leet = vec4(0.5);
+	vec4 col = texture(_MainTex, i.uv);
+	col += bar ? foo : leet;
+	col += mat[0];
+	return col;
+}
+
+in mediump vec2 xlv_TEXCOORD0;
+void main() {
+    mediump vec4 xl_retval;
+    v2f xlt_i;
+    xlt_i.pos = vec4(0.0);
+    xlt_i.uv = vec2(xlv_TEXCOORD0);
+    xl_retval = frag(xlt_i);
+    gl_FragData[0] = vec4(xl_retval);
+}
+

+ 32 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-outES3.txt

@@ -0,0 +1,32 @@
+#version 300 es
+layout(location=0) out mediump vec4 _glesFragData[1];
+uniform sampler2D _MainTex;
+in mediump vec2 xlv_TEXCOORD0;
+void main ()
+{
+  mediump vec4 xl_retval_1;
+  lowp vec4 col_2;
+  highp vec4 mat_0_3;
+  bool bar_4;
+  highp vec4 foo_5;
+  lowp vec4 tmpvar_6;
+  tmpvar_6 = texture (_MainTex, xlv_TEXCOORD0);
+  col_2 = tmpvar_6;
+  highp vec4 tmpvar_7;
+  if (bar_4) {
+    tmpvar_7 = foo_5;
+  } else {
+    tmpvar_7 = vec4(0.5, 0.5, 0.5, 0.5);
+  };
+  col_2 = (tmpvar_6 + tmpvar_7);
+  col_2 = (col_2 + mat_0_3);
+  xl_retval_1 = col_2;
+  _glesFragData[0] = xl_retval_1;
+}
+
+
+// stats: 3 alu 1 tex 1 flow
+// inputs: 1
+//  #0: xlv_TEXCOORD0 (medium float) 2x1 [-1]
+// textures: 1
+//  #0: _MainTex (low 2d) 0x0 [-1]

+ 42 - 0
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/variables-initialization-outES3Metal.txt

@@ -0,0 +1,42 @@
+#include <metal_stdlib>
+#pragma clang diagnostic ignored "-Wparentheses-equality"
+using namespace metal;
+struct xlatMtlShaderInput {
+  half2 xlv_TEXCOORD0;
+};
+struct xlatMtlShaderOutput {
+  half4 _glesFragData_0 [[color(0)]];
+};
+struct xlatMtlShaderUniform {
+};
+fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]]
+  ,   texture2d<half> _MainTex [[texture(0)]], sampler _mtlsmp__MainTex [[sampler(0)]])
+{
+  xlatMtlShaderOutput _mtl_o;
+  half4 xl_retval_1 = 0;
+  half4 col_2 = 0;
+  float4 mat_0_3 = 0;
+  bool bar_4 = false;
+  float4 foo_5 = 0;
+  half4 tmpvar_6 = 0;
+  tmpvar_6 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
+  col_2 = tmpvar_6;
+  float4 tmpvar_7 = 0;
+  if (bar_4) {
+    tmpvar_7 = foo_5;
+  } else {
+    tmpvar_7 = float4(0.5, 0.5, 0.5, 0.5);
+  };
+  col_2 = (tmpvar_6 + (half4)(tmpvar_7));
+  col_2 = (col_2 + (half4)(mat_0_3));
+  xl_retval_1 = col_2;
+  _mtl_o._glesFragData_0 = xl_retval_1;
+  return _mtl_o;
+}
+
+
+// stats: 3 alu 1 tex 1 flow
+// inputs: 1
+//  #0: xlv_TEXCOORD0 (medium float) 2x1 [-1]
+// textures: 1
+//  #0: _MainTex (low 2d) 0x0 [-1] loc 0

+ 13 - 13
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-DirLMBasis-outES3Metal.txt

@@ -16,15 +16,15 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(2)]], sampler _mtlsmp__MainTex [[sampler(2)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half3 tmpvar_2;
-  half3 tmpvar_3;
-  half4 c_4;
-  half4 tmpvar_5;
+  half4 c_1 = 0;
+  half3 tmpvar_2 = 0;
+  half3 tmpvar_3 = 0;
+  half4 c_4 = 0;
+  half4 tmpvar_5 = 0;
   tmpvar_5 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
   c_4 = tmpvar_5;
   tmpvar_2 = c_4.xyz;
-  tmpvar_3 = ((c_4.xyz * (half)2.0) - (half)1.0);
+  tmpvar_3 = ((c_4.xyz * (half)(2.0)) - (half)(1.0));
   half3x3 tmpvar_6;
   tmpvar_6[0].x = half(0.8164966);
   tmpvar_6[0].y = half(-0.4082483);
@@ -35,15 +35,15 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   tmpvar_6[2].x = half(0.5773503);
   tmpvar_6[2].y = half(0.5773503);
   tmpvar_6[2].z = half(0.5773503);
-  half3 normal_7;
+  half3 normal_7 = 0;
   normal_7 = tmpvar_3;
-  half3 scalePerBasisVector_8;
-  half3 lm_9;
-  half3 tmpvar_10;
-  tmpvar_10 = ((half)2.0 * unity_Lightmap.sample(_mtlsmp_unity_Lightmap, (float2)(_mtl_i.xlv_TEXCOORD4.xy)).xyz);
+  half3 scalePerBasisVector_8 = 0;
+  half3 lm_9 = 0;
+  half3 tmpvar_10 = 0;
+  tmpvar_10 = ((half)(2.0) * unity_Lightmap.sample(_mtlsmp_unity_Lightmap, (float2)(_mtl_i.xlv_TEXCOORD4.xy)).xyz);
   lm_9 = tmpvar_10;
-  half3 tmpvar_11;
-  tmpvar_11 = ((half)2.0 * unity_LightmapInd.sample(_mtlsmp_unity_LightmapInd, (float2)(_mtl_i.xlv_TEXCOORD4.xy)).xyz);
+  half3 tmpvar_11 = 0;
+  tmpvar_11 = ((half)(2.0) * unity_LightmapInd.sample(_mtlsmp_unity_LightmapInd, (float2)(_mtl_i.xlv_TEXCOORD4.xy)).xyz);
   scalePerBasisVector_8 = tmpvar_11;
   lm_9 = (lm_9 * dot (clamp (
     (tmpvar_6 * normal_7)

+ 34 - 34
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-LightShaftsCoord-outES3Metal.txt

@@ -20,101 +20,101 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _CameraDepthTexture [[texture(0)]], sampler _mtlsmp__CameraDepthTexture [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float4 depth_1;
-  float2 coordTemp_2;
-  float sampleOnEpipolarLine_3;
-  float tmpvar_4;
+  float4 depth_1 = 0;
+  float2 coordTemp_2 = 0;
+  float sampleOnEpipolarLine_3 = 0;
+  float tmpvar_4 = 0;
   tmpvar_4 = clamp ((_mtl_i.xlv_TEXCOORD0.y - (0.5 / _mtl_u._CoordTexDim.y)), 0.0, 1.0);
   sampleOnEpipolarLine_3 = ((_mtl_i.xlv_TEXCOORD0.x - (0.5 / _mtl_u._CoordTexDim.x)) * (_mtl_u._CoordTexDim.x / (_mtl_u._CoordTexDim.x - 1.0)));
-  float tmpvar_5;
+  float tmpvar_5 = 0;
   tmpvar_5 = clamp (sampleOnEpipolarLine_3, 0.0, 1.0);
   sampleOnEpipolarLine_3 = tmpvar_5;
-  int tmpvar_6;
+  int tmpvar_6 = 0;
   tmpvar_6 = int(clamp (floor(
     (tmpvar_4 * 4.0)
   ), 0.0, 3.0));
-  float tmpvar_7;
+  float tmpvar_7 = 0;
   tmpvar_7 = (-1.0 + (2.0 * fract(
     (tmpvar_4 * 4.0)
   )));
-  float4 tmpvar_8;
+  float4 tmpvar_8 = 0;
   tmpvar_8.xz = float2(-1.0, 1.0);
   tmpvar_8.y = tmpvar_7;
   tmpvar_8.w = -(tmpvar_7);
-  float4 tmpvar_9;
+  float4 tmpvar_9 = 0;
   tmpvar_9.yw = float2(-1.0, 1.0);
   tmpvar_9.x = -(tmpvar_7);
   tmpvar_9.z = tmpvar_7;
-  bool4 tmpvar_10;
+  bool4 tmpvar_10 = false;
   tmpvar_10 = bool4((int4(tmpvar_6) == int4(0, 1, 2, 3)));
-  half4 tmpvar_11;
+  half4 tmpvar_11 = 0;
   tmpvar_11 = half4(tmpvar_10);
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = half4(tmpvar_10);
-  float2 tmpvar_13;
+  float2 tmpvar_13 = 0;
   tmpvar_13.x = dot (tmpvar_9, (float4)tmpvar_11);
   tmpvar_13.y = dot (tmpvar_8, (float4)tmpvar_12);
   coordTemp_2 = ((mix (_mtl_u._LightPos.xy, 
     -(tmpvar_13)
   , float2(tmpvar_5)) * 0.5) + 0.5);
-  float4 tmpvar_14;
+  float4 tmpvar_14 = 0;
   tmpvar_14.zw = float2(0.0, 0.0);
   tmpvar_14.xy = coordTemp_2;
   coordTemp_2 = ((floor(
     (coordTemp_2 * _mtl_u._ScreenTexDim.xy)
   ) + 0.5) * _mtl_u._ScreenTexDim.zw);
-  half4 tmpvar_15;
+  half4 tmpvar_15 = 0;
   tmpvar_15 = _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(coordTemp_2));
-  float tmpvar_16;
-  float z_17;
+  float tmpvar_16 = 0;
+  float z_17 = 0;
   z_17 = float(tmpvar_15.x);
   tmpvar_16 = (1.0/(((_mtl_u._ZBufferParams.x * z_17) + _mtl_u._ZBufferParams.y)));
   depth_1 = float4(tmpvar_16);
-  float4 v_18;
+  float4 v_18 = 0;
   v_18.x = _mtl_u._FrustumRays[0].x;
   v_18.y = _mtl_u._FrustumRays[1].x;
   v_18.z = _mtl_u._FrustumRays[2].x;
   v_18.w = _mtl_u._FrustumRays[3].x;
-  float4 v_19;
+  float4 v_19 = 0;
   v_19.x = _mtl_u._FrustumRays[0].y;
   v_19.y = _mtl_u._FrustumRays[1].y;
   v_19.z = _mtl_u._FrustumRays[2].y;
   v_19.w = _mtl_u._FrustumRays[3].y;
-  float4 v_20;
+  float4 v_20 = 0;
   v_20.x = _mtl_u._FrustumRays[0].w;
   v_20.y = _mtl_u._FrustumRays[1].w;
   v_20.z = _mtl_u._FrustumRays[2].w;
   v_20.w = _mtl_u._FrustumRays[3].w;
-  float4 v_21;
+  float4 v_21 = 0;
   v_21.x = _mtl_u._FrustumRays[0].z;
   v_21.y = _mtl_u._FrustumRays[1].z;
   v_21.z = _mtl_u._FrustumRays[2].z;
   v_21.w = _mtl_u._FrustumRays[3].z;
-  float3 tmpvar_22;
+  float3 tmpvar_22 = 0;
   tmpvar_22 = mix (mix (v_18.xyz, v_19.xyz, tmpvar_14.xxx), mix (v_20.xyz, v_21.xyz, tmpvar_14.xxx), tmpvar_14.yyy);
-  float tmpvar_23;
+  float tmpvar_23 = 0;
   tmpvar_23 = sqrt(dot (tmpvar_22, tmpvar_22));
-  bool tmpvar_24;
-  float3 tmpvar_25;
+  bool tmpvar_24 = false;
+  float3 tmpvar_25 = 0;
   tmpvar_25 = (1.0/((tmpvar_22 / tmpvar_23)));
-  float3 tmpvar_26;
+  float3 tmpvar_26 = 0;
   tmpvar_26 = (tmpvar_25 * (-0.5 - _mtl_u._CameraPosLocal.xyz));
-  float3 tmpvar_27;
+  float3 tmpvar_27 = 0;
   tmpvar_27 = (tmpvar_25 * (0.5 - _mtl_u._CameraPosLocal.xyz));
-  float3 tmpvar_28;
+  float3 tmpvar_28 = 0;
   tmpvar_28 = min (tmpvar_27, tmpvar_26);
-  float3 tmpvar_29;
+  float3 tmpvar_29 = 0;
   tmpvar_29 = max (tmpvar_27, tmpvar_26);
-  float2 tmpvar_30;
+  float2 tmpvar_30 = 0;
   tmpvar_30 = max (tmpvar_28.xx, tmpvar_28.yz);
-  float tmpvar_31;
+  float tmpvar_31 = 0;
   tmpvar_31 = max (tmpvar_30.x, tmpvar_30.y);
-  float2 tmpvar_32;
+  float2 tmpvar_32 = 0;
   tmpvar_32 = min (tmpvar_29.xx, tmpvar_29.yz);
-  float tmpvar_33;
+  float tmpvar_33 = 0;
   tmpvar_33 = min (tmpvar_32.x, tmpvar_32.y);
   tmpvar_24 = bool(((tmpvar_31 < tmpvar_33) && (tmpvar_33 > 0.0)));
-  if (((bool)!(tmpvar_24) || (tmpvar_16 < (tmpvar_31 / tmpvar_23)))) {
+  if (((bool)(!(tmpvar_24)) || (tmpvar_16 < (tmpvar_31 / tmpvar_23)))) {
     depth_1 = -(float4(tmpvar_16));
   } else {
     depth_1 = min (depth_1, float4((tmpvar_33 / tmpvar_23)));

+ 15 - 15
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-alphabumpspec-outES3Metal.txt

@@ -21,26 +21,26 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(1)]], sampler _mtlsmp__MainTex [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half3 tmpvar_2;
-  half tmpvar_3;
-  half4 tmpvar_4;
+  half4 c_1 = 0;
+  half3 tmpvar_2 = 0;
+  half tmpvar_3 = 0;
+  half4 tmpvar_4 = 0;
   tmpvar_4 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i._uv0.xy));
   tmpvar_2 = (tmpvar_4.xyz * _mtl_u._Color.xyz);
   tmpvar_3 = (tmpvar_4.w * _mtl_u._Color.w);
-  half4 tmpvar_5;
+  half4 tmpvar_5 = 0;
   tmpvar_5 = _BumpMap.sample(_mtlsmp__BumpMap, (float2)(_mtl_i._uv0.zw));
-  half4 packednormal_6;
+  half4 packednormal_6 = 0;
   packednormal_6 = tmpvar_5;
-  half4 normal_7;
-  normal_7.xy = ((packednormal_6.wy * (half)2.0) - (half)1.0);
-  normal_7.z = sqrt((((half)1.0 - 
+  half4 normal_7 = 0;
+  normal_7.xy = ((packednormal_6.wy * (half)(2.0)) - (half)(1.0));
+  normal_7.z = sqrt((((half)(1.0) - 
     (normal_7.x * normal_7.x)
   ) - (normal_7.y * normal_7.y)));
-  half4 c_8;
-  half spec_9;
-  half tmpvar_10;
-  float y_11;
+  half4 c_8 = 0;
+  half spec_9 = 0;
+  half tmpvar_10 = 0;
+  float y_11 = 0;
   y_11 = (_mtl_u._Shininess * 128.0);
   tmpvar_10 = ((half)pow ((float)max ((half)0.0, dot (normal_7.xyz, 
     normalize((_mtl_i._uv2 + normalize(_mtl_i._uv1)))
@@ -52,11 +52,11 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     max ((half)0.0, dot (normal_7.xyz, _mtl_i._uv2))
   ) + (
     (_mtl_u._LightColor0.xyz * _mtl_u._SpecColor.xyz)
-   * spec_9)) * (half)2.0);
+   * spec_9)) * (half)(2.0));
   c_8.w = (tmpvar_3 + ((_mtl_u._LightColor0.w * _mtl_u._SpecColor.w) * spec_9));
   c_1.xyz = (c_8.xyz + (tmpvar_2 * _mtl_i._uv3));
   c_1.w = tmpvar_3;
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = c_1;
   _mtl_o._fragData = tmpvar_12;
   return _mtl_o;

+ 20 - 20
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-collectshadows-outES3Metal.txt

@@ -23,34 +23,34 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _ShadowMapTexture [[texture(1)]], sampler _mtlsmp__ShadowMapTexture [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
-  float4 res_2;
-  float depth_3;
-  half4 tmpvar_4;
+  half4 tmpvar_1 = 0;
+  float4 res_2 = 0;
+  float depth_3 = 0;
+  half4 tmpvar_4 = 0;
   tmpvar_4 = _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(_mtl_i.xlv_TEXCOORD0));
   depth_3 = float(tmpvar_4.x);
-  float tmpvar_5;
+  float tmpvar_5 = 0;
   tmpvar_5 = (1.0/(((_mtl_u._ZBufferParams.x * depth_3) + _mtl_u._ZBufferParams.y)));
   depth_3 = tmpvar_5;
-  float4 tmpvar_6;
+  float4 tmpvar_6 = 0;
   tmpvar_6.w = 1.0;
   tmpvar_6.xyz = (_mtl_i.xlv_TEXCOORD1 * tmpvar_5);
-  half shadow_7;
-  float4 weights_8;
-  float4 far_9;
-  float4 near_10;
-  bool4 tmpvar_11;
+  half shadow_7 = 0;
+  float4 weights_8 = 0;
+  float4 far_9 = 0;
+  float4 near_10 = 0;
+  bool4 tmpvar_11 = false;
   tmpvar_11 = bool4((tmpvar_6.zzzz >= _mtl_u._LightSplitsNear));
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = half4(tmpvar_11);
   near_10 = float4(tmpvar_12);
-  bool4 tmpvar_13;
+  bool4 tmpvar_13 = false;
   tmpvar_13 = bool4((tmpvar_6.zzzz < _mtl_u._LightSplitsFar));
-  half4 tmpvar_14;
+  half4 tmpvar_14 = 0;
   tmpvar_14 = half4(tmpvar_13);
   far_9 = float4(tmpvar_14);
   weights_8 = (near_10 * far_9);
-  float4 tmpvar_15;
+  float4 tmpvar_15 = 0;
   tmpvar_15.w = 1.0;
   tmpvar_15.xyz = (((
     ((_mtl_u._View2Shadow * tmpvar_6).xyz * weights_8.x)
@@ -59,10 +59,10 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ) + (
     (_mtl_u._View2Shadow2 * tmpvar_6)
   .xyz * weights_8.z)) + ((_mtl_u._View2Shadow3 * tmpvar_6).xyz * weights_8.w));
-  half4 tmpvar_16;
+  half4 tmpvar_16 = 0;
   tmpvar_16 = _ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, (float2)(tmpvar_15.xy));
-  float tmpvar_17;
-  if (((float)tmpvar_16.x < tmpvar_15.z)) {
+  float tmpvar_17 = 0;
+  if (((float)(tmpvar_16.x) < tmpvar_15.z)) {
     tmpvar_17 = _mtl_u._LightShadowData.x;
   } else {
     tmpvar_17 = 1.0;
@@ -70,9 +70,9 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   shadow_7 = half(tmpvar_17);
   res_2.x = float(shadow_7);
   res_2.y = 1.0;
-  float2 enc_18;
+  float2 enc_18 = 0;
   enc_18 = (float2(1.0, 255.0) * (1.0 - tmpvar_5));
-  float2 tmpvar_19;
+  float2 tmpvar_19 = 0;
   tmpvar_19 = fract(enc_18);
   enc_18.y = tmpvar_19.y;
   enc_18.x = (tmpvar_19.x - (tmpvar_19.y * 0.00392157));

+ 97 - 97
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-fxaa-preset3-outES3Metal.txt

@@ -14,119 +14,119 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(0)]], sampler _mtlsmp__MainTex [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float2 rcpFrame_1;
+  float2 rcpFrame_1 = 0;
   rcpFrame_1 = _mtl_u._MainTex_TexelSize.xy;
-  half3 tmpvar_2;
-  bool doneP_4;
-  bool doneN_5;
-  half lumaEndP_6;
-  half lumaEndN_7;
-  float2 offNP_8;
-  float2 posP_9;
-  float2 posN_10;
-  half gradientN_11;
-  float lengthSign_12;
-  half3 rgbL_13;
-  half lumaS_14;
-  half lumaN_15;
-  float4 tmpvar_16;
+  half3 tmpvar_2 = 0;
+  bool doneP_4 = false;
+  bool doneN_5 = false;
+  half lumaEndP_6 = 0;
+  half lumaEndN_7 = 0;
+  float2 offNP_8 = 0;
+  float2 posP_9 = 0;
+  float2 posN_10 = 0;
+  half gradientN_11 = 0;
+  float lengthSign_12 = 0;
+  half3 rgbL_13 = 0;
+  half lumaS_14 = 0;
+  half lumaN_15 = 0;
+  float4 tmpvar_16 = 0;
   tmpvar_16.zw = float2(0.0, 0.0);
   tmpvar_16.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(0.0, -1.0) * _mtl_u._MainTex_TexelSize.xy));
-  half4 tmpvar_17;
+  half4 tmpvar_17 = 0;
   tmpvar_17 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_16.xy), level(0.0));
-  float4 tmpvar_18;
+  float4 tmpvar_18 = 0;
   tmpvar_18.zw = float2(0.0, 0.0);
   tmpvar_18.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(-1.0, 0.0) * _mtl_u._MainTex_TexelSize.xy));
-  half4 tmpvar_19;
+  half4 tmpvar_19 = 0;
   tmpvar_19 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_18.xy), level(0.0));
-  half4 tmpvar_20;
+  half4 tmpvar_20 = 0;
   tmpvar_20 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0), level(0.0));
-  float4 tmpvar_21;
+  float4 tmpvar_21 = 0;
   tmpvar_21.zw = float2(0.0, 0.0);
   tmpvar_21.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(1.0, 0.0) * _mtl_u._MainTex_TexelSize.xy));
-  half4 tmpvar_22;
+  half4 tmpvar_22 = 0;
   tmpvar_22 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_21.xy), level(0.0));
-  float4 tmpvar_23;
+  float4 tmpvar_23 = 0;
   tmpvar_23.zw = float2(0.0, 0.0);
   tmpvar_23.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(0.0, 1.0) * _mtl_u._MainTex_TexelSize.xy));
-  half4 tmpvar_24;
+  half4 tmpvar_24 = 0;
   tmpvar_24 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_23.xy), level(0.0));
-  half tmpvar_25;
-  tmpvar_25 = ((tmpvar_17.y * (half)1.963211) + tmpvar_17.x);
+  half tmpvar_25 = 0;
+  tmpvar_25 = ((tmpvar_17.y * (half)(1.963211)) + tmpvar_17.x);
   lumaN_15 = tmpvar_25;
-  half tmpvar_26;
-  tmpvar_26 = ((tmpvar_19.y * (half)1.963211) + tmpvar_19.x);
-  half tmpvar_27;
-  tmpvar_27 = ((tmpvar_20.y * (half)1.963211) + tmpvar_20.x);
-  half tmpvar_28;
-  tmpvar_28 = ((tmpvar_22.y * (half)1.963211) + tmpvar_22.x);
-  half tmpvar_29;
-  tmpvar_29 = ((tmpvar_24.y * (half)1.963211) + tmpvar_24.x);
+  half tmpvar_26 = 0;
+  tmpvar_26 = ((tmpvar_19.y * (half)(1.963211)) + tmpvar_19.x);
+  half tmpvar_27 = 0;
+  tmpvar_27 = ((tmpvar_20.y * (half)(1.963211)) + tmpvar_20.x);
+  half tmpvar_28 = 0;
+  tmpvar_28 = ((tmpvar_22.y * (half)(1.963211)) + tmpvar_22.x);
+  half tmpvar_29 = 0;
+  tmpvar_29 = ((tmpvar_24.y * (half)(1.963211)) + tmpvar_24.x);
   lumaS_14 = tmpvar_29;
-  half tmpvar_30;
+  half tmpvar_30 = 0;
   tmpvar_30 = max (max (tmpvar_27, tmpvar_25), max (max (tmpvar_26, tmpvar_29), tmpvar_28));
-  half tmpvar_31;
+  half tmpvar_31 = 0;
   tmpvar_31 = (tmpvar_30 - min (min (tmpvar_27, tmpvar_25), min (
     min (tmpvar_26, tmpvar_29)
   , tmpvar_28)));
-  half tmpvar_32;
-  tmpvar_32 = max ((half)0.04166667, (tmpvar_30 * (half)0.125));
+  half tmpvar_32 = 0;
+  tmpvar_32 = max ((half)0.04166667, (tmpvar_30 * (half)(0.125)));
   if ((tmpvar_31 < tmpvar_32)) {
     tmpvar_2 = tmpvar_20.xyz;
   } else {
-    half tmpvar_33;
+    half tmpvar_33 = 0;
     tmpvar_33 = min ((half)0.75, (max ((half)0.0, 
       ((abs((
-        (((tmpvar_25 + tmpvar_26) + (tmpvar_28 + tmpvar_29)) * (half)0.25)
-       - tmpvar_27)) / tmpvar_31) - (half)0.25)
-    ) * (half)1.333333));
-    float4 tmpvar_34;
+        (((tmpvar_25 + tmpvar_26) + (tmpvar_28 + tmpvar_29)) * (half)(0.25))
+       - tmpvar_27)) / tmpvar_31) - (half)(0.25))
+    ) * (half)(1.333333)));
+    float4 tmpvar_34 = 0;
     tmpvar_34.zw = float2(0.0, 0.0);
     tmpvar_34.xy = (_mtl_i.xlv_TEXCOORD0 - _mtl_u._MainTex_TexelSize.xy);
-    half4 tmpvar_35;
+    half4 tmpvar_35 = 0;
     tmpvar_35 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_34.xy), level(0.0));
-    float4 tmpvar_36;
+    float4 tmpvar_36 = 0;
     tmpvar_36.zw = float2(0.0, 0.0);
     tmpvar_36.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(1.0, -1.0) * _mtl_u._MainTex_TexelSize.xy));
-    half4 tmpvar_37;
+    half4 tmpvar_37 = 0;
     tmpvar_37 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_36.xy), level(0.0));
-    float4 tmpvar_38;
+    float4 tmpvar_38 = 0;
     tmpvar_38.zw = float2(0.0, 0.0);
     tmpvar_38.xy = (_mtl_i.xlv_TEXCOORD0 + (float2(-1.0, 1.0) * _mtl_u._MainTex_TexelSize.xy));
-    half4 tmpvar_39;
+    half4 tmpvar_39 = 0;
     tmpvar_39 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_38.xy), level(0.0));
-    float4 tmpvar_40;
+    float4 tmpvar_40 = 0;
     tmpvar_40.zw = float2(0.0, 0.0);
     tmpvar_40.xy = (_mtl_i.xlv_TEXCOORD0 + _mtl_u._MainTex_TexelSize.xy);
-    half4 tmpvar_41;
+    half4 tmpvar_41 = 0;
     tmpvar_41 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_40.xy), level(0.0));
     rgbL_13 = (((tmpvar_17.xyz + tmpvar_19.xyz) + (tmpvar_20.xyz + tmpvar_22.xyz)) + ((tmpvar_24.xyz + tmpvar_35.xyz) + (
       (tmpvar_37.xyz + tmpvar_39.xyz)
      + tmpvar_41.xyz)));
-    rgbL_13 = (rgbL_13 * (half3)float3(0.1111111, 0.1111111, 0.1111111));
-    half tmpvar_42;
-    tmpvar_42 = ((tmpvar_35.y * (half)1.963211) + tmpvar_35.x);
-    half tmpvar_43;
-    tmpvar_43 = ((tmpvar_37.y * (half)1.963211) + tmpvar_37.x);
-    half tmpvar_44;
-    tmpvar_44 = ((tmpvar_39.y * (half)1.963211) + tmpvar_39.x);
-    half tmpvar_45;
-    tmpvar_45 = ((tmpvar_41.y * (half)1.963211) + tmpvar_41.x);
-    bool tmpvar_46;
+    rgbL_13 = (rgbL_13 * (half3)(float3(0.1111111, 0.1111111, 0.1111111)));
+    half tmpvar_42 = 0;
+    tmpvar_42 = ((tmpvar_35.y * (half)(1.963211)) + tmpvar_35.x);
+    half tmpvar_43 = 0;
+    tmpvar_43 = ((tmpvar_37.y * (half)(1.963211)) + tmpvar_37.x);
+    half tmpvar_44 = 0;
+    tmpvar_44 = ((tmpvar_39.y * (half)(1.963211)) + tmpvar_39.x);
+    half tmpvar_45 = 0;
+    tmpvar_45 = ((tmpvar_41.y * (half)(1.963211)) + tmpvar_41.x);
+    bool tmpvar_46 = false;
     tmpvar_46 = (((
-      abs(((((half)0.25 * tmpvar_42) + ((half)-0.5 * tmpvar_26)) + ((half)0.25 * tmpvar_44)))
+      abs(((((half)(0.25) * tmpvar_42) + ((half)(-0.5) * tmpvar_26)) + ((half)(0.25) * tmpvar_44)))
      + 
-      abs(((((half)0.5 * tmpvar_25) - tmpvar_27) + ((half)0.5 * tmpvar_29)))
+      abs(((((half)(0.5) * tmpvar_25) - tmpvar_27) + ((half)(0.5) * tmpvar_29)))
     ) + abs(
-      ((((half)0.25 * tmpvar_43) + ((half)-0.5 * tmpvar_28)) + ((half)0.25 * tmpvar_45))
+      ((((half)(0.25) * tmpvar_43) + ((half)(-0.5) * tmpvar_28)) + ((half)(0.25) * tmpvar_45))
     )) >= ((
-      abs(((((half)0.25 * tmpvar_42) + ((half)-0.5 * tmpvar_25)) + ((half)0.25 * tmpvar_43)))
+      abs(((((half)(0.25) * tmpvar_42) + ((half)(-0.5) * tmpvar_25)) + ((half)(0.25) * tmpvar_43)))
      + 
-      abs(((((half)0.5 * tmpvar_26) - tmpvar_27) + ((half)0.5 * tmpvar_28)))
+      abs(((((half)(0.5) * tmpvar_26) - tmpvar_27) + ((half)(0.5) * tmpvar_28)))
     ) + abs(
-      ((((half)0.25 * tmpvar_44) + ((half)-0.5 * tmpvar_29)) + ((half)0.25 * tmpvar_45))
+      ((((half)(0.25) * tmpvar_44) + ((half)(-0.5) * tmpvar_29)) + ((half)(0.25) * tmpvar_45))
     )));
-    float tmpvar_47;
+    float tmpvar_47 = 0;
     if (tmpvar_46) {
       tmpvar_47 = -(_mtl_u._MainTex_TexelSize.y);
     } else {
@@ -139,14 +139,14 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     if (!(tmpvar_46)) {
       lumaS_14 = tmpvar_28;
     };
-    half tmpvar_48;
+    half tmpvar_48 = 0;
     tmpvar_48 = abs((lumaN_15 - tmpvar_27));
     gradientN_11 = tmpvar_48;
-    half tmpvar_49;
+    half tmpvar_49 = 0;
     tmpvar_49 = abs((lumaS_14 - tmpvar_27));
-    lumaN_15 = ((lumaN_15 + tmpvar_27) * (half)0.5);
-    lumaS_14 = ((lumaS_14 + tmpvar_27) * (half)0.5);
-    bool tmpvar_50;
+    lumaN_15 = ((lumaN_15 + tmpvar_27) * (half)(0.5));
+    lumaS_14 = ((lumaS_14 + tmpvar_27) * (half)(0.5));
+    bool tmpvar_50 = false;
     tmpvar_50 = (tmpvar_48 >= tmpvar_49);
     if (!(tmpvar_50)) {
       lumaN_15 = lumaS_14;
@@ -157,30 +157,30 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     if (!(tmpvar_50)) {
       lengthSign_12 = -(tmpvar_47);
     };
-    float tmpvar_51;
+    float tmpvar_51 = 0;
     if (tmpvar_46) {
       tmpvar_51 = 0.0;
     } else {
       tmpvar_51 = (lengthSign_12 * 0.5);
     };
     posN_10.x = (_mtl_i.xlv_TEXCOORD0.x + tmpvar_51);
-    float tmpvar_52;
+    float tmpvar_52 = 0;
     if (tmpvar_46) {
       tmpvar_52 = (lengthSign_12 * 0.5);
     } else {
       tmpvar_52 = 0.0;
     };
     posN_10.y = (_mtl_i.xlv_TEXCOORD0.y + tmpvar_52);
-    gradientN_11 = (gradientN_11 * (half)0.25);
+    gradientN_11 = (gradientN_11 * (half)(0.25));
     posP_9 = posN_10;
-    float2 tmpvar_53;
+    float2 tmpvar_53 = 0;
     if (tmpvar_46) {
-      float2 tmpvar_54;
+      float2 tmpvar_54 = 0;
       tmpvar_54.y = 0.0;
       tmpvar_54.x = rcpFrame_1.x;
       tmpvar_53 = tmpvar_54;
     } else {
-      float2 tmpvar_55;
+      float2 tmpvar_55 = 0;
       tmpvar_55.x = 0.0;
       tmpvar_55.y = rcpFrame_1.y;
       tmpvar_53 = tmpvar_55;
@@ -194,23 +194,23 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
     posP_9 = (posP_9 + tmpvar_53);
     for (int i_3 = 0; i_3 < 16; i_3++) {
       if (!(doneN_5)) {
-        half4 tmpvar_56;
+        half4 tmpvar_56 = 0;
         tmpvar_56 = _MainTex.sample(_mtlsmp__MainTex, (float2)(posN_10), level(0.0));
-        lumaEndN_7 = ((tmpvar_56.y * (half)1.963211) + tmpvar_56.x);
+        lumaEndN_7 = ((tmpvar_56.y * (half)(1.963211)) + tmpvar_56.x);
       };
       if (!(doneP_4)) {
-        half4 tmpvar_57;
+        half4 tmpvar_57 = 0;
         tmpvar_57 = _MainTex.sample(_mtlsmp__MainTex, (float2)(posP_9), level(0.0));
-        lumaEndP_6 = ((tmpvar_57.y * (half)1.963211) + tmpvar_57.x);
+        lumaEndP_6 = ((tmpvar_57.y * (half)(1.963211)) + tmpvar_57.x);
       };
-      bool tmpvar_58;
+      bool tmpvar_58 = false;
       if (doneN_5) {
         tmpvar_58 = bool(bool(1));
       } else {
         tmpvar_58 = (abs((lumaEndN_7 - lumaN_15)) >= gradientN_11);
       };
       doneN_5 = tmpvar_58;
-      bool tmpvar_59;
+      bool tmpvar_59 = false;
       if (doneP_4) {
         tmpvar_59 = bool(bool(1));
       } else {
@@ -227,66 +227,66 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
         posP_9 = (posP_9 + offNP_8);
       };
     };
-    float tmpvar_60;
+    float tmpvar_60 = 0;
     if (tmpvar_46) {
       tmpvar_60 = (_mtl_i.xlv_TEXCOORD0.x - posN_10.x);
     } else {
       tmpvar_60 = (_mtl_i.xlv_TEXCOORD0.y - posN_10.y);
     };
-    float tmpvar_61;
+    float tmpvar_61 = 0;
     if (tmpvar_46) {
       tmpvar_61 = (posP_9.x - _mtl_i.xlv_TEXCOORD0.x);
     } else {
       tmpvar_61 = (posP_9.y - _mtl_i.xlv_TEXCOORD0.y);
     };
-    bool tmpvar_62;
+    bool tmpvar_62 = false;
     tmpvar_62 = (tmpvar_60 < tmpvar_61);
-    half tmpvar_63;
+    half tmpvar_63 = 0;
     if (tmpvar_62) {
       tmpvar_63 = lumaEndN_7;
     } else {
       tmpvar_63 = lumaEndP_6;
     };
     lumaEndN_7 = tmpvar_63;
-    if ((((tmpvar_27 - lumaN_15) < (half)0.0) == ((tmpvar_63 - lumaN_15) < (half)0.0))) {
+    if ((((tmpvar_27 - lumaN_15) < (half)(0.0)) == ((tmpvar_63 - lumaN_15) < (half)(0.0)))) {
       lengthSign_12 = 0.0;
     };
-    float tmpvar_64;
+    float tmpvar_64 = 0;
     tmpvar_64 = (tmpvar_61 + tmpvar_60);
-    float tmpvar_65;
+    float tmpvar_65 = 0;
     if (tmpvar_62) {
       tmpvar_65 = tmpvar_60;
     } else {
       tmpvar_65 = tmpvar_61;
     };
-    float tmpvar_66;
+    float tmpvar_66 = 0;
     tmpvar_66 = ((0.5 + (tmpvar_65 * 
       (-1.0 / tmpvar_64)
     )) * lengthSign_12);
-    float tmpvar_67;
+    float tmpvar_67 = 0;
     if (tmpvar_46) {
       tmpvar_67 = 0.0;
     } else {
       tmpvar_67 = tmpvar_66;
     };
-    float tmpvar_68;
+    float tmpvar_68 = 0;
     if (tmpvar_46) {
       tmpvar_68 = tmpvar_66;
     } else {
       tmpvar_68 = 0.0;
     };
-    float2 tmpvar_69;
+    float2 tmpvar_69 = 0;
     tmpvar_69.x = (_mtl_i.xlv_TEXCOORD0.x + tmpvar_67);
     tmpvar_69.y = (_mtl_i.xlv_TEXCOORD0.y + tmpvar_68);
-    half4 tmpvar_70;
+    half4 tmpvar_70 = 0;
     tmpvar_70 = _MainTex.sample(_mtlsmp__MainTex, (float2)(tmpvar_69), level(0.0));
-    half3 tmpvar_71;
+    half3 tmpvar_71 = 0;
     tmpvar_71.x = -(tmpvar_33);
     tmpvar_71.y = -(tmpvar_33);
     tmpvar_71.z = -(tmpvar_33);
     tmpvar_2 = ((tmpvar_71 * tmpvar_70.xyz) + ((rgbL_13 * half3(tmpvar_33)) + tmpvar_70.xyz));
   };
-  half4 tmpvar_72;
+  half4 tmpvar_72 = 0;
   tmpvar_72.w = half(0.0);
   tmpvar_72.xyz = tmpvar_2;
   _mtl_o._fragData = tmpvar_72;

+ 56 - 56
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-prepasslight-outES3Metal.txt

@@ -28,138 +28,138 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texturecube<half> _ShadowMapTexture [[texture(4)]], sampler _mtlsmp__ShadowMapTexture [[sampler(4)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 res_1;
-  float spec_2;
-  half3 h_3;
-  float atten_4;
-  half3 lightDir_5;
-  float3 tolight_6;
-  float3 wpos_7;
-  float depth_8;
-  half3 normal_9;
-  half4 nspec_10;
-  float2 uv_11;
+  half4 res_1 = 0;
+  float spec_2 = 0;
+  half3 h_3 = 0;
+  float atten_4 = 0;
+  half3 lightDir_5 = 0;
+  float3 tolight_6 = 0;
+  float3 wpos_7 = 0;
+  float depth_8 = 0;
+  half3 normal_9 = 0;
+  half4 nspec_10 = 0;
+  float2 uv_11 = 0;
   uv_11 = (_mtl_i.xlv_TEXCOORD0.xy / _mtl_i.xlv_TEXCOORD0.w);
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = _CameraNormalsTexture.sample(_mtlsmp__CameraNormalsTexture, (float2)(uv_11));
   nspec_10 = tmpvar_12;
-  normal_9 = ((nspec_10.xyz * (half)2.0) - (half)1.0);
+  normal_9 = ((nspec_10.xyz * (half)(2.0)) - (half)(1.0));
   normal_9 = normalize(normal_9);
-  half4 tmpvar_13;
+  half4 tmpvar_13 = 0;
   tmpvar_13 = _CameraDepthTexture.sample(_mtlsmp__CameraDepthTexture, (float2)(uv_11));
   depth_8 = float(tmpvar_13.x);
-  float tmpvar_14;
+  float tmpvar_14 = 0;
   tmpvar_14 = (1.0/(((_mtl_u._ZBufferParams.x * depth_8) + _mtl_u._ZBufferParams.y)));
   depth_8 = tmpvar_14;
-  float4 tmpvar_15;
+  float4 tmpvar_15 = 0;
   tmpvar_15.w = 1.0;
   tmpvar_15.xyz = ((_mtl_i.xlv_TEXCOORD1 * (_mtl_u._ProjectionParams.z / _mtl_i.xlv_TEXCOORD1.z)) * tmpvar_14);
   wpos_7 = (_mtl_u._CameraToWorld * tmpvar_15).xyz;
   tolight_6 = (wpos_7 - _mtl_u._LightPos.xyz);
-  float3 tmpvar_16;
+  float3 tmpvar_16 = 0;
   tmpvar_16 = normalize(tolight_6);
   lightDir_5 = half3(-(tmpvar_16));
-  float2 tmpvar_17;
+  float2 tmpvar_17 = 0;
   tmpvar_17 = float2((dot (tolight_6, tolight_6) * _mtl_u._LightPos.w));
-  half4 tmpvar_18;
+  half4 tmpvar_18 = 0;
   tmpvar_18 = _LightTextureB0.sample(_mtlsmp__LightTextureB0, (float2)(tmpvar_17));
   atten_4 = float(tmpvar_18.w);
-  float mydist_19;
+  float mydist_19 = 0;
   mydist_19 = (sqrt(dot (tolight_6, tolight_6)) * _mtl_u._LightPositionRange.w);
   mydist_19 = (mydist_19 * 0.97);
-  float4 shadowVals_20;
-  float3 vec_21;
+  float4 shadowVals_20 = 0;
+  float3 vec_21 = 0;
   vec_21 = (tolight_6 + float3(0.0078125, 0.0078125, 0.0078125));
-  float4 packDist_22;
-  half4 tmpvar_23;
+  float4 packDist_22 = 0;
+  half4 tmpvar_23 = 0;
   tmpvar_23 = _ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, (float3)(vec_21));
   packDist_22 = float4(tmpvar_23);
   shadowVals_20.x = dot (packDist_22, float4(1.0, 0.00392157, 1.53787e-05, 6.22737e-09));
-  float3 vec_24;
+  float3 vec_24 = 0;
   vec_24 = (tolight_6 + float3(-0.0078125, -0.0078125, 0.0078125));
-  float4 packDist_25;
-  half4 tmpvar_26;
+  float4 packDist_25 = 0;
+  half4 tmpvar_26 = 0;
   tmpvar_26 = _ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, (float3)(vec_24));
   packDist_25 = float4(tmpvar_26);
   shadowVals_20.y = dot (packDist_25, float4(1.0, 0.00392157, 1.53787e-05, 6.22737e-09));
-  float3 vec_27;
+  float3 vec_27 = 0;
   vec_27 = (tolight_6 + float3(-0.0078125, 0.0078125, -0.0078125));
-  float4 packDist_28;
-  half4 tmpvar_29;
+  float4 packDist_28 = 0;
+  half4 tmpvar_29 = 0;
   tmpvar_29 = _ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, (float3)(vec_27));
   packDist_28 = float4(tmpvar_29);
   shadowVals_20.z = dot (packDist_28, float4(1.0, 0.00392157, 1.53787e-05, 6.22737e-09));
-  float3 vec_30;
+  float3 vec_30 = 0;
   vec_30 = (tolight_6 + float3(0.0078125, -0.0078125, -0.0078125));
-  float4 packDist_31;
-  half4 tmpvar_32;
+  float4 packDist_31 = 0;
+  half4 tmpvar_32 = 0;
   tmpvar_32 = _ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, (float3)(vec_30));
   packDist_31 = float4(tmpvar_32);
   shadowVals_20.w = dot (packDist_31, float4(1.0, 0.00392157, 1.53787e-05, 6.22737e-09));
-  bool4 tmpvar_33;
+  bool4 tmpvar_33 = false;
   tmpvar_33 = bool4((shadowVals_20 < float4(mydist_19)));
-  float4 tmpvar_34;
+  float4 tmpvar_34 = 0;
   tmpvar_34 = _mtl_u._LightShadowData.xxxx;
-  float tmpvar_35;
+  float tmpvar_35 = 0;
   if (tmpvar_33.x) {
     tmpvar_35 = tmpvar_34.x;
   } else {
     tmpvar_35 = 1.0;
   };
-  float tmpvar_36;
+  float tmpvar_36 = 0;
   if (tmpvar_33.y) {
     tmpvar_36 = tmpvar_34.y;
   } else {
     tmpvar_36 = 1.0;
   };
-  float tmpvar_37;
+  float tmpvar_37 = 0;
   if (tmpvar_33.z) {
     tmpvar_37 = tmpvar_34.z;
   } else {
     tmpvar_37 = 1.0;
   };
-  float tmpvar_38;
+  float tmpvar_38 = 0;
   if (tmpvar_33.w) {
     tmpvar_38 = tmpvar_34.w;
   } else {
     tmpvar_38 = 1.0;
   };
-  half4 tmpvar_39;
+  half4 tmpvar_39 = 0;
   tmpvar_39.x = half(tmpvar_35);
   tmpvar_39.y = half(tmpvar_36);
   tmpvar_39.z = half(tmpvar_37);
   tmpvar_39.w = half(tmpvar_38);
-  half tmpvar_40;
+  half tmpvar_40 = 0;
   tmpvar_40 = dot (tmpvar_39, (half4)float4(0.25, 0.25, 0.25, 0.25));
-  atten_4 = (atten_4 * (float)tmpvar_40);
-  float4 tmpvar_41;
+  atten_4 = (atten_4 * (float)(tmpvar_40));
+  float4 tmpvar_41 = 0;
   tmpvar_41.w = 1.0;
   tmpvar_41.xyz = wpos_7;
-  half4 tmpvar_42;
-  float3 P_43;
+  half4 tmpvar_42 = 0;
+  float3 P_43 = 0;
   P_43 = (_mtl_u._LightMatrix0 * tmpvar_41).xyz;
   tmpvar_42 = _LightTexture0.sample(_mtlsmp__LightTexture0, (float3)(P_43));
-  atten_4 = (atten_4 * (float)tmpvar_42.w);
-  float3 tmpvar_44;
-  tmpvar_44 = normalize(((float3)lightDir_5 - normalize(
+  atten_4 = (atten_4 * (float)(tmpvar_42.w));
+  float3 tmpvar_44 = 0;
+  tmpvar_44 = normalize(((float3)(lightDir_5) - normalize(
     (wpos_7 - _mtl_u._WorldSpaceCameraPos)
   )));
   h_3 = half3(tmpvar_44);
-  half tmpvar_45;
-  tmpvar_45 = pow (max ((half)0.0, dot (h_3, normal_9)), (nspec_10.w * (half)128.0));
+  half tmpvar_45 = 0;
+  tmpvar_45 = pow (max ((half)0.0, dot (h_3, normal_9)), (nspec_10.w * (half)(128.0)));
   spec_2 = float(tmpvar_45);
   spec_2 = (spec_2 * clamp (atten_4, 0.0, 1.0));
-  res_1.xyz = half3((_mtl_u._LightColor.xyz * ((float)max ((half)0.0, 
+  res_1.xyz = half3((_mtl_u._LightColor.xyz * ((float)(max ((half)0.0, 
     dot (lightDir_5, normal_9)
-  ) * atten_4)));
-  half3 c_46;
+  )) * atten_4)));
+  half3 c_46 = 0;
   c_46 = half3(_mtl_u._LightColor.xyz);
-  res_1.w = half((spec_2 * (float)dot (c_46, (half3)float3(0.22, 0.707, 0.071))));
-  float tmpvar_47;
+  res_1.w = half((spec_2 * (float)(dot (c_46, (half3)float3(0.22, 0.707, 0.071)))));
+  float tmpvar_47 = 0;
   tmpvar_47 = clamp ((1.0 - (
     (tmpvar_15.z * _mtl_u.unity_LightmapFade.z)
    + _mtl_u.unity_LightmapFade.w)), 0.0, 1.0);
-  res_1 = ((half4)((float4)res_1 * tmpvar_47));
+  res_1 = ((half4)((float4)(res_1) * tmpvar_47));
   _mtl_o._fragData = exp2(-(res_1));
   return _mtl_o;
 }

+ 9 - 9
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-tonemap-usercurve-outES3Metal.txt

@@ -15,26 +15,26 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _Curve [[texture(1)]], sampler _mtlsmp__Curve [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float newLum_1;
-  float3 cie_2;
-  float4 color_3;
-  half4 tmpvar_4;
+  float newLum_1 = 0;
+  float3 cie_2 = 0;
+  float4 color_3 = 0;
+  half4 tmpvar_4 = 0;
   tmpvar_4 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
   color_3 = float4(tmpvar_4);
-  float3 Yxy_5;
-  float3 tmpvar_6;
+  float3 Yxy_5 = 0;
+  float3 tmpvar_6 = 0;
   tmpvar_6 = (float3x3(float3(0.514136, 0.265068, 0.0241188), float3(0.323879, 0.670234, 0.122818), float3(0.160364, 0.0640916, 0.844427)) * color_3.xyz);
   Yxy_5.x = tmpvar_6.y;
   Yxy_5.yz = (tmpvar_6.xy / dot (float3(1.0, 1.0, 1.0), tmpvar_6));
   cie_2.yz = Yxy_5.yz;
-  float2 tmpvar_7;
+  float2 tmpvar_7 = 0;
   tmpvar_7.y = 0.5;
   tmpvar_7.x = (tmpvar_6.y * _mtl_u._RangeScale);
-  half tmpvar_8;
+  half tmpvar_8 = 0;
   tmpvar_8 = _Curve.sample(_mtlsmp__Curve, (float2)(tmpvar_7)).x;
   newLum_1 = float(tmpvar_8);
   cie_2.x = newLum_1;
-  float3 XYZ_9;
+  float3 XYZ_9 = 0;
   XYZ_9.x = ((newLum_1 * Yxy_5.y) / Yxy_5.z);
   XYZ_9.y = cie_2.x;
   XYZ_9.z = ((newLum_1 * (

+ 18 - 18
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-treeleafloop-outES3Metal.txt

@@ -24,31 +24,31 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _TranslucencyMap [[texture(2)]], sampler _mtlsmp__TranslucencyMap [[sampler(2)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half nh_2;
-  half nl_3;
-  half3 lightColor_4;
-  half3 backContribs_5;
-  half3 light_6;
-  half gloss_7;
-  half specular_8;
-  half3 albedo_9;
-  half4 tmpvar_10;
+  half4 c_1 = 0;
+  half nh_2 = 0;
+  half nl_3 = 0;
+  half3 lightColor_4 = 0;
+  half3 backContribs_5 = 0;
+  half3 light_6 = 0;
+  half gloss_7 = 0;
+  half specular_8 = 0;
+  half3 albedo_9 = 0;
+  half4 tmpvar_10 = 0;
   tmpvar_10 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
-  half x_11;
+  half x_11 = 0;
   x_11 = (tmpvar_10.w - _mtl_u._Cutoff);
-  if ((x_11 < (half)0.0)) {
+  if ((x_11 < (half)(0.0))) {
     discard_fragment();
   };
-  albedo_9 = half3(((float3)tmpvar_10.xyz * _mtl_i.xlv_TEXCOORD1));
-  half4 tmpvar_12;
+  albedo_9 = half3(((float3)(tmpvar_10.xyz) * _mtl_i.xlv_TEXCOORD1));
+  half4 tmpvar_12 = 0;
   tmpvar_12 = _BumpSpecMap.sample(_mtlsmp__BumpSpecMap, (float2)(_mtl_i.xlv_TEXCOORD0));
-  specular_8 = (tmpvar_12.x * (half)128.0);
-  half4 tmpvar_13;
+  specular_8 = (tmpvar_12.x * (half)(128.0));
+  half4 tmpvar_13 = 0;
   tmpvar_13 = _TranslucencyMap.sample(_mtlsmp__TranslucencyMap, (float2)(_mtl_i.xlv_TEXCOORD0));
   gloss_7 = tmpvar_13.w;
   light_6 = (_mtl_u.UNITY_LIGHTMODEL_AMBIENT.xyz * albedo_9);
-  backContribs_5 = half3((_mtl_i.xlv_TEXCOORD2 * (float)tmpvar_13.z));
+  backContribs_5 = half3((_mtl_i.xlv_TEXCOORD2 * (float)(tmpvar_13.z)));
   lightColor_4 = half3(_mtl_u._TerrainTreeLightColors[0].xyz);
   nl_3 = half(_mtl_i.xlv_TEXCOORD3.x);
   nh_2 = half(_mtl_i.xlv_TEXCOORD4.x);
@@ -73,7 +73,7 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
    + 
     (_mtl_u._SpecColor.xyz * (pow (nh_2, specular_8) * gloss_7))
   ) * lightColor_4));
-  c_1.xyz = (light_6 * (half)2.0);
+  c_1.xyz = (light_6 * (half)(2.0));
   c_1.w = half(1.0);
   _mtl_o._fragData = c_1;
   return _mtl_o;

+ 71 - 71
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-unishader-dirlm-outES3Metal.txt

@@ -35,10 +35,10 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _SelfIllum [[texture(11)]], sampler _mtlsmp__SelfIllum [[sampler(11)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half3 lightDir_1;
-  half3 env_2;
-  float3 tmpvar_3;
-  float3 tmpvar_4;
+  half3 lightDir_1 = 0;
+  half3 env_2 = 0;
+  float3 tmpvar_3 = 0;
+  float3 tmpvar_4 = 0;
   tmpvar_3 = _mtl_i.xlv_TEXCOORD3.xyz;
   tmpvar_4 = (((_mtl_i.xlv_TEXCOORD2.yzx * _mtl_i.xlv_TEXCOORD3.zxy) - (_mtl_i.xlv_TEXCOORD2.zxy * _mtl_i.xlv_TEXCOORD3.yzx)) * _mtl_i.xlv_TEXCOORD3.www);
   float3x3 tmpvar_5;
@@ -51,51 +51,51 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   tmpvar_5[2].x = tmpvar_3.z;
   tmpvar_5[2].y = tmpvar_4.z;
   tmpvar_5[2].z = _mtl_i.xlv_TEXCOORD2.z;
-  half3 normal_6;
-  normal_6.xy = ((_BumpMap.sample(_mtlsmp__BumpMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).wy * (half)2.0) - (half)1.0);
-  normal_6.xy = ((half2)((float2)normal_6.xy * _mtl_u._BumpScale));
-  normal_6.z = sqrt(((half)1.0 - clamp (
+  half3 normal_6 = 0;
+  normal_6.xy = ((_BumpMap.sample(_mtlsmp__BumpMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).wy * (half)(2.0)) - (half)(1.0));
+  normal_6.xy = ((half2)((float2)(normal_6.xy) * _mtl_u._BumpScale));
+  normal_6.z = sqrt(((half)(1.0) - clamp (
     dot (normal_6.xy, normal_6.xy)
   , (half)0.0, (half)1.0)));
-  half3 normal_7;
-  normal_7.xy = ((_DetailNormalMap.sample(_mtlsmp__DetailNormalMap, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).wy * (half)2.0) - (half)1.0);
-  normal_7.xy = ((half2)((float2)normal_7.xy * _mtl_u._DetailNormalMapScale));
-  normal_7.z = sqrt(((half)1.0 - clamp (
+  half3 normal_7 = 0;
+  normal_7.xy = ((_DetailNormalMap.sample(_mtlsmp__DetailNormalMap, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).wy * (half)(2.0)) - (half)(1.0));
+  normal_7.xy = ((half2)((float2)(normal_7.xy) * _mtl_u._DetailNormalMapScale));
+  normal_7.z = sqrt(((half)(1.0) - clamp (
     dot (normal_7.xy, normal_7.xy)
   , (half)0.0, (half)1.0)));
-  half3 tmpvar_8;
+  half3 tmpvar_8 = 0;
   tmpvar_8.xy = (normal_6.xy + normal_7.xy);
   tmpvar_8.z = (normal_6.z * normal_7.z);
-  half3 tmpvar_9;
+  half3 tmpvar_9 = 0;
   tmpvar_9 = normalize(tmpvar_8);
-  half3 tmpvar_10;
-  tmpvar_10 = ((half3)((float3)tmpvar_9 * tmpvar_5));
-  float3 tmpvar_11;
+  half3 tmpvar_10 = 0;
+  tmpvar_10 = ((half3)((float3)(tmpvar_9) * tmpvar_5));
+  float3 tmpvar_11 = 0;
   tmpvar_11 = normalize((_mtl_i.xlv_TEXCOORD1.xyz - _mtl_u._WorldSpaceCameraPos));
-  half4 tmpvar_12;
+  half4 tmpvar_12 = 0;
   tmpvar_12 = _SpecGlossMap.sample(_mtlsmp__SpecGlossMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy));
-  half tmpvar_13;
+  half tmpvar_13 = 0;
   tmpvar_13 = dot (tmpvar_12.xyz, (half3)float3(0.299, 0.587, 0.114));
-  half tmpvar_14;
-  tmpvar_14 = ((half)1.0 - tmpvar_12.w);
-  half4 tmpvar_15;
-  tmpvar_15.xyz = ((half3)(tmpvar_11 - (float3)((half)2.0 * (
+  half tmpvar_14 = 0;
+  tmpvar_14 = ((half)(1.0) - tmpvar_12.w);
+  half4 tmpvar_15 = 0;
+  tmpvar_15.xyz = ((half3)(tmpvar_11 - (float3)(((half)(2.0) * (
     ((half)dot ((float3)tmpvar_10, tmpvar_11))
-   * tmpvar_10))));
-  tmpvar_15.w = (tmpvar_14 * (half)5.0);
-  half4 tmpvar_16;
+   * tmpvar_10)))));
+  tmpvar_15.w = (tmpvar_14 * (half)(5.0));
+  half4 tmpvar_16 = 0;
   tmpvar_16 = _SpecCube.sample(_mtlsmp__SpecCube, (float3)(tmpvar_15.xyz), level(tmpvar_15.w));
-  half tmpvar_17;
+  half tmpvar_17 = 0;
   tmpvar_17 = (tmpvar_16.w * tmpvar_16.w);
-  half2 tmpvar_18;
+  half2 tmpvar_18 = 0;
   tmpvar_18.x = tmpvar_17;
   tmpvar_18.y = (tmpvar_16.w * tmpvar_17);
-  env_2 = (((half3)((float3)(tmpvar_16.xyz * 
+  env_2 = (((half3)((float3)((tmpvar_16.xyz * 
     dot ((half2)float2(0.7532, 0.2468), tmpvar_18)
-  ) * _mtl_u._Exposure)) * _Occlusion.sample(_mtlsmp__Occlusion, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).x);
-  half4 tmpvar_19;
+  )) * _mtl_u._Exposure)) * _Occlusion.sample(_mtlsmp__Occlusion, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).x);
+  half4 tmpvar_19 = 0;
   tmpvar_19 = unity_Lightmap.sample(_mtlsmp_unity_Lightmap, (float2)(_mtl_i.xlv_TEXCOORD4.xy));
-  half4 tmpvar_20;
+  half4 tmpvar_20 = 0;
   tmpvar_20 = unity_LightmapInd.sample(_mtlsmp_unity_LightmapInd, (float2)(_mtl_i.xlv_TEXCOORD4.xy));
   float3x3 tmpvar_21;
   tmpvar_21[0].x = 0.816497;
@@ -107,80 +107,80 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   tmpvar_21[2].x = 0.57735;
   tmpvar_21[2].y = 0.57735;
   tmpvar_21[2].z = 0.57735;
-  half3 tmpvar_22;
-  tmpvar_22 = (((half)8.0 * tmpvar_20.w) * tmpvar_20.xyz);
-  float3 v_23;
+  half3 tmpvar_22 = 0;
+  tmpvar_22 = (((half)(8.0) * tmpvar_20.w) * tmpvar_20.xyz);
+  float3 v_23 = 0;
   v_23.x = tmpvar_21[0].x;
   v_23.y = tmpvar_21[1].x;
   v_23.z = tmpvar_21[2].x;
-  float3 v_24;
+  float3 v_24 = 0;
   v_24.x = tmpvar_21[0].y;
   v_24.y = tmpvar_21[1].y;
   v_24.z = tmpvar_21[2].y;
-  float3 v_25;
+  float3 v_25 = 0;
   v_25.x = tmpvar_21[0].z;
   v_25.y = tmpvar_21[1].z;
   v_25.z = tmpvar_21[2].z;
-  lightDir_1 = ((half3)((float3)normalize((
-    ((tmpvar_22.x * (half3)v_23) + (tmpvar_22.y * (half3)v_24))
+  lightDir_1 = ((half3)((float3)(normalize((
+    ((tmpvar_22.x * (half3)(v_23)) + (tmpvar_22.y * (half3)(v_24)))
    + 
-    (tmpvar_22.z * (half3)v_25)
-  )) * tmpvar_5));
-  half3 tmpvar_26;
+    (tmpvar_22.z * (half3)(v_25))
+  ))) * tmpvar_5));
+  half3 tmpvar_26 = 0;
   tmpvar_26 = normalize(lightDir_1);
   lightDir_1 = tmpvar_26;
-  half3 lightColor_27;
+  half3 lightColor_27 = 0;
   lightColor_27 = (_ShadowMapTexture.sample(_mtlsmp__ShadowMapTexture, ((float2)(_mtl_i.xlv_TEXCOORD5).xy / (float)(_mtl_i.xlv_TEXCOORD5).w)).x * ((
-    ((half)8.0 * tmpvar_19.w)
+    ((half)(8.0) * tmpvar_19.w)
    * tmpvar_19.xyz) * dot (
-    clamp (((half3)(tmpvar_21 * (float3)tmpvar_9)), (half)0.0, (half)1.0)
+    clamp (((half3)(tmpvar_21 * (float3)(tmpvar_9))), (half)0.0, (half)1.0)
   , tmpvar_22)));
-  float3 viewDir_28;
+  float3 viewDir_28 = 0;
   viewDir_28 = -(tmpvar_11);
-  half3 tmpvar_29;
-  tmpvar_29 = normalize(((half3)((float3)tmpvar_26 + viewDir_28)));
-  half tmpvar_30;
+  half3 tmpvar_29 = 0;
+  tmpvar_29 = normalize(((half3)((float3)(tmpvar_26) + viewDir_28)));
+  half tmpvar_30 = 0;
   tmpvar_30 = max ((half)0.0, dot (tmpvar_10, tmpvar_26));
-  half tmpvar_31;
+  half tmpvar_31 = 0;
   tmpvar_31 = max ((half)0.0, dot (tmpvar_10, tmpvar_29));
-  half tmpvar_32;
+  half tmpvar_32 = 0;
   tmpvar_32 = max ((half)0.0, ((half)dot ((float3)tmpvar_10, viewDir_28)));
-  half tmpvar_33;
+  half tmpvar_33 = 0;
   tmpvar_33 = max ((half)0.0, ((half)dot (viewDir_28, (float3)tmpvar_29)));
-  half VdotH_34;
-  VdotH_34 = (tmpvar_33 + (half)1e-05);
-  half tmpvar_35;
+  half VdotH_34 = 0;
+  VdotH_34 = (tmpvar_33 + (half)(1e-05));
+  half tmpvar_35 = 0;
   tmpvar_35 = (((half)1.0/((
     pow (tmpvar_14, (half)4.0)
-   + (half)1e-05))) - (half)2.0);
-  half tmpvar_36;
-  half tmpvar_37;
+   + (half)(1e-05)))) - (half)(2.0));
+  half tmpvar_36 = 0;
+  half tmpvar_37 = 0;
   tmpvar_37 = max ((half)0.0, dot (tmpvar_26, tmpvar_29));
-  tmpvar_36 = ((half)0.5 + (((half)2.0 * tmpvar_37) * (tmpvar_37 * tmpvar_14)));
-  half4 tmpvar_38;
+  tmpvar_36 = ((half)(0.5) + (((half)(2.0) * tmpvar_37) * (tmpvar_37 * tmpvar_14)));
+  half4 tmpvar_38 = 0;
   tmpvar_38.xyz = (((
-    (min ((((half3)(_mtl_u._Color.xyz * (float3)_MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz)) * ((half)2.0 * _DetailAlbedoMap.sample(_mtlsmp__DetailAlbedoMap, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).xyz)), ((half3)float3(1.0, 1.0, 1.0) - tmpvar_13)) * (((
-      ((half)1.0 + ((tmpvar_36 - (half)1.0) * pow (((half)1.00001 - tmpvar_30), (half)5.0)))
+    (min ((((half3)(_mtl_u._Color.xyz * (float3)(_MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz))) * ((half)(2.0) * _DetailAlbedoMap.sample(_mtlsmp__DetailAlbedoMap, (float2)(_mtl_i.xlv_TEXCOORD0.zw)).xyz)), ((half3)(float3(1.0, 1.0, 1.0)) - tmpvar_13)) * (((
+      ((half)(1.0) + ((tmpvar_36 - (half)(1.0)) * pow (((half)(1.00001) - tmpvar_30), (half)5.0)))
      * 
-      ((half)1.0 + ((tmpvar_36 - (half)1.0) * pow (((half)1.00001 - tmpvar_32), (half)5.0)))
+      ((half)(1.0) + ((tmpvar_36 - (half)(1.0)) * pow (((half)(1.00001) - tmpvar_32), (half)5.0)))
     ) * tmpvar_30) * lightColor_27))
    + 
     (tmpvar_12.xyz * (env_2 + (lightColor_27 * max ((half)0.0, 
       ((((tmpvar_13 + 
-        (((half)1.0 - tmpvar_13) * pow (abs(((half)1.0 - tmpvar_33)), (half)5.0))
+        (((half)(1.0) - tmpvar_13) * pow (abs(((half)(1.0) - tmpvar_33)), (half)5.0))
       ) * min ((half)1.0, 
-        min (((((half)2.0 * tmpvar_31) * tmpvar_32) / VdotH_34), ((((half)2.0 * tmpvar_31) * tmpvar_30) / VdotH_34))
+        min (((((half)(2.0) * tmpvar_31) * tmpvar_32) / VdotH_34), ((((half)(2.0) * tmpvar_31) * tmpvar_30) / VdotH_34))
       )) * max ((half)0.0, (
         pow (tmpvar_31, tmpvar_35)
        * 
-        ((tmpvar_35 + (half)1.0) / (half)6.28318)
-      ))) / (((half)4.0 * tmpvar_32) + (half)1e-05))
+        ((tmpvar_35 + (half)(1.0)) / (half)(6.28318))
+      ))) / (((half)(4.0) * tmpvar_32) + (half)(1e-05)))
     ))))
   ) + (
-    ((((half)1.0 - dot (tmpvar_12.xyz, (half3)float3(0.299, 0.587, 0.114))) * ((half)1.0 - tmpvar_14)) * pow (abs(((half)1.0 - tmpvar_32)), (half)5.0))
-   * env_2)) + ((half3)((float3)_SelfIllum.sample(_mtlsmp__SelfIllum, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz * _mtl_u._SelfIllumScale)));
-  tmpvar_38.w = ((half)((float)_AlphaMap.sample(_mtlsmp__AlphaMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).w * _mtl_u._Color.w));
-  half4 tmpvar_39;
+    ((((half)(1.0) - dot (tmpvar_12.xyz, (half3)float3(0.299, 0.587, 0.114))) * ((half)(1.0) - tmpvar_14)) * pow (abs(((half)(1.0) - tmpvar_32)), (half)5.0))
+   * env_2)) + ((half3)((float3)(_SelfIllum.sample(_mtlsmp__SelfIllum, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).xyz) * _mtl_u._SelfIllumScale)));
+  tmpvar_38.w = ((half)((float)(_AlphaMap.sample(_mtlsmp__AlphaMap, (float2)(_mtl_i.xlv_TEXCOORD0.xy)).w) * _mtl_u._Color.w));
+  half4 tmpvar_39 = 0;
   tmpvar_39 = tmpvar_38;
   _mtl_o._fragData = tmpvar_39;
   return _mtl_o;

+ 21 - 21
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/z-unity-spot-outES3Metal.txt

@@ -20,44 +20,44 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(2)]], sampler _mtlsmp__MainTex [[sampler(2)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half atten_2;
-  half4 lightCoord_3;
-  float3 tmpvar_4;
+  half4 c_1 = 0;
+  half atten_2 = 0;
+  half4 lightCoord_3 = 0;
+  float3 tmpvar_4 = 0;
   tmpvar_4 = normalize((_mtl_u._WorldSpaceLightPos0.xyz - _mtl_i.xlv_TEXCOORD2));
-  half3 tmpvar_5;
-  half tmpvar_6;
-  half4 c_7;
-  half4 tmpvar_8;
+  half3 tmpvar_5 = 0;
+  half tmpvar_6 = 0;
+  half4 c_7 = 0;
+  half4 tmpvar_8 = 0;
   tmpvar_8 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
   c_7 = tmpvar_8;
   tmpvar_5 = c_7.xyz;
   tmpvar_6 = c_7.w;
-  float4 tmpvar_9;
+  float4 tmpvar_9 = 0;
   tmpvar_9.w = 1.0;
   tmpvar_9.xyz = _mtl_i.xlv_TEXCOORD2;
-  float4 tmpvar_10;
-  tmpvar_10 = ((float4)(_mtl_u._LightMatrix0 * (half4)tmpvar_9));
+  float4 tmpvar_10 = 0;
+  tmpvar_10 = ((float4)(_mtl_u._LightMatrix0 * (half4)(tmpvar_9)));
   lightCoord_3 = half4(tmpvar_10);
-  half4 tmpvar_11;
-  half2 P_12;
-  P_12 = ((lightCoord_3.xy / lightCoord_3.w) + (half)0.5);
+  half4 tmpvar_11 = 0;
+  half2 P_12 = 0;
+  P_12 = ((lightCoord_3.xy / lightCoord_3.w) + (half)(0.5));
   tmpvar_11 = _LightTexture0.sample(_mtlsmp__LightTexture0, (float2)(P_12));
-  half tmpvar_13;
+  half tmpvar_13 = 0;
   tmpvar_13 = dot (lightCoord_3.xyz, lightCoord_3.xyz);
-  half4 tmpvar_14;
+  half4 tmpvar_14 = 0;
   tmpvar_14 = _LightTextureB0.sample(_mtlsmp__LightTextureB0, (float2)(half2(tmpvar_13)));
-  half tmpvar_15;
+  half tmpvar_15 = 0;
   tmpvar_15 = ((half(
-    (lightCoord_3.z > (half)0.0)
+    (lightCoord_3.z > (half)(0.0))
   ) * tmpvar_11.w) * tmpvar_14.w);
   atten_2 = tmpvar_15;
-  half3 lightDir_16;
+  half3 lightDir_16 = 0;
   lightDir_16 = half3(tmpvar_4);
-  half4 c_17;
+  half4 c_17 = 0;
   c_17.xyz = ((tmpvar_5 * _mtl_u._LightColor0.xyz) * ((
     max ((half)0.0, dot (_mtl_i.xlv_TEXCOORD1, lightDir_16))
-   * atten_2) * (half)2.0));
+   * atten_2) * (half)(2.0)));
   c_17.w = tmpvar_6;
   c_1.xyz = c_17.xyz;
   c_1.w = half(0.0);

+ 11 - 11
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/zun-MobileBumpSpec-outES3Metal.txt

@@ -19,23 +19,23 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _MainTex [[texture(1)]], sampler _mtlsmp__MainTex [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 c_1;
-  half4 tmpvar_2;
+  half4 c_1 = 0;
+  half4 tmpvar_2 = 0;
   tmpvar_2 = _MainTex.sample(_mtlsmp__MainTex, (float2)(_mtl_i.xlv_TEXCOORD0));
-  half3 tmpvar_3;
-  tmpvar_3 = ((_BumpMap.sample(_mtlsmp__BumpMap, (float2)(_mtl_i.xlv_TEXCOORD0)).xyz * (half)2.0) - (half)1.0);
-  half3 halfDir_4;
+  half3 tmpvar_3 = 0;
+  tmpvar_3 = ((_BumpMap.sample(_mtlsmp__BumpMap, (float2)(_mtl_i.xlv_TEXCOORD0)).xyz * (half)(2.0)) - (half)(1.0));
+  half3 halfDir_4 = 0;
   halfDir_4 = _mtl_i.xlv_TEXCOORD1;
-  half4 c_5;
-  half spec_6;
-  half tmpvar_7;
+  half4 c_5 = 0;
+  half spec_6 = 0;
+  half tmpvar_7 = 0;
   tmpvar_7 = max ((half)0.0, dot (tmpvar_3, halfDir_4));
-  half tmpvar_8;
-  tmpvar_8 = pow (tmpvar_7, (_mtl_u._Shininess * (half)128.0));
+  half tmpvar_8 = 0;
+  tmpvar_8 = pow (tmpvar_7, (_mtl_u._Shininess * (half)(128.0)));
   spec_6 = (tmpvar_8 * tmpvar_2.w);
   c_5.xyz = (((
     (tmpvar_2.xyz * max ((half)0.0, dot (tmpvar_3, _mtl_i.xlv_TEXCOORD2)))
-   + spec_6) * _mtl_u._LightColor0.xyz) * (half)2.0);
+   + spec_6) * _mtl_u._LightColor0.xyz) * (half)(2.0));
   c_5.w = half(0.0);
   c_1.w = c_5.w;
   c_1.xyz = (c_5.xyz + (tmpvar_2.xyz * _mtl_i.xlv_TEXCOORD3));

+ 24 - 24
third/bgfx/3rdparty/glsl-optimizer/tests/fragment/zun-SSAO24-outES3Metal.txt

@@ -18,23 +18,23 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   ,   texture2d<half> _RandomTexture [[texture(1)]], sampler _mtlsmp__RandomTexture [[sampler(1)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half tmpvar_1;
-  float2 tmpvar_2;
+  half tmpvar_1 = 0;
+  float2 tmpvar_2 = 0;
   tmpvar_2 = _mtl_i.xlv_TEXCOORD0;
-  float occ_4;
-  float scale_5;
-  float depth_6;
-  float3 viewNorm_7;
-  half3 randN_8;
-  half3 tmpvar_9;
-  tmpvar_9 = ((_RandomTexture.sample(_mtlsmp__RandomTexture, (float2)(_mtl_i.xlv_TEXCOORD1)).xyz * (half)2.0) - (half)1.0);
+  float occ_4 = 0;
+  float scale_5 = 0;
+  float depth_6 = 0;
+  float3 viewNorm_7 = 0;
+  half3 randN_8 = 0;
+  half3 tmpvar_9 = 0;
+  tmpvar_9 = ((_RandomTexture.sample(_mtlsmp__RandomTexture, (float2)(_mtl_i.xlv_TEXCOORD1)).xyz * (half)(2.0)) - (half)(1.0));
   randN_8 = tmpvar_9;
-  float4 tmpvar_10;
+  float4 tmpvar_10 = 0;
   tmpvar_10 = _CameraDepthNormalsTexture.sample(_mtlsmp__CameraDepthNormalsTexture, (float2)(_mtl_i.xlv_TEXCOORD0));
-  float3 n_11;
-  float3 tmpvar_12;
+  float3 n_11 = 0;
+  float3 tmpvar_12 = 0;
   tmpvar_12 = ((tmpvar_10.xyz * float3(3.5554, 3.5554, 0.0)) + float3(-1.7777, -1.7777, 1.0));
-  float tmpvar_13;
+  float tmpvar_13 = 0;
   tmpvar_13 = (2.0 / dot (tmpvar_12, tmpvar_12));
   n_11.xy = (tmpvar_13 * tmpvar_12.xy);
   n_11.z = (tmpvar_13 - 1.0);
@@ -43,29 +43,29 @@ fragment xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]]
   scale_5 = (_mtl_u._Params.x / depth_6);
   occ_4 = 0.0;
   for (int s_3 = 0; s_3 < 8; s_3++) {
-    half3 randomDir_14;
-    float3 tmpvar_15;
-    float3 I_16;
+    half3 randomDir_14 = 0;
+    float3 tmpvar_15 = 0;
+    float3 I_16 = 0;
     I_16 = _xlat_mtl_const1[s_3];
-    tmpvar_15 = (I_16 - (float3)((half)2.0 * ((half3)(
+    tmpvar_15 = (I_16 - (float3)(((half)(2.0) * ((half3)(
       dot ((float3)randN_8, I_16)
-     * (float3)randN_8))));
+     * (float3)(randN_8))))));
     randomDir_14 = half3(tmpvar_15);
-    float tmpvar_17;
+    float tmpvar_17 = 0;
     tmpvar_17 = dot (viewNorm_7, (float3)randomDir_14);
-    half tmpvar_18;
+    half tmpvar_18 = 0;
     if ((tmpvar_17 < 0.0)) {
       tmpvar_18 = half(1.0);
     } else {
       tmpvar_18 = half(-1.0);
     };
     randomDir_14 = (randomDir_14 * -(tmpvar_18));
-    randomDir_14 = half3(((float3)randomDir_14 + (viewNorm_7 * 0.3)));
-    float tmpvar_19;
+    randomDir_14 = half3(((float3)(randomDir_14) + (viewNorm_7 * 0.3)));
+    float tmpvar_19 = 0;
     tmpvar_19 = clamp (((depth_6 - 
-      ((float)randomDir_14.z * _mtl_u._Params.x)
+      ((float)(randomDir_14.z) * _mtl_u._Params.x)
     ) - (
-      dot (_CameraDepthNormalsTexture.sample(_mtlsmp__CameraDepthNormalsTexture, (float2)((tmpvar_2 + ((float2)randomDir_14.xy * scale_5)))).zw, float2(1.0, 0.00392157))
+      dot (_CameraDepthNormalsTexture.sample(_mtlsmp__CameraDepthNormalsTexture, (float2)((tmpvar_2 + ((float2)(randomDir_14.xy) * scale_5)))).zw, float2(1.0, 0.00392157))
      * _mtl_u._ProjectionParams.z)), 0.0, 1.0);
     if ((tmpvar_19 > _mtl_u._Params.y)) {
       occ_4 = (occ_4 + pow ((1.0 - tmpvar_19), _mtl_u._Params.z));

+ 32 - 32
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/MF-GodRays-outES3Metal.txt

@@ -35,46 +35,46 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float3 tmpvar_1;
-  float4 tmpvar_2;
+  float3 tmpvar_1 = 0;
+  float4 tmpvar_2 = 0;
   tmpvar_1 = float3(_mtl_i._inNormal);
   tmpvar_2 = float4(_mtl_i._color);
-  half4 tmpvar_3;
-  float noiseWave_4;
-  float noiseTime_5;
-  float wave_6;
-  float time_7;
-  float3 BBLocalPos_8;
-  float3 localDir_9;
-  float3 centerLocal_10;
-  float3 centerOffs_11;
-  float3 tmpvar_12;
+  half4 tmpvar_3 = 0;
+  float noiseWave_4 = 0;
+  float noiseTime_5 = 0;
+  float wave_6 = 0;
+  float time_7 = 0;
+  float3 BBLocalPos_8 = 0;
+  float3 localDir_9 = 0;
+  float3 centerLocal_10 = 0;
+  float3 centerOffs_11 = 0;
+  float3 tmpvar_12 = 0;
   tmpvar_12.z = 0.0;
   tmpvar_12.xy = (float2(0.5, 0.5) - tmpvar_2.xy);
   centerOffs_11 = (tmpvar_12 * _mtl_i._uv1.xyy);
   centerLocal_10 = (_mtl_i._inVertex.xyz + centerOffs_11);
-  float4 tmpvar_13;
+  float4 tmpvar_13 = 0;
   tmpvar_13.w = 1.0;
   tmpvar_13.xyz = _mtl_u._WorldSpaceCameraPos;
   localDir_9 = ((_mtl_u._World2Object * tmpvar_13).xyz - centerLocal_10);
   localDir_9.y = (localDir_9.y * _mtl_u._VerticalBillboarding);
-  float tmpvar_14;
+  float tmpvar_14 = 0;
   tmpvar_14 = sqrt(dot (localDir_9, localDir_9));
-  float3 dir_15;
+  float3 dir_15 = 0;
   dir_15 = (localDir_9 / tmpvar_14);
-  float tmpvar_16;
+  float tmpvar_16 = 0;
   tmpvar_16 = abs(dir_15.y);
-  float3 tmpvar_17;
+  float3 tmpvar_17 = 0;
   if ((tmpvar_16 > 0.999)) {
     tmpvar_17 = float3(0.0, 0.0, 1.0);
   } else {
     tmpvar_17 = float3(0.0, 1.0, 0.0);
   };
-  float3 tmpvar_18;
+  float3 tmpvar_18 = 0;
   tmpvar_18 = normalize(((tmpvar_17.yzx * dir_15.zxy) - (tmpvar_17.zxy * dir_15.yzx)));
-  float3 tmpvar_19;
+  float3 tmpvar_19 = 0;
   tmpvar_19 = ((dir_15.yzx * tmpvar_18.zxy) - (dir_15.zxy * tmpvar_18.yzx));
-  float tmpvar_20;
+  float tmpvar_20 = 0;
   tmpvar_20 = min ((max (
     (tmpvar_14 - _mtl_u._SizeGrowStartDist)
   , 0.0) / _mtl_u._SizeGrowEndDist), 1.0);
@@ -92,23 +92,23 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
     (_mtl_u._MaxGrowSize * tmpvar_2.w)
   )));
   time_7 = (_mtl_u._Time.y + (_mtl_u._BlinkingTimeOffsScale * tmpvar_2.z));
-  float y_21;
+  float y_21 = 0;
   y_21 = (_mtl_u._TimeOnDuration + _mtl_u._TimeOffDuration);
-  float tmpvar_22;
+  float tmpvar_22 = 0;
   tmpvar_22 = (time_7 / y_21);
-  float tmpvar_23;
+  float tmpvar_23 = 0;
   tmpvar_23 = (fract(abs(tmpvar_22)) * y_21);
-  float tmpvar_24;
+  float tmpvar_24 = 0;
   if ((tmpvar_22 >= 0.0)) {
     tmpvar_24 = tmpvar_23;
   } else {
     tmpvar_24 = -(tmpvar_23);
   };
-  float tmpvar_25;
+  float tmpvar_25 = 0;
   tmpvar_25 = clamp ((tmpvar_24 / (_mtl_u._TimeOnDuration * 0.25)), 0.0, 1.0);
-  float edge0_26;
+  float edge0_26 = 0;
   edge0_26 = (_mtl_u._TimeOnDuration * 0.75);
-  float tmpvar_27;
+  float tmpvar_27 = 0;
   tmpvar_27 = clamp (((tmpvar_24 - edge0_26) / (_mtl_u._TimeOnDuration - edge0_26)), 0.0, 1.0);
   wave_6 = ((tmpvar_25 * (tmpvar_25 * 
     (3.0 - (2.0 * tmpvar_25))
@@ -123,19 +123,19 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
       (noiseTime_5 * 0.6366)
      + 56.7272))) + 0.5)
   )) + (1.0 - _mtl_u._NoiseAmount));
-  float tmpvar_28;
+  float tmpvar_28 = 0;
   if ((_mtl_u._NoiseAmount < 0.01)) {
     tmpvar_28 = wave_6;
   } else {
     tmpvar_28 = noiseWave_4;
   };
   wave_6 = (tmpvar_28 + _mtl_u._Bias);
-  float4 tmpvar_29;
+  float4 tmpvar_29 = 0;
   tmpvar_29.w = 1.0;
   tmpvar_29.xyz = BBLocalPos_8;
-  float ffadeout_30;
-  float nfadeout_31;
-  float tmpvar_32;
+  float ffadeout_30 = 0;
+  float nfadeout_31 = 0;
+  float tmpvar_32 = 0;
   tmpvar_32 = clamp ((tmpvar_14 / _mtl_u._FadeOutDistNear), 0.0, 1.0);
   ffadeout_30 = (1.0 - clamp ((
     max ((tmpvar_14 - _mtl_u._FadeOutDistFar), 0.0)

+ 15 - 15
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/bug-swizzle-lhs-cast-outES3Metal.txt

@@ -17,33 +17,33 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float3 viewDir_1;
-  float3 tmpvar_2;
-  float4 tmpvar_3;
+  float3 viewDir_1 = 0;
+  float3 tmpvar_2 = 0;
+  float4 tmpvar_3 = 0;
   tmpvar_3.w = 1.0;
   tmpvar_3.xyz = _mtl_u._WorldSpaceCameraPos;
   viewDir_1 = normalize(((_mtl_u._World2Object * tmpvar_3).xyz - _mtl_i._glesVertex.xyz));
-  half tmpvar_4;
-  float tmpvar_5;
+  half tmpvar_4 = 0;
+  float tmpvar_5 = 0;
   tmpvar_5 = clamp (dot (viewDir_1, -(_mtl_u._TerrainTreeLightDirections[0])), 0.0, 1.0);
   tmpvar_4 = half(tmpvar_5);
-  float3 tmpvar_6;
+  float3 tmpvar_6 = 0;
   tmpvar_6.yz = tmpvar_2.yz;
-  tmpvar_6.x = float((tmpvar_4 * (half)2.0));
-  half tmpvar_7;
-  float tmpvar_8;
+  tmpvar_6.x = float((tmpvar_4 * (half)(2.0)));
+  half tmpvar_7 = 0;
+  float tmpvar_8 = 0;
   tmpvar_8 = clamp (dot (viewDir_1, -(_mtl_u._TerrainTreeLightDirections[1])), 0.0, 1.0);
   tmpvar_7 = half(tmpvar_8);
-  float3 tmpvar_9;
+  float3 tmpvar_9 = 0;
   tmpvar_9.xz = tmpvar_6.xz;
-  tmpvar_9.y = float((tmpvar_7 * (half)2.0));
-  half tmpvar_10;
-  float tmpvar_11;
+  tmpvar_9.y = float((tmpvar_7 * (half)(2.0)));
+  half tmpvar_10 = 0;
+  float tmpvar_11 = 0;
   tmpvar_11 = clamp (dot (viewDir_1, -(_mtl_u._TerrainTreeLightDirections[2])), 0.0, 1.0);
   tmpvar_10 = half(tmpvar_11);
-  float3 tmpvar_12;
+  float3 tmpvar_12 = 0;
   tmpvar_12.xy = tmpvar_9.xy;
-  tmpvar_12.z = float((tmpvar_10 * (half)2.0));
+  tmpvar_12.z = float((tmpvar_10 * (half)(2.0)));
   tmpvar_2 = tmpvar_12;
   _mtl_o.gl_Position = (_mtl_u.glstate_matrix_mvp * _mtl_i._glesVertex);
   _mtl_o.xlv_TEXCOORD2 = tmpvar_12;

+ 2 - 2
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/builtin-vars-outES3Metal.txt

@@ -16,12 +16,12 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   , uint gl_VertexID [[vertex_id]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float3 p_1;
+  float3 p_1 = 0;
   p_1.z = _mtl_i._inPos.z;
   p_1.x = (_mtl_i._inPos.x + float(gl_VertexID));
   p_1.y = (_mtl_i._inPos.y + float(gl_InstanceID));
   p_1 = (p_1 + _mtl_i._inNor);
-  float4 tmpvar_2;
+  float4 tmpvar_2 = 0;
   tmpvar_2.w = 1.0;
   tmpvar_2.xyz = p_1;
   _mtl_o.gl_Position = tmpvar_2;

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/inputs-outES3Metal.txt

@@ -17,14 +17,14 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half2 tmpvar_1;
+  half2 tmpvar_1 = 0;
   tmpvar_1 = half2(_mtl_i._glesMultiTexCoord0.xy);
-  float4 tmpvar_2;
+  float4 tmpvar_2 = 0;
   tmpvar_2.xyz = normalize(_mtl_i._glesTANGENT.xyz);
   tmpvar_2.w = _mtl_i._glesTANGENT.w;
-  half4 tmpvar_3;
-  tmpvar_3.xy = (tmpvar_1 * (half)0.3);
-  tmpvar_3.xyz = half3(((float3)tmpvar_3.xyz + ((tmpvar_2.xyz * 0.5) + 0.5)));
+  half4 tmpvar_3 = 0;
+  tmpvar_3.xy = (tmpvar_1 * (half)(0.3));
+  tmpvar_3.xyz = half3(((float3)(tmpvar_3.xyz) + ((tmpvar_2.xyz * 0.5) + 0.5)));
   tmpvar_3.w = half(0.0);
   _mtl_o.gl_Position = (_mtl_u.glstate_matrix_mvp * _mtl_i._glesVertex);
   _mtl_o.xlv_TEXCOORD0 = tmpvar_1;

+ 6 - 6
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4-outES3Metal.txt

@@ -48,12 +48,12 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-float4 phase0_Output0_1;
-float4 Temp_0_2;
-float4 Temp_1_3;
-float4 Temp_2_4;
-float4 Temp_3_5;
-int4 Temp_int_0_6;
+float4 phase0_Output0_1 = 0;
+float4 Temp_0_2 = 0;
+float4 Temp_1_3 = 0;
+float4 Temp_2_4 = 0;
+float4 Temp_3_5 = 0;
+int4 Temp_int_0_6 = 0;
   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);

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-for-withvec4inductorW-outES3Metal.txt

@@ -28,11 +28,11 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-float4 phase0_Output2_1;
-float4 Temp_2_2;
-float4 Temp_3_3;
-int4 Temp_int_0_4;
-int4 Temp_int_1_5;
+float4 phase0_Output2_1 = 0;
+float4 Temp_2_2 = 0;
+float4 Temp_3_3 = 0;
+int4 Temp_int_0_4 = 0;
+int4 Temp_int_1_5 = 0;
   Temp_int_0_4 = as_type<int4>((_mtl_i.in_POSITION0.yyyy * _mtl_u.glstate_matrix_mvp[1]));
   Temp_int_0_4 = as_type<int4>(((_mtl_u.glstate_matrix_mvp[0] * _mtl_i.in_POSITION0.xxxx) + as_type<float4>(Temp_int_0_4)));
   Temp_int_0_4 = as_type<int4>(((_mtl_u.glstate_matrix_mvp[2] * _mtl_i.in_POSITION0.zzzz) + as_type<float4>(Temp_int_0_4)));

+ 15 - 15
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-forlimitbreak-outES3Metal.txt

@@ -17,38 +17,38 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float3 tmpvar_1;
+  float3 tmpvar_1 = 0;
   tmpvar_1 = _mtl_i._glesVertex.xyz;
-  int j_2;
-  int j_3;
-  int il_4;
-  half3 lcolor_5;
-  half3 eyeNormal_6;
-  half4 color_7;
-  half4 tmpvar_8;
+  int j_2 = 0;
+  int j_3 = 0;
+  int il_4 = 0;
+  half3 lcolor_5 = 0;
+  half3 eyeNormal_6 = 0;
+  half4 color_7 = 0;
+  half4 tmpvar_8 = 0;
   color_7 = half4(float4(0.0, 0.0, 0.0, 1.1));
   eyeNormal_6 = half3(_mtl_i._glesNormal);
   lcolor_5 = half3(float3(0.0, 0.0, 0.0));
   il_4 = 0;
   while (true) {
-    float tmpvar_9;
+    float tmpvar_9 = 0;
     tmpvar_9 = min (8.0, float(_mtl_u.unity_VertexLightParams.x));
     if ((float(il_4) >= tmpvar_9)) {
       break;
     };
-    float3 tmpvar_10;
+    float3 tmpvar_10 = 0;
     tmpvar_10 = _mtl_u.unity_LightPosition[il_4].xyz;
-    half3 dirToLight_11;
+    half3 dirToLight_11 = 0;
     dirToLight_11 = half3(tmpvar_10);
     lcolor_5 = (lcolor_5 + min ((
       (max (dot (eyeNormal_6, dirToLight_11), (half)0.0) * _mtl_u.unity_LightColor[il_4].xyz)
-     * (half)0.5), (half3)float3(1.0, 1.0, 1.0)));
+     * (half)(0.5)), (half3)float3(1.0, 1.0, 1.0)));
     il_4++;
   };
   color_7.xyz = lcolor_5;
   j_3 = 0;
   while (true) {
-    float tmpvar_12;
+    float tmpvar_12 = 0;
     tmpvar_12 = min (float(_mtl_u.unity_VertexLightParams.y), 4.0);
     if ((j_3 >= int(tmpvar_12))) {
       break;
@@ -58,7 +58,7 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   };
   j_2 = 0;
   while (true) {
-    int tmpvar_13;
+    int tmpvar_13 = 0;
     tmpvar_13 = min (_mtl_u.unity_VertexLightParams.y, 4);
     if ((j_2 >= tmpvar_13)) {
       break;
@@ -67,7 +67,7 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
     j_2++;
   };
   tmpvar_8 = color_7;
-  float4 tmpvar_14;
+  float4 tmpvar_14 = 0;
   tmpvar_14.w = 1.0;
   tmpvar_14.xyz = tmpvar_1;
   _mtl_o.xlv_COLOR0 = tmpvar_8;

+ 19 - 19
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/loops-forvarious-outES3Metal.txt

@@ -16,31 +16,31 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float4 l_1_1;
-  float4 l_2;
-  half4 tmpvar_3;
-  half4 tmpvar_4;
+  float4 l_1_1 = 0;
+  float4 l_2 = 0;
+  half4 tmpvar_3 = 0;
+  half4 tmpvar_4 = 0;
   tmpvar_3 = half4((_mtl_u.UNITY_MATRIX_MVP * _mtl_i._inVertex));
   tmpvar_4 = half4(_mtl_u.unity_LightColor[0]);
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[1]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[0]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[1]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[2]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[3]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[3]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[2]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[1]));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[0]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[1]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[0]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[1]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[2]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[3]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[3]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[2]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[1]));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[0]));
   l_2 = (_mtl_u.unity_LightColor[0] * _mtl_u.unity_LightAtten[0].x);
-  tmpvar_4 = half4(((float4)tmpvar_4 + l_2));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + l_2));
   l_2 = (_mtl_u.unity_LightColor[1] * _mtl_u.unity_LightAtten[1].x);
-  tmpvar_4 = half4(((float4)tmpvar_4 + l_2));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + l_2));
   l_1_1 = (_mtl_u.unity_LightColor[0] * _mtl_u.unity_LightAtten[0].z);
-  tmpvar_4 = half4(((float4)tmpvar_4 + l_1_1));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + l_1_1));
   l_1_1 = (_mtl_u.unity_LightColor[1] * _mtl_u.unity_LightAtten[1].z);
-  tmpvar_4 = half4(((float4)tmpvar_4 + l_1_1));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[1].x));
-  tmpvar_4 = half4(((float4)tmpvar_4 + _mtl_u.unity_LightColor[2].x));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + l_1_1));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[1].x));
+  tmpvar_4 = half4(((float4)(tmpvar_4) + _mtl_u.unity_LightColor[2].x));
   _mtl_o.gl_Position = float4(tmpvar_3);
   _mtl_o.xlv_TEXCOORD0 = tmpvar_4;
   return _mtl_o;

+ 3 - 3
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/matrix-casts-outES3Metal.txt

@@ -27,13 +27,13 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   float4x4 htof4_3;
   half2x2 ftoh2_4;
   half4x4 ftoh4_5;
-  float4 r_6;
+  float4 r_6 = 0;
   r_6.yzw = float3(0.0, 0.0, 0.0);
   ftoh4_5 = _xlcast_half4x4(_mtl_u.uniMat4F);
   r_6.x = float(ftoh4_5[0].x);
-  r_6.x = (r_6.x + (float)ftoh4_5[0].x);
+  r_6.x = (r_6.x + (float)(ftoh4_5[0].x));
   ftoh2_4 = _xlcast_half2x2(_mtl_u.uniMat2F);
-  r_6.x = (r_6.x + (float)ftoh2_4[0].x);
+  r_6.x = (r_6.x + (float)(ftoh2_4[0].x));
   htof4_3 = _xlcast_float4x4(_mtl_u.uniMat4H);
   r_6.x = (r_6.x + htof4_3[0].x);
   htof3_2 = _xlcast_float3x3(_mtl_u.uniMat3H);

+ 15 - 15
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/opt-matrix-transpose-mul-outES3Metal.txt

@@ -23,21 +23,21 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half3 lightDir_1;
-  float3 worldN_2;
-  half3 tmpvar_3;
-  half3 tmpvar_4;
-  half3 tmpvar_5;
+  half3 lightDir_1 = 0;
+  float3 worldN_2 = 0;
+  half3 tmpvar_3 = 0;
+  half3 tmpvar_4 = 0;
+  half3 tmpvar_5 = 0;
   float3x3 tmpvar_6;
   tmpvar_6[0] = _mtl_u._Object2World[0].xyz;
   tmpvar_6[1] = _mtl_u._Object2World[1].xyz;
   tmpvar_6[2] = _mtl_u._Object2World[2].xyz;
-  half3 tmpvar_7;
-  tmpvar_7 = ((half3)(tmpvar_6 * (float3)_mtl_i.attrNormal));
+  half3 tmpvar_7 = 0;
+  tmpvar_7 = ((half3)(tmpvar_6 * (float3)(_mtl_i.attrNormal)));
   worldN_2 = float3(tmpvar_7);
   tmpvar_5 = half3(worldN_2);
-  half3 tmpvar_8;
-  half3 tmpvar_9;
+  half3 tmpvar_8 = 0;
+  half3 tmpvar_9 = 0;
   tmpvar_8 = _mtl_i.attrTangent.xyz;
   tmpvar_9 = (((_mtl_i.attrNormal.yzx * _mtl_i.attrTangent.zxy) - (_mtl_i.attrNormal.zxy * _mtl_i.attrTangent.yzx)) * _mtl_i.attrTangent.w);
   half3x3 tmpvar_10;
@@ -50,16 +50,16 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   tmpvar_10[2].x = tmpvar_8.z;
   tmpvar_10[2].y = tmpvar_9.z;
   tmpvar_10[2].z = _mtl_i.attrNormal.z;
-  float3 tmpvar_11;
-  tmpvar_11 = ((float3)(tmpvar_10 * (half3)(_mtl_u._World2Object * (float4)_mtl_u._WorldSpaceLightPos0).xyz));
+  float3 tmpvar_11 = 0;
+  tmpvar_11 = ((float3)(tmpvar_10 * (half3)((_mtl_u._World2Object * (float4)(_mtl_u._WorldSpaceLightPos0)).xyz)));
   lightDir_1 = half3(tmpvar_11);
   tmpvar_3 = lightDir_1;
-  float4 tmpvar_12;
+  float4 tmpvar_12 = 0;
   tmpvar_12.w = 1.0;
   tmpvar_12.xyz = _mtl_u._WorldSpaceCameraPos;
-  float3 tmpvar_13;
-  tmpvar_13 = normalize(((float3)lightDir_1 + normalize(
-    ((float3)(tmpvar_10 * (half3)(((_mtl_u._World2Object * tmpvar_12).xyz * _mtl_u.unity_Scale.w) - _mtl_i.attrVertex.xyz)))
+  float3 tmpvar_13 = 0;
+  tmpvar_13 = normalize(((float3)(lightDir_1) + normalize(
+    ((float3)(tmpvar_10 * (half3)((((_mtl_u._World2Object * tmpvar_12).xyz * _mtl_u.unity_Scale.w) - _mtl_i.attrVertex.xyz))))
   )));
   tmpvar_4 = half3(tmpvar_13);
   _mtl_o.gl_Position = (_mtl_u.glstate_matrix_mvp * _mtl_i.attrVertex);

+ 2 - 2
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/swizzle-casts-outES3Metal.txt

@@ -16,9 +16,9 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half4 tmpvar_1;
+  half4 tmpvar_1 = 0;
   tmpvar_1 = half4(_mtl_i._glesMultiTexCoord0);
-  float4 tmpvar_2;
+  float4 tmpvar_2 = 0;
   tmpvar_2 = (_mtl_u.glstate_matrix_mvp * _mtl_i._glesVertex);
   tmpvar_2.z = (tmpvar_2.z + clamp ((_mtl_u.unity_LightShadowBias.x / tmpvar_2.w), 0.0, 1.0));
   tmpvar_2.z = mix (tmpvar_2.z, max (tmpvar_2.z, -(tmpvar_2.w)), _mtl_u.unity_LightShadowBias.y);

+ 2 - 2
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/types-outES3Metal.txt

@@ -18,8 +18,8 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half2 tmpvar_1;
-  half4 tmpvar_2;
+  half2 tmpvar_1 = 0;
+  half4 tmpvar_2 = 0;
   tmpvar_2.w = _mtl_i._color.w;
   tmpvar_2.xyz = (_mtl_i._color.xyz + _mtl_i._inNormal);
   tmpvar_1 = half2(_mtl_i._uv0);

+ 22 - 22
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/uniforms-arrays-outES3Metal.txt

@@ -24,18 +24,18 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float3 tmpvar_1;
+  float3 tmpvar_1 = 0;
   tmpvar_1 = _mtl_i._glesVertex.xyz;
-  float3 n_2;
+  float3 n_2 = 0;
   n_2 = float3(_mtl_i._glesNormal);
-  half4 tmpvar_3;
-  float4 tmpvar_4;
+  half4 tmpvar_3 = 0;
+  float4 tmpvar_4 = 0;
   tmpvar_4.w = 1.0;
   tmpvar_4.xyz = tmpvar_1;
-  float3 lightColor_5;
-  float3 viewN_6;
-  float3 viewpos_7;
-  float4 tmpvar_8;
+  float3 lightColor_5 = 0;
+  float3 viewN_6 = 0;
+  float3 viewpos_7 = 0;
+  float4 tmpvar_8 = 0;
   tmpvar_8.w = 1.0;
   tmpvar_8.xyz = tmpvar_1;
   viewpos_7 = (_mtl_u.glstate_matrix_modelview0 * tmpvar_8).xyz;
@@ -44,37 +44,37 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   tmpvar_9[1] = _mtl_u.glstate_matrix_invtrans_modelview0[1].xyz;
   tmpvar_9[2] = _mtl_u.glstate_matrix_invtrans_modelview0[2].xyz;
   viewN_6 = (tmpvar_9 * n_2);
-  float3 tmpvar_10;
+  float3 tmpvar_10 = 0;
   tmpvar_10 = (_mtl_u.unity_LightPosition[0].xyz - (viewpos_7 * _mtl_u.unity_LightPosition[0].w));
-  lightColor_5 = (_mtl_u.glstate_lightmodel_ambient.xyz + ((float3)_mtl_u.unity_LightColor[0].xyz * (
+  lightColor_5 = (_mtl_u.glstate_lightmodel_ambient.xyz + ((float3)(_mtl_u.unity_LightColor[0].xyz) * (
     max (0.0, dot (viewN_6, normalize(tmpvar_10)))
    * 
-    (1.0/((1.0 + (dot (tmpvar_10, tmpvar_10) * (float)_mtl_u.unity_LightAtten[0].z))))
+    (1.0/((1.0 + (dot (tmpvar_10, tmpvar_10) * (float)(_mtl_u.unity_LightAtten[0].z)))))
   )));
-  float3 tmpvar_11;
+  float3 tmpvar_11 = 0;
   tmpvar_11 = (_mtl_u.unity_LightPosition[1].xyz - (viewpos_7 * _mtl_u.unity_LightPosition[1].w));
-  lightColor_5 = (lightColor_5 + ((float3)_mtl_u.unity_LightColor[1].xyz * (
+  lightColor_5 = (lightColor_5 + ((float3)(_mtl_u.unity_LightColor[1].xyz) * (
     max (0.0, dot (viewN_6, normalize(tmpvar_11)))
    * 
-    (1.0/((1.0 + (dot (tmpvar_11, tmpvar_11) * (float)_mtl_u.unity_LightAtten[1].z))))
+    (1.0/((1.0 + (dot (tmpvar_11, tmpvar_11) * (float)(_mtl_u.unity_LightAtten[1].z)))))
   )));
-  float3 tmpvar_12;
+  float3 tmpvar_12 = 0;
   tmpvar_12 = (_mtl_u.unity_LightPosition[2].xyz - (viewpos_7 * _mtl_u.unity_LightPosition[2].w));
-  lightColor_5 = (lightColor_5 + ((float3)_mtl_u.unity_LightColor[2].xyz * (
+  lightColor_5 = (lightColor_5 + ((float3)(_mtl_u.unity_LightColor[2].xyz) * (
     max (0.0, dot (viewN_6, normalize(tmpvar_12)))
    * 
-    (1.0/((1.0 + (dot (tmpvar_12, tmpvar_12) * (float)_mtl_u.unity_LightAtten[2].z))))
+    (1.0/((1.0 + (dot (tmpvar_12, tmpvar_12) * (float)(_mtl_u.unity_LightAtten[2].z)))))
   )));
-  float3 tmpvar_13;
+  float3 tmpvar_13 = 0;
   tmpvar_13 = (_mtl_u.unity_LightPosition[3].xyz - (viewpos_7 * _mtl_u.unity_LightPosition[3].w));
-  lightColor_5 = (lightColor_5 + ((float3)_mtl_u.unity_LightColor[3].xyz * (
+  lightColor_5 = (lightColor_5 + ((float3)(_mtl_u.unity_LightColor[3].xyz) * (
     max (0.0, dot (viewN_6, normalize(tmpvar_13)))
    * 
-    (1.0/((1.0 + (dot (tmpvar_13, tmpvar_13) * (float)_mtl_u.unity_LightAtten[3].z))))
+    (1.0/((1.0 + (dot (tmpvar_13, tmpvar_13) * (float)(_mtl_u.unity_LightAtten[3].z)))))
   )));
-  float4 tmpvar_14;
+  float4 tmpvar_14 = 0;
   tmpvar_14.w = 1.0;
-  tmpvar_14.xyz = ((lightColor_5 * (float3)_mtl_u._Color.xyz) * 2.0);
+  tmpvar_14.xyz = ((lightColor_5 * (float3)(_mtl_u._Color.xyz)) * 2.0);
   tmpvar_3 = half4(tmpvar_14);
   _mtl_o.gl_Position = (_mtl_u.glstate_matrix_mvp * tmpvar_4);
   _mtl_o.xlv_COLOR0 = tmpvar_3;

+ 67 - 67
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-NichsHybridLightVectorInsertBug-outES3Metal.txt

@@ -17,140 +17,140 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   ,   texture2d<half> _DynLampInfo [[texture(0)]], sampler _mtlsmp__DynLampInfo [[sampler(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  half3 tmpvar_1;
-  float3 tmpvar_2;
+  half3 tmpvar_1 = 0;
+  float3 tmpvar_2 = 0;
   tmpvar_2 = (_mtl_u._Object2World * _mtl_i._glesVertex).xyz;
-  float3 tmpvar_3;
-  half3 hybridCol_4;
-  int4 tmpvar_5;
+  float3 tmpvar_3 = 0;
+  half3 hybridCol_4 = 0;
+  int4 tmpvar_5 = 0;
   tmpvar_5.xyz = int3(tmpvar_2);
   tmpvar_5.w = int(-(tmpvar_2.x));
-  float2 tmpvar_6;
+  float2 tmpvar_6 = 0;
   tmpvar_6.y = 1.0;
   tmpvar_6.x = float(tmpvar_5.x);
-  half2 coord_7;
+  half2 coord_7 = 0;
   coord_7 = half2(tmpvar_6);
-  half4 tmpvar_8;
+  half4 tmpvar_8 = 0;
   tmpvar_8.zw = half2(float2(0.0, 0.0));
   tmpvar_8.xy = (coord_7 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_9;
-  half4 tmpvar_10;
+  half4 tmpvar_9 = 0;
+  half4 tmpvar_10 = 0;
   tmpvar_10 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_8.xy), level(0.0));
   tmpvar_9 = tmpvar_10;
-  float2 tmpvar_11;
+  float2 tmpvar_11 = 0;
   tmpvar_11.y = 2.0;
   tmpvar_11.x = float(tmpvar_5.x);
-  half2 coord_12;
+  half2 coord_12 = 0;
   coord_12 = half2(tmpvar_11);
-  half4 tmpvar_13;
+  half4 tmpvar_13 = 0;
   tmpvar_13.zw = half2(float2(0.0, 0.0));
   tmpvar_13.xy = (coord_12 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_14;
-  half4 tmpvar_15;
+  half4 tmpvar_14 = 0;
+  half4 tmpvar_15 = 0;
   tmpvar_15 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_13.xy), level(0.0));
   tmpvar_14 = tmpvar_15;
-  float2 tmpvar_16;
+  float2 tmpvar_16 = 0;
   tmpvar_16.y = 1.0;
   tmpvar_16.x = float(tmpvar_5.y);
-  half2 coord_17;
+  half2 coord_17 = 0;
   coord_17 = half2(tmpvar_16);
-  half4 tmpvar_18;
+  half4 tmpvar_18 = 0;
   tmpvar_18.zw = half2(float2(0.0, 0.0));
   tmpvar_18.xy = (coord_17 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_19;
-  half4 tmpvar_20;
+  half4 tmpvar_19 = 0;
+  half4 tmpvar_20 = 0;
   tmpvar_20 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_18.xy), level(0.0));
   tmpvar_19 = tmpvar_20;
-  float2 tmpvar_21;
+  float2 tmpvar_21 = 0;
   tmpvar_21.y = 2.0;
   tmpvar_21.x = float(tmpvar_5.y);
-  half2 coord_22;
+  half2 coord_22 = 0;
   coord_22 = half2(tmpvar_21);
-  half4 tmpvar_23;
+  half4 tmpvar_23 = 0;
   tmpvar_23.zw = half2(float2(0.0, 0.0));
   tmpvar_23.xy = (coord_22 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_24;
-  half4 tmpvar_25;
+  half4 tmpvar_24 = 0;
+  half4 tmpvar_25 = 0;
   tmpvar_25 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_23.xy), level(0.0));
   tmpvar_24 = tmpvar_25;
-  float2 tmpvar_26;
+  float2 tmpvar_26 = 0;
   tmpvar_26.y = 1.0;
   tmpvar_26.x = float(tmpvar_5.z);
-  half2 coord_27;
+  half2 coord_27 = 0;
   coord_27 = half2(tmpvar_26);
-  half4 tmpvar_28;
+  half4 tmpvar_28 = 0;
   tmpvar_28.zw = half2(float2(0.0, 0.0));
   tmpvar_28.xy = (coord_27 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_29;
-  half4 tmpvar_30;
+  half4 tmpvar_29 = 0;
+  half4 tmpvar_30 = 0;
   tmpvar_30 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_28.xy), level(0.0));
   tmpvar_29 = tmpvar_30;
-  float2 tmpvar_31;
+  float2 tmpvar_31 = 0;
   tmpvar_31.y = 2.0;
   tmpvar_31.x = float(tmpvar_5.z);
-  half2 coord_32;
+  half2 coord_32 = 0;
   coord_32 = half2(tmpvar_31);
-  half4 tmpvar_33;
+  half4 tmpvar_33 = 0;
   tmpvar_33.zw = half2(float2(0.0, 0.0));
   tmpvar_33.xy = (coord_32 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_34;
-  half4 tmpvar_35;
+  half4 tmpvar_34 = 0;
+  half4 tmpvar_35 = 0;
   tmpvar_35 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_33.xy), level(0.0));
   tmpvar_34 = tmpvar_35;
-  float2 tmpvar_36;
+  float2 tmpvar_36 = 0;
   tmpvar_36.y = 1.0;
   tmpvar_36.x = float(tmpvar_5.w);
-  half2 coord_37;
+  half2 coord_37 = 0;
   coord_37 = half2(tmpvar_36);
-  half4 tmpvar_38;
+  half4 tmpvar_38 = 0;
   tmpvar_38.zw = half2(float2(0.0, 0.0));
   tmpvar_38.xy = (coord_37 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_39;
-  half4 tmpvar_40;
+  half4 tmpvar_39 = 0;
+  half4 tmpvar_40 = 0;
   tmpvar_40 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_38.xy), level(0.0));
   tmpvar_39 = tmpvar_40;
-  float2 tmpvar_41;
+  float2 tmpvar_41 = 0;
   tmpvar_41.y = 2.0;
   tmpvar_41.x = float(tmpvar_5.w);
-  half2 coord_42;
+  half2 coord_42 = 0;
   coord_42 = half2(tmpvar_41);
-  half4 tmpvar_43;
+  half4 tmpvar_43 = 0;
   tmpvar_43.zw = half2(float2(0.0, 0.0));
   tmpvar_43.xy = (coord_42 / _mtl_u._DynLampInfo_bufferSize);
-  half4 tmpvar_44;
-  half4 tmpvar_45;
+  half4 tmpvar_44 = 0;
+  half4 tmpvar_45 = 0;
   tmpvar_45 = _DynLampInfo.sample(_mtlsmp__DynLampInfo, (float2)(tmpvar_43.xy), level(0.0));
   tmpvar_44 = tmpvar_45;
-  half3 hybridCol_46;
-  half4 atten_47;
-  float3 tmpvar_48;
-  tmpvar_48 = ((float3)tmpvar_9.xyz - tmpvar_2);
-  float tmpvar_49;
+  half3 hybridCol_46 = 0;
+  half4 atten_47 = 0;
+  float3 tmpvar_48 = 0;
+  tmpvar_48 = ((float3)(tmpvar_9.xyz) - tmpvar_2);
+  float tmpvar_49 = 0;
   tmpvar_49 = dot (tmpvar_48, tmpvar_48);
-  half4 tmpvar_50;
+  half4 tmpvar_50 = 0;
   tmpvar_50.yzw = atten_47.yzw;
-  tmpvar_50.x = half((tmpvar_49 * (float)tmpvar_9.w));
-  float3 tmpvar_51;
-  tmpvar_51 = ((float3)tmpvar_19.xyz - tmpvar_2);
-  float tmpvar_52;
+  tmpvar_50.x = half((tmpvar_49 * (float)(tmpvar_9.w)));
+  float3 tmpvar_51 = 0;
+  tmpvar_51 = ((float3)(tmpvar_19.xyz) - tmpvar_2);
+  float tmpvar_52 = 0;
   tmpvar_52 = dot (tmpvar_51, tmpvar_51);
-  half4 tmpvar_53;
+  half4 tmpvar_53 = 0;
   tmpvar_53.xzw = tmpvar_50.xzw;
-  tmpvar_53.y = half((tmpvar_52 * (float)tmpvar_19.w));
-  float3 tmpvar_54;
-  tmpvar_54 = ((float3)tmpvar_29.xyz - tmpvar_2);
-  float tmpvar_55;
+  tmpvar_53.y = half((tmpvar_52 * (float)(tmpvar_19.w)));
+  float3 tmpvar_54 = 0;
+  tmpvar_54 = ((float3)(tmpvar_29.xyz) - tmpvar_2);
+  float tmpvar_55 = 0;
   tmpvar_55 = dot (tmpvar_54, tmpvar_54);
-  half4 tmpvar_56;
+  half4 tmpvar_56 = 0;
   tmpvar_56.xyw = tmpvar_53.xyw;
-  tmpvar_56.z = half((tmpvar_55 * (float)tmpvar_29.w));
-  float3 tmpvar_57;
-  tmpvar_57 = ((float3)tmpvar_39.xyz - tmpvar_2);
-  float tmpvar_58;
+  tmpvar_56.z = half((tmpvar_55 * (float)(tmpvar_29.w)));
+  float3 tmpvar_57 = 0;
+  tmpvar_57 = ((float3)(tmpvar_39.xyz) - tmpvar_2);
+  float tmpvar_58 = 0;
   tmpvar_58 = dot (tmpvar_57, tmpvar_57);
-  half4 tmpvar_59;
+  half4 tmpvar_59 = 0;
   tmpvar_59.xyz = tmpvar_56.xyz;
-  tmpvar_59.w = half((tmpvar_58 * (float)tmpvar_39.w));
+  tmpvar_59.w = half((tmpvar_58 * (float)(tmpvar_39.w)));
   atten_47 = tmpvar_59;
   hybridCol_46 = (hybridCol_4 + (tmpvar_14.xyz * tmpvar_50.x));
   hybridCol_46 = (hybridCol_46 + (tmpvar_24.xyz * tmpvar_53.y));

+ 5 - 5
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-prepasslight-outES3Metal.txt

@@ -18,18 +18,18 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float4 tmpvar_1;
-  float3 tmpvar_2;
+  float4 tmpvar_1 = 0;
+  float3 tmpvar_2 = 0;
   tmpvar_1 = (_mtl_u.glstate_matrix_mvp * _mtl_i._vertex);
-  float4 o_3;
+  float4 o_3 = 0;
   o_3 = (tmpvar_1 * 0.5);
-  float2 tmpvar_4;
+  float2 tmpvar_4 = 0;
   tmpvar_4.x = o_3.x;
   tmpvar_4.y = (o_3.y * _mtl_u._ProjectionParams.x);
   o_3.xy = (tmpvar_4 + o_3.w);
   o_3.zw = tmpvar_1.zw;
   tmpvar_2 = ((_mtl_u.glstate_matrix_modelview0 * _mtl_i._vertex).xyz * float3(-1.0, -1.0, 1.0));
-  float3 tmpvar_5;
+  float3 tmpvar_5 = 0;
   tmpvar_5 = mix (tmpvar_2, _mtl_i._normal, float3(float((_mtl_i._normal.z != 0.0))));
   tmpvar_2 = tmpvar_5;
   _mtl_o.gl_Position = tmpvar_1;

+ 30 - 30
third/bgfx/3rdparty/glsl-optimizer/tests/vertex/z-treeleaf-outES3Metal.txt

@@ -36,56 +36,56 @@ struct xlatMtlShaderUniform {
 vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]], constant xlatMtlShaderUniform& _mtl_u [[buffer(0)]])
 {
   xlatMtlShaderOutput _mtl_o;
-  float4 tmpvar_1;
-  float3 tmpvar_2;
-  float4 tmpvar_3;
+  float4 tmpvar_1 = 0;
+  float3 tmpvar_2 = 0;
+  float4 tmpvar_3 = 0;
   tmpvar_1 = float4(_mtl_i.TANGENT);
   tmpvar_2 = float3(_mtl_i._inNormal);
   tmpvar_3 = float4(_mtl_i._color);
-  float3 binormal_4;
-  float4 tmpvar_5;
-  float4 tmpvar_6;
-  float4 pos_7;
-  float isBillboard_8;
+  float3 binormal_4 = 0;
+  float4 tmpvar_5 = 0;
+  float4 tmpvar_6 = 0;
+  float4 pos_7 = 0;
+  float isBillboard_8 = 0;
   isBillboard_8 = (1.0 - abs(tmpvar_1.w));
-  float4 tmpvar_9;
+  float4 tmpvar_9 = 0;
   tmpvar_9.w = 0.0;
   tmpvar_9.xyz = tmpvar_2;
-  float4 tmpvar_10;
+  float4 tmpvar_10 = 0;
   tmpvar_10.w = 0.0;
   tmpvar_10.xyz = tmpvar_1.xyz;
-  float4 tmpvar_11;
+  float4 tmpvar_11 = 0;
   tmpvar_11.zw = float2(0.0, 0.0);
   tmpvar_11.xy = tmpvar_2.xy;
   pos_7 = (_mtl_i._inVertex + ((tmpvar_11 * _mtl_u.glstate_matrix_invtrans_modelview0) * isBillboard_8));
-  float3 tmpvar_12;
+  float3 tmpvar_12 = 0;
   tmpvar_12 = mix (tmpvar_2, normalize((tmpvar_9 * _mtl_u.glstate_matrix_invtrans_modelview0)).xyz, float3(isBillboard_8));
-  float4 tmpvar_13;
+  float4 tmpvar_13 = 0;
   tmpvar_13.w = -1.0;
   tmpvar_13.xyz = normalize((tmpvar_10 * _mtl_u.glstate_matrix_invtrans_modelview0)).xyz;
-  float4 tmpvar_14;
+  float4 tmpvar_14 = 0;
   tmpvar_14 = mix (tmpvar_1, tmpvar_13, float4(isBillboard_8));
   tmpvar_5.w = pos_7.w;
   tmpvar_6.w = tmpvar_14.w;
   tmpvar_5.xyz = (pos_7.xyz * _mtl_u._Scale.xyz);
-  float4 pos_15;
+  float4 pos_15 = 0;
   pos_15.w = tmpvar_5.w;
-  float3 bend_16;
-  float2 vWavesSum_17;
-  float4 vWaves_18;
-  float fBranchPhase_19;
+  float3 bend_16 = 0;
+  float2 vWavesSum_17 = 0;
+  float4 vWaves_18 = 0;
+  float fBranchPhase_19 = 0;
   fBranchPhase_19 = (dot (_mtl_u._Object2World[3].xyz, float3(1.0, 1.0, 1.0)) + tmpvar_3.x);
-  float2 tmpvar_20;
+  float2 tmpvar_20 = 0;
   tmpvar_20.x = dot (tmpvar_5.xyz, float3((tmpvar_3.y + fBranchPhase_19)));
   tmpvar_20.y = fBranchPhase_19;
   vWaves_18 = ((fract(
     ((_mtl_u._Time.yy + tmpvar_20).xxyy * float4(1.975, 0.793, 0.375, 0.193))
   ) * 2.0) - 1.0);
-  float4 tmpvar_21;
+  float4 tmpvar_21 = 0;
   tmpvar_21 = abs(((
     fract((vWaves_18 + 0.5))
    * 2.0) - 1.0));
-  float4 tmpvar_22;
+  float4 tmpvar_22 = 0;
   tmpvar_22 = ((tmpvar_21 * tmpvar_21) * (3.0 - (2.0 * tmpvar_21)));
   vWaves_18 = tmpvar_22;
   vWavesSum_17 = (tmpvar_22.xz + tmpvar_22.yw);
@@ -97,18 +97,18 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
     ((_mtl_u._Wind.xyz * vWavesSum_17.y) * _mtl_i._uv1.y)
   ) * _mtl_u._Wind.w));
   pos_15.xyz = (pos_15.xyz + (_mtl_i._uv1.x * _mtl_u._Wind.xyz));
-  float3 tmpvar_23;
+  float3 tmpvar_23 = 0;
   tmpvar_23 = mix ((pos_15.xyz - (
     (dot (_mtl_u._SquashPlaneNormal.xyz, pos_15.xyz) + _mtl_u._SquashPlaneNormal.w)
    * _mtl_u._SquashPlaneNormal.xyz)), pos_15.xyz, float3(_mtl_u._SquashAmount));
-  float4 tmpvar_24;
+  float4 tmpvar_24 = 0;
   tmpvar_24.w = 1.0;
   tmpvar_24.xyz = tmpvar_23;
   tmpvar_5 = tmpvar_24;
-  float4 tmpvar_25;
+  float4 tmpvar_25 = 0;
   tmpvar_25.xyz = float3(1.0, 1.0, 1.0);
   tmpvar_25.w = tmpvar_3.w;
-  float3 tmpvar_26;
+  float3 tmpvar_26 = 0;
   tmpvar_26 = normalize(tmpvar_12);
   tmpvar_6.xyz = normalize(tmpvar_14.xyz);
   binormal_4 = (((tmpvar_26.yzx * tmpvar_6.zxy) - (tmpvar_26.zxy * tmpvar_6.yzx)) * tmpvar_14.w);
@@ -122,21 +122,21 @@ vertex xlatMtlShaderOutput xlatMtlMain (xlatMtlShaderInput _mtl_i [[stage_in]],
   tmpvar_27[2].x = tmpvar_6.z;
   tmpvar_27[2].y = binormal_4.z;
   tmpvar_27[2].z = tmpvar_26.z;
-  float4 tmpvar_28;
+  float4 tmpvar_28 = 0;
   tmpvar_28.w = 1.0;
   tmpvar_28.xyz = _mtl_u._WorldSpaceCameraPos;
   _mtl_o.gl_Position = (_mtl_u.glstate_matrix_mvp * tmpvar_24);
   _mtl_o.xlv_TEXCOORD0 = ((_mtl_i._uv0.xy * _mtl_u._MainTex_ST.xy) + _mtl_u._MainTex_ST.zw);
   _mtl_o.xlv_COLOR0 = half4(tmpvar_25);
-  float3 tmpvar_29;
+  float3 tmpvar_29 = 0;
   tmpvar_29 = (tmpvar_27 * (_mtl_u._World2Object * _mtl_u._WorldSpaceLightPos0).xyz);
   _mtl_o.xlv_TEXCOORD1 = half3(tmpvar_29);
-  float3 tmpvar_30;
+  float3 tmpvar_30 = 0;
   tmpvar_30 = (tmpvar_27 * ((
     (_mtl_u._World2Object * tmpvar_28)
   .xyz * _mtl_u.unity_Scale.w) - tmpvar_23));
   _mtl_o.xlv_TEXCOORD2 = half3(tmpvar_30);
-  float2 tmpvar_31;
+  float2 tmpvar_31 = 0;
   tmpvar_31 = (_mtl_u._LightMatrix0 * (_mtl_u._Object2World * tmpvar_24)).xy;
   _mtl_o.xlv_TEXCOORD3 = half2(tmpvar_31);
   return _mtl_o;

Разница между файлами не показана из-за своего большого размера
+ 232 - 174
third/bgfx/3rdparty/ocornut-imgui/imgui.cpp


+ 59 - 62
third/bgfx/3rdparty/ocornut-imgui/imgui.h

@@ -62,15 +62,14 @@ struct ImGuiSizeConstraintCallbackData;// Structure used to constraint window si
 struct ImGuiListClipper;            // Helper to manually clip large list of items
 struct ImGuiContext;                // ImGui context (opaque)
 
-// Enumerations (declared as int for compatibility and to not pollute the top of this file)
-typedef unsigned int ImU32;
+// Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file)
+typedef unsigned int ImU32;         // 32-bit unsigned integer (typically used to store packed colors)
+typedef unsigned int ImGuiID;       // unique ID used by widgets (typically hashed from a stack of string)
 typedef unsigned short ImWchar;     // character for keyboard input/display
 typedef void* ImTextureID;          // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp)
-typedef ImU32 ImGuiID;              // unique ID used by widgets (typically hashed from a stack of string)
 typedef int ImGuiCol;               // a color identifier for styling       // enum ImGuiCol_
 typedef int ImGuiStyleVar;          // a variable identifier for styling    // enum ImGuiStyleVar_
 typedef int ImGuiKey;               // a key identifier (ImGui-side enum)   // enum ImGuiKey_
-typedef int ImGuiAlign;             // alignment                            // enum ImGuiAlign_
 typedef int ImGuiColorEditMode;     // color edit mode for ColorEdit*()     // enum ImGuiColorEditMode_
 typedef int ImGuiMouseCursor;       // a mouse cursor identifier            // enum ImGuiMouseCursor_
 typedef int ImGuiWindowFlags;       // window flags for Begin*()            // enum ImGuiWindowFlags_
@@ -332,7 +331,7 @@ namespace ImGui
     IMGUI_API void          TreePush(const void* ptr_id = NULL);                                    // "
     IMGUI_API void          TreePop();                                                              // ~ Unindent()+PopId()
     IMGUI_API void          TreeAdvanceToLabelPos();                                                // advance cursor x position by GetTreeNodeToLabelSpacing()
-    IMGUI_API float         GetTreeNodeToLabelSpacing();                                            // horizontal distance preceeding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
+    IMGUI_API float         GetTreeNodeToLabelSpacing();                                            // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode
     IMGUI_API void          SetNextTreeNodeOpen(bool is_open, ImGuiSetCond cond = 0);               // set next TreeNode/CollapsingHeader open state.
     IMGUI_API bool          CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0);      // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop().
     IMGUI_API bool          CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header
@@ -352,7 +351,7 @@ namespace ImGui
     IMGUI_API void          Value(const char* prefix, unsigned int v);
     IMGUI_API void          Value(const char* prefix, float v, const char* float_format = NULL);
     IMGUI_API void          ValueColor(const char* prefix, const ImVec4& v);
-    IMGUI_API void          ValueColor(const char* prefix, unsigned int v);
+    IMGUI_API void          ValueColor(const char* prefix, ImU32 v);
 
     // Tooltips
     IMGUI_API void          SetTooltip(const char* fmt, ...) IM_PRINTFARGS(1);                  // set tooltip under mouse-cursor, typically use with ImGui::IsHovered(). last call wins
@@ -409,7 +408,8 @@ namespace ImGui
     IMGUI_API bool          IsRootWindowFocused();                                              // is current root window focused (root = top-most parent of a child, otherwise self)
     IMGUI_API bool          IsRootWindowOrAnyChildFocused();                                    // is current root window or any of its child (including current window) focused
     IMGUI_API bool          IsRootWindowOrAnyChildHovered();                                    // is current root window or any of its child (including current window) hovered and hoverable (not blocked by a popup)
-    IMGUI_API bool          IsRectVisible(const ImVec2& size);                                  // test if rectangle of given size starting from cursor pos is visible (not clipped). to perform coarse clipping on user's side (as an optimization)
+    IMGUI_API bool          IsRectVisible(const ImVec2& size);                                  // test if rectangle (of given size, starting from cursor position) is visible / not clipped.
+    IMGUI_API bool          IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max);      // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side.
     IMGUI_API bool          IsPosHoveringAnyWindow(const ImVec2& pos);                          // is given position hovering any active imgui window
     IMGUI_API float         GetTime();
     IMGUI_API int           GetFrameCount();
@@ -467,15 +467,9 @@ namespace ImGui
     static inline bool      CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1<<5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } // OBSOLETE 1.49+
     static inline ImFont*   GetWindowFont() { return GetFont(); }                              // OBSOLETE 1.48+
     static inline float     GetWindowFontSize() { return GetFontSize(); }                      // OBSOLETE 1.48+
-    static inline void      OpenNextNode(bool open) { ImGui::SetNextTreeNodeOpen(open, 0); }   // OBSOLETE 1.34+
-    static inline bool      GetWindowIsFocused() { return ImGui::IsWindowFocused(); }          // OBSOLETE 1.36+
+    static inline void      SetScrollPosHere() { SetScrollHere(); }                            // OBSOLETE 1.42+
     static inline bool      GetWindowCollapsed() { return ImGui::IsWindowCollapsed(); }        // OBSOLETE 1.39+
-    static inline ImVec2    GetItemBoxMin() { return GetItemRectMin(); }                       // OBSOLETE 1.36+
-    static inline ImVec2    GetItemBoxMax() { return GetItemRectMax(); }                       // OBSOLETE 1.36+
-    static inline bool      IsClipped(const ImVec2& size) { return !IsRectVisible(size); }     // OBSOLETE 1.38+
     static inline bool      IsRectClipped(const ImVec2& size) { return !IsRectVisible(size); } // OBSOLETE 1.39+
-    static inline bool      IsMouseHoveringBox(const ImVec2& rect_min, const ImVec2& rect_max) { return IsMouseHoveringRect(rect_min, rect_max); }  // OBSOLETE 1.36+
-    static inline void      SetScrollPosHere() { SetScrollHere(); }                            // OBSOLETE 1.42+
 #endif
 
 } // namespace ImGui
@@ -652,17 +646,9 @@ enum ImGuiStyleVar_
     ImGuiStyleVar_ItemInnerSpacing,    // ImVec2
     ImGuiStyleVar_IndentSpacing,       // float
     ImGuiStyleVar_GrabMinSize,         // float
-    ImGuiStyleVar_ViewId               // uint8_t
-};
-
-enum ImGuiAlign_
-{
-    ImGuiAlign_Left     = 1 << 0,
-    ImGuiAlign_Center   = 1 << 1,
-    ImGuiAlign_Right    = 1 << 2,
-    ImGuiAlign_Top      = 1 << 3,
-    ImGuiAlign_VCenter  = 1 << 4,
-    ImGuiAlign_Default  = ImGuiAlign_Left | ImGuiAlign_Top
+    ImGuiStyleVar_ButtonTextAlign,     // flags ImGuiAlign_*
+    ImGuiStyleVar_ViewId,              // uint8_t
+    ImGuiStyleVar_Count_
 };
 
 // Enumeration for ColorEditMode()
@@ -679,6 +665,7 @@ enum ImGuiColorEditMode_
 // Enumeration for GetMouseCursor()
 enum ImGuiMouseCursor_
 {
+    ImGuiMouseCursor_None = -1,
     ImGuiMouseCursor_Arrow = 0,
     ImGuiMouseCursor_TextInput,         // When hovering over InputText, etc.
     ImGuiMouseCursor_Move,              // Unused
@@ -694,9 +681,9 @@ enum ImGuiMouseCursor_
 enum ImGuiSetCond_
 {
     ImGuiSetCond_Always        = 1 << 0, // Set the variable
-    ImGuiSetCond_Once          = 1 << 1, // Only set the variable on the first call per runtime session
-    ImGuiSetCond_FirstUseEver  = 1 << 2, // Only set the variable if the window doesn't exist in the .ini file
-    ImGuiSetCond_Appearing     = 1 << 3  // Only set the variable if the window is appearing after being inactive (or the first time)
+    ImGuiSetCond_Once          = 1 << 1, // Set the variable once per runtime session (only the first call with succeed)
+    ImGuiSetCond_FirstUseEver  = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file)
+    ImGuiSetCond_Appearing     = 1 << 3  // Set the variable if the window is appearing after being hidden/inactive (or the first time)
 };
 
 struct ImGuiStyle
@@ -705,7 +692,7 @@ struct ImGuiStyle
     ImVec2      WindowPadding;              // Padding within a window
     ImVec2      WindowMinSize;              // Minimum window size
     float       WindowRounding;             // Radius of window corners rounding. Set to 0.0f to have rectangular windows
-    ImGuiAlign  WindowTitleAlign;           // Alignment for title bar text
+    ImVec2      WindowTitleAlign;           // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered.
     float       ChildWindowRounding;        // Radius of child window corners rounding. Set to 0.0f to have rectangular windows
     ImVec2      FramePadding;               // Padding within a framed rectangle (used by most widgets)
     float       FrameRounding;              // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets).
@@ -719,6 +706,7 @@ struct ImGuiStyle
     float       GrabMinSize;                // Minimum width/height of a grab box for slider/scrollbar
     float       ViewId;
     float       GrabRounding;               // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
+    ImVec2      ButtonTextAlign;            // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered.
     ImVec2      DisplayWindowPadding;       // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows.
     ImVec2      DisplaySafeAreaPadding;     // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
     bool        AntiAliasedLines;           // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU.
@@ -758,10 +746,7 @@ struct ImGuiIO
     ImVec2        DisplayVisibleMax;        // <unset> (0.0f,0.0f)  // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize
 
     // Advanced/subtle behaviors
-    bool          WordMovementUsesAltKey;   // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl
-    bool          ShortcutsUseSuperKey;     // = defined(__APPLE__) // OS X style: Shortcuts using Cmd/Super instead of Ctrl
-    bool          DoubleClickSelectsWord;   // = defined(__APPLE__) // OS X style: Double click selects by word instead of selecting whole text
-    bool          MultiSelectUsesSuperKey;  // = defined(__APPLE__) // OS X style: Multi-selection in lists uses Cmd/Super instead of Ctrl [unused yet]
+    bool          OSXBehaviors;             // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl
 
     //------------------------------------------------------------------
     // User Functions
@@ -774,8 +759,9 @@ struct ImGuiIO
 
     // Optional: access OS clipboard
     // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures)
-    const char* (*GetClipboardTextFn)();
-    void        (*SetClipboardTextFn)(const char* text);
+    const char* (*GetClipboardTextFn)(void* user_data);
+    void        (*SetClipboardTextFn)(void* user_data, const char* text);
+    void*       ClipboardUserData;
 
     // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
     // (default to posix malloc/free)
@@ -821,7 +807,7 @@ struct ImGuiIO
     int         MetricsActiveWindows;       // Number of visible windows (exclude child windows)
 
     //------------------------------------------------------------------
-    // [Internal] ImGui will maintain those fields for you
+    // [Private] ImGui will maintain those fields. Forward compatibility not guaranteed!
     //------------------------------------------------------------------
 
     ImVec2      MousePosPrev;               // Previous mouse position
@@ -888,7 +874,8 @@ public:
         if (new_capacity <= Capacity) return;
         T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(value_type));
         memset(&new_data[Size], 0, (size_t)(new_capacity - Size) * sizeof(value_type)); // BK - clear garbage so that 0 initialized ImString works properly.
-        memcpy(new_data, Data, (size_t)Size * sizeof(value_type));
+        if (Data)
+            memcpy(new_data, Data, (size_t)Size * sizeof(value_type));
         ImGui::MemFree(Data);
         Data = new_data;
         Capacity = new_capacity;
@@ -967,10 +954,9 @@ struct ImGuiTextBuffer
 };
 
 // Helper: Simple Key->value storage
-// - Store collapse state for a tree (Int 0/1)
-// - Store color edit options (Int using values in ImGuiColorEditMode enum).
-// - Custom user storage for temporary values.
 // Typically you don't have to worry about this since a storage is held within each Window.
+// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options.
+// You can use it as custom user storage for temporary values.
 // Declare your own storage if:
 // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state).
 // - You want to store custom debug data easily without adding or editing structures in your code.
@@ -1002,9 +988,8 @@ struct ImGuiStorage
 
     // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set.
     // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
-    // - A typical use case where this is convenient:
+    // - A typical use case where this is convenient for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct)
     //      float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar;
-    // - You can also use this to quickly create temporary editable values during a session of using Edit&Continue, without restarting your application.
     IMGUI_API int*      GetIntRef(ImGuiID key, int default_val = 0);
     IMGUI_API bool*     GetBoolRef(ImGuiID key, bool default_val = false);
     IMGUI_API float*    GetFloatRef(ImGuiID key, float default_val = 0.0f);
@@ -1052,17 +1037,36 @@ struct ImGuiSizeConstraintCallbackData
     ImVec2  DesiredSize;    // Read-write.  Desired size, based on user's mouse position. Write to this field to restrain resizing.
 };
 
+// Helpers macros to generate 32-bits encoded colors
+#ifdef IMGUI_USE_BGRA_PACKED_COLOR
+#define IM_COL32_R_SHIFT    16
+#define IM_COL32_G_SHIFT    8
+#define IM_COL32_B_SHIFT    0
+#define IM_COL32_A_SHIFT    24
+#define IM_COL32_A_MASK     0xFF000000
+#else
+#define IM_COL32_R_SHIFT    0
+#define IM_COL32_G_SHIFT    8
+#define IM_COL32_B_SHIFT    16
+#define IM_COL32_A_SHIFT    24
+#define IM_COL32_A_MASK     0xFF000000
+#endif
+#define IM_COL32(R,G,B,A)    (((ImU32)(A)<<IM_COL32_A_SHIFT) | ((ImU32)(B)<<IM_COL32_B_SHIFT) | ((ImU32)(G)<<IM_COL32_G_SHIFT) | ((ImU32)(R)<<IM_COL32_R_SHIFT))
+#define IM_COL32_WHITE       IM_COL32(255,255,255,255)  // Opaque white
+#define IM_COL32_BLACK       IM_COL32(0,0,0,255)        // Opaque black
+#define IM_COL32_BLACK_TRANS IM_COL32(0,0,0,0)          // Transparent black
+
 // ImColor() helper to implicity converts colors to either ImU32 (packed 4x1 byte) or ImVec4 (4x1 float)
 // Prefer using IM_COL32() macros if you want a guaranteed compile-time ImU32 for usage with ImDrawList API.
-// Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
-// None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
+// **Avoid storing ImColor! Store either u32 of ImVec4. This is not a full-featured color class.
+// **None of the ImGui API are using ImColor directly but you can use it as a convenience to pass colors in either ImU32 or ImVec4 formats.
 struct ImColor
 {
     ImVec4              Value;
 
     ImColor()                                                       { Value.x = Value.y = Value.z = Value.w = 0.0f; }
     ImColor(int r, int g, int b, int a = 255)                       { float sc = 1.0f/255.0f; Value.x = (float)r * sc; Value.y = (float)g * sc; Value.z = (float)b * sc; Value.w = (float)a * sc; }
-    ImColor(ImU32 rgba)                                             { float sc = 1.0f/255.0f; Value.x = (float)(rgba&0xFF) * sc; Value.y = (float)((rgba>>8)&0xFF) * sc; Value.z = (float)((rgba>>16)&0xFF) * sc; Value.w = (float)(rgba >> 24) * sc; }
+    ImColor(ImU32 rgba)                                             { float sc = 1.0f/255.0f; Value.x = (float)((rgba>>IM_COL32_R_SHIFT)&0xFF) * sc; Value.y = (float)((rgba>>IM_COL32_G_SHIFT)&0xFF) * sc; Value.z = (float)((rgba>>IM_COL32_B_SHIFT)&0xFF) * sc; Value.w = (float)((rgba>>IM_COL32_A_SHIFT)&0xFF) * sc; }
     ImColor(float r, float g, float b, float a = 1.0f)              { Value.x = r; Value.y = g; Value.z = b; Value.w = a; }
     ImColor(const ImVec4& col)                                      { Value = col; }
     inline operator ImU32() const                                   { return ImGui::ColorConvertFloat4ToU32(Value); }
@@ -1108,12 +1112,6 @@ struct ImGuiListClipper
 // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
 //-----------------------------------------------------------------------------
 
-// Helpers macros to generate 32-bits encoded colors
-#define IM_COL32(R,G,B,A)    (((ImU32)(A)<<24) | ((ImU32)(B)<<16) | ((ImU32)(G)<<8) | ((ImU32)(R)))
-#define IM_COL32_WHITE       (0xFFFFFFFF)
-#define IM_COL32_BLACK       (0xFF000000)
-#define IM_COL32_BLACK_TRANS (0x00000000)    // Transparent black
-
 // Draw callbacks for advanced uses.
 // NB- You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering (you can poke into the draw list for that)
 // Draw callback may be useful for example, A) Change your GPU render state, B) render a complex 3D scene inside a UI element (without an intermediate texture/render target), etc.
@@ -1175,7 +1173,7 @@ struct ImDrawList
     ImVector<ImDrawVert>    VtxBuffer;          // Vertex buffer.
 
     // [Internal, used while building lists]
-    const char*             _OwnerName;         // Pointer to owner window's name (if any) for debugging
+    const char*             _OwnerName;         // Pointer to owner window's name for debugging
     unsigned int            _VtxCurrentIdx;     // [Internal] == VtxBuffer.Size
     ImDrawVert*             _VtxWritePtr;       // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
     ImDrawIdx*              _IdxWritePtr;       // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much)
@@ -1186,7 +1184,7 @@ struct ImDrawList
     int                     _ChannelsCount;     // [Internal] number of active channels (1+)
     ImVector<ImDrawChannel> _Channels;          // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size)
 
-    ImDrawList() { _OwnerName = NULL; Clear(); }
+    ImDrawList()  { _OwnerName = NULL; Clear(); }
     ~ImDrawList() { ClearFreeMemory(); }
     IMGUI_API void  PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false);  // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling)
     IMGUI_API void  PushClipRectFullScreen();
@@ -1196,8 +1194,8 @@ struct ImDrawList
 
     // Primitives
     IMGUI_API void  AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f);
-    IMGUI_API void  AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F, float thickness = 1.0f);   // a: upper-left, b: lower-right
-    IMGUI_API void  AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners = 0x0F);                     // a: upper-left, b: lower-right
+    IMGUI_API void  AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0, float thickness = 1.0f);   // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round
+    IMGUI_API void  AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ~0);                     // a: upper-left, b: lower-right
     IMGUI_API void  AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left);
     IMGUI_API void  AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f);
     IMGUI_API void  AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col);
@@ -1219,9 +1217,9 @@ struct ImDrawList
     inline    void  PathFill(ImU32 col)                                         { AddConvexPolyFilled(_Path.Data, _Path.Size, col, true); PathClear(); }
     inline    void  PathStroke(ImU32 col, bool closed, float thickness = 1.0f)  { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness, true); PathClear(); }
     IMGUI_API void  PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10);
-    IMGUI_API void  PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12);                 // Use precomputed angles for a 12 steps circle
+    IMGUI_API void  PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12);                                // Use precomputed angles for a 12 steps circle
     IMGUI_API void  PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0);
-    IMGUI_API void  PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners = 0x0F);
+    IMGUI_API void  PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ~0);   // rounding_corners_flags: 4-bits corresponding to which corner to round
 
     // Channels
     // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives)
@@ -1272,7 +1270,7 @@ struct ImFontConfig
     int             FontNo;                     // 0        // Index of font within TTF file
     float           SizePixels;                 //          // Size in pixels for rasterizer
     int             OversampleH, OversampleV;   // 3, 1     // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis.
-    bool            PixelSnapH;                 // false    // Align every character to pixel boundary (if enabled, set OversampleH/V to 1)
+    bool            PixelSnapH;                 // false    // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1.
     ImVec2          GlyphExtraSpacing;          // 0, 0     // Extra spacing (in pixels) between glyphs
     const ImWchar*  GlyphRanges;                //          // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE.
     bool            MergeMode;                  // false    // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs).
@@ -1325,6 +1323,7 @@ struct ImFontAtlas
     IMGUI_API const ImWchar*    GetGlyphRangesJapanese();   // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs
     IMGUI_API const ImWchar*    GetGlyphRangesChinese();    // Japanese + full set of about 21000 CJK Unified Ideographs
     IMGUI_API const ImWchar*    GetGlyphRangesCyrillic();   // Default + about 400 Cyrillic characters
+    IMGUI_API const ImWchar*    GetGlyphRangesThai();       // Default + Thai characters
 
     // Members
     // (Access texture data via GetTexData*() calls which will setup a default font for you.)
@@ -1361,7 +1360,7 @@ struct ImFont
     ImVec2                      DisplayOffset;      // = (0.f,1.f)  // Offset font rendering by xx pixels
     ImVector<Glyph>             Glyphs;             //              // All glyphs.
     ImVector<float>             IndexXAdvance;      //              // Sparse. Glyphs->XAdvance in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI).
-    ImVector<short>             IndexLookup;        //              // Sparse. Index glyphs by Unicode code-point.
+    ImVector<unsigned short>    IndexLookup;        //              // Sparse. Index glyphs by Unicode code-point.
     const Glyph*                FallbackGlyph;      // == FindGlyph(FontFallbackChar)
     float                       FallbackXAdvance;   // == FallbackGlyph->XAdvance
     ImWchar                     FallbackChar;       // = '?'        // Replacement glyph if one isn't found. Only set via SetFallbackChar()
@@ -1398,9 +1397,7 @@ struct ImFont
 #pragma clang diagnostic pop
 #endif
 
-//---- Include imgui_user.h at the end of imgui.h
-//---- So you can include code that extends ImGui using any of the types declared above.
-//---- (also convenient for user to only explicitly include vanilla imgui.h)
+// Include imgui_user.h at the end of imgui.h (convenient for user to only explicitly include vanilla imgui.h)
 #ifdef IMGUI_INCLUDE_IMGUI_USER_H
 #include "imgui_user.h"
 #endif

+ 103 - 21
third/bgfx/3rdparty/ocornut-imgui/imgui_demo.cpp

@@ -30,7 +30,9 @@
 #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast"   // warning : cast to 'void *' from smaller integer type 'int'
 #pragma clang diagnostic ignored "-Wformat-security"            // warning : warning: format string is not a string literal
 #pragma clang diagnostic ignored "-Wexit-time-destructors"      // warning : declaration requires an exit-time destructor       // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
-#pragma clang diagnostic ignored "-Wreserved-id-macro"          // warning : macro name is a reserved identifier                // 
+#if __has_warning("-Wreserved-id-macro")
+#pragma clang diagnostic ignored "-Wreserved-id-macro"          // warning : macro name is a reserved identifier                //
+#endif
 #elif defined(__GNUC__)
 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"          // warning: cast to pointer from integer of different size
 #pragma GCC diagnostic ignored "-Wformat-security"              // warning : format string is not a string literal (potentially insecure)
@@ -71,7 +73,13 @@ static void ShowHelpMarker(const char* desc)
 {
     ImGui::TextDisabled("(?)");
     if (ImGui::IsItemHovered())
-        ImGui::SetTooltip(desc);
+    {
+        ImGui::BeginTooltip();
+        ImGui::PushTextWrapPos(450.0f);
+        ImGui::TextUnformatted(desc);
+        ImGui::PopTextWrapPos();
+        ImGui::EndTooltip();
+    }
 }
 
 void ImGui::ShowUserGuide()
@@ -349,18 +357,18 @@ void ImGui::ShowTestWindow(bool* p_open)
 
             ImGui::Text("Test paragraph 1:");
             ImVec2 pos = ImGui::GetCursorScreenPos();
-            ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), 0xFFFF00FF);
+            ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255));
             ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
             ImGui::Text("lazy dog. This paragraph is made to fit within %.0f pixels. The quick brown fox jumps over the lazy dog.", wrap_width);
-            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF);
+            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255));
             ImGui::PopTextWrapPos();
 
             ImGui::Text("Test paragraph 2:");
             pos = ImGui::GetCursorScreenPos();
-            ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), 0xFFFF00FF);
+            ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255));
             ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width);
             ImGui::Text("aaaaaaaa bbbbbbbb, cccccccc,dddddddd. eeeeeeee   ffffffff. gggggggg!hhhhhhhh");
-            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), 0xFF00FFFF);
+            ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255));
             ImGui::PopTextWrapPos();
 
             ImGui::TreePop();
@@ -442,6 +450,19 @@ void ImGui::ShowTestWindow(bool* p_open)
                 ImGui::Selectable("Hello.h", &selected[2]);   ImGui::SameLine(300); ImGui::Text(" 2,345 bytes");
                 ImGui::TreePop();
             }
+            if (ImGui::TreeNode("In columns"))
+            {
+                ImGui::Columns(3, NULL, false);
+                static bool selected[16] = { 0 };
+                for (int i = 0; i < 16; i++)
+                {
+                    char label[32]; sprintf(label, "Item %d", i);
+                    if (ImGui::Selectable(label, &selected[i])) {}
+                    ImGui::NextColumn();
+                }
+                ImGui::Columns(1);
+                ImGui::TreePop();
+            }
             if (ImGui::TreeNode("Grid"))
             {
                 static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true };
@@ -777,7 +798,7 @@ void ImGui::ShowTestWindow(bool* p_open)
         ImGui::Separator();
         ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth();
         ImGui::SameLine();
-        ImGui::SliderInt("Sample count", &display_count, 1, 500);
+        ImGui::SliderInt("Sample count", &display_count, 1, 400);
         float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw;
         ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
         ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80));
@@ -883,7 +904,7 @@ void ImGui::ShowTestWindow(bool* p_open)
 
         if (ImGui::TreeNode("Basic Horizontal Layout"))
         {
-            ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceeding item)");
+            ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)");
 
             // Text
             ImGui::Text("Two items: Hello"); ImGui::SameLine();
@@ -1007,24 +1028,24 @@ void ImGui::ShowTestWindow(bool* p_open)
             ImGui::Text("Hello\nWorld"); ImGui::SameLine();
             ImGui::Text("One\nTwo\nThree");
 
-            ImGui::Button("HOP"); ImGui::SameLine();
+            ImGui::Button("HOP##1"); ImGui::SameLine();
             ImGui::Text("Banana"); ImGui::SameLine();
             ImGui::Text("Hello\nWorld"); ImGui::SameLine();
             ImGui::Text("Banana");
 
-            ImGui::Button("HOP"); ImGui::SameLine();
+            ImGui::Button("HOP##2"); ImGui::SameLine();
             ImGui::Text("Hello\nWorld"); ImGui::SameLine();
             ImGui::Text("Banana");
 
-            ImGui::Button("TEST"); ImGui::SameLine();
+            ImGui::Button("TEST##1"); ImGui::SameLine();
             ImGui::Text("TEST"); ImGui::SameLine();
-            ImGui::SmallButton("TEST");
+            ImGui::SmallButton("TEST##2");
 
             ImGui::AlignFirstTextHeightToWidgets(); // If your line starts with text, call this to align it to upcoming widgets.
             ImGui::Text("Text aligned to Widget"); ImGui::SameLine();
-            ImGui::Button("Widget"); ImGui::SameLine();
+            ImGui::Button("Widget##1"); ImGui::SameLine();
             ImGui::Text("Widget"); ImGui::SameLine();
-            ImGui::SmallButton("Widget");
+            ImGui::SmallButton("Widget##2");
 
             // Tree
             const float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
@@ -1312,7 +1333,22 @@ void ImGui::ShowTestWindow(bool* p_open)
         // Basic columns
         if (ImGui::TreeNode("Basic"))
         {
-            ImGui::Columns(4, "mycolumns");
+            ImGui::Text("Without border:");
+            ImGui::Columns(3, "mycolumns3", false);  // 3-ways, no border
+            ImGui::Separator();
+            for (int n = 0; n < 14; n++)
+            {
+                char label[32];
+                sprintf(label, "Item %d", n);
+                if (ImGui::Selectable(label)) {}
+                //if (ImGui::Button(label, ImVec2(-1,0))) {}
+                ImGui::NextColumn();
+            }
+            ImGui::Columns(1);
+            ImGui::Separator();
+
+            ImGui::Text("With border:");
+            ImGui::Columns(4, "mycolumns"); // 4-ways, with border
             ImGui::Separator();
             ImGui::Text("ID"); ImGui::NextColumn();
             ImGui::Text("Name"); ImGui::NextColumn();
@@ -1506,7 +1542,7 @@ void ImGui::ShowTestWindow(bool* p_open)
 
         if (ImGui::TreeNode("Dragging"))
         {
-            ImGui::TextWrapped("You can use ImGui::GetItemActiveDragDelta() to query for the dragged amount on any widget.");
+            ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget.");
             ImGui::Button("Drag Me");
             if (ImGui::IsItemActive())
             {
@@ -1604,7 +1640,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
         ImGui::TreePop();
     }
 
-    if (ImGui::TreeNode("Sizes"))
+    if (ImGui::TreeNode("Settings"))
     {
         ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f");
         ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 16.0f, "%.0f");
@@ -1619,6 +1655,9 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
         ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 16.0f, "%.0f");
         ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f");
         ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 16.0f, "%.0f");
+        ImGui::Text("Alignment");
+        ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
+        ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content.");
         ImGui::TreePop();
     }
 
@@ -1642,7 +1681,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
             }
             ImGui::LogFinish();
         }
-        ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY"); ImGui::PopItemWidth();
+        ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth();
         ImGui::SameLine(); ImGui::Checkbox("Only Modified Fields", &output_only_modified);
 
         static ImGuiColorEditMode edit_mode = ImGuiColorEditMode_RGB;
@@ -1700,7 +1739,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
             ImGui::PopFont();
             if (ImGui::TreeNode("Details"))
             {
-                ImGui::DragFloat("font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");             // scale only this font
+                ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f");   // Scale only this font
+                ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)");
                 ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent);
                 ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar);
                 for (int config_i = 0; config_i < font->ConfigDataCount; config_i++)
@@ -1708,6 +1748,47 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
                     ImFontConfig* cfg = &font->ConfigData[config_i];
                     ImGui::BulletText("Input %d: \'%s\'\nOversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH);
                 }
+                if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size))
+                {
+                    // Display all glyphs of the fonts in separate pages of 256 characters
+                    const ImFont::Glyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior.
+                    font->FallbackGlyph = NULL;
+                    for (int base = 0; base < 0x10000; base += 256)
+                    {
+                        int count = 0;
+                        for (int n = 0; n < 256; n++)
+                            count += font->FindGlyph((ImWchar)(base + n)) ? 1 : 0;
+                        if (count > 0 && ImGui::TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base+255, count, count > 1 ? "glyphs" : "glyph"))
+                        {
+                            float cell_spacing = style.ItemSpacing.y;
+                            ImVec2 cell_size(font->FontSize * 1, font->FontSize * 1);
+                            ImVec2 base_pos = ImGui::GetCursorScreenPos();
+                            ImDrawList* draw_list = ImGui::GetWindowDrawList();
+                            for (int n = 0; n < 256; n++)
+                            {
+                                ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing));
+                                ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y);
+                                const ImFont::Glyph* glyph = font->FindGlyph((ImWchar)(base+n));;
+                                draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50));
+                                font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string.
+                                if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2))
+                                {
+                                    ImGui::BeginTooltip();
+                                    ImGui::Text("Codepoint: U+%04X", base+n);
+                                    ImGui::Separator();
+                                    ImGui::Text("XAdvance+1: %.1f", glyph->XAdvance);
+                                    ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1);
+                                    ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1);
+                                    ImGui::EndTooltip();
+                                }
+                            }
+                            ImGui::Dummy(ImVec2((cell_size.x + cell_spacing) * 16, (cell_size.y + cell_spacing) * 16));
+                            ImGui::TreePop();
+                        }
+                    }
+                    font->FallbackGlyph = glyph_fallback;
+                    ImGui::TreePop();
+                }
                 ImGui::TreePop();
             }
             ImGui::TreePop();
@@ -1984,7 +2065,7 @@ static void ShowExampleAppCustomRendering(bool* p_open)
         }
         draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y));      // clip lines within the canvas (if we resize it, etc.)
         for (int i = 0; i < points.Size - 1; i += 2)
-            draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), 0xFF00FFFF, 2.0f);
+            draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), IM_COL32(255,255,0,255), 2.0f);
         draw_list->PopClipRect();
         if (adding_preview)
             points.pop_back();
@@ -2156,7 +2237,8 @@ struct ExampleAppConsole
         }
         else if (Stricmp(command_line, "HISTORY") == 0)
         {
-            for (int i = History.Size >= 10 ? History.Size - 10 : 0; i < History.Size; i++)
+            int first = History.Size - 10;
+            for (int i = first > 0 ? first : 0; i < History.Size; i++)
                 AddLog("%3d: %s\n", i, History[i]);
         }
         else

+ 48 - 33
third/bgfx/3rdparty/ocornut-imgui/imgui_draw.cpp

@@ -18,9 +18,11 @@
 #include "imgui_internal.h"
 
 #include <stdio.h>      // vsnprintf, sscanf, printf
-#if !defined(alloca) && !defined(__FreeBSD__) && !defined(__DragonFly__)
+#if !defined(alloca)
 #ifdef _WIN32
 #include <malloc.h>     // alloca
+#elif (defined(__FreeBSD__) || defined(FreeBSD_kernel) || defined(__DragonFly__)) && !defined(__GLIBC__)
+#include <stdlib.h>     // alloca. FreeBSD uses stdlib.h unless GLIBC
 #else
 #include <alloca.h>     // alloca
 #endif
@@ -37,7 +39,9 @@
 #pragma clang diagnostic ignored "-Wfloat-equal"            // warning : comparing floating point with == or != is unsafe   // storing and comparing against same constants ok.
 #pragma clang diagnostic ignored "-Wglobal-constructors"    // warning : declaration requires a global destructor           // similar to above, not sure what the exact difference it.
 #pragma clang diagnostic ignored "-Wsign-conversion"        // warning : implicit conversion changes signedness             //
+#if __has_warning("-Wreserved-id-macro")
 #pragma clang diagnostic ignored "-Wreserved-id-macro"      // warning : macro name is a reserved identifier                //
+#endif
 #elif defined(__GNUC__)
 #pragma GCC diagnostic ignored "-Wunused-function"          // warning: 'xxxx' defined but not used
 #pragma GCC diagnostic ignored "-Wdouble-promotion"         // warning: implicit conversion from 'float' to 'double' when passing argument to function
@@ -197,7 +201,7 @@ void ImDrawList::UpdateClipRect()
 
     // Try to merge with previous command if it matches, else use current command
     ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL;
-    if (prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL)
+    if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL)
         CmdBuffer.pop_back();
     else
         curr_cmd->ClipRect = curr_clip_rect;
@@ -429,7 +433,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
     {
         // Anti-aliased stroke
         const float AA_SIZE = 1.0f;
-        const ImU32 col_trans = col & 0x00ffffff;
+        const ImU32 col_trans = col & IM_COL32(255,255,255,0);
 
         const int idx_count = thick_line ? count*18 : count*12;
         const int vtx_count = thick_line ? points_count*4 : points_count*3;
@@ -602,7 +606,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
     {
         // Anti-aliased Fill
         const float AA_SIZE = 1.0f;
-        const ImU32 col_trans = col & 0x00ffffff;
+        const ImU32 col_trans = col & IM_COL32(255,255,255,0);
         const int idx_count = (points_count-2)*3 + points_count*6;
         const int vtx_count = (points_count*2);
         PrimReserve(idx_count, vtx_count);
@@ -797,7 +801,7 @@ void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int
 
 void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
     PathLineTo(a + ImVec2(0.5f,0.5f));
     PathLineTo(b + ImVec2(0.5f,0.5f));
@@ -805,21 +809,21 @@ void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thic
 }
 
 // a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly.
-void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners, float thickness)
+void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags, float thickness)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
-    PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners);
+    PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners_flags);
     PathStroke(col, true, thickness);
 }
 
-void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners)
+void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
     if (rounding > 0.0f)
     {
-        PathRect(a, b, rounding, rounding_corners);
+        PathRect(a, b, rounding, rounding_corners_flags);
         PathFill(col);
     }
     else
@@ -831,7 +835,7 @@ void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, floa
 
 void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left)
 {
-    if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) >> 24) == 0)
+    if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0)
         return;
 
     const ImVec2 uv = GImGui->FontTexUvWhitePixel;
@@ -846,7 +850,7 @@ void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32
 
 void ImDrawList::AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     PathLineTo(a);
@@ -858,7 +862,7 @@ void ImDrawList::AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, cons
 
 void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     PathLineTo(a);
@@ -870,7 +874,7 @@ void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c
 
 void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     PathLineTo(a);
@@ -881,7 +885,7 @@ void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c,
 
 void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     PathLineTo(a);
@@ -892,7 +896,7 @@ void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec
 
 void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
@@ -902,7 +906,7 @@ void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int nu
 
 void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments;
@@ -912,7 +916,7 @@ void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col,
 
 void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     PathLineTo(pos0);
@@ -922,7 +926,7 @@ void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImV
 
 void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     if (text_end == NULL)
@@ -957,7 +961,7 @@ void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, c
 
 void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv0, const ImVec2& uv1, ImU32 col)
 {
-    if ((col >> 24) == 0)
+    if ((col & IM_COL32_A_MASK) == 0)
         return;
 
     // FIXME-OPT: This is wasting draw calls.
@@ -1119,7 +1123,7 @@ void    ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_wid
         const unsigned char* src = pixels;
         unsigned int* dst = TexPixelsRGBA32;
         for (int n = TexWidth * TexHeight; n > 0; n--)
-            *dst++ = ((unsigned int)(*src++) << 24) | 0x00FFFFFF;
+            *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++));
     }
 
     *out_pixels = (unsigned char*)TexPixelsRGBA32;
@@ -1167,7 +1171,7 @@ static void         Decode85(const unsigned char* src, unsigned char* dst)
     while (*src)
     {
         unsigned int tmp = Decode85Byte(src[0]) + 85*(Decode85Byte(src[1]) + 85*(Decode85Byte(src[2]) + 85*(Decode85Byte(src[3]) + 85*Decode85Byte(src[4]))));
-        dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF);   // We can't assume little-endianess.
+        dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF);   // We can't assume little-endianness.
         src += 5;
         dst += 4;
     }
@@ -1652,6 +1656,17 @@ const ImWchar*  ImFontAtlas::GetGlyphRangesCyrillic()
     return &ranges[0];
 }
 
+const ImWchar*  ImFontAtlas::GetGlyphRangesThai()
+{
+    static const ImWchar ranges[] =
+    {
+        0x0020, 0x00FF, // Basic Latin
+        0x0E00, 0x0E7F, // Thai
+        0,
+    };
+    return &ranges[0];
+}
+
 //-----------------------------------------------------------------------------
 // ImFont
 //-----------------------------------------------------------------------------
@@ -1697,7 +1712,7 @@ void ImFont::BuildLookupTable()
     for (int i = 0; i != Glyphs.Size; i++)
         max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint);
 
-    IM_ASSERT(Glyphs.Size < 32*1024);
+    IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved
     IndexXAdvance.clear();
     IndexLookup.clear();
     GrowIndex(max_codepoint + 1);
@@ -1705,7 +1720,7 @@ void ImFont::BuildLookupTable()
     {
         int codepoint = (int)Glyphs[i].Codepoint;
         IndexXAdvance[codepoint] = Glyphs[i].XAdvance;
-        IndexLookup[codepoint] = (short)i;
+        IndexLookup[codepoint] = (unsigned short)i;
     }
 
     // Create a glyph to handle TAB
@@ -1719,7 +1734,7 @@ void ImFont::BuildLookupTable()
         tab_glyph.Codepoint = '\t';
         tab_glyph.XAdvance *= 4;
         IndexXAdvance[(int)tab_glyph.Codepoint] = (float)tab_glyph.XAdvance;
-        IndexLookup[(int)tab_glyph.Codepoint] = (short)(Glyphs.Size-1);
+        IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size-1);
     }
 
     FallbackGlyph = NULL;
@@ -1747,7 +1762,7 @@ void ImFont::GrowIndex(int new_size)
     for (int i = old_size; i < new_size; i++)
     {
         IndexXAdvance[i] = -1.0f;
-        IndexLookup[i] = (short)-1;
+        IndexLookup[i] = (unsigned short)-1;
     }
 }
 
@@ -1756,13 +1771,13 @@ void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst)
     IM_ASSERT(IndexLookup.Size > 0);    // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function.
     int index_size = IndexLookup.Size;
 
-    if (dst < index_size && IndexLookup.Data[dst] == -1 && !overwrite_dst) // 'dst' already exists
+    if (dst < index_size && IndexLookup.Data[dst] == (unsigned short)-1 && !overwrite_dst) // 'dst' already exists
         return;
     if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op
         return;
 
     GrowIndex(dst + 1);
-    IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : -1;
+    IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1;
     IndexXAdvance[dst] = (src < index_size) ? IndexXAdvance.Data[src] : 1.0f;
 }
 
@@ -1770,8 +1785,8 @@ const ImFont::Glyph* ImFont::FindGlyph(unsigned short c) const
 {
     if (c < IndexLookup.Size)
     {
-        const short i = IndexLookup[c];
-        if (i != -1)
+        const unsigned short i = IndexLookup[c];
+        if (i != (unsigned short)-1)
             return &Glyphs.Data[i];
     }
     return FallbackGlyph;
@@ -1830,7 +1845,7 @@ const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const c
             }
         }
 
-        const float char_width = ((int)c < IndexXAdvance.Size) ? IndexXAdvance[(int)c] * scale : FallbackXAdvance;
+        const float char_width = ((int)c < IndexXAdvance.Size ? IndexXAdvance[(int)c] : FallbackXAdvance) * scale;
         if (ImCharIsSpace(c))
         {
             if (inside_word)
@@ -2313,7 +2328,7 @@ static const char proggy_clean_ttf_compressed_data_base85[11980+1] =
     "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et"
     "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$<M-SGZ':+Q_k+uvOSLiEo(<aD/K<CCc`'Lx>'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:"
     "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VB<HFF*qL("
-    "$/V,;(kXZejWO`<[5??ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<[email protected];x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
+    "$/V,;(kXZejWO`<[5?\?ewY(*9=%wDc;,u<'9t3W-(H1th3+G]ucQ]kLs7df($/*JL]@*t7Bu_G3_7mp7<[email protected];x3B0lqp7Hf,^Ze7-##@/c58Mo(3;knp0%)A7?-W+eI'o8)b<"
     "nKnw'Ho8C=Y>pqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<<aG/1N$#FX$0V5Y6x'aErI3I$7x%E`v<-BY,)%-?Psf*l?%C3.mM(=/M0:JxG'?"
     "7WhH%o'a<-80g0NBxoO(GH<dM]n.+%q@jH?f.UsJ2Ggs&4<-e47&Kl+f//9@`b+?.TeN_&B8Ss?v;^Trk;f#YvJkl&w$]>-+k?'(<S:68tq*WoDfZu';mM?8X[ma8W%*`-=;D.(nc7/;"
     ")g:T1=^J$&BRV(-lTmNB6xqB[@0*o.erM*<SWF]u2=st-*(6v>^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M"

+ 37 - 22
third/bgfx/3rdparty/ocornut-imgui/imgui_internal.h

@@ -75,6 +75,7 @@ extern IMGUI_API ImGuiContext*  GImGui;     // current implicit ImGui context po
 
 #define IM_ARRAYSIZE(_ARR)      ((int)(sizeof(_ARR)/sizeof(*_ARR)))
 #define IM_PI                   3.14159265358979323846f
+#define IM_OFFSETOF(_TYPE,_ELM) ((size_t)&(((_TYPE*)0)->_ELM))
 
 // Helpers: UTF-8 <> wchar
 IMGUI_API int           ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end);      // return output UTF-8 bytes count
@@ -192,7 +193,17 @@ enum ImGuiPlotType
 enum ImGuiDataType
 {
     ImGuiDataType_Int,
-    ImGuiDataType_Float
+    ImGuiDataType_Float,
+    ImGuiDataType_Float2,
+};
+
+enum ImGuiCorner
+{
+    ImGuiCorner_TopLeft     = 1 << 0, // 1
+    ImGuiCorner_TopRight    = 1 << 1, // 2
+    ImGuiCorner_BottomRight = 1 << 2, // 4
+    ImGuiCorner_BottomLeft  = 1 << 3, // 8
+    ImGuiCorner_All         = 0x0F
 };
 
 // 2D axis aligned bounding-box
@@ -241,14 +252,17 @@ struct IMGUI_API ImRect
 struct ImGuiColMod
 {
     ImGuiCol    Col;
-    ImVec4      PreviousValue;
+    ImVec4      BackupValue;
 };
 
-// Stacked style modifier, backup of modified data so we can restore it
+// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
 struct ImGuiStyleMod
 {
-    ImGuiStyleVar   Var;
-    ImVec2          PreviousValue;
+    ImGuiStyleVar   VarIdx;
+    union           { int BackupInt[2]; float BackupFloat[2]; };
+    ImGuiStyleMod(ImGuiStyleVar idx, int v)     { VarIdx = idx; BackupInt[0] = v; }
+    ImGuiStyleMod(ImGuiStyleVar idx, float v)   { VarIdx = idx; BackupFloat[0] = v; }
+    ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v)  { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
 };
 
 // Stacked data for BeginGroup()/EndGroup()
@@ -257,9 +271,11 @@ struct ImGuiGroupData
     ImVec2      BackupCursorPos;
     ImVec2      BackupCursorMaxPos;
     float       BackupIndentX;
+    float       BackupGroupOffsetX;
     float       BackupCurrentLineHeight;
     float       BackupCurrentLineTextBaseOffset;
     float       BackupLogLinePosY;
+    bool        BackupActiveIdIsAlive;
     bool        AdvanceCursor;
 };
 
@@ -312,7 +328,7 @@ struct IMGUI_API ImGuiTextEditState
 struct ImGuiIniData
 {
     char*       Name;
-    ImGuiID     ID;
+    ImGuiID     Id;
     ImVec2      Pos;
     ImVec2      Size;
     bool        Collapsed;
@@ -331,13 +347,13 @@ struct ImGuiMouseCursorData
 // Storage for current popup stack
 struct ImGuiPopupRef
 {
-    ImGuiID         PopupID;        // Set on OpenPopup()
+    ImGuiID         PopupId;        // Set on OpenPopup()
     ImGuiWindow*    Window;         // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
     ImGuiWindow*    ParentWindow;   // Set on OpenPopup()
     ImGuiID         ParentMenuSet;  // Set on OpenPopup()
     ImVec2          MousePosOnOpen; // Copy of mouse position at the time of opening popup
 
-    ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupID = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
+    ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupId = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
 };
 
 // Main state for ImGui
@@ -481,7 +497,7 @@ struct ImGuiContext
         ScalarAsInputTextId = 0;
         DragCurrentValue = 0.0f;
         DragLastMouseDelta = ImVec2(0.0f, 0.0f);
-        DragSpeedDefaultRatio = 0.01f;
+        DragSpeedDefaultRatio = 1.0f / 100.0f;
         DragSpeedScaleSlow = 0.01f;
         DragSpeedScaleFast = 10.0f;
         ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f);
@@ -522,7 +538,7 @@ struct IMGUI_API ImGuiDrawContext
     float                   PrevLineTextBaseOffset;
     float                   LogLinePosY;
     int                     TreeDepth;
-    ImGuiID                 LastItemID;
+    ImGuiID                 LastItemId;
     ImRect                  LastItemRect;
     bool                    LastItemHoveredAndUsable;  // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window)
     bool                    LastItemHoveredRect;       // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window)
@@ -546,6 +562,7 @@ struct IMGUI_API ImGuiDrawContext
     int                     StackSizesBackup[6];    // Store size of various stacks for asserting
 
     float                   IndentX;                // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
+    float                   GroupOffsetX;
     float                   ColumnsOffsetX;         // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API.
     int                     ColumnsCurrent;
     int                     ColumnsCount;
@@ -555,7 +572,7 @@ struct IMGUI_API ImGuiDrawContext
     float                   ColumnsCellMinY;
     float                   ColumnsCellMaxY;
     bool                    ColumnsShowBorders;
-    ImGuiID                 ColumnsSetID;
+    ImGuiID                 ColumnsSetId;
     ImVector<ImGuiColumnData> ColumnsData;
 
     ImGuiDrawContext()
@@ -565,7 +582,7 @@ struct IMGUI_API ImGuiDrawContext
         CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f;
         LogLinePosY = -1.0f;
         TreeDepth = 0;
-        LastItemID = 0;
+        LastItemId = 0;
         LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f);
         LastItemHoveredAndUsable = LastItemHoveredRect = false;
         MenuBarAppending = false;
@@ -587,7 +604,7 @@ struct IMGUI_API ImGuiDrawContext
         ColumnsStartPosY = 0.0f;
         ColumnsCellMinY = ColumnsCellMaxY = 0.0f;
         ColumnsShowBorders = true;
-        ColumnsSetID = 0;
+        ColumnsSetId = 0;
     }
 };
 
@@ -606,7 +623,7 @@ struct IMGUI_API ImGuiWindow
     ImVec2                  SizeContentsExplicit;               // Size of contents explicitly set by the user via SetNextWindowContentSize()
     ImRect                  ContentsRegionRect;                 // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis
     ImVec2                  WindowPadding;                      // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect
-    ImGuiID                 MoveID;                             // == window->GetID("#MOVE")
+    ImGuiID                 MoveId;                             // == window->GetID("#MOVE")
     ImVec2                  Scroll;
     ImVec2                  ScrollTarget;                       // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
     ImVec2                  ScrollTargetCenterRatio;            // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
@@ -619,7 +636,7 @@ struct IMGUI_API ImGuiWindow
     bool                    Collapsed;                          // Set when collapsing window to become only title-bar
     bool                    SkipItems;                          // == Visible && !Collapsed
     int                     BeginCount;                         // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
-    ImGuiID                 PopupID;                            // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
+    ImGuiID                 PopupId;                            // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
     int                     AutoFitFramesX, AutoFitFramesY;
     bool                    AutoFitOnlyGrows;
     int                     AutoPosLastDirection;
@@ -643,7 +660,7 @@ struct IMGUI_API ImGuiWindow
     ImGuiWindow*            RootNonPopupWindow;                 // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself.
     ImGuiWindow*            ParentWindow;                       // If we are a child window, this is pointing to our parent window. Else point to NULL.
 
-    // Focus
+    // Navigation / Focus
     int                     FocusIdxAllCounter;                 // Start at -1 and increase as assigned via FocusItemRegister()
     int                     FocusIdxTabCounter;                 // (same, but only count widgets which you can Tab through)
     int                     FocusIdxAllRequestCurrent;          // Item being requested for focus
@@ -657,6 +674,7 @@ public:
 
     ImGuiID     GetID(const char* str, const char* str_end = NULL);
     ImGuiID     GetID(const void* ptr);
+    ImGuiID     GetIDNoKeepAlive(const char* str, const char* str_end = NULL);
 
     ImRect      Rect() const                            { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); }
     float       CalcFontSize() const                    { return GImGui->FontBaseSize * FontWindowScale; }
@@ -701,17 +719,14 @@ namespace ImGui
 
     IMGUI_API void          OpenPopupEx(const char* str_id, bool reopen_existing);
 
-    inline IMGUI_API ImU32  GetColorU32(ImGuiCol idx, float alpha_mul)  { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); }
-    inline IMGUI_API ImU32  GetColorU32(const ImVec4& col)              { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
-
     // NB: All position are in absolute pixels coordinates (not window coordinates)
-    // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp!
+    // FIXME: All those functions are a mess and needs to be refactored into something decent. AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION.
     // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers.
     IMGUI_API void          RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
     IMGUI_API void          RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
-    IMGUI_API void          RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
+    IMGUI_API void          RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL);
     IMGUI_API void          RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
-    IMGUI_API void          RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f, bool shadow = false);
+    IMGUI_API void          RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f);
     IMGUI_API void          RenderBullet(ImVec2 pos);
     IMGUI_API void          RenderCheckMark(ImVec2 pos, ImU32 col);
     IMGUI_API const char*   FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.

+ 1 - 0
third/bgfx/3rdparty/ocornut-imgui/imgui_user.h

@@ -44,3 +44,4 @@ namespace ImGui
 
 #include "widgets/file_list.h"
 #include "widgets/memory_editor.h"
+#include "widgets/gizmo.h"

+ 1 - 0
third/bgfx/3rdparty/ocornut-imgui/imgui_user.inl

@@ -74,3 +74,4 @@ namespace ImGui
 
 #include "widgets/file_list.inl"
 #include "widgets/memory_editor.inl"
+#include "widgets/gizmo.inl"

+ 10 - 3
third/bgfx/3rdparty/ocornut-imgui/imgui_wm.cpp

@@ -575,8 +575,8 @@ namespace ImGuiWM
                 ImColor oSelectedTab(37, 37, 37, 255); // selected
                 ImColor oBorderColor(72, 72, 72, 255); // border
 
-                ImVec2 oRectMin = ImGui::GetItemBoxMin();
-                ImVec2 oRectMax = ImGui::GetItemBoxMax();
+                ImVec2 oRectMin = ImGui::GetItemRectMin();
+                ImVec2 oRectMax = ImGui::GetItemRectMax();
 
                 const float fOverlap = 10.f;
                 const float fSlopWidth = 30.f;
@@ -647,7 +647,14 @@ namespace ImGuiWM
 
                 pDrawList->PathClear();
 
-                ImGui::RenderTextClipped(oRectMin, ImVec2(oRectMax.x, oRectMax.y), (*it)->GetTitle(), NULL, &oTextSize, ImGuiAlign_Center | ImGuiAlign_VCenter);
+                ImGui::RenderTextClipped(
+                      oRectMin
+                    , ImVec2(oRectMax.x, oRectMax.y)
+                    , (*it)->GetTitle()
+                    , NULL
+                    , &oTextSize
+                    , ImVec2(0.5f, 0.5f)
+                );
 
                 if (ImGui::BeginPopupContextItem("TabMenu"))
                 {

+ 5 - 0
third/bgfx/3rdparty/ocornut-imgui/widgets/file_list.inl

@@ -1,3 +1,4 @@
+#include <bx/bx.h>
 #include <dirent.h>
 #include <sys/stat.h>
 
@@ -15,6 +16,9 @@ namespace ImGui
 
 	void ImFileList::ChDir(const char* path)
 	{
+#if BX_PLATFORM_NACL || BX_PLATFORM_PS4
+		BX_UNUSED(path);
+#else
 		DIR* dir = opendir(path);
 		if (NULL != dir)
 		{
@@ -43,6 +47,7 @@ namespace ImGui
 
 			closedir(dir);
 		}
+#endif // BX_PLATFORM_NACL || BX_PLATFORM_PS4
 	}
 
 	void ImFileList::Draw()

+ 156 - 0
third/bgfx/3rdparty/ocornut-imgui/widgets/gizmo.h

@@ -0,0 +1,156 @@
+// https://github.com/CedricGuillemet/ImGuizmo
+// v 1.04 WIP
+//
+// The MIT License(MIT)
+// 
+// Copyright(c) 2016 Cedric Guillemet
+// 
+// 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 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.
+//
+// -------------------------------------------------------------------------------------------
+// History : 
+// 2016/09/11 Behind camera culling. Scaling Delta matrix not multiplied by source matrix scales. local/world rotation and translation fixed. Display message is incorrect (X: ... Y:...) in local mode.
+// 2016/09/09 Hatched negative axis. Snapping. Documentation update.
+// 2016/09/04 Axis switch and translation plan autohiding. Scale transform stability improved
+// 2016/09/01 Mogwai changed to Manipulate. Draw debug cube. Fixed inverted scale. Mixing scale and translation/rotation gives bad results.
+// 2016/08/31 First version
+//
+// -------------------------------------------------------------------------------------------
+// Future (no order):
+//
+// - Multi view
+// - display rotation/translation/scale infos in local/world space and not only local
+// - finish local/world matrix application
+// - OPERATION as bitmask
+// 
+// -------------------------------------------------------------------------------------------
+// Example 
+#if 0
+void EditTransform(const Camera& camera, matrix_t& matrix)
+{
+	static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
+	static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
+	if (ImGui::IsKeyPressed(90))
+		mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
+	if (ImGui::IsKeyPressed(69))
+		mCurrentGizmoOperation = ImGuizmo::ROTATE;
+	if (ImGui::IsKeyPressed(82)) // r Key
+		mCurrentGizmoOperation = ImGuizmo::SCALE;
+	if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
+		mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
+	ImGui::SameLine();
+	if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
+		mCurrentGizmoOperation = ImGuizmo::ROTATE;
+	ImGui::SameLine();
+	if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
+		mCurrentGizmoOperation = ImGuizmo::SCALE;
+	float matrixTranslation[3], matrixRotation[3], matrixScale[3];
+	ImGuizmo::DecomposeMatrixToComponents(matrix.m16, matrixTranslation, matrixRotation, matrixScale);
+	ImGui::InputFloat3("Tr", matrixTranslation, 3);
+	ImGui::InputFloat3("Rt", matrixRotation, 3);
+	ImGui::InputFloat3("Sc", matrixScale, 3);
+	ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, matrix.m16);
+
+	if (mCurrentGizmoOperation != ImGuizmo::SCALE)
+	{
+		if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
+			mCurrentGizmoMode = ImGuizmo::LOCAL;
+		ImGui::SameLine();
+		if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
+			mCurrentGizmoMode = ImGuizmo::WORLD;
+	}
+	static bool useSnap(false);
+	if (ImGui::IsKeyPressed(83))
+		useSnap = !useSnap;
+	ImGui::Checkbox("", &useSnap);
+	ImGui::SameLine();
+	vec_t snap;
+	switch (mCurrentGizmoOperation)
+	{
+	case ImGuizmo::TRANSLATE:
+		snap = config.mSnapTranslation;
+		ImGui::InputFloat3("Snap", &snap.x);
+		break;
+	case ImGuizmo::ROTATE:
+		snap = config.mSnapRotation;
+		ImGui::InputFloat("Angle Snap", &snap.x);
+		break;
+	case ImGuizmo::SCALE:
+		snap = config.mSnapScale;
+		ImGui::InputFloat("Scale Snap", &snap.x);
+		break;
+	}
+
+	ImGuizmo::Manipulate(camera.mView.m16, camera.mProjection.m16, mCurrentGizmoOperation, mCurrentGizmoMode, matrix.m16, NULL, useSnap ? &snap.x : NULL);
+}
+#endif
+#pragma once
+
+namespace ImGuizmo
+{
+	// call BeginFrame right after ImGui_XXXX_NewFrame();
+	void BeginFrame();
+
+	// return true if mouse cursor is over any gizmo control (axis, plan or screen component)
+	bool IsOver();
+
+	// return true if mouse IsOver or if the gizmo is in moving state
+	bool IsUsing();
+
+	// enable/disable the gizmo. Stay in the state until next call to Enable.
+	// gizmo is rendered with gray half transparent color when disabled
+	void Enable(bool enable);
+
+	// helper functions for manualy editing translation/rotation/scale with an input float
+	// translation, rotation and scale float points to 3 floats each
+	// Angles are in degrees (more suitable for human editing)
+	// example:
+	// float matrixTranslation[3], matrixRotation[3], matrixScale[3];
+	// ImGuizmo::DecomposeMatrixToComponents(gizmoMatrix.m16, matrixTranslation, matrixRotation, matrixScale);
+	// ImGui::InputFloat3("Tr", matrixTranslation, 3);
+	// ImGui::InputFloat3("Rt", matrixRotation, 3);
+	// ImGui::InputFloat3("Sc", matrixScale, 3);
+	// ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, gizmoMatrix.m16);
+	//
+	// These functions have some numerical stability issues for now. Use with caution.
+	void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale);
+	void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix);
+
+	// Render a cube with face color corresponding to face normal. Usefull for debug/tests
+	void DrawCube(const float *view, const float *projection, float *matrix);
+
+	// call it when you want a gizmo
+	// Needs view and projection matrices. 
+	// matrix parameter is the source matrix (where will be gizmo be drawn) and might be transformed by the function. Return deltaMatrix is optional
+	// translation is applied in world space
+	enum OPERATION
+	{
+		TRANSLATE,
+		ROTATE,
+		SCALE
+	};
+
+	enum MODE
+	{
+		LOCAL,
+		WORLD
+	};
+
+	void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix = 0, float *snap = 0);
+};

+ 1489 - 0
third/bgfx/3rdparty/ocornut-imgui/widgets/gizmo.inl

@@ -0,0 +1,1489 @@
+// The MIT License(MIT)
+// 
+// Copyright(c) 2016 Cedric Guillemet
+// 
+// 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 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.
+
+namespace ImGuizmo
+{
+	static const float ZPI = 3.14159265358979323846f;
+	static const float RAD2DEG = (180.f / ZPI);
+	static const float DEG2RAD = (ZPI / 180.f);
+
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// utility and math
+
+	void FPU_MatrixF_x_MatrixF(const float *a, const float *b, float *r)
+	{
+		r[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
+		r[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
+		r[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
+		r[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
+
+		r[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
+		r[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
+		r[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
+		r[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
+
+		r[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
+		r[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
+		r[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
+		r[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
+
+		r[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
+		r[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
+		r[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
+		r[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
+	}
+
+	//template <typename T> T LERP(T x, T y, float z) { return (x + (y - x)*z); }
+	template <typename T> T Clamp(T x, T y, T z) { return ((x<y) ? y : ((x>z) ? z : x)); }
+	template <typename T> T max(T x, T y) { return (x > y) ? x : y; }
+
+	struct matrix_t;
+	struct vec_t
+	{
+	public:
+		float x, y, z, w;
+
+		void Lerp(const vec_t& v, float t)
+		{
+			x += (v.x - x) * t;
+			y += (v.y - y) * t;
+			z += (v.z - z) * t;
+			w += (v.w - w) * t;
+		}
+
+		void Set(float v) { x = y = z = w = v; }
+		void Set(float _x, float _y, float _z = 0.f, float _w = 0.f) { x = _x; y = _y; z = _z; w = _w; }
+
+		vec_t& operator -= (const vec_t& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
+		vec_t& operator += (const vec_t& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
+		vec_t& operator *= (const vec_t& v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; }
+		vec_t& operator *= (float v) { x *= v;	y *= v;	z *= v;	w *= v;	return *this; }
+
+		vec_t operator * (float f) const;
+		vec_t operator - () const;
+		vec_t operator - (const vec_t& v) const;
+		vec_t operator + (const vec_t& v) const;
+		vec_t operator * (const vec_t& v) const;
+
+		const vec_t& operator + () const { return (*this); }
+		float Length() const { return sqrtf(x*x + y*y + z*z); };
+		float LengthSq() const { return (x*x + y*y + z*z); };
+		vec_t Normalize() { (*this) *= (1.f / Length()); return (*this); }
+		vec_t Normalize(const vec_t& v) { this->Set(v.x, v.y, v.z, v.w); this->Normalize(); return (*this); }
+
+		void Cross(const vec_t& v)
+		{
+			vec_t res;
+			res.x = y * v.z - z * v.y;
+			res.y = z * v.x - x * v.z;
+			res.z = x * v.y - y * v.x;
+
+			x = res.x;
+			y = res.y;
+			z = res.z;
+			w = 0.f;
+		}
+		void Cross(const vec_t& v1, const vec_t& v2)
+		{
+			x = v1.y * v2.z - v1.z * v2.y;
+			y = v1.z * v2.x - v1.x * v2.z;
+			z = v1.x * v2.y - v1.y * v2.x;
+			w = 0.f;
+		}
+		float Dot(const vec_t &v) const
+		{
+			return (x * v.x) + (y * v.y) + (z * v.z) + (w * v.w);
+		}
+		float Dot3(const vec_t &v) const
+		{
+			return (x * v.x) + (y * v.y) + (z * v.z);
+		}
+		
+		void Transform(const matrix_t& matrix);
+		void Transform(const vec_t & s, const matrix_t& matrix);
+
+		void TransformVector(const matrix_t& matrix);
+		void TransformPoint(const matrix_t& matrix);
+		void TransformVector(const vec_t& v, const matrix_t& matrix) { (*this) = v; this->TransformVector(matrix); }
+		void TransformPoint(const vec_t& v, const matrix_t& matrix) { (*this) = v; this->TransformPoint(matrix); }
+
+		float& operator [] (size_t index) { return ((float*)&x)[index]; }
+		const float& operator [] (size_t index) const { return ((float*)&x)[index]; }
+	};
+
+	vec_t makeVect(float _x, float _y, float _z = 0.f, float _w = 0.f) { vec_t res; res.x = _x; res.y = _y; res.z = _z; res.w = _w; return res; }
+	vec_t vec_t::operator * (float f) const { return makeVect(x * f, y * f, z * f, w *f); }
+	vec_t vec_t::operator - () const { return makeVect(-x, -y, -z, -w); }
+	vec_t vec_t::operator - (const vec_t& v) const { return makeVect(x - v.x, y - v.y, z - v.z, w - v.w); }
+	vec_t vec_t::operator + (const vec_t& v) const { return makeVect(x + v.x, y + v.y, z + v.z, w + v.w); }
+	vec_t vec_t::operator * (const vec_t& v) const { return makeVect(x * v.x, y * v.y, z * v.z, w * v.w); }
+
+	ImVec2 operator+ (const ImVec2& a, const ImVec2& b) { return ImVec2(a.x + b.x, a.y + b.y); }
+
+	vec_t Normalized(const vec_t& v) { vec_t res; res = v; res.Normalize(); return res; }
+	vec_t Cross(const vec_t& v1, const vec_t& v2)
+	{
+		vec_t res;
+		res.x = v1.y * v2.z - v1.z * v2.y;
+		res.y = v1.z * v2.x - v1.x * v2.z;
+		res.z = v1.x * v2.y - v1.y * v2.x;
+		res.w = 0.f;
+		return res;
+	}
+
+	float Dot(const vec_t &v1, const vec_t &v2)
+	{
+		return (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z);
+	}
+
+	vec_t BuildPlan(const vec_t & p_point1, const vec_t & p_normal)
+	{
+		vec_t normal, res;
+		normal.Normalize(p_normal);
+		res.w = normal.Dot(p_point1);
+		res.x = normal.x;
+		res.y = normal.y;
+		res.z = normal.z;
+		return res;
+	}
+
+	struct matrix_t
+	{
+	public:
+
+		union
+		{
+			float m[4][4];
+			float m16[16];
+			struct
+			{
+				vec_t right, up, dir, position;
+			} v;
+		};
+
+		matrix_t(const matrix_t& other) { memcpy(&m16[0], &other.m16[0], sizeof(float) * 16); }
+		matrix_t() {}
+
+		operator float * () { return m16; }
+		operator const float* () const { return m16; }
+		void Translation(float _x, float _y, float _z) { this->Translation(makeVect(_x, _y, _z)); }
+
+		void Translation(const vec_t& vt)
+		{
+			v.right.Set(1.f, 0.f, 0.f, 0.f);
+			v.up.Set(0.f, 1.f, 0.f, 0.f);
+			v.dir.Set(0.f, 0.f, 1.f, 0.f);
+			v.position.Set(vt.x, vt.y, vt.z, 1.f);
+		}
+
+		void Scale(float _x, float _y, float _z)
+		{
+			v.right.Set(_x, 0.f, 0.f, 0.f);
+			v.up.Set(0.f, _y, 0.f, 0.f);
+			v.dir.Set(0.f, 0.f, _z, 0.f);
+			v.position.Set(0.f, 0.f, 0.f, 1.f);
+		}
+		void Scale(const vec_t& s) { Scale(s.x, s.y, s.z); }
+
+		matrix_t& operator *= (const matrix_t& mat)
+		{
+			matrix_t tmpMat;
+			tmpMat = *this;
+			tmpMat.Multiply(mat);
+			*this = tmpMat;
+			return *this;
+		}
+		matrix_t operator * (const matrix_t& mat) const
+		{
+			matrix_t matT;
+			matT.Multiply(*this, mat);
+			return matT;
+		}
+
+		void Multiply(const matrix_t &matrix)
+		{
+			matrix_t tmp;
+			tmp = *this;
+
+			FPU_MatrixF_x_MatrixF((float*)&tmp, (float*)&matrix, (float*)this);
+		}
+
+		void Multiply(const matrix_t &m1, const matrix_t &m2)
+		{
+			FPU_MatrixF_x_MatrixF((float*)&m1, (float*)&m2, (float*)this);
+		}
+
+		float GetDeterminant() const
+		{
+			return m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] -
+				m[0][2] * m[1][1] * m[2][0] - m[0][1] * m[1][0] * m[2][2] - m[0][0] * m[1][2] * m[2][1];
+		}
+
+		float Inverse(const matrix_t &srcMatrix, bool affine = false);
+		float Inverse(bool affine = false);
+		void SetToIdentity() 
+		{
+			v.right.Set(1.f, 0.f, 0.f, 0.f);
+			v.up.Set(0.f, 1.f, 0.f, 0.f);
+			v.dir.Set(0.f, 0.f, 1.f, 0.f);
+			v.position.Set(0.f, 0.f, 0.f, 1.f);
+		}
+		void Transpose()
+		{
+			matrix_t tmpm;
+			for (int l = 0; l < 4; l++)
+			{
+				for (int c = 0; c < 4; c++)
+				{
+					tmpm.m[l][c] = m[c][l];
+				}
+			}
+			(*this) = tmpm;
+		}
+		
+		void RotationAxis(const vec_t & axis, float angle);
+
+		void OrthoNormalize()
+		{
+			v.right.Normalize();
+			v.up.Normalize();
+			v.dir.Normalize();
+		}
+	};
+
+	void vec_t::Transform(const matrix_t& matrix)
+	{
+		vec_t out;
+
+		out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0] + w * matrix.m[3][0];
+		out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1] + w * matrix.m[3][1];
+		out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2] + w * matrix.m[3][2];
+		out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3] + w * matrix.m[3][3];
+
+		x = out.x;
+		y = out.y;
+		z = out.z;
+		w = out.w;
+	}
+
+	void vec_t::Transform(const vec_t & s, const matrix_t& matrix)
+	{
+		*this = s;
+		Transform(matrix);
+	}
+
+	void vec_t::TransformPoint(const matrix_t& matrix)
+	{
+		vec_t out;
+
+		out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0] + matrix.m[3][0];
+		out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1] + matrix.m[3][1];
+		out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2] + matrix.m[3][2];
+		out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3] + matrix.m[3][3];
+
+		x = out.x;
+		y = out.y;
+		z = out.z;
+		w = out.w;
+	}
+
+
+	void vec_t::TransformVector(const matrix_t& matrix)
+	{
+		vec_t out;
+
+		out.x = x * matrix.m[0][0] + y * matrix.m[1][0] + z * matrix.m[2][0];
+		out.y = x * matrix.m[0][1] + y * matrix.m[1][1] + z * matrix.m[2][1];
+		out.z = x * matrix.m[0][2] + y * matrix.m[1][2] + z * matrix.m[2][2];
+		out.w = x * matrix.m[0][3] + y * matrix.m[1][3] + z * matrix.m[2][3];
+
+		x = out.x;
+		y = out.y;
+		z = out.z;
+		w = out.w;
+	}
+
+	float matrix_t::Inverse(const matrix_t &srcMatrix, bool affine)
+	{
+		float det = 0;
+
+		if (affine)
+		{
+			det = GetDeterminant();
+			float s = 1 / det;
+			m[0][0] = (srcMatrix.m[1][1] * srcMatrix.m[2][2] - srcMatrix.m[1][2] * srcMatrix.m[2][1]) * s;
+			m[0][1] = (srcMatrix.m[2][1] * srcMatrix.m[0][2] - srcMatrix.m[2][2] * srcMatrix.m[0][1]) * s;
+			m[0][2] = (srcMatrix.m[0][1] * srcMatrix.m[1][2] - srcMatrix.m[0][2] * srcMatrix.m[1][1]) * s;
+			m[1][0] = (srcMatrix.m[1][2] * srcMatrix.m[2][0] - srcMatrix.m[1][0] * srcMatrix.m[2][2]) * s;
+			m[1][1] = (srcMatrix.m[2][2] * srcMatrix.m[0][0] - srcMatrix.m[2][0] * srcMatrix.m[0][2]) * s;
+			m[1][2] = (srcMatrix.m[0][2] * srcMatrix.m[1][0] - srcMatrix.m[0][0] * srcMatrix.m[1][2]) * s;
+			m[2][0] = (srcMatrix.m[1][0] * srcMatrix.m[2][1] - srcMatrix.m[1][1] * srcMatrix.m[2][0]) * s;
+			m[2][1] = (srcMatrix.m[2][0] * srcMatrix.m[0][1] - srcMatrix.m[2][1] * srcMatrix.m[0][0]) * s;
+			m[2][2] = (srcMatrix.m[0][0] * srcMatrix.m[1][1] - srcMatrix.m[0][1] * srcMatrix.m[1][0]) * s;
+			m[3][0] = -(m[0][0] * srcMatrix.m[3][0] + m[1][0] * srcMatrix.m[3][1] + m[2][0] * srcMatrix.m[3][2]);
+			m[3][1] = -(m[0][1] * srcMatrix.m[3][0] + m[1][1] * srcMatrix.m[3][1] + m[2][1] * srcMatrix.m[3][2]);
+			m[3][2] = -(m[0][2] * srcMatrix.m[3][0] + m[1][2] * srcMatrix.m[3][1] + m[2][2] * srcMatrix.m[3][2]);
+		}
+		else
+		{
+			// transpose matrix
+			float src[16];
+			for (int i = 0; i < 4; ++i)
+			{
+				src[i] = srcMatrix.m16[i * 4];
+				src[i + 4] = srcMatrix.m16[i * 4 + 1];
+				src[i + 8] = srcMatrix.m16[i * 4 + 2];
+				src[i + 12] = srcMatrix.m16[i * 4 + 3];
+			}
+
+			// calculate pairs for first 8 elements (cofactors)
+			float tmp[12]; // temp array for pairs
+			tmp[0] = src[10] * src[15];
+			tmp[1] = src[11] * src[14];
+			tmp[2] = src[9] * src[15];
+			tmp[3] = src[11] * src[13];
+			tmp[4] = src[9] * src[14];
+			tmp[5] = src[10] * src[13];
+			tmp[6] = src[8] * src[15];
+			tmp[7] = src[11] * src[12];
+			tmp[8] = src[8] * src[14];
+			tmp[9] = src[10] * src[12];
+			tmp[10] = src[8] * src[13];
+			tmp[11] = src[9] * src[12];
+
+			// calculate first 8 elements (cofactors)
+			m16[0] = (tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]) - (tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]);
+			m16[1] = (tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]) - (tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]);
+			m16[2] = (tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]) - (tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]);
+			m16[3] = (tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]) - (tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]);
+			m16[4] = (tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]) - (tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]);
+			m16[5] = (tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]) - (tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]);
+			m16[6] = (tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]) - (tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]);
+			m16[7] = (tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]) - (tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]);
+
+			// calculate pairs for second 8 elements (cofactors)
+			tmp[0] = src[2] * src[7];
+			tmp[1] = src[3] * src[6];
+			tmp[2] = src[1] * src[7];
+			tmp[3] = src[3] * src[5];
+			tmp[4] = src[1] * src[6];
+			tmp[5] = src[2] * src[5];
+			tmp[6] = src[0] * src[7];
+			tmp[7] = src[3] * src[4];
+			tmp[8] = src[0] * src[6];
+			tmp[9] = src[2] * src[4];
+			tmp[10] = src[0] * src[5];
+			tmp[11] = src[1] * src[4];
+
+			// calculate second 8 elements (cofactors)
+			m16[8] = (tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]) - (tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]);
+			m16[9] = (tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]) - (tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]);
+			m16[10] = (tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]) - (tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]);
+			m16[11] = (tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]) - (tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]);
+			m16[12] = (tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]) - (tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]);
+			m16[13] = (tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]) - (tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]);
+			m16[14] = (tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]) - (tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]);
+			m16[15] = (tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]) - (tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]);
+
+			// calculate determinant
+			det = src[0] * m16[0] + src[1] * m16[1] + src[2] * m16[2] + src[3] * m16[3];
+
+			// calculate matrix inverse
+			float invdet = 1 / det;
+			for (int j = 0; j < 16; ++j)
+			{
+				m16[j] *= invdet;
+			}
+		}
+
+		return det;
+	}
+
+	void matrix_t::RotationAxis(const vec_t & axis, float angle)
+	{
+		float length2 = axis.LengthSq();
+		if (length2 < FLT_EPSILON)
+		{
+			SetToIdentity();
+			return;
+		}
+
+		vec_t n = axis * (1.f / sqrtf(length2));
+		float s = sinf(angle);
+		float c = cosf(angle);
+		float k = 1.f - c;
+
+		float xx = n.x * n.x * k + c;
+		float yy = n.y * n.y * k + c;
+		float zz = n.z * n.z * k + c;
+		float xy = n.x * n.y * k;
+		float yz = n.y * n.z * k;
+		float zx = n.z * n.x * k;
+		float xs = n.x * s;
+		float ys = n.y * s;
+		float zs = n.z * s;
+
+		m[0][0] = xx;
+		m[0][1] = xy + zs;
+		m[0][2] = zx - ys;
+		m[0][3] = 0.f;
+		m[1][0] = xy - zs;
+		m[1][1] = yy;
+		m[1][2] = yz + xs;
+		m[1][3] = 0.f;
+		m[2][0] = zx + ys;
+		m[2][1] = yz - xs;
+		m[2][2] = zz;
+		m[2][3] = 0.f;
+		m[3][0] = 0.f;
+		m[3][1] = 0.f;
+		m[3][2] = 0.f;
+		m[3][3] = 1.f;
+	}
+
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 
+
+	enum MOVETYPE
+	{
+		NONE,
+		MOVE_X,
+		MOVE_Y,
+		MOVE_Z,
+		MOVE_XY,
+		MOVE_XZ,
+		MOVE_YZ,
+		MOVE_SCREEN,
+		ROTATE_X,
+		ROTATE_Y,
+		ROTATE_Z,
+		ROTATE_SCREEN,
+		SCALE_X,
+		SCALE_Y,
+		SCALE_Z,
+		SCALE_XYZ,
+	};
+
+	struct Context
+	{
+		Context() : mbUsing(false), mbEnable(true)
+		{
+		}
+
+		ImDrawList* mDrawList;
+
+		MODE mMode;
+		matrix_t mViewMat;
+		matrix_t mProjectionMat;
+		matrix_t mModel;
+		matrix_t mModelInverse;
+		matrix_t mModelSource;
+		matrix_t mModelSourceInverse;
+		matrix_t mMVP;
+		matrix_t mViewProjection;
+
+		vec_t mModelScaleOrigin;
+		vec_t mCameraEye;
+		vec_t mCameraRight;
+		vec_t mCameraDir;
+		vec_t mCameraUp;
+		vec_t mRayOrigin;
+		vec_t mRayVector;
+
+		ImVec2 mScreenSquareCenter;
+		ImVec2 mScreenSquareMin;
+		ImVec2 mScreenSquareMax;
+
+		float mScreenFactor;
+		vec_t mRelativeOrigin;
+
+		bool mbUsing;
+		bool mbEnable;
+
+		// translation
+		vec_t mTranslationPlan;
+		vec_t mTranslationPlanOrigin;
+		vec_t mMatrixOrigin;
+
+		// rotation
+		vec_t mRotationVectorSource;
+		float mRotationAngle;
+		float mRotationAngleOrigin;
+		//vec_t mWorldToLocalAxis;
+
+		// scale
+		vec_t mScale;
+		vec_t mScaleValueOrigin;
+		float mSaveMousePosx;
+
+		// save axis factor when using gizmo
+		bool mBelowAxisLimit[3];
+		bool mBelowPlaneLimit[3];
+		float mAxisFactor[3];
+
+		//
+		int mCurrentOperation;
+	};
+
+	static Context gContext;
+
+	static const float angleLimit = 0.96f;
+	static const float planeLimit = 0.2f;
+
+	static const vec_t directionUnary[3] = { makeVect(1.f, 0.f, 0.f), makeVect(0.f, 1.f, 0.f), makeVect(0.f, 0.f, 1.f) };
+	static const ImU32 directionColor[3] = { 0xFF0000AA, 0xFF00AA00, 0xFFAA0000 };
+	static const ImU32 selectionColor = 0xFF1080FF;
+	static const ImU32 inactiveColor = 0x99999999;
+	static const ImU32 translationLineColor = 0xAAAAAAAA;
+	static const char *translationInfoMask[] = { "X : %5.3f", "Y : %5.3f", "Z : %5.3f", "X : %5.3f Y : %5.3f", "Y : %5.3f Z : %5.3f", "X : %5.3f Z : %5.3f", "X : %5.3f Y : %5.3f Z : %5.3f" };
+	static const char *scaleInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "XYZ : %5.2f" };
+	static const char *rotationInfoMask[] = { "X : %5.2f deg %5.2f rad", "Y : %5.2f deg %5.2f rad", "Z : %5.2f deg %5.2f rad", "Screen : %5.2f deg %5.2f rad" };
+	static const int translationInfoIndex[] = { 0,0,0, 1,0,0, 2,0,0, 0,1,0, 0,2,0, 1,2,0, 0,1,2 };
+	static const float quadMin = 0.5f;
+	static const float quadMax = 0.8f;
+	static const float quadUV[8] = { quadMin, quadMin, quadMin, quadMax, quadMax, quadMax, quadMax, quadMin };
+	static const int halfCircleSegmentCount = 64;
+	static const float snapTension = 0.5f;
+
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 
+	static int GetMoveType(vec_t *gizmoHitProportion);
+	static int GetRotateType();
+	static int GetScaleType();
+
+	static ImVec2 worldToPos(const vec_t& worldPos, const matrix_t& mat)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+
+		vec_t trans;
+		trans.TransformPoint(worldPos, mat);
+		trans *= 0.5f / trans.w;
+		trans += makeVect(0.5f, 0.5f);
+		trans.y = 1.f - trans.y;
+		trans.x *= io.DisplaySize.x;
+		trans.y *= io.DisplaySize.y;
+		return ImVec2(trans.x, trans.y);
+	}
+
+	static void ComputeCameraRay(vec_t &rayOrigin, vec_t &rayDir)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+
+		matrix_t mViewProjInverse;
+		mViewProjInverse.Inverse(gContext.mViewMat * gContext.mProjectionMat);
+
+		float mox = (io.MousePos.x / io.DisplaySize.x) * 2.f - 1.f;
+		float moy = (1.f - (io.MousePos.y / io.DisplaySize.y)) * 2.f - 1.f;
+
+		rayOrigin.Transform(makeVect(mox, moy, 0.f, 1.f), mViewProjInverse);
+		rayOrigin *= 1.f / rayOrigin.w;
+		vec_t rayEnd;
+		rayEnd.Transform(makeVect(mox, moy, 1.f, 1.f), mViewProjInverse);
+		rayEnd *= 1.f / rayEnd.w;
+		rayDir = Normalized(rayEnd - rayOrigin);
+	}
+
+	static float IntersectRayPlane(const vec_t & rOrigin, const vec_t& rVector, const vec_t& plan)
+	{
+		float numer = plan.Dot3(rOrigin) - plan.w;
+		float denom = plan.Dot3(rVector);
+
+		if (fabsf(denom) < FLT_EPSILON)  // normal is orthogonal to vector, cant intersect
+			return -1.0f;
+
+		return -(numer / denom);
+	}
+
+	void BeginFrame()
+	{
+		ImGuiIO& io = ImGui::GetIO();
+
+		ImGui::Begin("gizmo", NULL, io.DisplaySize, 0, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus);
+		gContext.mDrawList = ImGui::GetWindowDrawList();
+
+		ImGui::End();
+	}
+
+	bool IsUsing()
+	{
+		return gContext.mbUsing;
+	}
+
+	bool IsOver()
+	{
+		return (GetMoveType(NULL) != NONE) || GetRotateType() != NONE || GetScaleType() != NONE || IsUsing();
+	}
+
+	void Enable(bool enable)
+	{
+		gContext.mbEnable = enable;
+		if (!enable)
+			gContext.mbUsing = false;
+	}
+
+	static float GetUniform(const vec_t& position, const matrix_t& mat)
+	{
+		vec_t trf = makeVect(position.x, position.y, position.z, 1.f);
+		trf.Transform(mat);
+		return trf.w;
+	}
+
+	static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
+	{
+		gContext.mMode = mode;
+		gContext.mViewMat = *(matrix_t*)view;
+		gContext.mProjectionMat = *(matrix_t*)projection;
+		
+		if (mode == LOCAL)
+		{
+			gContext.mModel = *(matrix_t*)matrix;
+			gContext.mModel.OrthoNormalize();
+		}
+		else
+		{
+			gContext.mModel.Translation(((matrix_t*)matrix)->v.position);
+		}
+		gContext.mModelSource = *(matrix_t*)matrix;
+		gContext.mModelScaleOrigin.Set(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
+
+		gContext.mModelInverse.Inverse(gContext.mModel);
+		gContext.mModelSourceInverse.Inverse(gContext.mModelSource);
+		gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat;
+		gContext.mMVP = gContext.mModel * gContext.mViewProjection;
+
+		matrix_t viewInverse;
+		viewInverse.Inverse(gContext.mViewMat);
+		gContext.mCameraDir = viewInverse.v.dir;
+		gContext.mCameraEye = viewInverse.v.position;
+		gContext.mCameraRight = viewInverse.v.right;
+		gContext.mCameraUp = viewInverse.v.up;
+		gContext.mScreenFactor = 0.1f * GetUniform(gContext.mModel.v.position, gContext.mViewProjection);
+
+		ImVec2 centerSSpace = worldToPos(makeVect(0.f, 0.f), gContext.mMVP);
+		gContext.mScreenSquareCenter = centerSSpace;
+		gContext.mScreenSquareMin = ImVec2(centerSSpace.x - 10.f, centerSSpace.y - 10.f);
+		gContext.mScreenSquareMax = ImVec2(centerSSpace.x + 10.f, centerSSpace.y + 10.f);
+
+		ComputeCameraRay(gContext.mRayOrigin, gContext.mRayVector);
+	}
+
+	static void ComputeColors(ImU32 *colors, int type, OPERATION operation)
+	{
+		if (gContext.mbEnable)
+		{
+			switch (operation)
+			{
+			case TRANSLATE:
+				colors[0] = (type == MOVE_SCREEN) ? selectionColor : 0xFFFFFFFF;
+				for (int i = 0; i < 3; i++)
+				{
+					int colorPlaneIndex = (i + 2) % 3;
+					colors[i + 1] = (type == (int)(MOVE_X + i)) ? selectionColor : directionColor[i];
+					colors[i + 4] = (type == (int)(MOVE_XY + i)) ? selectionColor : directionColor[colorPlaneIndex];
+				}
+				break;
+			case ROTATE:
+				colors[0] = (type == ROTATE_SCREEN) ? selectionColor : 0xFFFFFFFF;
+				for (int i = 0; i < 3; i++)
+					colors[i + 1] = (type == (int)(ROTATE_X + i)) ? selectionColor : directionColor[i];
+				break;
+			case SCALE:
+				colors[0] = (type == SCALE_XYZ) ? selectionColor : 0xFFFFFFFF;
+				for (int i = 0; i < 3; i++)
+					colors[i + 1] = (type == (int)(SCALE_X + i)) ? selectionColor : directionColor[i];
+				break;
+			}
+		}
+		else
+		{
+			for (int i = 0; i < 7; i++)
+				colors[i] = inactiveColor;
+		}
+	}
+
+	static void ComputeTripodAxisAndVisibility(int axisIndex, vec_t& dirPlaneX, vec_t& dirPlaneY, bool& belowAxisLimit, bool& belowPlaneLimit)
+	{
+		const int planNormal = (axisIndex + 2) % 3;
+		dirPlaneX = directionUnary[axisIndex];
+		dirPlaneY = directionUnary[(axisIndex + 1) % 3];
+
+		if (gContext.mbUsing)
+		{
+			// when using, use stored factors so the gizmo doesn't flip when we translate
+			belowAxisLimit = gContext.mBelowAxisLimit[axisIndex];
+			belowPlaneLimit = gContext.mBelowPlaneLimit[axisIndex];
+
+			dirPlaneX *= gContext.mAxisFactor[axisIndex];
+			dirPlaneY *= gContext.mAxisFactor[(axisIndex + 1) % 3];
+		}
+		else
+		{
+			vec_t dirPlaneNormalWorld;
+			dirPlaneNormalWorld.TransformVector(directionUnary[planNormal], gContext.mModel);
+			dirPlaneNormalWorld.Normalize();
+
+			vec_t dirPlaneXWorld(dirPlaneX);
+			dirPlaneXWorld.TransformVector(gContext.mModel);
+			dirPlaneXWorld.Normalize();
+
+			vec_t dirPlaneYWorld(dirPlaneY);
+			dirPlaneYWorld.TransformVector(gContext.mModel);
+			dirPlaneYWorld.Normalize();
+
+			vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
+			float dotCameraDirX = cameraEyeToGizmo.Dot3(dirPlaneXWorld);
+			float dotCameraDirY = cameraEyeToGizmo.Dot3(dirPlaneYWorld);
+
+			// compute factor values
+			float mulAxisX = (dotCameraDirX > 0.f) ? -1.f : 1.f;
+			float mulAxisY = (dotCameraDirY > 0.f) ? -1.f : 1.f;
+			dirPlaneX *= mulAxisX;
+			dirPlaneY *= mulAxisY;
+
+			belowAxisLimit = fabsf(dotCameraDirX) < angleLimit;
+			belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneNormalWorld)) > planeLimit);
+
+			// and store values
+			gContext.mAxisFactor[axisIndex] = mulAxisX;
+			gContext.mAxisFactor[(axisIndex+1)%3] = mulAxisY;
+			gContext.mBelowAxisLimit[axisIndex] = belowAxisLimit;
+			gContext.mBelowPlaneLimit[axisIndex] = belowPlaneLimit;
+		}
+	}
+
+	static void ComputeSnap(float*value, float *snap)
+	{
+		if (*snap <= FLT_EPSILON)
+			return;
+		float modulo = fmodf(*value, *snap);
+		float moduloRatio = fabsf(modulo) / *snap;
+		if (moduloRatio < snapTension)
+			*value -= modulo;
+		else if (moduloRatio >(1.f - snapTension))
+			*value = *value - modulo + *snap * ((*value<0.f) ? -1.f : 1.f);
+	}
+	static void ComputeSnap(vec_t& value, float *snap)
+	{
+		for (int i = 0; i < 3; i++)
+		{
+			ComputeSnap(&value[i], &snap[i]);
+		}
+	}
+
+	static float ComputeAngleOnPlan()
+	{
+		const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+		vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position);
+
+		vec_t perpendicularVector;
+		perpendicularVector.Cross(gContext.mRotationVectorSource, gContext.mTranslationPlan);
+		perpendicularVector.Normalize();
+		float acosAngle = Clamp(Dot(localPos, gContext.mRotationVectorSource), -0.9999f, 0.9999f);
+		float angle = acosf(acosAngle);
+		angle *= (Dot(localPos, perpendicularVector) < 0.f) ? 1.f : -1.f;
+		return angle;
+	}
+
+	static void DrawRotationGizmo(int type)
+	{
+		ImDrawList* drawList = gContext.mDrawList;
+		ImGuiIO& io = ImGui::GetIO();
+
+		// colors
+		ImU32 colors[7];
+		ComputeColors(colors, type, ROTATE);
+
+		vec_t cameraToModelNormalized = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
+		cameraToModelNormalized.TransformVector(gContext.mModelInverse);
+		
+		for (int axis = 0; axis < 3; axis++)
+		{
+			ImVec2 circlePos[halfCircleSegmentCount];
+			
+			float angleStart = atan2f(cameraToModelNormalized[(4-axis)%3], cameraToModelNormalized[(3 - axis) % 3]) + ZPI * 0.5f;
+
+			for (unsigned int i = 0; i < halfCircleSegmentCount; i++)
+			{
+				float ng = angleStart + ZPI * ((float)i / (float)halfCircleSegmentCount);
+				vec_t axisPos = makeVect(cosf(ng), sinf(ng), 0.f);
+				vec_t pos = makeVect(axisPos[axis], axisPos[(axis+1)%3], axisPos[(axis+2)%3]) * gContext.mScreenFactor;
+				circlePos[i] = worldToPos(pos, gContext.mMVP);
+			}
+			drawList->AddPolyline(circlePos, halfCircleSegmentCount, colors[3 - axis], false, 2, true);
+		}
+		drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), 0.06f * io.DisplaySize.x, colors[0], 64);
+
+		if (gContext.mbUsing)
+		{
+			ImVec2 circlePos[halfCircleSegmentCount +1];
+
+			circlePos[0] = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
+			for (unsigned int i = 1; i < halfCircleSegmentCount; i++)
+			{
+				float ng = gContext.mRotationAngle * ((float)(i-1) / (float)(halfCircleSegmentCount -1));
+				matrix_t rotateVectorMatrix;
+				rotateVectorMatrix.RotationAxis(gContext.mTranslationPlan, ng);
+				vec_t pos;
+				pos.TransformPoint(gContext.mRotationVectorSource, rotateVectorMatrix);
+				pos *= gContext.mScreenFactor;
+				circlePos[i] = worldToPos(pos + gContext.mModel.v.position, gContext.mViewProjection);
+			}
+			drawList->AddConvexPolyFilled(circlePos, halfCircleSegmentCount, 0x801080FF, true);
+			drawList->AddPolyline(circlePos, halfCircleSegmentCount, 0xFF1080FF, true, 2, true);
+
+			ImVec2 destinationPosOnScreen = circlePos[1];
+			char tmps[512];
+			ImFormatString(tmps, sizeof(tmps), rotationInfoMask[type - ROTATE_X], (gContext.mRotationAngle/ZPI)*180.f, gContext.mRotationAngle);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), 0xFFFFFFFF, tmps);
+		}
+	}
+
+	static void DrawHatchedAxis(const vec_t& axis)
+	{
+		for (int j = 1; j < 10; j++)
+		{
+			ImVec2 baseSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2) * gContext.mScreenFactor, gContext.mMVP);
+			ImVec2 worldDirSSpace2 = worldToPos(axis * 0.05f * (float)(j * 2 + 1) * gContext.mScreenFactor, gContext.mMVP);
+			gContext.mDrawList->AddLine(baseSSpace2, worldDirSSpace2, 0x80000000, 6.f);
+		}
+	}
+
+	static void DrawScaleGizmo(int type)
+	{
+		ImDrawList* drawList = gContext.mDrawList;
+
+		// colors
+		ImU32 colors[7];
+		ComputeColors(colors, type, SCALE);
+
+		// draw screen cirle
+		drawList->AddCircleFilled(gContext.mScreenSquareCenter, 12.f, colors[0], 32);
+
+		// draw
+		vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
+		
+		if (gContext.mbUsing)
+			scaleDisplay = gContext.mScale;
+
+		for (unsigned int i = 0; i < 3; i++)
+		{
+			vec_t dirPlaneX, dirPlaneY;
+			bool belowAxisLimit, belowPlaneLimit;
+			ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
+
+			// draw axis
+			if (belowAxisLimit)
+			{
+				ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP);
+				ImVec2 worldDirSSpaceNoScale = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
+				ImVec2 worldDirSSpace = worldToPos((dirPlaneX * scaleDisplay[i]) * gContext.mScreenFactor, gContext.mMVP);
+
+				if (gContext.mbUsing)
+				{
+					drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, 0xFF404040, 6.f);
+					drawList->AddCircleFilled(worldDirSSpaceNoScale, 10.f, 0xFF404040);
+				}
+				
+				drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
+				drawList->AddCircleFilled(worldDirSSpace, 10.f, colors[i + 1]);
+
+				if (gContext.mAxisFactor[i] < 0.f)
+					DrawHatchedAxis(dirPlaneX * scaleDisplay[i]);
+			}
+		}
+		
+		if (gContext.mbUsing)
+		{
+			//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
+			ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
+			/*vec_t dif(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y);
+			dif.Normalize();
+			dif *= 5.f;
+			drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor);
+			drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor);
+			drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f);
+			*/
+			char tmps[512];
+			//vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin;
+			int componentInfoIndex = (type - SCALE_X) * 3;
+			ImFormatString(tmps, sizeof(tmps), scaleInfoMask[type - SCALE_X], scaleDisplay[translationInfoIndex[componentInfoIndex]]);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), 0xFFFFFFFF, tmps);
+		}
+	}
+
+
+	static void DrawTranslationGizmo(int type)
+	{
+		ImDrawList* drawList = gContext.mDrawList;
+
+		// colors
+		ImU32 colors[7];
+		ComputeColors(colors, type, TRANSLATE);
+
+		// draw screen quad
+		drawList->AddRectFilled(gContext.mScreenSquareMin, gContext.mScreenSquareMax, colors[0], 2.f);
+
+		// draw
+		for (unsigned int i = 0; i < 3; i++)
+		{
+			vec_t dirPlaneX, dirPlaneY;
+			bool belowAxisLimit, belowPlaneLimit;
+			ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
+			
+			// draw axis
+			if (belowAxisLimit)
+			{
+				ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP);
+				ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
+
+				drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
+				
+				if (gContext.mAxisFactor[i] < 0.f)
+					DrawHatchedAxis(dirPlaneX);
+			}
+
+			// draw plane
+			if (belowPlaneLimit)
+			{
+				ImVec2 screenQuadPts[4];
+				for (int j = 0; j < 4; j++)
+				{
+					vec_t cornerWorldPos = (dirPlaneX * quadUV[j * 2] + dirPlaneY  * quadUV[j * 2 + 1]) * gContext.mScreenFactor;
+					screenQuadPts[j] = worldToPos(cornerWorldPos, gContext.mMVP);
+				}
+				drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4], true);
+			}
+		}
+
+		if (gContext.mbUsing)
+		{
+			ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
+			ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
+			vec_t dif = { destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y, 0.f, 0.f };
+			dif.Normalize();
+			dif *= 5.f;
+			drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor);
+			drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor);
+			drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f);
+
+			char tmps[512];
+			vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin;
+			int componentInfoIndex = (type - MOVE_X) * 3;
+			ImFormatString(tmps, sizeof(tmps), translationInfoMask[type - MOVE_X], deltaInfo[translationInfoIndex[componentInfoIndex]], deltaInfo[translationInfoIndex[componentInfoIndex + 1]], deltaInfo[translationInfoIndex[componentInfoIndex + 2]]);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
+			drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), 0xFFFFFFFF, tmps);
+		}
+	}
+
+	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	// 
+
+	static int GetScaleType()
+	{
+		ImGuiIO& io = ImGui::GetIO();
+		int type = NONE;
+
+		// screen
+		if (io.MousePos.x >= gContext.mScreenSquareMin.x && io.MousePos.x <= gContext.mScreenSquareMax.x &&
+			io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y)
+			type = SCALE_XYZ;
+
+		const vec_t direction[3] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir };
+		// compute
+		for (unsigned int i = 0; i < 3 && type == NONE; i++)
+		{
+			vec_t dirPlaneX, dirPlaneY;
+			bool belowAxisLimit, belowPlaneLimit;
+			ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
+			dirPlaneX.TransformVector(gContext.mModel);
+			dirPlaneY.TransformVector(gContext.mModel);
+
+			const int planNormal = (i + 2) % 3;
+
+			const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.v.position, direction[planNormal]));
+			vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len;
+
+			const float dx = dirPlaneX.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
+			const float dy = dirPlaneY.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
+			if (belowAxisLimit && dy > -0.1f && dy < 0.1f && dx > 0.1f  && dx < 1.f)
+				type = SCALE_X + i;
+		}
+		return type;
+	}
+
+	static int GetRotateType()
+	{
+		ImGuiIO& io = ImGui::GetIO();
+		int type = NONE;
+
+		vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.f, 0.f };
+		float dist = deltaScreen.Length();
+		if (dist >= 0.058f * io.DisplaySize.x && dist < 0.062f * io.DisplaySize.x)
+			type = ROTATE_SCREEN;
+
+		const vec_t planNormals[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir};
+
+		for (unsigned int i = 0; i < 3 && type == NONE; i++)
+		{
+			// pickup plan
+			vec_t pickupPlan = BuildPlan(gContext.mModel.v.position, planNormals[i]);
+
+			const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, pickupPlan);
+			vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
+
+			if (Dot(Normalized(localPos), gContext.mRayVector) > FLT_EPSILON)
+				continue;
+
+			float distance = localPos.Length() / gContext.mScreenFactor;
+			if (distance > 0.9f && distance < 1.1f)
+				type = ROTATE_X + i;
+		}
+		
+		return type;
+	}
+
+	static int GetMoveType(vec_t *gizmoHitProportion)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+		int type = NONE;
+
+		// screen
+		if (io.MousePos.x >= gContext.mScreenSquareMin.x && io.MousePos.x <= gContext.mScreenSquareMax.x &&
+			io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y)
+			type = MOVE_SCREEN;
+
+		const vec_t direction[3] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir };
+
+		// compute
+		for (unsigned int i = 0; i < 3 && type == NONE; i++)
+		{
+			vec_t dirPlaneX, dirPlaneY;
+			bool belowAxisLimit, belowPlaneLimit;
+			ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
+			dirPlaneX.TransformVector(gContext.mModel);
+			dirPlaneY.TransformVector(gContext.mModel);
+
+			const int planNormal = (i + 2) % 3;
+
+			const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.v.position, direction[planNormal]));
+			vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len;
+
+			const float dx = dirPlaneX.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
+			const float dy = dirPlaneY.Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
+			if (belowAxisLimit && dy > -0.1f && dy < 0.1f && dx > 0.1f  && dx < 1.f)
+				type = MOVE_X + i;
+
+			if (belowPlaneLimit && dx >= quadUV[0] && dx <= quadUV[4] && dy >= quadUV[1] && dy <= quadUV[3])
+				type = MOVE_XY + i;
+
+			if (gizmoHitProportion)
+				*gizmoHitProportion = makeVect(dx, dy, 0.f);
+		}
+		return type;
+	}
+
+	static void HandleTranslation(float *matrix, float *deltaMatrix, int& type, float *snap)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+		bool applyRotationLocaly = gContext.mMode == LOCAL || type == MOVE_SCREEN;
+
+		// move
+		if (gContext.mbUsing)
+		{
+			const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+			vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
+
+			// compute delta
+			vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
+			vec_t delta = newOrigin - gContext.mModel.v.position;
+			
+			// 1 axis constraint
+			if (gContext.mCurrentOperation >= MOVE_X && gContext.mCurrentOperation <= MOVE_Z)
+			{
+				int axisIndex = gContext.mCurrentOperation - MOVE_X;
+				const vec_t& axisValue = *(vec_t*)&gContext.mModel.m[axisIndex];
+				float lengthOnAxis = Dot(axisValue, delta);
+				delta = axisValue * lengthOnAxis;
+			}
+
+			// snap
+			if (snap)
+			{
+				vec_t cumulativeDelta = gContext.mModel.v.position + delta - gContext.mMatrixOrigin;
+				if (applyRotationLocaly)
+				{
+					matrix_t modelSourceNormalized = gContext.mModelSource;
+					modelSourceNormalized.OrthoNormalize();
+					matrix_t modelSourceNormalizedInverse;
+					modelSourceNormalizedInverse.Inverse(modelSourceNormalized);
+					cumulativeDelta.TransformVector(modelSourceNormalizedInverse);
+					ComputeSnap(cumulativeDelta, snap);
+					cumulativeDelta.TransformVector(modelSourceNormalized);
+				}
+				else
+				{
+					ComputeSnap(cumulativeDelta, snap);
+				}
+				delta = gContext.mMatrixOrigin + cumulativeDelta - gContext.mModel.v.position;
+
+			}
+
+			// compute matrix & delta
+			matrix_t deltaMatrixTranslation;
+			deltaMatrixTranslation.Translation(delta);
+			if (deltaMatrix)
+				memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
+
+
+			matrix_t res = gContext.mModelSource * deltaMatrixTranslation;
+			*(matrix_t*)matrix = res;
+
+			if (!io.MouseDown[0])
+				gContext.mbUsing = false;
+
+			type = gContext.mCurrentOperation;
+		}
+		else
+		{
+			// find new possible way to move
+			vec_t gizmoHitProportion;
+			type = GetMoveType(&gizmoHitProportion);
+			if (io.MouseDown[0] && type != NONE)
+			{
+				gContext.mbUsing = true;
+				gContext.mCurrentOperation = type;
+				const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.up, -gContext.mCameraDir };
+				// pickup plan
+				gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - MOVE_X]);
+				const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+				gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
+				gContext.mMatrixOrigin = gContext.mModel.v.position;
+
+				gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
+			}
+		}
+	}
+
+	static void HandleScale(float *matrix, float *deltaMatrix, int& type, float *snap)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+
+		if (!gContext.mbUsing)
+		{
+			// find new possible way to scale
+			type = GetScaleType();
+			if (io.MouseDown[0] && type != NONE)
+			{
+				gContext.mbUsing = true;
+				gContext.mCurrentOperation = type;
+				const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.up, gContext.mModel.v.right, -gContext.mCameraDir };
+				// pickup plan
+
+				gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - SCALE_X]);
+				const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+				gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
+				gContext.mMatrixOrigin = gContext.mModel.v.position;
+				gContext.mScale.Set(1.f, 1.f, 1.f);
+				gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
+				gContext.mScaleValueOrigin = makeVect(gContext.mModelSource.v.right.Length(), gContext.mModelSource.v.up.Length(), gContext.mModelSource.v.dir.Length());
+				gContext.mSaveMousePosx = io.MousePos.x;
+			}
+		}
+		// scale
+		if (gContext.mbUsing)
+		{
+			const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+			vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
+			vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
+			vec_t delta = newOrigin - gContext.mModel.v.position;
+			
+			// 1 axis constraint
+			if (gContext.mCurrentOperation >= SCALE_X && gContext.mCurrentOperation <= SCALE_Z)
+			{
+				int axisIndex = gContext.mCurrentOperation - SCALE_X;
+				const vec_t& axisValue = *(vec_t*)&gContext.mModel.m[axisIndex];
+				float lengthOnAxis = Dot(axisValue, delta);
+				delta = axisValue * lengthOnAxis;
+
+				vec_t baseVector = gContext.mTranslationPlanOrigin - gContext.mModel.v.position;
+				float ratio = Dot(axisValue, baseVector + delta) / Dot(axisValue, baseVector);
+					
+				gContext.mScale[axisIndex] = max(ratio, 0.001f);
+			}
+			else
+			{			
+				float scaleDelta = (io.MousePos.x - gContext.mSaveMousePosx)  * 0.01f;
+				gContext.mScale.Set(max(1.f + scaleDelta, 0.001f));
+			}
+
+			// snap
+			if (snap)
+			{
+				float scaleSnap[] = { snap[0], snap[0], snap[0] };
+				ComputeSnap(gContext.mScale, scaleSnap);
+			}
+
+			// no 0 allowed
+			for (int i = 0; i < 3;i++)
+				gContext.mScale[i] = max(gContext.mScale[i], 0.001f);
+
+			// compute matrix & delta
+			matrix_t deltaMatrixScale;
+			deltaMatrixScale.Scale(gContext.mScale * gContext.mScaleValueOrigin);
+			
+			matrix_t res = deltaMatrixScale * gContext.mModel;
+			*(matrix_t*)matrix = res;
+			
+			if (deltaMatrix)
+			{
+				deltaMatrixScale.Scale(gContext.mScale);
+				memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
+			}
+
+			if (!io.MouseDown[0])
+				gContext.mbUsing = false;
+
+			type = gContext.mCurrentOperation;
+		}
+	}
+
+	static void HandleRotation(float *matrix, float *deltaMatrix, int& type, float *snap)
+	{
+		ImGuiIO& io = ImGui::GetIO();
+		bool applyRotationLocaly = gContext.mMode == LOCAL || type == ROTATE_SCREEN;
+
+		if (!gContext.mbUsing)
+		{
+			type = GetRotateType();
+			if (io.MouseDown[0] && type != NONE)
+			{
+				gContext.mbUsing = true;
+				gContext.mCurrentOperation = type;
+				const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
+				// pickup plan
+				if (applyRotationLocaly)
+				{
+					gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, rotatePlanNormal[type - ROTATE_X]);
+				}
+				else
+				{
+					gContext.mTranslationPlan = BuildPlan(gContext.mModelSource.v.position, directionUnary[type - ROTATE_X]);
+				}
+
+				const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
+				vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
+				gContext.mRotationVectorSource = Normalized(localPos);
+				gContext.mRotationAngleOrigin = ComputeAngleOnPlan();
+			}
+		}
+
+		// rotation
+		if (gContext.mbUsing)
+		{
+			gContext.mRotationAngle = ComputeAngleOnPlan();
+			if (snap)
+			{
+				float snapInRadian = snap[0] * DEG2RAD;
+				ComputeSnap(&gContext.mRotationAngle, &snapInRadian);
+			}
+			vec_t rotationAxisLocalSpace;
+			
+			rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
+			rotationAxisLocalSpace.Normalize();
+
+			matrix_t deltaRotation;
+			deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin);
+			gContext.mRotationAngleOrigin = gContext.mRotationAngle;
+
+			matrix_t scaleOrigin;
+			scaleOrigin.Scale(gContext.mModelScaleOrigin);
+			
+			if (applyRotationLocaly)
+			{
+				*(matrix_t*)matrix = scaleOrigin * deltaRotation * gContext.mModel;
+			}
+			else
+			{
+				matrix_t res = gContext.mModelSource;
+				res.v.position.Set(0.f);
+
+				*(matrix_t*)matrix = res * deltaRotation;
+				((matrix_t*)matrix)->v.position = gContext.mModelSource.v.position;
+			}
+
+			if (deltaMatrix)
+			{
+				*(matrix_t*)deltaMatrix = gContext.mModelInverse * deltaRotation * gContext.mModel;
+			}
+
+			if (!io.MouseDown[0])
+				gContext.mbUsing = false;
+
+			type = gContext.mCurrentOperation;
+		}
+	}
+
+	void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale)
+	{
+		matrix_t mat = *(matrix_t*)matrix;
+
+		scale[0] = mat.v.right.Length();
+		scale[1] = mat.v.up.Length();
+		scale[2] = mat.v.dir.Length(); 
+
+		mat.OrthoNormalize();
+
+		rotation[0] = RAD2DEG * atan2f(mat.m[1][2], mat.m[2][2]);
+		rotation[1] = RAD2DEG * atan2f(-mat.m[0][2], sqrtf(mat.m[1][2] * mat.m[1][2] + mat.m[2][2]* mat.m[2][2]));
+		rotation[2] = RAD2DEG * atan2f(mat.m[0][1], mat.m[0][0]);
+
+		translation[0] = mat.v.position.x;
+		translation[1] = mat.v.position.y;
+		translation[2] = mat.v.position.z;
+	}
+
+	void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix)
+	{
+		matrix_t& mat = *(matrix_t*)matrix;
+
+		matrix_t rot[3];
+		for (int i = 0; i < 3;i++)
+			rot[i].RotationAxis(directionUnary[i], rotation[i] * DEG2RAD);
+
+		mat = rot[0] * rot[1] * rot[2];
+
+		float validScale[3];
+		for (int i = 0; i < 3; i++)
+		{
+			if (fabsf(scale[i]) < FLT_EPSILON)
+				validScale[i] = 0.001f;
+			else
+				validScale[i] = scale[i];
+		}
+		mat.v.right *= validScale[0];
+		mat.v.up *= validScale[1];
+		mat.v.dir *= validScale[2];
+		mat.v.position.Set(translation[0], translation[1], translation[2], 1.f);
+	}
+
+	void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix, float *snap)
+	{
+		ComputeContext(view, projection, matrix, mode);
+
+		// set delta to identity 
+		if (deltaMatrix)
+			((matrix_t*)deltaMatrix)->SetToIdentity();
+
+		// behind camera
+		vec_t camSpacePosition;
+		camSpacePosition.TransformPoint(makeVect(0.f, 0.f, 0.f), gContext.mMVP);
+		if (camSpacePosition.z < 0.001f)
+			return;
+
+		// -- 
+		int type = NONE;
+		if (gContext.mbEnable)
+		{
+			switch (operation)
+			{
+			case ROTATE:
+				HandleRotation(matrix, deltaMatrix, type, snap);
+				break;
+			case TRANSLATE:
+				HandleTranslation(matrix, deltaMatrix, type, snap);
+				break;
+			case SCALE:
+				HandleScale(matrix, deltaMatrix, type, snap);
+				break;
+			}
+		}
+
+		switch (operation)
+		{
+		case ROTATE:
+			DrawRotationGizmo(type);
+			break;
+		case TRANSLATE:
+			DrawTranslationGizmo(type);
+			break;
+		case SCALE:
+			DrawScaleGizmo(type);
+			break;
+		}
+	}
+
+	void DrawCube(const float *view, const float *projection, float *matrix)
+	{
+		matrix_t viewInverse;
+		viewInverse.Inverse(*(matrix_t*)view);
+		const matrix_t& model = *(matrix_t*)matrix;
+		matrix_t res = *(matrix_t*)matrix * *(matrix_t*)view * *(matrix_t*)projection;
+
+		for (int iFace = 0; iFace < 6; iFace++)
+		{
+			const int normalIndex = (iFace % 3);
+			const int perpXIndex = (normalIndex + 1) % 3;
+			const int perpYIndex = (normalIndex + 2) % 3;
+			const float invert = (iFace > 2) ? -1.f : 1.f;
+			
+			const vec_t faceCoords[4] = { directionUnary[normalIndex] + directionUnary[perpXIndex] + directionUnary[perpYIndex],
+				directionUnary[normalIndex] + directionUnary[perpXIndex] - directionUnary[perpYIndex],
+				directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex],
+				directionUnary[normalIndex] - directionUnary[perpXIndex] + directionUnary[perpYIndex],
+			};
+
+			// clipping
+			bool skipFace = false;
+			for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
+			{
+				vec_t camSpacePosition;
+				camSpacePosition.TransformPoint(faceCoords[iCoord] * 0.5f * invert, gContext.mMVP);
+				if (camSpacePosition.z < 0.001f)
+				{
+					skipFace = true;
+					break;
+				}
+			}
+			if (skipFace)
+				continue;
+
+			// 3D->2D
+			ImVec2 faceCoordsScreen[4];
+			for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
+				faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res);
+
+			// back face culling 
+			vec_t cullPos, cullNormal;
+			cullPos.TransformPoint(faceCoords[0] * 0.5f * invert, model);
+			cullNormal.TransformVector(directionUnary[normalIndex] * invert, model);
+			float dt = Dot(Normalized(cullPos - viewInverse.v.position), Normalized(cullNormal));
+			if (dt>0.f)
+				continue;
+
+			// draw face with lighter color
+			gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, directionColor[normalIndex] | 0x808080, true);
+		}
+	}
+};
+

+ 266 - 88
third/bgfx/3rdparty/remotery/lib/Remotery.c

@@ -1,5 +1,5 @@
 //
-// Copyright 2014 Celtoys Ltd
+// Copyright 2014-2016 Celtoys Ltd
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -128,8 +128,11 @@ static rmtBool g_SettingsInitialized = RMT_FALSE;
 
 #endif
 
-
-#define RMT_UNREFERENCED_PARAMETER(i) (void)(1 ? (void)0 : ((void)i))
+#if 0 //def _MSC_VER
+    #define RMT_UNREFERENCED_PARAMETER(i) assert(i == 0 || i != 0);	// To fool warning C4100 on warning level 4
+#else
+    #define RMT_UNREFERENCED_PARAMETER(i) (void)(1 ? (void)0 : ((void)i))
+#endif
 
 
 #if RMT_USE_CUDA
@@ -173,9 +176,9 @@ static void rmtFree( void* ptr )
     g_Settings.free( g_Settings.mm_context, ptr );
 }
 
-
+#if RMT_USE_OPENGL
 // DLL/Shared Library functions
-void* rmtLoadLibrary(const char* path)
+static void* rmtLoadLibrary(const char* path)
 {
     #if defined(RMT_PLATFORM_WINDOWS)
         return (void*)LoadLibraryA(path);
@@ -198,14 +201,21 @@ static void rmtFreeLibrary(void* handle)
 static void* rmtGetProcAddress(void* handle, const char* symbol)
 {
     #if defined(RMT_PLATFORM_WINDOWS)
+        #ifdef _MSC_VER
+            #pragma warning(push)
+            #pragma warning(disable:4152) // C4152: nonstandard extension, function/data pointer conversion in expression
+        #endif
         return GetProcAddress((HMODULE)handle, (LPCSTR)symbol);
+        #ifdef _MSC_VER
+            #pragma warning(pop)
+        #endif
     #elif defined(RMT_PLATFORM_POSIX)
         return dlsym(handle, symbol);
     #else
         return NULL;
     #endif
 }
-
+#endif
 
 /*
 ------------------------------------------------------------------------------------------------------------------------
@@ -856,8 +866,9 @@ static void VirtualMirrorBuffer_Destructor(VirtualMirrorBuffer* buffer)
 */
 
 
-typedef struct Thread Thread;
-typedef rmtError(*ThreadProc)(Thread* thread);
+struct Thread;
+typedef rmtError(*ThreadProc)(struct Thread* thread);
+
 
 typedef struct Thread
 {
@@ -883,9 +894,6 @@ typedef struct Thread
 } Thread;
 
 
-typedef rmtError (*ThreadProc)(Thread* thread);
-
-
 #if defined(RMT_PLATFORM_WINDOWS)
 
     static DWORD WINAPI ThreadProcWindows(LPVOID lpParameter)
@@ -1046,6 +1054,7 @@ static void Thread_Destructor(Thread* thread)
 // NOTE: Microsoft also has its own version of these functions so I'm do some hacky PP to remove them
 #define strnlen_s strnlen_s_safe_c
 #define strncat_s strncat_s_safe_c
+#define strcpy_s strcpy_s_safe_c
 
 
 #define RSIZE_MAX_STR (4UL << 10)   /* 4KB */
@@ -1066,7 +1075,7 @@ static void Thread_Destructor(Thread* thread)
 typedef int errno_t;
 #endif
 
-#if !defined(_WIN64) && !defined(__APPLE__) || defined(__MINGW32__)
+#if (!defined(_WIN64) && !defined(__APPLE__)) || (defined(__MINGW32__) && !defined(RSIZE_T_DEFINED))
 typedef unsigned int rsize_t;
 #endif
 
@@ -1299,6 +1308,79 @@ strncat_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
 }
 
 
+errno_t
+strcpy_s(char *dest, rsize_t dmax, const char *src)
+{
+    const char *overlap_bumper;
+
+    if (dest == NULL) {
+        return RCNEGATE(ESNULLP);
+    }
+
+    if (dmax == 0) {
+        return RCNEGATE(ESZEROL);
+    }
+
+    if (dmax > RSIZE_MAX_STR) {
+        return RCNEGATE(ESLEMAX);
+    }
+
+    if (src == NULL) {
+        *dest = '\0';
+        return RCNEGATE(ESNULLP);
+    }
+
+    if (dest == src) {
+        return RCNEGATE(EOK);
+    }
+
+    /* hold base of dest in case src was not copied */
+    if (dest < src) {
+        overlap_bumper = src;
+
+        while (dmax > 0) {
+            if (dest == overlap_bumper) {
+                return RCNEGATE(ESOVRLP);
+            }
+
+            *dest = *src;
+            if (*dest == '\0') {
+                return RCNEGATE(EOK);
+            }
+
+            dmax--;
+            dest++;
+            src++;
+        }
+
+    }
+    else {
+        overlap_bumper = dest;
+
+        while (dmax > 0) {
+            if (src == overlap_bumper) {
+                return RCNEGATE(ESOVRLP);
+            }
+
+            *dest = *src;
+            if (*dest == '\0') {
+                return RCNEGATE(EOK);
+            }
+
+            dmax--;
+            dest++;
+            src++;
+        }
+    }
+
+    /*
+    * the entire src must have been copied, if not reset dest
+    * to null the string.
+    */
+    return RCNEGATE(ESNOSPC);
+}
+
+
 
 /* very simple integer to hex */
 static const char* hex_encoding_table = "0123456789ABCDEF";
@@ -1681,10 +1763,11 @@ static void TCPSocket_Destructor(TCPSocket* tcp_socket)
 }
 
 
-static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port)
+static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port, rmtBool limit_connections_to_localhost)
 {
     SOCKET s = INVALID_SOCKET;
     struct sockaddr_in sin;
+    int enable = 1;
     #ifdef RMT_PLATFORM_WINDOWS
         u_long nonblock = 1;
     #endif
@@ -1697,9 +1780,23 @@ static rmtError TCPSocket_RunServer(TCPSocket* tcp_socket, rmtU16 port)
     if (s == SOCKET_ERROR)
         return RMT_ERROR_SOCKET_CREATE_FAIL;
 
+    // set SO_REUSEADDR so binding doesn't fail when restarting the application
+    // (otherwise the same port can't be reused within TIME_WAIT)
+    // I'm not checking for errors because if this fails (unlikely) we might still
+    // be able to bind to the socket anyway
+    #ifdef RMT_PLATFORM_POSIX
+        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
+    #elif defined(RMT_PLATFORM_WINDOWS)
+        // windows also needs SO_EXCLUSEIVEADDRUSE,
+        // see http://www.andy-pearce.com/blog/posts/2013/Feb/so_reuseaddr-on-windows/
+        setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(enable));
+        enable = 1;
+        setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (char *)&enable, sizeof(enable));
+    #endif
+
     // Bind the socket to the incoming port
     sin.sin_family = AF_INET;
-    sin.sin_addr.s_addr = INADDR_ANY;
+    sin.sin_addr.s_addr = htonl(limit_connections_to_localhost ? INADDR_LOOPBACK : INADDR_ANY);
     sin.sin_port = htons(port);
     if (bind(s, (struct sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
         return RMT_ERROR_SOCKET_BIND_FAIL;
@@ -1816,6 +1913,18 @@ static rmtError TCPSocket_AcceptConnection(TCPSocket* tcp_socket, TCPSocket** cl
     if (s == SOCKET_ERROR)
         return RMT_ERROR_SOCKET_ACCEPT_FAIL;
 
+#ifdef SO_NOSIGPIPE
+    // On POSIX systems, send() may send a SIGPIPE signal when writing to an
+    // already closed connection. By setting this option, we prevent the
+    // signal from being emitted and send will instead return an error and set
+    // errno to EPIPE.
+    //
+    // This is supported on BSD platforms and not on Linux.
+    {
+        int flag = 1;
+        setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(flag));
+    }
+#endif
     // Create a client socket for the new connection
     assert(client_socket != NULL);
     New_0(TCPSocket, *client_socket);
@@ -1871,7 +1980,14 @@ static rmtError TCPSocket_Send(TCPSocket* tcp_socket, const void* data, rmtU32 l
     while (cur_data < end_data)
     {
         // Attempt to send the remaining chunk of data
-        int bytes_sent = (int)send(tcp_socket->socket, cur_data, (int)(end_data - cur_data), 0);
+        int bytes_sent;
+        int send_flags = 0;
+#ifdef MSG_NOSIGNAL
+        // On Linux this prevents send from emitting a SIGPIPE signal
+        // Equivalent on BSD to the SO_NOSIGPIPE option.
+        send_flags = MSG_NOSIGNAL;
+#endif
+        bytes_sent = (int)send(tcp_socket->socket, cur_data, (int)(end_data - cur_data), send_flags);
 
         if (bytes_sent == SOCKET_ERROR || bytes_sent == 0)
         {
@@ -2371,9 +2487,10 @@ typedef struct
 
     union
     {
-        rmtU8 data_mask[4];
-        rmtU32 data_mask_u32;
-    };
+        rmtU8 mask[4];
+        rmtU32 mask_u32;
+    } data;
+
 } WebSocket;
 
 
@@ -2536,10 +2653,10 @@ static rmtError WebSocket_Constructor(WebSocket* web_socket, TCPSocket* tcp_sock
     web_socket->mode = WEBSOCKET_NONE;
     web_socket->frame_bytes_remaining = 0;
     web_socket->mask_offset = 0;
-    web_socket->data_mask[0] = 0;
-    web_socket->data_mask[1] = 0;
-    web_socket->data_mask[2] = 0;
-    web_socket->data_mask[3] = 0;
+    web_socket->data.mask[0] = 0;
+    web_socket->data.mask[1] = 0;
+    web_socket->data.mask[2] = 0;
+    web_socket->data.mask[3] = 0;
 
     // Caller can optionally specify which TCP socket to use
     if (web_socket->tcp_socket == NULL)
@@ -2555,12 +2672,12 @@ static void WebSocket_Destructor(WebSocket* web_socket)
 }
 
 
-static rmtError WebSocket_RunServer(WebSocket* web_socket, rmtU32 port, enum WebSocketMode mode)
+static rmtError WebSocket_RunServer(WebSocket* web_socket, rmtU16 port, rmtBool limit_connections_to_localhost, enum WebSocketMode mode)
 {
     // Create the server's listening socket
     assert(web_socket != NULL);
     web_socket->mode = mode;
-    return TCPSocket_RunServer(web_socket->tcp_socket, (rmtU16)port);
+    return TCPSocket_RunServer(web_socket->tcp_socket, port, limit_connections_to_localhost);
 }
 
 
@@ -2728,7 +2845,7 @@ static rmtError ReceiveFrameHeader(WebSocket* web_socket)
     mask_present = (msg_header[1] & 0x80) != 0 ? RMT_TRUE : RMT_FALSE;
     if (mask_present)
     {
-        error = TCPSocket_Receive(web_socket->tcp_socket, web_socket->data_mask, 4, 20);
+        error = TCPSocket_Receive(web_socket->tcp_socket, web_socket->data.mask, 4, 20);
         if (error != RMT_ERROR_NONE)
             return error;
     }
@@ -2790,12 +2907,12 @@ static rmtError WebSocket_Receive(WebSocket* web_socket, void* data, rmtU32* msg
         }
 
         // Apply data mask
-        if (web_socket->data_mask_u32 != 0)
+        if (web_socket->data.mask_u32 != 0)
         {
             rmtU32 i;
             for (i = 0; i < bytes_to_read; i++)
             {
-                *((rmtU8*)cur_data + i) ^= web_socket->data_mask[web_socket->mask_offset & 3];
+                *((rmtU8*)cur_data + i) ^= web_socket->data.mask[web_socket->mask_offset & 3];
                 web_socket->mask_offset++;
             }
         }
@@ -2892,11 +3009,20 @@ static void MessageQueue_Destructor(MessageQueue* queue)
 }
 
 
+static rmtU32 MessageQueue_SizeForPayload(rmtU32 payload_size)
+{
+    // Add message header and align for ARM platforms
+    rmtU32 size = sizeof(Message) + payload_size;
+    size = (size + 3) & ~3U;
+    return size;
+}
+
+
 static Message* MessageQueue_AllocMessage(MessageQueue* queue, rmtU32 payload_size, struct ThreadSampler* thread_sampler)
 {
     Message* msg;
 
-    rmtU32 write_size = sizeof(Message) + payload_size;
+    rmtU32 write_size = MessageQueue_SizeForPayload(payload_size);
 
     assert(queue != NULL);
 
@@ -2926,9 +3052,8 @@ static Message* MessageQueue_AllocMessage(MessageQueue* queue, rmtU32 payload_si
 }
 
 
-static void MessageQueue_CommitMessage(MessageQueue* queue, Message* message, MessageID id)
+static void MessageQueue_CommitMessage(Message* message, MessageID id)
 {
-    assert(queue != NULL);
     assert(message != NULL);
 
     // Ensure message writes complete before commit
@@ -2937,8 +3062,6 @@ static void MessageQueue_CommitMessage(MessageQueue* queue, Message* message, Me
     // Setting the message ID signals to the consumer that the message is ready
     assert(message->id == MsgID_NotReady);
     message->id = id;
-
-    RMT_UNREFERENCED_PARAMETER(queue);
 }
 
 
@@ -2981,7 +3104,7 @@ static void MessageQueue_ConsumeNextMessage(MessageQueue* queue, Message* messag
     // the read position so that a winning thread's allocation will inherit the "not ready" state.
     //
     // This costs some write bandwidth and has the potential to flush cache to other cores.
-    message_size = sizeof(Message) + message->payload_size;
+    message_size = MessageQueue_SizeForPayload(message->payload_size);
     memset(message, MsgID_NotReady, message_size);
 
     // Ensure clear completes before advancing the read position
@@ -3009,31 +3132,33 @@ typedef struct
     rmtU32 last_ping_time;
 
     rmtU16 port;
+    rmtBool limit_connections_to_localhost;
 } Server;
 
 
-static rmtError Server_CreateListenSocket(Server* server, rmtU16 port)
+static rmtError Server_CreateListenSocket(Server* server, rmtU16 port, rmtBool limit_connections_to_localhost)
 {
     rmtError error = RMT_ERROR_NONE;
 
     New_1(WebSocket, server->listen_socket, NULL);
     if (error == RMT_ERROR_NONE)
-        error = WebSocket_RunServer(server->listen_socket, port, WEBSOCKET_TEXT);
+        error = WebSocket_RunServer(server->listen_socket, port, limit_connections_to_localhost, WEBSOCKET_TEXT);
 
     return error;
 }
 
 
-static rmtError Server_Constructor(Server* server, rmtU16 port)
+static rmtError Server_Constructor(Server* server, rmtU16 port, rmtBool limit_connections_to_localhost)
 {
     assert(server != NULL);
     server->listen_socket = NULL;
     server->client_socket = NULL;
     server->last_ping_time = 0;
     server->port = port;
+    server->limit_connections_to_localhost = limit_connections_to_localhost;
 
     // Create the listening WebSocket
-    return Server_CreateListenSocket(server, port);
+    return Server_CreateListenSocket(server, port, limit_connections_to_localhost);
 }
 
 
@@ -3129,7 +3254,7 @@ static void Server_Update(Server* server)
 
     // Recreate the listening socket if it's been destroyed earlier
     if (server->listen_socket == NULL)
-        Server_CreateListenSocket(server, server->port);
+        Server_CreateListenSocket(server, server->port, server->limit_connections_to_localhost);
 
     if (server->listen_socket != NULL && server->client_socket == NULL)
     {
@@ -3303,6 +3428,9 @@ static rmtError json_CloseArray(Buffer* buffer)
 
 
 
+#define SAMPLE_NAME_LEN 128
+
+
 enum SampleType
 {
     SampleType_CPU,
@@ -3324,7 +3452,7 @@ typedef struct Sample
     rmtU32 size_bytes;
 
     // Sample name and unique hash
-    rmtPStr name;
+    char name[SAMPLE_NAME_LEN];
     rmtU32 name_hash;
 
     // Unique, persistent ID among all samples
@@ -3343,9 +3471,10 @@ typedef struct Sample
     // This is also mixed with the callstack hash to allow consistent addressing of any point in the tree
     rmtU32 nb_children;
 
-    // Start and end of the sample in microseconds
+    // Sample end points and length in microseconds
     rmtU64 us_start;
     rmtU64 us_end;
+    rmtU64 us_length;
 
 } Sample;
 
@@ -3358,7 +3487,7 @@ static rmtError Sample_Constructor(Sample* sample)
 
     sample->type = SampleType_CPU;
     sample->size_bytes = sizeof(Sample);
-    sample->name = NULL;
+    sample->name[0] = 0;
     sample->name_hash = 0;
     sample->unique_id = 0;
     sample->unique_id_html_colour[0] = '#';
@@ -3371,6 +3500,7 @@ static rmtError Sample_Constructor(Sample* sample)
     sample->nb_children = 0;
     sample->us_start = 0;
     sample->us_end = 0;
+    sample->us_length = 0;
 
     return RMT_ERROR_NONE;
 }
@@ -3384,7 +3514,10 @@ static void Sample_Destructor(Sample* sample)
 
 static void Sample_Prepare(Sample* sample, rmtPStr name, rmtU32 name_hash, Sample* parent)
 {
-    sample->name = name;
+    // Copy sample name away for two reasons:
+    //   1. It allows dynamic sprintf-style strings to be transient
+    //   2. The Remotery thread can still inspect the sample even when the source module has been unloaded
+    strcpy_s(sample->name, sizeof(sample->name), name);
     sample->name_hash = name_hash;
     sample->unique_id = 0;
     sample->parent = parent;
@@ -3394,6 +3527,7 @@ static void Sample_Prepare(Sample* sample, rmtPStr name, rmtU32 name_hash, Sampl
     sample->nb_children = 0;
     sample->us_start = 0;
     sample->us_end = 0;
+    sample->us_length = 0;
 }
 
 
@@ -3416,7 +3550,7 @@ static rmtError json_Sample(Buffer* buffer, Sample* sample)
         JSON_ERROR_CHECK(json_Comma(buffer));
         JSON_ERROR_CHECK(json_FieldU64(buffer, "us_start", sample->us_start));
         JSON_ERROR_CHECK(json_Comma(buffer));
-        JSON_ERROR_CHECK(json_FieldU64(buffer, "us_length", maxS64(sample->us_end - sample->us_start, 0)));
+        JSON_ERROR_CHECK(json_FieldU64(buffer, "us_length", maxS64(sample->us_length, 0)));
 
         if (sample->first_child != NULL)
         {
@@ -3524,7 +3658,7 @@ static rmtU32 HashCombine(rmtU32 hash_a, rmtU32 hash_b)
 }
 
 
-static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, Sample** sample)
+static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, rmtU32 flags, Sample** sample)
 {
     Sample* parent;
     rmtError error;
@@ -3535,11 +3669,21 @@ static rmtError SampleTree_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash
     assert(tree->current_parent != NULL);
     parent = tree->current_parent;
 
-    if (parent->last_child != NULL && parent->last_child->name_hash == name_hash)
+    if ((flags & RMTSF_Aggregate) != 0)
     {
-        // TODO: Collapse siblings with flag exception?
-        //       Note that above check is not enough - requires a linear search
+        // Linear search for previous instance of this sample name
+        Sample* sibling;
+        for (sibling = parent->first_child; sibling != NULL; sibling = sibling->next_sibling)
+        {
+            if (sibling->name_hash == name_hash)
+            {
+                tree->current_parent = sibling;
+                *sample = sibling;
+                return RMT_ERROR_NONE;
+            }
+        }
     }
+
     if (parent->name_hash == name_hash)
     {
         // TODO: Collapse recursion on flag?
@@ -3657,7 +3801,7 @@ static void AddSampleTreeMessage(MessageQueue* queue, Sample* sample, ObjectAllo
     payload->root_sample = sample;
     payload->allocator = allocator;
     payload->thread_name = thread_name;
-    MessageQueue_CommitMessage(queue, message, MsgID_SampleTree);
+    MessageQueue_CommitMessage(message, MsgID_SampleTree);
 }
 
 
@@ -3686,8 +3830,6 @@ typedef struct ThreadSampler
 
 } ThreadSampler;
 
-static rmtS32 countThreads = 0;
-
 static rmtError ThreadSampler_Constructor(ThreadSampler* thread_sampler)
 {
     rmtError error;
@@ -3705,8 +3847,11 @@ static rmtError ThreadSampler_Constructor(ThreadSampler* thread_sampler)
     #if defined(RMT_PLATFORM_LINUX) && RMT_USE_POSIX_THREADNAMES
     prctl(PR_GET_NAME,thread_sampler->name,0,0,0);
     #else
-    strncat_s(thread_sampler->name, sizeof(thread_sampler->name), "Thread", 6);
-    itoahex_s(thread_sampler->name + 6, sizeof(thread_sampler->name) - 6, AtomicAdd(&countThreads, 1));
+    {
+        static rmtS32 countThreads = 0;
+        strncat_s(thread_sampler->name, sizeof(thread_sampler->name), "Thread", 6);
+        itoahex_s(thread_sampler->name + 6, sizeof(thread_sampler->name) - 6, AtomicAdd(&countThreads, 1));
+    }
     #endif
 
     // Create the CPU sample tree only - the rest are created on-demand as they need
@@ -3729,10 +3874,9 @@ static void ThreadSampler_Destructor(ThreadSampler* ts)
 }
 
 
-static rmtError ThreadSampler_Push(ThreadSampler* ts, SampleTree* tree, rmtPStr name, rmtU32 name_hash, Sample** sample)
+static rmtError ThreadSampler_Push(SampleTree* tree, rmtPStr name, rmtU32 name_hash, rmtU32 flags, Sample** sample)
 {
-    RMT_UNREFERENCED_PARAMETER(ts);
-    return SampleTree_Push(tree, name, name_hash, sample);
+    return SampleTree_Push(tree, name, name_hash, flags, sample);
 }
 
 
@@ -3967,7 +4111,7 @@ static rmtError Remotery_SendSampleTreeMessage(Remotery* rmt, Message* message)
     {
         // If these CUDA samples aren't ready yet, stick them to the back of the queue and continue
         rmtBool are_samples_ready;
-        rmt_BeginCPUSample(AreCUDASamplesReady);
+        rmt_BeginCPUSample(AreCUDASamplesReady, 0);
         are_samples_ready = AreCUDASamplesReady(sample);
         rmt_EndCPUSample();
         if (!are_samples_ready)
@@ -3977,7 +4121,7 @@ static rmtError Remotery_SendSampleTreeMessage(Remotery* rmt, Message* message)
         }
 
         // Retrieve timing of all CUDA samples
-        rmt_BeginCPUSample(GetCUDASampleTimes);
+        rmt_BeginCPUSample(GetCUDASampleTimes, 0);
         GetCUDASampleTimes(sample->parent, sample);
         rmt_EndCPUSample();
     }
@@ -4082,13 +4226,13 @@ static rmtError Remotery_ThreadMain(Thread* thread)
 
     while (thread->request_exit == RMT_FALSE)
     {
-        rmt_BeginCPUSample(Wakeup);
+        rmt_BeginCPUSample(Wakeup, 0);
 
-            rmt_BeginCPUSample(ServerUpdate);
+            rmt_BeginCPUSample(ServerUpdate, 0);
             Server_Update(rmt->server);
             rmt_EndCPUSample();
 
-            rmt_BeginCPUSample(ConsumeMessageQueue);
+            rmt_BeginCPUSample(ConsumeMessageQueue, 0);
             Remotery_ConsumeMessageQueue(rmt);
             rmt_EndCPUSample();
 
@@ -4129,6 +4273,23 @@ static rmtError Remotery_Constructor(Remotery* rmt)
     rmt->json_buf = NULL;
     rmt->thread = NULL;
 
+    #if RMT_USE_CUDA
+        rmt->cuda.CtxSetCurrent = NULL;
+        rmt->cuda.EventCreate = NULL;
+        rmt->cuda.EventDestroy = NULL;
+        rmt->cuda.EventElapsedTime = NULL;
+        rmt->cuda.EventQuery = NULL;
+        rmt->cuda.EventRecord = NULL;
+    #endif
+
+    #if RMT_USE_D3D11
+        rmt->d3d11 = NULL;
+    #endif
+
+    #if RMT_USE_OPENGL
+        rmt->opengl = NULL;
+    #endif
+
     // Kick-off the timer
     usTimer_Init(&rmt->timer);
 
@@ -4138,7 +4299,7 @@ static rmtError Remotery_Constructor(Remotery* rmt)
         return error;
 
     // Create the server
-    New_1( Server, rmt->server, g_Settings.port );
+    New_2(Server, rmt->server, g_Settings.port, g_Settings.limit_connections_to_localhost);
     if (error != RMT_ERROR_NONE)
         return error;
 
@@ -4152,26 +4313,13 @@ static rmtError Remotery_Constructor(Remotery* rmt)
     if (error != RMT_ERROR_NONE)
         return error;
 
-    #if RMT_USE_CUDA
-
-        rmt->cuda.CtxSetCurrent = NULL;
-        rmt->cuda.EventCreate = NULL;
-        rmt->cuda.EventDestroy = NULL;
-        rmt->cuda.EventElapsedTime = NULL;
-        rmt->cuda.EventQuery = NULL;
-        rmt->cuda.EventRecord = NULL;
-
-    #endif
-
     #if RMT_USE_D3D11
-        rmt->d3d11 = NULL;
         error = D3D11_Create(&rmt->d3d11);
         if (error != RMT_ERROR_NONE)
             return error;
     #endif
 
     #if RMT_USE_OPENGL
-        rmt->opengl = NULL;
         error = OpenGL_Create(&rmt->opengl);
         if (error != RMT_ERROR_NONE)
             return error;
@@ -4198,11 +4346,11 @@ static void Remotery_Destructor(Remotery* rmt)
     // Join the remotery thread before clearing the global object as the thread is profiling itself
     Delete(Thread, rmt->thread);
 
-    // Ensure this is the module that created it
-    assert(g_RemoteryCreated == RMT_TRUE);
-    assert(g_Remotery == rmt);
-    g_Remotery = NULL;
-    g_RemoteryCreated = RMT_FALSE;
+    if (g_RemoteryCreated)
+    {
+      g_Remotery = NULL;
+      g_RemoteryCreated = RMT_FALSE;
+    }
 
     #if RMT_USE_D3D11
         Delete(D3D11, rmt->d3d11);
@@ -4324,6 +4472,7 @@ RMT_API rmtSettings* _rmt_Settings(void)
     if( g_SettingsInitialized == RMT_FALSE )
     {
         g_Settings.port = 0x4597;
+        g_Settings.limit_connections_to_localhost = RMT_FALSE;
         g_Settings.msSleepBetweenServerUpdates = 10;
         g_Settings.messageQueueSizeInBytes = 64 * 1024;
         g_Settings.maxNbMessagesPerUpdate = 100;
@@ -4357,6 +4506,9 @@ RMT_API rmtError _rmt_CreateGlobalInstance(Remotery** remotery)
 
 RMT_API void _rmt_DestroyGlobalInstance(Remotery* remotery)
 {
+    // Ensure this is the module that created it
+    assert(g_RemoteryCreated == RMT_TRUE);
+    assert(g_Remotery == remotery);
     Delete(Remotery, remotery);
 }
 
@@ -4460,7 +4612,7 @@ static rmtBool QueueLine(MessageQueue* queue, char* text, rmtU32 size, struct Th
 
     // Copy the text and commit the message
     memcpy(message->payload, text, size);
-    MessageQueue_CommitMessage(queue, message, MsgID_LogText);
+    MessageQueue_CommitMessage(message, MsgID_LogText);
 
     return RMT_TRUE;
 }
@@ -4554,7 +4706,7 @@ static rmtU32 GetNameHash(rmtPStr name, rmtU32* hash_cache)
 }
 
 
-RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache)
+RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32 flags, rmtU32* hash_cache)
 {
     // 'hash_cache' stores a pointer to a sample name's hash value. Internally this is used to identify unique callstacks and it
     // would be ideal that it's not recalculated each time the sample is used. This can be statically cached at the point
@@ -4573,8 +4725,14 @@ RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache)
     {
         Sample* sample;
         rmtU32 name_hash = GetNameHash(name, hash_cache);
-        if (ThreadSampler_Push(ts, ts->sample_trees[SampleType_CPU], name, name_hash, &sample) == RMT_ERROR_NONE)
-            sample->us_start = usTimer_Get(&g_Remotery->timer);
+        if (ThreadSampler_Push(ts->sample_trees[SampleType_CPU], name, name_hash, flags, &sample) == RMT_ERROR_NONE)
+        {
+            // If this is an aggregate sample, store the time in 'end' as we want to preserve 'start'
+            if (sample->us_length != 0)
+                sample->us_end = usTimer_Get(&g_Remotery->timer);
+            else
+                sample->us_start = usTimer_Get(&g_Remotery->timer);
+        }
     }
 }
 
@@ -4589,6 +4747,21 @@ RMT_API void _rmt_EndCPUSample(void)
     if (Remotery_GetThreadSampler(g_Remotery, &ts) == RMT_ERROR_NONE)
     {
         Sample* sample = ts->sample_trees[SampleType_CPU]->current_parent;
+
+        rmtU64 us_end = usTimer_Get(&g_Remotery->timer);
+
+        // Is this an aggregate sample?
+        if (sample->us_length != 0)
+        {
+            sample->us_length += (us_end - sample->us_end);
+            sample->us_end = us_end;
+        }
+        else
+        {
+            sample->us_end = us_end;
+            sample->us_length = (us_end - sample->us_start);
+        }
+
         sample->us_end = usTimer_Get(&g_Remotery->timer);
         ThreadSampler_Pop(ts, g_Remotery->mq_to_rmt_thread, sample);
     }
@@ -4794,6 +4967,7 @@ static rmtBool GetCUDASampleTimes(Sample* root_sample, Sample* sample)
     // Convert to microseconds and add to the sample
     sample->us_start = (rmtU64)(ms_start * 1000);
     sample->us_end = (rmtU64)(ms_end * 1000);
+    sample->us_length = sample->us_end - sample->us_start;
 
     // Get child sample times
     for (child = sample->first_child; child != NULL; child = child->next_sibling)
@@ -4847,7 +5021,7 @@ RMT_API void _rmt_BeginCUDASample(rmtPStr name, rmtU32* hash_cache, void* stream
         }
 
         // Push the same and record its event
-        if (ThreadSampler_Push(ts, *cuda_tree, name, name_hash, &sample) == RMT_ERROR_NONE)
+        if (ThreadSampler_Push(*cuda_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE)
         {
             CUDASample* cuda_sample = (CUDASample*)sample;
             CUDAEventRecord(cuda_sample->event_start, stream);
@@ -5233,7 +5407,7 @@ RMT_API void _rmt_BeginD3D11Sample(rmtPStr name, rmtU32* hash_cache)
             New_3(ObjectAllocator, d3d11->timestamp_allocator, sizeof(D3D11Timestamp), (ObjConstructor)D3D11Timestamp_Constructor, (ObjDestructor)D3D11Timestamp_Destructor);
 
         // Push the sample
-        if (ThreadSampler_Push(ts, *d3d_tree, name, name_hash, &sample) == RMT_ERROR_NONE)
+        if (ThreadSampler_Push(*d3d_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE)
         {
             D3D11Sample* d3d_sample = (D3D11Sample*)sample;
 
@@ -5273,6 +5447,8 @@ static rmtBool GetD3D11SampleTimes(Sample* sample, rmtU64* out_first_timestamp)
             d3d11->last_error = result;
             return RMT_FALSE;
         }
+
+        sample->us_length = sample->us_end - sample->us_start;
     }
 
     // Get child sample times
@@ -5296,7 +5472,7 @@ static void UpdateD3D11Frame(void)
     d3d11 = g_Remotery->d3d11;
     assert(d3d11 != NULL);
 
-    rmt_BeginCPUSample(rmt_UpdateD3D11Frame);
+    rmt_BeginCPUSample(rmt_UpdateD3D11Frame, 0);
 
     // Process all messages in the D3D queue
     for (;;)
@@ -5820,7 +5996,7 @@ RMT_API void _rmt_BeginOpenGLSample(rmtPStr name, rmtU32* hash_cache)
             New_3(ObjectAllocator, opengl->timestamp_allocator, sizeof(OpenGLTimestamp), (ObjConstructor)OpenGLTimestamp_Constructor, (ObjDestructor)OpenGLTimestamp_Destructor);
 
         // Push the sample
-        if (ThreadSampler_Push(ts, *ogl_tree, name, name_hash, &sample) == RMT_ERROR_NONE)
+        if (ThreadSampler_Push(*ogl_tree, name, name_hash, 0, &sample) == RMT_ERROR_NONE)
         {
             OpenGLSample* ogl_sample = (OpenGLSample*)sample;
 
@@ -5845,6 +6021,8 @@ static rmtBool GetOpenGLSampleTimes(Sample* sample, rmtU64* out_first_timestamp)
     {
         if (!OpenGLTimestamp_GetData(ogl_sample->timestamp, &sample->us_start, &sample->us_end, out_first_timestamp))
             return RMT_FALSE;
+
+        sample->us_length = sample->us_end - sample->us_start;
     }
 
     // Get child sample times
@@ -5868,7 +6046,7 @@ static void UpdateOpenGLFrame(void)
     opengl = g_Remotery->opengl;
     assert(opengl != NULL);
 
-    rmt_BeginCPUSample(rmt_UpdateOpenGLFrame);
+    rmt_BeginCPUSample(rmt_UpdateOpenGLFrame, 0);
 
     // Process all messages in the OpenGL queue
     while (1)

+ 23 - 18
third/bgfx/3rdparty/remotery/lib/Remotery.h

@@ -82,17 +82,6 @@ documented just below this comment.
 */
 
 
-
-// Compiler identification
-#if defined(_MSC_VER)
-    #define RMT_COMPILER_MSVC
-#elif defined(__GNUC__)
-    #define RMT_COMPILER_GNUC
-#elif defined(__clang__)
-    #define RMT_COMPILER_CLANG
-#endif
-
-
 // Platform identification
 #if defined(_WINDOWS) || defined(_WIN32)
     #define RMT_PLATFORM_WINDOWS
@@ -254,6 +243,15 @@ typedef enum rmtError
 } rmtError;
 
 
+typedef enum rmtSampleFlags
+{
+    // Default behaviour
+    RMTSF_None          = 0,
+
+    // Search parent for same-named samples and merge timing instead of adding a new sample
+    RMTSF_Aggregate     = 1,
+} rmtSampleFlags;
+
 
 /*
 ------------------------------------------------------------------------------------------------------------------------
@@ -289,14 +287,14 @@ typedef enum rmtError
 #define rmt_LogText(text)                                                           \
     RMT_OPTIONAL(RMT_ENABLED, _rmt_LogText(text))
 
-#define rmt_BeginCPUSample(name)                                                    \
+#define rmt_BeginCPUSample(name, flags)                                             \
     RMT_OPTIONAL(RMT_ENABLED, {                                                     \
         static rmtU32 rmt_sample_hash_##name = 0;                                   \
-        _rmt_BeginCPUSample(#name, &rmt_sample_hash_##name);                        \
+        _rmt_BeginCPUSample(#name, flags, &rmt_sample_hash_##name);                 \
     })
 
-#define rmt_BeginCPUSampleDynamic(namestr)                                          \
-    RMT_OPTIONAL(RMT_ENABLED, _rmt_BeginCPUSample(namestr, NULL))
+#define rmt_BeginCPUSampleDynamic(namestr, flags)                                   \
+    RMT_OPTIONAL(RMT_ENABLED, _rmt_BeginCPUSample(namestr, flags, NULL))
 
 #define rmt_EndCPUSample()                                                          \
     RMT_OPTIONAL(RMT_ENABLED, _rmt_EndCPUSample())
@@ -312,8 +310,15 @@ typedef void (*rmtInputHandlerPtr)(const char* text, void* context);
 // Struture to fill in to modify Remotery default settings
 typedef struct rmtSettings
 {
+    // Which port to listen for incoming connections on
     rmtU16 port;
 
+    // Only allow connections on localhost?
+    // For dev builds you may want to access your game from other devices but if
+    // you distribute a game to your players with Remotery active, probably best
+    // to limit connections to localhost.
+    rmtBool limit_connections_to_localhost;
+
     // How long to sleep between server updates, hopefully trying to give
     // a little CPU back to other threads.
     rmtU32 msSleepBetweenServerUpdates;
@@ -485,8 +490,8 @@ struct rmt_EndOpenGLSampleOnScopeExit
 
 
 // Pairs a call to rmt_Begin<TYPE>Sample with its call to rmt_End<TYPE>Sample when leaving scope
-#define rmt_ScopedCPUSample(name)                                                                       \
-        RMT_OPTIONAL(RMT_ENABLED, rmt_BeginCPUSample(name));                                            \
+#define rmt_ScopedCPUSample(name, flags)                                                                \
+        RMT_OPTIONAL(RMT_ENABLED, rmt_BeginCPUSample(name, flags));                                     \
         RMT_OPTIONAL(RMT_ENABLED, rmt_EndCPUSampleOnScopeExit rmt_ScopedCPUSample##name);
 #define rmt_ScopedCUDASample(name, stream)                                                              \
         RMT_OPTIONAL(RMT_USE_CUDA, rmt_BeginCUDASample(name, stream));                                  \
@@ -525,7 +530,7 @@ RMT_API void _rmt_SetGlobalInstance(Remotery* remotery);
 RMT_API Remotery* _rmt_GetGlobalInstance(void);
 RMT_API void _rmt_SetCurrentThreadName(rmtPStr thread_name);
 RMT_API void _rmt_LogText(rmtPStr text);
-RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32* hash_cache);
+RMT_API void _rmt_BeginCPUSample(rmtPStr name, rmtU32 flags, rmtU32* hash_cache);
 RMT_API void _rmt_EndCPUSample(void);
 
 #if RMT_USE_CUDA

+ 2 - 2
third/bgfx/3rdparty/remotery/readme.md

@@ -54,14 +54,14 @@ See the sample directory for further examples. A quick example:
 
         // Explicit begin/end for C
         {
-            rmt_BeginCPUSample(LogText);
+            rmt_BeginCPUSample(LogText, 0);
             rmt_LogText("Time me, please!");
             rmt_EndCPUSample();
         }
 
         // Scoped begin/end for C++
         {
-            rmt_ScopedCPUSample(LogText);
+            rmt_ScopedCPUSample(LogText, 0);
             rmt_LogText("Time me, too!");
         }
 

+ 15 - 3
third/bgfx/3rdparty/remotery/sample/sample.c

@@ -1,12 +1,14 @@
 #include <stdlib.h>
 #include <math.h>
+#include <signal.h>
+#include <stdio.h>
 #include "Remotery.h"
 
 double delay() {
     int i, end;
     double j = 0;
 
-    rmt_BeginCPUSample(delay);
+    rmt_BeginCPUSample(delay, 0);
     for( i = 0, end = rand()/100; i < end; ++i ) {
         j += sin(i);
     }
@@ -14,20 +16,30 @@ double delay() {
     return j;
 }
 
+int sig = 0;
+
+/// Allow to close cleanly with ctrl + c
+void sigintHandler(int sig_num) {
+    sig = sig_num;
+    printf("Interrupted\n");
+}
+
+int main( ) {
+    signal(SIGINT, sigintHandler);
 
-int main( int argc, const char **argv ) {
     Remotery *rmt;
 
     if( RMT_ERROR_NONE != rmt_CreateGlobalInstance(&rmt) ) {
         return -1;
     }
 
-    for(;;) {
+    while (sig == 0) {
         rmt_LogText("start profiling");
         delay();
         rmt_LogText("end profiling");
     }
 
     rmt_DestroyGlobalInstance(rmt);
+    printf("Cleaned up and quit\n");
     return 0;
 }

+ 82 - 7
third/bgfx/3rdparty/remotery/vis/Code/Console.js

@@ -19,7 +19,16 @@ Console = (function()
 
 		// This accumulates log text as fast as is required
 		this.PageTextBuffer = "";
+		this.LastPageTextBufferLen = 0;
 		this.AppTextBuffer = "";
+		this.LastAppTextBufferLen = 0;
+
+		// Setup command history control
+		this.CommandHistory = LocalStore.Get("App", "Global", "CommandHistory", [ ]);
+		this.CommandIndex = 0;
+		this.MaxNbCommands = 200;
+		DOM.Event.AddHandler(this.UserInput.EditNode, "keydown", Bind(OnKeyPress, this));
+		DOM.Event.AddHandler(this.UserInput.EditNode, "focus", Bind(OnFocus, this));
 
 		// At a much lower frequency this will update the console window
 		window.setInterval(Bind(UpdateHTML, this), 500);
@@ -91,13 +100,21 @@ Console = (function()
 	{
 		// Reset the current text buffer as html
 
-		var page_node = self.PageContainer.Node;
-		page_node.innerHTML = self.PageTextBuffer;
-		page_node.scrollTop = page_node.scrollHeight;
-
-		var app_node = self.AppContainer.Node;
-		app_node.innerHTML = self.AppTextBuffer;
-		app_node.scrollTop = app_node.scrollHeight;
+		if (self.LastPageTextBufferLen != self.PageTextBuffer.length)
+		{
+			var page_node = self.PageContainer.Node;
+			page_node.innerHTML = self.PageTextBuffer;
+			page_node.scrollTop = page_node.scrollHeight;
+			self.LastPageTextBufferLen = self.PageTextBuffer.length;
+		}
+
+		if (self.LastAppTextBufferLen != self.AppTextBuffer.length)
+		{		
+			var app_node = self.AppContainer.Node;
+			app_node.innerHTML = self.AppTextBuffer;
+			app_node.scrollTop = app_node.scrollHeight;
+			self.LastAppTextBufferLen = self.AppTextBuffer.length;
+		}
 	}
 
 
@@ -110,6 +127,64 @@ Console = (function()
 		// Emit to console and clear
 		self.Log("> " + msg);
 		self.UserInput.SetValue("");
+
+		// Keep track of recently issued commands, with an upper bound
+		self.CommandHistory.push(msg);
+		var extra_commands = self.CommandHistory.length - self.MaxNbCommands;
+		if (extra_commands > 0)
+			self.CommandHistory.splice(0, extra_commands);
+
+		// Set command history index to the most recent command
+		self.CommandIndex = self.CommandHistory.length;
+
+		// Backup to local store
+		LocalStore.Set("App", "Global", "CommandHistory", self.CommandHistory);
+
+		// Keep focus with the edit box
+		return true;
+	}
+
+
+	function OnKeyPress(self, evt)
+	{
+		evt = DOM.Event.Get(evt);
+
+		if (evt.keyCode == Keyboard.Codes.UP)
+		{
+			if (self.CommandHistory.length > 0)
+			{
+				// Cycle backwards through the command history
+				self.CommandIndex--;
+				if (self.CommandIndex < 0)
+					self.CommandIndex = self.CommandHistory.length - 1;
+				var command = self.CommandHistory[self.CommandIndex];
+				self.UserInput.SetValue(command);
+			}
+
+			// Stops default behaviour of moving cursor to the beginning
+			DOM.Event.StopDefaultAction(evt);
+		}
+
+		else if (evt.keyCode == Keyboard.Codes.DOWN)
+		{
+			if (self.CommandHistory.length > 0)
+			{
+				// Cycle fowards through the command history
+				self.CommandIndex = (self.CommandIndex + 1) % self.CommandHistory.length;
+				var command = self.CommandHistory[self.CommandIndex];
+				self.UserInput.SetValue(command);
+			}
+
+			// Stops default behaviour of moving cursor to the end
+			DOM.Event.StopDefaultAction(evt);
+		}
+	}
+
+
+	function OnFocus(self)
+	{
+		// Reset command index on focus
+		self.CommandIndex = self.CommandHistory.length;
 	}
 
 

+ 3 - 0
third/bgfx/3rdparty/remotery/vis/Code/Remotery.js

@@ -92,6 +92,9 @@ Remotery = (function()
 		// Update and disconnect, relying on auto-connect to reconnect
 		self.ConnectionAddress = node.value;
 		self.Server.Disconnect();
+
+		// Give input focus away
+		return false;
 	}
 
 

+ 1 - 0
third/bgfx/3rdparty/remotery/vis/Styles/Remotery.css

@@ -67,6 +67,7 @@ body
     color: #BBB;
     font: 9px Verdana;
     margin: 2px;
+    white-space: pre;
 }
 
 

+ 13 - 11
third/bgfx/3rdparty/remotery/vis/extern/BrowserLib/WindowManager/Code/EditBox.js

@@ -27,11 +27,12 @@ WM.EditBox = (function()
 		this.SetPosition(x, y);
 		this.SetSize(w, h);
 
+		this.PreviousValue = "";
+
 		// Hook up the event handlers
 		DOM.Event.AddHandler(this.EditNode, "focus", Bind(OnFocus, this));
 		DOM.Event.AddHandler(this.EditNode, "keypress", Bind(OnKeyPress, this));
 		DOM.Event.AddHandler(this.EditNode, "keydown", Bind(OnKeyDown, this));
-		DOM.Event.AddHandler(this.EditNode, "change", Bind(OnChange, this));
 	}
 
 
@@ -88,9 +89,12 @@ WM.EditBox = (function()
 	function OnKeyPress(self, evt)
 	{
 		// Allow enter to confirm the text only when there's data
-		if (evt.keyCode == 13 && self.EditNode.value != "")
+		if (evt.keyCode == 13 && self.EditNode.value != "" && self.ChangeHandler)
 		{
-			self.EditNode.blur();
+			var focus = self.ChangeHandler(self.EditNode);
+			if (!focus)
+				self.EditNode.blur();
+			self.PreviousValue = "";
 		}
 	}
 
@@ -100,18 +104,16 @@ WM.EditBox = (function()
 		// Allow escape to cancel any text changes
 		if (evt.keyCode == 27)
 		{
-			self.EditNode.value = self.PreviousValue;
+			// On initial edit of the input, escape should NOT replace with the empty string
+			if (self.PreviousValue != "")
+			{
+				self.EditNode.value = self.PreviousValue;
+			}
+
 			self.EditNode.blur();
 		}
 	}
 
 
-	function OnChange(self, evt)
-	{
-		if (self.ChangeHandler)
-			self.ChangeHandler(self.EditNode);
-	}
-
-
 	return EditBox;
 })();

+ 1 - 0
third/bgfx/3rdparty/remotery/vis/index.html

@@ -17,6 +17,7 @@
 		<script type="text/javascript" src="extern/BrowserLib/Core/Code/Convert.js"></script>
 		<script type="text/javascript" src="extern/BrowserLib/Core/Code/LocalStore.js"></script>
 		<script type="text/javascript" src="extern/BrowserLib/Core/Code/Mouse.js"></script>
+		<script type="text/javascript" src="extern/BrowserLib/Core/Code/Keyboard.js"></script>
 
 		<!-- User Interface Window Manager -->
 		<script type="text/javascript" src="extern/BrowserLib/WindowManager/Code/WindowManager.js"></script>

+ 369 - 290
third/bgfx/3rdparty/renderdoc/renderdoc_app.h

@@ -1,18 +1,18 @@
 /******************************************************************************
  * The MIT License (MIT)
- * 
+ *
  * Copyright (c) 2015-2016 Baldur Karlsson
- * 
+ *
  * 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 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
@@ -24,16 +24,23 @@
 
 #pragma once
 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Documentation for the API is available at https://renderdoc.org/docs/in_application_api.html
+//
+
 #if !defined(RENDERDOC_NO_STDINT)
 #include <stdint.h>
 #endif
 
 #if defined(WIN32)
-	#define RENDERDOC_CC __cdecl
+#define RENDERDOC_CC __cdecl
 #elif defined(__linux__)
-	#define RENDERDOC_CC
+#define RENDERDOC_CC
+#elif defined(__APPLE__)
+#define RENDERDOC_CC
 #else
-	#error "Unknown platform"
+#error "Unknown platform"
 #endif
 
 #ifdef __cplusplus
@@ -45,137 +52,144 @@ extern "C" {
 
 // This is a GUID/magic value used for when applications pass a path where shader debug
 // information can be found to match up with a stripped shader.
-// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue = RENDERDOC_ShaderDebugMagicValue_value
-#define RENDERDOC_ShaderDebugMagicValue_struct { 0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff }
+// the define can be used like so: const GUID RENDERDOC_ShaderDebugMagicValue =
+// RENDERDOC_ShaderDebugMagicValue_value
+#define RENDERDOC_ShaderDebugMagicValue_struct                                \
+  {                                                                           \
+    0xeab25520, 0x6670, 0x4865, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \
+  }
 
 // as an alternative when you want a byte array (assuming x86 endianness):
-#define RENDERDOC_ShaderDebugMagicValue_bytearray { 0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff }
-	
+#define RENDERDOC_ShaderDebugMagicValue_bytearray                                                 \
+  {                                                                                               \
+    0x20, 0x55, 0xb2, 0xea, 0x70, 0x66, 0x65, 0x48, 0x84, 0x29, 0x6c, 0x8, 0x51, 0x54, 0x00, 0xff \
+  }
+
 // truncated version when only a uint64_t is available (e.g. Vulkan tags):
 #define RENDERDOC_ShaderDebugMagicValue_truncated 0x48656670eab25520ULL
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // RenderDoc capture options
-// 
+//
 
-typedef enum
-{
-	// Allow the application to enable vsync
-	//
-	// Default - enabled
-	//
-	// 1 - The application can enable or disable vsync at will
-	// 0 - vsync is force disabled
-	eRENDERDOC_Option_AllowVSync = 0,
-	
-	// Allow the application to enable fullscreen
-	//
-	// Default - enabled
-	//
-	// 1 - The application can enable or disable fullscreen at will
-	// 0 - fullscreen is force disabled
-	eRENDERDOC_Option_AllowFullscreen = 1,
-
-	// Record API debugging events and messages 
-	//
-	// Default - disabled
-	//
-	// 1 - Enable built-in API debugging features and records the results into
-	//     the capture logfile, which is matched up with events on replay
-	// 0 - no API debugging is forcibly enabled
-	eRENDERDOC_Option_DebugDeviceMode = 2,
-	
-	// Capture CPU callstacks for API events 
-	//
-	// Default - disabled
-	//
-	// 1 - Enables capturing of callstacks
-	// 0 - no callstacks are captured
-	eRENDERDOC_Option_CaptureCallstacks = 3,
-	
-	// When capturing CPU callstacks, only capture them from drawcalls.
-	// This option does nothing without the above option being enabled
-	//
-	// Default - disabled
-	//
-	// 1 - Only captures callstacks for drawcall type API events.
-	//     Ignored if CaptureCallstacks is disabled
-	// 0 - Callstacks, if enabled, are captured for every event.
-	eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4,
-
-	// Specify a delay in seconds to wait for a debugger to attach, after
-	// creating or injecting into a process, before continuing to allow it to run.
-	//
-	// 0 indicates no delay, and the process will run immediately after injection
-	//
-	// Default - 0 seconds
-	//
-	eRENDERDOC_Option_DelayForDebugger = 5,
-	
-	// Verify any writes to mapped buffers, by checking the memory after the
-	// bounds of the returned pointer to detect any modification.
-	//
-	// Default - disabled
-	//
-	// 1 - Verify any writes to mapped buffers
-	// 0 - No verification is performed, and overwriting bounds may cause
-	//     crashes or corruption in RenderDoc
-	eRENDERDOC_Option_VerifyMapWrites = 6,
-	
-	// Hooks any system API calls that create child processes, and injects
-	// RenderDoc into them recursively with the same options.
-	//
-	// Default - disabled
-	//
-	// 1 - Hooks into spawned child processes
-	// 0 - Child processes are not hooked by RenderDoc
-	eRENDERDOC_Option_HookIntoChildren = 7,
-
-	// By default RenderDoc only includes resources in the final logfile necessary
-	// for that frame, this allows you to override that behaviour.
-	//
-	// Default - disabled
-	//
-	// 1 - all live resources at the time of capture are included in the log
-	//     and available for inspection
-	// 0 - only the resources referenced by the captured frame are included
-	eRENDERDOC_Option_RefAllResources = 8,
-
-	// By default RenderDoc skips saving initial states for resources where the
-	// previous contents don't appear to be used, assuming that writes before
-	// reads indicate previous contents aren't used.
-	//
-	// Default - disabled
-	//
-	// 1 - initial contents at the start of each captured frame are saved, even if
-	//     they are later overwritten or cleared before being used.
-	// 0 - unless a read is detected, initial contents will not be saved and will
-	//     appear as black or empty data.
-	eRENDERDOC_Option_SaveAllInitials = 9,
-
-	// In APIs that allow for the recording of command lists to be replayed later,
-	// RenderDoc may choose to not capture command lists before a frame capture is
-	// triggered, to reduce overheads. This means any command lists recorded once
-	// and replayed many times will not be available and may cause a failure to
-	// capture.
-	//
-	// Note this is only true for APIs where multithreading is difficult or
-	// discouraged. Newer APIs like Vulkan and D3D12 will ignore this option
-	// and always capture all command lists since the API is heavily oriented
-	// around it and the overheads have been reduced by API design.
-	//
-	// 1 - All command lists are captured from the start of the application
-	// 0 - Command lists are only captured if their recording begins during
-	//     the period when a frame capture is in progress.
-	eRENDERDOC_Option_CaptureAllCmdLists = 10,
-
-	// Mute API debugging output when the debug device mode option is enabled 
-	//
-	// Default - enabled
-	//
-	// 1 - Mute any API debug messages from being displayed or passed through
-	// 0 - API debugging is displayed as normal
-	eRENDERDOC_Option_DebugOutputMute = 11,
+typedef enum {
+  // Allow the application to enable vsync
+  //
+  // Default - enabled
+  //
+  // 1 - The application can enable or disable vsync at will
+  // 0 - vsync is force disabled
+  eRENDERDOC_Option_AllowVSync = 0,
+
+  // Allow the application to enable fullscreen
+  //
+  // Default - enabled
+  //
+  // 1 - The application can enable or disable fullscreen at will
+  // 0 - fullscreen is force disabled
+  eRENDERDOC_Option_AllowFullscreen = 1,
+
+  // Record API debugging events and messages
+  //
+  // Default - disabled
+  //
+  // 1 - Enable built-in API debugging features and records the results into
+  //     the capture logfile, which is matched up with events on replay
+  // 0 - no API debugging is forcibly enabled
+  eRENDERDOC_Option_APIValidation = 2,
+  eRENDERDOC_Option_DebugDeviceMode = 2,    // deprecated name of this enum
+
+  // Capture CPU callstacks for API events
+  //
+  // Default - disabled
+  //
+  // 1 - Enables capturing of callstacks
+  // 0 - no callstacks are captured
+  eRENDERDOC_Option_CaptureCallstacks = 3,
+
+  // When capturing CPU callstacks, only capture them from drawcalls.
+  // This option does nothing without the above option being enabled
+  //
+  // Default - disabled
+  //
+  // 1 - Only captures callstacks for drawcall type API events.
+  //     Ignored if CaptureCallstacks is disabled
+  // 0 - Callstacks, if enabled, are captured for every event.
+  eRENDERDOC_Option_CaptureCallstacksOnlyDraws = 4,
+
+  // Specify a delay in seconds to wait for a debugger to attach, after
+  // creating or injecting into a process, before continuing to allow it to run.
+  //
+  // 0 indicates no delay, and the process will run immediately after injection
+  //
+  // Default - 0 seconds
+  //
+  eRENDERDOC_Option_DelayForDebugger = 5,
+
+  // Verify any writes to mapped buffers, by checking the memory after the
+  // bounds of the returned pointer to detect any modification.
+  //
+  // Default - disabled
+  //
+  // 1 - Verify any writes to mapped buffers
+  // 0 - No verification is performed, and overwriting bounds may cause
+  //     crashes or corruption in RenderDoc
+  eRENDERDOC_Option_VerifyMapWrites = 6,
+
+  // Hooks any system API calls that create child processes, and injects
+  // RenderDoc into them recursively with the same options.
+  //
+  // Default - disabled
+  //
+  // 1 - Hooks into spawned child processes
+  // 0 - Child processes are not hooked by RenderDoc
+  eRENDERDOC_Option_HookIntoChildren = 7,
+
+  // By default RenderDoc only includes resources in the final logfile necessary
+  // for that frame, this allows you to override that behaviour.
+  //
+  // Default - disabled
+  //
+  // 1 - all live resources at the time of capture are included in the log
+  //     and available for inspection
+  // 0 - only the resources referenced by the captured frame are included
+  eRENDERDOC_Option_RefAllResources = 8,
+
+  // By default RenderDoc skips saving initial states for resources where the
+  // previous contents don't appear to be used, assuming that writes before
+  // reads indicate previous contents aren't used.
+  //
+  // Default - disabled
+  //
+  // 1 - initial contents at the start of each captured frame are saved, even if
+  //     they are later overwritten or cleared before being used.
+  // 0 - unless a read is detected, initial contents will not be saved and will
+  //     appear as black or empty data.
+  eRENDERDOC_Option_SaveAllInitials = 9,
+
+  // In APIs that allow for the recording of command lists to be replayed later,
+  // RenderDoc may choose to not capture command lists before a frame capture is
+  // triggered, to reduce overheads. This means any command lists recorded once
+  // and replayed many times will not be available and may cause a failure to
+  // capture.
+  //
+  // Note this is only true for APIs where multithreading is difficult or
+  // discouraged. Newer APIs like Vulkan and D3D12 will ignore this option
+  // and always capture all command lists since the API is heavily oriented
+  // around it and the overheads have been reduced by API design.
+  //
+  // 1 - All command lists are captured from the start of the application
+  // 0 - Command lists are only captured if their recording begins during
+  //     the period when a frame capture is in progress.
+  eRENDERDOC_Option_CaptureAllCmdLists = 10,
+
+  // Mute API debugging output when the API validation mode option is enabled
+  //
+  // Default - enabled
+  //
+  // 1 - Mute any API debug messages from being displayed or passed through
+  // 0 - API debugging is displayed as normal
+  eRENDERDOC_Option_DebugOutputMute = 11,
 
 } RENDERDOC_CaptureOption;
 
@@ -183,140 +197,135 @@ typedef enum
 //
 // Returns 1 if the option and value are valid
 // Returns 0 if either is invalid and the option is unchanged
-typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val);
-typedef int (RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val);
+typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionU32)(RENDERDOC_CaptureOption opt, uint32_t val);
+typedef int(RENDERDOC_CC *pRENDERDOC_SetCaptureOptionF32)(RENDERDOC_CaptureOption opt, float val);
 
 // Gets the current value of an option as a uint32_t
 //
 // If the option is invalid, 0xffffffff is returned
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt);
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionU32)(RENDERDOC_CaptureOption opt);
 
 // Gets the current value of an option as a float
 //
 // If the option is invalid, -FLT_MAX is returned
-typedef float (RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt);
-
-typedef enum
-{
-	// '0' - '9' matches ASCII values
-	eRENDERDOC_Key_0 = 0x30,
-	eRENDERDOC_Key_1 = 0x31,
-	eRENDERDOC_Key_2 = 0x32,
-	eRENDERDOC_Key_3 = 0x33,
-	eRENDERDOC_Key_4 = 0x34,
-	eRENDERDOC_Key_5 = 0x35,
-	eRENDERDOC_Key_6 = 0x36,
-	eRENDERDOC_Key_7 = 0x37,
-	eRENDERDOC_Key_8 = 0x38,
-	eRENDERDOC_Key_9 = 0x39,
-
-	// 'A' - 'Z' matches ASCII values
-	eRENDERDOC_Key_A = 0x41,
-	eRENDERDOC_Key_B = 0x42,
-	eRENDERDOC_Key_C = 0x43,
-	eRENDERDOC_Key_D = 0x44,
-	eRENDERDOC_Key_E = 0x45,
-	eRENDERDOC_Key_F = 0x46,
-	eRENDERDOC_Key_G = 0x47,
-	eRENDERDOC_Key_H = 0x48,
-	eRENDERDOC_Key_I = 0x49,
-	eRENDERDOC_Key_J = 0x4A,
-	eRENDERDOC_Key_K = 0x4B,
-	eRENDERDOC_Key_L = 0x4C,
-	eRENDERDOC_Key_M = 0x4D,
-	eRENDERDOC_Key_N = 0x4E,
-	eRENDERDOC_Key_O = 0x4F,
-	eRENDERDOC_Key_P = 0x50,
-	eRENDERDOC_Key_Q = 0x51,
-	eRENDERDOC_Key_R = 0x52,
-	eRENDERDOC_Key_S = 0x53,
-	eRENDERDOC_Key_T = 0x54,
-	eRENDERDOC_Key_U = 0x55,
-	eRENDERDOC_Key_V = 0x56,
-	eRENDERDOC_Key_W = 0x57,
-	eRENDERDOC_Key_X = 0x58,
-	eRENDERDOC_Key_Y = 0x59,
-	eRENDERDOC_Key_Z = 0x5A,
-
-	// leave the rest of the ASCII range free
-	// in case we want to use it later
-	eRENDERDOC_Key_NonPrintable = 0x100,
-
-	eRENDERDOC_Key_Divide,
-	eRENDERDOC_Key_Multiply,
-	eRENDERDOC_Key_Subtract,
-	eRENDERDOC_Key_Plus,
-
-	eRENDERDOC_Key_F1,
-	eRENDERDOC_Key_F2,
-	eRENDERDOC_Key_F3,
-	eRENDERDOC_Key_F4,
-	eRENDERDOC_Key_F5,
-	eRENDERDOC_Key_F6,
-	eRENDERDOC_Key_F7,
-	eRENDERDOC_Key_F8,
-	eRENDERDOC_Key_F9,
-	eRENDERDOC_Key_F10,
-	eRENDERDOC_Key_F11,
-	eRENDERDOC_Key_F12,
-
-	eRENDERDOC_Key_Home,
-	eRENDERDOC_Key_End,
-	eRENDERDOC_Key_Insert,
-	eRENDERDOC_Key_Delete,
-	eRENDERDOC_Key_PageUp,
-	eRENDERDOC_Key_PageDn,
-
-	eRENDERDOC_Key_Backspace,
-	eRENDERDOC_Key_Tab,
-	eRENDERDOC_Key_PrtScrn,
-	eRENDERDOC_Key_Pause,
-
-	eRENDERDOC_Key_Max,
+typedef float(RENDERDOC_CC *pRENDERDOC_GetCaptureOptionF32)(RENDERDOC_CaptureOption opt);
+
+typedef enum {
+  // '0' - '9' matches ASCII values
+  eRENDERDOC_Key_0 = 0x30,
+  eRENDERDOC_Key_1 = 0x31,
+  eRENDERDOC_Key_2 = 0x32,
+  eRENDERDOC_Key_3 = 0x33,
+  eRENDERDOC_Key_4 = 0x34,
+  eRENDERDOC_Key_5 = 0x35,
+  eRENDERDOC_Key_6 = 0x36,
+  eRENDERDOC_Key_7 = 0x37,
+  eRENDERDOC_Key_8 = 0x38,
+  eRENDERDOC_Key_9 = 0x39,
+
+  // 'A' - 'Z' matches ASCII values
+  eRENDERDOC_Key_A = 0x41,
+  eRENDERDOC_Key_B = 0x42,
+  eRENDERDOC_Key_C = 0x43,
+  eRENDERDOC_Key_D = 0x44,
+  eRENDERDOC_Key_E = 0x45,
+  eRENDERDOC_Key_F = 0x46,
+  eRENDERDOC_Key_G = 0x47,
+  eRENDERDOC_Key_H = 0x48,
+  eRENDERDOC_Key_I = 0x49,
+  eRENDERDOC_Key_J = 0x4A,
+  eRENDERDOC_Key_K = 0x4B,
+  eRENDERDOC_Key_L = 0x4C,
+  eRENDERDOC_Key_M = 0x4D,
+  eRENDERDOC_Key_N = 0x4E,
+  eRENDERDOC_Key_O = 0x4F,
+  eRENDERDOC_Key_P = 0x50,
+  eRENDERDOC_Key_Q = 0x51,
+  eRENDERDOC_Key_R = 0x52,
+  eRENDERDOC_Key_S = 0x53,
+  eRENDERDOC_Key_T = 0x54,
+  eRENDERDOC_Key_U = 0x55,
+  eRENDERDOC_Key_V = 0x56,
+  eRENDERDOC_Key_W = 0x57,
+  eRENDERDOC_Key_X = 0x58,
+  eRENDERDOC_Key_Y = 0x59,
+  eRENDERDOC_Key_Z = 0x5A,
+
+  // leave the rest of the ASCII range free
+  // in case we want to use it later
+  eRENDERDOC_Key_NonPrintable = 0x100,
+
+  eRENDERDOC_Key_Divide,
+  eRENDERDOC_Key_Multiply,
+  eRENDERDOC_Key_Subtract,
+  eRENDERDOC_Key_Plus,
+
+  eRENDERDOC_Key_F1,
+  eRENDERDOC_Key_F2,
+  eRENDERDOC_Key_F3,
+  eRENDERDOC_Key_F4,
+  eRENDERDOC_Key_F5,
+  eRENDERDOC_Key_F6,
+  eRENDERDOC_Key_F7,
+  eRENDERDOC_Key_F8,
+  eRENDERDOC_Key_F9,
+  eRENDERDOC_Key_F10,
+  eRENDERDOC_Key_F11,
+  eRENDERDOC_Key_F12,
+
+  eRENDERDOC_Key_Home,
+  eRENDERDOC_Key_End,
+  eRENDERDOC_Key_Insert,
+  eRENDERDOC_Key_Delete,
+  eRENDERDOC_Key_PageUp,
+  eRENDERDOC_Key_PageDn,
+
+  eRENDERDOC_Key_Backspace,
+  eRENDERDOC_Key_Tab,
+  eRENDERDOC_Key_PrtScrn,
+  eRENDERDOC_Key_Pause,
+
+  eRENDERDOC_Key_Max,
 } RENDERDOC_InputButton;
 
 // Sets which key or keys can be used to toggle focus between multiple windows
 //
 // If keys is NULL or num is 0, toggle keys will be disabled
-typedef void (RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num);
+typedef void(RENDERDOC_CC *pRENDERDOC_SetFocusToggleKeys)(RENDERDOC_InputButton *keys, int num);
 
 // Sets which key or keys can be used to capture the next frame
 //
 // If keys is NULL or num is 0, captures keys will be disabled
-typedef void (RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num);
+typedef void(RENDERDOC_CC *pRENDERDOC_SetCaptureKeys)(RENDERDOC_InputButton *keys, int num);
 
-typedef enum
-{
-	// This single bit controls whether the overlay is enabled or disabled globally
-	eRENDERDOC_Overlay_Enabled = 0x1,
+typedef enum {
+  // This single bit controls whether the overlay is enabled or disabled globally
+  eRENDERDOC_Overlay_Enabled = 0x1,
 
-	// Show the average framerate over several seconds as well as min/max
-	eRENDERDOC_Overlay_FrameRate = 0x2,
+  // Show the average framerate over several seconds as well as min/max
+  eRENDERDOC_Overlay_FrameRate = 0x2,
 
-	// Show the current frame number
-	eRENDERDOC_Overlay_FrameNumber = 0x4,
+  // Show the current frame number
+  eRENDERDOC_Overlay_FrameNumber = 0x4,
 
-	// Show a list of recent captures, and how many captures have been made
-	eRENDERDOC_Overlay_CaptureList = 0x8,
+  // Show a list of recent captures, and how many captures have been made
+  eRENDERDOC_Overlay_CaptureList = 0x8,
 
-	// Default values for the overlay mask
-	eRENDERDOC_Overlay_Default =
-	       (eRENDERDOC_Overlay_Enabled|
-	        eRENDERDOC_Overlay_FrameRate|
-	        eRENDERDOC_Overlay_FrameNumber|
-	        eRENDERDOC_Overlay_CaptureList),
+  // Default values for the overlay mask
+  eRENDERDOC_Overlay_Default = (eRENDERDOC_Overlay_Enabled | eRENDERDOC_Overlay_FrameRate |
+                                eRENDERDOC_Overlay_FrameNumber | eRENDERDOC_Overlay_CaptureList),
 
-	// Enable all bits
-	eRENDERDOC_Overlay_All = ~0U,
+  // Enable all bits
+  eRENDERDOC_Overlay_All = ~0U,
 
-	// Disable all bits
-	eRENDERDOC_Overlay_None = 0,
+  // Disable all bits
+  eRENDERDOC_Overlay_None = 0,
 } RENDERDOC_OverlayBits;
 
 // returns the overlay bits that have been set
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetOverlayBits)();
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetOverlayBits)();
 // sets the overlay bits with an and & or mask
-typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or);
+typedef void(RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t Or);
 
 // this function will attempt to shut down RenderDoc.
 //
@@ -324,14 +333,14 @@ typedef void (RENDERDOC_CC *pRENDERDOC_MaskOverlayBits)(uint32_t And, uint32_t O
 // the dll is loaded, before any API work happens. RenderDoc will remove its
 // injected hooks and shut down. Behaviour is undefined if this is called
 // after any API functions have been called.
-typedef void (RENDERDOC_CC *pRENDERDOC_Shutdown)();
+typedef void(RENDERDOC_CC *pRENDERDOC_Shutdown)();
 
 // This function will unload RenderDoc's crash handler.
 //
 // If you use your own crash handler and don't want RenderDoc's handler to
 // intercede, you can call this function to unload it and any unhandled
 // exceptions will pass to the next handler.
-typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)();
+typedef void(RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)();
 
 // Sets the logfile path template
 //
@@ -350,13 +359,13 @@ typedef void (RENDERDOC_CC *pRENDERDOC_UnloadCrashHandler)();
 //
 // Capture #1 -> my_captures/example_frame123.rdc
 // Capture #2 -> my_captures/example_frame456.rdc
-typedef void (RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate);
+typedef void(RENDERDOC_CC *pRENDERDOC_SetLogFilePathTemplate)(const char *pathtemplate);
 
 // returns the current logfile template, see SetLogFileTemplate above, as a UTF-8 string
-typedef const char* (RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)();
+typedef const char *(RENDERDOC_CC *pRENDERDOC_GetLogFilePathTemplate)();
 
 // returns the number of captures that have been made
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)();
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetNumCaptures)();
 
 // This function returns the details of a capture, by index. New captures are added
 // to the end of the list.
@@ -372,29 +381,32 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetNumCaptures)();
 //
 // Note: when captures are deleted in the UI they will remain in this list, so the
 // logfile path may not exist anymore.
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile, uint32_t *pathlength, uint64_t *timestamp);
-
-// capture the next frame on whichever window and API is currently considered active
-typedef void (RENDERDOC_CC *pRENDERDOC_TriggerCapture)();
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_GetCapture)(uint32_t idx, char *logfile,
+                                                      uint32_t *pathlength, uint64_t *timestamp);
 
 // returns 1 if the RenderDoc UI is connected to this application, 0 otherwise
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)();
+// This was renamed to IsTargetControlConnected in API 1.1.1, the old typedef is kept here for
+// backwards compatibility with old code, it is castable either way since it's ABI compatible
+// as the same function pointer type.
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsRemoteAccessConnected)();
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsTargetControlConnected)();
 
 // This function will launch the Replay UI associated with the RenderDoc library injected
 // into the running application.
 //
-// if connectRemoteAccess is 1, the Replay UI will be launched with a command line parameter
+// if connectTargetControl is 1, the Replay UI will be launched with a command line parameter
 // to connect to this application
 // cmdline is the rest of the command line, as a UTF-8 string. E.g. a captures to open
 // if cmdline is NULL, the command line will be empty.
 //
 // returns the PID of the replay UI if successful, 0 if not successful.
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectRemoteAccess, const char *cmdline);
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_LaunchReplayUI)(uint32_t connectTargetControl,
+                                                          const char *cmdline);
 
 // RenderDoc can return a higher version than requested if it's backwards compatible,
 // this function returns the actual version returned. If a parameter is NULL, it will be
 // ignored and the others will be filled out.
-typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch);
+typedef void(RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, int *patch);
 
 //////////////////////////////////////////////////////////////////////////
 // Capturing functions
@@ -403,16 +415,23 @@ typedef void (RENDERDOC_CC *pRENDERDOC_GetAPIVersion)(int *major, int *minor, in
 // A device pointer is a pointer to the API's root handle.
 //
 // This would be an ID3D11Device, HGLRC/GLXContext, ID3D12Device, etc
-typedef void* RENDERDOC_DevicePointer;
+typedef void *RENDERDOC_DevicePointer;
 
 // A window handle is the OS's native window handle
 //
 // This would be an HWND, GLXDrawable, etc
-typedef void* RENDERDOC_WindowHandle;
+typedef void *RENDERDOC_WindowHandle;
 
 // This sets the RenderDoc in-app overlay in the API/window pair as 'active' and it will
 // respond to keypresses. Neither parameter can be NULL
-typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle);
+typedef void(RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer device,
+                                                       RENDERDOC_WindowHandle wndHandle);
+
+// capture the next frame on whichever window and API is currently considered active
+typedef void(RENDERDOC_CC *pRENDERDOC_TriggerCapture)();
+
+// capture the next N frames on whichever window and API is currently considered active
+typedef void(RENDERDOC_CC *pRENDERDOC_TriggerMultiFrameCapture)(uint32_t numFrames);
 
 // When choosing either a device pointer or a window handle to capture, you can pass NULL.
 // Passing NULL specifies a 'wildcard' match against anything. This allows you to specify
@@ -432,24 +451,26 @@ typedef void (RENDERDOC_CC *pRENDERDOC_SetActiveWindow)(RENDERDOC_DevicePointer
 //
 // The results are undefined (including crashes) if two captures are started overlapping,
 // even on separate devices and/oror windows.
-typedef void (RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle);
+typedef void(RENDERDOC_CC *pRENDERDOC_StartFrameCapture)(RENDERDOC_DevicePointer device,
+                                                         RENDERDOC_WindowHandle wndHandle);
 
 // Returns whether or not a frame capture is currently ongoing anywhere.
 //
 // This will return 1 if a capture is ongoing, and 0 if there is no capture running
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)();
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_IsFrameCapturing)();
 
 // Ends capturing immediately.
 //
 // This will return 1 if the capture succeeded, and 0 if there was an error capturing.
-typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device, RENDERDOC_WindowHandle wndHandle);
+typedef uint32_t(RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePointer device,
+                                                           RENDERDOC_WindowHandle wndHandle);
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // RenderDoc API versions
-// 
+//
 
 // RenderDoc uses semantic versioning (http://semver.org/).
-// 
+//
 // MAJOR version is incremented when incompatible API changes happen.
 // MINOR version is incremented when functionality is added in a backwards-compatible manner.
 // PATCH version is incremented when backwards-compatible bug fixes happen.
@@ -457,10 +478,12 @@ typedef uint32_t (RENDERDOC_CC *pRENDERDOC_EndFrameCapture)(RENDERDOC_DevicePoin
 // Note that this means the API returned can be higher than the one you might have requested.
 // e.g. if you are running against a newer RenderDoc that supports 1.0.1, it will be returned
 // instead of 1.0.0. You can check this with the GetAPIVersion entry point
-typedef enum
-{
-	eRENDERDOC_API_Version_1_0_0 = 10000, // RENDERDOC_API_1_0_0 = 1 00 00
-	eRENDERDOC_API_Version_1_0_1 = 10001, // RENDERDOC_API_1_0_1 = 1 00 01
+typedef enum {
+  eRENDERDOC_API_Version_1_0_0 = 10000,    // RENDERDOC_API_1_0_0 = 1 00 00
+  eRENDERDOC_API_Version_1_0_1 = 10001,    // RENDERDOC_API_1_0_1 = 1 00 01
+  eRENDERDOC_API_Version_1_0_2 = 10002,    // RENDERDOC_API_1_0_2 = 1 00 02
+  eRENDERDOC_API_Version_1_1_0 = 10100,    // RENDERDOC_API_1_1_0 = 1 01 00
+  eRENDERDOC_API_Version_1_1_1 = 10101,    // RENDERDOC_API_1_1_1 = 1 01 01
 } RENDERDOC_Version;
 
 // API version changelog:
@@ -468,52 +491,108 @@ typedef enum
 // 1.0.0 - initial release
 // 1.0.1 - Bugfix: IsFrameCapturing() was returning false for captures that were triggered
 //         by keypress or TriggerCapture, instead of Start/EndFrameCapture.
+// 1.0.2 - Refactor: Renamed eRENDERDOC_Option_DebugDeviceMode to eRENDERDOC_Option_APIValidation
+// 1.1.0 - Add feature: TriggerMultiFrameCapture(). Backwards compatible with 1.0.x since the new
+//         function pointer is added to the end of the struct, the original layout is identical
+// 1.1.1 - Refactor: Renamed remote access to target control (to better disambiguate from remote
+//         replay/remote server concept in replay UI)
 
-// eRENDERDOC_API_Version_1_0_1
+// eRENDERDOC_API_Version_1_1_0
 typedef struct
 {
-	pRENDERDOC_GetAPIVersion              GetAPIVersion;
+  pRENDERDOC_GetAPIVersion GetAPIVersion;
+
+  pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32;
+  pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32;
 
-	pRENDERDOC_SetCaptureOptionU32        SetCaptureOptionU32;
-	pRENDERDOC_SetCaptureOptionF32        SetCaptureOptionF32;
+  pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32;
+  pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32;
 
-	pRENDERDOC_GetCaptureOptionU32        GetCaptureOptionU32;
-	pRENDERDOC_GetCaptureOptionF32        GetCaptureOptionF32;
+  pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys;
+  pRENDERDOC_SetCaptureKeys SetCaptureKeys;
 
-	pRENDERDOC_SetFocusToggleKeys         SetFocusToggleKeys;
-	pRENDERDOC_SetCaptureKeys             SetCaptureKeys;
+  pRENDERDOC_GetOverlayBits GetOverlayBits;
+  pRENDERDOC_MaskOverlayBits MaskOverlayBits;
 
-	pRENDERDOC_GetOverlayBits             GetOverlayBits;
-	pRENDERDOC_MaskOverlayBits            MaskOverlayBits;
+  pRENDERDOC_Shutdown Shutdown;
+  pRENDERDOC_UnloadCrashHandler UnloadCrashHandler;
 
-	pRENDERDOC_Shutdown                   Shutdown;
-	pRENDERDOC_UnloadCrashHandler         UnloadCrashHandler;
+  pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate;
+  pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate;
 
-	pRENDERDOC_SetLogFilePathTemplate     SetLogFilePathTemplate;
-	pRENDERDOC_GetLogFilePathTemplate     GetLogFilePathTemplate;
+  pRENDERDOC_GetNumCaptures GetNumCaptures;
+  pRENDERDOC_GetCapture GetCapture;
 
-	pRENDERDOC_GetNumCaptures             GetNumCaptures;
-	pRENDERDOC_GetCapture                 GetCapture;
+  pRENDERDOC_TriggerCapture TriggerCapture;
 
-	pRENDERDOC_TriggerCapture             TriggerCapture;
+  pRENDERDOC_IsRemoteAccessConnected IsRemoteAccessConnected;
+  pRENDERDOC_LaunchReplayUI LaunchReplayUI;
 
-	pRENDERDOC_IsRemoteAccessConnected    IsRemoteAccessConnected;
-	pRENDERDOC_LaunchReplayUI             LaunchReplayUI;
+  pRENDERDOC_SetActiveWindow SetActiveWindow;
 
-	pRENDERDOC_SetActiveWindow            SetActiveWindow;
+  pRENDERDOC_StartFrameCapture StartFrameCapture;
+  pRENDERDOC_IsFrameCapturing IsFrameCapturing;
+  pRENDERDOC_EndFrameCapture EndFrameCapture;
 
-	pRENDERDOC_StartFrameCapture          StartFrameCapture;
-	pRENDERDOC_IsFrameCapturing           IsFrameCapturing;
-	pRENDERDOC_EndFrameCapture            EndFrameCapture;
-} RENDERDOC_API_1_0_1;
+  pRENDERDOC_TriggerMultiFrameCapture TriggerMultiFrameCapture;
+} RENDERDOC_API_1_1_0;
 
-typedef RENDERDOC_API_1_0_1 RENDERDOC_API_1_0_0;
+typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_0;
+typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_1;
+typedef RENDERDOC_API_1_1_0 RENDERDOC_API_1_0_2;
+
+// although this structure is identical to RENDERDOC_API_1_1_0, the member
+// IsRemoteAccessConnected was renamed to IsTargetControlConnected. So that
+// old code can still compile with a new header, we must declare a new struct
+// type. It can be casted back and forth though, so we will still return a
+// pointer to this type for all previous API versions - the above struct is
+// purely legacy for compilation compatibility
+
+// eRENDERDOC_API_Version_1_1_1
+typedef struct
+{
+  pRENDERDOC_GetAPIVersion GetAPIVersion;
+
+  pRENDERDOC_SetCaptureOptionU32 SetCaptureOptionU32;
+  pRENDERDOC_SetCaptureOptionF32 SetCaptureOptionF32;
+
+  pRENDERDOC_GetCaptureOptionU32 GetCaptureOptionU32;
+  pRENDERDOC_GetCaptureOptionF32 GetCaptureOptionF32;
+
+  pRENDERDOC_SetFocusToggleKeys SetFocusToggleKeys;
+  pRENDERDOC_SetCaptureKeys SetCaptureKeys;
+
+  pRENDERDOC_GetOverlayBits GetOverlayBits;
+  pRENDERDOC_MaskOverlayBits MaskOverlayBits;
+
+  pRENDERDOC_Shutdown Shutdown;
+  pRENDERDOC_UnloadCrashHandler UnloadCrashHandler;
+
+  pRENDERDOC_SetLogFilePathTemplate SetLogFilePathTemplate;
+  pRENDERDOC_GetLogFilePathTemplate GetLogFilePathTemplate;
+
+  pRENDERDOC_GetNumCaptures GetNumCaptures;
+  pRENDERDOC_GetCapture GetCapture;
+
+  pRENDERDOC_TriggerCapture TriggerCapture;
+
+  pRENDERDOC_IsTargetControlConnected IsTargetControlConnected;
+  pRENDERDOC_LaunchReplayUI LaunchReplayUI;
+
+  pRENDERDOC_SetActiveWindow SetActiveWindow;
+
+  pRENDERDOC_StartFrameCapture StartFrameCapture;
+  pRENDERDOC_IsFrameCapturing IsFrameCapturing;
+  pRENDERDOC_EndFrameCapture EndFrameCapture;
+
+  pRENDERDOC_TriggerMultiFrameCapture TriggerMultiFrameCapture;
+} RENDERDOC_API_1_1_1;
 
 //////////////////////////////////////////////////////////////////////////////////////////////////
 // RenderDoc API entry point
-// 
+//
 // This entry point can be obtained via GetProcAddress/dlsym if RenderDoc is available.
-// 
+//
 // The name is the same as the typedef - "RENDERDOC_GetAPI"
 //
 // This function is not thread safe, and should not be called on multiple threads at once.
@@ -531,8 +610,8 @@ typedef RENDERDOC_API_1_0_1 RENDERDOC_API_1_0_0;
 //   1 - if the outAPIPointers has been filled with a pointer to the API struct requested
 //   0 - if the requested version is not supported or the arguments are invalid.
 //
-typedef int (RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers);
+typedef int(RENDERDOC_CC *pRENDERDOC_GetAPI)(RENDERDOC_Version version, void **outAPIPointers);
 
 #ifdef __cplusplus
-}  // extern "C"
+}    // extern "C"
 #endif

+ 44 - 40
third/bgfx/3rdparty/stb/stb_textedit.h

@@ -1,9 +1,10 @@
-// [ImGui] this is a slightly modified version of stb_truetype.h 1.8
+// [ImGui] this is a slightly modified version of stb_truetype.h 1.9. Those changes would need to be pushed into nothings/sb
+// [ImGui] - fixed linestart handler when over last character of multi-line buffer + simplified existing code (#588, #815)
+// [ImGui] - fixed a state corruption/crash bug in stb_text_redo and stb_textedit_discard_redo (#715)
 // [ImGui] - fixed a crash bug in stb_textedit_discard_redo (#681)
 // [ImGui] - fixed some minor warnings
-// [ImGui] - added STB_TEXTEDIT_MOVEWORDLEFT/STB_TEXTEDIT_MOVEWORDRIGHT custom handler (#473)
 
-// stb_textedit.h - v1.8  - public domain - Sean Barrett
+// stb_textedit.h - v1.9  - public domain - Sean Barrett
 // Development of this library was sponsored by RAD Game Tools
 //
 // This C header file implements the guts of a multi-line text-editing
@@ -36,6 +37,7 @@
 //
 // VERSION HISTORY
 //
+//   1.9  (2016-08-27) customizable move-by-word
 //   1.8  (2016-04-02) better keyboard handling when mouse button is down
 //   1.7  (2015-09-13) change y range handling in case baseline is non-0
 //   1.6  (2015-04-15) allow STB_TEXTEDIT_memmove
@@ -424,10 +426,9 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
    // check if it's before the end of the line
    if (x < r.x1) {
       // search characters in row for one that straddles 'x'
-      k = i;
       prev_x = r.x0;
-      for (i=0; i < r.num_chars; ++i) {
-         float w = STB_TEXTEDIT_GETWIDTH(str, k, i);
+      for (k=0; k < r.num_chars; ++k) {
+         float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
          if (x < prev_x+w) {
             if (x < prev_x+w/2)
                return k+i;
@@ -617,15 +618,16 @@ static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditStat
 }
 
 #ifdef STB_TEXTEDIT_IS_SPACE
-static int is_word_boundary( STB_TEXTEDIT_STRING *_str, int _idx )
+static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx )
 {
-   return _idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str,_idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(_str, _idx) ) ) : 1;
+   return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1;
 }
 
 #ifndef STB_TEXTEDIT_MOVEWORDLEFT
-static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c )
+static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c )
 {
-   while( c >= 0 && !is_word_boundary( _str, c ) )
+   --c; // always move at least one character
+   while( c >= 0 && !is_word_boundary( str, c ) )
       --c;
 
    if( c < 0 )
@@ -637,10 +639,11 @@ static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *_str, int c
 #endif
 
 #ifndef STB_TEXTEDIT_MOVEWORDRIGHT
-static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *_str, int c )
+static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c )
 {
-   const int len = STB_TEXTEDIT_STRINGLEN(_str);
-   while( c < len && !is_word_boundary( _str, c ) )
+   const int len = STB_TEXTEDIT_STRINGLEN(str);
+   ++c; // always move at least one character
+   while( c < len && !is_word_boundary( str, c ) )
       ++c;
 
    if( c > len )
@@ -777,7 +780,7 @@ retry:
          if (STB_TEXT_HAS_SELECTION(state))
             stb_textedit_move_to_first(state);
          else {
-            state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
+            state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
             stb_textedit_clamp( str, state );
          }
          break;
@@ -786,7 +789,7 @@ retry:
          if( !STB_TEXT_HAS_SELECTION( state ) )
             stb_textedit_prep_selection_at_cursor(state);
 
-         state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor-1);
+         state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor);
          state->select_end = state->cursor;
 
          stb_textedit_clamp( str, state );
@@ -798,7 +801,7 @@ retry:
          if (STB_TEXT_HAS_SELECTION(state)) 
             stb_textedit_move_to_last(str, state);
          else {
-            state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
+            state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
             stb_textedit_clamp( str, state );
          }
          break;
@@ -807,7 +810,7 @@ retry:
          if( !STB_TEXT_HAS_SELECTION( state ) )
             stb_textedit_prep_selection_at_cursor(state);
 
-         state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor+1);
+         state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor);
          state->select_end = state->cursor;
 
          stb_textedit_clamp( str, state );
@@ -990,58 +993,58 @@ retry:
 #ifdef STB_TEXTEDIT_K_LINESTART2
       case STB_TEXTEDIT_K_LINESTART2:
 #endif
-      case STB_TEXTEDIT_K_LINESTART: {
-         StbFindState find;
+      case STB_TEXTEDIT_K_LINESTART:
          stb_textedit_clamp(str, state);
          stb_textedit_move_to_first(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->cursor = find.first_char;
+         if (state->single_line)
+            state->cursor = 0;
+         else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
+            --state->cursor;
          state->has_preferred_x = 0;
          break;
-      }
 
 #ifdef STB_TEXTEDIT_K_LINEEND2
       case STB_TEXTEDIT_K_LINEEND2:
 #endif
       case STB_TEXTEDIT_K_LINEEND: {
-         StbFindState find;
+         int n = STB_TEXTEDIT_STRINGLEN(str);
          stb_textedit_clamp(str, state);
          stb_textedit_move_to_first(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-
+         if (state->single_line)
+             state->cursor = n;
+         else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
+             ++state->cursor;
          state->has_preferred_x = 0;
-         state->cursor = find.first_char + find.length;
-         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
-            --state->cursor;
          break;
       }
 
 #ifdef STB_TEXTEDIT_K_LINESTART2
       case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
 #endif
-      case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
-         StbFindState find;
+      case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT:
          stb_textedit_clamp(str, state);
          stb_textedit_prep_selection_at_cursor(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->cursor = state->select_end = find.first_char;
+         if (state->single_line)
+            state->cursor = 0;
+         else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
+            --state->cursor;
+         state->select_end = state->cursor;
          state->has_preferred_x = 0;
          break;
-      }
 
 #ifdef STB_TEXTEDIT_K_LINEEND2
       case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
 #endif
       case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
-         StbFindState find;
+         int n = STB_TEXTEDIT_STRINGLEN(str);
          stb_textedit_clamp(str, state);
          stb_textedit_prep_selection_at_cursor(state);
-         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
-         state->has_preferred_x = 0;
-         state->cursor = find.first_char + find.length;
-         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
-            --state->cursor;
+         if (state->single_line)
+             state->cursor = n;
+         else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
+            ++state->cursor;
          state->select_end = state->cursor;
+         state->has_preferred_x = 0;
          break;
       }
 
@@ -1101,8 +1104,8 @@ static void stb_textedit_discard_redo(StbUndoState *state)
             if (state->undo_rec[i].char_storage >= 0)
                state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
       }
+      STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point-1, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
       ++state->redo_point;
-      STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
    }
 }
 
@@ -1260,6 +1263,7 @@ static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state)
    if (r.insert_length) {
       // easy case: need to insert n characters
       STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
+      s->redo_char_point += r.insert_length;
    }
 
    state->cursor = r.where + r.insert_length;

+ 19 - 2
third/bgfx/README.md

@@ -58,7 +58,9 @@ Languages:
  * [Go language API bindings](https://github.com/james4k/go-bgfx)
  * [Haskell language API bindings](https://github.com/haskell-game/bgfx)
  * [Java language API bindings](https://github.com/enleeten/twilight-bgfx)
+ * [Lightweight Java Game Library 3 bindings](https://github.com/LWJGL/lwjgl3)
  * [Lua language API bindings](https://github.com/excessive/lua-bgfx)
+ * [Nim language API bindings](https://github.com/Halsys/nim-bgfx)
  * [Python language API bindings](https://github.com/jnadro/pybgfx#pybgf)
  * [Rust language API bindings](https://github.com/rhoot/bgfx-rs)
  * [Swift language API bindings](https://github.com/stuartcarnie/SwiftBGFX)
@@ -139,7 +141,6 @@ https://github.com/mamedev/mame MAME - Multiple Arcade Machine Emulator
 https://blackshift.itch.io/blackshift - Blackshift is a grid-based, space-themed
 action puzzle game which isn't afraid of complexity — think Chip's Challenge on
 crack. 
-https://www.youtube.com/watch?v=PUl8612Y-ds
 <a href="http://www.youtube.com/watch?feature=player_embedded&v=PUl8612Y-ds
 " target="_blank"><img src="http://img.youtube.com/vi/PUl8612Y-ds/0.jpg" 
 alt="Blackshift Trailer, May 2016"
@@ -150,7 +151,23 @@ with Linearly Transformed Cosines, Eric Heitz, Jonathan Dupuy, Stephen Hill and
 David Neubelt, ACM SIGGRAPH 2016
 <a href="http://www.youtube.com/watch?feature=player_embedded&v=ZLRgEN7AQgM
 " target="_blank"><img src="http://img.youtube.com/vi/ZLRgEN7AQgM/0.jpg" 
-alt="Real-Time Polygonal-Light Shading with Linearly Transformed Cosines "
+alt="Real-Time Polygonal-Light Shading with Linearly Transformed Cosines"
+width="640" height="480" border="0" /></a>
+
+http://www.dogbytegames.com/dead_venture.html - Dead Venture is a new Drive 'N
+Gun game where you help a handful of survivals reach the safe haven: a military
+base on a far island.
+<a href="http://www.youtube.com/watch?feature=player_embedded&v=CgMr1g12yXw
+" target="_blank"><img src="http://img.youtube.com/vi/CgMr1g12yXw/0.jpg" 
+alt="Dead Venture - Gameplay Teaser (iOS / Android)"
+width="640" height="480" border="0" /></a>
+
+https://github.com/degenerated1123/REGoth - Open source reimplementation of the
+zEngine, used by the game "Gothic" and "Gothic II".
+
+<a href="http://www.youtube.com/watch?feature=player_embedded&v=8bLAGttYYpY
+" target="_blank"><img src="http://img.youtube.com/vi/8bLAGttYYpY/0.jpg" 
+alt="REGoth Engine"
 width="640" height="480" border="0" /></a>
 
 [License (BSD 2-clause)](https://bkaradzic.github.io/bgfx/license.html)

+ 182 - 39
third/bgfx/include/bgfx/bgfx.h

@@ -33,7 +33,6 @@ namespace bgfx
 		enum Enum
 		{
 			DebugCheck,
-			MinimumRequiredSpecs,
 			InvalidShader,
 			UnableToInitialize,
 			UnableToCreateTexture,
@@ -52,10 +51,11 @@ namespace bgfx
 		/// Renderer types:
 		enum Enum
 		{
-			Null,         //!< No rendering.
+			Noop,         //!< No rendering.
 			Direct3D9,    //!< Direct3D 9.0
 			Direct3D11,   //!< Direct3D 11.0
 			Direct3D12,   //!< Direct3D 12.0
+			Gnm,          //!< GNM
 			Metal,        //!< Metal
 			OpenGLES,     //!< OpenGL ES 2.0+
 			OpenGL,       //!< OpenGL 2.1+
@@ -285,6 +285,7 @@ namespace bgfx
 	///
 	struct OcclusionQueryResult
 	{
+		/// Occlusion query results:
 		enum Enum
 		{
 			Invisible, //!< Query failed test.
@@ -301,6 +302,7 @@ namespace bgfx
 	///
 	struct TopologyConvert
 	{
+		/// Topology conversion functions:
 		enum Enum
 		{
 			TriListFlipWinding,  //!< Flip winding order of triangle list.
@@ -312,6 +314,32 @@ namespace bgfx
 		};
 	};
 
+	/// Topology sort order.
+	///
+	/// @attention C99 equivalent is `bgfx_topology_sort_t`.
+	///
+	struct TopologySort
+	{
+		/// Topology sort order:
+		enum Enum
+		{
+			DirectionFrontToBackMin, //!<
+			DirectionFrontToBackAvg, //!<
+			DirectionFrontToBackMax, //!<
+			DirectionBackToFrontMin, //!<
+			DirectionBackToFrontAvg, //!<
+			DirectionBackToFrontMax, //!<
+			DistanceFrontToBackMin,  //!<
+			DistanceFrontToBackAvg,  //!<
+			DistanceFrontToBackMax,  //!<
+			DistanceBackToFrontMin,  //!<
+			DistanceBackToFrontAvg,  //!<
+			DistanceBackToFrontMax,  //!<
+
+			Count
+		};
+	};
+
 	static const uint16_t invalidHandle = UINT16_MAX;
 
 	BGFX_HANDLE(DynamicIndexBufferHandle);
@@ -492,15 +520,11 @@ namespace bgfx
 		///
 		uint64_t supported;
 
-		uint32_t maxDrawCalls;     //!< Maximum draw calls.
-		uint16_t maxTextureSize;   //!< Maximum texture size.
-		uint16_t maxViews;         //!< Maximum views.
-		uint8_t  maxFBAttachments; //!< Maximum frame buffer attachments.
-		uint8_t  numGPUs;          //!< Number of enumerated GPUs.
-		uint16_t vendorId;         //!< Selected GPU vendor id.
+		uint16_t vendorId;         //!< Selected GPU vendor PCI id.
 		uint16_t deviceId;         //!< Selected GPU device id.
 		bool     homogeneousDepth; //!< True when NDC depth is in [-1, 1] range.
 		bool     originBottomLeft; //!< True when NDC origin is at bottom left.
+		uint8_t  numGPUs;          //!< Number of enumerated GPUs.
 
 		/// GPU info.
 		///
@@ -508,17 +532,55 @@ namespace bgfx
 		///
 		struct GPU
 		{
-			uint16_t vendorId;
-			uint16_t deviceId;
+			uint16_t vendorId; //!< Vendor PCI id. See `BGFX_PCI_ID_*`.
+			uint16_t deviceId; //!< Device id.
 		};
 
 		GPU gpu[4]; //!< Enumerated GPUs.
 
+		struct Limits
+		{
+			uint32_t maxDrawCalls;            //!< Maximum draw calls.
+			uint32_t maxBlits;                //!< Maximum number of blit calls.
+			uint32_t maxTextureSize;          //!< Maximum texture size.
+			uint32_t maxViews;                //!< Maximum views.
+			uint32_t maxFrameBuffers;         //!< Maximum number of frame buffer handles.
+			uint32_t maxFBAttachments;        //!< Maximum frame buffer attachments.
+			uint32_t maxPrograms;             //!< Maximum number of program handles.
+			uint32_t maxShaders;              //!< Maximum number of shader handles.
+			uint32_t maxTextures;             //!< Maximum number of texture handles.
+			uint32_t maxTextureSamplers;      //!< Maximum number of texture samplers.
+			uint32_t maxVertexDecls;          //!< Maximum number of vertex format declarations.
+			uint32_t maxVertexStreams;        //!< Maximum number of vertex streams.
+			uint32_t maxIndexBuffers;         //!< Maximum number of index buffer handles.
+			uint32_t maxVertexBuffers;        //!< Maximum number of vertex buffer handles.
+			uint32_t maxDynamicIndexBuffers;  //!< Maximum number of dynamic index buffer handles.
+			uint32_t maxDynamicVertexBuffers; //!< Maximum number of dynamic vertex buffer handles.
+			uint32_t maxUniforms;             //!< Maximum number of uniform handles.
+			uint32_t maxOcclusionQueries;     //!< Maximum number of occlusion query handles.
+		};
+
+		Limits limits;
+
 		/// Supported texture formats.
-		///   - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - not supported
-		///   - `BGFX_CAPS_FORMAT_TEXTURE_2D` - supported
-		///   - `BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED` - emulated
-		///   - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - supported vertex texture
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_NONE` - Texture format is not supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_2D` - Texture format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_2D_SRGB` - Texture as sRGB format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_2D_EMULATED` - Texture format is emulated.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_3D` - Texture format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_3D_SRGB` - Texture as sRGB format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_3D_EMULATED` - Texture format is emulated.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_CUBE` - Texture format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_SRGB` - Texture as sRGB format is supported.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_CUBE_EMULATED` - Texture format is emulated.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_VERTEX` - Texture format can be used from vertex shader.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_IMAGE` - Texture format can be used as image from compute
+		///     shader.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER` - Texture format can be used as frame
+		///     buffer.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA` - Texture format can be used as MSAA
+		///     frame buffer.
+		///   - `BGFX_CAPS_FORMAT_TEXTURE_MSAA` - Texture can be sampled as MSAA.
 		uint16_t formats[TextureFormat::Count];
 	};
 
@@ -573,6 +635,7 @@ namespace bgfx
 		uint16_t width;             //!< Texture width.
 		uint16_t height;            //!< Texture height.
 		uint16_t depth;             //!< Texture depth.
+		uint16_t numLayers;         //!< Number of layers in texture array.
 		uint8_t numMips;            //!< Number of MIP maps.
 		uint8_t bitsPerPixel;       //!< Format bits per pixel.
 		bool    cubeMap;            //!< Texture is cubemap.
@@ -641,8 +704,9 @@ namespace bgfx
 		uint64_t gpuTimeEnd;   //!< GPU frame end time.
 		uint64_t gpuTimerFreq; //!< GPU timer frequency.
 
-		int64_t waitRender;    //!< Render wait time.
-		int64_t waitSubmit;    //!< Submit wait time.
+		int64_t waitRender;    //!< Time spent waiting for render backend thread to finish issuing
+		                       //!  draw commands to underlying graphics API.
+		int64_t waitSubmit;    //!< Time spent waiting for submit thread to advance to next frame.
 	};
 
 	/// Vertex declaration.
@@ -657,11 +721,11 @@ namespace bgfx
 		///
 		/// @attention C99 equivalent is `bgfx_vertex_decl_begin`.
 		///
-		VertexDecl& begin(RendererType::Enum _renderer = RendererType::Null);
+		VertexDecl& begin(RendererType::Enum _renderer = RendererType::Noop);
 
 		/// End VertexDecl.
 		///
-		/// @attention C99 equivalent is `bgfx_vertex_decl_begin`.
+		/// @attention C99 equivalent is `bgfx_vertex_decl_end`.
 		///
 		void end();
 
@@ -815,6 +879,38 @@ namespace bgfx
 		, bool _index32
 		);
 
+	/// Sort indices.
+	///
+	/// @param[in] _sort Sort order, see `TopologySort::Enum`.
+	/// @param[in] _dst Destination index buffer.
+	/// @param[in] _dstSize Destination index buffer in bytes. It must be
+	///    large enough to contain output indices. If destination size is
+	///    insufficient index buffer will be truncated.
+	/// @param[in] _dir Direction (vector must be normalized).
+	/// @param[in] _pos Position.
+	/// @param[in] _vertices Pointer to first vertex represented as
+	///    float x, y, z. Must contain at least number of vertices
+	///    referencende by index buffer.
+	/// @param[in] _stride Vertex stride.
+	/// @param[in] _indices Source indices.
+	/// @param[in] _numIndices Number of input indices.
+	/// @param[in] _index32 Set to `true` if input indices are 32-bit.
+	///
+	/// @attention C99 equivalent is `bgfx_topology_sort_tri_list`.
+	///
+	void topologySortTriList(
+		  TopologySort::Enum _sort
+		, void* _dst
+		, uint32_t _dstSize
+		, const float _dir[3]
+		, const float _pos[3]
+		, const void* _vertices
+		, uint32_t _stride
+		, const void* _indices
+		, uint32_t _numIndices
+		, bool _index32
+		);
+
 	/// Swizzle RGBA8 image to BGRA8.
 	///
 	/// @param[in] _width Width of input image (pixels).
@@ -855,9 +951,14 @@ namespace bgfx
 
 	/// Returns supported backend API renderers.
 	///
+	/// @param[in] _max Maximum number of elements in _enum array.
+	/// @param[inout] _enum Array where supported renderers will be written.
+	///
+	/// @returns Number of supported renderers.
+	///
 	/// @attention C99 equivalent is `bgfx_get_supported_renderers`.
 	///
-	uint8_t getSupportedRenderers(RendererType::Enum _enum[RendererType::Count]);
+	uint8_t getSupportedRenderers(uint8_t _max = 0, RendererType::Enum* _enum = NULL);
 
 	/// Returns name of renderer.
 	///
@@ -885,7 +986,7 @@ namespace bgfx
 	/// @param[in] _callback Provide application specific callback interface.
 	///   See: `bgfx::CallbackI`
 	///
-	/// @param[in] _reallocator Custom allocator. When custom allocator is not
+	/// @param[in] _allocator Custom allocator. When custom allocator is not
 	///   specified, library uses default CRT allocator. The library assumes
 	///   custom allocator is thread safe.
 	///
@@ -898,7 +999,7 @@ namespace bgfx
 		, uint16_t _vendorId = BGFX_PCI_ID_NONE
 		, uint16_t _deviceId = 0
 		, CallbackI* _callback = NULL
-		, bx::AllocatorI* _reallocator = NULL
+		, bx::AllocatorI* _allocator = NULL
 		);
 
 	/// Shutdown bgfx library.
@@ -1027,20 +1128,35 @@ namespace bgfx
 	///
 	void dbgTextClear(uint8_t _attr = 0, bool _small = false);
 
-	/// Print into internal debug text buffer.
+	/// Print into internal debug text character-buffer (VGA-compatible text mode).
+	///
+	/// @param[in] _x, _y 2D position from top-left.
+	/// @param[in] _attr Color palette. Where top 4-bits represent index of background, and bottom
+	///   4-bits represent foreground color from standard VGA text palette.
+	/// @param[in] _format `printf` style format.
 	///
 	/// @attention C99 equivalent is `bgfx_dbg_text_printf`.
 	///
 	void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...);
 
+	/// Print into internal debug text character-buffer (VGA-compatible text mode).
+	///
+	/// @param[in] _x, _y 2D position from top-left.
+	/// @param[in] _attr Color palette. Where top 4-bits represent index of background, and bottom
+	///   4-bits represent foreground color from standard VGA text palette.
+	/// @param[in] _format `printf` style format.
+	/// @param[in] _argList additional arguments for format string
+	///
+	/// @attention C99 equivalent is `bgfx_dbg_text_vprintf`.
+	///
+	void dbgTextPrintfVargs(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList);
+
 	/// Draw image into internal debug text buffer.
 	///
-	/// @param[in] _x      X position from top-left.
-	/// @param[in] _y      Y position from top-left.
-	/// @param[in] _width  Image width.
-	/// @param[in] _height Image height.
-	/// @param[in] _data   Raw image data (character/attribute raw encoding).
-	/// @param[in] _pitch  Image pitch in bytes.
+	/// @param[in] _x, _y 2D position from top-left.
+	/// @param[in] _width, _height  Image width and height.
+	/// @param[in] _data  Raw image data (character/attribute raw encoding).
+	/// @param[in] _pitch Image pitch in bytes.
 	///
 	/// @attention C99 equivalent is `bgfx_dbg_text_image`.
 	///
@@ -1435,6 +1551,15 @@ namespace bgfx
 
 	/// Calculate amount of memory required for texture.
 	///
+	/// @param[out] _info Resulting texture info structure.
+	/// @param[in] _width Width.
+	/// @param[in] _height Height.
+	/// @param[in] _depth Depth.
+	/// @param[in] _cubeMap Indicates that texture contains cubemap.
+	/// @param[in] _hasMips Indicates that texture contains full mip-map chain.
+	/// @param[in] _numLayers Number of layers in texture array.
+	/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
+	///
 	/// @attention C99 equivalent is `bgfx_calc_texture_size`.
 	///
 	void calcTextureSize(
@@ -1443,7 +1568,8 @@ namespace bgfx
 		, uint16_t _height
 		, uint16_t _depth
 		, bool _cubeMap
-		, uint8_t _numMips
+		, bool _hasMips
+		, uint16_t _numLayers
 		, TextureFormat::Enum _format
 		);
 
@@ -1474,7 +1600,9 @@ namespace bgfx
 	///
 	/// @param[in] _width Width.
 	/// @param[in] _height Height.
-	/// @param[in] _numMips Number of mip-maps.
+	/// @param[in] _hasMips Indicates that texture contains full mip-map chain.
+	/// @param[in] _numLayers Number of layers in texture array. Must be 1 if caps
+	///   `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set.
 	/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
 	/// @param[in] _flags Default texture sampling mode is linear, and wrap mode
 	///   is repeat.
@@ -1484,13 +1612,16 @@ namespace bgfx
 	///     sampling.
 	///
 	/// @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable.
+	///   When `_numLayers` is more than 1, expected memory layout is texture and all mips together
+	///   for each array element.
 	///
 	/// @attention C99 equivalent is `bgfx_create_texture_2d`.
 	///
 	TextureHandle createTexture2D(
 		  uint16_t _width
 		, uint16_t _height
-		, uint8_t _numMips
+		, bool     _hasMips
+		, uint16_t _numLayers
 		, TextureFormat::Enum _format
 		, uint32_t _flags = BGFX_TEXTURE_NONE
 		, const Memory* _mem = NULL
@@ -1501,7 +1632,9 @@ namespace bgfx
 	///
 	/// @param[in] _ratio Frame buffer size in respect to back-buffer size. See:
 	///   `BackbufferRatio::Enum`.
-	/// @param[in] _numMips Number of mip-maps.
+	/// @param[in] _hasMips Indicates that texture contains full mip-map chain.
+	/// @param[in] _numLayers Number of layers in texture array. Must be 1 if caps
+	///   `BGFX_CAPS_TEXTURE_2D_ARRAY` flag is not set.
 	/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
 	/// @param[in] _flags Default texture sampling mode is linear, and wrap mode
 	///   is repeat.
@@ -1514,7 +1647,8 @@ namespace bgfx
 	///
 	TextureHandle createTexture2D(
 		  BackbufferRatio::Enum _ratio
-		, uint8_t _numMips
+		, bool _hasMips
+		, uint16_t _numLayers
 		, TextureFormat::Enum _format
 		, uint32_t _flags = BGFX_TEXTURE_NONE
 		);
@@ -1524,7 +1658,7 @@ namespace bgfx
 	/// @param[in] _width Width.
 	/// @param[in] _height Height.
 	/// @param[in] _depth Depth.
-	/// @param[in] _numMips Number of mip-maps.
+	/// @param[in] _hasMips Indicates that texture contains full mip-map chain.
 	/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
 	/// @param[in] _flags Default texture sampling mode is linear, and wrap mode
 	///   is repeat.
@@ -1541,7 +1675,7 @@ namespace bgfx
 		  uint16_t _width
 		, uint16_t _height
 		, uint16_t _depth
-		, uint8_t _numMips
+		, bool _hasMips
 		, TextureFormat::Enum _format
 		, uint32_t _flags = BGFX_TEXTURE_NONE
 		, const Memory* _mem = NULL
@@ -1550,7 +1684,9 @@ namespace bgfx
 	/// Create Cube texture.
 	///
 	/// @param[in] _size Cube side size.
-	/// @param[in] _numMips Number of mip-maps.
+	/// @param[in] _hasMips Indicates that texture contains full mip-map chain.
+	/// @param[in] _numLayers Number of layers in texture array. Must be 1 if caps
+	///   `BGFX_CAPS_TEXTURE_CUBE_ARRAY` flag is not set.
 	/// @param[in] _format Texture format. See: `TextureFormat::Enum`.
 	/// @param[in] _flags Default texture sampling mode is linear, and wrap mode
 	///   is repeat.
@@ -1560,12 +1696,15 @@ namespace bgfx
 	///     sampling.
 	///
 	/// @param[in] _mem Texture data. If `_mem` is non-NULL, created texture will be immutable.
+	///   When `_numLayers` is more than 1, expected memory layout is cubemap texture and all mips
+	///   together for each array element.
 	///
 	/// @attention C99 equivalent is `bgfx_create_texture_cube`.
 	///
 	TextureHandle createTextureCube(
 		  uint16_t _size
-		, uint8_t _numMips
+		, bool _hasMips
+		, uint16_t _numLayers
 		, TextureFormat::Enum _format
 		, uint32_t _flags = BGFX_TEXTURE_NONE
 		, const Memory* _mem = NULL
@@ -1574,6 +1713,7 @@ namespace bgfx
 	/// Update 2D texture.
 	///
 	/// @param[in] _handle Texture handle.
+	/// @param[in] _layer Layers in texture array.
 	/// @param[in] _mip Mip level.
 	/// @param[in] _x X offset in texture.
 	/// @param[in] _y Y offset in texture.
@@ -1587,6 +1727,7 @@ namespace bgfx
 	///
 	void updateTexture2D(
 		  TextureHandle _handle
+		, uint16_t _layer
 		, uint8_t _mip
 		, uint16_t _x
 		, uint16_t _y
@@ -1625,6 +1766,7 @@ namespace bgfx
 	/// Update Cube texture.
 	///
 	/// @param[in] _handle Texture handle.
+	/// @param[in] _layer Layers in texture array.
 	/// @param[in] _side Cubemap side `BGFX_CUBE_MAP_<POSITIVE or NEGATIVE>_<X, Y or Z>`,
 	///   where 0 is +X, 1 is -X, 2 is +Y, 3 is -Y, 4 is +Z, and 5 is -Z.
 	///
@@ -1658,6 +1800,7 @@ namespace bgfx
 	///
 	void updateTextureCube(
 		  TextureHandle _handle
+		, uint16_t _layer
 		, uint8_t _side
 		, uint8_t _mip
 		, uint16_t _x
@@ -1775,7 +1918,7 @@ namespace bgfx
 	///
 	/// @returns Handle to frame buffer object.
 	///
-	/// @attention C99 equivalent is `bgfx_create_frame_buffer_from_handles`.
+	/// @attention C99 equivalent is `bgfx_create_frame_buffer_from_attachment`.
 	///
 	FrameBufferHandle createFrameBuffer(
 		  uint8_t _num
@@ -2420,7 +2563,7 @@ namespace bgfx
 	///   call submit.
 	/// @returns Number of draw calls.
 	///
-	/// @attention C99 equivalent is `bgfx_submit_occlusion_query.
+	/// @attention C99 equivalent is `bgfx_submit_occlusion_query`.
 	///
 	uint32_t submit(
 		  uint8_t _id

+ 26 - 22
third/bgfx/include/bgfx/bgfxdefines.h

@@ -6,7 +6,7 @@
 #ifndef BGFX_DEFINES_H_HEADER_GUARD
 #define BGFX_DEFINES_H_HEADER_GUARD
 
-#define BGFX_API_VERSION UINT32_C(16)
+#define BGFX_API_VERSION UINT32_C(26)
 
 ///
 #define BGFX_STATE_RGB_WRITE               UINT64_C(0x0000000000000001) //!< Enable RGB write.
@@ -365,27 +365,30 @@
 #define BGFX_RESET_RESERVED_MASK         UINT32_C(0x80000000) //!< Internal bits mask.
 
 ///
-#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000000001) //!< Texture compare less equal mode is supported.
-#define BGFX_CAPS_TEXTURE_COMPARE_ALL    UINT64_C(0x0000000000000003) //!< All texture compare modes are supported.
-#define BGFX_CAPS_TEXTURE_3D             UINT64_C(0x0000000000000004) //!< 3D textures are supported.
-#define BGFX_CAPS_VERTEX_ATTRIB_HALF     UINT64_C(0x0000000000000008) //!< Vertex attribute half-float is supported.
-#define BGFX_CAPS_VERTEX_ATTRIB_UINT10   UINT64_C(0x0000000000000010) //!< Vertex attribute 10_10_10_2 is supported.
-#define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000000000020) //!< Instancing is supported.
-#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000000040) //!< Renderer is on separate thread.
-#define BGFX_CAPS_FRAGMENT_DEPTH         UINT64_C(0x0000000000000080) //!< Fragment depth is accessible in fragment shader.
-#define BGFX_CAPS_BLEND_INDEPENDENT      UINT64_C(0x0000000000000100) //!< Blend independent is supported.
-#define BGFX_CAPS_COMPUTE                UINT64_C(0x0000000000000200) //!< Compute shaders are supported.
-#define BGFX_CAPS_FRAGMENT_ORDERING      UINT64_C(0x0000000000000400) //!< Fragment ordering is available in fragment shader.
-#define BGFX_CAPS_SWAP_CHAIN             UINT64_C(0x0000000000000800) //!< Multiple windows are supported.
-#define BGFX_CAPS_HMD                    UINT64_C(0x0000000000001000) //!< Head Mounted Display is available.
-#define BGFX_CAPS_INDEX32                UINT64_C(0x0000000000002000) //!< 32-bit indices are supported.
-#define BGFX_CAPS_DRAW_INDIRECT          UINT64_C(0x0000000000004000) //!< Draw indirect is supported.
-#define BGFX_CAPS_HIDPI                  UINT64_C(0x0000000000008000) //!< HiDPI rendering is supported.
-#define BGFX_CAPS_TEXTURE_BLIT           UINT64_C(0x0000000000010000) //!< Texture blit is supported.
-#define BGFX_CAPS_TEXTURE_READ_BACK      UINT64_C(0x0000000000020000) //!< Read-back texture is supported.
-#define BGFX_CAPS_OCCLUSION_QUERY        UINT64_C(0x0000000000040000) //!< Occlusion query is supported.
-#define BGFX_CAPS_ALPHA_TO_COVERAGE      UINT64_C(0x0000000000080000) //!< Alpha to coverage is supported.
-#define BGFX_CAPS_CONSERVATIVE_RASTER    UINT64_C(0x0000000000100000) //!< Conservative rasterization is supported.
+#define BGFX_CAPS_ALPHA_TO_COVERAGE      UINT64_C(0x0000000000000001) //!< Alpha to coverage is supported.
+#define BGFX_CAPS_BLEND_INDEPENDENT      UINT64_C(0x0000000000000003) //!< Blend independent is supported.
+#define BGFX_CAPS_COMPUTE                UINT64_C(0x0000000000000004) //!< Compute shaders are supported.
+#define BGFX_CAPS_CONSERVATIVE_RASTER    UINT64_C(0x0000000000000008) //!< Conservative rasterization is supported.
+#define BGFX_CAPS_DRAW_INDIRECT          UINT64_C(0x0000000000000010) //!< Draw indirect is supported.
+#define BGFX_CAPS_FRAGMENT_DEPTH         UINT64_C(0x0000000000000020) //!< Fragment depth is accessible in fragment shader.
+#define BGFX_CAPS_FRAGMENT_ORDERING      UINT64_C(0x0000000000000040) //!< Fragment ordering is available in fragment shader.
+#define BGFX_CAPS_GRAPHICS_DEBUGGER      UINT64_C(0x0000000000000080) //!< Graphics debugger is present.
+#define BGFX_CAPS_HIDPI                  UINT64_C(0x0000000000000100) //!< HiDPI rendering is supported.
+#define BGFX_CAPS_HMD                    UINT64_C(0x0000000000000200) //!< Head Mounted Display is available.
+#define BGFX_CAPS_INDEX32                UINT64_C(0x0000000000000400) //!< 32-bit indices are supported.
+#define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000000000800) //!< Instancing is supported.
+#define BGFX_CAPS_OCCLUSION_QUERY        UINT64_C(0x0000000000001000) //!< Occlusion query is supported.
+#define BGFX_CAPS_RENDERER_MULTITHREADED UINT64_C(0x0000000000002000) //!< Renderer is on separate thread.
+#define BGFX_CAPS_SWAP_CHAIN             UINT64_C(0x0000000000004000) //!< Multiple windows are supported.
+#define BGFX_CAPS_TEXTURE_2D_ARRAY       UINT64_C(0x0000000000008000) //!< 2D texture array is supported.
+#define BGFX_CAPS_TEXTURE_3D             UINT64_C(0x0000000000010000) //!< 3D textures are supported.
+#define BGFX_CAPS_TEXTURE_BLIT           UINT64_C(0x0000000000020000) //!< Texture blit is supported.
+#define BGFX_CAPS_TEXTURE_COMPARE_ALL    UINT64_C(0x0000000000040000) //!< All texture compare modes are supported.
+#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000080000) //!< Texture compare less equal mode is supported.
+#define BGFX_CAPS_TEXTURE_CUBE_ARRAY     UINT64_C(0x0000000000100000) //!< Cubemap texture array is supported.
+#define BGFX_CAPS_TEXTURE_READ_BACK      UINT64_C(0x0000000000200000) //!< Read-back texture is supported.
+#define BGFX_CAPS_VERTEX_ATTRIB_HALF     UINT64_C(0x0000000000400000) //!< Vertex attribute half-float is supported.
+#define BGFX_CAPS_VERTEX_ATTRIB_UINT10   UINT64_C(0x0000000000800000) //!< Vertex attribute 10_10_10_2 is supported.
 
 ///
 #define BGFX_CAPS_FORMAT_TEXTURE_NONE             UINT16_C(0x0000) //!< Texture format is not supported.
@@ -403,6 +406,7 @@
 #define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER      UINT16_C(0x0800) //!< Texture format can be used as frame buffer.
 #define BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA UINT16_C(0x1000) //!< Texture format can be used as MSAA frame buffer.
 #define BGFX_CAPS_FORMAT_TEXTURE_MSAA             UINT16_C(0x2000) //!< Texture can be sampled as MSAA.
+#define BGFX_CAPS_FORMAT_TEXTURE_MIP_AUTOGEN      UINT16_C(0x4000) //!< Texture format supports auto-generated mips.
 
 ///
 #define BGFX_VIEW_NONE   UINT8_C(0x00) //!<

+ 2 - 193
third/bgfx/include/bgfx/bgfxplatform.h

@@ -51,6 +51,7 @@ namespace bgfx
 		void* context;      //!< GL context, or D3D device.
 		void* backBuffer;   //!< GL backbuffer, or D3D render target view.
 		void* backBufferDS; //!< Backbuffer depth/stencil.
+		void* session;      //!< ovrSession, for Oculus SDK
 	};
 
 	/// Set platform data.
@@ -129,61 +130,7 @@ namespace bgfx
 
 } // namespace bgfx
 
-#if BX_PLATFORM_ANDROID
-#	include <android/native_window.h>
-
-namespace bgfx
-{
-	///
-	inline void androidSetWindow(::ANativeWindow* _window)
-	{
-		PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#elif BX_PLATFORM_IOS
-namespace bgfx
-{
-	///
-	inline void iosSetEaglLayer(void* _window)
-	{
-		PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#elif BX_PLATFORM_BSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI
-
-namespace bgfx
-{
-	///
-	inline void x11SetDisplayWindow(void* _display, uint32_t _window, void* _glx = NULL)
-	{
-		PlatformData pd;
-		pd.ndt          = _display;
-		pd.nwh          = (void*)(uintptr_t)_window;
-		pd.context      = _glx;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#elif BX_PLATFORM_NACL
+#if BX_PLATFORM_NACL
 #	include <ppapi/c/ppb_graphics_3d.h>
 #	include <ppapi/c/ppb_instance.h>
 
@@ -196,144 +143,6 @@ namespace bgfx
 
 } // namespace bgfx
 
-#elif BX_PLATFORM_OSX
-namespace bgfx
-{
-	///
-	inline void osxSetNSWindow(void* _window, void* _nsgl = NULL)
-	{
-		PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = _nsgl;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#elif BX_PLATFORM_WINDOWS
-#	include <windows.h>
-
-namespace bgfx
-{
-	///
-	inline void winSetHwnd(::HWND _window)
-	{
-		PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#elif BX_PLATFORM_XBOXONE || BX_PLATFORM_WINRT
-#   include <Unknwn.h>
-
-namespace bgfx
-{
-	///
-	inline void winrtSetWindow(::IUnknown* _window)
-	{
-		PlatformData pd;
-		pd.ndt          = NULL;
-		pd.nwh          = _window;
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
 #endif // BX_PLATFORM_
 
-#if defined(_SDL_syswm_h)
-// If SDL_syswm.h is included before bgfxplatform.h we can enable SDL window
-// interop convenience code.
-
-namespace bgfx
-{
-	///
-	inline bool sdlSetWindow(SDL_Window* _window)
-	{
-		SDL_SysWMinfo wmi;
-		SDL_VERSION(&wmi.version);
-		if (!SDL_GetWindowWMInfo(_window, &wmi) )
-		{
-			return false;
-		}
-
-		PlatformData pd;
-#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-		pd.ndt          = wmi.info.x11.display;
-		pd.nwh          = (void*)(uintptr_t)wmi.info.x11.window;
-#	elif BX_PLATFORM_OSX
-		pd.ndt          = NULL;
-		pd.nwh          = wmi.info.cocoa.window;
-#	elif BX_PLATFORM_WINDOWS
-		pd.ndt          = NULL;
-		pd.nwh          = wmi.info.win.window;
-#	elif BX_PLATFORM_STEAMLINK
-		pd.ndt          = wmi.info.vivante.display;
-		pd.nwh          = wmi.info.vivante.window;
-#	endif // BX_PLATFORM_
-		pd.context      = NULL;
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-
-		return true;
-	}
-
-} // namespace bgfx
-
-#elif defined(_glfw3_h_)
-// If GLFW/glfw3.h is included before bgfxplatform.h we can enable GLFW3
-// window interop convenience code.
-
-#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-#		define GLFW_EXPOSE_NATIVE_X11
-#		define GLFW_EXPOSE_NATIVE_GLX
-#	elif BX_PLATFORM_OSX
-#		define GLFW_EXPOSE_NATIVE_COCOA
-#		define GLFW_EXPOSE_NATIVE_NSGL
-#	elif BX_PLATFORM_WINDOWS
-#		define GLFW_EXPOSE_NATIVE_WIN32
-#		define GLFW_EXPOSE_NATIVE_WGL
-#	endif //
-#	include <GLFW/glfw3native.h>
-
-namespace bgfx
-{
-	inline void glfwSetWindow(GLFWwindow* _window)
-	{
-		PlatformData pd;
-#	if BX_PLATFORM_LINUX || BX_PLATFORM_BSD
-		pd.ndt          = glfwGetX11Display();
-		pd.nwh          = (void*)(uintptr_t)glfwGetX11Window(_window);
-		pd.context      = glfwGetGLXContext(_window);
-#	elif BX_PLATFORM_OSX
-		pd.ndt          = NULL;
-		pd.nwh          = glfwGetCocoaWindow(_window);
-		pd.context      = glfwGetNSGLContext(_window);
-#	elif BX_PLATFORM_WINDOWS
-		pd.ndt          = NULL;
-		pd.nwh          = glfwGetWin32Window(_window);
-		pd.context      = NULL;
-#	endif // BX_PLATFORM_WINDOWS
-		pd.backBuffer   = NULL;
-		pd.backBufferDS = NULL;
-		setPlatformData(pd);
-	}
-
-} // namespace bgfx
-
-#endif // defined(_SDL_H)
-
 #endif // BGFX_PLATFORM_H_HEADER_GUARD

+ 69 - 17
third/bgfx/include/bgfx/c99/bgfx.h

@@ -43,10 +43,11 @@
 
 typedef enum bgfx_renderer_type
 {
-    BGFX_RENDERER_TYPE_NULL,
+    BGFX_RENDERER_TYPE_NOOP,
     BGFX_RENDERER_TYPE_DIRECT3D9,
     BGFX_RENDERER_TYPE_DIRECT3D11,
     BGFX_RENDERER_TYPE_DIRECT3D12,
+    BGFX_RENDERER_TYPE_GNM,
     BGFX_RENDERER_TYPE_METAL,
     BGFX_RENDERER_TYPE_OPENGLES,
     BGFX_RENDERER_TYPE_OPENGL,
@@ -235,6 +236,25 @@ typedef enum bgfx_topology_convert
 
 } bgfx_topology_convert_t;
 
+typedef enum bgfx_topology_sort
+{
+    BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_MIN,
+    BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_AVG,
+    BGFX_TOPOLOGY_SORT_DIRECTION_FRONT_TO_BACK_MAX,
+    BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_MIN,
+    BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_AVG,
+    BGFX_TOPOLOGY_SORT_DIRECTION_BACK_TO_FRONT_MAX,
+    BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_MIN,
+    BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_AVG,
+    BGFX_TOPOLOGY_SORT_DISTANCE_FRONT_TO_BACK_MAX,
+    BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_MIN,
+    BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_AVG,
+    BGFX_TOPOLOGY_SORT_DISTANCE_BACK_TO_FRONT_MAX,
+
+    BGFX_TOPOLOGY_SORT_COUNT
+
+} bgfx_topology_sort_t;
+
 #define BGFX_HANDLE_T(_name) \
     typedef struct _name { uint16_t idx; } _name##_t
 
@@ -363,6 +383,7 @@ typedef struct bgfx_texture_info
     uint16_t width;
     uint16_t height;
     uint16_t depth;
+    uint16_t numLayers;
     uint8_t numMips;
     uint8_t bitsPerPixel;
     bool    cubeMap;
@@ -386,6 +407,29 @@ typedef struct bgfx_caps_gpu
 
 } bgfx_caps_gpu_t;
 
+typedef struct bgfx_caps_limits
+{
+    uint32_t maxDrawCalls;
+    uint32_t maxBlits;
+    uint32_t maxTextureSize;
+    uint32_t maxViews;
+    uint32_t maxFrameBuffers;
+    uint32_t maxFBAttachments;
+    uint32_t maxPrograms;
+    uint32_t maxShaders;
+    uint32_t maxTextures;
+    uint32_t maxTextureSamplers;
+    uint32_t maxVertexDecls;
+    uint32_t maxVertexStreams;
+    uint32_t maxIndexBuffers;
+    uint32_t maxVertexBuffers;
+    uint32_t maxDynamicIndexBuffers;
+    uint32_t maxDynamicVertexBuffers;
+    uint32_t maxUniforms;
+    uint32_t maxOcclusionQueries;
+
+} bgfx_caps_limits_t;
+
 /**/
 typedef struct bgfx_caps
 {
@@ -393,17 +437,14 @@ typedef struct bgfx_caps
 
     uint64_t supported;
 
-    uint32_t maxDrawCalls;
-    uint16_t maxTextureSize;
-    uint16_t maxViews;
-    uint8_t  maxFBAttachments;
-    uint8_t  numGPUs;
+    uint16_t vendorId;
+    uint16_t deviceId;
     bool     homogeneousDepth;
     bool     originBottomLeft;
+    uint8_t  numGPUs;
 
-    uint16_t vendorId;
-    uint16_t deviceId;
     bgfx_caps_gpu_t gpu[4];
+    bgfx_caps_limits_t limits;
 
     uint16_t formats[BGFX_TEXTURE_FORMAT_COUNT];
 
@@ -413,7 +454,6 @@ typedef struct bgfx_caps
 typedef enum bgfx_fatal
 {
     BGFX_FATAL_DEBUG_CHECK,
-    BGFX_FATAL_MINIMUM_REQUIRED_SPECS,
     BGFX_FATAL_INVALID_SHADER,
     BGFX_FATAL_UNABLE_TO_INITIALIZE,
     BGFX_FATAL_UNABLE_TO_CREATE_TEXTURE,
@@ -483,6 +523,12 @@ BGFX_C_API void bgfx_vertex_convert(const bgfx_vertex_decl_t* _destDecl, void* _
 /**/
 BGFX_C_API uint16_t bgfx_weld_vertices(uint16_t* _output, const bgfx_vertex_decl_t* _decl, const void* _data, uint16_t _num, float _epsilon);
 
+/**/
+BGFX_C_API uint32_t bgfx_topology_convert(bgfx_topology_convert_t _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32);
+
+/**/
+BGFX_C_API void bgfx_topology_sort_tri_list(bgfx_topology_sort_t _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32);
+
 /**/
 BGFX_C_API void bgfx_image_swizzle_bgra8(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);
 
@@ -490,7 +536,7 @@ BGFX_C_API void bgfx_image_swizzle_bgra8(uint32_t _width, uint32_t _height, uint
 BGFX_C_API void bgfx_image_rgba8_downsample_2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);
 
 /**/
-BGFX_C_API uint8_t bgfx_get_supported_renderers(bgfx_renderer_type_t _enum[BGFX_RENDERER_TYPE_COUNT]);
+BGFX_C_API uint8_t bgfx_get_supported_renderers(uint8_t _max, bgfx_renderer_type_t* _enum);
 
 /**/
 BGFX_C_API const char* bgfx_get_renderer_name(bgfx_renderer_type_t _type);
@@ -540,6 +586,9 @@ BGFX_C_API void bgfx_dbg_text_clear(uint8_t _attr, bool _small);
 /**/
 BGFX_C_API void bgfx_dbg_text_printf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...);
 
+/**/
+BGFX_C_API void bgfx_dbg_text_vprintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList);
+
 /**/
 BGFX_C_API void bgfx_dbg_text_image(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch);
 
@@ -628,31 +677,31 @@ BGFX_C_API bgfx_program_handle_t bgfx_create_compute_program(bgfx_shader_handle_
 BGFX_C_API void bgfx_destroy_program(bgfx_program_handle_t _handle);
 
 /**/
-BGFX_C_API void bgfx_calc_texture_size(bgfx_texture_info_t* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips, bgfx_texture_format_t _format);
+BGFX_C_API void bgfx_calc_texture_size(bgfx_texture_info_t* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format);
 
 /**/
 BGFX_C_API bgfx_texture_handle_t bgfx_create_texture(const bgfx_memory_t* _mem, uint32_t _flags, uint8_t _skip, bgfx_texture_info_t* _info);
 
 /**/
-BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
 
 /**/
-BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d_scaled(bgfx_backbuffer_ratio_t _ratio, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags);
+BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_2d_scaled(bgfx_backbuffer_ratio_t _ratio, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags);
 
 /**/
-BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_3d(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
 
 /**/
-BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+BGFX_C_API bgfx_texture_handle_t bgfx_create_texture_cube(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
 
 /**/
-BGFX_C_API void bgfx_update_texture_2d(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
+BGFX_C_API void bgfx_update_texture_2d(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
 
 /**/
 BGFX_C_API void bgfx_update_texture_3d(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const bgfx_memory_t* _mem);
 
 /**/
-BGFX_C_API void bgfx_update_texture_cube(bgfx_texture_handle_t _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
+BGFX_C_API void bgfx_update_texture_cube(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
 
 /**/
 BGFX_C_API uint32_t bgfx_read_texture(bgfx_texture_handle_t _handle, void* _data);
@@ -669,6 +718,9 @@ BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer(uint16_t _width,
 /**/
 BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_scaled(bgfx_backbuffer_ratio_t _ratio, bgfx_texture_format_t _format, uint32_t _textureFlags);
 
+/**/
+BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_from_handles(uint8_t _num, const bgfx_texture_handle_t* _handles, bool _destroyTextures);
+
 /**/
 BGFX_C_API bgfx_frame_buffer_handle_t bgfx_create_frame_buffer_from_attachment(uint8_t _num, const bgfx_attachment_t* _attachment, bool _destroyTextures);
 

+ 11 - 8
third/bgfx/include/bgfx/c99/bgfxplatform.h

@@ -39,6 +39,7 @@ typedef struct bgfx_platform_data
     void* context;
     void* backBuffer;
     void* backBufferDS;
+    void* session;
 
 } bgfx_platform_data_t;
 
@@ -78,9 +79,10 @@ typedef struct bgfx_interface_vtbl
     void (*vertex_convert)(const bgfx_vertex_decl_t* _destDecl, void* _destData, const bgfx_vertex_decl_t* _srcDecl, const void* _srcData, uint32_t _num);
     uint16_t (*weld_vertices)(uint16_t* _output, const bgfx_vertex_decl_t* _decl, const void* _data, uint16_t _num, float _epsilon);
     uint32_t (*topology_convert)(bgfx_topology_convert_t _conversion, void* _dst, uint32_t _dstSize, const void* _indices, uint32_t _numIndices, bool _index32);
+    void (*topology_sort_tri_list)(bgfx_topology_sort_t _sort, void* _dst, uint32_t _dstSize, const float _dir[3], const float _pos[3], const void* _vertices, uint32_t _stride, const void* _indices, uint32_t _numIndices, bool _index32);
     void (*image_swizzle_bgra8)(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);
     void (*image_rgba8_downsample_2x2)(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst);
-    uint8_t (*get_supported_renderers)(bgfx_renderer_type_t _enum[BGFX_RENDERER_TYPE_COUNT]);
+    uint8_t (*get_supported_renderers)(uint8_t _max, bgfx_renderer_type_t* _enum);
     const char* (*get_renderer_name)(bgfx_renderer_type_t _type);
     bool (*init)(bgfx_renderer_type_t _type, uint16_t _vendorId, uint16_t _deviceId, bgfx_callback_interface_t* _callback, bgfx_allocator_interface_t* _allocator);
     void (*shutdown)();
@@ -97,6 +99,7 @@ typedef struct bgfx_interface_vtbl
     void (*set_debug)(uint32_t _debug);
     void (*dbg_text_clear)(uint8_t _attr, bool _small);
     void (*dbg_text_printf)(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...);
+    void (*dbg_text_vprintf)(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, va_list _argList);
     void (*dbg_text_image)(uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const void* _data, uint16_t _pitch);
     bgfx_index_buffer_handle_t (*create_index_buffer)(const bgfx_memory_t* _mem, uint16_t _flags);
     void (*destroy_index_buffer)(bgfx_index_buffer_handle_t _handle);
@@ -126,15 +129,15 @@ typedef struct bgfx_interface_vtbl
     bgfx_program_handle_t (*create_program)(bgfx_shader_handle_t _vsh, bgfx_shader_handle_t _fsh, bool _destroyShaders);
     bgfx_program_handle_t (*create_compute_program)(bgfx_shader_handle_t _csh, bool _destroyShaders);
     void (*destroy_program)(bgfx_program_handle_t _handle);
-    void (*calc_texture_size)(bgfx_texture_info_t* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, uint8_t _numMips, bgfx_texture_format_t _format);
+    void (*calc_texture_size)(bgfx_texture_info_t* _info, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format);
     bgfx_texture_handle_t (*create_texture)(const bgfx_memory_t* _mem, uint32_t _flags, uint8_t _skip, bgfx_texture_info_t* _info);
-    bgfx_texture_handle_t (*create_texture_2d)(uint16_t _width, uint16_t _height, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
-    bgfx_texture_handle_t (*create_texture_2d_scaled)(bgfx_backbuffer_ratio_t _ratio, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags);
-    bgfx_texture_handle_t (*create_texture_3d)(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
-    bgfx_texture_handle_t (*create_texture_cube)(uint16_t _size, uint8_t _numMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
-    void (*update_texture_2d)(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
+    bgfx_texture_handle_t (*create_texture_2d)(uint16_t _width, uint16_t _height, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+    bgfx_texture_handle_t (*create_texture_2d_scaled)(bgfx_backbuffer_ratio_t _ratio, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags);
+    bgfx_texture_handle_t (*create_texture_3d)(uint16_t _width, uint16_t _height, uint16_t _depth, bool _hasMips, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+    bgfx_texture_handle_t (*create_texture_cube)(uint16_t _size, bool _hasMips, uint16_t _numLayers, bgfx_texture_format_t _format, uint32_t _flags, const bgfx_memory_t* _mem);
+    void (*update_texture_2d)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
     void (*update_texture_3d)(bgfx_texture_handle_t _handle, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _z, uint16_t _width, uint16_t _height, uint16_t _depth, const bgfx_memory_t* _mem);
-    void (*update_texture_cube)(bgfx_texture_handle_t _handle, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
+    void (*update_texture_cube)(bgfx_texture_handle_t _handle, uint16_t _layer, uint8_t _side, uint8_t _mip, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height, const bgfx_memory_t* _mem, uint16_t _pitch);
     void (*destroy_texture)(bgfx_texture_handle_t _handle);
     bgfx_frame_buffer_handle_t (*create_frame_buffer)(uint16_t _width, uint16_t _height, bgfx_texture_format_t _format, uint32_t _textureFlags);
     bgfx_frame_buffer_handle_t (*create_frame_buffer_scaled)(bgfx_backbuffer_ratio_t _ratio, bgfx_texture_format_t _format, uint32_t _textureFlags);

Некоторые файлы не были показаны из-за большого количества измененных файлов