mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-15 16:44:36 +00:00
opengl ubo setup
opengl can now compile with ubo buffer objects similar to cbuffers on dx side. cleaned double up of data from both sides, gfxhandles only need to use the desc info instead of holding onto its own.
This commit is contained in:
parent
fbed04050a
commit
9dc5ae833b
7 changed files with 941 additions and 605 deletions
|
|
@ -95,12 +95,9 @@ HRESULT gfxD3D11Include::Close( THIS_ LPCVOID pData )
|
||||||
|
|
||||||
GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader)
|
GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader)
|
||||||
: mShader(shader),
|
: mShader(shader),
|
||||||
mSize(0),
|
|
||||||
mSampler(-1),
|
|
||||||
mArraySize(1),
|
|
||||||
mInstancingConstant(false)
|
mInstancingConstant(false)
|
||||||
{
|
{
|
||||||
mType = GFXSCT_ConstBuffer;
|
dMemset(&mDesc, 0, sizeof(mDesc));
|
||||||
mValid = false;
|
mValid = false;
|
||||||
mStageFlags = 0;
|
mStageFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -108,18 +105,15 @@ GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader)
|
||||||
GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
|
GFXD3D11ShaderConstHandle::GFXD3D11ShaderConstHandle(GFXD3D11Shader* shader,
|
||||||
const GFXShaderConstDesc& desc)
|
const GFXShaderConstDesc& desc)
|
||||||
: mShader(shader),
|
: mShader(shader),
|
||||||
mSize(desc.size),
|
mDesc(desc),
|
||||||
mSampler(desc.samplerReg),
|
|
||||||
mType(desc.constType),
|
|
||||||
mArraySize(desc.arraySize),
|
|
||||||
mInstancingConstant(false)
|
mInstancingConstant(false)
|
||||||
{
|
{
|
||||||
if (desc.constType == GFXSCT_ConstBuffer)
|
if (desc.constType == GFXSCT_ConstBuffer)
|
||||||
mValid = false;
|
mValid = false;
|
||||||
else
|
else
|
||||||
mValid = true;
|
mValid = true;
|
||||||
addDesc(desc.shaderStage, desc);
|
|
||||||
|
|
||||||
|
addDesc(desc.shaderStage, desc);
|
||||||
mStageFlags = desc.shaderStage;
|
mStageFlags = desc.shaderStage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -976,7 +970,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection* refTable,
|
||||||
varDesc.constType = convertConstType(shaderTypeDesc);
|
varDesc.constType = convertConstType(shaderTypeDesc);
|
||||||
|
|
||||||
#ifdef D3D11_DEBUG_SPEW
|
#ifdef D3D11_DEBUG_SPEW
|
||||||
Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", varDesc.name.c_str(), varDesc.StartOffset, varDesc.Size, varDesc.arraySize);
|
Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", varDesc.name.c_str(), varDesc.offset, varDesc.size, varDesc.arraySize);
|
||||||
#endif
|
#endif
|
||||||
mShaderConsts.push_back(varDesc);
|
mShaderConsts.push_back(varDesc);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,15 +69,15 @@ public:
|
||||||
virtual ~GFXD3D11ShaderConstHandle();
|
virtual ~GFXD3D11ShaderConstHandle();
|
||||||
void addDesc(GFXShaderStage stage, const GFXShaderConstDesc& desc);
|
void addDesc(GFXShaderStage stage, const GFXShaderConstDesc& desc);
|
||||||
const GFXShaderConstDesc getDesc(GFXShaderStage stage);
|
const GFXShaderConstDesc getDesc(GFXShaderStage stage);
|
||||||
const String& getName() const { return mName; }
|
const String& getName() const { return mDesc.name; }
|
||||||
GFXShaderConstType getType() const { return mType; }
|
GFXShaderConstType getType() const { return mDesc.constType; }
|
||||||
U32 getArraySize() const { return mArraySize; }
|
U32 getArraySize() const { return mDesc.arraySize; }
|
||||||
|
|
||||||
U32 getSize() const { return mSize; }
|
U32 getSize() const { return mDesc.size; }
|
||||||
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 (!isSampler() || !mValid) ? -1 : mSampler; }
|
S32 getSamplerRegister() const { return (!isSampler() || !mValid) ? -1 : mDesc.samplerReg; }
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -93,13 +93,9 @@ public:
|
||||||
mValid = false;
|
mValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GFXShaderConstDesc mDesc;
|
||||||
GFXD3D11Shader* mShader;
|
GFXD3D11Shader* mShader;
|
||||||
DescMap mDescMap;
|
DescMap mDescMap;
|
||||||
String mName;
|
|
||||||
GFXShaderConstType mType;
|
|
||||||
U32 mSize;
|
|
||||||
U32 mArraySize;
|
|
||||||
S32 mSampler; // sampler number, will be -1 if not a sampler.
|
|
||||||
U32 mStageFlags;
|
U32 mStageFlags;
|
||||||
bool mInstancingConstant;
|
bool mInstancingConstant;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -81,11 +81,11 @@ struct GFXShaderConstDesc
|
||||||
public:
|
public:
|
||||||
String name;
|
String name;
|
||||||
GFXShaderConstType constType;
|
GFXShaderConstType constType;
|
||||||
U32 arraySize; // > 1 means it is an array!
|
U32 arraySize = 0; // > 1 means it is an array!
|
||||||
S32 bindPoint; // bind point used for ubo/cb.
|
S32 bindPoint = -1; // bind point used for ubo/cb
|
||||||
S32 samplerReg; // sampler register.
|
S32 samplerReg = -1; // sampler register.
|
||||||
U32 offset; // offset for vars
|
U32 offset = 0; // offset for vars
|
||||||
U32 size; // size of buffer/type
|
U32 size = 0; // size of buffer/type
|
||||||
GFXShaderStage shaderStage; // only used dx side.
|
GFXShaderStage shaderStage; // only used dx side.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -258,6 +258,7 @@ GFXGLDevice::GFXGLDevice(U32 adapterIndex) :
|
||||||
mModelViewProjSC[i] = NULL;
|
mModelViewProjSC[i] = NULL;
|
||||||
|
|
||||||
mOpenglStateCache = new GFXGLStateCache;
|
mOpenglStateCache = new GFXGLStateCache;
|
||||||
|
mCurrentConstBuffer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXGLDevice::~GFXGLDevice()
|
GFXGLDevice::~GFXGLDevice()
|
||||||
|
|
@ -958,9 +959,20 @@ void GFXGLDevice::setShader(GFXShader *shader, bool force)
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
|
void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
|
||||||
|
{
|
||||||
|
if (buffer)
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal);
|
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal);
|
||||||
static_cast<GFXGLShaderConstBuffer*>(buffer)->activate();
|
AssertFatal(static_cast<GFXGLShaderConstBuffer*>(buffer), "Incorrect shader const buffer type for this device!");
|
||||||
|
GFXGLShaderConstBuffer* oglBuffer = static_cast<GFXGLShaderConstBuffer*>(buffer);
|
||||||
|
|
||||||
|
oglBuffer->activate(mCurrentConstBuffer);
|
||||||
|
mCurrentConstBuffer = oglBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mCurrentConstBuffer = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 GFXGLDevice::getNumSamplers() const
|
U32 GFXGLDevice::getNumSamplers() const
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ class GFXGLCubemap;
|
||||||
class GFXGLCubemapArray;
|
class GFXGLCubemapArray;
|
||||||
class GFXGLStateCache;
|
class GFXGLStateCache;
|
||||||
class GFXGLVertexDecl;
|
class GFXGLVertexDecl;
|
||||||
|
class GFXGLShaderConstBuffer;
|
||||||
|
|
||||||
class GFXGLDevice : public GFXDevice
|
class GFXGLDevice : public GFXDevice
|
||||||
{
|
{
|
||||||
|
|
@ -200,7 +201,7 @@ protected:
|
||||||
|
|
||||||
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
|
virtual void setVertexStream( U32 stream, GFXVertexBuffer *buffer );
|
||||||
virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
|
virtual void setVertexStreamFrequency( U32 stream, U32 frequency );
|
||||||
|
StrongRefPtr<GFXGLShaderConstBuffer> mCurrentConstBuffer;
|
||||||
private:
|
private:
|
||||||
typedef GFXDevice Parent;
|
typedef GFXDevice Parent;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,51 +34,51 @@
|
||||||
|
|
||||||
#define CHECK_AARG(pos, name) static StringTableEntry attr_##name = StringTable->insert(#name); if (argName == attr_##name) { glBindAttribLocation(mProgram, pos, attr_##name); continue; }
|
#define CHECK_AARG(pos, name) static StringTableEntry attr_##name = StringTable->insert(#name); if (argName == attr_##name) { glBindAttribLocation(mProgram, pos, attr_##name); continue; }
|
||||||
|
|
||||||
|
|
||||||
class GFXGLShaderConstHandle : public GFXShaderConstHandle
|
|
||||||
{
|
|
||||||
friend class GFXGLShader;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
GFXGLShaderConstHandle( GFXGLShader *shader );
|
|
||||||
GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
|
|
||||||
virtual ~GFXGLShaderConstHandle();
|
|
||||||
|
|
||||||
void reinit( const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum );
|
|
||||||
|
|
||||||
const String& getName() const { return mDesc.name; }
|
|
||||||
GFXShaderConstType getType() const { return mDesc.constType; }
|
|
||||||
U32 getArraySize() const { return mDesc.arraySize; }
|
|
||||||
|
|
||||||
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; }
|
|
||||||
|
|
||||||
GFXShaderConstDesc mDesc;
|
|
||||||
GFXGLShader* mShader;
|
|
||||||
U32 mOffset;
|
|
||||||
U32 mSize;
|
|
||||||
GLuint mLocation;
|
|
||||||
S32 mSamplerNum;
|
|
||||||
bool mInstancingConstant;
|
|
||||||
};
|
|
||||||
|
|
||||||
GFXGLShaderConstHandle::GFXGLShaderConstHandle(GFXGLShader* shader)
|
GFXGLShaderConstHandle::GFXGLShaderConstHandle(GFXGLShader* shader)
|
||||||
: mShader( shader ), mLocation(0), mOffset(0), mSize(0), mSamplerNum(-1), mInstancingConstant(false)
|
: mShader(shader),
|
||||||
|
mUBOUniform(false),
|
||||||
|
mInstancingConstant(false)
|
||||||
{
|
{
|
||||||
dMemset(&mDesc, 0, sizeof(mDesc));
|
dMemset(&mDesc, 0, sizeof(mDesc));
|
||||||
mValid = false;
|
mValid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GFXGLShaderConstHandle::GFXGLShaderConstHandle(GFXGLShader* shader,
|
||||||
|
const GFXShaderConstDesc& desc)
|
||||||
|
: mShader(shader),
|
||||||
|
mDesc(desc),
|
||||||
|
mUBOUniform(false),
|
||||||
|
mInstancingConstant(false)
|
||||||
|
{
|
||||||
|
if (desc.constType == GFXSCT_ConstBuffer)
|
||||||
|
mValid = false;
|
||||||
|
else
|
||||||
|
mValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GFXGLShaderConstHandle::reinit(const GFXShaderConstDesc& desc)
|
||||||
|
{
|
||||||
|
mDesc = desc;
|
||||||
|
mValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GFXGLShaderConstHandle::~GFXGLShaderConstHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const GFXShaderConstDesc GFXGLShaderConstHandle::getDesc()
|
||||||
|
{
|
||||||
|
return mDesc;
|
||||||
|
}
|
||||||
|
|
||||||
static U32 shaderConstTypeSize(GFXShaderConstType type)
|
static U32 shaderConstTypeSize(GFXShaderConstType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case GFXSCT_Float:
|
case GFXSCT_Float:
|
||||||
case GFXSCT_Int:
|
case GFXSCT_Int:
|
||||||
|
case GFXSCT_UInt:
|
||||||
|
case GFXSCT_Bool:
|
||||||
case GFXSCT_Sampler:
|
case GFXSCT_Sampler:
|
||||||
case GFXSCT_SamplerCube:
|
case GFXSCT_SamplerCube:
|
||||||
case GFXSCT_SamplerCubeArray:
|
case GFXSCT_SamplerCubeArray:
|
||||||
|
|
@ -86,12 +86,18 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
|
||||||
return 4;
|
return 4;
|
||||||
case GFXSCT_Float2:
|
case GFXSCT_Float2:
|
||||||
case GFXSCT_Int2:
|
case GFXSCT_Int2:
|
||||||
|
case GFXSCT_UInt2:
|
||||||
|
case GFXSCT_Bool2:
|
||||||
return 8;
|
return 8;
|
||||||
case GFXSCT_Float3:
|
case GFXSCT_Float3:
|
||||||
case GFXSCT_Int3:
|
case GFXSCT_Int3:
|
||||||
|
case GFXSCT_UInt3:
|
||||||
|
case GFXSCT_Bool3:
|
||||||
return 12;
|
return 12;
|
||||||
case GFXSCT_Float4:
|
case GFXSCT_Float4:
|
||||||
case GFXSCT_Int4:
|
case GFXSCT_Int4:
|
||||||
|
case GFXSCT_UInt4:
|
||||||
|
case GFXSCT_Bool4:
|
||||||
return 16;
|
return 16;
|
||||||
case GFXSCT_Float2x2:
|
case GFXSCT_Float2x2:
|
||||||
return 16;
|
return 16;
|
||||||
|
|
@ -107,53 +113,14 @@ static U32 shaderConstTypeSize(GFXShaderConstType type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXGLShaderConstHandle::GFXGLShaderConstHandle( GFXGLShader *shader, const GFXShaderConstDesc &desc, GLuint loc, S32 samplerNum )
|
GFXGLShaderConstBuffer::GFXGLShaderConstBuffer(GFXGLShader* shader)
|
||||||
: mShader(shader), mInstancingConstant(false)
|
|
||||||
{
|
|
||||||
reinit(desc, loc, samplerNum);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GFXGLShaderConstHandle::reinit( const GFXShaderConstDesc& desc, GLuint loc, S32 samplerNum )
|
|
||||||
{
|
|
||||||
mDesc = desc;
|
|
||||||
mLocation = loc;
|
|
||||||
mSamplerNum = samplerNum;
|
|
||||||
mOffset = 0;
|
|
||||||
mInstancingConstant = false;
|
|
||||||
|
|
||||||
U32 elemSize = shaderConstTypeSize(mDesc.constType);
|
|
||||||
AssertFatal(elemSize, "GFXGLShaderConst::GFXGLShaderConst - elemSize is 0");
|
|
||||||
mSize = mDesc.arraySize * elemSize;
|
|
||||||
mValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
U32 GFXGLShaderConstHandle::getSize() const
|
|
||||||
{
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXGLShaderConstHandle::~GFXGLShaderConstHandle()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
GFXGLShaderConstBuffer::GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants)
|
|
||||||
{
|
{
|
||||||
mShader = shader;
|
mShader = shader;
|
||||||
mBuffer = new U8[bufSize];
|
|
||||||
mWasLost = true;
|
mWasLost = true;
|
||||||
|
|
||||||
// Copy the existing constant buffer to preserve sampler numbers
|
|
||||||
/// @warning This preserves a lot more than sampler numbers, obviously. If there
|
|
||||||
/// is any code that assumes a new constant buffer will have everything set to
|
|
||||||
/// 0, it will break.
|
|
||||||
dMemcpy(mBuffer, existingConstants, bufSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXGLShaderConstBuffer::~GFXGLShaderConstBuffer()
|
GFXGLShaderConstBuffer::~GFXGLShaderConstBuffer()
|
||||||
{
|
{
|
||||||
delete[] mBuffer;
|
|
||||||
|
|
||||||
if (mShader)
|
if (mShader)
|
||||||
mShader->_unlinkBuffer(this);
|
mShader->_unlinkBuffer(this);
|
||||||
}
|
}
|
||||||
|
|
@ -167,14 +134,30 @@ void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const Con
|
||||||
|
|
||||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||||
U8 *buf = mBuffer + _glHandle->mOffset;
|
|
||||||
|
U8* basePointer;
|
||||||
|
if (!_glHandle->mUBOUniform)
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[-1].data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[_glHandle->mDesc.bindPoint].data;
|
||||||
|
}
|
||||||
|
|
||||||
|
U8* buf = basePointer + _glHandle->mDesc.offset;
|
||||||
|
|
||||||
if (_glHandle->mInstancingConstant)
|
if (_glHandle->mInstancingConstant)
|
||||||
buf = mInstPtr + _glHandle->mOffset;
|
buf = mInstPtr + _glHandle->mDesc.offset;
|
||||||
|
|
||||||
dMemcpy(buf, ¶m, sizeof(ConstType));
|
dMemcpy(buf, ¶m, sizeof(ConstType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GFXShader* GFXGLShaderConstBuffer::getShader()
|
||||||
|
{
|
||||||
|
return mShader;
|
||||||
|
}
|
||||||
|
|
||||||
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv)
|
void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const F32 fv)
|
||||||
{
|
{
|
||||||
internalSet(handle, fv);
|
internalSet(handle, fv);
|
||||||
|
|
@ -235,10 +218,21 @@ void GFXGLShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const Ali
|
||||||
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
GFXGLShaderConstHandle* _glHandle = static_cast<GFXGLShaderConstHandle*>(handle);
|
||||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||||
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for array");
|
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for array");
|
||||||
|
|
||||||
|
U8* basePointer;
|
||||||
|
if (!_glHandle->mUBOUniform)
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[-1].data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[_glHandle->mDesc.bindPoint].data;
|
||||||
|
}
|
||||||
|
|
||||||
const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
|
const U8* fvBuffer = static_cast<const U8*>(fv.getBuffer());
|
||||||
for (U32 i = 0; i < fv.size(); ++i)
|
for (U32 i = 0; i < fv.size(); ++i)
|
||||||
{
|
{
|
||||||
dMemcpy(mBuffer + _glHandle->mOffset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType));
|
dMemcpy(basePointer + _glHandle->mDesc.offset + i * sizeof(ConstType), fvBuffer, sizeof(ConstType));
|
||||||
fvBuffer += fv.getElementSize();
|
fvBuffer += fv.getElementSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -293,27 +287,37 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
|
||||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||||
AssertFatal(!_glHandle->mInstancingConstant || matType == GFXSCT_Float4x4, "GFXGLShaderConstBuffer::set - Only support GFXSCT_Float4x4 for instancing");
|
AssertFatal(!_glHandle->mInstancingConstant || matType == GFXSCT_Float4x4, "GFXGLShaderConstBuffer::set - Only support GFXSCT_Float4x4 for instancing");
|
||||||
|
|
||||||
|
U8* basePointer;
|
||||||
|
if (!_glHandle->mUBOUniform)
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[-1].data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[_glHandle->mDesc.bindPoint].data;
|
||||||
|
}
|
||||||
|
|
||||||
switch (matType)
|
switch (matType)
|
||||||
{
|
{
|
||||||
case GFXSCT_Float2x2:
|
case GFXSCT_Float2x2:
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[0] = mat[0];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[0] = mat[0];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[1] = mat[1];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[1] = mat[1];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[2] = mat[4];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[2] = mat[4];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[3] = mat[5];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[3] = mat[5];
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float3x3:
|
case GFXSCT_Float3x3:
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[0] = mat[0];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[0] = mat[0];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[1] = mat[1];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[1] = mat[1];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[2] = mat[2];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[2] = mat[2];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[3] = mat[4];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[3] = mat[4];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[4] = mat[5];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[4] = mat[5];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[5] = mat[6];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[5] = mat[6];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[6] = mat[8];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[6] = mat[8];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[7] = mat[9];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[7] = mat[9];
|
||||||
reinterpret_cast<F32*>(mBuffer + _glHandle->mOffset)[8] = mat[10];
|
reinterpret_cast<F32*>(basePointer + _glHandle->mDesc.offset)[8] = mat[10];
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4x3:
|
case GFXSCT_Float4x3:
|
||||||
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off
|
dMemcpy(basePointer + _glHandle->mDesc.offset, (const F32*)mat, (sizeof(F32) * 12));// matrix with end row chopped off
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4x4:
|
case GFXSCT_Float4x4:
|
||||||
{
|
{
|
||||||
|
|
@ -321,11 +325,11 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF& ma
|
||||||
{
|
{
|
||||||
MatrixF transposed;
|
MatrixF transposed;
|
||||||
mat.transposeTo(transposed);
|
mat.transposeTo(transposed);
|
||||||
dMemcpy( mInstPtr + _glHandle->mOffset, (const F32*)transposed, sizeof(MatrixF) );
|
dMemcpy(mInstPtr + _glHandle->mDesc.offset, (const F32*)transposed, sizeof(MatrixF));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dMemcpy(mBuffer + _glHandle->mOffset, (const F32*)mat, sizeof(MatrixF));
|
dMemcpy(basePointer + _glHandle->mDesc.offset, (const F32*)mat, sizeof(MatrixF));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
@ -343,16 +347,26 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
|
||||||
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
AssertFatal(mShader == _glHandle->mShader, "GFXGLShaderConstBuffer::set - Should only set handles which are owned by our shader");
|
||||||
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
|
AssertFatal(!_glHandle->mInstancingConstant, "GFXGLShaderConstBuffer::set - Instancing not supported for matrix arrays");
|
||||||
|
|
||||||
|
U8* basePointer;
|
||||||
|
if (!_glHandle->mUBOUniform)
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[-1].data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
basePointer = mBufferMap[_glHandle->mDesc.bindPoint].data;
|
||||||
|
}
|
||||||
|
|
||||||
switch (matrixType) {
|
switch (matrixType) {
|
||||||
case GFXSCT_Float4x3:
|
case GFXSCT_Float4x3:
|
||||||
// Copy each item with the last row chopped off
|
// Copy each item with the last row chopped off
|
||||||
for (int i = 0; i < arraySize; i++)
|
for (int i = 0; i < arraySize; i++)
|
||||||
{
|
{
|
||||||
dMemcpy(mBuffer + _glHandle->mOffset + (i*(sizeof(F32) * 12)), (F32*)(mat + i), sizeof(F32) * 12);
|
dMemcpy(basePointer + _glHandle->mDesc.offset + (i * (sizeof(F32) * 12)), (F32*)(mat + i), sizeof(F32) * 12);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4x4:
|
case GFXSCT_Float4x4:
|
||||||
dMemcpy(mBuffer + _glHandle->mOffset, (F32*)mat, _glHandle->getSize());
|
dMemcpy(basePointer + _glHandle->mDesc.offset, (F32*)mat, _glHandle->getSize());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AssertFatal(false, "GFXGLShaderConstBuffer::set - setting array of non 4x4 matrices!");
|
AssertFatal(false, "GFXGLShaderConstBuffer::set - setting array of non 4x4 matrices!");
|
||||||
|
|
@ -360,13 +374,93 @@ void GFXGLShaderConstBuffer::set(GFXShaderConstHandle* handle, const MatrixF* ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXGLShaderConstBuffer::activate()
|
void GFXGLShaderConstBuffer::activate(GFXGLShaderConstBuffer* prevShaderBuffer)
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(GFXGLShaderConstBuffer_activate);
|
PROFILE_SCOPE(GFXGLShaderConstBuffer_activate);
|
||||||
mShader->setConstantsFromBuffer(this);
|
|
||||||
|
for (BufferMap::Iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i)
|
||||||
|
{
|
||||||
|
const S32 thisBufferDesc = i->key;
|
||||||
|
|
||||||
|
// set the global buffer differently
|
||||||
|
if (thisBufferDesc == -1)
|
||||||
|
{
|
||||||
|
mShader->setConstantsFromBuffer(mBufferMap[-1].data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstantBuffer thisBuff = i->value;
|
||||||
|
|
||||||
|
if (prevShaderBuffer && prevShaderBuffer != this)
|
||||||
|
{
|
||||||
|
const ConstantBuffer prevBuffer = prevShaderBuffer->mBufferMap[i->key];
|
||||||
|
|
||||||
|
if (prevBuffer.data && !prevBuffer.isDirty)
|
||||||
|
{
|
||||||
|
if (prevBuffer.size != thisBuff.size)
|
||||||
|
{
|
||||||
|
thisBuff.isDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dMemcmp(prevBuffer.data, thisBuff.data, thisBuff.size) != 0)
|
||||||
|
{
|
||||||
|
thisBuff.isDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisBuff.isDirty = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisBuff.isDirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thisBuff.isDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thisBuff.data && thisBuff.isDirty)
|
||||||
|
{
|
||||||
|
glBindBuffer(GL_UNIFORM_BUFFER, thisBuff.bufHandle);
|
||||||
|
glBufferData(GL_UNIFORM_BUFFER, thisBuff.size, thisBuff.data, GL_DYNAMIC_DRAW);
|
||||||
|
glBindBufferBase(GL_UNIFORM_BUFFER, thisBufferDesc, thisBuff.bufHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mWasLost = false;
|
mWasLost = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GFXGLShaderConstBuffer::addBuffer(S32 bufBindingPoint, U32 size)
|
||||||
|
{
|
||||||
|
// if this is the global buffer set it to the highest.
|
||||||
|
if (bufBindingPoint == -1)
|
||||||
|
{
|
||||||
|
// we dont create a bufferhandle for this one.
|
||||||
|
U8* buf = new U8[size];
|
||||||
|
dMemset(buf, 0, size);
|
||||||
|
mBufferMap[-1].data = buf;
|
||||||
|
mBufferMap[-1].size = size;
|
||||||
|
mBufferMap[-1].isDirty = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
U8* buf = new U8[size];
|
||||||
|
dMemset(buf, 0, size);
|
||||||
|
mBufferMap[bufBindingPoint].data = buf;
|
||||||
|
mBufferMap[bufBindingPoint].size = size;
|
||||||
|
mBufferMap[bufBindingPoint].isDirty = true;
|
||||||
|
|
||||||
|
GLuint uboHandle;
|
||||||
|
glGenBuffers(1, &uboHandle);
|
||||||
|
|
||||||
|
mBufferMap[bufBindingPoint].bufHandle = uboHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const String GFXGLShaderConstBuffer::describeSelf() const
|
const String GFXGLShaderConstBuffer::describeSelf() const
|
||||||
{
|
{
|
||||||
return String();
|
return String();
|
||||||
|
|
@ -376,9 +470,17 @@ void GFXGLShaderConstBuffer::onShaderReload( GFXGLShader *shader )
|
||||||
{
|
{
|
||||||
AssertFatal(shader == mShader, "GFXGLShaderConstBuffer::onShaderReload, mismatched shaders!");
|
AssertFatal(shader == mShader, "GFXGLShaderConstBuffer::onShaderReload, mismatched shaders!");
|
||||||
|
|
||||||
delete[] mBuffer;
|
for (auto& pair : mBufferMap) {
|
||||||
mBuffer = new U8[mShader->mConstBufferSize];
|
delete[] pair.value.data;
|
||||||
dMemset(mBuffer, 0, mShader->mConstBufferSize);
|
}
|
||||||
|
mBufferMap.clear(); // Clear the map
|
||||||
|
|
||||||
|
for (GFXGLShader::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.size);
|
||||||
|
}
|
||||||
|
|
||||||
mWasLost = true;
|
mWasLost = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,18 +490,23 @@ GFXGLShader::GFXGLShader(GFXGLDevice* device) :
|
||||||
mGeometryShader(0),
|
mGeometryShader(0),
|
||||||
mProgram(0),
|
mProgram(0),
|
||||||
mDevice(device),
|
mDevice(device),
|
||||||
mConstBufferSize(0),
|
mGlobalConstBuffer(NULL)
|
||||||
mConstBuffer(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXGLShader::~GFXGLShader()
|
GFXGLShader::~GFXGLShader()
|
||||||
{
|
{
|
||||||
clearShaders();
|
clearShaders();
|
||||||
for(HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); i++)
|
for (auto& pair : mHandles) {
|
||||||
delete i->value;
|
if (pair.value != nullptr) {
|
||||||
|
delete pair.value;
|
||||||
|
pair.value = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mHandles.clear();
|
||||||
|
|
||||||
delete[] mConstBuffer;
|
if (mGlobalConstBuffer)
|
||||||
|
delete[] mGlobalConstBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXGLShader::clearShaders()
|
void GFXGLShader::clearShaders()
|
||||||
|
|
@ -570,9 +677,9 @@ bool GFXGLShader::_init()
|
||||||
|
|
||||||
void GFXGLShader::initConstantDescs()
|
void GFXGLShader::initConstantDescs()
|
||||||
{
|
{
|
||||||
mConstants.clear();
|
// clear our vectors.
|
||||||
GLint numUniforms;
|
mShaderConsts.clear();
|
||||||
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
|
||||||
GLint maxNameLength;
|
GLint maxNameLength;
|
||||||
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
|
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength);
|
||||||
|
|
||||||
|
|
@ -582,83 +689,188 @@ void GFXGLShader::initConstantDescs()
|
||||||
|
|
||||||
FrameTemp<GLchar> uniformName(maxNameLength);
|
FrameTemp<GLchar> uniformName(maxNameLength);
|
||||||
|
|
||||||
|
// parse ubos first and add them to our table, same as in dx
|
||||||
|
// this is required so that in the other uniform loop we dont add
|
||||||
|
// a uniform that exists in a ubo again.
|
||||||
|
GLint numUBOS;
|
||||||
|
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORM_BLOCKS, &numUBOS);
|
||||||
|
for (U32 i = 0; i < numUBOS; i++) {
|
||||||
|
GFXShaderConstDesc desc;
|
||||||
|
GLint uboNameLen;
|
||||||
|
glGetActiveUniformBlockiv(mProgram, i, GL_UNIFORM_BLOCK_NAME_LENGTH, &uboNameLen);
|
||||||
|
if (!uboNameLen)
|
||||||
|
return;
|
||||||
|
uboNameLen++;
|
||||||
|
|
||||||
|
// get the name of the ubo for getting required data.
|
||||||
|
FrameTemp<GLchar> uboName(uboNameLen);
|
||||||
|
glGetActiveUniformBlockName(mProgram, i, uboNameLen, NULL, uboName);
|
||||||
|
GLint uboBinding;
|
||||||
|
glGetActiveUniformBlockiv(mProgram, i, GL_UNIFORM_BLOCK_BINDING, &uboBinding);
|
||||||
|
GLint uboSize;
|
||||||
|
glGetActiveUniformBlockiv(mProgram, i, GL_UNIFORM_BLOCK_DATA_SIZE, &uboSize);
|
||||||
|
GLint numUboUniforms;
|
||||||
|
glGetActiveUniformBlockiv(mProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUboUniforms);
|
||||||
|
GLint* indices = new GLint[numUboUniforms];
|
||||||
|
glGetActiveUniformBlockiv(mProgram, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, indices);
|
||||||
|
|
||||||
|
// fill out ubo desc.
|
||||||
|
desc.name = String((char*)uboName);
|
||||||
|
desc.bindPoint = uboBinding;
|
||||||
|
desc.size = uboSize;
|
||||||
|
desc.constType = GFXSCT_ConstBuffer;
|
||||||
|
desc.samplerReg = -1;
|
||||||
|
|
||||||
|
mBuffers[desc.name] = desc;
|
||||||
|
|
||||||
|
// loop uniforms in the ubo.
|
||||||
|
for (U32 j = 0; j < numUboUniforms; j++)
|
||||||
|
{
|
||||||
|
GFXShaderConstDesc varDesc;
|
||||||
|
|
||||||
|
GLint uniformIndex = indices[j];
|
||||||
|
GLint size;
|
||||||
|
GLenum type;
|
||||||
|
GLint offset;
|
||||||
|
glGetActiveUniformsiv(mProgram, 1, (const GLuint*)&uniformIndex, GL_UNIFORM_OFFSET, &offset);
|
||||||
|
glGetActiveUniform(mProgram, uniformIndex, maxNameLength, NULL, &size, &type, uniformName);
|
||||||
|
|
||||||
|
varDesc.name = String((char*)uniformName);
|
||||||
|
// remove array brackets.
|
||||||
|
varDesc.name = varDesc.name.substr(0, varDesc.name.find('['));
|
||||||
|
// Insert $ to match D3D behavior of having a $ prepended to parameters to main.
|
||||||
|
varDesc.name.insert(0, '$');
|
||||||
|
varDesc.bindPoint = desc.bindPoint; // just set to the buffer bindpoint for uniforms in a ubo.
|
||||||
|
varDesc.offset = offset;
|
||||||
|
varDesc.arraySize = size;
|
||||||
|
varDesc.constType = convertConstType(type);
|
||||||
|
varDesc.size = shaderConstTypeSize(varDesc.constType) * size;
|
||||||
|
varDesc.samplerReg = -1;
|
||||||
|
|
||||||
|
#ifdef OPENGL_DEBUG_SPEW
|
||||||
|
Con::printf("Variable Name %s:, offset: %d, size: %d, constantDesc.Elements: %d", varDesc.name.c_str(), varDesc.offset, varDesc.size, varDesc.arraySize);
|
||||||
|
#endif
|
||||||
|
mShaderConsts.push_back(varDesc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint numUniforms;
|
||||||
|
glGetProgramiv(mProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||||
|
|
||||||
for (U32 i = 0; i < numUniforms; i++)
|
for (U32 i = 0; i < numUniforms; i++)
|
||||||
{
|
{
|
||||||
|
// skip if this uniform is inside a ubo.
|
||||||
|
GLint blk;
|
||||||
|
glGetActiveUniformsiv(mProgram, 1, (GLuint*)&i, GL_UNIFORM_BLOCK_INDEX, &blk);
|
||||||
|
if (blk != -1)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
GLint size;
|
GLint size;
|
||||||
GLenum type;
|
GLenum type;
|
||||||
glGetActiveUniform(mProgram, i, maxNameLength, NULL, &size, &type, uniformName);
|
glGetActiveUniform(mProgram, i, maxNameLength, NULL, &size, &type, uniformName);
|
||||||
|
|
||||||
GFXShaderConstDesc desc;
|
GFXShaderConstDesc desc;
|
||||||
|
|
||||||
desc.name = String((char*)uniformName);
|
desc.name = String((char*)uniformName);
|
||||||
|
|
||||||
// Remove array brackets from the name
|
// Remove array brackets from the name
|
||||||
desc.name = desc.name.substr(0, desc.name.find('['));
|
desc.name = desc.name.substr(0, desc.name.find('['));
|
||||||
|
|
||||||
// Insert $ to match D3D behavior of having a $ prepended to parameters to main.
|
// Insert $ to match D3D behavior of having a $ prepended to parameters to main.
|
||||||
desc.name.insert(0, '$');
|
desc.name.insert(0, '$');
|
||||||
desc.arraySize = size;
|
|
||||||
|
|
||||||
switch(type)
|
desc.bindPoint = -1;
|
||||||
|
desc.arraySize = size;
|
||||||
|
desc.constType = convertConstType(type);
|
||||||
|
desc.size = shaderConstTypeSize(desc.constType) * size;
|
||||||
|
desc.samplerReg = -1;
|
||||||
|
mShaderConsts.push_back(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GFXShaderConstType GFXGLShader::convertConstType(GLenum constType)
|
||||||
|
{
|
||||||
|
switch (constType)
|
||||||
{
|
{
|
||||||
case GL_FLOAT:
|
case GL_FLOAT:
|
||||||
desc.constType = GFXSCT_Float;
|
return GFXSCT_Float;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_VEC2:
|
case GL_FLOAT_VEC2:
|
||||||
desc.constType = GFXSCT_Float2;
|
return GFXSCT_Float2;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_VEC3:
|
case GL_FLOAT_VEC3:
|
||||||
desc.constType = GFXSCT_Float3;
|
return GFXSCT_Float3;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_VEC4:
|
case GL_FLOAT_VEC4:
|
||||||
desc.constType = GFXSCT_Float4;
|
return GFXSCT_Float4;
|
||||||
break;
|
break;
|
||||||
case GL_INT:
|
case GL_INT:
|
||||||
desc.constType = GFXSCT_Int;
|
return GFXSCT_Int;
|
||||||
break;
|
break;
|
||||||
case GL_INT_VEC2:
|
case GL_INT_VEC2:
|
||||||
desc.constType = GFXSCT_Int2;
|
return GFXSCT_Int2;
|
||||||
break;
|
break;
|
||||||
case GL_INT_VEC3:
|
case GL_INT_VEC3:
|
||||||
desc.constType = GFXSCT_Int3;
|
return GFXSCT_Int3;
|
||||||
break;
|
break;
|
||||||
case GL_INT_VEC4:
|
case GL_INT_VEC4:
|
||||||
desc.constType = GFXSCT_Int4;
|
return GFXSCT_Int4;
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_INT:
|
||||||
|
return GFXSCT_UInt;
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_INT_VEC2:
|
||||||
|
return GFXSCT_UInt2;
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_INT_VEC3:
|
||||||
|
return GFXSCT_UInt3;
|
||||||
|
break;
|
||||||
|
case GL_UNSIGNED_INT_VEC4:
|
||||||
|
return GFXSCT_UInt4;
|
||||||
|
break;
|
||||||
|
case GL_BOOL:
|
||||||
|
return GFXSCT_Bool;
|
||||||
|
break;
|
||||||
|
case GL_BOOL_VEC2:
|
||||||
|
return GFXSCT_Bool2;
|
||||||
|
break;
|
||||||
|
case GL_BOOL_VEC3:
|
||||||
|
return GFXSCT_Bool3;
|
||||||
|
break;
|
||||||
|
case GL_BOOL_VEC4:
|
||||||
|
return GFXSCT_Bool4;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_MAT2:
|
case GL_FLOAT_MAT2:
|
||||||
desc.constType = GFXSCT_Float2x2;
|
return GFXSCT_Float2x2;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_MAT3:
|
case GL_FLOAT_MAT3:
|
||||||
desc.constType = GFXSCT_Float3x3;
|
return GFXSCT_Float3x3;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_MAT4:
|
case GL_FLOAT_MAT4:
|
||||||
desc.constType = GFXSCT_Float4x4;
|
return GFXSCT_Float4x4;
|
||||||
break;
|
break;
|
||||||
case GL_FLOAT_MAT4x3: // jamesu - columns, rows
|
case GL_FLOAT_MAT4x3: // jamesu - columns, rows
|
||||||
desc.constType = GFXSCT_Float4x3;
|
return GFXSCT_Float4x3;
|
||||||
break;
|
break;
|
||||||
case GL_SAMPLER_1D:
|
case GL_SAMPLER_1D:
|
||||||
case GL_SAMPLER_2D:
|
case GL_SAMPLER_2D:
|
||||||
case GL_SAMPLER_3D:
|
case GL_SAMPLER_3D:
|
||||||
case GL_SAMPLER_1D_SHADOW:
|
case GL_SAMPLER_1D_SHADOW:
|
||||||
case GL_SAMPLER_2D_SHADOW:
|
case GL_SAMPLER_2D_SHADOW:
|
||||||
desc.constType = GFXSCT_Sampler;
|
return GFXSCT_Sampler;
|
||||||
break;
|
break;
|
||||||
case GL_SAMPLER_CUBE:
|
case GL_SAMPLER_CUBE:
|
||||||
desc.constType = GFXSCT_SamplerCube;
|
return GFXSCT_SamplerCube;
|
||||||
break;
|
break;
|
||||||
case GL_SAMPLER_CUBE_MAP_ARRAY_ARB:
|
case GL_SAMPLER_CUBE_MAP_ARRAY_ARB:
|
||||||
desc.constType = GFXSCT_SamplerCubeArray;
|
return GFXSCT_SamplerCubeArray;
|
||||||
break;
|
break;
|
||||||
case GL_SAMPLER_2D_ARRAY:
|
case GL_SAMPLER_2D_ARRAY:
|
||||||
desc.constType = GFXSCT_SamplerTextureArray;
|
return GFXSCT_SamplerTextureArray;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AssertFatal(false, "GFXGLShader::initConstantDescs - unrecognized uniform type");
|
AssertFatal(false, "GFXGLShader::initConstantDescs - unrecognized uniform type");
|
||||||
// If we don't recognize the constant don't add its description.
|
// If we don't recognize the constant don't add its description.
|
||||||
continue;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
mConstants.push_back(desc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -668,13 +880,11 @@ void GFXGLShader::initHandles()
|
||||||
// Those that are found when parsing the descriptions will then be marked valid again.
|
// Those that are found when parsing the descriptions will then be marked valid again.
|
||||||
for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
|
for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
|
||||||
(iter->value)->setValid(false);
|
(iter->value)->setValid(false);
|
||||||
mValidHandles.clear();
|
|
||||||
|
|
||||||
// Loop through all ConstantDescriptions,
|
// Loop through constants that exist in ubos.
|
||||||
// if they aren't in the HandleMap add them, if they are reinitialize them.
|
for (U32 i = 0; i < mShaderConsts.size(); i++)
|
||||||
for ( U32 i = 0; i < mConstants.size(); i++ )
|
|
||||||
{
|
{
|
||||||
GFXShaderConstDesc &desc = mConstants[i];
|
GFXShaderConstDesc& desc = mShaderConsts[i];
|
||||||
|
|
||||||
// Index element 1 of the name to skip the '$' we inserted earier.
|
// Index element 1 of the name to skip the '$' we inserted earier.
|
||||||
GLint loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
|
GLint loc = glGetUniformLocation(mProgram, &desc.name.c_str()[1]);
|
||||||
|
|
@ -691,37 +901,71 @@ void GFXGLShader::initHandles()
|
||||||
S32 idx = mSamplerNamesOrdered.find_next(desc.name);
|
S32 idx = mSamplerNamesOrdered.find_next(desc.name);
|
||||||
AssertFatal(idx != -1, "");
|
AssertFatal(idx != -1, "");
|
||||||
sampler = idx; //assignedSamplerNum++;
|
sampler = idx; //assignedSamplerNum++;
|
||||||
|
desc.samplerReg = idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handle != mHandles.end())
|
if (handle != mHandles.end())
|
||||||
{
|
{
|
||||||
handle->value->reinit( desc, loc, sampler );
|
if (desc.bindPoint == -1)
|
||||||
|
{
|
||||||
|
desc.bindPoint = loc;
|
||||||
|
mHandles[desc.name]->mUBOUniform = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mHandles[desc.name] = new GFXGLShaderConstHandle( this, desc, loc, sampler );
|
mHandles[desc.name]->mUBOUniform = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle->value->reinit(desc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (desc.bindPoint == -1)
|
||||||
|
{
|
||||||
|
desc.bindPoint = loc;
|
||||||
|
mHandles[desc.name] = new GFXGLShaderConstHandle(this, desc);
|
||||||
|
mHandles[desc.name]->mUBOUniform = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mHandles[desc.name] = new GFXGLShaderConstHandle(this, desc);
|
||||||
|
mHandles[desc.name]->mUBOUniform = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through handles once more to set their offset and calculate our
|
|
||||||
// constBuffer size.
|
|
||||||
|
|
||||||
if ( mConstBuffer )
|
// we have a global const buffer, set it up and add it.
|
||||||
delete[] mConstBuffer;
|
U32 constBufferSize = 0;
|
||||||
mConstBufferSize = 0;
|
|
||||||
|
if (mGlobalConstBuffer)
|
||||||
|
delete[] mGlobalConstBuffer;
|
||||||
|
|
||||||
for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
|
for (HandleMap::Iterator iter = mHandles.begin(); iter != mHandles.end(); ++iter)
|
||||||
{
|
{
|
||||||
GFXGLShaderConstHandle* handle = iter->value;
|
GFXGLShaderConstHandle* handle = iter->value;
|
||||||
if ( handle->isValid() )
|
if (handle->isValid() && !handle->mUBOUniform)
|
||||||
{
|
{
|
||||||
mValidHandles.push_back(handle);
|
handle->mDesc.offset = constBufferSize;
|
||||||
handle->mOffset = mConstBufferSize;
|
constBufferSize += handle->getSize();
|
||||||
mConstBufferSize += handle->getSize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mConstBuffer = new U8[mConstBufferSize];
|
if (constBufferSize > 0)
|
||||||
dMemset(mConstBuffer, 0, mConstBufferSize);
|
{
|
||||||
|
GFXShaderConstDesc desc;
|
||||||
|
// fill out ubo desc.
|
||||||
|
desc.name = "Global";
|
||||||
|
desc.bindPoint = -1;
|
||||||
|
desc.size = constBufferSize;
|
||||||
|
desc.constType = GFXSCT_ConstBuffer;
|
||||||
|
desc.samplerReg = -1;
|
||||||
|
|
||||||
|
mBuffers[desc.name] = desc;
|
||||||
|
|
||||||
|
mGlobalConstBuffer = new U8[constBufferSize];
|
||||||
|
dMemset(mGlobalConstBuffer, 0, constBufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Set our program so uniforms are assigned properly.
|
// Set our program so uniforms are assigned properly.
|
||||||
mDevice->setShader(this, false);
|
mDevice->setShader(this, false);
|
||||||
|
|
@ -737,9 +981,9 @@ void GFXGLShader::initHandles()
|
||||||
handle->getType() == GFXSCT_SamplerTextureArray))
|
handle->getType() == GFXSCT_SamplerTextureArray))
|
||||||
{
|
{
|
||||||
// Set sampler number on our program.
|
// Set sampler number on our program.
|
||||||
glUniform1i(handle->mLocation, handle->mSamplerNum);
|
glUniform1i(handle->mDesc.bindPoint, handle->mDesc.samplerReg);
|
||||||
// Set sampler in constant buffer so it does not get unset later.
|
// Set sampler in constant buffer so it does not get unset later.
|
||||||
dMemcpy(mConstBuffer + handle->mOffset, &handle->mSamplerNum, handle->getSize());
|
dMemcpy(mGlobalConstBuffer + handle->mDesc.offset, &handle->mDesc.samplerReg, handle->getSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -776,9 +1020,10 @@ void GFXGLShader::initHandles()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXGLShaderConstHandle *h = new GFXGLShaderConstHandle( this, desc, -1, -1 );
|
GFXGLShaderConstHandle* h = new GFXGLShaderConstHandle(this, desc);
|
||||||
h->mInstancingConstant = true;
|
h->mInstancingConstant = true;
|
||||||
h->mOffset = offset;
|
h->mDesc.offset = offset;
|
||||||
|
h->mUBOUniform = false;
|
||||||
mHandles[constName] = h;
|
mHandles[constName] = h;
|
||||||
|
|
||||||
offset += element.getSizeInBytes();
|
offset += element.getSizeInBytes();
|
||||||
|
|
@ -833,77 +1078,90 @@ GFXShaderConstHandle* GFXGLShader::findShaderConstHandle(const String& name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GFXGLShader::setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer)
|
void GFXGLShader::setConstantsFromBuffer(U8* buffer)
|
||||||
{
|
{
|
||||||
for(Vector<GFXGLShaderConstHandle*>::iterator i = mValidHandles.begin(); i != mValidHandles.end(); ++i)
|
for (HandleMap::Iterator i = mHandles.begin(); i != mHandles.end(); ++i)
|
||||||
{
|
{
|
||||||
GFXGLShaderConstHandle* handle = *i;
|
GFXGLShaderConstHandle* handle = i->value;
|
||||||
AssertFatal(handle, "GFXGLShader::setConstantsFromBuffer - Null handle");
|
AssertFatal(handle, "GFXGLShader::setConstantsFromBuffer - Null handle");
|
||||||
|
// skip ubo uniforms.
|
||||||
|
if (handle->mUBOUniform || !handle->isValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
if (handle->mInstancingConstant)
|
if (handle->mInstancingConstant)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't set if the value has not be changed.
|
// Don't set if the value has not be changed.
|
||||||
if(dMemcmp(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize()) == 0)
|
if (dMemcmp(mGlobalConstBuffer + handle->mDesc.offset, buffer + handle->mDesc.offset, handle->getSize()) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Copy new value into our const buffer and set in GL.
|
// Copy new value into our const buffer and set in GL.
|
||||||
dMemcpy(mConstBuffer + handle->mOffset, buffer->mBuffer + handle->mOffset, handle->getSize());
|
dMemcpy(mGlobalConstBuffer + handle->mDesc.offset, buffer + handle->mDesc.offset, handle->getSize());
|
||||||
|
|
||||||
switch (handle->mDesc.constType)
|
switch (handle->mDesc.constType)
|
||||||
{
|
{
|
||||||
case GFXSCT_Float:
|
case GFXSCT_Float:
|
||||||
glUniform1fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniform1fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float2:
|
case GFXSCT_Float2:
|
||||||
glUniform2fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniform2fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float3:
|
case GFXSCT_Float3:
|
||||||
glUniform3fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniform3fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4:
|
case GFXSCT_Float4:
|
||||||
glUniform4fv(handle->mLocation, handle->mDesc.arraySize, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniform4fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Int:
|
|
||||||
case GFXSCT_Sampler:
|
case GFXSCT_Sampler:
|
||||||
case GFXSCT_SamplerCube:
|
case GFXSCT_SamplerCube:
|
||||||
case GFXSCT_SamplerCubeArray:
|
case GFXSCT_SamplerCubeArray:
|
||||||
case GFXSCT_SamplerTextureArray:
|
case GFXSCT_SamplerTextureArray:
|
||||||
glUniform1iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
|
// Set sampler number on our program.
|
||||||
|
glUniform1i(handle->mDesc.bindPoint, handle->mDesc.samplerReg);
|
||||||
|
break;
|
||||||
|
case GFXSCT_Int:
|
||||||
|
glUniform1iv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLint*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Int2:
|
case GFXSCT_Int2:
|
||||||
glUniform2iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
|
glUniform2iv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLint*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Int3:
|
case GFXSCT_Int3:
|
||||||
glUniform3iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
|
glUniform3iv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLint*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Int4:
|
case GFXSCT_Int4:
|
||||||
glUniform4iv(handle->mLocation, handle->mDesc.arraySize, (GLint*)(mConstBuffer + handle->mOffset));
|
glUniform4iv(handle->mDesc.bindPoint, handle->mDesc.arraySize, (GLint*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float2x2:
|
case GFXSCT_Float2x2:
|
||||||
glUniformMatrix2fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniformMatrix2fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, true, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float3x3:
|
case GFXSCT_Float3x3:
|
||||||
glUniformMatrix3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniformMatrix3fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, true, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4x3:
|
case GFXSCT_Float4x3:
|
||||||
// NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer.
|
// NOTE: To save a transpose here we could store the matrix transposed (i.e. column major) in the constant buffer.
|
||||||
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
|
// See _mesa_uniform_matrix in the mesa source for the correct transpose algorithm for a 4x3 matrix.
|
||||||
glUniformMatrix4x3fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniformMatrix4x3fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, true, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
case GFXSCT_Float4x4:
|
case GFXSCT_Float4x4:
|
||||||
glUniformMatrix4fv(handle->mLocation, handle->mDesc.arraySize, true, (GLfloat*)(mConstBuffer + handle->mOffset));
|
glUniformMatrix4fv(handle->mDesc.bindPoint, handle->mDesc.arraySize, true, (GLfloat*)(mGlobalConstBuffer + handle->mDesc.offset));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
AssertFatal(0, "");
|
AssertFatal(0, "");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXShaderConstBufferRef GFXGLShader::allocConstBuffer()
|
GFXShaderConstBufferRef GFXGLShader::allocConstBuffer()
|
||||||
{
|
{
|
||||||
GFXGLShaderConstBuffer* buffer = new GFXGLShaderConstBuffer(this, mConstBufferSize, mConstBuffer);
|
GFXGLShaderConstBuffer* buffer = new GFXGLShaderConstBuffer(this);
|
||||||
|
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.size);
|
||||||
|
}
|
||||||
|
|
||||||
buffer->registerResourceWithDevice(getOwningDevice());
|
buffer->registerResourceWithDevice(getOwningDevice());
|
||||||
mActiveBuffers.push_back(buffer);
|
mActiveBuffers.push_back(buffer);
|
||||||
return buffer;
|
return buffer;
|
||||||
|
|
@ -917,7 +1175,6 @@ void GFXGLShader::useProgram()
|
||||||
void GFXGLShader::zombify()
|
void GFXGLShader::zombify()
|
||||||
{
|
{
|
||||||
clearShaders();
|
clearShaders();
|
||||||
dMemset(mConstBuffer, 0, mConstBufferSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char* GFXGLShader::_handleIncludes(const Torque::Path& path, FileStream* s)
|
char* GFXGLShader::_handleIncludes(const Torque::Path& path, FileStream* s)
|
||||||
|
|
@ -1106,7 +1363,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(GFXGLShader_CompileShader);
|
PROFILE_SCOPE(GFXGLShader_CompileShader);
|
||||||
|
|
||||||
GLuint activeShader;
|
GLuint activeShader = 0;
|
||||||
|
|
||||||
switch (stage)
|
switch (stage)
|
||||||
{
|
{
|
||||||
|
|
@ -1185,7 +1442,7 @@ bool GFXGLShader::initShader( const Torque::Path &file,
|
||||||
const Vector<GFXShaderConstDesc>& GFXGLShader::getShaderConstDesc() const
|
const Vector<GFXShaderConstDesc>& GFXGLShader::getShaderConstDesc() const
|
||||||
{
|
{
|
||||||
PROFILE_SCOPE(GFXGLShader_GetShaderConstants);
|
PROFILE_SCOPE(GFXGLShader_GetShaderConstants);
|
||||||
return mConstants;
|
return mShaderConsts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the alignment value for constType
|
/// Returns the alignment value for constType
|
||||||
|
|
|
||||||
|
|
@ -29,96 +29,95 @@
|
||||||
#include "core/util/tSignal.h"
|
#include "core/util/tSignal.h"
|
||||||
#include "core/util/tDictionary.h"
|
#include "core/util/tDictionary.h"
|
||||||
|
|
||||||
class GFXGLShaderConstHandle;
|
|
||||||
class FileStream;
|
class FileStream;
|
||||||
class GFXGLShaderConstBuffer;
|
|
||||||
class GFXGLDevice;
|
class GFXGLDevice;
|
||||||
|
class GFXGLShader;
|
||||||
|
|
||||||
class GFXGLShader : public GFXShader
|
struct BufferRange
|
||||||
{
|
{
|
||||||
typedef Map<String, GFXGLShaderConstHandle*> HandleMap;
|
U32 mBufMin = U32_MAX;
|
||||||
|
U32 mBufMax = 0;
|
||||||
|
|
||||||
|
inline void addSlot(U32 slot)
|
||||||
|
{
|
||||||
|
mBufMin = getMin(mBufMin, slot);
|
||||||
|
mBufMax = getMax(mBufMax, slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isValid() const { return mBufMin <= mBufMax; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConstantBuffer
|
||||||
|
{
|
||||||
|
GLuint bufHandle;
|
||||||
|
U8* data;
|
||||||
|
U32 size;
|
||||||
|
bool isDirty;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GFXGLShaderConstHandle : public GFXShaderConstHandle
|
||||||
|
{
|
||||||
|
friend class GFXGLShader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GFXGLShader(GFXGLDevice* device);
|
// DX side needs the description map as the same uniform can exist across stages. for gl it is program wide.
|
||||||
virtual ~GFXGLShader();
|
GFXGLShaderConstHandle(GFXGLShader* shader);
|
||||||
|
GFXGLShaderConstHandle(GFXGLShader* shader,
|
||||||
|
const GFXShaderConstDesc& desc);
|
||||||
|
|
||||||
/// @name GFXShader interface
|
void reinit(const GFXShaderConstDesc& desc);
|
||||||
/// @{
|
|
||||||
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
|
|
||||||
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
|
|
||||||
|
|
||||||
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
virtual ~GFXGLShaderConstHandle();
|
||||||
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
|
const GFXShaderConstDesc getDesc();
|
||||||
|
const String& getName() const { return mDesc.name; }
|
||||||
|
GFXShaderConstType getType() const { return mDesc.constType; }
|
||||||
|
U32 getArraySize() const { return mDesc.arraySize; }
|
||||||
|
|
||||||
/// Returns the alignment value for constType
|
U32 getSize() const { return mDesc.size; }
|
||||||
virtual U32 getAlignmentValue(const GFXShaderConstType constType) 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 (!isSampler() || !mValid) ? -1 : mDesc.samplerReg; }
|
||||||
|
|
||||||
virtual GFXShaderConstBufferRef allocConstBuffer();
|
// Returns true if this is a handle to a sampler register.
|
||||||
|
bool isSampler() const
|
||||||
|
{
|
||||||
|
return (getType() >= GFXSCT_Sampler);
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// Restore to uninitialized state.
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
mShader = NULL;
|
||||||
|
mInstancingConstant = false;
|
||||||
|
mValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// @name GFXResource interface
|
GFXShaderConstDesc mDesc;
|
||||||
/// @{
|
GFXGLShader* mShader;
|
||||||
virtual void zombify();
|
bool mUBOUniform;
|
||||||
virtual void resurrect() { reload(); }
|
bool mInstancingConstant;
|
||||||
virtual const String describeSelf() const;
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
/// Activates this shader in the GL context.
|
|
||||||
void useProgram();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
friend class GFXGLShaderConstBuffer;
|
|
||||||
friend class GFXGLShaderConstHandle;
|
|
||||||
|
|
||||||
virtual bool _init();
|
|
||||||
|
|
||||||
bool initShader( const Torque::Path &file,
|
|
||||||
GFXShaderStage stage,
|
|
||||||
const Vector<GFXShaderMacro> ¯os );
|
|
||||||
|
|
||||||
void clearShaders();
|
|
||||||
void initConstantDescs();
|
|
||||||
void initHandles();
|
|
||||||
void setConstantsFromBuffer(GFXGLShaderConstBuffer* buffer);
|
|
||||||
|
|
||||||
static char* _handleIncludes( const Torque::Path &path, FileStream *s );
|
|
||||||
|
|
||||||
static bool _loadShaderFromStream( GLuint shader,
|
|
||||||
const Torque::Path& path,
|
|
||||||
FileStream* s,
|
|
||||||
const Vector<GFXShaderMacro>& macros );
|
|
||||||
|
|
||||||
/// @name Internal GL handles
|
|
||||||
/// @{
|
|
||||||
GLuint mVertexShader;
|
|
||||||
GLuint mPixelShader;
|
|
||||||
GLuint mGeometryShader;
|
|
||||||
GLuint mProgram;
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
Vector<GFXShaderConstDesc> mConstants;
|
|
||||||
U32 mConstBufferSize;
|
|
||||||
U8* mConstBuffer;
|
|
||||||
HandleMap mHandles;
|
|
||||||
GFXGLDevice* mDevice;
|
|
||||||
Vector<GFXGLShaderConstHandle*> mValidHandles;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
|
class GFXGLShaderConstBuffer : public GFXShaderConstBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GFXGLShaderConstBuffer(GFXGLShader* shader, U32 bufSize, U8* existingConstants);
|
// -1 is the global buffer.
|
||||||
|
typedef Map<S32, ConstantBuffer> BufferMap;
|
||||||
|
|
||||||
|
GFXGLShaderConstBuffer(GFXGLShader* shader);
|
||||||
~GFXGLShaderConstBuffer();
|
~GFXGLShaderConstBuffer();
|
||||||
|
|
||||||
/// Called by GFXGLDevice to activate this buffer.
|
/// Called by GFXGLDevice to activate this buffer.
|
||||||
void activate();
|
void activate(GFXGLShaderConstBuffer* prevShaderBuffer);
|
||||||
|
|
||||||
|
void addBuffer(S32 bufBindingPoint, U32 size);
|
||||||
|
|
||||||
/// Called when the shader this buffer references is reloaded.
|
/// Called when the shader this buffer references is reloaded.
|
||||||
void onShaderReload(GFXGLShader* shader);
|
void onShaderReload(GFXGLShader* shader);
|
||||||
|
|
||||||
// GFXShaderConstBuffer
|
// GFXShaderConstBuffer
|
||||||
virtual GFXShader* getShader() { return mShader; }
|
virtual GFXShader* getShader();
|
||||||
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
|
virtual void set(GFXShaderConstHandle* handle, const F32 fv);
|
||||||
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
|
virtual void set(GFXShaderConstHandle* handle, const Point2F& fv);
|
||||||
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
|
virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
|
||||||
|
|
@ -148,8 +147,9 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class GFXGLShader;
|
friend class GFXGLShader;
|
||||||
U8* mBuffer;
|
|
||||||
WeakRefPtr<GFXGLShader> mShader;
|
WeakRefPtr<GFXGLShader> mShader;
|
||||||
|
BufferMap mBufferMap;
|
||||||
|
|
||||||
template<typename ConstType>
|
template<typename ConstType>
|
||||||
void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
|
void internalSet(GFXShaderConstHandle* handle, const ConstType& param);
|
||||||
|
|
@ -158,4 +158,80 @@ private:
|
||||||
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
|
void internalSet(GFXShaderConstHandle* handle, const AlignedArray<ConstType>& fv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GFXGLShader : public GFXShader
|
||||||
|
{
|
||||||
|
friend class GFXGLShaderConstBuffer;
|
||||||
|
friend class GFXGLShaderConstHandle;
|
||||||
|
public:
|
||||||
|
typedef Map<String, GFXGLShaderConstHandle*> HandleMap;
|
||||||
|
typedef Map<String, GFXShaderConstDesc> BufferMap;
|
||||||
|
|
||||||
|
GFXGLShader(GFXGLDevice* device);
|
||||||
|
virtual ~GFXGLShader();
|
||||||
|
|
||||||
|
/// @name GFXShader interface
|
||||||
|
/// @{
|
||||||
|
virtual GFXShaderConstHandle* getShaderConstHandle(const String& name);
|
||||||
|
virtual GFXShaderConstHandle* findShaderConstHandle(const String& name);
|
||||||
|
|
||||||
|
/// Returns our list of shader constants, the material can get this and just set the constants it knows about
|
||||||
|
virtual const Vector<GFXShaderConstDesc>& getShaderConstDesc() const;
|
||||||
|
|
||||||
|
/// Returns the alignment value for constType
|
||||||
|
virtual U32 getAlignmentValue(const GFXShaderConstType constType) const;
|
||||||
|
|
||||||
|
virtual GFXShaderConstBufferRef allocConstBuffer();
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// @name GFXResource interface
|
||||||
|
/// @{
|
||||||
|
virtual void zombify();
|
||||||
|
virtual void resurrect() { reload(); }
|
||||||
|
virtual const String describeSelf() const;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// Activates this shader in the GL context.
|
||||||
|
void useProgram();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool _init();
|
||||||
|
|
||||||
|
bool initShader(const Torque::Path& file,
|
||||||
|
GFXShaderStage stage,
|
||||||
|
const Vector<GFXShaderMacro>& macros);
|
||||||
|
|
||||||
|
void clearShaders();
|
||||||
|
|
||||||
|
void initConstantDescs();
|
||||||
|
void initHandles();
|
||||||
|
void setConstantsFromBuffer(U8* buffer);
|
||||||
|
|
||||||
|
static char* _handleIncludes(const Torque::Path& path, FileStream* s);
|
||||||
|
|
||||||
|
static bool _loadShaderFromStream(GLuint shader,
|
||||||
|
const Torque::Path& path,
|
||||||
|
FileStream* s,
|
||||||
|
const Vector<GFXShaderMacro>& macros);
|
||||||
|
|
||||||
|
/// @name Internal GL handles
|
||||||
|
/// @{
|
||||||
|
GLuint mVertexShader;
|
||||||
|
GLuint mPixelShader;
|
||||||
|
GLuint mGeometryShader;
|
||||||
|
GLuint mProgram;
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
U8* mGlobalConstBuffer;
|
||||||
|
|
||||||
|
Vector<GFXShaderConstDesc> mShaderConsts;
|
||||||
|
|
||||||
|
HandleMap mHandles;
|
||||||
|
BufferMap mBuffers;
|
||||||
|
|
||||||
|
GFXGLDevice* mDevice;
|
||||||
|
|
||||||
|
GFXShaderConstType convertConstType(GLenum constType);
|
||||||
|
};
|
||||||
|
|
||||||
#endif // _GFXGLSHADER_H_
|
#endif // _GFXGLSHADER_H_
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue