1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4bf215546Sopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc.
5bf215546Sopenharmony_ci * All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
9bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
10bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
11bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
12bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
13bf215546Sopenharmony_ci * the following conditions:
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
16bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
17bf215546Sopenharmony_ci * of the Software.
18bf215546Sopenharmony_ci *
19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26bf215546Sopenharmony_ci *
27bf215546Sopenharmony_ci **************************************************************************/
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "pipe/p_screen.h"
30bf215546Sopenharmony_ci#include "frontend/drm_driver.h"
31bf215546Sopenharmony_ci#include "util/u_memory.h"
32bf215546Sopenharmony_ci#include "util/u_handle_table.h"
33bf215546Sopenharmony_ci#include "util/u_transfer.h"
34bf215546Sopenharmony_ci#include "vl/vl_winsys.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#include "va_private.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ciVAStatus
39bf215546Sopenharmony_civlVaCreateBuffer(VADriverContextP ctx, VAContextID context, VABufferType type,
40bf215546Sopenharmony_ci                 unsigned int size, unsigned int num_elements, void *data,
41bf215546Sopenharmony_ci                 VABufferID *buf_id)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   vlVaDriver *drv;
44bf215546Sopenharmony_ci   vlVaBuffer *buf;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci   if (!ctx)
47bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
48bf215546Sopenharmony_ci
49bf215546Sopenharmony_ci   buf = CALLOC(1, sizeof(vlVaBuffer));
50bf215546Sopenharmony_ci   if (!buf)
51bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci   buf->type = type;
54bf215546Sopenharmony_ci   buf->size = size;
55bf215546Sopenharmony_ci   buf->num_elements = num_elements;
56bf215546Sopenharmony_ci   buf->data = MALLOC(size * num_elements);
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   if (!buf->data) {
59bf215546Sopenharmony_ci      FREE(buf);
60bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
61bf215546Sopenharmony_ci   }
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_ci   if (data)
64bf215546Sopenharmony_ci      memcpy(buf->data, data, size * num_elements);
65bf215546Sopenharmony_ci
66bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
67bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
68bf215546Sopenharmony_ci   *buf_id = handle_table_add(drv->htab, buf);
69bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
72bf215546Sopenharmony_ci}
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ciVAStatus
75bf215546Sopenharmony_civlVaBufferSetNumElements(VADriverContextP ctx, VABufferID buf_id,
76bf215546Sopenharmony_ci                         unsigned int num_elements)
77bf215546Sopenharmony_ci{
78bf215546Sopenharmony_ci   vlVaDriver *drv;
79bf215546Sopenharmony_ci   vlVaBuffer *buf;
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   if (!ctx)
82bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
85bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
86bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
87bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
88bf215546Sopenharmony_ci   if (!buf)
89bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci   if (buf->derived_surface.resource)
92bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   buf->data = REALLOC(buf->data, buf->size * buf->num_elements,
95bf215546Sopenharmony_ci                       buf->size * num_elements);
96bf215546Sopenharmony_ci   buf->num_elements = num_elements;
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci   if (!buf->data)
99bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
102bf215546Sopenharmony_ci}
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ciVAStatus
105bf215546Sopenharmony_civlVaMapBuffer(VADriverContextP ctx, VABufferID buf_id, void **pbuff)
106bf215546Sopenharmony_ci{
107bf215546Sopenharmony_ci   vlVaDriver *drv;
108bf215546Sopenharmony_ci   vlVaBuffer *buf;
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   if (!ctx)
111bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
114bf215546Sopenharmony_ci   if (!drv)
115bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ci   if (!pbuff)
118bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_PARAMETER;
119bf215546Sopenharmony_ci
120bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
121bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
122bf215546Sopenharmony_ci   if (!buf || buf->export_refcount > 0) {
123bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
124bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
125bf215546Sopenharmony_ci   }
126bf215546Sopenharmony_ci
127bf215546Sopenharmony_ci   if (buf->derived_surface.resource) {
128bf215546Sopenharmony_ci      struct pipe_resource *resource;
129bf215546Sopenharmony_ci      struct pipe_box box = {};
130bf215546Sopenharmony_ci      void *(*map_func)(struct pipe_context *,
131bf215546Sopenharmony_ci             struct pipe_resource *resource,
132bf215546Sopenharmony_ci             unsigned level,
133bf215546Sopenharmony_ci             unsigned usage,  /* a combination of PIPE_MAP_x */
134bf215546Sopenharmony_ci             const struct pipe_box *,
135bf215546Sopenharmony_ci             struct pipe_transfer **out_transfer);
136bf215546Sopenharmony_ci
137bf215546Sopenharmony_ci      resource = buf->derived_surface.resource;
138bf215546Sopenharmony_ci      box.width = resource->width0;
139bf215546Sopenharmony_ci      box.height = resource->height0;
140bf215546Sopenharmony_ci      box.depth = resource->depth0;
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci      if (resource->target == PIPE_BUFFER)
143bf215546Sopenharmony_ci         map_func = drv->pipe->buffer_map;
144bf215546Sopenharmony_ci      else
145bf215546Sopenharmony_ci         map_func = drv->pipe->texture_map;
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci      *pbuff = map_func(drv->pipe, resource, 0, PIPE_MAP_WRITE,
148bf215546Sopenharmony_ci                        &box, &buf->derived_surface.transfer);
149bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci      if (!buf->derived_surface.transfer || !*pbuff)
152bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_BUFFER;
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci      if (buf->type == VAEncCodedBufferType) {
155bf215546Sopenharmony_ci         ((VACodedBufferSegment*)buf->data)->buf = *pbuff;
156bf215546Sopenharmony_ci         ((VACodedBufferSegment*)buf->data)->size = buf->coded_size;
157bf215546Sopenharmony_ci         ((VACodedBufferSegment*)buf->data)->next = NULL;
158bf215546Sopenharmony_ci         *pbuff = buf->data;
159bf215546Sopenharmony_ci      }
160bf215546Sopenharmony_ci   } else {
161bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
162bf215546Sopenharmony_ci      *pbuff = buf->data;
163bf215546Sopenharmony_ci   }
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
166bf215546Sopenharmony_ci}
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ciVAStatus
169bf215546Sopenharmony_civlVaUnmapBuffer(VADriverContextP ctx, VABufferID buf_id)
170bf215546Sopenharmony_ci{
171bf215546Sopenharmony_ci   vlVaDriver *drv;
172bf215546Sopenharmony_ci   vlVaBuffer *buf;
173bf215546Sopenharmony_ci   struct pipe_resource *resource;
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_ci   if (!ctx)
176bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
179bf215546Sopenharmony_ci   if (!drv)
180bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
183bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
184bf215546Sopenharmony_ci   if (!buf || buf->export_refcount > 0) {
185bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
186bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
187bf215546Sopenharmony_ci   }
188bf215546Sopenharmony_ci
189bf215546Sopenharmony_ci   resource = buf->derived_surface.resource;
190bf215546Sopenharmony_ci   if (resource) {
191bf215546Sopenharmony_ci      void (*unmap_func)(struct pipe_context *pipe,
192bf215546Sopenharmony_ci                         struct pipe_transfer *transfer);
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci      if (!buf->derived_surface.transfer) {
195bf215546Sopenharmony_ci         mtx_unlock(&drv->mutex);
196bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_BUFFER;
197bf215546Sopenharmony_ci      }
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci      if (resource->target == PIPE_BUFFER)
200bf215546Sopenharmony_ci         unmap_func = pipe_buffer_unmap;
201bf215546Sopenharmony_ci      else
202bf215546Sopenharmony_ci         unmap_func = pipe_texture_unmap;
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci      unmap_func(drv->pipe, buf->derived_surface.transfer);
205bf215546Sopenharmony_ci      buf->derived_surface.transfer = NULL;
206bf215546Sopenharmony_ci   }
207bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
208bf215546Sopenharmony_ci
209bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
210bf215546Sopenharmony_ci}
211bf215546Sopenharmony_ci
212bf215546Sopenharmony_ciVAStatus
213bf215546Sopenharmony_civlVaDestroyBuffer(VADriverContextP ctx, VABufferID buf_id)
214bf215546Sopenharmony_ci{
215bf215546Sopenharmony_ci   vlVaDriver *drv;
216bf215546Sopenharmony_ci   vlVaBuffer *buf;
217bf215546Sopenharmony_ci
218bf215546Sopenharmony_ci   if (!ctx)
219bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
220bf215546Sopenharmony_ci
221bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
222bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
223bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
224bf215546Sopenharmony_ci   if (!buf) {
225bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
226bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
227bf215546Sopenharmony_ci   }
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci   if (buf->derived_surface.resource) {
230bf215546Sopenharmony_ci      pipe_resource_reference(&buf->derived_surface.resource, NULL);
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci      if (buf->derived_image_buffer)
233bf215546Sopenharmony_ci         buf->derived_image_buffer->destroy(buf->derived_image_buffer);
234bf215546Sopenharmony_ci   }
235bf215546Sopenharmony_ci
236bf215546Sopenharmony_ci   FREE(buf->data);
237bf215546Sopenharmony_ci   FREE(buf);
238bf215546Sopenharmony_ci   handle_table_remove(VL_VA_DRIVER(ctx)->htab, buf_id);
239bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
242bf215546Sopenharmony_ci}
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ciVAStatus
245bf215546Sopenharmony_civlVaBufferInfo(VADriverContextP ctx, VABufferID buf_id, VABufferType *type,
246bf215546Sopenharmony_ci               unsigned int *size, unsigned int *num_elements)
247bf215546Sopenharmony_ci{
248bf215546Sopenharmony_ci   vlVaDriver *drv;
249bf215546Sopenharmony_ci   vlVaBuffer *buf;
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   if (!ctx)
252bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
255bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
256bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
257bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
258bf215546Sopenharmony_ci   if (!buf)
259bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   *type = buf->type;
262bf215546Sopenharmony_ci   *size = buf->size;
263bf215546Sopenharmony_ci   *num_elements = buf->num_elements;
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
266bf215546Sopenharmony_ci}
267bf215546Sopenharmony_ci
268bf215546Sopenharmony_ciVAStatus
269bf215546Sopenharmony_civlVaAcquireBufferHandle(VADriverContextP ctx, VABufferID buf_id,
270bf215546Sopenharmony_ci                        VABufferInfo *out_buf_info)
271bf215546Sopenharmony_ci{
272bf215546Sopenharmony_ci   vlVaDriver *drv;
273bf215546Sopenharmony_ci   uint32_t i;
274bf215546Sopenharmony_ci   uint32_t mem_type;
275bf215546Sopenharmony_ci   vlVaBuffer *buf ;
276bf215546Sopenharmony_ci   struct pipe_screen *screen;
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci   /* List of supported memory types, in preferred order. */
279bf215546Sopenharmony_ci   static const uint32_t mem_types[] = {
280bf215546Sopenharmony_ci      VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME,
281bf215546Sopenharmony_ci      0
282bf215546Sopenharmony_ci   };
283bf215546Sopenharmony_ci
284bf215546Sopenharmony_ci   if (!ctx)
285bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
288bf215546Sopenharmony_ci   screen = VL_VA_PSCREEN(ctx);
289bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
290bf215546Sopenharmony_ci   buf = handle_table_get(VL_VA_DRIVER(ctx)->htab, buf_id);
291bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci   if (!buf)
294bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci   /* Only VA surface|image like buffers are supported for now .*/
297bf215546Sopenharmony_ci   if (buf->type != VAImageBufferType)
298bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   if (!out_buf_info)
301bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_PARAMETER;
302bf215546Sopenharmony_ci
303bf215546Sopenharmony_ci   if (!out_buf_info->mem_type)
304bf215546Sopenharmony_ci      mem_type = mem_types[0];
305bf215546Sopenharmony_ci   else {
306bf215546Sopenharmony_ci      mem_type = 0;
307bf215546Sopenharmony_ci      for (i = 0; mem_types[i] != 0; i++) {
308bf215546Sopenharmony_ci         if (out_buf_info->mem_type & mem_types[i]) {
309bf215546Sopenharmony_ci            mem_type = out_buf_info->mem_type;
310bf215546Sopenharmony_ci            break;
311bf215546Sopenharmony_ci         }
312bf215546Sopenharmony_ci      }
313bf215546Sopenharmony_ci      if (!mem_type)
314bf215546Sopenharmony_ci         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
315bf215546Sopenharmony_ci   }
316bf215546Sopenharmony_ci
317bf215546Sopenharmony_ci   if (!buf->derived_surface.resource)
318bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci   if (buf->export_refcount > 0) {
321bf215546Sopenharmony_ci      if (buf->export_state.mem_type != mem_type)
322bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_PARAMETER;
323bf215546Sopenharmony_ci   } else {
324bf215546Sopenharmony_ci      VABufferInfo * const buf_info = &buf->export_state;
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_ci      switch (mem_type) {
327bf215546Sopenharmony_ci      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: {
328bf215546Sopenharmony_ci         struct winsys_handle whandle;
329bf215546Sopenharmony_ci
330bf215546Sopenharmony_ci         mtx_lock(&drv->mutex);
331bf215546Sopenharmony_ci         drv->pipe->flush(drv->pipe, NULL, 0);
332bf215546Sopenharmony_ci
333bf215546Sopenharmony_ci         memset(&whandle, 0, sizeof(whandle));
334bf215546Sopenharmony_ci         whandle.type = WINSYS_HANDLE_TYPE_FD;
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci         if (!screen->resource_get_handle(screen, drv->pipe,
337bf215546Sopenharmony_ci                                          buf->derived_surface.resource,
338bf215546Sopenharmony_ci                                          &whandle, PIPE_HANDLE_USAGE_FRAMEBUFFER_WRITE)) {
339bf215546Sopenharmony_ci            mtx_unlock(&drv->mutex);
340bf215546Sopenharmony_ci            return VA_STATUS_ERROR_INVALID_BUFFER;
341bf215546Sopenharmony_ci         }
342bf215546Sopenharmony_ci
343bf215546Sopenharmony_ci         mtx_unlock(&drv->mutex);
344bf215546Sopenharmony_ci
345bf215546Sopenharmony_ci         buf_info->handle = (intptr_t)whandle.handle;
346bf215546Sopenharmony_ci         break;
347bf215546Sopenharmony_ci      }
348bf215546Sopenharmony_ci      default:
349bf215546Sopenharmony_ci         return VA_STATUS_ERROR_UNSUPPORTED_MEMORY_TYPE;
350bf215546Sopenharmony_ci      }
351bf215546Sopenharmony_ci
352bf215546Sopenharmony_ci      buf_info->type = buf->type;
353bf215546Sopenharmony_ci      buf_info->mem_type = mem_type;
354bf215546Sopenharmony_ci      buf_info->mem_size = buf->num_elements * buf->size;
355bf215546Sopenharmony_ci   }
356bf215546Sopenharmony_ci
357bf215546Sopenharmony_ci   buf->export_refcount++;
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci   *out_buf_info = buf->export_state;
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
362bf215546Sopenharmony_ci}
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ciVAStatus
365bf215546Sopenharmony_civlVaReleaseBufferHandle(VADriverContextP ctx, VABufferID buf_id)
366bf215546Sopenharmony_ci{
367bf215546Sopenharmony_ci   vlVaDriver *drv;
368bf215546Sopenharmony_ci   vlVaBuffer *buf;
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci   if (!ctx)
371bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
374bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
375bf215546Sopenharmony_ci   buf = handle_table_get(drv->htab, buf_id);
376bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci   if (!buf)
379bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_ci   if (buf->export_refcount == 0)
382bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_BUFFER;
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   if (--buf->export_refcount == 0) {
385bf215546Sopenharmony_ci      VABufferInfo * const buf_info = &buf->export_state;
386bf215546Sopenharmony_ci
387bf215546Sopenharmony_ci      switch (buf_info->mem_type) {
388bf215546Sopenharmony_ci      case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME:
389bf215546Sopenharmony_ci         close((intptr_t)buf_info->handle);
390bf215546Sopenharmony_ci         break;
391bf215546Sopenharmony_ci      default:
392bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_BUFFER;
393bf215546Sopenharmony_ci      }
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci      buf_info->mem_type = 0;
396bf215546Sopenharmony_ci   }
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
399bf215546Sopenharmony_ci}
400