Hello,
I've spotted a bug in WineD3D's surface locking, and I have no clue how to fix
this. The problem is that unlocking the back buffer causes it to become
completely black, no matter what's written to it's memory or what has been
there before.
I have written a small D3D9 test app which shows this behavior: Compile it
with winemaker ., followed by make, and run it. Pressing ESC will cause it
to quit, pressing any other keys makes IDirect3DDevice9::Clear call on the
back buffer, with a color value based on the pressed keys. A click anywhere
will LockRect() the whole backbuffer, write 0xff into the whole locked
memory, and UnlockRect() it.
The screen should become completely white, but instead it goes black. With the
fglrx driver and 24 bit color depth it shows the correct behavior, but with
any other driver(radeon, software rendering) or 16 bit color depth, it
doesn't work. The bug is somehow related to some GL calls in
UnlockRect(glPixelZoom and glOrtho), but I couldn't find anything specific.
I hope you can help me, I am quite stuck here,
Stefan
#include stdio.h
#include windows.h
#include d3d9.h
#include assert.h
WNDCLASS wc;
HWND hwnd;
IDirect3D9 *D3D=NULL;
IDirect3DDevice9 *device=NULL;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam);
static void createwindow(void)
{
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandleA(0);
wc.hIcon = LoadIconA(wc.hInstance, IDI_APPLICATION);
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = TestWindowClass;
if(!RegisterClassA(wc))
assert(0);
hwnd = CreateWindowExA(0, TestWindowClass, TestWindowClass,
WS_POPUP, 0, 0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL, NULL, GetModuleHandleA(0), NULL);
assert(hwnd != NULL);
ShowWindow(hwnd, SW_HIDE);
UpdateWindow(hwnd);
SetFocus(hwnd);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMessage, WPARAM wParam, LPARAM lParam)
{
// printf(Message %lx, wparam %lx, lparam %lx\n, uiMessage, wParam, lParam);
static WPARAM old1 = 0;
static WPARAM old2 = 0;
HRESULT hr;
BYTE *lockedmem;
long memsize;
long i;
IDirect3DSurface9 *BackBuffer;
D3DLOCKED_RECT rect;
switch(uiMessage)
{
case WM_DESTROY:
// Close the window, terminate the app
PostQuitMessage(0);
return 0;
case WM_LBUTTONDOWN:
hr = IDirect3DDevice9_GetBackBuffer(device, 0, 0, D3DBACKBUFFER_TYPE_MONO, BackBuffer);
assert(hr == D3D_OK);
hr = IDirect3DSurface9_LockRect(BackBuffer, rect, NULL, 0);
assert(hr == D3D_OK);
memset(rect.pBits, 0xff, rect.Pitch * 480);
hr = IDirect3DSurface9_UnlockRect(BackBuffer);
assert(hr == D3D_OK);
hr = IDirect3DDevice9_Present(device, NULL, NULL, 0, NULL);
assert(hr == D3D_OK);
break;
case WM_KEYUP:
if(lParam == 0xc0010001) /* Escape */
{
PostQuitMessage(0);
return 0;
}
hr = IDirect3DDevice9_Clear(device,
0,
NULL,
D3DCLEAR_TARGET ,
(old2 16) + (old1 8) + wParam,
0, 0);
assert(hr == D3D_OK);
hr = IDirect3DDevice9_Present(device, NULL, NULL, 0, NULL);
assert(hr == D3D_OK);
old2 = old1;
old1 = wParam;
break;
default:
return DefWindowProc(hWnd, uiMessage, wParam, lParam);
}
}
int main()
{
D3DFORMAT format=D3DFMT_R5G6B5;
D3DPRESENT_PARAMETERS pp;
HRESULT hr;
MSG Message;
pp.BackBufferCount= 1;
pp.MultiSampleType=D3DMULTISAMPLE_NONE;
pp.MultiSampleQuality=0;
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
pp.hDeviceWindow=hwnd;
pp.Flags=0;
pp.Windowed = FALSE;
pp.BackBufferWidth = 640;
pp.BackBufferHeight = 480;
pp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
pp.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;
pp.BackBufferFormat=format;
pp.EnableAutoDepthStencil=FALSE;
createwindow();
D3D = Direct3DCreate9( D3D_SDK_VERSION);
hr=IDirect3D9_CreateDevice(D3D, D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
pp,
device);
assert(hr == D3D_OK);
while(GetMessage(Message, NULL, 0, 0))
{
TranslateMessage(Message);
DispatchMessage(Message);
}
IDirect3DDevice9_Release(device);
if(D3D)
{
IDirect3D9_Release(D3D);
D3D=NULL;
}
return 0;
}
pgpZ8y39ypuXb.pgp
Description: PGP signature