xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/va/surface.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /**************************************************************************
2*61046927SAndroid Build Coastguard Worker  *
3*61046927SAndroid Build Coastguard Worker  * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4*61046927SAndroid Build Coastguard Worker  * Copyright 2014 Advanced Micro Devices, Inc.
5*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the
9*61046927SAndroid Build Coastguard Worker  * "Software"), to deal in the Software without restriction, including
10*61046927SAndroid Build Coastguard Worker  * without limitation the rights to use, copy, modify, merge, publish,
11*61046927SAndroid Build Coastguard Worker  * distribute, sub license, and/or sell copies of the Software, and to
12*61046927SAndroid Build Coastguard Worker  * permit persons to whom the Software is furnished to do so, subject to
13*61046927SAndroid Build Coastguard Worker  * the following conditions:
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the
16*61046927SAndroid Build Coastguard Worker  * next paragraph) shall be included in all copies or substantial portions
17*61046927SAndroid Build Coastguard Worker  * of the Software.
18*61046927SAndroid Build Coastguard Worker  *
19*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*61046927SAndroid Build Coastguard Worker  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*61046927SAndroid Build Coastguard Worker  * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23*61046927SAndroid Build Coastguard Worker  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*61046927SAndroid Build Coastguard Worker  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*61046927SAndroid Build Coastguard Worker  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*61046927SAndroid Build Coastguard Worker  *
27*61046927SAndroid Build Coastguard Worker  **************************************************************************/
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker #include "pipe/p_screen.h"
30*61046927SAndroid Build Coastguard Worker #include "pipe/p_video_codec.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include "util/u_memory.h"
33*61046927SAndroid Build Coastguard Worker #include "util/u_handle_table.h"
34*61046927SAndroid Build Coastguard Worker #include "util/u_rect.h"
35*61046927SAndroid Build Coastguard Worker #include "util/u_sampler.h"
36*61046927SAndroid Build Coastguard Worker #include "util/u_surface.h"
37*61046927SAndroid Build Coastguard Worker #include "util/u_video.h"
38*61046927SAndroid Build Coastguard Worker #include "util/set.h"
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker #include "vl/vl_compositor.h"
41*61046927SAndroid Build Coastguard Worker #include "vl/vl_video_buffer.h"
42*61046927SAndroid Build Coastguard Worker #include "vl/vl_winsys.h"
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker #include "va_private.h"
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
47*61046927SAndroid Build Coastguard Worker #include "frontend/winsys_handle.h"
48*61046927SAndroid Build Coastguard Worker #include <va/va_win32.h>
49*61046927SAndroid Build Coastguard Worker #else
50*61046927SAndroid Build Coastguard Worker #include "frontend/drm_driver.h"
51*61046927SAndroid Build Coastguard Worker #include <va/va_drmcommon.h>
52*61046927SAndroid Build Coastguard Worker #include "drm-uapi/drm_fourcc.h"
53*61046927SAndroid Build Coastguard Worker #endif
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker static const enum pipe_format vpp_surface_formats[] = {
56*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_B8G8R8A8_UNORM, PIPE_FORMAT_R8G8B8A8_UNORM,
57*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_B8G8R8X8_UNORM, PIPE_FORMAT_R8G8B8X8_UNORM,
58*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_B10G10R10A2_UNORM, PIPE_FORMAT_R10G10B10A2_UNORM,
59*61046927SAndroid Build Coastguard Worker    PIPE_FORMAT_B10G10R10X2_UNORM, PIPE_FORMAT_R10G10B10X2_UNORM
60*61046927SAndroid Build Coastguard Worker };
61*61046927SAndroid Build Coastguard Worker 
62*61046927SAndroid Build Coastguard Worker VAStatus
vlVaCreateSurfaces(VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID * surfaces)63*61046927SAndroid Build Coastguard Worker vlVaCreateSurfaces(VADriverContextP ctx, int width, int height, int format,
64*61046927SAndroid Build Coastguard Worker                    int num_surfaces, VASurfaceID *surfaces)
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker    return vlVaCreateSurfaces2(ctx, format, width, height, surfaces, num_surfaces,
67*61046927SAndroid Build Coastguard Worker                               NULL, 0);
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker static void
vlVaRemoveDpbSurface(vlVaSurface * surf,VASurfaceID id)71*61046927SAndroid Build Coastguard Worker vlVaRemoveDpbSurface(vlVaSurface *surf, VASurfaceID id)
72*61046927SAndroid Build Coastguard Worker {
73*61046927SAndroid Build Coastguard Worker    assert(surf->ctx->templat.entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE);
74*61046927SAndroid Build Coastguard Worker 
75*61046927SAndroid Build Coastguard Worker    switch (u_reduce_video_profile(surf->ctx->templat.profile)) {
76*61046927SAndroid Build Coastguard Worker    case PIPE_VIDEO_FORMAT_MPEG4_AVC:
77*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < surf->ctx->desc.h264enc.dpb_size; i++) {
78*61046927SAndroid Build Coastguard Worker          if (surf->ctx->desc.h264enc.dpb[i].id == id) {
79*61046927SAndroid Build Coastguard Worker             memset(&surf->ctx->desc.h264enc.dpb[i], 0, sizeof(surf->ctx->desc.h264enc.dpb[i]));
80*61046927SAndroid Build Coastguard Worker             break;
81*61046927SAndroid Build Coastguard Worker          }
82*61046927SAndroid Build Coastguard Worker       }
83*61046927SAndroid Build Coastguard Worker       break;
84*61046927SAndroid Build Coastguard Worker    case PIPE_VIDEO_FORMAT_HEVC:
85*61046927SAndroid Build Coastguard Worker       for (unsigned i = 0; i < surf->ctx->desc.h265enc.dpb_size; i++) {
86*61046927SAndroid Build Coastguard Worker          if (surf->ctx->desc.h265enc.dpb[i].id == id) {
87*61046927SAndroid Build Coastguard Worker             memset(&surf->ctx->desc.h265enc.dpb[i], 0, sizeof(surf->ctx->desc.h265enc.dpb[i]));
88*61046927SAndroid Build Coastguard Worker             break;
89*61046927SAndroid Build Coastguard Worker          }
90*61046927SAndroid Build Coastguard Worker       }
91*61046927SAndroid Build Coastguard Worker       break;
92*61046927SAndroid Build Coastguard Worker    default:
93*61046927SAndroid Build Coastguard Worker       assert(false);
94*61046927SAndroid Build Coastguard Worker       break;
95*61046927SAndroid Build Coastguard Worker    }
96*61046927SAndroid Build Coastguard Worker }
97*61046927SAndroid Build Coastguard Worker 
98*61046927SAndroid Build Coastguard Worker VAStatus
vlVaDestroySurfaces(VADriverContextP ctx,VASurfaceID * surface_list,int num_surfaces)99*61046927SAndroid Build Coastguard Worker vlVaDestroySurfaces(VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces)
100*61046927SAndroid Build Coastguard Worker {
101*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
102*61046927SAndroid Build Coastguard Worker    int i;
103*61046927SAndroid Build Coastguard Worker 
104*61046927SAndroid Build Coastguard Worker    if (!ctx)
105*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
108*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
109*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_surfaces; ++i) {
110*61046927SAndroid Build Coastguard Worker       vlVaSurface *surf = handle_table_get(drv->htab, surface_list[i]);
111*61046927SAndroid Build Coastguard Worker       if (!surf) {
112*61046927SAndroid Build Coastguard Worker          mtx_unlock(&drv->mutex);
113*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_SURFACE;
114*61046927SAndroid Build Coastguard Worker       }
115*61046927SAndroid Build Coastguard Worker       if (surf->buffer)
116*61046927SAndroid Build Coastguard Worker          surf->buffer->destroy(surf->buffer);
117*61046927SAndroid Build Coastguard Worker       if (surf->ctx) {
118*61046927SAndroid Build Coastguard Worker          assert(_mesa_set_search(surf->ctx->surfaces, surf));
119*61046927SAndroid Build Coastguard Worker          _mesa_set_remove_key(surf->ctx->surfaces, surf);
120*61046927SAndroid Build Coastguard Worker          if (surf->fence && surf->ctx->decoder && surf->ctx->decoder->destroy_fence)
121*61046927SAndroid Build Coastguard Worker             surf->ctx->decoder->destroy_fence(surf->ctx->decoder, surf->fence);
122*61046927SAndroid Build Coastguard Worker          if (surf->is_dpb)
123*61046927SAndroid Build Coastguard Worker             vlVaRemoveDpbSurface(surf, surface_list[i]);
124*61046927SAndroid Build Coastguard Worker       }
125*61046927SAndroid Build Coastguard Worker       if (drv->last_efc_surface) {
126*61046927SAndroid Build Coastguard Worker          vlVaSurface *efc_surf = drv->last_efc_surface;
127*61046927SAndroid Build Coastguard Worker          if (efc_surf == surf || efc_surf->efc_surface == surf) {
128*61046927SAndroid Build Coastguard Worker             efc_surf->efc_surface = NULL;
129*61046927SAndroid Build Coastguard Worker             drv->last_efc_surface = NULL;
130*61046927SAndroid Build Coastguard Worker             drv->efc_count = -1;
131*61046927SAndroid Build Coastguard Worker          }
132*61046927SAndroid Build Coastguard Worker       }
133*61046927SAndroid Build Coastguard Worker       util_dynarray_fini(&surf->subpics);
134*61046927SAndroid Build Coastguard Worker       FREE(surf);
135*61046927SAndroid Build Coastguard Worker       handle_table_remove(drv->htab, surface_list[i]);
136*61046927SAndroid Build Coastguard Worker    }
137*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
138*61046927SAndroid Build Coastguard Worker 
139*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker static VAStatus
_vlVaSyncSurface(VADriverContextP ctx,VASurfaceID render_target,uint64_t timeout_ns)143*61046927SAndroid Build Coastguard Worker _vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target, uint64_t timeout_ns)
144*61046927SAndroid Build Coastguard Worker {
145*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
146*61046927SAndroid Build Coastguard Worker    vlVaContext *context;
147*61046927SAndroid Build Coastguard Worker    vlVaSurface *surf;
148*61046927SAndroid Build Coastguard Worker 
149*61046927SAndroid Build Coastguard Worker    if (!ctx)
150*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
151*61046927SAndroid Build Coastguard Worker 
152*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
153*61046927SAndroid Build Coastguard Worker    if (!drv)
154*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
157*61046927SAndroid Build Coastguard Worker    surf = handle_table_get(drv->htab, render_target);
158*61046927SAndroid Build Coastguard Worker    if (!surf) {
159*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
160*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
161*61046927SAndroid Build Coastguard Worker    }
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    /* This is checked before getting the context below as
164*61046927SAndroid Build Coastguard Worker     * surf->ctx is only set in begin_frame
165*61046927SAndroid Build Coastguard Worker     * and not when the surface is created
166*61046927SAndroid Build Coastguard Worker     * Some apps try to sync/map the surface right after creation and
167*61046927SAndroid Build Coastguard Worker     * would get VA_STATUS_ERROR_INVALID_CONTEXT
168*61046927SAndroid Build Coastguard Worker     */
169*61046927SAndroid Build Coastguard Worker    if (!surf->buffer || (!surf->feedback && !surf->fence)) {
170*61046927SAndroid Build Coastguard Worker       // No outstanding encode/decode operation: nothing to do.
171*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
172*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
173*61046927SAndroid Build Coastguard Worker    }
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    context = surf->ctx;
176*61046927SAndroid Build Coastguard Worker    if (!context) {
177*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
178*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
179*61046927SAndroid Build Coastguard Worker    }
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    if (!context->decoder) {
182*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
183*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
184*61046927SAndroid Build Coastguard Worker    }
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker    if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
187*61046927SAndroid Build Coastguard Worker       /* If driver does not implement get_processor_fence assume no
188*61046927SAndroid Build Coastguard Worker        * async work needed to be waited on and return success
189*61046927SAndroid Build Coastguard Worker        */
190*61046927SAndroid Build Coastguard Worker       int ret = (context->decoder->get_processor_fence) ? 0 : 1;
191*61046927SAndroid Build Coastguard Worker 
192*61046927SAndroid Build Coastguard Worker       if (context->decoder->get_processor_fence)
193*61046927SAndroid Build Coastguard Worker          ret = context->decoder->get_processor_fence(context->decoder,
194*61046927SAndroid Build Coastguard Worker                                                      surf->fence, timeout_ns);
195*61046927SAndroid Build Coastguard Worker 
196*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
197*61046927SAndroid Build Coastguard Worker       // Assume that the GPU has hung otherwise.
198*61046927SAndroid Build Coastguard Worker       return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT;
199*61046927SAndroid Build Coastguard Worker    } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
200*61046927SAndroid Build Coastguard Worker       int ret = 0;
201*61046927SAndroid Build Coastguard Worker 
202*61046927SAndroid Build Coastguard Worker       if (context->decoder->get_decoder_fence)
203*61046927SAndroid Build Coastguard Worker          ret = context->decoder->get_decoder_fence(context->decoder,
204*61046927SAndroid Build Coastguard Worker                                                    surf->fence, timeout_ns);
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
207*61046927SAndroid Build Coastguard Worker       // Assume that the GPU has hung otherwise.
208*61046927SAndroid Build Coastguard Worker       return ret ? VA_STATUS_SUCCESS : VA_STATUS_ERROR_TIMEDOUT;
209*61046927SAndroid Build Coastguard Worker    } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE && surf->feedback) {
210*61046927SAndroid Build Coastguard Worker       if (!drv->pipe->screen->get_video_param(drv->pipe->screen,
211*61046927SAndroid Build Coastguard Worker                               context->decoder->profile,
212*61046927SAndroid Build Coastguard Worker                               context->decoder->entrypoint,
213*61046927SAndroid Build Coastguard Worker                               PIPE_VIDEO_CAP_REQUIRES_FLUSH_ON_END_FRAME)) {
214*61046927SAndroid Build Coastguard Worker          if (u_reduce_video_profile(context->templat.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
215*61046927SAndroid Build Coastguard Worker             int frame_diff;
216*61046927SAndroid Build Coastguard Worker             if (context->desc.h264enc.frame_num_cnt >= surf->frame_num_cnt)
217*61046927SAndroid Build Coastguard Worker                frame_diff = context->desc.h264enc.frame_num_cnt - surf->frame_num_cnt;
218*61046927SAndroid Build Coastguard Worker             else
219*61046927SAndroid Build Coastguard Worker                frame_diff = 0xFFFFFFFF - surf->frame_num_cnt + 1 + context->desc.h264enc.frame_num_cnt;
220*61046927SAndroid Build Coastguard Worker             if ((frame_diff == 0) &&
221*61046927SAndroid Build Coastguard Worker                (surf->force_flushed == false) &&
222*61046927SAndroid Build Coastguard Worker                (context->desc.h264enc.frame_num_cnt % 2 != 0)) {
223*61046927SAndroid Build Coastguard Worker                context->decoder->flush(context->decoder);
224*61046927SAndroid Build Coastguard Worker                context->first_single_submitted = true;
225*61046927SAndroid Build Coastguard Worker             }
226*61046927SAndroid Build Coastguard Worker          }
227*61046927SAndroid Build Coastguard Worker       }
228*61046927SAndroid Build Coastguard Worker       if (context->decoder->get_feedback_fence &&
229*61046927SAndroid Build Coastguard Worker           !context->decoder->get_feedback_fence(context->decoder, surf->fence, timeout_ns)) {
230*61046927SAndroid Build Coastguard Worker          mtx_unlock(&drv->mutex);
231*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_TIMEDOUT;
232*61046927SAndroid Build Coastguard Worker       }
233*61046927SAndroid Build Coastguard Worker       context->decoder->get_feedback(context->decoder, surf->feedback, &(surf->coded_buf->coded_size), &(surf->coded_buf->extended_metadata));
234*61046927SAndroid Build Coastguard Worker       surf->feedback = NULL;
235*61046927SAndroid Build Coastguard Worker       surf->coded_buf->feedback = NULL;
236*61046927SAndroid Build Coastguard Worker       surf->coded_buf->associated_encode_input_surf = VA_INVALID_ID;
237*61046927SAndroid Build Coastguard Worker    }
238*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
239*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
240*61046927SAndroid Build Coastguard Worker }
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker VAStatus
vlVaSyncSurface(VADriverContextP ctx,VASurfaceID render_target)243*61046927SAndroid Build Coastguard Worker vlVaSyncSurface(VADriverContextP ctx, VASurfaceID render_target)
244*61046927SAndroid Build Coastguard Worker {
245*61046927SAndroid Build Coastguard Worker    return _vlVaSyncSurface(ctx, render_target, VA_TIMEOUT_INFINITE);
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker #if VA_CHECK_VERSION(1, 15, 0)
249*61046927SAndroid Build Coastguard Worker VAStatus
vlVaSyncSurface2(VADriverContextP ctx,VASurfaceID surface,uint64_t timeout_ns)250*61046927SAndroid Build Coastguard Worker vlVaSyncSurface2(VADriverContextP ctx, VASurfaceID surface, uint64_t timeout_ns)
251*61046927SAndroid Build Coastguard Worker {
252*61046927SAndroid Build Coastguard Worker    return _vlVaSyncSurface(ctx, surface, timeout_ns);
253*61046927SAndroid Build Coastguard Worker }
254*61046927SAndroid Build Coastguard Worker #endif
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQuerySurfaceStatus(VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus * status)257*61046927SAndroid Build Coastguard Worker vlVaQuerySurfaceStatus(VADriverContextP ctx, VASurfaceID render_target, VASurfaceStatus *status)
258*61046927SAndroid Build Coastguard Worker {
259*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
260*61046927SAndroid Build Coastguard Worker    vlVaSurface *surf;
261*61046927SAndroid Build Coastguard Worker    vlVaContext *context;
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker    if (!ctx)
264*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
267*61046927SAndroid Build Coastguard Worker    if (!drv)
268*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker    surf = handle_table_get(drv->htab, render_target);
273*61046927SAndroid Build Coastguard Worker    if (!surf) {
274*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
275*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
276*61046927SAndroid Build Coastguard Worker    }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker    /* This is checked before getting the context below as
279*61046927SAndroid Build Coastguard Worker     * surf->ctx is only set in begin_frame
280*61046927SAndroid Build Coastguard Worker     * and not when the surface is created
281*61046927SAndroid Build Coastguard Worker     * Some apps try to sync/map the surface right after creation and
282*61046927SAndroid Build Coastguard Worker     * would get VA_STATUS_ERROR_INVALID_CONTEXT
283*61046927SAndroid Build Coastguard Worker     */
284*61046927SAndroid Build Coastguard Worker    if (!surf->buffer || (!surf->feedback && !surf->fence)) {
285*61046927SAndroid Build Coastguard Worker       // No outstanding encode/decode operation: nothing to do.
286*61046927SAndroid Build Coastguard Worker       *status = VASurfaceReady;
287*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
288*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
289*61046927SAndroid Build Coastguard Worker    }
290*61046927SAndroid Build Coastguard Worker 
291*61046927SAndroid Build Coastguard Worker    context = surf->ctx;
292*61046927SAndroid Build Coastguard Worker    if (!context) {
293*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
294*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
295*61046927SAndroid Build Coastguard Worker    }
296*61046927SAndroid Build Coastguard Worker 
297*61046927SAndroid Build Coastguard Worker    if (!context->decoder) {
298*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
299*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
300*61046927SAndroid Build Coastguard Worker    }
301*61046927SAndroid Build Coastguard Worker 
302*61046927SAndroid Build Coastguard Worker    if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE) {
303*61046927SAndroid Build Coastguard Worker       if(surf->feedback == NULL)
304*61046927SAndroid Build Coastguard Worker          *status=VASurfaceReady;
305*61046927SAndroid Build Coastguard Worker       else
306*61046927SAndroid Build Coastguard Worker          *status=VASurfaceRendering;
307*61046927SAndroid Build Coastguard Worker    } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_BITSTREAM) {
308*61046927SAndroid Build Coastguard Worker       int ret = 0;
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker       if (context->decoder->get_decoder_fence)
311*61046927SAndroid Build Coastguard Worker          ret = context->decoder->get_decoder_fence(context->decoder,
312*61046927SAndroid Build Coastguard Worker                                                    surf->fence, 0);
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker       if (ret)
315*61046927SAndroid Build Coastguard Worker          *status = VASurfaceReady;
316*61046927SAndroid Build Coastguard Worker       else
317*61046927SAndroid Build Coastguard Worker       /* An approach could be to just tell the client that this is not
318*61046927SAndroid Build Coastguard Worker        * implemented, but this breaks other code.  Compromise by at least
319*61046927SAndroid Build Coastguard Worker        * conservatively setting the status to VASurfaceRendering if we can't
320*61046927SAndroid Build Coastguard Worker        * query the hardware.  Note that we _must_ set the status here, otherwise
321*61046927SAndroid Build Coastguard Worker        * it comes out of the function unchanged. As we are returning
322*61046927SAndroid Build Coastguard Worker        * VA_STATUS_SUCCESS, the client would be within his/her rights to use a
323*61046927SAndroid Build Coastguard Worker        * potentially uninitialized/invalid status value unknowingly.
324*61046927SAndroid Build Coastguard Worker        */
325*61046927SAndroid Build Coastguard Worker          *status = VASurfaceRendering;
326*61046927SAndroid Build Coastguard Worker    } else if (context->decoder->entrypoint == PIPE_VIDEO_ENTRYPOINT_PROCESSING) {
327*61046927SAndroid Build Coastguard Worker       /* If driver does not implement get_processor_fence assume no
328*61046927SAndroid Build Coastguard Worker        * async work needed to be waited on and return surface ready
329*61046927SAndroid Build Coastguard Worker        */
330*61046927SAndroid Build Coastguard Worker       int ret = (context->decoder->get_processor_fence) ? 0 : 1;
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker       if (context->decoder->get_processor_fence)
333*61046927SAndroid Build Coastguard Worker          ret = context->decoder->get_processor_fence(context->decoder,
334*61046927SAndroid Build Coastguard Worker                                                      surf->fence, 0);
335*61046927SAndroid Build Coastguard Worker       if (ret)
336*61046927SAndroid Build Coastguard Worker          *status = VASurfaceReady;
337*61046927SAndroid Build Coastguard Worker       else
338*61046927SAndroid Build Coastguard Worker          *status = VASurfaceRendering;
339*61046927SAndroid Build Coastguard Worker    }
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
344*61046927SAndroid Build Coastguard Worker }
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQuerySurfaceError(VADriverContextP ctx,VASurfaceID render_target,VAStatus error_status,void ** error_info)347*61046927SAndroid Build Coastguard Worker vlVaQuerySurfaceError(VADriverContextP ctx, VASurfaceID render_target, VAStatus error_status, void **error_info)
348*61046927SAndroid Build Coastguard Worker {
349*61046927SAndroid Build Coastguard Worker    if (!ctx)
350*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
351*61046927SAndroid Build Coastguard Worker 
352*61046927SAndroid Build Coastguard Worker    return VA_STATUS_ERROR_UNIMPLEMENTED;
353*61046927SAndroid Build Coastguard Worker }
354*61046927SAndroid Build Coastguard Worker 
355*61046927SAndroid Build Coastguard Worker static void
upload_sampler(struct pipe_context * pipe,struct pipe_sampler_view * dst,const struct pipe_box * dst_box,const void * src,unsigned src_stride,unsigned src_x,unsigned src_y)356*61046927SAndroid Build Coastguard Worker upload_sampler(struct pipe_context *pipe, struct pipe_sampler_view *dst,
357*61046927SAndroid Build Coastguard Worker                const struct pipe_box *dst_box, const void *src, unsigned src_stride,
358*61046927SAndroid Build Coastguard Worker                unsigned src_x, unsigned src_y)
359*61046927SAndroid Build Coastguard Worker {
360*61046927SAndroid Build Coastguard Worker    struct pipe_transfer *transfer;
361*61046927SAndroid Build Coastguard Worker    void *map;
362*61046927SAndroid Build Coastguard Worker 
363*61046927SAndroid Build Coastguard Worker    map = pipe->texture_map(pipe, dst->texture, 0, PIPE_MAP_WRITE,
364*61046927SAndroid Build Coastguard Worker                             dst_box, &transfer);
365*61046927SAndroid Build Coastguard Worker    if (!map)
366*61046927SAndroid Build Coastguard Worker       return;
367*61046927SAndroid Build Coastguard Worker 
368*61046927SAndroid Build Coastguard Worker    util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
369*61046927SAndroid Build Coastguard Worker                   dst_box->width, dst_box->height,
370*61046927SAndroid Build Coastguard Worker                   src, src_stride, src_x, src_y);
371*61046927SAndroid Build Coastguard Worker 
372*61046927SAndroid Build Coastguard Worker    pipe->texture_unmap(pipe, transfer);
373*61046927SAndroid Build Coastguard Worker }
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker static VAStatus
vlVaPutSubpictures(vlVaSurface * surf,vlVaDriver * drv,struct pipe_surface * surf_draw,struct u_rect * dirty_area,struct u_rect * src_rect,struct u_rect * dst_rect)376*61046927SAndroid Build Coastguard Worker vlVaPutSubpictures(vlVaSurface *surf, vlVaDriver *drv,
377*61046927SAndroid Build Coastguard Worker                    struct pipe_surface *surf_draw, struct u_rect *dirty_area,
378*61046927SAndroid Build Coastguard Worker                    struct u_rect *src_rect, struct u_rect *dst_rect)
379*61046927SAndroid Build Coastguard Worker {
380*61046927SAndroid Build Coastguard Worker    vlVaSubpicture *sub;
381*61046927SAndroid Build Coastguard Worker    int i;
382*61046927SAndroid Build Coastguard Worker 
383*61046927SAndroid Build Coastguard Worker    if (!(surf->subpics.data || surf->subpics.size))
384*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
385*61046927SAndroid Build Coastguard Worker 
386*61046927SAndroid Build Coastguard Worker    for (i = 0; i < surf->subpics.size/sizeof(vlVaSubpicture *); i++) {
387*61046927SAndroid Build Coastguard Worker       struct pipe_blend_state blend;
388*61046927SAndroid Build Coastguard Worker       void *blend_state;
389*61046927SAndroid Build Coastguard Worker       vlVaBuffer *buf;
390*61046927SAndroid Build Coastguard Worker       struct pipe_box box;
391*61046927SAndroid Build Coastguard Worker       struct u_rect *s, *d, sr, dr, c;
392*61046927SAndroid Build Coastguard Worker       int sw, sh, dw, dh;
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker       sub = ((vlVaSubpicture **)surf->subpics.data)[i];
395*61046927SAndroid Build Coastguard Worker       if (!sub)
396*61046927SAndroid Build Coastguard Worker          continue;
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker       buf = handle_table_get(drv->htab, sub->image->buf);
399*61046927SAndroid Build Coastguard Worker       if (!buf)
400*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_IMAGE;
401*61046927SAndroid Build Coastguard Worker 
402*61046927SAndroid Build Coastguard Worker       box.x = 0;
403*61046927SAndroid Build Coastguard Worker       box.y = 0;
404*61046927SAndroid Build Coastguard Worker       box.z = 0;
405*61046927SAndroid Build Coastguard Worker       box.width = sub->dst_rect.x1 - sub->dst_rect.x0;
406*61046927SAndroid Build Coastguard Worker       box.height = sub->dst_rect.y1 - sub->dst_rect.y0;
407*61046927SAndroid Build Coastguard Worker       box.depth = 1;
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker       s = &sub->src_rect;
410*61046927SAndroid Build Coastguard Worker       d = &sub->dst_rect;
411*61046927SAndroid Build Coastguard Worker       sw = s->x1 - s->x0;
412*61046927SAndroid Build Coastguard Worker       sh = s->y1 - s->y0;
413*61046927SAndroid Build Coastguard Worker       dw = d->x1 - d->x0;
414*61046927SAndroid Build Coastguard Worker       dh = d->y1 - d->y0;
415*61046927SAndroid Build Coastguard Worker       c.x0 = MAX2(d->x0, s->x0);
416*61046927SAndroid Build Coastguard Worker       c.y0 = MAX2(d->y0, s->y0);
417*61046927SAndroid Build Coastguard Worker       c.x1 = MIN2(d->x0 + dw, src_rect->x1);
418*61046927SAndroid Build Coastguard Worker       c.y1 = MIN2(d->y0 + dh, src_rect->y1);
419*61046927SAndroid Build Coastguard Worker       sr.x0 = s->x0 + (c.x0 - d->x0)*(sw/(float)dw);
420*61046927SAndroid Build Coastguard Worker       sr.y0 = s->y0 + (c.y0 - d->y0)*(sh/(float)dh);
421*61046927SAndroid Build Coastguard Worker       sr.x1 = s->x0 + (c.x1 - d->x0)*(sw/(float)dw);
422*61046927SAndroid Build Coastguard Worker       sr.y1 = s->y0 + (c.y1 - d->y0)*(sh/(float)dh);
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker       s = src_rect;
425*61046927SAndroid Build Coastguard Worker       d = dst_rect;
426*61046927SAndroid Build Coastguard Worker       sw = s->x1 - s->x0;
427*61046927SAndroid Build Coastguard Worker       sh = s->y1 - s->y0;
428*61046927SAndroid Build Coastguard Worker       dw = d->x1 - d->x0;
429*61046927SAndroid Build Coastguard Worker       dh = d->y1 - d->y0;
430*61046927SAndroid Build Coastguard Worker       dr.x0 = d->x0 + c.x0*(dw/(float)sw);
431*61046927SAndroid Build Coastguard Worker       dr.y0 = d->y0 + c.y0*(dh/(float)sh);
432*61046927SAndroid Build Coastguard Worker       dr.x1 = d->x0 + c.x1*(dw/(float)sw);
433*61046927SAndroid Build Coastguard Worker       dr.y1 = d->y0 + c.y1*(dh/(float)sh);
434*61046927SAndroid Build Coastguard Worker 
435*61046927SAndroid Build Coastguard Worker       memset(&blend, 0, sizeof(blend));
436*61046927SAndroid Build Coastguard Worker       blend.independent_blend_enable = 0;
437*61046927SAndroid Build Coastguard Worker       blend.rt[0].blend_enable = 1;
438*61046927SAndroid Build Coastguard Worker       blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_SRC_ALPHA;
439*61046927SAndroid Build Coastguard Worker       blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_INV_SRC_ALPHA;
440*61046927SAndroid Build Coastguard Worker       blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ZERO;
441*61046927SAndroid Build Coastguard Worker       blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
442*61046927SAndroid Build Coastguard Worker       blend.rt[0].rgb_func = PIPE_BLEND_ADD;
443*61046927SAndroid Build Coastguard Worker       blend.rt[0].alpha_func = PIPE_BLEND_ADD;
444*61046927SAndroid Build Coastguard Worker       blend.rt[0].colormask = PIPE_MASK_RGBA;
445*61046927SAndroid Build Coastguard Worker       blend.logicop_enable = 0;
446*61046927SAndroid Build Coastguard Worker       blend.logicop_func = PIPE_LOGICOP_CLEAR;
447*61046927SAndroid Build Coastguard Worker       blend.dither = 0;
448*61046927SAndroid Build Coastguard Worker       blend_state = drv->pipe->create_blend_state(drv->pipe, &blend);
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker       vl_compositor_clear_layers(&drv->cstate);
451*61046927SAndroid Build Coastguard Worker       vl_compositor_set_layer_blend(&drv->cstate, 0, blend_state, false);
452*61046927SAndroid Build Coastguard Worker       upload_sampler(drv->pipe, sub->sampler, &box, buf->data,
453*61046927SAndroid Build Coastguard Worker                      sub->image->pitches[0], 0, 0);
454*61046927SAndroid Build Coastguard Worker       vl_compositor_set_rgba_layer(&drv->cstate, &drv->compositor, 0, sub->sampler,
455*61046927SAndroid Build Coastguard Worker                                    &sr, NULL, NULL);
456*61046927SAndroid Build Coastguard Worker       vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dr);
457*61046927SAndroid Build Coastguard Worker       vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, false);
458*61046927SAndroid Build Coastguard Worker       drv->pipe->delete_blend_state(drv->pipe, blend_state);
459*61046927SAndroid Build Coastguard Worker    }
460*61046927SAndroid Build Coastguard Worker 
461*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
462*61046927SAndroid Build Coastguard Worker }
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker VAStatus
vlVaPutSurface(VADriverContextP ctx,VASurfaceID surface_id,void * draw,short srcx,short srcy,unsigned short srcw,unsigned short srch,short destx,short desty,unsigned short destw,unsigned short desth,VARectangle * cliprects,unsigned int number_cliprects,unsigned int flags)465*61046927SAndroid Build Coastguard Worker vlVaPutSurface(VADriverContextP ctx, VASurfaceID surface_id, void* draw, short srcx, short srcy,
466*61046927SAndroid Build Coastguard Worker                unsigned short srcw, unsigned short srch, short destx, short desty,
467*61046927SAndroid Build Coastguard Worker                unsigned short destw, unsigned short desth, VARectangle *cliprects,
468*61046927SAndroid Build Coastguard Worker                unsigned int number_cliprects,  unsigned int flags)
469*61046927SAndroid Build Coastguard Worker {
470*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
471*61046927SAndroid Build Coastguard Worker    vlVaSurface *surf;
472*61046927SAndroid Build Coastguard Worker    struct pipe_screen *screen;
473*61046927SAndroid Build Coastguard Worker    struct pipe_resource *tex;
474*61046927SAndroid Build Coastguard Worker    struct pipe_surface surf_templ, *surf_draw;
475*61046927SAndroid Build Coastguard Worker    struct vl_screen *vscreen;
476*61046927SAndroid Build Coastguard Worker    struct u_rect src_rect, *dirty_area;
477*61046927SAndroid Build Coastguard Worker    struct u_rect dst_rect = {destx, destx + destw, desty, desty + desth};
478*61046927SAndroid Build Coastguard Worker    enum pipe_format format;
479*61046927SAndroid Build Coastguard Worker    VAStatus status;
480*61046927SAndroid Build Coastguard Worker 
481*61046927SAndroid Build Coastguard Worker    if (!ctx)
482*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
485*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
486*61046927SAndroid Build Coastguard Worker    surf = handle_table_get(drv->htab, surface_id);
487*61046927SAndroid Build Coastguard Worker    vlVaGetSurfaceBuffer(drv, surf);
488*61046927SAndroid Build Coastguard Worker    if (!surf || !surf->buffer) {
489*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
490*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
491*61046927SAndroid Build Coastguard Worker    }
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker    screen = drv->pipe->screen;
494*61046927SAndroid Build Coastguard Worker    vscreen = drv->vscreen;
495*61046927SAndroid Build Coastguard Worker 
496*61046927SAndroid Build Coastguard Worker    tex = vscreen->texture_from_drawable(vscreen, draw);
497*61046927SAndroid Build Coastguard Worker    if (!tex) {
498*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
499*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_DISPLAY;
500*61046927SAndroid Build Coastguard Worker    }
501*61046927SAndroid Build Coastguard Worker 
502*61046927SAndroid Build Coastguard Worker    dirty_area = vscreen->get_dirty_area(vscreen);
503*61046927SAndroid Build Coastguard Worker 
504*61046927SAndroid Build Coastguard Worker    memset(&surf_templ, 0, sizeof(surf_templ));
505*61046927SAndroid Build Coastguard Worker    surf_templ.format = tex->format;
506*61046927SAndroid Build Coastguard Worker    surf_draw = drv->pipe->create_surface(drv->pipe, tex, &surf_templ);
507*61046927SAndroid Build Coastguard Worker    if (!surf_draw) {
508*61046927SAndroid Build Coastguard Worker       pipe_resource_reference(&tex, NULL);
509*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
510*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_DISPLAY;
511*61046927SAndroid Build Coastguard Worker    }
512*61046927SAndroid Build Coastguard Worker 
513*61046927SAndroid Build Coastguard Worker    src_rect.x0 = srcx;
514*61046927SAndroid Build Coastguard Worker    src_rect.y0 = srcy;
515*61046927SAndroid Build Coastguard Worker    src_rect.x1 = srcw + srcx;
516*61046927SAndroid Build Coastguard Worker    src_rect.y1 = srch + srcy;
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker    format = surf->buffer->buffer_format;
519*61046927SAndroid Build Coastguard Worker 
520*61046927SAndroid Build Coastguard Worker    vl_compositor_clear_layers(&drv->cstate);
521*61046927SAndroid Build Coastguard Worker 
522*61046927SAndroid Build Coastguard Worker    if (format == PIPE_FORMAT_B8G8R8A8_UNORM || format == PIPE_FORMAT_B8G8R8X8_UNORM ||
523*61046927SAndroid Build Coastguard Worker        format == PIPE_FORMAT_R8G8B8A8_UNORM || format == PIPE_FORMAT_R8G8B8X8_UNORM ||
524*61046927SAndroid Build Coastguard Worker        format == PIPE_FORMAT_B10G10R10A2_UNORM || format == PIPE_FORMAT_B10G10R10X2_UNORM ||
525*61046927SAndroid Build Coastguard Worker        format == PIPE_FORMAT_R10G10B10A2_UNORM || format == PIPE_FORMAT_R10G10B10X2_UNORM ||
526*61046927SAndroid Build Coastguard Worker        format == PIPE_FORMAT_L8_UNORM || format == PIPE_FORMAT_Y8_400_UNORM) {
527*61046927SAndroid Build Coastguard Worker       struct pipe_sampler_view **views;
528*61046927SAndroid Build Coastguard Worker 
529*61046927SAndroid Build Coastguard Worker       views = surf->buffer->get_sampler_view_planes(surf->buffer);
530*61046927SAndroid Build Coastguard Worker       vl_compositor_set_rgba_layer(&drv->cstate, &drv->compositor, 0, views[0], &src_rect, NULL, NULL);
531*61046927SAndroid Build Coastguard Worker    } else
532*61046927SAndroid Build Coastguard Worker       vl_compositor_set_buffer_layer(&drv->cstate, &drv->compositor, 0, surf->buffer, &src_rect, NULL, VL_COMPOSITOR_WEAVE);
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    vl_compositor_set_layer_dst_area(&drv->cstate, 0, &dst_rect);
535*61046927SAndroid Build Coastguard Worker    vl_compositor_render(&drv->cstate, &drv->compositor, surf_draw, dirty_area, true);
536*61046927SAndroid Build Coastguard Worker 
537*61046927SAndroid Build Coastguard Worker    status = vlVaPutSubpictures(surf, drv, surf_draw, dirty_area, &src_rect, &dst_rect);
538*61046927SAndroid Build Coastguard Worker    if (status) {
539*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
540*61046927SAndroid Build Coastguard Worker       return status;
541*61046927SAndroid Build Coastguard Worker    }
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker    drv->pipe->flush_resource(drv->pipe, tex);
544*61046927SAndroid Build Coastguard Worker 
545*61046927SAndroid Build Coastguard Worker    /* flush before calling flush_frontbuffer so that rendering is flushed
546*61046927SAndroid Build Coastguard Worker     * to back buffer so the texture can be copied in flush_frontbuffer
547*61046927SAndroid Build Coastguard Worker     */
548*61046927SAndroid Build Coastguard Worker    drv->pipe->flush(drv->pipe, NULL, 0);
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    screen->flush_frontbuffer(screen, drv->pipe, tex, 0, 0,
551*61046927SAndroid Build Coastguard Worker                              vscreen->get_private(vscreen), 0, NULL);
552*61046927SAndroid Build Coastguard Worker 
553*61046927SAndroid Build Coastguard Worker 
554*61046927SAndroid Build Coastguard Worker    pipe_resource_reference(&tex, NULL);
555*61046927SAndroid Build Coastguard Worker    pipe_surface_reference(&surf_draw, NULL);
556*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
559*61046927SAndroid Build Coastguard Worker }
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker VAStatus
vlVaLockSurface(VADriverContextP ctx,VASurfaceID surface,unsigned int * fourcc,unsigned int * luma_stride,unsigned int * chroma_u_stride,unsigned int * chroma_v_stride,unsigned int * luma_offset,unsigned int * chroma_u_offset,unsigned int * chroma_v_offset,unsigned int * buffer_name,void ** buffer)562*61046927SAndroid Build Coastguard Worker vlVaLockSurface(VADriverContextP ctx, VASurfaceID surface, unsigned int *fourcc,
563*61046927SAndroid Build Coastguard Worker                 unsigned int *luma_stride, unsigned int *chroma_u_stride, unsigned int *chroma_v_stride,
564*61046927SAndroid Build Coastguard Worker                 unsigned int *luma_offset, unsigned int *chroma_u_offset, unsigned int *chroma_v_offset,
565*61046927SAndroid Build Coastguard Worker                 unsigned int *buffer_name, void **buffer)
566*61046927SAndroid Build Coastguard Worker {
567*61046927SAndroid Build Coastguard Worker    if (!ctx)
568*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
569*61046927SAndroid Build Coastguard Worker 
570*61046927SAndroid Build Coastguard Worker    return VA_STATUS_ERROR_UNIMPLEMENTED;
571*61046927SAndroid Build Coastguard Worker }
572*61046927SAndroid Build Coastguard Worker 
573*61046927SAndroid Build Coastguard Worker VAStatus
vlVaUnlockSurface(VADriverContextP ctx,VASurfaceID surface)574*61046927SAndroid Build Coastguard Worker vlVaUnlockSurface(VADriverContextP ctx, VASurfaceID surface)
575*61046927SAndroid Build Coastguard Worker {
576*61046927SAndroid Build Coastguard Worker    if (!ctx)
577*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
578*61046927SAndroid Build Coastguard Worker 
579*61046927SAndroid Build Coastguard Worker    return VA_STATUS_ERROR_UNIMPLEMENTED;
580*61046927SAndroid Build Coastguard Worker }
581*61046927SAndroid Build Coastguard Worker 
582*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQuerySurfaceAttributes(VADriverContextP ctx,VAConfigID config_id,VASurfaceAttrib * attrib_list,unsigned int * num_attribs)583*61046927SAndroid Build Coastguard Worker vlVaQuerySurfaceAttributes(VADriverContextP ctx, VAConfigID config_id,
584*61046927SAndroid Build Coastguard Worker                            VASurfaceAttrib *attrib_list, unsigned int *num_attribs)
585*61046927SAndroid Build Coastguard Worker {
586*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
587*61046927SAndroid Build Coastguard Worker    vlVaConfig *config;
588*61046927SAndroid Build Coastguard Worker    VASurfaceAttrib *attribs;
589*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
590*61046927SAndroid Build Coastguard Worker    int i, j;
591*61046927SAndroid Build Coastguard Worker 
592*61046927SAndroid Build Coastguard Worker    STATIC_ASSERT(ARRAY_SIZE(vpp_surface_formats) <= VL_VA_MAX_IMAGE_FORMATS);
593*61046927SAndroid Build Coastguard Worker 
594*61046927SAndroid Build Coastguard Worker    if (config_id == VA_INVALID_ID)
595*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONFIG;
596*61046927SAndroid Build Coastguard Worker 
597*61046927SAndroid Build Coastguard Worker    if (!attrib_list && !num_attribs)
598*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker    if (!attrib_list) {
601*61046927SAndroid Build Coastguard Worker       *num_attribs = VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount;
602*61046927SAndroid Build Coastguard Worker       return VA_STATUS_SUCCESS;
603*61046927SAndroid Build Coastguard Worker    }
604*61046927SAndroid Build Coastguard Worker 
605*61046927SAndroid Build Coastguard Worker    if (!ctx)
606*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
607*61046927SAndroid Build Coastguard Worker 
608*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
609*61046927SAndroid Build Coastguard Worker 
610*61046927SAndroid Build Coastguard Worker    if (!drv)
611*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
612*61046927SAndroid Build Coastguard Worker 
613*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
614*61046927SAndroid Build Coastguard Worker    config = handle_table_get(drv->htab, config_id);
615*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
616*61046927SAndroid Build Coastguard Worker 
617*61046927SAndroid Build Coastguard Worker    if (!config)
618*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONFIG;
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker    pscreen = VL_VA_PSCREEN(ctx);
621*61046927SAndroid Build Coastguard Worker 
622*61046927SAndroid Build Coastguard Worker    if (!pscreen)
623*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
624*61046927SAndroid Build Coastguard Worker 
625*61046927SAndroid Build Coastguard Worker    attribs = CALLOC(VL_VA_MAX_IMAGE_FORMATS + VASurfaceAttribCount,
626*61046927SAndroid Build Coastguard Worker                     sizeof(VASurfaceAttrib));
627*61046927SAndroid Build Coastguard Worker 
628*61046927SAndroid Build Coastguard Worker    if (!attribs)
629*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_ALLOCATION_FAILED;
630*61046927SAndroid Build Coastguard Worker 
631*61046927SAndroid Build Coastguard Worker    i = 0;
632*61046927SAndroid Build Coastguard Worker 
633*61046927SAndroid Build Coastguard Worker    /* vlVaCreateConfig returns PIPE_VIDEO_PROFILE_UNKNOWN
634*61046927SAndroid Build Coastguard Worker     * only for VAEntrypointVideoProc. */
635*61046927SAndroid Build Coastguard Worker    if (config->profile == PIPE_VIDEO_PROFILE_UNKNOWN) {
636*61046927SAndroid Build Coastguard Worker       if (config->rt_format & VA_RT_FORMAT_RGB32 ||
637*61046927SAndroid Build Coastguard Worker           config->rt_format & VA_RT_FORMAT_RGB32_10) {
638*61046927SAndroid Build Coastguard Worker          for (j = 0; j < ARRAY_SIZE(vpp_surface_formats); ++j) {
639*61046927SAndroid Build Coastguard Worker             attribs[i].type = VASurfaceAttribPixelFormat;
640*61046927SAndroid Build Coastguard Worker             attribs[i].value.type = VAGenericValueTypeInteger;
641*61046927SAndroid Build Coastguard Worker             attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
642*61046927SAndroid Build Coastguard Worker             attribs[i].value.value.i = PipeFormatToVaFourcc(vpp_surface_formats[j]);
643*61046927SAndroid Build Coastguard Worker             i++;
644*61046927SAndroid Build Coastguard Worker          }
645*61046927SAndroid Build Coastguard Worker       }
646*61046927SAndroid Build Coastguard Worker    }
647*61046927SAndroid Build Coastguard Worker 
648*61046927SAndroid Build Coastguard Worker    if (config->rt_format & VA_RT_FORMAT_YUV420) {
649*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribPixelFormat;
650*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
651*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
652*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i = VA_FOURCC_NV12;
653*61046927SAndroid Build Coastguard Worker       i++;
654*61046927SAndroid Build Coastguard Worker    }
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker    if (config->rt_format & VA_RT_FORMAT_YUV420_10) {
657*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribPixelFormat;
658*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
659*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
660*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i = VA_FOURCC_P010;
661*61046927SAndroid Build Coastguard Worker       i++;
662*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribPixelFormat;
663*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
664*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
665*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i = VA_FOURCC_P016;
666*61046927SAndroid Build Coastguard Worker       i++;
667*61046927SAndroid Build Coastguard Worker    }
668*61046927SAndroid Build Coastguard Worker 
669*61046927SAndroid Build Coastguard Worker    if (config->profile == PIPE_VIDEO_PROFILE_JPEG_BASELINE) {
670*61046927SAndroid Build Coastguard Worker       if (config->rt_format & VA_RT_FORMAT_YUV400) {
671*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribPixelFormat;
672*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
673*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
674*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = VA_FOURCC_Y800;
675*61046927SAndroid Build Coastguard Worker          i++;
676*61046927SAndroid Build Coastguard Worker       }
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker       if (config->rt_format & VA_RT_FORMAT_YUV422) {
679*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribPixelFormat;
680*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
681*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
682*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = VA_FOURCC_YUY2;
683*61046927SAndroid Build Coastguard Worker          i++;
684*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribPixelFormat;
685*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
686*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
687*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = VA_FOURCC_422V;
688*61046927SAndroid Build Coastguard Worker          i++;
689*61046927SAndroid Build Coastguard Worker       }
690*61046927SAndroid Build Coastguard Worker 
691*61046927SAndroid Build Coastguard Worker       if (config->rt_format & VA_RT_FORMAT_YUV444) {
692*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribPixelFormat;
693*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
694*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
695*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = VA_FOURCC_444P;
696*61046927SAndroid Build Coastguard Worker          i++;
697*61046927SAndroid Build Coastguard Worker       }
698*61046927SAndroid Build Coastguard Worker       if (config->rt_format & VA_RT_FORMAT_RGBP) {
699*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribPixelFormat;
700*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
701*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
702*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = VA_FOURCC_RGBP;
703*61046927SAndroid Build Coastguard Worker          i++;
704*61046927SAndroid Build Coastguard Worker       }
705*61046927SAndroid Build Coastguard Worker    }
706*61046927SAndroid Build Coastguard Worker 
707*61046927SAndroid Build Coastguard Worker    attribs[i].type = VASurfaceAttribMemoryType;
708*61046927SAndroid Build Coastguard Worker    attribs[i].value.type = VAGenericValueTypeInteger;
709*61046927SAndroid Build Coastguard Worker    attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE | VA_SURFACE_ATTRIB_SETTABLE;
710*61046927SAndroid Build Coastguard Worker    attribs[i].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_VA |
711*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
712*61046927SAndroid Build Coastguard Worker          VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE |
713*61046927SAndroid Build Coastguard Worker          VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE;
714*61046927SAndroid Build Coastguard Worker #else
715*61046927SAndroid Build Coastguard Worker          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME |
716*61046927SAndroid Build Coastguard Worker          VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2;
717*61046927SAndroid Build Coastguard Worker #endif
718*61046927SAndroid Build Coastguard Worker    i++;
719*61046927SAndroid Build Coastguard Worker 
720*61046927SAndroid Build Coastguard Worker    attribs[i].type = VASurfaceAttribExternalBufferDescriptor;
721*61046927SAndroid Build Coastguard Worker    attribs[i].value.type = VAGenericValueTypePointer;
722*61046927SAndroid Build Coastguard Worker    attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
723*61046927SAndroid Build Coastguard Worker    attribs[i].value.value.p = NULL; /* ignore */
724*61046927SAndroid Build Coastguard Worker    i++;
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker #ifdef HAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS
727*61046927SAndroid Build Coastguard Worker    if (drv->pipe->create_video_buffer_with_modifiers) {
728*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribDRMFormatModifiers;
729*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypePointer;
730*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_SETTABLE;
731*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.p = NULL; /* ignore */
732*61046927SAndroid Build Coastguard Worker       i++;
733*61046927SAndroid Build Coastguard Worker    }
734*61046927SAndroid Build Coastguard Worker #endif
735*61046927SAndroid Build Coastguard Worker 
736*61046927SAndroid Build Coastguard Worker    /* If VPP supported entry, use the max dimensions cap values, if not fallback to this below */
737*61046927SAndroid Build Coastguard Worker    if (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_PROCESSING ||
738*61046927SAndroid Build Coastguard Worker        pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
739*61046927SAndroid Build Coastguard Worker                                 PIPE_VIDEO_ENTRYPOINT_PROCESSING,
740*61046927SAndroid Build Coastguard Worker                                 PIPE_VIDEO_CAP_SUPPORTED))
741*61046927SAndroid Build Coastguard Worker    {
742*61046927SAndroid Build Coastguard Worker       unsigned min_width, min_height;
743*61046927SAndroid Build Coastguard Worker       min_width = pscreen->get_video_param(pscreen,
744*61046927SAndroid Build Coastguard Worker                                   config->profile, config->entrypoint,
745*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_MIN_WIDTH);
746*61046927SAndroid Build Coastguard Worker       min_height = pscreen->get_video_param(pscreen,
747*61046927SAndroid Build Coastguard Worker                                   config->profile, config->entrypoint,
748*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_MIN_HEIGHT);
749*61046927SAndroid Build Coastguard Worker 
750*61046927SAndroid Build Coastguard Worker       if (min_width > 0 && min_height > 0) {
751*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribMinWidth;
752*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
753*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
754*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = min_width;
755*61046927SAndroid Build Coastguard Worker          i++;
756*61046927SAndroid Build Coastguard Worker 
757*61046927SAndroid Build Coastguard Worker          attribs[i].type = VASurfaceAttribMinHeight;
758*61046927SAndroid Build Coastguard Worker          attribs[i].value.type = VAGenericValueTypeInteger;
759*61046927SAndroid Build Coastguard Worker          attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
760*61046927SAndroid Build Coastguard Worker          attribs[i].value.value.i = min_height;
761*61046927SAndroid Build Coastguard Worker          i++;
762*61046927SAndroid Build Coastguard Worker       }
763*61046927SAndroid Build Coastguard Worker 
764*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribMaxWidth;
765*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
766*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
767*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i =
768*61046927SAndroid Build Coastguard Worker          pscreen->get_video_param(pscreen,
769*61046927SAndroid Build Coastguard Worker                                   config->profile, config->entrypoint,
770*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_MAX_WIDTH);
771*61046927SAndroid Build Coastguard Worker       i++;
772*61046927SAndroid Build Coastguard Worker 
773*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribMaxHeight;
774*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
775*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
776*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i =
777*61046927SAndroid Build Coastguard Worker          pscreen->get_video_param(pscreen,
778*61046927SAndroid Build Coastguard Worker                                   config->profile, config->entrypoint,
779*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_MAX_HEIGHT);
780*61046927SAndroid Build Coastguard Worker       i++;
781*61046927SAndroid Build Coastguard Worker #if VA_CHECK_VERSION(1, 21, 0)
782*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribAlignmentSize;
783*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
784*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
785*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i =
786*61046927SAndroid Build Coastguard Worker          pscreen->get_video_param(pscreen,
787*61046927SAndroid Build Coastguard Worker                                   config->profile, config->entrypoint,
788*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_ENC_SURFACE_ALIGNMENT);
789*61046927SAndroid Build Coastguard Worker       i++;
790*61046927SAndroid Build Coastguard Worker #endif
791*61046927SAndroid Build Coastguard Worker    } else {
792*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribMaxWidth;
793*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
794*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
795*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
796*61046927SAndroid Build Coastguard Worker       i++;
797*61046927SAndroid Build Coastguard Worker 
798*61046927SAndroid Build Coastguard Worker       attribs[i].type = VASurfaceAttribMaxHeight;
799*61046927SAndroid Build Coastguard Worker       attribs[i].value.type = VAGenericValueTypeInteger;
800*61046927SAndroid Build Coastguard Worker       attribs[i].flags = VA_SURFACE_ATTRIB_GETTABLE;
801*61046927SAndroid Build Coastguard Worker       attribs[i].value.value.i = vl_video_buffer_max_size(pscreen);
802*61046927SAndroid Build Coastguard Worker       i++;
803*61046927SAndroid Build Coastguard Worker    }
804*61046927SAndroid Build Coastguard Worker 
805*61046927SAndroid Build Coastguard Worker    if (i > *num_attribs) {
806*61046927SAndroid Build Coastguard Worker       *num_attribs = i;
807*61046927SAndroid Build Coastguard Worker       FREE(attribs);
808*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
809*61046927SAndroid Build Coastguard Worker    }
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker    *num_attribs = i;
812*61046927SAndroid Build Coastguard Worker    memcpy(attrib_list, attribs, i * sizeof(VASurfaceAttrib));
813*61046927SAndroid Build Coastguard Worker    FREE(attribs);
814*61046927SAndroid Build Coastguard Worker 
815*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
816*61046927SAndroid Build Coastguard Worker }
817*61046927SAndroid Build Coastguard Worker 
818*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
819*61046927SAndroid Build Coastguard Worker static VAStatus
surface_from_external_memory(VADriverContextP ctx,vlVaSurface * surface,VASurfaceAttribExternalBuffers * memory_attribute,unsigned index,struct pipe_video_buffer * templat)820*61046927SAndroid Build Coastguard Worker surface_from_external_memory(VADriverContextP ctx, vlVaSurface *surface,
821*61046927SAndroid Build Coastguard Worker                              VASurfaceAttribExternalBuffers *memory_attribute,
822*61046927SAndroid Build Coastguard Worker                              unsigned index, struct pipe_video_buffer *templat)
823*61046927SAndroid Build Coastguard Worker {
824*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
825*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
826*61046927SAndroid Build Coastguard Worker    struct pipe_resource res_templ;
827*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
828*61046927SAndroid Build Coastguard Worker    struct pipe_resource *resources[VL_NUM_COMPONENTS];
829*61046927SAndroid Build Coastguard Worker    enum pipe_format resource_formats[VL_NUM_COMPONENTS];
830*61046927SAndroid Build Coastguard Worker    VAStatus result;
831*61046927SAndroid Build Coastguard Worker    int i;
832*61046927SAndroid Build Coastguard Worker 
833*61046927SAndroid Build Coastguard Worker    pscreen = VL_VA_PSCREEN(ctx);
834*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
835*61046927SAndroid Build Coastguard Worker 
836*61046927SAndroid Build Coastguard Worker    if (!memory_attribute || !memory_attribute->buffers ||
837*61046927SAndroid Build Coastguard Worker        index > memory_attribute->num_buffers)
838*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker    if (surface->templat.width != memory_attribute->width ||
841*61046927SAndroid Build Coastguard Worker        surface->templat.height != memory_attribute->height ||
842*61046927SAndroid Build Coastguard Worker        memory_attribute->num_planes < 1)
843*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
844*61046927SAndroid Build Coastguard Worker 
845*61046927SAndroid Build Coastguard Worker    if (memory_attribute->num_planes > VL_NUM_COMPONENTS)
846*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
847*61046927SAndroid Build Coastguard Worker 
848*61046927SAndroid Build Coastguard Worker    vl_get_video_buffer_formats(pscreen, templat->buffer_format, resource_formats);
849*61046927SAndroid Build Coastguard Worker 
850*61046927SAndroid Build Coastguard Worker    memset(&res_templ, 0, sizeof(res_templ));
851*61046927SAndroid Build Coastguard Worker    res_templ.target = PIPE_TEXTURE_2D;
852*61046927SAndroid Build Coastguard Worker    res_templ.last_level = 0;
853*61046927SAndroid Build Coastguard Worker    res_templ.depth0 = 1;
854*61046927SAndroid Build Coastguard Worker    res_templ.array_size = 1;
855*61046927SAndroid Build Coastguard Worker    res_templ.bind = PIPE_BIND_SAMPLER_VIEW;
856*61046927SAndroid Build Coastguard Worker    res_templ.usage = PIPE_USAGE_DEFAULT;
857*61046927SAndroid Build Coastguard Worker 
858*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(struct winsys_handle));
859*61046927SAndroid Build Coastguard Worker    whandle.type = WINSYS_HANDLE_TYPE_FD;
860*61046927SAndroid Build Coastguard Worker    whandle.handle = memory_attribute->buffers[index];
861*61046927SAndroid Build Coastguard Worker    whandle.modifier = DRM_FORMAT_MOD_INVALID;
862*61046927SAndroid Build Coastguard Worker    whandle.format = templat->buffer_format;
863*61046927SAndroid Build Coastguard Worker 
864*61046927SAndroid Build Coastguard Worker    // Create a resource for each plane.
865*61046927SAndroid Build Coastguard Worker    memset(resources, 0, sizeof resources);
866*61046927SAndroid Build Coastguard Worker    for (i = 0; i < memory_attribute->num_planes; i++) {
867*61046927SAndroid Build Coastguard Worker       unsigned num_planes = util_format_get_num_planes(templat->buffer_format);
868*61046927SAndroid Build Coastguard Worker 
869*61046927SAndroid Build Coastguard Worker       res_templ.format = resource_formats[i];
870*61046927SAndroid Build Coastguard Worker       if (res_templ.format == PIPE_FORMAT_NONE) {
871*61046927SAndroid Build Coastguard Worker          if (i < num_planes) {
872*61046927SAndroid Build Coastguard Worker             result = VA_STATUS_ERROR_INVALID_PARAMETER;
873*61046927SAndroid Build Coastguard Worker             goto fail;
874*61046927SAndroid Build Coastguard Worker          } else {
875*61046927SAndroid Build Coastguard Worker             continue;
876*61046927SAndroid Build Coastguard Worker          }
877*61046927SAndroid Build Coastguard Worker       }
878*61046927SAndroid Build Coastguard Worker 
879*61046927SAndroid Build Coastguard Worker       res_templ.width0 = util_format_get_plane_width(templat->buffer_format, i,
880*61046927SAndroid Build Coastguard Worker                                                      memory_attribute->width);
881*61046927SAndroid Build Coastguard Worker       res_templ.height0 = util_format_get_plane_height(templat->buffer_format, i,
882*61046927SAndroid Build Coastguard Worker                                                        memory_attribute->height);
883*61046927SAndroid Build Coastguard Worker 
884*61046927SAndroid Build Coastguard Worker       whandle.stride = memory_attribute->pitches[i];
885*61046927SAndroid Build Coastguard Worker       whandle.offset = memory_attribute->offsets[i];
886*61046927SAndroid Build Coastguard Worker       resources[i] = pscreen->resource_from_handle(pscreen, &res_templ, &whandle,
887*61046927SAndroid Build Coastguard Worker                                                    PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
888*61046927SAndroid Build Coastguard Worker       if (!resources[i]) {
889*61046927SAndroid Build Coastguard Worker          result = VA_STATUS_ERROR_ALLOCATION_FAILED;
890*61046927SAndroid Build Coastguard Worker          goto fail;
891*61046927SAndroid Build Coastguard Worker       }
892*61046927SAndroid Build Coastguard Worker    }
893*61046927SAndroid Build Coastguard Worker 
894*61046927SAndroid Build Coastguard Worker    surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources);
895*61046927SAndroid Build Coastguard Worker    if (!surface->buffer) {
896*61046927SAndroid Build Coastguard Worker       result = VA_STATUS_ERROR_ALLOCATION_FAILED;
897*61046927SAndroid Build Coastguard Worker       goto fail;
898*61046927SAndroid Build Coastguard Worker    }
899*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
900*61046927SAndroid Build Coastguard Worker 
901*61046927SAndroid Build Coastguard Worker fail:
902*61046927SAndroid Build Coastguard Worker    for (i = 0; i < VL_NUM_COMPONENTS; i++)
903*61046927SAndroid Build Coastguard Worker       pipe_resource_reference(&resources[i], NULL);
904*61046927SAndroid Build Coastguard Worker    return result;
905*61046927SAndroid Build Coastguard Worker }
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker static VAStatus
surface_from_prime_2(VADriverContextP ctx,vlVaSurface * surface,VADRMPRIMESurfaceDescriptor * desc,struct pipe_video_buffer * templat)908*61046927SAndroid Build Coastguard Worker surface_from_prime_2(VADriverContextP ctx, vlVaSurface *surface,
909*61046927SAndroid Build Coastguard Worker                      VADRMPRIMESurfaceDescriptor *desc,
910*61046927SAndroid Build Coastguard Worker                      struct pipe_video_buffer *templat)
911*61046927SAndroid Build Coastguard Worker {
912*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
913*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
914*61046927SAndroid Build Coastguard Worker    struct pipe_resource res_templ;
915*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
916*61046927SAndroid Build Coastguard Worker    struct pipe_resource *resources[VL_NUM_COMPONENTS];
917*61046927SAndroid Build Coastguard Worker    enum pipe_format resource_formats[VL_NUM_COMPONENTS];
918*61046927SAndroid Build Coastguard Worker    unsigned num_format_planes, expected_planes, input_planes, plane;
919*61046927SAndroid Build Coastguard Worker    VAStatus result;
920*61046927SAndroid Build Coastguard Worker 
921*61046927SAndroid Build Coastguard Worker    num_format_planes = util_format_get_num_planes(templat->buffer_format);
922*61046927SAndroid Build Coastguard Worker    pscreen = VL_VA_PSCREEN(ctx);
923*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
924*61046927SAndroid Build Coastguard Worker 
925*61046927SAndroid Build Coastguard Worker    if (!desc || desc->num_layers >= 4 ||desc->num_objects == 0)
926*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
927*61046927SAndroid Build Coastguard Worker 
928*61046927SAndroid Build Coastguard Worker    if (surface->templat.width != desc->width ||
929*61046927SAndroid Build Coastguard Worker        surface->templat.height != desc->height ||
930*61046927SAndroid Build Coastguard Worker        desc->num_layers < 1)
931*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
932*61046927SAndroid Build Coastguard Worker 
933*61046927SAndroid Build Coastguard Worker    if (desc->num_layers > VL_NUM_COMPONENTS)
934*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
935*61046927SAndroid Build Coastguard Worker 
936*61046927SAndroid Build Coastguard Worker    input_planes = 0;
937*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < desc->num_layers; ++i) {
938*61046927SAndroid Build Coastguard Worker       if (desc->layers[i].num_planes == 0 || desc->layers[i].num_planes > 4)
939*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_PARAMETER;
940*61046927SAndroid Build Coastguard Worker 
941*61046927SAndroid Build Coastguard Worker       for (unsigned j = 0; j < desc->layers[i].num_planes; ++j)
942*61046927SAndroid Build Coastguard Worker          if (desc->layers[i].object_index[j] >= desc->num_objects)
943*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
944*61046927SAndroid Build Coastguard Worker 
945*61046927SAndroid Build Coastguard Worker       input_planes += desc->layers[i].num_planes;
946*61046927SAndroid Build Coastguard Worker    }
947*61046927SAndroid Build Coastguard Worker 
948*61046927SAndroid Build Coastguard Worker    expected_planes = num_format_planes;
949*61046927SAndroid Build Coastguard Worker    if (desc->objects[0].drm_format_modifier != DRM_FORMAT_MOD_INVALID &&
950*61046927SAndroid Build Coastguard Worker        pscreen->is_dmabuf_modifier_supported &&
951*61046927SAndroid Build Coastguard Worker        pscreen->is_dmabuf_modifier_supported(pscreen, desc->objects[0].drm_format_modifier,
952*61046927SAndroid Build Coastguard Worker                                             templat->buffer_format, NULL) &&
953*61046927SAndroid Build Coastguard Worker        pscreen->get_dmabuf_modifier_planes)
954*61046927SAndroid Build Coastguard Worker       expected_planes = pscreen->get_dmabuf_modifier_planes(pscreen, desc->objects[0].drm_format_modifier,
955*61046927SAndroid Build Coastguard Worker                                                            templat->buffer_format);
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker    if (input_planes != expected_planes)
958*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
959*61046927SAndroid Build Coastguard Worker 
960*61046927SAndroid Build Coastguard Worker    vl_get_video_buffer_formats(pscreen, templat->buffer_format, resource_formats);
961*61046927SAndroid Build Coastguard Worker 
962*61046927SAndroid Build Coastguard Worker    memset(&res_templ, 0, sizeof(res_templ));
963*61046927SAndroid Build Coastguard Worker    res_templ.target = PIPE_TEXTURE_2D;
964*61046927SAndroid Build Coastguard Worker    res_templ.last_level = 0;
965*61046927SAndroid Build Coastguard Worker    res_templ.depth0 = 1;
966*61046927SAndroid Build Coastguard Worker    res_templ.array_size = 1;
967*61046927SAndroid Build Coastguard Worker    res_templ.bind = PIPE_BIND_SAMPLER_VIEW;
968*61046927SAndroid Build Coastguard Worker    res_templ.usage = PIPE_USAGE_DEFAULT;
969*61046927SAndroid Build Coastguard Worker    res_templ.format = templat->buffer_format;
970*61046927SAndroid Build Coastguard Worker 
971*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(struct winsys_handle));
972*61046927SAndroid Build Coastguard Worker    whandle.type = WINSYS_HANDLE_TYPE_FD;
973*61046927SAndroid Build Coastguard Worker    whandle.format = templat->buffer_format;
974*61046927SAndroid Build Coastguard Worker    whandle.modifier = desc->objects[0].drm_format_modifier;
975*61046927SAndroid Build Coastguard Worker 
976*61046927SAndroid Build Coastguard Worker    // Create a resource for each plane.
977*61046927SAndroid Build Coastguard Worker    memset(resources, 0, sizeof resources);
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker    /* This does a backwards walk to set the next pointers. It interleaves so
980*61046927SAndroid Build Coastguard Worker     * that the main planes always come first and then the first compression metadata
981*61046927SAndroid Build Coastguard Worker     * plane of each main plane etc. */
982*61046927SAndroid Build Coastguard Worker    plane = input_planes - 1;
983*61046927SAndroid Build Coastguard Worker    for (int layer_plane = 3; layer_plane >= 0; --layer_plane) {
984*61046927SAndroid Build Coastguard Worker       for (int layer = desc->num_layers - 1; layer >= 0; --layer) {
985*61046927SAndroid Build Coastguard Worker          if (layer_plane >= desc->layers[layer].num_planes)
986*61046927SAndroid Build Coastguard Worker             continue;
987*61046927SAndroid Build Coastguard Worker 
988*61046927SAndroid Build Coastguard Worker          if (plane < num_format_planes)
989*61046927SAndroid Build Coastguard Worker             res_templ.format = resource_formats[plane];
990*61046927SAndroid Build Coastguard Worker 
991*61046927SAndroid Build Coastguard Worker          res_templ.width0 = util_format_get_plane_width(templat->buffer_format, plane,
992*61046927SAndroid Build Coastguard Worker                                                         desc->width);
993*61046927SAndroid Build Coastguard Worker          res_templ.height0 = util_format_get_plane_height(templat->buffer_format, plane,
994*61046927SAndroid Build Coastguard Worker                                                           desc->height);
995*61046927SAndroid Build Coastguard Worker          whandle.stride = desc->layers[layer].pitch[layer_plane];
996*61046927SAndroid Build Coastguard Worker          whandle.offset = desc->layers[layer].offset[layer_plane];
997*61046927SAndroid Build Coastguard Worker          whandle.handle = desc->objects[desc->layers[layer].object_index[layer_plane]].fd;
998*61046927SAndroid Build Coastguard Worker          whandle.plane = plane;
999*61046927SAndroid Build Coastguard Worker 
1000*61046927SAndroid Build Coastguard Worker          resources[plane] = pscreen->resource_from_handle(pscreen, &res_templ, &whandle,
1001*61046927SAndroid Build Coastguard Worker                                                           PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE);
1002*61046927SAndroid Build Coastguard Worker          if (!resources[plane]) {
1003*61046927SAndroid Build Coastguard Worker             result = VA_STATUS_ERROR_ALLOCATION_FAILED;
1004*61046927SAndroid Build Coastguard Worker             goto fail;
1005*61046927SAndroid Build Coastguard Worker          }
1006*61046927SAndroid Build Coastguard Worker 
1007*61046927SAndroid Build Coastguard Worker          /* After the resource gets created the resource now owns the next reference. */
1008*61046927SAndroid Build Coastguard Worker          res_templ.next = NULL;
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker          if (plane)
1011*61046927SAndroid Build Coastguard Worker             pipe_resource_reference(&res_templ.next, resources[plane]);
1012*61046927SAndroid Build Coastguard Worker          --plane;
1013*61046927SAndroid Build Coastguard Worker       }
1014*61046927SAndroid Build Coastguard Worker    }
1015*61046927SAndroid Build Coastguard Worker 
1016*61046927SAndroid Build Coastguard Worker    surface->buffer = vl_video_buffer_create_ex2(drv->pipe, templat, resources);
1017*61046927SAndroid Build Coastguard Worker    if (!surface->buffer) {
1018*61046927SAndroid Build Coastguard Worker       result = VA_STATUS_ERROR_ALLOCATION_FAILED;
1019*61046927SAndroid Build Coastguard Worker       goto fail;
1020*61046927SAndroid Build Coastguard Worker    }
1021*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1022*61046927SAndroid Build Coastguard Worker 
1023*61046927SAndroid Build Coastguard Worker fail:
1024*61046927SAndroid Build Coastguard Worker    pipe_resource_reference(&res_templ.next, NULL);
1025*61046927SAndroid Build Coastguard Worker    for (int i = 0; i < VL_NUM_COMPONENTS; i++)
1026*61046927SAndroid Build Coastguard Worker       pipe_resource_reference(&resources[i], NULL);
1027*61046927SAndroid Build Coastguard Worker    return result;
1028*61046927SAndroid Build Coastguard Worker }
1029*61046927SAndroid Build Coastguard Worker #else
1030*61046927SAndroid Build Coastguard Worker static VAStatus
surface_from_external_win32_memory(VADriverContextP ctx,vlVaSurface * surface,int memory_type,void * res_handle,struct pipe_video_buffer * templat)1031*61046927SAndroid Build Coastguard Worker surface_from_external_win32_memory(VADriverContextP ctx, vlVaSurface *surface,
1032*61046927SAndroid Build Coastguard Worker                              int memory_type, void *res_handle,
1033*61046927SAndroid Build Coastguard Worker                              struct pipe_video_buffer *templat)
1034*61046927SAndroid Build Coastguard Worker {
1035*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
1036*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
1037*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
1038*61046927SAndroid Build Coastguard Worker    VAStatus result;
1039*61046927SAndroid Build Coastguard Worker 
1040*61046927SAndroid Build Coastguard Worker    pscreen = VL_VA_PSCREEN(ctx);
1041*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
1042*61046927SAndroid Build Coastguard Worker 
1043*61046927SAndroid Build Coastguard Worker    templat->buffer_format = surface->templat.buffer_format;
1044*61046927SAndroid Build Coastguard Worker    templat->width = surface->templat.width;
1045*61046927SAndroid Build Coastguard Worker    templat->height = surface->templat.height;
1046*61046927SAndroid Build Coastguard Worker 
1047*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(whandle));
1048*61046927SAndroid Build Coastguard Worker    whandle.format = surface->templat.buffer_format;
1049*61046927SAndroid Build Coastguard Worker    if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE) {
1050*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_FD;
1051*61046927SAndroid Build Coastguard Worker       whandle.handle = res_handle;
1052*61046927SAndroid Build Coastguard Worker    } else if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE) {
1053*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
1054*61046927SAndroid Build Coastguard Worker       whandle.com_obj = res_handle;
1055*61046927SAndroid Build Coastguard Worker    } else {
1056*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
1057*61046927SAndroid Build Coastguard Worker    }
1058*61046927SAndroid Build Coastguard Worker 
1059*61046927SAndroid Build Coastguard Worker    surface->buffer = drv->pipe->video_buffer_from_handle(drv->pipe, templat, &whandle, PIPE_USAGE_DEFAULT);
1060*61046927SAndroid Build Coastguard Worker    if (!surface->buffer) {
1061*61046927SAndroid Build Coastguard Worker       result = VA_STATUS_ERROR_ALLOCATION_FAILED;
1062*61046927SAndroid Build Coastguard Worker       goto fail;
1063*61046927SAndroid Build Coastguard Worker    }
1064*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1065*61046927SAndroid Build Coastguard Worker 
1066*61046927SAndroid Build Coastguard Worker fail:
1067*61046927SAndroid Build Coastguard Worker    return result;
1068*61046927SAndroid Build Coastguard Worker }
1069*61046927SAndroid Build Coastguard Worker 
1070*61046927SAndroid Build Coastguard Worker #endif
1071*61046927SAndroid Build Coastguard Worker 
1072*61046927SAndroid Build Coastguard Worker VAStatus
vlVaHandleSurfaceAllocate(vlVaDriver * drv,vlVaSurface * surface,struct pipe_video_buffer * templat,const uint64_t * modifiers,unsigned int modifiers_count)1073*61046927SAndroid Build Coastguard Worker vlVaHandleSurfaceAllocate(vlVaDriver *drv, vlVaSurface *surface,
1074*61046927SAndroid Build Coastguard Worker                           struct pipe_video_buffer *templat,
1075*61046927SAndroid Build Coastguard Worker                           const uint64_t *modifiers,
1076*61046927SAndroid Build Coastguard Worker                           unsigned int modifiers_count)
1077*61046927SAndroid Build Coastguard Worker {
1078*61046927SAndroid Build Coastguard Worker    struct pipe_surface **surfaces;
1079*61046927SAndroid Build Coastguard Worker    unsigned i;
1080*61046927SAndroid Build Coastguard Worker 
1081*61046927SAndroid Build Coastguard Worker    if (modifiers_count > 0) {
1082*61046927SAndroid Build Coastguard Worker       if (!drv->pipe->create_video_buffer_with_modifiers)
1083*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1084*61046927SAndroid Build Coastguard Worker       surface->buffer =
1085*61046927SAndroid Build Coastguard Worker          drv->pipe->create_video_buffer_with_modifiers(drv->pipe, templat,
1086*61046927SAndroid Build Coastguard Worker                                                        modifiers,
1087*61046927SAndroid Build Coastguard Worker                                                        modifiers_count);
1088*61046927SAndroid Build Coastguard Worker    } else {
1089*61046927SAndroid Build Coastguard Worker       surface->buffer = drv->pipe->create_video_buffer(drv->pipe, templat);
1090*61046927SAndroid Build Coastguard Worker    }
1091*61046927SAndroid Build Coastguard Worker    if (!surface->buffer)
1092*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_ALLOCATION_FAILED;
1093*61046927SAndroid Build Coastguard Worker 
1094*61046927SAndroid Build Coastguard Worker    surfaces = surface->buffer->get_surfaces(surface->buffer);
1095*61046927SAndroid Build Coastguard Worker    if (surfaces) {
1096*61046927SAndroid Build Coastguard Worker       for (i = 0; i < VL_MAX_SURFACES; ++i) {
1097*61046927SAndroid Build Coastguard Worker          union pipe_color_union c;
1098*61046927SAndroid Build Coastguard Worker          memset(&c, 0, sizeof(c));
1099*61046927SAndroid Build Coastguard Worker 
1100*61046927SAndroid Build Coastguard Worker          if (!surfaces[i])
1101*61046927SAndroid Build Coastguard Worker             continue;
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker          if (i > !!surface->buffer->interlaced)
1104*61046927SAndroid Build Coastguard Worker             c.f[0] = c.f[1] = c.f[2] = c.f[3] = 0.5f;
1105*61046927SAndroid Build Coastguard Worker 
1106*61046927SAndroid Build Coastguard Worker          drv->pipe->clear_render_target(drv->pipe, surfaces[i], &c, 0, 0,
1107*61046927SAndroid Build Coastguard Worker                   surfaces[i]->width, surfaces[i]->height,
1108*61046927SAndroid Build Coastguard Worker                   false);
1109*61046927SAndroid Build Coastguard Worker       }
1110*61046927SAndroid Build Coastguard Worker       drv->pipe->flush(drv->pipe, NULL, 0);
1111*61046927SAndroid Build Coastguard Worker    }
1112*61046927SAndroid Build Coastguard Worker 
1113*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1114*61046927SAndroid Build Coastguard Worker }
1115*61046927SAndroid Build Coastguard Worker 
1116*61046927SAndroid Build Coastguard Worker struct pipe_video_buffer *
vlVaGetSurfaceBuffer(vlVaDriver * drv,vlVaSurface * surface)1117*61046927SAndroid Build Coastguard Worker vlVaGetSurfaceBuffer(vlVaDriver *drv, vlVaSurface *surface)
1118*61046927SAndroid Build Coastguard Worker {
1119*61046927SAndroid Build Coastguard Worker    if (!surface)
1120*61046927SAndroid Build Coastguard Worker       return NULL;
1121*61046927SAndroid Build Coastguard Worker    if (surface->buffer)
1122*61046927SAndroid Build Coastguard Worker       return surface->buffer;
1123*61046927SAndroid Build Coastguard Worker    vlVaHandleSurfaceAllocate(drv, surface, &surface->templat, NULL, 0);
1124*61046927SAndroid Build Coastguard Worker    return surface->buffer;
1125*61046927SAndroid Build Coastguard Worker }
1126*61046927SAndroid Build Coastguard Worker 
1127*61046927SAndroid Build Coastguard Worker VAStatus
vlVaCreateSurfaces2(VADriverContextP ctx,unsigned int format,unsigned int width,unsigned int height,VASurfaceID * surfaces,unsigned int num_surfaces,VASurfaceAttrib * attrib_list,unsigned int num_attribs)1128*61046927SAndroid Build Coastguard Worker vlVaCreateSurfaces2(VADriverContextP ctx, unsigned int format,
1129*61046927SAndroid Build Coastguard Worker                     unsigned int width, unsigned int height,
1130*61046927SAndroid Build Coastguard Worker                     VASurfaceID *surfaces, unsigned int num_surfaces,
1131*61046927SAndroid Build Coastguard Worker                     VASurfaceAttrib *attrib_list, unsigned int num_attribs)
1132*61046927SAndroid Build Coastguard Worker {
1133*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
1134*61046927SAndroid Build Coastguard Worker    VASurfaceAttribExternalBuffers *memory_attribute;
1135*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1136*61046927SAndroid Build Coastguard Worker    void **win32_handles;
1137*61046927SAndroid Build Coastguard Worker #else
1138*61046927SAndroid Build Coastguard Worker    VADRMPRIMESurfaceDescriptor *prime_desc = NULL;
1139*61046927SAndroid Build Coastguard Worker #ifdef HAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS
1140*61046927SAndroid Build Coastguard Worker    const VADRMFormatModifierList *modifier_list;
1141*61046927SAndroid Build Coastguard Worker #endif
1142*61046927SAndroid Build Coastguard Worker #endif
1143*61046927SAndroid Build Coastguard Worker    struct pipe_video_buffer templat;
1144*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen;
1145*61046927SAndroid Build Coastguard Worker    int i;
1146*61046927SAndroid Build Coastguard Worker    int memory_type;
1147*61046927SAndroid Build Coastguard Worker    int expected_fourcc;
1148*61046927SAndroid Build Coastguard Worker    VAStatus vaStatus;
1149*61046927SAndroid Build Coastguard Worker    vlVaSurface *surf;
1150*61046927SAndroid Build Coastguard Worker    bool protected;
1151*61046927SAndroid Build Coastguard Worker    const uint64_t *modifiers;
1152*61046927SAndroid Build Coastguard Worker    unsigned int modifiers_count;
1153*61046927SAndroid Build Coastguard Worker 
1154*61046927SAndroid Build Coastguard Worker    if (!ctx)
1155*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker    if (!(width && height))
1158*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
1159*61046927SAndroid Build Coastguard Worker 
1160*61046927SAndroid Build Coastguard Worker    drv = VL_VA_DRIVER(ctx);
1161*61046927SAndroid Build Coastguard Worker 
1162*61046927SAndroid Build Coastguard Worker    if (!drv)
1163*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1164*61046927SAndroid Build Coastguard Worker 
1165*61046927SAndroid Build Coastguard Worker    pscreen = VL_VA_PSCREEN(ctx);
1166*61046927SAndroid Build Coastguard Worker 
1167*61046927SAndroid Build Coastguard Worker    if (!pscreen)
1168*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1169*61046927SAndroid Build Coastguard Worker 
1170*61046927SAndroid Build Coastguard Worker    /* Default. */
1171*61046927SAndroid Build Coastguard Worker    memory_attribute = NULL;
1172*61046927SAndroid Build Coastguard Worker    memory_type = VA_SURFACE_ATTRIB_MEM_TYPE_VA;
1173*61046927SAndroid Build Coastguard Worker    expected_fourcc = 0;
1174*61046927SAndroid Build Coastguard Worker    modifiers = NULL;
1175*61046927SAndroid Build Coastguard Worker    modifiers_count = 0;
1176*61046927SAndroid Build Coastguard Worker 
1177*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_attribs && attrib_list; i++) {
1178*61046927SAndroid Build Coastguard Worker       if (!(attrib_list[i].flags & VA_SURFACE_ATTRIB_SETTABLE))
1179*61046927SAndroid Build Coastguard Worker          continue;
1180*61046927SAndroid Build Coastguard Worker 
1181*61046927SAndroid Build Coastguard Worker       switch (attrib_list[i].type) {
1182*61046927SAndroid Build Coastguard Worker       case VASurfaceAttribPixelFormat:
1183*61046927SAndroid Build Coastguard Worker          if (attrib_list[i].value.type != VAGenericValueTypeInteger)
1184*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1185*61046927SAndroid Build Coastguard Worker          expected_fourcc = attrib_list[i].value.value.i;
1186*61046927SAndroid Build Coastguard Worker          break;
1187*61046927SAndroid Build Coastguard Worker       case VASurfaceAttribMemoryType:
1188*61046927SAndroid Build Coastguard Worker          if (attrib_list[i].value.type != VAGenericValueTypeInteger)
1189*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1190*61046927SAndroid Build Coastguard Worker 
1191*61046927SAndroid Build Coastguard Worker          switch (attrib_list[i].value.value.i) {
1192*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
1193*61046927SAndroid Build Coastguard Worker 
1194*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1195*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
1196*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
1197*61046927SAndroid Build Coastguard Worker #else
1198*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
1199*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
1200*61046927SAndroid Build Coastguard Worker #endif
1201*61046927SAndroid Build Coastguard Worker             memory_type = attrib_list[i].value.value.i;
1202*61046927SAndroid Build Coastguard Worker             break;
1203*61046927SAndroid Build Coastguard Worker          default:
1204*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
1205*61046927SAndroid Build Coastguard Worker          }
1206*61046927SAndroid Build Coastguard Worker          break;
1207*61046927SAndroid Build Coastguard Worker       case VASurfaceAttribExternalBufferDescriptor:
1208*61046927SAndroid Build Coastguard Worker          if (attrib_list[i].value.type != VAGenericValueTypePointer)
1209*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1210*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1211*61046927SAndroid Build Coastguard Worker          if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
1212*61046927SAndroid Build Coastguard Worker             prime_desc = (VADRMPRIMESurfaceDescriptor *)attrib_list[i].value.value.p;
1213*61046927SAndroid Build Coastguard Worker #else
1214*61046927SAndroid Build Coastguard Worker          else if (memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE ||
1215*61046927SAndroid Build Coastguard Worker                   memory_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
1216*61046927SAndroid Build Coastguard Worker             win32_handles = (void**) attrib_list[i].value.value.p;
1217*61046927SAndroid Build Coastguard Worker #endif
1218*61046927SAndroid Build Coastguard Worker          else
1219*61046927SAndroid Build Coastguard Worker             memory_attribute = (VASurfaceAttribExternalBuffers *)attrib_list[i].value.value.p;
1220*61046927SAndroid Build Coastguard Worker          break;
1221*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1222*61046927SAndroid Build Coastguard Worker #ifdef HAVE_VA_SURFACE_ATTRIB_DRM_FORMAT_MODIFIERS
1223*61046927SAndroid Build Coastguard Worker       case VASurfaceAttribDRMFormatModifiers:
1224*61046927SAndroid Build Coastguard Worker          if (attrib_list[i].value.type != VAGenericValueTypePointer)
1225*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1226*61046927SAndroid Build Coastguard Worker          modifier_list = attrib_list[i].value.value.p;
1227*61046927SAndroid Build Coastguard Worker          if (modifier_list != NULL) {
1228*61046927SAndroid Build Coastguard Worker             modifiers = modifier_list->modifiers;
1229*61046927SAndroid Build Coastguard Worker             modifiers_count = modifier_list->num_modifiers;
1230*61046927SAndroid Build Coastguard Worker          }
1231*61046927SAndroid Build Coastguard Worker          break;
1232*61046927SAndroid Build Coastguard Worker #endif
1233*61046927SAndroid Build Coastguard Worker #endif
1234*61046927SAndroid Build Coastguard Worker       case VASurfaceAttribUsageHint:
1235*61046927SAndroid Build Coastguard Worker          if (attrib_list[i].value.type != VAGenericValueTypeInteger)
1236*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1237*61046927SAndroid Build Coastguard Worker          break;
1238*61046927SAndroid Build Coastguard Worker       default:
1239*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
1240*61046927SAndroid Build Coastguard Worker       }
1241*61046927SAndroid Build Coastguard Worker    }
1242*61046927SAndroid Build Coastguard Worker 
1243*61046927SAndroid Build Coastguard Worker    protected = format & VA_RT_FORMAT_PROTECTED;
1244*61046927SAndroid Build Coastguard Worker    format &= ~VA_RT_FORMAT_PROTECTED;
1245*61046927SAndroid Build Coastguard Worker 
1246*61046927SAndroid Build Coastguard Worker    if (VA_RT_FORMAT_YUV420 != format &&
1247*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_YUV422 != format &&
1248*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_YUV444 != format &&
1249*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_YUV400 != format &&
1250*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_YUV420_10BPP != format &&
1251*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_RGBP != format &&
1252*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_RGB32 != format &&
1253*61046927SAndroid Build Coastguard Worker        VA_RT_FORMAT_RGB32_10 != format) {
1254*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
1255*61046927SAndroid Build Coastguard Worker    }
1256*61046927SAndroid Build Coastguard Worker 
1257*61046927SAndroid Build Coastguard Worker    switch (memory_type) {
1258*61046927SAndroid Build Coastguard Worker    case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
1259*61046927SAndroid Build Coastguard Worker       break;
1260*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1261*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
1262*61046927SAndroid Build Coastguard Worker          case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
1263*61046927SAndroid Build Coastguard Worker          if (!win32_handles)
1264*61046927SAndroid Build Coastguard Worker             return VA_STATUS_ERROR_INVALID_PARAMETER;
1265*61046927SAndroid Build Coastguard Worker          break;
1266*61046927SAndroid Build Coastguard Worker #else
1267*61046927SAndroid Build Coastguard Worker    case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
1268*61046927SAndroid Build Coastguard Worker       if (!memory_attribute)
1269*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_PARAMETER;
1270*61046927SAndroid Build Coastguard Worker       if (modifiers)
1271*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_PARAMETER;
1272*61046927SAndroid Build Coastguard Worker 
1273*61046927SAndroid Build Coastguard Worker       expected_fourcc = memory_attribute->pixel_format;
1274*61046927SAndroid Build Coastguard Worker       break;
1275*61046927SAndroid Build Coastguard Worker    case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
1276*61046927SAndroid Build Coastguard Worker       if (!prime_desc)
1277*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_PARAMETER;
1278*61046927SAndroid Build Coastguard Worker 
1279*61046927SAndroid Build Coastguard Worker       expected_fourcc = prime_desc->fourcc;
1280*61046927SAndroid Build Coastguard Worker       break;
1281*61046927SAndroid Build Coastguard Worker #endif
1282*61046927SAndroid Build Coastguard Worker    default:
1283*61046927SAndroid Build Coastguard Worker       assert(0);
1284*61046927SAndroid Build Coastguard Worker    }
1285*61046927SAndroid Build Coastguard Worker 
1286*61046927SAndroid Build Coastguard Worker    memset(&templat, 0, sizeof(templat));
1287*61046927SAndroid Build Coastguard Worker 
1288*61046927SAndroid Build Coastguard Worker    templat.buffer_format = pscreen->get_video_param(
1289*61046927SAndroid Build Coastguard Worker       pscreen,
1290*61046927SAndroid Build Coastguard Worker       PIPE_VIDEO_PROFILE_UNKNOWN,
1291*61046927SAndroid Build Coastguard Worker       PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1292*61046927SAndroid Build Coastguard Worker       PIPE_VIDEO_CAP_PREFERED_FORMAT
1293*61046927SAndroid Build Coastguard Worker    );
1294*61046927SAndroid Build Coastguard Worker 
1295*61046927SAndroid Build Coastguard Worker    if (modifiers)
1296*61046927SAndroid Build Coastguard Worker       templat.interlaced = false;
1297*61046927SAndroid Build Coastguard Worker    else
1298*61046927SAndroid Build Coastguard Worker       templat.interlaced =
1299*61046927SAndroid Build Coastguard Worker          pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1300*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_ENTRYPOINT_BITSTREAM,
1301*61046927SAndroid Build Coastguard Worker                                   PIPE_VIDEO_CAP_PREFERS_INTERLACED);
1302*61046927SAndroid Build Coastguard Worker 
1303*61046927SAndroid Build Coastguard Worker    if (expected_fourcc) {
1304*61046927SAndroid Build Coastguard Worker       enum pipe_format expected_format = VaFourccToPipeFormat(expected_fourcc);
1305*61046927SAndroid Build Coastguard Worker 
1306*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1307*61046927SAndroid Build Coastguard Worker       if (expected_format != templat.buffer_format || memory_attribute || prime_desc)
1308*61046927SAndroid Build Coastguard Worker #else
1309*61046927SAndroid Build Coastguard Worker       if (expected_format != templat.buffer_format || memory_attribute)
1310*61046927SAndroid Build Coastguard Worker #endif
1311*61046927SAndroid Build Coastguard Worker         templat.interlaced = 0;
1312*61046927SAndroid Build Coastguard Worker 
1313*61046927SAndroid Build Coastguard Worker       templat.buffer_format = expected_format;
1314*61046927SAndroid Build Coastguard Worker    }
1315*61046927SAndroid Build Coastguard Worker 
1316*61046927SAndroid Build Coastguard Worker    templat.width = width;
1317*61046927SAndroid Build Coastguard Worker    templat.height = height;
1318*61046927SAndroid Build Coastguard Worker    if (protected)
1319*61046927SAndroid Build Coastguard Worker       templat.bind |= PIPE_BIND_PROTECTED;
1320*61046927SAndroid Build Coastguard Worker 
1321*61046927SAndroid Build Coastguard Worker    memset(surfaces, VA_INVALID_ID, num_surfaces * sizeof(VASurfaceID));
1322*61046927SAndroid Build Coastguard Worker 
1323*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
1324*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_surfaces; i++) {
1325*61046927SAndroid Build Coastguard Worker       surf = CALLOC(1, sizeof(vlVaSurface));
1326*61046927SAndroid Build Coastguard Worker       if (!surf) {
1327*61046927SAndroid Build Coastguard Worker          vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1328*61046927SAndroid Build Coastguard Worker          goto no_res;
1329*61046927SAndroid Build Coastguard Worker       }
1330*61046927SAndroid Build Coastguard Worker 
1331*61046927SAndroid Build Coastguard Worker       surf->templat = templat;
1332*61046927SAndroid Build Coastguard Worker 
1333*61046927SAndroid Build Coastguard Worker       switch (memory_type) {
1334*61046927SAndroid Build Coastguard Worker       case VA_SURFACE_ATTRIB_MEM_TYPE_VA:
1335*61046927SAndroid Build Coastguard Worker          /* The application will clear the TILING flag when the surface is
1336*61046927SAndroid Build Coastguard Worker           * intended to be exported as dmabuf. Adding shared flag because not
1337*61046927SAndroid Build Coastguard Worker           * null memory_attribute means VASurfaceAttribExternalBuffers is used.
1338*61046927SAndroid Build Coastguard Worker           */
1339*61046927SAndroid Build Coastguard Worker          if (memory_attribute &&
1340*61046927SAndroid Build Coastguard Worker              !(memory_attribute->flags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING))
1341*61046927SAndroid Build Coastguard Worker             surf->templat.bind = PIPE_BIND_LINEAR | PIPE_BIND_SHARED;
1342*61046927SAndroid Build Coastguard Worker 
1343*61046927SAndroid Build Coastguard Worker          if (modifiers) {
1344*61046927SAndroid Build Coastguard Worker             vaStatus = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, modifiers,
1345*61046927SAndroid Build Coastguard Worker                                                  modifiers_count);
1346*61046927SAndroid Build Coastguard Worker             if (vaStatus != VA_STATUS_SUCCESS)
1347*61046927SAndroid Build Coastguard Worker                goto free_surf;
1348*61046927SAndroid Build Coastguard Worker          } /* Delayed allocation from vlVaGetSurfaceBuffer otherwise */
1349*61046927SAndroid Build Coastguard Worker          break;
1350*61046927SAndroid Build Coastguard Worker 
1351*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1352*61046927SAndroid Build Coastguard Worker       case VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE:
1353*61046927SAndroid Build Coastguard Worker       case VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE:
1354*61046927SAndroid Build Coastguard Worker          vaStatus = surface_from_external_win32_memory(ctx, surf, memory_type, win32_handles[i], &templat);
1355*61046927SAndroid Build Coastguard Worker          if (vaStatus != VA_STATUS_SUCCESS)
1356*61046927SAndroid Build Coastguard Worker             goto free_surf;
1357*61046927SAndroid Build Coastguard Worker          break;
1358*61046927SAndroid Build Coastguard Worker #else
1359*61046927SAndroid Build Coastguard Worker       case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
1360*61046927SAndroid Build Coastguard Worker          vaStatus = surface_from_external_memory(ctx, surf, memory_attribute, i, &templat);
1361*61046927SAndroid Build Coastguard Worker          if (vaStatus != VA_STATUS_SUCCESS)
1362*61046927SAndroid Build Coastguard Worker             goto free_surf;
1363*61046927SAndroid Build Coastguard Worker          break;
1364*61046927SAndroid Build Coastguard Worker 
1365*61046927SAndroid Build Coastguard Worker       case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2:
1366*61046927SAndroid Build Coastguard Worker          vaStatus = surface_from_prime_2(ctx, surf, prime_desc, &templat);
1367*61046927SAndroid Build Coastguard Worker          if (vaStatus != VA_STATUS_SUCCESS)
1368*61046927SAndroid Build Coastguard Worker             goto free_surf;
1369*61046927SAndroid Build Coastguard Worker          break;
1370*61046927SAndroid Build Coastguard Worker #endif
1371*61046927SAndroid Build Coastguard Worker       default:
1372*61046927SAndroid Build Coastguard Worker          assert(0);
1373*61046927SAndroid Build Coastguard Worker       }
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker       util_dynarray_init(&surf->subpics, NULL);
1376*61046927SAndroid Build Coastguard Worker       surfaces[i] = handle_table_add(drv->htab, surf);
1377*61046927SAndroid Build Coastguard Worker       if (!surfaces[i]) {
1378*61046927SAndroid Build Coastguard Worker          vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
1379*61046927SAndroid Build Coastguard Worker          goto destroy_surf;
1380*61046927SAndroid Build Coastguard Worker       }
1381*61046927SAndroid Build Coastguard Worker    }
1382*61046927SAndroid Build Coastguard Worker 
1383*61046927SAndroid Build Coastguard Worker    if (memory_type != VA_SURFACE_ATTRIB_MEM_TYPE_VA)
1384*61046927SAndroid Build Coastguard Worker       drv->has_external_handles = true;
1385*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
1386*61046927SAndroid Build Coastguard Worker 
1387*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1388*61046927SAndroid Build Coastguard Worker 
1389*61046927SAndroid Build Coastguard Worker destroy_surf:
1390*61046927SAndroid Build Coastguard Worker    if (surf->buffer)
1391*61046927SAndroid Build Coastguard Worker       surf->buffer->destroy(surf->buffer);
1392*61046927SAndroid Build Coastguard Worker 
1393*61046927SAndroid Build Coastguard Worker free_surf:
1394*61046927SAndroid Build Coastguard Worker    FREE(surf);
1395*61046927SAndroid Build Coastguard Worker 
1396*61046927SAndroid Build Coastguard Worker no_res:
1397*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
1398*61046927SAndroid Build Coastguard Worker    if (i)
1399*61046927SAndroid Build Coastguard Worker       vlVaDestroySurfaces(ctx, surfaces, i);
1400*61046927SAndroid Build Coastguard Worker 
1401*61046927SAndroid Build Coastguard Worker    return vaStatus;
1402*61046927SAndroid Build Coastguard Worker }
1403*61046927SAndroid Build Coastguard Worker 
1404*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQueryVideoProcFilters(VADriverContextP ctx,VAContextID context,VAProcFilterType * filters,unsigned int * num_filters)1405*61046927SAndroid Build Coastguard Worker vlVaQueryVideoProcFilters(VADriverContextP ctx, VAContextID context,
1406*61046927SAndroid Build Coastguard Worker                           VAProcFilterType *filters, unsigned int *num_filters)
1407*61046927SAndroid Build Coastguard Worker {
1408*61046927SAndroid Build Coastguard Worker    unsigned int num = 0;
1409*61046927SAndroid Build Coastguard Worker 
1410*61046927SAndroid Build Coastguard Worker    if (!ctx)
1411*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1412*61046927SAndroid Build Coastguard Worker 
1413*61046927SAndroid Build Coastguard Worker    if (!num_filters || !filters)
1414*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
1415*61046927SAndroid Build Coastguard Worker 
1416*61046927SAndroid Build Coastguard Worker    filters[num++] = VAProcFilterDeinterlacing;
1417*61046927SAndroid Build Coastguard Worker 
1418*61046927SAndroid Build Coastguard Worker    *num_filters = num;
1419*61046927SAndroid Build Coastguard Worker 
1420*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1421*61046927SAndroid Build Coastguard Worker }
1422*61046927SAndroid Build Coastguard Worker 
1423*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQueryVideoProcFilterCaps(VADriverContextP ctx,VAContextID context,VAProcFilterType type,void * filter_caps,unsigned int * num_filter_caps)1424*61046927SAndroid Build Coastguard Worker vlVaQueryVideoProcFilterCaps(VADriverContextP ctx, VAContextID context,
1425*61046927SAndroid Build Coastguard Worker                              VAProcFilterType type, void *filter_caps,
1426*61046927SAndroid Build Coastguard Worker                              unsigned int *num_filter_caps)
1427*61046927SAndroid Build Coastguard Worker {
1428*61046927SAndroid Build Coastguard Worker    unsigned int i;
1429*61046927SAndroid Build Coastguard Worker 
1430*61046927SAndroid Build Coastguard Worker    if (!ctx)
1431*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1432*61046927SAndroid Build Coastguard Worker 
1433*61046927SAndroid Build Coastguard Worker    if (!filter_caps || !num_filter_caps)
1434*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
1435*61046927SAndroid Build Coastguard Worker 
1436*61046927SAndroid Build Coastguard Worker    i = 0;
1437*61046927SAndroid Build Coastguard Worker 
1438*61046927SAndroid Build Coastguard Worker    switch (type) {
1439*61046927SAndroid Build Coastguard Worker    case VAProcFilterNone:
1440*61046927SAndroid Build Coastguard Worker       break;
1441*61046927SAndroid Build Coastguard Worker    case VAProcFilterDeinterlacing: {
1442*61046927SAndroid Build Coastguard Worker       VAProcFilterCapDeinterlacing *deint = filter_caps;
1443*61046927SAndroid Build Coastguard Worker 
1444*61046927SAndroid Build Coastguard Worker       if (*num_filter_caps < 3) {
1445*61046927SAndroid Build Coastguard Worker          *num_filter_caps = 3;
1446*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_MAX_NUM_EXCEEDED;
1447*61046927SAndroid Build Coastguard Worker       }
1448*61046927SAndroid Build Coastguard Worker 
1449*61046927SAndroid Build Coastguard Worker       deint[i++].type = VAProcDeinterlacingBob;
1450*61046927SAndroid Build Coastguard Worker       deint[i++].type = VAProcDeinterlacingWeave;
1451*61046927SAndroid Build Coastguard Worker       deint[i++].type = VAProcDeinterlacingMotionAdaptive;
1452*61046927SAndroid Build Coastguard Worker       break;
1453*61046927SAndroid Build Coastguard Worker    }
1454*61046927SAndroid Build Coastguard Worker 
1455*61046927SAndroid Build Coastguard Worker    case VAProcFilterNoiseReduction:
1456*61046927SAndroid Build Coastguard Worker    case VAProcFilterSharpening:
1457*61046927SAndroid Build Coastguard Worker    case VAProcFilterColorBalance:
1458*61046927SAndroid Build Coastguard Worker    case VAProcFilterSkinToneEnhancement:
1459*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNIMPLEMENTED;
1460*61046927SAndroid Build Coastguard Worker    default:
1461*61046927SAndroid Build Coastguard Worker       assert(0);
1462*61046927SAndroid Build Coastguard Worker    }
1463*61046927SAndroid Build Coastguard Worker 
1464*61046927SAndroid Build Coastguard Worker    *num_filter_caps = i;
1465*61046927SAndroid Build Coastguard Worker 
1466*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1467*61046927SAndroid Build Coastguard Worker }
1468*61046927SAndroid Build Coastguard Worker 
1469*61046927SAndroid Build Coastguard Worker static VAProcColorStandardType vpp_input_color_standards[] = {
1470*61046927SAndroid Build Coastguard Worker    VAProcColorStandardBT601,
1471*61046927SAndroid Build Coastguard Worker    VAProcColorStandardBT709
1472*61046927SAndroid Build Coastguard Worker };
1473*61046927SAndroid Build Coastguard Worker 
1474*61046927SAndroid Build Coastguard Worker static VAProcColorStandardType vpp_output_color_standards[] = {
1475*61046927SAndroid Build Coastguard Worker    VAProcColorStandardBT601,
1476*61046927SAndroid Build Coastguard Worker    VAProcColorStandardBT709
1477*61046927SAndroid Build Coastguard Worker };
1478*61046927SAndroid Build Coastguard Worker 
1479*61046927SAndroid Build Coastguard Worker VAStatus
vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx,VAContextID context,VABufferID * filters,unsigned int num_filters,VAProcPipelineCaps * pipeline_cap)1480*61046927SAndroid Build Coastguard Worker vlVaQueryVideoProcPipelineCaps(VADriverContextP ctx, VAContextID context,
1481*61046927SAndroid Build Coastguard Worker                                VABufferID *filters, unsigned int num_filters,
1482*61046927SAndroid Build Coastguard Worker                                VAProcPipelineCaps *pipeline_cap)
1483*61046927SAndroid Build Coastguard Worker {
1484*61046927SAndroid Build Coastguard Worker    unsigned int i = 0;
1485*61046927SAndroid Build Coastguard Worker 
1486*61046927SAndroid Build Coastguard Worker    if (!ctx)
1487*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_CONTEXT;
1488*61046927SAndroid Build Coastguard Worker 
1489*61046927SAndroid Build Coastguard Worker    if (!pipeline_cap)
1490*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
1491*61046927SAndroid Build Coastguard Worker 
1492*61046927SAndroid Build Coastguard Worker    if (num_filters && !filters)
1493*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_PARAMETER;
1494*61046927SAndroid Build Coastguard Worker 
1495*61046927SAndroid Build Coastguard Worker    pipeline_cap->pipeline_flags = 0;
1496*61046927SAndroid Build Coastguard Worker    pipeline_cap->filter_flags = 0;
1497*61046927SAndroid Build Coastguard Worker    pipeline_cap->num_forward_references = 0;
1498*61046927SAndroid Build Coastguard Worker    pipeline_cap->num_backward_references = 0;
1499*61046927SAndroid Build Coastguard Worker    pipeline_cap->num_input_color_standards = ARRAY_SIZE(vpp_input_color_standards);
1500*61046927SAndroid Build Coastguard Worker    pipeline_cap->input_color_standards = vpp_input_color_standards;
1501*61046927SAndroid Build Coastguard Worker    pipeline_cap->num_output_color_standards = ARRAY_SIZE(vpp_output_color_standards);
1502*61046927SAndroid Build Coastguard Worker    pipeline_cap->output_color_standards = vpp_output_color_standards;
1503*61046927SAndroid Build Coastguard Worker 
1504*61046927SAndroid Build Coastguard Worker    struct pipe_screen *pscreen = VL_VA_PSCREEN(ctx);
1505*61046927SAndroid Build Coastguard Worker    uint32_t pipe_orientation_flags = pscreen->get_video_param(pscreen,
1506*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_PROFILE_UNKNOWN,
1507*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1508*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_CAP_VPP_ORIENTATION_MODES);
1509*61046927SAndroid Build Coastguard Worker 
1510*61046927SAndroid Build Coastguard Worker    pipeline_cap->rotation_flags = VA_ROTATION_NONE;
1511*61046927SAndroid Build Coastguard Worker    if(pipe_orientation_flags & PIPE_VIDEO_VPP_ROTATION_90)
1512*61046927SAndroid Build Coastguard Worker       pipeline_cap->rotation_flags |= (1 << VA_ROTATION_90);
1513*61046927SAndroid Build Coastguard Worker    if(pipe_orientation_flags & PIPE_VIDEO_VPP_ROTATION_180)
1514*61046927SAndroid Build Coastguard Worker       pipeline_cap->rotation_flags |= (1 << VA_ROTATION_180);
1515*61046927SAndroid Build Coastguard Worker    if(pipe_orientation_flags & PIPE_VIDEO_VPP_ROTATION_270)
1516*61046927SAndroid Build Coastguard Worker       pipeline_cap->rotation_flags |= (1 << VA_ROTATION_270);
1517*61046927SAndroid Build Coastguard Worker 
1518*61046927SAndroid Build Coastguard Worker    pipeline_cap->mirror_flags = VA_MIRROR_NONE;
1519*61046927SAndroid Build Coastguard Worker    if(pipe_orientation_flags & PIPE_VIDEO_VPP_FLIP_HORIZONTAL)
1520*61046927SAndroid Build Coastguard Worker       pipeline_cap->mirror_flags |= VA_MIRROR_HORIZONTAL;
1521*61046927SAndroid Build Coastguard Worker    if(pipe_orientation_flags & PIPE_VIDEO_VPP_FLIP_VERTICAL)
1522*61046927SAndroid Build Coastguard Worker       pipeline_cap->mirror_flags |= VA_MIRROR_VERTICAL;
1523*61046927SAndroid Build Coastguard Worker 
1524*61046927SAndroid Build Coastguard Worker    pipeline_cap->max_input_width = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1525*61046927SAndroid Build Coastguard Worker                                                             PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1526*61046927SAndroid Build Coastguard Worker                                                             PIPE_VIDEO_CAP_VPP_MAX_INPUT_WIDTH);
1527*61046927SAndroid Build Coastguard Worker 
1528*61046927SAndroid Build Coastguard Worker    pipeline_cap->max_input_height = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1529*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1530*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_CAP_VPP_MAX_INPUT_HEIGHT);
1531*61046927SAndroid Build Coastguard Worker 
1532*61046927SAndroid Build Coastguard Worker    pipeline_cap->min_input_width = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1533*61046927SAndroid Build Coastguard Worker                                                             PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1534*61046927SAndroid Build Coastguard Worker                                                             PIPE_VIDEO_CAP_VPP_MIN_INPUT_WIDTH);
1535*61046927SAndroid Build Coastguard Worker 
1536*61046927SAndroid Build Coastguard Worker    pipeline_cap->min_input_height = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1537*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1538*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_CAP_VPP_MIN_INPUT_HEIGHT);
1539*61046927SAndroid Build Coastguard Worker 
1540*61046927SAndroid Build Coastguard Worker    pipeline_cap->max_output_width = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1541*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1542*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_WIDTH);
1543*61046927SAndroid Build Coastguard Worker 
1544*61046927SAndroid Build Coastguard Worker    pipeline_cap->max_output_height = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1545*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1546*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_CAP_VPP_MAX_OUTPUT_HEIGHT);
1547*61046927SAndroid Build Coastguard Worker 
1548*61046927SAndroid Build Coastguard Worker    pipeline_cap->min_output_width = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1549*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1550*61046927SAndroid Build Coastguard Worker                                                              PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_WIDTH);
1551*61046927SAndroid Build Coastguard Worker 
1552*61046927SAndroid Build Coastguard Worker    pipeline_cap->min_output_height = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1553*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1554*61046927SAndroid Build Coastguard Worker                                                               PIPE_VIDEO_CAP_VPP_MIN_OUTPUT_HEIGHT);
1555*61046927SAndroid Build Coastguard Worker 
1556*61046927SAndroid Build Coastguard Worker    uint32_t pipe_blend_modes = pscreen->get_video_param(pscreen, PIPE_VIDEO_PROFILE_UNKNOWN,
1557*61046927SAndroid Build Coastguard Worker                                                         PIPE_VIDEO_ENTRYPOINT_PROCESSING,
1558*61046927SAndroid Build Coastguard Worker                                                         PIPE_VIDEO_CAP_VPP_BLEND_MODES);
1559*61046927SAndroid Build Coastguard Worker 
1560*61046927SAndroid Build Coastguard Worker    pipeline_cap->blend_flags = 0;
1561*61046927SAndroid Build Coastguard Worker    if (pipe_blend_modes & PIPE_VIDEO_VPP_BLEND_MODE_GLOBAL_ALPHA)
1562*61046927SAndroid Build Coastguard Worker       pipeline_cap->blend_flags |= VA_BLEND_GLOBAL_ALPHA;
1563*61046927SAndroid Build Coastguard Worker 
1564*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv = VL_VA_DRIVER(ctx);
1565*61046927SAndroid Build Coastguard Worker 
1566*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
1567*61046927SAndroid Build Coastguard Worker    for (i = 0; i < num_filters; i++) {
1568*61046927SAndroid Build Coastguard Worker       vlVaBuffer *buf = handle_table_get(drv->htab, filters[i]);
1569*61046927SAndroid Build Coastguard Worker       VAProcFilterParameterBufferBase *filter;
1570*61046927SAndroid Build Coastguard Worker 
1571*61046927SAndroid Build Coastguard Worker       if (!buf || buf->type != VAProcFilterParameterBufferType) {
1572*61046927SAndroid Build Coastguard Worker          mtx_unlock(&drv->mutex);
1573*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_INVALID_BUFFER;
1574*61046927SAndroid Build Coastguard Worker       }
1575*61046927SAndroid Build Coastguard Worker 
1576*61046927SAndroid Build Coastguard Worker       filter = buf->data;
1577*61046927SAndroid Build Coastguard Worker       switch (filter->type) {
1578*61046927SAndroid Build Coastguard Worker       case VAProcFilterDeinterlacing: {
1579*61046927SAndroid Build Coastguard Worker          VAProcFilterParameterBufferDeinterlacing *deint = buf->data;
1580*61046927SAndroid Build Coastguard Worker          if (deint->algorithm == VAProcDeinterlacingMotionAdaptive) {
1581*61046927SAndroid Build Coastguard Worker             pipeline_cap->num_forward_references = 2;
1582*61046927SAndroid Build Coastguard Worker             pipeline_cap->num_backward_references = 1;
1583*61046927SAndroid Build Coastguard Worker          }
1584*61046927SAndroid Build Coastguard Worker          break;
1585*61046927SAndroid Build Coastguard Worker       }
1586*61046927SAndroid Build Coastguard Worker       default:
1587*61046927SAndroid Build Coastguard Worker          mtx_unlock(&drv->mutex);
1588*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_UNIMPLEMENTED;
1589*61046927SAndroid Build Coastguard Worker       }
1590*61046927SAndroid Build Coastguard Worker    }
1591*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
1592*61046927SAndroid Build Coastguard Worker 
1593*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1594*61046927SAndroid Build Coastguard Worker }
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
pipe_format_to_drm_format(enum pipe_format format)1597*61046927SAndroid Build Coastguard Worker static uint32_t pipe_format_to_drm_format(enum pipe_format format)
1598*61046927SAndroid Build Coastguard Worker {
1599*61046927SAndroid Build Coastguard Worker    switch (format) {
1600*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8_UNORM:
1601*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_R8;
1602*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_UNORM:
1603*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_GR88;
1604*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16_UNORM:
1605*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_R16;
1606*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R16G16_UNORM:
1607*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_GR1616;
1608*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_B8G8R8A8_UNORM:
1609*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_ARGB8888;
1610*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8A8_UNORM:
1611*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_ABGR8888;
1612*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_B8G8R8X8_UNORM:
1613*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_XRGB8888;
1614*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8B8X8_UNORM:
1615*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_XBGR8888;
1616*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_B10G10R10A2_UNORM:
1617*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_ARGB2101010;
1618*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R10G10B10A2_UNORM:
1619*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_ABGR2101010;
1620*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_B10G10R10X2_UNORM:
1621*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_XRGB2101010;
1622*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R10G10B10X2_UNORM:
1623*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_XBGR2101010;
1624*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_NV12:
1625*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_NV12;
1626*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_P010:
1627*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_P010;
1628*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_YUYV:
1629*61046927SAndroid Build Coastguard Worker    case PIPE_FORMAT_R8G8_R8B8_UNORM:
1630*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_YUYV;
1631*61046927SAndroid Build Coastguard Worker    default:
1632*61046927SAndroid Build Coastguard Worker       return DRM_FORMAT_INVALID;
1633*61046927SAndroid Build Coastguard Worker    }
1634*61046927SAndroid Build Coastguard Worker }
1635*61046927SAndroid Build Coastguard Worker #endif
1636*61046927SAndroid Build Coastguard Worker 
1637*61046927SAndroid Build Coastguard Worker #if VA_CHECK_VERSION(1, 1, 0)
1638*61046927SAndroid Build Coastguard Worker VAStatus
vlVaExportSurfaceHandle(VADriverContextP ctx,VASurfaceID surface_id,uint32_t mem_type,uint32_t flags,void * descriptor)1639*61046927SAndroid Build Coastguard Worker vlVaExportSurfaceHandle(VADriverContextP ctx,
1640*61046927SAndroid Build Coastguard Worker                         VASurfaceID surface_id,
1641*61046927SAndroid Build Coastguard Worker                         uint32_t mem_type,
1642*61046927SAndroid Build Coastguard Worker                         uint32_t flags,
1643*61046927SAndroid Build Coastguard Worker                         void *descriptor)
1644*61046927SAndroid Build Coastguard Worker {
1645*61046927SAndroid Build Coastguard Worker    vlVaDriver *drv;
1646*61046927SAndroid Build Coastguard Worker    vlVaSurface *surf;
1647*61046927SAndroid Build Coastguard Worker    struct pipe_surface **surfaces;
1648*61046927SAndroid Build Coastguard Worker    struct pipe_screen *screen;
1649*61046927SAndroid Build Coastguard Worker    VAStatus ret;
1650*61046927SAndroid Build Coastguard Worker    unsigned int usage;
1651*61046927SAndroid Build Coastguard Worker 
1652*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1653*61046927SAndroid Build Coastguard Worker    if ((mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
1654*61046927SAndroid Build Coastguard Worker       && (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE))
1655*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
1656*61046927SAndroid Build Coastguard Worker 
1657*61046927SAndroid Build Coastguard Worker    if ((flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) == 0)
1658*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
1659*61046927SAndroid Build Coastguard Worker #else
1660*61046927SAndroid Build Coastguard Worker    int i, p;
1661*61046927SAndroid Build Coastguard Worker    if (mem_type != VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2)
1662*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
1663*61046927SAndroid Build Coastguard Worker #endif
1664*61046927SAndroid Build Coastguard Worker 
1665*61046927SAndroid Build Coastguard Worker    drv    = VL_VA_DRIVER(ctx);
1666*61046927SAndroid Build Coastguard Worker    screen = VL_VA_PSCREEN(ctx);
1667*61046927SAndroid Build Coastguard Worker    mtx_lock(&drv->mutex);
1668*61046927SAndroid Build Coastguard Worker 
1669*61046927SAndroid Build Coastguard Worker    surf = handle_table_get(drv->htab, surface_id);
1670*61046927SAndroid Build Coastguard Worker    vlVaGetSurfaceBuffer(drv, surf);
1671*61046927SAndroid Build Coastguard Worker    if (!surf || !surf->buffer) {
1672*61046927SAndroid Build Coastguard Worker       mtx_unlock(&drv->mutex);
1673*61046927SAndroid Build Coastguard Worker       return VA_STATUS_ERROR_INVALID_SURFACE;
1674*61046927SAndroid Build Coastguard Worker    }
1675*61046927SAndroid Build Coastguard Worker 
1676*61046927SAndroid Build Coastguard Worker    if (surf->buffer->interlaced) {
1677*61046927SAndroid Build Coastguard Worker       struct pipe_video_buffer *interlaced = surf->buffer;
1678*61046927SAndroid Build Coastguard Worker       struct u_rect src_rect, dst_rect;
1679*61046927SAndroid Build Coastguard Worker 
1680*61046927SAndroid Build Coastguard Worker       surf->templat.interlaced = false;
1681*61046927SAndroid Build Coastguard Worker 
1682*61046927SAndroid Build Coastguard Worker       ret = vlVaHandleSurfaceAllocate(drv, surf, &surf->templat, NULL, 0);
1683*61046927SAndroid Build Coastguard Worker       if (ret != VA_STATUS_SUCCESS) {
1684*61046927SAndroid Build Coastguard Worker          mtx_unlock(&drv->mutex);
1685*61046927SAndroid Build Coastguard Worker          return VA_STATUS_ERROR_ALLOCATION_FAILED;
1686*61046927SAndroid Build Coastguard Worker       }
1687*61046927SAndroid Build Coastguard Worker 
1688*61046927SAndroid Build Coastguard Worker       src_rect.x0 = dst_rect.x0 = 0;
1689*61046927SAndroid Build Coastguard Worker       src_rect.y0 = dst_rect.y0 = 0;
1690*61046927SAndroid Build Coastguard Worker       src_rect.x1 = dst_rect.x1 = surf->templat.width;
1691*61046927SAndroid Build Coastguard Worker       src_rect.y1 = dst_rect.y1 = surf->templat.height;
1692*61046927SAndroid Build Coastguard Worker 
1693*61046927SAndroid Build Coastguard Worker       vl_compositor_yuv_deint_full(&drv->cstate, &drv->compositor,
1694*61046927SAndroid Build Coastguard Worker                                    interlaced, surf->buffer,
1695*61046927SAndroid Build Coastguard Worker                                    &src_rect, &dst_rect,
1696*61046927SAndroid Build Coastguard Worker                                    VL_COMPOSITOR_WEAVE);
1697*61046927SAndroid Build Coastguard Worker       if (interlaced->codec && interlaced->codec->update_decoder_target)
1698*61046927SAndroid Build Coastguard Worker          interlaced->codec->update_decoder_target(interlaced->codec, interlaced, surf->buffer);
1699*61046927SAndroid Build Coastguard Worker 
1700*61046927SAndroid Build Coastguard Worker       interlaced->destroy(interlaced);
1701*61046927SAndroid Build Coastguard Worker    }
1702*61046927SAndroid Build Coastguard Worker 
1703*61046927SAndroid Build Coastguard Worker    surfaces = surf->buffer->get_surfaces(surf->buffer);
1704*61046927SAndroid Build Coastguard Worker 
1705*61046927SAndroid Build Coastguard Worker    usage = 0;
1706*61046927SAndroid Build Coastguard Worker    if (flags & VA_EXPORT_SURFACE_WRITE_ONLY)
1707*61046927SAndroid Build Coastguard Worker       usage |= PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE;
1708*61046927SAndroid Build Coastguard Worker 
1709*61046927SAndroid Build Coastguard Worker #ifdef _WIN32
1710*61046927SAndroid Build Coastguard Worker    struct winsys_handle whandle;
1711*61046927SAndroid Build Coastguard Worker    memset(&whandle, 0, sizeof(struct winsys_handle));
1712*61046927SAndroid Build Coastguard Worker    struct pipe_resource *resource = surfaces[0]->texture;
1713*61046927SAndroid Build Coastguard Worker 
1714*61046927SAndroid Build Coastguard Worker    if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
1715*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_FD;
1716*61046927SAndroid Build Coastguard Worker    else if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
1717*61046927SAndroid Build Coastguard Worker       whandle.type = WINSYS_HANDLE_TYPE_D3D12_RES;
1718*61046927SAndroid Build Coastguard Worker 
1719*61046927SAndroid Build Coastguard Worker    if (!screen->resource_get_handle(screen, drv->pipe, resource,
1720*61046927SAndroid Build Coastguard Worker                                     &whandle, usage)) {
1721*61046927SAndroid Build Coastguard Worker       ret = VA_STATUS_ERROR_INVALID_SURFACE;
1722*61046927SAndroid Build Coastguard Worker       goto fail;
1723*61046927SAndroid Build Coastguard Worker    }
1724*61046927SAndroid Build Coastguard Worker 
1725*61046927SAndroid Build Coastguard Worker    if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_NTHANDLE)
1726*61046927SAndroid Build Coastguard Worker       *(HANDLE**)descriptor = whandle.handle;
1727*61046927SAndroid Build Coastguard Worker    else if (mem_type == VA_SURFACE_ATTRIB_MEM_TYPE_D3D12_RESOURCE)
1728*61046927SAndroid Build Coastguard Worker       *(void**) descriptor = whandle.com_obj;
1729*61046927SAndroid Build Coastguard Worker 
1730*61046927SAndroid Build Coastguard Worker #else
1731*61046927SAndroid Build Coastguard Worker    VADRMPRIMESurfaceDescriptor *desc = descriptor;
1732*61046927SAndroid Build Coastguard Worker    desc->fourcc = PipeFormatToVaFourcc(surf->buffer->buffer_format);
1733*61046927SAndroid Build Coastguard Worker    desc->width = surf->templat.width;
1734*61046927SAndroid Build Coastguard Worker    desc->height = surf->templat.height;
1735*61046927SAndroid Build Coastguard Worker    desc->num_objects = 0;
1736*61046927SAndroid Build Coastguard Worker 
1737*61046927SAndroid Build Coastguard Worker    bool supports_contiguous_planes = screen->resource_get_info && surf->buffer->contiguous_planes;
1738*61046927SAndroid Build Coastguard Worker 
1739*61046927SAndroid Build Coastguard Worker    for (p = 0; p < ARRAY_SIZE(desc->objects); p++) {
1740*61046927SAndroid Build Coastguard Worker       struct winsys_handle whandle;
1741*61046927SAndroid Build Coastguard Worker       struct pipe_resource *resource;
1742*61046927SAndroid Build Coastguard Worker       uint32_t drm_format;
1743*61046927SAndroid Build Coastguard Worker 
1744*61046927SAndroid Build Coastguard Worker       if (!surfaces[p])
1745*61046927SAndroid Build Coastguard Worker          break;
1746*61046927SAndroid Build Coastguard Worker 
1747*61046927SAndroid Build Coastguard Worker       resource = surfaces[p]->texture;
1748*61046927SAndroid Build Coastguard Worker 
1749*61046927SAndroid Build Coastguard Worker       drm_format = pipe_format_to_drm_format(resource->format);
1750*61046927SAndroid Build Coastguard Worker       if (drm_format == DRM_FORMAT_INVALID) {
1751*61046927SAndroid Build Coastguard Worker          ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
1752*61046927SAndroid Build Coastguard Worker          goto fail;
1753*61046927SAndroid Build Coastguard Worker       }
1754*61046927SAndroid Build Coastguard Worker 
1755*61046927SAndroid Build Coastguard Worker       /* If the driver stores all planes contiguously in memory, only one
1756*61046927SAndroid Build Coastguard Worker        * handle needs to be exported. resource_get_info is used to obtain
1757*61046927SAndroid Build Coastguard Worker        * pitch and offset for each layer. */
1758*61046927SAndroid Build Coastguard Worker       if (!desc->num_objects || !supports_contiguous_planes) {
1759*61046927SAndroid Build Coastguard Worker          memset(&whandle, 0, sizeof(whandle));
1760*61046927SAndroid Build Coastguard Worker          whandle.type = WINSYS_HANDLE_TYPE_FD;
1761*61046927SAndroid Build Coastguard Worker 
1762*61046927SAndroid Build Coastguard Worker          if (!screen->resource_get_handle(screen, drv->pipe, resource,
1763*61046927SAndroid Build Coastguard Worker                                           &whandle, usage)) {
1764*61046927SAndroid Build Coastguard Worker             ret = VA_STATUS_ERROR_INVALID_SURFACE;
1765*61046927SAndroid Build Coastguard Worker             goto fail;
1766*61046927SAndroid Build Coastguard Worker          }
1767*61046927SAndroid Build Coastguard Worker 
1768*61046927SAndroid Build Coastguard Worker          desc->objects[desc->num_objects].fd = (int) whandle.handle;
1769*61046927SAndroid Build Coastguard Worker          /* As per VADRMPRIMESurfaceDescriptor documentation, size must be the
1770*61046927SAndroid Build Coastguard Worker          * "Total size of this object (may include regions which are not part
1771*61046927SAndroid Build Coastguard Worker          * of the surface)."" */
1772*61046927SAndroid Build Coastguard Worker          desc->objects[desc->num_objects].size = (uint32_t) whandle.size;
1773*61046927SAndroid Build Coastguard Worker          desc->objects[desc->num_objects].drm_format_modifier = whandle.modifier;
1774*61046927SAndroid Build Coastguard Worker 
1775*61046927SAndroid Build Coastguard Worker          desc->num_objects++;
1776*61046927SAndroid Build Coastguard Worker       }
1777*61046927SAndroid Build Coastguard Worker 
1778*61046927SAndroid Build Coastguard Worker       if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) {
1779*61046927SAndroid Build Coastguard Worker          desc->layers[0].object_index[p] = desc->num_objects - 1;
1780*61046927SAndroid Build Coastguard Worker 
1781*61046927SAndroid Build Coastguard Worker          if (supports_contiguous_planes) {
1782*61046927SAndroid Build Coastguard Worker             screen->resource_get_info(screen, resource, &desc->layers[0].pitch[p], &desc->layers[0].offset[p]);
1783*61046927SAndroid Build Coastguard Worker          } else {
1784*61046927SAndroid Build Coastguard Worker             desc->layers[0].pitch[p] = whandle.stride;
1785*61046927SAndroid Build Coastguard Worker             desc->layers[0].offset[p] = whandle.offset;
1786*61046927SAndroid Build Coastguard Worker          }
1787*61046927SAndroid Build Coastguard Worker       } else {
1788*61046927SAndroid Build Coastguard Worker          desc->layers[p].drm_format      = drm_format;
1789*61046927SAndroid Build Coastguard Worker          desc->layers[p].num_planes      = 1;
1790*61046927SAndroid Build Coastguard Worker          desc->layers[p].object_index[0] = desc->num_objects - 1;
1791*61046927SAndroid Build Coastguard Worker 
1792*61046927SAndroid Build Coastguard Worker          if (supports_contiguous_planes) {
1793*61046927SAndroid Build Coastguard Worker             screen->resource_get_info(screen, resource, &desc->layers[p].pitch[0], &desc->layers[p].offset[0]);
1794*61046927SAndroid Build Coastguard Worker          } else {
1795*61046927SAndroid Build Coastguard Worker             desc->layers[p].pitch[0] = whandle.stride;
1796*61046927SAndroid Build Coastguard Worker             desc->layers[p].offset[0] = whandle.offset;
1797*61046927SAndroid Build Coastguard Worker          }
1798*61046927SAndroid Build Coastguard Worker       }
1799*61046927SAndroid Build Coastguard Worker    }
1800*61046927SAndroid Build Coastguard Worker 
1801*61046927SAndroid Build Coastguard Worker    if (flags & VA_EXPORT_SURFACE_COMPOSED_LAYERS) {
1802*61046927SAndroid Build Coastguard Worker       uint32_t drm_format = pipe_format_to_drm_format(surf->buffer->buffer_format);
1803*61046927SAndroid Build Coastguard Worker       if (drm_format == DRM_FORMAT_INVALID) {
1804*61046927SAndroid Build Coastguard Worker          ret = VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
1805*61046927SAndroid Build Coastguard Worker          goto fail;
1806*61046927SAndroid Build Coastguard Worker       }
1807*61046927SAndroid Build Coastguard Worker 
1808*61046927SAndroid Build Coastguard Worker       desc->num_layers = 1;
1809*61046927SAndroid Build Coastguard Worker       desc->layers[0].drm_format = drm_format;
1810*61046927SAndroid Build Coastguard Worker       desc->layers[0].num_planes = p;
1811*61046927SAndroid Build Coastguard Worker    } else {
1812*61046927SAndroid Build Coastguard Worker       desc->num_layers = p;
1813*61046927SAndroid Build Coastguard Worker    }
1814*61046927SAndroid Build Coastguard Worker #endif
1815*61046927SAndroid Build Coastguard Worker 
1816*61046927SAndroid Build Coastguard Worker    drv->has_external_handles = true;
1817*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
1818*61046927SAndroid Build Coastguard Worker 
1819*61046927SAndroid Build Coastguard Worker    return VA_STATUS_SUCCESS;
1820*61046927SAndroid Build Coastguard Worker 
1821*61046927SAndroid Build Coastguard Worker fail:
1822*61046927SAndroid Build Coastguard Worker #ifndef _WIN32
1823*61046927SAndroid Build Coastguard Worker    for (i = 0; i < desc->num_objects; i++)
1824*61046927SAndroid Build Coastguard Worker       close(desc->objects[i].fd);
1825*61046927SAndroid Build Coastguard Worker #else
1826*61046927SAndroid Build Coastguard Worker    if(whandle.handle)
1827*61046927SAndroid Build Coastguard Worker       CloseHandle(whandle.handle);
1828*61046927SAndroid Build Coastguard Worker #endif
1829*61046927SAndroid Build Coastguard Worker 
1830*61046927SAndroid Build Coastguard Worker    mtx_unlock(&drv->mutex);
1831*61046927SAndroid Build Coastguard Worker 
1832*61046927SAndroid Build Coastguard Worker    return ret;
1833*61046927SAndroid Build Coastguard Worker }
1834*61046927SAndroid Build Coastguard Worker #endif
1835