Prevent rasterizing fragments outside the framebuffer

The scissor is now restricted to the framebuffer's size,
in order to avoid writing out of bounds of the image.

Vulkan 1.1 spec section 25.2. Scissor Test states that
"Rasterization does not produce fragments outside of the framebuffer"

Bug: b/141999739, angleproject:4060

Change-Id: Id0bce035b0ab9072f354b9f00be8d42577e4af54
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/38008
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Device/Renderer.cpp b/src/Device/Renderer.cpp
index 42dcfdd..c37150d 100644
--- a/src/Device/Renderer.cpp
+++ b/src/Device/Renderer.cpp
@@ -178,7 +178,7 @@
 	}
 
 	void Renderer::draw(const sw::Context* context, VkIndexType indexType, unsigned int count, int baseVertex,
-			TaskEvents *events, int instanceID, int viewID, void *indexBuffer,
+			TaskEvents *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D& framebufferExtent,
 			PushConstantStorage const & pushConstants, bool update)
 	{
 		if(count == 0) { return; }
@@ -384,10 +384,10 @@
 
 		// Scissor
 		{
-			data->scissorX0 = scissor.offset.x;
-			data->scissorX1 = scissor.offset.x + scissor.extent.width;
-			data->scissorY0 = scissor.offset.y;
-			data->scissorY1 = scissor.offset.y + scissor.extent.height;
+			data->scissorX0 = clamp<int>(scissor.offset.x, 0, framebufferExtent.width);
+			data->scissorX1 = clamp<int>(scissor.offset.x + scissor.extent.width, 0, framebufferExtent.width);
+			data->scissorY0 = clamp<int>(scissor.offset.y, 0, framebufferExtent.height);
+			data->scissorY1 = clamp<int>(scissor.offset.y + scissor.extent.height, 0, framebufferExtent.height);
 		}
 
 		// Push constants
diff --git a/src/Device/Renderer.hpp b/src/Device/Renderer.hpp
index 93bd9bf..ac38616 100644
--- a/src/Device/Renderer.hpp
+++ b/src/Device/Renderer.hpp
@@ -202,7 +202,7 @@
 		bool hasOcclusionQuery() const { return occlusionQuery != nullptr; }
 
 		void draw(const sw::Context* context, VkIndexType indexType, unsigned int count, int baseVertex,
-				TaskEvents *events, int instanceID, int viewID, void *indexBuffer,
+				TaskEvents *events, int instanceID, int viewID, void *indexBuffer, const VkExtent3D& framebufferExtent,
 				PushConstantStorage const & pushConstants, bool update = true);
 
 		// Viewport & Clipper
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 8562c2b..da411cd 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -617,6 +617,7 @@
 				{
 					executionState.renderer->draw(&context, executionState.indexType, indexBuffer.first, vertexOffset,
 												  executionState.events, instance, viewID, indexBuffer.second,
+												  executionState.renderPassFramebuffer->getExtent(),
 												  executionState.pushConstants);
 				}
 			}
diff --git a/src/Vulkan/VkFramebuffer.cpp b/src/Vulkan/VkFramebuffer.cpp
index ac9fc61..db29ba7 100644
--- a/src/Vulkan/VkFramebuffer.cpp
+++ b/src/Vulkan/VkFramebuffer.cpp
@@ -23,7 +23,8 @@
 
 Framebuffer::Framebuffer(const VkFramebufferCreateInfo* pCreateInfo, void* mem) :
 	attachmentCount(pCreateInfo->attachmentCount),
-	attachments(reinterpret_cast<ImageView**>(mem))
+	attachments(reinterpret_cast<ImageView**>(mem)),
+	extent{pCreateInfo->width, pCreateInfo->height, pCreateInfo->layers}
 {
 	for(uint32_t i = 0; i < attachmentCount; i++)
 	{
diff --git a/src/Vulkan/VkFramebuffer.hpp b/src/Vulkan/VkFramebuffer.hpp
index 0c4853b..ce9b16a 100644
--- a/src/Vulkan/VkFramebuffer.hpp
+++ b/src/Vulkan/VkFramebuffer.hpp
@@ -36,9 +36,12 @@
 	ImageView *getAttachment(uint32_t index) const;
 	void resolve(const RenderPass* renderPass, uint32_t subpassIndex);
 
+	const VkExtent3D& getExtent() const { return extent; }
+
 private:
-	uint32_t    attachmentCount = 0;
-	ImageView** attachments = nullptr;
+	uint32_t         attachmentCount = 0;
+	ImageView**      attachments = nullptr;
+	const VkExtent3D extent = {};
 };
 
 static inline Framebuffer* Cast(VkFramebuffer object)