Просмотр исходного кода

Shader refactor

Refactored DX Shader compilation and reflection to be more similar to opengl
Added support for more than 1 const buffer per shader stage.

This is boilerplate code, no functionality yet, that will be added in further commits. Though this builds without errors do not try and run it at this point.
marauder2k7 1 год назад
Родитель
Сommit
55519aac57

Разница между файлами не показана из-за своего большого размера
+ 239 - 843
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp


+ 36 - 294
Engine/source/gfx/D3D11/gfxD3D11Shader.h

@@ -34,263 +34,49 @@
 
 class GFXD3D11Shader;
 
-enum CONST_CLASS
+enum SHADER_STAGE
 {
-	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
-};
-
-struct ConstantDesc
-{
-   String Name = String::EmptyString;
-   S32 RegisterIndex = 0;
-   S32 RegisterCount = 0;
-   S32 Rows = 0;
-   S32 Columns = 0;
-   S32 Elements = 0;
-   S32 StructMembers = 0;
-   REGISTER_TYPE RegisterSet = D3DRS_FLOAT4;
-   CONST_CLASS Class = D3DPC_SCALAR;
-   CONST_TYPE Type = D3DPT_FLOAT;
-   U32 Bytes = 0;
-};
-
-class ConstantTable
-{
-public:
-   bool Create(const void* data);
-
-   U32 GetConstantCount() const { return m_constants.size(); }
-   const String& GetCreator() const { return m_creator; } 
-
-   const ConstantDesc* GetConstantByIndex(U32 i) const { return &m_constants[i]; }
-   const ConstantDesc* GetConstantByName(const String& name) const;
-
-   void ClearConstants() { m_constants.clear(); }
-
-private:
-   Vector<ConstantDesc> m_constants;
-   String m_creator;
-};
-
-// Structs
-struct CTHeader
-{
-   U32 Size;
-   U32 Creator;
-   U32 Version;
-   U32 Constants;
-   U32 ConstantInfo;
-   U32 Flags;
-   U32 Target;
-};
-
-struct CTInfo
-{
-   U32 Name;
-   U16 RegisterSet;
-   U16 RegisterIndex;
-   U16 RegisterCount;
-   U16 Reserved;
-   U32 TypeInfo;
-   U32 DefaultValue;
-};
-
-struct CTType
-{
-   U16 Class;
-   U16 Type;
-   U16 Rows;
-   U16 Columns;
-   U16 Elements;
-   U16 StructMembers;
-   U32 StructMemberInfo;
-};
-
-// Shader instruction opcodes
-const U32 SIO_COMMENT = 0x0000FFFE;
-const U32 SIO_END = 0x0000FFFF;
-const U32 SI_OPCODE_MASK = 0x0000FFFF;
-const U32 SI_COMMENTSIZE_MASK = 0x7FFF0000;
-const U32 CTAB_CONSTANT = 0x42415443;
-
-// Member functions
-inline bool ConstantTable::Create(const void* data)
-{
-   const U32* ptr = static_cast<const U32*>(data);
-   while(*++ptr != SIO_END)
-   {
-      if((*ptr & SI_OPCODE_MASK) == SIO_COMMENT)
-      {
-         // Check for CTAB comment
-         U32 comment_size = (*ptr & SI_COMMENTSIZE_MASK) >> 16;
-         if(*(ptr+1) != CTAB_CONSTANT)
-         {
-            ptr += comment_size;
-            continue;
-         }
-
-         // Read header
-         const char* ctab = reinterpret_cast<const char*>(ptr+2);
-         size_t ctab_size = (comment_size-1)*4;
-
-         const CTHeader* header = reinterpret_cast<const CTHeader*>(ctab);
-         if(ctab_size < sizeof(*header) || header->Size != sizeof(*header))
-            return false;
-         m_creator = ctab + header->Creator;
-
-         // Read constants
-         m_constants.reserve(header->Constants);
-         const CTInfo* info = reinterpret_cast<const CTInfo*>(ctab + header->ConstantInfo);
-         for(U32 i = 0; i < header->Constants; ++i)
-         {
-            const CTType* type = reinterpret_cast<const CTType*>(ctab + info[i].TypeInfo);
-
-            // Fill struct
-            ConstantDesc desc;
-            desc.Name = ctab + info[i].Name;
-            desc.RegisterSet = static_cast<REGISTER_TYPE>(info[i].RegisterSet);
-            desc.RegisterIndex = info[i].RegisterIndex;
-            desc.RegisterCount = info[i].RegisterCount;
-            desc.Rows = type->Rows;
-            desc.Class = static_cast<CONST_CLASS>(type->Class);
-            desc.Type = static_cast<CONST_TYPE>(type->Type);
-            desc.Columns = type->Columns;
-            desc.Elements = type->Elements;
-            desc.StructMembers = type->StructMembers;
-            desc.Bytes = 4 * desc.Elements * desc.Rows * desc.Columns;
-            m_constants.push_back(desc);
-         }
-
-         return true;
-      }
-   }
-   return false;
-}
-
-inline const ConstantDesc* ConstantTable::GetConstantByName(const String& name) const
-{
-   Vector<ConstantDesc>::const_iterator it;
-   for(it = m_constants.begin(); it != m_constants.end(); ++it)
-   {
-      if(it->Name == name)
-         return &(*it);
-   }
-   return NULL;
-}
-
-/////////////////// Constant Buffers /////////////////////////////
-
-// Maximum number of CBuffers ($Globals & $Params)
-const U32 CBUFFER_MAX = 2;
-
-struct ConstSubBufferDesc
-{
-   U32 start;
-   U32 size;
-
-   ConstSubBufferDesc() : start(0), size(0){}
-};
-
-class GFXD3D11ConstBufferLayout : public GenericConstBufferLayout
-{
-public:
-   GFXD3D11ConstBufferLayout();
-   /// Get our constant sub buffer data
-   Vector<ConstSubBufferDesc> &getSubBufferDesc(){ return mSubBuffers; }
-   
-   /// We need to manually set the size due to D3D11 alignment
-   void setSize(U32 size){ mBufferSize = size;}
-
-   /// Set a parameter, given a base pointer
-   virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
-
-protected:
-   /// Set a matrix, given a base pointer
-   virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
-
-   Vector<ConstSubBufferDesc> mSubBuffers;
+   VERTEX_SHADER,
+   PIXEL_SHADER,
+   GEOMETRY_SHADER,
+   DOMAIN_SHADER,
+   HULL_SHADER,
+   COMPUTE_SHADER
 };
 
 class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
 {
+   friend class GFXD3D11Shader;
 public:   
 
-   // GFXShaderConstHandle
-   const String& getName() const;
-   GFXShaderConstType getType() const;
-   U32 getArraySize() const;
-
-   WeakRefPtr<GFXD3D11Shader> mShader;
+   GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader);
+   GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader, const GFXShaderConstDesc& desc, S32 samplerNum);
+   virtual ~GFXD3D11ShaderConstHandle();
 
