BsVulkanGpuPipelineState.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsVulkanPrerequisites.h"
  5. #include "BsVulkanResource.h"
  6. #include "Renderapi/BsGpuPipelineState.h"
  7. namespace bs { namespace ct
  8. {
  9. /** @addtogroup Vulkan
  10. * @{
  11. */
  12. /** Wrapper around a Vulkan graphics pipeline that manages its usage and lifetime. */
  13. class VulkanPipeline : public VulkanResource
  14. {
  15. public:
  16. VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline,
  17. const std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS>& colorReadOnly, bool depthStencilReadOnly);
  18. VulkanPipeline(VulkanResourceManager* owner, VkPipeline pipeline);
  19. ~VulkanPipeline();
  20. /** Returns the internal handle to the Vulkan object. */
  21. VkPipeline getHandle() const { return mPipeline; }
  22. /** Checks is the specified color attachment read-only. Only relevant for graphics pipelines. */
  23. bool isColorReadOnly(UINT32 colorIdx) const { return mReadOnlyColor[colorIdx]; }
  24. /** Checks is the depth attachment read-only. Only relevant for graphics pipelines. */
  25. bool isDepthReadOnly() const { return mReadOnlyDepth; }
  26. private:
  27. VkPipeline mPipeline;
  28. std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS> mReadOnlyColor;
  29. bool mReadOnlyDepth;
  30. };
  31. /** Vulkan implementation of a graphics pipeline state. */
  32. class VulkanGraphicsPipelineState : public GraphicsPipelineState
  33. {
  34. public:
  35. ~VulkanGraphicsPipelineState();
  36. /** Checks does the pipeline enable scissor tests. */
  37. bool isScissorEnabled() const { return mScissorEnabled; }
  38. /** Returns the vertex input declaration from the vertex GPU program bound on the pipeline. */
  39. SPtr<VertexDeclaration> getInputDeclaration() const { return mVertexDecl; }
  40. /**
  41. * Attempts to find an existing pipeline matching the provided parameters, or creates a new one if one cannot be
  42. * found.
  43. *
  44. * @param[in] deviceIdx Index of the device to retrieve the pipeline for.
  45. * @param[in] framebuffer Framebuffer object that defines the surfaces this pipeline will render to.
  46. * @param[in] readOnlyFlags Flags that control which portion of the framebuffer is read-only. Accepts
  47. * combinations of FrameBufferType enum.
  48. * @param[in] drawOp Type of geometry that will be drawn using the pipeline.
  49. * @param[in] vertexInput State describing inputs to the vertex program.
  50. * @return Vulkan graphics pipeline object.
  51. *
  52. * @note Thread safe.
  53. */
  54. VulkanPipeline* getPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer, UINT32 readOnlyFlags,
  55. DrawOperationType drawOp, const SPtr<VulkanVertexInput>& vertexInput);
  56. /**
  57. * Returns a pipeline layout object for the specified device index. If the device index doesn't match a bit in the
  58. * device mask provided on pipeline creation, null is returned.
  59. */
  60. VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
  61. /**
  62. * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
  63. * a pipeline is bound to a command buffer.
  64. */
  65. void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
  66. protected:
  67. friend class VulkanRenderStateManager;
  68. VulkanGraphicsPipelineState(const PIPELINE_STATE_DESC& desc, GpuDeviceFlags deviceMask);
  69. /** @copydoc GraphicsPipelineState::initialize */
  70. void initialize() override;
  71. /**
  72. * Create a new Vulkan graphics pipeline.
  73. *
  74. * @param[in] deviceIdx Index of the device to create the pipeline for.
  75. * @param[in] framebuffer Framebuffer object that defines the surfaces this pipeline will render to.
  76. * @param[in] readOnlyFlags Flags that control which portion of the framebuffer is read-only. Accepts
  77. * combinations of FrameBufferType enum.
  78. * @param[in] drawOp Type of geometry that will be drawn using the pipeline.
  79. * @param[in] vertexInput State describing inputs to the vertex program.
  80. * @return Vulkan graphics pipeline object.
  81. *
  82. * @note Thread safe.
  83. */
  84. VulkanPipeline* createPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer, UINT32 readOnlyFlags,
  85. DrawOperationType drawOp, const SPtr<VulkanVertexInput>& vertexInput);
  86. /** Key uniquely identifying GPU pipelines. */
  87. struct GpuPipelineKey
  88. {
  89. GpuPipelineKey(UINT32 framebufferId, UINT32 vertexInputId, UINT32 readOnlyFlags, DrawOperationType drawOp);
  90. UINT32 framebufferId;
  91. UINT32 vertexInputId;
  92. UINT32 readOnlyFlags;
  93. DrawOperationType drawOp;
  94. };
  95. /** Creates a hash from GPU pipeline key. */
  96. class HashFunc
  97. {
  98. public:
  99. ::std::size_t operator()(const GpuPipelineKey& key) const;
  100. };
  101. /** Compares two GPU pipeline keys. */
  102. class EqualFunc
  103. {
  104. public:
  105. bool operator()(const GpuPipelineKey& a, const GpuPipelineKey& b) const;
  106. };
  107. /** Contains pipeline data specific to a single Vulkan device. */
  108. struct PerDeviceData
  109. {
  110. VulkanDevice* device;
  111. VkPipelineLayout pipelineLayout;
  112. UnorderedMap<GpuPipelineKey, VulkanPipeline*, HashFunc, EqualFunc> pipelines;
  113. };
  114. VkPipelineShaderStageCreateInfo mShaderStageInfos[5];
  115. VkPipelineInputAssemblyStateCreateInfo mInputAssemblyInfo;
  116. VkPipelineTessellationStateCreateInfo mTesselationInfo;
  117. VkPipelineViewportStateCreateInfo mViewportInfo;
  118. VkPipelineRasterizationStateCreateInfo mRasterizationInfo;
  119. VkPipelineMultisampleStateCreateInfo mMultiSampleInfo;
  120. VkPipelineDepthStencilStateCreateInfo mDepthStencilInfo;
  121. VkPipelineColorBlendAttachmentState mAttachmentBlendStates[BS_MAX_MULTIPLE_RENDER_TARGETS];
  122. VkPipelineColorBlendStateCreateInfo mColorBlendStateInfo;
  123. VkPipelineDynamicStateCreateInfo mDynamicStateInfo;
  124. VkDynamicState mDynamicStates[3];
  125. VkGraphicsPipelineCreateInfo mPipelineInfo;
  126. bool mScissorEnabled;
  127. SPtr<VertexDeclaration> mVertexDecl;
  128. GpuDeviceFlags mDeviceMask;
  129. PerDeviceData mPerDeviceData[BS_MAX_DEVICES];
  130. Mutex mMutex;
  131. };
  132. /** Vulkan implementation of a compute pipeline state. */
  133. class VulkanComputePipelineState : public ComputePipelineState
  134. {
  135. public:
  136. ~VulkanComputePipelineState();
  137. /**
  138. * Returns a pipeline object for the specified device index. If the device index doesn't match a bit in the
  139. * device mask provided on pipeline creation, null is returned.
  140. */
  141. VulkanPipeline* getPipeline(UINT32 deviceIdx) const;
  142. /**
  143. * Returns a pipeline layout object for the specified device index. If the device index doesn't match a bit in the
  144. * device mask provided on pipeline creation, null is returned.
  145. */
  146. VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
  147. /**
  148. * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
  149. * a pipeline is bound to a command buffer.
  150. */
  151. void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
  152. protected:
  153. friend class VulkanRenderStateManager;
  154. VulkanComputePipelineState(const SPtr<GpuProgram>& program, GpuDeviceFlags deviceMask);
  155. /** @copydoc ComputePipelineState::initialize */
  156. void initialize() override;
  157. /** Contains pipeline data specific to a single Vulkan device. */
  158. struct PerDeviceData
  159. {
  160. VulkanDevice* device;
  161. VulkanPipeline* pipeline;
  162. VkPipelineLayout pipelineLayout;
  163. };
  164. GpuDeviceFlags mDeviceMask;
  165. PerDeviceData mPerDeviceData[BS_MAX_DEVICES];
  166. };
  167. /** @} */
  168. }}