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
24namespace sw
25{
26 class ComputeProgram;
27 class SpirvShader;
28}
29
30namespace vk
31{
32
33class PipelineCache;
34class PipelineLayout;
35class ShaderModule;
36class Device;
37
38class Pipeline
39{
40public:
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
66protected:
67 PipelineLayout const *layout = nullptr;
68
69 const bool robustBufferAccess = true;
70};
71
72class GraphicsPipeline : public Pipeline, public ObjectBase<GraphicsPipeline, VkPipeline>
73{
74public:
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
99private:
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
113class ComputePipeline : public Pipeline, public ObjectBase<ComputePipeline, VkPipeline>
114{
115public:
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
138protected:
139 std::shared_ptr<sw::SpirvShader> shader;
140 std::shared_ptr<sw::ComputeProgram> program;
141};
142
143static inline Pipeline* Cast(VkPipeline object)
144{
145 return Pipeline::Cast(object);
146}
147
148} // namespace vk
149
150#endif // VK_PIPELINE_HPP_
151