virgl: make virgl_renderer_resource_{attach,detach}_iov generic

Add and use virgl_resource_{attach,detach}_iov.

When the iov of a virgl_resource is changed, we should in theory
notify all contexts where the virgl_resource has been attached to.
But because we plan to move to immutable iov for other renderers,
only vrend contexts need to be notified.  And because vrend contexts
use vrend_resource and refcount, we only need to update
vrend_resource.

Signed-off-by: Chia-I Wu <olvaffe@gmail.com>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Chia-I Wu 5 years ago
parent a40d51db63
commit 23ff16f993
  1. 34
      src/virgl_resource.c
  2. 18
      src/virgl_resource.h
  3. 17
      src/virglrenderer.c
  4. 79
      src/vrend_renderer.c
  5. 5
      src/vrend_renderer.h

@ -108,3 +108,37 @@ struct virgl_resource *virgl_resource_lookup(uint32_t res_id)
return util_hash_table_get(virgl_resource_table, return util_hash_table_get(virgl_resource_table,
uintptr_to_pointer(res_id)); 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;
}

@ -27,6 +27,7 @@
#include <stdint.h> #include <stdint.h>
struct iovec;
struct pipe_resource; struct pipe_resource;
/** /**
@ -40,6 +41,9 @@ struct pipe_resource;
struct virgl_resource { struct virgl_resource {
uint32_t res_id; uint32_t res_id;
const struct iovec *iov;
int iov_count;
void *private_data; void *private_data;
struct pipe_resource *pipe_resource; struct pipe_resource *pipe_resource;
@ -49,6 +53,12 @@ struct virgl_resource_pipe_callbacks {
void *data; void *data;
void (*unref)(struct pipe_resource *pres, 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 int
@ -69,4 +79,12 @@ virgl_resource_remove(uint32_t res_id);
struct virgl_resource * struct virgl_resource *
virgl_resource_lookup(uint32_t res_id); 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 */ #endif /* VIRGL_RESOURCE_H */

@ -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 virgl_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
int num_iovs) 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) 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) int virgl_renderer_create_fence(int client_fence_id, uint32_t ctx_id)

@ -5772,11 +5772,43 @@ static void vrend_pipe_resource_unref(struct pipe_resource *pres,
vrend_renderer_resource_destroy(res); 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 * static const struct virgl_resource_pipe_callbacks *
vrend_renderer_get_pipe_callbacks(void) vrend_renderer_get_pipe_callbacks(void)
{ {
static const struct virgl_resource_pipe_callbacks callbacks = { static const struct virgl_resource_pipe_callbacks callbacks = {
.unref = vrend_pipe_resource_unref, .unref = vrend_pipe_resource_unref,
.attach_iov = vrend_pipe_resource_attach_iov,
.detach_iov = vrend_pipe_resource_detach_iov,
}; };
return &callbacks; 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); 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, static int check_resource_valid(struct vrend_renderer_resource_create_args *args,
char errmsg[256]) char errmsg[256])
{ {

@ -372,11 +372,6 @@ void vrend_build_format_list_gles(void);
void vrend_build_emulated_format_list_gles(void); void vrend_build_emulated_format_list_gles(void);
void vrend_check_texture_storage(struct vrend_format_table *table); 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); void vrend_renderer_resource_destroy(struct vrend_resource *res);
static inline void static inline void

Loading…
Cancel
Save