gfxShader.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _GFXSHADER_H_
  23. #define _GFXSHADER_H_
  24. #ifndef _GFXRESOURCE_H_
  25. #include "gfx/gfxResource.h"
  26. #endif
  27. #ifndef _TORQUE_STRING_H_
  28. #include "core/util/str.h"
  29. #endif
  30. #ifndef _TVECTOR_H_
  31. #include "core/util/tVector.h"
  32. #endif
  33. #ifndef _ALIGNEDARRAY_H_
  34. #include "core/util/tAlignedArray.h"
  35. #endif
  36. #ifndef _MMATRIX_H_
  37. #include "math/mMatrix.h"
  38. #endif
  39. #ifndef _GFXENUMS_H_
  40. #include "gfx/gfxEnums.h"
  41. #endif
  42. #ifndef _GFXSTRUCTS_H_
  43. #include "gfx/gfxStructs.h"
  44. #endif
  45. #ifndef _COLOR_H_
  46. #include "core/color.h"
  47. #endif
  48. #ifndef _REFBASE_H_
  49. #include "core/util/refBase.h"
  50. #endif
  51. #ifndef _PATH_H_
  52. #include "core/util/path.h"
  53. #endif
  54. #ifndef _TSIGNAL_H_
  55. #include "core/util/tSignal.h"
  56. #endif
  57. class Point2I;
  58. class Point2F;
  59. class LinearColorF;
  60. #ifndef USE_TEMPLATE_MATRIX
  61. class MatrixF;
  62. #else
  63. template<typename DATA_TYPE, U32 rows, U32 cols> class Matrix;
  64. typedef Matrix<F32, 4, 4> MatrixF;
  65. #endif
  66. class GFXShader;
  67. class GFXVertexFormat;
  68. enum GFXShaderStage
  69. {
  70. VERTEX_SHADER = BIT(0),
  71. PIXEL_SHADER = BIT(1),
  72. GEOMETRY_SHADER = BIT(2),
  73. DOMAIN_SHADER = BIT(3),
  74. HULL_SHADER = BIT(4),
  75. COMPUTE_SHADER = BIT(5)
  76. };
  77. /// Instances of this struct are returned GFXShaderConstBuffer
  78. struct GFXShaderConstDesc
  79. {
  80. public:
  81. String name = String::EmptyString;
  82. GFXShaderConstType constType = GFXSCT_Uknown;
  83. U32 arraySize = 0; // > 1 means it is an array!
  84. S32 bindPoint = -1; // bind point used for ubo/cb
  85. S32 samplerReg = -1; // sampler register.
  86. U32 offset = 0; // offset for vars
  87. U32 size = 0; // size of buffer/type
  88. GFXShaderStage shaderStage = VERTEX_SHADER; // only used dx side.not wasting a bit for an unknown?
  89. };
  90. /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
  91. /// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
  92. /// (or shader). Client code should not free these.
  93. class GFXShaderConstHandle
  94. {
  95. public:
  96. GFXShaderConstHandle() { mValid = false; }
  97. virtual ~GFXShaderConstHandle() {}
  98. /// Returns true if this constant is valid and can
  99. /// be set on the shader.
  100. bool isValid() const { return mValid; }
  101. /// Returns the name of the constant handle.
  102. virtual const String& getName() const = 0;
  103. /// Returns the type of the constant handle.
  104. virtual GFXShaderConstType getType() const = 0;
  105. virtual U32 getArraySize() const = 0;
  106. /// Returns -1 if this handle does not point to a Sampler.
  107. virtual S32 getSamplerRegister() const = 0;
  108. protected:
  109. /// The state of the constant which is
  110. /// set from the derived class.
  111. bool mValid;
  112. };
  113. /// GFXShaderConstBuffer is a collection of shader data which
  114. /// are sent to the device in one call in most cases.
  115. ///
  116. /// The content of the buffer is persistant and if a value
  117. /// does not change frequently there is a savings in not setting
  118. /// the value every frame.
  119. ///
  120. class GFXShaderConstBuffer : public GFXResource, public StrongRefBase
  121. {
  122. protected:
  123. /// The lost state of the buffer content.
  124. ///
  125. /// Derived classes need to set the lost state
  126. /// on first creation of the buffer and shader
  127. /// reloads.
  128. ///
  129. /// @see wasLost
  130. bool mWasLost;
  131. GFXShaderConstBuffer()
  132. : mWasLost( true ),
  133. mInstPtr( NULL )
  134. {
  135. }
  136. public:
  137. /// Return the shader that created this buffer
  138. virtual GFXShader* getShader() = 0;
  139. /// The content of the buffer is in the lost state when
  140. /// first created or when the shader is reloaded. When
  141. /// the content is lost you must refill the buffer
  142. /// with all the constants used by your shader.
  143. ///
  144. /// Use this property to avoid setting constants which do
  145. /// not changefrom one frame to the next.
  146. ///
  147. bool wasLost() const { return mWasLost; }
  148. /// An inline helper which ensures the handle is valid
  149. /// before the virtual set method is called.
  150. ///
  151. /// You should prefer using this method unless your sure the
  152. /// handle is always valid or if your doing your own test.
  153. ///
  154. template< typename VALUE >
  155. inline void setSafe( GFXShaderConstHandle *handle, const VALUE& v )
  156. {
  157. if ( handle->isValid() )
  158. set( handle, v );
  159. }
  160. /// Set a shader constant.
  161. ///
  162. /// The constant handle is assumed to be valid.
  163. ///
  164. /// Perfer using setSafe unless you can check the handle
  165. /// validity yourself and skip a significat amount of work.
  166. ///
  167. /// @see GFXShaderConstHandle::isValid()
  168. ///
  169. virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
  170. virtual void set(GFXShaderConstHandle* handle, const Point2F& fv) = 0;
  171. virtual void set(GFXShaderConstHandle* handle, const Point3F& fv) = 0;
  172. virtual void set(GFXShaderConstHandle* handle, const Point4F& fv) = 0;
  173. virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv) = 0;
  174. virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv) = 0;
  175. virtual void set(GFXShaderConstHandle* handle, const S32 f) = 0;
  176. virtual void set(GFXShaderConstHandle* handle, const Point2I& fv) = 0;
  177. virtual void set(GFXShaderConstHandle* handle, const Point3I& fv) = 0;
  178. virtual void set(GFXShaderConstHandle* handle, const Point4I& fv) = 0;
  179. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv) = 0;
  180. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv) = 0;
  181. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv) = 0;
  182. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv) = 0;
  183. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv) = 0;
  184. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
  185. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
  186. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
  187. /// Set a variable sized matrix shader constant.
  188. virtual void set( GFXShaderConstHandle* handle,
  189. const MatrixF& mat,
  190. const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
  191. /// Set a variable sized matrix shader constant from
  192. /// an array of matricies.
  193. virtual void set( GFXShaderConstHandle* handle,
  194. const MatrixF* mat,
  195. const U32 arraySize,
  196. const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
  197. // TODO: Make this protected and put a real API around it.
  198. U8 *mInstPtr;
  199. };
  200. typedef StrongRefPtr<GFXShaderConstBuffer> GFXShaderConstBufferRef;
  201. //**************************************************************************
  202. // Shader
  203. //**************************************************************************
  204. class GFXShader : public StrongRefBase, public GFXResource
  205. {
  206. friend class GFXShaderConstBuffer;
  207. protected:
  208. /// These are system wide shader macros which are
  209. /// merged with shader specific macros at creation.
  210. static Vector<GFXShaderMacro> smGlobalMacros;
  211. /// If true the shader errors are spewed to the console.
  212. static bool smLogErrors;
  213. /// If true the shader warnings are spewed to the console.
  214. static bool smLogWarnings;
  215. /// The vertex shader file.
  216. Torque::Path mVertexFile;
  217. /// The pixel shader file.
  218. Torque::Path mPixelFile;
  219. // the geometry shader file.
  220. Torque::Path mGeometryFile;
  221. /// The macros to be passed to the shader.
  222. Vector<GFXShaderMacro> mMacros;
  223. /// Ordered SamplerNames
  224. /// We need to store a list of sampler for allow OpenGL to
  225. /// assign correct location for each sampler.
  226. /// GLSL 150 not allow explicit uniform location.
  227. /// Only used on OpenGL
  228. Vector<String> mSamplerNamesOrdered;
  229. /// The pixel version this is compiled for.
  230. F32 mPixVersion;
  231. ///
  232. String mDescription;
  233. /// Counter that is incremented each time this shader is reloaded.
  234. U32 mReloadKey;
  235. Signal<void()> mReloadSignal;
  236. /// Vector of buffers that reference this shader.
  237. /// It is the responsibility of the derived shader class to populate this
  238. /// vector and to notify them when this shader is reloaded. Classes
  239. /// derived from GFXShaderConstBuffer should call _unlinkBuffer from
  240. /// their destructor.
  241. Vector<GFXShaderConstBuffer*> mActiveBuffers;
  242. GFXVertexFormat *mInstancingFormat;
  243. /// A protected constructor so it cannot be instantiated.
  244. GFXShader();
  245. public:
  246. /// Adds a global shader macro which will be merged with
  247. /// the script defined macros on every shader reload.
  248. ///
  249. /// The macro will replace the value of an existing macro
  250. /// of the same name.
  251. ///
  252. /// For the new macro to take effect all the shaders/materials
  253. /// in the system need to be reloaded.
  254. ///
  255. /// @see MaterialManager::flushAndReInitInstances
  256. /// @see ShaderData::reloadAll
  257. static void addGlobalMacro( const String &name, const String &value = String::EmptyString );
  258. /// Removes an existing global macro by name.
  259. /// @see addGlobalMacro
  260. static bool removeGlobalMacro( const String &name );
  261. /// Toggle logging for shader errors.
  262. static void setLogging( bool logErrors,
  263. bool logWarning )
  264. {
  265. smLogErrors = logErrors;
  266. smLogWarnings = logWarning;
  267. }
  268. /// The destructor.
  269. virtual ~GFXShader();
  270. ///
  271. /// Deprecated. Remove on T3D 4.0
  272. #ifndef TORQUE_OPENGL
  273. bool init( const Torque::Path &vertFile,
  274. const Torque::Path &pixFile,
  275. F32 pixVersion,
  276. const Vector<GFXShaderMacro> &macros );
  277. #endif
  278. ///
  279. bool init( F32 pixVersion,
  280. const Vector<GFXShaderMacro> &macros,
  281. const Vector<String> &samplerNames,
  282. GFXVertexFormat *instanceFormat = NULL );
  283. /// Reloads the shader from disk.
  284. bool reload();
  285. Signal<void()> getReloadSignal() { return mReloadSignal; }
  286. /// Allocate a constant buffer
  287. virtual GFXShaderConstBufferRef allocConstBuffer() = 0;
  288. /// Returns our list of shader constants, the material can get this and just set the constants it knows about
  289. virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
  290. /// Returns a shader constant handle for the name constant.
  291. ///
  292. /// Since shaders can reload and later have handles that didn't
  293. /// exist originally this will return a handle in an invalid state
  294. /// if the constant doesn't exist at this time.
  295. virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0;
  296. /// Returns a shader constant handle for the name constant, if the variable doesn't exist NULL is returned.
  297. virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
  298. /// Returns the alignment value for constType
  299. virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;
  300. /// Returns the required vertex format for this shader.
  301. /// Returns the pixel shader version.
  302. F32 getPixVersion() const { return mPixVersion; }
  303. /// Returns a counter which is incremented each time this shader is reloaded.
  304. U32 getReloadKey() const { return mReloadKey; }
  305. /// Device specific shaders can override this method to return
  306. /// the shader disassembly.
  307. virtual bool getDisassembly( String &outStr ) const { return false; }
  308. void setShaderStageFile(const GFXShaderStage stage, const Torque::Path& filePath);
  309. /// Returns the vertex shader file path.
  310. const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
  311. /// Returns the pixel shader file path.
  312. const String& getPixelShaderFile() const { return mPixelFile.getFullPath(); }
  313. // GFXResource
  314. const String describeSelf() const override { return mDescription; }
  315. // Get instancing vertex format
  316. GFXVertexFormat *getInstancingFormat() { return mInstancingFormat; }
  317. protected:
  318. /// Called when the shader files change on disk.
  319. void _onFileChanged( const Torque::Path &path ) { reload(); }
  320. /// Internal initialization function overloaded for
  321. /// each GFX device type.
  322. virtual bool _init() = 0;
  323. /// Buffers call this from their destructor (so we don't have to ref count them).
  324. void _unlinkBuffer( GFXShaderConstBuffer *buf );
  325. /// Called to update the description string after init.
  326. void _updateDesc();
  327. };
  328. /// A strong pointer to a reference counted GFXShader.
  329. typedef StrongRefPtr<GFXShader> GFXShaderRef;
  330. /// A weak pointer to a reference counted GFXShader.
  331. typedef WeakRefPtr<GFXShader> GFXShaderWeakRef;
  332. #endif // GFXSHADER