1 #ifndef COMPOSITOR_VK_H 2 #define COMPOSITOR_VK_H 3 4 #include <array> 5 #include <glm/glm.hpp> 6 #include <memory> 7 #include <optional> 8 #include <tuple> 9 #include <variant> 10 #include <vector> 11 12 #include "vulkan/cereal/common/goldfish_vk_dispatch.h" 13 #include "vulkan/vk_util.h" 14 15 #include "Hwc2.h" 16 17 class ComposeLayerVk { 18 public: 19 VkSampler m_vkSampler; 20 VkImageView m_vkImageView; 21 struct LayerTransform { 22 glm::mat4 pos; 23 glm::mat4 texcoord; 24 } m_layerTransform; 25 26 static std::unique_ptr<ComposeLayerVk> createFromHwc2ComposeLayer( 27 VkSampler, VkImageView, const ComposeLayer &, uint32_t cbWidth, 28 uint32_t cbHeight, uint32_t dstWidth, uint32_t dstHeight); 29 30 private: 31 ComposeLayerVk() = delete; 32 explicit ComposeLayerVk(VkSampler, VkImageView, const LayerTransform &); 33 }; 34 35 // If we want to apply transform to all layers to rotate/clip/position the 36 // virtual display, we should add that functionality here. 37 class Composition { 38 public: 39 std::vector<std::unique_ptr<ComposeLayerVk>> m_composeLayers; 40 41 Composition() = delete; 42 explicit Composition( 43 std::vector<std::unique_ptr<ComposeLayerVk>> composeLayers); 44 }; 45 46 struct CompositorVkBase 47 : public vk_util::RunSingleTimeCommand< 48 CompositorVkBase, 49 vk_util::FindMemoryType< 50 CompositorVkBase, 51 vk_util::RecordImageLayoutTransformCommands<CompositorVkBase>>> { 52 const goldfish_vk::VulkanDispatch &m_vk; 53 const VkDevice m_vkDevice; 54 const VkPhysicalDevice m_vkPhysicalDevice; 55 const VkQueue m_vkQueue; 56 VkDescriptorSetLayout m_vkDescriptorSetLayout; 57 VkPipelineLayout m_vkPipelineLayout; 58 VkRenderPass m_vkRenderPass; 59 VkPipeline m_graphicsVkPipeline; 60 VkBuffer m_vertexVkBuffer; 61 VkDeviceMemory m_vertexVkDeviceMemory; 62 VkBuffer m_indexVkBuffer; 63 VkDeviceMemory m_indexVkDeviceMemory; 64 std::vector<VkCommandBuffer> m_vkCommandBuffers; 65 VkDescriptorPool m_vkDescriptorPool; 66 std::vector<VkDescriptorSet> m_vkDescriptorSets; 67 std::vector<VkFramebuffer> m_renderTargetVkFrameBuffers; 68 69 VkCommandPool m_vkCommandPool; 70 CompositorVkBaseCompositorVkBase71 explicit CompositorVkBase(const goldfish_vk::VulkanDispatch &vk, 72 VkDevice device, VkPhysicalDevice physicalDevice, 73 VkQueue queue, VkCommandPool commandPool) 74 : m_vk(vk), 75 m_vkDevice(device), 76 m_vkPhysicalDevice(physicalDevice), 77 m_vkQueue(queue), 78 m_vkDescriptorSetLayout(VK_NULL_HANDLE), 79 m_vkPipelineLayout(VK_NULL_HANDLE), 80 m_vkRenderPass(VK_NULL_HANDLE), 81 m_graphicsVkPipeline(VK_NULL_HANDLE), 82 m_vertexVkBuffer(VK_NULL_HANDLE), 83 m_vertexVkDeviceMemory(VK_NULL_HANDLE), 84 m_indexVkBuffer(VK_NULL_HANDLE), 85 m_indexVkDeviceMemory(VK_NULL_HANDLE), 86 m_vkCommandBuffers(0), 87 m_vkDescriptorPool(VK_NULL_HANDLE), 88 m_vkDescriptorSets(0), 89 m_renderTargetVkFrameBuffers(0), 90 m_vkCommandPool(commandPool) {} 91 }; 92 93 class CompositorVk : protected CompositorVkBase { 94 public: 95 static std::unique_ptr<CompositorVk> create( 96 const goldfish_vk::VulkanDispatch &vk, VkDevice, VkPhysicalDevice, 97 VkQueue, VkFormat, VkImageLayout initialLayout, 98 VkImageLayout finalLayout, uint32_t width, uint32_t height, 99 const std::vector<VkImageView> &renderTargets, VkCommandPool); 100 static bool validatePhysicalDeviceFeatures( 101 const VkPhysicalDeviceFeatures2 &features); 102 static bool validateQueueFamilyProperties( 103 const VkQueueFamilyProperties &properties); 104 static bool enablePhysicalDeviceFeatures( 105 VkPhysicalDeviceFeatures2 &features); 106 static std::vector<const char *> getRequiredDeviceExtensions(); 107 108 ~CompositorVk(); 109 VkCommandBuffer getCommandBuffer(uint32_t i) const; 110 void setComposition(uint32_t i, std::unique_ptr<Composition> &&composition); 111 112 private: 113 explicit CompositorVk(const goldfish_vk::VulkanDispatch &, VkDevice, 114 VkPhysicalDevice, VkQueue, VkCommandPool, 115 uint32_t renderTargetWidth, 116 uint32_t renderTargetHeight); 117 void setUpGraphicsPipeline(uint32_t width, uint32_t height, 118 VkFormat renderTargetFormat, 119 VkImageLayout initialLayout, 120 VkImageLayout finalLayout); 121 void setUpVertexBuffers(); 122 void setUpFramebuffers(const std::vector<VkImageView> &, uint32_t width, 123 uint32_t height); 124 void setUpDescriptorSets(); 125 void setUpCommandBuffers(uint32_t width, uint32_t height); 126 void setUpEmptyComposition(VkFormat); 127 void setUpUniformBuffers(); 128 129 std::optional<std::tuple<VkBuffer, VkDeviceMemory>> createBuffer( 130 VkDeviceSize, VkBufferUsageFlags, VkMemoryPropertyFlags) const; 131 std::tuple<VkBuffer, VkDeviceMemory> createStagingBufferWithData( 132 const void *data, VkDeviceSize size) const; 133 void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize) const; 134 135 struct UniformBufferObject { 136 alignas(16) glm::mat4 pos_transform; 137 alignas(16) glm::mat4 texcoord_transform; 138 }; 139 140 struct Vertex { 141 alignas(8) glm::vec2 pos; 142 alignas(8) glm::vec2 texPos; 143 144 static VkVertexInputBindingDescription getBindingDescription(); 145 static std::array<VkVertexInputAttributeDescription, 2> 146 getAttributeDescription(); 147 }; 148 149 static const std::vector<Vertex> k_vertices; 150 static const std::vector<uint16_t> k_indices; 151 static const VkExtent2D k_emptyCompositionExtent; 152 153 uint32_t m_renderTargetWidth; 154 uint32_t m_renderTargetHeight; 155 VkImage m_emptyCompositionVkImage; 156 VkDeviceMemory m_emptyCompositionVkDeviceMemory; 157 VkImageView m_emptyCompositionVkImageView; 158 VkSampler m_emptyCompositionVkSampler; 159 160 std::vector<std::unique_ptr<Composition>> m_currentCompositions; 161 struct UniformStorage { 162 VkBuffer m_vkBuffer; 163 VkDeviceMemory m_vkDeviceMemory; 164 void *m_data; 165 VkDeviceSize m_stride; 166 } m_uniformStorage; 167 }; 168 169 #endif /* COMPOSITOR_VK_H */ 170