Parcourir la source

pushed buffer creation up to the device level

now shaders ask the device to create a buffer, if a buffer of the same name and size already exist then a pointer to that buffer is returned instead. Going to see if something similar can be added to the opengl end.
marauder2k7 il y a 1 an
Parent
commit
1e8841e6b5

+ 41 - 0
Engine/source/gfx/D3D11/gfxD3D11Device.cpp

@@ -160,6 +160,11 @@ GFXD3D11Device::~GFXD3D11Device()
    for (; sampIter != mSamplersMap.end(); ++sampIter)
       SAFE_RELEASE(sampIter->value);
 
+   // Free device buffers
+   DeviceBufferMap::Iterator bufferIter = mDeviceBufferMap.begin();
+   for (; bufferIter != mDeviceBufferMap.end(); ++bufferIter)
+      SAFE_RELEASE(bufferIter->value);
+
    // Free the vertex declarations.
    VertexDeclMap::Iterator iter = mVertexDecls.begin();
    for (; iter != mVertexDecls.end(); ++iter)
@@ -1861,3 +1866,39 @@ const char* GFXD3D11Device::interpretDebugResult(long result)
    }
    return error;
 }
+
+ID3D11Buffer* GFXD3D11Device::getDeviceBuffer(const GFXShaderConstDesc desc)
+{
+   String name(desc.name + "_" + String::ToString(desc.size));
+   DeviceBufferMap::Iterator buf = mDeviceBufferMap.find(name);
+   if (buf != mDeviceBufferMap.end())
+   {
+      mDeviceBufferMap[name]->AddRef();
+      return mDeviceBufferMap[name];
+   }
+
+   ID3D11Buffer* tempBuf;
+   D3D11_BUFFER_DESC cbDesc;
+   cbDesc.ByteWidth = desc.size;
+   cbDesc.Usage = D3D11_USAGE_DEFAULT;
+   cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+   cbDesc.CPUAccessFlags = 0;
+   cbDesc.MiscFlags = 0;
+   cbDesc.StructureByteStride = 0;
+
+   HRESULT hr;
+   hr = D3D11DEVICE->CreateBuffer(&cbDesc, NULL, &tempBuf);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "Failed to create device buffer.");
+   }
+
+   mDeviceBufferMap[name] = tempBuf;
+
+#ifdef TORQUE_DEBUG
+   tempBuf->SetPrivateData(WKPDID_D3DDebugObjectName, name.size(), name.c_str());
+#endif
+
+   return tempBuf;
+}

+ 5 - 0
Engine/source/gfx/D3D11/gfxD3D11Device.h

@@ -51,6 +51,7 @@ class GFXD3D11Device : public GFXDevice
 {
 public:
    typedef Map<U32, ID3D11SamplerState*> SamplerMap;
+   typedef Map<String, ID3D11Buffer*> DeviceBufferMap;
 private:
 
    friend class GFXResource;
@@ -105,6 +106,7 @@ protected:
 
    /// Used to lookup sampler state for a given hash key
    SamplerMap mSamplersMap;
+   DeviceBufferMap mDeviceBufferMap;
 
    ID3D11RenderTargetView* mDeviceBackBufferView;
    ID3D11DepthStencilView* mDeviceDepthStencilView;
@@ -326,6 +328,9 @@ public:
    const SamplerMap &getSamplersMap() const { return mSamplersMap; }
    SamplerMap &getSamplersMap(){ return mSamplersMap; }
    const char* interpretDebugResult(long result);
+
+   // grab device buffer.
+   ID3D11Buffer* getDeviceBuffer(const GFXShaderConstDesc desc);
 };
 
 #endif

+ 31 - 43
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp

@@ -141,23 +141,15 @@ GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer(GFXD3D11Shader* shader)
 
    for (U32 i = 0; i < 6; i++)
    {
-      for (U32 j = 0; j < 3; j++)
+      for (U32 j = 0; j < 16; j++)
       {
-         mBoundBuffers[i][j] = NULL;
+         mBoundBuffers[i][j] = nullptr;
       }
    }
 }
 
 GFXD3D11ShaderConstBuffer::~GFXD3D11ShaderConstBuffer()
 {
-   for (U32 i = 0; i < 6; i++)
-   {
-      for (U32 j = 0; j < 3; j++)
-      {
-         SAFE_RELEASE(mBoundBuffers[i][j]);
-      }
-   }
-
    for (auto& pair : mBufferMap) {
       delete[] pair.value.data;
    }
@@ -459,11 +451,11 @@ const String GFXD3D11ShaderConstBuffer::describeSelf() const
    return ret;
 }
 
