• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Amber Authors.
2 // Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SRC_VULKAN_PIPELINE_H_
17 #define SRC_VULKAN_PIPELINE_H_
18 
19 #include <memory>
20 #include <string>
21 #include <unordered_map>
22 #include <vector>
23 
24 #include "amber/result.h"
25 #include "amber/vulkan_header.h"
26 #include "src/cast_hash.h"
27 #include "src/engine.h"
28 #include "src/vulkan/buffer_backed_descriptor.h"
29 #include "src/vulkan/command_buffer.h"
30 #include "src/vulkan/push_constant.h"
31 #include "src/vulkan/resource.h"
32 
33 namespace amber {
34 
35 class BufferCommand;
36 
37 namespace vulkan {
38 
39 class ComputePipeline;
40 class Device;
41 class GraphicsPipeline;
42 class RayTracingPipeline;
43 
44 /// Base class for a pipeline in Vulkan.
45 class Pipeline {
46  public:
47   virtual ~Pipeline();
48 
IsGraphics()49   bool IsGraphics() const { return pipeline_type_ == PipelineType::kGraphics; }
IsCompute()50   bool IsCompute() const { return pipeline_type_ == PipelineType::kCompute; }
IsRayTracing()51   bool IsRayTracing() const {
52     return pipeline_type_ == PipelineType::kRayTracing;
53   }
54 
55   GraphicsPipeline* AsGraphics();
56   ComputePipeline* AsCompute();
57   RayTracingPipeline* AsRayTracingPipeline();
58 
59   Result AddBufferDescriptor(const BufferCommand*);
60   Result AddSamplerDescriptor(const SamplerCommand*);
61   Result AddTLASDescriptor(const TLASCommand*);
62 
63   /// Add |buffer| data to the push constants at |offset|.
64   Result AddPushConstantBuffer(const Buffer* buf, uint32_t offset);
65 
66   /// Reads back the contents of resources of all descriptors to a
67   /// buffer data object and put it into buffer data queue in host.
68   Result ReadbackDescriptorsToHostDataQueue();
69 
70   std::unordered_map<Buffer*, std::unique_ptr<Resource>>&
GetDescriptorTransferResources()71   GetDescriptorTransferResources() {
72     return descriptor_transfer_resources_;
73   }
74 
SetEntryPointName(VkShaderStageFlagBits stage,const std::string & entry)75   void SetEntryPointName(VkShaderStageFlagBits stage,
76                          const std::string& entry) {
77     entry_points_[stage] = entry;
78   }
79 
GetCommandBuffer()80   CommandBuffer* GetCommandBuffer() const { return command_.get(); }
GetDevice()81   Device* GetDevice() const { return device_; }
GetBlases()82   virtual BlasesMap* GetBlases() { return nullptr; }
GetTlases()83   virtual TlasesMap* GetTlases() { return nullptr; }
GetVkPipelineLayout()84   VkPipelineLayout GetVkPipelineLayout() const { return pipeline_layout_; }
GetVkPipeline()85   VkPipeline GetVkPipeline() const { return pipeline_; }
86 
87  protected:
88   Pipeline(
89       PipelineType type,
90       Device* device,
91       uint32_t fence_timeout_ms,
92       bool pipeline_runtime_layer_enabled,
93       const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info,
94       VkPipelineCreateFlags create_flags = 0);
95 
96   /// Initializes the pipeline.
97   Result Initialize(CommandPool* pool);
98 
99   Result GetDescriptorSlot(uint32_t desc_set,
100                            uint32_t binding,
101                            Descriptor** desc);
102   void UpdateDescriptorSetsIfNeeded();
103 
104   // This functions are used in benchmarking when 'TIMED_EXECUTION' option is
105   // specifed.
106   void CreateTimingQueryObjectIfNeeded(bool is_timed_execution);
107   void DestroyTimingQueryObjectIfNeeded();
108   void BeginTimerQuery();
109   void EndTimerQuery();
110 
111   Result SendDescriptorDataToDeviceIfNeeded();
112   void BindVkDescriptorSets(const VkPipelineLayout& pipeline_layout);
113 
114   /// Records a Vulkan command for push contant.
115   Result RecordPushConstant(const VkPipelineLayout& pipeline_layout);
116 
GetVkShaderStageInfo()117   const std::vector<VkPipelineShaderStageCreateInfo>& GetVkShaderStageInfo()
118       const {
119     return shader_stage_info_;
120   }
121 
122   const char* GetEntryPointName(VkShaderStageFlagBits stage) const;
GetFenceTimeout()123   uint32_t GetFenceTimeout() const { return fence_timeout_ms_; }
GetPipelineRuntimeLayerEnabled()124   bool GetPipelineRuntimeLayerEnabled() const {
125     return pipeline_runtime_layer_enabled_;
126   }
127 
128   Result CreateVkPipelineLayout(VkPipelineLayout* pipeline_layout);
129 
SetVkPipelineLayout(VkPipelineLayout pipeline_layout)130   void SetVkPipelineLayout(VkPipelineLayout pipeline_layout) {
131     assert(pipeline_layout_ == VK_NULL_HANDLE);
132     pipeline_layout_ = pipeline_layout;
133   }
134 
SetVkPipeline(VkPipeline pipeline)135   void SetVkPipeline(VkPipeline pipeline) {
136     assert(pipeline_ == VK_NULL_HANDLE);
137     pipeline_ = pipeline;
138   }
139 
140   VkQueryPool query_pool_ = VK_NULL_HANDLE;
141   VkPipeline pipeline_ = VK_NULL_HANDLE;
142   VkPipelineLayout pipeline_layout_ = VK_NULL_HANDLE;
143 
144   Device* device_ = nullptr;
145   std::unique_ptr<CommandBuffer> command_;
146   VkPipelineCreateFlags create_flags_ = 0;
147 
148  private:
149   struct DescriptorSetInfo {
150     bool empty = true;
151     VkDescriptorSetLayout layout = VK_NULL_HANDLE;
152     VkDescriptorPool pool = VK_NULL_HANDLE;
153     VkDescriptorSet vk_desc_set = VK_NULL_HANDLE;
154     std::vector<std::unique_ptr<Descriptor>> descriptors;
155   };
156 
157   /// Creates Vulkan descriptor related objects.
158   Result CreateVkDescriptorRelatedObjectsIfNeeded();
159   Result CreateDescriptorSetLayouts();
160   Result CreateDescriptorPools();
161   Result CreateDescriptorSets();
162   /// Adds a buffer used by a descriptor. The added buffers are be stored in
163   /// |descriptor_buffers_| vector in the order they are added.
164   Result AddDescriptorBuffer(Buffer* amber_buffer);
165 
166   PipelineType pipeline_type_;
167   std::vector<DescriptorSetInfo> descriptor_set_info_;
168   std::vector<VkPipelineShaderStageCreateInfo> shader_stage_info_;
169   std::unordered_map<Buffer*, std::unique_ptr<Resource>>
170       descriptor_transfer_resources_;
171   /// Buffers used by descriptors (buffer descriptors and image descriptors).
172   std::vector<Buffer*> descriptor_buffers_;
173 
174   uint32_t fence_timeout_ms_ = 1000;
175   bool pipeline_runtime_layer_enabled_ = false;
176   bool descriptor_related_objects_already_created_ = false;
177   std::unordered_map<VkShaderStageFlagBits,
178                      std::string,
179                      CastHash<VkShaderStageFlagBits>>
180       entry_points_;
181 
182   std::unique_ptr<PushConstant> push_constant_;
183   bool in_timed_execution_ = false;
184 };
185 
186 }  // namespace vulkan
187 }  // namespace amber
188 
189 #endif  // SRC_VULKAN_PIPELINE_H_
190