diff --git a/panda/src/dxgsg/config_dxgsg.cxx b/panda/src/dxgsg/config_dxgsg.cxx index 0592bbf1a1..71fc14637d 100644 --- a/panda/src/dxgsg/config_dxgsg.cxx +++ b/panda/src/dxgsg/config_dxgsg.cxx @@ -60,6 +60,9 @@ bool dx_no_vertex_fog = config_dxgsg.GetBool("dx-no-vertex-fog", false); // variable bool dx_auto_normalize_lighting = config_dxgsg.GetBool("auto-normalize-lighting", false); +bool dx_allow_software_renderer = config_dxgsg.GetBool("dx-allow-software-renderer", false); +bool dx_force_software_renderer = config_dxgsg.GetBool("dx-force-software-renderer", false); + bool dx_show_fps_meter = config_dxgsg.GetBool("show-fps-meter", false); float dx_fps_meter_update_interval = max(0.5,config_dxgsg.GetFloat("fps-meter-update-interval", 1.7)); diff --git a/panda/src/dxgsg/config_dxgsg.h b/panda/src/dxgsg/config_dxgsg.h index 3b64ca9c02..beeb5c322f 100644 --- a/panda/src/dxgsg/config_dxgsg.h +++ b/panda/src/dxgsg/config_dxgsg.h @@ -33,6 +33,8 @@ extern bool dx_full_screen_antialiasing; extern float dx_fps_meter_update_interval; extern bool dx_auto_normalize_lighting; extern bool dx_use_rangebased_fog; +extern bool dx_allow_software_renderer; +extern bool dx_force_software_renderer; extern const bool link_tristrips; // debug flags we might want to use in full optimized build diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx index 08340bf44b..e16e753db9 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.cxx +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.cxx @@ -864,7 +864,12 @@ dx_init( void) { DX_DECLARE_CLEAN(DDSURFACEDESC2, ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ; ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTSTATIC; + + if(!scrn.bIsSWRast) + ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE | DDSCAPS2_HINTSTATIC; + else { + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + } ddsd.dwTextureStage=0; ddsd.dwFlags |= DDSD_TEXTURESTAGE; diff --git a/panda/src/dxgsg/dxGraphicsStateGuardian.h b/panda/src/dxgsg/dxGraphicsStateGuardian.h index ff4f5f673c..196dc74fe9 100644 --- a/panda/src/dxgsg/dxGraphicsStateGuardian.h +++ b/panda/src/dxgsg/dxGraphicsStateGuardian.h @@ -56,6 +56,7 @@ typedef struct { DWORD MaxAvailVidMem; bool bIsLowVidMemCard; bool bIsTNLDevice; + bool bIsSWRast; ushort depth_buffer_bitdepth; //GetSurfaceDesc is not reliable so must store this explicitly ushort CardIDNum; // its posn in DisplayArray, for dbgprint purposes DDDEVICEIDENTIFIER2 DXDeviceID; diff --git a/panda/src/dxgsg/dxTextureContext.cxx b/panda/src/dxgsg/dxTextureContext.cxx index f95825b239..893d0a9dbe 100644 --- a/panda/src/dxgsg/dxTextureContext.cxx +++ b/panda/src/dxgsg/dxTextureContext.cxx @@ -1503,8 +1503,12 @@ LPDIRECTDRAWSURFACE7 DXTextureContext::CreateTexture(LPDIRECT3DDEVICE7 pd3dDevic ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; - ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE // Turn on texture management - | DDSCAPS2_HINTSTATIC; // BUGBUG: is this ok for ALL textures? + if(pD3DDevDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { + ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE // Turn on texture management + | DDSCAPS2_HINTSTATIC; // BUGBUG: is this ok for ALL textures? + } else { + ddsd.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; + } // validate magfilter setting // degrade filtering if no HW support diff --git a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx index 21896befdd..4995f081ca 100644 --- a/panda/src/wdxdisplay/wdxGraphicsWindow.cxx +++ b/panda/src/wdxdisplay/wdxGraphicsWindow.cxx @@ -1302,15 +1302,17 @@ HRESULT CALLBACK EnumDevicesCallback(LPSTR pDeviceDescription, LPSTR pDeviceName wdxdisplay_cat.spam() << "Enumerating Device " << pDeviceName << " : " << pDeviceDescription << endl; #endif + #define REGHALIDX 0 #define TNLHALIDX 1 - - // only saves hal and tnl devs, not sw rasts +#define SWRASTIDX 2 if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DHALDevice)) { CopyMemory(&pd3ddevs[REGHALIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); } else if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DTnLHalDevice)) { CopyMemory(&pd3ddevs[TNLHALIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); + } else if(IsEqualGUID(pD3DDeviceDesc->deviceGUID,IID_IDirect3DRGBDevice)) { + CopyMemory(&pd3ddevs[SWRASTIDX],pD3DDeviceDesc,sizeof(D3DDEVICEDESC7)); } return DDENUMRET_OK; } @@ -1626,7 +1628,7 @@ check_for_color_cursor_support(void) { bool wdxGraphicsWindow::search_for_device(int devnum,DXDeviceInfo *pDevinfo) { DWORD dwRenderWidth = _props._xsize; DWORD dwRenderHeight = _props._ysize; - LPDIRECTDRAW7 pDD; + LPDIRECTDRAW7 pDD=NULL; HRESULT hr; assert(_dxgsg!=NULL); @@ -1639,8 +1641,8 @@ bool wdxGraphicsWindow::search_for_device(int devnum,DXDeviceInfo *pDevinfo) { assert(_pParentWindowGroup->_pDDCreateEx!=NULL); // Create the Direct Draw Objects - hr = (*_pParentWindowGroup->_pDDCreateEx)(pDDDeviceGUID,(void **)&pDD, IID_IDirectDraw7, NULL); - if(hr != DD_OK) { + hr = (*(_pParentWindowGroup->_pDDCreateEx))(pDDDeviceGUID,(void **)&pDD, IID_IDirectDraw7, NULL); + if((hr != DD_OK)||(pDD==NULL)) { wdxdisplay_cat.fatal() << "DirectDrawCreateEx failed for monitor("<scrn.DXDeviceID.szDescription<<")\n"; - goto error_exit; - } - + // select TNL if present if(d3ddevs[TNLHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { DeviceIdx=TNLHALIDX; - } + } else if(d3ddevs[REGHALIDX].dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) { + DeviceIdx=REGHALIDX; + } else if(dx_allow_software_renderer || dx_force_software_renderer) { + DeviceIdx=SWRASTIDX; + } else { + wdxdisplay_cat.error() << "No 3D HW present on device #"<scrn.DXDeviceID.szDescription<<")\n"; + goto error_exit; + } + + if(dx_force_software_renderer) { + DeviceIdx=SWRASTIDX; + } memcpy(&_dxgsg->scrn.D3DDevDesc,&d3ddevs[DeviceIdx],sizeof(D3DDEVICEDESC7)); _dxgsg->scrn.bIsTNLDevice=(DeviceIdx==TNLHALIDX); - + // Get Current VidMem avail. Note this is only an estimate, when we switch to fullscreen // mode from desktop, more vidmem will be available (typically 1.2 meg). I dont want // to switch to fullscreen more than once due to the annoying monitor flicker, so try @@ -1725,6 +1731,13 @@ bool wdxGraphicsWindow::search_for_device(int devnum,DXDeviceInfo *pDevinfo) { // assume buggy drivers (this means you, FireGL2) may return zero for dwVidMemFree, so ignore value if its 0 _dxgsg->scrn.bIsLowVidMemCard = ((dwVidMemFree>0) && (dwVidMemFree< LOWVIDMEMTHRESHOLD)); + if(DeviceIdx==SWRASTIDX) { + // this will force 640x480x16, is this what we want for all sw rast? + _dxgsg->scrn.bIsLowVidMemCard = true; + _dxgsg->scrn.bIsSWRast = true; + dx_force_16bpp_zbuffer = true; + } + if(dx_full_screen) { _props._xorg = _props._yorg = 0; @@ -1933,7 +1946,6 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { assert(pDD!=NULL); assert(pD3DI!=NULL); - assert(pD3DDevDesc->dwDevCaps & D3DDEVCAPS_HWRASTERIZATION ); /* // select the best device if the caller does not provide one @@ -2169,7 +2181,7 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { // Setup the surface desc for the z-buffer. ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT; - ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY; + ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | ((_dxgsg->scrn.bIsSWRast) ? DDSCAPS_SYSTEMMEMORY : DDSCAPS_VIDEOMEMORY); DDPIXELFORMAT ZBufPixFmts[MAX_DX_ZBUF_FMTS]; cNumZBufFmts=0; @@ -2224,7 +2236,10 @@ CreateScreenBuffersAndDevice(DXScreenData &Display) { } #define SET_ZBUF_DEPTH(DEPTH) { assert(pz##DEPTH != NULL); Display.depth_buffer_bitdepth=DEPTH; ddsd.ddpfPixelFormat = *pz##DEPTH;} - + + if(_dxgsg->scrn.bIsSWRast) { + SET_ZBUF_DEPTH(16); // need this for fast path rasterizers + } else if(IS_NVIDIA(Display.DXDeviceID)) { DX_DECLARE_CLEAN(DDSURFACEDESC2,ddsd_pri) pPrimaryDDSurf->GetSurfaceDesc(&ddsd_pri); @@ -2898,13 +2913,18 @@ void wdxGraphicsWindowGroup::initWindowGroup(void) { } } + assert(_windows[0] != NULL); + for(i=0;iconfig_window(this); } + assert(_windows[0] != NULL); + DWORD good_device_count=0; if(num_windows==1) { + assert(_windows[0] != NULL); if(_windows[0]->search_for_device(0,NULL)) good_device_count=1; } else {