Merge pull request #731 from KhronosGroup/travis-windows

Add Windows support in Travis CI
diff --git a/.travis.yml b/.travis.yml
index becc7cb..a1f922b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,17 +1,52 @@
-language: cpp
-os:
-  - linux
-  - osx
-osx_image: xcode10
+language:
+  - cpp
+  - python
 
-# Use Ubuntu 14.04 LTS (Trusty) as the Linux testing environment.
-sudo: required
-dist: trusty
+python: 3.7
+
+matrix:
+  include:
+    - os: linux
+      dist: trusty
+      compiler: gcc
+      env:
+        - GENERATOR="Unix Makefiles"
+    - os: linux
+      dist: trusty
+      compiler: clang
+      env:
+        - GENERATOR="Unix Makefiles"
+    - os: osx
+      compiler: clang
+      osx_image: xcode10
+      env:
+        - GENERATOR="Unix Makefiles"
+    - os: windows
+      before_install:
+        - choco install python3
+        - choco install python2
+        - export PATH="/c/Python27:/c/Python27/Scripts:$PATH"
+        - export PATH="/c/Python37:/c/Python37/Scripts:$PATH"
+      env:
+        - GENERATOR="Visual Studio 15 2017"
+    - os: windows
+      before_install:
+        - choco install python3
+        - choco install python2
+        - export PATH="/c/Python27:/c/Python27/Scripts:$PATH"
+        - export PATH="/c/Python37:/c/Python37/Scripts:$PATH"
+      env:
+        - GENERATOR="Visual Studio 15 2017 Win64"
 
 before_script:
   - ./checkout_glslang_spirv_tools.sh
 
 script:
