1/*
2 * Copyright © 2006 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 *    Xiang Haihao <haihao.xiang@intel.com>
25 *
26 */
27
28#include <sys/ioctl.h>
29
30#include "i915_xvmc.h"
31#include "i915_structs.h"
32#include "i915_program.h"
33
34#define YOFFSET(surface)        (surface->srf.offset)
35#define UOFFSET(surface)        (surface->srf.offset + \
36                                 SIZE_Y420(surface->width, surface->height) + \
37                                 SIZE_UV420(surface->width, surface->height))
38#define VOFFSET(surface)        (surface->srf.offset + \
39                                 SIZE_Y420(surface->width, surface->height))
40
41typedef union {
42    int16_t component[2];
43    int32_t v;
44} vector_t;
45
46#if 0
47static int findOverlap(unsigned int width, unsigned int height,
48                       short *dstX, short *dstY,
49                       short *srcX, short *srcY,
50                       unsigned short *areaW, unsigned short *areaH)
51{
52    int w, h;
53    unsigned int mWidth, mHeight;
54
55    w = *areaW;
56    h = *areaH;
57
58    if ((*dstX >= width) || (*dstY >= height))
59        return 1;
60
61    if (*dstX < 0) {
62        w += *dstX;
63        *srcX -= *dstX;
64        *dstX = 0;
65    }
66
67    if (*dstY < 0) {
68        h += *dstY;
69        *srcY -= *dstY;
70        *dstY = 0;
71    }
72
73    if ((w <= 0) || ((h <= 0)))
74        return 1;
75
76    mWidth = width - *dstX;
77    mHeight = height - *dstY;
78    *areaW = (w <= mWidth) ? w : mWidth;
79    *areaH = (h <= mHeight) ? h : mHeight;
80    return 0;
81}
82#endif
83
84static void i915_inst_arith(unsigned int *inst,
85                            unsigned int op,
86                            unsigned int dest,
87                            unsigned int mask,
88                            unsigned int saturate,
89                            unsigned int src0, unsigned int src1, unsigned int src2)
90{
91    dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
92    *inst = (op | A0_DEST(dest) | mask | saturate | A0_SRC0(src0));
93    inst++;
94    *inst = (A1_SRC0(src0) | A1_SRC1(src1));
95    inst++;
96    *inst = (A2_SRC1(src1) | A2_SRC2(src2));
97}
98
99static void i915_inst_decl(unsigned int *inst,
100                           unsigned int type,
101                           unsigned int nr,
102                           unsigned int d0_flags)
103{
104    unsigned int reg = UREG(type, nr);
105
106    *inst = (D0_DCL | D0_DEST(reg) | d0_flags);
107    inst++;
108    *inst = D1_MBZ;
109    inst++;
110    *inst = D2_MBZ;
111}
112
113static void i915_inst_texld(unsigned int *inst,
114                              unsigned int op,
115                              unsigned int dest,
116                              unsigned int coord,
117                              unsigned int sampler)
118{
119   dest = UREG(GET_UREG_TYPE(dest), GET_UREG_NR(dest));
120   *inst = (op | T0_DEST(dest) | T0_SAMPLER(sampler));
121   inst++;
122   *inst = T1_ADDRESS_REG(coord);
123   inst++;
124   *inst = T2_MBZ;
125}
126
127static void i915_emit_batch(void *data, int size, int flag)
128{
129    intelBatchbufferData(data, size, flag);
130}
131
132/* one time context initialization buffer */
133static uint32_t *one_time_load_state_imm1;
134static uint32_t *one_time_load_indirect;
135static int one_time_load_state_imm1_size, one_time_load_indirect_size;
136
137/* load indirect buffer for mc rendering */
138static uint32_t *mc_render_load_indirect;
139static int mc_render_load_indirect_size;
140
141static void i915_mc_one_time_context_init(XvMCContext *context)
142{
143    unsigned int dest, src0, src1, src2;
144    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
145    int i;
146    struct i915_3dstate_sampler_state *sampler_state;
147    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
148    struct i915_3dstate_pixel_shader_constants *pixel_shader_constants;
149
150    /* sampler static state */
151    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
152    /* pixel shader static state */
153    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
154    /* pixel shader contant static state */
155    pixel_shader_constants = (struct i915_3dstate_pixel_shader_constants *)pI915XvMC->psc.map;
156
157    memset(sampler_state, 0, sizeof(*sampler_state));
158    sampler_state->dw0.type = CMD_3D;
159    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
160    sampler_state->dw0.length = 6;
161    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1;
162
163    sampler_state->sampler0.ts0.reverse_gamma = 0;
164    sampler_state->sampler0.ts0.planar2packet = 0;
165    sampler_state->sampler0.ts0.color_conversion = 0;
166    sampler_state->sampler0.ts0.chromakey_index = 0;
167    sampler_state->sampler0.ts0.base_level = 0;
168    sampler_state->sampler0.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
169    sampler_state->sampler0.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
170    sampler_state->sampler0.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
171    sampler_state->sampler0.ts0.lod_bias = 0;       /* 0.0 */
172    sampler_state->sampler0.ts0.shadow_enable = 0;
173    sampler_state->sampler0.ts0.max_anisotropy = ANISORATIO_2;
174    sampler_state->sampler0.ts0.shadow_function = PREFILTEROP_ALWAYS;
175    sampler_state->sampler0.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
176    sampler_state->sampler0.ts1.kill_pixel = 0;
177    sampler_state->sampler0.ts1.keyed_texture_filter = 0;
178    sampler_state->sampler0.ts1.chromakey_enable = 0;
179    sampler_state->sampler0.ts1.tcx_control = TEXCOORDMODE_CLAMP;
180    sampler_state->sampler0.ts1.tcy_control = TEXCOORDMODE_CLAMP;
181    sampler_state->sampler0.ts1.tcz_control = TEXCOORDMODE_CLAMP;
182    sampler_state->sampler0.ts1.normalized_coor = 0;
183    sampler_state->sampler0.ts1.map_index = 0;
184    sampler_state->sampler0.ts1.east_deinterlacer = 0;
185    sampler_state->sampler0.ts2.default_color = 0;
186
187    sampler_state->sampler1.ts0.reverse_gamma = 0;
188    sampler_state->sampler1.ts0.planar2packet = 0;
189    sampler_state->sampler1.ts0.color_conversion = 0;
190    sampler_state->sampler1.ts0.chromakey_index = 0;
191    sampler_state->sampler1.ts0.base_level = 0;
192    sampler_state->sampler1.ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
193    sampler_state->sampler1.ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
194    sampler_state->sampler1.ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
195    sampler_state->sampler1.ts0.lod_bias = 0;       /* 0.0 */
196    sampler_state->sampler1.ts0.shadow_enable = 0;
197    sampler_state->sampler1.ts0.max_anisotropy = ANISORATIO_2;
198    sampler_state->sampler1.ts0.shadow_function = PREFILTEROP_ALWAYS;
199    sampler_state->sampler1.ts1.min_lod = 0;        /* 0.0 Maximum Mip Level */
200    sampler_state->sampler1.ts1.kill_pixel = 0;
201    sampler_state->sampler1.ts1.keyed_texture_filter = 0;
202    sampler_state->sampler1.ts1.chromakey_enable = 0;
203    sampler_state->sampler1.ts1.tcx_control = TEXCOORDMODE_CLAMP;
204    sampler_state->sampler1.ts1.tcy_control = TEXCOORDMODE_CLAMP;
205    sampler_state->sampler1.ts1.tcz_control = TEXCOORDMODE_CLAMP;
206    sampler_state->sampler1.ts1.normalized_coor = 0;
207    sampler_state->sampler1.ts1.map_index = 1;
208    sampler_state->sampler1.ts1.east_deinterlacer = 0;
209    sampler_state->sampler1.ts2.default_color = 0;
210
211    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
212    pixel_shader_program->shader0.type = CMD_3D;
213    pixel_shader_program->shader0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
214    pixel_shader_program->shader0.retain = 1;
215    pixel_shader_program->shader0.length = 2; /* 1 inst */
216    i = 0;
217
218    dest = UREG(REG_TYPE_OC, 0);
219    src0 = UREG(REG_TYPE_CONST, 0);
220    src1 = 0;
221    src2 = 0;
222    i915_inst_arith(&pixel_shader_program->inst0[i], A0_MOV,
223	    dest, A0_DEST_CHANNEL_ALL, A0_DEST_SATURATE, src0, src1, src2);
224
225    pixel_shader_program->shader1.type = CMD_3D;
226    pixel_shader_program->shader1.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
227    pixel_shader_program->shader1.retain = 1;
228    pixel_shader_program->shader1.length = 14; /* 5 inst */
229    i = 0;
230    /* dcl t0.xy */
231    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
232    i+=3;
233    /* dcl t1.xy */
234    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
235    /* dcl_2D s0 */
236    i += 3;
237    i915_inst_decl(&pixel_shader_program->inst1[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
238    /* texld r0, t0, s0 */
239    i += 3;
240    dest = UREG(REG_TYPE_R, 0);
241    src0 = UREG(REG_TYPE_T, 0); /* COORD */
242    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
243    i915_inst_texld(&pixel_shader_program->inst1[i], T0_TEXLD, dest, src0, src1);
244    /* mov oC, r0 */
245    i += 3;
246    dest = UREG(REG_TYPE_OC, 0);
247    src0 = UREG(REG_TYPE_R, 0);
248    src1 = src2 = 0;
249    i915_inst_arith(&pixel_shader_program->inst1[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
250                    A0_DEST_SATURATE, src0, src1, src2);
251
252
253    pixel_shader_program->shader2.type = CMD_3D;
254    pixel_shader_program->shader2.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
255    pixel_shader_program->shader2.retain = 1;
256    pixel_shader_program->shader2.length = 14; /* 5 inst */
257    i = 0;
258    /* dcl t2.xy */
259    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
260    /* dcl t3.xy */
261    i += 3;
262    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
263    /* dcl_2D s1 */
264    i += 3;
265    i915_inst_decl(&pixel_shader_program->inst2[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
266    /* texld r0, t2, s1 */
267    i += 3;
268    dest = UREG(REG_TYPE_R, 0);
269    src0 = UREG(REG_TYPE_T, 2); /* COORD */
270    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
271    i915_inst_texld(&pixel_shader_program->inst2[i], T0_TEXLD, dest, src0, src1);
272    /* mov oC, r0 */
273    i += 3;
274    dest = UREG(REG_TYPE_OC, 0);
275    src0 = UREG(REG_TYPE_R, 0);
276    src1 = src2 = 0;
277    i915_inst_arith(&pixel_shader_program->inst2[i], A0_MOV, dest, A0_DEST_CHANNEL_ALL,
278                    A0_DEST_SATURATE, src0, src1, src2);
279
280    /* Shader 3 */
281    pixel_shader_program->shader3.type = CMD_3D;
282    pixel_shader_program->shader3.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
283    pixel_shader_program->shader3.retain = 1;
284    pixel_shader_program->shader3.length = 29; /* 10 inst */
285    i = 0;
286    /* dcl t0.xy */
287    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
288    /* dcl t1.xy */
289    i += 3;
290    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
291    /* dcl t2.xy */
292    i += 3;
293    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX2, D0_CHANNEL_XY);
294    /* dcl t3.xy */
295    i += 3;
296    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_T, T_TEX3, D0_CHANNEL_XY);
297    /* dcl_2D s0 */
298    i += 3;
299    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
300    /* dcl_2D s1 */
301    i += 3;
302    i915_inst_decl(&pixel_shader_program->inst3[i], REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
303    /* texld r0, t0, s0 */
304    i += 3;
305    dest = UREG(REG_TYPE_R, 0);
306    src0 = UREG(REG_TYPE_T, 0); /* COORD */
307    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
308    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
309    /* texld r1, t2, s1 */
310    i += 3;
311    dest = UREG(REG_TYPE_R, 1);
312    src0 = UREG(REG_TYPE_T, 2); /* COORD */
313    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
314    i915_inst_texld(&pixel_shader_program->inst3[i], T0_TEXLD, dest, src0, src1);
315    /* add r0, r0, r1 */
316    i += 3;
317    dest = UREG(REG_TYPE_R, 0);
318    src0 = UREG(REG_TYPE_R, 0);
319    src1 = UREG(REG_TYPE_R, 1);
320    src2 = 0;
321    i915_inst_arith(&pixel_shader_program->inst3[i], A0_ADD, dest, A0_DEST_CHANNEL_ALL,
322                    0 /* A0_DEST_SATURATE */, src0, src1, src2);
323    /* mul oC, r0, c0 */
324    i += 3;
325    dest = UREG(REG_TYPE_OC, 0);
326    src0 = UREG(REG_TYPE_R, 0);
327    src1 = UREG(REG_TYPE_CONST, 0);
328    src2 = 0;
329    i915_inst_arith(&pixel_shader_program->inst3[i], A0_MUL, dest, A0_DEST_CHANNEL_ALL,
330                    A0_DEST_SATURATE, src0, src1, src2);
331
332    memset(pixel_shader_constants, 0, sizeof(*pixel_shader_constants));
333    pixel_shader_constants->dw0.type = CMD_3D;
334    pixel_shader_constants->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_CONSTANTS;
335    pixel_shader_constants->dw0.length = 4;
336    pixel_shader_constants->dw1.reg_mask = REG_CR0;
337    pixel_shader_constants->value.x = 0.5;
338    pixel_shader_constants->value.y = 0.5;
339    pixel_shader_constants->value.z = 0.5;
340    pixel_shader_constants->value.w = 0.5;
341
342}
343
344static void i915_mc_one_time_state_init(XvMCContext *context)
345{
346    struct s3_dword *s3 = NULL;
347    struct s6_dword *s6 = NULL;
348    dis_state *dis = NULL;
349    ssb_state *ssb = NULL;
350    psp_state *psp = NULL;
351    psc_state *psc = NULL;
352    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
353    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1;
354    struct i915_3dstate_load_indirect *load_indirect;
355    int mem_select;
356
357    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
358    one_time_load_state_imm1_size = sizeof(*load_state_immediate_1) + sizeof(*s3) + sizeof(*s6);
359    one_time_load_state_imm1 = calloc(1, one_time_load_state_imm1_size);
360    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)one_time_load_state_imm1;
361    load_state_immediate_1->dw0.type = CMD_3D;
362    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
363    load_state_immediate_1->dw0.load_s3 = 1;
364    load_state_immediate_1->dw0.load_s6 = 1;
365    load_state_immediate_1->dw0.length = (one_time_load_state_imm1_size >> 2) - 2;
366
367    s3 = (struct s3_dword *)(++load_state_immediate_1);
368    s3->set0_pcd = 1;
369    s3->set1_pcd = 1;
370    s3->set2_pcd = 1;
371    s3->set3_pcd = 1;
372    s3->set4_pcd = 1;
373    s3->set5_pcd = 1;
374    s3->set6_pcd = 1;
375    s3->set7_pcd = 1;
376
377    s6 = (struct s6_dword *)(++s3);
378    s6->alpha_test_enable = 0;
379    s6->alpha_test_function = 0;
380    s6->alpha_reference_value = 0;
381    s6->depth_test_enable = 1;
382    s6->depth_test_function = 0;
383    s6->color_buffer_blend = 0;
384    s6->color_blend_function = 0;
385    s6->src_blend_factor = 1;
386    s6->dest_blend_factor = 1;
387    s6->depth_buffer_write = 0;
388    s6->color_buffer_write = 1;
389    s6->triangle_pv = 0;
390
391    /* 3DSTATE_LOAD_INDIRECT */
392    one_time_load_indirect_size = sizeof(*load_indirect) + sizeof(*dis) + sizeof(*ssb) + sizeof(*psp) + sizeof(*psc);
393    one_time_load_indirect = calloc(1, one_time_load_indirect_size);
394    load_indirect = (struct i915_3dstate_load_indirect *)one_time_load_indirect;
395    load_indirect->dw0.type = CMD_3D;
396    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
397    load_indirect->dw0.block_mask = BLOCK_DIS | BLOCK_SSB | BLOCK_PSP | BLOCK_PSC;
398    load_indirect->dw0.length = (one_time_load_indirect_size >> 2) - 2;
399
400    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
401        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
402	mem_select = 0; /* use physical address */
403    else
404	mem_select = 1; /* use gfx address */
405
406    load_indirect->dw0.mem_select = mem_select;
407
408
409    /* Dynamic indirect state buffer */
410    dis = (dis_state *)(++load_indirect);
411    dis->dw0.valid = 0;
412    dis->dw0.reset = 0;
413    dis->dw0.buffer_address = 0;
414
415    /* Sample state buffer */
416    ssb = (ssb_state *)(++dis);
417    ssb->dw0.valid = 1;
418    ssb->dw0.force = 1;
419    ssb->dw1.length = 7; /* 8 - 1 */
420
421    if (mem_select)
422        ssb->dw0.buffer_address = (pI915XvMC->ssb.offset >> 2);
423    else
424	ssb->dw0.buffer_address = (pI915XvMC->ssb.bus_addr >> 2);
425
426    /* Pixel shader program buffer */
427    psp = (psp_state *)(++ssb);
428    psp->dw0.valid = 1;
429    psp->dw0.force = 1;
430    psp->dw1.length = 66; /* 4 + 16 + 16 + 31 - 1 */
431
432    if (mem_select)
433	psp->dw0.buffer_address = (pI915XvMC->psp.offset >> 2);
434    else
435	psp->dw0.buffer_address = (pI915XvMC->psp.bus_addr >> 2);
436
437    /* Pixel shader constant buffer */
438    psc = (psc_state *)(++psp);
439    psc->dw0.valid = 1;
440    psc->dw0.force = 1;
441    psc->dw1.length = 5; /* 6 - 1 */
442
443    if (mem_select)
444        psc->dw0.buffer_address = (pI915XvMC->psc.offset >> 2);
445    else
446        psc->dw0.buffer_address = (pI915XvMC->psc.bus_addr >> 2);
447}
448
449static void i915_mc_one_time_state_emit(void)
450{
451    i915_emit_batch(one_time_load_state_imm1, one_time_load_state_imm1_size, 0);
452    i915_emit_batch(one_time_load_indirect, one_time_load_indirect_size, 0);
453}
454
455static void i915_mc_static_indirect_state_init(XvMCContext *context)
456{
457    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
458    struct i915_mc_static_indirect_state_buffer *buffer_info =
459	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
460
461    memset(buffer_info, 0, sizeof(*buffer_info));
462    /* dest Y */
463    buffer_info->dest_y.dw0.type = CMD_3D;
464    buffer_info->dest_y.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
465    buffer_info->dest_y.dw0.length = 1;
466    buffer_info->dest_y.dw1.aux_id = 0;
467    buffer_info->dest_y.dw1.buffer_id = BUFFERID_COLOR_BACK;
468    buffer_info->dest_y.dw1.fence_regs = 0;    /* disabled */ /* FIXME: tiled y for performance */
469    buffer_info->dest_y.dw1.tiled_surface = 0; /* linear */
470    buffer_info->dest_y.dw1.walk = TILEWALK_XMAJOR;
471
472    /* dest U */
473    buffer_info->dest_u.dw0.type = CMD_3D;
474    buffer_info->dest_u.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
475    buffer_info->dest_u.dw0.length = 1;
476    buffer_info->dest_u.dw1.aux_id = 0;
477    buffer_info->dest_u.dw1.buffer_id = BUFFERID_COLOR_AUX;
478    buffer_info->dest_u.dw1.fence_regs = 0;
479    buffer_info->dest_u.dw1.tiled_surface = 0;
480    buffer_info->dest_u.dw1.walk = TILEWALK_XMAJOR;
481
482    /* dest V */
483    buffer_info->dest_v.dw0.type = CMD_3D;
484    buffer_info->dest_v.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
485    buffer_info->dest_v.dw0.length = 1;
486    buffer_info->dest_v.dw1.aux_id = 1;
487    buffer_info->dest_v.dw1.buffer_id = BUFFERID_COLOR_AUX;
488    buffer_info->dest_v.dw1.fence_regs = 0;
489    buffer_info->dest_v.dw1.tiled_surface = 0;
490    buffer_info->dest_v.dw1.walk = TILEWALK_XMAJOR;
491
492    buffer_info->dest_buf.dw0.type = CMD_3D;
493    buffer_info->dest_buf.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
494    buffer_info->dest_buf.dw0.length = 0;
495    buffer_info->dest_buf.dw1.dest_v_bias = 8; /* 0.5 */
496    buffer_info->dest_buf.dw1.dest_h_bias = 8; /* 0.5 */
497    buffer_info->dest_buf.dw1.color_fmt = COLORBUFFER_8BIT;
498    buffer_info->dest_buf.dw1.v_ls = 0; /* fill later */
499    buffer_info->dest_buf.dw1.v_ls_offset = 0; /* fill later */
500
501    buffer_info->dest_buf_mpeg.dw0.type = CMD_3D;
502    buffer_info->dest_buf_mpeg.dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES_MPEG;
503    buffer_info->dest_buf_mpeg.dw0.length = 1;
504    buffer_info->dest_buf_mpeg.dw1.decode_mode = MPEG_DECODE_MC;
505    buffer_info->dest_buf_mpeg.dw1.rcontrol = 0;               /* for MPEG-1/MPEG-2 */
506    buffer_info->dest_buf_mpeg.dw1.bidir_avrg_control = 0;     /* for MPEG-1/MPEG-2/MPEG-4 */
507    buffer_info->dest_buf_mpeg.dw1.abort_on_error = 1;
508    buffer_info->dest_buf_mpeg.dw1.intra8 = 0;         /* 16-bit formatted correction data */
509    buffer_info->dest_buf_mpeg.dw1.tff = 1; /* fill later */
510
511    buffer_info->dest_buf_mpeg.dw1.v_subsample_factor = MC_SUB_1V;
512    buffer_info->dest_buf_mpeg.dw1.h_subsample_factor = MC_SUB_1H;
513
514    buffer_info->corr.dw0.type = CMD_3D;
515    buffer_info->corr.dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
516    buffer_info->corr.dw0.length = 1;
517    buffer_info->corr.dw1.aux_id = 0;
518    buffer_info->corr.dw1.buffer_id = BUFFERID_MC_INTRA_CORR;
519    buffer_info->corr.dw1.aux_id = 0;
520    buffer_info->corr.dw1.fence_regs = 0;
521    buffer_info->corr.dw1.tiled_surface = 0;
522    buffer_info->corr.dw1.walk = 0;
523    buffer_info->corr.dw1.pitch = 0;
524    buffer_info->corr.dw2.base_address = (pI915XvMC->corrdata.offset >> 2);  /* starting DWORD address */
525}
526
527static void i915_mc_static_indirect_state_set(XvMCContext *context, XvMCSurface *dest,
528	unsigned int picture_structure, unsigned int flags, unsigned int picture_coding_type)
529{
530    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
531    i915XvMCSurface *pI915Surface = (i915XvMCSurface *)dest->privData;
532    struct i915_mc_static_indirect_state_buffer *buffer_info =
533	(struct i915_mc_static_indirect_state_buffer *)pI915XvMC->sis.map;
534    unsigned int w = dest->width;
535
536    buffer_info->dest_y.dw1.pitch = (pI915Surface->yStride >> 2);      /* in DWords */
537    buffer_info->dest_y.dw2.base_address = (YOFFSET(pI915Surface) >> 2);    /* starting DWORD address */
538    buffer_info->dest_u.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in DWords */
539    buffer_info->dest_u.dw2.base_address = (UOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
540    buffer_info->dest_v.dw1.pitch = (pI915Surface->uvStride >> 2);      /* in Dwords */
541    buffer_info->dest_v.dw2.base_address = (VOFFSET(pI915Surface) >> 2);      /* starting DWORD address */
542
543    if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
544        ;
545    } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_TOP_FIELD) {
546        buffer_info->dest_buf.dw1.v_ls = 1;
547    } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_BOTTOM_FIELD) {
548        buffer_info->dest_buf.dw1.v_ls = 1;
549        buffer_info->dest_buf.dw1.v_ls_offset = 1;
550    }
551
552    if (picture_structure & XVMC_FRAME_PICTURE) {
553        ;
554    } else if (picture_structure & XVMC_TOP_FIELD) {
555        if (flags & XVMC_SECOND_FIELD)
556            buffer_info->dest_buf_mpeg.dw1.tff = 0;
557        else
558            buffer_info->dest_buf_mpeg.dw1.tff = 1;
559    } else if (picture_structure & XVMC_BOTTOM_FIELD) {
560        if (flags & XVMC_SECOND_FIELD)
561            buffer_info->dest_buf_mpeg.dw1.tff = 1;
562        else
563            buffer_info->dest_buf_mpeg.dw1.tff = 0;
564    }
565
566    buffer_info->dest_buf_mpeg.dw1.picture_width = (dest->width >> 4);     /* in macroblocks */
567    buffer_info->dest_buf_mpeg.dw2.picture_coding_type = picture_coding_type;
568}
569
570static void i915_mc_map_state_init(XvMCContext *context)
571{
572    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
573    unsigned int w = context->width;
574    unsigned int h = context->height;
575    struct i915_mc_map_state *map_state;
576
577    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
578
579    memset(map_state, 0, sizeof(*map_state));
580
581    /* 3DSATE_MAP_STATE: Y */
582    map_state->y_map.dw0.type = CMD_3D;
583    map_state->y_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
584    map_state->y_map.dw0.retain = 1;
585    map_state->y_map.dw0.length = 6;
586    map_state->y_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
587
588    /* Y Forward (Past) */
589    map_state->y_forward.tm0.v_ls_offset = 0;
590    map_state->y_forward.tm0.v_ls = 0;
591    map_state->y_forward.tm1.tile_walk = TILEWALK_XMAJOR;
592    map_state->y_forward.tm1.tiled_surface = 0;
593    map_state->y_forward.tm1.utilize_fence_regs = 0;
594    map_state->y_forward.tm1.texel_fmt = 0;      /* 8bit */
595    map_state->y_forward.tm1.surface_fmt = 1;    /* 8bit */
596    map_state->y_forward.tm1.width = w - 1;
597    map_state->y_forward.tm1.height = h - 1;
598    map_state->y_forward.tm2.depth = 0;
599    map_state->y_forward.tm2.max_lod = 0;
600    map_state->y_forward.tm2.cube_face = 0;
601
602    /* Y Backward (Future) */
603    map_state->y_backward.tm0.v_ls_offset = 0;
604    map_state->y_backward.tm0.v_ls = 0;
605    map_state->y_backward.tm1.tile_walk = TILEWALK_XMAJOR;
606    map_state->y_backward.tm1.tiled_surface = 0;
607    map_state->y_backward.tm1.utilize_fence_regs = 0;
608    map_state->y_backward.tm1.texel_fmt = 0;      /* 8bit */
609    map_state->y_backward.tm1.surface_fmt = 1;    /* 8bit */
610    map_state->y_backward.tm1.width = w - 1;
611    map_state->y_backward.tm1.height = h - 1;
612    map_state->y_backward.tm2.depth = 0;
613    map_state->y_backward.tm2.max_lod = 0;
614    map_state->y_backward.tm2.cube_face = 0;
615
616    /* 3DSATE_MAP_STATE: U */
617    map_state->u_map.dw0.type = CMD_3D;
618    map_state->u_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
619    map_state->u_map.dw0.retain = 1;
620    map_state->u_map.dw0.length = 6;
621    map_state->u_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
622
623    /* U Forward */
624    map_state->u_forward.tm0.v_ls_offset = 0;
625    map_state->u_forward.tm0.v_ls = 0;
626    map_state->u_forward.tm1.tile_walk = TILEWALK_XMAJOR;
627    map_state->u_forward.tm1.tiled_surface = 0;
628    map_state->u_forward.tm1.utilize_fence_regs = 0;
629    map_state->u_forward.tm1.texel_fmt = 0;      /* 8bit */
630    map_state->u_forward.tm1.surface_fmt = 1;    /* 8bit */
631    map_state->u_forward.tm1.width = (w >> 1) - 1;
632    map_state->u_forward.tm1.height = (h >> 1) - 1;
633    map_state->u_forward.tm2.depth = 0;
634    map_state->u_forward.tm2.max_lod = 0;
635    map_state->u_forward.tm2.cube_face = 0;
636
637    /* U Backward */
638    map_state->u_backward.tm0.v_ls_offset = 0;
639    map_state->u_backward.tm0.v_ls = 0;
640    map_state->u_backward.tm1.tile_walk = TILEWALK_XMAJOR;
641    map_state->u_backward.tm1.tiled_surface = 0;
642    map_state->u_backward.tm1.utilize_fence_regs = 0;
643    map_state->u_backward.tm1.texel_fmt = 0;
644    map_state->u_backward.tm1.surface_fmt = 1;
645    map_state->u_backward.tm1.width = (w >> 1) - 1;
646    map_state->u_backward.tm1.height = (h >> 1) - 1;
647    map_state->u_backward.tm2.depth = 0;
648    map_state->u_backward.tm2.max_lod = 0;
649    map_state->u_backward.tm2.cube_face = 0;
650
651    /* 3DSATE_MAP_STATE: V */
652    map_state->v_map.dw0.type = CMD_3D;
653    map_state->v_map.dw0.opcode = OPC_3DSTATE_MAP_STATE;
654    map_state->v_map.dw0.retain = 1;
655    map_state->v_map.dw0.length = 6;
656    map_state->v_map.dw1.map_mask = MAP_MAP0 | MAP_MAP1;
657
658    /* V Forward */
659    map_state->v_forward.tm0.v_ls_offset = 0;
660    map_state->v_forward.tm0.v_ls = 0;
661    map_state->v_forward.tm1.tile_walk = TILEWALK_XMAJOR;
662    map_state->v_forward.tm1.tiled_surface = 0;
663    map_state->v_forward.tm1.utilize_fence_regs = 0;
664    map_state->v_forward.tm1.texel_fmt = 0;
665    map_state->v_forward.tm1.surface_fmt = 1;
666    map_state->v_forward.tm1.width = (w >> 1) - 1;
667    map_state->v_forward.tm1.height = (h >> 1) - 1;
668    map_state->v_forward.tm2.depth = 0;
669    map_state->v_forward.tm2.max_lod = 0;
670    map_state->v_forward.tm2.cube_face = 0;
671
672    /* V Backward */
673    map_state->v_backward.tm0.v_ls_offset = 0;
674    map_state->v_backward.tm0.v_ls = 0;
675    map_state->v_backward.tm1.tile_walk = TILEWALK_XMAJOR;
676    map_state->v_backward.tm1.tiled_surface = 0;
677    map_state->v_backward.tm1.utilize_fence_regs = 0;
678    map_state->v_backward.tm1.texel_fmt = 0;
679    map_state->v_backward.tm1.surface_fmt = 1;
680    map_state->v_backward.tm1.width = (w >> 1) - 1;
681    map_state->v_backward.tm1.height = (h >> 1) - 1;
682    map_state->v_backward.tm2.depth = 0;
683    map_state->v_backward.tm2.max_lod = 0;
684    map_state->v_backward.tm2.cube_face = 0;
685}
686
687static void i915_mc_map_state_set(XvMCContext *context,
688	i915XvMCSurface *privPast,
689	i915XvMCSurface *privFuture)
690{
691    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
692    struct i915_mc_map_state *map_state;
693
694    map_state = (struct i915_mc_map_state *)pI915XvMC->msb.map;
695
696    map_state->y_forward.tm0.base_address = (YOFFSET(privPast) >> 2);
697    map_state->y_forward.tm2.pitch = (privPast->yStride >> 2) - 1;       /* in DWords - 1 */
698    map_state->y_backward.tm0.base_address = (YOFFSET(privFuture) >> 2);
699    map_state->y_backward.tm2.pitch = (privFuture->yStride >> 2) - 1;
700    map_state->u_forward.tm0.base_address = (UOFFSET(privPast) >> 2);
701    map_state->u_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
702    map_state->u_backward.tm0.base_address = (UOFFSET(privFuture) >> 2);
703    map_state->u_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
704    map_state->v_forward.tm0.base_address = (VOFFSET(privPast) >> 2);
705    map_state->v_forward.tm2.pitch = (privPast->uvStride >> 2) - 1;       /* in DWords - 1 */
706    map_state->v_backward.tm0.base_address = (VOFFSET(privFuture) >> 2);
707    map_state->v_backward.tm2.pitch = (privFuture->uvStride >> 2) - 1;
708}
709
710static void i915_flush(int map, int render)
711{
712    struct i915_mi_flush mi_flush;
713
714    memset(&mi_flush, 0, sizeof(mi_flush));
715    mi_flush.dw0.type = CMD_MI;
716    mi_flush.dw0.opcode = OPC_MI_FLUSH;
717    mi_flush.dw0.map_cache_invalidate = map;
718    mi_flush.dw0.render_cache_flush_inhibit = render;
719
720    intelBatchbufferData(&mi_flush, sizeof(mi_flush), 0);
721}
722
723static void i915_mc_load_indirect_render_init(XvMCContext *context)
724{
725    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
726    sis_state *sis;
727    msb_state *msb;
728    struct i915_3dstate_load_indirect *load_indirect;
729    int mem_select;
730
731    mc_render_load_indirect_size = sizeof(*load_indirect) + sizeof(*sis)
732					+ sizeof(*msb);
733    mc_render_load_indirect = calloc(1, mc_render_load_indirect_size);
734
735    load_indirect = (struct i915_3dstate_load_indirect *)mc_render_load_indirect;
736    load_indirect->dw0.type = CMD_3D;
737    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
738    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_MSB;
739    load_indirect->dw0.length = (mc_render_load_indirect_size >> 2) - 2;
740
741    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
742        pI915XvMC->deviceID == PCI_CHIP_I915_GM)
743        mem_select = 0;
744    else
745	mem_select = 1;
746
747    load_indirect->dw0.mem_select = mem_select;
748
749    /* Static Indirect state buffer (dest buffer info) */
750    sis = (sis_state *)(++load_indirect);
751    sis->dw0.valid = 1;
752    sis->dw0.force = 1;
753    sis->dw1.length = 16; /* 4 * 3 + 2 + 3 - 1 */
754
755    if (mem_select)
756	sis->dw0.buffer_address = (pI915XvMC->sis.offset >> 2);
757    else
758	sis->dw0.buffer_address = (pI915XvMC->sis.bus_addr >> 2);
759
760    /* Map state buffer (reference buffer info) */
761    msb = (msb_state *)(++sis);
762    msb->dw0.valid = 1;
763    msb->dw0.force = 1;
764    msb->dw1.length = 23; /* 3 * 8 - 1 */
765
766    if (mem_select)
767	msb->dw0.buffer_address = (pI915XvMC->msb.offset >> 2);
768    else
769	msb->dw0.buffer_address = (pI915XvMC->msb.bus_addr >> 2);
770}
771
772static void i915_mc_load_indirect_render_emit(void)
773{
774    i915_emit_batch(mc_render_load_indirect, mc_render_load_indirect_size, 0);
775}
776
777static void i915_mc_mpeg_set_origin(XvMCContext *context, XvMCMacroBlock *mb)
778{
779    struct i915_3dmpeg_set_origin set_origin;
780
781    /* 3DMPEG_SET_ORIGIN */
782    memset(&set_origin, 0, sizeof(set_origin));
783    set_origin.dw0.type = CMD_3D;
784    set_origin.dw0.opcode = OPC_3DMPEG_SET_ORIGIN;
785    set_origin.dw0.length = 0;
786    set_origin.dw1.h_origin = mb->x;
787    set_origin.dw1.v_origin = mb->y;
788
789    intelBatchbufferData(&set_origin, sizeof(set_origin), 0);
790}
791
792static void i915_mc_mpeg_macroblock_ipicture(XvMCContext *context, XvMCMacroBlock *mb)
793{
794    struct i915_3dmpeg_macroblock_ipicture macroblock_ipicture;
795
796    /* 3DMPEG_MACROBLOCK_IPICTURE */
797    memset(&macroblock_ipicture, 0, sizeof(macroblock_ipicture));
798    macroblock_ipicture.dw0.type = CMD_3D;
799    macroblock_ipicture.dw0.opcode = OPC_3DMPEG_MACROBLOCK_IPICTURE;
800    macroblock_ipicture.dw0.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
801
802    intelBatchbufferData(&macroblock_ipicture, sizeof(macroblock_ipicture), 0);
803}
804
805#if 0
806static void i915_mc_mpeg_macroblock_0mv(XvMCContext *context, XvMCMacroBlock *mb)
807{
808    struct i915_3dmpeg_macroblock_0mv macroblock_0mv;
809
810    /* 3DMPEG_MACROBLOCK(0mv) */
811    memset(&macroblock_0mv, 0, sizeof(macroblock_0mv));
812    macroblock_0mv.header.dw0.type = CMD_3D;
813    macroblock_0mv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
814    macroblock_0mv.header.dw0.length = 0;
815    macroblock_0mv.header.dw1.mb_intra = 1;     /* should be 1 */
816    macroblock_0mv.header.dw1.forward = 0;      /* should be 0 */
817    macroblock_0mv.header.dw1.backward = 0;     /* should be 0 */
818    macroblock_0mv.header.dw1.h263_4mv = 0;     /* should be 0 */
819    macroblock_0mv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
820
821/*
822    if (!mb->coded_block_pattern)
823        macroblock_0mv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
824*/
825
826    macroblock_0mv.header.dw1.motion_type = 0; // (mb->motion_type & 0x3);
827    macroblock_0mv.header.dw1.vertical_field_select = 0; // mb->motion_vertical_field_select & 0xf;
828    macroblock_0mv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
829    macroblock_0mv.header.dw1.skipped_macroblocks = 0;
830
831    intelBatchbufferData(&macroblock_0mv, sizeof(macroblock_0mv), 0);
832}
833#endif
834
835static void i915_mc_mpeg_macroblock_1fbmv(XvMCContext *context, XvMCMacroBlock *mb)
836{
837    struct i915_3dmpeg_macroblock_1fbmv macroblock_1fbmv;
838    vector_t mv0[2];
839
840    /* 3DMPEG_MACROBLOCK(1fbmv) */
841    memset(&macroblock_1fbmv, 0, sizeof(macroblock_1fbmv));
842    macroblock_1fbmv.header.dw0.type = CMD_3D;
843    macroblock_1fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
844    macroblock_1fbmv.header.dw0.length = 2;
845    macroblock_1fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
846    macroblock_1fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
847    macroblock_1fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
848    macroblock_1fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
849    macroblock_1fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
850
851    if (!(mb->coded_block_pattern & 0x3f))
852        macroblock_1fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
853
854    macroblock_1fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
855    macroblock_1fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
856    macroblock_1fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
857    macroblock_1fbmv.header.dw1.skipped_macroblocks = 0;
858
859    mv0[0].component[0] = mb->PMV[0][0][0];
860    mv0[0].component[1] = mb->PMV[0][0][1];
861    mv0[1].component[0] = mb->PMV[0][1][0];
862    mv0[1].component[1] = mb->PMV[0][1][1];
863
864    macroblock_1fbmv.dw2 = mv0[0].v;
865    macroblock_1fbmv.dw3 = mv0[1].v;
866
867    intelBatchbufferData(&macroblock_1fbmv, sizeof(macroblock_1fbmv), 0);
868}
869
870static void i915_mc_mpeg_macroblock_2fbmv(XvMCContext *context, XvMCMacroBlock *mb, unsigned int ps)
871{
872    struct i915_3dmpeg_macroblock_2fbmv macroblock_2fbmv;
873    vector_t mv0[2];
874    vector_t mv1[2];
875
876    /* 3DMPEG_MACROBLOCK(2fbmv) */
877    memset(&macroblock_2fbmv, 0, sizeof(macroblock_2fbmv));
878    macroblock_2fbmv.header.dw0.type = CMD_3D;
879    macroblock_2fbmv.header.dw0.opcode = OPC_3DMPEG_MACROBLOCK;
880    macroblock_2fbmv.header.dw0.length = 4;
881    macroblock_2fbmv.header.dw1.mb_intra = 0;   /* should be 0 */
882    macroblock_2fbmv.header.dw1.forward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_FORWARD) ? 1 : 0);
883    macroblock_2fbmv.header.dw1.backward = ((mb->macroblock_type & XVMC_MB_TYPE_MOTION_BACKWARD) ? 1 : 0);
884    macroblock_2fbmv.header.dw1.h263_4mv = 0;   /* should be 0 */
885    macroblock_2fbmv.header.dw1.dct_type = (mb->dct_type == XVMC_DCT_TYPE_FIELD);
886
887    if (!(mb->coded_block_pattern & 0x3f))
888        macroblock_2fbmv.header.dw1.dct_type = XVMC_DCT_TYPE_FRAME;
889
890    macroblock_2fbmv.header.dw1.motion_type = (mb->motion_type & 0x03);
891    macroblock_2fbmv.header.dw1.vertical_field_select = (mb->motion_vertical_field_select & 0x0f);
892    macroblock_2fbmv.header.dw1.coded_block_pattern = mb->coded_block_pattern;
893    macroblock_2fbmv.header.dw1.skipped_macroblocks = 0;
894
895    mv0[0].component[0] = mb->PMV[0][0][0];
896    mv0[0].component[1] = mb->PMV[0][0][1];
897    mv0[1].component[0] = mb->PMV[0][1][0];
898    mv0[1].component[1] = mb->PMV[0][1][1];
899    mv1[0].component[0] = mb->PMV[1][0][0];
900    mv1[0].component[1] = mb->PMV[1][0][1];
901    mv1[1].component[0] = mb->PMV[1][1][0];
902    mv1[1].component[1] = mb->PMV[1][1][1];
903
904    if ((ps & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
905        if ((mb->motion_type & 3) == XVMC_PREDICTION_FIELD) {
906            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
907            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;
908            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
909            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
910        } else if ((mb->motion_type & 3) == XVMC_PREDICTION_DUAL_PRIME) {
911            mv0[0].component[1] = mb->PMV[0][0][1] >> 1;
912            mv0[1].component[1] = mb->PMV[0][1][1] >> 1;  // MPEG2 MV[0][1] isn't used
913            mv1[0].component[1] = mb->PMV[1][0][1] >> 1;
914            mv1[1].component[1] = mb->PMV[1][1][1] >> 1;
915        }
916    }
917
918    macroblock_2fbmv.dw2 = mv0[0].v;
919    macroblock_2fbmv.dw3 = mv0[1].v;
920    macroblock_2fbmv.dw4 = mv1[0].v;
921    macroblock_2fbmv.dw5 = mv1[1].v;
922
923    intelBatchbufferData(&macroblock_2fbmv, sizeof(macroblock_2fbmv), 0);
924}
925
926#if 0
927static void i915_mc_invalidate_subcontext_buffers(XvMCContext *context, unsigned int mask)
928{
929    struct i915_3dstate_load_indirect *load_indirect = NULL;
930    sis_state *sis = NULL;
931    dis_state *dis = NULL;
932    ssb_state *ssb = NULL;
933    msb_state *msb = NULL;
934    psp_state *psp = NULL;
935    psc_state *psc = NULL;
936    i915XvMCContext *pI915XvMC = (i915XvMCContext *)context->privData;
937    unsigned int size;
938    void *base = NULL, *ptr = NULL;
939
940    size = sizeof(*load_indirect);
941    if (mask & BLOCK_SIS)
942        size += sizeof(*sis);
943    if (mask & BLOCK_DIS)
944        size += sizeof(*dis);
945    if (mask & BLOCK_SSB)
946        size += sizeof(*ssb);
947    if (mask & BLOCK_MSB)
948        size += sizeof(*msb);
949    if (mask & BLOCK_PSP)
950        size += sizeof(*psp);
951    if (mask & BLOCK_PSC)
952        size += sizeof(*psc);
953
954    if (size == sizeof(*load_indirect)) {
955        XVMC_ERR("There must be at least one bit set\n");
956        return;
957    }
958
959    /* 3DSTATE_LOAD_INDIRECT */
960    base = calloc(1, size);
961    load_indirect = (struct i915_3dstate_load_indirect *)base;
962    load_indirect->dw0.type = CMD_3D;
963    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
964
965    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
966        pI915XvMC->deviceID == PCI_CHIP_I915_GM ||
967        pI915XvMC->deviceID == PCI_CHIP_I945_G ||
968        pI915XvMC->deviceID == PCI_CHIP_I945_GM)
969        load_indirect->dw0.mem_select = 0;
970    else
971        load_indirect->dw0.mem_select = 1;
972
973    load_indirect->dw0.block_mask = mask;
974    load_indirect->dw0.length = (size >> 2) - 2;
975    ptr = ++load_indirect;
976
977    /* SIS */
978    if (mask & BLOCK_SIS) {
979        sis = (sis_state *)ptr;
980        sis->dw0.valid = 0;
981        sis->dw0.buffer_address = 0;
982        sis->dw1.length = 0;
983        ptr = ++sis;
984    }
985
986    /* DIS */
987    if (mask & BLOCK_DIS) {
988        dis = (dis_state *)ptr;
989        dis->dw0.valid = 0;
990        dis->dw0.reset = 0;
991        dis->dw0.buffer_address = 0;
992        ptr = ++dis;
993    }
994
995    /* SSB */
996    if (mask & BLOCK_SSB) {
997        ssb = (ssb_state *)ptr;
998        ssb->dw0.valid = 0;
999        ssb->dw0.buffer_address = 0;
1000        ssb->dw1.length = 0;
1001        ptr = ++ssb;
1002    }
1003
1004    /* MSB */
1005    if (mask & BLOCK_MSB) {
1006        msb = (msb_state *)ptr;
1007        msb->dw0.valid = 0;
1008        msb->dw0.buffer_address = 0;
1009        msb->dw1.length = 0;
1010        ptr = ++msb;
1011    }
1012
1013    /* PSP */
1014    if (mask & BLOCK_PSP) {
1015        psp = (psp_state *)ptr;
1016        psp->dw0.valid = 0;
1017        psp->dw0.buffer_address = 0;
1018        psp->dw1.length = 0;
1019        ptr = ++psp;
1020    }
1021
1022    /* PSC */
1023    if (mask & BLOCK_PSC) {
1024        psc = (psc_state *)ptr;
1025        psc->dw0.valid = 0;
1026        psc->dw0.buffer_address = 0;
1027        psc->dw1.length = 0;
1028        ptr = ++psc;
1029    }
1030
1031    intelBatchbufferData(base, size, 0);
1032    free(base);
1033}
1034#endif
1035
1036static int i915_xvmc_map_buffers(i915XvMCContext *pI915XvMC)
1037{
1038    if (drmMap(xvmc_driver->fd,
1039               pI915XvMC->sis.handle,
1040               pI915XvMC->sis.size,
1041               (drmAddress *)&pI915XvMC->sis.map) != 0) {
1042        return -1;
1043    }
1044
1045    if (drmMap(xvmc_driver->fd,
1046               pI915XvMC->ssb.handle,
1047               pI915XvMC->ssb.size,
1048               (drmAddress *)&pI915XvMC->ssb.map) != 0) {
1049        return -1;
1050    }
1051
1052    if (drmMap(xvmc_driver->fd,
1053               pI915XvMC->msb.handle,
1054               pI915XvMC->msb.size,
1055               (drmAddress *)&pI915XvMC->msb.map) != 0) {
1056        return -1;
1057    }
1058
1059    if (drmMap(xvmc_driver->fd,
1060               pI915XvMC->psp.handle,
1061               pI915XvMC->psp.size,
1062               (drmAddress *)&pI915XvMC->psp.map) != 0) {
1063        return -1;
1064    }
1065
1066    if (drmMap(xvmc_driver->fd,
1067               pI915XvMC->psc.handle,
1068               pI915XvMC->psc.size,
1069               (drmAddress *)&pI915XvMC->psc.map) != 0) {
1070        return -1;
1071    }
1072
1073    if (drmMap(xvmc_driver->fd,
1074               pI915XvMC->corrdata.handle,
1075               pI915XvMC->corrdata.size,
1076               (drmAddress *)&pI915XvMC->corrdata.map) != 0) {
1077        return -1;
1078    }
1079
1080    return 0;
1081}
1082
1083static void i915_xvmc_unmap_buffers(i915XvMCContext *pI915XvMC)
1084{
1085    if (pI915XvMC->sis.map) {
1086        drmUnmap(pI915XvMC->sis.map, pI915XvMC->sis.size);
1087        pI915XvMC->sis.map = NULL;
1088    }
1089
1090    if (pI915XvMC->ssb.map) {
1091        drmUnmap(pI915XvMC->ssb.map, pI915XvMC->ssb.size);
1092        pI915XvMC->ssb.map = NULL;
1093    }
1094
1095    if (pI915XvMC->msb.map) {
1096        drmUnmap(pI915XvMC->msb.map, pI915XvMC->msb.size);
1097        pI915XvMC->msb.map = NULL;
1098    }
1099
1100    if (pI915XvMC->psp.map) {
1101        drmUnmap(pI915XvMC->psp.map, pI915XvMC->psp.size);
1102        pI915XvMC->psp.map = NULL;
1103    }
1104
1105    if (pI915XvMC->psc.map) {
1106        drmUnmap(pI915XvMC->psc.map, pI915XvMC->psc.size);
1107        pI915XvMC->psc.map = NULL;
1108    }
1109
1110    if (pI915XvMC->corrdata.map) {
1111        drmUnmap(pI915XvMC->corrdata.map, pI915XvMC->corrdata.size);
1112        pI915XvMC->corrdata.map = NULL;
1113    }
1114}
1115
1116#if 0
1117/*
1118 * Video post processing
1119 */
1120static void i915_yuv2rgb_map_state_buffer(XvMCSurface *target_surface)
1121{
1122    struct i915_3dstate_map_state *map_state;
1123    struct texture_map *tm;
1124    i915XvMCSurface *privTarget = NULL;
1125    i915XvMCContext *pI915XvMC = NULL;
1126    unsigned int w = target_surface->width, h = target_surface->height;
1127
1128    privTarget = (i915XvMCSurface *)target_surface->privData;
1129    pI915XvMC = (i915XvMCContext *)privTarget->privContext;
1130    /* 3DSATE_MAP_STATE */
1131    map_state = (struct i915_3dstate_map_state *)pI915XvMC->msb.map;
1132    memset(map_state, 0, sizeof(*map_state));
1133    map_state->dw0.type = CMD_3D;
1134    map_state->dw0.opcode = OPC_3DSTATE_MAP_STATE;
1135    map_state->dw0.retain = 0;
1136    map_state->dw0.length = 9;
1137    map_state->dw1.map_mask = MAP_MAP0 | MAP_MAP1 | MAP_MAP2;
1138
1139    /* texture map 0: V Plane */
1140    tm = (struct texture_map *)(++map_state);
1141    memset(tm, 0, sizeof(*tm));
1142    tm->tm0.v_ls_offset = 0;
1143    tm->tm0.v_ls = 0;
1144    tm->tm0.base_address = VOFFSET(privTarget);
1145    tm->tm1.tile_walk = TILEWALK_XMAJOR;
1146    tm->tm1.tiled_surface = 0;
1147    tm->tm1.utilize_fence_regs = 1;
1148    tm->tm1.texel_fmt = 0;
1149    tm->tm1.surface_fmt = 1;
1150    tm->tm1.width = (w >> 1) - 1;
1151    tm->tm1.height = (h >> 1) - 1;
1152    tm->tm2.depth = 0;
1153    tm->tm2.max_lod = 0;
1154    tm->tm2.cube_face = 0;
1155    tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
1156
1157    /* texture map 1: Y Plane */
1158    ++tm;
1159    memset(tm, 0, sizeof(*tm));
1160    tm->tm0.v_ls_offset = 0;
1161    tm->tm0.v_ls = 0;
1162    tm->tm0.base_address = YOFFSET(privTarget);
1163    tm->tm1.tile_walk = TILEWALK_XMAJOR;
1164    tm->tm1.tiled_surface = 0;
1165    tm->tm1.utilize_fence_regs = 1;
1166    tm->tm1.texel_fmt = 0;
1167    tm->tm1.surface_fmt = 1;
1168    tm->tm1.width = w - 1;
1169    tm->tm1.height = h - 1;
1170    tm->tm2.depth = 0;
1171    tm->tm2.max_lod = 0;
1172    tm->tm2.cube_face = 0;
1173    tm->tm2.pitch = (privTarget->yStride >> 2) - 1;     /* in DWords - 1 */
1174
1175    /* texture map 2: U Plane */
1176    ++tm;
1177    memset(tm, 0, sizeof(*tm));
1178    tm->tm0.v_ls_offset = 0;
1179    tm->tm0.v_ls = 0;
1180    tm->tm0.base_address = UOFFSET(privTarget);
1181    tm->tm1.tile_walk = TILEWALK_XMAJOR;
1182    tm->tm1.tiled_surface = 0;
1183    tm->tm1.utilize_fence_regs = 1;
1184    tm->tm1.texel_fmt = 0;
1185    tm->tm1.surface_fmt = 1;
1186    tm->tm1.width = (w >> 1) - 1;
1187    tm->tm1.height = (h >> 1) - 1;
1188    tm->tm2.depth = 0;
1189    tm->tm2.max_lod = 0;
1190    tm->tm2.cube_face = 0;
1191    tm->tm2.pitch = (privTarget->uvStride >> 2) - 1;    /* in DWords - 1 */
1192}
1193#endif
1194
1195#if 0
1196static void i915_yuv2rgb_sampler_state_buffer(XvMCSurface *surface)
1197{
1198    struct i915_3dstate_sampler_state *sampler_state;
1199    struct texture_sampler *ts;
1200    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
1201    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
1202
1203    /* 3DSATE_SAMPLER_STATE */
1204    sampler_state = (struct i915_3dstate_sampler_state *)pI915XvMC->ssb.map;
1205    memset(sampler_state, 0, sizeof(*sampler_state));
1206    sampler_state->dw0.type = CMD_3D;
1207    sampler_state->dw0.opcode = OPC_3DSTATE_SAMPLER_STATE;
1208    sampler_state->dw0.length = 9;
1209    sampler_state->dw1.sampler_masker = SAMPLER_SAMPLER0 | SAMPLER_SAMPLER1 | SAMPLER_SAMPLER2;
1210
1211    /* Sampler 0 */
1212    ts = (struct texture_sampler *)(++sampler_state);
1213    memset(ts, 0, sizeof(*ts));
1214    ts->ts0.reverse_gamma = 0;
1215    ts->ts0.planar2packet = 1;
1216    ts->ts0.color_conversion = 1;
1217    ts->ts0.chromakey_index = 0;
1218    ts->ts0.base_level = 0;
1219    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
1220    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
1221    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
1222    ts->ts0.lod_bias = 0;
1223    ts->ts0.shadow_enable = 0;
1224    ts->ts0.max_anisotropy = ANISORATIO_2;
1225    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
1226    ts->ts1.min_lod = 0;        /* Maximum Mip Level */
1227    ts->ts1.kill_pixel = 0;
1228    ts->ts1.keyed_texture_filter = 0;
1229    ts->ts1.chromakey_enable = 0;
1230    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
1231    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
1232    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
1233    ts->ts1.normalized_coor = 0;
1234    ts->ts1.map_index = 0;
1235    ts->ts1.east_deinterlacer = 0;
1236    ts->ts2.default_color = 0;
1237
1238    /* Sampler 1 */
1239    ++ts;
1240    memset(ts, 0, sizeof(*ts));
1241    ts->ts0.reverse_gamma = 0;
1242    ts->ts0.planar2packet = 1;
1243    ts->ts0.color_conversion = 1;
1244    ts->ts0.chromakey_index = 0;
1245    ts->ts0.base_level = 0;
1246    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
1247    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
1248    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
1249    ts->ts0.lod_bias = 0;
1250    ts->ts0.shadow_enable = 0;
1251    ts->ts0.max_anisotropy = ANISORATIO_2;
1252    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
1253    ts->ts1.min_lod = 0;        /* Maximum Mip Level */
1254    ts->ts1.kill_pixel = 0;
1255    ts->ts1.keyed_texture_filter = 0;
1256    ts->ts1.chromakey_enable = 0;
1257    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
1258    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
1259    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
1260    ts->ts1.normalized_coor = 0;
1261    ts->ts1.map_index = 1;
1262    ts->ts1.east_deinterlacer = 0;
1263    ts->ts2.default_color = 0;
1264
1265    /* Sampler 2 */
1266    ++ts;
1267    memset(ts, 0, sizeof(*ts));
1268    ts->ts0.reverse_gamma = 0;
1269    ts->ts0.planar2packet = 1;
1270    ts->ts0.color_conversion = 1;
1271    ts->ts0.chromakey_index = 0;
1272    ts->ts0.base_level = 0;
1273    ts->ts0.mip_filter = MIPFILTER_NONE;        /* NONE */
1274    ts->ts0.mag_filter = MAPFILTER_LINEAR;      /* LINEAR */
1275    ts->ts0.min_filter = MAPFILTER_LINEAR;      /* LINEAR */
1276    ts->ts0.lod_bias = 0;
1277    ts->ts0.shadow_enable = 0;
1278    ts->ts0.max_anisotropy = ANISORATIO_2;
1279    ts->ts0.shadow_function = PREFILTEROP_ALWAYS;
1280    ts->ts1.min_lod = 0;        /* Maximum Mip Level */
1281    ts->ts1.kill_pixel = 0;
1282    ts->ts1.keyed_texture_filter = 0;
1283    ts->ts1.chromakey_enable = 0;
1284    ts->ts1.tcx_control = TEXCOORDMODE_CLAMP;
1285    ts->ts1.tcy_control = TEXCOORDMODE_CLAMP;
1286    ts->ts1.tcz_control = TEXCOORDMODE_CLAMP;
1287    ts->ts1.normalized_coor = 0;
1288    ts->ts1.map_index = 2;
1289    ts->ts1.east_deinterlacer = 0;
1290    ts->ts2.default_color = 0;
1291}
1292#endif
1293
1294#if 0
1295static void i915_yuv2rgb_static_indirect_state_buffer(XvMCSurface *surface,
1296                                                      unsigned int dstaddr,
1297                                                      int dstpitch)
1298{
1299    struct i915_3dstate_buffer_info *buffer_info;
1300    struct i915_3dstate_dest_buffer_variables *dest_buffer_variables;
1301    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
1302    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
1303
1304    /* 3DSTATE_BUFFER_INFO */
1305    buffer_info = (struct i915_3dstate_buffer_info *)pI915XvMC->sis.map;
1306    memset(buffer_info, 0, sizeof(*buffer_info));
1307    buffer_info->dw0.type = CMD_3D;
1308    buffer_info->dw0.opcode = OPC_3DSTATE_BUFFER_INFO;
1309    buffer_info->dw0.length = 1;
1310    buffer_info->dw1.aux_id = 0;
1311    buffer_info->dw1.buffer_id = BUFFERID_COLOR_BACK;
1312    buffer_info->dw1.fence_regs = 1;
1313    buffer_info->dw1.tiled_surface = 0;   /* linear */
1314    buffer_info->dw1.walk = TILEWALK_XMAJOR;
1315    buffer_info->dw1.pitch = dstpitch;
1316    buffer_info->dw2.base_address = dstaddr;
1317
1318    /* 3DSTATE_DEST_BUFFER_VARIABLES */
1319    dest_buffer_variables = (struct i915_3dstate_dest_buffer_variables *)(++buffer_info);
1320    memset(dest_buffer_variables, 0, sizeof(*dest_buffer_variables));
1321    dest_buffer_variables->dw0.type = CMD_3D;
1322    dest_buffer_variables->dw0.opcode = OPC_3DSTATE_DEST_BUFFER_VARIABLES;
1323    dest_buffer_variables->dw0.length = 0;
1324    dest_buffer_variables->dw1.dest_v_bias = 8; /* FIXME 0x1000 .5 ??? */
1325    dest_buffer_variables->dw1.dest_h_bias = 8;
1326    dest_buffer_variables->dw1.color_fmt = COLORBUFFER_A8R8G8B8;  /* FIXME */
1327}
1328#endif
1329
1330#if 0
1331static void i915_yuv2rgb_pixel_shader_program_buffer(XvMCSurface *surface)
1332{
1333    struct i915_3dstate_pixel_shader_program *pixel_shader_program;
1334    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
1335    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
1336    unsigned int *inst;
1337    unsigned int dest, src0, src1;
1338
1339    /* Shader 0 */
1340    pixel_shader_program = (struct i915_3dstate_pixel_shader_program *)pI915XvMC->psp.map;
1341    memset(pixel_shader_program, 0, sizeof(*pixel_shader_program));
1342    pixel_shader_program->dw0.type = CMD_3D;
1343    pixel_shader_program->dw0.opcode = OPC_3DSTATE_PIXEL_SHADER_PROGRAM;
1344    pixel_shader_program->dw0.retain = 0;
1345    pixel_shader_program->dw0.length = 23;
1346    /* dcl      t0.xy */
1347    inst = (unsigned int*)(++pixel_shader_program);
1348    i915_inst_decl(inst, REG_TYPE_T, T_TEX0, D0_CHANNEL_XY);
1349    /* dcl         t1.xy */
1350    inst += 3;
1351    i915_inst_decl(inst, REG_TYPE_T, T_TEX1, D0_CHANNEL_XY);
1352    /* dcl_2D   s0 */
1353    inst += 3;
1354    i915_inst_decl(inst, REG_TYPE_S, 0, D0_SAMPLE_TYPE_2D);
1355    /* dcl_2D   s1 */
1356    inst += 3;
1357    i915_inst_decl(inst, REG_TYPE_S, 1, D0_SAMPLE_TYPE_2D);
1358    /* dcl_2D   s2 */
1359    inst += 3;
1360    i915_inst_decl(inst, REG_TYPE_S, 2, D0_SAMPLE_TYPE_2D);
1361    /* texld    r0 t1 s0 */
1362    inst += 3;
1363    dest = UREG(REG_TYPE_R, 0);
1364    src0 = UREG(REG_TYPE_T, 1); /* COORD */
1365    src1 = UREG(REG_TYPE_S, 0); /* SAMPLER */
1366    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
1367    /* texld    r0 t0 s1 */
1368    inst += 3;
1369    dest = UREG(REG_TYPE_R, 0);
1370    src0 = UREG(REG_TYPE_T, 0); /* COORD */
1371    src1 = UREG(REG_TYPE_S, 1); /* SAMPLER */
1372    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
1373    /* texld    oC t1 s2 */
1374    inst += 3;
1375    dest = UREG(REG_TYPE_OC, 0);
1376    src0 = UREG(REG_TYPE_T, 1); /* COORD */
1377    src1 = UREG(REG_TYPE_S, 2); /* SAMPLER */
1378    i915_inst_texld(inst, T0_TEXLD, dest, src0, src1);
1379}
1380#endif
1381
1382#if 0
1383static void i915_yuv2rgb_proc(XvMCSurface *surface)
1384{
1385    i915XvMCSurface *privSurface = (i915XvMCSurface *)surface->privData;
1386    i915XvMCContext *pI915XvMC = (i915XvMCContext *)privSurface->privContext;
1387    struct i915_3dstate_load_state_immediate_1 *load_state_immediate_1 = NULL;
1388    struct s2_dword *s2 = NULL;
1389    struct s3_dword *s3 = NULL;
1390    struct s4_dword *s4 = NULL;
1391    struct s5_dword *s5 = NULL;
1392    struct s6_dword *s6 = NULL;
1393    struct s7_dword *s7 = NULL;
1394    struct i915_3dstate_scissor_rectangle scissor_rectangle;
1395    struct i915_3dstate_load_indirect *load_indirect = NULL;
1396    sis_state *sis = NULL;
1397    ssb_state *ssb = NULL;
1398    msb_state *msb = NULL;
1399    psp_state *psp = NULL;
1400    struct i915_3dprimitive *_3dprimitive = NULL;
1401    struct vertex_data *vd = NULL;
1402    unsigned int size;
1403    void *base = NULL;
1404
1405    /* 3DSTATE_LOAD_STATE_IMMEDIATE_1 */
1406    size = sizeof(*load_state_immediate_1) + sizeof(*s2) + sizeof(*s3) +
1407        sizeof(*s4) + sizeof(*s5) + sizeof(*s6) + sizeof(*s7);
1408    base = calloc(1, size);
1409    load_state_immediate_1 = (struct i915_3dstate_load_state_immediate_1 *)base;
1410    load_state_immediate_1->dw0.type = CMD_3D;
1411    load_state_immediate_1->dw0.opcode = OPC_3DSTATE_LOAD_STATE_IMMEDIATE_1;
1412    load_state_immediate_1->dw0.load_s2 = 1;
1413    load_state_immediate_1->dw0.load_s3 = 1;
1414    load_state_immediate_1->dw0.load_s4 = 1;
1415    load_state_immediate_1->dw0.load_s5 = 1;
1416    load_state_immediate_1->dw0.load_s6 = 1;
1417    load_state_immediate_1->dw0.load_s7 = 1;
1418    load_state_immediate_1->dw0.length = 5;
1419
1420    s2 = (struct s2_dword *)(++load_state_immediate_1);
1421    s2->set0_texcoord_fmt = TEXCOORDFMT_2FP;
1422    s2->set1_texcoord_fmt = TEXCOORDFMT_2FP;
1423    s2->set2_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1424    s2->set3_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1425    s2->set4_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1426    s2->set5_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1427    s2->set6_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1428    s2->set7_texcoord_fmt = TEXCOORDFMT_NOT_PRESENT;
1429
1430    s3 = (struct s3_dword *)(++s2);
1431    s4 = (struct s4_dword *)(++s3);
1432    s4->position_mask = VERTEXHAS_XY;
1433    s4->cull_mode = CULLMODE_NONE;
1434    s4->color_shade_mode = SHADEMODE_FLAT;
1435    s4->specular_shade_mode = SHADEMODE_FLAT;
1436    s4->fog_shade_mode = SHADEMODE_FLAT;
1437    s4->alpha_shade_mode = SHADEMODE_FLAT;
1438    s4->line_width = 0x2;     /* FIXME: 1.0??? */
1439    s4->point_width = 0x1;
1440
1441    s5 = (struct s5_dword *)(++s4);
1442    s6 = (struct s6_dword *)(++s5);
1443    s6->src_blend_factor = 1;
1444    s6->dest_blend_factor = 1;
1445    s6->color_buffer_write = 1;
1446
1447    s7 = (struct s7_dword *)(++s6);
1448    intelBatchbufferData(base, size, 0);
1449    free(base);
1450
1451    /* 3DSTATE_3DSTATE_SCISSOR_RECTANGLE */
1452    scissor_rectangle.dw0.type = CMD_3D;
1453    scissor_rectangle.dw0.opcode = OPC_3DSTATE_SCISSOR_RECTANGLE;
1454    scissor_rectangle.dw0.length = 1;
1455    scissor_rectangle.dw1.min_x = 0;
1456    scissor_rectangle.dw1.min_y = 0;
1457    scissor_rectangle.dw2.max_x = 2047;
1458    scissor_rectangle.dw2.max_y = 2047;
1459    intelBatchbufferData(&scissor_rectangle, sizeof(scissor_rectangle), 0);
1460
1461    /* 3DSTATE_LOAD_INDIRECT */
1462    size = sizeof(*load_indirect) + sizeof(*sis) + sizeof(*ssb) + sizeof(*msb) + sizeof(*psp);
1463    base = calloc(1, size);
1464    load_indirect = (struct i915_3dstate_load_indirect *)base;
1465    load_indirect->dw0.type = CMD_3D;
1466    load_indirect->dw0.opcode = OPC_3DSTATE_LOAD_INDIRECT;
1467    load_indirect->dw0.mem_select = 1;  /* Bearlake only */
1468    load_indirect->dw0.block_mask = BLOCK_SIS | BLOCK_SSB | BLOCK_MSB | BLOCK_PSP;
1469    load_indirect->dw0.length = 7;
1470
1471    /* SIS */
1472    sis = (sis_state *)(++load_indirect);
1473    sis->dw0.valid = 1;
1474    sis->dw0.buffer_address = pI915XvMC->sis.offset;
1475    sis->dw1.length = ((sizeof(struct i915_3dstate_buffer_info) +
1476                        sizeof(struct i915_3dstate_dest_buffer_variables)) >> 2) - 1;
1477
1478    /* SSB */
1479    ssb = (ssb_state *)(++sis);
1480    ssb->dw0.valid = 1;
1481    ssb->dw0.buffer_address = pI915XvMC->ssb.offset;
1482    ssb->dw1.length = ((sizeof(struct i915_3dstate_sampler_state) +
1483                        sizeof(struct texture_sampler) * 3) >> 2) - 1;
1484
1485    /* MSB */
1486    msb = (msb_state *)(++ssb);
1487    msb->dw0.valid = 1;
1488    msb->dw0.buffer_address = pI915XvMC->msb.offset;
1489    msb->dw1.length = ((sizeof(struct i915_3dstate_map_state) +
1490                        sizeof(struct texture_map) * 3) >> 2) - 1;
1491
1492    /* PSP */
1493    psp = (psp_state *)(++msb);
1494    psp->dw0.valid = 1;
1495    psp->dw0.buffer_address = pI915XvMC->psp.offset;
1496    psp->dw1.length = ((sizeof(struct i915_3dstate_pixel_shader_program) +
1497                        sizeof(union shader_inst)) >> 2) - 1;
1498
1499    intelBatchbufferData(base, size, 0);
1500    free(base);
1501
1502    /* 3DPRIMITIVE */
1503    size = sizeof(*_3dprimitive) + sizeof(*vd) * 3;
1504    base = calloc(1, size);
1505    _3dprimitive = (struct i915_3dprimitive *)base;
1506    _3dprimitive->dw0.inline_prim.type = CMD_3D;
1507    _3dprimitive->dw0.inline_prim.opcode = OPC_3DPRIMITIVE;
1508    _3dprimitive->dw0.inline_prim.vertex_location = VERTEX_INLINE;
1509    _3dprimitive->dw0.inline_prim.prim = PRIM_RECTLIST;
1510    _3dprimitive->dw0.inline_prim.length = size - 2;
1511
1512    vd = (struct vertex_data *)(++_3dprimitive);
1513    vd->x = 0;          /* FIXME!!! */
1514    vd->x = 0;          /* FIXME */
1515    vd->tc0.tcx = 0;
1516    vd->tc0.tcy = 0;
1517    vd->tc1.tcx = 0;
1518    vd->tc1.tcy = 0;
1519
1520    ++vd;
1521    vd->x = 0;          /* FIXME!!! */
1522    vd->x = 0;          /* FIXME */
1523    vd->tc0.tcx = 0;
1524    vd->tc0.tcy = 0;
1525    vd->tc1.tcx = 0;
1526    vd->tc1.tcy = 0;
1527
1528    ++vd;
1529    vd->x = 0;          /* FIXME!!! */
1530    vd->x = 0;          /* FIXME */
1531    vd->tc0.tcx = 0;
1532    vd->tc0.tcy = 0;
1533    vd->tc1.tcx = 0;
1534    vd->tc1.tcy = 0;
1535
1536    intelBatchbufferData(base, size, 0);
1537    free(base);
1538}
1539#endif
1540
1541/*
1542 * Function: i915_release_resource
1543 */
1544static void i915_release_resource(Display *display, XvMCContext *context)
1545{
1546    i915XvMCContext *pI915XvMC;
1547
1548    if (!(pI915XvMC = context->privData))
1549        return;
1550
1551    pI915XvMC->ref--;
1552    i915_xvmc_unmap_buffers(pI915XvMC);
1553
1554    free(pI915XvMC);
1555    context->privData = NULL;
1556}
1557
1558static Status i915_xvmc_mc_create_context(Display *display, XvMCContext *context,
1559	int priv_count, CARD32 *priv_data)
1560{
1561    i915XvMCContext *pI915XvMC = NULL;
1562    I915XvMCCreateContextRec *tmpComm = NULL;
1563
1564    XVMC_DBG("%s\n", __FUNCTION__);
1565
1566    if (priv_count != (sizeof(I915XvMCCreateContextRec) >> 2)) {
1567        XVMC_ERR("_xvmc_create_context() returned incorrect data size!");
1568        XVMC_INFO("\tExpected %d, got %d",
1569               (int)(sizeof(I915XvMCCreateContextRec) >> 2),priv_count);
1570        _xvmc_destroy_context(display, context);
1571        XFree(priv_data);
1572        context->privData = NULL;
1573        return BadValue;
1574    }
1575
1576    context->privData = (void *)calloc(1, sizeof(i915XvMCContext));
1577    if (!context->privData) {
1578        XVMC_ERR("Unable to allocate resources for XvMC context.");
1579        return BadAlloc;
1580    }
1581    pI915XvMC = (i915XvMCContext *)context->privData;
1582
1583    tmpComm = (I915XvMCCreateContextRec *)priv_data;
1584    pI915XvMC->ctxno = tmpComm->ctxno;
1585    pI915XvMC->deviceID = tmpComm->deviceID;
1586    pI915XvMC->sis.handle = tmpComm->sis.handle;
1587    pI915XvMC->sis.offset = tmpComm->sis.offset;
1588    pI915XvMC->sis.size = tmpComm->sis.size;
1589    pI915XvMC->ssb.handle = tmpComm->ssb.handle;
1590    pI915XvMC->ssb.offset = tmpComm->ssb.offset;
1591    pI915XvMC->ssb.size = tmpComm->ssb.size;
1592    pI915XvMC->msb.handle = tmpComm->msb.handle;
1593    pI915XvMC->msb.offset = tmpComm->msb.offset;
1594    pI915XvMC->msb.size = tmpComm->msb.size;
1595    pI915XvMC->psp.handle = tmpComm->psp.handle;
1596    pI915XvMC->psp.offset = tmpComm->psp.offset;
1597    pI915XvMC->psp.size = tmpComm->psp.size;
1598    pI915XvMC->psc.handle = tmpComm->psc.handle;
1599    pI915XvMC->psc.offset = tmpComm->psc.offset;
1600    pI915XvMC->psc.size = tmpComm->psc.size;
1601
1602    if (pI915XvMC->deviceID == PCI_CHIP_I915_G ||
1603        pI915XvMC->deviceID == PCI_CHIP_I915_GM) {
1604        pI915XvMC->sis.bus_addr = tmpComm->sis.bus_addr;
1605        pI915XvMC->ssb.bus_addr = tmpComm->ssb.bus_addr;
1606        pI915XvMC->msb.bus_addr = tmpComm->msb.bus_addr;
1607        pI915XvMC->psp.bus_addr = tmpComm->psp.bus_addr;
1608        pI915XvMC->psc.bus_addr = tmpComm->psc.bus_addr;
1609    }
1610
1611    pI915XvMC->corrdata.handle = tmpComm->corrdata.handle;
1612    pI915XvMC->corrdata.offset = tmpComm->corrdata.offset;
1613    pI915XvMC->corrdata.size = tmpComm->corrdata.size;
1614
1615    /* Must free the private data we were passed from X */
1616    XFree(priv_data);
1617    priv_data = NULL;
1618
1619    if (i915_xvmc_map_buffers(pI915XvMC)) {
1620        i915_xvmc_unmap_buffers(pI915XvMC);
1621        free(pI915XvMC);
1622        context->privData = NULL;
1623        return BadAlloc;
1624    }
1625
1626    /* Initialize private context values */
1627    pI915XvMC->yStride = STRIDE(context->width);
1628    pI915XvMC->uvStride = STRIDE(context->width >> 1);
1629    pI915XvMC->haveXv = 0;
1630    pI915XvMC->dual_prime = 0;
1631    pI915XvMC->last_flip = 0;
1632    pI915XvMC->port = context->port;
1633    pI915XvMC->ref = 1;
1634
1635    /* pre-init state buffers */
1636    i915_mc_one_time_context_init(context);
1637    i915_mc_one_time_state_init(context);
1638
1639    i915_mc_static_indirect_state_init(context);
1640
1641    i915_mc_map_state_init(context);
1642
1643    i915_mc_load_indirect_render_init(context);
1644    return Success;
1645}
1646
1647static int i915_xvmc_mc_destroy_context(Display *display, XvMCContext *context)
1648{
1649    i915XvMCContext *pI915XvMC;
1650
1651    if (!(pI915XvMC = context->privData))
1652        return XvMCBadContext;
1653
1654    /* Pass Control to the X server to destroy the drm_context_t */
1655    i915_release_resource(display,context);
1656
1657    free(one_time_load_state_imm1);
1658    free(one_time_load_indirect);
1659    free(mc_render_load_indirect);
1660    return Success;
1661}
1662
1663static Status i915_xvmc_mc_create_surface(Display *display,
1664	XvMCContext *context, XvMCSurface *surface, int priv_count,
1665	CARD32 *priv_data)
1666{
1667    i915XvMCContext *pI915XvMC;
1668    i915XvMCSurface *pI915Surface;
1669    I915XvMCCreateSurfaceRec *tmpComm = NULL;
1670
1671    if (!(pI915XvMC = context->privData))
1672        return XvMCBadContext;
1673
1674    XVMC_DBG("%s\n", __FUNCTION__);
1675
1676    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
1677        XVMC_ERR("_xvmc_create_surface() returned incorrect data size!");
1678        XVMC_INFO("\tExpected %d, got %d",
1679               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
1680        _xvmc_destroy_surface(display, surface);
1681        XFree(priv_data);
1682        return BadAlloc;
1683    }
1684
1685    PPTHREAD_MUTEX_LOCK();
1686    surface->privData = (i915XvMCSurface *)malloc(sizeof(i915XvMCSurface));
1687
1688    if (!(pI915Surface = surface->privData)) {
1689        PPTHREAD_MUTEX_UNLOCK();
1690        return BadAlloc;
1691    }
1692
1693    /* Initialize private values */
1694    pI915Surface->last_render = 0;
1695    pI915Surface->last_flip = 0;
1696    pI915Surface->yStride = pI915XvMC->yStride;
1697    pI915Surface->uvStride = pI915XvMC->uvStride;
1698    pI915Surface->width = context->width;
1699    pI915Surface->height = context->height;
1700    pI915Surface->privContext = pI915XvMC;
1701    pI915Surface->privSubPic = NULL;
1702    pI915Surface->srf.map = NULL;
1703
1704    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
1705
1706    pI915Surface->srfNo = tmpComm->srfno;
1707    pI915Surface->srf.handle = tmpComm->srf.handle;
1708    pI915Surface->srf.offset = tmpComm->srf.offset;
1709    pI915Surface->srf.size = tmpComm->srf.size;
1710
1711    XFree(priv_data);
1712
1713    if (drmMap(xvmc_driver->fd,
1714               pI915Surface->srf.handle,
1715               pI915Surface->srf.size,
1716               (drmAddress *)&pI915Surface->srf.map) != 0) {
1717	XVMC_ERR("mapping surface memory failed!\n");
1718        _xvmc_destroy_surface(display, surface);
1719        free(pI915Surface);
1720        surface->privData = NULL;
1721        PPTHREAD_MUTEX_UNLOCK();
1722        return BadAlloc;
1723    }
1724
1725    pI915XvMC->ref++;
1726    PPTHREAD_MUTEX_UNLOCK();
1727    return 0;
1728}
1729
1730
1731static int i915_xvmc_mc_destroy_surface(Display *display, XvMCSurface *surface)
1732{
1733    i915XvMCSurface *pI915Surface;
1734    i915XvMCContext *pI915XvMC;
1735
1736    if (!display || !surface)
1737        return BadValue;
1738
1739    if (!(pI915Surface = surface->privData))
1740        return XvMCBadSurface;
1741
1742    if (!(pI915XvMC = pI915Surface->privContext))
1743        return XvMCBadSurface;
1744
1745    if (pI915Surface->last_flip)
1746        XvMCSyncSurface(display,surface);
1747
1748    if (pI915Surface->srf.map)
1749        drmUnmap(pI915Surface->srf.map, pI915Surface->srf.size);
1750
1751    free(pI915Surface);
1752    surface->privData = NULL;
1753    pI915XvMC->ref--;
1754
1755    return Success;
1756}
1757
1758
1759static int i915_xvmc_mc_render_surface(Display *display, XvMCContext *context,
1760                         unsigned int picture_structure,
1761                         XvMCSurface *target_surface,
1762                         XvMCSurface *past_surface,
1763                         XvMCSurface *future_surface,
1764                         unsigned int flags,
1765                         unsigned int num_macroblocks,
1766                         unsigned int first_macroblock,
1767                         XvMCMacroBlockArray *macroblock_array,
1768                         XvMCBlockArray *blocks)
1769{
1770    int i;
1771    int picture_coding_type = MPEG_I_PICTURE;
1772    /* correction data buffer */
1773    char *corrdata_ptr;
1774    int corrdata_size = 0;
1775
1776    /* Block Pointer */
1777    short *block_ptr;
1778    /* Current Macroblock Pointer */
1779    XvMCMacroBlock *mb;
1780
1781    intel_xvmc_context_ptr intel_ctx;
1782
1783    i915XvMCSurface *privTarget = NULL;
1784    i915XvMCSurface *privFuture = NULL;
1785    i915XvMCSurface *privPast = NULL;
1786    i915XvMCContext *pI915XvMC = NULL;
1787
1788    XVMC_DBG("%s\n", __FUNCTION__);
1789
1790    /* Check Parameters for validity */
1791    if (!display || !context || !target_surface) {
1792        XVMC_ERR("Invalid Display, Context or Target!");
1793        return BadValue;
1794    }
1795
1796    if (!num_macroblocks)
1797        return Success;
1798
1799    if (!macroblock_array || !blocks) {
1800        XVMC_ERR("Invalid block data!");
1801        return BadValue;
1802    }
1803
1804    if (macroblock_array->num_blocks < (num_macroblocks + first_macroblock)) {
1805        XVMC_ERR("Too many macroblocks requested for MB array size.");
1806        return BadValue;
1807    }
1808
1809    if (!(pI915XvMC = context->privData))
1810        return XvMCBadContext;
1811
1812    if (!(privTarget = target_surface->privData))
1813        return XvMCBadSurface;
1814
1815    if (context->surface_type_id >= SURFACE_TYPE_MAX) {
1816        XVMC_ERR("Unsupprted surface_type_id %d.", context->surface_type_id);
1817        return BadValue;
1818    }
1819
1820    intel_ctx = intel_xvmc_find_context(context->context_id);
1821    if (!intel_ctx) {
1822	XVMC_ERR("Can't find intel xvmc context\n");
1823	return BadValue;
1824    }
1825
1826    /* P Frame Test */
1827    if (!past_surface) {
1828        /* Just to avoid some ifs later. */
1829        privPast = privTarget;
1830    } else {
1831        if (!(privPast = past_surface->privData)) {
1832            XVMC_ERR("Invalid Past Surface!");
1833            return XvMCBadSurface;
1834        }
1835        picture_coding_type = MPEG_P_PICTURE;
1836    }
1837
1838    /* B Frame Test */
1839    if (!future_surface) {
1840        privFuture = privPast; // privTarget;
1841    } else {
1842        if (!past_surface) {
1843            XVMC_ERR("No Past Surface!");
1844            return BadValue;
1845        }
1846
1847        if (!(privFuture = future_surface->privData)) {
1848            XVMC_ERR("Invalid Future Surface!");
1849            return XvMCBadSurface;
1850        }
1851
1852        picture_coding_type = MPEG_B_PICTURE;
1853    }
1854
1855    LOCK_HARDWARE(intel_ctx->hw_context);
1856    corrdata_ptr = pI915XvMC->corrdata.map;
1857    corrdata_size = 0;
1858
1859    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
1860        int bspm = 0;
1861        mb = &macroblock_array->macro_blocks[i];
1862        block_ptr = &(blocks->blocks[mb->index << 6]);
1863
1864        /* Lockup can happen if the coordinates are too far out of range */
1865        if (mb->x > (target_surface->width >> 4)) {
1866            mb->x = 0;
1867            XVMC_INFO("reset x");
1868        }
1869
1870        if (mb->y > (target_surface->height >> 4)) {
1871            mb->y = 0;
1872            XVMC_INFO("reset y");
1873        }
1874
1875        /* Catch no pattern case */
1876        if (!(mb->macroblock_type & XVMC_MB_TYPE_PATTERN) &&
1877            !(mb->macroblock_type & XVMC_MB_TYPE_INTRA) &&
1878            mb->coded_block_pattern) {
1879            mb->coded_block_pattern = 0;
1880            XVMC_INFO("no coded blocks present!");
1881        }
1882
1883        bspm = mb_bytes_420[mb->coded_block_pattern];
1884
1885        if (!bspm)
1886            continue;
1887
1888        corrdata_size += bspm;
1889
1890        if (corrdata_size > pI915XvMC->corrdata.size) {
1891            XVMC_ERR("correction data buffer overflow.");
1892            break;
1893        }
1894        memcpy(corrdata_ptr, block_ptr, bspm);
1895        corrdata_ptr += bspm;
1896    }
1897
1898    i915_flush(1, 0);
1899    // i915_mc_invalidate_subcontext_buffers(context, BLOCK_SIS | BLOCK_DIS | BLOCK_SSB
1900    // | BLOCK_MSB | BLOCK_PSP | BLOCK_PSC);
1901
1902    i915_mc_one_time_state_emit();
1903
1904    i915_mc_static_indirect_state_set(context, target_surface, picture_structure,
1905	    flags, picture_coding_type);
1906    /* setup reference surfaces */
1907    i915_mc_map_state_set(context, privPast, privFuture);
1908
1909    i915_mc_load_indirect_render_emit();
1910
1911    i915_mc_mpeg_set_origin(context, &macroblock_array->macro_blocks[first_macroblock]);
1912
1913    for (i = first_macroblock; i < (num_macroblocks + first_macroblock); i++) {
1914        mb = &macroblock_array->macro_blocks[i];
1915
1916        /* Intra Blocks */
1917        if (mb->macroblock_type & XVMC_MB_TYPE_INTRA) {
1918            i915_mc_mpeg_macroblock_ipicture(context, mb);
1919        } else if ((picture_structure & XVMC_FRAME_PICTURE) == XVMC_FRAME_PICTURE) {
1920	    /* Frame Picture */
1921            switch (mb->motion_type & 3) {
1922            case XVMC_PREDICTION_FIELD: /* Field Based */
1923                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
1924                break;
1925
1926            case XVMC_PREDICTION_FRAME: /* Frame Based */
1927                i915_mc_mpeg_macroblock_1fbmv(context, mb);
1928                break;
1929
1930            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
1931                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
1932                break;
1933
1934            default:    /* No Motion Type */
1935		XVMC_ERR("Invalid Macroblock Parameters found.");
1936                break;
1937            }
1938        } else {        /* Field Picture */
1939            switch (mb->motion_type & 3) {
1940            case XVMC_PREDICTION_FIELD: /* Field Based */
1941                i915_mc_mpeg_macroblock_1fbmv(context, mb);
1942                break;
1943
1944            case XVMC_PREDICTION_16x8:  /* 16x8 MC */
1945                i915_mc_mpeg_macroblock_2fbmv(context, mb, picture_structure);
1946                break;
1947
1948            case XVMC_PREDICTION_DUAL_PRIME:    /* Dual Prime */
1949                i915_mc_mpeg_macroblock_1fbmv(context, mb);
1950                break;
1951
1952            default:    /* No Motion Type */
1953		XVMC_ERR("Invalid Macroblock Parameters found.");
1954                break;
1955            }
1956        }
1957    }
1958
1959    intelFlushBatch(TRUE);
1960    xvmc_driver->last_render = xvmc_driver->alloc.irq_emitted;
1961    privTarget->last_render = xvmc_driver->last_render;
1962
1963    UNLOCK_HARDWARE(intel_ctx->hw_context);
1964    return 0;
1965}
1966
1967static int i915_xvmc_mc_put_surface(Display *display,XvMCSurface *surface,
1968                      Drawable draw, short srcx, short srcy,
1969                      unsigned short srcw, unsigned short srch,
1970                      short destx, short desty,
1971                      unsigned short destw, unsigned short desth,
1972                      int flags, struct intel_xvmc_command *data)
1973{
1974    i915XvMCContext *pI915XvMC;
1975    i915XvMCSurface *pI915Surface;
1976    i915XvMCSubpicture *pI915SubPic;
1977
1978    if (!(pI915Surface = surface->privData))
1979        return XvMCBadSurface;
1980
1981    if (!(pI915XvMC = pI915Surface->privContext))
1982        return XvMCBadSurface;
1983
1984    PPTHREAD_MUTEX_LOCK();
1985
1986    data->command = INTEL_XVMC_COMMAND_DISPLAY;
1987    data->ctxNo = pI915XvMC->ctxno;
1988    data->srfNo = pI915Surface->srfNo;
1989    pI915SubPic = pI915Surface->privSubPic;
1990    data->subPicNo = (!pI915SubPic ? 0 : pI915SubPic->srfNo);
1991    data->real_id = FOURCC_YV12;
1992    data->flags = flags;
1993
1994    PPTHREAD_MUTEX_UNLOCK();
1995
1996    return 0;
1997}
1998
1999static int i915_xvmc_mc_get_surface_status(Display *display,
2000	XvMCSurface *surface, int *stat)
2001{
2002    i915XvMCSurface *pI915Surface;
2003    i915XvMCContext *pI915XvMC;
2004
2005    if (!display || !surface || !stat)
2006        return BadValue;
2007
2008    *stat = 0;
2009
2010    if (!(pI915Surface = surface->privData))
2011        return XvMCBadSurface;
2012
2013    if (!(pI915XvMC = pI915Surface->privContext))
2014        return XvMCBadSurface;
2015
2016    PPTHREAD_MUTEX_LOCK();
2017    if (pI915Surface->last_flip) {
2018        /* This can not happen */
2019        if (pI915XvMC->last_flip < pI915Surface->last_flip) {
2020            XVMC_ERR("Context last flip is less than surface last flip.");
2021            PPTHREAD_MUTEX_UNLOCK();
2022            return BadValue;
2023        }
2024
2025        /*
2026          If the context has 2 or more flips after this surface it
2027          cannot be displaying. Don't bother to check.
2028        */
2029        if (!(pI915XvMC->last_flip > (pI915Surface->last_flip + 1))) {
2030            /*
2031              If this surface was the last flipped it is either displaying
2032              or about to be so don't bother checking.
2033            */
2034            if (pI915XvMC->last_flip == pI915Surface->last_flip) {
2035                *stat |= XVMC_DISPLAYING;
2036            }
2037        }
2038    }
2039
2040    PPTHREAD_MUTEX_UNLOCK();
2041    return 0;
2042}
2043
2044/* XXX WIP code */
2045#if 0
2046Status XvMCHideSurface(Display *display, XvMCSurface *surface)
2047{
2048    i915XvMCSurface *pI915Surface;
2049    i915XvMCContext *pI915XvMC;
2050    int stat = 0, ret;
2051
2052    if (!display || !surface)
2053        return BadValue;
2054
2055    if (!(pI915Surface = surface->privData))
2056        return XvMCBadSurface;
2057
2058    /* Get the associated context pointer */
2059    if (!(pI915XvMC = pI915Surface->privContext))
2060        return XvMCBadSurface;
2061
2062    XvMCSyncSurface(display, surface);
2063
2064    /*
2065      Get the status of the surface, if it is not currently displayed
2066      we don't need to worry about it.
2067    */
2068    if ((ret = XvMCGetSurfaceStatus(display, surface, &stat)) != Success)
2069        return ret;
2070
2071    if (!(stat & XVMC_DISPLAYING))
2072        return Success;
2073
2074    /* FIXME: */
2075    return Success;
2076}
2077
2078Status i915_xvmc_create_subpict(Display *display, XvMCContext *context,
2079                            XvMCSubpicture *subpicture,
2080                            unsigned short width, unsigned short height,
2081                            int xvimage_id)
2082{
2083    Status ret;
2084    i915XvMCContext *pI915XvMC;
2085    i915XvMCSubpicture *pI915Subpicture;
2086    I915XvMCCreateSurfaceRec *tmpComm = NULL;
2087    int priv_count;
2088    uint *priv_data;
2089
2090    if (!subpicture || !context || !display)
2091        return BadValue;
2092
2093    pI915XvMC = (i915XvMCContext *)context->privData;
2094
2095    if (!pI915XvMC)
2096        return XvMCBadContext;
2097
2098    subpicture->privData =
2099        (i915XvMCSubpicture *)malloc(sizeof(i915XvMCSubpicture));
2100
2101    if (!subpicture->privData)
2102        return BadAlloc;
2103
2104    PPTHREAD_MUTEX_LOCK();
2105    subpicture->context_id = context->context_id;
2106    subpicture->xvimage_id = xvimage_id;
2107    subpicture->width = width;
2108    subpicture->height = height;
2109    pI915Subpicture = (i915XvMCSubpicture *)subpicture->privData;
2110
2111    XLockDisplay(display);
2112    if ((ret = _xvmc_create_subpicture(display, context, subpicture,
2113                                       &priv_count, &priv_data))) {
2114        XUnlockDisplay(display);
2115        XVMC_ERR("Unable to create XvMCSubpicture.");
2116        free(pI915Subpicture);
2117        subpicture->privData = NULL;
2118        PPTHREAD_MUTEX_UNLOCK();
2119        return ret;
2120    }
2121    XUnlockDisplay(display);
2122
2123    if (priv_count != (sizeof(I915XvMCCreateSurfaceRec) >> 2)) {
2124        XVMC_ERR("_xvmc_create_subpicture() returned incorrect data size!");
2125        XVMC_INFO("\tExpected %d, got %d",
2126               (int)(sizeof(I915XvMCCreateSurfaceRec) >> 2), priv_count);
2127        XLockDisplay(display);
2128        _xvmc_destroy_subpicture(display, subpicture);
2129        XUnlockDisplay(display);
2130        XFree(priv_data);
2131        free(pI915Subpicture);
2132        subpicture->privData = NULL;
2133        PPTHREAD_MUTEX_UNLOCK();
2134        return BadAlloc;
2135    }
2136
2137    tmpComm = (I915XvMCCreateSurfaceRec *)priv_data;
2138    pI915Subpicture->srfNo = tmpComm->srfno;
2139    pI915Subpicture->srf.handle = tmpComm->srf.handle;
2140    pI915Subpicture->srf.offset = tmpComm->srf.offset;
2141    pI915Subpicture->srf.size = tmpComm->srf.size;
2142    XFree(priv_data);
2143
2144    if (drmMap(pI915XvMC->fd,
2145               pI915Subpicture->srf.handle,
2146               pI915Subpicture->srf.size,
2147               (drmAddress *)&pI915Subpicture->srf.map) != 0) {
2148        XLockDisplay(display);
2149        _xvmc_destroy_subpicture(display, subpicture);
2150        XUnlockDisplay(display);
2151        free(pI915Subpicture);
2152        subpicture->privData = NULL;
2153        PPTHREAD_MUTEX_UNLOCK();
2154        return BadAlloc;
2155    }
2156
2157    /* subpicture */
2158    subpicture->num_palette_entries = I915_SUBPIC_PALETTE_SIZE;
2159    subpicture->entry_bytes = 3;
2160    strncpy(subpicture->component_order, "YUV", 4);
2161
2162    /* Initialize private values */
2163    pI915Subpicture->privContext = pI915XvMC;
2164    pI915Subpicture->last_render= 0;
2165    pI915Subpicture->last_flip = 0;
2166    pI915Subpicture->pitch = ((subpicture->width + 3) & ~3);
2167
2168    switch(subpicture->xvimage_id) {
2169    case FOURCC_IA44:
2170    case FOURCC_AI44:
2171        break;
2172
2173    default:
2174        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
2175        XLockDisplay(display);
2176        _xvmc_destroy_subpicture(display, subpicture);
2177        XUnlockDisplay(display);
2178        free(pI915Subpicture);
2179        subpicture->privData = NULL;
2180        PPTHREAD_MUTEX_UNLOCK();
2181        return BadMatch;
2182    }
2183
2184    pI915XvMC->ref++;
2185    PPTHREAD_MUTEX_UNLOCK();
2186    return Success;
2187}
2188
2189Status i915_xvmc_clear_subpict(Display *display, XvMCSubpicture *subpicture,
2190                           short x, short y,
2191                           unsigned short width, unsigned short height,
2192                           unsigned int color)
2193{
2194    i915XvMCContext *pI915XvMC;
2195    i915XvMCSubpicture *pI915Subpicture;
2196
2197    if (!display || !subpicture)
2198        return BadValue;
2199
2200    if (!(pI915Subpicture = subpicture->privData))
2201        return XvMCBadSubpicture;
2202
2203    if (!(pI915XvMC = pI915Subpicture->privContext))
2204        return XvMCBadSubpicture;
2205
2206    if ((x < 0) || (x + width) > subpicture->width)
2207        return BadValue;
2208
2209    if ((y < 0) || (y + height) > subpicture->height)
2210        return BadValue;
2211
2212    /* FIXME: clear the area */
2213
2214    return Success;
2215}
2216
2217Status i915_xvmc_composite_subpict(Display *display, XvMCSubpicture *subpicture,
2218                               XvImage *image,
2219                               short srcx, short srcy,
2220                               unsigned short width, unsigned short height,
2221                               short dstx, short dsty)
2222{
2223    i915XvMCContext *pI915XvMC;
2224    i915XvMCSubpicture *pI915Subpicture;
2225
2226    if (!display || !subpicture)
2227        return BadValue;
2228
2229    if (!(pI915Subpicture = subpicture->privData))
2230        return XvMCBadSubpicture;
2231
2232    if (!(pI915XvMC = pI915Subpicture->privContext))
2233        return XvMCBadSubpicture;
2234
2235    if ((srcx < 0) || (srcx + width) > subpicture->width)
2236        return BadValue;
2237
2238    if ((srcy < 0) || (srcy + height) > subpicture->height)
2239        return BadValue;
2240
2241    if ((dstx < 0) || (dstx + width) > subpicture->width)
2242        return BadValue;
2243
2244    if ((dsty < 0) || (dsty + width) > subpicture->height)
2245        return BadValue;
2246
2247    if (image->id != subpicture->xvimage_id)
2248        return BadMatch;
2249
2250    /* FIXME */
2251    return Success;
2252}
2253
2254
2255Status i915_xvmc_destroy_subpict(Display *display, XvMCSubpicture *subpicture)
2256{
2257    i915XvMCSubpicture *pI915Subpicture;
2258    i915XvMCContext *pI915XvMC;
2259
2260    if (!display || !subpicture)
2261        return BadValue;
2262
2263    if (!(pI915Subpicture = subpicture->privData))
2264        return XvMCBadSubpicture;
2265
2266    if (!(pI915XvMC = pI915Subpicture->privContext))
2267        return XvMCBadSubpicture;
2268
2269    if (pI915Subpicture->last_render)
2270        XvMCSyncSubpicture(display, subpicture);
2271
2272    if (pI915Subpicture->srf.map)
2273        drmUnmap(pI915Subpicture->srf.map, pI915Subpicture->srf.size);
2274
2275    PPTHREAD_MUTEX_LOCK();
2276    XLockDisplay(display);
2277    _xvmc_destroy_subpicture(display,subpicture);
2278    XUnlockDisplay(display);
2279
2280    free(pI915Subpicture);
2281    subpicture->privData = NULL;
2282    pI915XvMC->ref--;
2283    PPTHREAD_MUTEX_UNLOCK();
2284
2285    return Success;
2286}
2287
2288
2289Status i915_xvmc_set_subpict_palette(Display *display,
2290	XvMCSubpicture *subpicture,
2291	unsigned char *palette)
2292{
2293    i915XvMCSubpicture *pI915Subpicture;
2294    int i, j;
2295
2296    if (!display || !subpicture)
2297        return BadValue;
2298
2299    if (!(pI915Subpicture = subpicture->privData))
2300        return XvMCBadSubpicture;
2301
2302    j = 0;
2303    for (i = 0; i < 16; i++) {
2304        pI915Subpicture->palette[0][i] = palette[j++];
2305        pI915Subpicture->palette[1][i] = palette[j++];
2306        pI915Subpicture->palette[2][i] = palette[j++];
2307    }
2308
2309    /* FIXME: Update the subpicture with the new palette */
2310    return Success;
2311}
2312
2313Status i915_xvmc_blend_subpict(Display *display, XvMCSurface *target_surface,
2314                           XvMCSubpicture *subpicture,
2315                           short subx, short suby,
2316                           unsigned short subw, unsigned short subh,
2317                           short surfx, short surfy,
2318                           unsigned short surfw, unsigned short surfh)
2319{
2320    i915XvMCSubpicture *pI915Subpicture;
2321    i915XvMCSurface *privTargetSurface;
2322
2323    if (!display || !target_surface)
2324        return BadValue;
2325
2326    if (!(privTargetSurface = target_surface->privData))
2327        return XvMCBadSurface;
2328
2329    if (subpicture) {
2330        if (!(pI915Subpicture = subpicture->privData))
2331            return XvMCBadSubpicture;
2332
2333        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
2334            (FOURCC_IA44 != subpicture->xvimage_id))
2335            return XvMCBadSubpicture;
2336
2337        privTargetSurface->privSubPic = pI915Subpicture;
2338    } else {
2339        privTargetSurface->privSubPic = NULL;
2340    }
2341
2342    return Success;
2343}
2344
2345Status i915_xvmc_blend_subpict2(Display *display,
2346                            XvMCSurface *source_surface,
2347                            XvMCSurface *target_surface,
2348                            XvMCSubpicture *subpicture,
2349                            short subx, short suby,
2350                            unsigned short subw, unsigned short subh,
2351                            short surfx, short surfy,
2352                            unsigned short surfw, unsigned short surfh)
2353{
2354    i915XvMCContext *pI915XvMC;
2355    i915XvMCSubpicture *pI915Subpicture;
2356    i915XvMCSurface *privSourceSurface;
2357    i915XvMCSurface *privTargetSurface;
2358
2359    if (!display || !source_surface || !target_surface)
2360        return BadValue;
2361
2362    if (!(privSourceSurface = source_surface->privData))
2363        return XvMCBadSurface;
2364
2365    if (!(privTargetSurface = target_surface->privData))
2366        return XvMCBadSurface;
2367
2368    if (!(pI915XvMC = privTargetSurface->privContext))
2369        return XvMCBadSurface;
2370
2371    if (((surfx + surfw) > privTargetSurface->width) ||
2372        ((surfy + surfh) > privTargetSurface->height))
2373        return BadValue;
2374
2375    if ((privSourceSurface->width != privTargetSurface->width) ||
2376        (privTargetSurface->height != privTargetSurface->height))
2377        return BadValue;
2378
2379    if (XvMCSyncSurface(display, source_surface))
2380        return BadValue;
2381
2382    /* FIXME: update Target Surface */
2383
2384    if (subpicture) {
2385        if (((subx + subw) > subpicture->width) ||
2386            ((suby + subh) > subpicture->height))
2387            return BadValue;
2388
2389        if (!(pI915Subpicture = subpicture->privData))
2390            return XvMCBadSubpicture;
2391
2392        if ((FOURCC_AI44 != subpicture->xvimage_id) &&
2393            (FOURCC_IA44 != subpicture->xvimage_id))
2394            return XvMCBadSubpicture;
2395
2396        privTargetSurface->privSubPic = pI915Subpicture;
2397    } else {
2398        privTargetSurface->privSubPic = NULL;
2399    }
2400
2401    return Success;
2402}
2403
2404Status i915_xvmc_sync_subpict(Display *display, XvMCSubpicture *subpicture)
2405{
2406    Status ret;
2407    int stat = 0;
2408
2409    if (!display || !subpicture)
2410        return BadValue;
2411
2412    do {
2413        ret = XvMCGetSubpictureStatus(display, subpicture, &stat);
2414    } while(!ret && (stat & XVMC_RENDERING));
2415
2416    return ret;
2417}
2418
2419Status i915_xvmc_flush_subpict(Display *display, XvMCSubpicture *subpicture)
2420{
2421    i915XvMCSubpicture *pI915Subpicture;
2422
2423    if (!display || !subpicture)
2424        return BadValue;
2425
2426    if (!(pI915Subpicture = subpicture->privData))
2427        return XvMCBadSubpicture;
2428
2429    return Success;
2430}
2431
2432Status i915_xvmc_get_subpict_status(Display *display, XvMCSubpicture *subpicture,
2433                               int *stat)
2434{
2435    i915XvMCSubpicture *pI915Subpicture;
2436    i915XvMCContext *pI915XvMC;
2437
2438    if (!display || !subpicture || stat)
2439        return BadValue;
2440
2441    *stat = 0;
2442
2443    if (!(pI915Subpicture = subpicture->privData))
2444        return XvMCBadSubpicture;
2445
2446    if (!(pI915XvMC = pI915Subpicture->privContext))
2447        return XvMCBadSubpicture;
2448
2449    PPTHREAD_MUTEX_LOCK();
2450
2451    PPTHREAD_MUTEX_UNLOCK();
2452    return Success;
2453}
2454
2455#endif
2456
2457struct _intel_xvmc_driver i915_xvmc_mc_driver = {
2458    .type		= XVMC_I915_MPEG2_MC,
2459    .num_ctx		= 0,
2460    .ctx_list		= NULL,
2461    .create_context	= i915_xvmc_mc_create_context,
2462    .destroy_context	= i915_xvmc_mc_destroy_context,
2463    .create_surface	= i915_xvmc_mc_create_surface,
2464    .destroy_surface	= i915_xvmc_mc_destroy_surface,
2465    .render_surface	= i915_xvmc_mc_render_surface,
2466    .put_surface	= i915_xvmc_mc_put_surface,
2467    .get_surface_status	= i915_xvmc_mc_get_surface_status,
2468};
2469