1 | // Copyright 2018 The SwiftShader Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #ifndef VK_PIPELINE_HPP_ |
16 | #define VK_PIPELINE_HPP_ |
17 | |
18 | #include "VkObject.hpp" |
19 | #include "Vulkan/VkDescriptorSet.hpp" |
20 | #include "Vulkan/VkPipelineCache.hpp" |
21 | #include "Device/Renderer.hpp" |
22 | #include <memory> |
23 | |
24 | namespace sw |
25 | { |
26 | class ComputeProgram; |
27 | class SpirvShader; |
28 | } |
29 | |
30 | namespace vk |
31 | { |
32 | |
33 | class PipelineCache; |
34 | class PipelineLayout; |
35 | class ShaderModule; |
36 | class Device; |
37 | |
38 | class Pipeline |
39 | { |
40 | public: |
41 | Pipeline(PipelineLayout const *layout, const Device *device); |
42 | virtual ~Pipeline() = default; |
43 | |
44 | operator VkPipeline() |
45 | { |
46 | return vk::TtoVkT<Pipeline, VkPipeline>(this); |
47 | } |
48 | |
49 | static inline Pipeline* Cast(VkPipeline object) |
50 | { |
51 | return vk::VkTtoT<Pipeline, VkPipeline>(object); |
52 | } |
53 | |
54 | void destroy(const VkAllocationCallbacks* pAllocator) |
55 | { |
56 | destroyPipeline(pAllocator); |
57 | } |
58 | |
59 | virtual void destroyPipeline(const VkAllocationCallbacks* pAllocator) = 0; |
60 | #ifndef NDEBUG |
61 | virtual VkPipelineBindPoint bindPoint() const = 0; |
62 | #endif |
63 | |
64 | PipelineLayout const * getLayout() const { return layout; } |
65 | |
66 | protected: |
67 | PipelineLayout const *layout = nullptr; |
68 | |
69 | const bool robustBufferAccess = true; |
70 | }; |
71 | |
72 | class GraphicsPipeline : public Pipeline, public ObjectBase<GraphicsPipeline, VkPipeline> |
73 | { |
74 | public: |
75 | GraphicsPipeline(const VkGraphicsPipelineCreateInfo* pCreateInfo, void* mem, const Device *device); |
76 | virtual ~GraphicsPipeline() = default; |
77 | |
78 | void destroyPipeline(const VkAllocationCallbacks* pAllocator) override; |
79 | |
80 | #ifndef NDEBUG |
81 | VkPipelineBindPoint bindPoint() const override |
82 | { |
83 | return VK_PIPELINE_BIND_POINT_GRAPHICS; |
84 | } |
85 | #endif |
86 | |
87 | static size_t ComputeRequiredAllocationSize(const VkGraphicsPipelineCreateInfo* pCreateInfo); |
88 | |
89 | void compileShaders(const VkAllocationCallbacks* pAllocator, const VkGraphicsPipelineCreateInfo* pCreateInfo, PipelineCache* pipelineCache); |
90 | |
91 | uint32_t computePrimitiveCount(uint32_t vertexCount) const; |
92 | const sw::Context& getContext() const; |
93 | const VkRect2D& getScissor() const; |
94 | const VkViewport& getViewport() const; |
95 | const sw::Color<float>& getBlendConstants() const; |
96 | bool hasDynamicState(VkDynamicState dynamicState) const; |
97 | bool hasPrimitiveRestartEnable() const { return primitiveRestartEnable; } |
98 | |
99 | private: |
100 | void setShader(const VkShaderStageFlagBits& stage, const std::shared_ptr<sw::SpirvShader> spirvShader); |
101 | const std::shared_ptr<sw::SpirvShader> getShader(const VkShaderStageFlagBits& stage) const; |
102 | std::shared_ptr<sw::SpirvShader> vertexShader; |
103 | std::shared_ptr<sw::SpirvShader> fragmentShader; |
104 | |
105 | uint32_t dynamicStateFlags = 0; |
106 | bool primitiveRestartEnable = false; |
107 | sw::Context context; |
108 | VkRect2D scissor; |
109 | VkViewport viewport; |
110 | sw::Color<float> blendConstants; |
111 | }; |
112 | |
113 | class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPipeline> |
114 | { |
115 | public: |
116 | ComputePipeline(const VkComputePipelineCreateInfo* pCreateInfo, void* mem, const Device *device); |
117 | virtual ~ComputePipeline() = default; |
118 | |
119 | void destroyPipeline(const VkAllocationCallbacks* pAllocator) override; |
120 | |
121 | #ifndef NDEBUG |
122 | VkPipelineBindPoint bindPoint() const override |
123 | { |
124 | return VK_PIPELINE_BIND_POINT_COMPUTE; |
125 | } |
126 | #endif |
127 | |
128 | static size_t ComputeRequiredAllocationSize(const VkComputePipelineCreateInfo* pCreateInfo); |
129 | |
130 | void compileShaders(const VkAllocationCallbacks* pAllocator, const VkComputePipelineCreateInfo* pCreateInfo, PipelineCache* pipelineCache); |
131 | |
132 | void run(uint32_t baseGroupX, uint32_t baseGroupY, uint32_t baseGroupZ, |
133 | uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ, |
134 | vk::DescriptorSet::Bindings const &descriptorSets, |
135 | vk::DescriptorSet::DynamicOffsets const &descriptorDynamicOffsets, |
136 | sw::PushConstantStorage const &pushConstants); |
137 | |
138 | protected: |
139 | std::shared_ptr<sw::SpirvShader> shader; |
140 | std::shared_ptr<sw::ComputeProgram> program; |
141 | }; |
142 | |
143 | static inline Pipeline* Cast(VkPipeline object) |
144 | { |
145 | return Pipeline::Cast(object); |
146 | } |
147 | |
148 | } // namespace vk |
149 | |
150 | #endif // VK_PIPELINE_HPP_ |
151 | |