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:
marauder2k7 2024-03-13 22:23:01 +00:00
parent fbed04050a
commit 9dc5ae833b
7 changed files with 941 additions and 605 deletions

View file

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

View file

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

View file

@ -81,12 +81,12 @@ 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.
}; };
/// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants. /// This is an opaque handle used by GFXShaderConstBuffer clients to set individual shader constants.

View file

@ -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()
@ -959,8 +960,19 @@ void GFXGLDevice::setShader(GFXShader *shader, bool force)
void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer) void GFXGLDevice::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
{ {
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal); if (buffer)
static_cast<GFXGLShaderConstBuffer*>(buffer)->activate(); {
PROFILE_SCOPE(GFXGLDevice_setShaderConstBufferInternal);
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

View file

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

File diff suppressed because it is too large Load diff

View file

@ -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> &macros );
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_