Don't use 2D coordinates for 1D sampling

1D images were being treated as 2D ones with the second coordinate set
to 0.0. It required other workarounds like moving the array layer
coordinate and providing an addressing mode for the second coordinate.
These have been removed, and the texel address calculation now ignores
the second coordinate for 1D images.

Note this doesn't specialize filtering for the 1D case yet, so the
weights for filtering in the v-direction are explicitly zeroed out.

Fixes: b/162858741
Bug: b/134669567
Change-Id: I4684ee0337ac500860e9939087045a953bad813a
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/47428
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 6336730..43a7fa2 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -38,15 +38,10 @@
 	Float4 a;  // Array layer coordinate
 	switch(state.textureType)
 	{
-		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:  // Treated as 2D array
-		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
-			a = uvwa[2];
-			break;
-		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
-			a = uvwa[3];
-			break;
-		default:
-			break;
+		case VK_IMAGE_VIEW_TYPE_1D_ARRAY: a = uvwa[1]; break;
+		case VK_IMAGE_VIEW_TYPE_2D_ARRAY: a = uvwa[2]; break;
+		case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: a = uvwa[3]; break;
+		default: break;
 	}
 
 	Float lod;
@@ -1388,21 +1383,30 @@
 void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, const Short4 &layerIndex, Vector4i &offset, const Int4 &sample, const Pointer<Byte> &mipmap, SamplerFunction function)
 {
 	uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
-	vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
 
 	if(function.offset)
 	{
 		uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)), state.addressingModeU);
-		vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
 	}
 
-	Short4 uuu2 = uuuu;
-	uuuu = As<Short4>(UnpackLow(uuuu, vvvv));
-	uuu2 = As<Short4>(UnpackHigh(uuu2, vvvv));
-	uuuu = As<Short4>(MulAdd(uuuu, *Pointer<Short4>(mipmap + OFFSET(Mipmap, onePitchP))));
-	uuu2 = As<Short4>(MulAdd(uuu2, *Pointer<Short4>(mipmap + OFFSET(Mipmap, onePitchP))));
+	UInt4 indices = Int4(uuuu);
 
-	UInt4 uv(As<UInt2>(uuuu), As<UInt2>(uuu2));
+	if(state.addressingModeV != ADDRESSING_UNUSED)
+	{
+		vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
+
+		if(function.offset)
+		{
+			vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)), state.addressingModeV);
+		}
+
+		Short4 uv0uv1 = As<Short4>(UnpackLow(uuuu, vvvv));
+		Short4 uv2uv3 = As<Short4>(UnpackHigh(uuuu, vvvv));
+		Int2 i01 = MulAdd(uv0uv1, *Pointer<Short4>(mipmap + OFFSET(Mipmap, onePitchP)));
+		Int2 i23 = MulAdd(uv2uv3, *Pointer<Short4>(mipmap + OFFSET(Mipmap, onePitchP)));
+
+		indices = UInt4(As<UInt2>(i01), As<UInt2>(i23));
+	}
 
 	if(state.textureType == VK_IMAGE_VIEW_TYPE_3D)
 	{
@@ -1413,7 +1417,7 @@
 			wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)), state.addressingModeW);
 		}
 
-		uv += As<UInt4>(Int4(As<UShort4>(wwww))) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP));
+		indices += As<UInt4>(Int4(As<UShort4>(wwww))) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP));
 	}
 
 	if(state.isArrayed())
@@ -1427,25 +1431,30 @@
 
 		UInt4 layerOffset = As<UInt4>(layer) * *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sliceP));
 
-		uv += layerOffset;
+		indices += layerOffset;
 	}
 
 	if(function.sample)
 	{
 		UInt4 sampleOffset = Min(As<UInt4>(sample), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) *
 		                     *Pointer<UInt4>(mipmap + OFFSET(Mipmap, samplePitchP), 16);
-		uv += sampleOffset;
+		indices += sampleOffset;
 	}
 
