NvVulkanRenderer.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /*
  2. * Copyright (c) 2023, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of NVIDIA CORPORATION nor the names of its
  13. * contributors may be used to endorse or promote products derived
  14. * from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  19. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  20. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  21. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  22. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  23. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  24. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  26. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. /**
  29. * @file
  30. * <b>NVIDIA Multimedia API: Vulkan Renderer API</b>
  31. *
  32. * @b Description: This file declares the NvVulkan Renderer API.
  33. */
  34. #ifndef __NV_VULKAN_RENDERER_H__
  35. #define __NV_VULKAN_RENDERER_H__
  36. #include <vector>
  37. #include <limits>
  38. #include <algorithm>
  39. #define VK_USE_PLATFORM_XLIB_KHR
  40. #include <vulkan/vulkan.h>
  41. #include "NvElement.h"
  42. #include <X11/Xlib.h>
  43. #include <vulkan/vulkan_xlib.h>
  44. #include <X11/Xutil.h>
  45. /**
  46. * @defgroup l4t_mm_nvvulkanrenderer_group Rendering API
  47. *
  48. * The \c %NvVulkanRenderer API uses external dma_buf extension to
  49. * import the foreign FD and then display it using Vulkan swapchain.
  50. *
  51. * @ingroup aa_framework_api_group
  52. * @{
  53. */
  54. /**
  55. *
  56. * @c %NvVulkanRenderer is a helper class for rendering using Vulkan
  57. * The renderer requires the file descriptor (FD) of a buffer
  58. * as an input. The rendering rate, in frames per second (fps), is
  59. * configurable.
  60. *
  61. * The renderer creates an X Window of its own. The width, height,
  62. * horizontal offset, and vertical offset of the window are
  63. * configurable.
  64. */
  65. struct MemoryTypeResult {
  66. bool found;
  67. uint32_t typeIndex;
  68. };
  69. struct QueueFamilyIndices {
  70. int graphicsFamily = -1;
  71. int computeFamily = -1;
  72. int presentFamily = -1;
  73. };
  74. struct SwapChainSupportDetails {
  75. VkSurfaceCapabilitiesKHR capabilities;
  76. std::vector<VkSurfaceFormatKHR> formats;
  77. std::vector<VkPresentModeKHR> presentModes;
  78. };
  79. class NvVulkanRenderer:public NvElement
  80. {
  81. private:
  82. Display * m_XDisplay; /**< Connection to the X server created using
  83. XOpenDisplay(). */
  84. Window m_XWindow; /**< Holds the window to be used for rendering created using
  85. XCreateWindow(). */
  86. VkInstance m_instance;
  87. VkDebugUtilsMessengerEXT m_debugMessenger;
  88. QueueFamilyIndices m_queueFamilyIndices;
  89. VkPhysicalDevice m_physicalDevice;
  90. VkDevice m_device;
  91. VkQueue m_graphicsQueue;
  92. VkQueue m_presentQueue;
  93. VkSurfaceKHR m_surface;
  94. VkSwapchainKHR m_swapChain;
  95. std::vector<VkImage> m_swapChainImages;
  96. VkFormat m_swapChainImageFormat;
  97. VkExtent2D m_swapChainExtent;
  98. std::vector<VkDeviceMemory> m_vkImageMemory;
  99. int m_vkImageMemoryIndex, m_oldImageIndex;
  100. VkCommandPool m_commandPool;
  101. VkCommandBuffer m_commandBuffer;
  102. VkSemaphore m_imageAvailableSemaphore;
  103. VkSemaphore m_renderFinishedSemaphore;
  104. VkFence m_inFlightFence;
  105. const std::vector<const char*> m_validationLayers = {
  106. #ifdef USE_VALIDATION
  107. "VK_LAYER_KHRONOS_validation",
  108. #endif
  109. };
  110. const std::vector<const char*> m_instanceExtensions{
  111. #ifdef USE_VALIDATION
  112. VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
  113. #endif
  114. VK_KHR_SURFACE_EXTENSION_NAME,
  115. VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
  116. };
  117. const std::vector<const char*> m_deviceExtensions{
  118. VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
  119. VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
  120. VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME,
  121. VK_KHR_SWAPCHAIN_EXTENSION_NAME,
  122. };
  123. template <typename T>
  124. uint32_t ui32Size(const T& container)
  125. {
  126. return static_cast<uint32_t>(container.size());
  127. }
  128. VkImageTiling m_imageTiling = VK_IMAGE_TILING_OPTIMAL;
  129. VkFormat m_imageFormat = VK_FORMAT_R8G8B8A8_UNORM;
  130. /**
  131. * Constructor called by the wrapper creatVulkanRenderer.
  132. */
  133. NvVulkanRenderer(const char *name, uint32_t width, uint32_t height,
  134. uint32_t x_offset, uint32_t y_offset);
  135. static const NvElementProfiler::ProfilerField valid_fields =
  136. NvElementProfiler::PROFILER_FIELD_TOTAL_UNITS |
  137. NvElementProfiler::PROFILER_FIELD_FPS |
  138. NvElementProfiler::PROFILER_FIELD_LATE_UNITS;
  139. public:
  140. /**
  141. * Creates a new Vulkan-based renderer named @a name.
  142. *
  143. * This method creates a new X window for rendering, of size @a
  144. * width and @a height, that is offset by @a x_offset and @a
  145. * y_offset. If @a width or @a height is zero, a full screen
  146. * window is created with @a x_offset and @a y_offset set to zero.
  147. *
  148. * @param[in] name Specifies a pointer to a unique name to identity the
  149. * element instance.
  150. * @param[in] width Specifies the width of the window in pixels.
  151. * @param[in] height Specifies the height of the window in pixels.
  152. * @param[in] x_offset Specifies the horizontal offset of the window in pixels.
  153. * @param[in] y_offset Specifies the vertical offset of the window in pixels.
  154. * @return A reference to the newly created renderer object, otherwise @c NULL in
  155. * case of failure during initialization.
  156. */
  157. static NvVulkanRenderer *createVulkanRenderer(const char *name, uint32_t width,
  158. uint32_t height, uint32_t x_offset,
  159. uint32_t y_offset);
  160. ~NvVulkanRenderer();
  161. void initVulkan();
  162. void createInstance();
  163. void createSurface();
  164. void getPhysicalDevice();
  165. void getQueueFamilies();
  166. void createDevice();
  167. void createSwapChain();
  168. void createCommandPool();
  169. void createCommandBuffer();
  170. void createSyncObjects();
  171. void displayFrame(VkImage image);
  172. void recordCommandBuffer(VkImage image, uint32_t imageIndex);
  173. void createVkImageFromFd(int fd);
  174. void render(int fd);
  175. void setSize(uint32_t width, uint32_t height);
  176. PFN_vkVoidFunction getInstanceFunction(VkInstance instance, const char* name);
  177. uint32_t m_windowWidth;
  178. uint32_t m_windowHeight;
  179. };
  180. /** @} */
  181. #endif