[PATCH] wined3d: Don't discard buffer data if buffer is not bound.

Axel Davy davyaxel0 at gmail.com
Thu Jul 9 04:17:39 CDT 2020


On 08/07/2020 22:44, Paul Gofman wrote:
> hr = IDirect3DVertexBuffer9_Lock(buffer, (quad_count - 1) * sizeof(quad2),
> +            sizeof(quad2), (void **)&quads, D3DLOCK_DISCARD);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    *quads = quad2;
> +    hr = IDirect3DVertexBuffer9_Unlock(buffer);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, 0);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    /* The data has been reset for the whole buffer. */
> +    for (i = 0; i < quad_count - 1; ++i)
> +        ok(memcmp(&quads[i], &quad1, sizeof(quad1)), "Quads match, i %u.\n", i);
> +
> +    ok(!memcmp(&quads[i], &quad2, sizeof(quad2)), "Quads do not match, i %u.\n", i);
> +
> +    for (i = 0; i < quad_count; ++i)
> +        quads[i] = quad1;
> +
> +    hr = IDirect3DVertexBuffer9_Unlock(buffer);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    hr = IDirect3DDevice9_SetStreamSource(device, 0, buffer2, 0, sizeof(*quads->strip));
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff0000ff, 0.0f, 0);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    hr = IDirect3DDevice9_BeginScene(device);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    hr = IDirect3DDevice9_DrawPrimitive(device, D3DPT_TRIANGLESTRIP, 0, tri_count);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    hr = IDirect3DDevice9_EndScene(device);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    hr = IDirect3DVertexBuffer9_Lock(buffer, (quad_count - 1) * sizeof(quad2),
> +            sizeof(quad2), (void **)&quads, D3DLOCK_DISCARD);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +    *quads = quad2;
> +    hr = IDirect3DVertexBuffer9_Unlock(buffer);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    hr = IDirect3DVertexBuffer9_Lock(buffer, 0, size, (void **)&quads, 0);
> +    ok(hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
> +
> +    /* The data are preserved when mapping with MAP_DISCARD on unbound buffer. */
> +    for (i = 0; i < quad_count - 1; ++i)
> +        ok(!memcmp(&quads[i], &quad1, sizeof(quad1)), "Quads do not match, i %u.\n", i);
> +
> +    ok(!memcmp(&quads[i], &quad2, sizeof(quad2)), "Quads do not match, i %u.\n", i);

Hi,

I have another explanation for this behaviour:

For the first DISCARD you try, the buffer backing is busy because it is 
doing to be used for rendering not yet finished.
Thus the DISCARD does actually do something.

Then when you map for reading the buffer it flushes everything and 
rendering has to finish. Thus for the next DISCARD, the driver finds 
that the driver backing is not busy, it decides to keep it.

Definitely you should discard buffer data if the buffer is not bound. It 
will happen in a lot of games. A buffer not bound doesn't mean it is not 
used by the GPU. What you really want is to not discard when the buffer 
is not bound nor used in any pending rendering. That is of course much 
harder to detect. I would bet your application just needs the DISCARD to 
do nothing before the buffer is used for rendering for the first time.

Yours,

Axel Davy




More information about the wine-devel mailing list