First xvmc-r600 implementation
[mesa.git] / src / gallium / drivers / r600 / r600_video_context.c
1 #include <X11/Xlib.h>
2 #include <X11/Xutil.h>
3 #include <pipe/p_defines.h>
4 #include <pipe/p_context.h>
5 #include <pipe/p_screen.h>
6 #include <util/u_memory.h>
7 #include <X11/Xlib.h>
8
9 #include <fcntl.h>
10
11 #include "softpipe/sp_texture.h"
12
13 #include "r600_video_context.h"
14 #include <softpipe/sp_video_context.h>
15
16 #if 0
17
18 static void r600_mpeg12_destroy(struct pipe_video_context *vpipe)
19 {
20 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
21
22 assert(vpipe);
23
24 ctx->pipe->bind_vs_state(ctx->pipe, NULL);
25 ctx->pipe->bind_fs_state(ctx->pipe, NULL);
26
27 ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
28 ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
29 ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
30
31 pipe_video_surface_reference(&ctx->decode_target, NULL);
32 vl_compositor_cleanup(&ctx->compositor);
33 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
34 ctx->pipe->destroy(ctx->pipe);
35
36 FREE(ctx);
37 }
38
39 static void
40 r600_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
41 struct pipe_video_surface *past,
42 struct pipe_video_surface *future,
43 unsigned num_macroblocks,
44 struct pipe_macroblock *macroblocks,
45 struct pipe_fence_handle **fence)
46 {
47 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
48 struct pipe_mpeg12_macroblock *mpeg12_macroblocks =
49 (struct pipe_mpeg12_macroblock*)macroblocks;
50
51 assert(vpipe);
52 assert(num_macroblocks);
53 assert(macroblocks);
54 assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
55 assert(ctx->decode_target);
56
57 vl_mpeg12_mc_renderer_render_macroblocks(
58 &ctx->mc_renderer,
59 r600_video_surface(ctx->decode_target)->tex,
60 past ? r600_video_surface(past)->tex : NULL,
61 future ? r600_video_surface(future)->tex : NULL,
62 num_macroblocks, mpeg12_macroblocks, fence);
63 }
64
65 static void r600_mpeg12_clear_surface(struct pipe_video_context *vpipe,
66 unsigned x, unsigned y,
67 unsigned width, unsigned height,
68 unsigned value,
69 struct pipe_surface *surface)
70 {
71 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
72
73 assert(vpipe);
74 assert(surface);
75
76 if (ctx->pipe->surface_fill)
77 ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value);
78 else
79 util_surface_fill(ctx->pipe, surface, x, y, width, height, value);
80 }
81
82 static void
83 r600_mpeg12_render_picture(struct pipe_video_context *vpipe,
84 struct pipe_video_surface *src_surface,
85 enum pipe_mpeg12_picture_type picture_type,
86 struct pipe_video_rect *src_area,
87 struct pipe_surface *dst_surface,
88 struct pipe_video_rect *dst_area,
89 struct pipe_fence_handle **fence)
90 {
91 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
92
93 assert(vpipe);
94 assert(src_surface);
95 assert(src_area);
96 assert(dst_surface);
97 assert(dst_area);
98
99 vl_compositor_render(&ctx->compositor,
100 r600_video_surface(src_surface)->tex,
101 picture_type, src_area, dst_surface->texture,
102 dst_area, fence);
103 }
104
105 static void r600_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
106 struct pipe_video_surface *dt)
107 {
108 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
109
110 assert(vpipe);
111 assert(dt);
112
113 pipe_video_surface_reference(&ctx->decode_target, dt);
114 }
115
116 static void r600_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe,
117 const float *mat)
118 {
119 struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
120
121 assert(vpipe);
122
123 vl_compositor_set_csc_matrix(&ctx->compositor, mat);
124 }
125
126 static bool r600_mpeg12_init_pipe_state(struct radeon_mpeg12_context *ctx)
127 {
128 struct pipe_rasterizer_state rast;
129 struct pipe_blend_state blend;
130 struct pipe_depth_stencil_alpha_state dsa;
131 unsigned i;
132
133 assert(ctx);
134
135 rast.flatshade = 1;
136 rast.flatshade_first = 0;
137 rast.light_twoside = 0;
138 rast.front_winding = PIPE_WINDING_CCW;
139 rast.cull_mode = PIPE_WINDING_CW;
140 rast.fill_cw = PIPE_POLYGON_MODE_FILL;
141 rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
142 rast.offset_cw = 0;
143 rast.offset_ccw = 0;
144 rast.scissor = 0;
145 rast.poly_smooth = 0;
146 rast.poly_stipple_enable = 0;
147 rast.point_sprite = 0;
148 rast.point_size_per_vertex = 0;
149 rast.multisample = 0;
150 rast.line_smooth = 0;
151 rast.line_stipple_enable = 0;
152 rast.line_stipple_factor = 0;
153 rast.line_stipple_pattern = 0;
154 rast.line_last_pixel = 0;
155 rast.bypass_vs_clip_and_viewport = 0;
156 rast.line_width = 1;
157 rast.point_smooth = 0;
158 rast.point_size = 1;
159 rast.offset_units = 1;
160 rast.offset_scale = 1;
161 /*rast.sprite_coord_mode[i] = ;*/
162 ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
163 ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
164
165 blend.blend_enable = 0;
166 blend.rgb_func = PIPE_BLEND_ADD;
167 blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
168 blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
169 blend.alpha_func = PIPE_BLEND_ADD;
170 blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
171 blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
172 blend.logicop_enable = 0;
173 blend.logicop_func = PIPE_LOGICOP_CLEAR;
174 /* Needed to allow color writes to FB, even if blending disabled */
175 blend.colormask = PIPE_MASK_RGBA;
176 blend.dither = 0;
177 ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
178 ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
179
180 dsa.depth.enabled = 0;
181 dsa.depth.writemask = 0;
182 dsa.depth.func = PIPE_FUNC_ALWAYS;
183 for (i = 0; i < 2; ++i)
184 {
185 dsa.stencil[i].enabled = 0;
186 dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
187 dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
188 dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
189 dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
190 dsa.stencil[i].ref_value = 0;
191 dsa.stencil[i].valuemask = 0;
192 dsa.stencil[i].writemask = 0;
193 }
194 dsa.alpha.enabled = 0;
195 dsa.alpha.func = PIPE_FUNC_ALWAYS;
196 dsa.alpha.ref_value = 0;
197 ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
198 ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
199 }
200
201 static struct pipe_video_context *
202 r600_mpeg12_context_create(struct pipe_screen *screen,
203 enum pipe_video_profile profile,
204 enum pipe_video_chroma_format chroma_format,
205 unsigned int width,
206 unsigned int height)
207 {
208 struct radeon_mpeg12_context *ctx;
209 ctx = CALLOC_STRUCT(radeon_mpeg12_context);
210 if (!ctx)
211 return NULL;
212
213 ctx->base.profile = profile;
214 ctx->base.chroma_format = chroma_format;
215 ctx->base.width = width;
216 ctx->base.height = height;
217 ctx->base.screen = screen;
218
219 ctx->base.destroy = radeon_mpeg12_destroy;
220 ctx->base.decode_macroblocks = radeon_mpeg12_decode_macroblocks;
221 ctx->base.clear_surface = radeon_mpeg12_clear_surface;
222 ctx->base.render_picture = radeon_mpeg12_render_picture;
223 ctx->base.set_decode_target = radeon_mpeg12_set_decode_target;
224 ctx->base.set_csc_matrix = radeon_mpeg12_set_csc_matrix;
225
226 ctx->pipe = r600_create_context(screen,(struct r600_winsys*)screen->winsys);
227 if (!ctx->pipe)
228 {
229 FREE(ctx);
230 return NULL;
231 }
232
233 if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
234 width, height, chroma_format,
235 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
236 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
237 true))
238 {
239 ctx->pipe->destroy(ctx->pipe);
240 FREE(ctx);
241 return NULL;
242 }
243
244 if (!vl_compositor_init(&ctx->compositor, ctx->pipe))
245 {
246 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
247 ctx->pipe->destroy(ctx->pipe);
248 FREE(ctx);
249 return NULL;
250 }
251
252 if (!radeon_mpeg12_init_pipe_state(ctx))
253 {
254 vl_compositor_cleanup(&ctx->compositor);
255 vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
256 ctx->pipe->destroy(ctx->pipe);
257 FREE(ctx);
258 return NULL;
259 }
260
261 return &ctx->base;
262 }
263
264 #endif
265
266 struct pipe_video_context *
267 r600_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
268 enum pipe_video_chroma_format chroma_format,
269 unsigned width, unsigned height, void *priv)
270 {
271 struct pipe_context *pipe;
272
273 assert(screen);
274
275 pipe = screen->context_create(screen, priv);
276 if (!pipe)
277 return NULL;
278
279 return sp_video_create_ex(pipe, profile, chroma_format, width, height,
280 VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
281 VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
282 true,
283 PIPE_FORMAT_VUYX);
284
285 #if 0
286 struct pipe_video_context *vpipe;
287 struct radeon_vl_context *rvl_ctx;
288
289 assert(p_screen);
290 assert(width && height);
291
292 /* create radeon pipe_context */
293 switch(u_reduce_video_profile(profile))
294 {
295 case PIPE_VIDEO_CODEC_MPEG12:
296 vpipe = radeon_mpeg12_context_create(p_screen, profile, chr_f,
297 width, height);
298 break;
299 default:
300 return NULL;
301 }
302
303 /* create radeon_vl_context */
304 rvl_ctx = calloc(1, sizeof(struct radeon_vl_context));
305 rvl_ctx->display = display;
306 rvl_ctx->screen = screen;
307
308 vpipe->priv = rvl_ctx;
309
310 return vpipe;
311 #endif
312 }