mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 09:04:38 +00:00
commit before pr
This commit is contained in:
parent
25bc9cf354
commit
e24971517e
3 changed files with 1 additions and 663 deletions
|
|
@ -273,6 +273,7 @@ void GFXD3D11ShaderConstBuffer::internalSet(GFXShaderConstHandle* handle, const
|
||||||
case GFXSCT_Float2:
|
case GFXSCT_Float2:
|
||||||
if (size > sizeof(Point2F))
|
if (size > sizeof(Point2F))
|
||||||
size = _dxHandle->mDesc.size;
|
size = _dxHandle->mDesc.size;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,289 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2012 GarageGames, LLC
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "platform/platform.h"
|
|
||||||
#include "gfx/genericConstBuffer.h"
|
|
||||||
|
|
||||||
#include "platform/profiler.h"
|
|
||||||
#include "core/stream/stream.h"
|
|
||||||
|
|
||||||
|
|
||||||
GenericConstBufferLayout::GenericConstBufferLayout()
|
|
||||||
{
|
|
||||||
VECTOR_SET_ASSOCIATION( mParams );
|
|
||||||
|
|
||||||
mBufferSize = 0;
|
|
||||||
mCurrentIndex = 0;
|
|
||||||
mTimesCleared = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericConstBufferLayout::addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue)
|
|
||||||
{
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
// Make sure we don't have overlapping parameters
|
|
||||||
S32 start = offset;
|
|
||||||
S32 end = offset + size;
|
|
||||||
for (Params::iterator i = mParams.begin(); i != mParams.end(); i++)
|
|
||||||
{
|
|
||||||
const ParamDesc& dp = *i;
|
|
||||||
S32 pstart = dp.offset;
|
|
||||||
S32 pend = pstart + dp.size;
|
|
||||||
pstart -= start;
|
|
||||||
pend -= end;
|
|
||||||
// This is like a minkowski sum for two line segments, if the newly formed line contains
|
|
||||||
// the origin, then they intersect
|
|
||||||
bool intersect = ((pstart >= 0 && 0 >= pend) || ((pend >= 0 && 0 >= pstart)));
|
|
||||||
AssertFatal(!intersect, "Overlapping shader parameter!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ParamDesc desc;
|
|
||||||
desc.name = name;
|
|
||||||
desc.constType = constType;
|
|
||||||
desc.offset = offset;
|
|
||||||
desc.size = size;
|
|
||||||
desc.arraySize = arraySize;
|
|
||||||
desc.alignValue = alignValue;
|
|
||||||
desc.index = mCurrentIndex++;
|
|
||||||
mParams.push_back(desc);
|
|
||||||
mBufferSize = getMax(desc.offset + desc.size, mBufferSize);
|
|
||||||
AssertFatal(mBufferSize, "Empty constant buffer!");
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericConstBufferLayout::set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE(GenericConstBufferLayout_set);
|
|
||||||
|
|
||||||
// Shader compilers like to optimize float4x4 uniforms into float3x3s.
|
|
||||||
// So long as the real paramater is a matrix of-some-type and the data
|
|
||||||
// passed in is a MatrixF ( which is will be ), we DO NOT have a
|
|
||||||
// mismatched const type.
|
|
||||||
AssertFatal( pd.constType == constType ||
|
|
||||||
(
|
|
||||||
( pd.constType == GFXSCT_Float2x2 ||
|
|
||||||
pd.constType == GFXSCT_Float3x3 ||
|
|
||||||
pd.constType == GFXSCT_Float3x4 ||
|
|
||||||
pd.constType == GFXSCT_Float4x3 ||
|
|
||||||
pd.constType == GFXSCT_Float4x4 ) &&
|
|
||||||
( constType == GFXSCT_Float2x2 ||
|
|
||||||
constType == GFXSCT_Float3x3 ||
|
|
||||||
constType == GFXSCT_Float3x4 ||
|
|
||||||
constType == GFXSCT_Float4x3 ||
|
|
||||||
constType == GFXSCT_Float4x4 )
|
|
||||||
), "Mismatched const type!" );
|
|
||||||
|
|
||||||
// This "cute" bit of code allows us to support 2x3 and 3x3 matrices in shader constants but use our MatrixF class. Yes, a hack. -BTR
|
|
||||||
switch (pd.constType)
|
|
||||||
{
|
|
||||||
case GFXSCT_Float2x2 :
|
|
||||||
case GFXSCT_Float3x3 :
|
|
||||||
case GFXSCT_Float4x3 :
|
|
||||||
case GFXSCT_Float4x4 :
|
|
||||||
return setMatrix(pd, constType, size, data, basePointer);
|
|
||||||
break;
|
|
||||||
default :
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
|
|
||||||
|
|
||||||
// Ok, we only set data if it's different than the data we already have, this maybe more expensive than just setting the data, but
|
|
||||||
// we'll have to do some timings to see. For example, the lighting shader constants rarely change, but we can't assume that at the
|
|
||||||
// renderInstMgr level, but we can check down here. -BTR
|
|
||||||
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
|
|
||||||
{
|
|
||||||
dMemcpy(basePointer+pd.offset, data, size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer)
|
|
||||||
{
|
|
||||||
PROFILE_SCOPE(GenericConstBufferLayout_setMatrix);
|
|
||||||
|
|
||||||
// We're generic, so just copy the full MatrixF in
|
|
||||||
AssertFatal(pd.size >= size, "Not enough room in the buffer for this data!");
|
|
||||||
|
|
||||||
// Matrices are an annoying case because of the alignment issues. There are alignment issues in the matrix itself, and then potential inter matrices alignment issues.
|
|
||||||
// So GL and DX will need to derive their own GenericConstBufferLayout classes and override this method to deal with that stuff. For GenericConstBuffer, copy the whole
|
|
||||||
// 4x4 matrix regardless of the target case.
|
|
||||||
|
|
||||||
if (dMemcmp(basePointer+pd.offset, data, size) != 0)
|
|
||||||
{
|
|
||||||
dMemcpy(basePointer+pd.offset, data, size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericConstBufferLayout::getDesc(const String& name, ParamDesc& param) const
|
|
||||||
{
|
|
||||||
for (U32 i = 0; i < mParams.size(); i++)
|
|
||||||
{
|
|
||||||
if (mParams[i].name.equal(name))
|
|
||||||
{
|
|
||||||
param = mParams[i];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericConstBufferLayout::getDesc(const U32 index, ParamDesc& param) const
|
|
||||||
{
|
|
||||||
if ( index < mParams.size() )
|
|
||||||
{
|
|
||||||
param = mParams[index];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenericConstBufferLayout::write(Stream* s)
|
|
||||||
{
|
|
||||||
// Write out the size of the ParamDesc structure as a sanity check.
|
|
||||||
if (!s->write((U32) sizeof(ParamDesc)))
|
|
||||||
return false;
|
|
||||||
// Next, write out the number of elements we've got.
|
|
||||||
if (!s->write(mParams.size()))
|
|
||||||
return false;
|
|
||||||
for (U32 i = 0; i < mParams.size(); i++)
|
|
||||||
{
|
|
||||||
s->write(mParams[i].name);
|
|
||||||
|
|
||||||
if (!s->write(mParams[i].offset))
|
|
||||||
return false;
|
|
||||||
if (!s->write(mParams[i].size))
|
|
||||||
return false;
|
|
||||||
U32 t = (U32) mParams[i].constType;
|
|
||||||
if (!s->write(t))
|
|
||||||
return false;
|
|
||||||
if (!s->write(mParams[i].arraySize))
|
|
||||||
return false;
|
|
||||||
if (!s->write(mParams[i].alignValue))
|
|
||||||
return false;
|
|
||||||
if (!s->write(mParams[i].index))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load this layout from a stream
|
|
||||||
bool GenericConstBufferLayout::read(Stream* s)
|
|
||||||
{
|
|
||||||
U32 structSize;
|
|
||||||
if (!s->read(&structSize))
|
|
||||||
return false;
|
|
||||||
if (structSize != sizeof(ParamDesc))
|
|
||||||
{
|
|
||||||
AssertFatal(false, "Invalid shader layout structure size!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
U32 numParams;
|
|
||||||
if (!s->read(&numParams))
|
|
||||||
return false;
|
|
||||||
mParams.setSize(numParams);
|
|
||||||
mBufferSize = 0;
|
|
||||||
mCurrentIndex = 0;
|
|
||||||
for (U32 i = 0; i < mParams.size(); i++)
|
|
||||||
{
|
|
||||||
s->read(&mParams[i].name);
|
|
||||||
if (!s->read(&mParams[i].offset))
|
|
||||||
return false;
|
|
||||||
if (!s->read(&mParams[i].size))
|
|
||||||
return false;
|
|
||||||
U32 t;
|
|
||||||
if (!s->read(&t))
|
|
||||||
return false;
|
|
||||||
mParams[i].constType = (GFXShaderConstType) t;
|
|
||||||
if (!s->read(&mParams[i].arraySize))
|
|
||||||
return false;
|
|
||||||
if (!s->read(&mParams[i].alignValue))
|
|
||||||
return false;
|
|
||||||
if (!s->read(&mParams[i].index))
|
|
||||||
return false;
|
|
||||||
mBufferSize = getMax(mParams[i].offset + mParams[i].size, mBufferSize);
|
|
||||||
mCurrentIndex = getMax(mParams[i].index, mCurrentIndex);
|
|
||||||
}
|
|
||||||
mCurrentIndex++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericConstBufferLayout::clear()
|
|
||||||
{
|
|
||||||
mParams.clear();
|
|
||||||
mBufferSize = 0;
|
|
||||||
mCurrentIndex = 0;
|
|
||||||
mTimesCleared++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GenericConstBuffer::GenericConstBuffer(GenericConstBufferLayout* layout)
|
|
||||||
: mLayout( layout ),
|
|
||||||
mBuffer( NULL ),
|
|
||||||
mDirtyStart( U32_MAX ),
|
|
||||||
mDirtyEnd( 0 )
|
|
||||||
{
|
|
||||||
if ( layout && layout->getBufferSize() > 0 )
|
|
||||||
{
|
|
||||||
mBuffer = new U8[mLayout->getBufferSize()];
|
|
||||||
|
|
||||||
// Always set a default value, that way our isEqual checks
|
|
||||||
// will work in release as well.
|
|
||||||
dMemset( mBuffer, 0xFFFF, mLayout->getBufferSize() );
|
|
||||||
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
|
|
||||||
// Clear the debug assignment tracking.
|
|
||||||
mWasAssigned.setSize( layout->getParameterCount() );
|
|
||||||
dMemset( mWasAssigned.address(), 0, mWasAssigned.memSize() );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GenericConstBuffer::~GenericConstBuffer()
|
|
||||||
{
|
|
||||||
delete [] mBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
|
|
||||||
void GenericConstBuffer::assertUnassignedConstants( const char *shaderName )
|
|
||||||
{
|
|
||||||
for ( U32 i=0; i < mWasAssigned.size(); i++ )
|
|
||||||
{
|
|
||||||
if ( mWasAssigned[i] )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
GenericConstBufferLayout::ParamDesc pd;
|
|
||||||
mLayout->getDesc( i, pd );
|
|
||||||
|
|
||||||
// Assert on the unassigned constant.
|
|
||||||
//AssertFatal( false, avar( "The '%s' shader constant in shader '%s' was unassigned!",
|
|
||||||
// pd.name.c_str(), shaderName ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,374 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (c) 2012 GarageGames, LLC
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
// of this software and associated documentation files (the "Software"), to
|
|
||||||
// deal in the Software without restriction, including without limitation the
|
|
||||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
||||||
// sell copies of the Software, and to permit persons to whom the Software is
|
|
||||||
// furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included in
|
|
||||||
// all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
||||||
// IN THE SOFTWARE.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#ifndef _GENERICCONSTBUFFER_H_
|
|
||||||
#define _GENERICCONSTBUFFER_H_
|
|
||||||
|
|
||||||
#ifndef _TORQUE_STRING_H_
|
|
||||||
#include "core/util/str.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _TDICTIONARY_H_
|
|
||||||
#include "core/util/tDictionary.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _TVECTOR_H_
|
|
||||||
#include "core/util/tVector.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _ALIGNEDARRAY_H_
|
|
||||||
#include "core/util/tAlignedArray.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _COLOR_H_
|
|
||||||
#include "core/color.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _MMATRIX_H_
|
|
||||||
#include "math/mMatrix.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _MPOINT2_H_
|
|
||||||
#include "math/mPoint2.h"
|
|
||||||
#endif
|
|
||||||
#ifndef _GFXENUMS_H_
|
|
||||||
#include "gfx/gfxEnums.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Stream;
|
|
||||||
|
|
||||||
|
|
||||||
/// This class defines the memory layout for a GenericConstBuffer.
|
|
||||||
class GenericConstBufferLayout
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// Describes the parameters we contain
|
|
||||||
struct ParamDesc
|
|
||||||
{
|
|
||||||
ParamDesc()
|
|
||||||
: name(),
|
|
||||||
offset( 0 ),
|
|
||||||
size( 0 ),
|
|
||||||
constType( GFXSCT_Float ),
|
|
||||||
arraySize( 0 ),
|
|
||||||
alignValue( 0 ),
|
|
||||||
index( 0 )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
name = String::EmptyString;
|
|
||||||
offset = 0;
|
|
||||||
size = 0;
|
|
||||||
constType = GFXSCT_Float;
|
|
||||||
arraySize = 0;
|
|
||||||
alignValue = 0;
|
|
||||||
index = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Parameter name
|
|
||||||
String name;
|
|
||||||
|
|
||||||
/// Offset into the memory block
|
|
||||||
U32 offset;
|
|
||||||
|
|
||||||
/// Size of the block
|
|
||||||
U32 size;
|
|
||||||
|
|
||||||
/// Type of data
|
|
||||||
GFXShaderConstType constType;
|
|
||||||
|
|
||||||
// For arrays, how many elements
|
|
||||||
U32 arraySize;
|
|
||||||
|
|
||||||
// Array element alignment value
|
|
||||||
U32 alignValue;
|
|
||||||
|
|
||||||
/// 0 based index of this param, in order of addParameter calls.
|
|
||||||
U32 index;
|
|
||||||
};
|
|
||||||
|
|
||||||
GenericConstBufferLayout();
|
|
||||||
virtual ~GenericConstBufferLayout() {}
|
|
||||||
|
|
||||||
/// Add a parameter to the buffer
|
|
||||||
virtual void addParameter(const String& name, const GFXShaderConstType constType, const U32 offset, const U32 size, const U32 arraySize, const U32 alignValue);
|
|
||||||
|
|
||||||
/// Get the size of the buffer
|
|
||||||
inline U32 getBufferSize() const { return mBufferSize; }
|
|
||||||
|
|
||||||
/// Get the number of parameters
|
|
||||||
inline U32 getParameterCount() const { return mParams.size(); }
|
|
||||||
|
|
||||||
/// Returns the ParamDesc of a parameter
|
|
||||||
bool getDesc(const String& name, ParamDesc& param) const;
|
|
||||||
|
|
||||||
/// Returns the ParamDesc of a parameter
|
|
||||||
bool getDesc(const U32 index, ParamDesc& param) const;
|
|
||||||
|
|
||||||
/// Set a parameter, given a base pointer
|
|
||||||
virtual bool set(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
|
|
||||||
|
|
||||||
/// Save this layout to a stream
|
|
||||||
bool write(Stream* s);
|
|
||||||
|
|
||||||
/// Load this layout from a stream
|
|
||||||
bool read(Stream* s);
|
|
||||||
|
|
||||||
/// Restore to initial state.
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/// Set a matrix, given a base pointer.
|
|
||||||
virtual bool setMatrix(const ParamDesc& pd, const GFXShaderConstType constType, const U32 size, const void* data, U8* basePointer);
|
|
||||||
|
|
||||||
/// Vector of parameter descriptions.
|
|
||||||
typedef Vector<ParamDesc> Params;
|
|
||||||
|
|
||||||
/// Vector of parameter descriptions.
|
|
||||||
Params mParams;
|
|
||||||
U32 mBufferSize;
|
|
||||||
U32 mCurrentIndex;
|
|
||||||
|
|
||||||
// This if for debugging shader reloading and can be removed later.
|
|
||||||
U32 mTimesCleared;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// This class manages shader constant data in a system memory buffer. It is
|
|
||||||
/// used by device specific classes for batching together many constant changes
|
|
||||||
/// which are then copied to the device thru a single API call.
|
|
||||||
///
|
|
||||||
/// @see GenericConstBufferLayout
|
|
||||||
///
|
|
||||||
class GenericConstBuffer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GenericConstBuffer(GenericConstBufferLayout* layout);
|
|
||||||
~GenericConstBuffer();
|
|
||||||
|
|
||||||
/// @name Set shader constant values
|
|
||||||
/// @{
|
|
||||||
/// Actually set shader constant values
|
|
||||||
/// @param name Name of the constant, this should be a name contained in the array returned in getShaderConstDesc,
|
|
||||||
/// if an invalid name is used, its ignored, but it's not an error.
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const F32 f) { internalSet(pd, GFXSCT_Float, sizeof(F32), &f); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2F& fv) { internalSet(pd, GFXSCT_Float2, sizeof(Point2F), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3F& fv) { internalSet(pd, GFXSCT_Float3, sizeof(Point3F), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4F& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const PlaneF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(PlaneF), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const LinearColorF& fv) { internalSet(pd, GFXSCT_Float4, sizeof(Point4F), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const S32 f) { internalSet(pd, GFXSCT_Int, sizeof(S32), &f); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point2I& fv) { internalSet(pd, GFXSCT_Int2, sizeof(Point2I), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point3I& fv) { internalSet(pd, GFXSCT_Int3, sizeof(Point3I), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const Point4I& fv) { internalSet(pd, GFXSCT_Int4, sizeof(Point4I), &fv); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<F32>& fv) { internalSet(pd, GFXSCT_Float, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2F>& fv) { internalSet(pd, GFXSCT_Float2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3F>& fv) { internalSet(pd, GFXSCT_Float3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4F>& fv) { internalSet(pd, GFXSCT_Float4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<S32>& fv) { internalSet(pd, GFXSCT_Int, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point2I>& fv) { internalSet(pd, GFXSCT_Int2, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point3I>& fv) { internalSet(pd, GFXSCT_Int3, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
inline void set(const GenericConstBufferLayout::ParamDesc& pd, const AlignedArray<Point4I>& fv) { internalSet(pd, GFXSCT_Int4, fv.getElementSize() * fv.size(), fv.getBuffer()); }
|
|
||||||
|
|
||||||
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF& mat, const GFXShaderConstType matrixType )
|
|
||||||
{
|
|
||||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
|
||||||
matrixType == GFXSCT_Float3x3 ||
|
|
||||||
matrixType == GFXSCT_Float3x4 ||
|
|
||||||
matrixType == GFXSCT_Float4x3 ||
|
|
||||||
matrixType == GFXSCT_Float4x4,
|
|
||||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
|
||||||
|
|
||||||
internalSet( pd, matrixType, sizeof(MatrixF), &mat );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set( const GenericConstBufferLayout::ParamDesc& pd, const MatrixF* mat, const U32 arraySize, const GFXShaderConstType matrixType )
|
|
||||||
{
|
|
||||||
AssertFatal( matrixType == GFXSCT_Float2x2 ||
|
|
||||||
matrixType == GFXSCT_Float3x3 ||
|
|
||||||
matrixType == GFXSCT_Float3x4 ||
|
|
||||||
matrixType == GFXSCT_Float4x3 ||
|
|
||||||
matrixType == GFXSCT_Float4x4,
|
|
||||||
"GenericConstBuffer::set() - Invalid matrix type!" );
|
|
||||||
|
|
||||||
internalSet( pd, matrixType, sizeof(MatrixF)*arraySize, mat );
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the dirty buffer range and clears the dirty
|
|
||||||
/// state at the same time.
|
|
||||||
inline const U8* getDirtyBuffer( U32 *start, U32 *size );
|
|
||||||
|
|
||||||
/// Gets the entire buffer ignoring dirty range
|
|
||||||
inline const U8* getEntireBuffer();
|
|
||||||
|
|
||||||
/// Sets the entire buffer as dirty or clears the dirty state.
|
|
||||||
inline void setDirty( bool dirty );
|
|
||||||
|
|
||||||
/// Returns true if the buffer has been modified since the
|
|
||||||
/// last call to getDirtyBuffer or setDirty. The buffer is
|
|
||||||
/// not dirty on initial creation.
|
|
||||||
///
|
|
||||||
/// @see getDirtyBuffer
|
|
||||||
/// @see setDirty
|
|
||||||
inline bool isDirty() const { return mDirtyEnd != 0; }
|
|
||||||
|
|
||||||
/// Returns true if have the same layout and hold the same
|
|
||||||
/// data as the input buffer.
|
|
||||||
inline bool isEqual( const GenericConstBuffer *buffer ) const;
|
|
||||||
|
|
||||||
/// Returns our layout object.
|
|
||||||
inline GenericConstBufferLayout* getLayout() const { return mLayout; }
|
|
||||||
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
|
|
||||||
/// Helper function used to assert on unset constants.
|
|
||||||
void assertUnassignedConstants( const char *shaderName );
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/// Returns a pointer to the raw buffer
|
|
||||||
inline const U8* getBuffer() const { return mBuffer; }
|
|
||||||
|
|
||||||
/// Called by the inlined set functions above to do the
|
|
||||||
/// real dirty work of copying the data to the right location
|
|
||||||
/// within the buffer.
|
|
||||||
inline void internalSet( const GenericConstBufferLayout::ParamDesc &pd,
|
|
||||||
const GFXShaderConstType constType,
|
|
||||||
const U32 size,
|
|
||||||
const void *data );
|
|
||||||
|
|
||||||
/// The buffer layout.
|
|
||||||
GenericConstBufferLayout *mLayout;
|
|
||||||
|
|
||||||
/// The pointer to the contant store or
|
|
||||||
/// NULL if the layout is empty.
|
|
||||||
U8 *mBuffer;
|
|
||||||
|
|
||||||
/// The byte offset to the start of the dirty
|
|
||||||
/// range within the buffer or U32_MAX if the
|
|
||||||
/// buffer is not dirty.
|
|
||||||
U32 mDirtyStart;
|
|
||||||
|
|
||||||
/// The btye offset to the end of the dirty
|
|
||||||
/// range within the buffer or 0 if the buffer
|
|
||||||
/// is not dirty.
|
|
||||||
U32 mDirtyEnd;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
|
|
||||||
/// A vector used to keep track if a constant
|
|
||||||
/// has beed assigned a value or not.
|
|
||||||
///
|
|
||||||
/// @see assertUnassignedConstants
|
|
||||||
Vector<bool> mWasAssigned;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE: These inlines below are here to get the very best possible
|
|
||||||
// performance when setting the device shader constants and can be
|
|
||||||
// called 4000-8000 times per frame or more.
|
|
||||||
//
|
|
||||||
// You need a very good reason to consider changing them.
|
|
||||||
|
|
||||||
inline void GenericConstBuffer::internalSet( const GenericConstBufferLayout::ParamDesc &pd,
|
|
||||||
const GFXShaderConstType constType,
|
|
||||||
const U32 size,
|
|
||||||
const void *data )
|
|
||||||
{
|
|
||||||
// NOTE: We should have never gotten here if the buffer
|
|
||||||
// was null as no valid shader constant could have been
|
|
||||||
// assigned.
|
|
||||||
//
|
|
||||||
// If this happens its a bug in another part of the code.
|
|
||||||
//
|
|
||||||
AssertFatal( mBuffer, "GenericConstBuffer::internalSet - The buffer is NULL!" );
|
|
||||||
|
|
||||||
if ( mLayout->set( pd, constType, size, data, mBuffer ) )
|
|
||||||
{
|
|
||||||
#ifdef TORQUE_DEBUG
|
|
||||||
|
|
||||||
// Update the debug assignment tracking.
|
|
||||||
mWasAssigned[ pd.index ] = true;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Keep track of the dirty range so it can be queried
|
|
||||||
// later in GenericConstBuffer::getDirtyBuffer.
|
|
||||||
mDirtyStart = getMin( pd.offset, mDirtyStart );
|
|
||||||
mDirtyEnd = getMax( pd.offset + pd.size, mDirtyEnd );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GenericConstBuffer::setDirty( bool dirty )
|
|
||||||
{
|
|
||||||
if ( !mBuffer )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( dirty )
|
|
||||||
{
|
|
||||||
mDirtyStart = 0;
|
|
||||||
mDirtyEnd = mLayout->getBufferSize();
|
|
||||||
}
|
|
||||||
else if ( !dirty )
|
|
||||||
{
|
|
||||||
mDirtyStart = U32_MAX;
|
|
||||||
mDirtyEnd = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const U8* GenericConstBuffer::getDirtyBuffer( U32 *start, U32 *size )
|
|
||||||
{
|
|
||||||
AssertFatal( isDirty(), "GenericConstBuffer::getDirtyBuffer() - Buffer is not dirty!" );
|
|
||||||
AssertFatal( mDirtyEnd > mDirtyStart, "GenericConstBuffer::getDirtyBuffer() - Dirty range is invalid!" );
|
|
||||||
AssertFatal( mBuffer, "GenericConstBuffer::getDirtyBuffer() - Buffer is empty!" );
|
|
||||||
|
|
||||||
// Use the area we calculated during internalSet.
|
|
||||||
*size = mDirtyEnd - mDirtyStart;
|
|
||||||
*start = mDirtyStart;
|
|
||||||
const U8 *buffer = mBuffer + mDirtyStart;
|
|
||||||
|
|
||||||
// Clear the dirty state while we're here.
|
|
||||||
mDirtyStart = U32_MAX;
|
|
||||||
mDirtyEnd = 0;
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const U8* GenericConstBuffer::getEntireBuffer()
|
|
||||||
{
|
|
||||||
AssertFatal(mBuffer, "GenericConstBuffer::getDirtyBuffer() - Buffer is empty!");
|
|
||||||
|
|
||||||
return mBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool GenericConstBuffer::isEqual( const GenericConstBuffer *buffer ) const
|
|
||||||
{
|
|
||||||
U32 bsize = mLayout->getBufferSize();
|
|
||||||
if ( bsize != buffer->mLayout->getBufferSize() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return dMemcmp( mBuffer, buffer->getBuffer(), bsize ) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _GENERICCONSTBUFFER_H_
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue