Initial implementation of Pipeline, PipelineLayout

Basic shell classes for Pipeline, PipelineLayout

b/118386749

Change-Id: I1ec82d1bf2334d5e2cd338d96eff63f3714db198
Reviewed-on: https://swiftshader-review.googlesource.com/c/21888
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Vulkan/VkDestroy.h b/src/Vulkan/VkDestroy.h
index 99a16e9..15e2192 100644
--- a/src/Vulkan/VkDestroy.h
+++ b/src/Vulkan/VkDestroy.h
@@ -20,6 +20,8 @@
 #include "VkEvent.hpp"
 #include "VkFence.hpp"
 #include "VkInstance.hpp"
+#include "VkPipeline.hpp"
+#include "VkPipelineLayout.hpp"
 #include "VkPhysicalDevice.hpp"
 #include "VkQueue.hpp"
 #include "VkSemaphore.hpp"
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
new file mode 100644
index 0000000..04b96d8
--- /dev/null
+++ b/src/Vulkan/VkPipeline.cpp
@@ -0,0 +1,47 @@
+// Copyright 2018 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.
+
+#include "VkPipeline.hpp"
+
+namespace vk
+{
+
+GraphicsPipeline::GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem)
+{
+}
+
+void GraphicsPipeline::destroy(const VkAllocationCallbacks* pAllocator)
+{
+}
+
+size_t GraphicsPipeline::ComputeRequiredAllocationSize(const VkGraphicsPipelineCreateInfo* pCreateInfo)
+{
+	return 0;
+}
+
+ComputePipeline::ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem)
+{
+}
+
+void ComputePipeline::destroy(const VkAllocationCallbacks* pAllocator)
+{
+}
+
+
+size_t ComputePipeline::ComputeRequiredAllocationSize(const VkComputePipelineCreateInfo* pCreateInfo)
+{
+	return 0;
+}
+
+} // namespace vk
diff --git a/src/Vulkan/VkPipeline.hpp b/src/Vulkan/VkPipeline.hpp
new file mode 100644
index 0000000..725e109
--- /dev/null
+++ b/src/Vulkan/VkPipeline.hpp
@@ -0,0 +1,73 @@
+// Copyright 2018 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 VK_PIPELINE_HPP_
+#define VK_PIPELINE_HPP_
+
+#include "VkObject.hpp"
+
+namespace vk
+{
+
+class Pipeline
+{
+public:
+	virtual void destroy(const VkAllocationCallbacks* pAllocator) = 0;
+#ifndef NDEBUG
+	virtual VkPipelineBindPoint bindPoint() const = 0;
+#endif
+};
+
+class GraphicsPipeline : public Pipeline, public Object<GraphicsPipeline, VkPipeline>
+{
+public:
+	GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem);
+	~GraphicsPipeline() = delete;
+	void destroy(const VkAllocationCallbacks* pAllocator) override;
+
+#ifndef NDEBUG
+	VkPipelineBindPoint bindPoint() const override
+	{
+		return VK_PIPELINE_BIND_POINT_GRAPHICS;
+	}
+#endif
+
+	static size_t ComputeRequiredAllocationSize(const VkGraphicsPipelineCreateInfo* pCreateInfo);
+};
+
+class ComputePipeline : public Pipeline, public Object<ComputePipeline, VkPipeline>
+{
+public:
+	ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem);
+	~ComputePipeline() = delete;
+	void destroy(const VkAllocationCallbacks* pAllocator) override;
+
+#ifndef NDEBUG
+	VkPipelineBindPoint bindPoint() const override
+	{
+		return VK_PIPELINE_BIND_POINT_COMPUTE;
+	}
+#endif
+
+	static size_t ComputeRequiredAllocationSize(const VkComputePipelineCreateInfo* pCreateInfo);
+};
+
+static inline Pipeline* Cast(VkPipeline object)
+{
+	return reinterpret_cast<Pipeline*>(object);
+}
+
+} // namespace vk
+
+#endif // VK_PIPELINE_HPP_
diff --git a/src/Vulkan/VkPipelineLayout.cpp b/src/Vulkan/VkPipelineLayout.cpp
new file mode 100644
index 0000000..6757b05f
--- /dev/null
+++ b/src/Vulkan/VkPipelineLayout.cpp
@@ -0,0 +1,33 @@
+// Copyright 2018 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.
+
+#include "VkPipelineLayout.hpp"
+
+namespace vk
+{
+
+PipelineLayout::PipelineLayout(const VkPipelineLayoutCreateInfo* pCreateInfo, void* mem)
+{
+}
+
+void PipelineLayout::destroy(const VkAllocationCallbacks* pAllocator)
+{
+}
+
+size_t PipelineLayout::ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo* pCreateInfo)
+{
+	return 0;
+}
+
+} // namespace vk
diff --git a/src/Vulkan/VkPipelineLayout.hpp b/src/Vulkan/VkPipelineLayout.hpp
new file mode 100644
index 0000000..d220df2
--- /dev/null
+++ b/src/Vulkan/VkPipelineLayout.hpp
@@ -0,0 +1,42 @@
+// Copyright 2018 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 VK_PIPELINE_LAYOUT_HPP_
+#define VK_PIPELINE_LAYOUT_HPP_
+
+#include "VkObject.hpp"
+
+namespace vk
+{
+
+class PipelineLayout : public Object<PipelineLayout, VkPipelineLayout>
+{
+public:
+	PipelineLayout(const VkPipelineLayoutCreateInfo* pCreateInfo, void* mem);
+	~PipelineLayout() = delete;
+	void destroy(const VkAllocationCallbacks* pAllocator);
+
+	static size_t ComputeRequiredAllocationSize(const VkPipelineLayoutCreateInfo* pCreateInfo);
+
+private:
+};
+
+static inline PipelineLayout* Cast(VkPipelineLayout object)
+{
+	return reinterpret_cast<PipelineLayout*>(object);
+}
+
+} // namespace vk
+
+#endif // VK_PIPELINE_LAYOUT_HPP_
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 035379b..84bceab 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -14,8 +14,8 @@
 
 #include "VkBuffer.hpp"
 #include "VkBufferView.hpp"