-void GFXD3D11ShaderConstBuffer::addBuffer(U32 bufBindingPoint, GFXShaderStage shaderStage, U32 size)
+void GFXD3D11ShaderConstBuffer::addBuffer(const GFXShaderConstDesc desc)
 {
    S32 shaderStageID = -1; // Initialize to -1 (bit not found)
    for (int i = 0; i < sizeof(S32) * 8; ++i) {
-      if (shaderStage & (1 << i)) {
+      if (desc.shaderStage & (1 << i)) {
          shaderStageID = i;
          break;
       }
@@ -475,30 +467,15 @@ void GFXD3D11ShaderConstBuffer::addBuffer(U32 bufBindingPoint, GFXShaderStage sh
       AssertFatal(false, "DX Const buffer requires a shaderStage flag.");
    }
 
-   const BufferKey bufKey(bufBindingPoint, shaderStageID);
+   const BufferKey bufKey(desc.bindPoint, shaderStageID);
    // doesnt matter if its already added.
-   U8* buf = new U8[size];
-   dMemset(buf, 0, size);
+   U8* buf = new U8[desc.size];
+   dMemset(buf, 0, desc.size);
    mBufferMap[bufKey].data = buf;
-   mBufferMap[bufKey].size = size;
+   mBufferMap[bufKey].size = desc.size;
    mBufferMap[bufKey].isDirty = true;
 
-   //ID3D11Buffer* tempBuf;
-   D3D11_BUFFER_DESC cbDesc;
-   cbDesc.ByteWidth = size;
-   cbDesc.Usage = D3D11_USAGE_DEFAULT;
-   cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
-   cbDesc.CPUAccessFlags = 0;
-   cbDesc.MiscFlags = 0;
-   cbDesc.StructureByteStride = 0;
-
-   HRESULT hr;
-   hr = D3D11DEVICE->CreateBuffer(&cbDesc, NULL, &mBoundBuffers[(U32)shaderStageID][bufBindingPoint]);
-
-   if (FAILED(hr))
-   {
-      AssertFatal(false, "can't create constant buffer");
-   }
+   mBoundBuffers[(U32)shaderStageID][desc.bindPoint] = D3D11->getDeviceBuffer(desc);
 }
 
 void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
@@ -586,14 +563,6 @@ void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
 {
    AssertFatal( shader == mShader, "GFXD3D11ShaderConstBuffer::onShaderReload is hosed!" );
 
-   for (U32 i = 0; i < 6; i++)
-   {
-      for (U32 j = 0; j < 3; j++)
-      {
-         SAFE_RELEASE(mBoundBuffers[i][j]);
-      }
-   }
-
    for (auto& pair : mBufferMap) {
       delete[] pair.value.data;
    }
@@ -602,7 +571,7 @@ void GFXD3D11ShaderConstBuffer::onShaderReload( GFXD3D11Shader *shader )
    for (GFXD3D11Shader::BufferMap::Iterator i = shader->mBuffers.begin(); i != shader->mBuffers.end(); ++i)
    {
       // add our buffer descriptions to the full const buffer.
-      this->addBuffer(i->value.bindPoint, i->value.shaderStage, i->value.size);
+      this->addBuffer(i->value);
    }
 
    // Set the lost state.
@@ -922,7 +891,26 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection* refTable,
          desc.bindPoint = shaderInputBind.BindPoint;
          if (String::compare(desc.name, "$Globals") == 0 || String::compare(desc.name, "$Params") == 0)
          {
-            desc.name = desc.name + String::ToString((U32)shaderStage-1);
+            switch (shaderStage)
+            {
+            case VERTEX_SHADER:
+               desc.name = desc.name + "_" + mVertexFile.getFileName();
+               break;
+            case PIXEL_SHADER:
+               desc.name = desc.name + "_" + mPixelFile.getFileName();
+               break;
+            case GEOMETRY_SHADER:
+               desc.name = desc.name + "_" + mGeometryFile.getFileName();
+               break;
+            case DOMAIN_SHADER:
+               break;
+            case HULL_SHADER:
+               break;
+            case COMPUTE_SHADER:
+               break;
+            default:
+               break;
+            }
          }
 
          mBuffers[desc.name] = desc;
@@ -1227,7 +1215,7 @@ GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
    for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); ++i)
    {
       // add our buffer descriptions to the full const buffer.
-      buffer->addBuffer(i->value.bindPoint, i->value.shaderStage, i->value.size);
+      buffer->addBuffer(i->value);
    }
 
    mActiveBuffers.push_back( buffer );

+ 2 - 2
Engine/source/gfx/D3D11/gfxD3D11Shader.h

@@ -117,7 +117,7 @@ public:
    /// @param mPrevShaderBuffer The previously active buffer
    void activate(GFXD3D11ShaderConstBuffer *prevShaderBuffer);
 
-   void addBuffer(U32 bufBindingPoint, GFXShaderStage shaderStage, U32 size);
+   void addBuffer(const GFXShaderConstDesc desc);
 
    /// Called from GFXD3D11Shader when constants have changed and need
    /// to be the shader this buffer references is reloaded.
@@ -161,7 +161,7 @@ protected:
    void setMatrix(const GFXShaderConstDesc& handle, const U32 inSize, const void* data, U8* basePointer);
    void internalSet(GFXShaderConstHandle* handle, const U32 inSize, const void* data);
 
-   ID3D11Buffer* mBoundBuffers[6][3];
+   ID3D11Buffer* mBoundBuffers[6][16];
 };
 
 class gfxD3D11Include;