[PATCH 3/3] wined3d: Don't initialize system memory for buffers.

Zebediah Figura (she/her) zfigura at codeweavers.com
Wed Jan 26 10:45:39 CST 2022


On 1/26/22 07:47, Henri Verbeet wrote:
> On Tue, 25 Jan 2022 at 03:35, Zebediah Figura <zfigura at codeweavers.com> wrote:
>> This fixes test_map_synchronisation() on 64-bit machines, broken after
>> 194b47b4fd92dda8ebf24e88ca7a14fc926c84ab.
>>
> How is it broken, and why does that happen?

The test creates a buffer, maps it once, then maps it again with 
NOOVERWRITE while the GPU is still drawing, expecting the new data to be 
read by the GPU during the draw. On 32-bit machines, and 64-bit machines 
before 194b47b4fd9, we do the following:

First map: uses SYSMEM since the BO is not created yet
Draw: upload to VBO
Second map: map the existing VBO with GL_MAP_UNSYNCHRONIZED_BIT

After 194b47b4fd9, we don't use GL_MAP_UNSYNCHRONIZED_BIT since the 
buffer has READ access, which means that the second map will be 
synchronized and wait for the draw to complete.

After this patch, we do the following:

First map: create and map a VBO (not unsynchronized, but coherent and 
persistently mapped)
Draw: use mapped VBO
Second map: write to existing (coherent) VBO, which is unsynchronized

I'll make sure to include this explanation in the patch next revision.

Of course, although this motivated the patch, it seems like a good idea 
regardless. In most cases we don't want SYSMEM for buffer objects, 
especially for newer d3d versions, and we should avoid the overhead of 
allocating it and keeping it around.


It may also be that we want to translate D3DVBCAPS_WRITEONLY into 
~WINED3D_RESOURCE_ACCESS_MAP_R. My limited understanding is that this 
doesn't contradict test_vb_writeonly() per se, but rather would only be 
a bad idea performance-wise if ddraw applications rely on reading from 
such mapped buffers in critical paths. I don't know whether that's the case.

> 
>> @@ -1233,7 +1233,7 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d
>>       }
>>       buffer->buffer_ops = buffer_ops;
>>       buffer->structure_byte_stride = desc->structure_byte_stride;
>> -    buffer->locations = data ? WINED3D_LOCATION_DISCARDED : WINED3D_LOCATION_SYSMEM;
>> +    buffer->locations = WINED3D_LOCATION_DISCARDED;
>>
> I think avoiding WINED3D_LOCATION_SYSMEM would be great, but I'm not
> as convinced about using WINED3D_LOCATION_DISCARDED for that purpose.
> I'm not sure we've ever confirmed that buffer resources should be
> zeroed after creation, but we have for texture resources; it would not
> surprise me if this change would break some applications.
> 
> My preferred way of handling this would be to introduce
> WINED3D_LOCATION_CLEARED, which would effectively defer clearing the
> resource until loading it into another location. When replacing the
> entire (sub-)resource with e.g. a DISCARD map or sub-resource update,
> we can then just skip that clear. This approach would also allow us to
> avoid zeroing texture resources on creation, an in case of the Vulkan
> renderer, we could even extend that a bit further and merge
> render-target clears with starting render passes by using
> VK_ATTACHMENT_LOAD_OP_CLEAR and appropriate clear values.

I had in fact had that same idea :-)

I left off using it for buffers because it wasn't clear to me that it 
was necessary. Thus far we had only found evidence that it was necessary 
for textures (and perhaps just swapchain textures?)

Unfortunately I don't currently have access to any Windows machines 
(especially older machines), so I can't verify that buffers (or 
textures, for that matter) are implicitly cleared on initialization.



More information about the wine-devel mailing list