Cannot play yuv data without gbm
In my environment, the front end plays the YUV format video abnormally.
After analysis, it is found that because the backend cannot use GBM, the aux_plane_egl_image
member in the vrend_resource
corresponding to YUV is not created.
The front-end YUV sampler samplerExternalOES
will be converted into a new fragment shader in mesa. This new fragment shader will use the aux_plane_egl_image
member of vrend_resource
as input to calculate rgb.
So I added a new interface virgl_renderer_resource_create_panel
to assign eglimage to the aux_plane_egl_image
member of vrend_resource
.This interface is called after successfully creating a resource using virgl_renderer_resource_create
.
In this way, aux_plane_egl_image
can be used to implement YUV sampling in vrend_create_sampler_view
.
I want to ask if I can combine the virgl_renderer_resource_create_panel
function into the library
The following code is my implementation on 0.8.2
diff --git a/src/vrend_decode.c b/src/vrend_decode.c
index faf2ced..ff533f6 100644
--- a/src/vrend_decode.c
+++ b/src/vrend_decode.c
@@ -2182,7 +2211,7 @@ int vrend_create_sampler_view(struct vrend_context *ctx,
view->srgb_decode);
}
glBindTexture(view->target, 0);
- } else if (needs_view && view->val0 < ARRAY_SIZE(res->aux_plane_egl_image) &&
+ } else if ((needs_view || res->force_panel) && view->val0 < ARRAY_SIZE(res->aux_plane_egl_image) &&
res->aux_plane_egl_image[view->val0]) {
void *image = res->aux_plane_egl_image[view->val0];
glGenTextures(1, &view->id);
diff --git a/src/virglrenderer.c b/src/virglrenderer.c
index 8458b21..0f23e19 100644
--- a/src/virglrenderer.c
+++ b/src/virglrenderer.c
@@ -104,6 +104,21 @@ int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *a
return virgl_renderer_resource_create_internal(args, iov, num_iovs, NULL);
}
+int virgl_renderer_resource_create_panel(uint32_t res_handle, int panel, void *image)
+{
+ struct virgl_resource *res = virgl_resource_lookup(res_handle);
+ struct vrend_resource *gr = NULL;
+
+ if (!res || panel >= VIRGL_GBM_MAX_PLANES)
+ return -1;
+
+ gr = (struct vrend_resource *)res->pipe_resource;
+ gr->aux_plane_egl_image[panel] = image;
+ gr->force_panel = true;
+
+ return 0;
+}
+
diff --git a/src/virglrenderer.h b/src/virglrenderer.h
index e7592a8..8931aae 100644
--- a/src/virglrenderer.h
+++ b/src/virglrenderer.h
@@ -175,6 +175,7 @@ struct virgl_renderer_supported_structures {
typedef void (*virgl_debug_callback_type)(const char *fmt, va_list ap);
VIRGL_EXPORT int virgl_renderer_resource_create(struct virgl_renderer_resource_create_args *args, struct iovec *iov, uint32_t num_iovs);
+VIRGL_EXPORT int virgl_renderer_resource_create_panel(uint32_t res_handle, int panel, void *image);
VIRGL_EXPORT int virgl_renderer_resource_import_eglimage(struct virgl_renderer_resource_create_args *args, void *image);
VIRGL_EXPORT void virgl_renderer_resource_unref(uint32_t res_handle);
diff --git a/src/vrend_debug.c b/src/vrend_debug.c
diff --git a/src/vrend_renderer.h b/src/vrend_renderer.h
index da4ffe9..8ccf89c 100644
--- a/src/vrend_renderer.h
+++ b/src/vrend_renderer.h
@@ -88,6 +88,7 @@ struct vrend_resource {
uint64_t mipmap_offsets[VR_MAX_TEXTURE_2D_LEVELS];
void *gbm_bo, *egl_image;
void *aux_plane_egl_image[VIRGL_GBM_MAX_PLANES];
+ bool force_panel;
uint64_t size;
GLbitfield buffer_storage_flags;