bug fixes in framebuffer_copy_to_ram

This commit is contained in:
David Rose 2005-09-27 23:33:16 +00:00
parent 2c09d3b95a
commit d02ebe4d88
5 changed files with 169 additions and 115 deletions

View File

@ -1347,15 +1347,15 @@ framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, const
return; return;
} }
RECT SrcRect; RECT src_rect;
SrcRect.left = xo; src_rect.left = xo;
SrcRect.right = xo+w; src_rect.right = xo+w;
SrcRect.top = yo; src_rect.top = yo;
SrcRect.bottom = yo+h; src_rect.bottom = yo+h;
// now copy from fb to tex // now copy from fb to tex
hr = _d3d_device->CopyRects(render_target, &SrcRect, 1, tex_level_0, 0); hr = _d3d_device->CopyRects(render_target, &src_rect, 1, tex_level_0, 0);
if (FAILED(hr)) { if (FAILED(hr)) {
dxgsg8_cat.error() dxgsg8_cat.error()
<< "CopyRects failed in copy_texture" << D3DERRORSTRING(hr); << "CopyRects failed in copy_texture" << D3DERRORSTRING(hr);
@ -1392,73 +1392,105 @@ framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr, const Rend
rect.left = xo; rect.left = xo;
rect.right = xo + w; rect.right = xo + w;
rect.bottom = yo + h; rect.bottom = yo + h;
bool copy_inverted = false;
IDirect3DSurface8 *framebuffer; IDirect3DSurface8 *temp_surface = NULL;
HRESULT hr; HRESULT hr;
// Note if you try to grab the backbuffer and full-screen
// anti-aliasing is on, the backbuffer might be larger than the
// window size. For screenshots it's safer to get the front buffer.
if (_cur_read_pixel_buffer & RenderBuffer::T_back) { if (_cur_read_pixel_buffer & RenderBuffer::T_back) {
hr = _d3d_device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &framebuffer); IDirect3DSurface8 *backbuffer = NULL;
// GetRenderTarget() seems to be a little more reliable than
// GetBackBuffer(). Might just be related to the swap_chain
// thing.
hr = _d3d_device->GetRenderTarget(&backbuffer);
if (FAILED(hr)) { if (FAILED(hr)) {
dxgsg8_cat.error() << "GetBackBuffer failed" << D3DERRORSTRING(hr); dxgsg8_cat.error() << "GetRenderTarget failed" << D3DERRORSTRING(hr);
return false; return false;
} }
// note if you try to grab the backbuffer and full-screen // Since we might not be able to Lock the back buffer, we will
// anti-aliasing is on, the backbuffer might be larger than the // need to copy it to a temporary surface of the appropriate type
// window size. for screenshots its safer to get the front // first.
// buffer. hr = _d3d_device->CreateImageSurface(w, h, _screen->_display_mode.Format,
&temp_surface);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
backbuffer->Release();
return false;
}
// Now we must copy from the backbuffer to our temporary surface.
hr = _d3d_device->CopyRects(backbuffer, &rect, 1, temp_surface, NULL);
if (FAILED(hr)) {
dxgsg8_cat.error() << "CopyRects failed" << D3DERRORSTRING(hr);
temp_surface->Release();
backbuffer->Release();
return false;
}
RELEASE(backbuffer, dxgsg8, "backbuffer", RELEASE_ONCE);
} else if (_cur_read_pixel_buffer & RenderBuffer::T_front) { } else if (_cur_read_pixel_buffer & RenderBuffer::T_front) {
// must create a A8R8G8B8 sysmem surface for GetFrontBuffer to
// copy to
DWORD temp_x_size, temp_y_size;
if (_screen->_presentation_params.Windowed) { if (_screen->_presentation_params.Windowed) {
// GetFrontBuffer retrieves the entire desktop for a monitor, so // GetFrontBuffer() retrieves the entire desktop for a monitor,
// need space for that // so we need to reserve space for that.
// We have to use GetMonitorInfo(), since this GSG may not be
// for the primary monitor.
MONITORINFO minfo; MONITORINFO minfo;
minfo.cbSize = sizeof(MONITORINFO); minfo.cbSize = sizeof(MONITORINFO);
GetMonitorInfo(_screen->_monitor, &minfo); // have to use GetMonitorInfo, since this gsg may not be for primary monitor GetMonitorInfo(_screen->_monitor, &minfo);
temp_x_size = RECT_XSIZE(minfo.rcMonitor); w = RECT_XSIZE(minfo.rcMonitor);
temp_y_size = RECT_YSIZE(minfo.rcMonitor); h = RECT_YSIZE(minfo.rcMonitor);
// set rect to client area of window in scrn coords // set rect to client area of window in scrn coords
ClientToScreen(_screen->_window, (POINT*)&rect.left); ClientToScreen(_screen->_window, (POINT*)&rect.left);
ClientToScreen(_screen->_window, (POINT*)&rect.right); ClientToScreen(_screen->_window, (POINT*)&rect.right);
} else {
RECT wind_rect;
GetWindowRect(_screen->_window, &wind_rect);
temp_x_size = RECT_XSIZE(wind_rect);
temp_y_size = RECT_YSIZE(wind_rect);
} }
hr = _d3d_device->CreateImageSurface(temp_x_size, temp_y_size, D3DFMT_A8R8G8B8, &framebuffer); // For GetFrontBuffer(), we need a temporary surface of type
// A8R8G8B8. Unlike GetBackBuffer(), GetFrontBuffer() implicitly
// performs a copy.
hr = _d3d_device->CreateImageSurface(w, h, D3DFMT_A8R8G8B8, &temp_surface);
if (FAILED(hr)) { if (FAILED(hr)) {
dxgsg8_cat.error() << "CreateImageSurface failed in copy_pixel_buffer()" << D3DERRORSTRING(hr); dxgsg8_cat.error()
<< "CreateImageSurface failed in copy_pixel_buffer()"
<< D3DERRORSTRING(hr);
return false; return false;
} }
hr = _d3d_device->GetFrontBuffer(framebuffer); hr = _d3d_device->GetFrontBuffer(temp_surface);
if (hr == D3DERR_DEVICELOST) { if (hr == D3DERR_DEVICELOST) {
framebuffer->Release(); dxgsg8_cat.error()
dxgsg8_cat.error() << "copy_pixel_buffer failed: device lost\n"; << "copy_pixel_buffer failed: device lost\n";
temp_surface->Release();
return false; return false;
} }
// For some reason the front buffer comes out inverted, but the
// back buffer does not.
copy_inverted = true;
} else { } else {
dxgsg8_cat.error() << "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n"; dxgsg8_cat.error()
<< "copy_pixel_buffer: unhandled current_read_pixel_buffer type\n";
temp_surface->Release();
return false; return false;
} }
DXTextureContext8::d3d_surface_to_texture(rect, framebuffer, tex); DXTextureContext8::d3d_surface_to_texture(rect, temp_surface,
copy_inverted, tex);
RELEASE(framebuffer, dxgsg8, "framebuffer", RELEASE_ONCE); RELEASE(temp_surface, dxgsg8, "temp_surface", RELEASE_ONCE);
nassertr(tex->has_ram_image(), false); nassertr(tex->has_ram_image(), false);
return true; return true;

