[PATCH 3/5] ddraw: Fix offscreen flag handling in TransformVertices.
Stefan Dösinger
stefandoesinger at gmx.at
Mon Aug 29 16:01:26 CDT 2016
Signed-off-by: Stefan Dösinger <stefandoesinger at gmx.at>
---
dlls/ddraw/tests/ddraw1.c | 32 ++++++++++++++++++++++++--------
dlls/ddraw/viewport.c | 34 +++++++++++++---------------------
2 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index cff569b..fdec0ec 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -9341,12 +9341,7 @@ static void test_transform_vertices(void)
}
/* Finally try to figure out how the DWORD dwOffscreen works.
- * Apparently no vertex is offscreen with clipping off,
- * and with clipping on the offscreen flag is set if only one vertex
- * is transformed, and this vertex is offscreen.
- *
- * FIXME: This is wrong. It might be the logical AND of all
- * output clip flags. */
+ * It is a logical AND of the vertices' dwFlags members. */
vp_data = vp_template;
vp_data.dwWidth = 5;
vp_data.dwHeight = 5;
@@ -9366,17 +9361,38 @@ static void test_transform_vertices(void)
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
-
+ offscreen = 0xdeadbeef;
hr = IDirect3DViewport_TransformVertices(viewport, 2,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
- todo_wine ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
+ ok(offscreen == (D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
+ hr = IDirect3DViewport_TransformVertices(viewport, 3,
+ &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
+ ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
+ ok(!offscreen, "Offscreen is %x.\n", offscreen);
+
+ transformdata.lpIn = cliptest + 1;
+ hr = IDirect3DViewport_TransformVertices(viewport, 1,
+ &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
+ ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
+ ok(offscreen == (D3DCLIP_BACK | D3DCLIP_RIGHT | D3DCLIP_TOP), "Offscreen is %x.\n", offscreen);
transformdata.lpIn = cliptest + 2;
hr = IDirect3DViewport_TransformVertices(viewport, 1,
&transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
ok(offscreen == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
+ offscreen = 0xdeadbeef;
+ hr = IDirect3DViewport_TransformVertices(viewport, 2,
+ &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
+ ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
+ ok(offscreen == (D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
+
+ transformdata.lpIn = cliptest + 3;
+ hr = IDirect3DViewport_TransformVertices(viewport, 1,
+ &transformdata, D3DTRANSFORM_CLIPPED, &offscreen);
+ ok(SUCCEEDED(hr), "Failed to transform vertices, hr %#x.\n", hr);
+ ok(offscreen == (D3DCLIP_FRONT | D3DCLIP_BOTTOM | D3DCLIP_LEFT), "Offscreen is %x.\n", offscreen);
transformdata.lpIn = offscreentest;
transformdata.dwInSize = sizeof(offscreentest[0]);
diff --git a/dlls/ddraw/viewport.c b/dlls/ddraw/viewport.c
index 8a42faf..d857dc3 100644
--- a/dlls/ddraw/viewport.c
+++ b/dlls/ddraw/viewport.c
@@ -372,8 +372,8 @@ static HRESULT WINAPI d3d_viewport_SetViewport(IDirect3DViewport3 *iface, D3DVIE
* dwVertexCount: The number of vertices to be transformed
* lpData: Pointer to the vertex data
* dwFlags: D3DTRANSFORM_CLIPPED or D3DTRANSFORM_UNCLIPPED
- * lpOffScreen: Set to the clipping plane clipping the vertex, if only one
- * vertex is transformed and clipping is on. 0 otherwise
+ * offscreen: Logical AND of the planes that clipped the vertices if clipping
+ * is on. 0 if clipping is off.
*
* Returns:
* D3D_OK on success
@@ -391,7 +391,7 @@ struct transform_vertices_vertex
};
static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
- DWORD dwVertexCount, D3DTRANSFORMDATA *lpData, DWORD dwFlags, DWORD *lpOffScreen)
+ DWORD dwVertexCount, D3DTRANSFORMDATA *lpData, DWORD dwFlags, DWORD *offscreen)
{
struct d3d_viewport *viewport = impl_from_IDirect3DViewport3(iface);
D3DVIEWPORT vp = viewport->viewports.vp1;
@@ -401,8 +401,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
unsigned int i;
D3DHVERTEX *outH;
- TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, clip_plane %p.\n",
- iface, dwVertexCount, lpData, dwFlags, lpOffScreen);
+ TRACE("iface %p, vertex_count %u, vertex_data %p, flags %#x, offscreen %p.\n",
+ iface, dwVertexCount, lpData, dwFlags, offscreen);
/* Tests on windows show that Windows crashes when this occurs,
* so don't return the (intuitive) return value
@@ -428,6 +428,12 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
multiply_matrix(&mat, &view_mat, &world_mat);
multiply_matrix(&mat, &viewport->active_device->legacy_projection, &mat);
+ /* The pointer is not tested against NULL on Windows. */
+ if (dwFlags & D3DTRANSFORM_CLIPPED)
+ *offscreen = ~0U;
+ else
+ *offscreen = 0;
+
outH = lpData->lpHOut;
for(i = 0; i < dwVertexCount; i++)
{
@@ -460,6 +466,8 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
if(z > 1.0)
outH[i].dwFlags |= D3DCLIP_BACK;
+ *offscreen &= outH[i].dwFlags;
+
if(outH[i].dwFlags)
{
/* Looks like native just drops the vertex, leaves whatever data
@@ -485,22 +493,6 @@ static HRESULT WINAPI d3d_viewport_TransformVertices(IDirect3DViewport3 *iface,
out->payload = in->payload;
}
- /* According to the d3d test, the offscreen flag is set only
- * if exactly one vertex is transformed. It's not documented,
- * but the test shows that the lpOffscreen flag is set to the
- * flag combination of clipping planes that clips the vertex.
- *
- * If clipping is requested, Windows assumes that the offscreen
- * param is a valid pointer.
- */
- if(dwVertexCount == 1 && dwFlags & D3DTRANSFORM_CLIPPED)
- {
- *lpOffScreen = outH[0].dwFlags;
- }
- else if(*lpOffScreen)
- {
- *lpOffScreen = 0;
- }
wined3d_mutex_unlock();
TRACE("All done\n");
--
2.7.3
More information about the wine-patches
mailing list