-#include "VkConfig.h"
 #include "VkCommandBuffer.hpp"
+#include "VkConfig.h"
 #include "VkDebug.hpp"
 #include "VkDestroy.h"
 #include "VkDevice.hpp"
@@ -25,12 +25,14 @@
 #include "VkGetProcAddress.h"
 #include "VkInstance.hpp"
 #include "VkPhysicalDevice.hpp"
+#include "VkPipeline.hpp"
+#include "VkPipelineLayout.hpp"
 #include "VkQueue.hpp"
 #include "VkSemaphore.hpp"
 
+#include <algorithm>
 #include <cstring>
 #include <string>
-#include <algorithm>
 
 extern "C"
 {
@@ -793,9 +795,31 @@
 	TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, uint32_t createInfoCount = %d, const VkGraphicsPipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipeline* pPipelines = 0x%X)",
 		    device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
 
-	UNIMPLEMENTED();
+	if(pipelineCache != VK_NULL_HANDLE)
+	{
+		UNIMPLEMENTED();
+	}
 
-	return VK_SUCCESS;
+	VkResult errorResult = VK_SUCCESS;
+	for(uint32_t i = 0; i < createInfoCount; i++)
+	{
+		VkResult result = vk::GraphicsPipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i]);
+		if(result != VK_SUCCESS)
+		{
+			// According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
+			// "When an application attempts to create many pipelines in a single command,
+			//  it is possible that some subset may fail creation. In that case, the
+			//  corresponding entries in the pPipelines output array will be filled with
+			//  VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
+			//  out of memory errors), the vkCreate*Pipelines commands will return an
+			//  error code. The implementation will attempt to create all pipelines, and
+			//  only return VK_NULL_HANDLE values for those that actually failed."
+			pPipelines[i] = VK_NULL_HANDLE;
+			errorResult = result;
+		}
+	}
+
+	return errorResult;
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t createInfoCount, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator, VkPipeline* pPipelines)
@@ -803,9 +827,31 @@
 	TRACE("(VkDevice device = 0x%X, VkPipelineCache pipelineCache = 0x%X, uint32_t createInfoCount = %d, const VkComputePipelineCreateInfo* pCreateInfos, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipeline* pPipelines = 0x%X)",
 		device, pipelineCache, createInfoCount, pCreateInfos, pAllocator, pPipelines);
 
-	UNIMPLEMENTED();
+	if(pipelineCache != VK_NULL_HANDLE)
+	{
+		UNIMPLEMENTED();
+	}
 
-	return VK_SUCCESS;
+	VkResult errorResult = VK_SUCCESS;
+	for(uint32_t i = 0; i < createInfoCount; i++)
+	{
+		VkResult result = vk::ComputePipeline::Create(pAllocator, &pCreateInfos[i], &pPipelines[i]);
+		if(result != VK_SUCCESS)
+		{
+			// According to the Vulkan spec, section 9.4. Multiple Pipeline Creation
+			// "When an application attempts to create many pipelines in a single command,
+			//  it is possible that some subset may fail creation. In that case, the
+			//  corresponding entries in the pPipelines output array will be filled with
+			//  VK_NULL_HANDLE values. If any pipeline fails creation (for example, due to
+			//  out of memory errors), the vkCreate*Pipelines commands will return an
+			//  error code. The implementation will attempt to create all pipelines, and
+			//  only return VK_NULL_HANDLE values for those that actually failed."
+			pPipelines[i] = VK_NULL_HANDLE;
+			errorResult = result;
+		}
+	}
+
+	return errorResult;
 }
 
 VKAPI_ATTR void VKAPI_CALL vkDestroyPipeline(VkDevice device, VkPipeline pipeline, const VkAllocationCallbacks* pAllocator)
