virglrenderer: add virgl_renderer_execute

It's desirable to query or modify virgl_renderer state for various values.

We've done it for resources (virgl_renderer_get_fd_for_texture /
virgl_renderer_get_fd_for_texture2 / virgl_renderer_resource_get_info) a
few times, but more parameters are often desired.

Let's define a protocol instead.  That way, more queries/operations (is "ctx
{num} lost?", "is x host feature supported?") can be formulated.

It's also possible to put the protocol in virgl_hw.h, so in theory
the guest can recieve a response directly from virglrenderer. Any
opinions on this?

v2: virgl_renderer_query --> virgl_renderer_execute

Reviewed-by: David Riley <davidriley@chromium.org>
Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
macos/master
Gurchetan Singh 5 years ago
parent e3683f0fbd
commit 336f2f1911
  1. 59
      src/virgl_gbm.c
  2. 3
      src/virgl_gbm.h
  3. 5
      src/virglrenderer.c
  4. 34
      src/virglrenderer.h
  5. 38
      src/vrend_renderer.c
  6. 3
      src/vrend_renderer.h

@ -368,3 +368,62 @@ uint32_t virgl_gbm_convert_flags(uint32_t virgl_bind_flags)
flags |= GBM_BO_USE_CURSOR;
return flags;
}
int virgl_gbm_export_query(struct gbm_bo *bo, struct virgl_renderer_export_query *query)
{
int ret = -1;
uint32_t handles[4] = {0, 0, 0, 0};
struct gbm_device *gbm = gbm_bo_get_device(bo);
int num_planes = gbm_bo_get_plane_count(bo);
if (num_planes < 0 || num_planes > 4)
return ret;
query->out_num_fds = 0;
query->out_fourcc = 0;
query->out_modifier = 0;
for (int plane = 0; plane < 4; plane++) {
query->out_fds[plane] = -1;
query->out_strides[plane] = 0;
query->out_offsets[plane] = 0;
}
for (int plane = 0; plane < num_planes; plane++) {
uint32_t i, handle;
query->out_strides[plane] = gbm_bo_get_stride_for_plane(bo, plane);
query->out_offsets[plane] = gbm_bo_get_offset(bo, plane);
handle = gbm_bo_get_handle_for_plane(bo, plane).u32;
for (i = 0; i < query->out_num_fds; i++) {
if (handles[query->out_num_fds] == handle)
break;
}
if (i == query->out_num_fds) {
if (query->in_export_fds) {
ret = drmPrimeHandleToFD(gbm_device_get_fd(gbm), handle, DRM_CLOEXEC,
&query->out_fds[query->out_num_fds]);
if (ret)
goto err_close;
}
query->out_num_fds++;
}
}
query->out_modifier = gbm_bo_get_modifier(bo);
query->out_fourcc = gbm_bo_get_format(bo);
return 0;
err_close:
for (int plane = 0; plane < 4; plane++) {
if (query->out_fds[plane] >= 0) {
close(query->out_fds[plane]);
query->out_fds[plane] = -1;
}
query->out_strides[plane] = 0;
query->out_offsets[plane] = 0;
}
query->out_num_fds = 0;
return ret;
}

