gfxD3D handles and buffermap

init handles coded.
bufferMap added.
This commit is contained in:
marauder2k7 2024-02-23 17:18:45 +00:00
parent 630bee97c7
commit 97ed522667
3 changed files with 213 additions and 77 deletions

View file

@ -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;

View file

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

View file

@ -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.