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