/*============================================================================= D3DSystem.cpp : D3D initialization / system functions. Copyright (c) 2001 Crytek Studios. All Rights Reserved. Revision history: * Created by Honich Andrey =============================================================================*/ #include "RenderPCH.h" #include "DriverD3D9.h" #include #include "D3DCGVProgram.h" #include "D3DCGPShader.h" #undef THIS_FILE static char THIS_FILE[] = __FILE__; void CD3D9Renderer::DisplaySplash() { #ifdef GAME_IS_FARCRY HBITMAP hImage = (HBITMAP)LoadImage(GetModuleHandle(0), "fcsplash.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); #else HBITMAP hImage = (HBITMAP)LoadImage(GetModuleHandle(0), "splash.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); #endif if (hImage != INVALID_HANDLE_VALUE) { RECT rect; HDC hDC = GetDC(m_hWnd); HDC hDCBitmap = CreateCompatibleDC(hDC); BITMAP bm; GetClientRect(m_hWnd, &rect); GetObject(hImage, sizeof(bm), &bm); SelectObject(hDCBitmap, hImage); DWORD x = rect.left + (((rect.right-rect.left)-bm.bmWidth) >> 1); DWORD y = rect.top + (((rect.bottom-rect.top)-bm.bmHeight) >> 1); BitBlt(hDC, x, y, bm.bmWidth, bm.bmHeight, hDCBitmap, 0, 0, SRCCOPY); DeleteObject(hImage); DeleteDC(hDCBitmap); } } void CD3D9Renderer::UnSetRes() { m_Features |= RFT_DIRECTACCESSTOVIDEOMEMORY | RFT_SUPPORTZBIAS | RFT_DETAILTEXTURE; m_bActive = FALSE; m_bReady = FALSE; if( m_pd3dDevice ) { Cleanup3DEnvironment(); SAFE_RELEASE(m_pD3D); } } //----------------------------------------------------------------------------- // Name: FinalCleanup() // Desc: Called before the app exits, this function gives the app the chance // to cleanup after itself. //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::FinalCleanup() { UnSetRes(); DeleteContext(m_hWnd); DestroyWindow(); return S_OK; } void CD3D9Renderer::DestroyWindow(void) { if (m_hWnd) { ::DestroyWindow(m_hWnd); m_hWnd = NULL; } } void CD3D9Renderer::RestoreGamma(void) { if (!(GetFeatures() & RFT_HWGAMMA)) return; if (CV_r_nohwgamma) return; m_fLastGamma = 1.0f; m_fLastBrightness = 0.5f; m_fLastContrast = 0.5f; HDC dc; //iLog->Log("...RestoreGamma"); struct { ushort red[256]; ushort green[256]; ushort blue[256]; } Ramp; for(int i=0; i<256; i++) { Ramp.red[i] = Ramp.green[i] = Ramp.blue[i] = i << 8; } m_hWndDesktop = GetDesktopWindow(); dc = GetDC(m_hWndDesktop); SetDeviceGammaRamp(dc, &Ramp); ReleaseDC(m_hWndDesktop, dc); } void CD3D9Renderer::SetDeviceGamma(ushort *r, ushort *g, ushort *b) { ushort gamma[3][256]; int i; if (!(GetFeatures() & RFT_HWGAMMA)) return; if (CV_r_nohwgamma) return; m_hWndDesktop = GetDesktopWindow(); HDC dc = GetDC(m_hWndDesktop); if (!dc) return; for (i=0; i<256; i++) { gamma[0][i] = r[i]; gamma[1][i] = g[i]; gamma[2][i] = b[i]; } //iLog->Log("...SetDeviceGamma"); SetDeviceGammaRamp(dc, gamma); ReleaseDC(m_hWndDesktop, dc); } void CD3D9Renderer::SetGamma(float fGamma, float fBrightness, float fContrast, bool bForce) { int i; fGamma = CLAMP(fGamma, 0.1f, 3.0f); if (!bForce && m_fLastGamma == fGamma && m_fLastBrightness == fBrightness && m_fLastContrast == fContrast) return; //int n; for ( i=0; i<256; i++ ) { m_GammaTable[i] = CLAMP((int)((fContrast+0.5f)*cry_powf((float)i/255.f,1.0f/fGamma)*65535.f + (fBrightness-0.5f)*32768.f - fContrast*32768.f + 16384.f), 0, 65535); } m_fLastGamma = fGamma; m_fLastBrightness = fBrightness; m_fLastContrast = fContrast; //iLog->Log("...SetGamma %.3f", fGamma); SetDeviceGamma(m_GammaTable, m_GammaTable, m_GammaTable); } bool CD3D9Renderer::SetGammaDelta(const float fGamma) { m_fDeltaGamma = fGamma; SetGamma(CV_r_gamma + fGamma, CV_r_brightness, CV_r_contrast, false); return true; } //----------------------------------------------------------------------------- // Name: InvalidateDeviceObjects() // Desc: Called when the device-dependent objects are about to be lost. //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::InvalidateDeviceObjects() { int i = 0; int j; HRESULT hr; //iLog->Log("...InvalidateDeviceObjects"); m_nFrameReset++; SAFE_RELEASE(m_pVB2D); SAFE_RELEASE(m_pIB); SAFE_RELEASE(m_pQuery); for (j=0; j<3; j++) { for (i=0; i<4; i++) { SAFE_RELEASE(m_pVB3DAr[j][i]); } m_pVB3D[j] = NULL; } SAFE_RELEASE(m_pSphere); EF_Invalidate(); // Unload vertex/index buffers CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; //iLog->Log("Start Unload"); while (pLB != &CLeafBuffer::m_RootGlobal) { CLeafBuffer *Next = pLB->m_NextGlobal; if (pLB->m_bDynamic) { //if (pLB->m_sSource) // iLog->Log("Unload '%s' LB", pLB->m_sSource); pLB->Unload(); } pLB = Next; } //iLog->Log("End Unload\n\n"); CRendElement *pRE = CRendElement::m_RootGlobal.m_NextGlobal; while (pRE != &CRendElement::m_RootGlobal) { pRE->mfReset(); pRE = pRE->m_NextGlobal; } for (i=0; i<96; i++) { CCGVProgram_D3D::m_CurParams[i][0] = -99999.9f; CCGVProgram_D3D::m_CurParams[i][1] = -99999.9f; CCGVProgram_D3D::m_CurParams[i][2] = -99999.9f; CCGVProgram_D3D::m_CurParams[i][3] = -99999.9f; } for (i=0; i<32; i++) { CCGPShader_D3D::m_CurParams[i][0] = -99999.9f; CCGPShader_D3D::m_CurParams[i][1] = -99999.9f; CCGPShader_D3D::m_CurParams[i][2] = -99999.9f; CCGPShader_D3D::m_CurParams[i][3] = -99999.9f; } if (m_TexMan) { for (i=0; im_TexMan->m_Textures.Num(); i++) { STexPicD3D *tp = (STexPicD3D *)gRenDev->m_TexMan->m_Textures[i]; if (!tp || !tp->m_RefTex.m_VidTex || tp->m_Bind == TX_FIRSTBIND) continue; IDirect3DTexture9 *pID3DTexture = NULL; IDirect3DCubeTexture9 *pID3DCubeTexture = NULL; LPDIRECT3DSURFACE9 pSurf = NULL; D3DSURFACE_DESC Desc; if (tp->m_eTT == eTT_Cubemap || tp->m_eTT == eTT_AutoCubemap) { pID3DCubeTexture = (IDirect3DCubeTexture9*)tp->m_RefTex.m_VidTex; hr = pID3DCubeTexture->GetCubeMapSurface((D3DCUBEMAP_FACES)0, 0, &pSurf); } else if (tp->m_eTT == eTT_Base || tp->m_eTT == eTT_Bumpmap || tp->m_eTT == eTT_Rectangle || tp->m_eTT == eTT_DSDTBump) { pID3DTexture = (IDirect3DTexture9*)tp->m_RefTex.m_VidTex; hr = pID3DTexture->GetSurfaceLevel(0, &pSurf); } if (!pSurf) continue; hr = pSurf->GetDesc(&Desc); SAFE_RELEASE(pSurf); if (Desc.Pool != D3DPOOL_DEFAULT) continue; tp->m_Flags2 |= FT2_NEEDRESTORED; SAFE_RELEASE(pID3DTexture); SAFE_RELEASE(pID3DCubeTexture); tp->m_RefTex.m_VidTex = NULL; } for (i=0; im_TexMan->m_EnvLCMaps[i]; for (j=0; j<6; j++) { if (cur->m_RenderTargets[j]) { IDirect3DSurface9* pSurface = (IDirect3DSurface9* )cur->m_RenderTargets[j]; cur->m_RenderTargets[j] = NULL; pSurface->Release(); } } } } SAFE_RELEASE (m_pTempZBuffer); SAFE_RELEASE (m_pZBuffer); SAFE_RELEASE (m_pBackBuffer); m_pCurBackBuffer = NULL; m_pCurZBuffer = NULL; return S_OK; } HRESULT CD3D9Renderer::RestoreDeviceObjects() { HRESULT hr; int i, j; //InitTexFillers(); //Flush(); //iLog->Log("...RestoreDeviceObjects"); for (i=0; iCreateDepthStencilSurface( m_width, m_height, m_d3dpp.AutoDepthStencilFormat, ConvertFSAASamplesToType( m_FSAA_samples ), m_FSAA_quality, TRUE, &m_pZBuffer, 0 ); // if( SUCCEEDED( hr ) ) // { // hr = m_pd3dDevice->SetDepthStencilSurface( m_pZBuffer ); // //iLog->Log( "HDR-FSAA: Created multi-sampled Z-Buffer for current FSAA settings (samples = %d / quality = %d).", m_FSAA_samples, m_FSAA_quality ); // } // //else // // iLog->Log( "HDR-FSAA: Multi-sampled Z-Buffer creation failed render target creation failed!" ); //} //else // m_pd3dDevice->GetDepthStencilSurface( &m_pZBuffer ); // m_pZBuffer->GetDesc( &m_d3dsdZBuffer ); // m_pd3dDevice->CreateDepthStencilSurface(m_d3dsdZBuffer.Width, m_d3dsdZBuffer.Height, m_d3dsdZBuffer.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &m_pTempZBuffer, NULL); // m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer ); // m_pBackBuffer->GetDesc(&m_d3dsdBackBuffer); // m_pCurBackBuffer = m_pBackBuffer; // m_pCurZBuffer = m_pZBuffer; ////////////////////////////////////////////////////////////////////////// // new approach to re-use original non-aa z buffer for temp. render tasks ////////////////////////////////////////////////////////////////////////// if( m_FSAA == 2 ) { hr = m_pd3dDevice->CreateDepthStencilSurface( m_width, m_height, m_d3dpp.AutoDepthStencilFormat, ConvertFSAASamplesToType( m_FSAA_samples ), m_FSAA_quality, TRUE, &m_pZBuffer, 0 ); if( SUCCEEDED( hr ) ) { //iLog->Log( "HDR-FSAA: Created multi-sampled Z-Buffer for current FSAA settings (samples = %d / quality = %d).", m_FSAA_samples, m_FSAA_quality ); hr = m_pd3dDevice->GetDepthStencilSurface( &m_pTempZBuffer ); // re-use current non multi-sampled z buffer for temporary rendering tasks hr = m_pd3dDevice->SetDepthStencilSurface( m_pZBuffer ); m_pZBuffer->GetDesc( &m_d3dsdZBuffer ); } else { //iLog->Log( "HDR-FSAA: Multi-sampled Z-Buffer creation failed render target creation failed! Resorting back to r_FSAA 0!" ); m_FSAA = 0; CV_r_fsaa = 0; } } if( m_FSAA != 2 ) { m_pd3dDevice->GetDepthStencilSurface( &m_pZBuffer ); m_pZBuffer->GetDesc( &m_d3dsdZBuffer ); m_pd3dDevice->CreateDepthStencilSurface(m_d3dsdZBuffer.Width, m_d3dsdZBuffer.Height, m_d3dsdZBuffer.Format, D3DMULTISAMPLE_NONE, 0, FALSE, &m_pTempZBuffer, NULL); } m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer ); m_pBackBuffer->GetDesc(&m_d3dsdBackBuffer); m_pCurBackBuffer = m_pBackBuffer; m_pCurZBuffer = m_pZBuffer; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// SAFE_RELEASE(m_pVB2D); SAFE_RELEASE(m_pIB); SAFE_RELEASE(m_pQuery); for (j=0; j<3; j++) { for (i=0; i<4; i++) { SAFE_RELEASE(m_pVB3DAr[j][i]); } m_pVB3D[j] = NULL; } SAFE_RELEASE(m_pSphere); m_nVertsDMesh2D = 400; m_nIndsDMesh = CV_d3d9_rb_tris*3; m_nIOffsDMesh = m_nIndsDMesh; m_nOffsDMesh2D = m_nVertsDMesh2D; hr = m_pd3dDevice->CreateVertexBuffer(m_nVertsDMesh2D*sizeof(struct_VERTEX_FORMAT_TRP3F_COL4UB_TEX2F), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, D3DPOOL_DEFAULT, &m_pVB2D, NULL); if (FAILED(hr)) return hr; hr = m_pd3dDevice->CreateIndexBuffer(m_nIndsDMesh*sizeof(short), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &m_pIB, NULL); if (FAILED(hr)) return hr; hr = m_pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, &m_pQuery); if(hr != D3DERR_NOTAVAILABLE ) { assert(m_pQuery); m_pQuery->Issue(D3DISSUE_END); } for (j=0; j<3; j++) { int nVertSize; int fvf; switch (j) { case 0: default: m_nVertsDMesh3D[j] = MAX_DYNVB3D_VERTS; nVertSize = sizeof(struct_VERTEX_FORMAT_P3F_COL4UB_TEX2F); fvf = D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1; break; case 1: m_nVertsDMesh3D[j] = 16384; nVertSize = sizeof(struct_VERTEX_FORMAT_P3F_TEX2F); fvf = D3DFVF_XYZ | D3DFVF_TEX1; break; case 2: m_nVertsDMesh3D[j] = 16384; nVertSize = sizeof(SPipTangents); fvf = 0; break; } m_nOffsDMesh3D[j] = m_nVertsDMesh3D[j]; for (i=0; i<4; i++) { hr = m_pd3dDevice->CreateVertexBuffer(m_nVertsDMesh3D[j]*nVertSize, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, fvf, D3DPOOL_DEFAULT, &m_pVB3DAr[j][i], NULL); if (FAILED(hr)) return hr; } m_pVB3D[j] = m_pVB3DAr[j][0]; } hr = D3DXCreateSphere(m_pd3dDevice, 1, 16, 16, &m_pSphere, NULL); if (FAILED(hr)) return hr; memset(&m_Material, 0, sizeof(m_Material)); for (i=0; i<16; i++) { D3DLIGHT9 *l = &m_Lights[i]; memset(l, 0, sizeof(D3DLIGHT9)); l->Ambient.r = 0.0f; l->Ambient.g = 0.0f; l->Ambient.b = 0.0f; l->Ambient.a = 0.0f; l->Type = D3DLIGHT_DIRECTIONAL; l->Attenuation0 = 1.0f; } EF_Restore(); for (i=0; im_TexMan->m_Textures.Num(); i++) { STexPicD3D *tp = (STexPicD3D *)gRenDev->m_TexMan->m_Textures[i]; if (!tp || tp->m_Bind == TX_FIRSTBIND) continue; IDirect3DTexture9 *pID3DTexture = NULL; IDirect3DCubeTexture9 *pID3DCubeTexture = NULL; if (!(tp->m_Flags2 & FT2_NEEDRESTORED)) continue; int D3DUsage = 0; if (tp->m_Flags2 & FT2_RENDERTARGET) D3DUsage |= D3DUSAGE_RENDERTARGET; if (tp->m_DstFormat == D3DFMT_D24S8 || tp->m_DstFormat == D3DFMT_D16) { D3DUsage |= D3DUSAGE_DEPTHSTENCIL; D3DUsage &= ~D3DUSAGE_RENDERTARGET; } if (tp->m_Flags & FT_DYNAMIC) D3DUsage |= D3DUSAGE_DYNAMIC; if (tp->m_eTT == eTT_Cubemap) { hr = m_pd3dDevice->CreateCubeTexture(tp->m_Width, 1, D3DUsage, (D3DFORMAT)tp->m_DstFormat, D3DPOOL_DEFAULT, &pID3DCubeTexture, NULL); tp->m_RefTex.m_VidTex = pID3DCubeTexture; for (int i=0; i<6; i++) { HRESULT hr = S_OK; PDIRECT3DSURFACE9 pSurface = NULL; hr = pID3DCubeTexture->GetCubeMapSurface((D3DCUBEMAP_FACES)i, 0, &pSurface); if (SUCCEEDED(hr)) m_pd3dDevice->ColorFill(pSurface, NULL, D3DCOLOR_ARGB(0, 0, 0, 0)); SAFE_RELEASE(pSurface); } } else { hr = m_pd3dDevice->CreateTexture(tp->m_Width, tp->m_Height, 1, D3DUsage, (D3DFORMAT)tp->m_DstFormat, D3DPOOL_DEFAULT, &pID3DTexture, NULL); tp->m_RefTex.m_VidTex = pID3DTexture; if (D3DUsage & D3DUSAGE_RENDERTARGET) { HRESULT hr = S_OK; PDIRECT3DSURFACE9 pSurface = NULL; hr = pID3DTexture->GetSurfaceLevel(0, &pSurface); if (SUCCEEDED(hr)) m_pd3dDevice->ColorFill(pSurface, NULL, D3DCOLOR_ARGB(0, 0, 0, 0)); SAFE_RELEASE(pSurface); } } } m_bDeviceLost = false; // Restore onlyVideo buffers CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; while (pLB != &CLeafBuffer::m_RootGlobal) { CLeafBuffer *Next = pLB->m_NextGlobal; if (pLB->m_bDynamic) { if (pLB->m_bOnlyVideoBuffer) { pLB->CreateVidVertices(pLB->m_SecVertCount, pLB->m_nVertexFormat); } } pLB = Next; } m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); // ATI instancing if (m_bDeviceSupportsInstancing == 2) { // Notify the driver that instancing support is expected D3DFORMAT instanceSupport = (D3DFORMAT)MAKEFOURCC('I', 'N', 'S', 'T'); m_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, instanceSupport); } m_pLastVDeclaration = NULL; return S_OK; } void CD3D9Renderer::RefreshResources(int nFlags) { } void CD3D9Renderer::ShutDown(bool bReInit) { m_cEF.mfShutdown(); if (bReInit) FreeResources(FRR_SHADERS | FRR_TEXTURES | FRR_REINITHW); else FreeResources(FRR_ALL); EF_PipelineShutdown(); if (CV_r_printmemoryleaks) { FILE *fp = fxopen("LeafBufferLeaks.txt", "w"); if (fp) { CLeafBuffer *pLB = CLeafBuffer::m_RootGlobal.m_NextGlobal; while (pLB != &CLeafBuffer::m_RootGlobal) { CLeafBuffer *Next = pLB->m_NextGlobal; float fSize = pLB->Size(0)/1024.0f/1024.0f; fprintf(fp, "*** LB %s: %0.3fMb\n", pLB->m_sSource, fSize); iLog->Log("WARNING: LB Leak %s: %0.3fMb", pLB->m_sSource, fSize); //DeleteLeafBuffer(pLB); pLB = Next; } CRendElement *pRE = CRendElement::m_RootGlobal.m_NextGlobal; while (pRE != &CRendElement::m_RootGlobal) { CRendElement *Next = pRE->m_NextGlobal; float fSize = pRE->Size()/1024.0f/1024.0f; fprintf(fp, "*** RE %s: %0.3fMb\n", pRE->mfTypeString(), fSize); iLog->Log("WARNING: RE Leak %s: %0.3fMb", pRE->mfTypeString(), fSize); //SAFE_RELEASE(pRE); pRE = Next; } fclose(fp); } } #ifndef WIN64 // NOTE: AMD64 port: find the 64-bit CG runtime if (m_CGContext) { cgDestroyContext(m_CGContext); cgD3D9SetDevice(NULL); m_CGContext = NULL; } #endif FinalCleanup(); CName::mfExitSubsystem(); if (m_hLibHandle3DC) { ::FreeLibrary((HINSTANCE)m_hLibHandle3DC); m_hLibHandle3DC = NULL; } ////////////////////////////////////////////////////////////////////////// // Clear globals. ////////////////////////////////////////////////////////////////////////// if (!bReInit) { iLog = NULL; iConsole = NULL; iTimer = NULL; iSystem = NULL; pIPhysicalWorld = NULL; } STexPic::m_Root.m_Next = &STexPic::m_Root; STexPic::m_Root.m_Prev = &STexPic::m_Root; CLeafBuffer::m_Root.m_Next = &CLeafBuffer::m_Root; CLeafBuffer::m_Root.m_Prev = &CLeafBuffer::m_Root; CLeafBuffer::m_RootGlobal.m_NextGlobal = &CLeafBuffer::m_RootGlobal; CLeafBuffer::m_RootGlobal.m_PrevGlobal = &CLeafBuffer::m_RootGlobal; } bool CD3D9Renderer::SetWindow(int width, int height, bool fullscreen, WIN_HWND hWnd) { HWND temp = GetDesktopWindow(); RECT trect; GetWindowRect(temp, &trect); m_deskwidth =trect.right-trect.left; m_deskheight=trect.bottom-trect.top; DWORD style, exstyle; int x, y, wdt, hgt; if (width < 640) width = 640; if (height < 480) height = 480; m_dwWindowStyle = WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_OVERLAPPED; if (fullscreen) { #ifdef _DEBUG exstyle = 0; #else exstyle = WS_EX_TOPMOST; #endif style = WS_POPUP | WS_VISIBLE; } else { exstyle = WS_EX_APPWINDOW; style = m_dwWindowStyle; } x = (GetSystemMetrics(SM_CXFULLSCREEN)-width)/2; y = (GetSystemMetrics(SM_CYFULLSCREEN)-height)/2; wdt = GetSystemMetrics(SM_CXDLGFRAME)*2 + width; hgt = GetSystemMetrics(SM_CYCAPTION) + GetSystemMetrics(SM_CXDLGFRAME)*2 + height; if (!hWnd) { m_hWnd = CreateWindowEx(exstyle, "CryENGINE", m_WinTitle, style, x, y, wdt, hgt, NULL, NULL, m_hInst, NULL); } else m_hWnd = (HWND)hWnd; if (!m_hWnd) iConsole->Exit("Couldn't create window\n"); if (!hWnd) { if (fullscreen) { // Hide the cursor SetCursor(NULL); ShowCursor(FALSE); } } return true; } #ifdef USE_3DC #include "../Common/3Dc/CompressorLib.h" void (*DeleteDataATI)(void *pData); COMPRESSOR_ERROR (*CompressTextureATI)(DWORD width, DWORD height, UNCOMPRESSED_FORMAT sourceFormat, COMPRESSED_FORMAT destinationFormat, void *inputData, void **dataOut, DWORD *outDataSize); #endif WIN_HWND CD3D9Renderer::Init(int x,int y,int width,int height,unsigned int cbpp, int zbpp, int sbits, bool fullscreen,WIN_HINSTANCE hinst, WIN_HWND Glhwnd, WIN_HDC Glhdc, WIN_HGLRC hGLrc, bool bReInit) { if (m_IsDedicated) { m_MaxTextureSize = 256; return 0; } if (!iSystem || !iLog) return 0; /*float *f = (float *)0x402a92c0; FILE *fp = fopen("fl.txt", "w"); for (int i=0; i<4; i++) { fprintf(fp, "{\n"); for (int j=0; j<6; j++) { fprintf(fp, " {%ff, %ff, %ff, %ff},\n", f[0], f[1], f[2], f[3]); f += 4; } fprintf(fp, "}\n"); } fclose(fp);*/ bool b = false; m_CVWidth = iConsole->GetCVar("r_Width"); m_CVHeight = iConsole->GetCVar("r_Height"); m_CVFullScreen = iConsole->GetCVar("r_FullScreen"); m_CVColorBits = iConsole->GetCVar("r_ColorBits"); iLog->Log ( "Direct3D9 driver is creating...\n"); iLog->Log ( "\nCrytek Direct3D9 driver version %4.2f (%s <%s>).\n", VERSION_D3D, __DATE__, __TIME__); //strcpy(m_WinTitle, "- Far Cry -"); #ifdef GAME_IS_FARCRY sprintf(m_WinTitle,"- Far Cry - %s (%s)",__DATE__, __TIME__); #else sprintf(m_WinTitle,"- CryEngine - %s (%s)",__DATE__, __TIME__); #endif m_hInst = (HINSTANCE)hinst; if (Glhwnd) m_bEditor = true; #ifdef USE_3DC m_hLibHandle3DC = ::LoadLibrary("CompressATI.dll"); if (!m_hLibHandle3DC) m_hLibHandle3DC = ::LoadLibrary("CompressATI2.dll"); if (m_hLibHandle3DC) { CompressTextureATI = (FnCompressTextureATI)GetProcAddress((HINSTANCE)m_hLibHandle3DC, "CompressTextureATI"); DeleteDataATI = (FnDeleteDataATI)GetProcAddress((HINSTANCE)m_hLibHandle3DC, "DeleteDataATI"); } #endif // Save the new dimensions CRenderer::m_width = width; CRenderer::m_height = height; CRenderer::m_cbpp = cbpp; CRenderer::m_zbpp = zbpp; CRenderer::m_sbpp = sbits; m_bFullScreen = fullscreen; while (true) { if (!SetWindow(width, height, fullscreen, Glhwnd)) { ShutDown(); return 0; } if (SetRes()) break; ShutDown(true); if (b) return 0; m_bFullScreen ? m_bFullScreen = 0 : m_bFullScreen = 1; b = 1; } D3DAdapterInfo *pAI = m_D3DSettings.PAdapterInfo(); D3DADAPTER_IDENTIFIER9 *ai = &pAI->AdapterIdentifier; D3DDeviceInfo *di = m_D3DSettings.PDeviceInfo(); iLog->Log(" ****** D3D9 CryRender Stats ******"); iLog->Log(" Driver description: %s", ai->Description); iLog->Log(" Full stats: %s", m_strDeviceStats); iLog->Log(" Hardware acceleration: %s", (di->DevType == D3DDEVTYPE_HAL) ? "Yes" : "No"); //iLog->Log(" Full screen only: %s\n", (di->d3dCaps.Caps2 & D3DCAPS2_CANRENDERWINDOWED) ? "No" : "Yes"); if (CV_r_fsaa && (GetFeatures() & RFT_SUPPORTFSAA)) { TArray Formats; int nNum = GetAAFormat(Formats, false); iLog->Log(" Full scene AA: Enabled: %s (%d Quality)\n", Formats[nNum].szDescr, Formats[nNum].nQuality); GetAAFormat(Formats, true); } else iLog->Log(" Full scene AA: Disabled\n"); iLog->Log(" Projective EMBM: %s\n", (GetFeatures() & RFT_HW_ENVBUMPPROJECTED) ? "Enabled" : "Disabled"); iLog->Log(" Detail textures: %s\n", (GetFeatures() & RFT_DETAILTEXTURE) ? "Enabled" : "Disabled"); iLog->Log(" Z Buffer Locking: %s\n", (m_Features & RFT_ZLOCKABLE) ? "Enabled" : "Disabled"); iLog->Log(" Multitexturing: %s (%d textures)\n", (m_Features & RFT_MULTITEXTURE) ? "Supported" : "Not supported", di->Caps.MaxSimultaneousTextures); iLog->Log(" Use bumpmapping : %s\n", (m_Features & RFT_BUMP) ? "Enabled (DOT3)" : "Disabled"); iLog->Log(" Use paletted textures : %s\n", (m_Features & RFT_PALTEXTURE) ? "Enabled" : "Disabled"); iLog->Log(" Current Resolution: %dx%dx%d %s\n", CRenderer::m_width, CRenderer::m_height, CRenderer::m_cbpp, m_bFullScreen ? "Full Screen" : "Windowed"); iLog->Log(" Maximum Resolution: %dx%d\n", pAI->m_MaxWidth, pAI->m_MaxHeight); iLog->Log(" Maximum Texture size: %dx%d (Max Aspect: %d)\n", di->Caps.MaxTextureWidth, di->Caps.MaxTextureHeight, di->Caps.MaxTextureAspectRatio); iLog->Log(" Texture filtering type: %s\n", CV_d3d9_texturefilter->GetString()); iLog->Log(" HDR Rendering: %s\n", m_nHDRType == 1 ? "FP16" : m_nHDRType == 2 ? "MRT" : "Disabled"); iLog->Log(" MRT Rendering: %s\n", (m_bDeviceSupportsMRT) ? "Enabled" : "Disabled"); iLog->Log(" Occlusion queries: %s\n", (m_Features & RFT_OCCLUSIONTEST) ? "Supported" : "Not supported"); iLog->Log(" Geometry instancing: %s\n", (m_bDeviceSupportsInstancing) ? "Supported" : "Not supported"); iLog->Log(" NormalMaps compression: %s\n", m_bDeviceSupportsComprNormalmaps==1 ? "3Dc" : m_bDeviceSupportsComprNormalmaps==2 ? "V8U8" : m_bDeviceSupportsComprNormalmaps==3 ? "CxV8U8" : "Not supported"); iLog->Log(" Gamma control: %s\n", (m_Features & RFT_HWGAMMA) ? "Hardware" : "Software"); iLog->Log(" Vertex Shaders version %d.%d\n", D3DSHADER_VERSION_MAJOR(di->Caps.VertexShaderVersion), D3DSHADER_VERSION_MINOR(di->Caps.VertexShaderVersion)); iLog->Log(" Pixel Shaders version %d.%d\n", D3DSHADER_VERSION_MAJOR(di->Caps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(di->Caps.PixelShaderVersion)); int nGPU = m_Features & RFT_HW_MASK; if (nGPU == RFT_HW_NV4X) iLog->Log(" Use Hardware Shaders for NV4x GPU\n"); else if (nGPU == RFT_HW_GFFX) iLog->Log(" Use Hardware Shaders for NV3x GPU\n"); else if (nGPU == RFT_HW_GF2) iLog->Log(" Use Hardware Shaders for NV1x GPU\n"); else if (nGPU == RFT_HW_GF3) iLog->Log(" Use Hardware Shaders for NV2x GPU\n"); else if (nGPU == RFT_HW_RADEON) { if (m_bDeviceSupports_PS2X) iLog->Log(" Use Hardware Shaders for ATI R420 GPU\n"); else iLog->Log(" Use Hardware Shaders for ATI R300 GPU\n"); } else iLog->Log(" Hardware Shaders are not supported\n"); if (D3DSHADER_VERSION_MAJOR(di->Caps.PixelShaderVersion) >= 3) { if (CV_r_shadowtype == 0) m_Features |= RFT_SHADOWMAP_SELFSHADOW; m_Features |= RFT_HW_PS30 | RFT_HW_PS20; m_bDeviceSupports_PS30 = true; m_bDeviceSupports_PS2X = false; } else if (D3DSHADER_VERSION_MAJOR(di->Caps.PixelShaderVersion) >= 2) { if (CV_r_shadowtype == 0) m_Features |= RFT_SHADOWMAP_SELFSHADOW; m_Features |= RFT_HW_PS20; } #ifndef USE_HDR m_Features &= ~RFT_HW_HDR; #endif // Disable per-pixel lighting if pixel-shaders aren't supported if (!(m_Features & (RFT_HW_PS20 | RFT_HW_TS | RFT_HW_RC))) { if (CV_r_Quality_BumpMapping) _SetVar("r_Quality_BumpMapping", 0); if (CV_r_checkSunVis >= 2) _SetVar("r_checkSunVis", 1); } // Allow pixel shaders 2.0 lighting on Radeon only cards with PS.2.0 support if (CV_r_Quality_BumpMapping == 3) { if (!(m_Features & RFT_HW_PS20) || (nGPU == RFT_HW_GFFX && !CV_d3d9_nv30_ps20)) _SetVar("r_Quality_BumpMapping", 2); } // Shaders remapping for non-PS20 hardware if (!(m_Features & RFT_HW_PS20) || (nGPU == RFT_HW_GFFX && !CV_d3d9_nv30_ps20)) { _SetVar("r_NoPS20", 1); if (CV_r_shadowblur == 3) _SetVar("r_ShadowBlur", 2); } // Disable trees per-pixel lighting from medium and low spec settings if (CV_r_Quality_BumpMapping < 2) _SetVar("r_Vegetation_PerpixelLight", 0); // Allow offset bump-mapping and parametric shaders system for very high spec settings only if (CV_r_Quality_BumpMapping < 3) { if (CV_r_usehwshaders == 2) _SetVar("r_UseHWShaders", 1); if (CV_r_offsetbump) _SetVar("r_OffsetBump", 0); m_bDeviceSupports_PS2X = false; m_bDeviceSupports_PS30 = false; } if (!m_bDeviceSupports_PS2X && CV_r_sm2xpath) _SetVar("r_SM2XPATH", 0); if (!CV_r_sm2xpath) _SetVar("r_NoPS2X", 1); m_nEnabled_PS2X = CV_r_nops2x ? 0 : 1; m_NoPS2X = CV_r_nops2x; m_sm2xpath = CV_r_sm2xpath; if (!m_bDeviceSupports_PS30 && CV_r_sm30path) _SetVar("r_SM30PATH", 0); if (!CV_r_sm30path) _SetVar("r_NoPS30", 1); m_nEnabled_PS30 = CV_r_nops30 ? 0 : 1; m_NoPS30 = CV_r_nops30; m_sm30path = CV_r_sm30path; if (m_bDeviceSupportsComprNormalmaps == 0) _SetVar("r_TexNormalMapCompressed", 0); if ((m_sm30path || m_sm2xpath) && m_bDeviceSupportsInstancing) _SetVar("r_GeomInstancing", 1); if (m_nHDRType == 2) { // HDRFake mode works only on NV40 _SetVar("r_HDRFake", 0); } // DO NOT Use VB Pools with fixed pipeline (some driver bug) if (nGPU == RFT_HW_GF2 || CV_r_Quality_BumpMapping==0 || !(m_d3dCaps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET)) { _SetVar("d3d9_VBPools", 0); } char *str; if (nGPU == RFT_HW_GF2) str = "Not using pixel shaders"; else if (CV_r_nops20) str = "Replace PS.2.0 to PS.1.1"; else if (CV_r_Quality_BumpMapping == 3) { if (m_bDeviceSupports_PS30) str = "PS.3.0, PS.2.0 and PS.1.1"; else if (m_bDeviceSupports_PS2X) { if (nGPU == RFT_HW_GFFX) str = "PS.2.A, PS.2.0 and PS.1.1"; else str = "PS.2.B, PS.2.0 and PS.1.1"; } else str = "PS.2.0 and PS.1.1"; } else str ="PS1.1 only"; iLog->Log(" Pixel shaders usage: %s\n", str); if (nGPU == RFT_HW_GF2) str = "Not using vertex shaders"; else if (CV_r_nops20) str = "Replace VS.2.0 to VS.1.1"; else if (CV_r_Quality_BumpMapping == 3) { if (D3DSHADER_VERSION_MAJOR(di->Caps.VertexShaderVersion) >= 3) str = "VS.3.0, VS.2.0 and VS.1.1"; else str = "VS.2.0 and VS.1.1"; } else str ="VS1.1 only"; iLog->Log(" Vertex shaders usage: %s\n", str); iLog->Log(" Shadow maps type: %s\n", (m_Features & RFT_DEPTHMAPS) ? "Depth maps" : (m_Features & RFT_SHADOWMAP_SELFSHADOW) ? "Mixed Depth/2D maps" : "2D shadow maps"); iLog->Log(" Stencil shadows type: %s\n", m_d3dCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED ? "Two sided" : "Single sided"); iLog->Log(" Lighting quality: %s\n", CV_r_Quality_BumpMapping==0 ? "Low" : CV_r_Quality_BumpMapping==1 ? "Medium" : CV_r_Quality_BumpMapping==2 ? "High" : "Highest"); iLog->Log(" *****************************************\n\n"); iLog->Log("Init Shaders\n"); m_numtmus = di->Caps.MaxSimultaneousTextures; #ifndef WIN64 // NOTE: AMD64 port: find the 64-bit CG runtime if (!m_CGContext) { m_CGContext = cgCreateContext(); assert(m_CGContext); cgD3D9SetDevice(mfGetD3DDevice()); #ifdef _DEBUG cgD3D9EnableDebugTracing(true); #endif } #endif gRenDev->m_cEF.mfInit(); EF_Init(); //ChangeResolution(1024, 768, 32, 75, false); m_bInitialized = true; // Cry_memcheck(); // Success, return the window handle return (m_hWnd); } const char *CD3D9Renderer::D3DError( HRESULT h ) { const TCHAR* strHRESULT; strHRESULT = DXGetErrorString9(h); return strHRESULT; } bool CD3D9Renderer::Error(char *Msg, HRESULT h) { const char *str = D3DError(h); iLog->Log("Error: %s (%s)", Msg, str); //UnSetRes(); //if (Msg) // iConsole->Exit("%s (%s)\n", Msg, str); //else // iConsole->Exit("(%s)\n", str); return false; } //============================================================================= //----------------------------------------------------------------------------- // Name: FindBestWindowedMode() // Desc: Sets up m_D3DSettings with best available windowed mode, subject to // the bRequireHAL and bRequireREF constraints. Returns false if no such // mode can be found. //----------------------------------------------------------------------------- bool CD3D9Renderer::FindBestWindowedMode( bool bRequireHAL, bool bRequireREF ) { // Get display mode of primary adapter (which is assumed to be where the window // will appear) D3DDISPLAYMODE primaryDesktopDisplayMode; m_pD3D->GetAdapterDisplayMode(0, &primaryDesktopDisplayMode); D3DAdapterInfo* pBestAdapterInfo = NULL; D3DDeviceInfo* pBestDeviceInfo = NULL; D3DDeviceCombo* pBestDeviceCombo = NULL; for(int iai=0; iaiNum(); iai++) { D3DAdapterInfo* pAdapterInfo = m_D3DEnum.m_pAdapterInfoList->Get(iai); for(int idi=0; idipDeviceInfoList->Num(); idi++) { D3DDeviceInfo* pDeviceInfo = pAdapterInfo->pDeviceInfoList->Get(idi); if (bRequireHAL && pDeviceInfo->DevType != D3DDEVTYPE_HAL) continue; if (bRequireREF && pDeviceInfo->DevType != D3DDEVTYPE_REF) continue; for(int idc=0; idcpDeviceComboList->Num(); idc++) { D3DDeviceCombo* pDeviceCombo = pDeviceInfo->pDeviceComboList->Get(idc); bool bAdapterMatchesBB = (pDeviceCombo->BackBufferFormat == pDeviceCombo->AdapterFormat); if (!pDeviceCombo->IsWindowed) continue; if (pDeviceCombo->AdapterFormat != primaryDesktopDisplayMode.Format) continue; // If we haven't found a compatible DeviceCombo yet, or if this set // is better (because it's a HAL, and/or because formats match better), // save it if( pBestDeviceCombo == NULL || pBestDeviceCombo->DevType != D3DDEVTYPE_HAL && pDeviceCombo->DevType == D3DDEVTYPE_HAL || pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesBB) { pBestAdapterInfo = pAdapterInfo; pBestDeviceInfo = pDeviceInfo; pBestDeviceCombo = pDeviceCombo; if( pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesBB ) { // This windowed device combo looks great -- take it goto EndWindowedDeviceComboSearch; } // Otherwise keep looking for a better windowed device combo } } } } EndWindowedDeviceComboSearch: if (pBestDeviceCombo == NULL ) return false; m_D3DSettings.pWindowed_AdapterInfo = pBestAdapterInfo; m_D3DSettings.pWindowed_DeviceInfo = pBestDeviceInfo; m_D3DSettings.pWindowed_DeviceCombo = pBestDeviceCombo; m_D3DSettings.IsWindowed = true; m_D3DSettings.Windowed_DisplayMode = primaryDesktopDisplayMode; m_D3DSettings.Windowed_Width = m_rcWindowClient.right - m_rcWindowClient.left; m_D3DSettings.Windowed_Height = m_rcWindowClient.bottom - m_rcWindowClient.top; if (m_D3DEnum.AppUsesDepthBuffer) m_D3DSettings.Windowed_DepthStencilBufferFormat = pBestDeviceCombo->pDepthStencilFormatList->Get(0); m_D3DSettings.Windowed_MultisampleType = pBestDeviceCombo->pMultiSampleTypeList->Get(0); m_D3DSettings.Windowed_MultisampleQuality = 0; m_D3DSettings.Windowed_VertexProcessingType = pBestDeviceCombo->pVertexProcessingTypeList->Get(0); m_D3DSettings.Windowed_PresentInterval = pBestDeviceCombo->pPresentIntervalList->Get(0); return true; } //----------------------------------------------------------------------------- // Name: FindBestFullscreenMode() // Desc: Sets up m_D3DSettings with best available fullscreen mode, subject to // the bRequireHAL and bRequireREF constraints. Returns false if no such // mode can be found. //----------------------------------------------------------------------------- bool CD3D9Renderer::FindBestFullscreenMode( bool bRequireHAL, bool bRequireREF ) { // For fullscreen, default to first HAL DeviceCombo that supports the current desktop // display mode, or any display mode if HAL is not compatible with the desktop mode, or // non-HAL if no HAL is available D3DDISPLAYMODE adapterDesktopDisplayMode; D3DDISPLAYMODE bestAdapterDesktopDisplayMode; D3DDISPLAYMODE bestDisplayMode; bestAdapterDesktopDisplayMode.Width = 0; bestAdapterDesktopDisplayMode.Height = 0; bestAdapterDesktopDisplayMode.Format = D3DFMT_UNKNOWN; bestAdapterDesktopDisplayMode.RefreshRate = 0; D3DAdapterInfo* pBestAdapterInfo = NULL; D3DDeviceInfo* pBestDeviceInfo = NULL; D3DDeviceCombo* pBestDeviceCombo = NULL; for(int iai=0; iaiNum(); iai++) { D3DAdapterInfo* pAdapterInfo = m_D3DEnum.m_pAdapterInfoList->Get(iai); m_pD3D->GetAdapterDisplayMode( pAdapterInfo->AdapterOrdinal, &adapterDesktopDisplayMode ); for(int idi=0; idipDeviceInfoList->Num(); idi++) { D3DDeviceInfo* pDeviceInfo = pAdapterInfo->pDeviceInfoList->Get(idi); if (bRequireHAL && pDeviceInfo->DevType != D3DDEVTYPE_HAL) continue; if (bRequireREF && pDeviceInfo->DevType != D3DDEVTYPE_REF) continue; for(int idc=0; idcpDeviceComboList->Num(); idc++) { D3DDeviceCombo* pDeviceCombo = pDeviceInfo->pDeviceComboList->Get(idc); bool bAdapterMatchesBB = (pDeviceCombo->BackBufferFormat == pDeviceCombo->AdapterFormat); bool bAdapterMatchesDesktop = (pDeviceCombo->AdapterFormat == adapterDesktopDisplayMode.Format); if (pDeviceCombo->IsWindowed) continue; // If we haven't found a compatible set yet, or if this set // is better (because it's a HAL, and/or because formats match better), // save it if (pBestDeviceCombo == NULL || (pBestDeviceCombo->DevType != D3DDEVTYPE_HAL && pDeviceInfo->DevType == D3DDEVTYPE_HAL) || (pDeviceCombo->DevType == D3DDEVTYPE_HAL && pBestDeviceCombo->AdapterFormat != adapterDesktopDisplayMode.Format && bAdapterMatchesDesktop) || pDeviceCombo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB ) { bestAdapterDesktopDisplayMode = adapterDesktopDisplayMode; pBestAdapterInfo = pAdapterInfo; pBestDeviceInfo = pDeviceInfo; pBestDeviceCombo = pDeviceCombo; if (pDeviceInfo->DevType == D3DDEVTYPE_HAL && bAdapterMatchesDesktop && bAdapterMatchesBB) { // This fullscreen device combo looks great -- take it goto EndFullscreenDeviceComboSearch; } // Otherwise keep looking for a better fullscreen device combo } } } } EndFullscreenDeviceComboSearch: if (pBestDeviceCombo == NULL) return false; // Need to find a display mode on the best adapter that uses pBestDeviceCombo->AdapterFormat // and is as close to bestAdapterDesktopDisplayMode's res as possible bestDisplayMode.Width = 0; bestDisplayMode.Height = 0; bestDisplayMode.Format = D3DFMT_UNKNOWN; bestDisplayMode.RefreshRate = 0; for(int idm=0; idmpDisplayModeList->Num(); idm++) { D3DDISPLAYMODE* pdm = &pBestAdapterInfo->pDisplayModeList->Get(idm); if( pdm->Format != pBestDeviceCombo->AdapterFormat ) continue; if( pdm->Width == bestAdapterDesktopDisplayMode.Width && pdm->Height == bestAdapterDesktopDisplayMode.Height && pdm->RefreshRate == bestAdapterDesktopDisplayMode.RefreshRate ) { // found a perfect match, so stop bestDisplayMode = *pdm; break; } else if( pdm->Width == bestAdapterDesktopDisplayMode.Width && pdm->Height == bestAdapterDesktopDisplayMode.Height && pdm->RefreshRate > bestDisplayMode.RefreshRate ) { // refresh rate doesn't match, but width/height match, so keep this // and keep looking bestDisplayMode = *pdm; } else if( pdm->Width == bestAdapterDesktopDisplayMode.Width ) { // width matches, so keep this and keep looking bestDisplayMode = *pdm; } else if( bestDisplayMode.Width == 0 ) { // we don't have anything better yet, so keep this and keep looking bestDisplayMode = *pdm; } } m_D3DSettings.pFullscreen_AdapterInfo = pBestAdapterInfo; m_D3DSettings.pFullscreen_DeviceInfo = pBestDeviceInfo; m_D3DSettings.pFullscreen_DeviceCombo = pBestDeviceCombo; m_D3DSettings.IsWindowed = false; m_D3DSettings.Fullscreen_DisplayMode = bestDisplayMode; if (m_D3DEnum.AppUsesDepthBuffer) m_D3DSettings.Fullscreen_DepthStencilBufferFormat = pBestDeviceCombo->pDepthStencilFormatList->Get(0); m_D3DSettings.Fullscreen_MultisampleType = pBestDeviceCombo->pMultiSampleTypeList->Get(0); m_D3DSettings.Fullscreen_MultisampleQuality = 0; m_D3DSettings.Fullscreen_VertexProcessingType = pBestDeviceCombo->pVertexProcessingTypeList->Get(0); m_D3DSettings.Fullscreen_PresentInterval = D3DPRESENT_INTERVAL_DEFAULT; return true; } //----------------------------------------------------------------------------- // Name: ChooseInitialD3DSettings() // Desc: //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::ChooseInitialD3DSettings() { bool bFoundFullscreen = FindBestFullscreenMode( false, false ); bool bFoundWindowed = FindBestWindowedMode( false, false ); if( m_bFullScreen && bFoundFullscreen ) m_D3DSettings.IsWindowed = false; if( !bFoundWindowed && bFoundFullscreen ) m_D3DSettings.IsWindowed = false; if( !bFoundFullscreen && !bFoundWindowed ) return D3DAPPERR_NOCOMPATIBLEDEVICES; return S_OK; } //----------------------------------------------------------------------------- // Name: CD3D9Renderer::ConfirmDevice() // Desc: Called during device intialization, this code checks the device // for some minimum set of capabilities //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior, D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat ) { return S_OK; } //----------------------------------------------------------------------------- // Name: ConfirmDeviceHelper() // Desc: Static function used by D3DEnumeration //----------------------------------------------------------------------------- bool CD3D9Renderer::ConfirmDeviceHelper(D3DCAPS9* pCaps, VertexProcessingType vertexProcessingType, D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat) { DWORD dwBehavior; if (vertexProcessingType == SOFTWARE_VP) dwBehavior = D3DCREATE_SOFTWARE_VERTEXPROCESSING; else if (vertexProcessingType == MIXED_VP) dwBehavior = D3DCREATE_MIXED_VERTEXPROCESSING; else if (vertexProcessingType == HARDWARE_VP) dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING; else if (vertexProcessingType == PURE_HARDWARE_VP) dwBehavior = D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; else dwBehavior = 0; // TODO: throw exception return SUCCEEDED(gcpRendD3D->ConfirmDevice(pCaps, dwBehavior, adapterFormat, backBufferFormat)); } static char *sD3DFMT( D3DFORMAT fmt ) { switch( fmt ) { case D3DFMT_R8G8B8: return "D3DFMT_R8G8B8"; case D3DFMT_A8R8G8B8: return "D3DFMT_A8R8G8B8"; case D3DFMT_X8R8G8B8: return "D3DFMT_X8R8G8B8"; case D3DFMT_R5G6B5: return "D3DFMT_R5G6B5"; case D3DFMT_X1R5G5B5: return "D3DFMT_X1R5G5B5"; case D3DFMT_A1R5G5B5: return "D3DFMT_A1R5G5B5"; case D3DFMT_A4R4G4B4: return "D3DFMT_A4R4G4B4"; case D3DFMT_R3G3B2: return "D3DFMT_R3G3B2"; case D3DFMT_A8R3G3B2: return "D3DFMT_A8R3G3B2"; case D3DFMT_X4R4G4B4: return "D3DFMT_X4R4G4B4"; case D3DFMT_A2B10G10R10: return "D3DFMT_A2B10G10R10"; case D3DFMT_A2R10G10B10: return "D3DFMT_A2R10G10B10"; case D3DFMT_D24S8: return "D3DFMT_D24S8"; case D3DFMT_D24X8: return "D3DFMT_D24X8"; case D3DFMT_D16: return "D3DFMT_D16"; case D3DFMT_D24X4S4: return "D3DFMT_D24X4S4"; case D3DFMT_D32: return "D3DFMT_D32"; case D3DFMT_D16_LOCKABLE: return "D3DFMT_D16_LOCKABLE"; case D3DFMT_D15S1: return "D3DFMT_D15S1"; case D3DFMT_D32F_LOCKABLE: return "D3DFMT_D32F_LOCKABLE"; case D3DFMT_D24FS8: return "D3DFMT_D24FS8"; default: return "Unknown"; } } //----------------------------------------------------------------------------- // Name: Initialize3DEnvironment() // Desc: //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::Initialize3DEnvironment() { HRESULT hr; D3DAdapterInfo* pAdapterInfo = m_D3DSettings.PAdapterInfo(); D3DDeviceInfo* pDeviceInfo = m_D3DSettings.PDeviceInfo(); D3DDISPLAYMODE ModeInfo = m_D3DSettings.DisplayMode(); SetRendParms(&ModeInfo, pDeviceInfo); // Prepare window for possible windowed/fullscreen change AdjustWindowForChange(); // Set up the presentation parameters BuildPresentParamsFromSettings(); if( pDeviceInfo->Caps.PrimitiveMiscCaps & D3DPMISCCAPS_NULLREFERENCE ) { // Warn user about null ref device that can't render anything iLog->Log("ERROR: Chosed NULL Ref Device that can't render anything"); return E_FAIL; } DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE; if (CV_d3d9_forcesoftware) behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; else { if (m_D3DSettings.GetVertexProcessingType() == SOFTWARE_VP) behaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING; else if (m_D3DSettings.GetVertexProcessingType() == MIXED_VP) behaviorFlags |= D3DCREATE_MIXED_VERTEXPROCESSING; else if (m_D3DSettings.GetVertexProcessingType() == HARDWARE_VP) behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; else if (m_D3DSettings.GetVertexProcessingType() == PURE_HARDWARE_VP) behaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE; } // Create the device iLog->Log("Creating D3D device (Adapter format: %s, BackBuffer format: %s, Depth format: %s)", sD3DFMT(m_D3DSettings.AdapterFormat()), sD3DFMT(m_d3dpp.BackBufferFormat), sD3DFMT(m_d3dpp.AutoDepthStencilFormat)); if (!CV_d3d9_nvperfhud) hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice); else hr = m_pD3D->CreateDevice(m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, (HWND)m_CurrContext->m_hWnd, behaviorFlags & ~(D3DCREATE_PUREDEVICE), &m_d3dpp, &m_pd3dDevice); if( SUCCEEDED(hr) ) { // If we cannot use Queries Back Buffer should be lockable if (!(m_d3dpp.Flags & D3DPRESENTFLAG_LOCKABLE_BACKBUFFER)) { hr = m_pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, NULL); if(hr != D3DERR_NOTAVAILABLE) hr = m_pd3dDevice->CreateQuery (D3DQUERYTYPE_OCCLUSION, NULL); if(hr == D3DERR_NOTAVAILABLE) { SAFE_RELEASE(m_pd3dDevice); Sleep(1000); m_d3dpp.Flags |= D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; // Create the device hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice); if (FAILED(hr)) { SAFE_RELEASE(m_pd3dDevice); Sleep(1000); m_d3dpp.Flags &= ~D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; hr = m_pD3D->CreateDevice(m_D3DSettings.AdapterOrdinal(), pDeviceInfo->DevType, (HWND)m_CurrContext->m_hWnd, behaviorFlags, &m_d3dpp, &m_pd3dDevice); } } } if( SUCCEEDED(hr) ) { // When moving from fullscreen to windowed mode, it is important to // adjust the window size after recreating the device rather than // beforehand to ensure that you get the window size you want. For // example, when switching from 640x480 fullscreen to windowed with // a 1000x600 window on a 1024x768 desktop, it is impossible to set // the window size to 1000x600 until after the display mode has // changed to 1024x768, because windows cannot be larger than the // desktop. ShowWindow(m_hWnd, SW_SHOW); UpdateWindow(m_hWnd); SetForegroundWindow(m_hWnd); SetFocus(m_hWnd); if(!m_bFullScreen ) { SetWindowPos(m_hWnd, HWND_NOTOPMOST, m_rcWindowBounds.left, m_rcWindowBounds.top, (m_rcWindowBounds.right-m_rcWindowBounds.left), (m_rcWindowBounds.bottom - m_rcWindowBounds.top), SWP_SHOWWINDOW); } ChangeLog(); DisplaySplash(); // Store device Caps m_pd3dDevice->GetDeviceCaps(&m_d3dCaps); m_dwCreateFlags = behaviorFlags; // Store device description if(pDeviceInfo->DevType == D3DDEVTYPE_REF) lstrcpy(m_strDeviceStats, TEXT("REF")); else if(pDeviceInfo->DevType == D3DDEVTYPE_HAL) lstrcpy(m_strDeviceStats, TEXT("HAL")); else if(pDeviceInfo->DevType == D3DDEVTYPE_SW) lstrcpy( m_strDeviceStats, TEXT("SW") ); if(behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING && behaviorFlags & D3DCREATE_PUREDEVICE) { if(pDeviceInfo->DevType == D3DDEVTYPE_HAL) lstrcat( m_strDeviceStats, TEXT(" (pure hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated pure hw vp)") ); } else if(behaviorFlags & D3DCREATE_HARDWARE_VERTEXPROCESSING) { if(pDeviceInfo->DevType == D3DDEVTYPE_HAL) lstrcat( m_strDeviceStats, TEXT(" (hw vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated hw vp)") ); } else if(behaviorFlags & D3DCREATE_MIXED_VERTEXPROCESSING) { if( pDeviceInfo->DevType == D3DDEVTYPE_HAL ) lstrcat( m_strDeviceStats, TEXT(" (mixed vp)") ); else lstrcat( m_strDeviceStats, TEXT(" (simulated mixed vp)") ); } else if(behaviorFlags & D3DCREATE_SOFTWARE_VERTEXPROCESSING) { lstrcat( m_strDeviceStats, TEXT(" (sw vp)") ); } if(pDeviceInfo->DevType == D3DDEVTYPE_HAL) { // Be sure not to overflow m_strDeviceStats when appending the adapter // description, since it can be long. Note that the adapter description // is initially CHAR and must be converted to TCHAR. lstrcat( m_strDeviceStats, TEXT(": ") ); const int cchDesc = sizeof(pAdapterInfo->AdapterIdentifier.Description); TCHAR szDescription[cchDesc]; strncpy(szDescription, pAdapterInfo->AdapterIdentifier.Description, cchDesc); int maxAppend = sizeof(m_strDeviceStats) / sizeof(TCHAR) - lstrlen( m_strDeviceStats ) - 1; strncat(m_strDeviceStats, szDescription, maxAppend); } // Store render target surface desc CD3D9TexMan *pTM = (CD3D9TexMan *)m_TexMan; m_Features |= RFT_ZLOCKABLE; m_pd3dDevice->GetDepthStencilSurface( &m_pZBuffer ); m_pZBuffer->GetDesc( &m_d3dsdZBuffer ); m_pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_pBackBuffer ); m_pBackBuffer->GetDesc(&m_d3dsdBackBuffer); // Initialize the app's device-dependent objects hr = InitDeviceObjects(); if( FAILED(hr) ) { DeleteDeviceObjects(); } else { m_bDeviceObjectsInited = true; hr = RestoreDeviceObjects(); if( FAILED(hr) ) { InvalidateDeviceObjects(); } else { m_bDeviceObjectsRestored = true; return S_OK; } } // Cleanup before we try again Cleanup3DEnvironment(); } } return hr; } struct SMultiSample { D3DMULTISAMPLE_TYPE Type; DWORD Quality; }; int __cdecl MS_Cmp(const void* v1, const void* v2) { SMultiSample *pMS0 = (SMultiSample *)v1; SMultiSample *pMS1 = (SMultiSample *)v2; if (pMS0->Type < pMS1->Type) return -1; if (pMS0->Type > pMS1->Type) return 1; if (pMS0->Quality < pMS1->Quality) return -1; if (pMS0->Quality > pMS1->Quality) return 1; return 0; } //! Return all supported by video card video AA formats int CD3D9Renderer::EnumAAFormats(TArray& Formats, bool bReset) { int i; if (bReset) { Formats.Free(); return 0; } SAAFormat DF; D3DAdapterInfo *pAI = m_D3DSettings.PAdapterInfo(); D3DDeviceCombo *pDev = m_D3DSettings.PDeviceCombo(); TArray MSList; int nNONMaskable = 0; int nMaskable = 0; int nQuality = 0; for (i=0; ipMultiSampleTypeList->Num(); i++) { if (pDev->pMultiSampleTypeList->Get(i) == D3DMULTISAMPLE_NONE) continue; SMultiSample MS; MS.Type = pDev->pMultiSampleTypeList->Get(i); if (MS.Type == D3DMULTISAMPLE_NONMASKABLE) nNONMaskable++; else nMaskable++; for (DWORD j=0; jpMultiSampleQualityList->Get(i); j++) { MS.Quality = j; MSList.AddElem(MS); if (MS.Type == D3DMULTISAMPLE_NONMASKABLE) nQuality++; } } qsort(&MSList[0], MSList.Num(), sizeof(MSList[0]), MS_Cmp); DF.nAPIType = D3DMULTISAMPLE_NONMASKABLE; DF.nQuality = 0; DF.nSamples = 1; char str[64]; for (i=0; iAdapterIdentifier.VendorId == 4318 && nNONMaskable == 1 && nQuality == 4) { switch (DF.nQuality) { case 0: strcpy(DF.szDescr, "2x"); break; case 1: strcpy(DF.szDescr, "Quincunx"); break; case 2: strcpy(DF.szDescr, "4x"); break; case 3: strcpy(DF.szDescr, "4xS"); break; default: sprintf(str, "AA Quality lev. %d", DF.nQuality); strcpy(DF.szDescr, str); break; } } else { sprintf(str, "AA Quality lev. %d", MSList[i].Quality); strcpy(DF.szDescr, str); } Formats.AddElem(DF); } else { DF.nAPIType = MSList[i].Type; DF.nQuality = MSList[i].Quality; DF.nSamples = MSList[i].Type; sprintf(str, "%dx Samples", MSList[i].Type); strcpy(DF.szDescr, str); Formats.AddElem(DF); } } return Formats.Num(); } int CD3D9Renderer::GetAAFormat(TArray& Formats, bool bReset) { int nNums = EnumAAFormats(Formats, bReset); if (bReset) return nNums; int i; if (!CV_r_fsaa) return -1; for (i=0; iGetCVar("r_FSAA_samples"); if (pVar) pVar->Set(Formats[0].nSamples); pVar = iConsole->GetCVar("r_FSAA_quality"); if (pVar) pVar->Set(Formats[0].nQuality); return 0; } //----------------------------------------------------------------------------- // Name: BuildPresentParamsFromSettings() // Desc: //----------------------------------------------------------------------------- void CD3D9Renderer::BuildPresentParamsFromSettings() { m_d3dpp.Windowed = m_D3DSettings.IsWindowed; m_d3dpp.BackBufferCount = CV_d3d9_triplebuffering ? 2 : 1; m_d3dpp.MultiSampleType = m_D3DSettings.MultisampleType(); m_d3dpp.MultiSampleQuality = m_D3DSettings.MultisampleQuality(); m_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; m_d3dpp.EnableAutoDepthStencil = m_D3DEnum.AppUsesDepthBuffer; m_d3dpp.hDeviceWindow = m_hWnd; if( m_D3DEnum.AppUsesDepthBuffer ) { if (CV_d3d9_forcesoftware) m_d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; else m_d3dpp.Flags = 0; m_d3dpp.AutoDepthStencilFormat = m_D3DSettings.DepthStencilBufferFormat(); } else { m_d3dpp.Flags = 0; } if(!m_bFullScreen) { if (m_bEditor) { m_d3dpp.BackBufferWidth = m_deskwidth; m_d3dpp.BackBufferHeight = m_deskheight; } else { m_d3dpp.BackBufferWidth = m_width; m_d3dpp.BackBufferHeight = m_height; } m_d3dpp.BackBufferFormat = m_D3DSettings.PDeviceCombo()->BackBufferFormat; m_d3dpp.FullScreen_RefreshRateInHz = 0; m_d3dpp.PresentationInterval = m_D3DSettings.PresentInterval(); } else { m_d3dpp.BackBufferWidth = m_D3DSettings.DisplayMode().Width; m_d3dpp.BackBufferHeight = m_D3DSettings.DisplayMode().Height; m_d3dpp.BackBufferFormat = m_D3DSettings.PDeviceCombo()->BackBufferFormat; m_d3dpp.FullScreen_RefreshRateInHz = m_D3DSettings.Fullscreen_DisplayMode.RefreshRate; m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; //m_D3DSettings.PresentInterval(); } if (CV_r_fsaa) { TArray Formats; int nNum = GetAAFormat(Formats, false); D3DMULTISAMPLE_TYPE nType = (D3DMULTISAMPLE_TYPE)Formats[nNum].nAPIType; DWORD nQualityLevel = 0; HRESULT hr = m_pD3D->CheckDeviceMultiSampleType(m_D3DSettings.AdapterOrdinal(), m_D3DSettings.DevType(), m_d3dpp.BackBufferFormat, m_d3dpp.Windowed, nType, &nQualityLevel); if (!FAILED(hr) && nQualityLevel >= (DWORD)Formats[nNum].nQuality) { HRESULT hr = m_pD3D->CheckDeviceMultiSampleType(m_D3DSettings.AdapterOrdinal(), m_D3DSettings.DevType(), m_d3dpp.AutoDepthStencilFormat, m_d3dpp.Windowed, nType, &nQualityLevel); if (!FAILED(hr) && nQualityLevel >= (DWORD)Formats[nNum].nQuality) { if( CV_r_fsaa == 1 ) { m_d3dpp.MultiSampleType = nType; m_d3dpp.MultiSampleQuality = Formats[nNum].nQuality; m_Features |= RFT_SUPPORTFSAA; } else { // Use special mode to enable FSAA in HDR which requires the d3d device to be setup w/o a FSAA backbuffer! m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; m_d3dpp.MultiSampleQuality = 0; } } } m_FSAA = CV_r_fsaa; m_FSAA_samples = Formats[nNum].nSamples; m_FSAA_quality = Formats[nNum].nQuality; GetAAFormat(Formats, true); } else { m_FSAA = 0; m_d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; m_d3dpp.MultiSampleQuality = 0; } } //----------------------------------------------------------------------------- // Name: Cleanup3DEnvironment() // Desc: Cleanup scene objects //----------------------------------------------------------------------------- void CD3D9Renderer::Cleanup3DEnvironment() { if( m_pd3dDevice != NULL ) { if( m_bDeviceObjectsRestored ) { m_bDeviceObjectsRestored = false; InvalidateDeviceObjects(); } if( m_bDeviceObjectsInited ) { m_bDeviceObjectsInited = false; DeleteDeviceObjects(); } RestoreGamma(); if( m_pd3dDevice->Release() > 0 ) { iLog->Log("ERROR: CD3D9Renderer::Cleanup3DEnvironment: Non zero reference counter after release of D3D Device"); while( m_pd3dDevice->Release() ) {} } m_pd3dDevice = NULL; } } //----------------------------------------------------------------------------- // Name: Reset3DEnvironment() // Desc: //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::Reset3DEnvironment() { HRESULT hr; // Release all vidmem objects if( m_bDeviceObjectsRestored ) { m_bDeviceObjectsRestored = false; InvalidateDeviceObjects(); } /*for (int i=0; im_pRes->GetType() == D3DRTYPE_INDEXBUFFER) { D3DINDEXBUFFER_DESC desc; IDirect3DIndexBuffer9 *pIB = (IDirect3DIndexBuffer9 *)vb->m_pRes; pIB->GetDesc(&desc); assert(desc.Pool != D3DPOOL_DEFAULT); } else if (vb->m_pRes->GetType() == D3DRTYPE_VERTEXBUFFER) { D3DVERTEXBUFFER_DESC desc; IDirect3DVertexBuffer9 *pIB = (IDirect3DVertexBuffer9 *)vb->m_pRes; pIB->GetDesc(&desc); assert(desc.Pool != D3DPOOL_DEFAULT); } else assert(0); }*/ // Reset the device if( FAILED( hr = m_pd3dDevice->Reset( &m_d3dpp ) ) ) return hr; // Initialize the app's device-dependent objects hr = RestoreDeviceObjects(); if( FAILED(hr) ) { InvalidateDeviceObjects(); return hr; } m_bDeviceObjectsRestored = true; m_bTemporaryDisabledSFX = false; return S_OK; } bool CD3D9Renderer::ChooseDevice(void) { HRESULT hr; // Save window properties GetWindowRect( m_hWnd, &m_rcWindowBounds ); GetClientRect( m_hWnd, &m_rcWindowClient ); if(FAILED(hr = ChooseInitialD3DSettings())) return Error("Couldn't find any suitable device", hr); char drv[64]; strcpy(drv, CV_d3d9_device->GetString()); int numAdap = -1; bool bAuto = false; if (!strnicmp(drv, "auto", 4)) bAuto = true; else if (!strnicmp(drv, "primary", 7)) numAdap = 0; else if (!strnicmp(drv, "3dfx", 4) || !strnicmp(drv, "second", 6) || !strnicmp(drv, "Voodoo", 6)) numAdap = 1; else if (drv[0] && isdigit(drv[0])) numAdap = atol(drv); else { iLog->Log ( "Unknown device name '%s' (use AutoDetect)\n", drv); iLog->Log ( "Only 'Auto', 'Primary', '3dfx' or digital device ID are supported\n"); bAuto = true; } if (numAdap < 0) numAdap = 0; int nDev = -1; bool bAllowSoft = false; while (true) { if (bAuto) { for(int a=0; aNum(); a++) { if ((nDev=FindSuitableDevice(a, bAllowSoft)) >= 0) { numAdap = a; break; } } } else { nDev = FindSuitableDevice(numAdap, bAllowSoft); } if (nDev < 0) { if (!bAllowSoft) { if (CV_d3d9_allowsoftware) { bAllowSoft = true; continue; } } return Error("Can't find any suitable D3D device\n", 0); } break; } // The focus window can be a specified to be a different window than the // device window. If not, use the device window as the focus window. if( m_CurrContext == NULL ) CreateContext(m_hWnd); return true; } bool CD3D9Renderer::SetRes(void) { UnSetRes(); HRESULT hr; // Create the Direct3D object m_pD3D = Direct3DCreate9( D3D_SDK_VERSION ); if( m_pD3D == NULL ) return Error("DirectX9 not installed", 0); m_D3DEnum.SetD3D(m_pD3D); m_D3DEnum.ConfirmDeviceCallback = ConfirmDeviceHelper; // Build a list of Direct3D adapters, modes and devices. The // ConfirmDevice() callback is used to confirm that only devices that // meet the app's requirements are considered. if(FAILED(hr = m_D3DEnum.Enumerate())) { if (hr == D3DAPPERR_NOWINDOWABLEDEVICES) { if (!m_bFullScreen) return Error("Couldn't build list of D3D devices", hr); } else return Error("Couldn't build list of D3D devices", hr); } ChooseDevice(); // Initialize the 3D environment for the app if( FAILED( hr = Initialize3DEnvironment() ) ) return Error("Couldn't initialize 3D environment", hr); if (FAILED (hr = D3DXCreateMatrixStack(0, &m_matView))) return false; if (FAILED (hr = D3DXCreateMatrixStack(0, &m_matProj))) return false; D3DXMatrixIdentity(&m_TexMatrix[0]); D3DXMatrixIdentity(&m_TexMatrix[1]); D3DXMatrixIdentity(&m_TexMatrix[2]); D3DXMatrixIdentity(&m_TexMatrix[3]); RestoreDeviceObjects(); return true; } //----------------------------------------------------------------------------- // Name: CD3D9Renderer::mfAdjustWindowForChange() // Desc: Prepare the window for a possible change between windowed mode and // fullscreen mode. This function is virtual and thus can be overridden // to provide different behavior, such as switching to an entirely // different window for fullscreen mode (as in the MFC sample apps). //----------------------------------------------------------------------------- HRESULT CD3D9Renderer::AdjustWindowForChange() { if (m_bEditor) return S_OK; if( !m_bFullScreen ) { // Set windowed-mode style SetWindowLong( m_hWnd, GWL_STYLE, m_dwWindowStyle ); } else { // Set fullscreen-mode style SetWindowLong( m_hWnd, GWL_STYLE, WS_POPUP|WS_SYSMENU|WS_VISIBLE ); } return S_OK; } HRESULT CD3D9Renderer::InitDeviceObjects() { int i; // Gamma correction support if (m_d3dCaps.Caps2 & D3DCAPS2_FULLSCREENGAMMA) m_Features |= RFT_HWGAMMA; if (m_d3dCaps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) m_bGammaCalibrate = true; else m_bGammaCalibrate = false; // Device Id's D3DAdapterInfo *pAI = m_D3DSettings.PAdapterInfo(); D3DADAPTER_IDENTIFIER9 *ai = &pAI->AdapterIdentifier; iLog->Log ( "D3D Adapter: Driver name: %s\n", ai->Driver); iLog->Log ( "D3D Adapter: Driver description: %s\n", ai->Description); iLog->Log ( "D3D Adapter: Driver version: %d.%02d.%02d.%04d\n", HIWORD( ai->DriverVersion.u.HighPart ), LOWORD( ai->DriverVersion.u.HighPart ), HIWORD(ai->DriverVersion.u.LowPart), LOWORD(ai->DriverVersion.u.LowPart)); // Unique driver/device identifier: GUID *pGUID = &ai->DeviceIdentifier; iLog->Log ( "D3D Adapter: Driver GUID: %08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\n", pGUID->Data1, pGUID->Data2, pGUID->Data3, pGUID->Data4[0], pGUID->Data4[1], pGUID->Data4[2], pGUID->Data4[3], pGUID->Data4[4], pGUID->Data4[5], pGUID->Data4[6], pGUID->Data4[7] ); iLog->Log ( "D3D Adapter: VendorId = %i\n", ai->VendorId); iLog->Log ( "D3D Adapter: DeviceId = %i\n", ai->DeviceId); iLog->Log ( "D3D Adapter: SubSysId = %i\n", ai->SubSysId); iLog->Log ( "D3D Adapter: Revision = %i\n", ai->Revision); // Hardware-specific initialization and workarounds for driver bugs. { bool ConstrainAspect = 1; if( CV_d3d9_nodeviceid ) { iLog->Log ("D3D Detected: -nodeviceid specified, 3D device identification skipped\n"); } else if( ai->VendorId==4098 ) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_RADEON; iLog->Log ("D3D Detected: ATI video card\n"); if( ai->DeviceId==18242 ) { iLog->Log ("D3D Detected: ATI Rage Pro\n"); } else if( ai->DeviceId==21062 ) { iLog->Log ("D3D Detected: ATI Rage 128\n"); } else if( ai->DeviceId==20812 ) { iLog->Log ("D3D Detected: ATI Radeon 8500\n"); } else if( ai->DeviceId==20036 ) { iLog->Log ("D3D Detected: ATI Radeon 9700\n"); } else if( ai->DeviceId==0x4a49 ) { iLog->Log ("D3D Detected: ATI Radeon X800 Pro\n"); } if( ai->DeviceId==0x4a49 || ai->DeviceId==0x4a4a || ai->DeviceId==0x4a4b || ai->DeviceId==0x4a4c || ai->DeviceId==0x4a50 || ai->DeviceId==0x4a69 || ai->DeviceId==0x4a6a || ai->DeviceId==0x4a6b || ai->DeviceId==0x4a6c || ai->DeviceId==0x4a70 || ai->DeviceId==0x5b60 || ai->DeviceId==0x5b70 || ai->DeviceId==0x3e50 || ai->DeviceId==0x3e70 || ai->DeviceId==0x5549 || ai->DeviceId==0x5569 || ai->DeviceId==0x554b || ai->DeviceId==0x556b) { // Workaround for R42x to avoid terrain flickering _SetVar("d3d9_VBPools", 0); } } else if( ai->VendorId==4634 ) { iLog->Log ("D3D Detected: 3dfx video card\n"); if( ai->DeviceId==1 ) { iLog->Log ("D3D Detected: 3dfx Voodoo\n"); } else if( ai->DeviceId==2 ) { iLog->Log ("D3D Detected: 3dfx Voodoo2\n"); } else if( ai->DeviceId==3 ) { iLog->Log ("D3D Detected: 3dfx Voodoo Banshee\n"); } else if( ai->DeviceId==5 ) { iLog->Log ("D3D Detected: 3dfx Voodoo3\n"); } } else if( ai->VendorId==32902 ) { iLog->Log ("D3D Detected: Intel video card\n"); if( ai->DeviceId==30720 ) { iLog->Log ("D3D Detected: Intel i740\n"); } if( ai->DeviceId==7121 ) { iLog->Log ("D3D Detected: Intel 810L\n"); } if( ai->DeviceId==7123 ) { iLog->Log ("D3D Detected: Intel 810 DC100\n"); } if( ai->DeviceId==7125 ) { iLog->Log ("D3D Detected: Intel 810E\n"); } } else if( ai->VendorId==4818 ) { iLog->Log ("D3D Detected: NVidia Riva video card\n"); if( ai->DeviceId==0x18 || ai->DeviceId==0x19 ) iLog->Log ("D3D Detected: Riva 128\n"); else iLog->Log ("D3D Detected: Riva unknown\n"); } else if( ai->VendorId==4318 ) { m_Features |= RFT_FOGVP; iLog->Log ("D3D Detected: NVidia video card\n"); if( ai->DeviceId==0x20 ) { iLog->Log ("D3D Detected: Riva TNT\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x28 ) { iLog->Log ("D3D Detected: Riva TNT2/TNT2 Pro\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x29 ) { iLog->Log ("D3D Detected: Riva TNT2 Ultra\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x2c) { iLog->Log ("D3D Detected: Vanta/Vanta LT\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x2d) { iLog->Log ("D3D Detected: Riva TNT2 Model 64/Model 64 Pro\n"); ConstrainAspect = 0; } if( ai->DeviceId==0x40 ) { iLog->Log ("D3D Detected: Riva TNT2\n"); ConstrainAspect = 0; } if( ai->DeviceId==0xa0) { iLog->Log ("D3D Detected: Aladdin TNT2\n"); ConstrainAspect = 0; } if (ai->DeviceId == 0x100) iLog->Log ("D3D Detected: GeForce 256 SDR\n"); if (ai->DeviceId == 0x101) iLog->Log ("D3D Detected: GeForce 256 DDR\n"); if (ai->DeviceId == 0x103) iLog->Log ("D3D Detected: Quadro\n"); if (ai->DeviceId == 0x110) iLog->Log ("D3D Detected: GeForce2 MX/MX 400\n"); if (ai->DeviceId == 0x111) iLog->Log ("D3D Detected: GeForce2 MX 100/200\n"); if (ai->DeviceId == 0x112) iLog->Log ("D3D Detected: GeForce2 Go\n"); if (ai->DeviceId == 0x113) iLog->Log ("D3D Detected: Quadro2 MXR/EX/Go\n"); if (ai->DeviceId == 0x150) iLog->Log ("D3D Detected: GeForce2 GTS/GeForce2 Pro\n"); if (ai->DeviceId == 0x151) iLog->Log ("D3D Detected: GeForce2 Ti\n"); if (ai->DeviceId == 0x152) iLog->Log ("D3D Detected: GeForce2 Ultra\n"); if (ai->DeviceId == 0x153) iLog->Log ("D3D Detected: Quadro2 Pro\n"); if (ai->DeviceId == 0x170) iLog->Log ("D3D Detected: GeForce4 MX 460\n"); if (ai->DeviceId == 0x171) iLog->Log ("D3D Detected: GeForce4 MX 440\n"); if (ai->DeviceId == 0x172) iLog->Log ("D3D Detected: GeForce4 MX 420\n"); if (ai->DeviceId == 0x173) iLog->Log ("D3D Detected: GeForce4 MX 440-SE\n"); if (ai->DeviceId == 0x174) iLog->Log ("D3D Detected: GeForce4 440 Go\n"); if (ai->DeviceId == 0x175) iLog->Log ("D3D Detected: GeForce4 420 Go\n"); if (ai->DeviceId == 0x176) iLog->Log ("D3D Detected: GeForce4 420 Go 32M\n"); if (ai->DeviceId == 0x177) iLog->Log ("D3D Detected: GeForce4 460 Go\n"); if (ai->DeviceId == 0x178) iLog->Log ("D3D Detected: Quadro4 500 XGL\n"); if (ai->DeviceId == 0x179) iLog->Log ("D3D Detected: GeForce4 440 Go 64M\n"); if (ai->DeviceId == 0x17a) iLog->Log ("D3D Detected: Quadro4 200 NVS\n"); if (ai->DeviceId == 0x17c) iLog->Log ("D3D Detected: Quadro4 500 GoGL\n"); if (ai->DeviceId == 0x17d) iLog->Log ("D3D Detected: GeForce4 410 Go 16M\n"); if (ai->DeviceId == 0x181) iLog->Log ("D3D Detected: GeForce4 MX 440 with AGP8X\n"); if (ai->DeviceId == 0x182) iLog->Log ("D3D Detected: GeForce4 MX 440-SE with AGP8X\n"); if (ai->DeviceId == 0x183) iLog->Log ("D3D Detected: GeForce4 MX 420 with AGP8X\n"); if (ai->DeviceId == 0x186) iLog->Log ("D3D Detected: GeForce4 448 Go\n"); if (ai->DeviceId == 0x187) iLog->Log ("D3D Detected: GeForce4 488 Go\n"); if (ai->DeviceId == 0x188) iLog->Log ("D3D Detected: Quadro4 580 XGL\n"); if (ai->DeviceId == 0x18a) iLog->Log ("D3D Detected: Quadro NVS with AGP8X\n"); if (ai->DeviceId == 0x18b) iLog->Log ("D3D Detected: Quadro4 380 XGL\n"); if (ai->DeviceId == 0x1a0) iLog->Log ("D3D Detected: GeForce2 Integrated GPU\n"); if (ai->DeviceId == 0x1f0) iLog->Log ("D3D Detected: GeForce4 MX Integrated GPU\n"); if (ai->DeviceId == 0x200) iLog->Log ("D3D Detected: GeForce3\n"); if (ai->DeviceId == 0x201) iLog->Log ("D3D Detected: GeForce3 Ti 200\n"); if (ai->DeviceId == 0x202) iLog->Log ("D3D Detected: GeForce3 Ti 500\n"); if (ai->DeviceId == 0x203) iLog->Log ("D3D Detected: Quadro DCC\n"); if (ai->DeviceId == 0x250) iLog->Log ("D3D Detected: GeForce4 Ti 4600\n"); if (ai->DeviceId == 0x251) iLog->Log ("D3D Detected: GeForce4 Ti 4400\n"); if (ai->DeviceId == 0x251) iLog->Log ("D3D Detected: NV25\n"); if (ai->DeviceId == 0x253) iLog->Log ("D3D Detected: GeForce4 Ti 4200\n"); if (ai->DeviceId == 0x258) iLog->Log ("D3D Detected: Quadro4 900 XGL\n"); if (ai->DeviceId == 0x259) iLog->Log ("D3D Detected: Quadro4 750 XGL\n"); if (ai->DeviceId == 0x25b) iLog->Log ("D3D Detected: Quadro4 700 XGL\n"); if (ai->DeviceId == 0x280) iLog->Log ("D3D Detected: GeForce4 TI4800\n"); if (ai->DeviceId == 0x281) iLog->Log ("D3D Detected: GeForce4 TI4200 with AGP8X\n"); if (ai->DeviceId == 0x282) iLog->Log ("D3D Detected: GeForce4 TI4800 SE\n"); if (ai->DeviceId == 0x286) iLog->Log ("D3D Detected: GeForce4 4200 Go\n"); if (ai->DeviceId == 0x288) iLog->Log ("D3D Detected: Quadro4 980 XGL\n"); if (ai->DeviceId == 0x289) iLog->Log ("D3D Detected: Quadro4 780 XGL\n"); if (ai->DeviceId == 0x28c) iLog->Log ("D3D Detected: Quadro4 700 GoGL\n"); if (ai->DeviceId == 0x300) iLog->Log ("D3D Detected: GeForce FX 5800\n"); if (ai->DeviceId == 0x301) iLog->Log ("D3D Detected: GeForce FX 5800 Ultra\n"); if (ai->DeviceId == 0x302) iLog->Log ("D3D Detected: GeForce FX 5800\n"); if (ai->DeviceId == 0x308) iLog->Log ("D3D Detected: QuadroFX 2000\n"); if (ai->DeviceId == 0x309) iLog->Log ("D3D Detected: QuadroFX 1000\n"); if (ai->DeviceId == 0x30a) iLog->Log ("D3D Detected: ICE FX 2000\n"); if (ai->DeviceId == 0x311) iLog->Log ("D3D Detected: GeForce FX 5600 Ultra\n"); if (ai->DeviceId == 0x312) iLog->Log ("D3D Detected: GeForce FX 5600\n"); if (ai->DeviceId == 0x313) iLog->Log ("D3D Detected: NV31\n"); if (ai->DeviceId == 0x314) iLog->Log ("D3D Detected: GeForce FX 5600SE\n"); if (ai->DeviceId == 0x316) iLog->Log ("D3D Detected: NV31M\n"); if (ai->DeviceId == 0x317) iLog->Log ("D3D Detected: NV31M Pro\n"); if (ai->DeviceId == 0x31a) iLog->Log ("D3D Detected: GeForce FX Go5600\n"); if (ai->DeviceId == 0x31b) iLog->Log ("D3D Detected: GeForce FX Go5650\n"); if (ai->DeviceId == 0x31c) iLog->Log ("D3D Detected: Quadro FX Go700\n"); if (ai->DeviceId == 0x31d) iLog->Log ("D3D Detected: NV31GLM\n"); if (ai->DeviceId == 0x31e) iLog->Log ("D3D Detected: NV31GLM Pro\n"); if (ai->DeviceId == 0x31f) iLog->Log ("D3D Detected: NV31GLM Pro\n"); if (ai->DeviceId == 0x321) iLog->Log ("D3D Detected: GeForce FX 5200 Ultra\n"); if (ai->DeviceId == 0x322) iLog->Log ("D3D Detected: GeForce FX 5200\n"); if (ai->DeviceId == 0x323) iLog->Log ("D3D Detected: GeForce FX 5200SE\n"); if (ai->DeviceId == 0x324) iLog->Log ("D3D Detected: GeForce FX Go5200\n"); if (ai->DeviceId == 0x325) iLog->Log ("D3D Detected: GeForce FX Go5250\n"); if (ai->DeviceId == 0x328) iLog->Log ("D3D Detected: GeForce FX Go5200 32M/64M\n"); if (ai->DeviceId == 0x32a) iLog->Log ("D3D Detected: NV34GL\n"); if (ai->DeviceId == 0x32b) iLog->Log ("D3D Detected: Quadro FX 500\n"); if (ai->DeviceId == 0x32d) iLog->Log ("D3D Detected: GeForce FX Go5100\n"); if (ai->DeviceId == 0x32f) iLog->Log ("D3D Detected: NV34GL\n"); if (ai->DeviceId == 0x330) iLog->Log ("D3D Detected: GeForce FX 5900 Ultra\n"); if (ai->DeviceId == 0x331) iLog->Log ("D3D Detected: GeForce FX 5900\n"); if (ai->DeviceId == 0x332) iLog->Log ("D3D Detected: NV35\n"); if (ai->DeviceId <= 0x40 && ai->DeviceId <= 0x4f) iLog->Log ("D3D Detected: NV4X\n"); } else if( ai->VendorId==4818 ) { iLog->Log ("D3D Detected: NVidia video card\n"); if( ai->DeviceId==0x18 || ai->DeviceId==0x19) { iLog->Log ("D3D Detected: Riva 128\n"); ConstrainAspect = 0; } } else if( ai->VendorId==4139 ) { iLog->Log ("D3D Detected: Matrox video card\n"); if( ai->DeviceId==1313 ) iLog->Log ("D3D Detected: Matrox G200\n"); else if( ai->DeviceId==1317 ) iLog->Log ("D3D Detected: Matrox G400\n"); //G400 lies about texture stages, last one is for bump only } else if( ai->VendorId==0x18ca ) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_RADEON; iLog->Log ("D3D Detected: XGI video card\n"); if( ai->DeviceId==0x40 ) iLog->Log ("D3D Detected: XGI Volary V8 DUO Ultra\n"); else iLog->Log ("D3D Detected: XGI Unknown\n"); //G400 lies about texture stages, last one is for bump only } else { iLog->Log ("D3D Detected: Generic 3D accelerator\n"); // Hack for NVidia DualView if (!strnicmp(ai->Description, "NVIDIA", 6)) m_Features |= RFT_FOGVP; } } if (m_d3dCaps.PS20Caps.NumInstructionSlots >= 256 && (D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 2)) m_bDeviceSupports_PS2X = true; // Set viewport. SetViewport(0,0,CRenderer::m_width, CRenderer::m_height); // Check multitexture caps. iLog->Log ( "D3D Driver: MaxTextureBlendStages = %i\n", m_d3dCaps.MaxTextureBlendStages); iLog->Log ( "D3D Driver: MaxSimultaneousTextures = %i\n", m_d3dCaps.MaxSimultaneousTextures); if( m_d3dCaps.MaxSimultaneousTextures>=2 ) m_Features |= RFT_MULTITEXTURE; // Handle the texture formats we need. { // Zero them all. mFormatA8.Init(); // A mFormatA8L8.Init(); // A8L8 mFormat8888.Init(); // BGRA mFormat4444.Init(); // BGRA mFormat0565.Init(); // BGR mFormat0555.Init(); // BGR mFormat1555.Init(); // BGRA mFormatV8U8.Init(); // Bump mFormatCxV8U8.Init(); // Bump mFormatU5V5L6.Init(); // Bump mFormat3Dc.Init(); // 3Dc mFormatDXT1.Init(); // DXT1 mFormatDXT3.Init(); // DXT3 mFormatDXT5.Init(); // DXT5 mFormatPal8.Init(); // Paletted8 mFormatDepth24.Init(); // Depth teture mFormatDepth16.Init(); // Depth teture // Find the needed texture formats. { mFirstPixelFormat = NULL; if(m_TextureBits >= 24) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8))) RecognizePixelFormat(mFormat8888, D3DFMT_A8R8G8B8, 32, "8888"); } if( !mFirstPixelFormat ) { m_TextureBits = 16; if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_A1R5G5B5))) RecognizePixelFormat(mFormat1555, D3DFMT_A1R5G5B5, 16, "1555"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_A4R4G4B4))) RecognizePixelFormat(mFormat4444, D3DFMT_A4R4G4B4, 16, "4444"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5))) RecognizePixelFormat(mFormat0565, D3DFMT_R5G6B5, 16, "0565"); else if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5))) RecognizePixelFormat(mFormat0555, D3DFMT_X1R5G5B5, 16, "0555"); } // Alpha formats if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_A8))) RecognizePixelFormat(mFormatA8, D3DFMT_A8, 8, "Alpha8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8))) RecognizePixelFormat(mFormatA8L8, D3DFMT_A8L8, 16, "Alpha8Lum8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_V16U16))) RecognizePixelFormat(mFormatU16V16, D3DFMT_V16U16, 32, "V16U16"); // Depth formats if (CV_d3d9_forcesoftware) m_Features |= RFT_DEPTHMAPS; else if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_D24S8))) { m_Features |= RFT_DEPTHMAPS; RecognizePixelFormat(mFormatDepth24, D3DFMT_D24S8, 8, "Depth24"); } else if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_D16))) { m_Features |= RFT_DEPTHMAPS; RecognizePixelFormat(mFormatDepth16, D3DFMT_D16, 8, "Depth16"); } //// REMOVED DRIVER HACK -- Carsten // // Workaround for NVidia drivers less than 61.00 // // Depth maps are working extremely bad on rel5X drivers // if (LOWORD(ai->DriverVersion.u.LowPart) < 6100) // { // ICVar *pVar = iConsole->GetCVar("d3d9_NoDepthMaps"); // if (pVar) // pVar->Set(1); // } if (CV_r_shadowtype == 1 || CV_d3d9_nodepthmaps) m_Features &= ~RFT_DEPTHMAPS; // Bump formats if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_V8U8))) { RecognizePixelFormat(mFormatV8U8, D3DFMT_V8U8, 16, "BumpV8U8"); m_bDeviceSupportsComprNormalmaps = 2; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_CxV8U8))) { RecognizePixelFormat(mFormatCxV8U8, D3DFMT_CxV8U8, 16, "BumpCxV8U8"); //m_bDeviceSupportsComprNormalmaps = 3; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_Q8W8V8U8))) RecognizePixelFormat(mFormatQ8W8U8V8, D3DFMT_Q8W8V8U8, 32, "BumpQ8W8U8V8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_X8L8V8U8))) RecognizePixelFormat(mFormatX8L8U8V8, D3DFMT_X8L8V8U8, 32, "BumpX8L8U8V8"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_L6V5U5))) RecognizePixelFormat(mFormatU5V5L6, D3DFMT_L6V5U5, 16, "BumpU5V5L6"); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, (D3DFORMAT)(MAKEFOURCC('A', 'T', 'I', '2'))))) { RecognizePixelFormat(mFormat3Dc, (D3DFORMAT)(MAKEFOURCC('A', 'T', 'I', '2')), 16, "3Dc"); m_bDeviceSupportsComprNormalmaps = 1; } // Paletted formats if (CV_d3d9_palettedtextures) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_P8))) { RecognizePixelFormat(mFormatPal8, D3DFMT_P8, 8, "Paletted8"); m_Features |= RFT_PALTEXTURE; } } // Compressed formats if (CV_d3d9_compressedtextures) { if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1))) { RecognizePixelFormat(mFormatDXT1, D3DFMT_DXT1, 8, "DXT1"); m_Features |= RFT_COMPRESSTEXTURE; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3))) { RecognizePixelFormat(mFormatDXT3, D3DFMT_DXT3, 8, "DXT3"); m_Features |= RFT_COMPRESSTEXTURE; } if(SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5))) { RecognizePixelFormat(mFormatDXT5, D3DFMT_DXT5, 8, "DXT5"); m_Features |= RFT_COMPRESSTEXTURE; } } } } // Verify mipmapping supported. if (!(m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)) { iLog->Log ("D3D Driver: Mipmapping not available with this driver\n"); //m_Features |= RFT_NOMIPS; } else { if( m_d3dCaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR ) iLog->Log ("D3D Driver: Supports trilinear texture filtering\n"); } if (!(m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_NOPROJECTEDBUMPENV)) { iLog->Log ("D3D Driver: Allowed projected textures with Env. bump mapping\n"); m_Features |= RFT_HW_ENVBUMPPROJECTED; } else iLog->Log ("D3D Driver: projected textures with Env. bump mapping not allowed\n"); if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_ALPHAPALETTE ) { iLog->Log ("D3D Driver: Supports alpha palettes\n"); m_bAllowAlphaPalettes = true; } if( m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY ) { m_d3dCaps.MaxTextureAspectRatio = 1; iLog->Log ("D3D Driver: Requires square textures\n"); } else if( !m_d3dCaps.MaxTextureAspectRatio ) m_d3dCaps.MaxTextureAspectRatio = max(1,max(m_d3dCaps.MaxTextureWidth,m_d3dCaps.MaxTextureHeight)); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_FOGRANGE ) iLog->Log ("D3D Driver: Supports range-based fog\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_WFOG ) iLog->Log ("D3D Driver: Supports eye-relative fog\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY ) iLog->Log ("D3D Driver: Supports anisotropic filtering\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_MIPMAPLODBIAS ) iLog->Log ("D3D Driver: Supports LOD biasing\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS ) iLog->Log ("D3D Driver: Supports Z biasing\n"); else m_Features &= ~RFT_SUPPORTZBIAS; if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ZBUFFERLESSHSR ) iLog->Log ("D3D Driver: Device can perform hidden-surface removal (HSR)\n"); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST ) iLog->Log ("D3D Driver: Supports scissor test\n"); if (m_d3dCaps.DevCaps2 & D3DDEVCAPS2_STREAMOFFSET) iLog->Log ("D3D Driver: Supports stream offset\n"); if( !(m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_POW2) ) iLog->Log ("D3D Driver: Supports non-power-of-2 textures\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_ADDSIGNED2X ) iLog->Log ("D3D Driver: Supports D3DTOP_ADDSIGNED2X TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAP ) iLog->Log ("D3D Driver: Supports D3DTOP_BUMPENVMAP TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_BUMPENVMAPLUMINANCE ) iLog->Log ("D3D Driver: Supports D3DTOP_BUMPENVMAPLUMINANCE TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3 ) iLog->Log ("D3D Driver: Supports D3DTOP_DOTPRODUCT3 TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATEALPHA_ADDCOLOR ) iLog->Log ("D3D Driver: Supports D3DTOP_MODULATEALPHA_ADDCOLOR TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_MODULATECOLOR_ADDALPHA ) iLog->Log ("D3D Driver: Supports D3DTOP_MODULATECOLOR_ADDALPHA TextureOp\n"); if( m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_ADD ) iLog->Log ("D3D Driver: Supports D3DTOP_ADD TextureOp\n"); m_MaxAnisotropyLevel = 1; m_AnisotropyLevel = 1; // Check the device for supported filtering methods if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY ) { m_MaxAnisotropyLevel = m_AnisotropyLevel = m_d3dCaps.MaxAnisotropy; iLog->Log ("D3D Driver: Supports MaxAnisotropy level %d\n", m_AnisotropyLevel); m_Features |= RFT_ALLOWANISOTROPIC; } if( m_d3dCaps.StencilCaps & (D3DSTENCILCAPS_KEEP|D3DSTENCILCAPS_INCR|D3DSTENCILCAPS_DECR) ) { iLog->Log ("D3D Driver: Supports Stencil shadows\n"); if( m_d3dCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) iLog->Log ("D3D Driver: Supports Two-Sided stencil\n"); } else CRenderer::m_sbpp = 0; iLog->Log ("D3D Driver: Textures (%ix%i)-(%ix%i), Max aspect %i\n", mMinTextureWidth, mMinTextureHeight, m_d3dCaps.MaxTextureWidth, m_d3dCaps.MaxTextureHeight, m_d3dCaps.MaxTextureAspectRatio ); // Depth buffering. m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); /*if ( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_WBUFFER ) { m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_USEW ); m_bUseWBuffer = true; iLog->Log ("D3D Driver: Supports w-buffering\n"); } else*/ m_bUseWBuffer = false; m_Features &= ~RFT_BUMP; if( CV_d3d9_usebumpmap && (GetFeatures() & RFT_MULTITEXTURE)) { if ((m_d3dCaps.TextureOpCaps & D3DTEXOPCAPS_DOTPRODUCT3) && (m_d3dCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP)) m_Features |= RFT_BUMP; } // Init render states. { m_pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD); m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_COLORVERTEX, TRUE ); D3DSetCull(eCULL_None); m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 127 ); m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATER ); if( m_d3dCaps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS ) m_pd3dDevice->SetRenderState( D3DRS_DEPTHBIAS, 0 ); m_pd3dDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID ); m_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); m_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE); m_pd3dDevice->SetRenderState( D3DRS_FOGCOLOR, 0 ); m_pd3dDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE ); m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE); m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE ); m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE ); //m_pd3dDevice->SetBackBufferScale(1.0f, 1.0f); m_pd3dDevice->SetPixelShader( NULL ); m_pd3dDevice->SetRenderState( D3DRS_POINTSPRITEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_POINTSCALEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND, FALSE ); m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff ); m_FS.m_bEnable = false; // Set default stencil states m_CurStencilState = 0; m_CurStencMask = 0xffffffff; m_CurStencRef = 0; m_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); if (m_d3dCaps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) { m_pd3dDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); m_pd3dDevice->SetRenderState(D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS); } m_pd3dDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); m_pd3dDevice->SetRenderState(D3DRS_STENCILREF, 0); m_pd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); m_pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); } msCurState = GS_DEPTHWRITE | GS_NODEPTHTEST; for (i=0; iSetSamplerState( 0, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&LodBias ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); m_RP.m_TexStages[0].MinFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[0].MagFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[0].nMipFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[0].TCIndex = 0; m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); { if( GetFeatures() & RFT_MULTITEXTURE ) { for( i=1; i<(int)m_d3dCaps.MaxSimultaneousTextures; i++ ) { m_TexMan->m_CurStage = i; // Set stage i state. m_pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP ); m_pd3dDevice->SetSamplerState( i, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP ); EF_SetColorOp(eCO_DISABLE, eCO_DISABLE, DEF_TEXARG1, DEF_TEXARG1); m_pd3dDevice->SetSamplerState( i, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetSamplerState( i, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetSamplerState( i, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); m_pd3dDevice->SetTextureStageState( i, D3DTSS_TEXCOORDINDEX, i ); m_RP.m_TexStages[i].MinFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[i].MagFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[i].nMipFilter = D3DTEXF_LINEAR; m_RP.m_TexStages[0].TCIndex = i; } } } } // Check to see if device supports visibility query if (!CV_d3d9_occlusion_query || D3DERR_NOTAVAILABLE == m_pd3dDevice->CreateQuery (D3DQUERYTYPE_OCCLUSION, NULL)) m_Features &= ~RFT_OCCLUSIONTEST; else m_Features |= RFT_OCCLUSIONTEST; m_TexMan->m_CurStage = 0; m_TexMan->SetFilter(CV_d3d9_texturefilter->GetString()); // For safety, lots of drivers don't handle tiny texture sizes too tell. mMinTextureWidth = 8; mMinTextureHeight = 8; m_MaxTextureMemory = m_pd3dDevice->GetAvailableTextureMem(); if (CRenderer::CV_r_texturesstreampoolsize <= 0) CRenderer::CV_r_texturesstreampoolsize = (int)(m_MaxTextureMemory/1024.0f/1024.0f*0.75f); m_MaxTextureSize = min(m_d3dCaps.MaxTextureHeight, m_d3dCaps.MaxTextureWidth); //min(wdt, hgt); m_Features &= ~RFT_DEPTHMAPS; if (m_d3dCaps.MaxSimultaneousTextures <= 2) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GF2; } else { if (m_d3dCaps.MaxSimultaneousTextures == 4 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) == 1) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GF3; if (ai->VendorId==4318 && !CV_d3d9_nodepthmaps) m_Features |= RFT_DEPTHMAPS; } else if( ai->VendorId==4318 ) { if (m_d3dCaps.MaxSimultaneousTextures >= 8 && (D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 3 || (D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 2 && D3DSHADER_VERSION_MINOR(m_d3dCaps.PixelShaderVersion) >= 1))) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_NV4X; } else if (m_d3dCaps.MaxSimultaneousTextures >= 8 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 2) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GFFX; } else { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_GF3; } if (!CV_d3d9_nodepthmaps) m_Features |= RFT_DEPTHMAPS; if (m_bDeviceSupportsComprNormalmaps == 1) { iLog->Log ("Warning: Disabled 3DC for NVidia card\n"); if (mFormatV8U8.BitsPerPixel) m_bDeviceSupportsComprNormalmaps = 2; } } else if (m_d3dCaps.MaxSimultaneousTextures >= 8 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 2) { m_Features &= ~RFT_HW_MASK; m_Features |= RFT_HW_RADEON; } else if (!(m_Features & RFT_HW_MASK)) m_Features |= RFT_HW_GF3; } if (m_d3dCaps.MaxSimultaneousTextures >= 4 && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 1) m_Features |= RFT_HW_TS | RFT_HW_VS; m_bDeviceSupportsInstancing = (D3DSHADER_VERSION_MAJOR(m_d3dCaps.VertexShaderVersion) >= 3); if (!m_bDeviceSupportsInstancing) { D3DFORMAT instanceSupport = (D3DFORMAT)MAKEFOURCC('I', 'N', 'S', 'T'); if(SUCCEEDED(m_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, 0, D3DRTYPE_SURFACE, instanceSupport))) { m_bDeviceSupportsInstancing = 2; // Notify the driver that instancing support is expected m_pd3dDevice->SetRenderState(D3DRS_POINTSIZE, instanceSupport); } } m_bDeviceSupportsMRT = (m_d3dCaps.NumSimultaneousRTs>=4) && SUCCEEDED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_G16R16F)); //// REMOVED DRIVER HACK -- Carsten //// Workaround for NVidia drivers less than 66.00 // // Don't use MRT on old drivers // if (LOWORD(ai->DriverVersion.u.LowPart) < 6600) // { // m_bDeviceSupportsMRT = 0; // } m_bDeviceSupportsFP16Filter = true; if(FAILED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F))) m_bDeviceSupportsFP16Filter = false; if(FAILED(m_pD3D->CheckDeviceFormat(pAI->AdapterOrdinal, m_d3dCaps.DeviceType, m_D3DSettings.AdapterFormat(), D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_FILTER, D3DRTYPE_TEXTURE, D3DFMT_G16R16F))) m_bDeviceSupportsFP16Filter = false; int nHDRSupported = 1; { // Check support for HDR rendering D3DDeviceCombo *pDev = m_D3DSettings.PDeviceCombo(); m_HDR_FloatFormat_Scalar = D3DFMT_R16F; if (CV_r_Quality_BumpMapping < 3) nHDRSupported = 0; else if(FAILED(m_pD3D->CheckDeviceFormat(pDev->AdapterOrdinal, pDev->DevType, pDev->AdapterFormat, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F))) nHDRSupported = 0; else if(FAILED(m_pD3D->CheckDeviceFormat(pDev->AdapterOrdinal, pDev->DevType, pDev->AdapterFormat, D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_SURFACE, D3DFMT_A16B16G16R16F))) nHDRSupported = 0; else if(FAILED(m_pD3D->CheckDeviceFormat(pDev->AdapterOrdinal, pDev->DevType, pDev->AdapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_R16F))) { m_HDR_FloatFormat_Scalar = D3DFMT_R32F; if(FAILED(m_pD3D->CheckDeviceFormat(pDev->AdapterOrdinal, pDev->DevType, pDev->AdapterFormat, D3DUSAGE_RENDERTARGET, D3DRTYPE_TEXTURE, D3DFMT_R32F))) nHDRSupported = 0; } if (D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) < 2) nHDRSupported = 0; } if (!nHDRSupported && m_d3dCaps.NumSimultaneousRTs>=2 && (m_d3dCaps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) && D3DSHADER_VERSION_MAJOR(m_d3dCaps.PixelShaderVersion) >= 2 && CV_r_Quality_BumpMapping >= 3) nHDRSupported = 2; if (nHDRSupported == 2 || CV_r_Quality_BumpMapping < 3) nHDRSupported = 0; if (!nHDRSupported) { #ifdef USE_HDR _SetVar("r_HDRRendering", 0); #endif m_Features &= ~RFT_HW_HDR; } else m_Features |= RFT_HW_HDR; m_nHDRType = nHDRSupported; float fColor[4]; fColor[0] = fColor[1] = fColor[2] = fColor[3] = 0; EF_ClearBuffers(true, false, fColor); m_pd3dDevice->BeginScene(); m_SceneRecurseCount++; return S_OK; } void CD3D9Renderer::RecognizePixelFormat(SPixFormat& Dest, D3DFORMAT FromD3D, INT InBitsPerPixel, const TCHAR* InDesc) { Dest.Init(); Dest.Format = FromD3D; Dest.MaxWidth = m_d3dCaps.MaxTextureWidth; Dest.MaxHeight = m_d3dCaps.MaxTextureHeight; Dest.Desc = InDesc; Dest.BitsPerPixel = InBitsPerPixel; Dest.Next = mFirstPixelFormat; mFirstPixelFormat = &Dest; iLog->Log(" Using '%s' pixel texture format\n", InDesc); }