diff options
| author | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:31:46 -0800 |
|---|---|---|
| committer | Jørgen P. Tjernø <[email protected]> | 2013-12-02 19:46:31 -0800 |
| commit | f56bb35301836e56582a575a75864392a0177875 (patch) | |
| tree | de61ddd39de3e7df52759711950b4c288592f0dc /sp/src/public/togl/linuxwin/dxabstract.h | |
| parent | Mark some more files as text. (diff) | |
| download | source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip | |
Fix line endings. WHAMMY.
Diffstat (limited to 'sp/src/public/togl/linuxwin/dxabstract.h')
| -rw-r--r-- | sp/src/public/togl/linuxwin/dxabstract.h | 2824 |
1 files changed, 1412 insertions, 1412 deletions
diff --git a/sp/src/public/togl/linuxwin/dxabstract.h b/sp/src/public/togl/linuxwin/dxabstract.h index ab5940e5..0e367329 100644 --- a/sp/src/public/togl/linuxwin/dxabstract.h +++ b/sp/src/public/togl/linuxwin/dxabstract.h @@ -1,1412 +1,1412 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// dxabstract.h
-//
-//==================================================================================================
-#ifndef DXABSTRACT_H
-#define DXABSTRACT_H
-
-#ifdef DX_TO_GL_ABSTRACTION
-
-#include "togl/rendermechanism.h"
-
-#include "tier0/platform.h"
-#include "tier0/dbg.h"
-#include "tier1/utlmap.h"
-
-// turn this on to get refcount logging from IUnknown
-#define IUNKNOWN_ALLOC_SPEW 0
-#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0
-
-TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect );
-
-struct TOGL_CLASS IUnknown
-{
- int m_refcount[2];
- bool m_mark;
-
- IUnknown()
- {
- m_refcount[0] = 1;
- m_refcount[1] = 0;
- m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them
-
- #if IUNKNOWN_ALLOC_SPEW
- if (m_mark)
- {
- GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1]));
- }
- #endif
- };
-
- virtual ~IUnknown()
- {
- #if IUNKNOWN_ALLOC_SPEW
- if (m_mark)
- {
- GLMPRINTF(("-A- IUdel (%08x) ",this ));
- }
- #endif
- };
-
- void AddRef( int which=0, char *comment = NULL )
- {
- Assert( which >= 0 );
- Assert( which < 2 );
- m_refcount[which]++;
-
- #if IUNKNOWN_ALLOC_SPEW
- if (m_mark)
- {
- GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ;
- if (!comment)
- {
- GLMPRINTF(("")) ; // place to hang a breakpoint
- }
- }
- #endif
- };
-
- ULONG __stdcall Release( int which=0, char *comment = NULL )
- {
- Assert( which >= 0 );
- Assert( which < 2 );
-
- //int oldrefcs[2] = { m_refcount[0], m_refcount[1] };
- bool deleting = false;
-
- m_refcount[which]--;
- if ( (!m_refcount[0]) && (!m_refcount[1]) )
- {
- deleting = true;
- }
-
- #if IUNKNOWN_ALLOC_SPEW
- if (m_mark)
- {
- GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":""));
- if (!comment)
- {
- GLMPRINTF(("")) ; // place to hang a breakpoint
- }
- }
- #endif
-
- if (deleting)
- {
- if (m_mark)
- {
- GLMPRINTF(("")) ; // place to hang a breakpoint
- }
- delete this;
- return 0;
- }
- else
- {
- return m_refcount[0];
- }
- };
-
- void SetMark( bool markValue, char *comment=NULL )
- {
- #if IUNKNOWN_ALLOC_SPEW
- if (!m_mark && markValue) // leading edge detect
- {
- // print the same thing that the constructor would have printed if it had been marked from the beginning
- // i.e. it's anticipated that callers asking for marking will do so right at create time
- GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"..."));
- }
- #endif
-
- m_mark = markValue;
- }
-};
-
-// ------------------------------------------------------------------------------------------------------------------------------ //
-// INTERFACES
-// ------------------------------------------------------------------------------------------------------------------------------ //
-
-struct TOGL_CLASS IDirect3DResource9 : public IUnknown
-{
- IDirect3DDevice9 *m_device; // parent device
- D3DRESOURCETYPE m_restype;
-
- DWORD SetPriority(DWORD PriorityNew);
-};
-
-struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.."
-{
- D3DSURFACE_DESC m_descZero; // desc of top level.
- CGLMTex *m_tex; // a CGLMTex can represent all forms of tex
- int m_srgbFlipCount;
-
- virtual ~IDirect3DBaseTexture9();
- D3DRESOURCETYPE TOGLMETHODCALLTYPE GetType();
- DWORD TOGLMETHODCALLTYPE GetLevelCount();
- HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
-};
-
-struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D"
-{
- IDirect3DSurface9 *m_surfZero; // surf of top level.
- virtual ~IDirect3DTexture9();
- HRESULT TOGLMETHODCALLTYPE LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
- HRESULT TOGLMETHODCALLTYPE UnlockRect(UINT Level);
- HRESULT TOGLMETHODCALLTYPE GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel);
-};
-
-struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map"
-{
- IDirect3DSurface9 *m_surfZero[6]; // surfs of top level.
- virtual ~IDirect3DCubeTexture9();
- HRESULT TOGLMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface);
- HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc);
-};
-
-struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D"
-{
- IDirect3DSurface9 *m_surfZero; // surf of top level.
- D3DVOLUME_DESC m_volDescZero; // volume desc top level
- virtual ~IDirect3DVolumeTexture9();
- HRESULT TOGLMETHODCALLTYPE LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags);
- HRESULT TOGLMETHODCALLTYPE UnlockBox(UINT Level);
- HRESULT TOGLMETHODCALLTYPE GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc );
-};
-
-
-// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip.
-// no Create method, these are filled in by the various create surface methods.
-
-struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9
-{
- virtual ~IDirect3DSurface9();
- HRESULT TOGLMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags);
- HRESULT TOGLMETHODCALLTYPE UnlockRect();
- HRESULT TOGLMETHODCALLTYPE GetDesc(D3DSURFACE_DESC *pDesc);
-
- D3DSURFACE_DESC m_desc;
- CGLMTex *m_tex;
- int m_face;
- int m_mip;
-};
-
-struct TOGL_CLASS IDirect3D9 : public IUnknown
-{
- virtual ~IDirect3D9();
-
- UINT TOGLMETHODCALLTYPE GetAdapterCount();
-
- HRESULT TOGLMETHODCALLTYPE GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps);
- HRESULT TOGLMETHODCALLTYPE GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier);
- HRESULT TOGLMETHODCALLTYPE CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat);
- UINT TOGLMETHODCALLTYPE GetAdapterModeCount (UINT Adapter,D3DFORMAT Format);
- HRESULT TOGLMETHODCALLTYPE EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode);
- HRESULT TOGLMETHODCALLTYPE CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed);
- HRESULT TOGLMETHODCALLTYPE GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode);
- HRESULT TOGLMETHODCALLTYPE CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat);
- HRESULT TOGLMETHODCALLTYPE CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels);
-
- HRESULT TOGLMETHODCALLTYPE CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface);
-};
-
-struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown
-{
- IDirect3DDevice9 *m_device;
- uint m_elemCount;
- D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ];
-
- uint8 m_VertexAttribDescToStreamIndex[256];
-
- virtual ~IDirect3DVertexDeclaration9();
-};
-
-struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown
-{
- D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT
- GLMContext *m_ctx;
- CGLMQuery *m_query;
-
- uint m_nIssueStartThreadID, m_nIssueEndThreadID;
- uint m_nIssueStartDrawCallIndex, m_nIssueEndDrawCallIndex;
- uint m_nIssueStartFrameIndex, m_nIssueEndFrameIndex;
- uint m_nIssueStartQueryCreationCounter, m_nIssueEndQueryCreationCounter;
-
- virtual ~IDirect3DQuery9();
-
- HRESULT Issue(DWORD dwIssueFlags);
- HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags);
-};
-
-struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown
-{
- GLMContext *m_ctx;
- CGLMBuffer *m_vtxBuffer;
- D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc
-
- virtual ~IDirect3DVertexBuffer9();
- HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
- HRESULT Unlock();
- void UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
-};
-
-struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown
-{
- GLMContext *m_ctx;
- CGLMBuffer *m_idxBuffer;
- D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc
-
- virtual ~IDirect3DIndexBuffer9();
-
- HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags);
- HRESULT Unlock();
- void UnlockActualSize( uint nActualSize, const void *pActualData = NULL );
-
- HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc);
-};
-
-struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown
-{
- CGLMProgram *m_pixProgram;
- uint m_pixHighWater; // count of active constant slots referenced by shader.
- uint m_pixSamplerMask; // (1<<n) mask of samplers referemnced by this pixel shader
- // this can help FlushSamplers avoid SRGB flipping on textures not being referenced...
- uint m_pixSamplerTypes; // SAMPLER_TYPE_2D, etc.
-
- virtual ~IDirect3DPixelShader9();
-};
-
-struct TOGL_CLASS IDirect3DVertexShader9 : public IDirect3DResource9 //was IUnknown
-{
- CGLMProgram *m_vtxProgram;
- uint m_vtxHighWater; // count of active constant slots referenced by shader.
- uint m_vtxHighWaterBone;
- unsigned char m_vtxAttribMap[16]; // high nibble is usage, low nibble is usageindex, array position is attrib number
- uint m_maxVertexAttrs;
-
- virtual ~IDirect3DVertexShader9();
-};
-
-#ifdef _MSC_VER
- typedef class TOGL_CLASS CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator;
- typedef class TOGL_CLASS CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack;
-#else
- typedef class CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator;
- typedef class CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack;
-#endif
-
-struct TOGL_CLASS ID3DXMatrixStack //: public IUnknown
-{
- int m_refcount[2];
- bool m_mark;
- CD3DMATRIXStack m_stack;
- int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases.
-
- ID3DXMatrixStack();
- void AddRef( int which=0, char *comment = NULL );
- ULONG Release( int which=0, char *comment = NULL );
-
- HRESULT Create( void );
-
- D3DXMATRIX* GetTop();
- void Push();
- void Pop();
- void LoadIdentity();
- void LoadMatrix( const D3DXMATRIX *pMat );
- void MultMatrix( const D3DXMATRIX *pMat );
- void MultMatrixLocal( const D3DXMATRIX *pMat );
- HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z);
-
- // Left multiply the current matrix with the computed rotation
- // matrix, counterclockwise about the given axis with the given angle.
- // (rotation is about the local origin of the object)
- HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle);
-
- // Left multiply the current matrix with the computed translation
- // matrix. (transformation is about the local origin of the object)
- HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z);
-};
-
-typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK;
-
-struct RenderTargetState_t
-{
- void clear() { V_memset( this, 0, sizeof( *this ) ); }
-
- CGLMTex *m_pRenderTargets[4];
- CGLMTex *m_pDepthStencil;
-
- inline bool RefersTo( CGLMTex * pSurf ) const
- {
- for ( uint i = 0; i < 4; i++ )
- if ( m_pRenderTargets[i] == pSurf )
- return true;
-
- if ( m_pDepthStencil == pSurf )
- return true;
-
- return false;
- }
-
- static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs )
- {
- COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) );
- uint64 lhs0 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[0];
- uint64 rhs0 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[0];
- if ( lhs0 < rhs0 )
- return true;
- else if ( lhs0 == rhs0 )
- {
- uint64 lhs1 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[1];
- uint64 rhs1 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[1];
- if ( lhs1 < rhs1 )
- return true;
- else if ( lhs1 == rhs1 )
- {
- return lhs.m_pDepthStencil < rhs.m_pDepthStencil;
- }
- }
- return false;
- }
-
- inline bool operator < ( const RenderTargetState_t &rhs ) const
- {
- return LessFunc( *this, rhs );
- }
-};
-
-typedef CUtlMap< RenderTargetState_t, CGLMFBO *> CGLMFBOMap;
-
-class simple_bitmap;
-
-struct TOGL_CLASS IDirect3DDevice9 : public IUnknown
-{
- friend class GLMContext;
- friend struct IDirect3DBaseTexture9;
- friend struct IDirect3DTexture9;
- friend struct IDirect3DCubeTexture9;
- friend struct IDirect3DVolumeTexture9;
- friend struct IDirect3DSurface9;
- friend struct IDirect3DVertexBuffer9;
- friend struct IDirect3DIndexBuffer9;
- friend struct IDirect3DPixelShader9;
- friend struct IDirect3DVertexShader9;
- friend struct IDirect3DQuery9;
- friend struct IDirect3DVertexDeclaration9;
-
- IDirect3DDevice9();
- virtual ~IDirect3DDevice9();
-
- // Create call invoked from IDirect3D9
- HRESULT TOGLMETHODCALLTYPE Create( IDirect3DDevice9Params *params );
-
- //
- // Basics
- //
- HRESULT TOGLMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters);
- HRESULT TOGLMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport);
- HRESULT TOGLMETHODCALLTYPE BeginScene();
- HRESULT TOGLMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil);
- HRESULT TOGLMETHODCALLTYPE EndScene();
- HRESULT TOGLMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion);
-
- // textures
- HRESULT TOGLMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
- HRESULT TOGLMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
- HRESULT TOGLMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture);
- HRESULT TOGLMETHODCALLTYPE SetTextureNonInline(DWORD Stage,IDirect3DBaseTexture9* pTexture);
-
- HRESULT TOGLMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture);
-
- // render targets, color and depthstencil, surfaces, blit
- HRESULT TOGLMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL);
- HRESULT TOGLMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget);
- HRESULT TOGLMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget);
-
- HRESULT TOGLMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
-
- HRESULT TOGLMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle);
- HRESULT TOGLMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil);
- HRESULT TOGLMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface);
-
- HRESULT TOGLMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface); // ? is anyone using this ?
- HRESULT TOGLMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface);
- HRESULT TOGLMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter);
-
- // pixel shaders
- HRESULT TOGLMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *debugLabel = NULL, const uint32 *pCentroidMask = NULL );
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader);
- HRESULT TOGLMETHODCALLTYPE SetPixelShaderNonInline(IDirect3DPixelShader9* pShader);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
- HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
-
- HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
- HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
-
- // vertex shaders
- HRESULT TOGLMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader, const char *pShaderName, char *debugLabel = NULL);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader);
- HRESULT TOGLMETHODCALLTYPE SetVertexShaderNonInline(IDirect3DVertexShader9* pShader);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
- HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
- HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantBNonInline(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
- HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantINonInline(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount);
-
- // POSIX only - preheating for a specific vertex/pixel shader pair - trigger GLSL link inside GLM
- HRESULT TOGLMETHODCALLTYPE LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps );
- HRESULT TOGLMETHODCALLTYPE QueryShaderPair( int index, GLMShaderPairInfo *infoOut );
-
- // vertex buffers
- HRESULT TOGLMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl);
- HRESULT TOGLMETHODCALLTYPE SetVertexDeclarationNonInline(IDirect3DVertexDeclaration9* pDecl);
-
- HRESULT TOGLMETHODCALLTYPE SetFVF(DWORD FVF); // we might not be using these ?
- HRESULT TOGLMETHODCALLTYPE GetFVF(DWORD* pFVF);
-
- HRESULT CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
- HRESULT SetStreamSourceNonInline(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride);
-
- // index buffers
- HRESULT TOGLMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData);
- HRESULT TOGLMETHODCALLTYPE SetIndicesNonInline(IDirect3DIndexBuffer9* pIndexData);
-
- // State management.
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateInline(D3DRENDERSTATETYPE State,DWORD Value);
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateConstInline(D3DRENDERSTATETYPE State,DWORD Value);
- HRESULT TOGLMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value);
-
- FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
- HRESULT TOGLMETHODCALLTYPE SetSamplerStateNonInline(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value);
-
- FORCEINLINE void TOGLMETHODCALLTYPE SetSamplerStates(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter );
- void TOGLMETHODCALLTYPE SetSamplerStatesNonInline(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter );
-
- // Draw.
- HRESULT TOGLMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount);
- HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount);
- HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride);
-
- // misc
- BOOL TOGLMETHODCALLTYPE ShowCursor(BOOL bShow);
- HRESULT TOGLMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses);
- HRESULT TOGLMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial);
- HRESULT TOGLMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable);
- HRESULT TOGLMETHODCALLTYPE SetScissorRect(CONST RECT* pRect);
- HRESULT TOGLMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery);
- HRESULT TOGLMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps);
- HRESULT TOGLMETHODCALLTYPE TestCooperativeLevel();
- HRESULT TOGLMETHODCALLTYPE EvictManagedResources();
- HRESULT TOGLMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*);
- void TOGLMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp);
-
- void TOGLMETHODCALLTYPE SaveGLState();
- void TOGLMETHODCALLTYPE RestoreGLState();
-
- // Talk to JasonM about this one. It's tricky in GL.
- HRESULT TOGLMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane);
-
- //
- //
- // **** FIXED FUNCTION STUFF - None of this stuff needs support in GL.
- //
- //
- HRESULT TOGLMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix);
- HRESULT TOGLMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value);
-
- void TOGLMETHODCALLTYPE AcquireThreadOwnership( );
- void TOGLMETHODCALLTYPE ReleaseThreadOwnership( );
- inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; }
-
- FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg );
- void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg );
-
- void DumpStatsToConsole( const CCommand *pArgs );
-
-#if GLMDEBUG
- void DumpTextures( const CCommand *pArgs );
-#endif
-
-private:
- IDirect3DDevice9( const IDirect3DDevice9& );
- IDirect3DDevice9& operator= ( const IDirect3DDevice9& );
-
- // Flushing changes to GL
- void FlushClipPlaneEquation();
- void InitStates();
- void FullFlushStates();
- void UpdateBoundFBO();
- void ResetFBOMap();
- void ScrubFBOMap( CGLMTex *pTex );
-
- // response to retired objects (when refcount goes to zero and they self-delete..)
- void ReleasedVertexDeclaration( IDirect3DVertexDeclaration9 *pDecl );
- void ReleasedTexture( IDirect3DBaseTexture9 *baseTex ); // called from texture destructor - need to scrub samplers
- void ReleasedCGLMTex( CGLMTex *pTex );
- void ReleasedSurface( IDirect3DSurface9 *surface ); // called from any surface destructor - need to scrub RT table if an RT
- void ReleasedPixelShader( IDirect3DPixelShader9 *pixelShader ); // called from IDirect3DPixelShader9 destructor
- void ReleasedVertexShader( IDirect3DVertexShader9 *vertexShader ); // called from IDirect3DVertexShader9 destructor
- void ReleasedVertexBuffer( IDirect3DVertexBuffer9 *vertexBuffer ); // called from IDirect3DVertexBuffer9 destructor
- void ReleasedIndexBuffer( IDirect3DIndexBuffer9 *indexBuffer ); // called from IDirect3DIndexBuffer9 destructor
- void ReleasedQuery( IDirect3DQuery9 *query ); // called from IDirect3DQuery9 destructor
-
- // Member variables
-
- DWORD m_nValidMarker;
-
- IDirect3DDevice9Params m_params; // mirror of the creation inputs
-
- // D3D flavor stuff
- IDirect3DSurface9 *m_pRenderTargets[4];
- IDirect3DSurface9 *m_pDepthStencil;
-
- IDirect3DSurface9 *m_pDefaultColorSurface; // default color surface.
- IDirect3DSurface9 *m_pDefaultDepthStencilSurface; // queried by GetDepthStencilSurface.
-
- IDirect3DVertexDeclaration9 *m_pVertDecl; // Set by SetVertexDeclaration...
- D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource..
- CGLMBuffer *m_vtx_buffers[ D3D_MAX_STREAMS ];
- CGLMBuffer *m_pDummy_vtx_buffer;
- D3DIndexDesc m_indices; // Set by SetIndices..
-
- IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader...
- IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader...
-
- IDirect3DBaseTexture9 *m_textures[16]; // set by SetTexture... NULL if stage inactive
- D3DSamplerDesc m_samplers[16]; // set by SetSamplerState..
- // GLM flavor stuff
- GLMContext *m_ctx;
- CGLMFBOMap *m_pFBOs;
- bool m_bFBODirty;
-
- struct ObjectStats_t
- {
- int m_nTotalFBOs;
- int m_nTotalVertexShaders;
- int m_nTotalPixelShaders;
- int m_nTotalVertexDecls;
- int m_nTotalIndexBuffers;
- int m_nTotalVertexBuffers;
- int m_nTotalRenderTargets;
- int m_nTotalTextures;
- int m_nTotalSurfaces;
- int m_nTotalQueries;
-
- void clear() { V_memset( this, 0, sizeof(* this ) ); }
-
- ObjectStats_t &operator -= ( const ObjectStats_t &rhs )
- {
- m_nTotalFBOs -= rhs.m_nTotalFBOs;
- m_nTotalVertexShaders -= rhs.m_nTotalVertexShaders;
- m_nTotalPixelShaders -= rhs.m_nTotalPixelShaders;
- m_nTotalVertexDecls -= rhs.m_nTotalVertexDecls;
- m_nTotalIndexBuffers -= rhs.m_nTotalIndexBuffers;
- m_nTotalVertexBuffers -= rhs.m_nTotalVertexBuffers;
- m_nTotalRenderTargets -= rhs.m_nTotalRenderTargets;
- m_nTotalTextures -= rhs.m_nTotalTextures;
- m_nTotalSurfaces -= rhs.m_nTotalSurfaces;
- m_nTotalQueries -= m_nTotalQueries;
- return *this;
- }
- };
- ObjectStats_t m_ObjectStats;
- ObjectStats_t m_PrevObjectStats;
- void PrintObjectStats( const ObjectStats_t &stats );
-
- // GL state
- struct
- {
- // render state buckets
- GLAlphaTestEnable_t m_AlphaTestEnable;
- GLAlphaTestFunc_t m_AlphaTestFunc;
-
- GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable;
-
- GLDepthTestEnable_t m_DepthTestEnable;
- GLDepthMask_t m_DepthMask;
- GLDepthFunc_t m_DepthFunc;
-
- GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes];
- GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes];
-
- GLColorMaskSingle_t m_ColorMaskSingle;
- GLColorMaskMultiple_t m_ColorMaskMultiple;
-
- GLCullFaceEnable_t m_CullFaceEnable;
- GLCullFrontFace_t m_CullFrontFace;
- GLPolygonMode_t m_PolygonMode;
- GLDepthBias_t m_DepthBias;
- GLScissorEnable_t m_ScissorEnable;
- GLScissorBox_t m_ScissorBox;
- GLViewportBox_t m_ViewportBox;
- GLViewportDepthRange_t m_ViewportDepthRange;
-
- GLBlendEnable_t m_BlendEnable;
- GLBlendFactor_t m_BlendFactor;
- GLBlendEquation_t m_BlendEquation;
- GLBlendColor_t m_BlendColor;
- GLBlendEnableSRGB_t m_BlendEnableSRGB;
-
- GLStencilTestEnable_t m_StencilTestEnable;
- GLStencilFunc_t m_StencilFunc;
- GLStencilOp_t m_StencilOp;
- GLStencilWriteMask_t m_StencilWriteMask;
-
- GLClearColor_t m_ClearColor;
- GLClearDepth_t m_ClearDepth;
- GLClearStencil_t m_ClearStencil;
-
- bool m_FogEnable; // not really pushed to GL, just latched here
-
- // samplers
- GLMTexSamplingParams m_samplers[ 16 ];
- } gl;
-
-#if GL_BATCH_PERF_ANALYSIS
- simple_bitmap *m_pBatch_vis_bitmap;
- uint m_nBatchVisY;
- uint m_nBatchVisFrameIndex, m_nBatchVisFileIdx;
- uint m_nNumProgramChanges;
-
- uint m_nTotalD3DCalls;
- double m_flTotalD3DTime;
- uint m_nTotalGLCalls;
- double m_flTotalGLTime;
- uint m_nTotalPrims;
-
- uint m_nOverallProgramChanges;
- uint m_nOverallDraws;
- uint m_nOverallPrims;
- uint m_nOverallD3DCalls;
- double m_flOverallD3DTime;
- uint m_nOverallGLCalls;
- double m_flOverallGLTime;
-
- double m_flOverallPresentTime;
- double m_flOverallPresentTimeSquared;
- double m_flOverallSwapWindowTime;
- double m_flOverallSwapWindowTimeSquared;
- uint m_nOverallPresents;
-#endif
-};
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value )
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetSamplerStateNonInline( Sampler, Type, Value );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- Assert( Sampler < 16 );
-
- m_ctx->SetSamplerDirty( Sampler );
-
- switch( Type )
- {
- case D3DSAMP_ADDRESSU:
- m_ctx->SetSamplerAddressU( Sampler, Value );
- break;
- case D3DSAMP_ADDRESSV:
- m_ctx->SetSamplerAddressV( Sampler, Value );
- break;
- case D3DSAMP_ADDRESSW:
- m_ctx->SetSamplerAddressW( Sampler, Value );
- break;
- case D3DSAMP_BORDERCOLOR:
- m_ctx->SetSamplerBorderColor( Sampler, Value );
- break;
- case D3DSAMP_MAGFILTER:
- m_ctx->SetSamplerMagFilter( Sampler, Value );
- break;
- case D3DSAMP_MIPFILTER:
- m_ctx->SetSamplerMipFilter( Sampler, Value );
- break;
- case D3DSAMP_MINFILTER:
- m_ctx->SetSamplerMinFilter( Sampler, Value );
- break;
- case D3DSAMP_MIPMAPLODBIAS:
- m_ctx->SetSamplerMipMapLODBias( Sampler, Value );
- break;
- case D3DSAMP_MAXMIPLEVEL:
- m_ctx->SetSamplerMaxMipLevel( Sampler, Value);
- break;
- case D3DSAMP_MAXANISOTROPY:
- m_ctx->SetSamplerMaxAnisotropy( Sampler, Value);
- break;
- case D3DSAMP_SRGBTEXTURE:
- m_samplers[ Sampler ].m_srgb = Value;
- m_ctx->SetSamplerSRGBTexture(Sampler, Value);
- break;
- case D3DSAMP_SHADOWFILTER:
- m_ctx->SetShadowFilter(Sampler, Value);
- break;
-
- default: DXABSTRACT_BREAK_ON_ERROR(); break;
- }
- return S_OK;
-#endif
-}
-
-FORCEINLINE void TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerStates(
- DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW,
- DWORD MinFilter, DWORD MagFilter, DWORD MipFilter )
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- SetSamplerStatesNonInline( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- Assert( Sampler < 16);
-
- m_ctx->SetSamplerDirty( Sampler );
-
- m_ctx->SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter );
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetTextureNonInline( Stage, pTexture );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_textures[Stage] = pTexture;
- m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL );
- return S_OK;
-#endif
-}
-
-inline GLenum D3DCompareFuncToGL( DWORD function )
-{
- switch ( function )
- {
- case D3DCMP_NEVER : return GL_NEVER; // Always fail the test.
- case D3DCMP_LESS : return GL_LESS; // Accept the new pixel if its value is less than the value of the current pixel.
- case D3DCMP_EQUAL : return GL_EQUAL; // Accept the new pixel if its value equals the value of the current pixel.
- case D3DCMP_LESSEQUAL : return GL_LEQUAL; // Accept the new pixel if its value is less than or equal to the value of the current pixel. **
- case D3DCMP_GREATER : return GL_GREATER; // Accept the new pixel if its value is greater than the value of the current pixel.
- case D3DCMP_NOTEQUAL : return GL_NOTEQUAL; // Accept the new pixel if its value does not equal the value of the current pixel.
- case D3DCMP_GREATEREQUAL: return GL_GEQUAL; // Accept the new pixel if its value is greater than or equal to the value of the current pixel.
- case D3DCMP_ALWAYS : return GL_ALWAYS; // Always pass the test.
- default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF;
- }
-}
-
-FORCEINLINE GLenum D3DBlendOperationToGL( DWORD operation )
-{
- switch (operation)
- {
- case D3DBLENDOP_ADD : return GL_FUNC_ADD; // The result is the destination added to the source. Result = Source + Destination
-
- /* not covered by dxabstract.h..
- case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination
- case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source
- case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination)
- case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination)
- */
- default:
- DXABSTRACT_BREAK_ON_ERROR();
- return 0xFFFFFFFF;
- break;
- }
-}
-
-FORCEINLINE GLenum D3DBlendFactorToGL( DWORD equation )
-{
- switch (equation)
- {
- case D3DBLEND_ZERO : return GL_ZERO; // Blend factor is (0, 0, 0, 0).
- case D3DBLEND_ONE : return GL_ONE; // Blend factor is (1, 1, 1, 1).
- case D3DBLEND_SRCCOLOR : return GL_SRC_COLOR; // Blend factor is (Rs, Gs, Bs, As).
- case D3DBLEND_INVSRCCOLOR : return GL_ONE_MINUS_SRC_COLOR; // Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As).
- case D3DBLEND_SRCALPHA : return GL_SRC_ALPHA; // Blend factor is (As, As, As, As).
- case D3DBLEND_INVSRCALPHA : return GL_ONE_MINUS_SRC_ALPHA; // Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As).
- case D3DBLEND_DESTALPHA : return GL_DST_ALPHA; // Blend factor is (Ad Ad Ad Ad).
- case D3DBLEND_INVDESTALPHA : return GL_ONE_MINUS_DST_ALPHA; // Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad).
- case D3DBLEND_DESTCOLOR : return GL_DST_COLOR; // Blend factor is (Rd, Gd, Bd, Ad).
- case D3DBLEND_INVDESTCOLOR : return GL_ONE_MINUS_DST_COLOR; // Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad).
- case D3DBLEND_SRCALPHASAT : return GL_SRC_ALPHA_SATURATE; // Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad).
-
- /*
- // these are weird.... break if we hit them
- case D3DBLEND_BOTHSRCALPHA : Assert(0); return GL_ZERO; // Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls.
- case D3DBLEND_BOTHINVSRCALPHA: Assert(0); return GL_ZERO; // Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state.
- case D3DBLEND_BLENDFACTOR : Assert(0); return GL_ZERO; // Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
-
- dxabstract.h has not heard of these, so let them hit the debugger if they come through
- case D3DBLEND_INVBLENDFACTOR: //Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
- case D3DBLEND_SRCCOLOR2: // Blend factor is (PSOutColor[1]r, PSOutColor[1]g, PSOutColor[1]b, not used). This flag is available in Direct3D 9Ex only.
- case D3DBLEND_INVSRCCOLOR2: // Blend factor is (1 - PSOutColor[1]r, 1 - PSOutColor[1]g, 1 - PSOutColor[1]b, not used)). This flag is available in Direct3D 9Ex only.
- */
- default:
- DXABSTRACT_BREAK_ON_ERROR();
- return 0xFFFFFFFF;
- break;
- }
-}
-
-
-FORCEINLINE GLenum D3DStencilOpToGL( DWORD operation )
-{
- switch( operation )
- {
- case D3DSTENCILOP_KEEP : return GL_KEEP;
- case D3DSTENCILOP_ZERO : return GL_ZERO;
- case D3DSTENCILOP_REPLACE : return GL_REPLACE;
- case D3DSTENCILOP_INCRSAT : return GL_INCR;
- case D3DSTENCILOP_DECRSAT : return GL_DECR;
- case D3DSTENCILOP_INVERT : return GL_INVERT;
- case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT;
- case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT;
- default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF;
- }
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateInline( D3DRENDERSTATETYPE State, DWORD Value )
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetRenderState( State, Value );
-#else
- TOGL_NULL_DEVICE_CHECK;
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
-
- switch (State)
- {
- case D3DRS_ZENABLE: // kGLDepthTestEnable
- {
- gl.m_DepthTestEnable.enable = Value;
- m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable );
- break;
- }
- case D3DRS_ZWRITEENABLE: // kGLDepthMask
- {
- gl.m_DepthMask.mask = Value;
- m_ctx->WriteDepthMask( &gl.m_DepthMask );
- break;
- }
- case D3DRS_ZFUNC:
- {
- // kGLDepthFunc
- GLenum func = D3DCompareFuncToGL( Value );
- gl.m_DepthFunc.func = func;
- m_ctx->WriteDepthFunc( &gl.m_DepthFunc );
- break;
- }
- case D3DRS_COLORWRITEENABLE: // kGLColorMaskSingle
- {
- gl.m_ColorMaskSingle.r = ((Value & D3DCOLORWRITEENABLE_RED) != 0) ? 0xFF : 0x00;
- gl.m_ColorMaskSingle.g = ((Value & D3DCOLORWRITEENABLE_GREEN)!= 0) ? 0xFF : 0x00;
- gl.m_ColorMaskSingle.b = ((Value & D3DCOLORWRITEENABLE_BLUE) != 0) ? 0xFF : 0x00;
- gl.m_ColorMaskSingle.a = ((Value & D3DCOLORWRITEENABLE_ALPHA)!= 0) ? 0xFF : 0x00;
- m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle );
- break;
- }
- case D3DRS_CULLMODE: // kGLCullFaceEnable / kGLCullFrontFace
- {
- switch (Value)
- {
- case D3DCULL_NONE:
- {
- gl.m_CullFaceEnable.enable = false;
- gl.m_CullFrontFace.value = GL_CCW; //doesn't matter
-
- m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
- m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
- break;
- }
-
- case D3DCULL_CW:
- {
- gl.m_CullFaceEnable.enable = true;
- gl.m_CullFrontFace.value = GL_CW; //origGL_CCW;
-
- m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
- m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
- break;
- }
- case D3DCULL_CCW:
- {
- gl.m_CullFaceEnable.enable = true;
- gl.m_CullFrontFace.value = GL_CCW; //origGL_CW;
-
- m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable );
- m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace );
- break;
- }
- default:
- {
- DXABSTRACT_BREAK_ON_ERROR();
- break;
- }
- }
- break;
- }
- //-------------------------------------------------------------------------------------------- alphablend stuff
- case D3DRS_ALPHABLENDENABLE: // kGLBlendEnable
- {
- gl.m_BlendEnable.enable = Value;
- m_ctx->WriteBlendEnable( &gl.m_BlendEnable );
- break;
- }
- case D3DRS_BLENDOP: // kGLBlendEquation // D3D blend-op ==> GL blend equation
- {
- GLenum equation = D3DBlendOperationToGL( Value );
- gl.m_BlendEquation.equation = equation;
- m_ctx->WriteBlendEquation( &gl.m_BlendEquation );
- break;
- }
- case D3DRS_SRCBLEND: // kGLBlendFactor // D3D blend-factor ==> GL blend factor
- case D3DRS_DESTBLEND: // kGLBlendFactor
- {
- GLenum factor = D3DBlendFactorToGL( Value );
-
- if (State==D3DRS_SRCBLEND)
- {
- gl.m_BlendFactor.srcfactor = factor;
- }
- else
- {
- gl.m_BlendFactor.dstfactor = factor;
- }
- m_ctx->WriteBlendFactor( &gl.m_BlendFactor );
- break;
- }
- case D3DRS_SRGBWRITEENABLE: // kGLBlendEnableSRGB
- {
- gl.m_BlendEnableSRGB.enable = Value;
- m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB );
- break;
- }
- //-------------------------------------------------------------------------------------------- alphatest stuff
- case D3DRS_ALPHATESTENABLE:
- {
- gl.m_AlphaTestEnable.enable = Value;
- m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable );
- break;
- }
- case D3DRS_ALPHAREF:
- {
- gl.m_AlphaTestFunc.ref = Value / 255.0f;
- m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc );
- break;
- }
- case D3DRS_ALPHAFUNC:
- {
- GLenum func = D3DCompareFuncToGL( Value );;
- gl.m_AlphaTestFunc.func = func;
- m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc );
- break;
- }
- //-------------------------------------------------------------------------------------------- stencil stuff
- case D3DRS_STENCILENABLE: // GLStencilTestEnable_t
- {
- gl.m_StencilTestEnable.enable = Value;
- m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable );
- break;
- }
- case D3DRS_STENCILFAIL: // GLStencilOp_t "what do you do if stencil test fails"
- {
- GLenum stencilop = D3DStencilOpToGL( Value );
- gl.m_StencilOp.sfail = stencilop;
-
- m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
- m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
- break;
- }
- case D3DRS_STENCILZFAIL: // GLStencilOp_t "what do you do if stencil test passes *but* depth test fails, if depth test happened"
- {
- GLenum stencilop = D3DStencilOpToGL( Value );
- gl.m_StencilOp.dpfail = stencilop;
-
- m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
- m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
- break;
- }
- case D3DRS_STENCILPASS: // GLStencilOp_t "what do you do if stencil test and depth test both pass"
- {
- GLenum stencilop = D3DStencilOpToGL( Value );
- gl.m_StencilOp.dppass = stencilop;
-
- m_ctx->WriteStencilOp( &gl.m_StencilOp,0 );
- m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this
- break;
- }
- case D3DRS_STENCILFUNC: // GLStencilFunc_t
- {
- GLenum stencilfunc = D3DCompareFuncToGL( Value );
- gl.m_StencilFunc.frontfunc = gl.m_StencilFunc.backfunc = stencilfunc;
-
- m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
- break;
- }
- case D3DRS_STENCILREF: // GLStencilFunc_t
- {
- gl.m_StencilFunc.ref = Value;
- m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
- break;
- }
- case D3DRS_STENCILMASK: // GLStencilFunc_t
- {
- gl.m_StencilFunc.mask = Value;
- m_ctx->WriteStencilFunc( &gl.m_StencilFunc );
- break;
- }
- case D3DRS_STENCILWRITEMASK: // GLStencilWriteMask_t
- {
- gl.m_StencilWriteMask.mask = Value;
- m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask );
- break;
- }
- case D3DRS_FOGENABLE: // none of these are implemented yet... erk
- {
- gl.m_FogEnable = (Value != 0);
- GLMPRINTF(("-D- fogenable = %d",Value ));
- break;
- }
- case D3DRS_SCISSORTESTENABLE: // kGLScissorEnable
- {
- gl.m_ScissorEnable.enable = Value;
- m_ctx->WriteScissorEnable( &gl.m_ScissorEnable );
- break;
- }
- case D3DRS_DEPTHBIAS: // kGLDepthBias
- {
- // the value in the dword is actually a float
- float fvalue = *(float*)&Value;
- gl.m_DepthBias.units = fvalue;
-
- m_ctx->WriteDepthBias( &gl.m_DepthBias );
- break;
- }
- // good ref on these: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/
- case D3DRS_SLOPESCALEDEPTHBIAS:
- {
- // the value in the dword is actually a float
- float fvalue = *(float*)&Value;
- gl.m_DepthBias.factor = fvalue;
-
- m_ctx->WriteDepthBias( &gl.m_DepthBias );
- break;
- }
- // Alpha to coverage
- case D3DRS_ADAPTIVETESS_Y:
- {
- gl.m_AlphaToCoverageEnable.enable = Value;
- m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable );
- break;
- }
- case D3DRS_CLIPPLANEENABLE: // kGLClipPlaneEnable
- {
- // d3d packs all the enables into one word.
- // we break that out so we don't do N glEnable calls to sync -
- // GLM is tracking one unique enable per plane.
- for( int i=0; i<kGLMUserClipPlanes; i++)
- {
- gl.m_ClipPlaneEnable[i].enable = (Value & (1<<i)) != 0;
- }
-
- for( int x=0; x<kGLMUserClipPlanes; x++)
- m_ctx->WriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x );
- break;
- }
- //-------------------------------------------------------------------------------------------- polygon/fill mode
- case D3DRS_FILLMODE:
- {
- GLuint mode = 0;
- switch(Value)
- {
- case D3DFILL_POINT: mode = GL_POINT; break;
- case D3DFILL_WIREFRAME: mode = GL_LINE; break;
- case D3DFILL_SOLID: mode = GL_FILL; break;
- default: DXABSTRACT_BREAK_ON_ERROR(); break;
- }
- gl.m_PolygonMode.values[0] = gl.m_PolygonMode.values[1] = mode;
- m_ctx->WritePolygonMode( &gl.m_PolygonMode );
- break;
- }
- }
-
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateConstInline( D3DRENDERSTATETYPE State, DWORD Value )
-{
- // State is a compile time constant - luckily no need to do anything special to get the compiler to optimize this case.
- return SetRenderStateInline( State, Value );
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetIndicesNonInline( pIndexData );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- // just latch it.
- m_indices.m_idxBuffer = pIndexData;
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetStreamSourceNonInline( StreamNumber, pStreamData, OffsetInBytes, Stride );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- Assert( StreamNumber < D3D_MAX_STREAMS );
- Assert( ( Stride & 3 ) == 0 ); // we support non-DWORD aligned strides, but on some drivers (like AMD's) perf goes off a cliff
-
- // perfectly legal to see a vertex buffer of NULL get passed in here.
- // so we need an array to track these.
- // OK, we are being given the stride, we don't need to calc it..
-
- GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_name: -1, OffsetInBytes, Stride));
-
- if ( !pStreamData )
- {
- OffsetInBytes = 0;
- Stride = 0;
-
- m_vtx_buffers[ StreamNumber ] = m_pDummy_vtx_buffer;
- }
- else
- {
- // We do not support strides of 0
- Assert( Stride > 0 );
- m_vtx_buffers[ StreamNumber ] = pStreamData->m_vtxBuffer;
- }
-
- m_streams[ StreamNumber ].m_vtxBuffer = pStreamData;
- m_streams[ StreamNumber ].m_offset = OffsetInBytes;
- m_streams[ StreamNumber ].m_stride = Stride;
-
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) // groups of 4 floats!
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetVertexShaderConstantFNonInline( StartRegister, pConstantData, Vector4fCount );
-#else
- TOGL_NULL_DEVICE_CHECK;
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetProgramParametersF( kGLMVertexProgram, StartRegister, (float *)pConstantData, Vector4fCount );
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetVertexShaderConstantBNonInline( StartRegister, pConstantData, BoolCount );
-#else
- TOGL_NULL_DEVICE_CHECK;
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetProgramParametersB( kGLMVertexProgram, StartRegister, (int *)pConstantData, BoolCount );
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT IDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) // groups of 4 ints!
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetVertexShaderConstantINonInline( StartRegister, pConstantData, Vector4iCount );
-#else
- TOGL_NULL_DEVICE_CHECK;
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetProgramParametersI( kGLMVertexProgram, StartRegister, (int *)pConstantData, Vector4iCount );
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetPixelShaderConstantFNonInline(StartRegister, pConstantData, Vector4fCount);
-#else
- TOGL_NULL_DEVICE_CHECK;
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetProgramParametersF( kGLMFragmentProgram, StartRegister, (float *)pConstantData, Vector4fCount );
- return S_OK;
-#endif
-}
-
-HRESULT IDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetVertexShaderNonInline(pShader);
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetVertexProgram( pShader ? pShader->m_vtxProgram : NULL );
- m_vertexShader = pShader;
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetPixelShaderNonInline(pShader);
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetFragmentProgram( pShader ? pShader->m_pixProgram : NULL );
- m_pixelShader = pShader;
- return S_OK;
-#endif
-}
-
-FORCEINLINE HRESULT IDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl)
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetVertexDeclarationNonInline(pDecl);
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_pVertDecl = pDecl;
- return S_OK;
-#endif
-}
-
-FORCEINLINE void IDirect3DDevice9::SetMaxUsedVertexShaderConstantsHint( uint nMaxReg )
-{
-#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS
- return SetMaxUsedVertexShaderConstantsHintNonInline( nMaxReg );
-#else
- Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() );
- m_ctx->SetMaxUsedVertexShaderConstantsHint( nMaxReg );
-#endif
-}
-
-// ------------------------------------------------------------------------------------------------------------------------------ //
-// D3DX
-// ------------------------------------------------------------------------------------------------------------------------------ //
-struct ID3DXInclude
-{
- virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes);
- virtual HRESULT Close(LPCVOID pData);
-};
-typedef ID3DXInclude* LPD3DXINCLUDE;
-
-
-struct TOGL_CLASS ID3DXBuffer : public IUnknown
-{
- void* GetBufferPointer();
- DWORD GetBufferSize();
-};
-
-typedef ID3DXBuffer* LPD3DXBUFFER;
-
-class ID3DXConstantTable : public IUnknown
-{
-};
-typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE;
-
-TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice );
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 );
-TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM );
-
-TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack);
-TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * );
-
-TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
-{
- pOut->x = pV1->x - pV2->x;
- pOut->y = pV1->y - pV2->y;
- pOut->z = pV1->z - pV2->z;
- return pOut;
-}
-
-TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
-{
- D3DXVECTOR3 v;
-
- v.x = pV1->y * pV2->z - pV1->z * pV2->y;
- v.y = pV1->z * pV2->x - pV1->x * pV2->z;
- v.z = pV1->x * pV2->y - pV1->y * pV2->x;
-
- *pOut = v;
- return pOut;
-}
-
-TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 )
-{
- return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z;
-}
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM );
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM );
-
-TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP);
-
-TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM );
-
-
-TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV );
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z );
-
-// Build an ortho projection matrix. (right-handed)
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf );
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf );
-
-TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf );
-
-// Transform a plane by a matrix. The vector (a,b,c) must be normal.
-// M should be the inverse transpose of the transformation desired.
-TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM );
-
-TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion);
-
-TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions );
-
-TOGL_INTERFACE HRESULT D3DXCompileShader(
- LPCSTR pSrcData,
- UINT SrcDataLen,
- CONST D3DXMACRO* pDefines,
- LPD3DXINCLUDE pInclude,
- LPCSTR pFunctionName,
- LPCSTR pProfile,
- DWORD Flags,
- LPD3DXBUFFER* ppShader,
- LPD3DXBUFFER* ppErrorMsgs,
- LPD3DXCONSTANTTABLE* ppConstantTable);
-
-// fake D3D usage constant for SRGB tex creation
-#define D3DUSAGE_TEXTURE_SRGB (0x80000000L)
-
-#else
-
- //USE_ACTUAL_DX
- #ifndef WIN32
- #error sorry man
- #endif
-
- #ifdef _X360
- #include "d3d9.h"
- #include "d3dx9.h"
- #else
- #include <windows.h>
- #include "../../dx9sdk/include/d3d9.h"
- #include "../../dx9sdk/include/d3dx9.h"
- #endif
- typedef HWND VD3DHWND;
-
-#endif // DX_TO_GL_ABSTRACTION
-
-#endif // DXABSTRACT_H
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// dxabstract.h +// +//================================================================================================== +#ifndef DXABSTRACT_H +#define DXABSTRACT_H + +#ifdef DX_TO_GL_ABSTRACTION + +#include "togl/rendermechanism.h" + +#include "tier0/platform.h" +#include "tier0/dbg.h" +#include "tier1/utlmap.h" + +// turn this on to get refcount logging from IUnknown +#define IUNKNOWN_ALLOC_SPEW 0 +#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0 + +TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect ); + +struct TOGL_CLASS IUnknown +{ + int m_refcount[2]; + bool m_mark; + + IUnknown() + { + m_refcount[0] = 1; + m_refcount[1] = 0; + m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1])); + } + #endif + }; + + virtual ~IUnknown() + { + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUdel (%08x) ",this )); + } + #endif + }; + + void AddRef( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + m_refcount[which]++; + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ; + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + }; + + ULONG __stdcall Release( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + + //int oldrefcs[2] = { m_refcount[0], m_refcount[1] }; + bool deleting = false; + + m_refcount[which]--; + if ( (!m_refcount[0]) && (!m_refcount[1]) ) + { + deleting = true; + } + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":"")); + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + + if (deleting) + { + if (m_mark) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + delete this; + return 0; + } + else + { + return m_refcount[0]; + } + }; + + void SetMark( bool markValue, char *comment=NULL ) + { + #if IUNKNOWN_ALLOC_SPEW + if (!m_mark && markValue) // leading edge detect + { + // print the same thing that the constructor would have printed if it had been marked from the beginning + // i.e. it's anticipated that callers asking for marking will do so right at create time + GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"...")); + } + #endif + + m_mark = markValue; + } +}; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// INTERFACES +// ------------------------------------------------------------------------------------------------------------------------------ // + +struct TOGL_CLASS IDirect3DResource9 : public IUnknown +{ + IDirect3DDevice9 *m_device; // parent device + D3DRESOURCETYPE m_restype; + + DWORD SetPriority(DWORD PriorityNew); +}; + +struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.." +{ + D3DSURFACE_DESC m_descZero; // desc of top level. + CGLMTex *m_tex; // a CGLMTex can represent all forms of tex + int m_srgbFlipCount; + + virtual ~IDirect3DBaseTexture9(); + D3DRESOURCETYPE TOGLMETHODCALLTYPE GetType(); + DWORD TOGLMETHODCALLTYPE GetLevelCount(); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + virtual ~IDirect3DTexture9(); + HRESULT TOGLMETHODCALLTYPE LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockRect(UINT Level); + HRESULT TOGLMETHODCALLTYPE GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel); +}; + +struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map" +{ + IDirect3DSurface9 *m_surfZero[6]; // surfs of top level. + virtual ~IDirect3DCubeTexture9(); + HRESULT TOGLMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + D3DVOLUME_DESC m_volDescZero; // volume desc top level + virtual ~IDirect3DVolumeTexture9(); + HRESULT TOGLMETHODCALLTYPE LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockBox(UINT Level); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc ); +}; + + +// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip. +// no Create method, these are filled in by the various create surface methods. + +struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9 +{ + virtual ~IDirect3DSurface9(); + HRESULT TOGLMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockRect(); + HRESULT TOGLMETHODCALLTYPE GetDesc(D3DSURFACE_DESC *pDesc); + + D3DSURFACE_DESC m_desc; + CGLMTex *m_tex; + int m_face; + int m_mip; +}; + +struct TOGL_CLASS IDirect3D9 : public IUnknown +{ + virtual ~IDirect3D9(); + + UINT TOGLMETHODCALLTYPE GetAdapterCount(); + + HRESULT TOGLMETHODCALLTYPE GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps); + HRESULT TOGLMETHODCALLTYPE GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier); + HRESULT TOGLMETHODCALLTYPE CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat); + UINT TOGLMETHODCALLTYPE GetAdapterModeCount (UINT Adapter,D3DFORMAT Format); + HRESULT TOGLMETHODCALLTYPE EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode); + HRESULT TOGLMETHODCALLTYPE CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed); + HRESULT TOGLMETHODCALLTYPE GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode); + HRESULT TOGLMETHODCALLTYPE CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat); + HRESULT TOGLMETHODCALLTYPE CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels); + + HRESULT TOGLMETHODCALLTYPE CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface); +}; + +struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown +{ + IDirect3DDevice9 *m_device; + uint m_elemCount; + D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ]; + + uint8 m_VertexAttribDescToStreamIndex[256]; + + virtual ~IDirect3DVertexDeclaration9(); +}; + +struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown +{ + D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT + GLMContext *m_ctx; + CGLMQuery *m_query; + + uint m_nIssueStartThreadID, m_nIssueEndThreadID; + uint m_nIssueStartDrawCallIndex, m_nIssueEndDrawCallIndex; + uint m_nIssueStartFrameIndex, m_nIssueEndFrameIndex; + uint m_nIssueStartQueryCreationCounter, m_nIssueEndQueryCreationCounter; + + virtual ~IDirect3DQuery9(); + + HRESULT Issue(DWORD dwIssueFlags); + HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags); +}; + +struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown +{ + GLMContext *m_ctx; + CGLMBuffer *m_vtxBuffer; + D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc + + virtual ~IDirect3DVertexBuffer9(); + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + void UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); +}; + +struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown +{ + GLMContext *m_ctx; + CGLMBuffer *m_idxBuffer; + D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc + + virtual ~IDirect3DIndexBuffer9(); + + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + void UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); + + HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown +{ + CGLMProgram *m_pixProgram; + uint m_pixHighWater; // count of active constant slots referenced by shader. + uint m_pixSamplerMask; // (1<<n) mask of samplers referemnced by this pixel shader + // this can help FlushSamplers avoid SRGB flipping on textures not being referenced... + uint m_pixSamplerTypes; // SAMPLER_TYPE_2D, etc. + + virtual ~IDirect3DPixelShader9(); +}; + +struct TOGL_CLASS IDirect3DVertexShader9 : public IDirect3DResource9 //was IUnknown +{ + CGLMProgram *m_vtxProgram; + uint m_vtxHighWater; // count of active constant slots referenced by shader. + uint m_vtxHighWaterBone; + unsigned char m_vtxAttribMap[16]; // high nibble is usage, low nibble is usageindex, array position is attrib number + uint m_maxVertexAttrs; + + virtual ~IDirect3DVertexShader9(); +}; + +#ifdef _MSC_VER + typedef class TOGL_CLASS CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator; + typedef class TOGL_CLASS CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack; +#else + typedef class CUtlMemory<D3DMATRIX> CD3DMATRIXAllocator; + typedef class CUtlVector<D3DMATRIX, CD3DMATRIXAllocator> CD3DMATRIXStack; +#endif + +struct TOGL_CLASS ID3DXMatrixStack //: public IUnknown +{ + int m_refcount[2]; + bool m_mark; + CD3DMATRIXStack m_stack; + int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases. + + ID3DXMatrixStack(); + void AddRef( int which=0, char *comment = NULL ); + ULONG Release( int which=0, char *comment = NULL ); + + HRESULT Create( void ); + + D3DXMATRIX* GetTop(); + void Push(); + void Pop(); + void LoadIdentity(); + void LoadMatrix( const D3DXMATRIX *pMat ); + void MultMatrix( const D3DXMATRIX *pMat ); + void MultMatrixLocal( const D3DXMATRIX *pMat ); + HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z); + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle); + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z); +}; + +typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK; + +struct RenderTargetState_t +{ + void clear() { V_memset( this, 0, sizeof( *this ) ); } + + CGLMTex *m_pRenderTargets[4]; + CGLMTex *m_pDepthStencil; + + inline bool RefersTo( CGLMTex * pSurf ) const + { + for ( uint i = 0; i < 4; i++ ) + if ( m_pRenderTargets[i] == pSurf ) + return true; + + if ( m_pDepthStencil == pSurf ) + return true; + + return false; + } + + static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs ) + { + COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) ); + uint64 lhs0 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[0]; + uint64 rhs0 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[0]; + if ( lhs0 < rhs0 ) + return true; + else if ( lhs0 == rhs0 ) + { + uint64 lhs1 = reinterpret_cast<const uint64 *>(lhs.m_pRenderTargets)[1]; + uint64 rhs1 = reinterpret_cast<const uint64 *>(rhs.m_pRenderTargets)[1]; + if ( lhs1 < rhs1 ) + return true; + else if ( lhs1 == rhs1 ) + { + return lhs.m_pDepthStencil < rhs.m_pDepthStencil; + } + } + return false; + } + + inline bool operator < ( const RenderTargetState_t &rhs ) const + { + return LessFunc( *this, rhs ); + } +}; + +typedef CUtlMap< RenderTargetState_t, CGLMFBO *> CGLMFBOMap; + +class simple_bitmap; + +struct TOGL_CLASS IDirect3DDevice9 : public IUnknown +{ + friend class GLMContext; + friend struct IDirect3DBaseTexture9; + friend struct IDirect3DTexture9; + friend struct IDirect3DCubeTexture9; + friend struct IDirect3DVolumeTexture9; + friend struct IDirect3DSurface9; + friend struct IDirect3DVertexBuffer9; + friend struct IDirect3DIndexBuffer9; + friend struct IDirect3DPixelShader9; + friend struct IDirect3DVertexShader9; + friend struct IDirect3DQuery9; + friend struct IDirect3DVertexDeclaration9; + + IDirect3DDevice9(); + virtual ~IDirect3DDevice9(); + + // Create call invoked from IDirect3D9 + HRESULT TOGLMETHODCALLTYPE Create( IDirect3DDevice9Params *params ); + + // + // Basics + // + HRESULT TOGLMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters); + HRESULT TOGLMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport); + HRESULT TOGLMETHODCALLTYPE BeginScene(); + HRESULT TOGLMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil); + HRESULT TOGLMETHODCALLTYPE EndScene(); + HRESULT TOGLMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion); + + // textures + HRESULT TOGLMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture); + HRESULT TOGLMETHODCALLTYPE SetTextureNonInline(DWORD Stage,IDirect3DBaseTexture9* pTexture); + + HRESULT TOGLMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture); + + // render targets, color and depthstencil, surfaces, blit + HRESULT TOGLMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget); + HRESULT TOGLMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget); + + HRESULT TOGLMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle); + + HRESULT TOGLMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle); + HRESULT TOGLMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil); + HRESULT TOGLMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface); + + HRESULT TOGLMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface); // ? is anyone using this ? + HRESULT TOGLMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface); + HRESULT TOGLMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter); + + // pixel shaders + HRESULT TOGLMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *debugLabel = NULL, const uint32 *pCentroidMask = NULL ); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderNonInline(IDirect3DPixelShader9* pShader); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + + // vertex shaders + HRESULT TOGLMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader, const char *pShaderName, char *debugLabel = NULL); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderNonInline(IDirect3DVertexShader9* pShader); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantBNonInline(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantINonInline(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + + // POSIX only - preheating for a specific vertex/pixel shader pair - trigger GLSL link inside GLM + HRESULT TOGLMETHODCALLTYPE LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps ); + HRESULT TOGLMETHODCALLTYPE QueryShaderPair( int index, GLMShaderPairInfo *infoOut ); + + // vertex buffers + HRESULT TOGLMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl); + HRESULT TOGLMETHODCALLTYPE SetVertexDeclarationNonInline(IDirect3DVertexDeclaration9* pDecl); + + HRESULT TOGLMETHODCALLTYPE SetFVF(DWORD FVF); // we might not be using these ? + HRESULT TOGLMETHODCALLTYPE GetFVF(DWORD* pFVF); + + HRESULT CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); + HRESULT SetStreamSourceNonInline(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); + + // index buffers + HRESULT TOGLMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData); + HRESULT TOGLMETHODCALLTYPE SetIndicesNonInline(IDirect3DIndexBuffer9* pIndexData); + + // State management. + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateInline(D3DRENDERSTATETYPE State,DWORD Value); + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateConstInline(D3DRENDERSTATETYPE State,DWORD Value); + HRESULT TOGLMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value); + HRESULT TOGLMETHODCALLTYPE SetSamplerStateNonInline(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value); + + FORCEINLINE void TOGLMETHODCALLTYPE SetSamplerStates(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter ); + void TOGLMETHODCALLTYPE SetSamplerStatesNonInline(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter ); + + // Draw. + HRESULT TOGLMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount); + HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount); + HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride); + + // misc + BOOL TOGLMETHODCALLTYPE ShowCursor(BOOL bShow); + HRESULT TOGLMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses); + HRESULT TOGLMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial); + HRESULT TOGLMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable); + HRESULT TOGLMETHODCALLTYPE SetScissorRect(CONST RECT* pRect); + HRESULT TOGLMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery); + HRESULT TOGLMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps); + HRESULT TOGLMETHODCALLTYPE TestCooperativeLevel(); + HRESULT TOGLMETHODCALLTYPE EvictManagedResources(); + HRESULT TOGLMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*); + void TOGLMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp); + + void TOGLMETHODCALLTYPE SaveGLState(); + void TOGLMETHODCALLTYPE RestoreGLState(); + + // Talk to JasonM about this one. It's tricky in GL. + HRESULT TOGLMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane); + + // + // + // **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. + // + // + HRESULT TOGLMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix); + HRESULT TOGLMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value); + + void TOGLMETHODCALLTYPE AcquireThreadOwnership( ); + void TOGLMETHODCALLTYPE ReleaseThreadOwnership( ); + inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; } + + FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg ); + void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg ); + + void DumpStatsToConsole( const CCommand *pArgs ); + +#if GLMDEBUG + void DumpTextures( const CCommand *pArgs ); +#endif + +private: + IDirect3DDevice9( const IDirect3DDevice9& ); + IDirect3DDevice9& operator= ( const IDirect3DDevice9& ); + + // Flushing changes to GL + void FlushClipPlaneEquation(); + void InitStates(); + void FullFlushStates(); + void UpdateBoundFBO(); + void ResetFBOMap(); + void ScrubFBOMap( CGLMTex *pTex ); + + // response to retired objects (when refcount goes to zero and they self-delete..) + void ReleasedVertexDeclaration( IDirect3DVertexDeclaration9 *pDecl ); + void ReleasedTexture( IDirect3DBaseTexture9 *baseTex ); // called from texture destructor - need to scrub samplers + void ReleasedCGLMTex( CGLMTex *pTex ); + void ReleasedSurface( IDirect3DSurface9 *surface ); // called from any surface destructor - need to scrub RT table if an RT + void ReleasedPixelShader( IDirect3DPixelShader9 *pixelShader ); // called from IDirect3DPixelShader9 destructor + void ReleasedVertexShader( IDirect3DVertexShader9 *vertexShader ); // called from IDirect3DVertexShader9 destructor + void ReleasedVertexBuffer( IDirect3DVertexBuffer9 *vertexBuffer ); // called from IDirect3DVertexBuffer9 destructor + void ReleasedIndexBuffer( IDirect3DIndexBuffer9 *indexBuffer ); // called from IDirect3DIndexBuffer9 destructor + void ReleasedQuery( IDirect3DQuery9 *query ); // called from IDirect3DQuery9 destructor + + // Member variables + + DWORD m_nValidMarker; + + IDirect3DDevice9Params m_params; // mirror of the creation inputs + + // D3D flavor stuff + IDirect3DSurface9 *m_pRenderTargets[4]; + IDirect3DSurface9 *m_pDepthStencil; + + IDirect3DSurface9 *m_pDefaultColorSurface; // default color surface. + IDirect3DSurface9 *m_pDefaultDepthStencilSurface; // queried by GetDepthStencilSurface. + + IDirect3DVertexDeclaration9 *m_pVertDecl; // Set by SetVertexDeclaration... + D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource.. + CGLMBuffer *m_vtx_buffers[ D3D_MAX_STREAMS ]; + CGLMBuffer *m_pDummy_vtx_buffer; + D3DIndexDesc m_indices; // Set by SetIndices.. + + IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader... + IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader... + + IDirect3DBaseTexture9 *m_textures[16]; // set by SetTexture... NULL if stage inactive + D3DSamplerDesc m_samplers[16]; // set by SetSamplerState.. + // GLM flavor stuff + GLMContext *m_ctx; + CGLMFBOMap *m_pFBOs; + bool m_bFBODirty; + + struct ObjectStats_t + { + int m_nTotalFBOs; + int m_nTotalVertexShaders; + int m_nTotalPixelShaders; + int m_nTotalVertexDecls; + int m_nTotalIndexBuffers; + int m_nTotalVertexBuffers; + int m_nTotalRenderTargets; + int m_nTotalTextures; + int m_nTotalSurfaces; + int m_nTotalQueries; + + void clear() { V_memset( this, 0, sizeof(* this ) ); } + + ObjectStats_t &operator -= ( const ObjectStats_t &rhs ) + { + m_nTotalFBOs -= rhs.m_nTotalFBOs; + m_nTotalVertexShaders -= rhs.m_nTotalVertexShaders; + m_nTotalPixelShaders -= rhs.m_nTotalPixelShaders; + m_nTotalVertexDecls -= rhs.m_nTotalVertexDecls; + m_nTotalIndexBuffers -= rhs.m_nTotalIndexBuffers; + m_nTotalVertexBuffers -= rhs.m_nTotalVertexBuffers; + m_nTotalRenderTargets -= rhs.m_nTotalRenderTargets; + m_nTotalTextures -= rhs.m_nTotalTextures; + m_nTotalSurfaces -= rhs.m_nTotalSurfaces; + m_nTotalQueries -= m_nTotalQueries; + return *this; + } + }; + ObjectStats_t m_ObjectStats; + ObjectStats_t m_PrevObjectStats; + void PrintObjectStats( const ObjectStats_t &stats ); + + // GL state + struct + { + // render state buckets + GLAlphaTestEnable_t m_AlphaTestEnable; + GLAlphaTestFunc_t m_AlphaTestFunc; + + GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable; + + GLDepthTestEnable_t m_DepthTestEnable; + GLDepthMask_t m_DepthMask; + GLDepthFunc_t m_DepthFunc; + + GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes]; + GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes]; + + GLColorMaskSingle_t m_ColorMaskSingle; + GLColorMaskMultiple_t m_ColorMaskMultiple; + + GLCullFaceEnable_t m_CullFaceEnable; + GLCullFrontFace_t m_CullFrontFace; + GLPolygonMode_t m_PolygonMode; + GLDepthBias_t m_DepthBias; + GLScissorEnable_t m_ScissorEnable; + GLScissorBox_t m_ScissorBox; + GLViewportBox_t m_ViewportBox; + GLViewportDepthRange_t m_ViewportDepthRange; + + GLBlendEnable_t m_BlendEnable; + GLBlendFactor_t m_BlendFactor; + GLBlendEquation_t m_BlendEquation; + GLBlendColor_t m_BlendColor; + GLBlendEnableSRGB_t m_BlendEnableSRGB; + + GLStencilTestEnable_t m_StencilTestEnable; + GLStencilFunc_t m_StencilFunc; + GLStencilOp_t m_StencilOp; + GLStencilWriteMask_t m_StencilWriteMask; + + GLClearColor_t m_ClearColor; + GLClearDepth_t m_ClearDepth; + GLClearStencil_t m_ClearStencil; + + bool m_FogEnable; // not really pushed to GL, just latched here + + // samplers + GLMTexSamplingParams m_samplers[ 16 ]; + } gl; + +#if GL_BATCH_PERF_ANALYSIS + simple_bitmap *m_pBatch_vis_bitmap; + uint m_nBatchVisY; + uint m_nBatchVisFrameIndex, m_nBatchVisFileIdx; + uint m_nNumProgramChanges; + + uint m_nTotalD3DCalls; + double m_flTotalD3DTime; + uint m_nTotalGLCalls; + double m_flTotalGLTime; + uint m_nTotalPrims; + + uint m_nOverallProgramChanges; + uint m_nOverallDraws; + uint m_nOverallPrims; + uint m_nOverallD3DCalls; + double m_flOverallD3DTime; + uint m_nOverallGLCalls; + double m_flOverallGLTime; + + double m_flOverallPresentTime; + double m_flOverallPresentTimeSquared; + double m_flOverallSwapWindowTime; + double m_flOverallSwapWindowTimeSquared; + uint m_nOverallPresents; +#endif +}; + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetSamplerStateNonInline( Sampler, Type, Value ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( Sampler < 16 ); + + m_ctx->SetSamplerDirty( Sampler ); + + switch( Type ) + { + case D3DSAMP_ADDRESSU: + m_ctx->SetSamplerAddressU( Sampler, Value ); + break; + case D3DSAMP_ADDRESSV: + m_ctx->SetSamplerAddressV( Sampler, Value ); + break; + case D3DSAMP_ADDRESSW: + m_ctx->SetSamplerAddressW( Sampler, Value ); + break; + case D3DSAMP_BORDERCOLOR: + m_ctx->SetSamplerBorderColor( Sampler, Value ); + break; + case D3DSAMP_MAGFILTER: + m_ctx->SetSamplerMagFilter( Sampler, Value ); + break; + case D3DSAMP_MIPFILTER: + m_ctx->SetSamplerMipFilter( Sampler, Value ); + break; + case D3DSAMP_MINFILTER: + m_ctx->SetSamplerMinFilter( Sampler, Value ); + break; + case D3DSAMP_MIPMAPLODBIAS: + m_ctx->SetSamplerMipMapLODBias( Sampler, Value ); + break; + case D3DSAMP_MAXMIPLEVEL: + m_ctx->SetSamplerMaxMipLevel( Sampler, Value); + break; + case D3DSAMP_MAXANISOTROPY: + m_ctx->SetSamplerMaxAnisotropy( Sampler, Value); + break; + case D3DSAMP_SRGBTEXTURE: + m_samplers[ Sampler ].m_srgb = Value; + m_ctx->SetSamplerSRGBTexture(Sampler, Value); + break; + case D3DSAMP_SHADOWFILTER: + m_ctx->SetShadowFilter(Sampler, Value); + break; + + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + return S_OK; +#endif +} + +FORCEINLINE void TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerStates( + DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, + DWORD MinFilter, DWORD MagFilter, DWORD MipFilter ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + SetSamplerStatesNonInline( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( Sampler < 16); + + m_ctx->SetSamplerDirty( Sampler ); + + m_ctx->SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter ); +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetTextureNonInline( Stage, pTexture ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_textures[Stage] = pTexture; + m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL ); + return S_OK; +#endif +} + +inline GLenum D3DCompareFuncToGL( DWORD function ) +{ + switch ( function ) + { + case D3DCMP_NEVER : return GL_NEVER; // Always fail the test. + case D3DCMP_LESS : return GL_LESS; // Accept the new pixel if its value is less than the value of the current pixel. + case D3DCMP_EQUAL : return GL_EQUAL; // Accept the new pixel if its value equals the value of the current pixel. + case D3DCMP_LESSEQUAL : return GL_LEQUAL; // Accept the new pixel if its value is less than or equal to the value of the current pixel. ** + case D3DCMP_GREATER : return GL_GREATER; // Accept the new pixel if its value is greater than the value of the current pixel. + case D3DCMP_NOTEQUAL : return GL_NOTEQUAL; // Accept the new pixel if its value does not equal the value of the current pixel. + case D3DCMP_GREATEREQUAL: return GL_GEQUAL; // Accept the new pixel if its value is greater than or equal to the value of the current pixel. + case D3DCMP_ALWAYS : return GL_ALWAYS; // Always pass the test. + default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF; + } +} + +FORCEINLINE GLenum D3DBlendOperationToGL( DWORD operation ) +{ + switch (operation) + { + case D3DBLENDOP_ADD : return GL_FUNC_ADD; // The result is the destination added to the source. Result = Source + Destination + + /* not covered by dxabstract.h.. + case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination + case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source + case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination) + case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination) + */ + default: + DXABSTRACT_BREAK_ON_ERROR(); + return 0xFFFFFFFF; + break; + } +} + +FORCEINLINE GLenum D3DBlendFactorToGL( DWORD equation ) +{ + switch (equation) + { + case D3DBLEND_ZERO : return GL_ZERO; // Blend factor is (0, 0, 0, 0). + case D3DBLEND_ONE : return GL_ONE; // Blend factor is (1, 1, 1, 1). + case D3DBLEND_SRCCOLOR : return GL_SRC_COLOR; // Blend factor is (Rs, Gs, Bs, As). + case D3DBLEND_INVSRCCOLOR : return GL_ONE_MINUS_SRC_COLOR; // Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As). + case D3DBLEND_SRCALPHA : return GL_SRC_ALPHA; // Blend factor is (As, As, As, As). + case D3DBLEND_INVSRCALPHA : return GL_ONE_MINUS_SRC_ALPHA; // Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As). + case D3DBLEND_DESTALPHA : return GL_DST_ALPHA; // Blend factor is (Ad Ad Ad Ad). + case D3DBLEND_INVDESTALPHA : return GL_ONE_MINUS_DST_ALPHA; // Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad). + case D3DBLEND_DESTCOLOR : return GL_DST_COLOR; // Blend factor is (Rd, Gd, Bd, Ad). + case D3DBLEND_INVDESTCOLOR : return GL_ONE_MINUS_DST_COLOR; // Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad). + case D3DBLEND_SRCALPHASAT : return GL_SRC_ALPHA_SATURATE; // Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad). + + /* + // these are weird.... break if we hit them + case D3DBLEND_BOTHSRCALPHA : Assert(0); return GL_ZERO; // Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls. + case D3DBLEND_BOTHINVSRCALPHA: Assert(0); return GL_ZERO; // Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state. + case D3DBLEND_BLENDFACTOR : Assert(0); return GL_ZERO; // Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9. + + dxabstract.h has not heard of these, so let them hit the debugger if they come through + case D3DBLEND_INVBLENDFACTOR: //Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9. + case D3DBLEND_SRCCOLOR2: // Blend factor is (PSOutColor[1]r, PSOutColor[1]g, PSOutColor[1]b, not used). This flag is available in Direct3D 9Ex only. + case D3DBLEND_INVSRCCOLOR2: // Blend factor is (1 - PSOutColor[1]r, 1 - PSOutColor[1]g, 1 - PSOutColor[1]b, not used)). This flag is available in Direct3D 9Ex only. + */ + default: + DXABSTRACT_BREAK_ON_ERROR(); + return 0xFFFFFFFF; + break; + } +} + + +FORCEINLINE GLenum D3DStencilOpToGL( DWORD operation ) +{ + switch( operation ) + { + case D3DSTENCILOP_KEEP : return GL_KEEP; + case D3DSTENCILOP_ZERO : return GL_ZERO; + case D3DSTENCILOP_REPLACE : return GL_REPLACE; + case D3DSTENCILOP_INCRSAT : return GL_INCR; + case D3DSTENCILOP_DECRSAT : return GL_DECR; + case D3DSTENCILOP_INVERT : return GL_INVERT; + case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT; + case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT; + default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF; + } +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateInline( D3DRENDERSTATETYPE State, DWORD Value ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetRenderState( State, Value ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + + switch (State) + { + case D3DRS_ZENABLE: // kGLDepthTestEnable + { + gl.m_DepthTestEnable.enable = Value; + m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable ); + break; + } + case D3DRS_ZWRITEENABLE: // kGLDepthMask + { + gl.m_DepthMask.mask = Value; + m_ctx->WriteDepthMask( &gl.m_DepthMask ); + break; + } + case D3DRS_ZFUNC: + { + // kGLDepthFunc + GLenum func = D3DCompareFuncToGL( Value ); + gl.m_DepthFunc.func = func; + m_ctx->WriteDepthFunc( &gl.m_DepthFunc ); + break; + } + case D3DRS_COLORWRITEENABLE: // kGLColorMaskSingle + { + gl.m_ColorMaskSingle.r = ((Value & D3DCOLORWRITEENABLE_RED) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.g = ((Value & D3DCOLORWRITEENABLE_GREEN)!= 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.b = ((Value & D3DCOLORWRITEENABLE_BLUE) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.a = ((Value & D3DCOLORWRITEENABLE_ALPHA)!= 0) ? 0xFF : 0x00; + m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle ); + break; + } + case D3DRS_CULLMODE: // kGLCullFaceEnable / kGLCullFrontFace + { + switch (Value) + { + case D3DCULL_NONE: + { + gl.m_CullFaceEnable.enable = false; + gl.m_CullFrontFace.value = GL_CCW; //doesn't matter + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + + case D3DCULL_CW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CW; //origGL_CCW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + case D3DCULL_CCW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CCW; //origGL_CW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + default: + { + DXABSTRACT_BREAK_ON_ERROR(); + break; + } + } + break; + } + //-------------------------------------------------------------------------------------------- alphablend stuff + case D3DRS_ALPHABLENDENABLE: // kGLBlendEnable + { + gl.m_BlendEnable.enable = Value; + m_ctx->WriteBlendEnable( &gl.m_BlendEnable ); + break; + } + case D3DRS_BLENDOP: // kGLBlendEquation // D3D blend-op ==> GL blend equation + { + GLenum equation = D3DBlendOperationToGL( Value ); + gl.m_BlendEquation.equation = equation; + m_ctx->WriteBlendEquation( &gl.m_BlendEquation ); + break; + } + case D3DRS_SRCBLEND: // kGLBlendFactor // D3D blend-factor ==> GL blend factor + case D3DRS_DESTBLEND: // kGLBlendFactor + { + GLenum factor = D3DBlendFactorToGL( Value ); + + if (State==D3DRS_SRCBLEND) + { + gl.m_BlendFactor.srcfactor = factor; + } + else + { + gl.m_BlendFactor.dstfactor = factor; + } + m_ctx->WriteBlendFactor( &gl.m_BlendFactor ); + break; + } + case D3DRS_SRGBWRITEENABLE: // kGLBlendEnableSRGB + { + gl.m_BlendEnableSRGB.enable = Value; + m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB ); + break; + } + //-------------------------------------------------------------------------------------------- alphatest stuff + case D3DRS_ALPHATESTENABLE: + { + gl.m_AlphaTestEnable.enable = Value; + m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable ); + break; + } + case D3DRS_ALPHAREF: + { + gl.m_AlphaTestFunc.ref = Value / 255.0f; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + case D3DRS_ALPHAFUNC: + { + GLenum func = D3DCompareFuncToGL( Value );; + gl.m_AlphaTestFunc.func = func; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + //-------------------------------------------------------------------------------------------- stencil stuff + case D3DRS_STENCILENABLE: // GLStencilTestEnable_t + { + gl.m_StencilTestEnable.enable = Value; + m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable ); + break; + } + case D3DRS_STENCILFAIL: // GLStencilOp_t "what do you do if stencil test fails" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.sfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILZFAIL: // GLStencilOp_t "what do you do if stencil test passes *but* depth test fails, if depth test happened" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dpfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILPASS: // GLStencilOp_t "what do you do if stencil test and depth test both pass" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dppass = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILFUNC: // GLStencilFunc_t + { + GLenum stencilfunc = D3DCompareFuncToGL( Value ); + gl.m_StencilFunc.frontfunc = gl.m_StencilFunc.backfunc = stencilfunc; + + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILREF: // GLStencilFunc_t + { + gl.m_StencilFunc.ref = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILMASK: // GLStencilFunc_t + { + gl.m_StencilFunc.mask = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILWRITEMASK: // GLStencilWriteMask_t + { + gl.m_StencilWriteMask.mask = Value; + m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask ); + break; + } + case D3DRS_FOGENABLE: // none of these are implemented yet... erk + { + gl.m_FogEnable = (Value != 0); + GLMPRINTF(("-D- fogenable = %d",Value )); + break; + } + case D3DRS_SCISSORTESTENABLE: // kGLScissorEnable + { + gl.m_ScissorEnable.enable = Value; + m_ctx->WriteScissorEnable( &gl.m_ScissorEnable ); + break; + } + case D3DRS_DEPTHBIAS: // kGLDepthBias + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.units = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + // good ref on these: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/ + case D3DRS_SLOPESCALEDEPTHBIAS: + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.factor = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + // Alpha to coverage + case D3DRS_ADAPTIVETESS_Y: + { + gl.m_AlphaToCoverageEnable.enable = Value; + m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable ); + break; + } + case D3DRS_CLIPPLANEENABLE: // kGLClipPlaneEnable + { + // d3d packs all the enables into one word. + // we break that out so we don't do N glEnable calls to sync - + // GLM is tracking one unique enable per plane. + for( int i=0; i<kGLMUserClipPlanes; i++) + { + gl.m_ClipPlaneEnable[i].enable = (Value & (1<<i)) != 0; + } + + for( int x=0; x<kGLMUserClipPlanes; x++) + m_ctx->WriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x ); + break; + } + //-------------------------------------------------------------------------------------------- polygon/fill mode + case D3DRS_FILLMODE: + { + GLuint mode = 0; + switch(Value) + { + case D3DFILL_POINT: mode = GL_POINT; break; + case D3DFILL_WIREFRAME: mode = GL_LINE; break; + case D3DFILL_SOLID: mode = GL_FILL; break; + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + gl.m_PolygonMode.values[0] = gl.m_PolygonMode.values[1] = mode; + m_ctx->WritePolygonMode( &gl.m_PolygonMode ); + break; + } + } + + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateConstInline( D3DRENDERSTATETYPE State, DWORD Value ) +{ + // State is a compile time constant - luckily no need to do anything special to get the compiler to optimize this case. + return SetRenderStateInline( State, Value ); +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetIndicesNonInline( pIndexData ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + // just latch it. + m_indices.m_idxBuffer = pIndexData; + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetStreamSourceNonInline( StreamNumber, pStreamData, OffsetInBytes, Stride ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( StreamNumber < D3D_MAX_STREAMS ); + Assert( ( Stride & 3 ) == 0 ); // we support non-DWORD aligned strides, but on some drivers (like AMD's) perf goes off a cliff + + // perfectly legal to see a vertex buffer of NULL get passed in here. + // so we need an array to track these. + // OK, we are being given the stride, we don't need to calc it.. + + GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_name: -1, OffsetInBytes, Stride)); + + if ( !pStreamData ) + { + OffsetInBytes = 0; + Stride = 0; + + m_vtx_buffers[ StreamNumber ] = m_pDummy_vtx_buffer; + } + else + { + // We do not support strides of 0 + Assert( Stride > 0 ); + m_vtx_buffers[ StreamNumber ] = pStreamData->m_vtxBuffer; + } + + m_streams[ StreamNumber ].m_vtxBuffer = pStreamData; + m_streams[ StreamNumber ].m_offset = OffsetInBytes; + m_streams[ StreamNumber ].m_stride = Stride; + + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) // groups of 4 floats! +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantFNonInline( StartRegister, pConstantData, Vector4fCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersF( kGLMVertexProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantBNonInline( StartRegister, pConstantData, BoolCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersB( kGLMVertexProgram, StartRegister, (int *)pConstantData, BoolCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT IDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) // groups of 4 ints! +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantINonInline( StartRegister, pConstantData, Vector4iCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersI( kGLMVertexProgram, StartRegister, (int *)pConstantData, Vector4iCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetPixelShaderConstantFNonInline(StartRegister, pConstantData, Vector4fCount); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersF( kGLMFragmentProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +#endif +} + +HRESULT IDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderNonInline(pShader); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetVertexProgram( pShader ? pShader->m_vtxProgram : NULL ); + m_vertexShader = pShader; + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetPixelShaderNonInline(pShader); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetFragmentProgram( pShader ? pShader->m_pixProgram : NULL ); + m_pixelShader = pShader; + return S_OK; +#endif +} + +FORCEINLINE HRESULT IDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexDeclarationNonInline(pDecl); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_pVertDecl = pDecl; + return S_OK; +#endif +} + +FORCEINLINE void IDirect3DDevice9::SetMaxUsedVertexShaderConstantsHint( uint nMaxReg ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetMaxUsedVertexShaderConstantsHintNonInline( nMaxReg ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetMaxUsedVertexShaderConstantsHint( nMaxReg ); +#endif +} + +// ------------------------------------------------------------------------------------------------------------------------------ // +// D3DX +// ------------------------------------------------------------------------------------------------------------------------------ // +struct ID3DXInclude +{ + virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes); + virtual HRESULT Close(LPCVOID pData); +}; +typedef ID3DXInclude* LPD3DXINCLUDE; + + +struct TOGL_CLASS ID3DXBuffer : public IUnknown +{ + void* GetBufferPointer(); + DWORD GetBufferSize(); +}; + +typedef ID3DXBuffer* LPD3DXBUFFER; + +class ID3DXConstantTable : public IUnknown +{ +}; +typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE; + +TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); +TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack); +TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * ); + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build an ortho projection matrix. (right-handed) +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf ); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion); + +TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions ); + +TOGL_INTERFACE HRESULT D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +// fake D3D usage constant for SRGB tex creation +#define D3DUSAGE_TEXTURE_SRGB (0x80000000L) + +#else + + //USE_ACTUAL_DX + #ifndef WIN32 + #error sorry man + #endif + + #ifdef _X360 + #include "d3d9.h" + #include "d3dx9.h" + #else + #include <windows.h> + #include "../../dx9sdk/include/d3d9.h" + #include "../../dx9sdk/include/d3dx9.h" + #endif + typedef HWND VD3DHWND; + +#endif // DX_TO_GL_ABSTRACTION + +#endif // DXABSTRACT_H |