00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "wdxGraphicsPipe9.h"
00016 #include "dxGraphicsDevice9.h"
00017 #include "wdxGraphicsWindow9.h"
00018 #include "wdxGraphicsBuffer9.h"
00019 #include "config_dxgsg9.h"
00020
00021 TypeHandle wdxGraphicsPipe9::_type_handle;
00022
00023 #define LOWVIDMEMTHRESHOLD 5700000 // 4MB cards should fall below this
00024 #define CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD 1000000 // if # is > 1MB, card is lying and I cant tell what it is
00025 #define UNKNOWN_VIDMEM_SIZE 0xFFFFFFFF
00026
00027
00028
00029
00030
00031
00032 wdxGraphicsPipe9::
00033 wdxGraphicsPipe9() {
00034 _hDDrawDLL = NULL;
00035 _hD3D9_DLL = NULL;
00036 __d3d9 = NULL;
00037 _is_valid = init();
00038 }
00039
00040
00041
00042
00043
00044
00045 wdxGraphicsPipe9::
00046 ~wdxGraphicsPipe9() {
00047 RELEASE(__d3d9, wdxdisplay9, "ID3D9", RELEASE_DOWN_TO_ZERO);
00048 SAFE_FREELIB(_hD3D9_DLL);
00049 SAFE_FREELIB(_hDDrawDLL);
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 string wdxGraphicsPipe9::
00063 get_interface_name() const {
00064 return "DirectX9";
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074 PT(GraphicsPipe) wdxGraphicsPipe9::
00075 pipe_constructor() {
00076 return new wdxGraphicsPipe9;
00077 }
00078
00079
00080
00081
00082
00083
00084 PT(GraphicsOutput) wdxGraphicsPipe9::
00085 make_output(const string &name,
00086 const FrameBufferProperties &fb_prop,
00087 const WindowProperties &win_prop,
00088 int flags,
00089 GraphicsEngine *engine,
00090 GraphicsStateGuardian *gsg,
00091 GraphicsOutput *host,
00092 int retry,
00093 bool &precertify) {
00094
00095 if (!_is_valid) {
00096 return NULL;
00097 }
00098
00099 DXGraphicsStateGuardian9 *wdxgsg = 0;
00100 if (gsg != 0) {
00101 DCAST_INTO_R(wdxgsg, gsg, NULL);
00102 }
00103
00104
00105
00106 if (retry == 0) {
00107 if (((flags&BF_require_parasite)!=0)||
00108 ((flags&BF_refuse_window)!=0)||
00109 ((flags&BF_resizeable)!=0)||
00110 ((flags&BF_size_track_host)!=0)||
00111 ((flags&BF_rtt_cumulative)!=0)||
00112 ((flags&BF_can_bind_color)!=0)||
00113 ((flags&BF_can_bind_every)!=0)) {
00114 return NULL;
00115 }
00116
00117
00118 if ((flags & BF_fb_props_optional) == 0) {
00119 if ((fb_prop.get_aux_rgba() > 0)||
00120 (fb_prop.get_aux_rgba() > 0)||
00121 (fb_prop.get_aux_float() > 0)) {
00122 return NULL;
00123 }
00124 }
00125 return new wdxGraphicsWindow9(engine, this, name, fb_prop, win_prop,
00126 flags, gsg, host);
00127 }
00128
00129
00130
00131 if (retry == 1) {
00132 if ((!support_render_texture)||
00133 ((flags&BF_require_parasite)!=0)||
00134 ((flags&BF_require_window)!=0)||
00135 ((flags&BF_rtt_cumulative)!=0)||
00136 ((flags&BF_can_bind_every)!=0)) {
00137 return NULL;
00138 }
00139
00140
00141 if ((flags & BF_fb_props_optional) == 0) {
00142 if ((fb_prop.get_indexed_color() > 0)||
00143 (fb_prop.get_back_buffers() > 0)||
00144 (fb_prop.get_accum_bits() > 0)||
00145 (fb_prop.get_multisamples() > 0)) {
00146 return NULL;
00147 }
00148 }
00149
00150
00151
00152
00153 if ((gsg != 0)&&
00154 (gsg->is_valid())&&
00155 (!gsg->needs_reset())&&
00156 (DCAST(DXGraphicsStateGuardian9, gsg)->get_supports_render_texture())) {
00157 precertify = true;
00158 }
00159 return new wdxGraphicsBuffer9(engine, this, name, fb_prop, win_prop,
00160 flags, gsg, host);
00161 }
00162
00163
00164 return NULL;
00165 }
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176 bool wdxGraphicsPipe9::
00177 init() {
00178 if (!MyLoadLib(_hDDrawDLL, "ddraw.dll")) {
00179 goto error;
00180 }
00181
00182 if (!MyGetProcAddr(_hDDrawDLL, (FARPROC*)&_DirectDrawCreateEx, "DirectDrawCreateEx")) {
00183 goto error;
00184 }
00185
00186 if (!MyGetProcAddr(_hDDrawDLL, (FARPROC*)&_DirectDrawEnumerateExA, "DirectDrawEnumerateExA")) {
00187 goto error;
00188 }
00189
00190 if (!MyLoadLib(_hD3D9_DLL, "d3d9.dll")) {
00191 goto error;
00192 }
00193
00194 if (!MyGetProcAddr(_hD3D9_DLL, (FARPROC*)&_Direct3DCreate9, "Direct3DCreate9")) {
00195 goto error;
00196 }
00197
00198
00199
00200
00201 __is_dx9_1 = false;
00202
00203 #define D3D_SDK_VERSION_9_0 D3D_SDK_VERSION
00204 #define D3D_SDK_VERSION_9_1 D3D_SDK_VERSION
00205
00206
00207 WIN32_FIND_DATA TempFindData;
00208 HANDLE hFind;
00209 char tmppath[_MAX_PATH + 128];
00210 GetSystemDirectory(tmppath, MAX_PATH);
00211 strcat(tmppath, "\\dpnhpast.dll");
00212 hFind = FindFirstFile (tmppath, &TempFindData);
00213 if (hFind != INVALID_HANDLE_VALUE) {
00214 FindClose(hFind);
00215
00216
00217 __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_1);
00218 } else {
00219 __is_dx9_1 = false;
00220 __d3d9 = (*_Direct3DCreate9)(D3D_SDK_VERSION_9_0);
00221 }
00222 if (__d3d9 == NULL) {
00223 wdxdisplay9_cat.error() << "Direct3DCreate9(9." << (__is_dx9_1 ? "1" : "0") << ") failed!, error = " << GetLastError() << endl;
00224
00225 goto error;
00226 }
00227
00228 Init_D3DFORMAT_map();
00229
00230 if (dx_count_all_cards_memory){
00231 return find_all_card_memavails();
00232 }
00233
00234 return true;
00235
00236 error:
00237 return false;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 bool wdxGraphicsPipe9::
00248 find_all_card_memavails() {
00249 HRESULT hr;
00250
00251 hr = (*_DirectDrawEnumerateExA)(dx7_driver_enum_callback, this,
00252 DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES);
00253 if (FAILED(hr)) {
00254 wdxdisplay9_cat.fatal()
00255 << "DirectDrawEnumerateEx failed" << D3DERRORSTRING(hr);
00256 return false;
00257 }
00258
00259 if (_card_ids.empty()) {
00260 wdxdisplay9_cat.error()
00261 << "DirectDrawEnumerateEx enum'ed no devices!\n";
00262 return false;
00263 }
00264
00265 GUID ZeroGUID;
00266 ZeroMemory(&ZeroGUID, sizeof(GUID));
00267
00268 if (_card_ids.size() > 1) {
00269 assert(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID));
00270
00271
00272 _card_ids.erase(_card_ids.begin());
00273 }
00274
00275 for (UINT i = 0; i < _card_ids.size(); i++) {
00276 LPDIRECTDRAW7 pDD;
00277 BYTE ddd_space[sizeof(DDDEVICEIDENTIFIER2)+4];
00278 DDDEVICEIDENTIFIER2 *pDX7DeviceID = (DDDEVICEIDENTIFIER2 *)&ddd_space[0];
00279 GUID *pGUID = &(_card_ids[i].DX7_DeviceGUID);
00280
00281 if (IsEqualGUID(*pGUID, ZeroGUID)) {
00282 pGUID = NULL;
00283 }
00284
00285
00286 hr = (*_DirectDrawCreateEx)(pGUID, (void **)&pDD, IID_IDirectDraw7, NULL);
00287 if (FAILED(hr)) {
00288 wdxdisplay9_cat.error()
00289 << "DirectDrawCreateEx failed for device (" << i
00290 << ")" << D3DERRORSTRING(hr);
00291 continue;
00292 }
00293
00294 ZeroMemory(ddd_space, sizeof(DDDEVICEIDENTIFIER2));
00295
00296 hr = pDD->GetDeviceIdentifier(pDX7DeviceID, 0x0);
00297 if (FAILED(hr)) {
00298 wdxdisplay9_cat.error()
00299 << "GetDeviceID failed for device (" << i << ")" << D3DERRORSTRING(hr);
00300 continue;
00301 }
00302
00303 _card_ids[i].DeviceID = pDX7DeviceID->dwDeviceId;
00304 _card_ids[i].VendorID = pDX7DeviceID->dwVendorId;
00305
00306
00307
00308
00309
00310
00311 DDSCAPS2 ddsGAVMCaps;
00312 DWORD dwVidMemTotal, dwVidMemFree;
00313 dwVidMemTotal = dwVidMemFree = 0;
00314 {
00315
00316
00317
00318
00319 ZeroMemory(&ddsGAVMCaps, sizeof(DDSCAPS2));
00320 ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
00321
00322 hr = pDD->GetAvailableVidMem(&ddsGAVMCaps, &dwVidMemTotal, &dwVidMemFree);
00323 if (FAILED(hr)) {
00324 wdxdisplay9_cat.error()
00325 << "GetAvailableVidMem failed for device #" << i
00326 << D3DERRORSTRING(hr);
00327
00328
00329 }
00330 }
00331
00332 wdxdisplay9_cat.info()
00333 << "DX 9.0c GetAvailableVidMem (including AGP) returns Total: "
00334 << dwVidMemTotal <<", Free: " << dwVidMemFree
00335 << " for device #" << i << endl;
00336
00337 ZeroMemory(&ddsGAVMCaps, sizeof(DDSCAPS2));
00338
00339
00340 ddsGAVMCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
00341
00342 hr = pDD->GetAvailableVidMem(&ddsGAVMCaps, &dwVidMemTotal, &dwVidMemFree);
00343 if (FAILED(hr)) {
00344 wdxdisplay9_cat.error() << "GetAvailableVidMem failed for device #" << i<< D3DERRORSTRING(hr);
00345
00346
00347 if (hr == DDERR_NODIRECTDRAWHW)
00348 continue;
00349 exit(1);
00350 }
00351
00352 wdxdisplay9_cat.info()
00353 << "GetAvailableVidMem (no AGP) returns Total: " << dwVidMemTotal
00354 << ", Free: " << dwVidMemFree << " for device #" << i<< endl;
00355
00356 pDD->Release();
00357
00358 if (!dx_do_vidmemsize_check) {
00359
00360 _card_ids[i]._max_available_video_memory = UNKNOWN_VIDMEM_SIZE;
00361 _card_ids[i]._is_low_memory_card = false;
00362 continue;
00363 }
00364
00365 if (dwVidMemTotal == 0) {
00366 dwVidMemTotal = UNKNOWN_VIDMEM_SIZE;
00367 } else {
00368 if (!ISPOW2(dwVidMemTotal)) {
00369
00370
00371 UINT count = 0;
00372 while ((dwVidMemTotal >> count) != 0x0) {
00373 count++;
00374 }
00375 dwVidMemTotal = (1 << count);
00376 }
00377 }
00378
00379
00380
00381
00382
00383 _card_ids[i]._max_available_video_memory = dwVidMemTotal;
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 bool bLowVidMemFlag =
00394 ((dwVidMemTotal > CRAPPY_DRIVER_IS_LYING_VIDMEMTHRESHOLD) &&
00395 (dwVidMemTotal< LOWVIDMEMTHRESHOLD));
00396
00397 _card_ids[i]._is_low_memory_card = bLowVidMemFlag;
00398 wdxdisplay9_cat.info()
00399 << "SetLowVidMem flag to " << bLowVidMemFlag
00400 << " based on adjusted VidMemTotal: " << dwVidMemTotal << endl;
00401 }
00402 return true;
00403 }
00404
00405
00406
00407
00408
00409
00410 BOOL WINAPI wdxGraphicsPipe9::
00411 dx7_driver_enum_callback(GUID *pGUID, TCHAR *strDesc, TCHAR *strName,
00412 VOID *argptr, HMONITOR hm) {
00413 wdxGraphicsPipe9 *self = (wdxGraphicsPipe9 *)argptr;
00414
00415 CardID card_id;
00416 ZeroMemory(&card_id, sizeof(CardID));
00417
00418 if (hm == NULL) {
00419 card_id._monitor = MonitorFromWindow(GetDesktopWindow(),
00420 MONITOR_DEFAULTTOPRIMARY);
00421 } else {
00422 card_id._monitor = hm;
00423 }
00424
00425 if (pGUID != NULL) {
00426 memcpy(&card_id.DX7_DeviceGUID, pGUID, sizeof(GUID));
00427 }
00428
00429 card_id._max_available_video_memory = UNKNOWN_VIDMEM_SIZE;
00430
00431 self->_card_ids.push_back(card_id);
00432
00433 return DDENUMRET_OK;
00434 }
00435
00436
00437
00438
00439
00440
00441 bool wdxGraphicsPipe9::
00442 find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
00443 D3DFORMAT *pBestFmt, bool bWantStencil,
00444 bool bForce16bpp, bool bVerboseMode) const {
00445 if (dxgsg9_cat.is_debug()) {
00446 bVerboseMode = true;
00447 }
00448
00449
00450
00451 #define NUM_TEST_ZFMTS 6
00452 #define FIRST_NON_STENCIL_ZFMT 3
00453 static D3DFORMAT FormatPrefList[NUM_TEST_ZFMTS] = {
00454 D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1,
00455 D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16
00456 };
00457
00458
00459
00460 *pBestFmt = D3DFMT_UNKNOWN;
00461 HRESULT hr;
00462
00463
00464 bool bOnlySelect16bpp = (bForce16bpp ||
00465 (IS_NVIDIA(Display._dx_device_id) && IS_16BPP_DISPLAY_FORMAT(Test_display_mode.Format)));
00466
00467 if (bVerboseMode) {
00468 wdxdisplay9_cat.info()
00469 << "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl;
00470 }
00471
00472 int first_format = (bWantStencil ? 0 : FIRST_NON_STENCIL_ZFMT);
00473 for (int i = first_format; i < NUM_TEST_ZFMTS; i++) {
00474 D3DFORMAT TestDepthFmt = FormatPrefList[i];
00475
00476 if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) {
00477 continue;
00478 }
00479
00480 hr = Display._d3d9->CheckDeviceFormat(Display._card_id,
00481 D3DDEVTYPE_HAL,
00482 Test_display_mode.Format,
00483 D3DUSAGE_DEPTHSTENCIL,
00484 D3DRTYPE_SURFACE, TestDepthFmt);
00485
00486 if (FAILED(hr)) {
00487 if (hr == D3DERR_NOTAVAILABLE) {
00488 if (bVerboseMode)
00489 wdxdisplay9_cat.info()
00490 << "FindBestDepthFmt: ChkDevFmt returns NotAvail for "
00491 << D3DFormatStr(TestDepthFmt) << endl;
00492 continue;
00493 }
00494
00495 wdxdisplay9_cat.error()
00496 << "unexpected CheckDeviceFormat failure" << D3DERRORSTRING(hr)
00497 << endl;
00498 exit(1);
00499 }
00500
00501 hr = Display._d3d9->CheckDepthStencilMatch(Display._card_id,
00502 D3DDEVTYPE_HAL,
00503 Test_display_mode.Format,
00504 Test_display_mode.Format,
00505 TestDepthFmt);
00506 if (SUCCEEDED(hr)) {
00507 *pBestFmt = TestDepthFmt;
00508 break;
00509 } else {
00510 if (hr == D3DERR_NOTAVAILABLE) {
00511 if (bVerboseMode) {
00512 wdxdisplay9_cat.info()
00513 << "FindBestDepthFmt: ChkDepMatch returns NotAvail for "
00514 << D3DFormatStr(Test_display_mode.Format) << ", "
00515 << D3DFormatStr(TestDepthFmt) << endl;
00516 }
00517 } else {
00518 wdxdisplay9_cat.error()
00519 << "unexpected CheckDepthStencilMatch failure for "
00520 << D3DFormatStr(Test_display_mode.Format) << ", "
00521 << D3DFormatStr(TestDepthFmt) << endl;
00522 exit(1);
00523 }
00524 }
00525 }
00526
00527 if (bVerboseMode) {
00528 wdxdisplay9_cat.info()
00529 << "FindBestDepthFmt returns fmt " << D3DFormatStr(*pBestFmt) << endl;
00530 }
00531
00532 return (*pBestFmt != D3DFMT_UNKNOWN);
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542 bool wdxGraphicsPipe9::
00543 special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size, UINT y_size) {
00544 DWORD VendorId = scrn._dx_device_id.VendorId;
00545 DWORD DeviceId = scrn._dx_device_id.DeviceId;
00546
00547 switch (VendorId) {
00548 case 0x8086:
00549 if ((x_size == 640) && (y_size == 480)) {
00550 return true;
00551 }
00552 if ((x_size == 800) && (y_size == 600)) {
00553 return true;
00554 }
00555 if ((x_size == 1024) && (y_size == 768)) {
00556 return true;
00557 }
00558 break;
00559 }
00560
00561 return false;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 void wdxGraphicsPipe9::
00571 search_for_valid_displaymode(DXScreenData &scrn,
00572 UINT RequestedX_Size, UINT RequestedY_Size,
00573 bool bWantZBuffer, bool bWantStencil,
00574 UINT *p_supported_screen_depths_mask,
00575 bool *pCouldntFindAnyValidZBuf,
00576 D3DFORMAT *pSuggestedPixFmt,
00577 bool bForce16bppZBuffer,
00578 bool bVerboseMode) {
00579 if (dxgsg9_cat.is_debug()) {
00580 bVerboseMode = true;
00581 }
00582
00583 assert(IS_VALID_PTR(scrn._d3d9));
00584
00585 HRESULT hr;
00586
00587 *pSuggestedPixFmt = D3DFMT_UNKNOWN;
00588 *p_supported_screen_depths_mask = 0x0;
00589 *pCouldntFindAnyValidZBuf = false;
00590
00591 #define TOTAL_D3D_FORMATS 5
00592 static D3DFORMAT d3d_format_array [TOTAL_D3D_FORMATS] =
00593 {
00594 D3DFMT_X8R8G8B8,
00595 D3DFMT_A8R8G8B8,
00596 D3DFMT_R5G6B5,
00597 D3DFMT_X1R5G5B5,
00598 D3DFMT_A2R10G10B10,
00599 };
00600
00601
00602 int format_index;
00603 for (format_index = 0; format_index < TOTAL_D3D_FORMATS; format_index++) {
00604 D3DFORMAT d3d_format;
00605
00606 d3d_format = d3d_format_array [format_index];
00607
00608 int cNumModes = scrn._d3d9->GetAdapterModeCount(scrn._card_id, d3d_format);
00609
00610 D3DDISPLAYMODE BestDispMode;
00611 ZeroMemory(&BestDispMode, sizeof(BestDispMode));
00612
00613 if (bVerboseMode) {
00614 wdxdisplay9_cat.info()
00615 << "searching for valid display modes at res: ("
00616 << RequestedX_Size << ", " << RequestedY_Size
00617 << "), TotalModes: " << cNumModes << endl;
00618 }
00619
00620
00621
00622
00623 bool bDoMemBasedChecks =
00624 ((!((RequestedX_Size == 640)&&(RequestedY_Size == 480))) &&
00625 (scrn._max_available_video_memory != UNKNOWN_VIDMEM_SIZE) &&
00626 (!special_check_fullscreen_resolution(scrn, RequestedX_Size, RequestedY_Size)));
00627
00628 if (bVerboseMode) {
00629 wdxdisplay9_cat.info()
00630 << "DoMemBasedChecks = " << bDoMemBasedChecks << endl;
00631 }
00632
00633 for (int i = 0; i < cNumModes; i++) {
00634 D3DDISPLAYMODE dispmode;
00635 hr = scrn._d3d9->EnumAdapterModes(scrn._card_id, d3d_format, i, &dispmode);
00636 if (FAILED(hr)) {
00637 wdxdisplay9_cat.error()
00638 << "EnumAdapter_display_mode failed for device #"
00639 << scrn._card_id << D3DERRORSTRING(hr);
00640 continue;
00641 }
00642
00643 if ((dispmode.Width != RequestedX_Size) ||
00644 (dispmode.Height != RequestedY_Size)) {
00645 if (bVerboseMode) {
00646 wdxdisplay9_cat.info()
00647 << "Mode dimension " << dispmode.Width << "x" << dispmode.Height
00648 << "; format " << D3DFormatStr(dispmode.Format)
00649 << ": onto next mode\n";
00650 }
00651 continue;
00652 }
00653
00654
00655
00656 if (0) {
00657 if ((dispmode.RefreshRate<60) && (dispmode.RefreshRate>1)) {
00658
00659
00660 if (bVerboseMode) {
00661 wdxdisplay9_cat.info()
00662 << "skipping mode[" << i << "], bad refresh rate: "
00663 << dispmode.RefreshRate << endl;
00664 }
00665 continue;
00666 }
00667 }
00668
00669
00670
00671
00672
00673 hr = scrn._d3d9->CheckDeviceFormat(scrn._card_id, D3DDEVTYPE_HAL, dispmode.Format,
00674 D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE,
00675 dispmode.Format);
00676 if (FAILED(hr)) {
00677 if (hr == D3DERR_NOTAVAILABLE) {
00678 if (bVerboseMode) {
00679 wdxdisplay9_cat.info()
00680 << "skipping mode[" << i
00681 << "], CheckDevFmt returns NotAvail for fmt: "
00682 << D3DFormatStr(dispmode.Format) << endl;
00683 }
00684 continue;
00685 } else {
00686 wdxdisplay9_cat.error()
00687 << "CheckDeviceFormat failed for device #"
00688 << scrn._card_id << D3DERRORSTRING(hr);
00689 continue;
00690 }
00691 }
00692
00693 bool bIs16bppRenderTgt = IS_16BPP_DISPLAY_FORMAT(dispmode.Format);
00694 PN_stdfloat RendTgtMinMemReqmt = 0.0f;
00695
00696
00697
00698 if (bDoMemBasedChecks) {
00699
00700
00701
00702
00703
00704
00705
00706 #define REQD_TEXMEM 1800000
00707
00708 PN_stdfloat bytes_per_pixel = (bIs16bppRenderTgt ? 2 : 4);
00709
00710
00711
00712 RendTgtMinMemReqmt =
00713 ((PN_stdfloat)RequestedX_Size) * ((PN_stdfloat)RequestedY_Size) *
00714 bytes_per_pixel * 2 + REQD_TEXMEM;
00715
00716 if (bVerboseMode)
00717 wdxdisplay9_cat.info()
00718 << "Testing Mode (" <<RequestedX_Size<<"x" << RequestedY_Size
00719 << ", " << D3DFormatStr(dispmode.Format) << ")\nReqdVidMem: "
00720 << (int)RendTgtMinMemReqmt << " AvailVidMem: "
00721 << scrn._max_available_video_memory << endl;
00722
00723 if (RendTgtMinMemReqmt > scrn._max_available_video_memory) {
00724 if (bVerboseMode)
00725 wdxdisplay9_cat.info()
00726 << "not enough VidMem for render tgt, skipping display fmt "
00727 << D3DFormatStr(dispmode.Format) << " ("
00728 << (int)RendTgtMinMemReqmt << " > "
00729 << scrn._max_available_video_memory << ")\n";
00730 continue;
00731 }
00732 }
00733
00734 if (bWantZBuffer) {
00735 D3DFORMAT zformat;
00736 if (!find_best_depth_format(scrn, dispmode, &zformat,
00737 bWantStencil, bForce16bppZBuffer)) {
00738 *pCouldntFindAnyValidZBuf = true;
00739 continue;
00740 }
00741
00742 PN_stdfloat MinMemReqmt = 0.0f;
00743
00744 if (bDoMemBasedChecks) {
00745
00746 PN_stdfloat zbytes_per_pixel = (IS_16BPP_ZBUFFER(zformat) ? 2 : 4);
00747 PN_stdfloat MinMemReqmt = RendTgtMinMemReqmt + ((PN_stdfloat)RequestedX_Size)*((PN_stdfloat)RequestedY_Size)*zbytes_per_pixel;
00748
00749 if (bVerboseMode)
00750 wdxdisplay9_cat.info()
00751 << "Testing Mode w/Z (" << RequestedX_Size << "x"
00752 << RequestedY_Size << ", " << D3DFormatStr(dispmode.Format)
00753 << ")\nReqdVidMem: " << (int)MinMemReqmt << " AvailVidMem: "
00754 << scrn._max_available_video_memory << endl;
00755
00756 if (MinMemReqmt > scrn._max_available_video_memory) {
00757 if (bVerboseMode)
00758 wdxdisplay9_cat.info()
00759 << "not enough VidMem for RendTgt+zbuf, skipping display fmt "
00760 << D3DFormatStr(dispmode.Format) << " (" << (int)MinMemReqmt
00761 << " > " << scrn._max_available_video_memory << ")\n";
00762 continue;
00763 }
00764 }
00765
00766
00767 if (false) {
00768 if ((!bDoMemBasedChecks) || (MinMemReqmt<scrn._max_available_video_memory)) {
00769 if (!IS_16BPP_ZBUFFER(zformat)) {
00770
00771
00772 if (!find_best_depth_format(scrn, dispmode, &zformat,
00773 bWantStencil, true, bVerboseMode)) {
00774 if (bVerboseMode)
00775 wdxdisplay9_cat.info()
00776 << "FindBestDepthFmt rejected Mode[" << i << "] ("
00777 << RequestedX_Size << "x" << RequestedY_Size
00778 << ", " << D3DFormatStr(dispmode.Format) << endl;
00779 *pCouldntFindAnyValidZBuf = true;
00780 continue;
00781 }
00782
00783
00784
00785 *p_supported_screen_depths_mask |=
00786 (IS_16BPP_DISPLAY_FORMAT(dispmode.Format) ? DISPLAY_16BPP_REQUIRES_16BPP_ZBUFFER_FLAG : DISPLAY_32BPP_REQUIRES_16BPP_ZBUFFER_FLAG);
00787 }
00788 }
00789 }
00790 }
00791
00792 if (bVerboseMode)
00793 wdxdisplay9_cat.info()
00794 << "Validated Mode (" << RequestedX_Size << "x"
00795 << RequestedY_Size << ", " << D3DFormatStr(dispmode.Format) << endl;
00796
00797
00798
00799
00800
00801
00802 switch (dispmode.Format) {
00803 case D3DFMT_X1R5G5B5:
00804 *p_supported_screen_depths_mask |= X1R5G5B5_FLAG;
00805 break;
00806 case D3DFMT_X8R8G8B8:
00807 *p_supported_screen_depths_mask |= X8R8G8B8_FLAG;
00808 break;
00809 case D3DFMT_A8R8G8B8:
00810 *p_supported_screen_depths_mask |= A8R8G8B8_FLAG;
00811 break;
00812 case D3DFMT_R5G6B5:
00813 *p_supported_screen_depths_mask |= R5G6B5_FLAG;
00814 break;
00815 case D3DFMT_A2R10G10B10:
00816 *p_supported_screen_depths_mask |= A2B10G10R10_FLAG;
00817 break;
00818 default:
00819 wdxdisplay9_cat.error()
00820 << "unrecognized supported fmt " << D3DFormatStr(dispmode.Format)
00821 << " returned by EnumAdapter_display_modes!\n";
00822 }
00823 }
00824
00825
00826
00827 if (*p_supported_screen_depths_mask & X8R8G8B8_FLAG) {
00828 *pSuggestedPixFmt = D3DFMT_X8R8G8B8;
00829 } else if (*p_supported_screen_depths_mask & A8R8G8B8_FLAG) {
00830 *pSuggestedPixFmt = D3DFMT_A8R8G8B8;
00831 } else if (*p_supported_screen_depths_mask & R5G6B5_FLAG) {
00832 *pSuggestedPixFmt = D3DFMT_R5G6B5;
00833 } else if (*p_supported_screen_depths_mask & X1R5G5B5_FLAG) {
00834 *pSuggestedPixFmt = D3DFMT_X1R5G5B5;
00835 } else if (*p_supported_screen_depths_mask & A2B10G10R10_FLAG) {
00836 *pSuggestedPixFmt = D3DFMT_A2R10G10B10;
00837 }
00838
00839 if (bVerboseMode) {
00840 wdxdisplay9_cat.info()
00841 << "search_for_valid_device returns fmt: "
00842 << D3DFormatStr(*pSuggestedPixFmt) << endl;
00843 }
00844
00845 if (*pSuggestedPixFmt != D3DFMT_UNKNOWN) {
00846 break;
00847 }
00848 }
00849 }
00850
00851
00852
00853
00854
00855
00856
00857 PT(GraphicsDevice) wdxGraphicsPipe9::
00858 make_device(void *scrn) {
00859 PT(DXGraphicsDevice9) device = new DXGraphicsDevice9(this);
00860 memcpy(&device->_Scrn, scrn, sizeof(device->_Scrn));
00861 device->_d3d_device = device->_Scrn._d3d_device;
00862
00863 _device = device;
00864 wdxdisplay9_cat.info() << "walla: device" << device << "\n";
00865
00866 return device.p();
00867 }
00868
00869 pmap<D3DFORMAT_FLAG, D3DFORMAT> g_D3DFORMATmap;
00870
00871 void Init_D3DFORMAT_map() {
00872 if (g_D3DFORMATmap.size() != 0)
00873 return;
00874
00875 #define INSERT_ELEM(XX) g_D3DFORMATmap[XX##_FLAG] = D3DFMT_##XX;
00876
00877 INSERT_ELEM(R8G8B8);
00878 INSERT_ELEM(A8R8G8B8);
00879 INSERT_ELEM(X8R8G8B8);
00880 INSERT_ELEM(R5G6B5);
00881 INSERT_ELEM(X1R5G5B5);
00882 INSERT_ELEM(A1R5G5B5);
00883 INSERT_ELEM(A4R4G4B4);
00884 INSERT_ELEM(R3G3B2);
00885 INSERT_ELEM(A8);
00886 INSERT_ELEM(A8R3G3B2);
00887 INSERT_ELEM(X4R4G4B4);
00888 INSERT_ELEM(A2B10G10R10);
00889 INSERT_ELEM(G16R16);
00890 INSERT_ELEM(A8P8);
00891 INSERT_ELEM(P8);
00892 INSERT_ELEM(L8);
00893 INSERT_ELEM(A8L8);
00894 INSERT_ELEM(A4L4);
00895 INSERT_ELEM(V8U8);
00896 INSERT_ELEM(L6V5U5);
00897 INSERT_ELEM(X8L8V8U8);
00898 INSERT_ELEM(Q8W8V8U8);
00899 INSERT_ELEM(V16U16);
00900
00901
00902 INSERT_ELEM(A2W10V10U10);
00903 INSERT_ELEM(UYVY);
00904 INSERT_ELEM(YUY2);
00905 INSERT_ELEM(DXT1);
00906 INSERT_ELEM(DXT2);
00907 INSERT_ELEM(DXT3);
00908 INSERT_ELEM(DXT4);
00909 INSERT_ELEM(DXT5);
00910 }
00911
00912
00913
00914 const char *D3DFormatStr(D3DFORMAT fmt) {
00915
00916 #define CASESTR(XX) case XX: return #XX;
00917 switch(fmt) {
00918 CASESTR(D3DFMT_UNKNOWN);
00919 CASESTR(D3DFMT_R8G8B8);
00920 CASESTR(D3DFMT_A8R8G8B8);
00921 CASESTR(D3DFMT_X8R8G8B8);
00922 CASESTR(D3DFMT_R5G6B5);
00923 CASESTR(D3DFMT_X1R5G5B5);
00924 CASESTR(D3DFMT_A1R5G5B5);
00925 CASESTR(D3DFMT_A4R4G4B4);
00926 CASESTR(D3DFMT_R3G3B2);
00927 CASESTR(D3DFMT_A8);
00928 CASESTR(D3DFMT_A8R3G3B2);
00929 CASESTR(D3DFMT_X4R4G4B4);
00930 CASESTR(D3DFMT_A2B10G10R10);
00931 CASESTR(D3DFMT_G16R16);
00932 CASESTR(D3DFMT_A8P8);
00933 CASESTR(D3DFMT_P8);
00934 CASESTR(D3DFMT_L8);
00935 CASESTR(D3DFMT_A8L8);
00936 CASESTR(D3DFMT_A4L4);
00937 CASESTR(D3DFMT_V8U8);
00938 CASESTR(D3DFMT_L6V5U5);
00939 CASESTR(D3DFMT_X8L8V8U8);
00940 CASESTR(D3DFMT_Q8W8V8U8);
00941 CASESTR(D3DFMT_V16U16);
00942
00943
00944 CASESTR(D3DFMT_A2W10V10U10);
00945 CASESTR(D3DFMT_UYVY);
00946 CASESTR(D3DFMT_YUY2);
00947 CASESTR(D3DFMT_DXT1);
00948 CASESTR(D3DFMT_DXT2);
00949 CASESTR(D3DFMT_DXT3);
00950 CASESTR(D3DFMT_DXT4);
00951 CASESTR(D3DFMT_DXT5);
00952 CASESTR(D3DFMT_D16_LOCKABLE);
00953 CASESTR(D3DFMT_D32);
00954 CASESTR(D3DFMT_D15S1);
00955 CASESTR(D3DFMT_D24S8);
00956 CASESTR(D3DFMT_D16);
00957 CASESTR(D3DFMT_D24X8);
00958 CASESTR(D3DFMT_D24X4S4);
00959 CASESTR(D3DFMT_VERTEXDATA);
00960 CASESTR(D3DFMT_INDEX16);
00961 CASESTR(D3DFMT_INDEX32);
00962 CASESTR(D3DFMT_A16B16G16R16F);
00963 CASESTR(D3DFMT_A32B32G32R32F);
00964 }
00965
00966 return "Invalid D3DFORMAT";
00967 }