View File

@ -710,7 +710,8 @@ delete_texture() {
// texture // texture
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
HRESULT DXTextureContext8:: HRESULT DXTextureContext8::
d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Texture *result) { d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface,
bool inverted, Texture *result) {
// still need custom conversion since d3d/d3dx has no way to convert // still need custom conversion since d3d/d3dx has no way to convert
// arbitrary fmt to ARGB in-memory user buffer // arbitrary fmt to ARGB in-memory user buffer
@ -722,7 +723,8 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
nassertr((num_components == 3) || (num_components == 4), E_FAIL); // cant handle anything else now nassertr((num_components == 3) || (num_components == 4), E_FAIL); // cant handle anything else now
nassertr(IS_VALID_PTR(d3d_surface), E_FAIL); nassertr(IS_VALID_PTR(d3d_surface), E_FAIL);
BYTE *buf = result->modify_ram_image().p(); PTA_uchar ram_image = result->modify_ram_image();
BYTE *buf = ram_image.p();
if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) { if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) {
dxgsg8_cat.error() dxgsg8_cat.error()
@ -748,12 +750,15 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
if (!((copy_width == result->get_x_size()) && (copy_height <= (DWORD)result->get_y_size()))) { if (!((copy_width == result->get_x_size()) && (copy_height <= (DWORD)result->get_y_size()))) {
dxgsg8_cat.error() dxgsg8_cat.error()
<< "d3d_surface_to_texture, Texture size too small to hold display surface!\n"; << "d3d_surface_to_texture, Texture size (" << result->get_x_size()
<< ", " << result->get_y_size()
<< ") too small to hold display surface ("
<< copy_width << ", " << copy_height << ")\n";
nassertr(false, E_FAIL); nassertr(false, E_FAIL);
return E_FAIL; return E_FAIL;
} }
hr = d3d_surface->LockRect(&locked_rect, (CONST RECT*)NULL, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE /* | D3DLOCK_NOSYSLOCK */)); hr = d3d_surface->LockRect(&locked_rect, (CONST RECT*)NULL, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE));
if (FAILED(hr)) { if (FAILED(hr)) {
dxgsg8_cat.error() dxgsg8_cat.error()
<< "d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr); << "d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
@ -771,16 +776,24 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
//buf contains raw ARGB in Texture byteorder //buf contains raw ARGB in Texture byteorder
DWORD byte_pitch = locked_rect.Pitch; int byte_pitch = locked_rect.Pitch;
BYTE *surface_bytes = (BYTE *)locked_rect.pBits; BYTE *surface_bytes = (BYTE *)locked_rect.pBits;
if (inverted) {
surface_bytes += byte_pitch * (y_window_offset + copy_height - 1);
byte_pitch = -byte_pitch;
} else {
surface_bytes += byte_pitch * y_window_offset;
}
// writes out last line in DDSurf first in PixelBuf, so Y line order // writes out last line in DDSurf first in PixelBuf, so Y line order
// precedes inversely // precedes inversely
if (dxgsg8_cat.is_debug()) { if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug() dxgsg8_cat.debug()
<< "d3d_surface_to_texture converting " << D3DFormatStr(surface_desc.Format) << "d3d_surface_to_texture converting "
<< "bpp DDSurf to " << num_components << "-channel panda Texture\n"; << D3DFormatStr(surface_desc.Format)
<< " DDSurf to " << num_components << "-channel panda Texture\n";
} }
DWORD *dest_word = (DWORD *)buf; DWORD *dest_word = (DWORD *)buf;
@ -793,20 +806,19 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
DWORD *source_word; DWORD *source_word;
BYTE *dest_line = (BYTE*)dest_word; BYTE *dest_line = (BYTE*)dest_word;
surface_bytes += byte_pitch*(y_window_offset+copy_height-1); for (DWORD y = 0; y < copy_height; y++) {
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { source_word = ((DWORD*)surface_bytes) + x_window_offset;
source_word = ((DWORD*)surface_bytes)+x_window_offset;
memcpy(dest_line, source_word, byte_pitch); memcpy(dest_line, source_word, byte_pitch);
dest_line += byte_pitch; dest_line += byte_pitch;
surface_bytes += byte_pitch;
} }
} else { } else {
// 24bpp texture case (numComponents == 3) // 24bpp texture case (numComponents == 3)
DWORD *source_word; DWORD *source_word;
surface_bytes += byte_pitch*(y_window_offset+copy_height-1); for (DWORD y = 0; y < copy_height; y++) {
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { source_word = ((DWORD*)surface_bytes) + x_window_offset;
source_word = ((DWORD*)surface_bytes)+x_window_offset;
for (DWORD x = 0; x<copy_width; x++, source_word++) { for (DWORD x = 0; x < copy_width; x++) {
BYTE r, g, b; BYTE r, g, b;
DWORD pixel = *source_word; DWORD pixel = *source_word;
@ -814,10 +826,12 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
g = (BYTE)((pixel>> 8) & g_LowByteMask); g = (BYTE)((pixel>> 8) & g_LowByteMask);
b = (BYTE)((pixel ) & g_LowByteMask); b = (BYTE)((pixel ) & g_LowByteMask);
*dest_byte += b; *dest_byte++ = b;
*dest_byte += g; *dest_byte++ = g;
*dest_byte += r; *dest_byte++ = r;
source_word++;
} }
surface_bytes += byte_pitch;
} }
} }
break; break;
@ -825,12 +839,11 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
case D3DFMT_R8G8B8: { case D3DFMT_R8G8B8: {
BYTE *source_byte; BYTE *source_byte;
surface_bytes += byte_pitch*(y_window_offset+copy_height-1);
if (num_components == 4) { if (num_components == 4) {
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { for (DWORD y = 0; y < copy_height; y++) {
source_byte = surface_bytes+x_window_offset*3*sizeof(BYTE); source_byte = surface_bytes + x_window_offset * 3 * sizeof(BYTE);
for (DWORD x = 0; x<copy_width; x++, dest_word++) { for (DWORD x = 0; x < copy_width; x++) {
DWORD r, g, b; DWORD r, g, b;
b = *source_byte++; b = *source_byte++;
@ -838,14 +851,17 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
r = *source_byte++; r = *source_byte++;
*dest_word = 0xFF000000 | (r << 16) | (g << 8) | b; *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
dest_word++;
} }
surface_bytes += byte_pitch;
} }
} else { } else {
// 24bpp texture case (numComponents == 3) // 24bpp texture case (numComponents == 3)
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { for (DWORD y = 0; y < copy_height; y++) {
source_byte = surface_bytes+x_window_offset*3*sizeof(BYTE); source_byte = surface_bytes + x_window_offset * 3 * sizeof(BYTE);
memcpy(dest_byte, source_byte, byte_pitch); memcpy(dest_byte, source_byte, byte_pitch);
dest_byte += byte_pitch; dest_byte += byte_pitch;
surface_bytes += byte_pitch;
} }
} }
break; break;
@ -884,7 +900,6 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
blueshift = 3; blueshift = 3;
} }
surface_bytes += byte_pitch*(y_window_offset+copy_height-1);
if (num_components == 4) { if (num_components == 4) {
// Note: these 16bpp loops ignore input alpha completely (alpha // Note: these 16bpp loops ignore input alpha completely (alpha
// is set to fully opaque in texture!) // is set to fully opaque in texture!)
@ -892,9 +907,9 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
// if we need to capture alpha, probably need to make separate // if we need to capture alpha, probably need to make separate
// loops for diff 16bpp fmts for best speed // loops for diff 16bpp fmts for best speed
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { for (DWORD y = 0; y < copy_height; y++) {
source_word = ((WORD*)surface_bytes)+x_window_offset; source_word = ((WORD*)surface_bytes) + x_window_offset;
for (DWORD x = 0; x<copy_width; x++, source_word++, dest_word++) { for (DWORD x = 0; x < copy_width; x++) {
WORD pixel = *source_word; WORD pixel = *source_word;
BYTE r, g, b; BYTE r, g, b;
@ -905,13 +920,16 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
// alpha is just set to 0xFF // alpha is just set to 0xFF
*dest_word = 0xFF000000 | (r << 16) | (g << 8) | b; *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
source_word++;
dest_word++;
} }
surface_bytes += byte_pitch;
} }
} else { } else {
// 24bpp texture case (numComponents == 3) // 24bpp texture case (numComponents == 3)
for (DWORD y = 0; y<copy_height; y++, surface_bytes -= byte_pitch) { for (DWORD y = 0; y < copy_height; y++) {
source_word = ((WORD*)surface_bytes)+x_window_offset; source_word = ((WORD*)surface_bytes) + x_window_offset;
for (DWORD x = 0; x<copy_width; x++, source_word++) { for (DWORD x = 0; x < copy_width; x++) {
WORD pixel = *source_word; WORD pixel = *source_word;
BYTE r, g, b; BYTE r, g, b;
@ -922,7 +940,9 @@ d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Textur
*dest_byte += b; *dest_byte += b;
*dest_byte += g; *dest_byte += g;
*dest_byte += r; *dest_byte += r;
source_word++;
} }
surface_bytes += byte_pitch;
} }
} }
break; break;

