Bläddra i källkod

gfxD3D handles and buffermap

init handles coded.
bufferMap added.
marauder2k7 1 år sedan
förälder
incheckning
97ed522667

+ 171 - 53
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp

@@ -107,31 +107,45 @@ GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader)
 }
 
 GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
-                                                      const SHADER_STAGE shaderStage,
-                                                      const U32 offset,
-                                                      const U32 size,
-                                                      const GFXShaderConstDesc& desc,
-                                                      S32 bindingPoint,
-                                                      S32 samplerNum)
+                                                      const GFXShaderConstDesc& desc)
    : mShader(shader),
-   mStage(shaderStage),
-   mOffset(offset),
-   mSize(size),
    mDesc(desc),
-   mBinding(bindingPoint),
-   mSampler(bindingPoint),
+   mStage((SHADER_STAGE)desc.shaderStage),
+   mOffset(desc.offset),
+   mSize(desc.size * desc.arraySize),
+   mBinding(desc.bindPoint),
+   mSampler(desc.samplerReg),
    mInstancingConstant(false)
 {
-   mValid = false;
+   if (desc.constType == GFXSCT_ConstBuffer)
+      mValid = false;
+   else
+      mValid = true;
 }
 
 GFXD3D11ShaderConstHandle::~GFXD3D11ShaderConstHandle()
 {
 }
 
+void GFXD3D11ShaderConstHandle::reinit(const GFXShaderConstDesc& desc)
+{
+   mDesc                = desc;
+   mStage               = (SHADER_STAGE)desc.shaderStage;
+   mOffset              = desc.offset;
+   mSize                = desc.size * desc.arraySize;
+   mBinding             = desc.bindPoint;
+   mSampler             = desc.samplerReg;
+   mInstancingConstant  = false;
+
+   if (desc.constType == GFXSCT_ConstBuffer)
+      mValid = false;
+   else
+      mValid = true;
+}
+
 //------------------------------------------------------------------------------
 
-GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer( GFXD3D11Shader* shader, U32 bufSize, U8* existingConstants)
+GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer( GFXD3D11Shader* shader)
 {
    mDeviceContext = D3D11DEVICECONTEXT;
 }
