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 "util/u_memory.h"
30bf215546Sopenharmony_ci#include "util/u_handle_table.h"
31bf215546Sopenharmony_ci#include "util/u_sampler.h"
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "va_private.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_cistatic VAImageFormat subpic_formats[] = {
36bf215546Sopenharmony_ci   {
37bf215546Sopenharmony_ci   .fourcc = VA_FOURCC_BGRA,
38bf215546Sopenharmony_ci   .byte_order = VA_LSB_FIRST,
39bf215546Sopenharmony_ci   .bits_per_pixel = 32,
40bf215546Sopenharmony_ci   .depth = 32,
41bf215546Sopenharmony_ci   .red_mask   = 0x00ff0000ul,
42bf215546Sopenharmony_ci   .green_mask = 0x0000ff00ul,
43bf215546Sopenharmony_ci   .blue_mask  = 0x000000fful,
44bf215546Sopenharmony_ci   .alpha_mask = 0xff000000ul,
45bf215546Sopenharmony_ci   },
46bf215546Sopenharmony_ci};
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ciVAStatus
49bf215546Sopenharmony_civlVaQuerySubpictureFormats(VADriverContextP ctx, VAImageFormat *format_list,
50bf215546Sopenharmony_ci                           unsigned int *flags, unsigned int *num_formats)
51bf215546Sopenharmony_ci{
52bf215546Sopenharmony_ci   if (!ctx)
53bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   if (!(format_list && flags && num_formats))
56bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNKNOWN;
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   *num_formats = sizeof(subpic_formats)/sizeof(VAImageFormat);
59bf215546Sopenharmony_ci   memcpy(format_list, subpic_formats, sizeof(subpic_formats));
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
62bf215546Sopenharmony_ci}
63bf215546Sopenharmony_ci
64bf215546Sopenharmony_ciVAStatus
65bf215546Sopenharmony_civlVaCreateSubpicture(VADriverContextP ctx, VAImageID image,
66bf215546Sopenharmony_ci                     VASubpictureID *subpicture)
67bf215546Sopenharmony_ci{
68bf215546Sopenharmony_ci   vlVaDriver *drv;
69bf215546Sopenharmony_ci   vlVaSubpicture *sub;
70bf215546Sopenharmony_ci   VAImage *img;
71bf215546Sopenharmony_ci
72bf215546Sopenharmony_ci   if (!ctx)
73bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
76bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
77bf215546Sopenharmony_ci   img = handle_table_get(drv->htab, image);
78bf215546Sopenharmony_ci   if (!img) {
79bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
80bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_IMAGE;
81bf215546Sopenharmony_ci   }
82bf215546Sopenharmony_ci
83bf215546Sopenharmony_ci   sub = CALLOC(1, sizeof(*sub));
84bf215546Sopenharmony_ci   if (!sub) {
85bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
86bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
87bf215546Sopenharmony_ci   }
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   sub->image = img;
90bf215546Sopenharmony_ci   *subpicture = handle_table_add(VL_VA_DRIVER(ctx)->htab, sub);
91bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
94bf215546Sopenharmony_ci}
95bf215546Sopenharmony_ci
96bf215546Sopenharmony_ciVAStatus
97bf215546Sopenharmony_civlVaDestroySubpicture(VADriverContextP ctx, VASubpictureID subpicture)
98bf215546Sopenharmony_ci{
99bf215546Sopenharmony_ci   vlVaDriver *drv;
100bf215546Sopenharmony_ci   vlVaSubpicture *sub;
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_ci   if (!ctx)
103bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
106bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   sub = handle_table_get(drv->htab, subpicture);
109bf215546Sopenharmony_ci   if (!sub) {
110bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
111bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_SUBPICTURE;
112bf215546Sopenharmony_ci   }
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci   FREE(sub);
115bf215546Sopenharmony_ci   handle_table_remove(drv->htab, subpicture);
116bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
117bf215546Sopenharmony_ci
118bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_ciVAStatus
122bf215546Sopenharmony_civlVaSubpictureImage(VADriverContextP ctx, VASubpictureID subpicture, VAImageID image)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   vlVaDriver *drv;
125bf215546Sopenharmony_ci   vlVaSubpicture *sub;
126bf215546Sopenharmony_ci   VAImage *img;
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   if (!ctx)
129bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
132bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
133bf215546Sopenharmony_ci
134bf215546Sopenharmony_ci   img = handle_table_get(drv->htab, image);
135bf215546Sopenharmony_ci   if (!img) {
136bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
137bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_IMAGE;
138bf215546Sopenharmony_ci   }
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   sub = handle_table_get(drv->htab, subpicture);
141bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
142bf215546Sopenharmony_ci   if (!sub)
143bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_SUBPICTURE;
144bf215546Sopenharmony_ci
145bf215546Sopenharmony_ci   sub->image = img;
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
148bf215546Sopenharmony_ci}
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ciVAStatus
151bf215546Sopenharmony_civlVaSetSubpictureChromakey(VADriverContextP ctx, VASubpictureID subpicture,
152bf215546Sopenharmony_ci                           unsigned int chromakey_min, unsigned int chromakey_max, unsigned int chromakey_mask)
153bf215546Sopenharmony_ci{
154bf215546Sopenharmony_ci   if (!ctx)
155bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci   return VA_STATUS_ERROR_UNIMPLEMENTED;
158bf215546Sopenharmony_ci}
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ciVAStatus
161bf215546Sopenharmony_civlVaSetSubpictureGlobalAlpha(VADriverContextP ctx, VASubpictureID subpicture, float global_alpha)
162bf215546Sopenharmony_ci{
163bf215546Sopenharmony_ci   if (!ctx)
164bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   return VA_STATUS_ERROR_UNIMPLEMENTED;
167bf215546Sopenharmony_ci}
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ciVAStatus
170bf215546Sopenharmony_civlVaAssociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
171bf215546Sopenharmony_ci                        VASurfaceID *target_surfaces, int num_surfaces,
172bf215546Sopenharmony_ci                        short src_x, short src_y, unsigned short src_width,
173bf215546Sopenharmony_ci                        unsigned short src_height, short dest_x, short dest_y,
174bf215546Sopenharmony_ci                        unsigned short dest_width, unsigned short dest_height,
175bf215546Sopenharmony_ci                        unsigned int flags)
176bf215546Sopenharmony_ci{
177bf215546Sopenharmony_ci   vlVaSubpicture *sub;
178bf215546Sopenharmony_ci   struct pipe_resource tex_temp, *tex;
179bf215546Sopenharmony_ci   struct pipe_sampler_view sampler_templ;
180bf215546Sopenharmony_ci   vlVaDriver *drv;
181bf215546Sopenharmony_ci   vlVaSurface *surf;
182bf215546Sopenharmony_ci   int i;
183bf215546Sopenharmony_ci   struct u_rect src_rect = {src_x, src_x + src_width, src_y, src_y + src_height};
184bf215546Sopenharmony_ci   struct u_rect dst_rect = {dest_x, dest_x + dest_width, dest_y, dest_y + dest_height};
185bf215546Sopenharmony_ci
186bf215546Sopenharmony_ci   if (!ctx)
187bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
188bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
189bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci   sub = handle_table_get(drv->htab, subpicture);
192bf215546Sopenharmony_ci   if (!sub) {
193bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
194bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_SUBPICTURE;
195bf215546Sopenharmony_ci   }
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci   for (i = 0; i < num_surfaces; i++) {
198bf215546Sopenharmony_ci      surf = handle_table_get(drv->htab, target_surfaces[i]);
199bf215546Sopenharmony_ci      if (!surf) {
200bf215546Sopenharmony_ci         mtx_unlock(&drv->mutex);
201bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_SURFACE;
202bf215546Sopenharmony_ci      }
203bf215546Sopenharmony_ci   }
204bf215546Sopenharmony_ci
205bf215546Sopenharmony_ci   sub->src_rect = src_rect;
206bf215546Sopenharmony_ci   sub->dst_rect = dst_rect;
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   memset(&tex_temp, 0, sizeof(tex_temp));
209bf215546Sopenharmony_ci   tex_temp.target = PIPE_TEXTURE_2D;
210bf215546Sopenharmony_ci   tex_temp.format = PIPE_FORMAT_B8G8R8A8_UNORM;
211bf215546Sopenharmony_ci   tex_temp.last_level = 0;
212bf215546Sopenharmony_ci   tex_temp.width0 = src_width;
213bf215546Sopenharmony_ci   tex_temp.height0 = src_height;
214bf215546Sopenharmony_ci   tex_temp.depth0 = 1;
215bf215546Sopenharmony_ci   tex_temp.array_size = 1;
216bf215546Sopenharmony_ci   tex_temp.usage = PIPE_USAGE_DYNAMIC;
217bf215546Sopenharmony_ci   tex_temp.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
218bf215546Sopenharmony_ci   tex_temp.flags = 0;
219bf215546Sopenharmony_ci   if (!drv->pipe->screen->is_format_supported(
220bf215546Sopenharmony_ci          drv->pipe->screen, tex_temp.format, tex_temp.target,
221bf215546Sopenharmony_ci          tex_temp.nr_samples, tex_temp.nr_storage_samples, tex_temp.bind)) {
222bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
223bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
224bf215546Sopenharmony_ci   }
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci   tex = drv->pipe->screen->resource_create(drv->pipe->screen, &tex_temp);
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   memset(&sampler_templ, 0, sizeof(sampler_templ));
229bf215546Sopenharmony_ci   u_sampler_view_default_template(&sampler_templ, tex, tex->format);
230bf215546Sopenharmony_ci   sub->sampler = drv->pipe->create_sampler_view(drv->pipe, tex, &sampler_templ);
231bf215546Sopenharmony_ci   pipe_resource_reference(&tex, NULL);
232bf215546Sopenharmony_ci   if (!sub->sampler) {
233bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
234bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
235bf215546Sopenharmony_ci   }
236bf215546Sopenharmony_ci
237bf215546Sopenharmony_ci   for (i = 0; i < num_surfaces; i++) {
238bf215546Sopenharmony_ci      surf = handle_table_get(drv->htab, target_surfaces[i]);
239bf215546Sopenharmony_ci      util_dynarray_append(&surf->subpics, vlVaSubpicture *, sub);
240bf215546Sopenharmony_ci   }
241bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
242bf215546Sopenharmony_ci
243bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
244bf215546Sopenharmony_ci}
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ciVAStatus
247bf215546Sopenharmony_civlVaDeassociateSubpicture(VADriverContextP ctx, VASubpictureID subpicture,
248bf215546Sopenharmony_ci                          VASurfaceID *target_surfaces, int num_surfaces)
249bf215546Sopenharmony_ci{
250bf215546Sopenharmony_ci   int i;
251bf215546Sopenharmony_ci   int j;
252bf215546Sopenharmony_ci   vlVaSurface *surf;
253bf215546Sopenharmony_ci   vlVaSubpicture *sub, **array;
254bf215546Sopenharmony_ci   vlVaDriver *drv;
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   if (!ctx)
257bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
258bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
259bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci   sub = handle_table_get(drv->htab, subpicture);
262bf215546Sopenharmony_ci   if (!sub) {
263bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
264bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_SUBPICTURE;
265bf215546Sopenharmony_ci   }
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci   for (i = 0; i < num_surfaces; i++) {
268bf215546Sopenharmony_ci      surf = handle_table_get(drv->htab, target_surfaces[i]);
269bf215546Sopenharmony_ci      if (!surf) {
270bf215546Sopenharmony_ci         mtx_unlock(&drv->mutex);
271bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_SURFACE;
272bf215546Sopenharmony_ci      }
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_ci      array = surf->subpics.data;
275bf215546Sopenharmony_ci      if (!array)
276bf215546Sopenharmony_ci         continue;
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci      for (j = 0; j < surf->subpics.size/sizeof(vlVaSubpicture *); j++) {
279bf215546Sopenharmony_ci         if (array[j] == sub)
280bf215546Sopenharmony_ci            array[j] = NULL;
281bf215546Sopenharmony_ci      }
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci      while (surf->subpics.size && util_dynarray_top(&surf->subpics, vlVaSubpicture *) == NULL)
284bf215546Sopenharmony_ci         (void)util_dynarray_pop(&surf->subpics, vlVaSubpicture *);
285bf215546Sopenharmony_ci   }
286bf215546Sopenharmony_ci   pipe_sampler_view_reference(&sub->sampler,NULL);
287bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
290bf215546Sopenharmony_ci}
291