-   bool mVertexConstant;
-   GenericConstBufferLayout::ParamDesc mVertexHandle;
-   bool mPixelConstant;
-   GenericConstBufferLayout::ParamDesc mPixelHandle;
-   
-   /// Is true if this constant is for hardware mesh instancing.
-   ///
-   /// Note: We currently store its settings in mPixelHandle.
-   ///
-   bool mInstancingConstant;
+   const String& getName() const { return mDesc.name; }
+   GFXShaderConstType getType() const { return mDesc.constType; }
+   U32 getArraySize() const { return mDesc.arraySize; }
 
-   void setValid( bool valid ) { mValid = valid; }
-   S32 getSamplerRegister() const;
+   U32 getSize() const;
+   void setValid(bool valid) { mValid = valid; }
+   /// @warning This will always return the value assigned when the shader was
+   /// initialized.  If the value is later changed this method won't reflect that.
+   S32 getSamplerRegister() const { return mSamplerNum; }
 
    // Returns true if this is a handle to a sampler register.
    bool isSampler() const 
    {
-      return ( mPixelConstant && mPixelHandle.constType >= GFXSCT_Sampler ) || ( mVertexConstant && mVertexHandle.constType >= GFXSCT_Sampler );
-   }
-
-   /// Restore to uninitialized state.
-   void clear()
-   {
-      mShader = NULL;
-      mVertexConstant = false;
-      mPixelConstant = false;
-      mInstancingConstant = false;
-      mVertexHandle.clear();
-      mPixelHandle.clear();
-      mValid = false;
+      return (getType() >= GFXSCT_Sampler);
    }
 
    GFXD3D11ShaderConstHandle();