View File

@ -41,7 +41,9 @@ public:
INLINE IDirect3DVolumeTexture8 *get_d3d_volume_texture() const; INLINE IDirect3DVolumeTexture8 *get_d3d_volume_texture() const;
INLINE IDirect3DCubeTexture8 *get_d3d_cube_texture() const; INLINE IDirect3DCubeTexture8 *get_d3d_cube_texture() const;
static HRESULT d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface8 *d3d_surface, Texture *result); static HRESULT d3d_surface_to_texture(RECT &source_rect,
IDirect3DSurface8 *d3d_surface,
bool inverted, Texture *result);
private: private:
HRESULT fill_d3d_texture_pixels(); HRESULT fill_d3d_texture_pixels();

View File

@ -469,7 +469,7 @@ do_fullscreen_resize(int x_size, int y_size) {
// Sets _depth_buffer_bpp appropriately. // Sets _depth_buffer_bpp appropriately.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
bool wdxGraphicsWindow8:: bool wdxGraphicsWindow8::
create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer) { create_screen_buffers_and_device(DXScreenData &display, bool force_16bpp_zbuffer) {
wdxGraphicsPipe8 *dxpipe; wdxGraphicsPipe8 *dxpipe;
DCAST_INTO_R(dxpipe, _pipe, false); DCAST_INTO_R(dxpipe, _pipe, false);
@ -478,12 +478,12 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
// auto-res-select in any future init sequence. // auto-res-select in any future init sequence.
dx_pick_best_screenres = false; dx_pick_best_screenres = false;
DWORD dwRenderWidth = Display._display_mode.Width; DWORD dwRenderWidth = display._display_mode.Width;
DWORD dwRenderHeight = Display._display_mode.Height; DWORD dwRenderHeight = display._display_mode.Height;
DWORD dwBehaviorFlags = 0x0; DWORD dwBehaviorFlags = 0x0;
LPDIRECT3D8 _d3d8 = Display._d3d8; LPDIRECT3D8 _d3d8 = display._d3d8;
D3DCAPS8 *pD3DCaps = &Display._d3dcaps; D3DCAPS8 *pD3DCaps = &display._d3dcaps;
D3DPRESENT_PARAMETERS* presentation_params = &Display._presentation_params; D3DPRESENT_PARAMETERS* presentation_params = &display._presentation_params;
RECT view_rect; RECT view_rect;
HRESULT hr; HRESULT hr;
@ -498,7 +498,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
assert(_d3d8 != NULL); assert(_d3d8 != NULL);
assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION); assert(pD3DCaps->DevCaps & D3DDEVCAPS_HWRASTERIZATION);
presentation_params->BackBufferFormat = Display._display_mode.Format; // dont need dest alpha, so just use adapter format presentation_params->BackBufferFormat = display._display_mode.Format; // dont need dest alpha, so just use adapter format
bool do_sync = sync_video; bool do_sync = sync_video;
@ -509,28 +509,28 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
} }
// verify the rendertarget fmt one last time // verify the rendertarget fmt one last time
if (FAILED(_d3d8->CheckDeviceFormat(Display._card_id, D3DDEVTYPE_HAL, Display._display_mode.Format, D3DUSAGE_RENDERTARGET, if (FAILED(_d3d8->CheckDeviceFormat(display._card_id, D3DDEVTYPE_HAL, display._display_mode.Format, D3DUSAGE_RENDERTARGET,
D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) { D3DRTYPE_SURFACE, presentation_params->BackBufferFormat))) {
wdxdisplay8_cat.error() << "device #" << Display._card_id << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl; wdxdisplay8_cat.error() << "device #" << display._card_id << " CheckDeviceFmt failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
goto Fallback_to_16bpp_buffers; goto Fallback_to_16bpp_buffers;
} }
if (FAILED(_d3d8->CheckDeviceType(Display._card_id, D3DDEVTYPE_HAL, Display._display_mode.Format, presentation_params->BackBufferFormat, if (FAILED(_d3d8->CheckDeviceType(display._card_id, D3DDEVTYPE_HAL, display._display_mode.Format, presentation_params->BackBufferFormat,
is_fullscreen()))) { is_fullscreen()))) {
wdxdisplay8_cat.error() << "device #" << Display._card_id << " CheckDeviceType failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl; wdxdisplay8_cat.error() << "device #" << display._card_id << " CheckDeviceType failed for surface fmt " << D3DFormatStr(presentation_params->BackBufferFormat) << endl;
goto Fallback_to_16bpp_buffers; goto Fallback_to_16bpp_buffers;
} }
if (Display._presentation_params.EnableAutoDepthStencil) { if (display._presentation_params.EnableAutoDepthStencil) {
if (!dxpipe->find_best_depth_format(Display, Display._display_mode, if (!dxpipe->find_best_depth_format(display, display._display_mode,
&Display._presentation_params.AutoDepthStencilFormat, &display._presentation_params.AutoDepthStencilFormat,
bWantStencil, false)) { bWantStencil, false)) {
wdxdisplay8_cat.error() wdxdisplay8_cat.error()
<< "find_best_depth_format failed in CreateScreenBuffers for device #" << "find_best_depth_format failed in CreateScreenBuffers for device #"
<< Display._card_id << endl; << display._card_id << endl;
goto Fallback_to_16bpp_buffers; goto Fallback_to_16bpp_buffers;
} }
_depth_buffer_bpp = D3DFMT_to_DepthBits(Display._presentation_params.AutoDepthStencilFormat); _depth_buffer_bpp = D3DFMT_to_DepthBits(display._presentation_params.AutoDepthStencilFormat);
} else { } else {
_depth_buffer_bpp = 0; _depth_buffer_bpp = 0;
} }
@ -539,18 +539,18 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
if (dx_multisample_antialiasing_level>1) { if (dx_multisample_antialiasing_level>1) {
// need to check both rendertarget and zbuffer fmts // need to check both rendertarget and zbuffer fmts
hr = _d3d8->CheckDeviceMultiSampleType(Display._card_id, D3DDEVTYPE_HAL, Display._display_mode.Format, hr = _d3d8->CheckDeviceMultiSampleType(display._card_id, D3DDEVTYPE_HAL, display._display_mode.Format,
is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value())); is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value()));
if (FAILED(hr)) { if (FAILED(hr)) {
wdxdisplay8_cat.fatal() << "device #" << Display._card_id << " doesnt support multisample level " << dx_multisample_antialiasing_level << "surface fmt " << D3DFormatStr(Display._display_mode.Format) << endl; wdxdisplay8_cat.fatal() << "device #" << display._card_id << " doesnt support multisample level " << dx_multisample_antialiasing_level << "surface fmt " << D3DFormatStr(display._display_mode.Format) << endl;
return false; return false;
} }
if (Display._presentation_params.EnableAutoDepthStencil) { if (display._presentation_params.EnableAutoDepthStencil) {
hr = _d3d8->CheckDeviceMultiSampleType(Display._card_id, D3DDEVTYPE_HAL, Display._presentation_params.AutoDepthStencilFormat, hr = _d3d8->CheckDeviceMultiSampleType(display._card_id, D3DDEVTYPE_HAL, display._presentation_params.AutoDepthStencilFormat,
is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value())); is_fullscreen(), D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value()));
if (FAILED(hr)) { if (FAILED(hr)) {
wdxdisplay8_cat.fatal() << "device #" << Display._card_id << " doesnt support multisample level " << dx_multisample_antialiasing_level << "surface fmt " << D3DFormatStr(Display._presentation_params.AutoDepthStencilFormat) << endl; wdxdisplay8_cat.fatal() << "device #" << display._card_id << " doesnt support multisample level " << dx_multisample_antialiasing_level << "surface fmt " << D3DFormatStr(display._presentation_params.AutoDepthStencilFormat) << endl;
return false; return false;
} }
} }
@ -558,14 +558,14 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
presentation_params->MultiSampleType = D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value()); presentation_params->MultiSampleType = D3DMULTISAMPLE_TYPE(dx_multisample_antialiasing_level.get_value());
if (wdxdisplay8_cat.is_info()) if (wdxdisplay8_cat.is_info())
wdxdisplay8_cat.info() << "device #" << Display._card_id << " using multisample antialiasing level " << dx_multisample_antialiasing_level << endl; wdxdisplay8_cat.info() << "device #" << display._card_id << " using multisample antialiasing level " << dx_multisample_antialiasing_level << endl;
} }
presentation_params->BackBufferCount = 1; presentation_params->BackBufferCount = 1;
presentation_params->Flags = 0x0; presentation_params->Flags = 0x0;
presentation_params->hDeviceWindow = Display._window; presentation_params->hDeviceWindow = display._window;
presentation_params->BackBufferWidth = Display._display_mode.Width; presentation_params->BackBufferWidth = display._display_mode.Width;
presentation_params->BackBufferHeight = Display._display_mode.Height; presentation_params->BackBufferHeight = display._display_mode.Height;
if (_wcontext._is_tnl_device) { if (_wcontext._is_tnl_device) {
dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING; dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
@ -587,22 +587,22 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
// false, causing us to go into a 'wait-for WM_ACTIVATEAPP true' // false, causing us to go into a 'wait-for WM_ACTIVATEAPP true'
// loop, and the event never comes so we hang in fullscreen wait. // loop, and the event never comes so we hang in fullscreen wait.
// also doing this for windowed mode since it was requested. // also doing this for windowed mode since it was requested.
if (!SetForegroundWindow(Display._window)) { if (!SetForegroundWindow(display._window)) {
wdxdisplay8_cat.warning() << "SetForegroundWindow() failed!\n"; wdxdisplay8_cat.warning() << "SetForegroundWindow() failed!\n";
} }
if (is_fullscreen()) { if (is_fullscreen()) {
presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame presentation_params->SwapEffect = D3DSWAPEFFECT_DISCARD; // we dont care about preserving contents of old frame
presentation_params->FullScreen_PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE); presentation_params->FullScreen_PresentationInterval = (do_sync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE);
presentation_params->FullScreen_RefreshRateInHz = Display._display_mode.RefreshRate; presentation_params->FullScreen_RefreshRateInHz = display._display_mode.RefreshRate;
ClearToBlack(Display._window, get_properties()); ClearToBlack(display._window, get_properties());
hr = _d3d8->CreateDevice(Display._card_id, D3DDEVTYPE_HAL, _hWnd, hr = _d3d8->CreateDevice(display._card_id, D3DDEVTYPE_HAL, _hWnd,
dwBehaviorFlags, presentation_params, &Display._d3d_device); dwBehaviorFlags, presentation_params, &display._d3d_device);
if (FAILED(hr)) { if (FAILED(hr)) {
wdxdisplay8_cat.fatal() << "D3D CreateDevice failed for device #" << Display._card_id << ", " << D3DERRORSTRING(hr); wdxdisplay8_cat.fatal() << "D3D CreateDevice failed for device #" << display._card_id << ", " << D3DERRORSTRING(hr);
if (hr == D3DERR_OUTOFVIDEOMEMORY) if (hr == D3DERR_OUTOFVIDEOMEMORY)
goto Fallback_to_16bpp_buffers; goto Fallback_to_16bpp_buffers;
@ -616,7 +616,7 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
else { // CREATE WINDOWED BUFFERS else { // CREATE WINDOWED BUFFERS
D3DDISPLAYMODE dispmode; D3DDISPLAYMODE dispmode;
hr = Display._d3d8->GetAdapterDisplayMode(Display._card_id, &dispmode); hr = display._d3d8->GetAdapterDisplayMode(display._card_id, &dispmode);
if (FAILED(hr)) { if (FAILED(hr)) {
wdxdisplay8_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr); wdxdisplay8_cat.fatal() << "GetAdapterDisplayMode failed" << D3DERRORSTRING(hr);
@ -642,15 +642,15 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
//assert((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight)); //assert((dwRenderWidth == presentation_params->BackBufferWidth)&&(dwRenderHeight == presentation_params->BackBufferHeight));
hr = _d3d8->CreateDevice(Display._card_id, D3DDEVTYPE_HAL, _hWnd, hr = _d3d8->CreateDevice(display._card_id, D3DDEVTYPE_HAL, _hWnd,
dwBehaviorFlags, presentation_params, &Display._d3d_device); dwBehaviorFlags, presentation_params, &display._d3d_device);
if (FAILED(hr)) { if (FAILED(hr)) {
wdxdisplay8_cat.warning() << "presentation_params->BackBufferWidth : " << presentation_params->BackBufferWidth << endl; wdxdisplay8_cat.warning() << "presentation_params->BackBufferWidth : " << presentation_params->BackBufferWidth << endl;
wdxdisplay8_cat.warning() << "presentation_params->BackBufferHeight : " << presentation_params->BackBufferHeight << endl; wdxdisplay8_cat.warning() << "presentation_params->BackBufferHeight : " << presentation_params->BackBufferHeight << endl;
wdxdisplay8_cat.warning() << "presentation_params->BackBufferFormat : " << presentation_params->BackBufferFormat << endl; wdxdisplay8_cat.warning() << "presentation_params->BackBufferFormat : " << presentation_params->BackBufferFormat << endl;
wdxdisplay8_cat.warning() << "presentation_params->BackBufferCount : " << presentation_params->BackBufferCount << endl; wdxdisplay8_cat.warning() << "presentation_params->BackBufferCount : " << presentation_params->BackBufferCount << endl;
wdxdisplay8_cat.warning() << "D3D CreateDevice failed for device #" << Display._card_id << D3DERRORSTRING(hr); wdxdisplay8_cat.warning() << "D3D CreateDevice failed for device #" << display._card_id << D3DERRORSTRING(hr);
goto Fallback_to_16bpp_buffers; goto Fallback_to_16bpp_buffers;
} }
} // end create windowed buffers } // end create windowed buffers
@ -673,26 +673,26 @@ create_screen_buffers_and_device(DXScreenData &Display, bool force_16bpp_zbuffer
Fallback_to_16bpp_buffers: Fallback_to_16bpp_buffers:
if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) && if ((!IS_16BPP_DISPLAY_FORMAT(presentation_params->BackBufferFormat)) &&
(Display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) { (display._supported_screen_depths_mask & (R5G6B5_FLAG|X1R5G5B5_FLAG))) {
// fallback strategy, if we trying >16bpp, fallback to 16bpp buffers // fallback strategy, if we trying >16bpp, fallback to 16bpp buffers
Display._display_mode.Format = ((Display._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5); display._display_mode.Format = ((display._supported_screen_depths_mask & R5G6B5_FLAG) ? D3DFMT_R5G6B5 : D3DFMT_X1R5G5B5);
if (wdxdisplay8_cat.info()) { if (wdxdisplay8_cat.info()) {
wdxdisplay8_cat.info() wdxdisplay8_cat.info()
<< "CreateDevice failed with out-of-vidmem or invalid BackBufferFormat, retrying w/16bpp buffers on device #" << "CreateDevice failed with out-of-vidmem or invalid BackBufferFormat, retrying w/16bpp buffers on device #"
<< Display._card_id << endl; << display._card_id << endl;
} }
return create_screen_buffers_and_device(Display, true); return create_screen_buffers_and_device(display, true);
//return; //return;
} else if (!((dwRenderWidth == 640)&&(dwRenderHeight == 480))) { } else if (!((dwRenderWidth == 640)&&(dwRenderHeight == 480))) {
if (wdxdisplay8_cat.info()) if (wdxdisplay8_cat.info())
wdxdisplay8_cat.info() << "CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on device #" << Display._card_id << endl; wdxdisplay8_cat.info() << "CreateDevice failed w/out-of-vidmem, retrying at 640x480 w/16bpp buffers on device #" << display._card_id << endl;
// try final fallback to 640x480x16 // try final fallback to 640x480x16
Display._display_mode.Width = 640; display._display_mode.Width = 640;
Display._display_mode.Height = 480; display._display_mode.Height = 480;
return create_screen_buffers_and_device(Display, true); return create_screen_buffers_and_device(display, true);
//return; //return;
} else { } else {

View File

@ -65,7 +65,7 @@ private:
}; };
typedef pvector<DXDeviceInfo> DXDeviceInfoVec; typedef pvector<DXDeviceInfo> DXDeviceInfoVec;
bool create_screen_buffers_and_device(DXScreenData &Display, bool create_screen_buffers_and_device(DXScreenData &display,
bool force_16bpp_zbuffer); bool force_16bpp_zbuffer);
bool choose_device(); bool choose_device();