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