gfxShader.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  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. class MatrixF;
  61. class GFXShader;
  62. class GFXVertexFormat;
  63. /// Instances of this struct are returned GFXShaderConstBuffer
  64. struct GFXShaderConstDesc
  65. {
  66. public:
  67. String name;
  68. GFXShaderConstType constType;
  69. U32 arraySize; // > 1 means it is an array!
  70. };
  71. /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.
  72. /// Derived classes can put whatever info they need into here, these handles are owned by the shader constant buffer
  73. /// (or shader). Client code should not free these.
  74. class GFXShaderConstHandle
  75. {
  76. public:
  77. GFXShaderConstHandle() { mValid = false; }
  78. virtual ~GFXShaderConstHandle() {}
  79. /// Returns true if this constant is valid and can
  80. /// be set on the shader.
  81. bool isValid() const { return mValid; }
  82. /// Returns the name of the constant handle.
  83. virtual const String& getName() const = 0;
  84. /// Returns the type of the constant handle.
  85. virtual GFXShaderConstType getType() const = 0;
  86. virtual U32 getArraySize() const = 0;
  87. /// Returns -1 if this handle does not point to a Sampler.
  88. virtual S32 getSamplerRegister() const = 0;
  89. protected:
  90. /// The state of the constant which is
  91. /// set from the derived class.
  92. bool mValid;
  93. };
  94. /// GFXShaderConstBuffer is a collection of shader data which
  95. /// are sent to the device in one call in most cases.
  96. ///
  97. /// The content of the buffer is persistant and if a value
  98. /// does not change frequently there is a savings in not setting
  99. /// the value every frame.
  100. ///
  101. class GFXShaderConstBuffer : public GFXResource, public StrongRefBase
  102. {
  103. protected:
  104. /// The lost state of the buffer content.
  105. ///
  106. /// Derived classes need to set the lost state
  107. /// on first creation of the buffer and shader
  108. /// reloads.
  109. ///
  110. /// @see wasLost
  111. bool mWasLost;
  112. GFXShaderConstBuffer()
  113. : mWasLost( true ),
  114. mInstPtr( NULL )
  115. {
  116. }
  117. public:
  118. /// Return the shader that created this buffer
  119. virtual GFXShader* getShader() = 0;
  120. /// The content of the buffer is in the lost state when
  121. /// first created or when the shader is reloaded. When
  122. /// the content is lost you must refill the buffer
  123. /// with all the constants used by your shader.
  124. ///
  125. /// Use this property to avoid setting constants which do
  126. /// not changefrom one frame to the next.
  127. ///
  128. bool wasLost() const { return mWasLost; }
  129. /// An inline helper which ensures the handle is valid
  130. /// before the virtual set method is called.
  131. ///
  132. /// You should prefer using this method unless your sure the
  133. /// handle is always valid or if your doing your own test.
  134. ///
  135. template< typename VALUE >
  136. inline void setSafe( GFXShaderConstHandle *handle, const VALUE& v )
  137. {
  138. if ( handle->isValid() )
  139. set( handle, v );
  140. }
  141. /// Set a shader constant.
  142. ///
  143. /// The constant handle is assumed to be valid.
  144. ///
  145. /// Perfer using setSafe unless you can check the handle
  146. /// validity yourself and skip a significat amount of work.
  147. ///
  148. /// @see GFXShaderConstHandle::isValid()
  149. ///
  150. virtual void set(GFXShaderConstHandle* handle, const F32 f) = 0;
  151. virtual void set(GFXShaderConstHandle* handle, const Point2F& fv) = 0;
  152. virtual void set(GFXShaderConstHandle* handle, const Point3F& fv) = 0;
  153. virtual void set(GFXShaderConstHandle* handle, const Point4F& fv) = 0;
  154. virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv) = 0;
  155. virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv) = 0;
  156. virtual void set(GFXShaderConstHandle* handle, const S32 f) = 0;
  157. virtual void set(GFXShaderConstHandle* handle, const Point2I& fv) = 0;
  158. virtual void set(GFXShaderConstHandle* handle, const Point3I& fv) = 0;
  159. virtual void set(GFXShaderConstHandle* handle, const Point4I& fv) = 0;
  160. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv) = 0;
  161. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv) = 0;
  162. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv) = 0;
  163. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv) = 0;
  164. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv) = 0;
  165. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv) = 0;
  166. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv) = 0;
  167. virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv) = 0;
  168. /// Set a variable sized matrix shader constant.
  169. virtual void set( GFXShaderConstHandle* handle,
  170. const MatrixF& mat,
  171. const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
  172. /// Set a variable sized matrix shader constant from
  173. /// an array of matricies.
  174. virtual void set( GFXShaderConstHandle* handle,
  175. const MatrixF* mat,
  176. const U32 arraySize,
  177. const GFXShaderConstType matrixType = GFXSCT_Float4x4 ) = 0;
  178. // TODO: Make this protected and put a real API around it.
  179. U8 *mInstPtr;
  180. };
  181. typedef StrongRefPtr<GFXShaderConstBuffer> GFXShaderConstBufferRef;
  182. //**************************************************************************
  183. // Shader
  184. //**************************************************************************
  185. class GFXShader : public StrongRefBase, public GFXResource
  186. {
  187. friend class GFXShaderConstBuffer;
  188. protected:
  189. /// These are system wide shader macros which are
  190. /// merged with shader specific macros at creation.
  191. static Vector<GFXShaderMacro> smGlobalMacros;
  192. /// If true the shader errors are spewed to the console.
  193. static bool smLogErrors;
  194. /// If true the shader warnings are spewed to the console.
  195. static bool smLogWarnings;
  196. /// The vertex shader file.
  197. Torque::Path mVertexFile;
  198. /// The pixel shader file.
  199. Torque::Path mPixelFile;
  200. /// The macros to be passed to the shader.
  201. Vector<GFXShaderMacro> mMacros;
  202. /// Ordered SamplerNames
  203. /// We need to store a list of sampler for allow OpenGL to
  204. /// assign correct location for each sampler.
  205. /// GLSL 150 not allow explicit uniform location.
  206. /// Only used on OpenGL
  207. Vector<String> mSamplerNamesOrdered;
  208. /// The pixel version this is compiled for.
  209. F32 mPixVersion;
  210. ///
  211. String mDescription;
  212. /// Counter that is incremented each time this shader is reloaded.
  213. U32 mReloadKey;
  214. Signal<void()> mReloadSignal;
  215. /// Vector of buffers that reference this shader.
  216. /// It is the responsibility of the derived shader class to populate this
  217. /// vector and to notify them when this shader is reloaded. Classes
  218. /// derived from GFXShaderConstBuffer should call _unlinkBuffer from
  219. /// their destructor.
  220. Vector<GFXShaderConstBuffer*> mActiveBuffers;
  221. GFXVertexFormat *mInstancingFormat;
  222. /// A protected constructor so it cannot be instantiated.
  223. GFXShader();
  224. public:
  225. /// Adds a global shader macro which will be merged with
  226. /// the script defined macros on every shader reload.
  227. ///
  228. /// The macro will replace the value of an existing macro
  229. /// of the same name.
  230. ///
  231. /// For the new macro to take effect all the shaders/materials
  232. /// in the system need to be reloaded.
  233. ///
  234. /// @see MaterialManager::flushAndReInitInstances
  235. /// @see ShaderData::reloadAll
  236. static void addGlobalMacro( const String &name, const String &value = String::EmptyString );
  237. /// Removes an existing global macro by name.
  238. /// @see addGlobalMacro
  239. static bool removeGlobalMacro( const String &name );
  240. /// Toggle logging for shader errors.
  241. static void setLogging( bool logErrors,
  242. bool logWarning )
  243. {
  244. smLogErrors = logErrors;
  245. smLogWarnings = logWarning;
  246. }
  247. /// The destructor.
  248. virtual ~GFXShader();
  249. ///
  250. /// Deprecated. Remove on T3D 4.0
  251. #ifndef TORQUE_OPENGL
  252. bool init( const Torque::Path &vertFile,
  253. const Torque::Path &pixFile,
  254. F32 pixVersion,
  255. const Vector<GFXShaderMacro> &macros );
  256. #endif
  257. ///
  258. bool init( const Torque::Path &vertFile,
  259. const Torque::Path &pixFile,
  260. F32 pixVersion,
  261. const Vector<GFXShaderMacro> &macros,
  262. const Vector<String> &samplerNames,
  263. GFXVertexFormat *instanceFormat = NULL );
  264. /// Reloads the shader from disk.
  265. bool reload();
  266. Signal<void()> getReloadSignal() { return mReloadSignal; }
  267. /// Allocate a constant buffer
  268. virtual GFXShaderConstBufferRef allocConstBuffer() = 0;
  269. /// Returns our list of shader constants, the material can get this and just set the constants it knows about
  270. virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const = 0;
  271. /// Returns a shader constant handle for the name constant.
  272. ///
  273. /// Since shaders can reload and later have handles that didn't
  274. /// exist originally this will return a handle in an invalid state
  275. /// if the constant doesn't exist at this time.
  276. virtual GFXShaderConstHandle* getShaderConstHandle( const String& name ) = 0;
  277. /// Returns a shader constant handle for the name constant, if the variable doesn't exist NULL is returned.
  278. virtual GFXShaderConstHandle* findShaderConstHandle( const String& name ) = 0;
  279. /// Returns the alignment value for constType
  280. virtual U32 getAlignmentValue(const GFXShaderConstType constType) const = 0;
  281. /// Returns the required vertex format for this shader.
  282. /// Returns the pixel shader version.
  283. F32 getPixVersion() const { return mPixVersion; }
  284. /// Returns a counter which is incremented each time this shader is reloaded.
  285. U32 getReloadKey() const { return mReloadKey; }
  286. /// Device specific shaders can override this method to return
  287. /// the shader disassembly.
  288. virtual bool getDisassembly( String &outStr ) const { return false; }
  289. /// Returns the vertex shader file path.
  290. const String& getVertexShaderFile() const { return mVertexFile.getFullPath(); }
  291. /// Returns the pixel shader file path.
  292. const String& getPixelShaderFile() const { return mPixelFile.getFullPath(); }
  293. // GFXResource
  294. const String describeSelf() const { return mDescription; }
  295. // Get instancing vertex format
  296. GFXVertexFormat *getInstancingFormat() { return mInstancingFormat; }
  297. protected:
  298. /// Called when the shader files change on disk.
  299. void _onFileChanged( const Torque::Path &path ) { reload(); }
  300. /// Internal initialization function overloaded for
  301. /// each GFX device type.
  302. virtual bool _init() = 0;
  303. /// Buffers call this from their destructor (so we don't have to ref count them).
  304. void _unlinkBuffer( GFXShaderConstBuffer *buf );
  305. /// Called to update the description string after init.
  306. void _updateDesc();
  307. };
  308. /// A strong pointer to a reference counted GFXShader.
  309. typedef StrongRefPtr<GFXShader> GFXShaderRef;
  310. /// A weak pointer to a reference counted GFXShader.
  311. typedef WeakRefPtr<GFXShader> GFXShaderWeakRef;
  312. #endif // GFXSHADER