vl: Decode to XRGB, not ARGB.
[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_rect.h>
35 #include <util/u_video.h>
36 #include "sp_public.h"
37 #include "sp_texture.h"
38
39 static void
40 sp_mpeg12_destroy(struct pipe_video_context *vpipe)
41 {
42 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
43
44 assert(vpipe);
45
46 /* Asserted in softpipe_delete_fs_state() for some reason */
47 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
48 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
49
50 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
51 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
52 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
53
54 pipe_surface_reference(&ctx->decode_target, NULL);
55 vl_compositor_cleanup(&ctx->compositor);
56 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
57 ctx->pipe->destroy(ctx->pipe);
58
59 FREE(ctx);
60 }
61
62 static int
63 sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
64 {
65 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
66
67 assert(vpipe);
68
69 switch (param) {
70 case PIPE_CAP_NPOT_TEXTURES:
71 /* XXX: Temporary; not all paths are NPOT-tested */
72 #if 0
73 return ctx->pipe->screen->get_param(ctx->pipe->screen, param);
74 #endif
75 return FALSE;
76 case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
77 return ctx->decode_format;
78 default:
79 {
80 debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
81 return 0;
82 }
83 }
84 }
85
86 static boolean
87 sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
88 enum pipe_format format,
89 unsigned usage,
90 unsigned geom)
91 {
92 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
93
94 assert(vpipe);
95
96 /* XXX: Temporary; not all paths are NPOT-tested */
97 if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
98 return FALSE;
99
100 return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, PIPE_TEXTURE_2D,
101 format, usage, geom);
102 }
103
104 static void
105 sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
106 struct pipe_surface *past,
107 struct pipe_surface *future,
108 unsigned num_macroblocks,
109 struct pipe_macroblock *macroblocks,
110 struct pipe_fence_handle **fence)
111 {
112 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
113 struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
114
115 assert(vpipe);
116 assert(num_macroblocks);
117 assert(macroblocks);
118 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
119 assert(ctx->decode_target);
120
121 vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
122 ctx->decode_target,
123 past, future, num_macroblocks,
124 mpeg12_macroblocks, fence);
125 }
126
127 static void
128 sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
129 struct pipe_surface *dst,
130 unsigned dstx, unsigned dsty,
131 unsigned width, unsigned height,
132 unsigned value)
133 {
134 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
135
136 assert(vpipe);
137 assert(dst);
138
139 if (ctx->pipe->surface_fill)
140 ctx->pipe->surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
141 else
142 util_surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
143 }
144
145 static void
146 sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
147 struct pipe_surface *dst,
148 unsigned dstx, unsigned dsty,
149 struct pipe_surface *src,
150 unsigned srcx, unsigned srcy,
151 unsigned width, unsigned height)
152 {
153 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
154
155 assert(vpipe);
156 assert(dst);
157
158 if (ctx->pipe->surface_copy)
159 ctx->pipe->surface_copy(ctx->pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
160 else
161 util_surface_copy(ctx->pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height);
162 }
163
164 static void
165 sp_mpeg12_render_picture(struct pipe_video_context *vpipe,
166 struct pipe_surface *src_surface,
167 enum pipe_mpeg12_picture_type picture_type,
168 /*unsigned num_past_surfaces,
169 struct pipe_surface *past_surfaces,
170 unsigned num_future_surfaces,
171 struct pipe_surface *future_surfaces,*/
172 struct pipe_video_rect *src_area,
173 struct pipe_surface *dst_surface,
174 struct pipe_video_rect *dst_area,
175 struct pipe_fence_handle **fence)
176 {
177 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
178
179 assert(vpipe);
180 assert(src_surface);
181 assert(src_area);
182 assert(dst_surface);
183 assert(dst_area);
184
185 vl_compositor_render(&ctx->compositor, src_surface,
186 picture_type, src_area, dst_surface, dst_area, fence);
187 }
188
189 static void
190 sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
191 struct pipe_surface *bg,
192 struct pipe_video_rect *bg_src_rect)
193 {
194 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
195
196 assert(vpipe);
197 assert(bg);
198 assert(bg_src_rect);
199
200 vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
201 }
202
203 static void
204 sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
205 struct pipe_surface *layers[],
206 struct pipe_video_rect *src_rects[],
207 struct pipe_video_rect *dst_rects[],
208 unsigned num_layers)
209 {
210 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
211
212 assert(vpipe);
213 assert((layers && src_rects && dst_rects) ||
214 (!layers && !src_rects && !dst_rects));
215
216 vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
217 }
218
219 static void
220 sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
221 struct pipe_surface *dt)
222 {
223 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
224
225 assert(vpipe);
226 assert(dt);
227
228 pipe_surface_reference(&ctx->decode_target, dt);
229 }
230
231 static void
232 sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
233 {
234 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
235
236 assert(vpipe);
237
238 vl_compositor_set_csc_matrix(&ctx->compositor, mat);
239 }
240
241 static bool
242 init_pipe_state(struct sp_mpeg12_context *ctx)
243 {
244 struct pipe_rasterizer_state rast;
245 struct pipe_blend_state blend;
246 struct pipe_depth_stencil_alpha_state dsa;
247 unsigned i;
248
249 assert(ctx);
250
251 rast.flatshade = 1;
252 rast.flatshade_first = 0;
253 rast.light_twoside = 0;
254 rast.front_winding = PIPE_WINDING_CCW;
255 rast.cull_mode = PIPE_WINDING_CW;
256 rast.fill_cw = PIPE_POLYGON_MODE_FILL;
257 rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
258 rast.offset_cw = 0;
259 rast.offset_ccw = 0;
260 rast.scissor = 0;
261 rast.poly_smooth = 0;
262 rast.poly_stipple_enable = 0;
263 rast.sprite_coord_enable = 0;
264 rast.point_size_per_vertex = 0;
265 rast.multisample = 0;
266 rast.line_smooth = 0;
267 rast.line_stipple_enable = 0;
268 rast.line_stipple_factor = 0;
269 rast.line_stipple_pattern = 0;
270 rast.line_last_pixel = 0;
271 rast.line_width = 1;
272 rast.point_smooth = 0;
273 rast.point_quad_rasterization = 0;
274 rast.point_size = 1;
275 rast.offset_units = 1;
276 rast.offset_scale = 1;
277 rast.gl_rasterization_rules = 1;
278 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
279 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
280
281 blend.independent_blend_enable = 0;
282 blend.rt[0].blend_enable = 0;
283 blend.rt[0].rgb_func = PIPE_BLEND_ADD;
284 blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
285 blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
286 blend.rt[0].alpha_func = PIPE_BLEND_ADD;
287 blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
288 blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
289 blend.logicop_enable = 0;
290 blend.logicop_func = PIPE_LOGICOP_CLEAR;
291 /* Needed to allow color writes to FB, even if blending disabled */
292 blend.rt[0].colormask = PIPE_MASK_RGBA;
293 blend.dither = 0;
294 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
295 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
296
297 dsa.depth.enabled = 0;
298 dsa.depth.writemask = 0;
299 dsa.depth.func = PIPE_FUNC_ALWAYS;
300 for (i = 0; i < 2; ++i) {
301 dsa.stencil[i].enabled = 0;
302 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
303 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
304 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
305 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
306 dsa.stencil[i].valuemask = 0;
307 dsa.stencil[i].writemask = 0;
308 }
309 dsa.alpha.enabled = 0;
310 dsa.alpha.func = PIPE_FUNC_ALWAYS;
311 dsa.alpha.ref_value = 0;
312 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
313 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
314
315 return true;
316 }
317
318 static struct pipe_video_context *
319 sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
320 enum pipe_video_chroma_format chroma_format,
321 unsigned width, unsigned height,
322 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
323 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
324 bool pot_buffers,
325 enum pipe_format decode_format)
326 {
327 struct sp_mpeg12_context *ctx;
328
329 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
330
331 ctx = CALLOC_STRUCT(sp_mpeg12_context);
332
333 if (!ctx)
334 return NULL;
335
336 ctx->base.profile = profile;
337 ctx->base.chroma_format = chroma_format;
338 ctx->base.width = width;
339 ctx->base.height = height;
340
341 ctx->base.screen = pipe->screen;
342 ctx->base.destroy = sp_mpeg12_destroy;
343 ctx->base.get_param = sp_mpeg12_get_param;
344 ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
345 ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
346 ctx->base.render_picture = sp_mpeg12_render_picture;
347 ctx->base.surface_fill = sp_mpeg12_surface_fill;
348 ctx->base.surface_copy = sp_mpeg12_surface_copy;
349 ctx->base.set_picture_background = sp_mpeg12_set_picture_background;
350 ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers;
351 ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
352 ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
353
354 ctx->pipe = pipe;
355 ctx->decode_format = decode_format;
356
357 if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
358 width, height, chroma_format,
359 bufmode, eb_handling, pot_buffers)) {
360 ctx->pipe->destroy(ctx->pipe);
361 FREE(ctx);
362 return NULL;
363 }
364
365 if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
366 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
367 ctx->pipe->destroy(ctx->pipe);
368 FREE(ctx);
369 return NULL;
370 }
371
372 if (!init_pipe_state(ctx)) {
373 vl_compositor_cleanup(&ctx->compositor);
374 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
375 ctx->pipe->destroy(ctx->pipe);
376 FREE(ctx);
377 return NULL;
378 }
379
380 return &ctx->base;
381 }
382
383 struct pipe_video_context *
384 sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
385 enum pipe_video_chroma_format chroma_format,
386 unsigned width, unsigned height, void *priv)
387 {
388 struct pipe_context *pipe;
389
390 assert(screen);
391 assert(width && height);
392
393 pipe = screen->context_create(screen, NULL);
394 if (!pipe)
395 return NULL;
396
397 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
398 /* TODO: Use XFER_NONE when implemented */
399 return sp_video_create_ex(pipe, profile,
400 chroma_format,
401 width, height,
402 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
403 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
404 true,
405 PIPE_FORMAT_XYUV);
406 }
407
408 struct pipe_video_context *
409 sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
410 enum pipe_video_chroma_format chroma_format,
411 unsigned width, unsigned height,
412 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
413 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
414 bool pot_buffers,
415 enum pipe_format decode_format)
416 {
417 assert(pipe);
418 assert(width && height);
419
420 switch (u_reduce_video_profile(profile)) {
421 case PIPE_VIDEO_CODEC_MPEG12:
422 return sp_mpeg12_create(pipe, profile,
423 chroma_format,
424 width, height,
425 bufmode, eb_handling,
426 pot_buffers,
427 decode_format);
428 default:
429 return NULL;
430 }
431 }