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