[g3dvl] static usage for intermediate buffer
[mesa.git] / src / gallium / auxiliary / vl / vl_mpeg12_mc_renderer.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 "vl_mpeg12_mc_renderer.h"
29 #include "util/u_draw.h"
30 #include <assert.h>
31 #include <pipe/p_context.h>
32 #include <util/u_inlines.h>
33 #include <util/u_format.h>
34 #include <util/u_math.h>
35 #include <util/u_memory.h>
36 #include <util/u_keymap.h>
37 #include <util/u_sampler.h>
38 #include <tgsi/tgsi_ureg.h>
39
40 #define DEFAULT_BUF_ALIGNMENT 1
41 #define MACROBLOCK_WIDTH 16
42 #define MACROBLOCK_HEIGHT 16
43 #define BLOCK_WIDTH 8
44 #define BLOCK_HEIGHT 8
45
46 struct vertex_stream
47 {
48 struct vertex2s pos;
49 struct vertex2s mv[4];
50 struct {
51 int8_t y;
52 int8_t cr;
53 int8_t cb;
54 int8_t flag;
55 } eb[2][2];
56 };
57
58 enum VS_INPUT
59 {
60 VS_I_RECT,
61 VS_I_VPOS,
62 VS_I_MV0,
63 VS_I_MV1,
64 VS_I_MV2,
65 VS_I_MV3,
66 VS_I_EB_0_0,
67 VS_I_EB_0_1,
68 VS_I_EB_1_0,
69 VS_I_EB_1_1,
70
71 NUM_VS_INPUTS
72 };
73
74 enum VS_OUTPUT
75 {
76 VS_O_VPOS,
77 VS_O_LINE,
78 VS_O_TEX0,
79 VS_O_TEX1,
80 VS_O_TEX2,
81 VS_O_EB_0,
82 VS_O_EB_1,
83 VS_O_INFO,
84 VS_O_MV0,
85 VS_O_MV1,
86 VS_O_MV2,
87 VS_O_MV3
88 };
89
90 static const unsigned const_empty_block_mask_420[3][2][2] = {
91 { { 0x20, 0x10 }, { 0x08, 0x04 } },
92 { { 0x02, 0x02 }, { 0x02, 0x02 } },
93 { { 0x01, 0x01 }, { 0x01, 0x01 } }
94 };
95
96 static void *
97 create_vert_shader(struct vl_mpeg12_mc_renderer *r)
98 {
99 struct ureg_program *shader;
100 struct ureg_src block_scale, mv_scale;
101 struct ureg_src vrect, vpos, eb[2][2], vmv[4];
102 struct ureg_dst t_vpos, t_vtex, t_vmv;
103 struct ureg_dst o_vpos, o_line, o_vtex[3], o_eb[2], o_vmv[4], o_info;
104 unsigned i, label;
105
106 shader = ureg_create(TGSI_PROCESSOR_VERTEX);
107 if (!shader)
108 return NULL;
109
110 t_vpos = ureg_DECL_temporary(shader);
111 t_vtex = ureg_DECL_temporary(shader);
112 t_vmv = ureg_DECL_temporary(shader);
113
114 vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
115 vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
116 eb[0][0] = ureg_DECL_vs_input(shader, VS_I_EB_0_0);
117 eb[1][0] = ureg_DECL_vs_input(shader, VS_I_EB_1_0);
118 eb[0][1] = ureg_DECL_vs_input(shader, VS_I_EB_0_1);
119 eb[1][1] = ureg_DECL_vs_input(shader, VS_I_EB_1_1);
120
121 o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
122 o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE);
123 o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX0);
124 o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX1);
125 o_vtex[2] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX2);
126 o_eb[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_0);
127 o_eb[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_1);
128 o_info = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_INFO);
129
130 for (i = 0; i < 4; ++i) {
131 vmv[i] = ureg_DECL_vs_input(shader, VS_I_MV0 + i);
132 o_vmv[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0 + i);
133 }
134
135 /*
136 * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
137 * mv_scale = 0.5 / (dst.width, dst.height);
138 *
139 * t_vpos = (vpos + vrect) * block_scale
140 * o_vpos.xy = t_vpos
141 * o_vpos.zw = vpos
142 *
143 * o_eb[0..1] = vrect.x ? eb[0..1][1] : eb[0..1][0]
144 *
145 * o_frame_pred = frame_pred
146 * o_info.x = ref_frames
147 * o_info.y = ref_frames > 0
148 * o_info.z = bkwd_pred
149 *
150 * // Apply motion vectors
151 * o_vmv[0..count] = t_vpos + vmv[0..count] * mv_scale
152 *
153 * o_line.xy = vrect * 8
154 * o_line.z = interlaced
155 *
156 * if(eb[0][0].w) { //interlaced
157 * t_vtex.x = vrect.x
158 * t_vtex.y = vrect.y * 0.5
159 * t_vtex += vpos
160 *
161 * o_vtex[0].xy = t_vtex * block_scale
162 *
163 * t_vtex.y += 0.5
164 * o_vtex[1].xy = t_vtex * block_scale
165 * } else {
166 * o_vtex[0..1].xy = t_vpos
167 * }
168 * o_vtex[2].xy = t_vpos
169 *
170 */
171 block_scale = ureg_imm2f(shader,
172 (float)MACROBLOCK_WIDTH / r->buffer_width,
173 (float)MACROBLOCK_HEIGHT / r->buffer_height);
174
175 mv_scale = ureg_imm2f(shader,
176 0.5f / r->buffer_width,
177 0.5f / r->buffer_height);
178
179 ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
180 ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);
181 ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
182 ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
183
184 ureg_CMP(shader, ureg_writemask(o_eb[0], TGSI_WRITEMASK_XYZ),
185 ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)),
186 eb[0][1], eb[0][0]);
187 ureg_CMP(shader, ureg_writemask(o_eb[1], TGSI_WRITEMASK_XYZ),
188 ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)),
189 eb[1][1], eb[1][0]);
190
191 ureg_MOV(shader, ureg_writemask(o_info, TGSI_WRITEMASK_X),
192 ureg_scalar(eb[1][1], TGSI_SWIZZLE_W));
193 ureg_SGE(shader, ureg_writemask(o_info, TGSI_WRITEMASK_Y),
194 ureg_scalar(eb[1][1], TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.0f));
195 ureg_MOV(shader, ureg_writemask(o_info, TGSI_WRITEMASK_Z),
196 ureg_scalar(eb[1][0], TGSI_SWIZZLE_W));
197
198 ureg_MAD(shader, ureg_writemask(o_vmv[0], TGSI_WRITEMASK_XY), mv_scale, vmv[0], ureg_src(t_vpos));
199 ureg_MAD(shader, ureg_writemask(o_vmv[2], TGSI_WRITEMASK_XY), mv_scale, vmv[2], ureg_src(t_vpos));
200
201 ureg_CMP(shader, ureg_writemask(t_vmv, TGSI_WRITEMASK_XY),
202 ureg_negate(ureg_scalar(eb[0][1], TGSI_SWIZZLE_W)),
203 vmv[0], vmv[1]);
204 ureg_MAD(shader, ureg_writemask(o_vmv[1], TGSI_WRITEMASK_XY), mv_scale, ureg_src(t_vmv), ureg_src(t_vpos));
205
206 ureg_CMP(shader, ureg_writemask(t_vmv, TGSI_WRITEMASK_XY),
207 ureg_negate(ureg_scalar(eb[0][1], TGSI_SWIZZLE_W)),
208 vmv[2], vmv[3]);
209 ureg_MAD(shader, ureg_writemask(o_vmv[3], TGSI_WRITEMASK_XY), mv_scale, ureg_src(t_vmv), ureg_src(t_vpos));
210
211 ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
212 ureg_MOV(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
213 ureg_MOV(shader, ureg_writemask(o_vtex[2], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
214
215 ureg_MOV(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X), ureg_scalar(vrect, TGSI_SWIZZLE_Y));
216 ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y),
217 vrect, ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2));
218
219 ureg_IF(shader, ureg_scalar(eb[0][0], TGSI_SWIZZLE_W), &label);
220
221 ureg_MOV(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_X), vrect);
222 ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), vrect, ureg_imm1f(shader, 0.5f));
223 ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), vpos, ureg_src(t_vtex));
224 ureg_MUL(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale);
225 ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), ureg_src(t_vtex), ureg_imm1f(shader, 0.5f));
226 ureg_MUL(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale);
227
228 ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X),
229 ureg_scalar(vrect, TGSI_SWIZZLE_Y),
230 ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2));
231
232 ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
233 ureg_ENDIF(shader);
234
235 ureg_release_temporary(shader, t_vtex);
236 ureg_release_temporary(shader, t_vpos);
237 ureg_release_temporary(shader, t_vmv);
238
239 ureg_END(shader);
240
241 return ureg_create_shader_and_destroy(shader, r->pipe);
242 }
243
244 static struct ureg_dst
245 calc_field(struct ureg_program *shader)
246 {
247 struct ureg_dst tmp;
248 struct ureg_src line;
249
250 tmp = ureg_DECL_temporary(shader);
251
252 line = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE, TGSI_INTERPOLATE_LINEAR);
253
254 /*
255 * line.x going from 0 to 1 if not interlaced
256 * line.x going from 0 to 8 in steps of 0.5 if interlaced
257 * line.y going from 0 to 8 in steps of 0.5
258 *
259 * tmp.xy = fraction(line)
260 * tmp.xy = tmp.xy >= 0.5 ? 1 : 0
261 */
262 ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), line);
263 ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), ureg_src(tmp), ureg_imm1f(shader, 0.5f));
264
265 return tmp;
266 }
267
268 static struct ureg_dst
269 fetch_ycbcr(struct vl_mpeg12_mc_renderer *r, struct ureg_program *shader, struct ureg_dst field)
270 {
271 struct ureg_src tc[3], sampler[3], eb[2];
272 struct ureg_dst texel, t_tc, t_eb_info;
273 unsigned i, label;
274
275 texel = ureg_DECL_temporary(shader);
276 t_tc = ureg_DECL_temporary(shader);
277 t_eb_info = ureg_DECL_temporary(shader);
278
279 tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX0, TGSI_INTERPOLATE_LINEAR);
280 tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX1, TGSI_INTERPOLATE_LINEAR);
281 tc[2] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX2, TGSI_INTERPOLATE_LINEAR);
282
283 eb[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_0, TGSI_INTERPOLATE_CONSTANT);
284 eb[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_1, TGSI_INTERPOLATE_CONSTANT);
285
286 for (i = 0; i < 3; ++i) {
287 sampler[i] = ureg_DECL_sampler(shader, i);
288 }
289
290 /*
291 * texel.y = tex(field.y ? tc[1] : tc[0], sampler[0])
292 * texel.cb = tex(tc[2], sampler[1])
293 * texel.cr = tex(tc[2], sampler[2])
294 */
295
296 ureg_CMP(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_XY),
297 ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)),
298 tc[1], tc[0]);
299
300 ureg_CMP(shader, ureg_writemask(t_eb_info, TGSI_WRITEMASK_XYZ),
301 ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)),
302 eb[1], eb[0]);
303
304 /* r600g is ignoring TGSI_INTERPOLATE_CONSTANT, just workaround this */
305 ureg_SLT(shader, ureg_writemask(t_eb_info, TGSI_WRITEMASK_XYZ), ureg_src(t_eb_info), ureg_imm1f(shader, 0.5f));
306
307 ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.0f));
308 for (i = 0; i < 3; ++i) {
309 ureg_IF(shader, ureg_scalar(ureg_src(t_eb_info), TGSI_SWIZZLE_X + i), &label);
310
311 /* Nouveau can't writemask tex dst regs (yet?), so this won't work anymore on nvidia hardware */
312 if(i==0 || r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444) {
313 ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, ureg_src(t_tc), sampler[i]);
314 } else {
315 ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, tc[2], sampler[i]);
316 }
317
318 ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
319 ureg_ENDIF(shader);
320 }
321
322 ureg_release_temporary(shader, t_tc);
323 ureg_release_temporary(shader, t_eb_info);
324
325 return texel;
326 }
327
328 static struct ureg_dst
329 fetch_ref(struct ureg_program *shader, struct ureg_dst field)
330 {
331 struct ureg_src info;
332 struct ureg_src tc[4], sampler[2];
333 struct ureg_dst ref[2], result;
334 unsigned i, intra_label, bi_label, label;
335
336 info = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_INFO, TGSI_INTERPOLATE_CONSTANT);
337
338 for (i = 0; i < 4; ++i)
339 tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0 + i, TGSI_INTERPOLATE_LINEAR);
340
341 for (i = 0; i < 2; ++i) {
342 sampler[i] = ureg_DECL_sampler(shader, i + 3);
343 ref[i] = ureg_DECL_temporary(shader);
344 }
345
346 result = ureg_DECL_temporary(shader);
347
348 ureg_MOV(shader, ureg_writemask(result, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.5f));
349
350 ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_Y), &intra_label);
351 ureg_CMP(shader, ureg_writemask(ref[0], TGSI_WRITEMASK_XY),
352 ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
353 tc[1], tc[0]);
354
355 ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_X), &bi_label);
356
357 /*
358 * result = tex(field.z ? tc[1] : tc[0], sampler[bkwd_pred ? 1 : 0])
359 */
360 ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_Z), &label);
361 ureg_TEX(shader, result, TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[1]);
362 ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
363 ureg_ELSE(shader, &label);
364 ureg_TEX(shader, result, TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
365 ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
366 ureg_ENDIF(shader);
367
368 ureg_fixup_label(shader, bi_label, ureg_get_instruction_number(shader));
369 ureg_ELSE(shader, &bi_label);
370
371 /*
372 * if (field.z)
373 * ref[0..1] = tex(tc[0..1], sampler[0..1])
374 * else
375 * ref[0..1] = tex(tc[2..3], sampler[0..1])
376 */
377 ureg_CMP(shader, ureg_writemask(ref[1], TGSI_WRITEMASK_XY),
378 ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
379 tc[3], tc[2]);
380 ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
381 ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, ureg_src(ref[1]), sampler[1]);
382
383 ureg_LRP(shader, ureg_writemask(result, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.5f),
384 ureg_src(ref[0]), ureg_src(ref[1]));
385
386 ureg_fixup_label(shader, bi_label, ureg_get_instruction_number(shader));
387 ureg_ENDIF(shader);
388 ureg_fixup_label(shader, intra_label, ureg_get_instruction_number(shader));
389 ureg_ENDIF(shader);
390
391 for (i = 0; i < 2; ++i)
392 ureg_release_temporary(shader, ref[i]);
393
394 return result;
395 }
396
397 static void *
398 create_frag_shader(struct vl_mpeg12_mc_renderer *r)
399 {
400 struct ureg_program *shader;
401 struct ureg_dst result;
402 struct ureg_dst field, texel;
403 struct ureg_dst fragment;
404
405 shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
406 if (!shader)
407 return NULL;
408
409 fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
410
411 field = calc_field(shader);
412 texel = fetch_ycbcr(r, shader, field);
413
414 result = fetch_ref(shader, field);
415
416 ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(texel), ureg_src(result));
417
418 ureg_release_temporary(shader, field);
419 ureg_release_temporary(shader, texel);
420 ureg_release_temporary(shader, result);
421 ureg_END(shader);
422
423 return ureg_create_shader_and_destroy(shader, r->pipe);
424 }
425
426 static bool
427 init_pipe_state(struct vl_mpeg12_mc_renderer *r)
428 {
429 struct pipe_sampler_state sampler;
430 struct pipe_rasterizer_state rs_state;
431 unsigned filters[5];
432 unsigned i;
433
434 assert(r);
435
436 r->viewport.scale[0] = r->buffer_width;
437 r->viewport.scale[1] = r->buffer_height;
438 r->viewport.scale[2] = 1;
439 r->viewport.scale[3] = 1;
440 r->viewport.translate[0] = 0;
441 r->viewport.translate[1] = 0;
442 r->viewport.translate[2] = 0;
443 r->viewport.translate[3] = 0;
444
445 r->fb_state.width = r->buffer_width;
446 r->fb_state.height = r->buffer_height;
447 r->fb_state.nr_cbufs = 1;
448 r->fb_state.zsbuf = NULL;
449
450 /* Luma filter */
451 filters[0] = PIPE_TEX_FILTER_NEAREST;
452 /* Chroma filters */
453 if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444 || true) { //TODO
454 filters[1] = PIPE_TEX_FILTER_NEAREST;
455 filters[2] = PIPE_TEX_FILTER_NEAREST;
456 }
457 else {
458 filters[1] = PIPE_TEX_FILTER_LINEAR;
459 filters[2] = PIPE_TEX_FILTER_LINEAR;
460 }
461 /* Fwd, bkwd ref filters */
462 filters[3] = PIPE_TEX_FILTER_LINEAR;
463 filters[4] = PIPE_TEX_FILTER_LINEAR;
464
465 for (i = 0; i < 5; ++i) {
466 memset(&sampler, 0, sizeof(sampler));
467 sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
468 sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
469 sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_BORDER;
470 sampler.min_img_filter = filters[i];
471 sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
472 sampler.mag_img_filter = filters[i];
473 sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
474 sampler.compare_func = PIPE_FUNC_ALWAYS;
475 sampler.normalized_coords = 1;
476 /*sampler.shadow_ambient = ; */
477 /*sampler.lod_bias = ; */
478 sampler.min_lod = 0;
479 /*sampler.max_lod = ; */
480 sampler.border_color[0] = 0.0f;
481 sampler.border_color[1] = 0.0f;
482 sampler.border_color[2] = 0.0f;
483 sampler.border_color[3] = 0.0f;
484 /*sampler.max_anisotropy = ; */
485 r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
486 }
487
488 memset(&rs_state, 0, sizeof(rs_state));
489 /*rs_state.sprite_coord_enable */
490 rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
491 rs_state.point_quad_rasterization = true;
492 rs_state.point_size = BLOCK_WIDTH;
493 rs_state.gl_rasterization_rules = true;
494 r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state);
495
496 return true;
497 }
498
499 static void
500 cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
501 {
502 unsigned i;
503
504 assert(r);
505
506 for (i = 0; i < 5; ++i)
507 r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
508
509 r->pipe->delete_rasterizer_state(r->pipe, r->rs_state);
510 }
511
512 static bool
513 init_buffers(struct vl_mpeg12_mc_renderer *r)
514 {
515 struct pipe_resource *idct_matrix;
516 struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
517
518 const unsigned mbw =
519 align(r->buffer_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
520 const unsigned mbh =
521 align(r->buffer_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
522
523 unsigned i, chroma_width, chroma_height;
524
525 assert(r);
526
527 r->macroblocks_per_batch =
528 mbw * (r->bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE ? mbh : 1);
529
530 if (!(idct_matrix = vl_idct_upload_matrix(r->pipe)))
531 return false;
532
533 if (!vl_idct_init(&r->idct_luma, r->pipe, r->buffer_width, r->buffer_height, idct_matrix))
534 return false;
535
536 if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
537 chroma_width = r->buffer_width / 2;
538 chroma_height = r->buffer_height / 2;
539 } else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
540 chroma_width = r->buffer_width;
541 chroma_height = r->buffer_height / 2;
542 } else {
543 chroma_width = r->buffer_width;
544 chroma_height = r->buffer_height;
545 }
546
547 if(!vl_idct_init(&r->idct_chroma, r->pipe, chroma_width, chroma_height, idct_matrix))
548 return false;
549
550 memset(&vertex_elems, 0, sizeof(vertex_elems));
551
552 vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
553 r->quad = vl_vb_upload_quads(r->pipe, r->macroblocks_per_batch);
554
555 /* Position element */
556 vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
557
558 for (i = 0; i < 4; ++i)
559 /* motion vector 0..4 element */
560 vertex_elems[VS_I_MV0 + i].src_format = PIPE_FORMAT_R16G16_SSCALED;
561
562 /* y, cr, cb empty block element top left block */
563 vertex_elems[VS_I_EB_0_0].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
564
565 /* y, cr, cb empty block element top right block */
566 vertex_elems[VS_I_EB_0_1].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
567
568 /* y, cr, cb empty block element bottom left block */
569 vertex_elems[VS_I_EB_1_0].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
570
571 /* y, cr, cb empty block element bottom right block */
572 vertex_elems[VS_I_EB_1_1].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
573
574 r->vertex_stream_stride = vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 9, 1);
575
576 r->vertex_elems_state = r->pipe->create_vertex_elements_state(
577 r->pipe, NUM_VS_INPUTS, vertex_elems);
578
579 if (r->vertex_elems_state == NULL)
580 return false;
581
582 r->vs = create_vert_shader(r);
583 r->fs = create_frag_shader(r);
584
585 if (r->vs == NULL || r->fs == NULL)
586 return false;
587
588 return true;
589 }
590
591 static void
592 cleanup_buffers(struct vl_mpeg12_mc_renderer *r)
593 {
594 assert(r);
595
596 r->pipe->delete_vs_state(r->pipe, r->vs);
597 r->pipe->delete_fs_state(r->pipe, r->fs);
598
599 vl_idct_cleanup(&r->idct_luma);
600 vl_idct_cleanup(&r->idct_chroma);
601
602 r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems_state);
603 }
604
605 static struct pipe_sampler_view
606 *find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
607 {
608 struct pipe_sampler_view *sampler_view;
609 assert(r);
610 assert(surface);
611
612 sampler_view = (struct pipe_sampler_view*)util_keymap_lookup(r->texview_map, &surface);
613 if (!sampler_view) {
614 struct pipe_sampler_view templat;
615 boolean added_to_map;
616
617 u_sampler_view_default_template(&templat, surface->texture,
618 surface->texture->format);
619 sampler_view = r->pipe->create_sampler_view(r->pipe, surface->texture,
620 &templat);
621 if (!sampler_view)
622 return NULL;
623
624 added_to_map = util_keymap_insert(r->texview_map, &surface,
625 sampler_view, r->pipe);
626 assert(added_to_map);
627 }
628
629 return sampler_view;
630 }
631
632 static void
633 get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex2s mv[4])
634 {
635 switch (mb->mb_type) {
636 case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
637 {
638 if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
639
640 mv[2].x = mb->pmv[0][1][0];
641 mv[2].y = mb->pmv[0][1][1];
642
643 } else {
644 mv[2].x = mb->pmv[0][1][0];
645 mv[2].y = mb->pmv[0][1][1] - (mb->pmv[0][1][1] % 4);
646
647 mv[3].x = mb->pmv[1][1][0];
648 mv[3].y = mb->pmv[1][1][1] - (mb->pmv[1][1][1] % 4);
649
650 if(mb->mvfs[0][1]) mv[2].y += 2;
651 if(!mb->mvfs[1][1]) mv[3].y -= 2;
652 }
653
654 /* fall-through */
655 }
656 case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
657 case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
658 {
659 if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) {
660
661 if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
662 mv[0].x = mb->pmv[0][1][0];
663 mv[0].y = mb->pmv[0][1][1];
664
665 } else {
666 mv[0].x = mb->pmv[0][1][0];
667 mv[0].y = mb->pmv[0][1][1] - (mb->pmv[0][1][1] % 4);
668
669 mv[1].x = mb->pmv[1][1][0];
670 mv[1].y = mb->pmv[1][1][1] - (mb->pmv[1][1][1] % 4);
671
672 if(mb->mvfs[0][1]) mv[0].y += 2;
673 if(!mb->mvfs[1][1]) mv[1].y -= 2;
674 }
675
676 } else {
677
678 if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
679 mv[0].x = mb->pmv[0][0][0];
680 mv[0].y = mb->pmv[0][0][1];
681
682 } else {
683 mv[0].x = mb->pmv[0][0][0];
684 mv[0].y = mb->pmv[0][0][1] - (mb->pmv[0][0][1] % 4);
685
686 mv[1].x = mb->pmv[1][0][0];
687 mv[1].y = mb->pmv[1][0][1] - (mb->pmv[1][0][1] % 4);
688
689 if(mb->mvfs[0][0]) mv[0].y += 2;
690 if(!mb->mvfs[1][0]) mv[1].y -= 2;
691 }
692 }
693 }
694 default:
695 break;
696 }
697 }
698
699 static void
700 grab_vectors(struct vl_mpeg12_mc_renderer *r,
701 struct vl_mpeg12_mc_buffer *buffer,
702 struct pipe_mpeg12_macroblock *mb)
703 {
704 struct vertex_stream stream;
705
706 unsigned i, j;
707
708 assert(r);
709 assert(mb);
710
711 stream.pos.x = mb->mbx;
712 stream.pos.y = mb->mby;
713 for ( i = 0; i < 2; ++i) {
714 for ( j = 0; j < 2; ++j) {
715 stream.eb[i][j].y = !(mb->cbp & (*r->empty_block_mask)[0][i][j]);
716 stream.eb[i][j].cr = !(mb->cbp & (*r->empty_block_mask)[1][i][j]);
717 stream.eb[i][j].cb = !(mb->cbp & (*r->empty_block_mask)[2][i][j]);
718 }
719 }
720 stream.eb[0][0].flag = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
721 stream.eb[0][1].flag = mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME;
722 stream.eb[1][0].flag = mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD;
723 switch (mb->mb_type) {
724 case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA:
725 stream.eb[1][1].flag = -1;
726 break;
727
728 case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
729 case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
730 stream.eb[1][1].flag = 1;
731 break;
732
733 case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
734 stream.eb[1][1].flag = 0;
735 break;
736
737 default:
738 assert(0);
739 }
740
741 get_motion_vectors(mb, stream.mv);
742 vl_vb_add_block(&buffer->vertex_stream, &stream);
743 }
744
745 static void
746 grab_blocks(struct vl_mpeg12_mc_renderer *r,
747 struct vl_mpeg12_mc_buffer *buffer,
748 unsigned mbx, unsigned mby,
749 unsigned cbp, short *blocks)
750 {
751 unsigned tb = 0;
752 unsigned x, y;
753
754 assert(r);
755 assert(blocks);
756
757 for (y = 0; y < 2; ++y) {
758 for (x = 0; x < 2; ++x, ++tb) {
759 if (cbp & (*r->empty_block_mask)[0][y][x]) {
760 vl_idct_add_block(&buffer->idct_y, mbx * 2 + x, mby * 2 + y, blocks);
761 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
762 }
763 }
764 }
765
766 /* TODO: Implement 422, 444 */
767 assert(r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
768
769 for (tb = 1; tb < 3; ++tb) {
770 if (cbp & (*r->empty_block_mask)[tb][0][0]) {
771 if(tb == 1)
772 vl_idct_add_block(&buffer->idct_cb, mbx, mby, blocks);
773 else
774 vl_idct_add_block(&buffer->idct_cr, mbx, mby, blocks);
775 blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
776 }
777 }
778 }
779
780 static void
781 grab_macroblock(struct vl_mpeg12_mc_renderer *r,
782 struct vl_mpeg12_mc_buffer *buffer,
783 struct pipe_mpeg12_macroblock *mb)
784 {
785 assert(r);
786 assert(mb);
787 assert(mb->blocks);
788 assert(buffer->num_macroblocks < r->macroblocks_per_batch);
789
790 grab_vectors(r, buffer, mb);
791 grab_blocks(r, buffer, mb->mbx, mb->mby, mb->cbp, mb->blocks);
792
793 ++buffer->num_macroblocks;
794 }
795
796 static void
797 texview_map_delete(const struct keymap *map,
798 const void *key, void *data,
799 void *user)
800 {
801 struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data;
802
803 assert(map);
804 assert(key);
805 assert(data);
806 assert(user);
807
808 pipe_sampler_view_reference(&sv, NULL);
809 }
810
811 bool
812 vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
813 struct pipe_context *pipe,
814 unsigned buffer_width,
815 unsigned buffer_height,
816 enum pipe_video_chroma_format chroma_format,
817 enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode)
818 {
819 assert(renderer);
820 assert(pipe);
821
822 /* TODO: Implement other policies */
823 assert(bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE);
824
825 memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer));
826
827 renderer->pipe = pipe;
828 renderer->buffer_width = buffer_width;
829 renderer->buffer_height = buffer_height;
830 renderer->chroma_format = chroma_format;
831 renderer->bufmode = bufmode;
832
833 /* TODO: Implement 422, 444 */
834 assert(chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
835 renderer->empty_block_mask = &const_empty_block_mask_420;
836
837 renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
838 texview_map_delete);
839 if (!renderer->texview_map)
840 return false;
841
842 if (!init_pipe_state(renderer))
843 goto error_pipe_state;
844
845 if (!init_buffers(renderer))
846 goto error_buffers;
847
848 return true;
849
850 error_buffers:
851 cleanup_pipe_state(renderer);
852
853 error_pipe_state:
854 util_delete_keymap(renderer->texview_map, renderer->pipe);
855 return false;
856 }
857
858 void
859 vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
860 {
861 assert(renderer);
862
863 util_delete_keymap(renderer->texview_map, renderer->pipe);
864 cleanup_pipe_state(renderer);
865 cleanup_buffers(renderer);
866 }
867
868 bool
869 vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
870 {
871 struct pipe_resource template;
872 struct pipe_sampler_view sampler_view;
873
874 unsigned i;
875
876 assert(renderer && buffer);
877
878 buffer->surface = NULL;
879 buffer->past = NULL;
880 buffer->future = NULL;
881 buffer->num_macroblocks = 0;
882
883 memset(&template, 0, sizeof(struct pipe_resource));
884 template.target = PIPE_TEXTURE_2D;
885 /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
886 template.format = PIPE_FORMAT_R16_SNORM;
887 template.last_level = 0;
888 template.width0 = renderer->buffer_width;
889 template.height0 = renderer->buffer_height;
890 template.depth0 = 1;
891 template.usage = PIPE_USAGE_STATIC;
892 template.bind = PIPE_BIND_SAMPLER_VIEW;
893 template.flags = 0;
894
895 buffer->textures.individual.y = renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
896
897 if (!vl_idct_init_buffer(&renderer->idct_luma, &buffer->idct_y, buffer->textures.individual.y))
898 return false;
899
900 if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
901 template.width0 = renderer->buffer_width / 2;
902 template.height0 = renderer->buffer_height / 2;
903 }
904 else if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
905 template.height0 = renderer->buffer_height / 2;
906
907 buffer->textures.individual.cb =
908 renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
909 buffer->textures.individual.cr =
910 renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
911
912 if (!vl_idct_init_buffer(&renderer->idct_chroma, &buffer->idct_cb, buffer->textures.individual.cb))
913 return false;
914
915 if (!vl_idct_init_buffer(&renderer->idct_chroma, &buffer->idct_cr, buffer->textures.individual.cr))
916 return false;
917
918 for (i = 0; i < 3; ++i) {
919 u_sampler_view_default_template(&sampler_view,
920 buffer->textures.all[i],
921 buffer->textures.all[i]->format);
922 sampler_view.swizzle_r = i == 0 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
923 sampler_view.swizzle_g = i == 1 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
924 sampler_view.swizzle_b = i == 2 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
925 sampler_view.swizzle_a = PIPE_SWIZZLE_ONE;
926 buffer->sampler_views.all[i] = renderer->pipe->create_sampler_view(
927 renderer->pipe, buffer->textures.all[i], &sampler_view);
928 }
929
930 buffer->vertex_bufs.individual.quad.stride = renderer->quad.stride;
931 buffer->vertex_bufs.individual.quad.max_index = renderer->quad.max_index;
932 buffer->vertex_bufs.individual.quad.buffer_offset = renderer->quad.buffer_offset;
933 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, renderer->quad.buffer);
934
935 buffer->vertex_bufs.individual.stream = vl_vb_init(
936 &buffer->vertex_stream, renderer->pipe, renderer->macroblocks_per_batch,
937 renderer->vertex_stream_stride);
938
939 return true;
940 }
941
942 void
943 vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
944 {
945 unsigned i;
946
947 assert(renderer && buffer);
948
949 for (i = 0; i < 3; ++i) {
950 pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
951 pipe_resource_reference(&buffer->vertex_bufs.all[i].buffer, NULL);
952 pipe_resource_reference(&buffer->textures.all[i], NULL);
953 }
954
955 pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, NULL);
956 vl_vb_cleanup(&buffer->vertex_stream);
957
958 vl_idct_cleanup_buffer(&renderer->idct_luma, &buffer->idct_y);
959 vl_idct_cleanup_buffer(&renderer->idct_chroma, &buffer->idct_cb);
960 vl_idct_cleanup_buffer(&renderer->idct_chroma, &buffer->idct_cr);
961
962 pipe_surface_reference(&buffer->surface, NULL);
963 pipe_surface_reference(&buffer->past, NULL);
964 pipe_surface_reference(&buffer->future, NULL);
965 }
966
967 void
968 vl_mpeg12_mc_map_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
969 {
970 assert(renderer && buffer);
971
972 vl_idct_map_buffers(&renderer->idct_luma, &buffer->idct_y);
973 vl_idct_map_buffers(&renderer->idct_chroma, &buffer->idct_cr);
974 vl_idct_map_buffers(&renderer->idct_chroma, &buffer->idct_cb);
975
976 vl_vb_map(&buffer->vertex_stream, renderer->pipe);
977 }
978
979 void
980 vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
981 struct vl_mpeg12_mc_buffer *buffer,
982 struct pipe_surface *surface,
983 struct pipe_surface *past,
984 struct pipe_surface *future,
985 unsigned num_macroblocks,
986 struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
987 struct pipe_fence_handle **fence)
988 {
989 assert(renderer && buffer);
990 assert(surface);
991 assert(num_macroblocks);
992 assert(mpeg12_macroblocks);
993
994 if (surface != buffer->surface) {
995 pipe_surface_reference(&buffer->surface, surface);
996 pipe_surface_reference(&buffer->past, past);
997 pipe_surface_reference(&buffer->future, future);
998 buffer->fence = fence;
999 } else {
1000 /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
1001 assert(buffer->past == past);
1002 assert(buffer->future == future);
1003 }
1004
1005 while (num_macroblocks) {
1006 unsigned left_in_batch = renderer->macroblocks_per_batch - buffer->num_macroblocks;
1007 unsigned num_to_submit = MIN2(num_macroblocks, left_in_batch);
1008 unsigned i;
1009
1010 for (i = 0; i < num_to_submit; ++i) {
1011 assert(mpeg12_macroblocks[i].base.codec == PIPE_VIDEO_CODEC_MPEG12);
1012 grab_macroblock(renderer, buffer, &mpeg12_macroblocks[i]);
1013 }
1014
1015 num_macroblocks -= num_to_submit;
1016
1017 if (buffer->num_macroblocks == renderer->macroblocks_per_batch) {
1018 vl_mpeg12_mc_unmap_buffer(renderer, buffer);
1019 vl_mpeg12_mc_renderer_flush(renderer, buffer);
1020 pipe_surface_reference(&buffer->surface, surface);
1021 pipe_surface_reference(&buffer->past, past);
1022 pipe_surface_reference(&buffer->future, future);
1023 vl_mpeg12_mc_map_buffer(renderer, buffer);
1024 }
1025 }
1026 }
1027
1028 void
1029 vl_mpeg12_mc_unmap_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
1030 {
1031 assert(renderer && buffer);
1032
1033 vl_idct_unmap_buffers(&renderer->idct_luma, &buffer->idct_y);
1034 vl_idct_unmap_buffers(&renderer->idct_chroma, &buffer->idct_cr);
1035 vl_idct_unmap_buffers(&renderer->idct_chroma, &buffer->idct_cb);
1036
1037 vl_vb_unmap(&buffer->vertex_stream, renderer->pipe);
1038 }
1039
1040 void
1041 vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
1042 {
1043 assert(renderer && buffer);
1044 assert(buffer->num_macroblocks <= renderer->macroblocks_per_batch);
1045
1046 if (buffer->num_macroblocks == 0)
1047 return;
1048
1049 vl_idct_flush(&renderer->idct_luma, &buffer->idct_y);
1050 vl_idct_flush(&renderer->idct_chroma, &buffer->idct_cr);
1051 vl_idct_flush(&renderer->idct_chroma, &buffer->idct_cb);
1052
1053 vl_vb_restart(&buffer->vertex_stream);
1054
1055 renderer->fb_state.cbufs[0] = buffer->surface;
1056 renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
1057 renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
1058 renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
1059 renderer->pipe->set_vertex_buffers(renderer->pipe, 2, buffer->vertex_bufs.all);
1060 renderer->pipe->bind_vertex_elements_state(renderer->pipe, renderer->vertex_elems_state);
1061
1062 if (buffer->past) {
1063 buffer->textures.individual.ref[0] = buffer->past->texture;
1064 buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->past);
1065 } else {
1066 buffer->textures.individual.ref[0] = buffer->surface->texture;
1067 buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->surface);
1068 }
1069
1070 if (buffer->future) {
1071 buffer->textures.individual.ref[1] = buffer->future->texture;
1072 buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->future);
1073 } else {
1074 buffer->textures.individual.ref[1] = buffer->surface->texture;
1075 buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->surface);
1076 }
1077
1078 renderer->pipe->set_fragment_sampler_views(renderer->pipe, 5, buffer->sampler_views.all);
1079 renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 5, renderer->samplers.all);
1080
1081 renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
1082 renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs);
1083 util_draw_arrays(renderer->pipe, PIPE_PRIM_QUADS, 0, buffer->num_macroblocks * 4);
1084
1085 renderer->pipe->flush(renderer->pipe, PIPE_FLUSH_RENDER_CACHE, buffer->fence);
1086
1087 /* Next time we get this surface it may have new ref frames */
1088 pipe_surface_reference(&buffer->surface, NULL);
1089 pipe_surface_reference(&buffer->past, NULL);
1090 pipe_surface_reference(&buffer->future, NULL);
1091
1092 buffer->num_macroblocks = 0;
1093 }