Wire up indirect dispatch

Bug: b/118619338
Change-Id: Ia03cbc8908efcbb5264f9fbdc91f06eac964c396
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/27908
Tested-by: Chris Forbes <chrisforbes@google.com>
Presubmit-Ready: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkCommandBuffer.cpp b/src/Vulkan/VkCommandBuffer.cpp
index 447075e..65e8331 100644
--- a/src/Vulkan/VkCommandBuffer.cpp
+++ b/src/Vulkan/VkCommandBuffer.cpp
@@ -185,6 +185,32 @@
 	uint32_t groupCountZ;
 };
 
+class DispatchIndirect : public CommandBuffer::Command
+{
+public:
+	DispatchIndirect(VkBuffer buffer, VkDeviceSize offset) :
+			buffer(buffer), offset(offset)
+	{
+	}
+
+protected:
+	void play(CommandBuffer::ExecutionState& executionState) override
+	{
+		auto cmd = reinterpret_cast<VkDispatchIndirectCommand const *>(Cast(buffer)->getOffsetPointer(offset));
+
+		ComputePipeline* pipeline = static_cast<ComputePipeline*>(
+				executionState.pipelines[VK_PIPELINE_BIND_POINT_COMPUTE]);
+		pipeline->run(cmd->x, cmd->y, cmd->z,
+					  MAX_BOUND_DESCRIPTOR_SETS,
+					  executionState.boundDescriptorSets[VK_PIPELINE_BIND_POINT_COMPUTE],
+					  executionState.pushConstants);
+	}
+
+private:
+	VkBuffer buffer;
+	VkDeviceSize offset;
+};
+
 struct VertexBufferBind : public CommandBuffer::Command
 {
 	VertexBufferBind(uint32_t pBinding, const VkBuffer pBuffer, const VkDeviceSize pOffset) :
@@ -981,7 +1007,7 @@
 
 void CommandBuffer::dispatchIndirect(VkBuffer buffer, VkDeviceSize offset)
 {
-	UNIMPLEMENTED("dispatchIndirect");
+	addCommand<DispatchIndirect>(buffer, offset);
 }
 
 void CommandBuffer::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, uint32_t regionCount, const VkBufferCopy* pRegions)