high lvl object data -> cbuffer data -> update subresource (data being copied)
This also annoys me, on a higer lvl I end up working with more readable/manageable data, instead of using cbuffer raw data, so I end up having a update that copies data to cbuffer and then copies data to ID3D11Buffer..Is it viable to work straight on a cbuffer data so that you dont need to copy data to it?[edit] answered on previous post[/edit]
Im doing this way (my system is "working", but its barely tested (got things rendering yesterday), so it might be really lame and full of yet to detect bugs):
my cbuffer class:
#pragma once
// system/standard headers
#include <D3D11.h>
#include <boost/smart_ptr.hpp>
namespace render{
//========================================================================
// holds CBs actual data(values)
//========================================================================
class ConstantBuffer{
typedef UINT byteoffset;
UINT m_nBytes;
UINT m_nVariables;
boost::scoped_array<BYTE> m_variablesBuffer;
boost::scoped_array<byteoffset> m_variablesOffsets;
boost::scoped_array<UINT> m_variablesSizes;
bool m_bNeedUpdate; // used to check if it needs update to the pipeline
public:
//------------------------------------------------------------------------
// ctor
//------------------------------------------------------------------------
ConstantBuffer( const UINT size_p, const UINT nVariables_p, const UINT * pVariablesSizes_p )
: m_variablesBuffer(new BYTE[size_p]()),
m_variablesOffsets(new byteoffset[nVariables_p]),
m_variablesSizes(new UINT[nVariables_p]){
m_nBytes = size_p;
m_nVariables = nVariables_p;
m_bNeedUpdate = false;
UINT iOffsetCache = 0;
for( UINT it = 0; it < m_nVariables; ++it ){
m_variablesOffsets[it] = iOffsetCache;
m_variablesSizes[it] = pVariablesSizes_p[it];
iOffsetCache += m_variablesSizes[it];
}
}
UINT GetSize() const{
return m_nBytes;
}
//------------------------------------------------------------------------
// Set variable by index
//------------------------------------------------------------------------
void SetVariable( UINT index_p, const BYTE* data_p ){
memcpy( &m_variablesBuffer[ m_variablesOffsets[index_p] ], data_p, m_variablesSizes[index_p] );
m_bNeedUpdate = true;
}
//------------------------------------------------------------------------
// Set the entire buffer at once
//------------------------------------------------------------------------
void Set( const BYTE * data_p ){
memcpy( m_variablesBuffer.get(), data_p, m_nBytes );
m_bNeedUpdate = true;
}
//------------------------------------------------------------------------
// Test if buffer data was modified since last update call, than updates it,
// or not.
//------------------------------------------------------------------------
void Update( ID3D11DeviceContext * pContext_p, ID3D11Buffer *& pConstantBuffer_p ){
if( m_bNeedUpdate ){
pContext_p->UpdateSubresource( pConstantBuffer_p, 0, NULL, m_variablesBuffer.get(), 0, 0 );
m_bNeedUpdate = false;
}
}
};
typedef boost::shared_ptr<ConstantBuffer> shared_CBuffer_ptr;
}
Then my binder cbuff command :
class BindVSConstantBuffer : public Binder{
UINT m_iStartSlot;
ID3D11Buffer *m_pConstantBuffer;
boost::shared_ptr<render::ConstantBuffer> m_pConstantBufferData;
public:
BindVSConstantBuffer( UINT iSlot_p, ID3D11Buffer *pConstantBuffers_p, const boost::shared_ptr<render::ConstantBuffer> & pConstBufferData_p )
:
Binder( 1LL << (E_VS_CBuffer0 + iSlot_p), E_BIND(E_VS_CBuffer0 + iSlot_p) ),
m_iStartSlot( iSlot_p ), m_pConstantBuffer( pConstantBuffers_p ),
m_pConstantBufferData(pConstBufferData_p){
assert( iSlot_p < 4); // handling up to 4 cbuffers slot
}
//------------------------------------------------------------------------
// Updates data to the buffer before binding it.
//------------------------------------------------------------------------
virtual void Execute( ID3D11DeviceContext * pDeviceContext_p ){
m_pConstantBufferData->Update( pDeviceContext_p, m_pConstantBuffer );
pDeviceContext_p->VSSetConstantBuffers( m_iStartSlot, 1, &m_pConstantBuffer);
}
};