• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Amber Authors.
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 SRC_VULKAN_PIPELINE_H_
16 #define SRC_VULKAN_PIPELINE_H_
17 
18 #include <memory>
19 #include <string>
20 #include <unordered_map>
21 #include <vector>
22 
23 #include "amber/result.h"
24 #include "amber/vulkan_header.h"
25 #include "src/cast_hash.h"
26 #include "src/engine.h"
27 #include "src/vulkan/buffer_backed_descriptor.h"
28 #include "src/vulkan/command_buffer.h"
29 #include "src/vulkan/push_constant.h"
30 
31 namespace amber {
32 
33 class BufferCommand;
34 
35 namespace vulkan {
36 
37 class ComputePipeline;
38 class Device;
39 class GraphicsPipeline;
40 
41 /// Base class for a pipeline in Vulkan.
42 class Pipeline {
43  public:
44   virtual ~Pipeline();
45 
IsGraphics()46   bool IsGraphics() const { return pipeline_type_ == PipelineType::kGraphics; }
IsCompute()47   bool IsCompute() const { return pipeline_type_ == PipelineType::kCompute; }
48 
49   GraphicsPipeline* AsGraphics();
50   ComputePipeline* AsCompute();
51 
52   Result AddBufferDescriptor(const BufferCommand*);
53   Result AddSamplerDescriptor(const SamplerCommand*);
54 
55   /// Add |buffer| data to the push constants at |offset|.
56   Result AddPushConstantBuffer(const Buffer* buf, uint32_t offset);
57 
58   /// Reads back the contents of resources of all descriptors to a
59   /// buffer data object and put it into buffer data queue in host.
60   Result ReadbackDescriptorsToHostDataQueue();
61 
SetEntryPointName(VkShaderStageFlagBits stage,const std::string & entry)62   void SetEntryPointName(VkShaderStageFlagBits stage,
63                          const std::string& entry) {
64     entry_points_[stage] = entry;
65   }
66 
GetCommandBuffer()67   CommandBuffer* GetCommandBuffer() const { return command_.get(); }
GetDevice()68   Device* GetDevice() const { return device_; }
69 
70  protected:
71   Pipeline(
72       PipelineType type,
73       Device* device,
74       uint32_t fence_timeout_ms,
75       const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info);
76 
77   /// Initializes the pipeline.
78   Result Initialize(CommandPool* pool);
79 
80   Result GetDescriptorSlot(uint32_t desc_set,
81                            uint32_t binding,
82                            Descriptor** desc);
83   void UpdateDescriptorSetsIfNeeded();
84 
85   Result SendDescriptorDataToDeviceIfNeeded();
86   void BindVkDescriptorSets(const VkPipelineLayout& pipeline_layout);
87 
88   /// Records a Vulkan command for push contant.
89   Result RecordPushConstant(const VkPipelineLayout& pipeline_layout);
90 
GetVkShaderStageInfo()91   const std::vector<VkPipelineShaderStageCreateInfo>& GetVkShaderStageInfo()
92       const {
93     return shader_stage_info_;
94   }
95 
96   const char* GetEntryPointName(VkShaderStageFlagBits stage) const;
GetFenceTimeout()97   uint32_t GetFenceTimeout() const { return fence_timeout_ms_; }
98 
99   Result CreateVkPipelineLayout(VkPipelineLayout* pipeline_layout);
100 
101   Device* device_ = nullptr;
102   std::unique_ptr<CommandBuffer> command_;
103 
104  private:
105   struct DescriptorSetInfo {
106     bool empty = true;
107     VkDescriptorSetLayout layout = VK_NULL_HANDLE;
108     VkDescriptorPool pool = VK_NULL_HANDLE;
109     VkDescriptorSet vk_desc_set = VK_NULL_HANDLE;
110     std::vector<std::unique_ptr<Descriptor>> descriptors;
111   };
112 
113   /// Creates Vulkan descriptor related objects.
114   Result CreateVkDescriptorRelatedObjectsIfNeeded();
115   Result CreateDescriptorSetLayouts();
116   Result CreateDescriptorPools();
117   Result CreateDescriptorSets();
118 
119   PipelineType pipeline_type_;
120   std::vector<DescriptorSetInfo> descriptor_set_info_;
121   std::vector<VkPipelineShaderStageCreateInfo> shader_stage_info_;
122 
123   uint32_t fence_timeout_ms_ = 1000;
124   bool descriptor_related_objects_already_created_ = false;
125   std::unordered_map<VkShaderStageFlagBits,
126                      std::string,
127                      CastHash<VkShaderStageFlagBits>>
128       entry_points_;
129 
130   std::unique_ptr<PushConstant> push_constant_;
131 };
132 
133 }  // namespace vulkan
134 }  // namespace amber
135 
136 #endif  // SRC_VULKAN_PIPELINE_H_
137