[g3dvl] split compositor out of video context
[mesa.git] / src / gallium / auxiliary / vl / vl_mpeg12_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 "vl_mpeg12_context.h"
32 #include "vl_defines.h"
33 #include <pipe/p_shader_tokens.h>
34 #include <util/u_inlines.h>
35 #include <util/u_memory.h>
36 #include <util/u_keymap.h>
37 #include <util/u_rect.h>
38 #include <util/u_video.h>
39 #include <util/u_surface.h>
40 #include <util/u_sampler.h>
41
42 static const unsigned const_empty_block_mask_420[3][2][2] = {
43 { { 0x20, 0x10 }, { 0x08, 0x04 } },
44 { { 0x02, 0x02 }, { 0x02, 0x02 } },
45 { { 0x01, 0x01 }, { 0x01, 0x01 } }
46 };
47
48 static void
49 upload_buffer(struct vl_mpeg12_context *ctx,
50 struct vl_mpeg12_buffer *buffer,
51 struct pipe_mpeg12_macroblock *mb)
52 {
53 short *blocks;
54 unsigned tb, x, y;
55
56 assert(ctx);
57 assert(buffer);
58 assert(mb);
59
60 blocks = mb->blocks;
61
62 for (y = 0; y < 2; ++y) {
63 for (x = 0; x < 2; ++x, ++tb) {
64 if (mb->cbp & (*ctx->empty_block_mask)[0][y][x]) {
65 vl_idct_add_block(&buffer->idct_y, mb->mbx * 2 + x, mb->mby * 2 + y, blocks);
66 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
67 }
68 }
69 }
70
71 /* TODO: Implement 422, 444 */
72 assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
73
74 for (tb = 1; tb < 3; ++tb) {
75 if (mb->cbp & (*ctx->empty_block_mask)[tb][0][0]) {
76 if(tb == 1)
77 vl_idct_add_block(&buffer->idct_cb, mb->mbx, mb->mby, blocks);
78 else
79 vl_idct_add_block(&buffer->idct_cr, mb->mbx, mb->mby, blocks);
80 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
81 }
82 }
83 }
84
85 static void
86 vl_mpeg12_buffer_destroy(struct pipe_video_buffer *buffer)
87 {
88 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
89 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)buf->base.context;
90 assert(buf && ctx);
91
92 vl_ycbcr_buffer_cleanup(&buf->idct_source);
93 vl_ycbcr_buffer_cleanup(&buf->idct_2_mc);
94 vl_ycbcr_buffer_cleanup(&buf->render_result);
95 vl_vb_cleanup(&buf->vertex_stream);
96 vl_idct_cleanup_buffer(&ctx->idct_y, &buf->idct_y);
97 vl_idct_cleanup_buffer(&ctx->idct_c, &buf->idct_cb);
98 vl_idct_cleanup_buffer(&ctx->idct_c, &buf->idct_cr);
99 vl_mpeg12_mc_cleanup_buffer(&buf->mc_y);
100 vl_mpeg12_mc_cleanup_buffer(&buf->mc_cb);
101 vl_mpeg12_mc_cleanup_buffer(&buf->mc_cr);
102
103 FREE(buf);
104 }
105
106 static void
107 vl_mpeg12_buffer_map(struct pipe_video_buffer *buffer)
108 {
109 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
110 struct vl_mpeg12_context *ctx;
111 assert(buf);
112
113 ctx = (struct vl_mpeg12_context *)buf->base.context;
114 assert(ctx);
115
116 vl_vb_map(&buf->vertex_stream, ctx->pipe);
117 vl_idct_map_buffers(&ctx->idct_y, &buf->idct_y);
118 vl_idct_map_buffers(&ctx->idct_c, &buf->idct_cb);
119 vl_idct_map_buffers(&ctx->idct_c, &buf->idct_cr);
120 }
121
122 static void
123 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_buffer *buffer,
124 unsigned num_macroblocks,
125 struct pipe_macroblock *macroblocks)
126 {
127 struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
128 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
129 struct vl_mpeg12_context *ctx;
130 unsigned i;
131
132 assert(buf);
133
134 ctx = (struct vl_mpeg12_context*)buf->base.context;
135 assert(ctx);
136
137 assert(num_macroblocks);
138 assert(macroblocks);
139 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
140
141 for ( i = 0; i < num_macroblocks; ++i ) {
142 vl_vb_add_block(&buf->vertex_stream, &mpeg12_macroblocks[i], ctx->empty_block_mask);
143 upload_buffer(ctx, buf, &mpeg12_macroblocks[i]);
144 }
145 }
146
147 static void
148 vl_mpeg12_buffer_unmap(struct pipe_video_buffer *buffer)
149 {
150 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
151 struct vl_mpeg12_context *ctx;
152 assert(buf);
153
154 ctx = (struct vl_mpeg12_context *)buf->base.context;
155 assert(ctx);
156
157 vl_vb_unmap(&buf->vertex_stream, ctx->pipe);
158 vl_idct_unmap_buffers(&ctx->idct_y, &buf->idct_y);
159 vl_idct_unmap_buffers(&ctx->idct_c, &buf->idct_cb);
160 vl_idct_unmap_buffers(&ctx->idct_c, &buf->idct_cr);
161 }
162
163 static void
164 vl_mpeg12_buffer_flush(struct pipe_video_buffer *buffer,
165 struct pipe_video_buffer *refs[2],
166 struct pipe_fence_handle **fence)
167 {
168 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer *)buffer;
169 struct vl_mpeg12_buffer *past = (struct vl_mpeg12_buffer *)refs[0];
170 struct vl_mpeg12_buffer *future = (struct vl_mpeg12_buffer *)refs[1];
171
172 struct vl_ycbcr_surfaces *surfaces;
173 struct vl_ycbcr_sampler_views *sv_past;
174 struct vl_ycbcr_sampler_views *sv_future;
175
176 struct pipe_sampler_view *sv_refs[2];
177 unsigned ne_start, ne_num, e_start, e_num;
178 struct vl_mpeg12_context *ctx;
179
180 assert(buf);
181
182 ctx = (struct vl_mpeg12_context *)buf->base.context;
183 assert(ctx);
184
185 surfaces = vl_ycbcr_get_surfaces(&buf->render_result);
186
187 sv_past = past ? vl_ycbcr_get_sampler_views(&past->render_result) : NULL;
188 sv_future = future ? vl_ycbcr_get_sampler_views(&future->render_result) : NULL;
189
190 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
191
192 ctx->pipe->set_vertex_buffers(ctx->pipe, 2, buf->vertex_bufs.all);
193 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
194
195
196 ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->ves_y);
197 vl_idct_flush(&ctx->idct_y, &buf->idct_y, ne_num);
198
199 sv_refs[0] = sv_past ? sv_past->y : NULL;
200 sv_refs[1] = sv_future ? sv_future->y : NULL;
201
202 vl_mpeg12_mc_renderer_flush(&ctx->mc, &buf->mc_y, surfaces->y,
203 sv_refs, ne_start, ne_num, e_start, e_num, fence);
204
205 ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->ves_cb);
206 vl_idct_flush(&ctx->idct_c, &buf->idct_cb, ne_num);
207
208 sv_refs[0] = sv_past ? sv_past->cb : NULL;
209 sv_refs[1] = sv_future ? sv_future->cb : NULL;
210
211 vl_mpeg12_mc_renderer_flush(&ctx->mc, &buf->mc_cb, surfaces->cb,
212 sv_refs, ne_start, ne_num, e_start, e_num, fence);
213
214 ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->ves_cr);
215 vl_idct_flush(&ctx->idct_c, &buf->idct_cr, ne_num);
216
217 sv_refs[0] = sv_past ? sv_past->cr : NULL;
218 sv_refs[1] = sv_future ? sv_future->cr : NULL;
219
220 vl_mpeg12_mc_renderer_flush(&ctx->mc, &buf->mc_cr, surfaces->cr,
221 sv_refs, ne_start, ne_num, e_start, e_num, fence);
222 }
223
224 static void
225 vl_mpeg12_buffer_get_sampler_views(struct pipe_video_buffer *buffer,
226 struct pipe_sampler_view *sampler_views[3])
227 {
228 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
229 struct vl_ycbcr_sampler_views *samplers;
230
231 assert(buf);
232
233 samplers = vl_ycbcr_get_sampler_views(&buf->render_result);
234
235 assert(samplers);
236
237 pipe_sampler_view_reference(&sampler_views[0], samplers->y);
238 pipe_sampler_view_reference(&sampler_views[1], samplers->cb);
239 pipe_sampler_view_reference(&sampler_views[2], samplers->cr);
240 }
241
242 static void
243 vl_mpeg12_destroy(struct pipe_video_context *vpipe)
244 {
245 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
246
247 assert(vpipe);
248
249 /* Asserted in softpipe_delete_fs_state() for some reason */
250 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
251 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
252
253 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
254 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
255 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
256
257 vl_mpeg12_mc_renderer_cleanup(&ctx->mc);
258 vl_idct_cleanup(&ctx->idct_y);
259 vl_idct_cleanup(&ctx->idct_c);
260 ctx->pipe->delete_vertex_elements_state(ctx->pipe, ctx->ves_y);
261 ctx->pipe->delete_vertex_elements_state(ctx->pipe, ctx->ves_cb);
262 ctx->pipe->delete_vertex_elements_state(ctx->pipe, ctx->ves_cr);
263 pipe_resource_reference(&ctx->quads.buffer, NULL);
264 ctx->pipe->destroy(ctx->pipe);
265
266 FREE(ctx);
267 }
268
269 static int
270 vl_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
271 {
272 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
273
274 assert(vpipe);
275
276 if (param == PIPE_CAP_NPOT_TEXTURES)
277 return !ctx->pot_buffers;
278
279 debug_printf("vl_mpeg12_context: Unknown PIPE_CAP %d\n", param);
280 return 0;
281 }
282
283 static struct pipe_surface *
284 vl_mpeg12_create_surface(struct pipe_video_context *vpipe,
285 struct pipe_resource *resource,
286 const struct pipe_surface *templ)
287 {
288 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
289
290 assert(ctx);
291
292 return ctx->pipe->create_surface(ctx->pipe, resource, templ);
293 }
294
295 static struct pipe_sampler_view *
296 vl_mpeg12_create_sampler_view(struct pipe_video_context *vpipe,
297 struct pipe_resource *resource,
298 const struct pipe_sampler_view *templ)
299 {
300 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
301
302 assert(ctx);
303
304 return ctx->pipe->create_sampler_view(ctx->pipe, resource, templ);
305 }
306
307 static struct pipe_video_buffer *
308 vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
309 {
310 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
311 struct vl_mpeg12_buffer *buffer;
312
313 struct vl_ycbcr_sampler_views *idct_views, *mc_views;
314 struct vl_ycbcr_surfaces *idct_surfaces;
315
316 assert(ctx);
317
318 buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
319 if (buffer == NULL)
320 return NULL;
321
322 buffer->base.context = vpipe;
323 buffer->base.destroy = vl_mpeg12_buffer_destroy;
324 buffer->base.map = vl_mpeg12_buffer_map;
325 buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
326 buffer->base.unmap = vl_mpeg12_buffer_unmap;
327 buffer->base.flush = vl_mpeg12_buffer_flush;
328 buffer->base.get_sampler_views = vl_mpeg12_buffer_get_sampler_views;
329
330 buffer->vertex_bufs.individual.quad.stride = ctx->quads.stride;
331 buffer->vertex_bufs.individual.quad.buffer_offset = ctx->quads.buffer_offset;
332 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, ctx->quads.buffer);
333
334 buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, ctx->pipe,
335 ctx->vertex_buffer_size);
336 if (!buffer->vertex_bufs.individual.stream.buffer)
337 goto error_vertex_stream;
338
339 if (!vl_ycbcr_buffer_init(&buffer->idct_source, ctx->pipe,
340 ctx->buffer_width, ctx->buffer_height,
341 ctx->base.chroma_format,
342 PIPE_FORMAT_R16G16B16A16_SNORM,
343 PIPE_USAGE_STREAM))
344 goto error_idct_source;
345
346 if (!vl_ycbcr_buffer_init(&buffer->idct_2_mc, ctx->pipe,
347 ctx->buffer_width, ctx->buffer_height,
348 ctx->base.chroma_format,
349 PIPE_FORMAT_R16_SNORM,
350 PIPE_USAGE_STATIC))
351 goto error_idct_2_mc;
352
353 if (!vl_ycbcr_buffer_init(&buffer->render_result, ctx->pipe,
354 ctx->buffer_width, ctx->buffer_height,
355 ctx->base.chroma_format,
356 PIPE_FORMAT_R8_SNORM,
357 PIPE_USAGE_STATIC))
358 goto error_render_result;
359
360 idct_views = vl_ycbcr_get_sampler_views(&buffer->idct_source);
361 if (!idct_views)
362 goto error_idct_views;
363
364 idct_surfaces = vl_ycbcr_get_surfaces(&buffer->idct_2_mc);
365 if (!idct_surfaces)
366 goto error_idct_surfaces;
367
368 if (!vl_idct_init_buffer(&ctx->idct_y, &buffer->idct_y,
369 idct_views->y, idct_surfaces->y))
370 goto error_idct_y;
371
372 if (!vl_idct_init_buffer(&ctx->idct_c, &buffer->idct_cb,
373 idct_views->cb, idct_surfaces->cb))
374 goto error_idct_cb;
375
376 if (!vl_idct_init_buffer(&ctx->idct_c, &buffer->idct_cr,
377 idct_views->cr, idct_surfaces->cr))
378 goto error_idct_cr;
379
380 mc_views = vl_ycbcr_get_sampler_views(&buffer->idct_2_mc);
381 if (!mc_views)
382 goto error_mc_views;
383
384 if(!vl_mpeg12_mc_init_buffer(&ctx->mc, &buffer->mc_y, mc_views->y))
385 goto error_mc_y;
386
387 if(!vl_mpeg12_mc_init_buffer(&ctx->mc, &buffer->mc_cb, mc_views->cb))
388 goto error_mc_cb;
389
390 if(!vl_mpeg12_mc_init_buffer(&ctx->mc, &buffer->mc_cr, mc_views->cr))
391 goto error_mc_cr;
392
393 return &buffer->base;
394
395 error_mc_cr:
396 vl_mpeg12_mc_cleanup_buffer(&buffer->mc_cb);
397
398 error_mc_cb:
399 vl_mpeg12_mc_cleanup_buffer(&buffer->mc_y);
400
401 error_mc_y:
402 error_mc_views:
403 vl_idct_cleanup_buffer(&ctx->idct_c, &buffer->idct_cr);
404
405 error_idct_cr:
406 vl_idct_cleanup_buffer(&ctx->idct_c, &buffer->idct_cb);
407
408 error_idct_cb:
409 vl_idct_cleanup_buffer(&ctx->idct_y, &buffer->idct_y);
410
411 error_idct_y:
412 error_idct_surfaces:
413 error_idct_views:
414 vl_ycbcr_buffer_cleanup(&buffer->render_result);
415
416 error_render_result:
417 vl_ycbcr_buffer_cleanup(&buffer->idct_2_mc);
418
419 error_idct_2_mc:
420 vl_ycbcr_buffer_cleanup(&buffer->idct_source);
421
422 error_idct_source:
423 vl_vb_cleanup(&buffer->vertex_stream);
424
425 error_vertex_stream:
426 FREE(buffer);
427 return NULL;
428 }
429
430 static boolean
431 vl_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
432 enum pipe_format format,
433 unsigned usage)
434 {
435 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
436
437 assert(vpipe);
438
439 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format,
440 PIPE_TEXTURE_2D,
441 0, usage);
442 }
443
444 static void
445 vl_mpeg12_clear_sampler(struct pipe_video_context *vpipe,
446 struct pipe_sampler_view *dst,
447 const struct pipe_box *dst_box,
448 const float *rgba)
449 {
450 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
451 struct pipe_transfer *transfer;
452 union util_color uc;
453 void *map;
454 unsigned i;
455
456 assert(vpipe);
457 assert(dst);
458 assert(dst_box);
459 assert(rgba);
460
461 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
462 if (!transfer)
463 return;
464
465 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
466 if (!transfer)
467 goto error_map;
468
469 for ( i = 0; i < 4; ++i)
470 uc.f[i] = rgba[i];
471
472 util_fill_rect(map, dst->texture->format, transfer->stride, 0, 0,
473 dst_box->width, dst_box->height, &uc);
474
475 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
476
477 error_map:
478 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
479 }
480
481 static void
482 vl_mpeg12_upload_sampler(struct pipe_video_context *vpipe,
483 struct pipe_sampler_view *dst,
484 const struct pipe_box *dst_box,
485 const void *src, unsigned src_stride,
486 unsigned src_x, unsigned src_y)
487 {
488 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
489 struct pipe_transfer *transfer;
490 void *map;
491
492 assert(vpipe);
493 assert(dst);
494 assert(dst_box);
495 assert(src);
496
497 transfer = ctx->pipe->get_transfer(ctx->pipe, dst->texture, 0, PIPE_TRANSFER_WRITE, dst_box);
498 if (!transfer)
499 return;
500
501 map = ctx->pipe->transfer_map(ctx->pipe, transfer);
502 if (!transfer)
503 goto error_map;
504
505 util_copy_rect(map, dst->texture->format, transfer->stride, 0, 0,
506 dst_box->width, dst_box->height,
507 src, src_stride, src_x, src_y);
508
509 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
510
511 error_map:
512 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
513 }
514
515 static struct pipe_video_compositor *
516 vl_mpeg12_create_compositor(struct pipe_video_context *vpipe)
517 {
518 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
519
520 assert(vpipe);
521
522 return vl_compositor_init(vpipe, ctx->pipe);
523 }
524
525 static bool
526 init_pipe_state(struct vl_mpeg12_context *ctx)
527 {
528 struct pipe_rasterizer_state rast;
529 struct pipe_blend_state blend;
530 struct pipe_depth_stencil_alpha_state dsa;
531 unsigned i;
532
533 assert(ctx);
534
535 memset(&rast, 0, sizeof rast);
536 rast.flatshade = 1;
537 rast.flatshade_first = 0;
538 rast.light_twoside = 0;
539 rast.front_ccw = 1;
540 rast.cull_face = PIPE_FACE_NONE;
541 rast.fill_back = PIPE_POLYGON_MODE_FILL;
542 rast.fill_front = PIPE_POLYGON_MODE_FILL;
543 rast.offset_point = 0;
544 rast.offset_line = 0;
545 rast.scissor = 0;
546 rast.poly_smooth = 0;
547 rast.poly_stipple_enable = 0;
548 rast.sprite_coord_enable = 0;
549 rast.point_size_per_vertex = 0;
550 rast.multisample = 0;
551 rast.line_smooth = 0;
552 rast.line_stipple_enable = 0;
553 rast.line_stipple_factor = 0;
554 rast.line_stipple_pattern = 0;
555 rast.line_last_pixel = 0;
556 rast.line_width = 1;
557 rast.point_smooth = 0;
558 rast.point_quad_rasterization = 0;
559 rast.point_size_per_vertex = 1;
560 rast.offset_units = 1;
561 rast.offset_scale = 1;
562 rast.gl_rasterization_rules = 1;
563
564 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
565 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
566
567 memset(&blend, 0, sizeof blend);
568
569 blend.independent_blend_enable = 0;
570 blend.rt[0].blend_enable = 0;
571 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
572 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
573 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
574 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
575 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
576 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
577 blend.logicop_enable = 0;
578 blend.logicop_func = PIPE_LOGICOP_CLEAR;
579 /* Needed to allow color writes to FB, even if blending disabled */
580 blend.rt[0].colormask = PIPE_MASK_RGBA;
581 blend.dither = 0;
582 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
583
584 memset(&dsa, 0, sizeof dsa);
585 dsa.depth.enabled = 0;
586 dsa.depth.writemask = 0;
587 dsa.depth.func = PIPE_FUNC_ALWAYS;
588 for (i = 0; i < 2; ++i) {
589 dsa.stencil[i].enabled = 0;
590 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
591 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
592 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
593 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
594 dsa.stencil[i].valuemask = 0;
595 dsa.stencil[i].writemask = 0;
596 }
597 dsa.alpha.enabled = 0;
598 dsa.alpha.func = PIPE_FUNC_ALWAYS;
599 dsa.alpha.ref_value = 0;
600 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
601 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
602
603 return true;
604 }
605
606 static bool
607 init_idct(struct vl_mpeg12_context *ctx, unsigned buffer_width, unsigned buffer_height)
608 {
609 unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
610 struct pipe_sampler_view *idct_matrix;
611
612 /* TODO: Implement 422, 444 */
613 assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
614 ctx->empty_block_mask = &const_empty_block_mask_420;
615
616 if (!(idct_matrix = vl_idct_upload_matrix(ctx->pipe)))
617 goto error_idct_matrix;
618
619 if (!vl_idct_init(&ctx->idct_y, ctx->pipe, buffer_width, buffer_height,
620 2, 2, idct_matrix))
621 goto error_idct_y;
622
623 if (ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
624 chroma_width = buffer_width / 2;
625 chroma_height = buffer_height / 2;
626 chroma_blocks_x = 1;
627 chroma_blocks_y = 1;
628 } else if (ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
629 chroma_width = buffer_width;
630 chroma_height = buffer_height / 2;
631 chroma_blocks_x = 2;
632 chroma_blocks_y = 1;
633 } else {
634 chroma_width = buffer_width;
635 chroma_height = buffer_height;
636 chroma_blocks_x = 2;
637 chroma_blocks_y = 2;
638 }
639
640 if(!vl_idct_init(&ctx->idct_c, ctx->pipe, chroma_width, chroma_height,
641 chroma_blocks_x, chroma_blocks_y, idct_matrix))
642 goto error_idct_c;
643
644 pipe_sampler_view_reference(&idct_matrix, NULL);
645 return true;
646
647 error_idct_c:
648 vl_idct_cleanup(&ctx->idct_y);
649
650 error_idct_y:
651 pipe_sampler_view_reference(&idct_matrix, NULL);
652
653 error_idct_matrix:
654 return false;
655 }
656
657 struct pipe_video_context *
658 vl_create_mpeg12_context(struct pipe_context *pipe,
659 enum pipe_video_profile profile,
660 enum pipe_video_chroma_format chroma_format,
661 unsigned width, unsigned height,
662 bool pot_buffers)
663 {
664 struct vl_mpeg12_context *ctx;
665
666 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
667
668 ctx = CALLOC_STRUCT(vl_mpeg12_context);
669
670 if (!ctx)
671 return NULL;
672
673 ctx->base.profile = profile;
674 ctx->base.chroma_format = chroma_format;
675 ctx->base.width = width;
676 ctx->base.height = height;
677
678 ctx->base.screen = pipe->screen;
679
680 ctx->base.destroy = vl_mpeg12_destroy;
681 ctx->base.get_param = vl_mpeg12_get_param;
682 ctx->base.is_format_supported = vl_mpeg12_is_format_supported;
683 ctx->base.create_surface = vl_mpeg12_create_surface;
684 ctx->base.create_sampler_view = vl_mpeg12_create_sampler_view;
685 ctx->base.create_buffer = vl_mpeg12_create_buffer;
686 ctx->base.clear_sampler = vl_mpeg12_clear_sampler;
687 ctx->base.upload_sampler = vl_mpeg12_upload_sampler;
688 ctx->base.create_compositor = vl_mpeg12_create_compositor;
689
690 ctx->pipe = pipe;
691 ctx->pot_buffers = pot_buffers;
692
693 ctx->quads = vl_vb_upload_quads(ctx->pipe, 2, 2);
694 ctx->vertex_buffer_size = width / MACROBLOCK_WIDTH * height / MACROBLOCK_HEIGHT;
695 ctx->ves_y = vl_vb_get_elems_state(ctx->pipe, TGSI_SWIZZLE_X);
696 ctx->ves_cb = vl_vb_get_elems_state(ctx->pipe, TGSI_SWIZZLE_Y);
697 ctx->ves_cr = vl_vb_get_elems_state(ctx->pipe, TGSI_SWIZZLE_Z);
698
699 ctx->buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH);
700 ctx->buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT);
701
702 if (!init_idct(ctx, ctx->buffer_width, ctx->buffer_height))
703 goto error_idct;
704
705 if (!vl_mpeg12_mc_renderer_init(&ctx->mc, ctx->pipe, ctx->buffer_width, ctx->buffer_height))
706 goto error_mc;
707
708 if (!init_pipe_state(ctx))
709 goto error_pipe_state;
710
711 return &ctx->base;
712
713 error_pipe_state:
714 vl_mpeg12_mc_renderer_cleanup(&ctx->mc);
715
716 error_mc:
717 vl_idct_cleanup(&ctx->idct_y);
718 vl_idct_cleanup(&ctx->idct_c);
719
720 error_idct:
721 ctx->pipe->destroy(ctx->pipe);
722 FREE(ctx);
723 return NULL;
724 }