Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / gallium / state_trackers / g3dvl / vl_r16snorm_mc_buf.c
1 #define VL_INTERNAL
2 #include "vl_r16snorm_mc_buf.h"
3 #include <assert.h>
4 #include <stdlib.h>
5 #include <pipe/p_context.h>
6 #include <pipe/p_winsys.h>
7 #include <pipe/p_screen.h>
8 #include <pipe/p_state.h>
9 #include <pipe/p_inlines.h>
10 #include <tgsi/tgsi_parse.h>
11 #include <tgsi/tgsi_build.h>
12 #include <util/u_math.h>
13 #include "vl_render.h"
14 #include "vl_shader_build.h"
15 #include "vl_surface.h"
16 #include "vl_util.h"
17 #include "vl_types.h"
18 #include "vl_defs.h"
19
20 /*
21 * TODO: Dynamically determine number of buf sets to use, based on
22 * video size and available mem, since we can easily run out of memory
23 * for high res videos.
24 * Note: Destroying previous frame's buffers and creating new ones
25 * doesn't work, since the buffer are not actually destroyed until their
26 * fence is signalled, and if we render fast enough we will create faster
27 * than we destroy.
28 */
29 #define NUM_BUF_SETS 4 /* Number of rotating buffer sets to use */
30
31 enum vlMacroBlockTypeEx
32 {
33 vlMacroBlockExTypeIntra,
34 vlMacroBlockExTypeFwdPredictedFrame,
35 vlMacroBlockExTypeFwdPredictedField,
36 vlMacroBlockExTypeBkwdPredictedFrame,
37 vlMacroBlockExTypeBkwdPredictedField,
38 vlMacroBlockExTypeBiPredictedFrame,
39 vlMacroBlockExTypeBiPredictedField,
40
41 vlNumMacroBlockExTypes
42 };
43
44 struct vlVertexShaderConsts
45 {
46 struct vlVertex4f denorm;
47 };
48
49 struct vlFragmentShaderConsts
50 {
51 struct vlVertex4f multiplier;
52 struct vlVertex4f div;
53 };
54
55 struct vlR16SnormBufferedMC
56 {
57 struct vlRender base;
58
59 unsigned int picture_width, picture_height;
60 enum vlFormat picture_format;
61
62 unsigned int cur_buf;
63 struct vlSurface *buffered_surface;
64 struct vlSurface *past_surface, *future_surface;
65 struct vlVertex2f surface_tex_inv_size;
66 struct vlVertex2f zero_block[3];
67 unsigned int num_macroblocks;
68 struct vlMpeg2MacroBlock *macroblocks;
69
70 struct pipe_context *pipe;
71 struct pipe_viewport_state viewport;
72 struct pipe_framebuffer_state render_target;
73 struct pipe_sampler_state *samplers[5];
74 struct pipe_texture *textures[NUM_BUF_SETS][5];
75 struct pipe_surface *tex_surface[3];
76 short *texels[3];
77 void *i_vs, *p_vs[2], *b_vs[2];
78 void *i_fs, *p_fs[2], *b_fs[2];
79 struct pipe_vertex_buffer vertex_bufs[NUM_BUF_SETS][3];
80 struct pipe_vertex_element vertex_elems[8];
81 struct pipe_constant_buffer vs_const_buf, fs_const_buf;
82 };
83
84 static int vlBegin
85 (
86 struct vlRender *render
87 )
88 {
89 assert(render);
90
91 return 0;
92 }
93
94 static inline int vlGrabFrameCodedBlock(short *src, short *dst, unsigned int dst_pitch)
95 {
96 unsigned int y;
97
98 for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
99 memcpy
100 (
101 dst + y * dst_pitch,
102 src + y * VL_BLOCK_WIDTH,
103 VL_BLOCK_WIDTH * 2
104 );
105
106 return 0;
107 }
108
109 static inline int vlGrabFieldCodedBlock(short *src, short *dst, unsigned int dst_pitch)
110 {
111 unsigned int y;
112
113 for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
114 memcpy
115 (
116 dst + y * dst_pitch * 2,
117 src + y * VL_BLOCK_WIDTH,
118 VL_BLOCK_WIDTH * 2
119 );
120
121 return 0;
122 }
123
124 static inline int vlGrabNoBlock(short *dst, unsigned int dst_pitch)
125 {
126 unsigned int y;
127
128 for (y = 0; y < VL_BLOCK_HEIGHT; ++y)
129 memset
130 (
131 dst + y * dst_pitch,
132 0,
133 VL_BLOCK_WIDTH * 2
134 );
135
136 return 0;
137 }
138
139 static inline int vlGrabBlocks
140 (
141 struct vlR16SnormBufferedMC *mc,
142 unsigned int mbx,
143 unsigned int mby,
144 enum vlDCTType dct_type,
145 unsigned int coded_block_pattern,
146 short *blocks
147 )
148 {
149 short *texels;
150 unsigned int tex_pitch;
151 unsigned int x, y, tb = 0, sb = 0;
152 unsigned int mbpx = mbx * VL_MACROBLOCK_WIDTH, mbpy = mby * VL_MACROBLOCK_HEIGHT;
153
154 assert(mc);
155 assert(blocks);
156
157 tex_pitch = mc->tex_surface[0]->stride / mc->tex_surface[0]->block.size;
158 texels = mc->texels[0] + mbpy * tex_pitch + mbpx;
159
160 for (y = 0; y < 2; ++y)
161 {
162 for (x = 0; x < 2; ++x, ++tb)
163 {
164 if ((coded_block_pattern >> (5 - tb)) & 1)
165 {
166 short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
167
168 if (dct_type == vlDCTTypeFrameCoded)
169 {
170 vlGrabFrameCodedBlock
171 (
172 cur_block,
173 texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH,
174 tex_pitch
175 );
176 }
177 else
178 {
179 vlGrabFieldCodedBlock
180 (
181 cur_block,
182 texels + y * tex_pitch + x * VL_BLOCK_WIDTH,
183 tex_pitch
184 );
185 }
186
187 ++sb;
188 }
189 else if (mc->zero_block[0].x < 0.0f)
190 {
191 vlGrabNoBlock(texels + y * tex_pitch * VL_BLOCK_HEIGHT + x * VL_BLOCK_WIDTH, tex_pitch);
192
193 mc->zero_block[0].x = (mbpx + x * 8) * mc->surface_tex_inv_size.x;
194 mc->zero_block[0].y = (mbpy + y * 8) * mc->surface_tex_inv_size.y;
195 }
196 }
197 }
198
199 /* TODO: Implement 422, 444 */
200 mbpx >>= 1;
201 mbpy >>= 1;
202
203 for (tb = 0; tb < 2; ++tb)
204 {
205 tex_pitch = mc->tex_surface[tb + 1]->stride / mc->tex_surface[tb + 1]->block.size;
206 texels = mc->texels[tb + 1] + mbpy * tex_pitch + mbpx;
207
208 if ((coded_block_pattern >> (1 - tb)) & 1)
209 {
210 short *cur_block = blocks + sb * VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT;
211
212 vlGrabFrameCodedBlock
213 (
214 cur_block,
215 texels,
216 tex_pitch
217 );
218
219 ++sb;
220 }
221 else if (mc->zero_block[tb + 1].x < 0.0f)
222 {
223 vlGrabNoBlock(texels, tex_pitch);
224
225 mc->zero_block[tb + 1].x = (mbpx << 1) * mc->surface_tex_inv_size.x;
226 mc->zero_block[tb + 1].y = (mbpy << 1) * mc->surface_tex_inv_size.y;
227 }
228 }
229
230 return 0;
231 }
232
233 static inline enum vlMacroBlockTypeEx vlGetMacroBlockTypeEx(struct vlMpeg2MacroBlock *mb)
234 {
235 assert(mb);
236
237 switch (mb->mb_type)
238 {
239 case vlMacroBlockTypeIntra:
240 return vlMacroBlockExTypeIntra;
241 case vlMacroBlockTypeFwdPredicted:
242 return mb->mo_type == vlMotionTypeFrame ?
243 vlMacroBlockExTypeFwdPredictedFrame : vlMacroBlockExTypeFwdPredictedField;
244 case vlMacroBlockTypeBkwdPredicted:
245 return mb->mo_type == vlMotionTypeFrame ?
246 vlMacroBlockExTypeBkwdPredictedFrame : vlMacroBlockExTypeBkwdPredictedField;
247 case vlMacroBlockTypeBiPredicted:
248 return mb->mo_type == vlMotionTypeFrame ?
249 vlMacroBlockExTypeBiPredictedFrame : vlMacroBlockExTypeBiPredictedField;
250 default:
251 assert(0);
252 }
253
254 /* Unreachable */
255 return -1;
256 }
257
258 static inline int vlGrabMacroBlock
259 (
260 struct vlR16SnormBufferedMC *mc,
261 struct vlMpeg2MacroBlock *macroblock
262 )
263 {
264 assert(mc);
265 assert(macroblock);
266
267 mc->macroblocks[mc->num_macroblocks].mbx = macroblock->mbx;
268 mc->macroblocks[mc->num_macroblocks].mby = macroblock->mby;
269 mc->macroblocks[mc->num_macroblocks].mb_type = macroblock->mb_type;
270 mc->macroblocks[mc->num_macroblocks].mo_type = macroblock->mo_type;
271 mc->macroblocks[mc->num_macroblocks].dct_type = macroblock->dct_type;
272 mc->macroblocks[mc->num_macroblocks].PMV[0][0][0] = macroblock->PMV[0][0][0];
273 mc->macroblocks[mc->num_macroblocks].PMV[0][0][1] = macroblock->PMV[0][0][1];
274 mc->macroblocks[mc->num_macroblocks].PMV[0][1][0] = macroblock->PMV[0][1][0];
275 mc->macroblocks[mc->num_macroblocks].PMV[0][1][1] = macroblock->PMV[0][1][1];
276 mc->macroblocks[mc->num_macroblocks].PMV[1][0][0] = macroblock->PMV[1][0][0];
277 mc->macroblocks[mc->num_macroblocks].PMV[1][0][1] = macroblock->PMV[1][0][1];
278 mc->macroblocks[mc->num_macroblocks].PMV[1][1][0] = macroblock->PMV[1][1][0];
279 mc->macroblocks[mc->num_macroblocks].PMV[1][1][1] = macroblock->PMV[1][1][1];
280 mc->macroblocks[mc->num_macroblocks].cbp = macroblock->cbp;
281 mc->macroblocks[mc->num_macroblocks].blocks = macroblock->blocks;
282
283 vlGrabBlocks
284 (
285 mc,
286 macroblock->mbx,
287 macroblock->mby,
288 macroblock->dct_type,
289 macroblock->cbp,
290 macroblock->blocks
291 );
292
293 mc->num_macroblocks++;
294
295 return 0;
296 }
297
298 #define SET_BLOCK(vb, cbp, mbx, mby, unitx, unity, ofsx, ofsy, hx, hy, lm, cbm, crm, zb) \
299 (vb)[0].pos.x = (mbx) * (unitx) + (ofsx); (vb)[0].pos.y = (mby) * (unity) + (ofsy); \
300 (vb)[1].pos.x = (mbx) * (unitx) + (ofsx); (vb)[1].pos.y = (mby) * (unity) + (ofsy) + (hy); \
301 (vb)[2].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].pos.y = (mby) * (unity) + (ofsy); \
302 (vb)[3].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].pos.y = (mby) * (unity) + (ofsy); \
303 (vb)[4].pos.x = (mbx) * (unitx) + (ofsx); (vb)[4].pos.y = (mby) * (unity) + (ofsy) + (hy); \
304 (vb)[5].pos.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].pos.y = (mby) * (unity) + (ofsy) + (hy); \
305 \
306 if ((cbp) & (lm)) \
307 { \
308 (vb)[0].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].luma_tc.y = (mby) * (unity) + (ofsy); \
309 (vb)[1].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
310 (vb)[2].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].luma_tc.y = (mby) * (unity) + (ofsy); \
311 (vb)[3].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].luma_tc.y = (mby) * (unity) + (ofsy); \
312 (vb)[4].luma_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
313 (vb)[5].luma_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].luma_tc.y = (mby) * (unity) + (ofsy) + (hy); \
314 } \
315 else \
316 { \
317 (vb)[0].luma_tc.x = (zb)[0].x; (vb)[0].luma_tc.y = (zb)[0].y; \
318 (vb)[1].luma_tc.x = (zb)[0].x; (vb)[1].luma_tc.y = (zb)[0].y + (hy); \
319 (vb)[2].luma_tc.x = (zb)[0].x + (hx); (vb)[2].luma_tc.y = (zb)[0].y; \
320 (vb)[3].luma_tc.x = (zb)[0].x + (hx); (vb)[3].luma_tc.y = (zb)[0].y; \
321 (vb)[4].luma_tc.x = (zb)[0].x; (vb)[4].luma_tc.y = (zb)[0].y + (hy); \
322 (vb)[5].luma_tc.x = (zb)[0].x + (hx); (vb)[5].luma_tc.y = (zb)[0].y + (hy); \
323 } \
324 \
325 if ((cbp) & (cbm)) \
326 { \
327 (vb)[0].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cb_tc.y = (mby) * (unity) + (ofsy); \
328 (vb)[1].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
329 (vb)[2].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cb_tc.y = (mby) * (unity) + (ofsy); \
330 (vb)[3].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cb_tc.y = (mby) * (unity) + (ofsy); \
331 (vb)[4].cb_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
332 (vb)[5].cb_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cb_tc.y = (mby) * (unity) + (ofsy) + (hy); \
333 } \
334 else \
335 { \
336 (vb)[0].cb_tc.x = (zb)[1].x; (vb)[0].cb_tc.y = (zb)[1].y; \
337 (vb)[1].cb_tc.x = (zb)[1].x; (vb)[1].cb_tc.y = (zb)[1].y + (hy); \
338 (vb)[2].cb_tc.x = (zb)[1].x + (hx); (vb)[2].cb_tc.y = (zb)[1].y; \
339 (vb)[3].cb_tc.x = (zb)[1].x + (hx); (vb)[3].cb_tc.y = (zb)[1].y; \
340 (vb)[4].cb_tc.x = (zb)[1].x; (vb)[4].cb_tc.y = (zb)[1].y + (hy); \
341 (vb)[5].cb_tc.x = (zb)[1].x + (hx); (vb)[5].cb_tc.y = (zb)[1].y + (hy); \
342 } \
343 \
344 if ((cbp) & (crm)) \
345 { \
346 (vb)[0].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[0].cr_tc.y = (mby) * (unity) + (ofsy); \
347 (vb)[1].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[1].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
348 (vb)[2].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[2].cr_tc.y = (mby) * (unity) + (ofsy); \
349 (vb)[3].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[3].cr_tc.y = (mby) * (unity) + (ofsy); \
350 (vb)[4].cr_tc.x = (mbx) * (unitx) + (ofsx); (vb)[4].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
351 (vb)[5].cr_tc.x = (mbx) * (unitx) + (ofsx) + (hx); (vb)[5].cr_tc.y = (mby) * (unity) + (ofsy) + (hy); \
352 } \
353 else \
354 { \
355 (vb)[0].cr_tc.x = (zb)[2].x; (vb)[0].cr_tc.y = (zb)[2].y; \
356 (vb)[1].cr_tc.x = (zb)[2].x; (vb)[1].cr_tc.y = (zb)[2].y + (hy); \
357 (vb)[2].cr_tc.x = (zb)[2].x + (hx); (vb)[2].cr_tc.y = (zb)[2].y; \
358 (vb)[3].cr_tc.x = (zb)[2].x + (hx); (vb)[3].cr_tc.y = (zb)[2].y; \
359 (vb)[4].cr_tc.x = (zb)[2].x; (vb)[4].cr_tc.y = (zb)[2].y + (hy); \
360 (vb)[5].cr_tc.x = (zb)[2].x + (hx); (vb)[5].cr_tc.y = (zb)[2].y + (hy); \
361 }
362
363 static inline int vlGrabMacroBlockVB
364 (
365 struct vlR16SnormBufferedMC *mc,
366 struct vlMpeg2MacroBlock *macroblock,
367 unsigned int pos
368 )
369 {
370 struct vlVertex2f mo_vec[2];
371 unsigned int i;
372
373 assert(mc);
374 assert(macroblock);
375
376 switch (macroblock->mb_type)
377 {
378 case vlMacroBlockTypeBiPredicted:
379 {
380 struct vlVertex2f *vb;
381
382 vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
383 (
384 mc->pipe->winsys,
385 mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer,
386 PIPE_BUFFER_USAGE_CPU_WRITE
387 ) + pos * 2 * 24;
388
389 mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x;
390 mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y;
391
392 if (macroblock->mo_type == vlMotionTypeFrame)
393 {
394 for (i = 0; i < 24 * 2; i += 2)
395 {
396 vb[i].x = mo_vec[0].x;
397 vb[i].y = mo_vec[0].y;
398 }
399 }
400 else
401 {
402 mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x;
403 mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y;
404
405 for (i = 0; i < 24 * 2; i += 2)
406 {
407 vb[i].x = mo_vec[0].x;
408 vb[i].y = mo_vec[0].y;
409 vb[i + 1].x = mo_vec[1].x;
410 vb[i + 1].y = mo_vec[1].y;
411 }
412 }
413
414 mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][2].buffer);
415
416 /* fall-through */
417 }
418 case vlMacroBlockTypeFwdPredicted:
419 case vlMacroBlockTypeBkwdPredicted:
420 {
421 struct vlVertex2f *vb;
422
423 vb = (struct vlVertex2f*)mc->pipe->winsys->buffer_map
424 (
425 mc->pipe->winsys,
426 mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer,
427 PIPE_BUFFER_USAGE_CPU_WRITE
428 ) + pos * 2 * 24;
429
430 if (macroblock->mb_type == vlMacroBlockTypeBkwdPredicted)
431 {
432 mo_vec[0].x = macroblock->PMV[0][1][0] * 0.5f * mc->surface_tex_inv_size.x;
433 mo_vec[0].y = macroblock->PMV[0][1][1] * 0.5f * mc->surface_tex_inv_size.y;
434
435 if (macroblock->mo_type == vlMotionTypeField)
436 {
437 mo_vec[1].x = macroblock->PMV[1][1][0] * 0.5f * mc->surface_tex_inv_size.x;
438 mo_vec[1].y = macroblock->PMV[1][1][1] * 0.5f * mc->surface_tex_inv_size.y;
439 }
440 }
441 else
442 {
443 mo_vec[0].x = macroblock->PMV[0][0][0] * 0.5f * mc->surface_tex_inv_size.x;
444 mo_vec[0].y = macroblock->PMV[0][0][1] * 0.5f * mc->surface_tex_inv_size.y;
445
446 if (macroblock->mo_type == vlMotionTypeField)
447 {
448 mo_vec[1].x = macroblock->PMV[1][0][0] * 0.5f * mc->surface_tex_inv_size.x;
449 mo_vec[1].y = macroblock->PMV[1][0][1] * 0.5f * mc->surface_tex_inv_size.y;
450 }
451 }
452
453 if (macroblock->mo_type == vlMotionTypeFrame)
454 {
455 for (i = 0; i < 24 * 2; i += 2)
456 {
457 vb[i].x = mo_vec[0].x;
458 vb[i].y = mo_vec[0].y;
459 }
460 }
461 else
462 {
463 for (i = 0; i < 24 * 2; i += 2)
464 {
465 vb[i].x = mo_vec[0].x;
466 vb[i].y = mo_vec[0].y;
467 vb[i + 1].x = mo_vec[1].x;
468 vb[i + 1].y = mo_vec[1].y;
469 }
470 }
471
472 mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][1].buffer);
473
474 /* fall-through */
475 }
476 case vlMacroBlockTypeIntra:
477 {
478 const struct vlVertex2f unit =
479 {
480 mc->surface_tex_inv_size.x * VL_MACROBLOCK_WIDTH,
481 mc->surface_tex_inv_size.y * VL_MACROBLOCK_HEIGHT
482 };
483 const struct vlVertex2f half =
484 {
485 mc->surface_tex_inv_size.x * (VL_MACROBLOCK_WIDTH / 2),
486 mc->surface_tex_inv_size.y * (VL_MACROBLOCK_HEIGHT / 2)
487 };
488
489 struct vlMacroBlockVertexStream0
490 {
491 struct vlVertex2f pos;
492 struct vlVertex2f luma_tc;
493 struct vlVertex2f cb_tc;
494 struct vlVertex2f cr_tc;
495 } *vb;
496
497 vb = (struct vlMacroBlockVertexStream0*)mc->pipe->winsys->buffer_map
498 (
499 mc->pipe->winsys,
500 mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer,
501 PIPE_BUFFER_USAGE_CPU_WRITE
502 ) + pos * 24;
503
504 SET_BLOCK
505 (
506 vb,
507 macroblock->cbp, macroblock->mbx, macroblock->mby,
508 unit.x, unit.y, 0, 0, half.x, half.y,
509 32, 2, 1, mc->zero_block
510 );
511
512 SET_BLOCK
513 (
514 vb + 6,
515 macroblock->cbp, macroblock->mbx, macroblock->mby,
516 unit.x, unit.y, half.x, 0, half.x, half.y,
517 16, 2, 1, mc->zero_block
518 );
519
520 SET_BLOCK
521 (
522 vb + 12,
523 macroblock->cbp, macroblock->mbx, macroblock->mby,
524 unit.x, unit.y, 0, half.y, half.x, half.y,
525 8, 2, 1, mc->zero_block
526 );
527
528 SET_BLOCK
529 (
530 vb + 18,
531 macroblock->cbp, macroblock->mbx, macroblock->mby,
532 unit.x, unit.y, half.x, half.y, half.x, half.y,
533 4, 2, 1, mc->zero_block
534 );
535
536 mc->pipe->winsys->buffer_unmap(mc->pipe->winsys, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS][0].buffer);
537
538 break;
539 }
540 default:
541 assert(0);
542 }
543
544 return 0;
545 }
546
547 static int vlFlush
548 (
549 struct vlRender *render
550 )
551 {
552 struct vlR16SnormBufferedMC *mc;
553 struct pipe_context *pipe;
554 struct vlVertexShaderConsts *vs_consts;
555 unsigned int num_macroblocks[vlNumMacroBlockExTypes] = {0};
556 unsigned int offset[vlNumMacroBlockExTypes];
557 unsigned int vb_start = 0;
558 unsigned int mbw;
559 unsigned int mbh;
560 unsigned int num_mb_per_frame;
561 unsigned int i;
562
563 assert(render);
564
565 mc = (struct vlR16SnormBufferedMC*)render;
566
567 if (!mc->buffered_surface)
568 return 0;
569
570 mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
571 mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
572 num_mb_per_frame = mbw * mbh;
573
574 if (mc->num_macroblocks < num_mb_per_frame)
575 return 0;
576
577 pipe = mc->pipe;
578
579 for (i = 0; i < mc->num_macroblocks; ++i)
580 {
581 enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
582
583 num_macroblocks[mb_type_ex]++;
584 }
585
586 offset[0] = 0;
587
588 for (i = 1; i < vlNumMacroBlockExTypes; ++i)
589 offset[i] = offset[i - 1] + num_macroblocks[i - 1];
590
591 for (i = 0; i < mc->num_macroblocks; ++i)
592 {
593 enum vlMacroBlockTypeEx mb_type_ex = vlGetMacroBlockTypeEx(&mc->macroblocks[i]);
594
595 vlGrabMacroBlockVB(mc, &mc->macroblocks[i], offset[mb_type_ex]);
596
597 offset[mb_type_ex]++;
598 }
599
600 for (i = 0; i < 3; ++i)
601 {
602 pipe_surface_unmap(mc->tex_surface[i]);
603 mc->pipe->screen->tex_surface_release(mc->pipe->screen, &mc->tex_surface[i]);
604 }
605
606 mc->render_target.cbufs[0] = pipe->screen->get_tex_surface
607 (
608 pipe->screen,
609 mc->buffered_surface->texture,
610 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE
611 );
612
613 pipe->set_framebuffer_state(pipe, &mc->render_target);
614 pipe->set_viewport_state(pipe, &mc->viewport);
615 vs_consts = pipe->winsys->buffer_map
616 (
617 pipe->winsys,
618 mc->vs_const_buf.buffer,
619 PIPE_BUFFER_USAGE_CPU_WRITE
620 );
621
622 vs_consts->denorm.x = mc->buffered_surface->texture->width[0];
623 vs_consts->denorm.y = mc->buffered_surface->texture->height[0];
624
625 pipe->winsys->buffer_unmap(pipe->winsys, mc->vs_const_buf.buffer);
626 pipe->set_constant_buffer(pipe, PIPE_SHADER_VERTEX, 0, &mc->vs_const_buf);
627 pipe->set_constant_buffer(pipe, PIPE_SHADER_FRAGMENT, 0, &mc->fs_const_buf);
628
629 if (num_macroblocks[vlMacroBlockExTypeIntra] > 0)
630 {
631 pipe->set_vertex_buffers(pipe, 1, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
632 pipe->set_vertex_elements(pipe, 4, mc->vertex_elems);
633 pipe->set_sampler_textures(pipe, 3, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
634 pipe->bind_sampler_states(pipe, 3, (void**)mc->samplers);
635 pipe->bind_vs_state(pipe, mc->i_vs);
636 pipe->bind_fs_state(pipe, mc->i_fs);
637
638 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeIntra] * 24);
639 vb_start += num_macroblocks[vlMacroBlockExTypeIntra] * 24;
640 }
641
642 if (num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] > 0)
643 {
644 pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
645 pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
646 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
647 pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
648 pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
649 pipe->bind_vs_state(pipe, mc->p_vs[0]);
650 pipe->bind_fs_state(pipe, mc->p_fs[0]);
651
652 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24);
653 vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedFrame] * 24;
654 }
655
656 if (num_macroblocks[vlMacroBlockExTypeFwdPredictedField] > 0)
657 {
658 pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
659 pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
660 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
661 pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
662 pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
663 pipe->bind_vs_state(pipe, mc->p_vs[1]);
664 pipe->bind_fs_state(pipe, mc->p_fs[1]);
665
666 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24);
667 vb_start += num_macroblocks[vlMacroBlockExTypeFwdPredictedField] * 24;
668 }
669
670 if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] > 0)
671 {
672 pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
673 pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
674 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
675 pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
676 pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
677 pipe->bind_vs_state(pipe, mc->p_vs[0]);
678 pipe->bind_fs_state(pipe, mc->p_fs[0]);
679
680 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24);
681 vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedFrame] * 24;
682 }
683
684 if (num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] > 0)
685 {
686 pipe->set_vertex_buffers(pipe, 2, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
687 pipe->set_vertex_elements(pipe, 6, mc->vertex_elems);
688 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->future_surface->texture;
689 pipe->set_sampler_textures(pipe, 4, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
690 pipe->bind_sampler_states(pipe, 4, (void**)mc->samplers);
691 pipe->bind_vs_state(pipe, mc->p_vs[1]);
692 pipe->bind_fs_state(pipe, mc->p_fs[1]);
693
694 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24);
695 vb_start += num_macroblocks[vlMacroBlockExTypeBkwdPredictedField] * 24;
696 }
697
698 if (num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] > 0)
699 {
700 pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
701 pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
702 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
703 mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
704 pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
705 pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
706 pipe->bind_vs_state(pipe, mc->b_vs[0]);
707 pipe->bind_fs_state(pipe, mc->b_fs[0]);
708
709 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24);
710 vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedFrame] * 24;
711 }
712
713 if (num_macroblocks[vlMacroBlockExTypeBiPredictedField] > 0)
714 {
715 pipe->set_vertex_buffers(pipe, 3, mc->vertex_bufs[mc->cur_buf % NUM_BUF_SETS]);
716 pipe->set_vertex_elements(pipe, 8, mc->vertex_elems);
717 mc->textures[mc->cur_buf % NUM_BUF_SETS][3] = mc->past_surface->texture;
718 mc->textures[mc->cur_buf % NUM_BUF_SETS][4] = mc->future_surface->texture;
719 pipe->set_sampler_textures(pipe, 5, mc->textures[mc->cur_buf % NUM_BUF_SETS]);
720 pipe->bind_sampler_states(pipe, 5, (void**)mc->samplers);
721 pipe->bind_vs_state(pipe, mc->b_vs[1]);
722 pipe->bind_fs_state(pipe, mc->b_fs[1]);
723
724 pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, vb_start, num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24);
725 vb_start += num_macroblocks[vlMacroBlockExTypeBiPredictedField] * 24;
726 }
727
728 pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, &mc->buffered_surface->render_fence);
729
730 for (i = 0; i < 3; ++i)
731 mc->zero_block[i].x = -1.0f;
732
733 mc->buffered_surface = NULL;
734 mc->num_macroblocks = 0;
735 mc->cur_buf++;
736
737 return 0;
738 }
739
740 static int vlRenderMacroBlocksMpeg2R16SnormBuffered
741 (
742 struct vlRender *render,
743 struct vlMpeg2MacroBlockBatch *batch,
744 struct vlSurface *surface
745 )
746 {
747 struct vlR16SnormBufferedMC *mc;
748 unsigned int i;
749
750 assert(render);
751
752 mc = (struct vlR16SnormBufferedMC*)render;
753
754 if (mc->buffered_surface)
755 {
756 if (mc->buffered_surface != surface)
757 {
758 vlFlush(&mc->base);
759 mc->buffered_surface = surface;
760 mc->past_surface = batch->past_surface;
761 mc->future_surface = batch->future_surface;
762 mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
763 mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
764
765 for (i = 0; i < 3; ++i)
766 {
767 mc->tex_surface[i] = mc->pipe->screen->get_tex_surface
768 (
769 mc->pipe->screen,
770 mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
771 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
772 );
773
774 mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
775 }
776 }
777 }
778 else
779 {
780 mc->buffered_surface = surface;
781 mc->past_surface = batch->past_surface;
782 mc->future_surface = batch->future_surface;
783 mc->surface_tex_inv_size.x = 1.0f / surface->texture->width[0];
784 mc->surface_tex_inv_size.y = 1.0f / surface->texture->height[0];
785
786 for (i = 0; i < 3; ++i)
787 {
788 mc->tex_surface[i] = mc->pipe->screen->get_tex_surface
789 (
790 mc->pipe->screen,
791 mc->textures[mc->cur_buf % NUM_BUF_SETS][i],
792 0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
793 );
794
795 mc->texels[i] = pipe_surface_map(mc->tex_surface[i], PIPE_BUFFER_USAGE_CPU_WRITE);
796 }
797 }
798
799 for (i = 0; i < batch->num_macroblocks; ++i)
800 vlGrabMacroBlock(mc, &batch->macroblocks[i]);
801
802 return 0;
803 }
804
805 static int vlEnd
806 (
807 struct vlRender *render
808 )
809 {
810 assert(render);
811
812 return 0;
813 }
814
815 static int vlDestroy
816 (
817 struct vlRender *render
818 )
819 {
820 struct vlR16SnormBufferedMC *mc;
821 struct pipe_context *pipe;
822 unsigned int h, i;
823
824 assert(render);
825
826 mc = (struct vlR16SnormBufferedMC*)render;
827 pipe = mc->pipe;
828
829 for (i = 0; i < 5; ++i)
830 pipe->delete_sampler_state(pipe, mc->samplers[i]);
831
832 for (h = 0; h < NUM_BUF_SETS; ++h)
833 for (i = 0; i < 3; ++i)
834 pipe->winsys->buffer_destroy(pipe->winsys, mc->vertex_bufs[h][i].buffer);
835
836 /* Textures 3 & 4 are not created directly, no need to release them here */
837 for (i = 0; i < NUM_BUF_SETS; ++i)
838 {
839 pipe_texture_release(&mc->textures[i][0]);
840 pipe_texture_release(&mc->textures[i][1]);
841 pipe_texture_release(&mc->textures[i][2]);
842 }
843
844 pipe->delete_vs_state(pipe, mc->i_vs);
845 pipe->delete_fs_state(pipe, mc->i_fs);
846
847 for (i = 0; i < 2; ++i)
848 {
849 pipe->delete_vs_state(pipe, mc->p_vs[i]);
850 pipe->delete_fs_state(pipe, mc->p_fs[i]);
851 pipe->delete_vs_state(pipe, mc->b_vs[i]);
852 pipe->delete_fs_state(pipe, mc->b_fs[i]);
853 }
854
855 pipe->winsys->buffer_destroy(pipe->winsys, mc->vs_const_buf.buffer);
856 pipe->winsys->buffer_destroy(pipe->winsys, mc->fs_const_buf.buffer);
857
858 free(mc->macroblocks);
859 free(mc);
860
861 return 0;
862 }
863
864 /*
865 * Muliplier renormalizes block samples from 16 bits to 12 bits.
866 * Divider is used when calculating Y % 2 for choosing top or bottom
867 * field for P or B macroblocks.
868 * TODO: Use immediates.
869 */
870 static const struct vlFragmentShaderConsts fs_consts =
871 {
872 {32767.0f / 255.0f, 32767.0f / 255.0f, 32767.0f / 255.0f, 0.0f},
873 {0.5f, 2.0f, 0.0f, 0.0f}
874 };
875
876 #include "vl_r16snorm_mc_buf_shaders.inc"
877
878 static int vlCreateDataBufs
879 (
880 struct vlR16SnormBufferedMC *mc
881 )
882 {
883 const unsigned int mbw = align(mc->picture_width, VL_MACROBLOCK_WIDTH) / VL_MACROBLOCK_WIDTH;
884 const unsigned int mbh = align(mc->picture_height, VL_MACROBLOCK_HEIGHT) / VL_MACROBLOCK_HEIGHT;
885 const unsigned int num_mb_per_frame = mbw * mbh;
886
887 struct pipe_context *pipe;
888 unsigned int h, i;
889
890 assert(mc);
891
892 pipe = mc->pipe;
893
894 /* Create our vertex buffers */
895 for (h = 0; h < NUM_BUF_SETS; ++h)
896 {
897 mc->vertex_bufs[h][0].pitch = sizeof(struct vlVertex2f) * 4;
898 mc->vertex_bufs[h][0].max_index = 24 * num_mb_per_frame - 1;
899 mc->vertex_bufs[h][0].buffer_offset = 0;
900 mc->vertex_bufs[h][0].buffer = pipe->winsys->buffer_create
901 (
902 pipe->winsys,
903 1,
904 PIPE_BUFFER_USAGE_VERTEX,
905 sizeof(struct vlVertex2f) * 4 * 24 * num_mb_per_frame
906 );
907
908 for (i = 1; i < 3; ++i)
909 {
910 mc->vertex_bufs[h][i].pitch = sizeof(struct vlVertex2f) * 2;
911 mc->vertex_bufs[h][i].max_index = 24 * num_mb_per_frame - 1;
912 mc->vertex_bufs[h][i].buffer_offset = 0;
913 mc->vertex_bufs[h][i].buffer = pipe->winsys->buffer_create
914 (
915 pipe->winsys,
916 1,
917 PIPE_BUFFER_USAGE_VERTEX,
918 sizeof(struct vlVertex2f) * 2 * 24 * num_mb_per_frame
919 );
920 }
921 }
922
923 /* Position element */
924 mc->vertex_elems[0].src_offset = 0;
925 mc->vertex_elems[0].vertex_buffer_index = 0;
926 mc->vertex_elems[0].nr_components = 2;
927 mc->vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
928
929 /* Luma, texcoord element */
930 mc->vertex_elems[1].src_offset = sizeof(struct vlVertex2f);
931 mc->vertex_elems[1].vertex_buffer_index = 0;
932 mc->vertex_elems[1].nr_components = 2;
933 mc->vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
934
935 /* Chroma Cr texcoord element */
936 mc->vertex_elems[2].src_offset = sizeof(struct vlVertex2f) * 2;
937 mc->vertex_elems[2].vertex_buffer_index = 0;
938 mc->vertex_elems[2].nr_components = 2;
939 mc->vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
940
941 /* Chroma Cb texcoord element */
942 mc->vertex_elems[3].src_offset = sizeof(struct vlVertex2f) * 3;
943 mc->vertex_elems[3].vertex_buffer_index = 0;
944 mc->vertex_elems[3].nr_components = 2;
945 mc->vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
946
947 /* First ref surface top field texcoord element */
948 mc->vertex_elems[4].src_offset = 0;
949 mc->vertex_elems[4].vertex_buffer_index = 1;
950 mc->vertex_elems[4].nr_components = 2;
951 mc->vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
952
953 /* First ref surface bottom field texcoord element */
954 mc->vertex_elems[5].src_offset = sizeof(struct vlVertex2f);
955 mc->vertex_elems[5].vertex_buffer_index = 1;
956 mc->vertex_elems[5].nr_components = 2;
957 mc->vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
958
959 /* Second ref surface top field texcoord element */
960 mc->vertex_elems[6].src_offset = 0;
961 mc->vertex_elems[6].vertex_buffer_index = 2;
962 mc->vertex_elems[6].nr_components = 2;
963 mc->vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
964
965 /* Second ref surface bottom field texcoord element */
966 mc->vertex_elems[7].src_offset = sizeof(struct vlVertex2f);
967 mc->vertex_elems[7].vertex_buffer_index = 2;
968 mc->vertex_elems[7].nr_components = 2;
969 mc->vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
970
971 /* Create our constant buffer */
972 mc->vs_const_buf.size = sizeof(struct vlVertexShaderConsts);
973 mc->vs_const_buf.buffer = pipe->winsys->buffer_create
974 (
975 pipe->winsys,
976 1,
977 PIPE_BUFFER_USAGE_CONSTANT,
978 mc->vs_const_buf.size
979 );
980
981 mc->fs_const_buf.size = sizeof(struct vlFragmentShaderConsts);
982 mc->fs_const_buf.buffer = pipe->winsys->buffer_create
983 (
984 pipe->winsys,
985 1,
986 PIPE_BUFFER_USAGE_CONSTANT,
987 mc->fs_const_buf.size
988 );
989
990 memcpy
991 (
992 pipe->winsys->buffer_map(pipe->winsys, mc->fs_const_buf.buffer, PIPE_BUFFER_USAGE_CPU_WRITE),
993 &fs_consts,
994 sizeof(struct vlFragmentShaderConsts)
995 );
996
997 pipe->winsys->buffer_unmap(pipe->winsys, mc->fs_const_buf.buffer);
998
999 mc->macroblocks = malloc(sizeof(struct vlMpeg2MacroBlock) * num_mb_per_frame);
1000
1001 return 0;
1002 }
1003
1004 static int vlInit
1005 (
1006 struct vlR16SnormBufferedMC *mc
1007 )
1008 {
1009 struct pipe_context *pipe;
1010 struct pipe_sampler_state sampler;
1011 struct pipe_texture template;
1012 unsigned int filters[5];
1013 unsigned int i;
1014
1015 assert(mc);
1016
1017 pipe = mc->pipe;
1018
1019 /* For MC we render to textures, which are rounded up to nearest POT */
1020 mc->viewport.scale[0] = vlRoundUpPOT(mc->picture_width);
1021 mc->viewport.scale[1] = vlRoundUpPOT(mc->picture_height);
1022 mc->viewport.scale[2] = 1;
1023 mc->viewport.scale[3] = 1;
1024 mc->viewport.translate[0] = 0;
1025 mc->viewport.translate[1] = 0;
1026 mc->viewport.translate[2] = 0;
1027 mc->viewport.translate[3] = 0;
1028
1029 mc->render_target.width = vlRoundUpPOT(mc->picture_width);
1030 mc->render_target.height = vlRoundUpPOT(mc->picture_height);
1031 mc->render_target.num_cbufs = 1;
1032 /* FB for MC stage is a vlSurface created by the user, set at render time */
1033 mc->render_target.zsbuf = NULL;
1034
1035 filters[0] = PIPE_TEX_FILTER_NEAREST;
1036 /* FIXME: Linear causes discoloration around block edges */
1037 filters[1] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
1038 filters[2] = /*mc->picture_format == vlFormatYCbCr444 ?*/ PIPE_TEX_FILTER_NEAREST /*: PIPE_TEX_FILTER_LINEAR*/;
1039 filters[3] = PIPE_TEX_FILTER_LINEAR;
1040 filters[4] = PIPE_TEX_FILTER_LINEAR;
1041
1042 for (i = 0; i < 5; ++i)
1043 {
1044 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
1045 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
1046 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
1047 sampler.min_img_filter = filters[i];
1048 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
1049 sampler.mag_img_filter = filters[i];
1050 sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
1051 sampler.compare_func = PIPE_FUNC_ALWAYS;
1052 sampler.normalized_coords = 1;
1053 /*sampler.prefilter = ;*/
1054 /*sampler.shadow_ambient = ;*/
1055 /*sampler.lod_bias = ;*/
1056 sampler.min_lod = 0;
1057 /*sampler.max_lod = ;*/
1058 /*sampler.border_color[i] = ;*/
1059 /*sampler.max_anisotropy = ;*/
1060 mc->samplers[i] = pipe->create_sampler_state(pipe, &sampler);
1061 }
1062
1063 memset(&template, 0, sizeof(struct pipe_texture));
1064 template.target = PIPE_TEXTURE_2D;
1065 template.format = PIPE_FORMAT_R16_SNORM;
1066 template.last_level = 0;
1067 template.width[0] = vlRoundUpPOT(mc->picture_width);
1068 template.height[0] = vlRoundUpPOT(mc->picture_height);
1069 template.depth[0] = 1;
1070 template.compressed = 0;
1071 pf_get_block(template.format, &template.block);
1072 template.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
1073
1074 for (i = 0; i < NUM_BUF_SETS; ++i)
1075 mc->textures[i][0] = pipe->screen->texture_create(pipe->screen, &template);
1076
1077 if (mc->picture_format == vlFormatYCbCr420)
1078 {
1079 template.width[0] = vlRoundUpPOT(mc->picture_width / 2);
1080 template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
1081 }
1082 else if (mc->picture_format == vlFormatYCbCr422)
1083 template.height[0] = vlRoundUpPOT(mc->picture_height / 2);
1084
1085 for (i = 0; i < NUM_BUF_SETS; ++i)
1086 {
1087 mc->textures[i][1] = pipe->screen->texture_create(pipe->screen, &template);
1088 mc->textures[i][2] = pipe->screen->texture_create(pipe->screen, &template);
1089 }
1090
1091 /* textures[3] & textures[4] are assigned from vlSurfaces for P and B macroblocks at render time */
1092
1093 vlCreateVertexShaderIMB(mc);
1094 vlCreateFragmentShaderIMB(mc);
1095 vlCreateVertexShaderFramePMB(mc);
1096 vlCreateVertexShaderFieldPMB(mc);
1097 vlCreateFragmentShaderFramePMB(mc);
1098 vlCreateFragmentShaderFieldPMB(mc);
1099 vlCreateVertexShaderFrameBMB(mc);
1100 vlCreateVertexShaderFieldBMB(mc);
1101 vlCreateFragmentShaderFrameBMB(mc);
1102 vlCreateFragmentShaderFieldBMB(mc);
1103 vlCreateDataBufs(mc);
1104
1105 return 0;
1106 }
1107
1108 int vlCreateR16SNormBufferedMC
1109 (
1110 struct pipe_context *pipe,
1111 unsigned int picture_width,
1112 unsigned int picture_height,
1113 enum vlFormat picture_format,
1114 struct vlRender **render
1115 )
1116 {
1117 struct vlR16SnormBufferedMC *mc;
1118 unsigned int i;
1119
1120 assert(pipe);
1121 assert(render);
1122
1123 mc = calloc(1, sizeof(struct vlR16SnormBufferedMC));
1124
1125 mc->base.vlBegin = &vlBegin;
1126 mc->base.vlRenderMacroBlocksMpeg2 = &vlRenderMacroBlocksMpeg2R16SnormBuffered;
1127 mc->base.vlEnd = &vlEnd;
1128 mc->base.vlFlush = &vlFlush;
1129 mc->base.vlDestroy = &vlDestroy;
1130 mc->pipe = pipe;
1131 mc->picture_width = picture_width;
1132 mc->picture_height = picture_height;
1133
1134 mc->cur_buf = 0;
1135 mc->buffered_surface = NULL;
1136 mc->past_surface = NULL;
1137 mc->future_surface = NULL;
1138 for (i = 0; i < 3; ++i)
1139 mc->zero_block[i].x = -1.0f;
1140 mc->num_macroblocks = 0;
1141
1142 vlInit(mc);
1143
1144 *render = &mc->base;
1145
1146 return 0;
1147 }