Flatten required bits of imageview into SampledImageDescriptor

Bug: b/123244275
Bug: b/129523279
Change-Id: I46e59313ac152ba493fad78cfcdadbcd31566554
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/30929
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 85cde56..34db239 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -4586,7 +4586,6 @@
 		auto &coordinateType = getType(coordinate.type);
 
 		Pointer<Byte> sampler = samplerDescriptor + OFFSET(vk::SampledImageDescriptor, sampler); // vk::Sampler*
-		Pointer<Byte> imageView = *Pointer<Pointer<Byte>>(imageDescriptor + OFFSET(vk::SampledImageDescriptor, imageView)); // vk::ImageView*
 		Pointer<Byte> texture = imageDescriptor + OFFSET(vk::SampledImageDescriptor, texture);  // sw::Texture*
 
 		uint32_t imageOperands = spv::ImageOperandsMaskNone;
@@ -4720,7 +4719,7 @@
 			}
 		}
 
-		auto samplerFunc = Call(getImageSampler, instruction.parameters, imageView, sampler);
+		auto samplerFunc = Call(getImageSampler, instruction.parameters, imageDescriptor, sampler);
 
 		Array<SIMD::Float> out(4);
 		Call<ImageSampler>(samplerFunc, texture, sampler, &in[0], &out[0], state->routine->constants);
diff --git a/src/Pipeline/SpirvShader.hpp b/src/Pipeline/SpirvShader.hpp
index 8e3fb76..d26f1a6 100644
--- a/src/Pipeline/SpirvShader.hpp
+++ b/src/Pipeline/SpirvShader.hpp
@@ -46,6 +46,7 @@
 	class ImageView;
 	class Sampler;
 	class RenderPass;
+	struct SampledImageDescriptor;
 } // namespace vk
 
 namespace sw
@@ -955,7 +956,7 @@
 		// Returns the pair <significand, exponent>
 		std::pair<SIMD::Float, SIMD::Int> Frexp(RValue<SIMD::Float> val) const;
 
-		static ImageSampler *getImageSampler(uint32_t instruction, const vk::ImageView *imageView, const vk::Sampler *sampler);
+		static ImageSampler *getImageSampler(uint32_t instruction, vk::SampledImageDescriptor const *imageDescriptor, const vk::Sampler *sampler);
 		static ImageSampler *emitSamplerFunction(ImageInstruction instruction, const Sampler &samplerState);
 
 		// TODO(b/129523279): Eliminate conversion and use vk::Sampler members directly.
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index 4d9e677..59dcb57 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -37,34 +37,36 @@
 
 namespace sw {
 
-SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, const vk::ImageView *imageView, const vk::Sampler *sampler)
+SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, vk::SampledImageDescriptor const *imageDescriptor, const vk::Sampler *sampler)
 {
 	ImageInstruction instruction(inst);
-	ASSERT(imageView->id != 0 && (sampler->id != 0 || instruction.samplerMethod == Fetch));
+	ASSERT(imageDescriptor->imageViewId != 0 && (sampler->id != 0 || instruction.samplerMethod == Fetch));
 
 	// TODO(b/129523279): Move somewhere sensible.
 	static std::unordered_map<uint64_t, ImageSampler*> cache;
 	static std::mutex mutex;
 
 	// FIXME(b/129523279): Take instruction opcode and optional parameters into acount (SamplerMethod / SamplerOption).
-	auto key = (static_cast<uint64_t>(imageView->id) << 32) | static_cast<uint64_t>(sampler->id);
+	auto key = (static_cast<uint64_t>(imageDescriptor->imageViewId) << 32) | static_cast<uint64_t>(sampler->id);
 
 	std::unique_lock<std::mutex> lock(mutex);
 	auto it = cache.find(key);
 	if (it != cache.end()) { return it->second; }
 
+	auto type = imageDescriptor->type;
+
 	Sampler samplerState = {};
-	samplerState.textureType = convertTextureType(imageView->getType());
-	samplerState.textureFormat = imageView->getFormat(vk::ImageView::SAMPLING);
+	samplerState.textureType = convertTextureType(type);
+	samplerState.textureFormat = imageDescriptor->format;
 	samplerState.textureFilter = convertFilterMode(sampler);
 	samplerState.border = sampler->borderColor;
 
-	samplerState.addressingModeU = convertAddressingMode(0, sampler->addressModeU, imageView->getType());
-	samplerState.addressingModeV = convertAddressingMode(1, sampler->addressModeV, imageView->getType());
-	samplerState.addressingModeW = convertAddressingMode(2, sampler->addressModeW, imageView->getType());
+	samplerState.addressingModeU = convertAddressingMode(0, sampler->addressModeU, type);
+	samplerState.addressingModeV = convertAddressingMode(1, sampler->addressModeV, type);
+	samplerState.addressingModeW = convertAddressingMode(2, sampler->addressModeW, type);
 
 	samplerState.mipmapFilter = convertMipmapMode(sampler);
-	samplerState.swizzle = imageView->getComponentMapping();
+	samplerState.swizzle = imageDescriptor->swizzle;
 	samplerState.highPrecisionFiltering = false;
 	samplerState.compareEnable = (sampler->compareEnable == VK_TRUE);
 	samplerState.compareOp = sampler->compareOp;
diff --git a/src/Vulkan/VkDescriptorSetLayout.cpp b/src/Vulkan/VkDescriptorSetLayout.cpp
index 8116aba..060a773 100644
--- a/src/Vulkan/VkDescriptorSetLayout.cpp
+++ b/src/Vulkan/VkDescriptorSetLayout.cpp
@@ -319,9 +319,12 @@
 				imageSampler[i].updateSampler(vk::Cast(update->sampler));
 			}
 
-			imageSampler[i].imageView = imageView;
+			imageSampler[i].imageViewId = imageView->id;
 			imageSampler[i].extent = imageView->getMipLevelExtent(0);
 			imageSampler[i].arrayLayers = imageView->getSubresourceRange().layerCount;
+			imageSampler[i].type = imageView->getType();
+			imageSampler[i].swizzle = imageView->getComponentMapping();
+			imageSampler[i].format = imageView->getFormat(ImageView::SAMPLING);
 
 			auto &subresourceRange = imageView->getSubresourceRange();
 			int baseLevel = subresourceRange.baseMipLevel;
diff --git a/src/Vulkan/VkDescriptorSetLayout.hpp b/src/Vulkan/VkDescriptorSetLayout.hpp
index 22b0e0f..7a96b44 100644
--- a/src/Vulkan/VkDescriptorSetLayout.hpp
+++ b/src/Vulkan/VkDescriptorSetLayout.hpp
@@ -34,7 +34,10 @@
 	// TODO(b/129523279): Minimize to the data actually needed.
 	vk::Sampler sampler;
 
-	const vk::ImageView *imageView;
+	uint32_t imageViewId;
+	VkImageViewType type;
+	VkFormat format;
+	VkComponentMapping swizzle;
 	alignas(16) sw::Texture texture;
 	VkExtent3D extent; // Of base mip-level.
 	int arrayLayers;