-  - ./build_glslang_spirv_tools.sh Debug 2
-  - make -j2
-  - ./test_shaders.sh
+  - if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then PYTHON3=$(which python); fi
+  - if [[ "$TRAVIS_OS_NAME" != "windows" ]]; then PYTHON3=$(which python3); fi
+  - ./build_glslang_spirv_tools.sh Release
+  - mkdir build
+  - cd build
+  - cmake .. -DCMAKE_BUILD_TYPE=Debug -G "${GENERATOR}" -DPYTHON_EXECUTABLE:FILEPATH="${PYTHON3}"
+  - cmake --build .
+  - PATH="../external/glslang-build/output/bin:../external/spirv-tools-build/output/bin:$PATH" ctest --verbose -C Debug
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c80ae36..e00f8c7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -134,32 +134,45 @@
 if (${PYTHONINTERP_FOUND})
   if (${PYTHON_VERSION_MAJOR} GREATER 2)
 	add_test(NAME spirv-cross-test
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-no-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-no-opt)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-no-opt
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-metal
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-metal-no-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl-no-opt)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl-no-opt
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-hlsl
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-hlsl-no-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl-no-opt)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl-no-opt
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --opt
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --opt --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-metal-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --opt
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --metal --opt --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-msl
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
 	add_test(NAME spirv-cross-test-hlsl-opt
-		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --opt
-			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl)
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --hlsl --opt --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-hlsl
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
+	add_test(NAME spirv-cross-test-reflection
+		COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_shaders.py --reflect --parallel
+			${CMAKE_CURRENT_SOURCE_DIR}/shaders-reflection
+		WORKING_DIRECTORY $<TARGET_FILE_DIR:spirv-cross>)
   endif()
 else()
   message(WARNING "Testing disabled. Could not find python3. If you have python3 installed try running "
diff --git a/build_glslang_spirv_tools.sh b/build_glslang_spirv_tools.sh
index a966427..1095f30 100755
--- a/build_glslang_spirv_tools.sh
+++ b/build_glslang_spirv_tools.sh
@@ -5,22 +5,21 @@
 	PROFILE=$1
 fi
 
-NPROC=$(nproc)
 if [ ! -z $2 ]; then
-	NPROC=$2
+	NPROC="--parallel $2"
 fi
 
 echo "Building glslang."
 mkdir -p external/glslang-build
 cd external/glslang-build
-cmake ../glslang -DCMAKE_BUILD_TYPE=$PROFILE -G"Unix Makefiles"
-make -j$NPROC
+cmake ../glslang -DCMAKE_BUILD_TYPE=$PROFILE -DCMAKE_INSTALL_PREFIX=output
+cmake --build . --target install ${NPROC}
 cd ../..
 
 echo "Building SPIRV-Tools."
 mkdir -p external/spirv-tools-build
 cd external/spirv-tools-build
-cmake ../spirv-tools -DCMAKE_BUILD_TYPE=$PROFILE -G"Unix Makefiles" -DSPIRV_WERROR=OFF
-make -j$NPROC
+cmake ../spirv-tools -DCMAKE_BUILD_TYPE=$PROFILE -DSPIRV_WERROR=OFF -DCMAKE_INSTALL_PREFIX=output
+cmake --build . --target install ${NPROC}
 cd ../..
 
diff --git a/checkout_glslang_spirv_tools.sh b/checkout_glslang_spirv_tools.sh
index 0679c67..c90d1da 100755
--- a/checkout_glslang_spirv_tools.sh
+++ b/checkout_glslang_spirv_tools.sh
@@ -2,6 +2,7 @@
 
 GLSLANG_REV=91ac4290bcf2cb930b4fb0981f09c00c0b6797e1
 SPIRV_TOOLS_REV=9bfe0eb25e3dfdf4f3fd86ab6c0cda009c9bd661
+SPIRV_HEADERS_REV=d5b2e1255f706ce1f88812217e9a554f299848af
 
 if [ -d external/glslang ]; then
 	echo "Updating glslang to revision $GLSLANG_REV."
@@ -35,9 +36,13 @@
 if [ -d external/spirv-headers ]; then
 	cd external/spirv-headers
 	git pull origin master
+	git checkout $SPIRV_HEADERS_REV
 	cd ../..
 else
 	git clone git://github.com/KhronosGroup/SPIRV-Headers.git external/spirv-headers
+	cd external/spirv-headers
+	git checkout $SPIRV_HEADERS_REV
+	cd ../..
 fi
 
 cd ../..
diff --git a/reference/opt/shaders-hlsl/frag/inf-nan-constant.frag b/reference/opt/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/opt/shaders-hlsl/frag/inf-nan-constant.frag
rename to reference/opt/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
diff --git a/reference/opt/shaders-msl/frag/inf-nan-constant.frag b/reference/opt/shaders-msl/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/opt/shaders-msl/frag/inf-nan-constant.frag
rename to reference/opt/shaders-msl/asm/frag/inf-nan-constant.asm.frag
diff --git a/reference/opt/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag b/reference/opt/shaders/asm/frag/inf-nan-constant-double.asm.frag
similarity index 100%
rename from reference/opt/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag
rename to reference/opt/shaders/asm/frag/inf-nan-constant-double.asm.frag
diff --git a/reference/opt/shaders/frag/inf-nan-constant.frag b/reference/opt/shaders/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/opt/shaders/frag/inf-nan-constant.frag
rename to reference/opt/shaders/asm/frag/inf-nan-constant.asm.frag
diff --git a/reference/shaders-hlsl/frag/inf-nan-constant.frag b/reference/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/shaders-hlsl/frag/inf-nan-constant.frag
rename to reference/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
diff --git a/reference/shaders-msl/frag/inf-nan-constant.frag b/reference/shaders-msl/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/shaders-msl/frag/inf-nan-constant.frag
rename to reference/shaders-msl/asm/frag/inf-nan-constant.asm.frag
diff --git a/reference/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag b/reference/shaders/asm/frag/inf-nan-constant-double.asm.frag
similarity index 100%
rename from reference/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag
rename to reference/shaders/asm/frag/inf-nan-constant-double.asm.frag
diff --git a/reference/shaders/frag/inf-nan-constant.frag b/reference/shaders/asm/frag/inf-nan-constant.asm.frag
similarity index 100%
rename from reference/shaders/frag/inf-nan-constant.frag
rename to reference/shaders/asm/frag/inf-nan-constant.asm.frag
diff --git a/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag b/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
new file mode 100644
index 0000000..40e5d3a
--- /dev/null
+++ b/shaders-hlsl/asm/frag/inf-nan-constant.asm.frag
@@ -0,0 +1,29 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 14
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource ESSL 310
+               OpName %main "main"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColor Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+  %FragColor = OpVariable %_ptr_Output_v3float Output
+%float_0x1p_128 = OpConstant %float 0x1p+128
+%float_n0x1p_128 = OpConstant %float -0x1p+128
+%float_0x1_8p_128 = OpConstant %float 0x1.8p+128
+         %13 = OpConstantComposite %v3float %float_0x1p_128 %float_n0x1p_128 %float_0x1_8p_128
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpStore %FragColor %13
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders-hlsl/frag/inf-nan-constant.frag b/shaders-hlsl/frag/inf-nan-constant.frag
deleted file mode 100644
index 78b93c3..0000000
--- a/shaders-hlsl/frag/inf-nan-constant.frag
+++ /dev/null
@@ -1,14 +0,0 @@
-#version 310 es
-precision highp float;
-
-const float posinf = 1.0 / 0.0;
-const float neginf = -1.0 / 0.0;
-const float nan = 0.0 / 0.0;
-
-layout(location = 0) out vec3 FragColor;
-
-void main()
-{
-	FragColor = vec3(posinf, neginf, nan);
-}
-
diff --git a/shaders-msl/asm/frag/inf-nan-constant.asm.frag b/shaders-msl/asm/frag/inf-nan-constant.asm.frag
new file mode 100644
index 0000000..40e5d3a
--- /dev/null
+++ b/shaders-msl/asm/frag/inf-nan-constant.asm.frag
@@ -0,0 +1,29 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 14
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource ESSL 310
+               OpName %main "main"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColor Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+  %FragColor = OpVariable %_ptr_Output_v3float Output
+%float_0x1p_128 = OpConstant %float 0x1p+128
+%float_n0x1p_128 = OpConstant %float -0x1p+128
+%float_0x1_8p_128 = OpConstant %float 0x1.8p+128
+         %13 = OpConstantComposite %v3float %float_0x1p_128 %float_n0x1p_128 %float_0x1_8p_128
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpStore %FragColor %13
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders-msl/frag/inf-nan-constant.frag b/shaders-msl/frag/inf-nan-constant.frag
deleted file mode 100644
index 78b93c3..0000000
--- a/shaders-msl/frag/inf-nan-constant.frag
+++ /dev/null
@@ -1,14 +0,0 @@
-#version 310 es
-precision highp float;
-
-const float posinf = 1.0 / 0.0;
-const float neginf = -1.0 / 0.0;
-const float nan = 0.0 / 0.0;
-
-layout(location = 0) out vec3 FragColor;
-
-void main()
-{
-	FragColor = vec3(posinf, neginf, nan);
-}
-
diff --git a/shaders/asm/frag/inf-nan-constant-double.asm.frag b/shaders/asm/frag/inf-nan-constant-double.asm.frag
new file mode 100644
index 0000000..2d0c18a
--- /dev/null
+++ b/shaders/asm/frag/inf-nan-constant-double.asm.frag
@@ -0,0 +1,41 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 22
+; Schema: 0
+               OpCapability Shader
+               OpCapability Float64
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColor %vTmp
+               OpExecutionMode %main OriginUpperLeft
+               OpSource GLSL 450
+               OpName %main "main"
+               OpName %FragColor "FragColor"
+               OpName %vTmp "vTmp"
+               OpDecorate %FragColor Location 0
+               OpDecorate %vTmp Flat
+               OpDecorate %vTmp Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+  %FragColor = OpVariable %_ptr_Output_v3float Output
+     %double = OpTypeFloat 64
+   %v3double = OpTypeVector %double 3
+%double_0x1p_1024 = OpConstant %double 0x1p+1024
+%double_n0x1p_1024 = OpConstant %double -0x1p+1024
+%double_0x1_8p_1024 = OpConstant %double 0x1.8p+1024
+         %15 = OpConstantComposite %v3double %double_0x1p_1024 %double_n0x1p_1024 %double_0x1_8p_1024
+%_ptr_Input_double = OpTypePointer Input %double
+       %vTmp = OpVariable %_ptr_Input_double Input
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+         %18 = OpLoad %double %vTmp
+         %19 = OpCompositeConstruct %v3double %18 %18 %18
+         %20 = OpFAdd %v3double %15 %19
+         %21 = OpFConvert %v3float %20
+               OpStore %FragColor %21
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders/asm/frag/inf-nan-constant.asm.frag b/shaders/asm/frag/inf-nan-constant.asm.frag
new file mode 100644
index 0000000..40e5d3a
--- /dev/null
+++ b/shaders/asm/frag/inf-nan-constant.asm.frag
@@ -0,0 +1,29 @@
+; SPIR-V
+; Version: 1.0
+; Generator: Khronos Glslang Reference Front End; 7
+; Bound: 14
+; Schema: 0
+               OpCapability Shader
+          %1 = OpExtInstImport "GLSL.std.450"
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main" %FragColor
+               OpExecutionMode %main OriginUpperLeft
+               OpSource ESSL 310
+               OpName %main "main"
+               OpName %FragColor "FragColor"
+               OpDecorate %FragColor Location 0
+       %void = OpTypeVoid
+          %3 = OpTypeFunction %void
+      %float = OpTypeFloat 32
+    %v3float = OpTypeVector %float 3
+%_ptr_Output_v3float = OpTypePointer Output %v3float
+  %FragColor = OpVariable %_ptr_Output_v3float Output
+%float_0x1p_128 = OpConstant %float 0x1p+128
+%float_n0x1p_128 = OpConstant %float -0x1p+128
+%float_0x1_8p_128 = OpConstant %float 0x1.8p+128
+         %13 = OpConstantComposite %v3float %float_0x1p_128 %float_n0x1p_128 %float_0x1_8p_128
+       %main = OpFunction %void None %3
+          %5 = OpLabel
+               OpStore %FragColor %13
+               OpReturn
+               OpFunctionEnd
diff --git a/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag b/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag
deleted file mode 100644
index d2a80fe..0000000
--- a/shaders/desktop-only/frag/inf-nan-constant-double.desktop.frag
+++ /dev/null
@@ -1,13 +0,0 @@
-#version 450
-
-const double posinf = 1.0lf / 0.0lf;
-const double neginf = -1.0lf / 0.0lf;
-const double nan = 0.0lf / 0.0lf;
-
-layout(location = 0) out vec3 FragColor;
-layout(location = 0) flat in double vTmp;
-
-void main()
-{
-	FragColor = vec3(dvec3(posinf, neginf, nan) + vTmp);
-}
diff --git a/shaders/frag/inf-nan-constant.frag b/shaders/frag/inf-nan-constant.frag
deleted file mode 100644
index 78b93c3..0000000
--- a/shaders/frag/inf-nan-constant.frag
+++ /dev/null
@@ -1,14 +0,0 @@
-#version 310 es
-precision highp float;
-
-const float posinf = 1.0 / 0.0;
-const float neginf = -1.0 / 0.0;
-const float nan = 0.0 / 0.0;
-
-layout(location = 0) out vec3 FragColor;
-
-void main()
-{
-	FragColor = vec3(posinf, neginf, nan);
-}
-
diff --git a/spirv_glsl.cpp b/spirv_glsl.cpp
index 113dc0f..240c605 100644
--- a/spirv_glsl.cpp
+++ b/spirv_glsl.cpp
@@ -9283,7 +9283,7 @@
 		// Only sensible solution is to make a ladder variable, which we declare at the top of the switch block,
 		// write to the ladder here, and defer the break.
 		// The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case.
-		if (current_emitting_switch && is_loop_break(to) && current_emitting_switch->loop_dominator != -1u &&
+		if (current_emitting_switch && is_loop_break(to) && current_emitting_switch->loop_dominator != ~0u &&
 		    get<SPIRBlock>(current_emitting_switch->loop_dominator).merge_block == to)
 		{
 			if (!current_emitting_switch->need_ladder_break)
diff --git a/test_shaders.py b/test_shaders.py
index a627b45..045c255 100755
--- a/test_shaders.py
+++ b/test_shaders.py
@@ -16,9 +16,6 @@
 import errno
 from functools import partial
 
-backend = 'glsl'
-args = {}
-
 def remove_file(path):
     #print('Removing file:', path)
     os.remove(path)
@@ -194,11 +191,11 @@
     return shader
 
 ignore_fxc = False
-def validate_shader_hlsl(shader):
+def validate_shader_hlsl(shader, force_no_external_validation):
     subprocess.check_call(['glslangValidator', '-e', 'main', '-D', '--target-env', 'vulkan1.1', '-V', shader])
     is_no_fxc = '.nofxc.' in shader
     global ignore_fxc
-    if (not ignore_fxc) and (not args.force_no_external_validation) and (not is_no_fxc):
+    if (not ignore_fxc) and (not force_no_external_validation) and (not is_no_fxc):
         try:
             win_path = shader_to_win_path(shader)
             subprocess.check_call(['fxc', '-nologo', shader_model_hlsl(shader), win_path])
@@ -221,7 +218,7 @@
     else:
         return '50'
 
-def cross_compile_hlsl(shader, spirv, opt):
+def cross_compile_hlsl(shader, spirv, opt, force_no_external_validation):
     spirv_path = create_temporary()
     hlsl_path = create_temporary(os.path.basename(shader))
 
@@ -241,7 +238,7 @@
     if not shader_is_invalid_spirv(hlsl_path):
         subprocess.check_call(['spirv-val', '--target-env', 'vulkan1.1', spirv_path])
 
-    validate_shader_hlsl(hlsl_path)
+    validate_shader_hlsl(hlsl_path, force_no_external_validation)
     
     return (spirv_path, hlsl_path)
 
@@ -496,7 +493,7 @@
             a.append(str(i))
         print(','.join(a), file = stats)
 
-def test_shader_msl(stats, shader, update, keep, opt):
+def test_shader_msl(stats, shader, update, keep, opt, force_no_external_validation):
     joined_path = os.path.join(shader[0], shader[1])
     print('\nTesting MSL shader:', joined_path)
     is_spirv = shader_is_spirv(shader[1])
@@ -512,17 +509,17 @@
     # executable from Xcode using args: `--msl --entry main --output msl_path spirv_path`.
 #    print('SPRIV shader: ' + spirv)
 
-    if not args.force_no_external_validation:
+    if not force_no_external_validation:
         validate_shader_msl(shader, opt)
 
     remove_file(spirv)
 
-def test_shader_hlsl(stats, shader, update, keep, opt):
+def test_shader_hlsl(stats, shader, update, keep, opt, force_no_external_validation):
     joined_path = os.path.join(shader[0], shader[1])
     print('Testing HLSL shader:', joined_path)
     is_spirv = shader_is_spirv(shader[1])
     noopt = shader_is_noopt(shader[1])
-    spirv, hlsl = cross_compile_hlsl(joined_path, is_spirv, opt and (not noopt))
+    spirv, hlsl = cross_compile_hlsl(joined_path, is_spirv, opt and (not noopt), force_no_external_validation)
     regression_check(shader, hlsl, update, keep, opt)
     remove_file(spirv)
 
@@ -535,17 +532,17 @@
     regression_check_reflect(shader, reflect, update, keep, opt)
     remove_file(spirv)
 
-def test_shader_file(relpath, stats, shader_dir, update, keep, opt, backend):
+def test_shader_file(relpath, stats, shader_dir, update, keep, opt, force_no_external_validation, backend):
     if backend == 'msl':
-        test_shader_msl(stats, (shader_dir, relpath), update, keep, opt)
+        test_shader_msl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation)
     elif backend == 'hlsl':
-        test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt)
+        test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt, force_no_external_validation)
     elif backend == 'reflect':
         test_shader_reflect(stats, (shader_dir, relpath), update, keep, opt)
     else:
         test_shader(stats, (shader_dir, relpath), update, keep, opt)
 