+   GFXShaderConstDesc mDesc;
+   GFXD3D11Shader* mShader;
+   U32 mOffset;
+   U32 mSize;
+   S32 mSamplerNum;
+   SHADER_STAGE stage;
+   bool mInstancingConstant;
 };
 
 /// The D3D11 implementation of a shader constant buffer.
@@ -302,9 +88,7 @@ class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
 
 public:
 
-   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader,
-      GFXD3D11ConstBufferLayout* vertexLayout,
-      GFXD3D11ConstBufferLayout* pixelLayout);
+   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader, U32 bufSize, U8* existingConstants);
 
    virtual ~GFXD3D11ShaderConstBuffer();
 
@@ -351,26 +135,9 @@ protected:
 
    void _createBuffers();
 
-   template<class T>
-   inline void SET_CONSTANT(GFXShaderConstHandle* handle,
-      const T& fv,
-      GenericConstBuffer *vBuffer,
-      GenericConstBuffer *pBuffer);
-
-   // Constant buffers, VSSetConstantBuffers1 has issues on win 7. So unfortunately for now we have multiple constant buffers
-   ID3D11Buffer* mConstantBuffersV[CBUFFER_MAX];
-   ID3D11Buffer* mConstantBuffersP[CBUFFER_MAX];
-
    /// We keep a weak reference to the shader 
    /// because it will often be deleted.
    WeakRefPtr<GFXD3D11Shader> mShader;
-
-   //vertex
-   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
-   GenericConstBuffer* mVertexConstBuffer;
-   //pixel
-   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;
-   GenericConstBuffer* mPixelConstBuffer;
 };
 
 class gfxD3D11Include;
@@ -407,57 +174,32 @@ protected:
 
    static const U32 smCompiledShaderTag;
 
-   ConstantTable table;
-
    ID3D11VertexShader *mVertShader;
    ID3D11PixelShader *mPixShader;
 
-   GFXD3D11ConstBufferLayout* mVertexConstBufferLayout;
-   GFXD3D11ConstBufferLayout* mPixelConstBufferLayout;   
-
    static gfxD3DIncludeRef smD3DInclude;
 
    HandleMap mHandles;
-
+   U32 mConstBufferSize;
+   U8* mConstBuffer;
+   Vector<GFXD3D11ShaderConstHandle*> mValidHandles;
    /// The shader disassembly from DX when this shader is compiled.
    /// We only store this data in non-release builds.
    String mDissasembly;
 
-   /// Vector of sampler type descriptions consolidated from _compileShader.
-   Vector<GFXShaderConstDesc> mSamplerDescriptions;
-
    /// Vector of descriptions (consolidated for the getShaderConstDesc call)
    Vector<GFXShaderConstDesc> mShaderConsts;
    
    // These two functions are used when compiling shaders from hlsl
    virtual bool _compileShader( const Torque::Path &filePath, 
-                                const String &target, 
-                                const D3D_SHADER_MACRO *defines, 
-                                GenericConstBufferLayout *bufferLayout, 
-                                Vector<GFXShaderConstDesc> &samplerDescriptions );
-
-   void _getShaderConstants( ID3D11ShaderReflection* refTable, 
-	                         GenericConstBufferLayout *bufferLayout,
-                             Vector<GFXShaderConstDesc> &samplerDescriptions );
+                                SHADER_STAGE shaderStage, 
+                                const D3D_SHADER_MACRO *defines);
 
