mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
frontends/va: Add surface pipe_fence for vl_compositor rendering
Wait on it in SyncSurface. Fixes sync issues when using surfaces from processing context (shader path) in external APIs (eg. Vulkan interop). Reviewed-by: Ruijing Dong <ruijing.dong@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33165>
This commit is contained in:
parent
d4a6a22ef4
commit
0f20a3a4f1
4 changed files with 31 additions and 9 deletions
|
|
@ -548,6 +548,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
|
|||
ret = vlVaPostProcCompositor(drv, &src_rect, &dst_rect,
|
||||
surf->buffer, tmp_surf.buffer,
|
||||
VL_COMPOSITOR_NONE, &proc);
|
||||
drv->pipe->flush(drv->pipe, NULL, 0);
|
||||
if (ret != VA_STATUS_SUCCESS) {
|
||||
tmp_surf.buffer->destroy(tmp_surf.buffer);
|
||||
mtx_unlock(&drv->mutex);
|
||||
|
|
@ -715,14 +716,14 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
|
|||
ret = vlVaPostProcCompositor(drv, &src_rect, &dst_rect,
|
||||
tmp_surf.buffer, surf->buffer,
|
||||
VL_COMPOSITOR_NONE, &proc);
|
||||
vlVaSurfaceFlush(drv, surf);
|
||||
tmp_surf.buffer->destroy(tmp_surf.buffer);
|
||||
mtx_unlock(&drv->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vlVaUploadImage(drv, surf, img_buf, vaimage);
|
||||
|
||||
drv->pipe->flush(drv->pipe, NULL, 0);
|
||||
vlVaSurfaceFlush(drv, surf);
|
||||
mtx_unlock(&drv->mutex);
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
|
|
|
|||
|
|
@ -232,7 +232,6 @@ vlVaPostProcCompositor(vlVaDriver *drv,
|
|||
|
||||
drv->cstate.chroma_location = VL_COMPOSITOR_LOCATION_NONE;
|
||||
|
||||
drv->pipe->flush(drv->pipe, NULL, 0);
|
||||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
@ -572,6 +571,8 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
|
|||
return VA_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return vlVaPostProcCompositor(drv, src_region, dst_region,
|
||||
src, context->target, deinterlace, param);
|
||||
VAStatus ret = vlVaPostProcCompositor(drv, src_region, dst_region,
|
||||
src, context->target, deinterlace, param);
|
||||
vlVaSurfaceFlush(drv, dst_surface);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,6 +119,8 @@ vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_sur
|
|||
}
|
||||
if (surf->buffer)
|
||||
surf->buffer->destroy(surf->buffer);
|
||||
if (surf->pipe_fence)
|
||||
drv->pipe->screen->fence_reference(drv->pipe->screen, &surf->pipe_fence, NULL);
|
||||
if (surf->ctx) {
|
||||
assert(_mesa_set_search(surf->ctx->surfaces, surf));
|
||||
_mesa_set_remove_key(surf->ctx->surfaces, surf);
|
||||
|
|
@ -176,13 +178,22 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
|
|||
fence = surf->fence;
|
||||
}
|
||||
|
||||
if (surf->pipe_fence) {
|
||||
struct pipe_screen *pscreen = drv->pipe->screen;
|
||||
if (!pscreen->fence_finish(pscreen, NULL, surf->pipe_fence, timeout_ns)) {
|
||||
mtx_unlock(&drv->mutex);
|
||||
return VA_STATUS_ERROR_TIMEDOUT;
|
||||
}
|
||||
pscreen->fence_reference(pscreen, &surf->pipe_fence, NULL);
|
||||
}
|
||||
|
||||
/* This is checked before getting the context below as
|
||||
* surf->ctx is only set in begin_frame
|
||||
* and not when the surface is created
|
||||
* Some apps try to sync/map the surface right after creation and
|
||||
* would get VA_STATUS_ERROR_INVALID_CONTEXT
|
||||
*/
|
||||
if (!surf->buffer || !fence) {
|
||||
if (!surf->fence) {
|
||||
// No outstanding encode/decode operation: nothing to do.
|
||||
mtx_unlock(&drv->mutex);
|
||||
return VA_STATUS_SUCCESS;
|
||||
|
|
@ -441,7 +452,7 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
|
|||
/* flush before calling flush_frontbuffer so that rendering is flushed
|
||||
* to back buffer so the texture can be copied in flush_frontbuffer
|
||||
*/
|
||||
drv->pipe->flush(drv->pipe, NULL, 0);
|
||||
vlVaSurfaceFlush(drv, surf);
|
||||
|
||||
screen->flush_frontbuffer(screen, drv->pipe, tex, 0, 0,
|
||||
vscreen->get_private(vscreen), 0, NULL);
|
||||
|
|
@ -996,7 +1007,7 @@ vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface,
|
|||
surfaces[i]->width, surfaces[i]->height,
|
||||
false);
|
||||
}
|
||||
drv->pipe->flush(drv->pipe, NULL, 0);
|
||||
vlVaSurfaceFlush(drv, surface);
|
||||
}
|
||||
|
||||
return VA_STATUS_SUCCESS;
|
||||
|
|
@ -1013,6 +1024,13 @@ vlVaGetSurfaceBuffer(vlVaDriver *drv, vlVaSurface *surface)
|
|||
return surface->buffer;
|
||||
}
|
||||
|
||||
void
|
||||
vlVaSurfaceFlush(vlVaDriver *drv, vlVaSurface *surf)
|
||||
{
|
||||
drv->pipe->flush(drv->pipe, &surf->pipe_fence,
|
||||
drv->has_external_handles ? 0 : PIPE_FLUSH_ASYNC);
|
||||
}
|
||||
|
||||
static int
|
||||
rt_format_to_fourcc(uint32_t format)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -448,7 +448,8 @@ typedef struct vlVaSurface {
|
|||
vlVaContext *ctx;
|
||||
vlVaBuffer *coded_buf;
|
||||
bool full_range;
|
||||
struct pipe_fence_handle *fence;
|
||||
struct pipe_fence_handle *fence; /* pipe_video_codec fence */
|
||||
struct pipe_fence_handle *pipe_fence; /* pipe_context fence */
|
||||
struct vlVaSurface *efc_surface; /* input surface for EFC */
|
||||
bool is_dpb;
|
||||
} vlVaSurface;
|
||||
|
|
@ -569,6 +570,7 @@ VAStatus vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContex
|
|||
VAStatus vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface, struct pipe_video_buffer *templat,
|
||||
const uint64_t *modifiers, unsigned int modifiers_count);
|
||||
struct pipe_video_buffer *vlVaGetSurfaceBuffer(vlVaDriver *drv, vlVaSurface *surface);
|
||||
void vlVaSurfaceFlush(vlVaDriver *drv, vlVaSurface *surf);
|
||||
void vlVaAddRawHeader(struct util_dynarray *headers, uint8_t type, uint32_t size, uint8_t *buf,
|
||||
bool is_slice, uint32_t emulation_bytes_start);
|
||||
void vlVaGetBufferFeedback(vlVaBuffer *buf);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue