g3dvl: Unbreak debug build.
[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 "sp_video_context.h"
29 #include <pipe/p_inlines.h>
30 #include <util/u_memory.h>
31 #include <util/u_rect.h>
32 #include <util/u_video.h>
33 #include "sp_winsys.h"
34 #include "sp_texture.h"
35
36 static void
37 sp_mpeg12_destroy(struct pipe_video_context *vpipe)
38 {
39 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
40
41 assert(vpipe);
42
43 /* Asserted in softpipe_delete_fs_state() for some reason */
44 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
45 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
46
47 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
48 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
49 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
50
51 pipe_video_surface_reference(&ctx->decode_target, NULL);
52 vl_compositor_cleanup(&ctx->compositor);
53 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
54 ctx->pipe->destroy(ctx->pipe);
55
56 FREE(ctx);
57 }
58
59 static void
60 sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
61 struct pipe_video_surface *past,
62 struct pipe_video_surface *future,
63 unsigned num_macroblocks,
64 struct pipe_macroblock *macroblocks,
65 struct pipe_fence_handle **fence)
66 {
67 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
68 struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
69
70 assert(vpipe);
71 assert(num_macroblocks);
72 assert(macroblocks);
73 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
74 assert(ctx->decode_target);
75
76 vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
77 softpipe_video_surface(ctx->decode_target)->tex,
78 past ? softpipe_video_surface(past)->tex : NULL,
79 future ? softpipe_video_surface(future)->tex : NULL,
80 num_macroblocks, mpeg12_macroblocks, fence);
81 }
82
83 static void
84 sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
85 struct pipe_surface *dst,
86 unsigned dstx, unsigned dsty,
87 unsigned width, unsigned height,
88 unsigned value)
89 {
90 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
91
92 assert(vpipe);
93 assert(dst);
94
95 if (ctx->pipe->surface_fill)
96 ctx->pipe->surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
97 else
98 util_surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
99 }
100
101 static void
102 sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
103 struct pipe_surface *dst,
104 unsigned dstx, unsigned dsty,
105 struct pipe_surface *src,
106 unsigned srcx, unsigned srcy,
107 unsigned width, unsigned height)
108 {
109 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
110
111 assert(vpipe);
112 assert(dst);
113
114 if (ctx->pipe->surface_copy)
115 ctx->pipe->surface_copy(ctx->pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
116 else
117 util_surface_copy(ctx->pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height);
118 }
119
120 static void
121 sp_mpeg12_render_picture(struct pipe_video_context *vpipe,
122 /*struct pipe_surface *backround,
123 struct pipe_video_rect *backround_area,*/
124 struct pipe_video_surface *src_surface,
125 enum pipe_mpeg12_picture_type picture_type,
126 /*unsigned num_past_surfaces,
127 struct pipe_video_surface *past_surfaces,
128 unsigned num_future_surfaces,
129 struct pipe_video_surface *future_surfaces,*/
130 struct pipe_video_rect *src_area,
131 struct pipe_surface *dst_surface,
132 struct pipe_video_rect *dst_area,
133 /*unsigned num_layers,
134 struct pipe_surface *layers,
135 struct pipe_video_rect *layer_src_areas,
136 struct pipe_video_rect *layer_dst_areas*/
137 struct pipe_fence_handle **fence)
138 {
139 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
140
141 assert(vpipe);
142 assert(src_surface);
143 assert(src_area);
144 assert(dst_surface);
145 assert(dst_area);
146
147 vl_compositor_render(&ctx->compositor, softpipe_video_surface(src_surface)->tex,
148 picture_type, src_area, dst_surface->texture, dst_area, fence);
149 }
150
151 static void
152 sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
153 struct pipe_video_surface *dt)
154 {
155 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
156
157 assert(vpipe);
158 assert(dt);
159
160 pipe_video_surface_reference(&ctx->decode_target, dt);
161 }
162
163 static void
164 sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
165 {
166 struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
167
168 assert(vpipe);
169
170 vl_compositor_set_csc_matrix(&ctx->compositor, mat);
171 }
172
173 static bool
174 init_pipe_state(struct sp_mpeg12_context *ctx)
175 {
176 struct pipe_rasterizer_state rast;
177 struct pipe_blend_state blend;
178 struct pipe_depth_stencil_alpha_state dsa;
179 unsigned i;
180
181 assert(ctx);
182
183 rast.flatshade = 1;
184 rast.flatshade_first = 0;
185 rast.light_twoside = 0;
186 rast.front_winding = PIPE_WINDING_CCW;
187 rast.cull_mode = PIPE_WINDING_CW;
188 rast.fill_cw = PIPE_POLYGON_MODE_FILL;
189 rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
190 rast.offset_cw = 0;
191 rast.offset_ccw = 0;
192 rast.scissor = 0;
193 rast.poly_smooth = 0;
194 rast.poly_stipple_enable = 0;
195 rast.point_sprite = 0;
196 rast.point_size_per_vertex = 0;
197 rast.multisample = 0;
198 rast.line_smooth = 0;
199 rast.line_stipple_enable = 0;
200 rast.line_stipple_factor = 0;
201 rast.line_stipple_pattern = 0;
202 rast.line_last_pixel = 0;
203 rast.bypass_vs_clip_and_viewport = 0;
204 rast.line_width = 1;
205 rast.point_smooth = 0;
206 rast.point_size = 1;
207 rast.offset_units = 1;
208 rast.offset_scale = 1;
209 rast.gl_rasterization_rules = 1;
210 /*rast.sprite_coord_mode[i] = ;*/
211 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
212 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
213
214 blend.blend_enable = 0;
215 blend.rgb_func = PIPE_BLEND_ADD;
216 blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
217 blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
218 blend.alpha_func = PIPE_BLEND_ADD;
219 blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
220 blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
221 blend.logicop_enable = 0;
222 blend.logicop_func = PIPE_LOGICOP_CLEAR;
223 /* Needed to allow color writes to FB, even if blending disabled */
224 blend.colormask = PIPE_MASK_RGBA;
225 blend.dither = 0;
226 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
227 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
228
229 dsa.depth.enabled = 0;
230 dsa.depth.writemask = 0;
231 dsa.depth.func = PIPE_FUNC_ALWAYS;
232 for (i = 0; i < 2; ++i) {
233 dsa.stencil[i].enabled = 0;
234 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
235 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
236 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
237 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
238 dsa.stencil[i].ref_value = 0;
239 dsa.stencil[i].valuemask = 0;
240 dsa.stencil[i].writemask = 0;
241 }
242 dsa.alpha.enabled = 0;
243 dsa.alpha.func = PIPE_FUNC_ALWAYS;
244 dsa.alpha.ref_value = 0;
245 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
246 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
247
248 return true;
249 }
250
251 static struct pipe_video_context *
252 sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
253 enum pipe_video_chroma_format chroma_format,
254 unsigned width, unsigned height,
255 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
256 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
257 bool pot_buffers)
258 {
259 struct sp_mpeg12_context *ctx;
260
261 assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
262
263 ctx = CALLOC_STRUCT(sp_mpeg12_context);
264
265 if (!ctx)
266 return NULL;
267
268 ctx->base.profile = profile;
269 ctx->base.chroma_format = chroma_format;
270 ctx->base.width = width;
271 ctx->base.height = height;
272
273 ctx->base.screen = pipe->screen;
274 ctx->base.destroy = sp_mpeg12_destroy;
275 ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
276 ctx->base.render_picture = sp_mpeg12_render_picture;
277 ctx->base.surface_fill = sp_mpeg12_surface_fill;
278 ctx->base.surface_copy = sp_mpeg12_surface_copy;
279 ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
280 ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
281
282 ctx->pipe = pipe;
283
284 if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
285 width, height, chroma_format,
286 bufmode, eb_handling, pot_buffers)) {
287 ctx->pipe->destroy(ctx->pipe);
288 FREE(ctx);
289 return NULL;
290 }
291
292 if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
293 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
294 ctx->pipe->destroy(ctx->pipe);
295 FREE(ctx);
296 return NULL;
297 }
298
299 if (!init_pipe_state(ctx)) {
300 vl_compositor_cleanup(&ctx->compositor);
301 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
302 ctx->pipe->destroy(ctx->pipe);
303 FREE(ctx);
304 return NULL;
305 }
306
307 return &ctx->base;
308 }
309
310 struct pipe_video_context *
311 sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
312 enum pipe_video_chroma_format chroma_format,
313 unsigned width, unsigned height)
314 {
315 struct pipe_context *pipe;
316
317 assert(screen);
318 assert(width && height);
319
320 pipe = softpipe_create(screen);
321 if (!pipe)
322 return NULL;
323
324 /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
325 /* TODO: Use XFER_NONE when implemented */
326 return sp_video_create_ex(pipe, profile,
327 chroma_format,
328 width, height,
329 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
330 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
331 true);
332 }
333
334 struct pipe_video_context *
335 sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
336 enum pipe_video_chroma_format chroma_format,
337 unsigned width, unsigned height,
338 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
339 enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
340 bool pot_buffers)
341 {
342 assert(pipe);
343 assert(width && height);
344
345 switch (u_reduce_video_profile(profile)) {
346 case PIPE_VIDEO_CODEC_MPEG12:
347 return sp_mpeg12_create(pipe, profile,
348 chroma_format,
349 width, height,
350 bufmode, eb_handling,
351 pot_buffers);
352 default:
353 return NULL;
354 }
355 }