Stefan Dösinger : ddraw: D3DOP_BRANCHFORWARD includes the current instruction size.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 5 13:31:24 CDT 2007


Module: wine
Branch: master
Commit: 5fa4de27bc780cdc54e5e20ca8ec825b7a069510
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5fa4de27bc780cdc54e5e20ca8ec825b7a069510

Author: Stefan Dösinger <stefan at 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();
 }




More information about the wine-cvs mailing list