#ifndef _GRAPHICS_PIPELINE_VULKAN_H #define _GRAPHICS_PIPELINE_VULKAN_H #include "graphics-pipeline.hpp" #include #include #include #include "vulkan-utils.hpp" using namespace std; // TODO: Maybe change the name of this struct so I can call the list something other than descriptorInfoList struct DescriptorInfo { VkDescriptorType type; VkShaderStageFlags stageFlags; // Only one of the below properties should be set vector* bufferDataList; VkDescriptorImageInfo* imageData; }; class GraphicsPipeline_Vulkan : public GraphicsPipeline { public: GraphicsPipeline_Vulkan(VkPhysicalDevice physicalDevice, VkDevice device, VkRenderPass renderPass, Viewport viewport, int vertexSize); ~GraphicsPipeline_Vulkan(); void updateRenderPass(VkRenderPass renderPass); template void bindData(const vector& vertices, const vector& indices, VkCommandPool commandPool, VkQueue graphicsQueue); void createVertexBuffer(const void* bufferData, int vertexSize, VkCommandPool commandPool, VkQueue graphicsQueue); void createIndexBuffer(const void* bufferData, int indexSize, VkCommandPool commandPool, VkQueue graphicsQueue); // Maybe I should rename these to addVertexAttribute (addVaryingAttribute) and addUniformAttribute void addAttribute(VkFormat format, size_t offset); void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, vector* bufferData); void addDescriptorInfo(VkDescriptorType type, VkShaderStageFlags stageFlags, VkDescriptorImageInfo* imageData); void createPipeline(string vertShaderFile, string fragShaderFile); void createDescriptorSetLayout(); void createDescriptorPool(vector& swapChainImages); void createDescriptorSets(vector& swapChainImages); void createRenderCommands(VkCommandBuffer& commandBuffer, uint32_t currentImage); template bool addObject(const vector& vertices, vector& indices, VkCommandPool commandPool, VkQueue graphicsQueue); void cleanup(); void cleanupBuffers(); private: VkShaderModule createShaderModule(const vector& code); vector readFile(const string& filename); VkPhysicalDevice physicalDevice; VkDevice device; VkRenderPass renderPass; VkPipeline pipeline; VkPipelineLayout pipelineLayout; VkVertexInputBindingDescription bindingDescription; vector attributeDescriptions; vector descriptorInfoList; VkDescriptorSetLayout descriptorSetLayout; VkDescriptorPool descriptorPool; vector descriptorSets; size_t numVertices; size_t vertexCapacity; VkBuffer vertexBuffer; VkDeviceMemory vertexBufferMemory; size_t numIndices; size_t indexCapacity; VkBuffer indexBuffer; VkDeviceMemory indexBufferMemory; }; // TODO: Probably better to template the whole class // TODO: Change the index type to uint32_t and check the Vulkan Tutorial loading model section as a reference // TODO: combine this function and the constructor since I call this right after the constructor anyway template void GraphicsPipeline_Vulkan::bindData(const vector& vertices, const vector& indices, VkCommandPool commandPool, VkQueue graphicsQueue) { numVertices = vertices.size(); vertexCapacity = numVertices * 2; createVertexBuffer(vertices.data(), sizeof(VertexType), commandPool, graphicsQueue); numIndices = indices.size(); indexCapacity = numIndices * 2; createIndexBuffer(indices.data(), sizeof(uint16_t), commandPool, graphicsQueue); } template bool GraphicsPipeline_Vulkan::addObject(const vector& vertices, vector& indices, VkCommandPool commandPool, VkQueue graphicsQueue) { if (numVertices + vertices.size() > vertexCapacity) { throw runtime_error("ERROR: Need to resize vertex buffers"); } else if (numIndices + indices.size() > indexCapacity) { throw runtime_error("ERROR: Need to resize index buffers"); } else { for (uint16_t& idx : indices) { idx += numVertices; } VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, vertices, vertexBuffer, numVertices, graphicsQueue); numVertices += vertices.size(); VulkanUtils::copyDataToBuffer(device, physicalDevice, commandPool, indices, indexBuffer, numIndices, graphicsQueue); numIndices += indices.size(); return true; } return false; } #endif // _GRAPHICS_PIPELINE_VULKAN_H