|
|
/*==========================================================================;
* * Copyright (C) 1997 Microsoft Corporation. All Rights Reserved. * * File: devstate.c * Content: device state management * ***************************************************************************/
#include "pch.cpp"
#pragma hdrstop
#include "drawprim.hpp"
extern HRESULT checkDeviceSurface(LPDIRECT3DDEVICEI lpD3DDev, LPDIRECTDRAWSURFACE lpDDS); extern HRESULT CalcDDSurfInfo(LPDIRECT3DDEVICEI lpDevI, BOOL bUpdateZBufferFields); extern HRESULT downloadView(LPDIRECT3DVIEWPORTI lpViewI);
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetCurrentViewport"
HRESULT D3DAPI DIRECT3DDEVICEI::SetCurrentViewport(LPDIRECT3DVIEWPORT2 lpViewport) { return SetCurrentViewport((LPDIRECT3DVIEWPORT3)lpViewport); }
HRESULT D3DAPI DIRECT3DDEVICEI::SetCurrentViewport(LPDIRECT3DVIEWPORT3 lpViewport) { LPDIRECT3DVIEWPORTI lpD3DViewI,lpOldViewportI; HRESULT err;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
/*
* validate parms */ TRY { lpD3DViewI = (LPDIRECT3DVIEWPORTI)lpViewport; if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_DIRECT3DVIEWPORT3_PTR(lpViewport)) { D3D_ERR( "Invalid viewport pointer passed to SetCurrentViewport" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in SetCurrentViewport" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "SetCurrentViewport in Begin" ); return D3DERR_INBEGIN; }
/*
* The viewport must be associated with this device */ if (lpD3DViewI->lpDevI != this) { D3D_ERR( "Viewport not associated with this device" ); return (DDERR_INVALIDPARAMS); }
lpOldViewportI=this->lpCurrentViewport; this->lpCurrentViewport = lpD3DViewI;
if (lpD3DViewI->v_id != v_id && lpD3DViewI->v_data_is_set) { err = downloadView(lpD3DViewI); if (err != D3D_OK) { this->lpCurrentViewport = lpOldViewportI; return err; } }
if(lpOldViewportI!=NULL) lpOldViewportI->Release();
this->lpCurrentViewport->AddRef();
return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetCurrentViewport"
HRESULT D3DAPI DIRECT3DDEVICEI::GetCurrentViewport(LPDIRECT3DVIEWPORT2 *lpViewport) { return GetCurrentViewport((LPDIRECT3DVIEWPORT3*)lpViewport); }
HRESULT D3DAPI DIRECT3DDEVICEI::GetCurrentViewport(LPDIRECT3DVIEWPORT3 *lpViewport) { LPDIRECT3DVIEWPORTI lpD3DViewI;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
/*
* validate parms */ TRY { lpD3DViewI = (LPDIRECT3DVIEWPORTI)lpViewport; if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_PTR_PTR(lpViewport)) { D3D_ERR( "Invalid viewport pointer passed to GetCurrentViewport" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in GetCurrentViewport" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "GetCurrentViewport in Begin" ); return D3DERR_INBEGIN; }
if (VALID_DIRECT3DVIEWPORT3_PTR(this->lpCurrentViewport)) { this->lpCurrentViewport->AddRef(); *lpViewport = (LPDIRECT3DVIEWPORT3)this->lpCurrentViewport; return D3D_OK; } else { return D3DERR_NOCURRENTVIEWPORT; } }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetRenderState"
HRESULT D3DAPI DIRECT3DDEVICEI::SetRenderState(D3DRENDERSTATETYPE dwState, DWORD value) { // Takes D3D lock (MT only).
// Lock released in the destructor.
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND(""));
#if DBG
#ifdef DEBUG_PIPELINE
extern void SetDebugRenderState(DWORD value); if (dwState == (D3DRENDERSTATETYPE)0xFFFFFFFF) { SetDebugRenderState(value); return D3D_OK; } #endif
#endif //DBG range check below is needed for backward comp with DX5
if (dwState >= D3DHAL_MAX_RSTATES || dwState == 0) { D3D_ERR( "Invalid render state type" ); return DDERR_INVALIDPARAMS; }
#if DBG
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in SetRenderState" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "SetRenderState in Begin" ); return D3DERR_INBEGIN; } #endif
if (D3DRENDERSTATE_FLUSHBATCH == dwState) { CLockD3DST lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (ST only).
// Release in the destructor
HRESULT ret; ret = FlushStates(); if (ret != D3D_OK) { D3D_ERR("Error trying to render batched commands in SetRenderState"); return ret; }
return D3D_OK; }
// map legacy renderstate into WRAP0 - needed for clipping if nothing else
if ( (D3DRENDERSTATE_WRAPU == dwState) || (D3DRENDERSTATE_WRAPV == dwState) ) { DWORD dwWRAP0State = this->rstates[D3DRENDERSTATE_WRAP0]; DWORD dwWrapFlag = (D3DRENDERSTATE_WRAPU == dwState) ? (D3DWRAP_U) : (D3DWRAP_V); if (value) dwWRAP0State |= dwWrapFlag; else dwWRAP0State &= ~dwWrapFlag; if ( dwWRAP0State != this->rstates[D3DRENDERSTATE_WRAP0] ) { SetDeviceRenderState(this, D3DRENDERSTATE_WRAP0, dwWRAP0State); // send new RS's to DX6 aware drivers only
if (IS_DP2HAL_DEVICE(this)) { SetRenderStateI(D3DRENDERSTATE_WRAP0, dwWRAP0State); } } }
// map WRAP0 into legacy renderstate
if (D3DRENDERSTATE_WRAP0 == dwState) { if (!(IS_DP2HAL_DEVICE(this))) { BOOLEAN ustate = (value & D3DWRAP_U) ? TRUE : FALSE; BOOLEAN vstate = (value & D3DWRAP_V) ? TRUE : FALSE; if (this->rstates[D3DRENDERSTATE_WRAPU] == ustate && this->rstates[D3DRENDERSTATE_WRAPV] == vstate) { D3D_WARN(4,"Ignoring redundant SetRenderState"); } else { SetDeviceRenderState(this, D3DRENDERSTATE_WRAPU, ustate); SetRenderStateI(D3DRENDERSTATE_WRAPU, ustate); SetDeviceRenderState(this, D3DRENDERSTATE_WRAPV, vstate); SetRenderStateI(D3DRENDERSTATE_WRAPV, vstate); } } }
if (this->rstates[dwState] == value && IS_DP2HAL_DEVICE(this)) { D3D_WARN(4,"Ignoring redundant SetRenderState"); return D3D_OK; }
/* Save latest state for GetRenderState() */ SetDeviceRenderState(this, dwState, value);
return SetRenderStateI(dwState, value); }
#undef DPF_MODNAME
#define DPF_MODNAME "CDirect3DDeviceIHW::SetRenderStateI"
HRESULT D3DAPI CDirect3DDeviceIHW::SetRenderStateI(D3DRENDERSTATETYPE dwState, DWORD value) { LPDWORD lpRS; if (dwState > D3DRENDERSTATE_STIPPLEPATTERN31) { D3D_WARN(4,"Trying to send invalid state %d to legacy driver",dwState); return D3D_OK; } if (dwState > D3DRENDERSTATE_FLUSHBATCH && dwState < D3DRENDERSTATE_STIPPLEPATTERN00) { D3D_WARN(4,"Trying to send invalid state %d to legacy driver",dwState); return D3D_OK; } if ( this->dwHWOffset + 8 >= dwHWBufferSize ) { CLockD3DST lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (ST only).
// Release in the destructor
HRESULT ret; ret = FlushStates(); if (ret != D3D_OK) { D3D_ERR("Error trying to render batched commands in BeginIndexed"); return ret; } } if (this->lpHWCounts[this->dwHWNumCounts].wNumVertices) { this->dwHWNumCounts += 1; memset(&this->lpHWCounts[this->dwHWNumCounts], 0, sizeof(D3DI_HWCOUNTS) ); }
lpRS = (LPDWORD) (((char *) this->lpHWVertices) + this->dwHWOffset); lpRS[0] = dwState; lpRS[1] = value; this->lpHWCounts[this->dwHWNumCounts].wNumStateChanges += 1; this->dwHWOffset += 8;
return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetRenderState"
HRESULT D3DAPI DIRECT3DDEVICEI::GetRenderState(D3DRENDERSTATETYPE dwState, LPDWORD lpdwValue) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
if (dwState >= D3DHAL_MAX_RSTATES || dwState == 0) { D3D_ERR( "Invalid render state value" ); return DDERR_INVALIDPARAMS; }
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_PTR(lpdwValue, sizeof(DWORD))) { D3D_ERR( "Invalid DWORD pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
*lpdwValue = this->rstates[dwState]; return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetTexture"
HRESULT D3DAPI DIRECT3DDEVICEI::GetTexture(DWORD dwStage, LPDIRECT3DTEXTURE2 *lplpTex) { // Takes D3D lock (MT only).
// Lock released in the destructor.
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND(""));
#if DBG
if (dwStage >= D3DHAL_TSS_MAXSTAGES) { D3D_ERR( "Invalid texture stage or state index" ); return DDERR_INVALIDPARAMS; } #endif
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_PTR(lplpTex, sizeof(DWORD))) { D3D_ERR( "Invalid DWORD pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
// Don't bother to check for DX6 support, just return the
// cached value.
*lplpTex = lpD3DMappedTexI[dwStage]; if (*lplpTex) (*lplpTex)->AddRef(); return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetTexture"
HRESULT D3DAPI DIRECT3DDEVICEI::SetTexture(DWORD dwStage, LPDIRECT3DTEXTURE2 lpTex) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); #if DBG
if (dwStage >= D3DHAL_TSS_MAXSTAGES) { D3D_ERR( "Invalid texture stage or state index" ); return DDERR_INVALIDPARAMS; }
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } }
EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; } #endif
if (lpD3DMappedTexI[dwStage] == (LPDIRECT3DTEXTUREI)lpTex) { return D3D_OK; }
#if DBG
if (lpTex) { LPDIRECT3DTEXTUREI lpTexI= (LPDIRECT3DTEXTUREI)lpTex; HRESULT ret; if ( (!lpTexI->lpDDSSys) && (lpTexI->DDSInt4.lpLcl->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) && (!(lpD3DHALGlobalDriverData->hwCaps.dwDevCaps & D3DDEVCAPS_TEXTURESYSTEMMEMORY)) ) { D3D_ERR( "Device cannot render using texture surface from system memory" ); return DDERR_INVALIDPARAMS; } ret=VerifyTextureCaps(this, &lpTexI->DDSInt4); if (D3D_OK != ret) { return ret; } } #endif
LPDDRAWI_DDRAWSURFACE_INT surf_int; LPDDRAWI_DDRAWSURFACE_LCL surf_lcl; LPDDRAWI_DDRAWSURFACE_GBL surf_gbl; // we are ssumeing lpTex->lpOwningIUnknown is always a LPDDRAWI_DDRAWSURFACE_INT
// if in the future when texture is not aggregated on ddraw surface, change is needed here
if (lpD3DMappedTexI[dwStage]) { //the following is a hack of Surface Release() for perf reason
surf_int=(LPDDRAWI_DDRAWSURFACE_INT)lpD3DMappedTexI[dwStage]->lpOwningIUnknown; if (surf_int->dwIntRefCnt > 1) // only do this short way when it's not going away
{ surf_lcl=surf_int->lpLcl; surf_gbl=surf_lcl->lpGbl; surf_gbl->dwRefCnt--; surf_lcl->dwLocalRefCnt--; surf_int->dwIntRefCnt--; } else lpD3DMappedTexI[dwStage]->Release(); }
lpD3DMappedTexI[dwStage] = (LPDIRECT3DTEXTUREI)lpTex; if (lpTex) { //the following is a hack of lpTex->AddRef() for perf reason
surf_int=(LPDDRAWI_DDRAWSURFACE_INT)((LPDIRECT3DTEXTUREI)lpTex)->lpOwningIUnknown; surf_lcl=surf_int->lpLcl; surf_gbl=surf_lcl->lpGbl; surf_gbl->dwRefCnt++; surf_lcl->dwLocalRefCnt++; surf_int->dwIntRefCnt++; lpD3DMappedBlock[dwStage] = NULL; } else { lpD3DMappedBlock[dwStage] = (LPD3DI_TEXTUREBLOCK)TRUE; //indicate a dirty if lpTex==NULL
} if (this->tsstates[dwStage][D3DTSS_COLOROP] != D3DTOP_DISABLE) { this->dwFVFLastIn = 0; // Force to recompute outputVID
this->dwFEFlags |= D3DFE_TSSINDEX_DIRTY; } return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetTextureStageState"
HRESULT D3DAPI DIRECT3DDEVICEI::GetTextureStageState(DWORD dwStage, D3DTEXTURESTAGESTATETYPE dwState, LPDWORD pdwValue) { // Takes D3D lock (MT only).
// Lock released in the destructor.
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND(""));
#if DBG
if (dwStage >= D3DHAL_TSS_MAXSTAGES || dwState == 0 || dwState >= D3DTSS_MAX) { D3D_ERR( "Invalid texture stage or state index" ); return DDERR_INVALIDPARAMS; } #endif //DBG
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_PTR(pdwValue, sizeof(DWORD))) { D3D_ERR( "Invalid DWORD pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
// Don't bother to check for DX6 support, just return the
// cached value.
*pdwValue = tsstates[dwStage][dwState]; return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3D::CreateDevice"
extern HRESULT WINAPI Direct3DCreateDevice(REFCLSID riid, LPUNKNOWN lpDirect3D, LPDIRECTDRAWSURFACE lpDDSTarget, LPUNKNOWN* lplpD3DDevice, IUnknown* pUnkOuter, DWORD dwVersion);
HRESULT D3DAPI DIRECT3DI::CreateDevice(REFCLSID devType, LPDIRECTDRAWSURFACE4 lpDDS4, LPDIRECT3DDEVICE3 *lplpDirect3DDevice3, LPUNKNOWN pUnkOuter) { HRESULT ret; LPUNKNOWN lpUnkDevice; LPDIRECTDRAWSURFACE lpDDS;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
TRY { if (!VALID_DIRECT3D3_PTR(this)) { D3D_ERR( "Invalid Direct3D pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_OUTPTR(lplpDirect3DDevice3)) { D3D_ERR( "Invalid pointer to Device object pointer" ); return DDERR_INVALIDPARAMS; } if (!VALID_D3D_DIRECTDRAWSURFACE4_PTR(((LPDDRAWI_DDRAWSURFACE_INT)lpDDS4))) { D3D_ERR( "Invalid DirectDrawSurface4 pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in CreateDevice" ); return DDERR_INVALIDPARAMS; }
if (pUnkOuter != NULL) { return CLASS_E_NOAGGREGATION; }
*lplpDirect3DDevice3=NULL;
// QI lpDDS4 for lpDDS interface
ret = lpDDS4->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&lpDDS); if (FAILED(ret)) return ret; lpDDS->Release();
ret = Direct3DCreateDevice(devType, &this->mD3DUnk, lpDDS, (LPUNKNOWN *) &lpUnkDevice, NULL, 3);
if(FAILED(ret) || (lpUnkDevice==NULL)) return ret;
// QI device1 for a device3 interface
ret = lpUnkDevice->QueryInterface(IID_IDirect3DDevice3, (LPVOID*)lplpDirect3DDevice3);
lpUnkDevice->Release(); // release unneeded interface
return ret; }
HRESULT D3DAPI DIRECT3DI::CreateDevice(REFCLSID devType, LPDIRECTDRAWSURFACE lpDDS, LPDIRECT3DDEVICE2 *lplpDirect3DDevice2) { HRESULT ret; LPUNKNOWN lpUnkDevice; ULONG refcnt;
TRY { if (!VALID_DIRECT3D3_PTR(this)) { D3D_ERR( "Invalid Direct3D pointer" ); return DDERR_INVALIDOBJECT; }
if (!VALID_OUTPTR(lplpDirect3DDevice2)) { D3D_ERR( "Invalid pointer to Device object pointer" ); return DDERR_INVALIDPARAMS; } if (!VALID_D3D_DIRECTDRAWSURFACE_PTR(((LPDDRAWI_DDRAWSURFACE_INT)lpDDS))) { D3D_ERR( "Invalid DirectDrawSurface pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in CreateDevice" ); return DDERR_INVALIDPARAMS; }
*lplpDirect3DDevice2=NULL;
// Create a device3 object
ret = Direct3DCreateDevice(devType, &this->mD3DUnk, lpDDS, (LPUNKNOWN *) &lpUnkDevice, NULL, 2);
if(FAILED(ret) || (lpUnkDevice==NULL)) { return ret; }
// QI it for a device2 interface
ret = lpUnkDevice->QueryInterface(IID_IDirect3DDevice2, (LPVOID*)lplpDirect3DDevice2);
lpUnkDevice->Release(); // releasing unneeded interface
return ret; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetLightState"
HRESULT D3DAPI DIRECT3DDEVICEI::SetLightState(D3DLIGHTSTATETYPE dwState, DWORD value) { HRESULT ret = D3D_OK; D3DSTATE state;
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
state.dlstLightStateType = dwState; state.dwArg[0] = value;
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "SetLightState in Begin" ); return D3DERR_INBEGIN; }
return D3DHELInst_D3DOP_STATELIGHT(this, 1, &state); }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetLightState"
HRESULT D3DAPI DIRECT3DDEVICEI::GetLightState(D3DLIGHTSTATETYPE dwState, LPDWORD lpValue) {
CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
float* lpfValue = (float*)lpValue; #if DBG
/*
* validate parms */ TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if (!VALID_PTR(lpValue, sizeof(DWORD))) { D3D_ERR( "Invalid DWORD pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in GetLightState" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "GetLightState in Begin" ); return D3DERR_INBEGIN; } #endif
switch (dwState) { case D3DLIGHTSTATE_MATERIAL: *lpValue = (DWORD)this->lighting.hMat; break; case D3DLIGHTSTATE_AMBIENT: *lpValue = this->lighting.ambient_save; break; case D3DLIGHTSTATE_FOGMODE: *lpValue = this->lighting.fog_mode; break; case D3DLIGHTSTATE_FOGSTART: *lpfValue = this->lighting.fog_start; break; case D3DLIGHTSTATE_FOGEND: *lpfValue = this->lighting.fog_end; break; case D3DLIGHTSTATE_FOGDENSITY: *lpfValue = this->lighting.fog_density; break; case D3DLIGHTSTATE_COLORMODEL: *lpValue = this->lighting.color_model; break; case D3DLIGHTSTATE_COLORVERTEX: // return value for Device3 only
if (dwVersion == 3) { *lpValue = (0x0 != (dwFEFlags & D3DFE_COLORVERTEX)); break; } // else fall through to error return
default: D3D_ERR( "Invalid state value passed to GetLightState" ); return DDERR_INVALIDPARAMS; /* Do we return an error code or should we just ignore ? */ } return D3D_OK; }
/*
transform matrix functions */
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetTransform"
HRESULT D3DAPI DIRECT3DDEVICEI::SetTransform(D3DTRANSFORMSTATETYPE dtsTransformState, LPD3DMATRIX lpMat) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
HRESULT ret = D3D_OK; D3DFE_TRANSFORM *lpHelTransform = &this->transform; #if DBG
if (!lpMat) { D3D_ERR( "NULL matrix pointer passed to SetTransform" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "SetTransform in Begin" ); return D3DERR_INBEGIN; } #endif
switch (dtsTransformState) { case D3DTRANSFORMSTATE_WORLD : D3DFE_SetMatrixWorld(this, lpMat); break; case D3DTRANSFORMSTATE_VIEW : D3DFE_SetMatrixView(this, lpMat); break; case D3DTRANSFORMSTATE_PROJECTION : D3DFE_SetMatrixProj(this, lpMat); if ((ret = this->UpdateDrvWInfo()) != DD_OK) { return ret; } break; default : D3D_ERR( "Invalid state value passed to SetTransform" ); ret = DDERR_INVALIDPARAMS; /* Work Item: Generate new meaningful return code */ break; }
return ret; } // end of D3DDev_SetTransform()
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetTransform"
HRESULT D3DAPI DIRECT3DDEVICEI::GetTransform(D3DTRANSFORMSTATETYPE dtsTransformState, LPD3DMATRIX lpMat) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
HRESULT ret = D3D_OK; D3DFE_TRANSFORM *lpHelTransform; #if DBG
if (!lpMat) { D3D_ERR( "NULL matrix pointer" ); return DDERR_INVALIDPARAMS; } if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "GetTransform in Begin" ); return D3DERR_INBEGIN; } #endif
lpHelTransform = &this->transform; switch (dtsTransformState) { case D3DTRANSFORMSTATE_WORLD : *lpMat = *(LPD3DMATRIX)&lpHelTransform->world._11; break; case D3DTRANSFORMSTATE_VIEW : *lpMat = *(LPD3DMATRIX)&lpHelTransform->view._11; break; case D3DTRANSFORMSTATE_PROJECTION : *lpMat = *(LPD3DMATRIX)&lpHelTransform->proj._11; break; default : D3D_ERR( "Invalid state value passed to GetTransform" ); ret = DDERR_INVALIDPARAMS; /* Work Item: Generate new meaningful return code */ break; }
return ret; } // end of D3DDev2_GetTransform()
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::MultiplyTransform"
/*
MultiplyTransform -- this preconcatenates the new matrix to the specified transform matrix
this really screams for overloaded matrix ops... */ HRESULT D3DAPI DIRECT3DDEVICEI::MultiplyTransform(D3DTRANSFORMSTATETYPE dtsTransformState, LPD3DMATRIX lpMat) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
HRESULT ret = D3D_OK; D3DFE_TRANSFORM *lpHelTransform; #if DBG
if (!lpMat) { D3D_ERR( "NULL matrix pointer passed to MultiplyTransform" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "MultiplyTransform in Begin" ); return D3DERR_INBEGIN; } #endif
lpHelTransform = &this->transform; switch (dtsTransformState) { case D3DTRANSFORMSTATE_WORLD : D3DFE_MultMatrixWorld(this, lpMat); break; case D3DTRANSFORMSTATE_VIEW : D3DFE_MultMatrixView(this, lpMat); break; case D3DTRANSFORMSTATE_PROJECTION : D3DFE_MultMatrixProj(this, lpMat); break; default : D3D_ERR( "Invalid state value passed to MultiplyTransform" ); ret = DDERR_INVALIDPARAMS; /* Work Item: Generate new meaningful return code */ return ret; } return ret; } // end of D3DDev2_MultiplyTransform()
void InvalidateHandles(LPDIRECT3DDEVICEI lpDevI) { /* free up all textures created by this object */ LPD3DI_TEXTUREBLOCK tBlock=LIST_FIRST(&lpDevI->texBlocks); while (tBlock) { D3DI_RemoveTextureHandle(tBlock); tBlock=LIST_NEXT(tBlock,devList); } }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetRenderTarget"
HRESULT D3DAPI DIRECT3DDEVICEI::SetRenderTarget(LPDIRECTDRAWSURFACE lpDDS, DWORD dwFlags) {
LPDIRECTDRAWSURFACE4 lpDDS4; HRESULT ret;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
TRY { if (!VALID_DIRECT3DDEVICE2_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice2 pointer" ); return DDERR_INVALIDOBJECT; }
if (!VALID_D3D_DIRECTDRAWSURFACE_PTR((LPDDRAWI_DDRAWSURFACE_INT)lpDDS)) { D3D_ERR( "Invalid DirectDrawSurface pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in SetRenderTarget" ); return DDERR_INVALIDPARAMS; }
/* Make sure this device was not aggregated from DDS (DX3-style) */ if ((LPDIRECTDRAWSURFACE)this->lpOwningIUnknown==this->lpDDSTarget) { D3D_ERR("Cannot change render target on old device (those QI'ed from a ddraw-surface"); return D3DERR_DEVICEAGGREGATED; }
// QI lpDDS for lpDDS4 interface, which will be used internally by D3D
ret = lpDDS->QueryInterface(IID_IDirectDrawSurface4, (LPVOID*)&lpDDS4);
if(FAILED(ret)) return ret;
// SetRenderTarget AddRef'd the DDS4 interface, so it's safe to release it here and decrmt the refcnt
lpDDS4->Release();
ret=this->SetRenderTarget(lpDDS4,dwFlags);
return ret; }
HRESULT D3DAPI DIRECT3DDEVICEI::SetRenderTarget(LPDIRECTDRAWSURFACE4 lpDDS4, DWORD dwFlags) { DDSCAPS2 ddscaps; DDSURFACEDESC2 ddsd; HRESULT ret, ddrval; LPDIRECTDRAWSURFACE lpZ=NULL,lpDDS=NULL; LPDIRECTDRAWSURFACE4 lpZ_DDS4=NULL; LPDIRECTDRAWPALETTE lpPal=NULL; DWORD i, j;
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; }
if (!VALID_D3D_DIRECTDRAWSURFACE4_PTR(((LPDDRAWI_DDRAWSURFACE_INT)lpDDS4))) { D3D_ERR( "Invalid DirectDrawSurface4 pointer" ); return DDERR_INVALIDOBJECT; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters in SetRenderTarget" ); return DDERR_INVALIDPARAMS; }
// Flush before switching RenderTarget..
ret = FlushStates(); if (ret != D3D_OK) { D3D_ERR("Error trying to FlushStates in SetRenderTarget"); return ret; }
/* Make sure this device was not aggregated from DDS (DX3-style) */ if ((LPDIRECTDRAWSURFACE)this->lpOwningIUnknown==this->lpDDSTarget) { D3D_ERR("Cannot change render target on device QI'ed from DDS"); return D3DERR_DEVICEAGGREGATED; }
/*
* Check if the 3D cap is set on the surface. */ memset(&ddsd, 0, sizeof ddsd); ddsd.dwSize = sizeof ddsd; ddrval = lpDDS4->GetSurfaceDesc(&ddsd); if (ddrval != DD_OK) { D3D_ERR("Failed to get surface description of device's surface."); return (ddrval); }
if (!(ddsd.ddsCaps.dwCaps & DDSCAPS_3DDEVICE)) { D3D_ERR("**** The DDSCAPS_3DDEVICE is not set on this surface."); D3D_ERR("**** You need to add DDSCAPS_3DDEVICE to ddsCaps.dwCaps"); D3D_ERR("**** when creating the surface."); return (DDERR_INVALIDCAPS); } if (!(this->lpD3DHALGlobalDriverData->hwCaps.dwDeviceRenderBitDepth & BitDepthToDDBD(ddsd.ddpfPixelFormat.dwRGBBitCount))) { D3D_ERR("Rendering surface's RGB bit count not supported by hardware device"); return (DDERR_INVALIDCAPS); } if (ddsd.dwWidth > 2048 || ddsd.dwHeight > 2048) { D3D_ERR("Surface dimension > 2048"); return DDERR_INVALIDPARAMS; }
/* The z-buffer... */ ddscaps.dwCaps = DDSCAPS_ZBUFFER; ret = lpDDS4->GetAttachedSurface(&ddscaps, &lpZ_DDS4); if ((ret != DD_OK) && (ret != DDERR_NOTFOUND)) { /*
* NOTE: Not an error if the z-buffer is not found. We will let the * dirver handle that (it might fail or create its own z-buffer). */ D3D_ERR("Supplied DirectDraw Z-Buffer is invalid - can't set render target"); ret=DDERR_INVALIDPARAMS; goto handle_error; } if (lpZ_DDS4) lpZ_DDS4->Release(); // We do not need to addref this one;
// QI lpDDS4 for lpDDS interface, which will be used internally by D3D
ret = lpDDS4->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&lpDDS);
if(FAILED(ret)) goto handle_error;
/* The palette... */ ret = lpDDS->GetPalette(&lpPal); if ((ret != DD_OK) && (ret != DDERR_NOPALETTEATTACHED)) { /*
* NOTE: Again, not an error (yet) if there is no palette attached. * But if there is palette and we can't get at it for some reason * - fail. */ D3D_ERR("Supplied DirectDraw Palette is invalid - can't create device"); ret=DDERR_INVALIDPARAMS; goto handle_error; }
/*
* We're going to check now whether we should have got a palette. */ if (ret == DDERR_NOPALETTEATTACHED) { if (ddsd.ddpfPixelFormat.dwRGBBitCount < 16) { D3D_ERR("No palette supplied for palettized surface"); ret=DDERR_NOPALETTEATTACHED; goto handle_error; } }
/* Verify Z buffer */
if (lpZ_DDS4!=NULL) { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); if ((ret=lpZ_DDS4->GetSurfaceDesc(&ddsd)) != DD_OK) { D3D_ERR("Failed to getsurfacedesc on Z"); goto handle_error; }
// QI lpDDS4 for lpDDS interface, which will be used internally by D3D
ret = lpZ_DDS4->QueryInterface(IID_IDirectDrawSurface, (LPVOID*)&lpZ);
if(FAILED(ret)) goto handle_error; } else { if (this->lpDDSZBuffer) { D3D_ERR("Current rendertarget contains ZBuffer, but new one does not!"); ret=DDERR_INVALIDPARAMS; goto handle_error; } } if (IS_DX7HAL_DEVICE(this)) { static_cast<CDirect3DDeviceIDP2*>(this)->SetRenderTargetI(lpDDS, lpZ); } else if (this->lpD3DHALCallbacks2->SetRenderTarget) { D3DHAL_SETRENDERTARGETDATA rtData;
rtData.dwhContext = this->dwhContext; #ifndef WIN95
if (dwFEFlags & D3DFE_REALHAL) { if (lpDDS) rtData.lpDDSLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDS)->lpLcl; else rtData.lpDDSLcl = NULL; if (lpZ) rtData.lpDDSZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpZ)->lpLcl; else rtData.lpDDSZLcl = NULL; } else #endif //WIN95
{ rtData.lpDDS = lpDDS; rtData.lpDDSZ = lpZ; } rtData.ddrval = 0; CALL_HAL2ONLY(ret, this, SetRenderTarget, &rtData); if ((ret != DDHAL_DRIVER_HANDLED) || (rtData.ddrval != DD_OK)) { D3D_ERR( "Driver call failed in SetRenderTarget" ); // Need sensible return value in this case,
// currently we return whatever the driver stuck in here.
ret = rtData.ddrval; goto handle_error; } } else { D3DHAL_CONTEXTCREATEDATA cdata; D3DHAL_CONTEXTDESTROYDATA ddata;
/* Destroy old context */ memset(&ddata, 0, sizeof(D3DHAL_CONTEXTDESTROYDATA)); ddata.dwhContext = this->dwhContext;
CALL_HALONLY(ret, this, ContextDestroy, &ddata); if (ret != DDHAL_DRIVER_HANDLED || ddata.ddrval != DD_OK) { DPF(0, "(ERROR) ContextDestroy. Failed. dwhContext = %d", ddata.dwhContext); // Need sensible return value in this case,
// currently we return whatever the driver stuck in here.
ret = ddata.ddrval; goto handle_error; }
/* Create new context */ memset(&cdata, 0, sizeof(D3DHAL_CONTEXTCREATEDATA));
#ifndef WIN95
if (dwFEFlags & D3DFE_REALHAL) { if (this->lpDD) cdata.lpDDLcl = ((LPDDRAWI_DIRECTDRAW_INT)(this->lpDD))->lpLcl; else cdata.lpDDLcl = NULL; if (lpDDS) cdata.lpDDSLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDS)->lpLcl; else cdata.lpDDSLcl = NULL; if (lpZ) cdata.lpDDSZLcl = ((LPDDRAWI_DDRAWSURFACE_INT)lpZ)->lpLcl; else cdata.lpDDSZLcl = NULL; } else #endif //WIN95
{ cdata.lpDDGbl = this->lpDDGbl; cdata.lpDDS = lpDDS; cdata.lpDDSZ = lpZ; }
cdata.dwPID = GetCurrentProcessId();
CALL_HALONLY(ret, this, ContextCreate, &cdata); if (ret != DDHAL_DRIVER_HANDLED || cdata.ddrval != DD_OK) { D3D_ERR("HAL call to ContextCreate failed in SetRenderTarget"); // Need sensible return value in this case,
// currently we return whatever the driver stuck in here.
return cdata.ddrval; } this->dwhContext = cdata.dwhContext; D3D_INFO(9, "in halCreateContext. Succeeded. dwhContext = %d", cdata.dwhContext);
/* Set up renderstates */ // note we can't do a loop from 1 to D3DHAL_MAX_RSTATES(256) as some of rstates are not
// valid states, passin them down to drivers(like voodoo2 DX6 driver) will crash.
for (i= 1 ; i< D3DRENDERSTATE_WRAPBIAS+8; ++i) { this->SetRenderStateI((D3DRENDERSTATETYPE)i, this->rstates[i]); } if ( IS_DP2HAL_DEVICE(this) ) { CDirect3DDeviceIDP2 *dp2dev = static_cast<CDirect3DDeviceIDP2 *>(this); for (i=0; i<dwMaxTextureBlendStages; ++i) for (j=0; j<D3DTSS_MAX; ++j) { D3D_INFO(6,"Calling SetTSSI(%d,%d,%08lx)",i,j,this->tsstates[i][j]); dp2dev->SetTSSI(i, (D3DTEXTURESTAGESTATETYPE)j, this->tsstates[i][j]); } } }
if (this->lpDDSTarget) UnHookD3DDeviceFromSurface(this,((LPDDRAWI_DDRAWSURFACE_INT)this->lpDDSTarget)->lpLcl); //unhook previous surfaces if any
if (this->lpDDSZBuffer) UnHookD3DDeviceFromSurface(this,((LPDDRAWI_DDRAWSURFACE_INT)this->lpDDSZBuffer)->lpLcl); //unhook previous surfaces if any
if (DDERR_OUTOFMEMORY == (ret=HookD3DDeviceToSurface(this, ((LPDDRAWI_DDRAWSURFACE_INT) lpDDS4)->lpLcl))) { goto handle_error; } if (lpZ_DDS4 && (DDERR_OUTOFMEMORY == (ret=HookD3DDeviceToSurface(this, ((LPDDRAWI_DDRAWSURFACE_INT) lpZ_DDS4)->lpLcl)))) { UnHookD3DDeviceFromSurface(this, ((LPDDRAWI_DDRAWSURFACE_INT) lpDDS4)->lpLcl); goto handle_error; } // release old device DDS/DDS4 interfaces and replace with the new ones,
// which are mostly already AddRef'd (except for lpDDS4)
/// DDSZBuffer ///
if(this->lpDDSZBuffer) this->lpDDSZBuffer->Release();
// lpZ AddRef'd by QI
this->lpDDSZBuffer = lpZ;
/// DDSZBuffer DDS4 ///
this->lpDDSZBuffer_DDS4=lpZ_DDS4; // This needs no AddRef or Release
/// DDSTarget ///
if (this->dwVersion == 2) { this->lpDDSTarget->Release(); // lpDDS AddRef'd by QI
this->lpDDSTarget = lpDDS; } else { this->lpDDSTarget = lpDDS; // lpDDS AddRef'd by QI so release it
this->lpDDSTarget->Release(); } #ifndef WIN95
hSurfaceTarget = ((LPDDRAWI_DDRAWSURFACE_INT)lpDDS)->lpLcl->hDDSurface; D3D_INFO(6,"in SetRenderTarget hSurfaceTarget=%08lx lpDDSTarget=%08lx",hSurfaceTarget,lpDDSTarget); #else
hSurfaceTarget = (unsigned long)((LPDDRAWI_DDRAWSURFACE_INT)lpDDS)->lpLcl->lpSurfMore->dwSurfaceHandle; D3D_INFO(6,"in SetRenderTarget hSurfaceTarget=%08lx lpDDSTarget=%08lx",hSurfaceTarget,lpDDSTarget); #endif
/// DDSTarget DDS4 ///
if (this->dwVersion == 3) { this->lpDDSTarget_DDS4->Release(); lpDDS4->AddRef(); // ensure lpDDS4 (which was an argument) doesnt disappear
} this->lpDDSTarget_DDS4=lpDDS4;
if (this->lpDDPalTarget) this->lpDDPalTarget->Release();
// already AddRef'd by GetPalette()
this->lpDDPalTarget = lpPal;
InvalidateHandles(this);
if( FAILED( ret=CalcDDSurfInfo(this,FALSE) ) ) goto handle_error; return ret;
handle_error:
if(lpPal) lpPal->Release(); if(lpZ) lpZ->Release(); if(lpZ_DDS4) lpZ_DDS4->Release(); if(lpDDS) lpDDS->Release();
return ret; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetRenderTarget"
HRESULT D3DAPI DIRECT3DDEVICEI::GetRenderTarget(LPDIRECTDRAWSURFACE* lplpDDS) {
CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
TRY { if (!VALID_DIRECT3DDEVICE2_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice2 pointer" ); return DDERR_INVALIDOBJECT; } if ( !VALID_OUTPTR( lplpDDS ) ) { D3D_ERR( "Invalid ptr to DDS ptr" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
*lplpDDS = this->lpDDSTarget;
this->lpDDSTarget->AddRef(); return D3D_OK;
}
HRESULT D3DAPI DIRECT3DDEVICEI::GetRenderTarget(LPDIRECTDRAWSURFACE4* lplpDDS) { CLockD3D lockObject(DPF_MODNAME, REMIND("")); // Takes D3D lock.
// Release in the destructor
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice3 pointer" ); return DDERR_INVALIDOBJECT; } if ( !VALID_OUTPTR( lplpDDS ) ) { D3D_ERR( "Invalid ptr to DDS ptr" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
*lplpDDS = this->lpDDSTarget_DDS4;
this->lpDDSTarget_DDS4->AddRef(); return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::SetClipStatus"
#define D3DSTATUS_VALID 0x80000000L /* Reserved Status flag to indicate SetClipStatus is called */
HRESULT D3DAPI DIRECT3DDEVICEI::SetClipStatus(LPD3DCLIPSTATUS status) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
#if DBG
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice pointer" ); return DDERR_INVALIDOBJECT; } if (! VALID_PTR(status, sizeof(D3DCLIPSTATUS)) ) { D3D_ERR( "Invalid status pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; }
if (this->dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "SetClipStatus in Begin" ); return D3DERR_INBEGIN; } #endif
// D3DCLIPSTATUS_EXTENTS3 not supported in Device3
if (dwVersion == 3 && status->dwFlags & D3DCLIPSTATUS_EXTENTS3) { D3D_ERR( "D3DCLIPSTATUS_EXTENTS3 not supported for Device3" ); return DDERR_INVALIDPARAMS; } if (status->dwFlags & D3DCLIPSTATUS_STATUS) this->iClipStatus = status->dwStatus;
if (status->dwFlags & (D3DCLIPSTATUS_EXTENTS2 | D3DCLIPSTATUS_EXTENTS3)) { this->rExtents.x1 = status->minx; this->rExtents.y1 = status->miny; this->rExtents.x2 = status->maxx; this->rExtents.y2 = status->maxy; } return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::GetClipStatus"
HRESULT D3DAPI DIRECT3DDEVICEI::GetClipStatus(LPD3DCLIPSTATUS status) { CLockD3DMT lockObject(this, DPF_MODNAME, REMIND("")); // Takes D3D lock (MT only).
// Release in the destructor
#if DBG
TRY { if (!VALID_DIRECT3DDEVICE3_PTR(this)) { D3D_ERR( "Invalid Direct3DDevice pointer" ); return DDERR_INVALIDOBJECT; } if (! VALID_PTR(status, sizeof(D3DCLIPSTATUS)) ) { D3D_ERR( "Invalid status pointer" ); return DDERR_INVALIDPARAMS; } } EXCEPT( EXCEPTION_EXECUTE_HANDLER ) { D3D_ERR( "Exception encountered validating parameters" ); return DDERR_INVALIDPARAMS; } if (dwHintFlags & D3DDEVBOOL_HINTFLAGS_INBEGIN) { D3D_ERR( "GetClipStatus in Begin" ); return D3DERR_INBEGIN; } #endif
status->dwStatus = iClipStatus; status->dwFlags = D3DCLIPSTATUS_EXTENTS2; status->minx = this->rExtents.x1; status->miny = this->rExtents.y1; status->maxx = this->rExtents.x2; status->maxy = this->rExtents.y2; return D3D_OK; }
#undef DPF_MODNAME
#define DPF_MODNAME "Direct3DDevice::UpdateTextures"
HRESULT DIRECT3DDEVICEI::UpdateTextures() { BOOL bFlushed=FALSE; DWORD dwStage; D3DTEXTUREHANDLE dwDDIHandle; LPDIRECT3DTEXTUREI lpTexI; LPD3DI_TEXTUREBLOCK lpBlock; for (dwStage=0;dwStage < this->dwMaxTextureBlendStages; dwStage++) { lpTexI=this->lpD3DMappedTexI[dwStage]; lpBlock=this->lpD3DMappedBlock[dwStage]; if(lpTexI) { if (lpTexI->lpTMBucket) { if (lpTexI->bDirty) { FlushD3DStates(((LPDDRAWI_DDRAWSURFACE_INT)(lpTexI->lpDDS))->lpLcl); if (DD_OK != CopySurface(lpTexI->lpDDS,lpTexI->lpDDSSys,this->lpClipper)) { D3D_ERR("Error copying surface while updating textures"); } else { lpTexI->bDirty=FALSE; D3D_INFO(4,"UpdateTextures: Dirty texture updated"); } } } if (lpBlock) { if (lpBlock->hTex) { continue; //nothing need to be done further
} }
GetTextureDDIHandle(lpTexI, this, &lpBlock); this->lpD3DMappedBlock[dwStage]=lpBlock; if (lpBlock) { dwDDIHandle = lpBlock->hTex; if (dwDDIHandle) { if(lpTexI->lpDDS != NULL) { BatchTextureToDevice(this, ((LPDDRAWI_DDRAWSURFACE_INT) lpTexI->lpDDS)->lpLcl); } else { BatchTextureToDevice(this, ((LPDDRAWI_DDRAWSURFACE_INT) lpTexI->lpDDSSys)->lpLcl); } } } else { dwDDIHandle = 0; //something is wrong we disable this texture
} } else if (lpBlock) { this->lpD3DMappedBlock[dwStage]=NULL; //a SetTexture(Stage,NULL) issued
dwDDIHandle = 0; //tell driver to disable this texture
} else { continue; //both zero, no action needed
} if (IS_DP2HAL_DEVICE(this)) { CDirect3DDeviceIDP2 *dp2dev = static_cast<CDirect3DDeviceIDP2 *>(this); dp2dev->SetTSSI(dwStage, (D3DTEXTURESTAGESTATETYPE)D3DTSS_TEXTUREMAP, dwDDIHandle); // Update runtime copy of state.
dp2dev->tsstates[dwStage][D3DTSS_TEXTUREMAP] = dwDDIHandle; } else { if(this->dwFEFlags & D3DFE_DISABLE_TEXTURES) break; CDirect3DDeviceIHW *dev = static_cast<CDirect3DDeviceIHW *>(this); (void)dev->SetRenderStateI(D3DRENDERSTATE_TEXTUREHANDLE, dwDDIHandle); // Update runtime copy of state.
dev->rstates[D3DRENDERSTATE_TEXTUREHANDLE] = dwDDIHandle; } } return D3D_OK; }
//---------------------------------------------------------------------
// This function is called from HALEXE.CPP, from device::SetRenderState and
// from device::SetTexture.
// Always use this function to update RSTATES.
//
HRESULT SetDeviceRenderState(LPDIRECT3DDEVICEI lpDevI, D3DRENDERSTATETYPE type, DWORD value) { DWORD *rstates = lpDevI->rstates; switch (type) { case D3DRENDERSTATE_FOGENABLE: rstates[type] = value; // set rstates BEFORE calling SetFogFlags
SetFogFlags(lpDevI); break; case D3DRENDERSTATE_SPECULARENABLE: lpDevI->dwFEFlags |= D3DFE_MATERIAL_DIRTY | D3DFE_LIGHTS_DIRTY; lpDevI->dwFVFLastIn = 0; // Force re-computing of FVF id
break; case D3DRENDERSTATE_TEXTUREHANDLE: if ((rstates[D3DRENDERSTATE_TEXTUREHANDLE] == 0) != (value == 0)) lpDevI->dwFVFLastIn = 0; if (value) lpDevI->dwDeviceFlags |= D3DDEV_LEGACYTEXTURE; else lpDevI->dwDeviceFlags &= ~D3DDEV_LEGACYTEXTURE;
break; } rstates[type] = value; // set rstates for all other cases
return D3D_OK; }
#if DBG
static char ProfileStr[PROF_DRAWINDEXEDPRIMITIVEVB+1][32]= { "Execute", "Begin", "BeginIndexed", "DrawPrimitive(Device2)", "DrawIndexedPrimitive(Device2)", "DrawPrimitiveStrided", "DrawIndexedPrimitiveStrided", "DrawPrimitive(Device3)", "DrawIndexedPrimitive(Device3)", "DrawPrimitiveVB", "DrawIndexedPrimitiveVB", }; static char PrimitiveStr[D3DPT_TRIANGLEFAN][16]= { "POINTLIST", "LINELIST", "LINESTRIP", "TRIANGLELIST", "TRIANGLESTRIP", "TRIANGLEFAN", }; static char VertexStr[D3DVT_TLVERTEX][16]= { "D3DVERTEX", "D3DLVERTEX", "D3DTLVERTEX", }; #define PROFILE_LEVEL 1
void DIRECT3DDEVICEI::Profile(DWORD caller, D3DPRIMITIVETYPE dwPrimitive, DWORD dwVertex) { DWORD bitwisecaller= 1 << caller; DWORD bitwisePrimitive = 1 << (DWORD)dwPrimitive; DWORD bitwiseVertex1 = 1 << (dwVertex & 0x001F); DWORD bitwiseVertex2 = 1 << ((dwVertex & 0x03E0) >> 5); char str[256]; DDASSERT(PROF_DRAWINDEXEDPRIMITIVEVB >= caller); DDASSERT(D3DPT_TRIANGLEFAN >= dwPrimitive && D3DPT_POINTLIST<= dwPrimitive); if (dwCaller & bitwisecaller) { if (dwPrimitiveType[caller] & bitwisePrimitive) { if ((dwVertexType1[caller] & bitwiseVertex1) && (dwVertexType2[caller] & bitwiseVertex2)) { return; //matching a previous api call, no spew, could count stat though
} else { dwVertexType1[caller] |= bitwiseVertex1; dwVertexType2[caller] |= bitwiseVertex2; } } else { dwPrimitiveType[caller] |= bitwisePrimitive; dwVertexType1[caller] |= bitwiseVertex1; dwVertexType2[caller] |= bitwiseVertex2; } } else { this->dwCaller |= bitwisecaller; dwPrimitiveType[caller] |= bitwisePrimitive; dwVertexType1[caller] |= bitwiseVertex1; dwVertexType2[caller] |= bitwiseVertex2; } wsprintf( (LPSTR) str, ProfileStr[caller]); strcat(str,":"); strcat(str,PrimitiveStr[dwPrimitive-1]); if (dwVertex > D3DVT_TLVERTEX) { if (dwVertex == D3DFVF_VERTEX) { dwVertex = D3DVT_VERTEX; } else if (dwVertex == D3DFVF_LVERTEX) { dwVertex = D3DVT_LVERTEX; } else if (dwVertex == D3DFVF_TLVERTEX) { dwVertex = D3DVT_TLVERTEX; } else { D3D_INFO(PROFILE_LEVEL,"Profile:%s FVFType=%08lx",str,dwVertex); return; } } else { DDASSERT(dwVertex >= D3DVT_VERTEX); } strcat(str,":"); strcat(str,VertexStr[dwVertex-1]); D3D_INFO(PROFILE_LEVEL,"Profile:%s",str); } #endif
|