You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
775 lines
22 KiB
775 lines
22 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
// |
|
//===========================================================================// |
|
|
|
#include <d3d10.h> |
|
#undef GetCommandLine |
|
|
|
#include "meshdx10.h" |
|
#include "utlvector.h" |
|
#include "materialsystem/imaterialsystem.h" |
|
#include "IHardwareConfigInternal.h" |
|
#include "shaderapi_global.h" |
|
#include "shaderapi/ishaderutil.h" |
|
#include "shaderapi/ishaderapi.h" |
|
#include "shaderdevicedx10.h" |
|
#include "materialsystem/imesh.h" |
|
#include "tier0/vprof.h" |
|
#include "tier0/dbg.h" |
|
#include "materialsystem/idebugtextureinfo.h" |
|
#include "materialsystem/ivballoctracker.h" |
|
#include "tier2/tier2.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Dx10 implementation of a vertex buffer |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// globals |
|
//----------------------------------------------------------------------------- |
|
#ifdef _DEBUG |
|
int CVertexBufferDx10::s_nBufferCount = 0; |
|
#endif |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CVertexBufferDx10::CVertexBufferDx10( ShaderBufferType_t type, VertexFormat_t fmt, int nVertexCount, const char *pBudgetGroupName ) : |
|
BaseClass( pBudgetGroupName ) |
|
{ |
|
Assert( nVertexCount != 0 ); |
|
|
|
m_pVertexBuffer = NULL; |
|
m_VertexFormat = fmt; |
|
m_nVertexCount = ( fmt == VERTEX_FORMAT_UNKNOWN ) ? 0 : nVertexCount; |
|
m_nBufferSize = ( fmt == VERTEX_FORMAT_UNKNOWN ) ? nVertexCount : nVertexCount * VertexSize(); |
|
m_nFirstUnwrittenOffset = 0; |
|
m_bIsLocked = false; |
|
m_bIsDynamic = ( type == SHADER_BUFFER_TYPE_DYNAMIC ) || ( type == SHADER_BUFFER_TYPE_DYNAMIC_TEMP ); |
|
m_bFlush = false; |
|
} |
|
|
|
CVertexBufferDx10::~CVertexBufferDx10() |
|
{ |
|
Free(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Creates, destroys the vertex buffer |
|
//----------------------------------------------------------------------------- |
|
bool CVertexBufferDx10::Allocate( ) |
|
{ |
|
Assert( !m_pVertexBuffer ); |
|
|
|
m_nFirstUnwrittenOffset = 0; |
|
|
|
D3D10_BUFFER_DESC bd; |
|
bd.Usage = D3D10_USAGE_DYNAMIC; |
|
bd.ByteWidth = m_nBufferSize; |
|
bd.BindFlags = D3D10_BIND_VERTEX_BUFFER; |
|
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; |
|
bd.MiscFlags = 0; |
|
|
|
HRESULT hr = D3D10Device()->CreateBuffer( &bd, NULL, &m_pVertexBuffer ); |
|
bool bOk = !FAILED( hr ) && ( m_pVertexBuffer != 0 ); |
|
|
|
if ( bOk ) |
|
{ |
|
// Track VB allocations |
|
g_VBAllocTracker->CountVB( m_pVertexBuffer, m_bIsDynamic, m_nBufferSize, VertexSize(), GetVertexFormat() ); |
|
|
|
if ( !m_bIsDynamic ) |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); |
|
} |
|
else |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); |
|
// Dynamic meshes should never be compressed (slows down writing to them) |
|
Assert( CompressionType( GetVertexFormat() ) == VERTEX_COMPRESSION_NONE ); |
|
} |
|
#ifdef _DEBUG |
|
++s_nBufferCount; |
|
#endif |
|
} |
|
|
|
return bOk; |
|
} |
|
|
|
void CVertexBufferDx10::Free() |
|
{ |
|
if ( m_pVertexBuffer ) |
|
{ |
|
#ifdef _DEBUG |
|
--s_nBufferCount; |
|
#endif |
|
|
|
// Track VB allocations |
|
g_VBAllocTracker->UnCountVB( m_pVertexBuffer ); |
|
|
|
m_pVertexBuffer->Release(); |
|
m_pVertexBuffer = NULL; |
|
|
|
if ( !m_bIsDynamic ) |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, - m_nBufferSize ); |
|
} |
|
else |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, - m_nBufferSize ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Vertex Buffer info |
|
//----------------------------------------------------------------------------- |
|
int CVertexBufferDx10::VertexCount() const |
|
{ |
|
Assert( !m_bIsDynamic ); |
|
return m_nVertexCount; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the buffer format (only valid for static index buffers) |
|
//----------------------------------------------------------------------------- |
|
VertexFormat_t CVertexBufferDx10::GetVertexFormat() const |
|
{ |
|
Assert( !m_bIsDynamic ); |
|
return m_VertexFormat; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns true if the buffer is dynamic |
|
//----------------------------------------------------------------------------- |
|
bool CVertexBufferDx10::IsDynamic() const |
|
{ |
|
return m_bIsDynamic; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Only used by dynamic buffers, indicates the next lock should perform a discard. |
|
//----------------------------------------------------------------------------- |
|
void CVertexBufferDx10::Flush() |
|
{ |
|
// This strange-looking line makes a flush only occur if the buffer is dynamic. |
|
m_bFlush = m_bIsDynamic; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Casts a dynamic buffer to be a particular vertex type |
|
//----------------------------------------------------------------------------- |
|
void CVertexBufferDx10::BeginCastBuffer( VertexFormat_t format ) |
|
{ |
|
Assert( format != MATERIAL_INDEX_FORMAT_UNKNOWN ); |
|
Assert( m_bIsDynamic && ( m_VertexFormat == 0 || m_VertexFormat == format ) ); |
|
if ( !m_bIsDynamic ) |
|
return; |
|
|
|
m_VertexFormat = format; |
|
m_nVertexCount = m_nBufferSize / VertexSize(); |
|
} |
|
|
|
void CVertexBufferDx10::EndCastBuffer( ) |
|
{ |
|
Assert( m_bIsDynamic && m_VertexFormat != 0 ); |
|
if ( !m_bIsDynamic ) |
|
return; |
|
m_VertexFormat = 0; |
|
m_nVertexCount = 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the number of indices that can be written into the buffer |
|
//----------------------------------------------------------------------------- |
|
int CVertexBufferDx10::GetRoomRemaining() const |
|
{ |
|
return ( m_nBufferSize - m_nFirstUnwrittenOffset ) / VertexSize(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Lock, unlock |
|
//----------------------------------------------------------------------------- |
|
bool CVertexBufferDx10::Lock( int nMaxVertexCount, bool bAppend, VertexDesc_t &desc ) |
|
{ |
|
Assert( !m_bIsLocked && ( nMaxVertexCount != 0 ) && ( nMaxVertexCount <= m_nVertexCount ) ); |
|
Assert( m_VertexFormat != 0 ); |
|
|
|
// FIXME: Why do we need to sync matrices now? |
|
ShaderUtil()->SyncMatrices(); |
|
g_ShaderMutex.Lock(); |
|
|
|
void *pLockedData = NULL; |
|
HRESULT hr; |
|
|
|
// This can happen if the buffer was locked but a type wasn't bound |
|
if ( m_VertexFormat == 0 ) |
|
goto vertexBufferLockFailed; |
|
|
|
// Just give the app crap buffers to fill up while we're suppressed... |
|
if ( g_pShaderDevice->IsDeactivated() || ( nMaxVertexCount == 0 ) ) |
|
goto vertexBufferLockFailed; |
|
|
|
// Did we ask for something too large? |
|
if ( nMaxVertexCount > m_nVertexCount ) |
|
{ |
|
Warning( "Too many vertices for vertex buffer. . tell a programmer (%d>%d)\n", nMaxVertexCount, m_nVertexCount ); |
|
goto vertexBufferLockFailed; |
|
} |
|
|
|
// We might not have a buffer owing to alt-tab type stuff |
|
if ( !m_pVertexBuffer ) |
|
{ |
|
if ( !Allocate() ) |
|
goto vertexBufferLockFailed; |
|
} |
|
|
|
// Check to see if we have enough memory |
|
int nMemoryRequired = nMaxVertexCount * VertexSize(); |
|
bool bHasEnoughMemory = ( m_nFirstUnwrittenOffset + nMemoryRequired <= m_nBufferSize ); |
|
|
|
D3D10_MAP map; |
|
if ( bAppend ) |
|
{ |
|
// Can't have the first lock after a flush be an appending lock |
|
Assert( !m_bFlush ); |
|
|
|
// If we're appending and we don't have enough room, then puke! |
|
if ( !bHasEnoughMemory || m_bFlush ) |
|
goto vertexBufferLockFailed; |
|
map = ( m_nFirstUnwrittenOffset == 0 ) ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE; |
|
} |
|
else |
|
{ |
|
// If we're not appending, no overwrite unless we don't have enough room |
|
// If we're a static buffer, always discard if we're not appending |
|
if ( !m_bFlush && bHasEnoughMemory && m_bIsDynamic ) |
|
{ |
|
map = ( m_nFirstUnwrittenOffset == 0 ) ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE; |
|
} |
|
else |
|
{ |
|
map = D3D10_MAP_WRITE_DISCARD; |
|
m_nFirstUnwrittenOffset = 0; |
|
m_bFlush = false; |
|
} |
|
} |
|
|
|
hr = m_pVertexBuffer->Map( map, 0, &pLockedData ); |
|
if ( FAILED( hr ) ) |
|
{ |
|
Warning( "Failed to lock vertex buffer in CVertexBufferDx10::Lock\n" ); |
|
goto vertexBufferLockFailed; |
|
} |
|
|
|
ComputeVertexDescription( (unsigned char*)pLockedData + m_nFirstUnwrittenOffset, m_VertexFormat, desc ); |
|
desc.m_nFirstVertex = 0; |
|
desc.m_nOffset = m_nFirstUnwrittenOffset; |
|
m_bIsLocked = true; |
|
return true; |
|
|
|
vertexBufferLockFailed: |
|
g_ShaderMutex.Unlock(); |
|
|
|
// Set up a bogus index descriptor |
|
ComputeVertexDescription( 0, 0, desc ); |
|
desc.m_nFirstVertex = 0; |
|
desc.m_nOffset = 0; |
|
return false; |
|
} |
|
|
|
void CVertexBufferDx10::Unlock( int nWrittenVertexCount, VertexDesc_t &desc ) |
|
{ |
|
Assert( nWrittenVertexCount <= m_nVertexCount ); |
|
|
|
// NOTE: This can happen if the lock occurs during alt-tab |
|
// or if another application is initializing |
|
if ( !m_bIsLocked ) |
|
return; |
|
|
|
if ( m_pVertexBuffer ) |
|
{ |
|
m_pVertexBuffer->Unmap(); |
|
} |
|
|
|
m_nFirstUnwrittenOffset += nWrittenVertexCount * VertexSize(); |
|
m_bIsLocked = false; |
|
g_ShaderMutex.Unlock(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// Dx10 implementation of an index buffer |
|
// |
|
//----------------------------------------------------------------------------- |
|
|
|
//----------------------------------------------------------------------------- |
|
// globals |
|
//----------------------------------------------------------------------------- |
|
|
|
// shove indices into this if you don't actually want indices |
|
static unsigned int s_nScratchIndexBuffer = 0; |
|
|
|
#ifdef _DEBUG |
|
int CIndexBufferDx10::s_nBufferCount = 0; |
|
#endif |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// constructor, destructor |
|
//----------------------------------------------------------------------------- |
|
CIndexBufferDx10::CIndexBufferDx10( ShaderBufferType_t type, MaterialIndexFormat_t fmt, int nIndexCount, const char *pBudgetGroupName ) : |
|
BaseClass( pBudgetGroupName ) |
|
{ |
|
Assert( nIndexCount != 0 ); |
|
Assert( IsDynamicBufferType( type ) || ( fmt != MATERIAL_INDEX_FORMAT_UNKNOWN ) ); |
|
|
|
m_pIndexBuffer = NULL; |
|
m_IndexFormat = fmt; |
|
m_nIndexCount = ( fmt == MATERIAL_INDEX_FORMAT_UNKNOWN ) ? 0 : nIndexCount; |
|
m_nBufferSize = ( fmt == MATERIAL_INDEX_FORMAT_UNKNOWN ) ? nIndexCount : nIndexCount * IndexSize(); |
|
m_nFirstUnwrittenOffset = 0; |
|
m_bIsLocked = false; |
|
m_bIsDynamic = IsDynamicBufferType( type ); |
|
m_bFlush = false; |
|
|
|
// NOTE: This has to happen at the end since m_IndexFormat must be valid for IndexSize() to work |
|
if ( m_bIsDynamic ) |
|
{ |
|
m_IndexFormat = MATERIAL_INDEX_FORMAT_UNKNOWN; |
|
m_nIndexCount = 0; |
|
} |
|
} |
|
|
|
CIndexBufferDx10::~CIndexBufferDx10() |
|
{ |
|
Free(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Creates, destroys the index buffer |
|
//----------------------------------------------------------------------------- |
|
bool CIndexBufferDx10::Allocate( ) |
|
{ |
|
Assert( !m_pIndexBuffer ); |
|
|
|
m_nFirstUnwrittenOffset = 0; |
|
|
|
D3D10_BUFFER_DESC bd; |
|
bd.Usage = D3D10_USAGE_DYNAMIC; |
|
bd.ByteWidth = m_nBufferSize; |
|
bd.BindFlags = D3D10_BIND_INDEX_BUFFER; |
|
bd.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE; |
|
bd.MiscFlags = 0; |
|
|
|
HRESULT hr = D3D10Device()->CreateBuffer( &bd, NULL, &m_pIndexBuffer ); |
|
bool bOk = !FAILED( hr ) && ( m_pIndexBuffer != NULL ); |
|
|
|
if ( bOk ) |
|
{ |
|
if ( !m_bIsDynamic ) |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); |
|
} |
|
else |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, m_nBufferSize ); |
|
} |
|
#ifdef _DEBUG |
|
++s_nBufferCount; |
|
#endif |
|
} |
|
|
|
return bOk; |
|
} |
|
|
|
void CIndexBufferDx10::Free() |
|
{ |
|
if ( m_pIndexBuffer ) |
|
{ |
|
#ifdef _DEBUG |
|
--s_nBufferCount; |
|
#endif |
|
|
|
m_pIndexBuffer->Release(); |
|
m_pIndexBuffer = NULL; |
|
|
|
if ( !m_bIsDynamic ) |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_STATIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, - m_nBufferSize ); |
|
} |
|
else |
|
{ |
|
VPROF_INCREMENT_GROUP_COUNTER( "TexGroup_global_" TEXTURE_GROUP_DYNAMIC_INDEX_BUFFER, |
|
COUNTER_GROUP_TEXTURE_GLOBAL, - m_nBufferSize ); |
|
} |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the buffer size (only valid for static index buffers) |
|
//----------------------------------------------------------------------------- |
|
int CIndexBufferDx10::IndexCount() const |
|
{ |
|
Assert( !m_bIsDynamic ); |
|
return m_nIndexCount; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the buffer format (only valid for static index buffers) |
|
//----------------------------------------------------------------------------- |
|
MaterialIndexFormat_t CIndexBufferDx10::IndexFormat() const |
|
{ |
|
Assert( !m_bIsDynamic ); |
|
return m_IndexFormat; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns true if the buffer is dynamic |
|
//----------------------------------------------------------------------------- |
|
bool CIndexBufferDx10::IsDynamic() const |
|
{ |
|
return m_bIsDynamic; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Only used by dynamic buffers, indicates the next lock should perform a discard. |
|
//----------------------------------------------------------------------------- |
|
void CIndexBufferDx10::Flush() |
|
{ |
|
// This strange-looking line makes a flush only occur if the buffer is dynamic. |
|
m_bFlush = m_bIsDynamic; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Casts a dynamic buffer to be a particular index type |
|
//----------------------------------------------------------------------------- |
|
void CIndexBufferDx10::BeginCastBuffer( MaterialIndexFormat_t format ) |
|
{ |
|
Assert( format != MATERIAL_INDEX_FORMAT_UNKNOWN ); |
|
Assert( m_bIsDynamic && ( m_IndexFormat == MATERIAL_INDEX_FORMAT_UNKNOWN || m_IndexFormat == format ) ); |
|
if ( !m_bIsDynamic ) |
|
return; |
|
|
|
m_IndexFormat = format; |
|
m_nIndexCount = m_nBufferSize / IndexSize(); |
|
} |
|
|
|
void CIndexBufferDx10::EndCastBuffer( ) |
|
{ |
|
Assert( m_bIsDynamic && m_IndexFormat != MATERIAL_INDEX_FORMAT_UNKNOWN ); |
|
if ( !m_bIsDynamic ) |
|
return; |
|
m_IndexFormat = MATERIAL_INDEX_FORMAT_UNKNOWN; |
|
m_nIndexCount = 0; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Returns the number of indices that can be written into the buffer |
|
//----------------------------------------------------------------------------- |
|
int CIndexBufferDx10::GetRoomRemaining() const |
|
{ |
|
return ( m_nBufferSize - m_nFirstUnwrittenOffset ) / IndexSize(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Locks, unlocks the mesh |
|
//----------------------------------------------------------------------------- |
|
bool CIndexBufferDx10::Lock( int nMaxIndexCount, bool bAppend, IndexDesc_t &desc ) |
|
{ |
|
Assert( !m_bIsLocked && ( nMaxIndexCount != 0 ) && ( nMaxIndexCount <= m_nIndexCount ) ); |
|
Assert( m_IndexFormat != MATERIAL_INDEX_FORMAT_UNKNOWN ); |
|
|
|
// FIXME: Why do we need to sync matrices now? |
|
ShaderUtil()->SyncMatrices(); |
|
g_ShaderMutex.Lock(); |
|
|
|
void *pLockedData = NULL; |
|
HRESULT hr; |
|
|
|
// This can happen if the buffer was locked but a type wasn't bound |
|
if ( m_IndexFormat == MATERIAL_INDEX_FORMAT_UNKNOWN ) |
|
goto indexBufferLockFailed; |
|
|
|
// Just give the app crap buffers to fill up while we're suppressed... |
|
if ( g_pShaderDevice->IsDeactivated() || ( nMaxIndexCount == 0 ) ) |
|
goto indexBufferLockFailed; |
|
|
|
// Did we ask for something too large? |
|
if ( nMaxIndexCount > m_nIndexCount ) |
|
{ |
|
Warning( "Too many indices for index buffer. . tell a programmer (%d>%d)\n", nMaxIndexCount, m_nIndexCount ); |
|
goto indexBufferLockFailed; |
|
} |
|
|
|
// We might not have a buffer owing to alt-tab type stuff |
|
if ( !m_pIndexBuffer ) |
|
{ |
|
if ( !Allocate() ) |
|
goto indexBufferLockFailed; |
|
} |
|
|
|
// Check to see if we have enough memory |
|
int nMemoryRequired = nMaxIndexCount * IndexSize(); |
|
bool bHasEnoughMemory = ( m_nFirstUnwrittenOffset + nMemoryRequired <= m_nBufferSize ); |
|
|
|
D3D10_MAP map; |
|
if ( bAppend ) |
|
{ |
|
// Can't have the first lock after a flush be an appending lock |
|
Assert( !m_bFlush ); |
|
|
|
// If we're appending and we don't have enough room, then puke! |
|
if ( !bHasEnoughMemory || m_bFlush ) |
|
goto indexBufferLockFailed; |
|
map = ( m_nFirstUnwrittenOffset == 0 ) ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE; |
|
} |
|
else |
|
{ |
|
// If we're not appending, no overwrite unless we don't have enough room |
|
if ( !m_bFlush && bHasEnoughMemory && m_bIsDynamic ) |
|
{ |
|
map = ( m_nFirstUnwrittenOffset == 0 ) ? D3D10_MAP_WRITE_DISCARD : D3D10_MAP_WRITE_NO_OVERWRITE; |
|
} |
|
else |
|
{ |
|
map = D3D10_MAP_WRITE_DISCARD; |
|
m_nFirstUnwrittenOffset = 0; |
|
m_bFlush = false; |
|
} |
|
} |
|
|
|
hr = m_pIndexBuffer->Map( map, 0, &pLockedData ); |
|
if ( FAILED( hr ) ) |
|
{ |
|
Warning( "Failed to lock index buffer in CIndexBufferDx10::Lock\n" ); |
|
goto indexBufferLockFailed; |
|
} |
|
|
|
desc.m_pIndices = (unsigned short*)( (unsigned char*)pLockedData + m_nFirstUnwrittenOffset ); |
|
desc.m_nIndexSize = IndexSize() >> 1; |
|
desc.m_nFirstIndex = 0; |
|
desc.m_nOffset = m_nFirstUnwrittenOffset; |
|
m_bIsLocked = true; |
|
return true; |
|
|
|
indexBufferLockFailed: |
|
g_ShaderMutex.Unlock(); |
|
|
|
// Set up a bogus index descriptor |
|
desc.m_pIndices = (unsigned short*)( &s_nScratchIndexBuffer ); |
|
desc.m_nFirstIndex = 0; |
|
desc.m_nIndexSize = 0; |
|
desc.m_nOffset = 0; |
|
return false; |
|
} |
|
|
|
void CIndexBufferDx10::Unlock( int nWrittenIndexCount, IndexDesc_t &desc ) |
|
{ |
|
Assert( nWrittenIndexCount <= m_nIndexCount ); |
|
|
|
// NOTE: This can happen if the lock occurs during alt-tab |
|
// or if another application is initializing |
|
if ( !m_bIsLocked ) |
|
return; |
|
|
|
if ( m_pIndexBuffer ) |
|
{ |
|
m_pIndexBuffer->Unmap(); |
|
} |
|
|
|
m_nFirstUnwrittenOffset += nWrittenIndexCount * IndexSize(); |
|
m_bIsLocked = false; |
|
g_ShaderMutex.Unlock(); |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Locks, unlocks an existing mesh |
|
//----------------------------------------------------------------------------- |
|
void CIndexBufferDx10::ModifyBegin( bool bReadOnly, int nFirstIndex, int nIndexCount, IndexDesc_t& desc ) |
|
{ |
|
Assert( 0 ); |
|
} |
|
|
|
void CIndexBufferDx10::ModifyEnd( IndexDesc_t& desc ) |
|
{ |
|
|
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
// The empty mesh... |
|
// |
|
//----------------------------------------------------------------------------- |
|
CMeshDx10::CMeshDx10() |
|
{ |
|
m_pVertexMemory = new unsigned char[VERTEX_BUFFER_SIZE]; |
|
} |
|
|
|
CMeshDx10::~CMeshDx10() |
|
{ |
|
delete[] m_pVertexMemory; |
|
} |
|
|
|
void CMeshDx10::LockMesh( int numVerts, int numIndices, MeshDesc_t& desc ) |
|
{ |
|
// Who cares about the data? |
|
desc.m_pPosition = (float*)m_pVertexMemory; |
|
desc.m_pNormal = (float*)m_pVertexMemory; |
|
desc.m_pColor = m_pVertexMemory; |
|
int i; |
|
for ( i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i) |
|
desc.m_pTexCoord[i] = (float*)m_pVertexMemory; |
|
desc.m_pIndices = (unsigned short*)m_pVertexMemory; |
|
|
|
desc.m_pBoneWeight = (float*)m_pVertexMemory; |
|
desc.m_pBoneMatrixIndex = (unsigned char*)m_pVertexMemory; |
|
desc.m_pTangentS = (float*)m_pVertexMemory; |
|
desc.m_pTangentT = (float*)m_pVertexMemory; |
|
desc.m_pUserData = (float*)m_pVertexMemory; |
|
desc.m_NumBoneWeights = 2; |
|
|
|
desc.m_VertexSize_Position = 0; |
|
desc.m_VertexSize_BoneWeight = 0; |
|
desc.m_VertexSize_BoneMatrixIndex = 0; |
|
desc.m_VertexSize_Normal = 0; |
|
desc.m_VertexSize_Color = 0; |
|
for( i=0; i < VERTEX_MAX_TEXTURE_COORDINATES; i++ ) |
|
desc.m_VertexSize_TexCoord[i] = 0; |
|
desc.m_VertexSize_TangentS = 0; |
|
desc.m_VertexSize_TangentT = 0; |
|
desc.m_VertexSize_UserData = 0; |
|
desc.m_ActualVertexSize = 0; // Size of the vertices.. Some of the m_VertexSize_ elements above |
|
|
|
desc.m_nFirstVertex = 0; |
|
desc.m_nIndexSize = 0; |
|
} |
|
|
|
void CMeshDx10::UnlockMesh( int numVerts, int numIndices, MeshDesc_t& desc ) |
|
{ |
|
} |
|
|
|
void CMeshDx10::ModifyBeginEx( bool bReadOnly, int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc ) |
|
{ |
|
// Who cares about the data? |
|
desc.m_pPosition = (float*)m_pVertexMemory; |
|
desc.m_pNormal = (float*)m_pVertexMemory; |
|
desc.m_pColor = m_pVertexMemory; |
|
int i; |
|
for ( i = 0; i < VERTEX_MAX_TEXTURE_COORDINATES; ++i) |
|
desc.m_pTexCoord[i] = (float*)m_pVertexMemory; |
|
desc.m_pIndices = (unsigned short*)m_pVertexMemory; |
|
|
|
desc.m_pBoneWeight = (float*)m_pVertexMemory; |
|
desc.m_pBoneMatrixIndex = (unsigned char*)m_pVertexMemory; |
|
desc.m_pTangentS = (float*)m_pVertexMemory; |
|
desc.m_pTangentT = (float*)m_pVertexMemory; |
|
desc.m_pUserData = (float*)m_pVertexMemory; |
|
desc.m_NumBoneWeights = 2; |
|
|
|
desc.m_VertexSize_Position = 0; |
|
desc.m_VertexSize_BoneWeight = 0; |
|
desc.m_VertexSize_BoneMatrixIndex = 0; |
|
desc.m_VertexSize_Normal = 0; |
|
desc.m_VertexSize_Color = 0; |
|
for( i=0; i < VERTEX_MAX_TEXTURE_COORDINATES; i++ ) |
|
desc.m_VertexSize_TexCoord[i] = 0; |
|
desc.m_VertexSize_TangentS = 0; |
|
desc.m_VertexSize_TangentT = 0; |
|
desc.m_VertexSize_UserData = 0; |
|
desc.m_ActualVertexSize = 0; // Size of the vertices.. Some of the m_VertexSize_ elements above |
|
|
|
desc.m_nFirstVertex = 0; |
|
desc.m_nIndexSize = 0; |
|
} |
|
|
|
void CMeshDx10::ModifyBegin( int firstVertex, int numVerts, int firstIndex, int numIndices, MeshDesc_t& desc ) |
|
{ |
|
ModifyBeginEx( false, firstVertex, numVerts, firstIndex, numIndices, desc ); |
|
} |
|
|
|
void CMeshDx10::ModifyEnd( MeshDesc_t& desc ) |
|
{ |
|
} |
|
|
|
// returns the # of vertices (static meshes only) |
|
int CMeshDx10::VertexCount() const |
|
{ |
|
return 0; |
|
} |
|
|
|
// Sets the primitive type |
|
void CMeshDx10::SetPrimitiveType( MaterialPrimitiveType_t type ) |
|
{ |
|
} |
|
|
|
// Draws the entire mesh |
|
void CMeshDx10::Draw( int firstIndex, int numIndices ) |
|
{ |
|
} |
|
|
|
void CMeshDx10::Draw(CPrimList *pPrims, int nPrims) |
|
{ |
|
} |
|
|
|
// Copy verts and/or indices to a mesh builder. This only works for temp meshes! |
|
void CMeshDx10::CopyToMeshBuilder( |
|
int iStartVert, // Which vertices to copy. |
|
int nVerts, |
|
int iStartIndex, // Which indices to copy. |
|
int nIndices, |
|
int indexOffset, // This is added to each index. |
|
CMeshBuilder &builder ) |
|
{ |
|
} |
|
|
|
// Spews the mesh data |
|
void CMeshDx10::Spew( int numVerts, int numIndices, const MeshDesc_t & desc ) |
|
{ |
|
} |
|
|
|
void CMeshDx10::ValidateData( int numVerts, int numIndices, const MeshDesc_t & desc ) |
|
{ |
|
} |
|
|
|
// gets the associated material |
|
IMaterial* CMeshDx10::GetMaterial() |
|
{ |
|
// umm. this don't work none |
|
Assert(0); |
|
return 0; |
|
}
|
|
|