-def test_shaders_helper(stats):
+def test_shaders_helper(stats, backend, args):
     all_files = []
     for root, dirs, files in os.walk(os.path.join(args.folder)):
         files = [ f for f in files if not f.startswith(".") ]   #ignore system files (esp OSX)
@@ -558,18 +555,25 @@
     # at this point we need to switch to explicit arguments
     if args.parallel:
         pool = multiprocessing.Pool(multiprocessing.cpu_count())
-        pool.map(partial(test_shader_file, stats=stats, shader_dir=args.folder, update=args.update, keep=args.keep, opt=args.opt, backend=backend), all_files)
+        pool.map(partial(test_shader_file,
+            stats = stats,
+            shader_dir = args.folder,
+            update = args.update,
+            keep = args.keep,
+            opt = args.opt,
+            force_no_external_validation = args.force_no_external_validation,
+            backend = backend), all_files)
     else:
         for i in all_files:
-            test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, backend) 
+            test_shader_file(i, stats, args.folder, args.update, args.keep, args.opt, args.force_no_external_validation, backend)
 
-def test_shaders():
+def test_shaders(backend, args):
     if args.malisc:
         with open('stats.csv', 'w') as stats:
             print('Shader,OrigRegs,OrigUniRegs,OrigALUShort,OrigLSShort,OrigTEXShort,OrigALULong,OrigLSLong,OrigTEXLong,CrossRegs,CrossUniRegs,CrossALUShort,CrossLSShort,CrossTEXShort,CrossALULong,CrossLSLong,CrossTEXLong', file = stats)
