mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
Set constant buffers
added logic to set constant buffers dx side
This commit is contained in:
parent
97ed522667
commit
a1e2f781a8
2 changed files with 180 additions and 18 deletions
|
|
@ -331,6 +331,30 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF&
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (matrixType == GFXSCT_Float4x4)
|
||||||
|
{
|
||||||
|
dMemcpy(buf, transposed, sizeof(MatrixF));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 csize;
|
||||||
|
switch (matrixType)
|
||||||
|
{
|
||||||
|
case GFXSCT_Float2x2:
|
||||||
|
csize = 24; //this takes up 16+8
|
||||||
|
break;
|
||||||
|
case GFXSCT_Float3x3:
|
||||||
|
csize = 44; //This takes up 16+16+12
|
||||||
|
break;
|
||||||
|
case GFXSCT_Float4x3:
|
||||||
|
csize = 48;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dMemcpy(buf, transposed, csize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,9 +364,13 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF*
|
||||||
AssertFatal(handle->isValid(), "Handle is not valid!");
|
AssertFatal(handle->isValid(), "Handle is not valid!");
|
||||||
|
|
||||||
AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!");
|
AssertFatal(static_cast<const GFXD3D11ShaderConstHandle*>(handle), "Incorrect const buffer type!");
|
||||||
const GFXD3D11ShaderConstHandle* h = static_cast<const GFXD3D11ShaderConstHandle*>(handle);
|
const GFXD3D11ShaderConstHandle* _dxHandle = static_cast<const GFXD3D11ShaderConstHandle*>(handle);
|
||||||
AssertFatal(!h->isSampler(), "Handle is sampler constant!");
|
AssertFatal(!_dxHandle->isSampler(), "Handle is sampler constant!");
|
||||||
AssertFatal(h->mShader == mShader, "Mismatched shaders!");
|
AssertFatal(_dxHandle->mShader == mShader, "Mismatched shaders!");
|
||||||
|
|
||||||
|
BufferDesc bufDesc(_dxHandle->mBinding, (SHADER_STAGE)_dxHandle->mStage);
|
||||||
|
|
||||||
|
U8* buf = mBufferMap[bufDesc] ;
|
||||||
|
|
||||||
static Vector<MatrixF> transposed;
|
static Vector<MatrixF> transposed;
|
||||||
if (arraySize > transposed.size())
|
if (arraySize > transposed.size())
|
||||||
|
|
@ -359,8 +387,37 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF*
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Maybe support this in the future?
|
// TODO: Maybe support this in the future?
|
||||||
if (h->mInstancingConstant)
|
if (_dxHandle->mInstancingConstant)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (matrixType == GFXSCT_Float4x4)
|
||||||
|
{
|
||||||
|
dMemcpy(buf + _dxHandle->mOffset, transposed.address(), _dxHandle->getSize());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
U32 csize;
|
||||||
|
switch (matrixType)
|
||||||
|
{
|
||||||
|
case GFXSCT_Float2x2:
|
||||||
|
csize = 24; //this takes up 16+8
|
||||||
|
break;
|
||||||
|
case GFXSCT_Float3x3:
|
||||||
|
csize = 44; //This takes up 16+16+12
|
||||||
|
break;
|
||||||
|
case GFXSCT_Float4x3:
|
||||||
|
csize = 48;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < arraySize; i++)
|
||||||
|
{
|
||||||
|
dMemcpy(buf + _dxHandle->mOffset + (i * csize), transposed[i], csize);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const String GFXD3D11ShaderConstBuffer::describeSelf() const
|
const String GFXD3D11ShaderConstBuffer::describeSelf() const
|
||||||
|
|
@ -372,19 +429,22 @@ const String GFXD3D11ShaderConstBuffer::describeSelf() const
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXD3D11ShaderConstBuffer::zombify()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXD3D11ShaderConstBuffer::resurrect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GFXD3D11ShaderConstBuffer::isDirty()
|
bool GFXD3D11ShaderConstBuffer::isDirty()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GFXD3D11ShaderConstBuffer::addBuffer(BufferDesc bufDesc, U32 size)
|
||||||
|
{
|
||||||
|
BufferMap::Iterator buffer = mBufferMap.find(bufDesc);
|
||||||
|
// already added? pass...
|
||||||
|
if (buffer != mBufferMap.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// new buffer with our size.
|
||||||
|
mBufferMap[bufDesc] = new U8[size];
|
||||||
|
}
|
||||||
|
|
||||||
void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
|
void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderBuffer )
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate);
|
PROFILE_SCOPE(GFXD3D11ShaderConstBuffer_activate);
|
||||||
|
|
@ -422,7 +482,14 @@ GFXD3D11Shader::~GFXD3D11Shader()
|
||||||
delete i->value;
|
delete i->value;
|
||||||
|
|
||||||
for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); i++)
|
for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); i++)
|
||||||
|
{
|
||||||
delete[] i->value;
|
delete[] i->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (U32 i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
SAFE_RELEASE(mBoundConstantBuffers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
// release shaders
|
// release shaders
|
||||||
SAFE_RELEASE(mVertShader);
|
SAFE_RELEASE(mVertShader);
|
||||||
|
|
@ -707,6 +774,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
|
||||||
desc.constType = GFXSCT_ConstBuffer;
|
desc.constType = GFXSCT_ConstBuffer;
|
||||||
desc.bindPoint = shaderInputBind.BindPoint;
|
desc.bindPoint = shaderInputBind.BindPoint;
|
||||||
desc.shaderStage = shaderStage;
|
desc.shaderStage = shaderStage;
|
||||||
|
desc.samplerReg = -1;
|
||||||
ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByName(shaderInputBind.Name);
|
ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByName(shaderInputBind.Name);
|
||||||
D3D11_SHADER_BUFFER_DESC constantBufferDesc;
|
D3D11_SHADER_BUFFER_DESC constantBufferDesc;
|
||||||
|
|
||||||
|
|
@ -737,6 +805,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
|
||||||
varDesc.arraySize = mMax(shaderTypeDesc.Elements, 1);
|
varDesc.arraySize = mMax(shaderTypeDesc.Elements, 1);
|
||||||
varDesc.size = shaderVarDesc.Size;
|
varDesc.size = shaderVarDesc.Size;
|
||||||
varDesc.shaderStage = shaderStage;
|
varDesc.shaderStage = shaderStage;
|
||||||
|
varDesc.samplerReg = -1;
|
||||||
|
|
||||||
if (shaderTypeDesc.Class == D3D_SVC_SCALAR || shaderTypeDesc.Class == D3D_SVC_VECTOR)
|
if (shaderTypeDesc.Class == D3D_SVC_SCALAR || shaderTypeDesc.Class == D3D_SVC_VECTOR)
|
||||||
{
|
{
|
||||||
|
|
@ -823,6 +892,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
|
||||||
desc.name = String::ToString("$%s", desc.name.c_str());
|
desc.name = String::ToString("$%s", desc.name.c_str());
|
||||||
desc.constType = GFXSCT_Sampler;
|
desc.constType = GFXSCT_Sampler;
|
||||||
desc.samplerReg = shaderInputBind.BindPoint;
|
desc.samplerReg = shaderInputBind.BindPoint;
|
||||||
|
desc.bindPoint = shaderInputBind.BindPoint; // not really needed but hey..
|
||||||
desc.shaderStage = shaderStage;
|
desc.shaderStage = shaderStage;
|
||||||
mShaderConsts.push_back(desc);
|
mShaderConsts.push_back(desc);
|
||||||
}
|
}
|
||||||
|
|
@ -892,12 +962,35 @@ void GFXD3D11Shader::_buildShaderConstantHandles()
|
||||||
if (buffer != mBuffers.end())
|
if (buffer != mBuffers.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ID3D11Buffer* constBuffer = nullptr;
|
||||||
|
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, &constBuffer);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
AssertFatal(false, "can't create constant buffer: %s", desc.name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
mBoundConstantBuffers[desc.bindPoint] = constBuffer;
|
||||||
|
|
||||||
// new buffer with our size.
|
// new buffer with our size.
|
||||||
mBuffers[bufDesc] = new U8[desc.size];
|
mBuffers[bufDesc] = new U8[desc.size];
|
||||||
|
|
||||||
|
// do not add to handles..
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleMap::Iterator handle = mHandles.find(desc.name);
|
HandleMap::Iterator handle = mHandles.find(desc.name);
|
||||||
// already added? reinit just in case..
|
// already added? reinit just in case..
|
||||||
|
// not sure if we need to do anything different with samplers.
|
||||||
if (handle != mHandles.end())
|
if (handle != mHandles.end())
|
||||||
{
|
{
|
||||||
handle->value->reinit(desc);
|
handle->value->reinit(desc);
|
||||||
|
|
@ -954,9 +1047,59 @@ void GFXD3D11Shader::_buildInstancingShaderConstantHandles()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GFXD3D11Shader::setConstantsFromBuffer(GFXD3D11ShaderConstBuffer* buffer)
|
||||||
|
{
|
||||||
|
BufferRange bufRanges[6] = {};
|
||||||
|
|
||||||
|
for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); ++i)
|
||||||
|
{
|
||||||
|
BufferDesc oldBufferDesc = i->key;
|
||||||
|
U8* oldBuff = i->value;
|
||||||
|
|
||||||
|
U8* newBuff = buffer->mBufferMap[i->key];
|
||||||
|
|
||||||
|
if (dMemcmp(oldBuff, newBuff, sizeof(oldBuff)) != 0)
|
||||||
|
{
|
||||||
|
// else copy new over the buffer.
|
||||||
|
dMemcpy(oldBuff, newBuff, sizeof(oldBuff));
|
||||||
|
|
||||||
|
// buffer has been changed and needs updating.
|
||||||
|
D3D11DEVICECONTEXT->UpdateSubresource(mBoundConstantBuffers[oldBufferDesc.bindingPoint], 0, NULL, oldBuff, sizeof(oldBuff), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufRanges[oldBufferDesc.stage].addSlot(oldBufferDesc.bindingPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mVertShader != nullptr)
|
||||||
|
{
|
||||||
|
const U32 bufStartSlot = bufRanges[SHADER_STAGE::VERTEX_SHADER].mBufMin;
|
||||||
|
const U32 numBufs = bufRanges[SHADER_STAGE::VERTEX_SHADER].mBufMax - bufRanges[SHADER_STAGE::VERTEX_SHADER].mBufMin + 1;
|
||||||
|
ID3D11Buffer** vsBuffers = mBoundConstantBuffers + bufStartSlot;
|
||||||
|
|
||||||
|
D3D11DEVICECONTEXT->VSSetConstantBuffers(bufStartSlot, numBufs, vsBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPixShader != nullptr)
|
||||||
|
{
|
||||||
|
const U32 bufStartSlot = bufRanges[SHADER_STAGE::PIXEL_SHADER].mBufMin;
|
||||||
|
const U32 numBufs = bufRanges[SHADER_STAGE::PIXEL_SHADER].mBufMax - bufRanges[SHADER_STAGE::PIXEL_SHADER].mBufMin + 1;
|
||||||
|
ID3D11Buffer** psBuffers = mBoundConstantBuffers + bufStartSlot;
|
||||||
|
|
||||||
|
D3D11DEVICECONTEXT->PSSetConstantBuffers(bufStartSlot, numBufs, psBuffers);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
|
GFXShaderConstBufferRef GFXD3D11Shader::allocConstBuffer()
|
||||||
{
|
{
|
||||||
GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this);
|
GFXD3D11ShaderConstBuffer* buffer = new GFXD3D11ShaderConstBuffer(this);
|
||||||
|
|
||||||
|
for (BufferMap::Iterator i = mBuffers.begin(); i != mBuffers.end(); ++i)
|
||||||
|
{
|
||||||
|
// add our buffer descriptions to the full const buffer.
|
||||||
|
buffer->addBuffer(i->key, sizeof(i->value));
|
||||||
|
}
|
||||||
|
|
||||||
mActiveBuffers.push_back( buffer );
|
mActiveBuffers.push_back( buffer );
|
||||||
buffer->registerResourceWithDevice(getOwningDevice());
|
buffer->registerResourceWithDevice(getOwningDevice());
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,13 @@ class GFXD3D11Shader;
|
||||||
|
|
||||||
enum SHADER_STAGE
|
enum SHADER_STAGE
|
||||||
{
|
{
|
||||||
UNKNOWN_STAGE,
|
|
||||||
VERTEX_SHADER,
|
VERTEX_SHADER,
|
||||||
PIXEL_SHADER,
|
PIXEL_SHADER,
|
||||||
GEOMETRY_SHADER,
|
GEOMETRY_SHADER,
|
||||||
DOMAIN_SHADER,
|
DOMAIN_SHADER,
|
||||||
HULL_SHADER,
|
HULL_SHADER,
|
||||||
COMPUTE_SHADER
|
COMPUTE_SHADER,
|
||||||
|
UNKNOWN_STAGE
|
||||||
};
|
};
|
||||||
|
|
||||||
// simple class to hold everything required for a buffer map.
|
// simple class to hold everything required for a buffer map.
|
||||||
|
|
@ -62,6 +62,18 @@ struct BufferDesc
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BufferRange
|
||||||
|
{
|
||||||
|
U32 mBufMin = 0xFFFFFFFF;
|
||||||
|
U32 mBufMax = 0;
|
||||||
|
|
||||||
|
inline void addSlot(U32 slot)
|
||||||
|
{
|
||||||
|
mBufMin = getMin(mBufMin, slot);
|
||||||
|
mBufMax = getMax(mBufMax, slot);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
|
class GFXD3D11ShaderConstHandle : public GFXShaderConstHandle
|
||||||
{
|
{
|
||||||
friend class GFXD3D11Shader;
|
friend class GFXD3D11Shader;
|
||||||
|
|
@ -81,7 +93,7 @@ public:
|
||||||
void setValid(bool valid) { mValid = valid; }
|
void setValid(bool valid) { mValid = valid; }
|
||||||
/// @warning This will always return the value assigned when the shader was
|
/// @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.
|
/// initialized. If the value is later changed this method won't reflect that.
|
||||||
S32 getSamplerRegister() const { return mSampler; }
|
S32 getSamplerRegister() const { return (!isSampler() || !mValid) ? -1 : mSampler; }
|
||||||
|
|
||||||
// Returns true if this is a handle to a sampler register.
|
// Returns true if this is a handle to a sampler register.
|
||||||
bool isSampler() const
|
bool isSampler() const
|
||||||
|
|
@ -94,7 +106,7 @@ public:
|
||||||
U32 mOffset;
|
U32 mOffset;
|
||||||
U32 mSize;
|
U32 mSize;
|
||||||
S32 mBinding; // buffer binding point used to map handles to buffers.
|
S32 mBinding; // buffer binding point used to map handles to buffers.
|
||||||
S32 mSampler; // sampler.
|
S32 mSampler; // sampler number, will be -1 if not a sampler.
|
||||||
SHADER_STAGE mStage;
|
SHADER_STAGE mStage;
|
||||||
bool mInstancingConstant;
|
bool mInstancingConstant;
|
||||||
};
|
};
|
||||||
|
|
@ -102,7 +114,6 @@ public:
|
||||||
/// The D3D11 implementation of a shader constant buffer.
|
/// The D3D11 implementation of a shader constant buffer.
|
||||||
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
|
class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
|
||||||
{
|
{
|
||||||
friend class GFXD3D11Shader;
|
|
||||||
// Cache device context
|
// Cache device context
|
||||||
ID3D11DeviceContext* mDeviceContext;
|
ID3D11DeviceContext* mDeviceContext;
|
||||||
|
|
||||||
|
|
@ -120,6 +131,8 @@ public:
|
||||||
/// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
|
/// Used internally by GXD3D11ShaderConstBuffer to determine if it's dirty.
|
||||||
bool isDirty();
|
bool isDirty();
|
||||||
|
|
||||||
|
void addBuffer(BufferDesc bufDesc, U32 size);
|
||||||
|
|
||||||
/// Called from GFXD3D11Shader when constants have changed and need
|
/// Called from GFXD3D11Shader when constants have changed and need
|
||||||
/// to be the shader this buffer references is reloaded.
|
/// to be the shader this buffer references is reloaded.
|
||||||
void onShaderReload(GFXD3D11Shader *shader);
|
void onShaderReload(GFXD3D11Shader *shader);
|
||||||
|
|
@ -153,6 +166,7 @@ public:
|
||||||
virtual void resurrect() {}
|
virtual void resurrect() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class GFXD3D11Shader;
|
||||||
/// We keep a weak reference to the shader
|
/// We keep a weak reference to the shader
|
||||||
/// because it will often be deleted.
|
/// because it will often be deleted.
|
||||||
WeakRefPtr<GFXD3D11Shader> mShader;
|
WeakRefPtr<GFXD3D11Shader> mShader;
|
||||||
|
|
@ -203,6 +217,9 @@ protected:
|
||||||
ID3D11VertexShader *mVertShader;
|
ID3D11VertexShader *mVertShader;
|
||||||
ID3D11PixelShader *mPixShader;
|
ID3D11PixelShader *mPixShader;
|
||||||
|
|
||||||
|
// we probably want this to be GFXDevice and not per shader.
|
||||||
|
ID3D11Buffer* mBoundConstantBuffers[16] = {};
|
||||||
|
|
||||||
static gfxD3DIncludeRef smD3DInclude;
|
static gfxD3DIncludeRef smD3DInclude;
|
||||||
|
|
||||||
HandleMap mHandles;
|
HandleMap mHandles;
|
||||||
|
|
@ -215,7 +232,9 @@ protected:
|
||||||
|
|
||||||
/// Vector of descriptions (consolidated for the getShaderConstDesc call)
|
/// Vector of descriptions (consolidated for the getShaderConstDesc call)
|
||||||
Vector<GFXShaderConstDesc> mShaderConsts;
|
Vector<GFXShaderConstDesc> mShaderConsts;
|
||||||
|
|
||||||
|
//Vector<ID3D11Buffer*> mDeviceBuffers;
|
||||||
|
|
||||||
// These two functions are used when compiling shaders from hlsl
|
// These two functions are used when compiling shaders from hlsl
|
||||||
virtual bool _compileShader( const Torque::Path &filePath,
|
virtual bool _compileShader( const Torque::Path &filePath,
|
||||||
SHADER_STAGE shaderStage,
|
SHADER_STAGE shaderStage,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue