fix DX8,DX9 in 16-bit color mode

This commit is contained in:
David Rose 2009-02-11 21:45:44 +00:00
parent 0350e26e7c
commit 3bef83d72a
7 changed files with 150 additions and 63 deletions

View File

@ -625,6 +625,7 @@ clear(DrawableRegion *clearable) {
<< "Unable to clear stencil buffer; removing.\n";
// This is really hacky code.
((FrameBufferProperties *)_current_properties)->set_stencil_bits(0);
_supports_stencil = false;
}
}
}
@ -742,7 +743,17 @@ prepare_lens() {
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
begin_frame(Thread *current_thread) {
return GraphicsStateGuardian::begin_frame(current_thread);
if (!GraphicsStateGuardian::begin_frame(current_thread)) {
return false;
}
if (_d3d_device == NULL) {
dxgsg8_cat.debug()
<< this << "::begin_frame(): no device.\n";
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////
@ -1793,8 +1804,11 @@ reset() {
// TransformState::make_identity());
// want gsg to pass all state settings down so any non-matching defaults we set here get overwritten
assert(_screen->_d3d8 != NULL);
assert(_d3d_device != NULL);
if (_d3d_device == NULL) {
return;
}
nassertv(_screen->_d3d8 != NULL);
D3DCAPS8 d3d_caps;
_d3d_device->GetDeviceCaps(&d3d_caps);
@ -1830,7 +1844,30 @@ reset() {
if (support_stencil) {
int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
_supports_stencil = true;
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "Checking for stencil; mode = "
<< D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
<< "\n";
}
switch (_screen->_presentation_params.AutoDepthStencilFormat) {
// These are the only formats that support stencil.
case D3DFMT_D15S1:
case D3DFMT_D24S8:
case D3DFMT_D24X4S4:
_supports_stencil = true;
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "Stencils supported.\n";
}
break;
default:
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "Stencils NOT supported.\n";
}
}
}
}
@ -1972,7 +2009,7 @@ reset() {
} else {
// every card is going to have vertex fog, since it's implemented
// in d3d runtime.
assert((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
nassertv((_screen->_d3dcaps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) != 0);
// vertex fog may look crappy if you have large polygons in the
// foreground and they get clipped, so you may want to disable it
@ -3474,6 +3511,10 @@ set_context(DXScreenData *new_context) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
set_render_target() {
if (_d3d_device == NULL) {
return;
}
LPDIRECT3DSURFACE8 back = NULL, stencil = NULL;
if (!_swap_chain) //maybe fullscreen mode or main/single window
@ -3699,9 +3740,9 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
DXScreenData **screen) {
HRESULT hr;
assert(IS_VALID_PTR(presentation_params));
assert(IS_VALID_PTR(_screen->_d3d8));
assert(IS_VALID_PTR(_d3d_device));
nassertr(IS_VALID_PTR(presentation_params), E_FAIL);
nassertr(IS_VALID_PTR(_screen->_d3d8), E_FAIL);
nassertr(IS_VALID_PTR(_d3d_device), E_FAIL);
// for windowed mode make sure our format matches the desktop fmt,
// in case the desktop mode has been changed
@ -3816,10 +3857,13 @@ reset_d3d_device(D3DPRESENT_PARAMETERS *presentation_params,
bool DXGraphicsStateGuardian8::
check_cooperative_level() {
bool bDoReactivateWindow = false;
if (_d3d_device == NULL) {
return false;
}
HRESULT hr = _d3d_device->TestCooperativeLevel();
if (SUCCEEDED(hr)) {
assert(SUCCEEDED(_last_testcooplevel_result));
nassertr(SUCCEEDED(_last_testcooplevel_result), false);
return true;
}

View File

@ -126,7 +126,7 @@ bool DInput8Info::CreateJoystickOrPad(HWND _window) {
goto handle_error;
}
assert(pJoyDevice!=NULL);
nassertr(pJoyDevice!=NULL, false);
_DeviceList.push_back(pJoyDevice);
// Set the data format to "simple joystick" - a predefined data format
@ -143,7 +143,7 @@ bool DInput8Info::CreateJoystickOrPad(HWND _window) {
// must be called AFTER SetDataFormat to get all the proper flags
DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps);
hr = pJoyDevice->GetCapabilities(&DIDevCaps);
assert(SUCCEEDED(hr));
nassertr(SUCCEEDED(hr), false);
_DevCaps.push_back(DIDevCaps);
@ -214,7 +214,7 @@ BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi,
bool DInput8Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) {
LPDIRECTINPUTDEVICE8 pJoystick = _DeviceList[devnum];
assert(pJoystick!=NULL);
nassertr(pJoystick!=NULL, false);
HRESULT hr;
char *errstr;

View File

@ -263,7 +263,7 @@ find_all_card_memavails() {
ZeroMemory(&ZeroGUID, sizeof(GUID));
if (_card_ids.size() > 1) {
assert(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID));
nassertr(IsEqualGUID(ZeroGUID, _card_ids[0].DX7_DeviceGUID), false);
// delete enum of primary display (always the first), since it is
// duplicated by explicit entry
_card_ids.erase(_card_ids.begin());
@ -439,10 +439,18 @@ bool wdxGraphicsPipe8::
find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
D3DFORMAT *pBestFmt, bool bWantStencil,
bool bForce16bpp, bool bVerboseMode) const {
// list fmts in order of preference
#define NUM_TEST_ZFMTS 3
static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16};
static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1};
if (dxgsg8_cat.is_debug()) {
bVerboseMode = true;
}
// list formats to try in order of preference.
#define NUM_TEST_ZFMTS 6
#define FIRST_NON_STENCIL_ZFMT 3
static D3DFORMAT FormatPrefList[NUM_TEST_ZFMTS] = {
D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1, // with stencil
D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16 // without stencil
};
// do not use Display._display_mode since that is probably not set yet, use Test_display_mode instead
@ -458,9 +466,9 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
<< "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl;
}
for (int i = 0; i < NUM_TEST_ZFMTS; i++) {
D3DFORMAT TestDepthFmt =
(bWantStencil ? StencilPrefList[i] : NoStencilPrefList[i]);
int first_format = (bWantStencil ? 0 : FIRST_NON_STENCIL_ZFMT);
for (int i = first_format; i < NUM_TEST_ZFMTS; i++) {
D3DFORMAT TestDepthFmt = FormatPrefList[i];
if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) {
continue;
@ -508,7 +516,6 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
<< "unexpected CheckDepthStencilMatch failure for "
<< D3DFormatStr(Test_display_mode.Format) << ", "
<< D3DFormatStr(TestDepthFmt) << endl;
exit(1);
}
}
}
@ -566,7 +573,7 @@ search_for_valid_displaymode(DXScreenData &scrn,
bool bForce16bppZBuffer,
bool bVerboseMode) {
assert(IS_VALID_PTR(scrn._d3d8));
nassertv(IS_VALID_PTR(scrn._d3d8));
HRESULT hr;
*pSuggestedPixFmt = D3DFMT_UNKNOWN;

View File

@ -246,11 +246,16 @@ verify_window_sizes(int numsizes, int *dimen) {
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow8::
close_window() {
wdxdisplay8_cat.debug() << "wdx closed window\n";
if (wdxdisplay8_cat.is_debug()) {
wdxdisplay8_cat.debug()
<< "wdxGraphicsWindow8::close_window() " << this << "\n";
}
if (_gsg != (GraphicsStateGuardian*)NULL) {
_gsg.clear();
_active = false;
}
_dxgsg->release_swap_chain(&_wcontext);
WinGraphicsWindow::close_window();
}
@ -286,6 +291,15 @@ open_window() {
return false;
}
// Ensure the window properties get set to the actual size of the
// window.
{
WindowProperties resized_props;
resized_props.set_size(_wcontext._display_mode.Width,
_wcontext._display_mode.Height);
_properties.add_properties(resized_props);
}
wdxdisplay8_cat.debug() << "_wcontext._window is " << _wcontext._window << "\n";
if (!WinGraphicsWindow::open_window()) {
return false;
@ -309,8 +323,8 @@ open_window() {
wdxdisplay8_cat.debug() << "device width " << _wcontext._display_mode.Width << "\n";
if (!create_screen_buffers_and_device(_wcontext, dx_force_16bpp_zbuffer)) {
// just crash here
wdxdisplay8_cat.error() << "fatal: must be trying to create two fullscreen windows: not supported\n";
wdxdisplay8_cat.error() << "Unable to create window with specified parameters.\n";
close_window();
return false;
}
_dxgsg->get_pipe()->make_device((void*)(&_wcontext));
@ -536,10 +550,11 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
PRINT_REFCNT(wdxdisplay8, _d3d8);
assert(_d3d8 != NULL);
assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION);
nassertr(_d3d8 != NULL, false);
nassertr(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION, false);
presentation_params->BackBufferFormat = display._display_mode.Format; // dont need dest alpha, so just use adapter format
cerr << "attempting " << D3DFormatStr(presentation_params->BackBufferFormat) << "\n";
bool do_sync = sync_video;
@ -691,7 +706,7 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD;
}
//assert((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight));
//nassertv((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight));
hr = _d3d8->CreateDevice(display._card_id, D3DDEVTYPE_HAL, _hWnd,
dwBehaviorFlags, presentation_params, &display._d3d_device);
@ -759,7 +774,6 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
return true;
Fallback_to_16bpp_buffers:
if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
(display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
// fallback strategy, if we trying >16bpp, fallback to 16bpp buffers
@ -903,14 +917,14 @@ choose_device() {
bool wdxGraphicsWindow8::
search_for_device(wdxGraphicsPipe8 *dxpipe, DXDeviceInfo *device_info) {
assert(dxpipe != NULL);
nassertr(dxpipe != NULL, false);
WindowProperties properties = get_properties();
DWORD dwRenderWidth = properties.get_x_size();
DWORD dwRenderHeight = properties.get_y_size();
HRESULT hr;
LPDIRECT3D8 _d3d8 = dxpipe->__d3d8;
assert(_dxgsg != NULL);
nassertr(_dxgsg != NULL, false);
_wcontext._d3d8 = _d3d8;
_wcontext._is_dx8_1 = dxpipe->__is_dx8_1;
_wcontext._card_id = device_info->cardID; // could this change by end?
@ -1145,8 +1159,8 @@ init_resized_window() {
DWORD newWidth = _wcontext._presentation_params.BackBufferWidth;
DWORD newHeight = _wcontext._presentation_params.BackBufferHeight;
assert((newWidth != 0) && (newHeight != 0));
assert(_wcontext._window != NULL);
nassertv((newWidth != 0) && (newHeight != 0));
nassertv(_wcontext._window != NULL);
if (_wcontext._presentation_params.Windowed) {
POINT ul, lr;
@ -1169,7 +1183,7 @@ init_resized_window() {
}
// clear window to black ASAP
assert(_wcontext._window != NULL);
nassertv(_wcontext._window != NULL);
ClearToBlack(_wcontext._window, get_properties());
// clear textures and VB's out of video&AGP mem, so cache is reset

View File

@ -908,6 +908,7 @@ clear(DrawableRegion *clearable) {
<< "Unable to clear stencil buffer; removing.\n";
// This is really hacky code.
((FrameBufferProperties *)_current_properties)->set_stencil_bits(0);
_supports_stencil = false;
}
}
}
@ -2483,7 +2484,30 @@ reset() {
if (support_stencil) {
int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
_supports_stencil = true;
if (dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug()
<< "Checking for stencil; mode = "
<< D3DFormatStr(_screen->_presentation_params.AutoDepthStencilFormat)
<< "\n";
}
switch (_screen->_presentation_params.AutoDepthStencilFormat) {
// These are the only formats that support stencil.
case D3DFMT_D15S1:
case D3DFMT_D24S8:
case D3DFMT_D24X4S4:
_supports_stencil = true;
if (dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug()
<< "Stencils supported.\n";
}
break;
default:
if (dxgsg9_cat.is_debug()) {
dxgsg9_cat.debug()
<< "Stencils NOT supported.\n";
}
}
}
}

View File

@ -441,10 +441,14 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
bVerboseMode = true;
}
// list fmts in order of preference
#define NUM_TEST_ZFMTS 3
static D3DFORMAT NoStencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16};
static D3DFORMAT StencilPrefList[NUM_TEST_ZFMTS] = {D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1};
// list formats to try in order of preference.
#define NUM_TEST_ZFMTS 6
#define FIRST_NON_STENCIL_ZFMT 3
static D3DFORMAT FormatPrefList[NUM_TEST_ZFMTS] = {
D3DFMT_D24S8, D3DFMT_D24X4S4, D3DFMT_D15S1, // with stencil
D3DFMT_D32, D3DFMT_D24X8, D3DFMT_D16 // without stencil
};
// do not use Display._display_mode since that is probably not set yet, use Test_display_mode instead
@ -460,9 +464,9 @@ find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
<< "FindBestDepthFmt: bSelectOnly16bpp: " << bOnlySelect16bpp << endl;
}
for (int i = 0; i < NUM_TEST_ZFMTS; i++) {
D3DFORMAT TestDepthFmt =
(bWantStencil ? StencilPrefList[i] : NoStencilPrefList[i]);
int first_format = (bWantStencil ? 0 : FIRST_NON_STENCIL_ZFMT);
for (int i = first_format; i < NUM_TEST_ZFMTS; i++) {
D3DFORMAT TestDepthFmt = FormatPrefList[i];
if (bOnlySelect16bpp && !IS_16BPP_ZBUFFER(TestDepthFmt)) {
continue;

View File

@ -285,6 +285,8 @@ open_window() {
if (_gsg == 0) {
_dxgsg = new DXGraphicsStateGuardian9(_pipe);
_gsg = _dxgsg;
} else {
DCAST_INTO_R(_dxgsg, _gsg, false);
}
if (!choose_device()) {
@ -585,33 +587,26 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
do_sync = false;
}
bool check_device_format;
presentation_params->BackBufferFormat = display._display_mode.Format;
// check for D3DFMT_A8R8G8B8 first
check_device_format = false;
if (bWantAlpha) {
presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8;
// verify the rendertarget fmt
if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
wdxdisplay9_cat.error() << "adpater #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
}
else {
check_device_format = true;
if (!FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
D3DRTYPE_SURFACE, D3DFMT_A8R8G8B8))) {
if (!FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, D3DFMT_A8R8G8B8,
is_fullscreen()))) {
// We can accept D3DFMT_A8R8G8B8, so use it.
presentation_params->BackBufferFormat = D3DFMT_A8R8G8B8;
}
}
}
// check for same format as display_mode
if (check_device_format == false) {
presentation_params->BackBufferFormat = display._display_mode.Format;
// verify the rendertarget fmt
if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
wdxdisplay9_cat.error() << "adapter #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
}
else {
check_device_format = true;
}
// verify the rendertarget fmt
if (FAILED(_d3d9->CheckDeviceFormat(adapter, device_type, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
wdxdisplay9_cat.error() << "adapter #" << adapter << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
goto Fallback_to_16bpp_buffers;
}
if (FAILED(_d3d9->CheckDeviceType(adapter, device_type, display._display_mode.Format, presentation_params->BackBufferFormat,
@ -844,7 +839,6 @@ create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer
return true;
Fallback_to_16bpp_buffers:
if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
(display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
// fallback strategy, if we trying >16bpp, fallback to 16bpp buffers