[g3dvl] static usage for intermediate buffer
[mesa.git] / src / gallium / drivers / softpipe / sp_video_context.c
1 /**************************************************************************
2 *
3 * Copyright 2009 Younes Manton.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 #include "util/u_inlines.h"
29 #include "util/u_memory.h"
30
31 #include "sp_video_context.h"
32 #include <util/u_inlines.h>
33 #include <util/u_memory.h>
34 #include <util/u_keymap.h>
35 #include <util/u_rect.h>
36 #include <util/u_video.h>
37 #include <util/u_surface.h>
38 #include "sp_public.h"
39 #include "sp_texture.h"
40
41 #define NUM_BUFFERS 2
42
43 static void
44 flush_buffer(struct sp_mpeg12_context *ctx)
45 {
46 assert(ctx);
47
48 if(ctx->mc_buffer != NULL) {
49
50 vl_mpeg12_mc_unmap_buffer(&ctx->mc_renderer, ctx->mc_buffer);
51 vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, ctx->mc_buffer);
52
53 ctx->mc_buffer = NULL;
54 }
55 }
56
57 static void
58 rotate_buffer(struct sp_mpeg12_context *ctx)
59 {
60 static unsigned key = 0;
61 struct vl_mpeg12_mc_buffer *buffer;
62
63 assert(ctx);
64
65 flush_buffer(ctx);
66
67 buffer = (struct vl_mpeg12_mc_buffer*)util_keymap_lookup(ctx->buffer_map, &key);
68 if (!buffer) {
69 boolean added_to_map;
70
71 buffer = CALLOC_STRUCT(vl_mpeg12_mc_buffer);
72 if (buffer == NULL)
73 return;
74
75 if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, buffer)) {
76 FREE(buffer);
77 return;
78 }
79
80 added_to_map = util_keymap_insert(ctx->buffer_map, &key, buffer, ctx);
81 assert(added_to_map);
82 }
83 ++key;
84 key %= NUM_BUFFERS;
85 ctx->mc_buffer = buffer;
86
87 vl_mpeg12_mc_map_buffer(&ctx->mc_renderer, ctx->mc_buffer);
88 }
89
90 static void
91 delete_buffer(const struct keymap *map,
92 const void *key, void *data,
93 void *user)
94 {
95 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)user;
96 struct vl_mpeg12_mc_buffer *buf = (struct vl_mpeg12_mc_buffer*)data;
97
98 assert(map);
99 assert(key);
100 assert(data);
101 assert(user);
102
103 vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, buf);
104 }
105
106 static void
107 sp_mpeg12_destroy(struct pipe_video_context *vpipe)
108 {
109 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
110
111 assert(vpipe);
112
113 flush_buffer(ctx);
114
115 /* Asserted in softpipe_delete_fs_state() for some reason */
116 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
117 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
118
119 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
120 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
121 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
122
123 pipe_surface_reference(&ctx->decode_target, NULL);
124 vl_compositor_cleanup(&ctx->compositor);
125 util_delete_keymap(ctx->buffer_map, ctx);
126 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
127 ctx->pipe->destroy(ctx->pipe);
128
129 FREE(ctx);
130 }
131
132 static int
133 sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
134 {
135 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
136
137 assert(vpipe);
138
139 switch (param) {
140 case PIPE_CAP_NPOT_TEXTURES:
141 /* XXX: Temporary; not all paths are NPOT-tested */
142 #if 0
143 return ctx->pipe->screen->get_param(ctx->pipe->screen, param);
144 #endif
145 return FALSE;
146 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
147 return ctx->decode_format;
148 default:
149 {
150 debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
151 return 0;
152 }
153 }
154 }
155
156 static struct pipe_surface *
157 sp_mpeg12_create_surface(struct pipe_video_context *vpipe,
158 struct pipe_resource *resource,
159 const struct pipe_surface *templat)
160 {
161 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
162
163 assert(vpipe);
164
165 return ctx->pipe->create_surface(ctx->pipe, resource, templat);
166 }
167
168 static boolean
169 sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
170 enum pipe_format format,
171 unsigned usage,
172 unsigned geom)
173 {
174 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
175
176 assert(vpipe);
177
178 /* XXX: Temporary; not all paths are NPOT-tested */
179 if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
180 return FALSE;
181
182 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format, PIPE_TEXTURE_2D,
183 0, usage, geom);
184 }
185
186 static void
187 sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
188 struct pipe_surface *past,
189 struct pipe_surface *future,
190 unsigned num_macroblocks,
191 struct pipe_macroblock *macroblocks,
192 struct pipe_fence_handle **fence)
193 {
194 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
195 struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
196
197 assert(vpipe);
198 assert(num_macroblocks);
199 assert(macroblocks);
200 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
201 assert(ctx->decode_target);
202 assert(ctx->mc_buffer);
203
204 vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
205 ctx->mc_buffer,
206 ctx->decode_target,
207 past, future, num_macroblocks,
208 mpeg12_macroblocks, fence);
209 }
210
211 static void
212 sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
213 struct pipe_surface *dst,
214 unsigned dstx, unsigned dsty,
215 unsigned width, unsigned height,
216 unsigned value)
217 {
218 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
219 float rgba[4] = { 0, 0, 0, 0 };
220
221 assert(vpipe);
222 assert(dst);
223
224 if (ctx->pipe->clear_render_target)
225 ctx->pipe->clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
226 else
227 util_clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
228 }
229
230 static void
231 sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
232 struct pipe_surface *dst,
233 unsigned dstx, unsigned dsty,
234 struct pipe_surface *src,
235 unsigned srcx, unsigned srcy,
236 unsigned width, unsigned height)
237 {
238 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
239
240 assert(vpipe);
241 assert(dst);
242
243 struct pipe_box box;
244 box.x = srcx;
245 box.y = srcy;
246 box.z = 0;
247 box.width = width;
248 box.height = height;
249
250 if (ctx->pipe->resource_copy_region)
251 ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
252 dstx, dsty, dst->u.tex.first_layer,
253 src->texture, src->u.tex.level, &box);
254 else
255 util_resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
256 dstx, dsty, dst->u.tex.first_layer,
257 src->texture, src->u.tex.level, &box);
258 }
259
260 static struct pipe_transfer*
261 sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
262 struct pipe_resource *resource,
263 unsigned level,
264 unsigned usage, /* a combination of PIPE_TRANSFER_x */
265 const struct pipe_box *box)
266 {
267 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
268
269 assert(vpipe);
270 assert(resource);
271 assert(box);
272
273 return ctx->pipe->get_transfer(ctx->pipe, resource, level, usage, box);
274 }
275
276 static void
277 sp_mpeg12_transfer_destroy(struct pipe_video_context *vpipe,
278 struct pipe_transfer *transfer)
279 {
280 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
281
282 assert(vpipe);
283 assert(transfer);
284
285 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
286 }
287
288 static void*
289 sp_mpeg12_transfer_map(struct pipe_video_context *vpipe,
290 struct pipe_transfer *transfer)
291 {
292 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
293
294 assert(vpipe);
295 assert(transfer);
296
297 return ctx->pipe->transfer_map(ctx->pipe, transfer);
298 }
299
300 static void
301 sp_mpeg12_transfer_flush_region(struct pipe_video_context *vpipe,
302 struct pipe_transfer *transfer,
303 const struct pipe_box *box)
304 {
305 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
306
307 assert(vpipe);
308 assert(transfer);
309 assert(box);
310
311 ctx->pipe->transfer_flush_region(ctx->pipe, transfer, box);
312 }
313
314 static void
315 sp_mpeg12_transfer_unmap(struct pipe_video_context *vpipe,
316 struct pipe_transfer *transfer)
317 {
318 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
319
320 assert(vpipe);
321 assert(transfer);
322
323 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
324 }
325
326 static void
327 sp_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
328 struct pipe_resource *resource,
329 unsigned level,
330 unsigned usage, /* a combination of PIPE_TRANSFER_x */
331 const struct pipe_box *box,
332 const void *data,
333 unsigned stride,
334 unsigned slice_stride)
335 {
336 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
337
338 assert(vpipe);
339 assert(resource);
340 assert(box);
341 assert(data);
342 assert(ctx->pipe->transfer_inline_write);
343
344 ctx->pipe->transfer_inline_write(ctx->pipe, resource, level, usage,
345 box, data, stride, slice_stride);
346 }
347
348 static void
349 sp_mpeg12_render_picture(struct pipe_video_context *vpipe,
350 struct pipe_surface *src_surface,
351 enum pipe_mpeg12_picture_type picture_type,
352 /*unsigned num_past_surfaces,
353 struct pipe_surface *past_surfaces,
354 unsigned num_future_surfaces,
355 struct pipe_surface *future_surfaces,*/
356 struct pipe_video_rect *src_area,
357 struct pipe_surface *dst_surface,
358 struct pipe_video_rect *dst_area,
359 struct pipe_fence_handle **fence)
360 {
361 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
362
363 assert(vpipe);
364 assert(src_surface);
365 assert(src_area);
366 assert(dst_surface);
367 assert(dst_area);
368
369 flush_buffer(ctx);
370
371 vl_compositor_render(&ctx->compositor, src_surface,
372 picture_type, src_area, dst_surface, dst_area, fence);
373 }
374
375 static void
376 sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
377 struct pipe_surface *bg,
378 struct pipe_video_rect *bg_src_rect)
379 {
380 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
381
382 assert(vpipe);
383 assert(bg);
384 assert(bg_src_rect);
385
386 vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
387 }
388
389 static void
390 sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
391 struct pipe_surface *layers[],
392 struct pipe_video_rect *src_rects[],
393 struct pipe_video_rect *dst_rects[],
394 unsigned num_layers)
395 {
396 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
397
398 assert(vpipe);
399 assert((layers && src_rects && dst_rects) ||
400 (!layers && !src_rects && !dst_rects));
401
402 vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
403 }
404
405 static void
406 sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
407 struct pipe_surface *dt)
408 {
409 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
410
411 assert(vpipe);
412 assert(dt);
413
414 if (ctx->decode_target != dt || ctx->mc_buffer == NULL) {
415 rotate_buffer(ctx);
416
417 pipe_surface_reference(&ctx->decode_target, dt);
418 }
419 }
420
421 static void
422 sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
423 {
424 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
425
426 assert(vpipe);
427
428 vl_compositor_set_csc_matrix(&ctx->compositor, mat);
429 }
430
431 static bool
432 init_pipe_state(struct sp_mpeg12_context *ctx)
433 {
434 struct pipe_rasterizer_state rast;
435 struct pipe_blend_state blend;
436 struct pipe_depth_stencil_alpha_state dsa;
437 unsigned i;
438
439 assert(ctx);
440
441 memset(&rast, 0, sizeof rast);
442 rast.flatshade = 1;
443 rast.flatshade_first = 0;
444 rast.light_twoside = 0;
445 rast.front_ccw = 1;
446 rast.cull_face = PIPE_FACE_NONE;
447 rast.fill_back = PIPE_POLYGON_MODE_FILL;
448 rast.fill_front = PIPE_POLYGON_MODE_FILL;
449 rast.offset_point = 0;
450 rast.offset_line = 0;
451 rast.scissor = 0;
452 rast.poly_smooth = 0;
453 rast.poly_stipple_enable = 0;
454 rast.sprite_coord_enable = 0;
455 rast.point_size_per_vertex = 0;
456 rast.multisample = 0;
457 rast.line_smooth = 0;
458 rast.line_stipple_enable = 0;
459 rast.line_stipple_factor = 0;
460 rast.line_stipple_pattern = 0;
461 rast.line_last_pixel = 0;
462 rast.line_width = 1;
463 rast.point_smooth = 0;
464 rast.point_quad_rasterization = 0;
465 rast.point_size = 1;
466 rast.offset_units = 1;
467 rast.offset_scale = 1;
468 rast.gl_rasterization_rules = 1;
469 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
470 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
471
472 memset(&blend, 0, sizeof blend);
473 blend.independent_blend_enable = 0;
474 blend.rt[0].blend_enable = 0;
475 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
476 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
477 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
478 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
479 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
480 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
481 blend.logicop_enable = 0;
482 blend.logicop_func = PIPE_LOGICOP_CLEAR;
483 /* Needed to allow color writes to FB, even if blending disabled */
484 blend.rt[0].colormask = PIPE_MASK_RGBA;
485 blend.dither = 0;
486 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
487 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
488
489 memset(&dsa, 0, sizeof dsa);
490 dsa.depth.enabled = 0;
491 dsa.depth.writemask = 0;
492 dsa.depth.func = PIPE_FUNC_ALWAYS;
493 for (i = 0; i < 2; ++i) {
494 dsa.stencil[i].enabled = 0;
495 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
496 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
497 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
498 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
499 dsa.stencil[i].valuemask = 0;
500 dsa.stencil[i].writemask = 0;
501 }
502 dsa.alpha.enabled = 0;
503 dsa.alpha.func = PIPE_FUNC_ALWAYS;
504 dsa.alpha.ref_value = 0;
505 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
506 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
507
508 return true;
509 }
510
511 static struct pipe_video_context *
512 sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
513 enum pipe_video_chroma_format chroma_format,
514 unsigned width, unsigned height,
515 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
516 bool pot_buffers,
517 enum pipe_format decode_format)
518 {
519 unsigned buffer_width, buffer_height;
520 struct sp_mpeg12_context *ctx;
521
522 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
523
524 ctx = CALLOC_STRUCT(sp_mpeg12_context);
525
526 if (!ctx)
527 return NULL;
528
529 /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
530 assert(pot_buffers);
531
532 buffer_width = pot_buffers ? util_next_power_of_two(width) : width;
533 buffer_height = pot_buffers ? util_next_power_of_two(height) : height;
534
535 ctx->base.profile = profile;
536 ctx->base.chroma_format = chroma_format;
537 ctx->base.width = width;
538 ctx->base.height = height;
539
540 ctx->base.screen = pipe->screen;
541 ctx->base.destroy = sp_mpeg12_destroy;
542 ctx->base.get_param = sp_mpeg12_get_param;
543 ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
544 ctx->base.create_surface = sp_mpeg12_create_surface;
545 ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
546 ctx->base.render_picture = sp_mpeg12_render_picture;
547 ctx->base.surface_fill = sp_mpeg12_surface_fill;
548 ctx->base.surface_copy = sp_mpeg12_surface_copy;
549 ctx->base.get_transfer = sp_mpeg12_get_transfer;
550 ctx->base.transfer_destroy = sp_mpeg12_transfer_destroy;
551 ctx->base.transfer_map = sp_mpeg12_transfer_map;
552 ctx->base.transfer_flush_region = sp_mpeg12_transfer_flush_region;
553 ctx->base.transfer_unmap = sp_mpeg12_transfer_unmap;
554 if (pipe->transfer_inline_write)
555 ctx->base.transfer_inline_write = sp_mpeg12_transfer_inline_write;
556 ctx->base.set_picture_background = sp_mpeg12_set_picture_background;
557 ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers;
558 ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
559 ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
560
561 ctx->pipe = pipe;
562 ctx->decode_format = decode_format;
563
564 if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
565 buffer_width, buffer_height, chroma_format,
566 bufmode)) {
567 ctx->pipe->destroy(ctx->pipe);
568 FREE(ctx);
569 return NULL;
570 }
571
572 ctx->buffer_map = util_new_keymap(sizeof(unsigned), -1, delete_buffer);
573 if (!ctx->buffer_map) {
574 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
575 ctx->pipe->destroy(ctx->pipe);
576 FREE(ctx);
577 return NULL;
578 }
579
580 if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
581 util_delete_keymap(ctx->buffer_map, ctx);
582 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
583 ctx->pipe->destroy(ctx->pipe);
584 FREE(ctx);
585 return NULL;
586 }
587
588 if (!init_pipe_state(ctx)) {
589 vl_compositor_cleanup(&ctx->compositor);
590 util_delete_keymap(ctx->buffer_map, ctx);
591 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
592 ctx->pipe->destroy(ctx->pipe);
593 FREE(ctx);
594 return NULL;
595 }
596
597 return &ctx->base;
598 }
599
600 struct pipe_video_context *
601 sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
602 enum pipe_video_chroma_format chroma_format,
603 unsigned width, unsigned height, void *priv)
604 {
605 struct pipe_context *pipe;
606
607 assert(screen);
608 assert(width && height);
609
610 pipe = screen->context_create(screen, NULL);
611 if (!pipe)
612 return NULL;
613
614 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
615 return sp_video_create_ex(pipe, profile,
616 chroma_format,
617 width, height,
618 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
619 true,
620 PIPE_FORMAT_XYUV);
621 }
622
623 struct pipe_video_context *
624 sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
625 enum pipe_video_chroma_format chroma_format,
626 unsigned width, unsigned height,
627 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
628 bool pot_buffers,
629 enum pipe_format decode_format)
630 {
631 assert(pipe);
632 assert(width && height);
633
634 switch (u_reduce_video_profile(profile)) {
635 case PIPE_VIDEO_CODEC_MPEG12:
636 return sp_mpeg12_create(pipe, profile,
637 chroma_format,
638 width, height,
639 bufmode,
640 pot_buffers,
641 decode_format);
642 default:
643 return NULL;
644 }
645 }