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>