Expand parameter interface

This commit is contained in:
kaetemi 2013-09-09 12:18:20 +02:00
parent 0cf5dbab8a
commit ea25e5375d
3 changed files with 359 additions and 19 deletions

View file

@ -1132,7 +1132,7 @@ public:
/** Return true if the driver supports the specified pixel program profile. /** Return true if the driver supports the specified pixel program profile.
*/ */
virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::nelvp) const = 0; virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0;
/** Compile the given pixel program, return if successful. Error information is returned as a string. /** Compile the given pixel program, return if successful. Error information is returned as a string.
*/ */
@ -1162,10 +1162,16 @@ public:
virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) = 0; virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) = 0;
virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) = 0; virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) = 0;
virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0; virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) = 0;
virtual void setUniform1ui(TProgram program, uint index, uint32 ui0) = 0;
virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) = 0;
virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) = 0;
virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) = 0;
virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0;
virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0;
virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0;
virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0;
virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) = 0;
virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) = 0;
// Set builtin parameters // Set builtin parameters
virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0; virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) = 0;
virtual void setUniformFog(TProgram program, uint index) = 0; virtual void setUniformFog(TProgram program, uint index) = 0;

View file

@ -60,7 +60,7 @@ class CGPUProgramParams
{ {
public: public:
enum TType { Float, Int, UInt }; enum TType { Float, Int, UInt };
struct CMeta { uint Index, Size, Count; TType Type; size_t Next, Prev; }; // size is element size, count is nb of elements struct CMeta { uint Index, Size, Count; TType Type; std::string Name; size_t Next, Prev; }; // size is element size, count is nb of elements
private: private:
union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; }; union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; };
@ -69,6 +69,8 @@ public:
CGPUProgramParams(); CGPUProgramParams();
virtual ~CGPUProgramParams(); virtual ~CGPUProgramParams();
/// \name User functions
// @{
// Copy from another params storage // Copy from another params storage
void copy(CGPUProgramParams *params); void copy(CGPUProgramParams *params);
@ -81,10 +83,16 @@ public:
void set2i(uint index, sint32 i0, sint32 i1); void set2i(uint index, sint32 i0, sint32 i1);
void set3i(uint index, sint32 i0, sint32 i1, sint32 i2); void set3i(uint index, sint32 i0, sint32 i1, sint32 i2);
void set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3); void set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
void set1ui(uint index, uint32 ui0);
void set2ui(uint index, uint32 ui0, uint32 ui1);
void set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2);
void set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
void set3f(uint index, const NLMISC::CVector& v); void set3f(uint index, const NLMISC::CVector& v);
void set4f(uint index, const NLMISC::CVector& v, float f3); void set4f(uint index, const NLMISC::CVector& v, float f3);
void set4x4f(uint index, const NLMISC::CMatrix& m); void set4x4f(uint index, const NLMISC::CMatrix& m);
void set4fv(uint index, size_t num, const float *src); void set4fv(uint index, size_t num, const float *src);
void set4iv(uint index, size_t num, const sint32 *src);
void set4uiv(uint index, size_t num, const uint32 *src);
void unset(uint index); void unset(uint index);
// Set by name, it is recommended to use index when repeatedly setting an element // Set by name, it is recommended to use index when repeatedly setting an element
@ -96,25 +104,42 @@ public:
void set2i(const std::string &name, sint32 i0, sint32 i1); void set2i(const std::string &name, sint32 i0, sint32 i1);
void set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2); void set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2);
void set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3); void set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
void set1ui(const std::string &name, uint32 ui0);
void set2ui(const std::string &name, uint32 ui0, uint32 ui1);
void set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2);
void set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3);
void set3f(const std::string &name, const NLMISC::CVector& v); void set3f(const std::string &name, const NLMISC::CVector& v);
void set4f(const std::string &name, const NLMISC::CVector& v, float f3); void set4f(const std::string &name, const NLMISC::CVector& v, float f3);
void set4x4f(const std::string &name, const NLMISC::CMatrix& m); void set4x4f(const std::string &name, const NLMISC::CMatrix& m);
void set4fv(const std::string &name, size_t num, const float *src); void set4fv(const std::string &name, size_t num, const float *src);
void set4iv(const std::string &name, size_t num, const sint32 *src);
void set4uiv(const std::string &name, size_t num, const uint32 *src);
void unset(const std::string &name); void unset(const std::string &name);
// @}
/// Maps the given name to the given index, on duplicate entry the data set by name will be prefered as it can be assumed to have been set after the data set by index // Maps the given name to the given index.
// on duplicate entry the data set by name will be prefered, as it can be
// assumed to have been set after the data set by index, and the mapping
// will usually happen while iterating and finding an element with name
// but no known index.
// Unknown index will be set to ~0, unknown name will have an empty string.
void map(uint index, const std::string &name); void map(uint index, const std::string &name);
// Internal /// \name Internal
/// Allocate specified number of components if necessary // @{
/// Allocate specified number of components if necessary (internal use only)
size_t allocOffset(uint index, uint size, uint count, TType type); size_t allocOffset(uint index, uint size, uint count, TType type);
size_t allocOffset(const std::string &name, uint size, uint count, TType type); size_t allocOffset(const std::string &name, uint size, uint count, TType type);
size_t allocOffset(uint size, uint count, TType type);
/// Return offset for specified index /// Return offset for specified index
size_t getOffset(uint index) const; size_t getOffset(uint index) const;
size_t getOffset(const std::string &name) const; size_t getOffset(const std::string &name) const;
/// Remove by offset /// Remove by offset
void freeOffset(size_t offset); void freeOffset(size_t offset);
// @}
/// \name Driver and dev tools
// @{
// Iteration (returns the offsets for access using getFooByOffset) // Iteration (returns the offsets for access using getFooByOffset)
inline size_t getBegin() const { return m_Meta.size() ? m_First : s_End; } inline size_t getBegin() const { return m_Meta.size() ? m_First : s_End; }
inline size_t getNext(size_t offset) const { return m_Meta[offset].Next; } inline size_t getNext(size_t offset) const { return m_Meta[offset].Next; }
@ -129,7 +154,8 @@ public:
inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; } inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; }
inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; } inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; }
inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; } inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; }
const std::string *getNameByOffset(size_t offset) const; // non-optimized for dev tools only, may return NULL if name unknown const std::string &getNameByOffset(size_t offset) const { return m_Meta[offset].Name; };
// @}
// Utility // Utility
static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components

