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 bool pipeline_runtime_layer_enabled, 82 const std::vector<VkPipelineShaderStageCreateInfo>& shader_stage_info); 83 84 /// Initializes the pipeline. 85 Result Initialize(CommandPool* pool); 86 87 Result GetDescriptorSlot(uint32_t desc_set, 88 uint32_t binding, 89 Descriptor** desc); 90 void UpdateDescriptorSetsIfNeeded(); 91 92 Result SendDescriptorDataToDeviceIfNeeded(); 93 void BindVkDescriptorSets(const VkPipelineLayout& pipeline_layout); 94 95 /// Records a Vulkan command for push contant. 96 Result RecordPushConstant(const VkPipelineLayout& pipeline_layout); 97 GetVkShaderStageInfo()98 const std::vector<VkPipelineShaderStageCreateInfo>& GetVkShaderStageInfo() 99 const { 100 return shader_stage_info_; 101 } 102 103 const char* GetEntryPointName(VkShaderStageFlagBits stage) const; GetFenceTimeout()104 uint32_t GetFenceTimeout() const { return fence_timeout_ms_; } GetPipelineRuntimeLayerEnabled()105 bool GetPipelineRuntimeLayerEnabled() 106 const { return pipeline_runtime_layer_enabled_; } 107 108 Result CreateVkPipelineLayout(VkPipelineLayout* pipeline_layout); 109 110 Device* device_ = nullptr; 111 std::unique_ptr<CommandBuffer> command_; 112 113 private: 114 struct DescriptorSetInfo { 115 bool empty = true; 116 VkDescriptorSetLayout layout = VK_NULL_HANDLE; 117 VkDescriptorPool pool = VK_NULL_HANDLE; 118 VkDescriptorSet vk_desc_set = VK_NULL_HANDLE; 119 std::vector<std::unique_ptr<Descriptor>> descriptors; 120 }; 121 122 /// Creates Vulkan descriptor related objects. 123 Result CreateVkDescriptorRelatedObjectsIfNeeded(); 124 Result CreateDescriptorSetLayouts(); 125 Result CreateDescriptorPools(); 126 Result CreateDescriptorSets(); 127 /// Adds a buffer used by a descriptor. The added buffers are be stored in 128 /// |descriptor_buffers_| vector in the order they are added. 129 Result AddDescriptorBuffer(Buffer* amber_buffer); 130 131 PipelineType pipeline_type_; 132 std::vector<DescriptorSetInfo> descriptor_set_info_; 133 std::vector<VkPipelineShaderStageCreateInfo> shader_stage_info_; 134 std::unordered_map<Buffer*, std::unique_ptr<Resource>> 135 descriptor_transfer_resources_; 136 /// Buffers used by descriptors (buffer descriptors and image descriptors). 137 std::vector<Buffer*> descriptor_buffers_; 138 139 uint32_t fence_timeout_ms_ = 1000; 140 bool pipeline_runtime_layer_enabled_ = false; 141 bool descriptor_related_objects_already_created_ = false; 142 std::unordered_map<VkShaderStageFlagBits, 143 std::string, 144 CastHash<VkShaderStageFlagBits>> 145 entry_points_; 146 147 std::unique_ptr<PushConstant> push_constant_; 148 }; 149 150 } // namespace vulkan 151 } // namespace amber 152 153 #endif // SRC_VULKAN_PIPELINE_H_ 154