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:
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user