Torque3D Documentation / _generateds / gfxD3D11Shader.h

gfxD3D11Shader.h

Engine/source/gfx/D3D11/gfxD3D11Shader.h

More...

Classes:

class
class
class

The D3D11 implementation of a shader constant buffer.

Public Enumerations

enum
CONST_CLASS {
  D3DPC_SCALAR 
  D3DPC_VECTOR 
  D3DPC_MATRIX_ROWS 
  D3DPC_MATRIX_COLUMNS 
  D3DPC_OBJECT 
  D3DPC_STRUCT 
}
enum
CONST_TYPE {
  D3DPT_VOID 
  D3DPT_BOOL 
  D3DPT_INT 
  D3DPT_FLOAT 
  D3DPT_STRING 
  D3DPT_TEXTURE 
  D3DPT_TEXTURE1D 
  D3DPT_TEXTURE2D 
  D3DPT_TEXTURE3D 
  D3DPT_TEXTURECUBE 
  D3DPT_SAMPLER 
  D3DPT_SAMPLER1D 
  D3DPT_SAMPLER2D 
  D3DPT_SAMPLER3D 
  D3DPT_SAMPLERCUBE 
  D3DPT_PIXELSHADER 
  D3DPT_VERTEXSHADER 
  D3DPT_PIXELFRAGMENT 
  D3DPT_VERTEXFRAGMENT 
}
enum
REGISTER_TYPE {
  D3DRS_BOOL 
  D3DRS_INT4 
  D3DRS_FLOAT4 
  D3DRS_SAMPLER 
}

Public Typedefs

gfxD3DIncludeRef 

Detailed Description

Public Enumerations

CONST_CLASS

Enumerator

D3DPC_SCALAR
D3DPC_VECTOR
D3DPC_MATRIX_ROWS
D3DPC_MATRIX_COLUMNS
D3DPC_OBJECT
D3DPC_STRUCT
CONST_TYPE

Enumerator

D3DPT_VOID
D3DPT_BOOL
D3DPT_INT
D3DPT_FLOAT
D3DPT_STRING
D3DPT_TEXTURE
D3DPT_TEXTURE1D
D3DPT_TEXTURE2D
D3DPT_TEXTURE3D
D3DPT_TEXTURECUBE
D3DPT_SAMPLER
D3DPT_SAMPLER1D
D3DPT_SAMPLER2D
D3DPT_SAMPLER3D
D3DPT_SAMPLERCUBE
D3DPT_PIXELSHADER
D3DPT_VERTEXSHADER
D3DPT_PIXELFRAGMENT
D3DPT_VERTEXFRAGMENT
REGISTER_TYPE

Enumerator

D3DRS_BOOL
D3DRS_INT4
D3DRS_FLOAT4
D3DRS_SAMPLER

Public Typedefs

typedef StrongRefPtr< gfxD3D11Include > gfxD3DIncludeRef 

Public Variables

