From bf6a415841a79ed52fa6b76cd40f75417488dfb7 Mon Sep 17 00:00:00 2001 From: Sil Vilerino Date: Thu, 3 Aug 2023 10:49:23 -0400 Subject: [PATCH] frontend/va: Support media only post proc without compositor using shaders or surfaces Reviewed-by: Thong Thai Reviewed-by: Jesse Natalie Part-of: --- src/gallium/auxiliary/util/u_inlines.h | 5 ++++- src/gallium/auxiliary/vl/vl_compositor.c | 18 ++++++++-------- src/gallium/frontends/va/context.c | 26 ++++++++++++++++-------- src/gallium/frontends/va/postproc.c | 7 +++++++ src/gallium/frontends/va/surface.c | 24 ++++++++++++---------- src/gallium/include/pipe/p_defines.h | 10 +++++++++ 6 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h index 6db4350214c..5aba9db49d7 100644 --- a/src/gallium/auxiliary/util/u_inlines.h +++ b/src/gallium/auxiliary/util/u_inlines.h @@ -906,7 +906,10 @@ pipe_create_multimedia_context(struct pipe_screen *screen) { unsigned flags = 0; - if (!screen->get_param(screen, PIPE_CAP_GRAPHICS)) + if (!screen->get_param(screen, PIPE_CAP_GRAPHICS) && + !screen->get_param(screen, PIPE_CAP_COMPUTE)) + flags |= PIPE_CONTEXT_MEDIA_ONLY; + else if (!screen->get_param(screen, PIPE_CAP_GRAPHICS)) flags |= PIPE_CONTEXT_COMPUTE_ONLY; return screen->context_create(screen, NULL, flags); diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c index 658a87adb14..5094fbf0864 100644 --- a/src/gallium/auxiliary/vl/vl_compositor.c +++ b/src/gallium/auxiliary/vl/vl_compositor.c @@ -148,13 +148,13 @@ init_pipe_state(struct vl_compositor *c) sampler.compare_mode = PIPE_TEX_COMPARE_NONE; sampler.compare_func = PIPE_FUNC_ALWAYS; - c->sampler_linear = c->pipe->create_sampler_state(c->pipe, &sampler); - - sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; - sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; - c->sampler_nearest = c->pipe->create_sampler_state(c->pipe, &sampler); - if (c->pipe_gfx_supported) { + c->sampler_linear = c->pipe->create_sampler_state(c->pipe, &sampler); + + sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + c->sampler_nearest = c->pipe->create_sampler_state(c->pipe, &sampler); + memset(&blend, 0, sizeof blend); blend.independent_blend_enable = 0; blend.rt[0].blend_enable = 0; @@ -228,8 +228,10 @@ static void cleanup_pipe_state(struct vl_compositor *c) c->pipe->delete_blend_state(c->pipe, c->blend_add); c->pipe->delete_rasterizer_state(c->pipe, c->rast); } - c->pipe->delete_sampler_state(c->pipe, c->sampler_linear); - c->pipe->delete_sampler_state(c->pipe, c->sampler_nearest); + if (c->sampler_linear) + c->pipe->delete_sampler_state(c->pipe, c->sampler_linear); + if (c->sampler_nearest) + c->pipe->delete_sampler_state(c->pipe, c->sampler_nearest); } static bool diff --git a/src/gallium/frontends/va/context.c b/src/gallium/frontends/va/context.c index f33fcf733dd..d1281d58dd5 100644 --- a/src/gallium/frontends/va/context.c +++ b/src/gallium/frontends/va/context.c @@ -188,14 +188,20 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx) if (!drv->htab) goto error_htab; - if (!vl_compositor_init(&drv->compositor, drv->pipe)) - goto error_compositor; - if (!vl_compositor_init_state(&drv->cstate, drv->pipe)) - goto error_compositor_state; + bool can_init_compositor = (drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_GRAPHICS) || + drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_COMPUTE)); + + if (can_init_compositor) { + if (!vl_compositor_init(&drv->compositor, drv->pipe)) + goto error_compositor; + if (!vl_compositor_init_state(&drv->cstate, drv->pipe)) + goto error_compositor_state; + + vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc); + if (!vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc, 1.0f, 0.0f)) + goto error_csc_matrix; + } - vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_BT_601, NULL, true, &drv->csc); - if (!vl_compositor_set_csc_matrix(&drv->cstate, (const vl_csc_matrix *)&drv->csc, 1.0f, 0.0f)) - goto error_csc_matrix; (void) mtx_init(&drv->mutex, mtx_plain); ctx->pDriverData = (void *)drv; @@ -218,10 +224,12 @@ VA_DRIVER_INIT_FUNC(VADriverContextP ctx) return VA_STATUS_SUCCESS; error_csc_matrix: - vl_compositor_cleanup_state(&drv->cstate); + if (can_init_compositor) + vl_compositor_cleanup_state(&drv->cstate); error_compositor_state: - vl_compositor_cleanup(&drv->compositor); + if (can_init_compositor) + vl_compositor_cleanup(&drv->compositor); error_compositor: handle_table_destroy(drv->htab); diff --git a/src/gallium/frontends/va/postproc.c b/src/gallium/frontends/va/postproc.c index b43f0dff1d0..ac963906af0 100644 --- a/src/gallium/frontends/va/postproc.c +++ b/src/gallium/frontends/va/postproc.c @@ -690,6 +690,13 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex return VA_STATUS_SUCCESS; } + /* Some devices may be media only (PIPE_VIDEO_ENTRYPOINT_PROCESSING with video engine) + * and won't have shader support + */ + if (!drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_GRAPHICS) && + !drv->vscreen->pscreen->get_param(drv->vscreen->pscreen, PIPE_CAP_COMPUTE)) + return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; + vlVaSetProcParameters(drv, src_surface, dst_surface, param); /* Try other post proc implementations */ diff --git a/src/gallium/frontends/va/surface.c b/src/gallium/frontends/va/surface.c index f40c0af231a..0f92246c2f6 100644 --- a/src/gallium/frontends/va/surface.c +++ b/src/gallium/frontends/va/surface.c @@ -1029,21 +1029,23 @@ vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface, return VA_STATUS_ERROR_ALLOCATION_FAILED; surfaces = surface->buffer->get_surfaces(surface->buffer); - for (i = 0; i < VL_MAX_SURFACES; ++i) { - union pipe_color_union c; - memset(&c, 0, sizeof(c)); + if (surfaces) { + for (i = 0; i < VL_MAX_SURFACES; ++i) { + union pipe_color_union c; + memset(&c, 0, sizeof(c)); - if (!surfaces[i]) - continue; + if (!surfaces[i]) + continue; - if (i > !!surface->buffer->interlaced) - c.f[0] = c.f[1] = c.f[2] = c.f[3] = 0.5f; + if (i > !!surface->buffer->interlaced) + c.f[0] = c.f[1] = c.f[2] = c.f[3] = 0.5f; - drv->pipe->clear_render_target(drv->pipe, surfaces[i], &c, 0, 0, - surfaces[i]->width, surfaces[i]->height, - false); + drv->pipe->clear_render_target(drv->pipe, surfaces[i], &c, 0, 0, + surfaces[i]->width, surfaces[i]->height, + false); + } + drv->pipe->flush(drv->pipe, NULL, 0); } - drv->pipe->flush(drv->pipe, NULL, 0); return VA_STATUS_SUCCESS; } diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index ee6d894a65a..05917e53aa4 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -403,6 +403,16 @@ enum pipe_flush_flags */ #define PIPE_CONTEXT_NO_LOD_BIAS (1 << 8) +/** + * Create a media-only context. Use in pipe_screen::context_create. + * This disables draw, blit, and clear*, render_condition, and other graphics. + * This also disabled all compute related functions + * functions. Interop with other media contexts is still allowed. + * This allows scheduling jobs on a media-only hardware command queue that + * can run in parallel with media without stalling it. + */ +#define PIPE_CONTEXT_MEDIA_ONLY (1 << 9) + /** * Flags for pipe_context::memory_barrier. */