@@ -148,29 +162,35 @@ GFXShader* GFXD3D11ShaderConstBuffer::getShader()
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv) 
 {
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2F& fv) 
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3F& fv) 
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4F& fv) 
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF& fv) 
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
-void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 f)
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 fv)
 { 
    // This is the only type that is allowed to be used
    // with a sampler shader constant type, but it is only
@@ -181,52 +201,104 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const S32 f)
    if ( ((GFXD3D11ShaderConstHandle*)handle)->isSampler() )
       return;
 
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point2I& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point3I& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const Point4I& fv)
-{ 
+{
+   internalSet(handle, fv);
+}
+
+
+template<typename ConstType>
+void GFXD3D11ShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const ConstType& param)
+{
+   AssertFatal(handle, "GFXD3D11ShaderConstBuffer::internalSet - Handle is NULL!");
+   AssertFatal(handle->isValid(), "GFXD3D11ShaderConstBuffer::internalSet - Handle is not valid!");
+   AssertFatal(dynamic_cast<GFXD3D11ShaderConstHandle*>(handle), "GFXD3D11ShaderConstBuffer::internalSet - Incorrect const buffer type");
+
+   GFXD3D11ShaderConstHandle* _dxHandle = static_cast<GFXD3D11ShaderConstHandle*>(handle);
+   AssertFatal(mShader == _dxHandle->mShader, "GFXD3D11ShaderConstBuffer::internalSet - Should only set handles which are owned by our shader");
+
+   BufferDesc bufDesc(_dxHandle->mBinding, (SHADER_STAGE)_dxHandle->mStage);
+   U8* buf = mBufferMap[bufDesc] + _dxHandle->mOffset;
+
+   if (_dxHandle->mInstancingConstant)
+      buf = mInstPtr + _dxHandle->mOffset;
+
+   dMemcpy(buf, &param, sizeof(ConstType));
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<F32>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2F>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3F>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4F>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<S32>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point2I>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point3I>& fv)
-{ 
+{
+   internalSet(handle, fv);
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const AlignedArray<Point4I>& fv)
-{ 
+{
+   internalSet(handle, fv);
+}
+
+template<typename ConstType>
+void GFXD3D11ShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv)
+{
+   AssertFatal(handle, "GFXD3D11ShaderConstBuffer::internalSet - Handle is NULL!");
+   AssertFatal(handle->isValid(), "GFXD3D11ShaderConstBuffer::internalSet - Handle is not valid!");
+   AssertFatal(dynamic_cast<GFXD3D11ShaderConstHandle*>(handle), "GFXD3D11ShaderConstBuffer::internalSet - Incorrect const buffer type");
+
+   GFXD3D11ShaderConstHandle* _dxHandle = static_cast<GFXD3D11ShaderConstHandle*>(handle);
+   AssertFatal(mShader == _dxHandle->mShader, "GFXD3D11ShaderConstBuffer::internalSet - Should only set handles which are owned by our shader");
+   AssertFatal(!_glHandle->mInstancingConstant, "GFXD3D11ShaderConstBuffer::internalSet - Instancing not supported for array");
+   BufferDesc bufDesc(_dxHandle->mBinding, (SHADER_STAGE)_dxHandle->mStage);
+   U8* buf = mBufferMap[bufDesc];
+   const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
+   for (U32 i = 0; i < fv.size(); ++i)
+   {
+      dMemcpy(buf + _dxHandle->mOffset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType));
+      fvBuffer += fv.getElementSize();
+   }
+
 }
-#undef SET_CONSTANT
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& mat, const GFXShaderConstType matrixType) 
 {    
@@ -234,11 +306,32 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
    AssertFatal(handle->isValid(), "Handle is not valid!" );
 
    AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!"); 
-   const GFXD3D11ShaderConstHandle* h = static_cast<const GFXD3D11ShaderConstHandle*>(handle); 
-   AssertFatal(!h->isSampler(), "Handle is sampler constant!" );
-   AssertFatal(h->mShader == mShader, "Mismatched shaders!"); 
+   const GFXD3D11ShaderConstHandle* _dxHandle = static_cast<const GFXD3D11ShaderConstHandle*>(handle);
+   AssertFatal(!_dxHandle->isSampler(), "Handle is sampler constant!" );
+   AssertFatal(_dxHandle->mShader == mShader, "Mismatched shaders!");
+   BufferDesc bufDesc(_dxHandle->mBinding, (SHADER_STAGE)_dxHandle->mStage);
+   U8* buf = mBufferMap[bufDesc] + _dxHandle->mOffset;
 
    MatrixF transposed;
+   if (matrixType == GFXSCT_Float4x3)
+   {
+      transposed = mat;
+   }
+   else
+   {
+      mat.transposeTo(transposed);
+   }
+
+   if (_dxHandle->mInstancingConstant)
+   {
+      if (matrixType == GFXSCT_Float4x4)
+         dMemcpy(mInstPtr + _dxHandle->mOffset, mat, sizeof(mat));
+
+      // TODO: Support 3x3 and 2x2 matricies?      
+      return;
+   }
+
+
 }
 
 void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType)
@@ -287,10 +380,6 @@ void GFXD3D11ShaderConstBuffer::resurrect()
 {
 }
 
