RenderPass begin and end

Implemented vkCmdBeginRenderPass and vkCmdEndRenderPass.
The RenderPass object begin and end are noop for now, but
the framebuffer gets cleared within vkCmdBeginRenderPass.

Bug b/119620965 b/118619338

Change-Id: I8e1f2932d9d52b3dcb5c10d4e60cba83b28bb95d
Reviewed-on: https://swiftshader-review.googlesource.com/c/23108
Reviewed-by: Corentin Wallez <cwallez@google.com>
Tested-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 1b74365..d2a50af 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -13,7 +13,9 @@
 // limitations under the License.
 
 #include "VkCommandBuffer.hpp"
+#include "VkFramebuffer.hpp"
 #include "VkImage.hpp"
+#include "VkRenderpass.hpp"
 
 #include <cstring>
 
@@ -24,7 +26,7 @@
 {
 public:
 	// FIXME (b/119421344): change the commandBuffer argument to a CommandBuffer state
-	virtual void play(CommandBuffer* commandBuffer) = 0;
+	virtual void play(CommandBuffer::ExecutionState& executionState) = 0;
 	virtual ~Command() {}
 };
 
@@ -47,9 +49,10 @@
 	}
 
 protected:
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
-		UNIMPLEMENTED();
+		Cast(renderPass)->begin();
+		Cast(framebuffer)->clear(clearValueCount, clearValues, renderArea);
 	}
 
 private:
@@ -68,9 +71,9 @@
 	}
 
 protected:
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
-		UNIMPLEMENTED();
+		Cast(executionState.renderpass)->end();
 	}
 
 private:
@@ -85,9 +88,9 @@
 	}
 
 protected:
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
-		UNIMPLEMENTED();
+		executionState.pipelines[pipelineBindPoint] = pipeline;
 	}
 
 private:
@@ -102,9 +105,9 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
-		UNIMPLEMENTED();
+		executionState.vertexInputBindings[binding] = { buffer, offset };
 	}
 
 	uint32_t binding;
@@ -118,7 +121,7 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
 		UNIMPLEMENTED();
 	}
@@ -133,7 +136,7 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
 		Cast(srcImage)->copyTo(dstImage, region);
 	}
@@ -151,7 +154,7 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
 		Cast(srcImage)->copyTo(dstBuffer, region);
 	}
@@ -169,7 +172,7 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
 		Cast(dstImage)->copyFrom(srcBuffer, region);
 	}
@@ -186,7 +189,7 @@
 	{
 	}
 
-	void play(CommandBuffer* commandBuffer)
+	void play(CommandBuffer::ExecutionState& executionState)
 	{
 		// This can currently be a noop. The sw::Surface locking/unlocking mechanism used by the renderer already takes care of
 		// making sure the read/writes always happen in order. Eventually, if we remove this synchronization mechanism, we can
@@ -205,9 +208,6 @@
 {
 	// FIXME (b/119409619): replace this vector by an allocator so we can control all memory allocations
 	commands = new std::vector<std::unique_ptr<Command> >();
-
-	pipelines[VK_PIPELINE_BIND_POINT_GRAPHICS] = VK_NULL_HANDLE;
-	pipelines[VK_PIPELINE_BIND_POINT_COMPUTE] = VK_NULL_HANDLE;
 }
 
 void CommandBuffer::destroy(const VkAllocationCallbacks* pAllocator)
@@ -591,14 +591,14 @@
 	UNIMPLEMENTED();
 }
 
-void CommandBuffer::submit()
+void CommandBuffer::submit(CommandBuffer::ExecutionState& executionState)
 {
 	// Perform recorded work
 	state = PENDING;
 
 	for(auto& command : *commands)
 	{
-		command->play(this);
+		command->play(executionState);
 	}
 
 	// After work is completed