BsVulkanGpuPipelineState.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 "BsGpuPipelineState.h"
  7. namespace bs
  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-stencil attachment read-only. Only relevant for graphics pipelines. */
  25. bool isDepthStencilReadOnly() const { return mReadOnlyDepthStencil; }
  26. private:
  27. VkPipeline mPipeline;
  28. std::array<bool, BS_MAX_MULTIPLE_RENDER_TARGETS> mReadOnlyColor;
  29. bool mReadOnlyDepthStencil;
  30. };
  31. /** Vulkan implementation of a graphics pipeline state. */
  32. class VulkanGraphicsPipelineStateCore : public GraphicsPipelineStateCore
  33. {
  34. public:
  35. ~VulkanGraphicsPipelineStateCore();
  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<VertexDeclarationCore> 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] readOnlyDepth True if the pipeline is only allowed to read the depth buffer, without writes.
  47. * @param[in] loadMask Mask that controls for which framebuffer surfaces should the existing contents
  48. * be preserved for.
  49. * @param[in] readMask Mask that controls which framebuffer surfaces can be read from the shader while
  50. * they're bound for rendering.
  51. * @param[in] drawOp Type of geometry that will be drawn using the pipeline.
  52. * @param[in] vertexInput State describing inputs to the vertex program.
  53. * @return Vulkan graphics pipeline object.
  54. *
  55. * @note Thread safe.
  56. */
  57. VulkanPipeline* getPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer, bool readOnlyDepth,
  58. RenderSurfaceMask loadMask, RenderSurfaceMask readMask, DrawOperationType drawOp,
  59. const SPtr<VulkanVertexInput>& vertexInput);
  60. /**
  61. * Returns a pipeline layout object for the specified device index. If the device index doesn't match a bit in the
  62. * device mask provided on pipeline creation, null is returned.
  63. */
  64. VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
  65. /**
  66. * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
  67. * a pipeline is bound to a command buffer.
  68. */
  69. void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
  70. protected:
  71. friend class VulkanRenderStateCoreManager;
  72. VulkanGraphicsPipelineStateCore(const PIPELINE_STATE_CORE_DESC& desc, GpuDeviceFlags deviceMask);
  73. /** @copydoc GraphicsPipelineStateCore::initialize */
  74. void initialize() override;
  75. /**
  76. * Create a new Vulkan graphics pipeline.
  77. *
  78. * @param[in] deviceIdx Index of the device to create the pipeline for.
  79. * @param[in] framebuffer Framebuffer object that defines the surfaces this pipeline will render to.
  80. * @param[in] readOnlyDepth True if the pipeline is only allowed to read the depth buffer, without writes.
  81. * @param[in] loadMask Mask that controls for which framebuffer surfaces should the existing contents
  82. * be preserved for.
  83. * @param[in] readMask Mask that controls which framebuffer surfaces can be read from the shader while
  84. * they're bound for rendering.
  85. * @param[in] drawOp Type of geometry that will be drawn using the pipeline.
  86. * @param[in] vertexInput State describing inputs to the vertex program.
  87. * @return Vulkan graphics pipeline object.
  88. *
  89. * @note Thread safe.
  90. */
  91. VulkanPipeline* createPipeline(UINT32 deviceIdx, VulkanFramebuffer* framebuffer, bool readOnlyDepth,
  92. RenderSurfaceMask loadMask, RenderSurfaceMask readMask, DrawOperationType drawOp,
  93. const SPtr<VulkanVertexInput>& vertexInput);
  94. /** Key uniquely identifying GPU pipelines. */
  95. struct GpuPipelineKey
  96. {
  97. GpuPipelineKey(UINT32 framebufferId, UINT32 vertexInputId, bool readOnlyDepth, RenderSurfaceMask loadMask,
  98. RenderSurfaceMask readMask, DrawOperationType drawOp);
  99. UINT32 framebufferId;
  100. UINT32 vertexInputId;
  101. bool readOnlyDepth;
  102. RenderSurfaceMask loadMask;
  103. RenderSurfaceMask readMask;
  104. DrawOperationType drawOp;
  105. };
  106. /** Creates a hash from GPU pipeline key. */
  107. class HashFunc
  108. {
  109. public:
  110. ::std::size_t operator()(const GpuPipelineKey& key) const;
  111. };
  112. /** Compares two GPU pipeline keys. */
  113. class EqualFunc
  114. {
  115. public:
  116. bool operator()(const GpuPipelineKey& a, const GpuPipelineKey& b) const;
  117. };
  118. /** Contains pipeline data specific to a single Vulkan device. */
  119. struct PerDeviceData
  120. {
  121. VulkanDevice* device;
  122. VkPipelineLayout pipelineLayout;
  123. UnorderedMap<GpuPipelineKey, VulkanPipeline*, HashFunc, EqualFunc> pipelines;
  124. };
  125. VkPipelineShaderStageCreateInfo mShaderStageInfos[5];
  126. VkPipelineInputAssemblyStateCreateInfo mInputAssemblyInfo;
  127. VkPipelineTessellationStateCreateInfo mTesselationInfo;
  128. VkPipelineViewportStateCreateInfo mViewportInfo;
  129. VkPipelineRasterizationStateCreateInfo mRasterizationInfo;
  130. VkPipelineMultisampleStateCreateInfo mMultiSampleInfo;
  131. VkPipelineDepthStencilStateCreateInfo mDepthStencilInfo;
  132. VkPipelineColorBlendAttachmentState mAttachmentBlendStates[BS_MAX_MULTIPLE_RENDER_TARGETS];
  133. VkPipelineColorBlendStateCreateInfo mColorBlendStateInfo;
  134. VkPipelineDynamicStateCreateInfo mDynamicStateInfo;
  135. VkDynamicState mDynamicStates[3];
  136. VkGraphicsPipelineCreateInfo mPipelineInfo;
  137. bool mScissorEnabled;
  138. SPtr<VertexDeclarationCore> mVertexDecl;
  139. GpuDeviceFlags mDeviceMask;
  140. PerDeviceData mPerDeviceData[BS_MAX_DEVICES];
  141. Mutex mMutex;
  142. };
  143. /** Vulkan implementation of a compute pipeline state. */
  144. class VulkanComputePipelineStateCore : public ComputePipelineStateCore
  145. {
  146. public:
  147. ~VulkanComputePipelineStateCore();
  148. /**
  149. * Returns a pipeline object for the specified device index. If the device index doesn't match a bit in the
  150. * device mask provided on pipeline creation, null is returned.
  151. */
  152. VulkanPipeline* getPipeline(UINT32 deviceIdx) const;
  153. /**
  154. * Returns a pipeline layout object for the specified device index. If the device index doesn't match a bit in the
  155. * device mask provided on pipeline creation, null is returned.
  156. */
  157. VkPipelineLayout getPipelineLayout(UINT32 deviceIdx) const;
  158. /**
  159. * Registers any resources used by the pipeline with the provided command buffer. This should be called whenever
  160. * a pipeline is bound to a command buffer.
  161. */
  162. void registerPipelineResources(VulkanCmdBuffer* cmdBuffer);
  163. protected:
  164. friend class VulkanRenderStateCoreManager;
  165. VulkanComputePipelineStateCore(const SPtr<GpuProgramCore>& program, GpuDeviceFlags deviceMask);
  166. /** @copydoc ComputePipelineStateCore::initialize */
  167. void initialize() override;
  168. /** Contains pipeline data specific to a single Vulkan device. */
  169. struct PerDeviceData
  170. {
  171. VulkanDevice* device;
  172. VulkanPipeline* pipeline;
  173. VkPipelineLayout pipelineLayout;
  174. };
  175. GpuDeviceFlags mDeviceMask;
  176. PerDeviceData mPerDeviceData[BS_MAX_DEVICES];
  177. };
  178. /** @} */
  179. }