mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 19:08:55 -04:00
bug fixes in framebuffer_copy_to_ram
This commit is contained in:
parent
2c09d3b95a
commit
d02ebe4d88
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
@ -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 {
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user