Parse 'Sample' image instruction operand

OpImageFetch/Read/Write can have an optional 'Sample' operand which
indicates the sample index to operate on. It is orthogonal to other
operands so it is indicated by a new Boolean field in
sw::SamplerFunction and SpirvShader::ImageInstruction. The offset
operand was also turned into a Boolean field / component count.

The sample index is not wired up to be taken into account by the Fetch
sampling routine yet. OpImageRead already had support for the Sample
operand, but OpImageWrite does not.

Bug: b/135265531
Tests: dEQP-VK.pipeline.multisample.sampled_image.*
Change-Id: I20f50a888436775b996221e8283a4c4ab7f28e17
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/32908
Tested-by: Nicolas Capens <nicolascapens@google.com>
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 25763a9..a54eb8d 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -164,25 +164,24 @@
 		}
 		else if(instruction.samplerMethod == Grad)
 		{
-			for(uint32_t j = 0; j < instruction.gradComponents; j++, i++)
+			for(uint32_t j = 0; j < instruction.grad; j++, i++)
 			{
 				dsx[j] = in[i];
 			}
 
-			for(uint32_t j = 0; j < instruction.gradComponents; j++, i++)
+			for(uint32_t j = 0; j < instruction.grad; j++, i++)
 			{
 				dsy[j] = in[i];
 			}
 		}
 
-		if(instruction.samplerOption == Offset)
+		for(uint32_t j = 0; j < instruction.offset; j++, i++)
 		{
-			for(uint32_t j = 0; j < instruction.offsetComponents; j++, i++)
-			{
-				offset[j] = in[i];
-			}
+			offset[j] = in[i];
 		}
 
+		// TODO(b/133868964): Handle 'Sample' operand.
+
 		SamplerCore s(constants, samplerState);
 
 		// For explicit-lod instructions the LOD can be different per SIMD lane. SamplerCore currently assumes