[g3dvl] buffers must be aligned to macroblock size
[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
41 static const unsigned const_empty_block_mask_420[3][2][2] = {
42 { { 0x20, 0x10 }, { 0x08, 0x04 } },
43 { { 0x02, 0x02 }, { 0x02, 0x02 } },
44 { { 0x01, 0x01 }, { 0x01, 0x01 } }
45 };
46
47 static void
48 map_buffer(struct vl_mpeg12_buffer *buf)
49 {
50 struct vl_mpeg12_context *ctx;
51 assert(buf);
52
53 ctx = (struct vl_mpeg12_context *)buf->base.context;
54 assert(ctx);
55
56 if (!buf->mapped) {
57 vl_vb_map(&buf->vertex_stream, ctx->pipe);
58 vl_idct_map_buffers(&ctx->idct_y, &buf->idct_y);
59 vl_idct_map_buffers(&ctx->idct_cr, &buf->idct_cr);
60 vl_idct_map_buffers(&ctx->idct_cb, &buf->idct_cb);
61 buf->mapped = 1;
62 }
63 }
64
65 static void
66 unmap_buffer(struct vl_mpeg12_buffer *buf)
67 {
68 struct vl_mpeg12_context *ctx;
69 assert(buf);
70
71 ctx = (struct vl_mpeg12_context *)buf->base.context;
72 assert(ctx);
73
74 if (buf->mapped) {
75 vl_vb_unmap(&buf->vertex_stream, ctx->pipe);
76 vl_idct_unmap_buffers(&ctx->idct_y, &buf->idct_y);
77 vl_idct_unmap_buffers(&ctx->idct_cr, &buf->idct_cr);
78 vl_idct_unmap_buffers(&ctx->idct_cb, &buf->idct_cb);
79 buf->mapped = 0;
80 }
81 }
82
83 static void
84 flush_buffer(struct vl_mpeg12_buffer *buf)
85 {
86 unsigned ne_start, ne_num, e_start, e_num;
87 struct vl_mpeg12_context *ctx;
88 assert(buf);
89
90 ctx = (struct vl_mpeg12_context *)buf->base.context;
91 assert(ctx);
92
93 vl_vb_restart(&buf->vertex_stream, &ne_start, &ne_num, &e_start, &e_num);
94
95 ctx->pipe->set_vertex_buffers(ctx->pipe, 2, buf->vertex_bufs.all);
96 ctx->pipe->bind_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
97 vl_idct_flush(&ctx->idct_y, &buf->idct_y, ne_num);
98 vl_idct_flush(&ctx->idct_cr, &buf->idct_cr, ne_num);
99 vl_idct_flush(&ctx->idct_cb, &buf->idct_cb, ne_num);
100 vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, &buf->mc,
101 ne_start, ne_num, e_start, e_num);
102 }
103
104 static void
105 upload_buffer(struct vl_mpeg12_context *ctx,
106 struct vl_mpeg12_buffer *buffer,
107 struct pipe_mpeg12_macroblock *mb)
108 {
109 short *blocks;
110 unsigned tb, x, y;
111
112 assert(ctx);
113 assert(buffer);
114 assert(mb);
115
116 blocks = mb->blocks;
117
118 for (y = 0; y < 2; ++y) {
119 for (x = 0; x < 2; ++x, ++tb) {
120 if (mb->cbp & (*ctx->empty_block_mask)[0][y][x]) {
121 vl_idct_add_block(&buffer->idct_y, mb->mbx * 2 + x, mb->mby * 2 + y, blocks);
122 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
123 }
124 }
125 }
126
127 /* TODO: Implement 422, 444 */
128 assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
129
130 for (tb = 1; tb < 3; ++tb) {
131 if (mb->cbp & (*ctx->empty_block_mask)[tb][0][0]) {
132 if(tb == 1)
133 vl_idct_add_block(&buffer->idct_cb, mb->mbx, mb->mby, blocks);
134 else
135 vl_idct_add_block(&buffer->idct_cr, mb->mbx, mb->mby, blocks);
136 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
137 }
138 }
139 }
140
141 static void
142 vl_mpeg12_buffer_destroy(struct pipe_video_buffer *buffer)
143 {
144 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
145 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)buf->base.context;
146 assert(buf && ctx);
147
148 vl_vb_cleanup(&buf->vertex_stream);
149 vl_idct_cleanup_buffer(&ctx->idct_y, &buf->idct_y);
150 vl_idct_cleanup_buffer(&ctx->idct_cb, &buf->idct_cb);
151 vl_idct_cleanup_buffer(&ctx->idct_cr, &buf->idct_cr);
152 vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, &buf->mc);
153 pipe_surface_reference(&buf->surface, NULL);
154
155 FREE(buf);
156 }
157
158 static void
159 vl_mpeg12_buffer_add_macroblocks(struct pipe_video_buffer *buffer,
160 struct pipe_video_buffer *past,
161 struct pipe_video_buffer *future,
162 unsigned num_macroblocks,
163 struct pipe_macroblock *macroblocks,
164 struct pipe_fence_handle **fence)
165 {
166 struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
167 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)buffer;
168 struct vl_mpeg12_buffer *buf_past = (struct vl_mpeg12_buffer*)past;
169 struct vl_mpeg12_buffer *buf_future = (struct vl_mpeg12_buffer*)future;
170 struct vl_mpeg12_context *ctx;
171 unsigned i;
172
173 assert(buf);
174
175 ctx = (struct vl_mpeg12_context*)buf->base.context;
176 assert(ctx);
177
178 assert(num_macroblocks);
179 assert(macroblocks);
180 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
181
182 map_buffer(buf);
183
184 for ( i = 0; i < num_macroblocks; ++i ) {
185 vl_vb_add_block(&buf->vertex_stream, &mpeg12_macroblocks[i], ctx->empty_block_mask);
186 upload_buffer(ctx, buf, &mpeg12_macroblocks[i]);
187 }
188
189 // TODO this doesn't belong here
190 if (buf_past) {
191 unmap_buffer(buf_past);
192 flush_buffer(buf_past);
193 }
194
195 if (buf_future) {
196 unmap_buffer(buf_future);
197 flush_buffer(buf_future);
198 }
199
200 vl_mpeg12_mc_set_surfaces(&ctx->mc_renderer, &buf->mc, buf->surface,
201 buf_past ? buf_past->surface : NULL,
202 buf_future ? buf_future->surface : NULL,
203 fence);
204 }
205
206 static void
207 vl_mpeg12_destroy(struct pipe_video_context *vpipe)
208 {
209 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
210
211 assert(vpipe);
212
213 /* Asserted in softpipe_delete_fs_state() for some reason */
214 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
215 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
216
217 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
218 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
219 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
220
221 vl_compositor_cleanup(&ctx->compositor);
222 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
223 vl_idct_cleanup(&ctx->idct_y);
224 vl_idct_cleanup(&ctx->idct_cr);
225 vl_idct_cleanup(&ctx->idct_cb);
226 ctx->pipe->delete_vertex_elements_state(ctx->pipe, ctx->vertex_elems_state);
227 pipe_resource_reference(&ctx->quads.buffer, NULL);
228 ctx->pipe->destroy(ctx->pipe);
229
230 FREE(ctx);
231 }
232
233 static int
234 vl_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
235 {
236 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
237
238 assert(vpipe);
239
240 switch (param) {
241 case PIPE_CAP_NPOT_TEXTURES:
242 return !ctx->pot_buffers;
243 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
244 return ctx->decode_format;
245 default:
246 {
247 debug_printf("vl_mpeg12_context: Unknown PIPE_CAP %d\n", param);
248 return 0;
249 }
250 }
251 }
252
253 static struct pipe_surface *
254 vl_mpeg12_create_surface(struct pipe_video_context *vpipe,
255 struct pipe_resource *resource,
256 const struct pipe_surface *templat)
257 {
258 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
259
260 assert(ctx);
261
262 return ctx->pipe->create_surface(ctx->pipe, resource, templat);
263 }
264
265 static struct pipe_video_buffer *
266 vl_mpeg12_create_buffer(struct pipe_video_context *vpipe)
267 {
268 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
269 struct pipe_resource *y, *cr, *cb;
270 struct vl_mpeg12_buffer *buffer;
271
272 struct pipe_resource res_template, *resource;
273 struct pipe_surface surf_template;
274
275 assert(ctx);
276
277 buffer = CALLOC_STRUCT(vl_mpeg12_buffer);
278 if (buffer == NULL)
279 return NULL;
280
281 buffer->base.context = vpipe;
282 buffer->base.destroy = vl_mpeg12_buffer_destroy;
283 buffer->base.add_macroblocks = vl_mpeg12_buffer_add_macroblocks;
284
285 memset(&res_template, 0, sizeof(res_template));
286 res_template.target = PIPE_TEXTURE_2D;
287 res_template.format = ctx->decode_format;
288 res_template.last_level = 0;
289 res_template.width0 = ctx->buffer_width;
290 res_template.height0 = ctx->buffer_height;
291 res_template.depth0 = 1;
292 res_template.array_size = 1;
293 res_template.usage = PIPE_USAGE_DEFAULT;
294 res_template.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
295 res_template.flags = 0;
296 resource = ctx->pipe->screen->resource_create(ctx->pipe->screen, &res_template);
297 if (!resource) {
298 FREE(buffer);
299 return NULL;
300 }
301
302 memset(&surf_template, 0, sizeof(surf_template));
303 surf_template.format = resource->format;
304 surf_template.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
305 buffer->surface = ctx->pipe->create_surface(ctx->pipe, resource, &surf_template);
306 pipe_resource_reference(&resource, NULL);
307 if (!buffer->surface) {
308 FREE(buffer);
309 return NULL;
310 }
311
312 buffer->vertex_bufs.individual.quad.stride = ctx->quads.stride;
313 buffer->vertex_bufs.individual.quad.buffer_offset = ctx->quads.buffer_offset;
314 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, ctx->quads.buffer);
315
316 buffer->vertex_bufs.individual.stream = vl_vb_init(&buffer->vertex_stream, ctx->pipe,
317 ctx->vertex_buffer_size);
318 if (!(y = vl_idct_init_buffer(&ctx->idct_y, &buffer->idct_y))) {
319 FREE(buffer);
320 return NULL;
321 }
322
323 if (!(cr = vl_idct_init_buffer(&ctx->idct_cr, &buffer->idct_cr))) {
324 FREE(buffer);
325 return NULL;
326 }
327
328 if (!(cb = vl_idct_init_buffer(&ctx->idct_cb, &buffer->idct_cb))) {
329 FREE(buffer);
330 return NULL;
331 }
332
333 if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, &buffer->mc, y, cr, cb)) {
334 FREE(buffer);
335 return NULL;
336 }
337
338 return &buffer->base;
339 }
340
341 static boolean
342 vl_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
343 enum pipe_format format,
344 unsigned usage)
345 {
346 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
347
348 assert(vpipe);
349
350 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, format,
351 PIPE_TEXTURE_2D,
352 0, usage);
353 }
354
355 static void
356 vl_mpeg12_clear_render_target(struct pipe_video_context *vpipe,
357 struct pipe_surface *dst,
358 unsigned dstx, unsigned dsty,
359 const float *rgba,
360 unsigned width, unsigned height)
361 {
362 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
363
364 assert(vpipe);
365 assert(dst);
366
367 if (ctx->pipe->clear_render_target)
368 ctx->pipe->clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
369 else
370 util_clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
371 }
372
373 #if 0
374 static void
375 vl_mpeg12_resource_copy_region(struct pipe_video_context *vpipe,
376 struct pipe_resource *dst,
377 unsigned dstx, unsigned dsty, unsigned dstz,
378 struct pipe_resource *src,
379 unsigned srcx, unsigned srcy, unsigned srcz,
380 unsigned width, unsigned height)
381 {
382 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
383
384 assert(vpipe);
385 assert(dst);
386
387 struct pipe_box box;
388 box.x = srcx;
389 box.y = srcy;
390 box.z = srcz;
391 box.width = width;
392 box.height = height;
393
394 if (ctx->pipe->resource_copy_region)
395 ctx->pipe->resource_copy_region(ctx->pipe, dst, 0,
396 dstx, dsty, dstz,
397 src, 0, &box);
398 else
399 util_resource_copy_region(ctx->pipe, dst, 0,
400 dstx, dsty, dstz,
401 src, 0, &box);
402 }
403 #endif
404
405 static struct pipe_transfer*
406 vl_mpeg12_get_transfer(struct pipe_video_context *vpipe,
407 struct pipe_resource *resource,
408 unsigned level,
409 unsigned usage, /* a combination of PIPE_TRANSFER_x */
410 const struct pipe_box *box)
411 {
412 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
413
414 assert(vpipe);
415 assert(resource);
416 assert(box);
417
418 return ctx->pipe->get_transfer(ctx->pipe, resource, level, usage, box);
419 }
420
421 static void
422 vl_mpeg12_transfer_destroy(struct pipe_video_context *vpipe,
423 struct pipe_transfer *transfer)
424 {
425 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
426
427 assert(vpipe);
428 assert(transfer);
429
430 ctx->pipe->transfer_destroy(ctx->pipe, transfer);
431 }
432
433 static void*
434 vl_mpeg12_transfer_map(struct pipe_video_context *vpipe,
435 struct pipe_transfer *transfer)
436 {
437 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
438
439 assert(vpipe);
440 assert(transfer);
441
442 return ctx->pipe->transfer_map(ctx->pipe, transfer);
443 }
444
445 static void
446 vl_mpeg12_transfer_flush_region(struct pipe_video_context *vpipe,
447 struct pipe_transfer *transfer,
448 const struct pipe_box *box)
449 {
450 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
451
452 assert(vpipe);
453 assert(transfer);
454 assert(box);
455
456 ctx->pipe->transfer_flush_region(ctx->pipe, transfer, box);
457 }
458
459 static void
460 vl_mpeg12_transfer_unmap(struct pipe_video_context *vpipe,
461 struct pipe_transfer *transfer)
462 {
463 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
464
465 assert(vpipe);
466 assert(transfer);
467
468 ctx->pipe->transfer_unmap(ctx->pipe, transfer);
469 }
470
471 static void
472 vl_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
473 struct pipe_resource *resource,
474 unsigned level,
475 unsigned usage, /* a combination of PIPE_TRANSFER_x */
476 const struct pipe_box *box,
477 const void *data,
478 unsigned stride,
479 unsigned slice_stride)
480 {
481 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
482
483 assert(vpipe);
484 assert(resource);
485 assert(box);
486 assert(data);
487 assert(ctx->pipe->transfer_inline_write);
488
489 ctx->pipe->transfer_inline_write(ctx->pipe, resource, level, usage,
490 box, data, stride, slice_stride);
491 }
492
493 static void
494 vl_mpeg12_render_picture(struct pipe_video_context *vpipe,
495 struct pipe_video_buffer *src_surface,
496 struct pipe_video_rect *src_area,
497 enum pipe_mpeg12_picture_type picture_type,
498 struct pipe_surface *dst_surface,
499 struct pipe_video_rect *dst_area,
500 struct pipe_fence_handle **fence)
501 {
502 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
503 struct vl_mpeg12_buffer *buf = (struct vl_mpeg12_buffer*)src_surface;
504
505 assert(vpipe);
506 assert(src_surface);
507 assert(src_area);
508 assert(dst_surface);
509 assert(dst_area);
510
511 unmap_buffer(buf);
512 flush_buffer(buf);
513
514 vl_compositor_render(&ctx->compositor, buf->surface,
515 picture_type, src_area,
516 dst_surface, dst_area, fence);
517 }
518
519 static void
520 vl_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
521 struct pipe_surface *bg,
522 struct pipe_video_rect *bg_src_rect)
523 {
524 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
525
526 assert(vpipe);
527 assert(bg);
528 assert(bg_src_rect);
529
530 vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
531 }
532
533 static void
534 vl_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
535 struct pipe_surface *layers[],
536 struct pipe_video_rect *src_rects[],
537 struct pipe_video_rect *dst_rects[],
538 unsigned num_layers)
539 {
540 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
541
542 assert(vpipe);
543 assert((layers && src_rects && dst_rects) ||
544 (!layers && !src_rects && !dst_rects));
545
546 vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
547 }
548
549 static void
550 vl_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
551 {
552 struct vl_mpeg12_context *ctx = (struct vl_mpeg12_context*)vpipe;
553
554 assert(vpipe);
555
556 vl_compositor_set_csc_matrix(&ctx->compositor, mat);
557 }
558
559 static bool
560 init_pipe_state(struct vl_mpeg12_context *ctx)
561 {
562 struct pipe_rasterizer_state rast;
563 struct pipe_blend_state blend;
564 struct pipe_depth_stencil_alpha_state dsa;
565 unsigned i;
566
567 assert(ctx);
568
569 memset(&rast, 0, sizeof rast);
570 rast.flatshade = 1;
571 rast.flatshade_first = 0;
572 rast.light_twoside = 0;
573 rast.front_ccw = 1;
574 rast.cull_face = PIPE_FACE_NONE;
575 rast.fill_back = PIPE_POLYGON_MODE_FILL;
576 rast.fill_front = PIPE_POLYGON_MODE_FILL;
577 rast.offset_point = 0;
578 rast.offset_line = 0;
579 rast.scissor = 0;
580 rast.poly_smooth = 0;
581 rast.poly_stipple_enable = 0;
582 rast.sprite_coord_enable = 0;
583 rast.point_size_per_vertex = 0;
584 rast.multisample = 0;
585 rast.line_smooth = 0;
586 rast.line_stipple_enable = 0;
587 rast.line_stipple_factor = 0;
588 rast.line_stipple_pattern = 0;
589 rast.line_last_pixel = 0;
590 rast.line_width = 1;
591 rast.point_smooth = 0;
592 rast.point_quad_rasterization = 0;
593 rast.point_size_per_vertex = 1;
594 rast.offset_units = 1;
595 rast.offset_scale = 1;
596 rast.gl_rasterization_rules = 1;
597
598 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
599 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
600
601 memset(&blend, 0, sizeof blend);
602
603 blend.independent_blend_enable = 0;
604 blend.rt[0].blend_enable = 0;
605 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
606 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
607 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
608 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
609 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
610 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
611 blend.logicop_enable = 0;
612 blend.logicop_func = PIPE_LOGICOP_CLEAR;
613 /* Needed to allow color writes to FB, even if blending disabled */
614 blend.rt[0].colormask = PIPE_MASK_RGBA;
615 blend.dither = 0;
616 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
617 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
618
619 memset(&dsa, 0, sizeof dsa);
620 dsa.depth.enabled = 0;
621 dsa.depth.writemask = 0;
622 dsa.depth.func = PIPE_FUNC_ALWAYS;
623 for (i = 0; i < 2; ++i) {
624 dsa.stencil[i].enabled = 0;
625 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
626 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
627 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
628 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
629 dsa.stencil[i].valuemask = 0;
630 dsa.stencil[i].writemask = 0;
631 }
632 dsa.alpha.enabled = 0;
633 dsa.alpha.func = PIPE_FUNC_ALWAYS;
634 dsa.alpha.ref_value = 0;
635 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
636 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
637
638 return true;
639 }
640
641 static bool
642 init_idct(struct vl_mpeg12_context *ctx, unsigned buffer_width, unsigned buffer_height)
643 {
644 unsigned chroma_width, chroma_height, chroma_blocks_x, chroma_blocks_y;
645 struct pipe_resource *idct_matrix;
646
647 /* TODO: Implement 422, 444 */
648 assert(ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
649 ctx->empty_block_mask = &const_empty_block_mask_420;
650
651 if (!(idct_matrix = vl_idct_upload_matrix(ctx->pipe)))
652 return false;
653
654 if (!vl_idct_init(&ctx->idct_y, ctx->pipe, buffer_width, buffer_height,
655 2, 2, TGSI_SWIZZLE_X, idct_matrix))
656 return false;
657
658 if (ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
659 chroma_width = buffer_width / 2;
660 chroma_height = buffer_height / 2;
661 chroma_blocks_x = 1;
662 chroma_blocks_y = 1;
663 } else if (ctx->base.chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
664 chroma_width = buffer_width;
665 chroma_height = buffer_height / 2;
666 chroma_blocks_x = 2;
667 chroma_blocks_y = 1;
668 } else {
669 chroma_width = buffer_width;
670 chroma_height = buffer_height;
671 chroma_blocks_x = 2;
672 chroma_blocks_y = 2;
673 }
674
675 if(!vl_idct_init(&ctx->idct_cr, ctx->pipe, chroma_width, chroma_height,
676 chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Z, idct_matrix))
677 return false;
678
679 if(!vl_idct_init(&ctx->idct_cb, ctx->pipe, chroma_width, chroma_height,
680 chroma_blocks_x, chroma_blocks_y, TGSI_SWIZZLE_Y, idct_matrix))
681 return false;
682
683 return true;
684 }
685
686 struct pipe_video_context *
687 vl_create_mpeg12_context(struct pipe_context *pipe,
688 enum pipe_video_profile profile,
689 enum pipe_video_chroma_format chroma_format,
690 unsigned width, unsigned height,
691 bool pot_buffers,
692 enum pipe_format decode_format)
693 {
694 struct vl_mpeg12_context *ctx;
695
696 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
697
698 ctx = CALLOC_STRUCT(vl_mpeg12_context);
699
700 if (!ctx)
701 return NULL;
702
703 ctx->base.profile = profile;
704 ctx->base.chroma_format = chroma_format;
705 ctx->base.width = width;
706 ctx->base.height = height;
707
708 ctx->base.screen = pipe->screen;
709
710 ctx->base.destroy = vl_mpeg12_destroy;
711 ctx->base.get_param = vl_mpeg12_get_param;
712 ctx->base.is_format_supported = vl_mpeg12_is_format_supported;
713 ctx->base.create_surface = vl_mpeg12_create_surface;
714 ctx->base.create_buffer = vl_mpeg12_create_buffer;
715 ctx->base.render_picture = vl_mpeg12_render_picture;
716 ctx->base.clear_render_target = vl_mpeg12_clear_render_target;
717 //ctx->base.resource_copy_region = vl_mpeg12_resource_copy_region;
718 ctx->base.get_transfer = vl_mpeg12_get_transfer;
719 ctx->base.transfer_destroy = vl_mpeg12_transfer_destroy;
720 ctx->base.transfer_map = vl_mpeg12_transfer_map;
721 ctx->base.transfer_flush_region = vl_mpeg12_transfer_flush_region;
722 ctx->base.transfer_unmap = vl_mpeg12_transfer_unmap;
723 if (pipe->transfer_inline_write)
724 ctx->base.transfer_inline_write = vl_mpeg12_transfer_inline_write;
725 ctx->base.set_picture_background = vl_mpeg12_set_picture_background;
726 ctx->base.set_picture_layers = vl_mpeg12_set_picture_layers;
727 ctx->base.set_csc_matrix = vl_mpeg12_set_csc_matrix;
728
729 ctx->pipe = pipe;
730 ctx->decode_format = decode_format;
731 ctx->pot_buffers = pot_buffers;
732
733 ctx->quads = vl_vb_upload_quads(ctx->pipe, 2, 2);
734 ctx->vertex_buffer_size = width / MACROBLOCK_WIDTH * height / MACROBLOCK_HEIGHT;
735 ctx->vertex_elems_state = vl_vb_get_elems_state(ctx->pipe, true);
736
737 if (ctx->vertex_elems_state == NULL) {
738 ctx->pipe->destroy(ctx->pipe);
739 FREE(ctx);
740 return NULL;
741 }
742
743 ctx->buffer_width = pot_buffers ? util_next_power_of_two(width) : align(width, MACROBLOCK_WIDTH);
744 ctx->buffer_height = pot_buffers ? util_next_power_of_two(height) : align(height, MACROBLOCK_HEIGHT);
745
746 if (!init_idct(ctx, ctx->buffer_width, ctx->buffer_height)) {
747 ctx->pipe->destroy(ctx->pipe);
748 FREE(ctx);
749 return NULL;
750 }
751
752 if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
753 ctx->buffer_width, ctx->buffer_height,
754 chroma_format)) {
755 vl_idct_cleanup(&ctx->idct_y);
756 vl_idct_cleanup(&ctx->idct_cr);
757 vl_idct_cleanup(&ctx->idct_cb);
758 ctx->pipe->destroy(ctx->pipe);
759 FREE(ctx);
760 return NULL;
761 }
762
763 if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
764 vl_idct_cleanup(&ctx->idct_y);
765 vl_idct_cleanup(&ctx->idct_cr);
766 vl_idct_cleanup(&ctx->idct_cb);
767 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
768 ctx->pipe->destroy(ctx->pipe);
769 FREE(ctx);
770 return NULL;
771 }
772
773 if (!init_pipe_state(ctx)) {
774 vl_idct_cleanup(&ctx->idct_y);
775 vl_idct_cleanup(&ctx->idct_cr);
776 vl_idct_cleanup(&ctx->idct_cb);
777 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
778 vl_compositor_cleanup(&ctx->compositor);
779 ctx->pipe->destroy(ctx->pipe);
780 FREE(ctx);
781 return NULL;
782 }
783
784 return &ctx->base;
785 }