-   bool _convertShaderVariable(const D3D11_SHADER_TYPE_DESC &typeDesc, GFXShaderConstDesc &desc);
-
-
-   bool _saveCompiledOutput( const Torque::Path &filePath, 
-                             ID3DBlob *buffer, 
-                             GenericConstBufferLayout *bufferLayout,
-                             Vector<GFXShaderConstDesc> &samplerDescriptions );
-
-   // Loads precompiled shaders
-   bool _loadCompiledOutput( const Torque::Path &filePath, 
-                             const String &target, 
-                             GenericConstBufferLayout *bufferLayoutF, 
-                             Vector<GFXShaderConstDesc> &samplerDescriptions );
+   void _getShaderConstants( ID3D11ShaderReflection* refTable,
+                             SHADER_STAGE shaderStage);
   
    // This is used in both cases
-   virtual void _buildShaderConstantHandles(GenericConstBufferLayout *layout, bool vertexConst);
-   
-   virtual void _buildSamplerShaderConstantHandles( Vector<GFXShaderConstDesc> &samplerDescriptions );
+   virtual void _buildShaderConstantHandles();
 
    /// Used to build the instancing shader constants from 
    /// the instancing vertex format.

+ 23 - 10
Engine/source/gfx/gfxEnums.h

@@ -313,24 +313,37 @@ enum GFXMatrixType
 enum GFXShaderConstType
 {
    /// GFX"S"hader"C"onstant"T"ype
+   GFXSCT_ConstBuffer,
    // Scalar
-   GFXSCT_Float, 
+   GFXSCT_Float,
    // Vectors
-   GFXSCT_Float2, 
-   GFXSCT_Float3, 
-   GFXSCT_Float4, 
+   GFXSCT_Float2,
+   GFXSCT_Float3,
+   GFXSCT_Float4,
    // Matrices
-   GFXSCT_Float2x2, 
+   GFXSCT_Float2x2,
    GFXSCT_Float3x3,
    GFXSCT_Float3x4,
    GFXSCT_Float4x3,
-   GFXSCT_Float4x4, 
+   GFXSCT_Float4x4,
    // Scalar
-   GFXSCT_Int, 
+   GFXSCT_Int,
    // Vectors
-   GFXSCT_Int2, 
-   GFXSCT_Int3, 
-   GFXSCT_Int4, 
+   GFXSCT_Int2,
+   GFXSCT_Int3,
+   GFXSCT_Int4,
+   // Scalar
+   GFXSCT_UInt,
+   // Vectors
+   GFXSCT_UInt2,
+   GFXSCT_UInt3,
+   GFXSCT_UInt4,
+   // Scalar
+   GFXSCT_Bool,
+   // Vectors
+   GFXSCT_Bool2,
+   GFXSCT_Bool3,
+   GFXSCT_Bool4,
    // Samplers
    GFXSCT_Sampler,
    GFXSCT_SamplerCube,

+ 4 - 0
Engine/source/gfx/gfxShader.h

@@ -72,6 +72,10 @@ public:
    String name;
    GFXShaderConstType constType;   
    U32 arraySize; // > 1 means it is an array!
+   U32 bindPoint; // bind point used for ubo/cb, sampler register for samplers.
+   U32 offset;    // offset for vars
+   U32 size;      // size of buffer/type
+   U32 shaderStage; // only used dx side.
 };
 
 /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.

Некоторые файлы не были показаны из-за большого количества измененных файлов