~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/frontends/va/buffer.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

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