Be more careful about Block decorations on structs

In spirv/SPIR-V@9701a9f9 we changed the SPIR-V spec to say that
block-decorated structures could not be nested.  This is needed for
sorting out certain variable pointers issues inside a SPIR-V parser.
Unfortunately, the mentioned group of CTS tests violates this rule.
Their %input_buffer type is a struct containing two instances of
%outer_struct and both %input_buffer and %outer_struct are decorated
Block.  Fortunately, only one of the two struct types is actually
required for an input at any given type so we just need to be more
careful about the decorations.

Affects:

dEQP-VK.spirv_assembly.instruction.compute.variable_pointers.complex_types_compute.*

Components: Vulkan

VK-GL-CTS issue: 1518
Change-Id: I87a832fab94a9c06317d20b32afedf16b52ab2f2
(cherry picked from commit 1dbdfe34947fdb3e6d24226a58f02d0b8a515da8)
diff --git a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariablePointersTests.cpp b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariablePointersTests.cpp
index 77e9b33..972baa5 100644
--- a/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariablePointersTests.cpp
+++ b/external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmVariablePointersTests.cpp
@@ -642,21 +642,13 @@
 	// 7. inputC.a.r[?][?].(x|y)[?][?]	or	inputC.b.r[?][?].(x|y)[?][?]	= scalars
 	const int numLevels = 7;
 
