+ /* For small data, make a copy, schedule an in-band update and go home. The copy is placed on the + * CS buffer itself to avoid malloc/free in this performance critical path.
There are a few things I don't particularly like about this approach:
- It places the data inside the CS, and that could end up affecting the throughput of actual commands. - It prefers this path over map_upload_bo even for cases where that path would have given us a GPU bo. - It duplicates a bunch of code from both map_upload_bo and wined3d_device_context_emit_update_sub_resource() itself.
How does this compare with using a private heap (possibly with HEAP_NO_SERIALIZE) for these allocations, much like we do in wined3d_deferred_context_map_upload_bo()?
+ else + { + _aligned_free(buffer->resource.heap_memory); + buffer->resource.heap_memory = (void *)upload_bo->addr.addr; + wined3d_buffer_validate_location(buffer, WINED3D_LOCATION_SYSMEM); + wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_SYSMEM); + /* We are done here. Due to the invalidated LOCATION_BUFFER the data will be uplooaded on the next draw. */ + return; + }
Does that make sense? I don't think you can assume WINED3D_RESOURCE_ACCESS_CPU here, and I wouldn't typically expect D3DUSAGE_DYNAMIC buffers to have it.
@@ -3138,8 +3138,12 @@ void wined3d_context_gl_copy_bo_address(struct wined3d_context_gl *context_gl, wined3d_context_gl_reference_bo(context_gl, dst_bo); } } - else + else if (dst->addr != src->addr) { + /* Copies between the same address can happen if we NOOVERWRITE mapped into heap_memory + * and buffer_get_location picked the sysmem location to copy the new data to (e.g. because + * the buffer has been invalidated after DISCARD. This function will get called again on + * the next draw to copy the data into the BO. */
wined3d_context_gl_copy_bo_address() doesn't know about buffer resources, and shouldn't have to care about them.
+ * heap_alloc + heap_free. It is incorrect for maps - even if we have a write-only map, there + * is no guarantee that the application will overwrite every single byte in the mapped range, + * so we would have to copy the current buffer data into the new buffer before returning it. */
...and maps don't use that path for pretty much that reason.
wined3d_cs_map_upload_bo() doesn't know about resource maps though, and shouldn't have to care about them. The issue here would be with WINED3D_MAP_NOOVERWRITE, which is supposed to return the existing bo for the resource; that's obviously incompatible with allocating a new bo.
+/* If RENAME_ON_UNMAP or FREE_ON_UNMAP are used, then the "const" qualifier in addr is wrong. In the + * first case the destination d3d buffer takes ownership of the BO (either GL/vulkan BO or sysmem + * allocation), in the second case the sysmem allocation is freed.
I don't think either of those operations modify the contents of the bo?