Module: wine Branch: master Commit: 5fa4de27bc780cdc54e5e20ca8ec825b7a069510 URL: http://source.winehq.org/git/wine.git/?a=commit;h=5fa4de27bc780cdc54e5e20ca8...
Author: Stefan Dösinger stefan@codeweavers.com Date: Sun Jul 1 13:53:29 2007 +0200
ddraw: D3DOP_BRANCHFORWARD includes the current instruction size.
Native D3DRM puts a branchforward with offset 0 at the beginning of each execute buffer. With the old code this used to get stuck in an endless loop. This patch adds a test that shows that such a branchforward terminates properly.
---
dlls/ddraw/executebuffer.c | 2 - dlls/ddraw/surface.c | 3 +- dlls/ddraw/tests/d3d.c | 110 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/dlls/ddraw/executebuffer.c b/dlls/ddraw/executebuffer.c index ceb5605..fa51c39 100644 --- a/dlls/ddraw/executebuffer.c +++ b/dlls/ddraw/executebuffer.c @@ -519,13 +519,11 @@ IDirect3DExecuteBufferImpl_Execute(IDirect3DExecuteBufferImpl *This, if (!ci->bNegate) { TRACE(" Branch to %d\n", ci->dwOffset); instr = (char*)current + ci->dwOffset; - break; } } else { if (ci->bNegate) { TRACE(" Branch to %d\n", ci->dwOffset); instr = (char*)current + ci->dwOffset; - break; } }
diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c index 39ed549..1d61530 100644 --- a/dlls/ddraw/surface.c +++ b/dlls/ddraw/surface.c @@ -110,7 +110,8 @@ IDirectDrawSurfaceImpl_QueryInterface(IDirectDrawSurface7 *iface, return S_OK; } else if( IsEqualGUID(riid, &IID_D3DDEVICE_WineD3D) || - IsEqualGUID(riid, &IID_IDirect3DHALDevice) ) + IsEqualGUID(riid, &IID_IDirect3DHALDevice)|| + IsEqualGUID(riid, &IID_IDirect3DRGBDevice) ) { IDirect3DDevice7 *d3d;
diff --git a/dlls/ddraw/tests/d3d.c b/dlls/ddraw/tests/d3d.c index 0c69b42..b9d79da 100644 --- a/dlls/ddraw/tests/d3d.c +++ b/dlls/ddraw/tests/d3d.c @@ -818,6 +818,115 @@ static void CapsTest(void) IDirectDraw_Release(dd1); }
+static void ExecutebufferTest(void) +{ + IDirect3DDevice *dev1 = NULL; + IDirectDraw *dd; + IDirect3D *d3d; + IDirectDrawSurface *dds; + IDirect3DExecuteBuffer *exebuf; + IDirect3DViewport *vp; + HRESULT hr; + DDSURFACEDESC ddsd; + D3DEXECUTEBUFFERDESC desc; + D3DVIEWPORT vp_data; + D3DINSTRUCTION *instr; + D3DBRANCH *branch; + unsigned int idx = 0; + + /* An IDirect3DDevice cannot be queryInterfaced from an IDirect3DDevice7 on windows */ + hr = DirectDrawCreate(NULL, &dd, NULL); + ok(hr==DD_OK || hr==DDERR_NODIRECTDRAWSUPPORT, "DirectDrawCreate returned: %x\n", hr); + if (!dd) { + trace("DirectDrawCreate() failed with an error %x\n", hr); + return; + } + + hr = IDirectDraw_SetCooperativeLevel(dd, NULL, DDSCL_NORMAL); + ok(hr==DD_OK, "SetCooperativeLevel returned: %x\n", hr); + + hr = IDirectDraw_QueryInterface(dd, &IID_IDirect3D, (void**) &d3d); + ok(hr==DD_OK, "QueryInterface returned: %x\n", hr); + + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + ddsd.dwWidth = 256; + ddsd.dwHeight = 256; + hr = IDirectDraw_CreateSurface(dd, &ddsd, &dds, NULL); + ok(hr==DD_OK, "CreateSurface returned: %x\n", hr); + + dev1 = NULL; + hr = IDirectDrawSurface_QueryInterface(dds, &IID_IDirect3DRGBDevice, (void **) &dev1); + ok(hr==D3D_OK || hr==DDERR_NOPALETTEATTACHED || hr==E_OUTOFMEMORY, "CreateDevice returned: %x\n", hr); + if(!dev1) return; + + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + desc.dwFlags = D3DDEB_BUFSIZE | D3DDEB_CAPS; + desc.dwCaps = D3DDEBCAPS_VIDEOMEMORY; + desc.dwBufferSize = 128; + desc.lpData = NULL; + hr = IDirect3DDevice_CreateExecuteBuffer(dev1, &desc, &exebuf, NULL); + ok(hr == D3D_OK, "IDirect3DDevice_CreateExecuteBuffer failed: %08x\n", hr); + + memset(&desc, 0, sizeof(desc)); + desc.dwSize = sizeof(desc); + + hr = IDirect3DExecuteBuffer_Lock(exebuf, &desc); + ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Lock failed: %08x\n", hr); + instr = desc.lpData; + instr[idx].bOpcode = D3DOP_BRANCHFORWARD; + instr[idx].bSize = sizeof(*branch); + instr[idx].wCount = 1; + idx++; + branch = (D3DBRANCH *) &instr[idx]; + branch->dwMask = 0x0; + branch->dwValue = 1; + branch->bNegate = TRUE; + branch->dwOffset = 0; + idx += (sizeof(*branch) / sizeof(*instr)); + instr[idx].bOpcode = D3DOP_EXIT; + instr[idx].bSize = 0; + instr[idx].bSize = 0; + hr = IDirect3DExecuteBuffer_Unlock(exebuf); + ok(hr == D3D_OK, "IDirect3DExecuteBuffer_Unlock failed: %08x\n", hr); + + hr = IDirect3D_CreateViewport(d3d, &vp, NULL); + ok(hr == D3D_OK, "IDirect3D_CreateViewport failed: %08x\n", hr); + hr = IDirect3DViewport_Initialize(vp, d3d); + ok(hr == DDERR_ALREADYINITIALIZED, "IDirect3DViewport_Initialize returned %08x\n", hr); + hr = IDirect3DDevice_AddViewport(dev1, vp); + ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr); + vp_data.dwSize = sizeof(vp_data); + vp_data.dwX = 0; + vp_data.dwY = 0; + vp_data.dwWidth = 256; + vp_data.dwHeight = 256; + vp_data.dvScaleX = 1; + vp_data.dvScaleY = 1; + vp_data.dvMaxX = 256; + vp_data.dvMaxY = 256; + vp_data.dvMinZ = 0; + vp_data.dvMaxZ = 1; + hr = IDirect3DViewport_SetViewport(vp, &vp_data); + ok(hr == D3D_OK, "IDirect3DViewport_SetViewport returned %08x\n", hr); + + hr = IDirect3DDevice_Execute(dev1, exebuf, vp, D3DEXECUTE_CLIPPED); + ok(hr == D3D_OK, "IDirect3DDevice_Execute returned %08x\n", hr); + + hr = IDirect3DDevice_DeleteViewport(dev1, vp); + ok(hr == D3D_OK, "IDirect3DDevice_AddViewport returned %08x\n", hr); + IDirect3DViewport_Release(vp); + IDirect3DExecuteBuffer_Release(exebuf); + IDirect3DDevice_Release(dev1); + IDirectDrawSurface_Release(dds); + IDirect3D_Release(d3d); + IDirectDraw_Release(dd); + return; +} + START_TEST(d3d) { init_function_pointers(); @@ -837,4 +946,5 @@ START_TEST(d3d) LimitTest(); CapsTest(); ReleaseDirect3D(); + ExecutebufferTest(); }