-	const string decorations (
+	const string commonDecorations (
 		// Decorations
 		"OpDecorate %id BuiltIn GlobalInvocationId		\n"
-		"OpDecorate %inputA DescriptorSet 0				\n"
-		"OpDecorate %inputB DescriptorSet 0				\n"
-		"OpDecorate %inputC DescriptorSet 0				\n"
 		"OpDecorate %outdata DescriptorSet 0			\n"
-		"OpDecorate %inputA Binding 0					\n"
-		"OpDecorate %inputB Binding 1					\n"
-		"OpDecorate %inputC Binding 2					\n"
 		"OpDecorate %outdata Binding 3					\n"
 
 		// Set the Block decoration
-		"OpDecorate %outer_struct	Block				\n"
-		"OpDecorate %input_buffer	Block				\n"
 		"OpDecorate %output_buffer	Block				\n"
 
 		// Set the Offsets
@@ -675,6 +667,24 @@
 		"OpDecorate %v4f32_ptr           ArrayStride 16		\n"
 	);
 
+	const string inputABDecorations (
+		"OpDecorate %inputA DescriptorSet 0				\n"
+		"OpDecorate %inputB DescriptorSet 0				\n"
+		"OpDecorate %inputA Binding 0					\n"
+		"OpDecorate %inputB Binding 1					\n"
+
+		// inputA and inputB have type outer_struct so it needs Block
+		"OpDecorate %outer_struct	Block				\n"
+	);
+
+	const string inputCDecorations (
+		"OpDecorate %inputC DescriptorSet 0				\n"
+		"OpDecorate %inputC Binding 2					\n"
+
+		// inputC has type input_buffer so it needs Block
+		"OpDecorate %input_buffer	Block				\n"
+	);
+
 	const string types (
 		///////////////
 		// CONSTANTS //
@@ -734,10 +744,22 @@
 		// VARIABLES //
 		///////////////
 		"%id					= OpVariable %uvec3ptr			Input				\n"
+		"%outdata				= OpVariable %output_buffer_ptr	StorageBuffer		\n"
+	);
+
+	const string inputABVariables (
 		"%inputA				= OpVariable %outer_struct_ptr	StorageBuffer		\n"
 		"%inputB				= OpVariable %outer_struct_ptr	StorageBuffer		\n"
+	);
+
+	const string inputCVariables (
 		"%inputC				= OpVariable %input_buffer_ptr	StorageBuffer		\n"
-		"%outdata				= OpVariable %output_buffer_ptr	StorageBuffer		\n"
+	);
+
+	const string inputCIntermediates (
+		// Here are the 2 nested structures within InputC.
+		"%inputC_a				= OpAccessChain %outer_struct_ptr %inputC %c_i32_0\n"
+		"%inputC_b				= OpAccessChain %outer_struct_ptr %inputC %c_i32_1\n"
 	);
 
 	const StringTemplate shaderTemplate (
@@ -755,12 +777,16 @@
 		"OpName %main           \"main\"\n"
 		"OpName %id             \"gl_GlobalInvocationID\"\n"
 
-		+ decorations
+		+ commonDecorations +
+
+		"${input_decorations}\n"
 
 		+ string(getComputeAsmCommonTypes())
 
 		+ types +
 
+		"${input_variables}\n"
+
 		// These selector functions return variable pointers.
 		// These functions are used by tests that use OpFunctionCall to obtain the variable pointer
 		"%selector_func_type	= OpTypeFunction ${selected_type} %bool ${selected_type} ${selected_type}\n"
@@ -777,9 +803,7 @@
 		"%main					= OpFunction %void None %voidf\n"
 		"%label					= OpLabel\n"
 
-		// Here are the 2 nested structures within InputC.
-		"%inputC_a				= OpAccessChain %outer_struct_ptr %inputC %c_i32_0\n"
-		"%inputC_b				= OpAccessChain %outer_struct_ptr %inputC %c_i32_1\n"
+		"${input_intermediates}\n"
 
 		// Define the 2 pointers from which we're going to choose one.
 		"${a_loc} \n"
@@ -811,6 +835,9 @@
 		for (int selectInputA = 0; selectInputA < 2; ++selectInputA)
 		{
 			const string extraCap					= isSingleInputBuffer	? "OpCapability VariablePointersStorageBuffer\n" : "OpCapability VariablePointers\n";
+			const string inputDecorations			= isSingleInputBuffer	? inputCDecorations								 : inputABDecorations;
+			const string inputVariables				= isSingleInputBuffer	? inputCVariables								 : inputABVariables;
+			const string inputIntermediates			= isSingleInputBuffer	? inputCIntermediates							 : "";
 			const vector<float>& selectedInput		= isSingleInputBuffer	? inputC										 : (selectInputA ? inputA : inputB);
 			const string bufferType					= isSingleInputBuffer	? "single_buffer_"								 : "two_buffers_";
 			const string baseA						= isSingleInputBuffer	? "%inputC_a"									 : "%inputA";
@@ -907,6 +934,9 @@
 					string opCodeForTests			= "opselect";
 					string name						= opCodeForTests + indexLevelNames[indexLevel] + bufferType + selectedInputStr;
 					specs["extra_capability"]		= extraCap;
+					specs["input_decorations"]		= inputDecorations;
+					specs["input_variables"]		= inputVariables;
+					specs["input_intermediates"]	= inputIntermediates;
 					specs["selected_type"]			= pointerTypeAtLevel[indexLevel];
 					specs["select_inputA"]			= spirvSelectInputA;
 					specs["a_loc"]					= inputALocations[indexLevel];
@@ -939,6 +969,9 @@
 					string opCodeForTests			= "opfunctioncall";
 					string name						= opCodeForTests + indexLevelNames[indexLevel] + bufferType + selectedInputStr;
 					specs["extra_capability"]		= extraCap;
+					specs["input_decorations"]		= inputDecorations;
+					specs["input_variables"]		= inputVariables;
+					specs["input_intermediates"]	= inputIntermediates;
 					specs["selected_type"]			= pointerTypeAtLevel[indexLevel];
 					specs["select_inputA"]			= spirvSelectInputA;
 					specs["a_loc"]					= inputALocations[indexLevel];
@@ -973,6 +1006,9 @@
 					string opCodeForTests			= "opphi";
 					string name						= opCodeForTests + indexLevelNames[indexLevel] + bufferType + selectedInputStr;
 					specs["extra_capability"]		= extraCap;
+					specs["input_decorations"]		= inputDecorations;
+					specs["input_variables"]		= inputVariables;
+					specs["input_intermediates"]	= inputIntermediates;
 					specs["selected_type"]			= pointerTypeAtLevel[indexLevel];
 					specs["select_inputA"]			= spirvSelectInputA;
 					specs["a_loc"]					= inputALocations[indexLevel];
@@ -1014,6 +1050,9 @@
 					string opCodeForTests			= "opcopyobject";
 					string name						= opCodeForTests + indexLevelNames[indexLevel] + bufferType + selectedInputStr;
 					specs["extra_capability"]		= extraCap;
+					specs["input_decorations"]		= inputDecorations;
+					specs["input_variables"]		= inputVariables;
+					specs["input_intermediates"]	= inputIntermediates;
 					specs["selected_type"]			= pointerTypeAtLevel[indexLevel];
 					specs["select_inputA"]			= spirvSelectInputA;
 					specs["a_loc"]					= inputALocations[indexLevel];
@@ -1045,6 +1084,9 @@
 					string opCodeForTests			= "opptraccesschain";
 					string name						= opCodeForTests + indexLevelNames[indexLevel] + bufferType + selectedInputStr;
 					specs["extra_capability"]		= extraCap;
+					specs["input_decorations"]		= inputDecorations;
+					specs["input_variables"]		= inputVariables;
+					specs["input_intermediates"]	= inputIntermediates;
 					specs["selected_type"]			= pointerTypeAtLevel[indexLevel];
 					specs["select_inputA"]			= spirvSelectInputA;
 					specs["a_loc"]					= inputAPtrAccessChain[indexLevel];