-	index[0] = Extract(As<Int4>(uv), 0);
-	index[1] = Extract(As<Int4>(uv), 1);
-	index[2] = Extract(As<Int4>(uv), 2);
-	index[3] = Extract(As<Int4>(uv), 3);
+	index[0] = Extract(indices, 0);
+	index[1] = Extract(indices, 1);
+	index[2] = Extract(indices, 2);
+	index[3] = Extract(indices, 3);
 }
 
 void SamplerCore::computeIndices(UInt index[4], Int4 uuuu, Int4 vvvv, Int4 wwww, const Int4 &sample, Int4 valid, const Pointer<Byte> &mipmap, SamplerFunction function)
 {
-	UInt4 indices = uuuu + vvvv;
+	UInt4 indices = uuuu;
+
+	if(state.addressingModeV != ADDRESSING_UNUSED)
+	{
+		indices += As<UInt4>(vvvv);
+	}
 
 	if(state.addressingModeW != ADDRESSING_UNUSED || state.isArrayed())
 	{
@@ -2192,7 +2201,7 @@
 {
 	if(addressingMode == ADDRESSING_UNUSED)
 	{
-		return Short4();
+		return Short4(0);  // TODO(b/134669567): Optimize for 1D filtering
 	}
 	else if(addressingMode == ADDRESSING_CLAMP || addressingMode == ADDRESSING_BORDER)
 	{
@@ -2256,6 +2265,7 @@
 {
 	if(addressingMode == ADDRESSING_UNUSED)
 	{
+		f = Float4(0.0f);  // TODO(b/134669567): Optimize for 1D filtering
 		return;
 	}
 
@@ -2301,8 +2311,8 @@
 					// Don't map to a valid range here.
 					break;
 				default:
-					// If unnormalizedCoordinates is VK_TRUE, addressModeU and addressModeV must each be
-					// either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER
+					// "If unnormalizedCoordinates is VK_TRUE, addressModeU and addressModeV must each be
+					//  either VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE or VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER"
 					UNREACHABLE("addressingMode %d", int(addressingMode));
 					break;
 			}
@@ -2541,13 +2551,6 @@
 	return state.textureFormat.componentCount();
 }
 
-bool SamplerCore::hasThirdCoordinate() const
-{
-	return (state.textureType == VK_IMAGE_VIEW_TYPE_3D) ||
-	       (state.textureType == VK_IMAGE_VIEW_TYPE_2D_ARRAY) ||
-	       (state.textureType == VK_IMAGE_VIEW_TYPE_1D_ARRAY);  // Treated as 2D texture with second coordinate 0. TODO(b/134669567)
-}
-
 bool SamplerCore::has16bitPackedTextureFormat() const
 {
 	return state.textureFormat.has16bitPackedTextureFormat();
diff --git a/src/Pipeline/SamplerCore.hpp b/src/Pipeline/SamplerCore.hpp
index a05bf75..82c6079 100644
--- a/src/Pipeline/SamplerCore.hpp
+++ b/src/Pipeline/SamplerCore.hpp
@@ -100,7 +100,6 @@
 	bool hasUnnormalizedIntegerTexture() const;
 	bool hasUnsignedTextureComponent(int component) const;
 	int textureComponentCount() const;
-	bool hasThirdCoordinate() const;
 	bool has16bitPackedTextureFormat() const;
 	bool has8bitTextureComponents() const;
 	bool has16bitTextureComponents() const;
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 2e0858d..c7902cb 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -124,18 +124,6 @@
 			i++;
 		}
 
-		// TODO(b/134669567): Currently 1D textures are treated as 2D by setting the second coordinate to 0.
-		// Implement optimized 1D sampling.
-		if(samplerState.textureType == VK_IMAGE_VIEW_TYPE_1D)
-		{
-			uvwa[1] = SIMD::Float(0);
-		}
-		else if(samplerState.textureType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
-		{
-			uvwa[1] = SIMD::Float(0);
-			uvwa[2] = in[1];  // Move 1D layer coordinate to 2D layer coordinate index.
-		}
-
 		if(instruction.samplerMethod == Lod || instruction.samplerMethod == Bias || instruction.samplerMethod == Fetch)
 		{
 			lodOrBias = in[i];
@@ -289,13 +277,13 @@
 {
 	switch(imageViewType)
 	{
-		case VK_IMAGE_VIEW_TYPE_1D:  // Treated as 2D texture with second coordinate 0. TODO(b/134669567)
+		case VK_IMAGE_VIEW_TYPE_1D:
 		case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
-			if(coordinateIndex == 1)
+			if(coordinateIndex >= 1)
 			{
-				return ADDRESSING_WRAP;
+				return ADDRESSING_UNUSED;
 			}
-			// Fall through to 2D case:
+			break;
 		case VK_IMAGE_VIEW_TYPE_2D:
 		case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
 			if(coordinateIndex == 2)
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 7c5892b..f987562 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -311,7 +311,7 @@
 			mipmap.pitchP.x = mipmap.pitchP.y = mipmap.pitchP.z = mipmap.pitchP.w = numElements;
 			mipmap.sliceP.x = mipmap.sliceP.y = mipmap.sliceP.z = mipmap.sliceP.w = 0;
 			mipmap.onePitchP[0] = mipmap.onePitchP[2] = 1;
-			mipmap.onePitchP[1] = mipmap.onePitchP[3] = static_cast<short>(numElements);
+			mipmap.onePitchP[1] = mipmap.onePitchP[3] = 0;
 		}
 	}
 	else if(entry.descriptorType == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER ||