Eliminate large image specialization

Images with dimensions of 65536 texels or more exceed the 16-bit logic
used by our 'low' precision sampler code. Thus we were treating them
differently and forced them to use our 32-bit code path. However,
ordinary images can't have such large dimensions. Only texel buffers
must support 65536 or more texels.

Those can only be accessed by OpImageFetch, OpImageRead, and
OpImageWrite instructions, and the latter two already use custom 32-bit
addressing logic. Thus we can simply specify all Fetch operations to
use the 32-bit sampler code path instead of differentiating based on
resource dimensions.

This fixes dEQP robustness tests which are enabled by the
shaderStorageImageExtendedFormats feature, because the 16-bit code path
does not bounds check fetch coordinates correctly.

Note that fetch does not perform filtering, and thus there is no excess
from using 32-bit filtering code.

Bug: b/152224843
Tests: dEQP-VK.robustness.buffer_access.*.texel_copy.a2b10g10r10_unorm_pack32.oob_uniform_read.*
Change-Id: Ie658e0fc9da05cad8efec58bac3238fb498ff10b
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/46131
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro-Result: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Sampler.hpp b/src/Device/Sampler.hpp
index fb094cc..e65b2e1 100644
--- a/src/Device/Sampler.hpp
+++ b/src/Device/Sampler.hpp
@@ -106,7 +106,6 @@
 	VkCompareOp compareOp;
 	VkBorderColor border;
 	bool unnormalizedCoordinates;
-	bool largeTexture;
 
 	VkSamplerYcbcrModelConversion ycbcrModel;
 	bool studioSwing;    // Narrow range
diff --git a/src/Pipeline/SamplerCore.cpp b/src/Pipeline/SamplerCore.cpp
index 6540c06..d278cea 100644
--- a/src/Pipeline/SamplerCore.cpp
+++ b/src/Pipeline/SamplerCore.cpp
@@ -151,8 +151,8 @@
 	bool force32BitFiltering = state.highPrecisionFiltering && !isYcbcrFormat() && (state.textureFilter != FILTER_POINT);
 	bool seamlessCube = (state.addressingModeU == ADDRESSING_SEAMLESS);
 	bool use32BitFiltering = hasFloatTexture() || hasUnnormalizedIntegerTexture() || force32BitFiltering ||
-	                         seamlessCube || state.unnormalizedCoordinates || state.compareEnable || state.largeTexture ||
-	                         borderModeActive() || (function == Gather);
+	                         seamlessCube || state.unnormalizedCoordinates || state.compareEnable ||
+	                         borderModeActive() || (function == Gather) || (function == Fetch);
 
 	if(use32BitFiltering)
 	{
@@ -520,11 +520,9 @@
 	Pointer<Byte> buffer;
 	selectMipmap(texture, mipmap, buffer, lod, secondLOD);
 
-	bool texelFetch = (function == Fetch);
-
-	Short4 uuuu = texelFetch ? Short4(As<Int4>(u)) : address(u, state.addressingModeU, mipmap);
-	Short4 vvvv = texelFetch ? Short4(As<Int4>(v)) : address(v, state.addressingModeV, mipmap);
-	Short4 wwww = texelFetch ? Short4(As<Int4>(w)) : address(w, state.addressingModeW, mipmap);
+	Short4 uuuu = address(u, state.addressingModeU, mipmap);
+	Short4 vvvv = address(v, state.addressingModeV, mipmap);
+	Short4 wwww = address(w, state.addressingModeW, mipmap);
 
 	Short4 cubeArrayId(0);
 	if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
@@ -532,7 +530,7 @@
 		cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
 	}
 
-	if(state.textureFilter == FILTER_POINT || texelFetch)
+	if(state.textureFilter == FILTER_POINT)
 	{
 		c = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
 	}
@@ -729,11 +727,9 @@
 	Pointer<Byte> buffer;
 	selectMipmap(texture, mipmap, buffer, lod, secondLOD);
 
-	bool texelFetch = (function == Fetch);
-
-	Short4 uuuu = texelFetch ? Short4(As<Int4>(u_)) : address(u_, state.addressingModeU, mipmap);
-	Short4 vvvv = texelFetch ? Short4(As<Int4>(v_)) : address(v_, state.addressingModeV, mipmap);
-	Short4 wwww = texelFetch ? Short4(As<Int4>(w_)) : address(w_, state.addressingModeW, mipmap);
+	Short4 uuuu = address(u_, state.addressingModeU, mipmap);
+	Short4 vvvv = address(v_, state.addressingModeV, mipmap);
+	Short4 wwww = address(w_, state.addressingModeW, mipmap);
 
 	Short4 cubeArrayId(0);
 	if(state.textureType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
@@ -741,7 +737,7 @@
 		cubeArrayId = address(cubeArrayCoord, state.addressingModeY, mipmap);
 	}
 
-	if(state.textureFilter == FILTER_POINT || texelFetch)
+	if(state.textureFilter == FILTER_POINT)
 	{
 		c_ = sampleTexel(uuuu, vvvv, wwww, offset, mipmap, cubeArrayId, sampleId, buffer, function);
 	}
