vrend: Rework resource storage

Rename VREND_RESOURCE_STORAGE_IOVEC to
VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM and introduce
VREND_RESOURCE_STORAGE_GUEST. The former is used as storage for query
buffers, and the latter will be used in upcoming commits for staging
buffers.

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
Reviewed-by: Chia-I Wu <olvaffe@gmail.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Alexandros Frantzis 6 years ago committed by Gert Wollny
parent 10dff6b5ab
commit faa38808c9
  1. 62
      src/iov.c
  2. 4
      src/vrend_iov.h
  3. 56
      src/vrend_renderer.c
  4. 10
      src/vrend_renderer.h

@ -39,6 +39,8 @@
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "vrend_iov.h"
size_t vrend_get_iovec_size(const struct iovec *iov, int iovlen) {
@ -140,3 +142,63 @@ size_t vrend_read_from_iovec_cb(const struct iovec *iov, int iovlen,
}
/**
* Copy data from one iovec to another iovec.
*
* TODO: Implement iovec copy without copy to intermediate buffer.
*
* \param src_iov The source iov.
* \param src_iovlen The number of memory regions in the source iov.
* \param src_offset The byte offset in the source iov to start reading from.
* \param dst_iov The destination iov.
* \param dst_iovlen The number of memory regions in the destination iov.
* \param dst_offset The byte offset in the destination iov to start writing to.
* \param count The number of bytes to copy
* \param buf If not NULL, a pointer to a buffer of at least count size
* to use a temporary storage for the copy operation.
* \return -1 on failure, 0 on success
*/
int vrend_copy_iovec(const struct iovec *src_iov, int src_iovlen, size_t src_offset,
const struct iovec *dst_iov, int dst_iovlen, size_t dst_offset,
size_t count, char *buf)
{
int ret = 0;
bool needs_free;
size_t nread;
size_t nwritten;
if (src_iov == NULL || dst_iov == NULL)
return -1;
if (src_iov == dst_iov && src_offset == dst_offset)
return 0;
if (!buf) {
buf = malloc(count);
needs_free = true;
} else {
needs_free = false;
}
if (!buf)
return -1;
nread = vrend_read_from_iovec(src_iov, src_iovlen, src_offset, buf, count);
if (nread != count) {
ret = -1;
goto out;
}
nwritten = vrend_write_to_iovec(dst_iov, dst_iovlen, dst_offset, buf, count);
if (nwritten != count) {
ret = -1;
goto out;
}
out:
if (needs_free)
free(buf);
return ret;
}

@ -46,4 +46,8 @@ size_t vrend_write_to_iovec(const struct iovec *iov, int iov_cnt,
size_t vrend_read_from_iovec_cb(const struct iovec *iov, int iov_cnt,
size_t offset, size_t bytes, iov_cb iocb, void *cookie);
int vrend_copy_iovec(const struct iovec *src_iov, int src_iovlen, size_t src_offset,
const struct iovec *dst_iov, int dst_iovlen, size_t dst_offset,
size_t count, char *buf);
#endif

@ -5818,7 +5818,7 @@ int vrend_renderer_resource_attach_iov(int res_handle, struct iovec *iov,
res->iov = iov;
res->num_iovs = num_iovs;
if (res->storage == VREND_RESOURCE_STORAGE_IOVEC) {
if (res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM) {
vrend_write_to_iovec(res->iov, res->num_iovs, 0,
res->ptr, res->base.width0);
}
@ -5840,7 +5840,7 @@ void vrend_renderer_resource_detach_iov(int res_handle,
if (num_iovs_p)
*num_iovs_p = res->num_iovs;
if (res->storage == VREND_RESOURCE_STORAGE_IOVEC) {
if (res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM) {
vrend_read_from_iovec(res->iov, res->num_iovs, 0,
res->ptr, res->base.width0);
}
@ -6154,7 +6154,7 @@ int vrend_renderer_resource_create(struct vrend_renderer_resource_create_args *a
if (args->bind == VIRGL_BIND_CUSTOM) {
assert(args->target == PIPE_BUFFER);
/* use iovec directly when attached */
gr->storage = VREND_RESOURCE_STORAGE_IOVEC;
gr->storage = VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM;
gr->ptr = malloc(args->width);
if (!gr->ptr) {
FREE(gr);
@ -6225,7 +6225,7 @@ void vrend_renderer_resource_destroy(struct vrend_resource *res)
if (res->tbo_tex_id)
glDeleteTextures(1, &res->tbo_tex_id);
break;
case VREND_RESOURCE_STORAGE_IOVEC:
case VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM:
free(res->ptr);
break;
default:
@ -6475,20 +6475,17 @@ static int vrend_renderer_transfer_write_iov(struct vrend_context *ctx,
{
void *data;
if (res->storage == VREND_RESOURCE_STORAGE_IOVEC) {
const bool need_write = (res->iov == NULL ||
res->iov != iov ||
info->offset != (size_t) info->box->x);
if (need_write) {
vrend_read_from_iovec(iov, num_iovs, info->offset,
res->ptr + info->box->x, info->box->width);
if (res->iov) {
vrend_write_to_iovec(res->iov, res->num_iovs, info->box->x,
res->ptr + info->box->x, info->box->width);
}
}
if (res->storage == VREND_RESOURCE_STORAGE_GUEST ||
(res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM && res->iov)) {
return vrend_copy_iovec(iov, num_iovs, info->offset,
res->iov, res->num_iovs, info->box->x,
info->box->width, res->ptr);
}
if (res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM) {
assert(!res->iov);
vrend_read_from_iovec(iov, num_iovs, info->offset,
res->ptr + info->box->x, info->box->width);
return 0;
}
@ -7000,20 +6997,17 @@ static int vrend_renderer_transfer_send_iov(struct vrend_resource *res,
struct iovec *iov, int num_iovs,
const struct vrend_transfer_info *info)
{
if (res->storage == VREND_RESOURCE_STORAGE_IOVEC) {
const bool need_send = (res->iov == NULL ||
res->iov != iov ||
info->offset != (size_t) info->box->x);
if (need_send) {
if (res->iov) {
vrend_read_from_iovec(res->iov, res->num_iovs, info->box->x,
res->ptr + info->box->x, info->box->width);
}
vrend_write_to_iovec(iov, num_iovs, info->offset,
res->ptr + info->box->x, info->box->width);
}
if (res->storage == VREND_RESOURCE_STORAGE_GUEST ||
(res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM && res->iov)) {
return vrend_copy_iovec(res->iov, res->num_iovs, info->box->x,
iov, num_iovs, info->offset,
info->box->width, res->ptr);
}
if (res->storage == VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM) {
assert(!res->iov);
vrend_write_to_iovec(iov, num_iovs, info->offset,
res->ptr + info->box->x, info->box->width);
return 0;
}
@ -8198,7 +8192,7 @@ int vrend_create_query(struct vrend_context *ctx, uint32_t handle,
struct vrend_resource *res;
uint32_t ret_handle;
res = vrend_renderer_ctx_res_lookup(ctx, res_handle);
if (!res || res->storage != VREND_RESOURCE_STORAGE_IOVEC) {
if (!res || res->storage != VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM) {
report_context_error(ctx, VIRGL_ERROR_CTX_ILLEGAL_RESOURCE, res_handle);
return EINVAL;
}

@ -52,7 +52,11 @@ struct vrend_context;
enum vrend_resource_storage_type {
VREND_RESOURCE_STORAGE_TEXTURE,
VREND_RESOURCE_STORAGE_BUFFER,
VREND_RESOURCE_STORAGE_IOVEC,
/* The resource contents are stored in shared guest memory. */
VREND_RESOURCE_STORAGE_GUEST,
/* The resource contents are stored in shared guest memory if it's
* attached, otherwise in host system memory. */
VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM,
};
struct vrend_resource {
@ -71,7 +75,11 @@ struct vrend_resource {
GLuint handle;
void *priv;
/* Pointer to system memory storage for this resource. Only valid for
* VREND_RESOURCE_STORAGE_GUEST_ELSE_SYSTEM buffer storage.
*/
char *ptr;
/* IOV pointing to shared guest memory storage for this resource. */
struct iovec *iov;
uint32_t num_iovs;
uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];

Loading…
Cancel
Save