178 lines
7 KiB
C++
178 lines
7 KiB
C++
/**
|
|
* \file gpu_program_params.h
|
|
* \brief CGPUProgramParams
|
|
* \date 2013-09-07 22:17GMT
|
|
* \author Jan Boon (Kaetemi)
|
|
* CGPUProgramParams
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2013 by authors
|
|
*
|
|
* This file is part of NL3D.
|
|
* NL3D is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU Affero General Public License as
|
|
* published by the Free Software Foundation, either version 3 of the
|
|
* License, or (at your option) any later version.
|
|
*
|
|
* NL3D is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public
|
|
* License along with NL3D. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef NL3D_GPU_PROGRAM_PARAMS_H
|
|
#define NL3D_GPU_PROGRAM_PARAMS_H
|
|
#include <nel/misc/types_nl.h>
|
|
|
|
// STL includes
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
// NeL includes
|
|
|
|
// Project includes
|
|
|
|
namespace NLMISC {
|
|
class CVector;
|
|
class CMatrix;
|
|
}
|
|
|
|
namespace NL3D {
|
|
|
|
/**
|
|
* \brief CGPUProgramParams
|
|
* \date 2013-09-07 22:17GMT
|
|
* \author Jan Boon (Kaetemi)
|
|
* A storage for USERCODE-PROVIDED parameters for GPU programs.
|
|
* Allows for fast updating and iteration of parameters.
|
|
* NOTE TO DRIVER IMPLEMENTORS: DO NOT USE FOR STORING COPIES
|
|
* OF HARDCODED DRIVER MATERIAL PARAMETERS OR DRIVER PARAMETERS!!!
|
|
* The 4-component alignment that is done in this storage
|
|
* class is necessary to simplify support for register-based
|
|
* assembly shaders, which require setting per 4 components.
|
|
*/
|
|
class CGPUProgramParams
|
|
{
|
|
public:
|
|
enum TType { Float, Int, UInt };
|
|
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:
|
|
union CVec { float F[4]; sint32 I[4]; uint32 UI[4]; };
|
|
|
|
public:
|
|
CGPUProgramParams();
|
|
virtual ~CGPUProgramParams();
|
|
|
|
/// \name User functions
|
|
// @{
|
|
// Copy from another params storage
|
|
void copy(CGPUProgramParams *params);
|
|
|
|
// Set by index, available only when the associated program has been compiled
|
|
void set1f(uint index, float f0);
|
|
void set2f(uint index, float f0, float f1);
|
|
void set3f(uint index, float f0, float f1, float f2);
|
|
void set4f(uint index, float f0, float f1, float f2, float f3);
|
|
void set1i(uint index, sint32 i0);
|
|
void set2i(uint index, sint32 i0, sint32 i1);
|
|
void set3i(uint index, sint32 i0, sint32 i1, sint32 i2);
|
|
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 set4f(uint index, const NLMISC::CVector& v, float f3);
|
|
void set4x4f(uint index, const NLMISC::CMatrix& m);
|
|
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);
|
|
|
|
// Set by name, it is recommended to use index when repeatedly setting an element
|
|
void set1f(const std::string &name, float f0);
|
|
void set2f(const std::string &name, float f0, float f1);
|
|
void set3f(const std::string &name, float f0, float f1, float f2);
|
|
void set4f(const std::string &name, float f0, float f1, float f2, float f3);
|
|
void set1i(const std::string &name, sint32 i0);
|
|
void set2i(const std::string &name, sint32 i0, sint32 i1);
|
|
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 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 set4f(const std::string &name, const NLMISC::CVector& v, float f3);
|
|
void set4x4f(const std::string &name, const NLMISC::CMatrix& m);
|
|
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);
|
|
// @}
|
|
|
|
// 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);
|
|
|
|
/// \name Internal
|
|
// @{
|
|
/// Allocate specified number of components if necessary (internal use only)
|
|
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(uint size, uint count, TType type);
|
|
/// Return offset for specified index
|
|
size_t getOffset(uint index) const;
|
|
size_t getOffset(const std::string &name) const;
|
|
/// Remove by offset
|
|
void freeOffset(size_t offset);
|
|
// @}
|
|
|
|
/// \name Driver and dev tools
|
|
// @{
|
|
// Iteration (returns the offsets for access using getFooByOffset)
|
|
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 getEnd() const { return s_End; }
|
|
|
|
// Data access
|
|
inline uint getSizeByOffset(size_t offset) const { return m_Meta[offset].Size; } // size of element (4 for float4)
|
|
inline uint getCountByOffset(size_t offset) const { return m_Meta[offset].Count; } // number of elements (usually 1)
|
|
inline uint getNbComponentsByOffset(size_t offset) const { return m_Meta[offset].Size * m_Meta[offset].Count; } // nb of components (size * count)
|
|
inline float *getPtrFByOffset(size_t offset) { return m_Vec[offset].F; }
|
|
inline sint32 *getPtrIByOffset(size_t offset) { return m_Vec[offset].I; }
|
|
inline uint32 *getPtrUIByOffset(size_t offset) { return m_Vec[offset].UI; }
|
|
inline TType getTypeByOffset(size_t offset) const { return m_Meta[offset].Type; }
|
|
inline uint getIndexByOffset(size_t offset) const { return m_Meta[offset].Index; }
|
|
const std::string &getNameByOffset(size_t offset) const { return m_Meta[offset].Name; };
|
|
// @}
|
|
|
|
// Utility
|
|
static inline uint getNbRegistersByComponents(uint nbComponents) { return (nbComponents + 3) >> 2; } // vector register per 4 components
|
|
|
|
private:
|
|
std::vector<CVec> m_Vec;
|
|
std::vector<CMeta> m_Meta;
|
|
std::vector<size_t> m_Map; // map from index to offset
|
|
std::map<std::string, size_t> m_MapName; // map from name to offset
|
|
size_t m_First;
|
|
size_t m_Last;
|
|
static const size_t s_End = -1;
|
|
|
|
}; /* class CGPUProgramParams */
|
|
|
|
} /* namespace NL3D */
|
|
|
|
#endif /* #ifndef NL3D_GPU_PROGRAM_PARAMS_H */
|
|
|
|
/* end of file */
|