View file

@ -83,36 +83,66 @@ void CGPUProgramParams::set4f(uint index, float f0, float f1, float f2, float f3
f[3] = f3; f[3] = f3;
} }
void CGPUProgramParams::set1i(uint index, int i0) void CGPUProgramParams::set1i(uint index, sint32 i0)
{ {
int *i = getPtrIByOffset(allocOffset(index, 1, 1, Int)); sint32 *i = getPtrIByOffset(allocOffset(index, 1, 1, Int));
i[0] = i0; i[0] = i0;
} }
void CGPUProgramParams::set2i(uint index, int i0, int i1) void CGPUProgramParams::set2i(uint index, sint32 i0, sint32 i1)
{ {
int *i = getPtrIByOffset(allocOffset(index, 2, 1, Int)); sint32 *i = getPtrIByOffset(allocOffset(index, 2, 1, Int));
i[0] = i0; i[0] = i0;
i[1] = i1; i[1] = i1;
} }
void CGPUProgramParams::set3i(uint index, int i0, int i1, int i2) void CGPUProgramParams::set3i(uint index, sint32 i0, sint32 i1, sint32 i2)
{ {
int *i = getPtrIByOffset(allocOffset(index, 3, 1, Int)); sint32 *i = getPtrIByOffset(allocOffset(index, 3, 1, Int));
i[0] = i0; i[0] = i0;
i[1] = i1; i[1] = i1;
i[2] = i2; i[2] = i2;
} }
void CGPUProgramParams::set4i(uint index, int i0, int i1, int i2, int i3) void CGPUProgramParams::set4i(uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
{ {
int *i = getPtrIByOffset(allocOffset(index, 4, 1, Int)); sint32 *i = getPtrIByOffset(allocOffset(index, 4, 1, Int));
i[0] = i0; i[0] = i0;
i[1] = i1; i[1] = i1;
i[2] = i2; i[2] = i2;
i[3] = i3; i[3] = i3;
} }
void CGPUProgramParams::set1ui(uint index, uint32 ui0)
{
uint32 *ui = getPtrUIByOffset(allocOffset(index, 1, 1, UInt));
ui[0] = ui0;
}
void CGPUProgramParams::set2ui(uint index, uint32 ui0, uint32 ui1)
{
uint32 *ui = getPtrUIByOffset(allocOffset(index, 2, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
}
void CGPUProgramParams::set3ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2)
{
uint32 *ui = getPtrUIByOffset(allocOffset(index, 3, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
ui[2] = ui2;
}
void CGPUProgramParams::set4ui(uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
{
uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
ui[2] = ui2;
ui[3] = ui3;
}
void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v) void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v)
{ {
float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float)); float *f = getPtrFByOffset(allocOffset(index, 3, 1, Float));
@ -121,6 +151,15 @@ void CGPUProgramParams::set3f(uint index, const NLMISC::CVector& v)
f[2] = v.z; f[2] = v.z;
} }
void CGPUProgramParams::set4f(uint index, const NLMISC::CVector& v, float f3)
{
float *f = getPtrFByOffset(allocOffset(index, 4, 1, Float));
f[0] = v.x;
f[1] = v.y;
f[2] = v.z;
f[3] = f3;
}
void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m) void CGPUProgramParams::set4x4f(uint index, const NLMISC::CMatrix& m)
{ {
// TODO: Verify this! // TODO: Verify this!
@ -138,6 +177,210 @@ void CGPUProgramParams::set4fv(uint index, size_t num, const float *src)
f[c] = src[c]; f[c] = src[c];
} }
void CGPUProgramParams::set4iv(uint index, size_t num, const sint32 *src)
{
sint32 *i = getPtrIByOffset(allocOffset(index, 4, num, Int));
size_t nb = 4 * num;
for (uint c = 0; c < nb; ++c)
i[c] = src[c];
}
void CGPUProgramParams::set4uiv(uint index, size_t num, const uint32 *src)
{
uint32 *ui = getPtrUIByOffset(allocOffset(index, 4, num, UInt));
size_t nb = 4 * num;
for (uint c = 0; c < nb; ++c)
ui[c] = src[c];
}
void CGPUProgramParams::unset(uint index)
{
size_t offset = getOffset(index);
if (offset != getEnd())
{
freeOffset(offset);
}
}
void CGPUProgramParams::set1f(const std::string &name, float f0)
{
float *f = getPtrFByOffset(allocOffset(name, 1, 1, Float));
f[0] = f0;
}
void CGPUProgramParams::set2f(const std::string &name, float f0, float f1)
{
float *f = getPtrFByOffset(allocOffset(name, 2, 1, Float));
f[0] = f0;
f[1] = f1;
}
void CGPUProgramParams::set3f(const std::string &name, float f0, float f1, float f2)
{
float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float));
f[0] = f0;
f[1] = f1;
f[2] = f2;
}
void CGPUProgramParams::set4f(const std::string &name, float f0, float f1, float f2, float f3)
{
float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float));
f[0] = f0;
f[1] = f1;
f[2] = f2;
f[3] = f3;
}
void CGPUProgramParams::set1i(const std::string &name, sint32 i0)
{
sint32 *i = getPtrIByOffset(allocOffset(name, 1, 1, Int));
i[0] = i0;
}
void CGPUProgramParams::set2i(const std::string &name, sint32 i0, sint32 i1)
{
sint32 *i = getPtrIByOffset(allocOffset(name, 2, 1, Int));
i[0] = i0;
i[1] = i1;
}
void CGPUProgramParams::set3i(const std::string &name, sint32 i0, sint32 i1, sint32 i2)
{
sint32 *i = getPtrIByOffset(allocOffset(name, 3, 1, Int));
i[0] = i0;
i[1] = i1;
i[2] = i2;
}
void CGPUProgramParams::set4i(const std::string &name, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
{
sint32 *i = getPtrIByOffset(allocOffset(name, 4, 1, Int));
i[0] = i0;
i[1] = i1;
i[2] = i2;
i[3] = i3;
}
void CGPUProgramParams::set1ui(const std::string &name, uint32 ui0)
{
uint32 *ui = getPtrUIByOffset(allocOffset(name, 1, 1, UInt));
ui[0] = ui0;
}
void CGPUProgramParams::set2ui(const std::string &name, uint32 ui0, uint32 ui1)
{
uint32 *ui = getPtrUIByOffset(allocOffset(name, 2, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
}
void CGPUProgramParams::set3ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2)
{
uint32 *ui = getPtrUIByOffset(allocOffset(name, 3, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
ui[2] = ui2;
}
void CGPUProgramParams::set4ui(const std::string &name, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
{
uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, 1, UInt));
ui[0] = ui0;
ui[1] = ui1;
ui[2] = ui2;
ui[3] = ui3;
}
void CGPUProgramParams::set3f(const std::string &name, const NLMISC::CVector& v)
{
float *f = getPtrFByOffset(allocOffset(name, 3, 1, Float));
f[0] = v.x;
f[1] = v.y;
f[2] = v.z;
}
void CGPUProgramParams::set4f(const std::string &name, const NLMISC::CVector& v, float f3)
{
float *f = getPtrFByOffset(allocOffset(name, 4, 1, Float));
f[0] = v.x;
f[1] = v.y;
f[2] = v.z;
f[3] = f3;
}
void CGPUProgramParams::set4x4f(const std::string &name, const NLMISC::CMatrix& m)
{
// TODO: Verify this!
float *f = getPtrFByOffset(allocOffset(name, 4, 4, Float));
NLMISC::CMatrix mt = m;
mt.transpose();
mt.get(f);
}
void CGPUProgramParams::set4fv(const std::string &name, size_t num, const float *src)
{
float *f = getPtrFByOffset(allocOffset(name, 4, num, Float));
size_t nb = 4 * num;
for (uint c = 0; c < nb; ++c)
f[c] = src[c];
}
void CGPUProgramParams::set4iv(const std::string &name, size_t num, const sint32 *src)
{
sint32 *i = getPtrIByOffset(allocOffset(name, 4, num, Int));
size_t nb = 4 * num;
for (uint c = 0; c < nb; ++c)
i[c] = src[c];
}
void CGPUProgramParams::set4uiv(const std::string &name, size_t num, const uint32 *src)
{
uint32 *ui = getPtrUIByOffset(allocOffset(name, 4, num, UInt));
size_t nb = 4 * num;
for (uint c = 0; c < nb; ++c)
ui[c] = src[c];
}
void CGPUProgramParams::unset(const std::string &name)
{
size_t offset = getOffset(name);
if (offset != getEnd())
{
freeOffset(offset);
}
}
void CGPUProgramParams::map(uint index, const std::string &name)
{
size_t offsetIndex = getOffset(index);
size_t offsetName = getOffset(name);
if (offsetName != getEnd())
{
// Remove possible duplicate
if (offsetIndex != getEnd())
{
freeOffset(offsetIndex);
}
// Set index
m_Meta[offsetName].Index = index;
// Map index to name
if (index >= m_Map.size())
m_Map.resize(index + 1, s_End);
m_Map[index] = offsetName;
}
else if (offsetIndex != getEnd())
{
// Set name
m_Meta[offsetIndex].Name = name;
// Map name to index
m_MapName[name] = offsetIndex;
}
}
/// Allocate specified number of components if necessary /// Allocate specified number of components if necessary
size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type) size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType type)
{ {
@ -163,18 +406,67 @@ size_t CGPUProgramParams::allocOffset(uint index, uint size, uint count, TType t
} }
// Allocate space // Allocate space
offset = m_Meta.size(); offset = allocOffset(size, count, type);
uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components
m_Meta.resize(offset + blocks); // Fill
m_Vec.resize(offset + blocks); m_Meta[offset].Index = index;
// Store offset in map // Store offset in map
if (index >= m_Map.size()) if (index >= m_Map.size())
m_Map.resize(index + 1, s_End); m_Map.resize(index + 1, s_End);
m_Map[index] = offset; m_Map[index] = offset;
return offset;
}
/// Allocate specified number of components if necessary
size_t CGPUProgramParams::allocOffset(const std::string &name, uint size, uint count, TType type)
{
nlassert(count > 0); // this code will not properly handle 0
nlassert(size > 0); // this code will not properly handle 0
nlassert(!name.empty()); // sanity check
uint nbComponents = size * count;
size_t offset = getOffset(name);
if (offset != s_End)
{
if (getCountByOffset(offset) >= nbComponents)
{
m_Meta[offset].Type = type;
m_Meta[offset].Size = size;
m_Meta[offset].Count = count;
return offset;
}
if (getCountByOffset(offset) < nbComponents)
{
freeOffset(offset);
}
}
// Allocate space
offset = allocOffset(size, count, type);
// Fill
m_Meta[offset].Name = name;
// Store offset in map
m_MapName[name] = offset;
return offset;
}
/// Allocate specified number of components if necessary
size_t CGPUProgramParams::allocOffset(uint size, uint count, TType type)
{
uint nbComponents = size * count;
// Allocate space
size_t offset = m_Meta.size();
uint blocks = getNbRegistersByComponents(nbComponents); // per 4 components
m_Meta.resize(offset + blocks);
m_Vec.resize(offset + blocks);
// Fill // Fill
m_Meta[offset].Index = index;
m_Meta[offset].Size = size; m_Meta[offset].Size = size;
m_Meta[offset].Count = count; m_Meta[offset].Count = count;
m_Meta[offset].Type = type; m_Meta[offset].Type = type;
@ -207,6 +499,22 @@ size_t CGPUProgramParams::getOffset(uint index) const
/// Remove by offset /// Remove by offset
void CGPUProgramParams::freeOffset(size_t offset) void CGPUProgramParams::freeOffset(size_t offset)
{ {
uint index = getIndexByOffset(offset);
if (index != ~0)
{
if (m_Map.size() > index)
{
m_Map[index] = getEnd();
}
}
const std::string &name = getNameByOffset(offset);
if (!name.empty())
{
if (m_MapName.find(name) != m_MapName.end())
{
m_MapName.erase(name);
}
}
if (offset == m_Last) if (offset == m_Last)
{ {
nlassert(m_Meta[offset].Next == s_End); nlassert(m_Meta[offset].Next == s_End);