-void GFXD3D11ShaderConstBuffer::_createBuffers()
-{
-}
-
 bool GFXD3D11ShaderConstBuffer::isDirty()
 {
    return true;
@@ -299,16 +388,14 @@ bool GFXD3D11ShaderConstBuffer::isDirty()
 void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
 {
    PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate);
-
+   mShader->setConstantsFromBuffer(this);
+   mWasLost = false;
 }
 
 void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
 {
    AssertFatal( shader == mShader, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
 
-  
-   _createBuffers();
-	
    // Set the lost state.
    mWasLost = true;
 }
@@ -316,8 +403,6 @@ void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
 //------------------------------------------------------------------------------
 
 GFXD3D11Shader::GFXD3D11Shader()
-   :mConstBufferSize(0),
-   mConstBuffer(NULL)
 {
    VECTOR_SET_ASSOCIATION( mShaderConsts );
 
@@ -336,7 +421,8 @@ GFXD3D11Shader::~GFXD3D11Shader()
    for (HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++)
       delete i->value;
 
-   delete[] mConstBuffer;
+   for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); i++)
+      delete[] i->value;
 
    // release shaders
    SAFE_RELEASE(mVertShader);
@@ -374,10 +460,6 @@ bool GFXD3D11Shader::_init()
 
    mShaderConsts.clear();
 
-   for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
-      (iter->value)->setValid(false);
-   mValidHandles.clear();
-
    if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, SHADER_STAGE::VERTEX_SHADER, d3dMacros) )
       return false;
 
@@ -696,7 +778,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
             }
             else if (shaderTypeDesc.Class == D3D_SVC_STRUCT)
             {
-               // we gotta loop through its variables =/ ad support in future. for now continue so it skips.
+               // we gotta loop through its variables =/ add support in future. for now continue so it skips.
                continue;
             }
 
@@ -740,7 +822,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
          if (desc.name.find("$") != 0)
             desc.name = String::ToString("$%s", desc.name.c_str());
          desc.constType = GFXSCT_Sampler;
-         desc.bindPoint = shaderInputBind.BindPoint;
+         desc.samplerReg = shaderInputBind.BindPoint;
          desc.shaderStage = shaderStage;
          mShaderConsts.push_back(desc);
       }
@@ -790,7 +872,43 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
 
 void GFXD3D11Shader::_buildShaderConstantHandles()
 {
+   // Mark all existing handles as invalid.
+   // Those that are found when parsing the descriptions will then be marked valid again.
+   for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
+      (iter->value)->setValid(false);
+   mValidHandles.clear();
+
+   // loop through all constants, add them to the handle map
+   // and add the const buffers to the buffer map.
+   for (U32 i = 0; i < mShaderConsts.size(); i++)
+   {
+      GFXShaderConstDesc& desc = mShaderConsts[i];
 
+      if (desc.constType == GFXSCT_ConstBuffer)
+      {
+         BufferDesc bufDesc(desc.bindPoint, (SHADER_STAGE)desc.shaderStage);
+         BufferMap::Iterator buffer = mBuffers.find(bufDesc);
+         // already added? pass...
+         if (buffer != mBuffers.end())
+            continue;
+
+         // new buffer with our size.
+         mBuffers[bufDesc] = new U8[desc.size];
+      }
+
+      HandleMap::Iterator handle = mHandles.find(desc.name);
+      // already added? reinit just in case..
+      if (handle != mHandles.end())
+      {
+         handle->value->reinit(desc);
+      }
+      else
+      {
+         mHandles[desc.name] = new GFXD3D11ShaderConstHandle(this, desc);
+      }
+   }
+
+   _buildInstancingShaderConstantHandles();
 }
 
 void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
@@ -819,7 +937,7 @@ void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
 
       handle->setValid( true );         
       handle->mInstancingConstant = true;
-
+      handle->mOffset = offset;
 
       // If this is a matrix we will have 2 or 3 more of these
       // semantics with the same name after it.
@@ -838,7 +956,7 @@ void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
 
 GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
 {
-   GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this, mConstBufferSize, mConstBuffer);
+   GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this);
    mActiveBuffers.push_back( buffer );
    buffer->registerResourceWithDevice(getOwningDevice());
    return buffer;

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

