|
|
//======Copyright 1996-2006, Valve Corporation, All rights reserved. ======//
//
// Purpose:
//
// methods for muti-core dx9 threading
//===========================================================================//
#include "togl/rendermechanism.h"
#include "utlsymbol.h"
#include "utlvector.h"
#include "utldict.h"
#include "utlbuffer.h"
#include "UtlStringMap.h"
#include "locald3dtypes.h"
#include "shaderapidx8_global.h"
#include "recording.h"
#include "tier0/vprof.h"
#include "materialsystem/imaterialsystem.h"
#include "materialsystem/imaterialsystemhardwareconfig.h"
#include "shaderapidx8.h"
#include "materialsystem/IShader.h"
#include "utllinkedlist.h"
#include "materialsystem/ishadersystem.h"
#include "tier0/fasttimer.h"
#include <stdlib.h>
#include "convar.h"
#include "materialsystem/shader_vcs_version.h"
#include "datacache/idatacache.h"
#include "winutils.h"
#include "tier0/memdbgon.h"
#if SHADERAPI_USE_SMP
// Set this to 1 to get vprof nodes for playing back the command stream. This is good for counting calls in a frame, etc.
#define SHADERAPI_VPROF_BUFFER_PLAYBACK 1
#if SHADERAPI_VPROF_BUFFER_PLAYBACK && SHADERAPI_BUFFER_D3DCALLS
#define VPROF_BUFFER_PLAYBACK(name) VPROF(name)
#else
#define VPROF_BUFFER_PLAYBACK(name) ((void)0)
#endif
template<class T, int QSIZE> class FixedWorkQueue { T Data[QSIZE]; char pad0[256]; volatile int n_added; int write_index; char pad1[256]; // make sure these don't share cache lines
volatile int n_removed; int read_index;
public: FixedWorkQueue(void) { read_index=write_index=0; n_added=n_removed=0; }
int IsEmpty(void) { return (n_added==n_removed); }
int IsFull(void) { return (n_added-n_removed)>=QSIZE; }
T GetWorkUnit(void) { if (IsEmpty()) return 0; return Data[read_index]; }
void MarkUnitDone(void) { n_removed++; read_index=(read_index+1) % QSIZE; }
void AddWorkUnit(T unit) { #if SHADERAPI_BUFFER_D3DCALLS
Assert( !IsFull() ); #else
while (IsFull()) Sleep(0); #endif
Data[write_index]=unit; n_added++; write_index=(write_index+1) % QSIZE; } };
#if SHADERAPI_BUFFER_D3DCALLS
#define N_PUSH_BUFFERS 5000
#else
#define N_PUSH_BUFFERS 500
#endif
static volatile PushBuffer *PushBuffers[N_PUSH_BUFFERS]; FixedWorkQueue<PushBuffer *, N_PUSH_BUFFERS> PBQueue;
uintp OurThreadInit( void * ourthis ) { (( D3DDeviceWrapper *) ourthis )->RunThread(); return 0; }
void D3DDeviceWrapper::RunThread( void ) { SetThreadAffinityMask(GetCurrentThread(), 2); for(;;) { PushBuffer *Pbuf=PBQueue.GetWorkUnit(); if (! Pbuf) { ; //Sleep(0);
} else { ExecutePushBuffer( Pbuf ); PBQueue.MarkUnitDone(); Pbuf->m_State = PUSHBUFFER_AVAILABLE; } } }
#if SHADERAPI_BUFFER_D3DCALLS
void D3DDeviceWrapper::ExecuteAllWork( void ) { if( !m_bBufferingD3DCalls ) return; VPROF_BUDGET( "ExecuteAllWork", "ExecuteAllWork" ); SubmitPushBufferAndGetANewOne(); PushBuffer *Pbuf; while( ( Pbuf = PBQueue.GetWorkUnit() ) != NULL ) { ExecutePushBuffer( Pbuf ); PBQueue.MarkUnitDone(); Pbuf->m_State = PUSHBUFFER_AVAILABLE; } m_bBufferingD3DCalls = false; } #endif
#if SHADERAPI_BUFFER_D3DCALLS
#define MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE 1600
#else
#define MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE 16
#endif
struct RememberedPointer { void *m_pKey; void *m_pRememberedPtr; } RememberedPointerHistory[MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE];
void D3DDeviceWrapper::SetASyncMode( bool onoff ) { #if SHADERAPI_BUFFER_D3DCALLS
if ( onoff ) { m_bBufferingD3DCalls = true; // allocate push buffers if we need to
if ( PushBuffers[0] == NULL ) { for(int i=0; i<N_PUSH_BUFFERS; i++) PushBuffers[i]=new PushBuffer; } // create thread and init communications
memset( RememberedPointerHistory,0,sizeof(RememberedPointerHistory) ); } #else
if ( onoff ) { if (! m_pASyncThreadHandle ) { // allocate push buffers if we need to
if ( PushBuffers[0] == NULL ) { for(int i=0; i<N_PUSH_BUFFERS; i++) PushBuffers[i]=new PushBuffer; } // create thread and init communications
memset( RememberedPointerHistory,0,sizeof(RememberedPointerHistory) ); SetThreadAffinityMask(GetCurrentThread(), 1); #ifdef WIN32
m_pASyncThreadHandle = CreateSimpleThread( OurThreadInit, this, 128*1024 ); #else
#warning "D3DDeviceWrapper::SetASyncMode might need a beginthread version"
Assert( !"Impl D3DDeviceWrapper::SetASyncMode" ); #endif
} } else { Synchronize(); } #endif
}
PushBuffer *D3DDeviceWrapper::FindFreePushBuffer( PushBufferState newstate ) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::FindFreePushBuffer" ); for(;;) { for(int i=0;i<N_PUSH_BUFFERS;i++) { if (PushBuffers[i]->m_State == PUSHBUFFER_AVAILABLE ) { PushBuffers[i]->m_State = newstate; return (PushBuffer *) PushBuffers[i]; } } // hmm, out of push buffers. better sleep and try again later
SubmitPushBufferAndGetANewOne(); Sleep(0); } }
void D3DDeviceWrapper::GetPushBuffer( void ) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::GetPushBuffer" ); m_pCurPushBuffer = FindFreePushBuffer( PUSHBUFFER_BEING_FILLED ); m_pOutputPtr = m_pCurPushBuffer->m_BufferData; m_PushBufferFreeSlots = PUSHBUFFER_NELEMS - 1; // leave room for end marker
}
void D3DDeviceWrapper::SubmitPushBufferAndGetANewOne( void ) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::SubmitPushBufferAndGetANewOne" );
// submit the current push buffer
if ( m_pCurPushBuffer ) { if (m_pOutputPtr == m_pCurPushBuffer->m_BufferData) // haven't done anyting, don't bother
return; *(m_pOutputPtr) = PBCMD_END; // mark end
m_pCurPushBuffer->m_State = PUSHBUFFER_SUBMITTED; // here, enqueue for task
PBQueue.AddWorkUnit( m_pCurPushBuffer ); } GetPushBuffer(); }
void D3DDeviceWrapper::SubmitIfNotBusy( void ) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::SubmitIfNotBusy" ); if ( PBQueue.IsEmpty() ) SubmitPushBufferAndGetANewOne(); }
void D3DDeviceWrapper::UpdateStereoTexture( IDirect3DTexture9 *pTex, bool devLost, bool *pStereoActiveThisFrame ) { #if ( IS_WINDOWS_PC ) && !NO_STEREO_D3D9
Assert( m_pStereoTexUpdater ); if ( m_pStereoTexUpdater ) { if ( pStereoActiveThisFrame != NULL ) { *pStereoActiveThisFrame = m_pStereoTexUpdater->IsStereoActive(); }
// We always want to call this so it can deal with a lost device
m_pStereoTexUpdater->UpdateStereoTexture( Dx9Device(), pTex, devLost ); } #else
if ( pStereoActiveThisFrame != NULL ) { *pStereoActiveThisFrame = false; } #endif
}
void D3DDeviceWrapper::Synchronize( void ) { #if SHADERAPI_BUFFER_D3DCALLS
if( m_bBufferingD3DCalls ) { Assert( 0 ); Error( "Synchronize not supported with SHADERAPI_BUFFER_D3DCALLS" ); } return; #endif
if ( ASyncMode()) { SubmitPushBufferAndGetANewOne(); // here, wait for queue to become empty
while (! PBQueue.IsEmpty() ) { // Sleep(1);
} } }
void D3DDeviceWrapper::AsynchronousLock( IDirect3DIndexBuffer9* ib, size_t offset, size_t size, void **ptr, DWORD flags, LockedBufferContext *lb) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::AsynchronousLock index" );
if ( size <= sizeof( PushBuffers[0]->m_BufferData )) { // can use one of our pushbuffers for this
lb->m_pPushBuffer = FindFreePushBuffer( PUSHBUFFER_BEING_USED_FOR_LOCKEDDATA ); *(ptr) = lb->m_pPushBuffer->m_BufferData; Assert( *ptr ); lb->m_pMallocedMemory = NULL; } else // out of buffer space or size too big
{ lb->m_pPushBuffer = NULL; lb->m_pMallocedMemory = new uint8 [ size ]; *(ptr) = lb->m_pMallocedMemory; } // now, push lock commands
AllocatePushBufferSpace( 1+N_DWORDS_IN_PTR+3 ); *(m_pOutputPtr++)=PBCMD_ASYNC_LOCK_IB; *((LPDIRECT3DINDEXBUFFER *) m_pOutputPtr)=ib; m_pOutputPtr+=N_DWORDS_IN_PTR; *(m_pOutputPtr++)=offset; *(m_pOutputPtr++)=size; *(m_pOutputPtr++)=flags; }
void D3DDeviceWrapper::AsynchronousLock( IDirect3DVertexBuffer9* vb, size_t offset, size_t size, void **ptr, DWORD flags, LockedBufferContext *lb) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::AsynchronousLock vertex" ); // we have commands in flight. Need to use temporary memory for this lock.
// if the size needed is < the amount of space in a push buffer, we can use
// a push buffer for the buffer. Otherwise, we're going to malloc one.
if ( size <= sizeof( PushBuffers[0]->m_BufferData )) { // can use one of our pushbuffers for this
lb->m_pPushBuffer = FindFreePushBuffer( PUSHBUFFER_BEING_USED_FOR_LOCKEDDATA ); *(ptr) = lb->m_pPushBuffer->m_BufferData; Assert( *ptr ); lb->m_pMallocedMemory = NULL; } else // out of buffer space or size too big
{ lb->m_pPushBuffer = NULL; lb->m_pMallocedMemory = new uint8 [ size ]; *(ptr) = lb->m_pMallocedMemory; } // now, push lock commands
AllocatePushBufferSpace( 1+N_DWORDS_IN_PTR+3 ); *(m_pOutputPtr++)=PBCMD_ASYNC_LOCK_VB; *((LPDIRECT3DVERTEXBUFFER *) m_pOutputPtr)=vb; m_pOutputPtr+=N_DWORDS_IN_PTR; *(m_pOutputPtr++)=offset; *(m_pOutputPtr++)=size; *(m_pOutputPtr++)=flags; }
inline void RememberLockedPointer( void *key, void *value ) { VPROF_BUFFER_PLAYBACK( "RememberLockedPointer" ); int repl=-1; int i; for(i=0;i<MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE;i++) { if ( RememberedPointerHistory[i].m_pKey==key ) break; if ( (repl == -1 ) && (RememberedPointerHistory[i].m_pRememberedPtr == 0 ) ) repl=i; } if (i != MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE ) { RememberedPointerHistory[i].m_pRememberedPtr = value; if ( value==NULL ) RememberedPointerHistory[i].m_pKey = NULL; } else { if (repl == -1 ) { Assert( 0 ); } else { RememberedPointerHistory[repl].m_pKey = key; RememberedPointerHistory[repl].m_pRememberedPtr = value; } } }
inline void *RecallLockedPointer( void *key ) { VPROF_BUFFER_PLAYBACK( "RecallLockedPointer" );
for(int i=0;i<MAXIMUM_NUMBER_OF_BUFFERS_LOCKED_AT_ONCE;i++) if ( RememberedPointerHistory[i].m_pKey == key ) return RememberedPointerHistory[i].m_pRememberedPtr; return NULL;
}
void D3DDeviceWrapper::HandleAsynchronousLockVBCommand( uint32 const *dptr ) { dptr++; LPDIRECT3DVERTEXBUFFER vb=*((LPDIRECT3DVERTEXBUFFER *) dptr); dptr+=N_DWORDS_IN_PTR; uint32 offset=*(dptr++); uint32 size=*(dptr++); uint32 flags=*(dptr++); void *locked_ptr=0; vb->Lock( offset, size, &locked_ptr, flags ); RememberLockedPointer( vb, locked_ptr ); }
void D3DDeviceWrapper::HandleAsynchronousUnLockVBCommand( uint32 const *dptr ) { dptr++; LPDIRECT3DVERTEXBUFFER vb=*((LPDIRECT3DVERTEXBUFFER *) dptr); dptr+=N_DWORDS_IN_PTR; LockedBufferContext lb=*((LockedBufferContext *) dptr); dptr+=N_DWORDS( LockedBufferContext ); size_t unlock_size=*( dptr++ ); void *locked_data=RecallLockedPointer( vb ); Assert( locked_data ); if (lb.m_pPushBuffer) { Assert( ! lb.m_pMallocedMemory ); if ( locked_data ) memcpy( locked_data, lb.m_pPushBuffer->m_BufferData, unlock_size ); lb.m_pPushBuffer->m_State = PUSHBUFFER_AVAILABLE; } else if ( lb.m_pMallocedMemory ) { Assert( ! lb.m_pPushBuffer ); if ( locked_data ) memcpy( locked_data, lb.m_pMallocedMemory, unlock_size ); delete[] lb.m_pMallocedMemory; } // now, actually unlock
RememberLockedPointer( vb, NULL ); vb->Unlock(); }
void D3DDeviceWrapper::HandleAsynchronousLockIBCommand( uint32 const *dptr ) { dptr++; LPDIRECT3DINDEXBUFFER ib=*((LPDIRECT3DINDEXBUFFER *) dptr); Assert( ib ); dptr+=N_DWORDS_IN_PTR; uint32 offset=*(dptr++); uint32 size=*(dptr++); uint32 flags=*(dptr++); void *locked_ptr=0; ib->Lock( offset, size, &locked_ptr, flags ); RememberLockedPointer( ib, locked_ptr ); }
void D3DDeviceWrapper::HandleAsynchronousUnLockIBCommand( uint32 const *dptr ) { dptr++; LPDIRECT3DINDEXBUFFER ib=*((LPDIRECT3DINDEXBUFFER *) dptr); dptr+=N_DWORDS_IN_PTR; LockedBufferContext lb=*((LockedBufferContext *) dptr); dptr+=N_DWORDS( LockedBufferContext ); size_t unlock_size=*( dptr++ ); void *locked_data=RecallLockedPointer( ib ); Assert( locked_data ); if (lb.m_pPushBuffer) { Assert( ! lb.m_pMallocedMemory ); if ( locked_data ) memcpy( locked_data, lb.m_pPushBuffer->m_BufferData, unlock_size ); lb.m_pPushBuffer->m_State = PUSHBUFFER_AVAILABLE; } else if ( lb.m_pMallocedMemory ) { Assert( ! lb.m_pPushBuffer ); if ( locked_data ) memcpy( locked_data, lb.m_pMallocedMemory, unlock_size ); delete[] lb.m_pMallocedMemory; } // now, actually unlock
RememberLockedPointer( ib, NULL ); ib->Unlock();
}
static inline void *FetchPtr( uint32 const *mem) { void **p=(void **) mem; return *p; }
#define CALC_STATS 1
#if CALC_STATS
int n_commands_executed=0; int n_pbs_executed=0; #endif
void D3DDeviceWrapper::ExecutePushBuffer( PushBuffer const* pb) { VPROF_BUFFER_PLAYBACK( "D3DDeviceWrapper::ExecutePushBuffer" ); uint32 const *dptr=pb->m_BufferData; n_pbs_executed++; for(;;) { n_commands_executed++; switch( dptr[0] ) { case PBCMD_END: { VPROF_BUFFER_PLAYBACK( "END" ); n_commands_executed--; // doesn't count
return; }
case PBCMD_SET_RENDERSTATE: { VPROF_BUFFER_PLAYBACK( "SET_RENDERSTATE" ); Dx9Device()->SetRenderState((D3DRENDERSTATETYPE) dptr[1],dptr[2]); dptr+=3; break; }
case PBCMD_SET_SAMPLER_STATE: { VPROF_BUFFER_PLAYBACK( "SET_SAMPLER_STATE" ); Dx9Device()->SetSamplerState(dptr[1], (D3DSAMPLERSTATETYPE) dptr[2], dptr[3]); dptr+=4; break; }
#ifdef DX_TO_GL_ABSTRACTION
case PBCMD_SET_RENDERSTATEINLINE: { VPROF_BUFFER_PLAYBACK( "SET_RENDERSTATEINLINE" ); Dx9Device()->SetRenderStateInline( (D3DRENDERSTATETYPE)dptr[1], dptr[2] ); dptr += 3; break; }
case PBCMD_SET_SAMPLER_STATES: { VPROF_BUFFER_PLAYBACK( "SET_SAMPLER_STATES" ); Dx9Device()->SetSamplerStates( dptr[1], dptr[2], dptr[3], dptr[4], dptr[5], dptr[6], dptr[7] ); dptr += 8; break; } #endif
case PBCMD_DRAWPRIM: { VPROF_BUFFER_PLAYBACK( "DRAWPRIM" ); Dx9Device()->DrawPrimitive( (D3DPRIMITIVETYPE) dptr[1], dptr[2], dptr[3] ); dptr+=4; break; }
#ifndef DX_TO_GL_ABSTRACTION
case PBCMD_DRAWPRIMUP_RESZ: { VPROF_BUFFER_PLAYBACK( "DRAWPRIMUP_RESZ" );
struct sPoints { FLOAT pos[3]; }; sPoints verts[1];
verts[0].pos[0] = 0.0f; verts[0].pos[1] = 0.0f; verts[0].pos[2] = 0.0f;
Dx9Device()->DrawPrimitiveUP( D3DPT_POINTLIST, 1, verts, sizeof( sPoints ) ); dptr++; break; } #endif
case PBCMD_DRAWINDEXEDPRIM: { VPROF_BUFFER_PLAYBACK( "DRAWINDEXEDPRIM" ); Dx9Device()->DrawIndexedPrimitive( (D3DPRIMITIVETYPE) dptr[1], dptr[2], dptr[3], dptr[4], dptr[5], dptr[6]); dptr+=7; break; }
case PBCMD_SET_STREAM_SOURCE: { VPROF_BUFFER_PLAYBACK( "SET_STREAM_SOURCE" ); Dx9Device()->SetStreamSource( dptr[1],(IDirect3DVertexBuffer9 *) FetchPtr(dptr+2), dptr[3],dptr[4] ); dptr += 4+N_DWORDS( IDirect3DVertexBuffer9 * ); break; }
case PBCMD_SET_TEXTURE: { VPROF_BUFFER_PLAYBACK( "SET_TEXTURE" ); Dx9Device()->SetTexture( dptr[1],(IDirect3DBaseTexture *) FetchPtr(dptr+2)); dptr += 2+N_DWORDS_IN_PTR; break; }
case PBCMD_SET_RENDER_TARGET: { VPROF_BUFFER_PLAYBACK( "SET_RENDER_TARGET" ); Dx9Device()->SetRenderTarget( dptr[1],(IDirect3DSurface *) FetchPtr(dptr+2)); dptr += 2+N_DWORDS_IN_PTR; break; }
case PBCMD_SET_PIXEL_SHADER: { VPROF_BUFFER_PLAYBACK( "SET_PIXEL_SHADER" ); Dx9Device()->SetPixelShader( (IDirect3DPixelShader9 *) FetchPtr(dptr+1)); dptr += 1+N_DWORDS_IN_PTR; break; }
case PBCMD_SET_INDICES: { VPROF_BUFFER_PLAYBACK( "SET_INDICES" ); Dx9Device()->SetIndices( (IDirect3DIndexBuffer9*) FetchPtr(dptr+1)); dptr += 1+N_DWORDS_IN_PTR; break; }
case PBCMD_SET_DEPTH_STENCIL_SURFACE: { VPROF_BUFFER_PLAYBACK( "SET_DEPTH_STENCIL_SURFACE" ); Dx9Device()->SetDepthStencilSurface( (IDirect3DSurface9*) FetchPtr(dptr+1)); dptr += 1+N_DWORDS_IN_PTR; break; }
case PBCMD_SETVIEWPORT: { VPROF_BUFFER_PLAYBACK( "SETVIEWPORT" ); Dx9Device()->SetViewport( (D3DVIEWPORT9 const *) (dptr+1) ); dptr += 1+N_DWORDS(D3DVIEWPORT9); break; }
case PBCMD_SET_VERTEX_SHADER: { VPROF_BUFFER_PLAYBACK( "SET_VERTEX_SHADER" ); Dx9Device()->SetVertexShader( (IDirect3DVertexShader9 *) FetchPtr(dptr+1)); dptr += 1+N_DWORDS_IN_PTR; break; }
case PBCMD_ASYNC_LOCK_VB: { VPROF_BUFFER_PLAYBACK( "ASYNC_LOCK_VB" ); HandleAsynchronousLockVBCommand(dptr); dptr+=1+N_DWORDS_IN_PTR+3; break; }
case PBCMD_ASYNC_UNLOCK_VB: { VPROF_BUFFER_PLAYBACK( "ASYNC_UNLOCK_VB" ); HandleAsynchronousUnLockVBCommand( dptr ); dptr+=1+N_DWORDS_IN_PTR+N_DWORDS( LockedBufferContext )+1; break; }
case PBCMD_ASYNC_LOCK_IB: { VPROF_BUFFER_PLAYBACK( "ASYNC_LOCK_IB" ); HandleAsynchronousLockIBCommand(dptr); dptr+=1+N_DWORDS_IN_PTR+3; break; }
case PBCMD_ASYNC_UNLOCK_IB: { VPROF_BUFFER_PLAYBACK( "ASYNC_UNLOCK_IB" ); HandleAsynchronousUnLockIBCommand( dptr ); dptr+=1+N_DWORDS_IN_PTR+N_DWORDS( LockedBufferContext )+1; break; }
case PBCMD_UNLOCK_VB: { VPROF_BUFFER_PLAYBACK( "UNLOCK_VB" ); IDirect3DVertexBuffer9 *p=(IDirect3DVertexBuffer9 *) FetchPtr(dptr+1); p->Unlock(); dptr += 1+N_DWORDS_IN_PTR; break; } case PBCMD_UNLOCK_IB: { VPROF_BUFFER_PLAYBACK( "UNLOCK_IB" ); IDirect3DIndexBuffer9 *p=(IDirect3DIndexBuffer9 *) FetchPtr(dptr+1); p->Unlock(); dptr += 1+N_DWORDS_IN_PTR; break; }
#ifdef DX_TO_GL_ABSTRACTION
case PBCMD_UNLOCK_ACTAULSIZE_VB: { VPROF_BUFFER_PLAYBACK( "UNLOCK_ACTUALSIZE_VB" ); IDirect3DVertexBuffer9 *p = (IDirect3DVertexBuffer9 *)FetchPtr( dptr + 1 ); p->UnlockActualSize( dptr[2] ); dptr += 1 + N_DWORDS_IN_PTR + 1; break; }
case PBCMD_UNLOCK_ACTAULSIZE_IB: { VPROF_BUFFER_PLAYBACK( "UNLOCK_ACTUALSIZE_IB" ); IDirect3DIndexBuffer9 *p = (IDirect3DIndexBuffer9 *)FetchPtr( dptr + 1 ); p->UnlockActualSize( dptr[2] ); dptr += 1 + N_DWORDS_IN_PTR + 1; break; }
case PBCMD_SET_MAX_USED_VERTEX_SHADER_CONSTANTS_HINT: { VPROF_BUFFER_PLAYBACK( "SET_MAX_USED_VERTEX_SHADER_CONSTANTS_HINT" ); Dx9Device()->SetMaxUsedVertexShaderConstantsHint( dptr[1] ); dptr += 2; break; } #endif
case PBCMD_SET_VERTEX_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_VERTEX_SHADER_CONSTANT" ); Dx9Device()->SetVertexShaderConstantF( dptr[1], (float const *) dptr+3, dptr[2]); dptr += 3+4*dptr[2]; break; } case PBCMD_SET_BOOLEAN_VERTEX_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_BOOLEAN_VERTEX_SHADER_CONSTANT" ); Dx9Device()->SetVertexShaderConstantB( dptr[1], (int const *) dptr+3, dptr[2]); dptr += 3+dptr[2]; break; }
case PBCMD_SET_INTEGER_VERTEX_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_INTEGER_VERTEX_SHADER_CONSTANT" ); Dx9Device()->SetVertexShaderConstantI( dptr[1], (int const *) dptr+3, dptr[2]); dptr += 3+4*dptr[2]; break; }
case PBCMD_SET_PIXEL_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_PIXEL_SHADER_CONSTANT" ); Dx9Device()->SetPixelShaderConstantF( dptr[1], (float const *) dptr+3, dptr[2]); dptr += 3+4*dptr[2]; break; } case PBCMD_SET_BOOLEAN_PIXEL_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_BOOLEAN_PIXEL_SHADER_CONSTANT" ); Dx9Device()->SetPixelShaderConstantB( dptr[1], (int const *) dptr+3, dptr[2]); dptr += 3+dptr[2]; break; }
case PBCMD_SET_INTEGER_PIXEL_SHADER_CONSTANT: { VPROF_BUFFER_PLAYBACK( "SET_INTEGER_PIXEL_SHADER_CONSTANT" ); Dx9Device()->SetPixelShaderConstantI( dptr[1], (int const *) dptr+3, dptr[2]); dptr += 3+4*dptr[2]; break; }
case PBCMD_BEGIN_SCENE: { VPROF_BUFFER_PLAYBACK( "BEGIN_SCENE" ); Dx9Device()->BeginScene(); dptr++; break; } case PBCMD_END_SCENE: { VPROF_BUFFER_PLAYBACK( "END_SCENE" ); Dx9Device()->EndScene(); dptr++; break; }
case PBCMD_CLEAR: { VPROF_BUFFER_PLAYBACK( "CLEAR" ); dptr++; int count=*(dptr++); D3DRECT const *pRects=0; if (count) { pRects=(D3DRECT const *) dptr; dptr+=count*N_DWORDS( D3DRECT ); } int flags=*(dptr++); D3DCOLOR color=*((D3DCOLOR const *) (dptr++)); float z=*((float const *) (dptr++)); int stencil=*(dptr++); Dx9Device()->Clear( count, pRects, flags, color, z, stencil ); break; }
case PBCMD_SET_VERTEXDECLARATION: { VPROF_BUFFER_PLAYBACK( "SET_VERTEXDECLARATION" ); Dx9Device()->SetVertexDeclaration( (IDirect3DVertexDeclaration9 *) FetchPtr(dptr+1)); dptr += 1+N_DWORDS_IN_PTR; break; }
case PBCMD_SETCLIPPLANE: { VPROF_BUFFER_PLAYBACK( "SETCLIPPLANE" ); Dx9Device()->SetClipPlane( dptr[1], (float const *) dptr+2 ); dptr+=6; } break;
case PBCMD_STRETCHRECT: { VPROF_BUFFER_PLAYBACK( "STRETCHRECT" ); dptr++; IDirect3DSurface9 *pSourceSurface=(IDirect3DSurface9 *) FetchPtr(dptr); dptr+=N_DWORDS_IN_PTR; RECT const *pSourceRect=0; if (*(dptr++)) pSourceRect=(RECT const *) dptr; dptr += N_DWORDS( RECT ); IDirect3DSurface9 *pDestSurface= (IDirect3DSurface9 *) FetchPtr( dptr ); dptr += N_DWORDS_IN_PTR; RECT const *pDestRect=0; if (*(dptr++)) pDestRect=(RECT const *) dptr; dptr += N_DWORDS( RECT ); D3DTEXTUREFILTERTYPE Filter = (D3DTEXTUREFILTERTYPE) *(dptr++); Dx9Device()->StretchRect( pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter ); } break; #ifndef DX_TO_GL_ABSTRACTION
case PBCMD_STRETCHRECT_NVAPI: { VPROF_BUFFER_PLAYBACK( "STRETCHRECTNVAPI" ); TM_ZONE( TELEMETRY_LEVEL1, TMZF_NONE, "NvAPI_D3D9_StretchRectEx_async" );
dptr++; IDirect3DResource9 *pSourceResource = (IDirect3DResource9 *)FetchPtr( dptr ); dptr += N_DWORDS_IN_PTR; RECT const *pSourceRect = 0; if ( *(dptr++) ) pSourceRect = (RECT const *)dptr; dptr += N_DWORDS( RECT ); IDirect3DResource9 *pDestResource = (IDirect3DResource9 *)FetchPtr( dptr ); dptr += N_DWORDS_IN_PTR; RECT const *pDestRect = 0; if ( *(dptr++) ) pDestRect = (RECT const *)dptr; dptr += N_DWORDS( RECT ); D3DTEXTUREFILTERTYPE Filter = (D3DTEXTUREFILTERTYPE)*(dptr++);
NvAPI_D3D9_StretchRectEx( Dx9Device(), pSourceResource, pSourceRect, pDestResource, pDestRect, Filter ); pSourceResource->Release(); } break; #endif
case PBCMD_PRESENT: { VPROF_BUFFER_PLAYBACK( "PRESENT" ); dptr++; RECT const *pSourceRect=0; if (* (dptr++) ) pSourceRect=(RECT const *) dptr; dptr+=N_DWORDS( RECT ); RECT const *pDestRect = 0; if (* (dptr++) ) pDestRect=(RECT const *) dptr; dptr+=N_DWORDS( RECT ); VD3DHWND hDestWindowOverride = (VD3DHWND) *(dptr++); RGNDATA const *pDirtyRegion=0; if ( *(dptr++) ) pDirtyRegion= (RGNDATA const *) dptr; dptr+=N_DWORDS( RGNDATA ); Dx9Device()->Present( pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion ); break; }
case PBCMD_SET_SCISSOR_RECT: { VPROF_BUFFER_PLAYBACK( "SET_SCISSOR_RECT" ); dptr++; const RECT *pRect = ( RECT * )FetchPtr( dptr ); dptr += sizeof( RECT ); Dx9Device()->SetScissorRect( pRect ); }
#ifdef DX_TO_GL_ABSTRACTION
case PBCMD_ACQUIRE_THREAD_OWNERSHIP: { VPROF_BUFFER_PLAYBACK( "ACQUIRE_THREAD_OWNERSHIP" ); Dx9Device()->AcquireThreadOwnership(); dptr++; break; }
case PBCMD_RELEASE_THREAD_OWNERSHIP: { VPROF_BUFFER_PLAYBACK( "PBCMD_RELEASE_THREAD_OWNERSHIP" ); Dx9Device()->ReleaseThreadOwnership(); dptr++; break; } #endif
} } }
#endif
|