You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
170 lines
6.0 KiB
170 lines
6.0 KiB
#ifndef COMPOSITOR_VK_H
|
|
#define COMPOSITOR_VK_H
|
|
|
|
#include <array>
|
|
#include <glm/glm.hpp>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <tuple>
|
|
#include <variant>
|
|
#include <vector>
|
|
|
|
#include "vulkan/cereal/common/goldfish_vk_dispatch.h"
|
|
#include "vulkan/vk_util.h"
|
|
|
|
#include "Hwc2.h"
|
|
|
|
class ComposeLayerVk {
|
|
public:
|
|
VkSampler m_vkSampler;
|
|
VkImageView m_vkImageView;
|
|
struct LayerTransform {
|
|
glm::mat4 pos;
|
|
glm::mat4 texcoord;
|
|
} m_layerTransform;
|
|
|
|
static std::unique_ptr<ComposeLayerVk> createFromHwc2ComposeLayer(
|
|
VkSampler, VkImageView, const ComposeLayer &, uint32_t cbWidth,
|
|
uint32_t cbHeight, uint32_t dstWidth, uint32_t dstHeight);
|
|
|
|
private:
|
|
ComposeLayerVk() = delete;
|
|
explicit ComposeLayerVk(VkSampler, VkImageView, const LayerTransform &);
|
|
};
|
|
|
|
// If we want to apply transform to all layers to rotate/clip/position the
|
|
// virtual display, we should add that functionality here.
|
|
class Composition {
|
|
public:
|
|
std::vector<std::unique_ptr<ComposeLayerVk>> m_composeLayers;
|
|
|
|
Composition() = delete;
|
|
explicit Composition(
|
|
std::vector<std::unique_ptr<ComposeLayerVk>> composeLayers);
|
|
};
|
|
|
|
struct CompositorVkBase
|
|
: public vk_util::RunSingleTimeCommand<
|
|
CompositorVkBase,
|
|
vk_util::FindMemoryType<
|
|
CompositorVkBase,
|
|
vk_util::RecordImageLayoutTransformCommands<CompositorVkBase>>> {
|
|
const goldfish_vk::VulkanDispatch &m_vk;
|
|
const VkDevice m_vkDevice;
|
|
const VkPhysicalDevice m_vkPhysicalDevice;
|
|
const VkQueue m_vkQueue;
|
|
VkDescriptorSetLayout m_vkDescriptorSetLayout;
|
|
VkPipelineLayout m_vkPipelineLayout;
|
|
VkRenderPass m_vkRenderPass;
|
|
VkPipeline m_graphicsVkPipeline;
|
|
VkBuffer m_vertexVkBuffer;
|
|
VkDeviceMemory m_vertexVkDeviceMemory;
|
|
VkBuffer m_indexVkBuffer;
|
|
VkDeviceMemory m_indexVkDeviceMemory;
|
|
std::vector<VkCommandBuffer> m_vkCommandBuffers;
|
|
VkDescriptorPool m_vkDescriptorPool;
|
|
std::vector<VkDescriptorSet> m_vkDescriptorSets;
|
|
std::vector<VkFramebuffer> m_renderTargetVkFrameBuffers;
|
|
|
|
VkCommandPool m_vkCommandPool;
|
|
|
|
explicit CompositorVkBase(const goldfish_vk::VulkanDispatch &vk,
|
|
VkDevice device, VkPhysicalDevice physicalDevice,
|
|
VkQueue queue, VkCommandPool commandPool)
|
|
: m_vk(vk),
|
|
m_vkDevice(device),
|
|
m_vkPhysicalDevice(physicalDevice),
|
|
m_vkQueue(queue),
|
|
m_vkDescriptorSetLayout(VK_NULL_HANDLE),
|
|
m_vkPipelineLayout(VK_NULL_HANDLE),
|
|
m_vkRenderPass(VK_NULL_HANDLE),
|
|
m_graphicsVkPipeline(VK_NULL_HANDLE),
|
|
m_vertexVkBuffer(VK_NULL_HANDLE),
|
|
m_vertexVkDeviceMemory(VK_NULL_HANDLE),
|
|
m_indexVkBuffer(VK_NULL_HANDLE),
|
|
m_indexVkDeviceMemory(VK_NULL_HANDLE),
|
|
m_vkCommandBuffers(0),
|
|
m_vkDescriptorPool(VK_NULL_HANDLE),
|
|
m_vkDescriptorSets(0),
|
|
m_renderTargetVkFrameBuffers(0),
|
|
m_vkCommandPool(commandPool) {}
|
|
};
|
|
|
|
class CompositorVk : protected CompositorVkBase {
|
|
public:
|
|
static std::unique_ptr<CompositorVk> create(
|
|
const goldfish_vk::VulkanDispatch &vk, VkDevice, VkPhysicalDevice,
|
|
VkQueue, VkFormat, VkImageLayout initialLayout,
|
|
VkImageLayout finalLayout, uint32_t width, uint32_t height,
|
|
const std::vector<VkImageView> &renderTargets, VkCommandPool);
|
|
static bool validatePhysicalDeviceFeatures(
|
|
const VkPhysicalDeviceFeatures2 &features);
|
|
static bool validateQueueFamilyProperties(
|
|
const VkQueueFamilyProperties &properties);
|
|
static bool enablePhysicalDeviceFeatures(
|
|
VkPhysicalDeviceFeatures2 &features);
|
|
static std::vector<const char *> getRequiredDeviceExtensions();
|
|
|
|
~CompositorVk();
|
|
VkCommandBuffer getCommandBuffer(uint32_t i) const;
|
|
void setComposition(uint32_t i, std::unique_ptr<Composition> &&composition);
|
|
|
|
private:
|
|
explicit CompositorVk(const goldfish_vk::VulkanDispatch &, VkDevice,
|
|
VkPhysicalDevice, VkQueue, VkCommandPool,
|
|
uint32_t renderTargetWidth,
|
|
uint32_t renderTargetHeight);
|
|
void setUpGraphicsPipeline(uint32_t width, uint32_t height,
|
|
VkFormat renderTargetFormat,
|
|
VkImageLayout initialLayout,
|
|
VkImageLayout finalLayout);
|
|
void setUpVertexBuffers();
|
|
void setUpFramebuffers(const std::vector<VkImageView> &, uint32_t width,
|
|
uint32_t height);
|
|
void setUpDescriptorSets();
|
|
void setUpCommandBuffers(uint32_t width, uint32_t height);
|
|
void setUpEmptyComposition(VkFormat);
|
|
void setUpUniformBuffers();
|
|
|
|
std::optional<std::tuple<VkBuffer, VkDeviceMemory>> createBuffer(
|
|
VkDeviceSize, VkBufferUsageFlags, VkMemoryPropertyFlags) const;
|
|
std::tuple<VkBuffer, VkDeviceMemory> createStagingBufferWithData(
|
|
const void *data, VkDeviceSize size) const;
|
|
void copyBuffer(VkBuffer src, VkBuffer dst, VkDeviceSize) const;
|
|
|
|
struct UniformBufferObject {
|
|
alignas(16) glm::mat4 pos_transform;
|
|
alignas(16) glm::mat4 texcoord_transform;
|
|
};
|
|
|
|
struct Vertex {
|
|
alignas(8) glm::vec2 pos;
|
|
alignas(8) glm::vec2 texPos;
|
|
|
|
static VkVertexInputBindingDescription getBindingDescription();
|
|
static std::array<VkVertexInputAttributeDescription, 2>
|
|
getAttributeDescription();
|
|
};
|
|
|
|
static const std::vector<Vertex> k_vertices;
|
|
static const std::vector<uint16_t> k_indices;
|
|
static const VkExtent2D k_emptyCompositionExtent;
|
|
|
|
uint32_t m_renderTargetWidth;
|
|
uint32_t m_renderTargetHeight;
|
|
VkImage m_emptyCompositionVkImage;
|
|
VkDeviceMemory m_emptyCompositionVkDeviceMemory;
|
|
VkImageView m_emptyCompositionVkImageView;
|
|
VkSampler m_emptyCompositionVkSampler;
|
|
|
|
std::vector<std::unique_ptr<Composition>> m_currentCompositions;
|
|
struct UniformStorage {
|
|
VkBuffer m_vkBuffer;
|
|
VkDeviceMemory m_vkDeviceMemory;
|
|
void *m_data;
|
|
VkDeviceSize m_stride;
|
|
} m_uniformStorage;
|
|
};
|
|
|
|
#endif /* COMPOSITOR_VK_H */
|