1703 lines
65 KiB
C++
1703 lines
65 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
// TOGL CODE LICENSE
|
|
//
|
|
// Copyright 2011-2014 Valve Corporation
|
|
// All Rights Reserved.
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to
|
|
// deal in the Software without restriction, including without limitation the
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
// furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
// IN THE SOFTWARE.
|
|
//
|
|
// dxabstract.h
|
|
//
|
|
//==================================================================================================
|
|
#ifndef DXABSTRACT_H
|
|
#define DXABSTRACT_H
|
|
|
|
#ifdef DX_TO_GL_ABSTRACTION
|
|
|
|
#include "togl/rendermechanism.h"
|
|
|
|
#include "tier0/dbg.h"
|
|
#include "tier0/platform.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
|
|
|
|
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.
|
|
uint m_pixFragDataMask; // (1<<n) mask of gl_FragData[n] referenced by this
|
|
// pixel shader
|
|
|
|
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 GetViewport(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 ValidateShaderPair(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);
|
|
|
|
#ifdef OSX
|
|
// required for 10.6 support
|
|
HRESULT TOGLMETHODCALLTYPE
|
|
FlushIndexBindings(void); // push index buffer (set index ptr)
|
|
HRESULT TOGLMETHODCALLTYPE FlushVertexBindings(
|
|
uint baseVertexIndex); // push vertex streams (set attrib ptrs)
|
|
#endif
|
|
|
|
// 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;
|
|
|
|
public:
|
|
IDirect3DDevice9Params m_params; // mirror of the creation inputs
|
|
private:
|
|
// 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[GLM_SAMPLER_COUNT]; // set by SetTexture... NULL if stage
|
|
// inactive
|
|
|
|
// 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[GLM_SAMPLER_COUNT];
|
|
} 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 < GLM_SAMPLER_COUNT);
|
|
|
|
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 < GLM_SAMPLER_COUNT);
|
|
|
|
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());
|
|
Assert(Stage < GLM_SAMPLER_COUNT);
|
|
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
|
|
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
|