Graphics.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /**
  2. * Copyright (c) 2006-2024 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #pragma once
  21. // löve
  22. #include "common/config.h"
  23. #include "graphics/Graphics.h"
  24. #include "StreamBuffer.h"
  25. #include "ShaderStage.h"
  26. #include "Shader.h"
  27. #include "Texture.h"
  28. // libraries
  29. #include "VulkanWrapper.h"
  30. #include "libraries/xxHash/xxhash.h"
  31. // c++
  32. #include <iostream>
  33. #include <memory>
  34. #include <functional>
  35. #include <set>
  36. #include <tuple>
  37. namespace love
  38. {
  39. namespace graphics
  40. {
  41. namespace vulkan
  42. {
  43. struct ColorAttachment
  44. {
  45. VkFormat format = VK_FORMAT_UNDEFINED;
  46. VkAttachmentLoadOp loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  47. VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
  48. bool operator==(const ColorAttachment &attachment) const
  49. {
  50. return format == attachment.format &&
  51. loadOp == attachment.loadOp &&
  52. msaaSamples == attachment.msaaSamples;
  53. }
  54. };
  55. struct DepthStencilAttachment
  56. {
  57. VkFormat format = VK_FORMAT_UNDEFINED;
  58. VkAttachmentLoadOp depthLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  59. VkAttachmentLoadOp stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
  60. VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
  61. bool operator==(const DepthStencilAttachment &attachment) const
  62. {
  63. return format == attachment.format &&
  64. depthLoadOp == attachment.depthLoadOp &&
  65. stencilLoadOp == attachment.stencilLoadOp &&
  66. msaaSamples == attachment.msaaSamples;
  67. }
  68. };
  69. struct RenderPassConfiguration
  70. {
  71. std::vector<ColorAttachment> colorAttachments;
  72. struct StaticRenderPassConfiguration
  73. {
  74. DepthStencilAttachment depthStencilAttachment;
  75. bool resolve = false;
  76. } staticData;
  77. bool operator==(const RenderPassConfiguration &conf) const
  78. {
  79. return colorAttachments == conf.colorAttachments &&
  80. (memcmp(&staticData, &conf.staticData, sizeof(StaticRenderPassConfiguration)) == 0);
  81. }
  82. };
  83. struct RenderPassConfigurationHasher
  84. {
  85. size_t operator()(const RenderPassConfiguration &configuration) const
  86. {
  87. size_t hashes[] = {
  88. XXH32(configuration.colorAttachments.data(), configuration.colorAttachments.size() * sizeof(ColorAttachment), 0),
  89. XXH32(&configuration.staticData, sizeof(configuration.staticData), 0),
  90. };
  91. return XXH32(hashes, sizeof(hashes), 0);
  92. }
  93. };
  94. struct FramebufferConfiguration
  95. {
  96. std::vector<VkImageView> colorViews;
  97. struct StaticFramebufferConfiguration
  98. {
  99. VkImageView depthView = VK_NULL_HANDLE;
  100. VkImageView resolveView = VK_NULL_HANDLE;
  101. uint32_t width = 0;
  102. uint32_t height = 0;
  103. VkRenderPass renderPass = VK_NULL_HANDLE;
  104. } staticData;
  105. bool operator==(const FramebufferConfiguration &conf) const
  106. {
  107. return colorViews == conf.colorViews &&
  108. (memcmp(&staticData, &conf.staticData, sizeof(StaticFramebufferConfiguration)) == 0);
  109. }
  110. };
  111. struct FramebufferConfigurationHasher
  112. {
  113. size_t operator()(const FramebufferConfiguration &configuration) const
  114. {
  115. size_t hashes[] = {
  116. XXH32(configuration.colorViews.data(), configuration.colorViews.size() * sizeof(VkImageView), 0),
  117. XXH32(&configuration.staticData, sizeof(configuration.staticData), 0),
  118. };
  119. return XXH32(hashes, sizeof(hashes), 0);
  120. }
  121. };
  122. struct OptionalInstanceExtensions
  123. {
  124. // VK_KHR_get_physical_device_properties2
  125. bool physicalDeviceProperties2 = false;
  126. // VK_EXT_debug_info
  127. bool debugInfo = false;
  128. };
  129. struct OptionalDeviceExtensions
  130. {
  131. // VK_EXT_extended_dynamic_state
  132. bool extendedDynamicState = false;
  133. // VK_KHR_get_memory_requirements2
  134. bool memoryRequirements2 = false;
  135. // VK_KHR_dedicated_allocation
  136. bool dedicatedAllocation = false;
  137. // VK_EXT_memory_budget
  138. bool memoryBudget = false;
  139. // VK_KHR_shader_float_controls
  140. bool shaderFloatControls = false;
  141. // VK_KHR_spirv_1_4
  142. bool spirv14 = false;
  143. };
  144. struct QueueFamilyIndices
  145. {
  146. Optional<uint32_t> graphicsFamily;
  147. Optional<uint32_t> presentFamily;
  148. bool isComplete() const
  149. {
  150. return graphicsFamily.hasValue && presentFamily.hasValue;
  151. }
  152. };
  153. struct SwapChainSupportDetails
  154. {
  155. VkSurfaceCapabilitiesKHR capabilities{};
  156. std::vector<VkSurfaceFormatKHR> formats;
  157. std::vector<VkPresentModeKHR> presentModes;
  158. };
  159. struct RenderpassState
  160. {
  161. bool active = false;
  162. VkRenderPassBeginInfo beginInfo{};
  163. bool isWindow = false;
  164. RenderPassConfiguration renderPassConfiguration{};
  165. FramebufferConfiguration framebufferConfiguration{};
  166. VkPipeline pipeline = VK_NULL_HANDLE;
  167. std::vector<std::tuple<VkImage, PixelFormat, VkImageLayout, VkImageLayout, int, int>> transitionImages;
  168. uint32_t numColorAttachments = 0;
  169. float width = 0.0f;
  170. float height = 0.0f;
  171. VkSampleCountFlagBits msaa = VK_SAMPLE_COUNT_1_BIT;
  172. std::vector<VkClearValue> clearColors;
  173. bool windowClearRequested = false;
  174. OptionalColorD mainWindowClearColorValue;
  175. OptionalDouble mainWindowClearDepthValue;
  176. OptionalInt mainWindowClearStencilValue;
  177. };
  178. enum SubmitMode
  179. {
  180. SUBMIT_PRESENT,
  181. SUBMIT_NOPRESENT,
  182. SUBMIT_RESTART,
  183. SUBMIT_MAXENUM,
  184. };
  185. class Graphics final : public love::graphics::Graphics
  186. {
  187. public:
  188. Graphics();
  189. ~Graphics();
  190. // implementation for virtual functions
  191. love::graphics::Texture *newTexture(const love::graphics::Texture::Settings &settings, const love::graphics::Texture::Slices *data) override;
  192. love::graphics::Texture *newTextureView(love::graphics::Texture *base, const Texture::ViewSettings &viewsettings) override;
  193. 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;
  194. graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Buffer *buffer, size_t offset, size_t size, data::ByteData *dest, size_t destoffset) override;
  195. graphics::GraphicsReadback *newReadbackInternal(ReadbackMethod method, love::graphics::Texture *texture, int slice, int mipmap, const Rect &rect, image::ImageData *dest, int destx, int desty) override;
  196. void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
  197. void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override;
  198. void discard(const std::vector<bool>& colorbuffers, bool depthstencil) override;
  199. void present(void *screenshotCallbackdata) override;
  200. void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override;
  201. bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override;
  202. void unSetMode() override;
  203. void setActive(bool active) override;
  204. int getRequestedBackbufferMSAA() const override;
  205. int getBackbufferMSAA() const override;
  206. void setColor(Colorf c) override;
  207. void setScissor(const Rect &rect) override;
  208. void setScissor() override;
  209. void setStencilState(const StencilState &s) override;
  210. void setDepthMode(CompareMode compare, bool write) override;
  211. void setFrontFaceWinding(Winding winding) override;
  212. void setColorMask(ColorChannelMask mask) override;
  213. void setBlendState(const BlendState &blend) override;
  214. void setPointSize(float size) override;
  215. void setWireframe(bool enable) override;
  216. bool isPixelFormatSupported(PixelFormat format, uint32 usage) override;
  217. Renderer getRenderer() const override;
  218. bool usesGLSLES() const override;
  219. RendererInfo getRendererInfo() const override;
  220. void draw(const DrawCommand &cmd) override;
  221. void draw(const DrawIndexedCommand &cmd) override;
  222. void drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, graphics::Texture *texture) override;
  223. // internal functions.
  224. VkDevice getDevice() const;
  225. VmaAllocator getVmaAllocator() const;
  226. VkCommandBuffer getCommandBufferForDataTransfer();
  227. void queueCleanUp(std::function<void()> cleanUp);
  228. void addReadbackCallback(std::function<void()> callback);
  229. void submitGpuCommands(SubmitMode, void *screenshotCallbackData = nullptr);
  230. VkSampler getCachedSampler(const SamplerState &sampler);
  231. void setComputeShader(Shader *computeShader);
  232. graphics::Shader::BuiltinUniformData getCurrentBuiltinUniformData();
  233. const OptionalDeviceExtensions &getEnabledOptionalDeviceExtensions() const;
  234. const OptionalInstanceExtensions &getEnabledOptionalInstanceExtensions() const;
  235. VkSampleCountFlagBits getMsaaCount(int requestedMsaa) const;
  236. void setVsync(int vsync);
  237. int getVsync() const;
  238. void mapLocalUniformData(void *data, size_t size, VkDescriptorBufferInfo &bufferInfo);
  239. VkPipeline createGraphicsPipeline(Shader *shader, const GraphicsPipelineConfiguration &configuration);
  240. uint32 getDeviceApiVersion() const { return deviceApiVersion; }
  241. protected:
  242. graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
  243. graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const Shader::CompileOptions &options) override;
  244. graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
  245. bool dispatch(love::graphics::Shader *shader, int x, int y, int z) override;
  246. bool dispatch(love::graphics::Shader *shader, love::graphics::Buffer *indirectargs, size_t argsoffset) override;
  247. void initCapabilities() override;
  248. void getAPIStats(int &shaderswitches) const override;
  249. void setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
  250. private:
  251. bool checkValidationSupport();
  252. void pickPhysicalDevice();
  253. int rateDeviceSuitability(VkPhysicalDevice device);
  254. QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device);
  255. void createLogicalDevice();
  256. void createPipelineCache();
  257. void initVMA();
  258. void createSurface();
  259. bool checkDeviceExtensionSupport(VkPhysicalDevice device);
  260. SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device);
  261. VkSurfaceFormatKHR chooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR> &availableFormats);
  262. VkPresentModeKHR chooseSwapPresentMode(const std::vector<VkPresentModeKHR> &availablePresentModes);
  263. VkExtent2D chooseSwapExtent(const VkSurfaceCapabilitiesKHR &capabilities);
  264. VkCompositeAlphaFlagBitsKHR chooseCompositeAlpha(const VkSurfaceCapabilitiesKHR &capabilities);
  265. void createSwapChain();
  266. void createImageViews();
  267. VkFramebuffer createFramebuffer(FramebufferConfiguration &configuration);
  268. VkFramebuffer getFramebuffer(FramebufferConfiguration &configuration);
  269. void createDefaultShaders();
  270. VkRenderPass createRenderPass(RenderPassConfiguration &configuration);
  271. VkRenderPass getRenderPass(RenderPassConfiguration &configuration);
  272. void createColorResources();
  273. VkFormat findSupportedFormat(const std::vector<VkFormat> &candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
  274. VkFormat findDepthFormat();
  275. void createDepthResources();
  276. void createCommandPool();
  277. void createCommandBuffers();
  278. void createSyncObjects();
  279. void cleanup();
  280. void cleanupSwapChain();
  281. void recreateSwapChain();
  282. void initDynamicState();
  283. void beginFrame();
  284. void startRecordingGraphicsCommands();
  285. void endRecordingGraphicsCommands();
  286. void createVulkanVertexFormat(
  287. Shader *shader,
  288. const VertexAttributes &attributes,
  289. std::vector<VkVertexInputBindingDescription> &bindingDescriptions,
  290. std::vector<VkVertexInputAttributeDescription> &attributeDescriptions);
  291. void prepareDraw(
  292. const VertexAttributes &attributes,
  293. const BufferBindings &buffers, graphics::Texture *texture,
  294. PrimitiveType, CullMode);
  295. void setRenderPass(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture);
  296. void setDefaultRenderPass();
  297. void startRenderPass();
  298. void endRenderPass();
  299. void applyScissor();
  300. VkSampler createSampler(const SamplerState &sampler);
  301. void cleanupUnusedObjects();
  302. void requestSwapchainRecreation();
  303. VkInstance instance = VK_NULL_HANDLE;
  304. VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
  305. uint32_t deviceApiVersion = VK_API_VERSION_1_0;
  306. int requestedMsaa = 0;
  307. VkDevice device = VK_NULL_HANDLE;
  308. OptionalInstanceExtensions optionalInstanceExtensions;
  309. OptionalDeviceExtensions optionalDeviceExtensions;
  310. VkQueue graphicsQueue = VK_NULL_HANDLE;
  311. VkQueue presentQueue = VK_NULL_HANDLE;
  312. VkSurfaceKHR surface = VK_NULL_HANDLE;
  313. VkSwapchainKHR swapChain = VK_NULL_HANDLE;
  314. std::vector<VkImage> swapChainImages;
  315. StrongRef<Texture> fakeBackbuffer;
  316. VkFormat swapChainImageFormat = VK_FORMAT_UNDEFINED;
  317. PixelFormat swapChainPixelFormat = PIXELFORMAT_UNKNOWN;
  318. VkFormat depthStencilFormat = VK_FORMAT_UNDEFINED;
  319. PixelFormat depthStencilPixelFormat = PIXELFORMAT_UNKNOWN;
  320. VkExtent2D swapChainExtent = VkExtent2D();
  321. std::vector<VkImageView> swapChainImageViews;
  322. VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT;
  323. VkImage colorImage = VK_NULL_HANDLE;
  324. VkImageView colorImageView = VK_NULL_HANDLE;
  325. VmaAllocation colorImageAllocation = VK_NULL_HANDLE;
  326. VkImage depthImage = VK_NULL_HANDLE;
  327. VkImageView depthImageView = VK_NULL_HANDLE;
  328. VmaAllocation depthImageAllocation = VK_NULL_HANDLE;
  329. VkPipelineCache pipelineCache = VK_NULL_HANDLE;
  330. std::unordered_map<RenderPassConfiguration, VkRenderPass, RenderPassConfigurationHasher> renderPasses;
  331. std::unordered_map<FramebufferConfiguration, VkFramebuffer, FramebufferConfigurationHasher> framebuffers;
  332. std::unordered_map<VkRenderPass, bool> renderPassUsages;
  333. std::unordered_map<VkFramebuffer, bool> framebufferUsages;
  334. std::unordered_map<uint64, VkSampler> samplers;
  335. VkCommandPool commandPool = VK_NULL_HANDLE;
  336. std::vector<VkCommandBuffer> commandBuffers;
  337. Shader *computeShader = nullptr;
  338. std::vector<VkSemaphore> imageAvailableSemaphores;
  339. std::vector<VkSemaphore> renderFinishedSemaphores;
  340. std::vector<VkFence> inFlightFences;
  341. std::vector<VkFence> imagesInFlight;
  342. int vsync = 1;
  343. VkDeviceSize minUniformBufferOffsetAlignment = 0;
  344. bool imageRequested = false;
  345. uint32_t frameCounter = 0;
  346. size_t currentFrame = 0;
  347. uint32_t imageIndex = 0;
  348. bool swapChainRecreationRequested = false;
  349. bool transitionColorDepthLayouts = false;
  350. VmaAllocator vmaAllocator = VK_NULL_HANDLE;
  351. StrongRef<love::graphics::Buffer> defaultVertexBuffer;
  352. StrongRef<StreamBuffer> localUniformBuffer;
  353. // functions that need to be called to cleanup objects that were needed for rendering a frame.
  354. // We need a vector for each frame in flight.
  355. std::vector<std::vector<std::function<void()>>> cleanUpFunctions;
  356. std::vector<std::vector<std::function<void()>>> readbackCallbacks;
  357. std::set<StrongRef<Shader>> usedShadersInFrame;
  358. RenderpassState renderPassState;
  359. };
  360. } // vulkan
  361. } // graphics
  362. } // love