Graphics.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. #ifndef LOVE_GRAPHICS_VULKAN_GRAPHICS_H
  2. #define LOVE_GRAPHICS_VULKAN_GRAPHICS_H
  3. #include "graphics/Graphics.h"
  4. #include "StreamBuffer.h"
  5. #include "ShaderStage.h"
  6. #include "Shader.h"
  7. #include "Texture.h"
  8. #include <vulkan/vulkan.h>
  9. #include "vk_mem_alloc.h"
  10. #include <common/config.h>
  11. #include <optional>
  12. #include <iostream>
  13. #include <memory>
  14. namespace love {
  15. namespace graphics {
  16. namespace vulkan {
  17. struct GraphicsPipelineConfiguration {
  18. std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions;
  19. std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
  20. friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
  21. };
  22. struct DecriptorSetConfiguration {
  23. graphics::Texture* texture;
  24. graphics::StreamBuffer* buffer;
  25. bool operator==(const DecriptorSetConfiguration& conf2) {
  26. return this->texture == conf2.texture && this->buffer == conf2.buffer;
  27. }
  28. };
  29. struct BatchedDrawBuffers {
  30. StreamBuffer* vertexBuffer1;
  31. StreamBuffer* vertexBuffer2;
  32. StreamBuffer* indexBuffer;
  33. StreamBuffer* constantColorBuffer;
  34. ~BatchedDrawBuffers() {
  35. delete vertexBuffer1;
  36. delete vertexBuffer2;
  37. delete indexBuffer;
  38. delete constantColorBuffer;
  39. }
  40. };
  41. struct QueueFamilyIndices {
  42. std::optional<uint32_t> graphicsFamily;
  43. std::optional<uint32_t> presentFamily;
  44. bool isComplete() {
  45. return graphicsFamily.has_value() && presentFamily.has_value();
  46. }
  47. };
  48. struct SwapChainSupportDetails {
  49. VkSurfaceCapabilitiesKHR capabilities{};
  50. std::vector<VkSurfaceFormatKHR> formats;
  51. std::vector<VkPresentModeKHR> presentModes;
  52. };
  53. class Graphics final : public love::graphics::Graphics {
  54. public:
  55. Graphics() = default;
  56. virtual ~Graphics();
  57. const char* getName() const override;
  58. const VkDevice getDevice() const;
  59. const VkPhysicalDevice getPhysicalDevice() const;
  60. const VmaAllocator getVmaAllocator() const;
  61. // implementation for virtual functions
  62. love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data = nullptr) override {
  63. return new Texture(this, settings, data);
  64. }
  65. love::graphics::Buffer* newBuffer(const love::graphics::Buffer::Settings& settings, const std::vector<love::graphics::Buffer::DataDeclaration>& format, const void* data, size_t size, size_t arraylength) override;
  66. void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override { std::cout << "clear1 "; }
  67. void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override { std::cout << "clear2 "; }
  68. Matrix4 computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const override;
  69. void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override { std::cout << "discard "; }
  70. void present(void* screenshotCallbackdata) override;
  71. void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
  72. bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
  73. void unSetMode() override;
  74. void setActive(bool active) override { std::cout << "setActive "; }
  75. int getRequestedBackbufferMSAA() const override { std::cout << "getRequestedBackbufferMSAA "; return 0; }
  76. int getBackbufferMSAA() const override { std::cout << "getBackbufferMSAA "; return 0; }
  77. void setColor(Colorf c) override;
  78. void setScissor(const Rect& rect) override { std::cout << "setScissor "; }
  79. void setScissor() override { std::cout << "setScissor2 "; }
  80. void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { std::cout << "setStencilMode "; }
  81. void setDepthMode(CompareMode compare, bool write) override { std::cout << "setDepthMode "; }
  82. void setFrontFaceWinding(Winding winding) override { std::cout << "setFrontFaceWinding "; }
  83. void setColorMask(ColorChannelMask mask) override { std::cout << "setColorMask "; }
  84. void setBlendState(const BlendState& blend) override { std::cout << "setBlendState "; }
  85. void setPointSize(float size) override { std::cout << "setPointSize "; }
  86. void setWireframe(bool enable) override { std::cout << "setWireframe "; }
  87. PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
  88. bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB = false) override;
  89. Renderer getRenderer() const override { std::cout << "getRenderer "; return RENDERER_VULKAN; }
  90. bool usesGLSLES() const override { std::cout << "usesGLSES "; return false; }
  91. RendererInfo getRendererInfo() const override;
  92. void draw(const DrawCommand& cmd) override { std::cout << "draw "; }
  93. void draw(const DrawIndexedCommand& cmd) override;
  94. void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override;
  95. GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; };
  96. GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; }
  97. VkCommandBuffer beginSingleTimeCommands();
  98. void endSingleTimeCommands(VkCommandBuffer);
  99. protected:
  100. graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override {
  101. std::cout << "newShaderStageInternal ";
  102. return new ShaderStage(this, stage, source, gles, cachekey);
  103. }
  104. graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override {
  105. std::cout << "newShaderInternal ";
  106. return new Shader(stages);
  107. }
  108. graphics::StreamBuffer* newStreamBuffer(BufferUsage type, size_t size) override;
  109. bool dispatch(int x, int y, int z) override { std::cout << "dispatch "; return false; }
  110. void initCapabilities() override;
  111. void getAPIStats(int& shaderswitches) const override { std::cout << "getAPIStats "; }
  112. void setRenderTargetsInternal(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture) override { std::cout << "setRenderTargetsInternal "; }
  113. private:
  114. void createVulkanInstance();
  115. bool checkValidationSupport();
  116. void pickPhysicalDevice();
  117. int rateDeviceSuitability(VkPhysicalDevice device);
  118. QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
  119. void createLogicalDevice();
  120. void initVMA();
  121. void createSurface();
  122. bool checkDeviceExtensionSupport(VkPhysicalDevice device);
  123. SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
  124. VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
  125. VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
  126. VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
  127. void createSwapChain();
  128. void createImageViews();
  129. void createRenderPass();
  130. void createDefaultShaders();
  131. void createDescriptorSetLayout();
  132. void createDescriptorPool();
  133. std::vector<VkDescriptorSet> createDescriptorSets(DecriptorSetConfiguration);
  134. VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
  135. void createFramebuffers();
  136. void createCommandPool();
  137. void createCommandBuffers();
  138. void createSyncObjects();
  139. void createDefaultTexture();
  140. void createQuadIndexBuffer();
  141. void cleanup();
  142. void cleanupSwapChain();
  143. void recreateSwapChain();
  144. void startRecordingGraphicsCommands();
  145. void endRecordingGraphicsCommands();
  146. void ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration);
  147. graphics::StreamBuffer* createUniformBufferFromData(graphics::Shader::BuiltinUniformData);
  148. graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
  149. void setTexture(graphics::Texture* texture);
  150. void updatedBatchedDrawBuffers();
  151. VkDescriptorSet* getDescriptorSet(int currentFrame);
  152. graphics::StreamBuffer* getUniformBuffer();
  153. void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
  154. void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture);
  155. VkInstance instance = VK_NULL_HANDLE;
  156. VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
  157. VkDevice device = VK_NULL_HANDLE;
  158. VkQueue graphicsQueue = VK_NULL_HANDLE;
  159. VkQueue presentQueue = VK_NULL_HANDLE;
  160. VkSurfaceKHR surface = VK_NULL_HANDLE;
  161. VkSwapchainKHR swapChain = VK_NULL_HANDLE;
  162. std::vector<VkImage> swapChainImages;
  163. VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
  164. VkExtent2D swapChainExtent = VkExtent2D();
  165. std::vector<VkImageView> swapChainImageViews;
  166. VkDescriptorSetLayout descriptorSetLayout = VK_NULL_HANDLE;
  167. VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
  168. VkRenderPass renderPass = VK_NULL_HANDLE;
  169. VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
  170. std::vector<std::pair<GraphicsPipelineConfiguration, VkPipeline>> graphicsPipelines; // FIXME improve performance by using a hash map
  171. std::vector<VkPipelineLayout> graphicsPipelineLayouts;
  172. std::vector<VkFramebuffer> swapChainFramBuffers;
  173. VkCommandPool commandPool = VK_NULL_HANDLE;
  174. std::vector<VkCommandBuffer> commandBuffers;
  175. VkClearValue clearColor = { {{0.0f, 0.0f, 0.0f, 1.0f}} };
  176. VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
  177. std::vector<VkSemaphore> imageAvailableSemaphores;
  178. std::vector<VkSemaphore> renderFinishedSemaphores;
  179. std::vector<VkFence> inFlightFences;
  180. std::vector<VkFence> imagesInFlight;
  181. size_t currentFrame = 0;
  182. uint32_t imageIndex = 0;
  183. bool framebufferResized = false;
  184. VmaAllocator vmaAllocator = VK_NULL_HANDLE;
  185. std::unique_ptr<Texture> standardTexture = nullptr;
  186. std::unique_ptr<StreamBuffer> quadIndexBuffer = nullptr;
  187. // we need an array of draw buffers, since the frames are being rendered asynchronously
  188. // and we can't (or shouldn't) update the contents of the buffers while they're still in flight / being rendered.
  189. std::vector<BatchedDrawBuffers> batchedDrawBuffers;
  190. graphics::Texture* currentTexture = nullptr;
  191. std::vector<std::pair<graphics::Shader::BuiltinUniformData, graphics::StreamBuffer*>> uniformBufferMap;
  192. std::vector<std::pair<DecriptorSetConfiguration, std::vector<VkDescriptorSet>>> descriptorSetsMap;
  193. };
  194. }
  195. }
  196. }
  197. #endif