gfxD3D11Shader.h
Engine/source/gfx/D3D11/gfxD3D11Shader.h
Classes:
class
class
class
class
class
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
Public Variables
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; 82 S32 RegisterIndex; 83 S32 RegisterCount; 84 S32 Rows; 85 S32 Columns; 86 S32 Elements; 87 S32 StructMembers; 88 REGISTER_TYPE RegisterSet; 89 CONST_CLASS Class; 90 CONST_TYPE Type; 91 U32 Bytes; 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 302public: 303 304 GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader, 305 GFXD3D11ConstBufferLayout* vertexLayout, 306 GFXD3D11ConstBufferLayout* pixelLayout); 307 308 virtual ~GFXD3D11ShaderConstBuffer(); 309 310 /// Called by GFXD3D11Device to activate this buffer. 311 /// @param mPrevShaderBuffer The previously active buffer 312 void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer); 313 314 /// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty. 315 bool isDirty(); 316 317 /// Called from GFXD3D11Shader when constants have changed and need 318 /// to be the shader this buffer references is reloaded. 319 void onShaderReload(GFXD3D11Shader *shader); 320 321 // GFXShaderConstBuffer 322 virtual GFXShader* getShader(); 323 virtual void set(GFXShaderConstHandle* handle, const F32 fv); 324 virtual void set(GFXShaderConstHandle* handle, const Point2F& fv); 325 virtual void set(GFXShaderConstHandle* handle, const Point3F& fv); 326 virtual void set(GFXShaderConstHandle* handle, const Point4F& fv); 327 virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv); 328 virtual void set(GFXShaderConstHandle* handle, const ColorF& fv); 329 virtual void set(GFXShaderConstHandle* handle, const S32 f); 330 virtual void set(GFXShaderConstHandle* handle, const Point2I& fv); 331 virtual void set(GFXShaderConstHandle* handle, const Point3I& fv); 332 virtual void set(GFXShaderConstHandle* handle, const Point4I& fv); 333 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv); 334 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv); 335 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv); 336 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv); 337 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv); 338 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv); 339 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv); 340 virtual void set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv); 341 virtual void set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matType = GFXSCT_Float4x4); 342 virtual void set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType = GFXSCT_Float4x4); 343 344 // GFXResource 345 virtual const String describeSelf() const; 346 virtual void zombify(); 347 virtual void resurrect(); 348 349protected: 350 351 void _createBuffers(); 352 353 template<class T> 354 inline void SET_CONSTANT(GFXShaderConstHandle* handle, 355 const T& fv, 356 GenericConstBuffer *vBuffer, 357 GenericConstBuffer *pBuffer); 358 359 // Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers 360 ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX]; 361 ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX]; 362 363 /// We keep a weak reference to the shader 364 /// because it will often be deleted. 365 WeakRefPtr<GFXD3D11Shader> mShader; 366 367 //vertex 368 GFXD3D11ConstBufferLayout* mVertexConstBufferLayout; 369 GenericConstBuffer* mVertexConstBuffer; 370 //pixel 371 GFXD3D11ConstBufferLayout* mPixelConstBufferLayout; 372 GenericConstBuffer* mPixelConstBuffer; 373}; 374 375class gfxD3D11Include; 376typedef StrongRefPtr<gfxD3D11Include> gfxD3DIncludeRef; 377 378/////////////////// GFXShader implementation ///////////////////////////// 379 380class GFXD3D11Shader : public GFXShader 381{ 382 friend class GFXD3D11Device; 383 friend class GFXD3D11ShaderConstBuffer; 384 385public: 386 typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap; 387 388 GFXD3D11Shader(); 389 virtual ~GFXD3D11Shader(); 390 391 // GFXShader 392 virtual GFXShaderConstBufferRef allocConstBuffer(); 393 virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const; 394 virtual GFXShaderConstHandle* getShaderConstHandle(const String& name); 395 virtual GFXShaderConstHandle* findShaderConstHandle(const String& name); 396 virtual U32 getAlignmentValue(const GFXShaderConstType constType) const; 397 virtual bool getDisassembly( String &outStr ) const; 398 399 // GFXResource 400 virtual void zombify(); 401 virtual void resurrect(); 402 403protected: 404 405 virtual bool _init(); 406 407 static const U32 smCompiledShaderTag; 408 409 ConstantTable table; 410 411 ID3D11VertexShader *mVertShader; 412 ID3D11PixelShader *mPixShader; 413 414 GFXD3D11ConstBufferLayout* mVertexConstBufferLayout; 415 GFXD3D11ConstBufferLayout* mPixelConstBufferLayout; 416 417 static gfxD3DIncludeRef smD3DInclude; 418 419 HandleMap mHandles; 420 421 /// The shader disassembly from DX when this shader is compiled. 422 /// We only store this data in non-release builds. 423 String mDissasembly; 424 425 /// Vector of sampler type descriptions consolidated from _compileShader. 426 Vector<GFXShaderConstDesc> mSamplerDescriptions; 427 428 /// Vector of descriptions (consolidated for the getShaderConstDesc call) 429 Vector<GFXShaderConstDesc> mShaderConsts; 430 431 // These two functions are used when compiling shaders from hlsl 432 virtual bool _compileShader( const Torque::Path &filePath, 433 const String &target, 434 const D3D_SHADER_MACRO *defines, 435 GenericConstBufferLayout *bufferLayout, 436 Vector<GFXShaderConstDesc> &samplerDescriptions ); 437 438 void _getShaderConstants( ID3D11ShaderReflection* table, 439 GenericConstBufferLayout *bufferLayout, 440 Vector<GFXShaderConstDesc> &samplerDescriptions ); 441 442 bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc); 443 444 445 bool _saveCompiledOutput( const Torque::Path &filePath, 446 ID3DBlob *buffer, 447 GenericConstBufferLayout *bufferLayout, 448 Vector<GFXShaderConstDesc> &samplerDescriptions ); 449 450 // Loads precompiled shaders 451 bool _loadCompiledOutput( const Torque::Path &filePath, 452 const String &target, 453 GenericConstBufferLayout *bufferLayoutF, 454 Vector<GFXShaderConstDesc> &samplerDescriptions ); 455 456 // This is used in both cases 457 virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst); 458 459 virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions ); 460 461 /// Used to build the instancing shader constants from 462 /// the instancing vertex format. 463 void _buildInstancingShaderConstantHandles(); 464}; 465 466inline bool GFXD3D11Shader::getDisassembly(String &outStr) const 467{ 468 outStr = mDissasembly; 469 return (outStr.isNotEmpty()); 470} 471 472#endif 473