@@ -45,6 +45,23 @@ enum SHADER_STAGE
    COMPUTE_SHADER
 };
 
+// simple class to hold everything required for a buffer map.
+struct BufferDesc
+{
+   // for the moment we dont really need to care about the buffer name.
+   S32 bindingPoint;
+   SHADER_STAGE stage;
+
+   BufferDesc()
+      : bindingPoint(-1), stage(SHADER_STAGE::UNKNOWN_STAGE)
+   {}
+
+   BufferDesc( U32 inBindingPoint, SHADER_STAGE inputStage)
+      : bindingPoint(inBindingPoint), stage(inputStage)
+   {}
+
+};
+
 class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
 {
    friend class GFXD3D11Shader;
@@ -52,15 +69,10 @@ public:
 
    GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader);
    GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
-      const SHADER_STAGE shaderStage,
-      const U32 offset,
-      const U32 size,
-      const GFXShaderConstDesc& desc,
-      S32 bindingPoint,
-      S32 samplerNum);
+                              const GFXShaderConstDesc& desc);
 
    virtual ~GFXD3D11ShaderConstHandle();
-
+   void reinit(const GFXShaderConstDesc& desc);
    const String& getName() const { return mDesc.name; }
    GFXShaderConstType getType() const { return mDesc.constType; }
    U32 getArraySize() const { return mDesc.arraySize; }
@@ -95,8 +107,9 @@ class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
    ID3D11DeviceContext* mDeviceContext;
 
 public:
+   typedef Map<BufferDesc, U8*> BufferMap;
 
-   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader, U32 bufSize, U8* existingConstants);
+   GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader);
 
    virtual ~GFXD3D11ShaderConstBuffer();
 
@@ -136,16 +149,20 @@ public:
 
    // GFXResource
    virtual const String describeSelf() const;
-   virtual void zombify();
-   virtual void resurrect();
-
-protected:
-
-   void _createBuffers();
+   virtual void zombify() {}
+   virtual void resurrect() {}
 
+private:
    /// We keep a weak reference to the shader 
    /// because it will often be deleted.
    WeakRefPtr<GFXD3D11Shader> mShader;
+   BufferMap mBufferMap;
+
+   template<typename ConstType>
+   void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
+
+   template<typename ConstType>
+   void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
 };
 
 class gfxD3D11Include;
@@ -160,6 +177,7 @@ class GFXD3D11Shader : public GFXShader
 
 public:
    typedef Map<String, GFXD3D11ShaderConstHandle*> HandleMap;
+   typedef Map<BufferDesc, U8*> BufferMap;
 
    GFXD3D11Shader();
    virtual ~GFXD3D11Shader();   
@@ -188,8 +206,8 @@ protected:
    static gfxD3DIncludeRef smD3DInclude;
 
    HandleMap mHandles;
-   U32 mConstBufferSize;
-   U8* mConstBuffer;
+   BufferMap mBuffers;
+
    Vector<GFXD3D11ShaderConstHandle*> mValidHandles;
    /// The shader disassembly from DX when this shader is compiled.
    /// We only store this data in non-release builds.
@@ -208,10 +226,9 @@ protected:
   
    // This is used in both cases
    virtual void _buildShaderConstantHandles();
-
-   /// Used to build the instancing shader constants from 
-   /// the instancing vertex format.
    void _buildInstancingShaderConstantHandles();
+
+   void setConstantsFromBuffer(GFXD3D11ShaderConstBuffer* buffer);
 };
 
 inline bool GFXD3D11Shader::getDisassembly(String &outStr) const

+ 6 - 5
Engine/source/gfx/gfxShader.h

@@ -71,11 +71,12 @@ struct GFXShaderConstDesc
 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.
+   U32 arraySize;    // > 1 means it is an array!
+   S32 bindPoint;    // bind point used for ubo/cb.
+   S32 samplerReg;   // sampler register.
+   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.