Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/wined3d/cs.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c index 50a08334dab..e6f84134795 100644 --- a/dlls/wined3d/cs.c +++ b/dlls/wined3d/cs.c @@ -490,6 +490,7 @@ struct wined3d_cs_update_sub_resource unsigned int sub_resource_idx; struct wined3d_box box; struct wined3d_sub_resource_data data; + /* If data.data is NULL, the structure is followed by the data in memory. */ };
struct wined3d_cs_add_dirty_texture_region @@ -2597,6 +2598,7 @@ void wined3d_device_context_emit_blt_sub_resource(struct wined3d_device_context static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const void *data) { const struct wined3d_cs_update_sub_resource *op = data; + const void *src_data = op->data.data ? op->data.data : (const BYTE *)(op + 1); struct wined3d_resource *resource = op->resource; const struct wined3d_box *box = &op->box; unsigned int width, height, depth, level; @@ -2617,7 +2619,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi goto done; }
- wined3d_buffer_upload_data(buffer, context, box, op->data.data); + wined3d_buffer_upload_data(buffer, context, box, src_data); wined3d_buffer_invalidate_location(buffer, ~WINED3D_LOCATION_BUFFER); goto done; } @@ -2630,7 +2632,7 @@ static void wined3d_cs_exec_update_sub_resource(struct wined3d_cs *cs, const voi depth = wined3d_texture_get_level_depth(texture, level);
addr.buffer_object = 0; - addr.addr = op->data.data; + addr.addr = src_data;
/* Only load the sub-resource for partial updates. */ if (!box->left && !box->top && !box->front @@ -3375,8 +3377,35 @@ static void wined3d_deferred_context_update_sub_resource(struct wined3d_device_c struct wined3d_resource *resource, unsigned int sub_resource_idx, const struct wined3d_box *box, const void *data, unsigned int row_pitch, unsigned int slice_pitch) { - FIXME("context %p, resource %p, sub_resource_idx %u, box %s, data %p, row_pitch %u, slice_pitch %u, stub!\n", - context, resource, sub_resource_idx, debug_box(box), data, row_pitch, slice_pitch); + struct wined3d_cs_update_sub_resource *op; + size_t data_size; + + if (resource->type == WINED3D_RTYPE_BUFFER) + { + data_size = box->right - box->left; + } + else + { + const struct wined3d_format *format = resource->format; + + data_size = (box->back - box->front - 1) * slice_pitch + + ((box->bottom - box->top - 1) / format->block_height) * row_pitch + + ((box->right - box->left + format->block_width - 1) / format->block_width) * format->block_byte_count; + } + + op = wined3d_device_context_require_space(context, sizeof(*op) + data_size, WINED3D_CS_QUEUE_DEFAULT); + op->opcode = WINED3D_CS_OP_UPDATE_SUB_RESOURCE; + op->resource = resource; + op->sub_resource_idx = sub_resource_idx; + op->box = *box; + op->data.row_pitch = row_pitch; + op->data.slice_pitch = slice_pitch; + op->data.data = NULL; + memcpy(op + 1, data, data_size); + + wined3d_device_context_acquire_resource(context, resource); + + wined3d_device_context_submit(context, WINED3D_CS_QUEUE_DEFAULT); }
static void wined3d_deferred_context_issue_query(struct wined3d_device_context *context,