@@ -1355,8 +1351,6 @@
 		case AddressingMode::ADDRESSING_BORDER:  // FIXME: Implement and test ADDRESSING_MIRROR, ADDRESSING_MIRRORONCE, ADDRESSING_BORDER
 			tmp = Min(Max(tmp, Int4(0)), whd - Int4(1));
 			break;
-		case ADDRESSING_TEXELFETCH:
-			break;
 		case AddressingMode::ADDRESSING_SEAMLESS:
 			ASSERT(false);  // Cube sampling doesn't support offset.
 		default:
@@ -1368,21 +1362,15 @@
 
 void SamplerCore::computeIndices(UInt index[4], Short4 uuuu, Short4 vvvv, Short4 wwww, Vector4f &offset, const Pointer<Byte> &mipmap, const Short4 &cubeArrayId, const Int4 &sampleId, SamplerFunction function)
 {
-	bool texelFetch = (function == Fetch);
 	bool hasOffset = (function.offset != 0);
 
-	if(!texelFetch)
-	{
-		uuuu = MulHigh(As<UShort4>(uuuu), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, width))));
-		vvvv = MulHigh(As<UShort4>(vvvv), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, height))));
-	}
+	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(hasOffset)
 	{
-		uuuu = applyOffset(uuuu, offset.x, *Pointer<Int4>(mipmap + OFFSET(Mipmap, width)),
-		                   texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeU);
-		vvvv = applyOffset(vvvv, offset.y, *Pointer<Int4>(mipmap + OFFSET(Mipmap, height)),
-		                   texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeV);
+		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;
@@ -1395,15 +1383,11 @@
 	{
 		if(state.textureType == VK_IMAGE_VIEW_TYPE_3D)
 		{
-			if(!texelFetch)
-			{
-				wwww = MulHigh(As<UShort4>(wwww), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth))));
-			}
+			wwww = MulHigh(As<UShort4>(wwww), UShort4(*Pointer<Int4>(mipmap + OFFSET(Mipmap, depth))));
 
 			if(hasOffset)
 			{
-				wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)),
-				                   texelFetch ? ADDRESSING_TEXELFETCH : state.addressingModeW);
+				wwww = applyOffset(wwww, offset.z, *Pointer<Int4>(mipmap + OFFSET(Mipmap, depth)), state.addressingModeW);
 			}
 		}
 
@@ -1423,22 +1407,6 @@
 		index[3] = Extract(As<Int2>(uuu2), 1);
 	}
 
-	if(texelFetch)
-	{
-		Int size = *Pointer<Int>(mipmap + OFFSET(Mipmap, sliceP));
-		if(hasThirdCoordinate())
-		{
-			size *= *Pointer<Int>(mipmap + OFFSET(Mipmap, depth));
-		}
-		UInt min = 0;
-		UInt max = size - 1;
-
-		for(int i = 0; i < 4; i++)
-		{
-			index[i] = Min(Max(index[i], min), max);
-		}
-	}
-
 	if(function.sample)
 	{
 		UInt4 sampleOffset = Min(As<UInt4>(sampleId), *Pointer<UInt4>(mipmap + OFFSET(Mipmap, sampleMax), 16)) *
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index d1d845c..1660da1 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -56,9 +56,6 @@
 		samplerState.mipmapFilter = convertMipmapMode(sampler);
 		samplerState.swizzle = imageDescriptor->swizzle;
 		samplerState.gatherComponent = instruction.gatherComponent;
-		samplerState.largeTexture = (imageDescriptor->extent.width > SHRT_MAX) ||
-		                            (imageDescriptor->extent.height > SHRT_MAX) ||
-		                            (imageDescriptor->extent.depth > SHRT_MAX);
 
 		if(sampler)
 		{
diff --git a/src/Vulkan/VkImageView.cpp b/src/Vulkan/VkImageView.cpp
index 37a8aa0..a351ab2 100644
--- a/src/Vulkan/VkImageView.cpp
+++ b/src/Vulkan/VkImageView.cpp
@@ -64,12 +64,6 @@
 	g = mapping.g;
 	b = mapping.b;
 	a = mapping.a;
-
-	// TODO(b/152224843): eliminate
-	auto extent = image->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);
-	large = (extent.width > SHRT_MAX) ||
-	        (extent.height > SHRT_MAX) ||
-	        (extent.depth > SHRT_MAX);
 }
 
 Identifier::Identifier(VkFormat fmt)
diff --git a/src/Vulkan/VkImageView.hpp b/src/Vulkan/VkImageView.hpp
index 1a2240e..7ab4bb3 100644
--- a/src/Vulkan/VkImageView.hpp
+++ b/src/Vulkan/VkImageView.hpp
@@ -53,7 +53,6 @@
 		uint32_t g : 3;
 		uint32_t b : 3;
 		uint32_t a : 3;
-		uint32_t large : 1;  // Has dimension larger than SHRT_MAX (see b/133429305).
 	};
 };