2
0

BsGpuParams.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsGpuParam.h"
  4. #include "BsCoreObject.h"
  5. #include "BsIResourceListener.h"
  6. namespace BansheeEngine
  7. {
  8. /**
  9. * @brief Stores information needed for binding a texture to the pipeline.
  10. */
  11. struct BoundTextureInfo
  12. {
  13. BoundTextureInfo()
  14. :isLoadStore(false)
  15. { }
  16. bool isLoadStore;
  17. TextureSurface surface;
  18. };
  19. /**
  20. * @brief Helper structure whose specializations convert an engine data type into a GPU program data parameter type.
  21. */
  22. template<class T> struct TGpuDataParamInfo { };
  23. template<> struct TGpuDataParamInfo < float > { enum { TypeId = GPDT_FLOAT1 }; };
  24. template<> struct TGpuDataParamInfo < Color > { enum { TypeId = GPDT_FLOAT4 }; };
  25. template<> struct TGpuDataParamInfo < Vector2 > { enum { TypeId = GPDT_FLOAT2 }; };
  26. template<> struct TGpuDataParamInfo < Vector3 > { enum { TypeId = GPDT_FLOAT3 }; };
  27. template<> struct TGpuDataParamInfo < Vector4 > { enum { TypeId = GPDT_FLOAT4 }; };
  28. template<> struct TGpuDataParamInfo < Matrix3 > { enum { TypeId = GPDT_MATRIX_3X3 }; };
  29. template<> struct TGpuDataParamInfo < Matrix4 > { enum { TypeId = GPDT_MATRIX_4X4 }; };
  30. /**
  31. * @brief Contains functionality common for both sim and core thread
  32. * version of GpuParams.
  33. */
  34. class BS_CORE_EXPORT GpuParamsBase
  35. {
  36. public:
  37. /**
  38. * @brief Creates new GpuParams object using the specified parameter descriptions.
  39. *
  40. * @param paramDesc Reference to parameter descriptions that will be used for
  41. * finding needed parameters.
  42. * @param transposeMatrices If true the stored matrices will be transposed before
  43. * submitted to the GPU (some APIs require different
  44. * matrix layout).
  45. *
  46. * @note You normally do not want to call this manually. Instead use GpuProgram::createParameters.
  47. */
  48. GpuParamsBase(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  49. virtual ~GpuParamsBase();
  50. // Note: Disallow copy/assign because it would require some care when copying (copy internal data shared_ptr and
  51. // all the internal buffers too). Trivial to implement but not needed at this time. Un-delete and implement if necessary.
  52. GpuParamsBase(const GpuParamsBase& other) = delete;
  53. GpuParamsBase& operator=(const GpuParamsBase& rhs) = delete;
  54. /**
  55. * @brief Returns a description of all stored parameters.
  56. */
  57. const GpuParamDesc& getParamDesc() const { return *mParamDesc; }
  58. /**
  59. * @brief Returns the size of a data parameter with the specified name, in bytes.
  60. * Returns 0 if such parameter doesn't exist.
  61. */
  62. UINT32 getDataParamSize(const String& name) const;
  63. /**
  64. * @brief Checks if parameter with the specified name exists.
  65. */
  66. bool hasParam(const String& name) const;
  67. /**
  68. * @brief Checks if texture parameter with the specified name exists.
  69. */
  70. bool hasTexture(const String& name) const;
  71. /**
  72. * @brief Checks if sampler state parameter with the specified name exists.
  73. */
  74. bool hasSamplerState(const String& name) const;
  75. /**
  76. * @brief Checks if a parameter block with the specified name exists.
  77. */
  78. bool hasParamBlock(const String& name) const;
  79. /**
  80. * @brief Checks is the texture at the specified slot to be bound as
  81. * random load/store texture instead of a normal sampled texture.
  82. */
  83. bool isLoadStoreTexture(UINT32 slot) const;
  84. /**
  85. * @brief Changes the type of the texture at the specified slot.
  86. */
  87. void setIsLoadStoreTexture(UINT32 slot, bool isLoadStore);
  88. /**
  89. * @brief Returns information that determines which texture surfaces to bind
  90. * as load/store parameters.
  91. */
  92. const TextureSurface& getLoadStoreSurface(UINT32 slot) const;
  93. /**
  94. * @brief Sets information that determines which texture surfaces to bind
  95. * as load/store parameters.
  96. */
  97. void setLoadStoreSurface(UINT32 slot, const TextureSurface& surface) const;
  98. /**
  99. * @brief Checks whether matrices should be transformed before
  100. * being written to the parameter buffer.
  101. */
  102. bool getTransposeMatrices() const { return mTransposeMatrices; }
  103. /**
  104. * @copydoc CoreObject::markCoreDirty
  105. *
  106. * @note Internal method.
  107. */
  108. virtual void _markCoreDirty() { }
  109. /**
  110. * @copydoc IResourceListener::markResourcesDirty
  111. *
  112. * @note Internal method.
  113. */
  114. virtual void _markResourcesDirty() { }
  115. protected:
  116. /**
  117. * @brief Gets a descriptor for a data parameter with the specified name.
  118. */
  119. GpuParamDataDesc* getParamDesc(const String& name) const;
  120. GpuParamDescPtr mParamDesc;
  121. UINT32 mNumParamBlocks;
  122. UINT32 mNumTextures;
  123. UINT32 mNumSamplerStates;
  124. BoundTextureInfo* mTextureInfo;
  125. bool mTransposeMatrices;
  126. };
  127. /**
  128. * @brief Templated version of GpuParams that contains functionality for both
  129. * sim and core thread versions of stored data.
  130. */
  131. template <bool Core>
  132. class BS_CORE_EXPORT TGpuParams : public GpuParamsBase
  133. {
  134. public:
  135. template<bool Core> struct TTypes { };
  136. template<> struct TTypes < false >
  137. {
  138. typedef GpuParams GpuParamsType;
  139. typedef HTexture TextureType;
  140. typedef SamplerStatePtr SamplerType;
  141. typedef SPtr<GpuParamBlockBuffer> ParamsBufferType;
  142. };
  143. template<> struct TTypes < true >
  144. {
  145. typedef GpuParamsCore GpuParamsType;
  146. typedef SPtr<TextureCore> TextureType;
  147. typedef SPtr<SamplerStateCore> SamplerType;
  148. typedef SPtr<GpuParamBlockBufferCore> ParamsBufferType;
  149. };
  150. typedef typename TTypes<Core>::GpuParamsType GpuParamsType;
  151. typedef typename TTypes<Core>::TextureType TextureType;
  152. typedef typename TTypes<Core>::SamplerType SamplerType;
  153. typedef typename TTypes<Core>::ParamsBufferType ParamsBufferType;
  154. /**
  155. * @copydoc GpuParamsBase::GpuParamsBase(const GpuParamDescPtr&, bool)
  156. */
  157. TGpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  158. virtual ~TGpuParams();
  159. /**
  160. * @brief Binds a new parameter buffer to the specified slot. Any following parameter reads or
  161. * writes that are referencing that buffer slot will use the new buffer.
  162. *
  163. * @note This is useful if you want to share a parameter buffer among multiple GPU programs.
  164. * You would only set the values once and then share the buffer among all other GpuParams.
  165. *
  166. * It is up to the caller to guarantee the provided buffer matches parameter block
  167. * descriptor for this slot.
  168. */
  169. void setParamBlockBuffer(UINT32 slot, const ParamsBufferType& paramBlockBuffer);
  170. /**
  171. * @brief Replaces the parameter buffer with the specified name. Any following parameter reads or
  172. * writes that are referencing that buffer will use the new buffer.
  173. *
  174. * @note This is useful if you want to share a parameter buffer among multiple GPU programs.
  175. * You would only set the values once and then share the buffer among all other GpuParams.
  176. *
  177. * It is up to the caller to guarantee the provided buffer matches parameter block
  178. * descriptor for this slot.
  179. */
  180. void setParamBlockBuffer(const String& name, const ParamsBufferType& paramBlockBuffer);
  181. /**
  182. * @brief Returns a handle for the parameter with the specified name.
  183. * Handle may then be stored and used for quickly setting or retrieving
  184. * values to/from that parameter.
  185. *
  186. * Throws exception if parameter with that name and type doesn't exist.
  187. *
  188. * Parameter handles will be invalidated when their parent GpuParams object changes.
  189. */
  190. template<class T> void getParam(const String& name, TGpuDataParam<T, Core>& output) const;
  191. /**
  192. * @copydoc getParam(const String&, TGpuDataParam<T, Core>&)
  193. */
  194. void getStructParam(const String& name, TGpuParamStruct<Core>& output) const;
  195. /**
  196. * @copydoc getParam(const String&, TGpuDataParam<T, Core>&)
  197. */
  198. void getTextureParam(const String& name, TGpuParamTexture<Core>& output) const;
  199. /**
  200. * @copydoc getParam(const String&, TGpuDataParam<T, Core>&)
  201. */
  202. void getLoadStoreTextureParam(const String& name, TGpuParamLoadStoreTexture<Core>& output) const;
  203. /**
  204. * @copydoc getParam(const String&, TGpuDataParam<T, Core>&)
  205. */
  206. void getSamplerStateParam(const String& name, TGpuParamSampState<Core>& output) const;
  207. /**
  208. * @brief Gets a parameter block buffer from the specified slot.
  209. */
  210. ParamsBufferType getParamBlockBuffer(UINT32 slot) const;
  211. /**
  212. * @brief Gets a texture bound to the specified slot.
  213. */
  214. TextureType getTexture(UINT32 slot);
  215. /**
  216. * @brief Gets a sampler state bound to the specified slot.
  217. */
  218. SamplerType getSamplerState(UINT32 slot);
  219. /**
  220. * @brief Sets a texture at the specified slot.
  221. */
  222. void setTexture(UINT32 slot, const TextureType& texture);
  223. /**
  224. * @brief Sets a sampler state at the specified slot.
  225. */
  226. void setSamplerState(UINT32 slot, const SamplerType& sampler);
  227. protected:
  228. /**
  229. * @copydoc CoreObject::getThisPtr
  230. */
  231. virtual SPtr<GpuParamsType> _getThisPtr() const = 0;
  232. ParamsBufferType* mParamBlockBuffers;
  233. TextureType* mTextures;
  234. SamplerType* mSamplerStates;
  235. };
  236. /**
  237. * @brief Core thread version of GpuParams.
  238. *
  239. * @see GpuParams
  240. *
  241. * @note Core thread only.
  242. */
  243. class BS_CORE_EXPORT GpuParamsCore : public CoreObjectCore, public TGpuParams<true>
  244. {
  245. public:
  246. ~GpuParamsCore() { }
  247. /**
  248. * @brief Uploads all CPU stored parameter buffer data to the GPU buffers.
  249. */
  250. void updateHardwareBuffers();
  251. /**
  252. * @copydoc GpuParamsBase::GpuParamsBase
  253. */
  254. static SPtr<GpuParamsCore> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  255. protected:
  256. friend class GpuParams;
  257. /**
  258. * @copydoc GpuParamsBase::GpuParamsBase
  259. */
  260. GpuParamsCore(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  261. /**
  262. * @copydoc CoreObject::getThisPtr
  263. */
  264. SPtr<GpuParamsCore> _getThisPtr() const override;
  265. /**
  266. * @copydoc CoreObjectCore::syncToCore
  267. */
  268. void syncToCore(const CoreSyncData& data) override;
  269. };
  270. /**
  271. * @brief Contains descriptions for all parameters in a GPU program and also
  272. * allows you to write and read those parameters. All parameter values
  273. * are stored internally on the CPU, and are only submitted to the GPU
  274. * once the parameters are bound to the pipeline.
  275. *
  276. * @see CoreThreadAccessor::setConstantBuffers
  277. *
  278. * @note Sim thread only.
  279. */
  280. class BS_CORE_EXPORT GpuParams : public CoreObject, public TGpuParams<false>, public IResourceListener
  281. {
  282. public:
  283. ~GpuParams() { }
  284. /**
  285. * @copydoc CoreObject::markCoreDirty
  286. *
  287. * @note Internal method.
  288. */
  289. void _markCoreDirty() override;
  290. /**
  291. * @copydoc IResourceListener::markResourcesDirty
  292. *
  293. * @note Internal method.
  294. */
  295. void _markResourcesDirty() override;
  296. /**
  297. * @brief Retrieves a core implementation of a mesh usable only from the
  298. * core thread.
  299. */
  300. SPtr<GpuParamsCore> getCore() const;
  301. /**
  302. * @copydoc GpuParamsBase::GpuParamsBase
  303. */
  304. static SPtr<GpuParams> create(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  305. /**
  306. * @brief Contains a lookup table for sizes of all data parameters. Sizes are in bytes.
  307. */
  308. const static GpuDataParamInfos PARAM_SIZES;
  309. protected:
  310. /**
  311. * @copydoc GpuParamsBase::GpuParamsBase
  312. */
  313. GpuParams(const GpuParamDescPtr& paramDesc, bool transposeMatrices);
  314. /**
  315. * @copydoc CoreObject::getThisPtr
  316. */
  317. SPtr<GpuParams> _getThisPtr() const override;
  318. /**
  319. * @copydoc CoreObject::createCore
  320. */
  321. SPtr<CoreObjectCore> createCore() const override;
  322. /**
  323. * @copydoc CoreObject::syncToCore
  324. */
  325. CoreSyncData syncToCore(FrameAlloc* allocator) override;
  326. /**
  327. * @copydoc IResourceListener::getListenerResources
  328. */
  329. void getListenerResources(Vector<HResource>& resources) override;
  330. /**
  331. * @copydoc IResourceListener::notifyResourceLoaded
  332. */
  333. void notifyResourceLoaded(const HResource& resource) override { markCoreDirty(); }
  334. /**
  335. * @copydoc IResourceListener::notifyResourceDestroyed
  336. */
  337. void notifyResourceDestroyed(const HResource& resource) override { markCoreDirty(); }
  338. /**
  339. * @copydoc IResourceListener::notifyResourceChanged
  340. */
  341. void notifyResourceChanged(const HResource& resource) override { markCoreDirty(); }
  342. };
  343. }