Vulkan: Plumb bound descriptor sets down to SpirvRoutine.

Choice of tests is slightly odd -- but there are a number of tests in
this group which *don't* use the derivative instructions (glslang is
smart enough to not emit them when the expression is known to be uniform).

Bug: b/126330097
Test: dEQP-VK.glsl.derivate.*
Test: dEQP-VK.ubo.*
Change-Id: I8864149104f2ea9b62c75ceae59da4ff8adebc32
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26548
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Device/Context.cpp b/src/Device/Context.cpp
index dc3ad68..877c721 100644
--- a/src/Device/Context.cpp
+++ b/src/Device/Context.cpp
@@ -156,6 +156,11 @@
 
 	void Context::init()
 	{
+		for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
+		{
+			descriptorSets[i] = nullptr;
+		}
+
 		// Set vertex streams to null stream
 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
 		{
diff --git a/src/Device/Context.hpp b/src/Device/Context.hpp
index 8645a1a..2f3a0f4 100644
--- a/src/Device/Context.hpp
+++ b/src/Device/Context.hpp
@@ -22,8 +22,11 @@
 #include "Vertex.hpp"
 #include "System/Types.hpp"
 
+#include <Vulkan/VkConfig.h>
+
 namespace vk
 {
+	class DescriptorSet;
 	class ImageView;
 	class PipelineLayout;
 } // namespace vk
@@ -182,6 +185,7 @@
 		int colorWriteActive(int index);
 		bool colorUsed();
 
+		vk::DescriptorSet *descriptorSets[vk::MAX_BOUND_DESCRIPTOR_SETS];
 		Stream input[MAX_VERTEX_INPUTS];
 		void *indexBuffer;
 
diff --git a/src/Device/QuadRasterizer.hpp b/src/Device/QuadRasterizer.hpp
index 456887d..a41464c 100644
--- a/src/Device/QuadRasterizer.hpp
+++ b/src/Device/QuadRasterizer.hpp
@@ -28,7 +28,7 @@
 		QuadRasterizer(const PixelProcessor::State &state, SpirvShader const *spirvShader);
 		virtual ~QuadRasterizer();
 
-		void generate();
+		virtual void generate();
 
 	protected:
 		Pointer<Byte> constants;
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 042d68d..0694105 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -310,6 +310,11 @@
 		draw->setupPrimitives = setupPrimitives;
 		draw->setupState = setupState;
 
+		for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
+		{
+			data->descriptorSets[i] = context->descriptorSets[i];
+		}
+
 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
 		{
 			data->input[i] = context->input[i].buffer;
diff --git a/src/Device/Renderer.hpp b/src/Device/Renderer.hpp
index eb93485..3e6e09f 100644
--- a/src/Device/Renderer.hpp
+++ b/src/Device/Renderer.hpp
@@ -26,6 +26,11 @@
 
 #include <list>
 
+namespace vk
+{
+	class DescriptorSet;
+}
+
 namespace sw
 {
 	class Clipper;
@@ -115,6 +120,8 @@
 	{
 		const Constants *constants;
 
+		vk::DescriptorSet *descriptorSets[vk::MAX_BOUND_DESCRIPTOR_SETS];
+
 		const void *input[MAX_VERTEX_INPUTS];
 		unsigned int stride[MAX_VERTEX_INPUTS];
 		Texture mipmap[TOTAL_IMAGE_UNITS];
diff --git a/src/Main/libX11.hpp b/src/Main/libX11.hpp
index c188386..b923d3d 100644
--- a/src/Main/libX11.hpp
+++ b/src/Main/libX11.hpp
@@ -48,7 +48,7 @@
 	int (*XShmPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, bool send_event);
 };
 
-#undef Bool
+#undef Bool // b/127920555
 
 class LibX11
 {
diff --git a/src/Pipeline/PixelRoutine.cpp b/src/Pipeline/PixelRoutine.cpp
index b904014..782d8b8 100644
--- a/src/Pipeline/PixelRoutine.cpp
+++ b/src/Pipeline/PixelRoutine.cpp
@@ -20,6 +20,11 @@
 #include "Device/QuadRasterizer.hpp"
 #include "Device/Primitive.hpp"
 #include "Vulkan/VkDebug.hpp"
+#include "Vulkan/VkPipelineLayout.hpp"
+
+#ifdef Bool
+#undef Bool // b/127920555
+#endif
 
 namespace sw
 {
@@ -49,6 +54,18 @@
 	{
 	}
 
+	void PixelRoutine::generate()
+	{
+		Pointer<Pointer<Byte>> descriptorSets = Pointer<Pointer<Byte>>(data + OFFSET(DrawData, descriptorSets));
+		auto numDescriptorSets = routine.pipelineLayout->getNumDescriptorSets();
+		for(unsigned int i = 0; i < numDescriptorSets; i++)
+		{
+			routine.descriptorSets[i] = descriptorSets[i];
+		}
+
+		QuadRasterizer::generate();
+	}
+
 	void PixelRoutine::quad(Pointer<Byte> cBuffer[RENDERTARGETS], Pointer<Byte> &zBuffer, Pointer<Byte> &sBuffer, Int cMask[4], Int &x, Int &y)
 	{
 		#if PERF_PROFILE
diff --git a/src/Pipeline/PixelRoutine.hpp b/src/Pipeline/PixelRoutine.hpp
index 824c7ce..7b3bb4a 100644
--- a/src/Pipeline/PixelRoutine.hpp
+++ b/src/Pipeline/PixelRoutine.hpp
@@ -31,6 +31,8 @@
 
 		virtual ~PixelRoutine();
 
+		void generate() override;
+
 	protected:
 		Float4 z[4]; // Multisampled z
 		Float4 w;    // Used as is
diff --git a/src/Pipeline/VertexProgram.cpp b/src/Pipeline/VertexProgram.cpp
index 9a40f79..d286718 100644
--- a/src/Pipeline/VertexProgram.cpp
+++ b/src/Pipeline/VertexProgram.cpp
@@ -20,6 +20,8 @@
 #include "System/Half.hpp"
 #include "Vulkan/VkDebug.hpp"
 
+#include "Vulkan/VkPipelineLayout.hpp"
+
 namespace sw
 {
 	VertexProgram::VertexProgram(
@@ -45,6 +47,13 @@
 		}
 
 		routine.pushConstants = data + OFFSET(DrawData, pushConstants);
+
+		Pointer<Pointer<Byte>> descriptorSets = Pointer<Pointer<Byte>>(data + OFFSET(DrawData, descriptorSets));
+		auto numDescriptorSets = routine.pipelineLayout->getNumDescriptorSets();
+		for(unsigned int i = 0; i < numDescriptorSets; i++)
+		{
+			routine.descriptorSets[i] = descriptorSets[i];
+		}
 	}
 
 	VertexProgram::~VertexProgram()
diff --git a/src/Reactor/Reactor.hpp b/src/Reactor/Reactor.hpp
index 1cdc32d..964674e 100644
--- a/src/Reactor/Reactor.hpp
+++ b/src/Reactor/Reactor.hpp
@@ -24,7 +24,7 @@
 
 #include <string>
 
-#undef Bool
+#undef Bool // b/127920555
 
 #if !defined(NDEBUG) && (REACTOR_LLVM_VERSION >= 7)
 #define ENABLE_RR_PRINT 1 // Enables RR_PRINT(), RR_WATCH()
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index f860482..dd74fa9 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -247,6 +247,12 @@
 		sw::Context context = pipeline->getContext();
 		executionState.bindVertexInputs(context, firstVertex);
 
+		const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS];
+		for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
+		{
+			context.descriptorSets[i] = reinterpret_cast<vk::DescriptorSet*>(boundDescriptorSets[i]);
+		}
+
 		context.pushConstants = executionState.pushConstants;
 
 		executionState.renderer->setContext(context);
@@ -286,6 +292,12 @@
 		sw::Context context = pipeline->getContext();
 		executionState.bindVertexInputs(context, vertexOffset);
 
+		const auto& boundDescriptorSets = executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_GRAPHICS];
+		for(int i = 0; i < vk::MAX_BOUND_DESCRIPTOR_SETS; i++)
+		{
+			context.descriptorSets[i] = reinterpret_cast<vk::DescriptorSet*>(boundDescriptorSets[i]);
+		}
+
 		context.pushConstants = executionState.pushConstants;
 
 		context.indexBuffer = Cast(executionState.indexBufferBinding.buffer)->getOffsetPointer(
diff --git a/src/WSI/libX11.hpp b/src/WSI/libX11.hpp
index c188386..b923d3d 100644
--- a/src/WSI/libX11.hpp
+++ b/src/WSI/libX11.hpp
@@ -48,7 +48,7 @@
 	int (*XShmPutImage)(Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height, bool send_event);
 };
 
-#undef Bool
+#undef Bool // b/127920555
 
 class LibX11
 {