@@ -813,7 +859,7 @@
 	TRACE("(VkDevice device = 0x%X, VkPipeline pipeline = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
 		    device, pipeline, pAllocator);
 
-	UNIMPLEMENTED();
+	vk::destroy(pipeline, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkCreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkPipelineLayout* pPipelineLayout)
@@ -821,9 +867,12 @@
 	TRACE("(VkDevice device = 0x%X, const VkPipelineLayoutCreateInfo* pCreateInfo = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X, VkPipelineLayout* pPipelineLayout = 0x%X)",
 		    device, pCreateInfo, pAllocator, pPipelineLayout);
 
-	UNIMPLEMENTED();
+	if(pCreateInfo->pNext || pCreateInfo->flags)
+	{
+		UNIMPLEMENTED();
+	}
 
-	return VK_SUCCESS;
+	return vk::PipelineLayout::Create(pAllocator, pCreateInfo, pPipelineLayout);
 }
 
 VKAPI_ATTR void VKAPI_CALL vkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, const VkAllocationCallbacks* pAllocator)
@@ -831,7 +880,7 @@
 	TRACE("(VkDevice device = 0x%X, VkPipelineLayout pipelineLayout = 0x%X, const VkAllocationCallbacks* pAllocator = 0x%X)",
 		    device, pipelineLayout, pAllocator);
 
-	UNIMPLEMENTED();
+	vk::destroy(pipelineLayout, pAllocator);
 }
 
 VKAPI_ATTR VkResult VKAPI_CALL vkCreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSampler* pSampler)
diff --git a/src/Vulkan/vulkan.vcxproj b/src/Vulkan/vulkan.vcxproj
index 5258dc6..b57b6d8 100644
--- a/src/Vulkan/vulkan.vcxproj
+++ b/src/Vulkan/vulkan.vcxproj
@@ -109,6 +109,8 @@
     <ClCompile Include="VkInstance.cpp" />

     <ClCompile Include="VkMemory.cpp" />

     <ClCompile Include="VkPhysicalDevice.cpp" />

+    <ClCompile Include="VkPipeline.cpp" />

+    <ClCompile Include="VkPipelineLayout.cpp" />

     <ClCompile Include="VkPromotedExtensions.cpp" />

     <ClCompile Include="VkQueue.cpp" />

     <ClCompile Include="..\Device\Blitter.cpp" />

@@ -197,6 +199,8 @@
     <ClInclude Include="VkMemory.h" />

     <ClInclude Include="VkObject.hpp" />

     <ClInclude Include="VkPhysicalDevice.hpp" />

+    <ClInclude Include="VkPipeline.hpp" />

+    <ClInclude Include="VkPipelineLayout.hpp" />

     <ClInclude Include="VkQueue.hpp" />

     <ClInclude Include="VkSemaphore.hpp" />

     <ClInclude Include="..\Device\Blitter.hpp" />

diff --git a/src/Vulkan/vulkan.vcxproj.filters b/src/Vulkan/vulkan.vcxproj.filters
index 297d7e3..12784c0 100644
--- a/src/Vulkan/vulkan.vcxproj.filters
+++ b/src/Vulkan/vulkan.vcxproj.filters
@@ -225,6 +225,12 @@
     <ClCompile Include="VkPhysicalDevice.cpp">

       <Filter>Source Files\Vulkan</Filter>

     </ClCompile>

+    <ClCompile Include="VkPipeline.cpp">

+      <Filter>Source Files\Vulkan</Filter>

+    </ClCompile>

+    <ClCompile Include="VkPipelineLayout.cpp">

+      <Filter>Source Files\Vulkan</Filter>

+    </ClCompile>

     <ClCompile Include="VkPromotedExtensions.cpp">

       <Filter>Source Files\Vulkan</Filter>

     </ClCompile>

@@ -272,6 +278,12 @@
     <ClInclude Include="VkObject.hpp">

       <Filter>Header Files\Vulkan</Filter>

     </ClInclude>

+    <ClInclude Include="VkPipeline.hpp">

+      <Filter>Header Files\Vulkan</Filter>

+    </ClInclude>

+    <ClInclude Include="VkPipelineLayout.hpp">

+      <Filter>Header Files\Vulkan</Filter>

+    </ClInclude>

     <ClInclude Include="VkPhysicalDevice.hpp">

       <Filter>Header Files\Vulkan</Filter>

     </ClInclude>