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