-            test_shaders_helper(stats)
+            test_shaders_helper(stats, backend, args)
     else:
-        test_shaders_helper(None)
+        test_shaders_helper(None, backend, args)
 
 def main():
     parser = argparse.ArgumentParser(description = 'Script for regression testing.')
@@ -606,7 +610,6 @@
             action = 'store_true',
             help = 'Execute tests in parallel.  Useful for doing regression quickly, but bad for debugging and stat output.')
     
-    global args
     args = parser.parse_args()
     if not args.folder:
         sys.stderr.write('Need shader folder.\n')
@@ -619,7 +622,7 @@
     if args.msl:
         print_msl_compiler_version()
 
-    global backend
+    backend = 'glsl'
     if (args.msl or args.metal): 
         backend = 'msl'
     elif args.hlsl: 
@@ -627,7 +630,7 @@
     elif args.reflect:
         backend = 'reflect'
 
-    test_shaders()
+    test_shaders(backend, args)
     if args.malisc:
         print('Stats in stats.csv!')
     print('Tests completed!')
diff --git a/test_shaders.sh b/test_shaders.sh
index 8a43afb..d49ceb2 100755
--- a/test_shaders.sh
+++ b/test_shaders.sh
@@ -3,7 +3,7 @@
 echo "Building spirv-cross"
 make -j$(nproc)
 
-export PATH="./external/glslang-build/StandAlone:./external/spirv-tools-build/tools:.:$PATH"
+export PATH="./external/glslang-build/output/bin:./external/spirv-tools-build/output/bin:.:$PATH"
 echo "Using glslangValidation in: $(which glslangValidator)."
 echo "Using spirv-opt in: $(which spirv-opt)."
 
diff --git a/update_test_shaders.sh b/update_test_shaders.sh
index 1582c6c..2fb5ffa 100755
--- a/update_test_shaders.sh
+++ b/update_test_shaders.sh
@@ -3,7 +3,7 @@
 echo "Building spirv-cross"
 make -j$(nproc)
 
-export PATH="./external/glslang-build/StandAlone:./external/spirv-tools-build/tools:.:$PATH"
+export PATH="./external/glslang-build/output/bin:./external/spirv-tools-build/output/bin:.:$PATH"
 echo "Using glslangValidation in: $(which glslangValidator)."
 echo "Using spirv-opt in: $(which spirv-opt)."