Vulkan: Very rough first implementation of compute shaders

This is by no means finished:
* ComputeProgram holds the codegen and the invoke logic. ComputeProgram::run() should probably be moved somewhere else (maybe Renderer?).
* ComputeProgram::run() is currently fully single threaded.
* The compute routines are currently not cached.

With that said, this is enough to start passing a whole bunch of dEQP compute tests.

Test: *.compute.*
Bug: b/126871859
Change-Id: Ic6a76826b2fec0d34d54e0bed564b360ea0610c0
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26551
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/ComputeProgram.hpp b/src/Pipeline/ComputeProgram.hpp
new file mode 100644
index 0000000..d547a91
--- /dev/null
+++ b/src/Pipeline/ComputeProgram.hpp
@@ -0,0 +1,75 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef sw_ComputeProgram_hpp
+#define sw_ComputeProgram_hpp
+
+#include "SpirvShader.hpp"
+
+#include "Reactor/Reactor.hpp"
+
+#include <functional>
+
+namespace vk
+{
+	class PipelineLayout;
+} // namespace vk
+
+namespace sw
+{
+
+	using namespace rr;
+
+	class DescriptorSetsLayout;
+
+	// ComputeProgram builds a SPIR-V compute shader.
+	class ComputeProgram : public Function<Void(Pointer<Byte>)>
+	{
+	public:
+		ComputeProgram(SpirvShader const *spirvShader, vk::PipelineLayout const *pipelineLayout);
+
+		virtual ~ComputeProgram();
+
+		// generate builds the shader program.
+		void generate();
+
+		// run executes the compute shader routine for all workgroups.
+		// TODO(bclayton): This probably does not belong here. Consider moving.
+		static void run(
+			Routine *routine,
+			uint32_t numDescriptorSets, void** descriptorSets,
+			uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
+
+	protected:
+		void emit();
+
+		void setInputBuiltin(spv::BuiltIn id, std::function<void(const SpirvShader::BuiltinMapping& builtin, Array<Float4>& value)> cb);
+
+		Pointer<Byte> data; // argument 0
+
+		struct Data
+		{
+			void** descriptorSets;
+			uint4 numWorkgroups;
+			uint4 workgroupID;
+		};
+
+		SpirvRoutine routine;
+		SpirvShader const * const shader;
+		vk::PipelineLayout const * const pipelineLayout;
+	};
+
+} // namespace sw
+
+#endif   // sw_ComputeProgram_hpp