@ -27,6 +27,7 @@
#include <gbm.h>
#include "vrend_iov.h"
#include "virglrenderer.h"
/*
* If fd >= 0, virglrenderer owns the fd since it was opened via a rendernode
@ -49,4 +50,6 @@ int virgl_gbm_transfer(struct gbm_bo *bo, uint32_t direction, struct iovec *iove
uint32_t virgl_gbm_convert_flags(uint32_t virgl_bind_flags);
int virgl_gbm_export_query(struct gbm_bo *bo, struct virgl_renderer_export_query *query);
#endif

@ -422,3 +422,8 @@ virgl_debug_callback_type virgl_set_debug_callback(virgl_debug_callback_type cb)
{
return vrend_set_debug_callback(cb);
}
int virgl_renderer_execute(void *execute_args, uint32_t execute_size)
{
return vrend_renderer_execute(execute_args, execute_size);
}

@ -98,6 +98,11 @@ VIRGL_EXPORT int virgl_renderer_get_fd_for_texture2(uint32_t tex_id, int *fd, in
#define VIRGL_RES_BIND_SCANOUT (1 << 18)
#define VIRGL_RES_BIND_SHARED (1 << 20)
enum virgl_renderer_structure_type_v0 {
VIRGL_RENDERER_STRUCTURE_TYPE_NONE = 0x00000000,
VIRGL_RENDERER_STRUCTURE_TYPE_EXPORT_QUERY = 0x00000001,
};
struct virgl_renderer_resource_create_args {
uint32_t handle;
uint32_t target;
@ -112,6 +117,33 @@ struct virgl_renderer_resource_create_args {
uint32_t flags;
};
struct virgl_renderer_hdr {
uint32_t stype;
uint32_t stype_version;
uint32_t size;
};
/*
* "out_num_fds" represents the number of distinct kernel buffers backing an
* allocation. If this number or 'out_fourcc' is zero, the resource is not
* exportable. The "out_fds" field will be populated with "out_num_fds" file
* descriptors if "in_export_fds" is non-zero.
*/
struct virgl_renderer_export_query {
struct virgl_renderer_hdr hdr;
uint32_t in_resource_id;
uint32_t out_num_fds;
uint32_t in_export_fds;
uint32_t out_fourcc;
uint32_t pad;
int32_t out_fds[4];
uint32_t out_strides[4];
uint32_t out_offsets[4];
uint64_t out_modifier;
};
/* new API */
/* This typedef must be kept in sync with vrend_debug.h */
typedef void (*virgl_debug_callback_type)(const char *fmt, va_list ap);
@ -190,4 +222,6 @@ VIRGL_EXPORT void virgl_renderer_reset(void);
VIRGL_EXPORT int virgl_renderer_get_poll_fd(void);
VIRGL_EXPORT int virgl_renderer_execute(void *execute_args, uint32_t execute_size);
#endif

@ -50,6 +50,7 @@
#include "vrend_debug.h"
#include "virgl_hw.h"
#include "virglrenderer.h"
#include "tgsi/tgsi_text.h"
@ -9625,6 +9626,7 @@ void *vrend_renderer_get_cursor_contents(uint32_t res_handle, uint32_t *width, u
return data2;
}
void vrend_renderer_force_ctx_0(void)
{
struct vrend_context *ctx0 = vrend_lookup_renderer_ctx(0);
@ -9922,3 +9924,39 @@ int vrend_renderer_get_poll_fd(void)
return vrend_state.eventfd;
}
int vrend_renderer_execute(void *execute_args, uint32_t execute_size)
{
/*
* This function only supports VIRGL_RENDERER_STRUCTURE_TYPE_RESOURCE_QUERY currently.
*/
struct vrend_resource *res;
struct virgl_renderer_export_query *export_query = execute_args;
if (execute_size != sizeof(struct virgl_renderer_export_query))
return -EINVAL;
if (export_query->hdr.stype != VIRGL_RENDERER_STRUCTURE_TYPE_EXPORT_QUERY ||
export_query->hdr.stype_version != 0 ||
export_query->hdr.size != sizeof(struct virgl_renderer_export_query))
return -EINVAL;
res = vrend_resource_lookup(export_query->in_resource_id, 0);
if (!res)
return -EINVAL;
#ifdef ENABLE_GBM_ALLOCATION
if (res->gbm_bo)
return virgl_gbm_export_query(res->gbm_bo, export_query);
#endif
/*
* Implementations that support eglExportDMABUFImageMESA can also export certain resources.
* This is omitted currently since virgl_renderer_get_fd_for_texture supports that use case.
*/
export_query->out_num_fds = 0;
export_query->out_fourcc = 0;
if (export_query->in_export_fds)
return -EINVAL;
return 0;
}

@ -452,4 +452,7 @@ static const struct gl_version gl_versions[] = { {4,5}, {4,4}, {4,3}, {4,2}, {4,
{3,3}, {3,2}, {3,1}, {3,0} };
extern struct vrend_if_cbs *vrend_clicbs;
int vrend_renderer_execute(void *execute_args, uint32_t execute_size);
#endif

Loading…
Cancel
Save