frontends/va: Allocate surface buffers on demand

This saves memory by not allocating encode DPB surface buffers which
are currently not used by drivers.

Reviewed-By: Sil Vilerino <sivileri@microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30843>
This commit is contained in:
David Rosca
2024-07-22 15:38:50 +02:00
committed by Marge Bot
parent de61cb72fe
commit 64ca0fd2f2
5 changed files with 36 additions and 14 deletions

View File

@@ -286,7 +286,7 @@ vlVaDeriveImage(VADriverContextP ctx, VASurfaceID surface, VAImage *image)
return VA_STATUS_ERROR_INVALID_CONTEXT;
surf = handle_table_get(drv->htab, surface);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;
@@ -538,6 +538,7 @@ vlVaGetImage(VADriverContextP ctx, VASurfaceID surface, int x, int y,
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, surface);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
@@ -679,6 +680,7 @@ vlVaPutImage(VADriverContextP ctx, VASurfaceID surface, VAImageID image,
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, surface);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;

View File

@@ -97,6 +97,7 @@ vlVaBeginPicture(VADriverContextP ctx, VAContextID context_id, VASurfaceID rende
}
surf = handle_table_get(drv->htab, render_target);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
@@ -174,7 +175,7 @@ vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id,
{
vlVaSurface *surf = handle_table_get(drv->htab, surface_id);
if (surf)
*ref_frame = surf->buffer;
*ref_frame = vlVaGetSurfaceBuffer(drv, surf);
else
*ref_frame = NULL;
}
@@ -1161,6 +1162,7 @@ vlVaEndPicture(VADriverContextP ctx, VAContextID context_id)
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, output_id);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;

View File

@@ -551,6 +551,8 @@ vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *contex
dst_surface = handle_table_get(drv->htab, context->target_id);
if (!src_surface || !dst_surface)
return VA_STATUS_ERROR_INVALID_SURFACE;
vlVaGetSurfaceBuffer(drv, src_surface);
vlVaGetSurfaceBuffer(drv, dst_surface);
if (!src_surface->buffer || !dst_surface->buffer)
return VA_STATUS_ERROR_INVALID_SURFACE;

View File

@@ -155,8 +155,7 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, render_target);
if (!surf || !surf->buffer) {
if (!surf) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
}
@@ -167,7 +166,7 @@ _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeo
* Some apps try to sync/map the surface right after creation and
* would get VA_STATUS_ERROR_INVALID_CONTEXT
*/
if ((!surf->feedback) && (!surf->fence)) {
if (!surf->buffer || (!surf->feedback && !surf->fence)) {
// No outstanding encode/decode operation: nothing to do.
mtx_unlock(&drv->mutex);
return VA_STATUS_SUCCESS;
@@ -271,7 +270,7 @@ vlVaQuerySurfaceStatus(VADriverContextP ctx, VASurfaceID render_target, VASurfac
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, render_target);
if (!surf || !surf->buffer) {
if (!surf) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
}
@@ -282,7 +281,7 @@ vlVaQuerySurfaceStatus(VADriverContextP ctx, VASurfaceID render_target, VASurfac
* Some apps try to sync/map the surface right after creation and
* would get VA_STATUS_ERROR_INVALID_CONTEXT
*/
if ((!surf->feedback) && (!surf->fence)) {
if (!surf->buffer || (!surf->feedback && !surf->fence)) {
// No outstanding encode/decode operation: nothing to do.
*status = VASurfaceReady;
mtx_unlock(&drv->mutex);
@@ -485,7 +484,8 @@ vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short s
drv = VL_VA_DRIVER(ctx);
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, surface_id);
if (!surf) {
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;
}
@@ -1111,6 +1111,17 @@ vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface,
return VA_STATUS_SUCCESS;
}
struct pipe_video_buffer *
vlVaGetSurfaceBuffer(vlVaDriver *drv, vlVaSurface *surface)
{
if (!surface)
return NULL;
if (surface->buffer)
return surface->buffer;
vlVaHandleSurfaceAllocate(drv, surface, &surface->templat, NULL, 0);
return surface->buffer;
}
VAStatus
vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
unsigned int width, unsigned int height,
@@ -1325,12 +1336,14 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
*/
if (memory_attribute &&
!(memory_attribute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
templat.bind = PIPE_BIND_LINEAR | PIPE_BIND_SHARED;
surf->templat.bind = PIPE_BIND_LINEAR | PIPE_BIND_SHARED;
vaStatus = vlVaHandleSurfaceAllocate(drv, surf, &templat, modifiers,
modifiers_count);
if (vaStatus != VA_STATUS_SUCCESS)
goto free_surf;
if (modifiers) {
vaStatus = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, modifiers,
modifiers_count);
if (vaStatus != VA_STATUS_SUCCESS)
goto free_surf;
} /* Delayed allocation from vlVaGetSurfaceBuffer otherwise */
break;
#ifdef _WIN32
@@ -1372,7 +1385,8 @@ vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
return VA_STATUS_SUCCESS;
destroy_surf:
surf->buffer->destroy(surf->buffer);
if (surf->buffer)
surf->buffer->destroy(surf->buffer);
free_surf:
FREE(surf);
@@ -1644,6 +1658,7 @@ vlVaExportSurfaceHandle(VADriverContextP ctx,
mtx_lock(&drv->mutex);
surf = handle_table_get(drv->htab, surface_id);
vlVaGetSurfaceBuffer(drv, surf);
if (!surf || !surf->buffer) {
mtx_unlock(&drv->mutex);
return VA_STATUS_ERROR_INVALID_SURFACE;

View File

@@ -564,6 +564,7 @@ VAStatus vlVaMapBuffer2(VADriverContextP ctx, VABufferID buf_id, void **pbuf, ui
VAStatus vlVaHandleVAProcPipelineParameterBufferType(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);
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 vlVaSetSurfaceContext(vlVaDriver *drv, vlVaSurface *surf, vlVaContext *context);
void vlVaGetReferenceFrame(vlVaDriver *drv, VASurfaceID surface_id, struct pipe_video_buffer **ref_frame);
void vlVaHandlePictureParameterBufferMPEG12(vlVaDriver *drv, vlVaContext *context, vlVaBuffer *buf);