vk::Queue: Lazily construct Renderers

They're big and take a while to initialize. Only construct them if we need them.
This also pushes the construction onto the queue, speeding up the main thread.

Bug: b/139010488
Change-Id: I2d1d25f24162339de62cea4d946532b1a2e346ca
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34330
Tested-by: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
diff --git a/src/Vulkan/VkQueue.cpp b/src/Vulkan/VkQueue.cpp
index 3aee60a..e654ca0 100644
--- a/src/Vulkan/VkQueue.cpp
+++ b/src/Vulkan/VkQueue.cpp
@@ -74,9 +74,9 @@
 namespace vk
 {
 
-Queue::Queue(Device* device) : renderer(device)
+Queue::Queue(Device* device) : device(device)
 {
-	queueThread = std::thread(TaskLoop, this);
+	queueThread = std::thread(&Queue::taskLoop, this);
 }
 
 Queue::~Queue()
@@ -110,13 +110,13 @@
 	return VK_SUCCESS;
 }
 
-void Queue::TaskLoop(vk::Queue* queue)
-{
-	queue->taskLoop();
-}
-
 void Queue::submitQueue(const Task& task)
 {
+	if (renderer == nullptr)
+	{
+		renderer.reset(new sw::Renderer(device));
+	}
+
 	for(uint32_t i = 0; i < task.submitCount; i++)
 	{
 		auto& submitInfo = task.pSubmits[i];
@@ -127,7 +127,7 @@
 
 		{
 			CommandBuffer::ExecutionState executionState;
-			executionState.renderer = &renderer;
+			executionState.renderer = renderer.get();
 			executionState.events = task.events;
 			for(uint32_t j = 0; j < submitInfo.commandBufferCount; j++)
 			{
@@ -150,7 +150,7 @@
 	{
 		// TODO: fix renderer signaling so that work submitted separately from (but before) a fence
 		// is guaranteed complete by the time the fence signals.
-		renderer.synchronize();
+		renderer->synchronize();
 		task.events->finish();
 	}
 }
diff --git a/src/Vulkan/VkQueue.hpp b/src/Vulkan/VkQueue.hpp
index 2926e10..6d5913e 100644
--- a/src/Vulkan/VkQueue.hpp
+++ b/src/Vulkan/VkQueue.hpp
@@ -69,7 +69,8 @@
 	void garbageCollect();
 	void submitQueue(const Task& task);
 
-	sw::Renderer renderer;
+	Device* device;
+	std::unique_ptr<sw::Renderer> renderer;
 	sw::Chan<Task> pending;
 	sw::Chan<VkSubmitInfo*> toDelete;
 	std::thread queueThread;