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 = 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