HRESULT CDirect3D::InitializeDX(HWND wnd, bool triplebuf) { #if LOG_D3D LOG_MSG("D3D:Starting Direct3D"); #endif backbuffer_clear_countdown = 0; // Check for display window if(!wnd) { LOG_MSG("Error: No display window set!"); return E_FAIL; } hwnd = wnd; if (mhmodDX9 == NULL) mhmodDX9 = LoadLibrary("d3d9.dll"); if (mhmodDX9 == NULL) return E_FAIL; // Set the presentation parameters ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferWidth = dwWidth; d3dpp.BackBufferHeight = dwHeight; d3dpp.BackBufferCount = 1; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.Windowed = true; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; Section_prop * sec=static_cast<Section_prop *>(control->GetSection("vsync")); if(sec) { d3dpp.PresentationInterval = (!strcmp(sec->Get_string("vsyncmode"),"host"))?D3DPRESENT_INTERVAL_DEFAULT:D3DPRESENT_INTERVAL_IMMEDIATE; } if(triplebuf) { LOG_MSG("D3D:Using triple buffering"); d3dpp.BackBufferCount = 2; } // Init Direct3D if(FAILED(InitD3D())) { DestroyD3D(); LOG_MSG("Error: Unable to initialize DirectX9!"); return E_FAIL; } #if D3D_THREAD #if LOG_D3D LOG_MSG("D3D:Starting worker thread from thread: %u", SDL_ThreadID()); #endif thread_run = true; thread_command = D3D_IDLE; thread = SDL_CreateThread(EntryPoint, this); SDL_SemWait(thread_ack); #endif return S_OK; }
void CHW::DestroyDevice () { _SHOW_REF ("refCount:pBaseZB",pBaseZB); _RELEASE (pBaseZB); _SHOW_REF ("refCount:pBaseRT",pBaseRT); _RELEASE (pBaseRT); #ifdef DEBUG _SHOW_REF ("refCount:dwDebugSB",dwDebugSB); _RELEASE (dwDebugSB); #endif #ifdef _EDITOR _RELEASE (HW.pDevice); #else _SHOW_REF ("DeviceREF:",HW.pDevice); _RELEASE (HW.pDevice); #endif DestroyD3D (); #ifndef _EDITOR free_vid_mode_list (); #endif }
HRESULT CDirect3D::InitD3D(void) { IDirect3D9 *(APIENTRY *pDirect3DCreate9)(UINT) = (IDirect3D9 *(APIENTRY *)(UINT))GetProcAddress(mhmodDX9, "Direct3DCreate9"); if(!pDirect3DCreate9) return E_FAIL; // create the IDirect3D9 object pD3D9 = pDirect3DCreate9(D3D_SDK_VERSION); if(pD3D9 == NULL) return E_FAIL; D3DCAPS9 d3dCaps; // get device capabilities ZeroMemory(&d3dCaps, sizeof(d3dCaps)); if(FAILED(pD3D9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps))) return E_FAIL; // get the display mode D3DDISPLAYMODE d3ddm; pD3D9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm); d3dpp.BackBufferFormat = d3ddm.Format; HRESULT hr; // Check if hardware vertex processing is available if(d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) { // Create device with hardware vertex processing hr = pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING|0x00000800L|D3DCREATE_FPU_PRESERVE, &d3dpp, &pD3DDevice9); } else { // Create device with software vertex processing hr = pD3D9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING|0x00000800L|D3DCREATE_FPU_PRESERVE, &d3dpp, &pD3DDevice9); } // Make sure device was created if(FAILED(hr)) { LOG_MSG("D3D:Unable to create D3D device!"); return E_FAIL; } if(FAILED(pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8))) { if(FAILED(pD3D9->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, d3ddm.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5))) { DestroyD3D(); LOG_MSG("Error: Cannot find a working texture color format!"); return E_FAIL; } bpp16 = true; LOG_MSG("D3D:Running in 16-bit color mode"); } if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) { #if LOG_D3D LOG_MSG("D3D:Square-only textures"); #endif square = true; } else { #if LOG_D3D LOG_MSG("D3D:Non-square textures"); #endif square = false; } if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_POW2) { if(d3dCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) { #if LOG_D3D LOG_MSG("D3D:Conditional non-pow2 texture size support"); #endif pow2 = false; } else { #if LOG_D3D LOG_MSG("D3D:Textures must be a power of 2 in size"); #endif pow2 = true; } } else { #if LOG_D3D LOG_MSG("D3D:Textures do not need to be a power of 2 in size"); #endif pow2 = false; } if(d3dCaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) { #if LOG_D3D LOG_MSG("D3D:Dynamic textures supported"); #endif dynamic = true; } else { LOG_MSG("D3D:Dynamic textures NOT supported. Performance will suffer!"); dynamic = false; } #if LOG_D3D LOG_MSG("D3D:Max texture width: %d", d3dCaps.MaxTextureWidth); LOG_MSG("D3D:Max texture height: %d", d3dCaps.MaxTextureHeight); #endif if((d3dCaps.MaxTextureWidth < 1024) || (d3dCaps.MaxTextureHeight < 1024)) { DestroyD3D(); LOG_MSG("Error: Your card does not support large textures!"); return E_FAIL; } #if C_D3DSHADERS // allow scale2x_ps14.fx with 1.4 shaders, everything else requires 2.0 if(d3dCaps.PixelShaderVersion >= D3DPS_VERSION(1,4)) { #if LOG_D3D LOG_MSG("D3D:Hardware PS version %d.%d", D3DSHADER_VERSION_MAJOR(d3dCaps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(d3dCaps.PixelShaderVersion)); #endif if(d3dCaps.PixelShaderVersion == D3DPS_VERSION(1,4)) LOG_MSG("D3D:Hardware PS version 1.4 detected. Most shaders probably won't work..."); if((d3dCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) && (dynamic)) { psEnabled = true; square = true; pow2 = true; // pow2 texture size has to be enabled as well } else { LOG_MSG("D3D:Error when initializing pixel shader support. Disabling shaders."); psEnabled = false; } } else { LOG_MSG("D3D:Hardware PS version too low. Disabling support for shaders."); psEnabled = false; } #endif DWORD dwNumAdapterModes; D3DDISPLAYMODE DisplayMode; DWORD m; dwNumModes = 0; if(bpp16) dwNumAdapterModes = pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_R5G6B5); else dwNumAdapterModes = pD3D9->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); if(dwNumAdapterModes == 0) { LOG_MSG("D3D:No display modes found"); return E_FAIL; } #if LOG_D3D LOG_MSG("D3D:Found %d display modes", dwNumAdapterModes); #endif modes = (D3DDISPLAYMODE*)malloc(sizeof(D3DDISPLAYMODE)*dwNumAdapterModes); if(!modes) { LOG_MSG("D3D:Error allocating memory!"); DestroyD3D(); return E_FAIL; } for(iMode=0;iMode<dwNumAdapterModes;iMode++) { // Get the display mode attributes if(bpp16) pD3D9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_R5G6B5, iMode, &DisplayMode); else pD3D9->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, iMode, &DisplayMode); // Check if the mode already exists for(m=0;m<dwNumModes;m++) { if((modes[m].Width == DisplayMode.Width) && (modes[m].Height == DisplayMode.Height) && (modes[m].Format == DisplayMode.Format)) break; } // If we found a new mode, add it to the list of modes if(m==dwNumModes) { #if LOG_D3D LOG_MSG("D3D:Display mode: %dx%dx%d", DisplayMode.Width, DisplayMode.Height, DisplayMode.Format); #endif // Try to sort resolutions if(dwNumModes>0) { if(((modes[m - 1].Width == DisplayMode.Width) && (modes[m - 1].Height > DisplayMode.Height)) || (modes[m - 1].Width > DisplayMode.Width)) { modes[m].Width = modes[m - 1].Width; modes[m].Height = modes[m - 1].Height; modes[m].Format = modes[m - 1].Format; m--; } } modes[m].Width = DisplayMode.Width; modes[m].Height = DisplayMode.Height; modes[m].Format = DisplayMode.Format; modes[m].RefreshRate = 0; ++dwNumModes; } } // Free some unused memory modes = (D3DDISPLAYMODE*)realloc(modes, sizeof(D3DDISPLAYMODE)*dwNumModes); if(!modes) { LOG_MSG("D3D:Error allocating memory!"); DestroyD3D(); return E_FAIL; } dwTexHeight = 0; dwTexWidth = 0; return S_OK; }