Graphics.h 10 KB

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