const U32 CBUFFER_MAX 
const U32 CTAB_CONSTANT 
const U32 SI_COMMENTSIZE_MASK 
const U32 SI_OPCODE_MASK 
const U32 SIO_COMMENT 
const U32 SIO_END 
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2015 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _GFXD3D11SHADER_H_
 25#define _GFXD3D11SHADER_H_
 26
 27#include <d3dcompiler.h>
 28
 29#include "core/util/path.h"
 30#include "core/util/tDictionary.h"
 31#include "gfx/gfxShader.h"
 32#include "gfx/gfxResource.h"
 33#include "gfx/genericConstBuffer.h"
 34#include "gfx/D3D11/gfxD3D11Device.h"
 35
 36class GFXD3D11Shader;
 37
 38enum CONST_CLASS
 39{
 40   D3DPC_SCALAR,
 41   D3DPC_VECTOR,
 42   D3DPC_MATRIX_ROWS,
 43   D3DPC_MATRIX_COLUMNS,
 44   D3DPC_OBJECT,
 45   D3DPC_STRUCT
 46};
 47
 48enum CONST_TYPE 
 49{ 
 50   D3DPT_VOID, 
 51   D3DPT_BOOL, 
 52   D3DPT_INT, 
 53   D3DPT_FLOAT, 
 54   D3DPT_STRING, 
 55   D3DPT_TEXTURE, 
 56   D3DPT_TEXTURE1D, 
 57   D3DPT_TEXTURE2D, 
 58   D3DPT_TEXTURE3D, 
 59   D3DPT_TEXTURECUBE, 
 60   D3DPT_SAMPLER, 
 61   D3DPT_SAMPLER1D, 
 62   D3DPT_SAMPLER2D, 
 63   D3DPT_SAMPLER3D, 
 64   D3DPT_SAMPLERCUBE, 
 65   D3DPT_PIXELSHADER, 
 66   D3DPT_VERTEXSHADER, 
 67   D3DPT_PIXELFRAGMENT, 
 68   D3DPT_VERTEXFRAGMENT
 69};
 70
 71enum REGISTER_TYPE
 72{
 73   D3DRS_BOOL,
 74   D3DRS_INT4,
 75   D3DRS_FLOAT4,
 76   D3DRS_SAMPLER
 77};
 78
 79struct ConstantDesc
 80{
 81   String Name = String::EmptyString;
 82   S32 RegisterIndex = 0;
 83   S32 RegisterCount = 0;
 84   S32 Rows = 0;
 85   S32 Columns = 0;
 86   S32 Elements = 0;
 87   S32 StructMembers = 0;
 88   REGISTER_TYPE RegisterSet = D3DRS_FLOAT4;
 89   CONST_CLASS Class = D3DPC_SCALAR;
 90   CONST_TYPE Type = D3DPT_FLOAT;
 91   U32 Bytes = 0;
 92};
 93
 94class ConstantTable
 95{
 96public:
 97   bool Create(const void* data);
 98
 99   U32 GetConstantCount() const { return m_constants.size(); }
100   const String& GetCreator() const { return m_creator; } 
101
102   const ConstantDesc* GetConstantByIndex(U32 i) const { return &m_constants[i]; }
103   const ConstantDesc* GetConstantByName(const String& name) const;
104
105   void ClearConstants() { m_constants.clear(); }
106
107private:
108   Vector<ConstantDesc> m_constants;
109   String m_creator;
110};
111
112// Structs
113struct CTHeader
114{
115   U32 Size;
116   U32 Creator;
117   U32 Version;
118   U32 Constants;
119   U32 ConstantInfo;
120   U32 Flags;
121   U32 Target;
122};
123
124struct CTInfo
125{
126   U32 Name;
127   U16 RegisterSet;
128   U16 RegisterIndex;
129   U16 RegisterCount;
130   U16 Reserved;
131   U32 TypeInfo;
132   U32 DefaultValue;
133};
134
135struct CTType
136{
137   U16 Class;
138   U16 Type;
139   U16 Rows;
140   U16 Columns;
141   U16 Elements;
142   U16 StructMembers;
143   U32 StructMemberInfo;
144};
145
146// Shader instruction opcodes
147const U32 SIO_COMMENT = 0x0000FFFE;
148const U32 SIO_END = 0x0000FFFF;
149const U32 SI_OPCODE_MASK = 0x0000FFFF;
150const U32 SI_COMMENTSIZE_MASK = 0x7FFF0000;
151const U32 CTAB_CONSTANT = 0x42415443;
152
153// Member functions
154inline bool ConstantTable::Create(const void* data)
155{
156   const U32* ptr = static_cast<const U32*>(data);
157   while(*++ptr != SIO_END)
158   {
159      if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT)
160      {
161         // Check for CTAB comment
162         U32 comment_size = (*ptr & SI_COMMENTSIZE_MASK) >> 16;
163         if(*(ptr+1) != CTAB_CONSTANT)
164         {
165            ptr += comment_size;
166            continue;
167         }
168
169         // Read header
170         const char* ctab = reinterpret_cast<const char*>(ptr+2);
171         size_t ctab_size = (comment_size-1)*4;
172
173         const CTHeader* header = reinterpret_cast<const CTHeader*>(ctab);
174         if(ctab_size < sizeof(*header) || header->Size != sizeof(*header))
175            return false;
176         m_creator = ctab + header->Creator;
177
178         // Read constants
179         m_constants.reserve(header->Constants);
180         const CTInfo* info = reinterpret_cast<const CTInfo*>(ctab + header->ConstantInfo);
181         for(U32 i = 0; i < header->Constants; ++i)
182         {
183            const CTType* type = reinterpret_cast<const CTType*>(ctab + info[i].TypeInfo);
184
185            // Fill struct
186            ConstantDesc desc;
187            desc.Name = ctab + info[i].Name;
188            desc.RegisterSet = static_cast<REGISTER_TYPE>(info[i].RegisterSet);
189            desc.RegisterIndex = info[i].RegisterIndex;
190            desc.RegisterCount = info[i].RegisterCount;
191            desc.Rows = type->Rows;
192            desc.Class = static_cast<CONST_CLASS>(type->Class);
193            desc.Type = static_cast<CONST_TYPE>(type->Type);
194            desc.Columns = type->Columns;
195            desc.Elements = type->Elements;
196            desc.StructMembers = type->StructMembers;
197            desc.Bytes = 4 * desc.Elements * desc.Rows * desc.Columns;
198            m_constants.push_back(desc);
199         }
200
201         return true;
202      }
203   }
204   return false;
205}
206
207inline const ConstantDesc* ConstantTable::GetConstantByName(const String& name) const
208{
209   Vector<ConstantDesc>::const_iterator it;
210   for(it = m_constants.begin(); it != m_constants.end(); ++it)
211   {
212      if(it->Name == name)
213         return &(*it);
214   }
215   return NULL;
216}
217
218/////////////////// Constant Buffers /////////////////////////////
219
220// Maximum number of CBuffers ($Globals & $Params)
221const U32 CBUFFER_MAX = 2;
222
223struct ConstSubBufferDesc
224{
225   U32 start;
226   U32 size;
227
228   ConstSubBufferDesc() : start(0), size(0){}
229};
230
231class GFXD3D11ConstBufferLayout : public GenericConstBufferLayout
232{
233public:
234   GFXD3D11ConstBufferLayout();
235   /// Get our constant sub buffer data
236   Vector<ConstSubBufferDesc> &getSubBufferDesc(){ return mSubBuffers; }
237   
238   /// We need to manually set the size due to D3D11 alignment
239   void setSize(U32 size){ mBufferSize = size;}
240
241   /// Set a parameter, given a base pointer
242   virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
243
244protected:
245   /// Set a matrix, given a base pointer
246   virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
247
248   Vector<ConstSubBufferDesc> mSubBuffers;
249};
250
251class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
252{
253public:   
254
255   // GFXShaderConstHandle
256   const String& getName() const;
257   GFXShaderConstType getType() const;
258   U32 getArraySize() const;
259
260   WeakRefPtr<GFXD3D11Shader> mShader;
261
262   bool mVertexConstant;
263   GenericConstBufferLayout::ParamDesc mVertexHandle;
264   bool mPixelConstant;
265   GenericConstBufferLayout::ParamDesc mPixelHandle;
266   
267   /// Is true if this constant is for hardware mesh instancing.
268   ///
269   /// Note: We currently store its settings in mPixelHandle.
270   ///
271   bool mInstancingConstant;
272
273   void setValid( bool valid ) { mValid = valid; }
274   S32 getSamplerRegister() const;
275
276   // Returns true if this is a handle to a sampler register.
277   bool isSampler() const 
278   {
279      return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) || ( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler );
280   }
281
282   /// Restore to uninitialized state.
283   void clear()
284   {
285      mShader = NULL;
286      mVertexConstant = false;
287      mPixelConstant = false;
288      mInstancingConstant = false;
289      mVertexHandle.clear();
290      mPixelHandle.clear();
291      mValid = false;
292   }
293
294   GFXD3D11ShaderConstHandle();
295};
296
297/// The D3D11 implementation of a shader constant buffer.
298class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
299{
300   friend class GFXD3D11Shader;
301   // Cache device context
302   ID3D11DeviceContext* mDeviceContext;
303
304public:
305
306   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader,
307      GFXD3D11ConstBufferLayout* vertexLayout,
308      GFXD3D11ConstBufferLayout* pixelLayout);
309
310   virtual ~GFXD3D11ShaderConstBuffer();
311
312   /// Called by GFXD3D11Device to activate this buffer.
313   /// @param mPrevShaderBuffer The previously active buffer
314   void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
315
316   /// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
317   bool isDirty();
318
319   /// Called from GFXD3D11Shader when constants have changed and need
320   /// to be the shader this buffer references is reloaded.
321   void onShaderReload(GFXD3D11Shader *shader);
322
323   // GFXShaderConstBuffer
324   virtual GFXShader* getShader();
325   virtual void set(GFXShaderConstHandle* handle, const F32 fv);
326   virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
327   virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
328   virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
329   virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
330   virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv);
331   virtual void set(GFXShaderConstHandle* handle, const S32 f);
332   virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
333   virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
334   virtual void set(GFXShaderConstHandle* handle, const Point4I& fv);
335   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv);
336   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv);
337   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv);
338   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv);
339   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv);
340   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv);
341   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv);
342   virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv);
343   virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4);
344   virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4);
345
346   // GFXResource
347   virtual const String describeSelf() const;
348   virtual void zombify();
349   virtual void resurrect();
350
351protected:
352
353   void _createBuffers();
354
355   template<class T>
356   inline void SET_CONSTANT(GFXShaderConstHandle* handle,
357      const T& fv,
358      GenericConstBuffer *vBuffer,
359      GenericConstBuffer *pBuffer);
360
361   // Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers
362   ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX];
363   ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX];
364
365   /// We keep a weak reference to the shader 
366   /// because it will often be deleted.
367   WeakRefPtr<GFXD3D11Shader> mShader;
368
369   //vertex
370   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
371   GenericConstBuffer* mVertexConstBuffer;
372   //pixel
373   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
374   GenericConstBuffer* mPixelConstBuffer;
375};
376
377class gfxD3D11Include;
378typedef StrongRefPtr<gfxD3D11Include> gfxD3DIncludeRef;
379
380/////////////////// GFXShader implementation /////////////////////////////
381
382class GFXD3D11Shader : public GFXShader
383{
384   friend class GFXD3D11Device;
385   friend class GFXD3D11ShaderConstBuffer;
386
387public:
388   typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
389
390   GFXD3D11Shader();
391   virtual ~GFXD3D11Shader();   
392
393   // GFXShader
394   virtual GFXShaderConstBufferRef allocConstBuffer();
395   virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
396   virtual GFXShaderConstHandle* getShaderConstHandle(const String& name); 
397   virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
398   virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
399   virtual bool getDisassembly( String &outStr ) const;
400
401   // GFXResource
402   virtual void zombify();
403   virtual void resurrect();
404
405protected:
406
407   virtual bool _init();   
408
409   static const U32 smCompiledShaderTag;
410
411   ConstantTable table;
412
413   ID3D11VertexShader *mVertShader;
414   ID3D11PixelShader *mPixShader;
415
416   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
417   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;   
418
419   static gfxD3DIncludeRef smD3DInclude;
420
421   HandleMap mHandles;
422
423   /// The shader disassembly from DX when this shader is compiled.
424   /// We only store this data in non-release builds.
425   String mDissasembly;
426
427   /// Vector of sampler type descriptions consolidated from _compileShader.
428   Vector<GFXShaderConstDesc> mSamplerDescriptions;
429
430   /// Vector of descriptions (consolidated for the getShaderConstDesc call)
431   Vector<GFXShaderConstDesc> mShaderConsts;
432   
433   // These two functions are used when compiling shaders from hlsl
434   virtual bool _compileShader( const Torque::Path &filePath, 
435                                const String &target, 
436                                const D3D_SHADER_MACRO *defines, 
437                                GenericConstBufferLayout *bufferLayout, 
438                                Vector<GFXShaderConstDesc> &samplerDescriptions );
439
440   void _getShaderConstants( ID3D11ShaderReflection* refTable, 
441                            GenericConstBufferLayout *bufferLayout,
442                             Vector<GFXShaderConstDesc> &samplerDescriptions );
443
444   bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc);
445
446
447   bool _saveCompiledOutput( const Torque::Path &filePath, 
448                             ID3DBlob *buffer, 
449                             GenericConstBufferLayout *bufferLayout,
450                             Vector<GFXShaderConstDesc> &samplerDescriptions );
451
452   // Loads precompiled shaders
453   bool _loadCompiledOutput( const Torque::Path &filePath, 
454                             const String &target, 
455                             GenericConstBufferLayout *bufferLayoutF, 
456                             Vector<GFXShaderConstDesc> &samplerDescriptions );
457  
458   // This is used in both cases
459   virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst);
460   
461   virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
462
463   /// Used to build the instancing shader constants from 
464   /// the instancing vertex format.
465   void _buildInstancingShaderConstantHandles();
466};
467
468inline bool GFXD3D11Shader::getDisassembly(String &outStr) const
469{
470   outStr = mDissasembly;
471   return (outStr.isNotEmpty());
472}
473
474#endif
475