Based on patches by Matteo Bruni and Michael Müller.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/cs.c | 30 ++++++++++++++++++++++++++++++ dlls/wined3d/wined3d_private.h | 1 + 2 files changed, 31 insertions(+)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index f0328f82794..827b7fbdc0b 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -2755,6 +2755,14 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi context_release(context);
wined3d_resource_release(resource); + + if (op->bo.flags & UPLOAD_BO_FREE_ON_UNMAP) + { + if (op->bo.addr.buffer_object) + FIXME("Free BO address %s.\n", debug_const_bo_address(&op->bo.addr)); + else + heap_free((void *)op->bo.addr.addr); + } }
void wined3d_device_context_emit_update_sub_resource(struct wined3d_device_context *context, @@ -3186,6 +3194,28 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str return true; }
+ if (!(flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))) + { + struct wined3d_client_resource *client = &resource->client; + const struct wined3d_format *format = resource->format; + size_t size; + + wined3d_format_calculate_pitch(format, 1, box->right - box->left, + box->bottom - box->top, &map_desc->row_pitch, &map_desc->slice_pitch); + + size = (box->back - box->front - 1) * map_desc->slice_pitch + + ((box->bottom - box->top - 1) / format->block_height) * map_desc->row_pitch + + ((box->right - box->left + format->block_width - 1) / format->block_width) * format->block_byte_count; + + if (!(map_desc->data = heap_alloc(size))) + return false; + client->mapped_upload.addr.buffer_object = 0; + client->mapped_upload.addr.addr = map_desc->data; + client->mapped_upload.flags = UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_FREE_ON_UNMAP; + client->mapped_box = *box; + return true; + } + return false; }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a9837911ea6..a9a71b44a0e 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -3382,6 +3382,7 @@ bool wined3d_driver_info_init(struct wined3d_driver_info *driver_info,
#define UPLOAD_BO_UPLOAD_ON_UNMAP 0x1 #define UPLOAD_BO_RENAME_ON_UNMAP 0x2 +#define UPLOAD_BO_FREE_ON_UNMAP 0x4
struct upload_bo {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/wined3d/cs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 827b7fbdc0b..ce71abf3a31 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -3216,6 +3216,8 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str return true; }
+ WARN_(d3d_perf)("Unable to allocate an upload BO for resource type %#x, map flags %#x.\n", resource->type, flags); + return false; }
On Fri, 25 Feb 2022 at 03:22, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -3186,6 +3194,28 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str return true; }
- if (!(flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
- {
struct wined3d_client_resource *client = &resource->client;
const struct wined3d_format *format = resource->format;
size_t size;
wined3d_format_calculate_pitch(format, 1, box->right - box->left,
box->bottom - box->top, &map_desc->row_pitch, &map_desc->slice_pitch);
size = (box->back - box->front - 1) * map_desc->slice_pitch
+ ((box->bottom - box->top - 1) / format->block_height) * map_desc->row_pitch
+ ((box->right - box->left + format->block_width - 1) / format->block_width) * format->block_byte_count;
if (!(map_desc->data = heap_alloc(size)))
return false;
client->mapped_upload.addr.buffer_object = 0;
client->mapped_upload.addr.addr = map_desc->data;
client->mapped_upload.flags = UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_FREE_ON_UNMAP;
client->mapped_box = *box;
return true;
- }
- return false;
}
It's not the worst thing, but note that the "flags" check here is redundant; if either DISCARD or NOOVERWRITE was set, we would have returned from the preceding block. That also means the final "return false;" should be unreachable though, and that makes the next patch in the series slightly weird.
On 2/25/22 08:22, Henri Verbeet wrote:
On Fri, 25 Feb 2022 at 03:22, Zebediah Figura zfigura@codeweavers.com wrote:
@@ -3186,6 +3194,28 @@ static bool wined3d_cs_map_upload_bo(struct wined3d_device_context *context, str return true; }
- if (!(flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE)))
- {
struct wined3d_client_resource *client = &resource->client;
const struct wined3d_format *format = resource->format;
size_t size;
wined3d_format_calculate_pitch(format, 1, box->right - box->left,
box->bottom - box->top, &map_desc->row_pitch, &map_desc->slice_pitch);
size = (box->back - box->front - 1) * map_desc->slice_pitch
+ ((box->bottom - box->top - 1) / format->block_height) * map_desc->row_pitch
+ ((box->right - box->left + format->block_width - 1) / format->block_width) * format->block_byte_count;
if (!(map_desc->data = heap_alloc(size)))
return false;
client->mapped_upload.addr.buffer_object = 0;
client->mapped_upload.addr.addr = map_desc->data;
client->mapped_upload.flags = UPLOAD_BO_UPLOAD_ON_UNMAP | UPLOAD_BO_FREE_ON_UNMAP;
client->mapped_box = *box;
return true;
- }
}return false;
It's not the worst thing, but note that the "flags" check here is redundant; if either DISCARD or NOOVERWRITE was set, we would have returned from the preceding block. That also means the final "return false;" should be unreachable though, and that makes the next patch in the series slightly weird.
Indeed. These patches may be a little older...