• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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