st/vdpau: Various whitespace cleanups found while reading some code
[mesa.git] / src / gallium / state_trackers / vdpau / output.c
1 /**************************************************************************
2 *
3 * Copyright 2010 Thomas Balling Sørensen.
4 * Copyright 2011 Christian König.
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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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 <vdpau/vdpau.h>
30
31 #include "util/u_debug.h"
32 #include "util/u_memory.h"
33 #include "util/u_sampler.h"
34 #include "util/u_format.h"
35
36 #include "vdpau_private.h"
37
38 VdpStatus
39 vlVdpOutputSurfaceCreate(VdpDevice device,
40 VdpRGBAFormat rgba_format,
41 uint32_t width, uint32_t height,
42 VdpOutputSurface *surface)
43 {
44 struct pipe_context *pipe;
45 struct pipe_resource res_tmpl, *res;
46 struct pipe_sampler_view sv_templ;
47 struct pipe_surface surf_templ;
48
49 vlVdpOutputSurface *vlsurface = NULL;
50
51 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Creating output surface\n");
52 if (!(width && height))
53 return VDP_STATUS_INVALID_SIZE;
54
55 vlVdpDevice *dev = vlGetDataHTAB(device);
56 if (!dev)
57 return VDP_STATUS_INVALID_HANDLE;
58
59 pipe = dev->context->pipe;
60 if (!pipe)
61 return VDP_STATUS_INVALID_HANDLE;
62
63 vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface));
64 if (!vlsurface)
65 return VDP_STATUS_RESOURCES;
66
67 vlsurface->device = dev;
68
69 memset(&res_tmpl, 0, sizeof(res_tmpl));
70
71 res_tmpl.target = PIPE_TEXTURE_2D;
72 res_tmpl.format = FormatRGBAToPipe(rgba_format);
73 res_tmpl.width0 = width;
74 res_tmpl.height0 = height;
75 res_tmpl.depth0 = 1;
76 res_tmpl.array_size = 1;
77 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
78 res_tmpl.usage = PIPE_USAGE_STATIC;
79
80 res = pipe->screen->resource_create(pipe->screen, &res_tmpl);
81 if (!res) {
82 FREE(dev);
83 return VDP_STATUS_ERROR;
84 }
85
86 memset(&sv_templ, 0, sizeof(sv_templ));
87 u_sampler_view_default_template(&sv_templ, res, res->format);
88 vlsurface->sampler_view = pipe->create_sampler_view(pipe, res, &sv_templ);
89 if (!vlsurface->sampler_view) {
90 pipe_resource_reference(&res, NULL);
91 FREE(dev);
92 return VDP_STATUS_ERROR;
93 }
94
95 memset(&surf_templ, 0, sizeof(surf_templ));
96 surf_templ.format = res->format;
97 surf_templ.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
98 vlsurface->surface = pipe->create_surface(pipe, res, &surf_templ);
99 if (!vlsurface->surface) {
100 pipe_resource_reference(&res, NULL);
101 FREE(dev);
102 return VDP_STATUS_ERROR;
103 }
104
105 *surface = vlAddDataHTAB(vlsurface);
106 if (*surface == 0) {
107 pipe_resource_reference(&res, NULL);
108 FREE(dev);
109 return VDP_STATUS_ERROR;
110 }
111
112 pipe_resource_reference(&res, NULL);
113
114 return VDP_STATUS_OK;
115 }
116
117 VdpStatus
118 vlVdpOutputSurfaceDestroy(VdpOutputSurface surface)
119 {
120 vlVdpOutputSurface *vlsurface;
121
122 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] Destroying output surface\n");
123
124 vlsurface = vlGetDataHTAB(surface);
125 if (!vlsurface)
126 return VDP_STATUS_INVALID_HANDLE;
127
128 pipe_surface_reference(&vlsurface->surface, NULL);
129 pipe_sampler_view_reference(&vlsurface->sampler_view, NULL);
130
131 vlRemoveDataHTAB(surface);
132 FREE(vlsurface);
133
134 return VDP_STATUS_OK;
135 }
136
137 VdpStatus
138 vlVdpOutputSurfaceGetParameters(VdpOutputSurface surface,
139 VdpRGBAFormat *rgba_format,
140 uint32_t *width, uint32_t *height)
141 {
142 vlVdpOutputSurface *vlsurface;
143
144 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] getting surface parameters\n");
145
146 vlsurface = vlGetDataHTAB(surface);
147 if (!vlsurface)
148 return VDP_STATUS_INVALID_HANDLE;
149
150 *rgba_format = PipeToFormatRGBA(vlsurface->sampler_view->texture->format);
151 *width = vlsurface->sampler_view->texture->width0;
152 *height = vlsurface->sampler_view->texture->height0;
153
154 return VDP_STATUS_OK;
155 }
156
157 VdpStatus
158 vlVdpOutputSurfaceGetBitsNative(VdpOutputSurface surface,
159 VdpRect const *source_rect,
160 void *const *destination_data,
161 uint32_t const *destination_pitches)
162 {
163 return VDP_STATUS_NO_IMPLEMENTATION;
164 }
165
166 VdpStatus
167 vlVdpOutputSurfacePutBitsNative(VdpOutputSurface surface,
168 void const *const *source_data,
169 uint32_t const *source_pitches,
170 VdpRect const *destination_rect)
171 {
172 return VDP_STATUS_NO_IMPLEMENTATION;
173 }
174
175 VdpStatus
176 vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
177 VdpIndexedFormat source_indexed_format,
178 void const *const *source_data,
179 uint32_t const *source_pitch,
180 VdpRect const *destination_rect,
181 VdpColorTableFormat color_table_format,
182 void const *color_table)
183 {
184 vlVdpOutputSurface *vlsurface;
185 struct pipe_context *context;
186 struct vl_compositor *compositor;
187
188 enum pipe_format index_format;
189 enum pipe_format colortbl_format;
190
191 struct pipe_resource *res, res_tmpl;
192 struct pipe_sampler_view sv_tmpl;
193 struct pipe_sampler_view *sv_idx = NULL, *sv_tbl = NULL;
194
195 struct pipe_box box;
196 struct pipe_video_rect dst_rect;
197
198 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] uploading indexed output surface\n");
199
200 vlsurface = vlGetDataHTAB(surface);
201 if (!vlsurface)
202 return VDP_STATUS_INVALID_HANDLE;
203
204 context = vlsurface->device->context->pipe;
205 compositor = &vlsurface->device->compositor;
206
207 index_format = FormatIndexedToPipe(source_indexed_format);
208 if (index_format == PIPE_FORMAT_NONE)
209 return VDP_STATUS_INVALID_INDEXED_FORMAT;
210
211 if (!source_data || !source_pitch)
212 return VDP_STATUS_INVALID_POINTER;
213
214 colortbl_format = FormatColorTableToPipe(color_table_format);
215 if (colortbl_format == PIPE_FORMAT_NONE)
216 return VDP_STATUS_INVALID_COLOR_TABLE_FORMAT;
217
218 if (!color_table)
219 return VDP_STATUS_INVALID_POINTER;
220
221 memset(&res_tmpl, 0, sizeof(res_tmpl));
222 res_tmpl.target = PIPE_TEXTURE_2D;
223 res_tmpl.format = index_format;
224
225 if (destination_rect) {
226 res_tmpl.width0 = abs(destination_rect->x0-destination_rect->x1);
227 res_tmpl.height0 = abs(destination_rect->y0-destination_rect->y1);
228 } else {
229 res_tmpl.width0 = vlsurface->surface->texture->width0;
230 res_tmpl.height0 = vlsurface->surface->texture->height0;
231 }
232 res_tmpl.depth0 = 1;
233 res_tmpl.array_size = 1;
234 res_tmpl.usage = PIPE_USAGE_STAGING;
235 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
236
237 res = context->screen->resource_create(context->screen, &res_tmpl);
238 if (!res)
239 goto error_resource;
240
241 box.x = box.y = box.z = 0;
242 box.width = res->width0;
243 box.height = res->height0;
244 box.depth = res->depth0;
245
246 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box,
247 source_data[0], source_pitch[0],
248 source_pitch[0] * res->height0);
249
250 memset(&sv_tmpl, 0, sizeof(sv_tmpl));
251 u_sampler_view_default_template(&sv_tmpl, res, res->format);
252
253 sv_idx = context->create_sampler_view(context, res, &sv_tmpl);
254 pipe_resource_reference(&res, NULL);
255
256 if (!sv_idx)
257 goto error_resource;
258
259 memset(&res_tmpl, 0, sizeof(res_tmpl));
260 res_tmpl.target = PIPE_TEXTURE_1D;
261 res_tmpl.format = colortbl_format;
262 res_tmpl.width0 = 1 << util_format_get_component_bits(
263 index_format, UTIL_FORMAT_COLORSPACE_RGB, 0);
264 res_tmpl.height0 = 1;
265 res_tmpl.depth0 = 1;
266 res_tmpl.array_size = 1;
267 res_tmpl.usage = PIPE_USAGE_STAGING;
268 res_tmpl.bind = PIPE_BIND_SAMPLER_VIEW;
269
270 res = context->screen->resource_create(context->screen, &res_tmpl);
271 if (!res)
272 goto error_resource;
273
274 box.x = box.y = box.z = 0;
275 box.width = res->width0;
276 box.height = res->height0;
277 box.depth = res->depth0;
278
279 context->transfer_inline_write(context, res, 0, PIPE_TRANSFER_WRITE, &box, color_table,
280 util_format_get_stride(colortbl_format, res->width0), 0);
281
282 memset(&sv_tmpl, 0, sizeof(sv_tmpl));
283 u_sampler_view_default_template(&sv_tmpl, res, res->format);
284
285 sv_tbl = context->create_sampler_view(context, res, &sv_tmpl);
286 pipe_resource_reference(&res, NULL);
287
288 if (!sv_tbl)
289 goto error_resource;
290
291 vl_compositor_clear_layers(compositor);
292 vl_compositor_set_palette_layer(compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);
293 vl_compositor_render(compositor, vlsurface->surface,
294 RectToPipe(destination_rect, &dst_rect), NULL, false);
295
296 pipe_sampler_view_reference(&sv_idx, NULL);
297 pipe_sampler_view_reference(&sv_tbl, NULL);
298
299 return VDP_STATUS_OK;
300
301 error_resource:
302 pipe_sampler_view_reference(&sv_idx, NULL);
303 pipe_sampler_view_reference(&sv_tbl, NULL);
304 return VDP_STATUS_RESOURCES;
305 }
306
307 VdpStatus
308 vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
309 VdpYCbCrFormat source_ycbcr_format,
310 void const *const *source_data,
311 uint32_t const *source_pitches,
312 VdpRect const *destination_rect,
313 VdpCSCMatrix const *csc_matrix)
314 {
315 return VDP_STATUS_NO_IMPLEMENTATION;
316 }
317
318 static unsigned
319 BlendFactorToPipe(VdpOutputSurfaceRenderBlendFactor factor)
320 {
321 switch (factor) {
322 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO:
323 return PIPE_BLENDFACTOR_ZERO;
324 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE:
325 return PIPE_BLENDFACTOR_ONE;
326 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR:
327 return PIPE_BLENDFACTOR_SRC_COLOR;
328 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR:
329 return PIPE_BLENDFACTOR_INV_SRC_COLOR;
330 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA:
331 return PIPE_BLENDFACTOR_SRC_ALPHA;
332 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA:
333 return PIPE_BLENDFACTOR_INV_SRC_ALPHA;
334 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA:
335 return PIPE_BLENDFACTOR_DST_ALPHA;
336 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA:
337 return PIPE_BLENDFACTOR_INV_DST_ALPHA;
338 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR:
339 return PIPE_BLENDFACTOR_DST_COLOR;
340 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR:
341 return PIPE_BLENDFACTOR_INV_DST_COLOR;
342 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE:
343 return PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE;
344 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR:
345 return PIPE_BLENDFACTOR_CONST_COLOR;
346 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR:
347 return PIPE_BLENDFACTOR_INV_CONST_COLOR;
348 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA:
349 return PIPE_BLENDFACTOR_CONST_ALPHA;
350 case VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA:
351 return PIPE_BLENDFACTOR_INV_CONST_ALPHA;
352 default:
353 assert(0);
354 return PIPE_BLENDFACTOR_ONE;
355 }
356 }
357
358 static unsigned
359 BlendEquationToPipe(VdpOutputSurfaceRenderBlendEquation equation)
360 {
361 switch (equation) {
362 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT:
363 return PIPE_BLEND_SUBTRACT;
364 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT:
365 return PIPE_BLEND_REVERSE_SUBTRACT;
366 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD:
367 return PIPE_BLEND_ADD;
368 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN:
369 return PIPE_BLEND_MIN;
370 case VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX:
371 return PIPE_BLEND_MAX;
372 default:
373 assert(0);
374 return PIPE_BLEND_ADD;
375 }
376 }
377
378 static void *
379 BlenderToPipe(struct pipe_context *context,
380 VdpOutputSurfaceRenderBlendState const *blend_state)
381 {
382 struct pipe_blend_state blend;
383
384 memset(&blend, 0, sizeof blend);
385 blend.independent_blend_enable = 0;
386
387 if (blend_state) {
388 blend.rt[0].blend_enable = 1;
389 blend.rt[0].rgb_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_color);
390 blend.rt[0].rgb_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_color);
391 blend.rt[0].alpha_src_factor = BlendFactorToPipe(blend_state->blend_factor_source_alpha);
392 blend.rt[0].alpha_dst_factor = BlendFactorToPipe(blend_state->blend_factor_destination_alpha);
393 blend.rt[0].rgb_func = BlendEquationToPipe(blend_state->blend_equation_color);
394 blend.rt[0].alpha_func = BlendEquationToPipe(blend_state->blend_equation_alpha);
395 } else {
396 blend.rt[0].blend_enable = 0;
397 }
398
399 blend.logicop_enable = 0;
400 blend.logicop_func = PIPE_LOGICOP_CLEAR;
401 blend.rt[0].colormask = PIPE_MASK_RGBA;
402 blend.dither = 0;
403
404 return context->create_blend_state(context, &blend);
405 }
406
407 VdpStatus
408 vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
409 VdpRect const *destination_rect,
410 VdpOutputSurface source_surface,
411 VdpRect const *source_rect,
412 VdpColor const *colors,
413 VdpOutputSurfaceRenderBlendState const *blend_state,
414 uint32_t flags)
415 {
416 vlVdpOutputSurface *dst_vlsurface;
417 vlVdpOutputSurface *src_vlsurface;
418
419 struct pipe_context *context;
420 struct vl_compositor *compositor;
421
422 struct pipe_video_rect src_rect;
423 struct pipe_video_rect dst_rect;
424
425 void *blend;
426
427 VDPAU_MSG(VDPAU_TRACE, "[VDPAU] composing output surfaces\n");
428
429 dst_vlsurface = vlGetDataHTAB(destination_surface);
430 if (!dst_vlsurface)
431 return VDP_STATUS_INVALID_HANDLE;
432
433 src_vlsurface = vlGetDataHTAB(source_surface);
434 if (!src_vlsurface)
435 return VDP_STATUS_INVALID_HANDLE;
436
437 if (dst_vlsurface->device != src_vlsurface->device)
438 return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
439
440 context = dst_vlsurface->device->context->pipe;
441 compositor = &dst_vlsurface->device->compositor;
442
443 blend = BlenderToPipe(context, blend_state);
444
445 vl_compositor_clear_layers(compositor);
446 vl_compositor_set_layer_blend(compositor, 0, blend, false);
447 vl_compositor_set_rgba_layer(compositor, 0, src_vlsurface->sampler_view,
448 RectToPipe(source_rect, &src_rect), NULL);
449 vl_compositor_render(compositor, dst_vlsurface->surface,
450 RectToPipe(destination_rect, &dst_rect), NULL, false);
451
452 context->delete_blend_state(context, blend);
453
454 return VDP_STATUS_OK;
455 }
456
457 VdpStatus
458 vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface,
459 VdpRect const *destination_rect,
460 VdpBitmapSurface source_surface,
461 VdpRect const *source_rect,
462 VdpColor const *colors,
463 VdpOutputSurfaceRenderBlendState const *blend_state,
464 uint32_t flags)
465 {
466 return VDP_STATUS_NO_IMPLEMENTATION;
467 }