Graphics.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  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. #include <functional>
  15. namespace love {
  16. namespace graphics {
  17. namespace vulkan {
  18. struct GraphicsPipelineConfiguration {
  19. std::vector<VkVertexInputBindingDescription> vertexInputBindingDescriptions;
  20. std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
  21. Shader* shader = nullptr;
  22. PrimitiveType primitiveType = PRIMITIVE_MAX_ENUM;
  23. VkPolygonMode polygonMode = VK_POLYGON_MODE_FILL;
  24. BlendState blendState;
  25. ColorChannelMask colorChannelMask;
  26. Winding winding;
  27. CullMode cullmode;
  28. VkFormat framebufferFormat;
  29. float viewportWidth;
  30. float viewportHeight;
  31. std::optional<Rect> scissorRect;
  32. friend static bool operator==(const GraphicsPipelineConfiguration& first, const GraphicsPipelineConfiguration& other);
  33. };
  34. struct BatchedDrawBuffers {
  35. StreamBuffer* vertexBuffer1;
  36. StreamBuffer* vertexBuffer2;
  37. StreamBuffer* indexBuffer;
  38. StreamBuffer* constantColorBuffer;
  39. ~BatchedDrawBuffers() {
  40. delete vertexBuffer1;
  41. delete vertexBuffer2;
  42. delete indexBuffer;
  43. delete constantColorBuffer;
  44. }
  45. };
  46. struct QueueFamilyIndices {
  47. std::optional<uint32_t> graphicsFamily;
  48. std::optional<uint32_t> presentFamily;
  49. bool isComplete() {
  50. return graphicsFamily.has_value() && presentFamily.has_value();
  51. }
  52. };
  53. struct SwapChainSupportDetails {
  54. VkSurfaceCapabilitiesKHR capabilities{};
  55. std::vector<VkSurfaceFormatKHR> formats;
  56. std::vector<VkPresentModeKHR> presentModes;
  57. };
  58. class Graphics final : public love::graphics::Graphics {
  59. public:
  60. Graphics() = default;
  61. virtual ~Graphics();
  62. const char* getName() const override;
  63. const VkDevice getDevice() const;
  64. const VkPhysicalDevice getPhysicalDevice() const;
  65. const VmaAllocator getVmaAllocator() const;
  66. // implementation for virtual functions
  67. love::graphics::Texture* newTexture(const love::graphics::Texture::Settings& settings, const love::graphics::Texture::Slices* data = nullptr) override;
  68. 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;
  69. void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
  70. void clear(const std::vector<OptionalColorD>& colors, OptionalInt stencil, OptionalDouble depth) override;
  71. Matrix4 computeDeviceProjection(const Matrix4& projection, bool rendertotexture) const override;
  72. void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override { }
  73. void present(void* screenshotCallbackdata) override;
  74. void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
  75. bool setMode(void* context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override;
  76. void unSetMode() override;
  77. void setActive(bool active) override;
  78. int getRequestedBackbufferMSAA() const override { return 0; }
  79. int getBackbufferMSAA() const override { return 0; }
  80. void setColor(Colorf c) override;
  81. void setScissor(const Rect& rect) override;
  82. void setScissor() override;
  83. void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override { }
  84. void setDepthMode(CompareMode compare, bool write) override { }
  85. void setFrontFaceWinding(Winding winding) override;
  86. void setColorMask(ColorChannelMask mask) override;
  87. void setBlendState(const BlendState& blend) override;
  88. void setPointSize(float size) override;
  89. void setWireframe(bool enable) override;
  90. PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
  91. bool isPixelFormatSupported(PixelFormat format, uint32 usage, bool sRGB = false) override;
  92. Renderer getRenderer() const override;
  93. bool usesGLSLES() const override;
  94. RendererInfo getRendererInfo() const override;
  95. void draw(const DrawCommand& cmd) override;
  96. void draw(const DrawIndexedCommand& cmd) override;
  97. void drawQuads(int start, int count, const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture) override;
  98. GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Buffer* buffer, size_t offset, size_t size, data::ByteData* dest, size_t destoffset) override { return nullptr; };
  99. GraphicsReadback* newReadbackInternal(ReadbackMethod method, love::graphics::Texture* texture, int slice, int mipmap, const Rect& rect, image::ImageData* dest, int destx, int desty) { return nullptr; }
  100. void executeCommand(std::function<void(VkCommandBuffer)> command, std::function<void()> cleanUp);
  101. VkCommandBuffer beginSingleTimeCommands();
  102. void endSingleTimeCommands(VkCommandBuffer);
  103. uint32_t getNumImagesInFlight() const;
  104. const PFN_vkCmdPushDescriptorSetKHR getVkCmdPushDescriptorSetKHRFunctionPointer() const;
  105. const VkDeviceSize getMinUniformBufferOffsetAlignment() const;
  106. protected:
  107. graphics::ShaderStage* newShaderStageInternal(ShaderStageType stage, const std::string& cachekey, const std::string& source, bool gles) override {
  108. return new ShaderStage(this, stage, source, gles, cachekey);
  109. }
  110. graphics::Shader* newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override {
  111. return new Shader(stages);
  112. }
  113. graphics::StreamBuffer* newStreamBuffer(BufferUsage type, size_t size) override;
  114. bool dispatch(int x, int y, int z) override { return false; }
  115. void initCapabilities() override;
  116. void getAPIStats(int& shaderswitches) const override;
  117. void setRenderTargetsInternal(const RenderTargets& rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
  118. private:
  119. void createVulkanInstance();
  120. bool checkValidationSupport();
  121. void pickPhysicalDevice();
  122. int rateDeviceSuitability(VkPhysicalDevice device);
  123. QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
  124. void createLogicalDevice();
  125. void initVMA();
  126. void createSurface();
  127. bool checkDeviceExtensionSupport(VkPhysicalDevice device);
  128. SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
  129. VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
  130. VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes);
  131. VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities);
  132. void createSwapChain();
  133. void createImageViews();
  134. void createDefaultShaders();
  135. VkPipeline createGraphicsPipeline(GraphicsPipelineConfiguration);
  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::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
  148. void updatedBatchedDrawBuffers();
  149. void createVulkanVertexFormat(VertexAttributes vertexAttributes, bool& useConstantVertexColor, GraphicsPipelineConfiguration& configuration);
  150. void prepareDraw(const VertexAttributes& attributes, const BufferBindings& buffers, graphics::Texture* texture, PrimitiveType, CullMode);
  151. void startRenderPass(Texture*, uint32_t w, uint32_t h);
  152. void endRenderPass();
  153. VkInstance instance = VK_NULL_HANDLE;
  154. VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
  155. VkDevice device = VK_NULL_HANDLE;
  156. VkQueue graphicsQueue = VK_NULL_HANDLE;
  157. VkQueue presentQueue = VK_NULL_HANDLE;
  158. VkSurfaceKHR surface = VK_NULL_HANDLE;
  159. VkSwapchainKHR swapChain = VK_NULL_HANDLE;
  160. std::vector<VkImage> swapChainImages;
  161. VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
  162. VkExtent2D swapChainExtent = VkExtent2D();
  163. std::vector<VkImageView> swapChainImageViews;
  164. VkPipelineLayout pipelineLayout = VK_NULL_HANDLE;
  165. VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE;
  166. std::vector<std::pair<GraphicsPipelineConfiguration, VkPipeline>> graphicsPipelines; // FIXME improve performance by using a hash map
  167. VkCommandPool commandPool = VK_NULL_HANDLE;
  168. std::vector<VkCommandBuffer> commandBuffers;
  169. VkDescriptorPool descriptorPool = VK_NULL_HANDLE;
  170. std::vector<VkSemaphore> imageAvailableSemaphores;
  171. std::vector<VkSemaphore> renderFinishedSemaphores;
  172. std::vector<VkFence> inFlightFences;
  173. std::vector<VkFence> imagesInFlight;
  174. VkDeviceSize minUniformBufferOffsetAlignment;
  175. PFN_vkCmdPushDescriptorSetKHR vkCmdPushDescriptorSet;
  176. size_t currentFrame = 0;
  177. uint32_t imageIndex = 0;
  178. bool framebufferResized = false;
  179. VmaAllocator vmaAllocator = VK_NULL_HANDLE;
  180. std::unique_ptr<Texture> standardTexture = nullptr;
  181. std::unique_ptr<StreamBuffer> quadIndexBuffer = nullptr;
  182. // we need an array of draw buffers, since the frames are being rendered asynchronously
  183. // and we can't (or shouldn't) update the contents of the buffers while they're still in flight / being rendered.
  184. std::vector<BatchedDrawBuffers> batchedDrawBuffers;
  185. // functions that need to be called to cleanup objects that were needed for rendering a frame.
  186. // just like batchedDrawBuffers we need a vector for each frame in flight.
  187. std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
  188. graphics::Texture* currentTexture = nullptr;
  189. VkPolygonMode currentPolygonMode = VK_POLYGON_MODE_FILL;
  190. // render pass variables.
  191. VkFormat currentFramebufferOutputFormat = VK_FORMAT_UNDEFINED;
  192. Texture* renderTargetTexture;
  193. float currentViewportWidth = 0;
  194. float currentViewportHeight = 0;
  195. };
  196. }
  197. }
  198. }
  199. #endif