diff --git a/src/virgl_resource.c b/src/virgl_resource.c index 73c1e27..9c30e49 100644 --- a/src/virgl_resource.c +++ b/src/virgl_resource.c @@ -108,3 +108,37 @@ struct virgl_resource *virgl_resource_lookup(uint32_t res_id) return util_hash_table_get(virgl_resource_table, uintptr_to_pointer(res_id)); } + +int +virgl_resource_attach_iov(struct virgl_resource *res, + const struct iovec *iov, + int iov_count) +{ + if (res->iov) + return EINVAL; + + res->iov = iov; + res->iov_count = iov_count; + + if (res->pipe_resource) { + pipe_callbacks.attach_iov(res->pipe_resource, + iov, + iov_count, + pipe_callbacks.data); + } + + return 0; +} + +void +virgl_resource_detach_iov(struct virgl_resource *res) +{ + if (!res->iov) + return; + + if (res->pipe_resource) + pipe_callbacks.detach_iov(res->pipe_resource, pipe_callbacks.data); + + res->iov = NULL; + res->iov_count = 0; +} diff --git a/src/virgl_resource.h b/src/virgl_resource.h index 406ccd8..8cbb982 100644 --- a/src/virgl_resource.h +++ b/src/virgl_resource.h @@ -27,6 +27,7 @@ #include +struct iovec; struct pipe_resource; /** @@ -40,6 +41,9 @@ struct pipe_resource; struct virgl_resource { uint32_t res_id; + const struct iovec *iov; + int iov_count; + void *private_data; struct pipe_resource *pipe_resource; @@ -49,6 +53,12 @@ struct virgl_resource_pipe_callbacks { void *data; void (*unref)(struct pipe_resource *pres, void *data); + + void (*attach_iov)(struct pipe_resource *pres, + const struct iovec *iov, + int iov_count, + void *data); + void (*detach_iov)(struct pipe_resource *pres, void *data); }; int @@ -69,4 +79,12 @@ virgl_resource_remove(uint32_t res_id); struct virgl_resource * virgl_resource_lookup(uint32_t res_id); +int +virgl_resource_attach_iov(struct virgl_resource *res, + const struct iovec *iov, + int iov_count); + +void +virgl_resource_detach_iov(struct virgl_resource *res); + #endif /* VIRGL_RESOURCE_H */ diff --git a/src/virglrenderer.c b/src/virglrenderer.c index a389407..b6b04ba 100644 --- a/src/virglrenderer.c +++ b/src/virglrenderer.c @@ -218,12 +218,25 @@ int virgl_renderer_transfer_read_iov(uint32_t handle, uint32_t ctx_id, int virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov, int num_iovs) { - return vrend_renderer_resource_attach_iov(res_handle, iov, num_iovs); + struct virgl_resource *res = virgl_resource_lookup(res_handle); + if (!res) + return EINVAL; + + return virgl_resource_attach_iov(res, iov, num_iovs); } void virgl_renderer_resource_detach_iov(int res_handle, struct iovec **iov_p, int *num_iovs_p) { - vrend_renderer_resource_detach_iov(res_handle, iov_p, num_iovs_p); + struct virgl_resource *res = virgl_resource_lookup(res_handle); + if (!res) + return; + + if (iov_p) + *iov_p = (struct iovec *)res->iov; + if (num_iovs_p) + *num_iovs_p = res->iov_count; + + virgl_resource_detach_iov(res); } int virgl_renderer_create_fence(int client_fence_id, uint32_t ctx_id) diff --git a/src/vrend_renderer.c b/src/vrend_renderer.c index be902f5..a227b26 100644 --- a/src/vrend_renderer.c +++ b/src/vrend_renderer.c @@ -5772,11 +5772,43 @@ static void vrend_pipe_resource_unref(struct pipe_resource *pres, vrend_renderer_resource_destroy(res); } +static void vrend_pipe_resource_attach_iov(struct pipe_resource *pres, + const struct iovec *iov, + int iov_count, + UNUSED void *data) +{ + struct vrend_resource *res = (struct vrend_resource *)pres; + + res->iov = iov; + res->num_iovs = iov_count; + + if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) { + vrend_write_to_iovec(res->iov, res->num_iovs, 0, + res->ptr, res->base.width0); + } +} + +static void vrend_pipe_resource_detach_iov(struct pipe_resource *pres, + UNUSED void *data) +{ + struct vrend_resource *res = (struct vrend_resource *)pres; + + if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) { + vrend_read_from_iovec(res->iov, res->num_iovs, 0, + res->ptr, res->base.width0); + } + + res->iov = NULL; + res->num_iovs = 0; +} + static const struct virgl_resource_pipe_callbacks * vrend_renderer_get_pipe_callbacks(void) { static const struct virgl_resource_pipe_callbacks callbacks = { .unref = vrend_pipe_resource_unref, + .attach_iov = vrend_pipe_resource_attach_iov, + .detach_iov = vrend_pipe_resource_detach_iov, }; return &callbacks; @@ -6089,53 +6121,6 @@ static struct vrend_resource *vrend_renderer_res_lookup(uint32_t res_id) return (struct vrend_resource *) (res ? res->pipe_resource : NULL); } -int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov, - int num_iovs) -{ - struct vrend_resource *res; - - res = vrend_renderer_res_lookup(res_handle); - if (!res) - return EINVAL; - - if (res->iov) - return 0; - - /* work out size and max resource size */ - res->iov = iov; - res->num_iovs = num_iovs; - - if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) { - vrend_write_to_iovec(res->iov, res->num_iovs, 0, - res->ptr, res->base.width0); - } - - return 0; -} - -void vrend_renderer_resource_detach_iov(int res_handle, - struct iovec **iov_p, - int *num_iovs_p) -{ - struct vrend_resource *res; - res = vrend_renderer_res_lookup(res_handle); - if (!res) { - return; - } - if (iov_p) - *iov_p = (struct iovec *)res->iov; - if (num_iovs_p) - *num_iovs_p = res->num_iovs; - - if (has_bit(res->storage_bits, VREND_STORAGE_HOST_SYSTEM_MEMORY)) { - vrend_read_from_iovec(res->iov, res->num_iovs, 0, - res->ptr, res->base.width0); - } - - res->iov = NULL; - res->num_iovs = 0; -} - static int check_resource_valid(struct vrend_renderer_resource_create_args *args, char errmsg[256]) { diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h index 7deb81c..562eb2c 100644 --- a/src/vrend_renderer.h +++ b/src/vrend_renderer.h @@ -372,11 +372,6 @@ void vrend_build_format_list_gles(void); void vrend_build_emulated_format_list_gles(void); void vrend_check_texture_storage(struct vrend_format_table *table); -int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov, - int num_iovs); -void vrend_renderer_resource_detach_iov(int res_handle, - struct iovec **iov_p, - int *num_iovs_p); void vrend_renderer_resource_destroy(struct vrend_resource *res); static inline void