MEDIA_OBJECT uses hardware scoreboard during VME prediction on Haswell
[profile/ivi/vaapi-intel-driver.git] / src / i965_gpe_utils.c
1 /*
2  * Copyright © 2012 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
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Xiang Haihao <haihao.xiang@intel.com>
25  */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <assert.h>
31
32 #include "intel_batchbuffer.h"
33 #include "intel_driver.h"
34
35 #include "i965_gpe_utils.h"
36
37 static void
38 i965_gpe_select(VADriverContextP ctx,
39                 struct i965_gpe_context *gpe_context,
40                 struct intel_batchbuffer *batch)
41 {
42     BEGIN_BATCH(batch, 1);
43     OUT_BATCH(batch, CMD_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA);
44     ADVANCE_BATCH(batch);
45 }
46
47 static void
48 gen6_gpe_state_base_address(VADriverContextP ctx,
49                             struct i965_gpe_context *gpe_context,
50                             struct intel_batchbuffer *batch)
51 {
52     BEGIN_BATCH(batch, 10);
53
54     OUT_BATCH(batch, CMD_STATE_BASE_ADDRESS | (10 - 2));
55     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* General State Base Address */
56     OUT_RELOC(batch,
57               gpe_context->surface_state_binding_table.bo,
58               I915_GEM_DOMAIN_INSTRUCTION,
59               0,
60               BASE_ADDRESS_MODIFY);                     /* Surface state base address */
61     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Dynamic State Base Address */
62     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Indirect Object Base Address */
63     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Instruction Base Address */
64     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* General State Access Upper Bound */
65     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Dynamic State Access Upper Bound */
66     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Indirect Object Access Upper Bound */
67     OUT_BATCH(batch, BASE_ADDRESS_MODIFY);              /* Instruction Access Upper Bound */
68
69     ADVANCE_BATCH(batch);
70 }
71
72 static void
73 gen6_gpe_vfe_state(VADriverContextP ctx,
74                    struct i965_gpe_context *gpe_context,
75                    struct intel_batchbuffer *batch)
76 {
77
78     BEGIN_BATCH(batch, 8);
79
80     OUT_BATCH(batch, CMD_MEDIA_VFE_STATE | (8 - 2));
81     OUT_BATCH(batch, 0);                                        /* Scratch Space Base Pointer and Space */
82     OUT_BATCH(batch,
83               gpe_context->vfe_state.max_num_threads << 16 |    /* Maximum Number of Threads */
84               gpe_context->vfe_state.num_urb_entries << 8 |     /* Number of URB Entries */
85               gpe_context->vfe_state.gpgpu_mode << 2);          /* MEDIA Mode */
86     OUT_BATCH(batch, 0);                                        /* Debug: Object ID */
87     OUT_BATCH(batch,
88               gpe_context->vfe_state.urb_entry_size << 16 |     /* URB Entry Allocation Size */
89               gpe_context->vfe_state.curbe_allocation_size);    /* CURBE Allocation Size */
90     /* the vfe_desc5/6/7 will decide whether the scoreboard is used. */
91     OUT_BATCH(batch, gpe_context->vfe_desc5.dword);                                        
92     OUT_BATCH(batch, gpe_context->vfe_desc6.dword);                                       
93     OUT_BATCH(batch, gpe_context->vfe_desc7.dword);                                       
94         
95     ADVANCE_BATCH(batch);
96
97 }
98
99 static void
100 gen6_gpe_curbe_load(VADriverContextP ctx,
101                     struct i965_gpe_context *gpe_context,
102                     struct intel_batchbuffer *batch)
103 {
104     BEGIN_BATCH(batch, 4);
105
106     OUT_BATCH(batch, CMD_MEDIA_CURBE_LOAD | (4 - 2));
107     OUT_BATCH(batch, 0);
108     OUT_BATCH(batch, gpe_context->curbe.length);
109     OUT_RELOC(batch, gpe_context->curbe.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
110
111     ADVANCE_BATCH(batch);
112 }
113
114 static void
115 gen6_gpe_idrt(VADriverContextP ctx,
116               struct i965_gpe_context *gpe_context,
117               struct intel_batchbuffer *batch)
118 {
119     BEGIN_BATCH(batch, 4);
120
121     OUT_BATCH(batch, CMD_MEDIA_INTERFACE_LOAD | (4 - 2));
122     OUT_BATCH(batch, 0);
123     OUT_BATCH(batch, gpe_context->idrt.max_entries * gpe_context->idrt.entry_size);
124     OUT_RELOC(batch, gpe_context->idrt.bo, I915_GEM_DOMAIN_INSTRUCTION, 0, 0);
125
126     ADVANCE_BATCH(batch);
127 }
128
129 void
130 i965_gpe_load_kernels(VADriverContextP ctx,
131                       struct i965_gpe_context *gpe_context,
132                       struct i965_kernel *kernel_list,
133                       unsigned int num_kernels)
134 {
135     struct i965_driver_data *i965 = i965_driver_data(ctx);
136     int i;
137
138     assert(num_kernels <= MAX_GPE_KERNELS);
139     memcpy(gpe_context->kernels, kernel_list, sizeof(*kernel_list) * num_kernels);
140     gpe_context->num_kernels = num_kernels;
141
142     for (i = 0; i < num_kernels; i++) {
143         struct i965_kernel *kernel = &gpe_context->kernels[i];
144
145         kernel->bo = dri_bo_alloc(i965->intel.bufmgr, 
146                                   kernel->name, 
147                                   kernel->size,
148                                   0x1000);
149         assert(kernel->bo);
150         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
151     }
152 }
153
154 void
155 i965_gpe_context_destroy(struct i965_gpe_context *gpe_context)
156 {
157     int i;
158
159     dri_bo_unreference(gpe_context->surface_state_binding_table.bo);
160     gpe_context->surface_state_binding_table.bo = NULL;
161
162     dri_bo_unreference(gpe_context->idrt.bo);
163     gpe_context->idrt.bo = NULL;
164
165     dri_bo_unreference(gpe_context->curbe.bo);
166     gpe_context->curbe.bo = NULL;
167
168     for (i = 0; i < gpe_context->num_kernels; i++) {
169         struct i965_kernel *kernel = &gpe_context->kernels[i];
170
171         dri_bo_unreference(kernel->bo);
172         kernel->bo = NULL;
173     }
174 }
175
176 void
177 i965_gpe_context_init(VADriverContextP ctx,
178                       struct i965_gpe_context *gpe_context)
179 {
180     struct i965_driver_data *i965 = i965_driver_data(ctx);
181     dri_bo *bo;
182
183     dri_bo_unreference(gpe_context->surface_state_binding_table.bo);
184     bo = dri_bo_alloc(i965->intel.bufmgr,
185                       "surface state & binding table",
186                       gpe_context->surface_state_binding_table.length,
187                       4096);
188     assert(bo);
189     gpe_context->surface_state_binding_table.bo = bo;
190
191     dri_bo_unreference(gpe_context->idrt.bo);
192     bo = dri_bo_alloc(i965->intel.bufmgr,
193                       "interface descriptor table",
194                       gpe_context->idrt.entry_size * gpe_context->idrt.max_entries,
195                       4096);
196     assert(bo);
197     gpe_context->idrt.bo = bo;
198
199     dri_bo_unreference(gpe_context->curbe.bo);
200     bo = dri_bo_alloc(i965->intel.bufmgr,
201                       "curbe buffer",
202                       gpe_context->curbe.length,
203                       4096);
204     assert(bo);
205     gpe_context->curbe.bo = bo;
206 }
207
208 void
209 gen6_gpe_pipeline_setup(VADriverContextP ctx,
210                         struct i965_gpe_context *gpe_context,
211                         struct intel_batchbuffer *batch)
212 {
213     intel_batchbuffer_emit_mi_flush(batch);
214
215     i965_gpe_select(ctx, gpe_context, batch);
216     gen6_gpe_state_base_address(ctx, gpe_context, batch);
217     gen6_gpe_vfe_state(ctx, gpe_context, batch);
218     gen6_gpe_curbe_load(ctx, gpe_context, batch);
219     gen6_gpe_idrt(ctx, gpe_context, batch);
220 }
221
222 static void
223 i965_gpe_set_surface_tiling(struct i965_surface_state *ss, unsigned int tiling)
224 {
225     switch (tiling) {
226     case I915_TILING_NONE:
227         ss->ss3.tiled_surface = 0;
228         ss->ss3.tile_walk = 0;
229         break;
230     case I915_TILING_X:
231         ss->ss3.tiled_surface = 1;
232         ss->ss3.tile_walk = I965_TILEWALK_XMAJOR;
233         break;
234     case I915_TILING_Y:
235         ss->ss3.tiled_surface = 1;
236         ss->ss3.tile_walk = I965_TILEWALK_YMAJOR;
237         break;
238     }
239 }
240
241 static void
242 i965_gpe_set_surface2_tiling(struct i965_surface_state2 *ss, unsigned int tiling)
243 {
244     switch (tiling) {
245     case I915_TILING_NONE:
246         ss->ss2.tiled_surface = 0;
247         ss->ss2.tile_walk = 0;
248         break;
249     case I915_TILING_X:
250         ss->ss2.tiled_surface = 1;
251         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
252         break;
253     case I915_TILING_Y:
254         ss->ss2.tiled_surface = 1;
255         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
256         break;
257     }
258 }
259
260 static void
261 gen7_gpe_set_surface_tiling(struct gen7_surface_state *ss, unsigned int tiling)
262 {
263     switch (tiling) {
264     case I915_TILING_NONE:
265         ss->ss0.tiled_surface = 0;
266         ss->ss0.tile_walk = 0;
267         break;
268     case I915_TILING_X:
269         ss->ss0.tiled_surface = 1;
270         ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
271         break;
272     case I915_TILING_Y:
273         ss->ss0.tiled_surface = 1;
274         ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
275         break;
276     }
277 }
278
279 static void
280 gen7_gpe_set_surface2_tiling(struct gen7_surface_state2 *ss, unsigned int tiling)
281 {
282     switch (tiling) {
283     case I915_TILING_NONE:
284         ss->ss2.tiled_surface = 0;
285         ss->ss2.tile_walk = 0;
286         break;
287     case I915_TILING_X:
288         ss->ss2.tiled_surface = 1;
289         ss->ss2.tile_walk = I965_TILEWALK_XMAJOR;
290         break;
291     case I915_TILING_Y:
292         ss->ss2.tiled_surface = 1;
293         ss->ss2.tile_walk = I965_TILEWALK_YMAJOR;
294         break;
295     }
296 }
297
298 static void
299 i965_gpe_set_surface2_state(VADriverContextP ctx,
300                             struct object_surface *obj_surface,
301                             struct i965_surface_state2 *ss)
302 {
303     int w, h, w_pitch;
304     unsigned int tiling, swizzle;
305
306     assert(obj_surface->bo);
307     assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
308
309     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
310     w = obj_surface->orig_width;
311     h = obj_surface->orig_height;
312     w_pitch = obj_surface->width;
313
314     memset(ss, 0, sizeof(*ss));
315     /* ss0 */
316     ss->ss0.surface_base_address = obj_surface->bo->offset;
317     /* ss1 */
318     ss->ss1.cbcr_pixel_offset_v_direction = 2;
319     ss->ss1.width = w - 1;
320     ss->ss1.height = h - 1;
321     /* ss2 */
322     ss->ss2.surface_format = MFX_SURFACE_PLANAR_420_8;
323     ss->ss2.interleave_chroma = 1;
324     ss->ss2.pitch = w_pitch - 1;
325     ss->ss2.half_pitch_for_chroma = 0;
326     i965_gpe_set_surface2_tiling(ss, tiling);
327     /* ss3: UV offset for interleave mode */
328     ss->ss3.x_offset_for_cb = obj_surface->x_cb_offset;
329     ss->ss3.y_offset_for_cb = obj_surface->y_cb_offset;
330 }
331
332 void
333 i965_gpe_surface2_setup(VADriverContextP ctx,
334                         struct i965_gpe_context *gpe_context,
335                         struct object_surface *obj_surface,
336                         unsigned long binding_table_offset,
337                         unsigned long surface_state_offset)
338 {
339     struct i965_surface_state2 *ss;
340     dri_bo *bo;
341
342     bo = gpe_context->surface_state_binding_table.bo;
343     dri_bo_map(bo, 1);
344     assert(bo->virtual);
345
346     ss = (struct i965_surface_state2 *)((char *)bo->virtual + surface_state_offset);
347     i965_gpe_set_surface2_state(ctx, obj_surface, ss);
348     dri_bo_emit_reloc(bo,
349                       I915_GEM_DOMAIN_RENDER, 0,
350                       0,
351                       surface_state_offset + offsetof(struct i965_surface_state2, ss0),
352                       obj_surface->bo);
353
354     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
355     dri_bo_unmap(bo);
356 }
357
358 static void
359 i965_gpe_set_media_rw_surface_state(VADriverContextP ctx,
360                                     struct object_surface *obj_surface,
361                                     struct i965_surface_state *ss)
362 {
363     int w, h, w_pitch;
364     unsigned int tiling, swizzle;
365
366     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
367     w = obj_surface->orig_width;
368     h = obj_surface->orig_height;
369     w_pitch = obj_surface->width;
370
371     memset(ss, 0, sizeof(*ss));
372     /* ss0 */
373     ss->ss0.surface_type = I965_SURFACE_2D;
374     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
375     /* ss1 */
376     ss->ss1.base_addr = obj_surface->bo->offset;
377     /* ss2 */
378     ss->ss2.width = w / 4 - 1;  /* in DWORDs for media read & write message */
379     ss->ss2.height = h - 1;
380     /* ss3 */
381     ss->ss3.pitch = w_pitch - 1;
382     i965_gpe_set_surface_tiling(ss, tiling);
383 }
384
385 void
386 i965_gpe_media_rw_surface_setup(VADriverContextP ctx,
387                                 struct i965_gpe_context *gpe_context,
388                                 struct object_surface *obj_surface,
389                                 unsigned long binding_table_offset,
390                                 unsigned long surface_state_offset)
391 {
392     struct i965_surface_state *ss;
393     dri_bo *bo;
394
395     bo = gpe_context->surface_state_binding_table.bo;
396     dri_bo_map(bo, True);
397     assert(bo->virtual);
398
399     ss = (struct i965_surface_state *)((char *)bo->virtual + surface_state_offset);
400     i965_gpe_set_media_rw_surface_state(ctx, obj_surface, ss);
401     dri_bo_emit_reloc(bo,
402                       I915_GEM_DOMAIN_RENDER, 0,
403                       0,
404                       surface_state_offset + offsetof(struct i965_surface_state, ss1),
405                       obj_surface->bo);
406
407     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
408     dri_bo_unmap(bo);
409 }
410
411 static void
412 i965_gpe_set_buffer_surface_state(VADriverContextP ctx,
413                                   struct i965_buffer_surface *buffer_surface,
414                                   struct i965_surface_state *ss)
415 {
416     int num_entries;
417
418     assert(buffer_surface->bo);
419     num_entries = buffer_surface->num_blocks * buffer_surface->size_block / buffer_surface->pitch;
420
421     memset(ss, 0, sizeof(*ss));
422     /* ss0 */
423     ss->ss0.render_cache_read_mode = 1;
424     ss->ss0.surface_type = I965_SURFACE_BUFFER;
425     /* ss1 */
426     ss->ss1.base_addr = buffer_surface->bo->offset;
427     /* ss2 */
428     ss->ss2.width = ((num_entries - 1) & 0x7f);
429     ss->ss2.height = (((num_entries - 1) >> 7) & 0x1fff);
430     /* ss3 */
431     ss->ss3.depth = (((num_entries - 1) >> 20) & 0x7f);
432     ss->ss3.pitch = buffer_surface->pitch - 1;
433 }
434
435 void
436 i965_gpe_buffer_suface_setup(VADriverContextP ctx,
437                              struct i965_gpe_context *gpe_context,
438                              struct i965_buffer_surface *buffer_surface,
439                              unsigned long binding_table_offset,
440                              unsigned long surface_state_offset)
441 {
442     struct i965_surface_state *ss;
443     dri_bo *bo;
444
445     bo = gpe_context->surface_state_binding_table.bo;
446     dri_bo_map(bo, 1);
447     assert(bo->virtual);
448
449     ss = (struct i965_surface_state *)((char *)bo->virtual + surface_state_offset);
450     i965_gpe_set_buffer_surface_state(ctx, buffer_surface, ss);
451     dri_bo_emit_reloc(bo,
452                       I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
453                       0,
454                       surface_state_offset + offsetof(struct i965_surface_state, ss1),
455                       buffer_surface->bo);
456
457     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
458     dri_bo_unmap(bo);
459 }
460
461 static void
462 gen7_gpe_set_surface2_state(VADriverContextP ctx,
463                             struct object_surface *obj_surface,
464                             struct gen7_surface_state2 *ss)
465 {
466     int w, h, w_pitch;
467     unsigned int tiling, swizzle;
468
469     assert(obj_surface->bo);
470     assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
471
472     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
473     w = obj_surface->orig_width;
474     h = obj_surface->orig_height;
475     w_pitch = obj_surface->width;
476
477     memset(ss, 0, sizeof(*ss));
478     /* ss0 */
479     ss->ss0.surface_base_address = obj_surface->bo->offset;
480     /* ss1 */
481     ss->ss1.cbcr_pixel_offset_v_direction = 2;
482     ss->ss1.width = w - 1;
483     ss->ss1.height = h - 1;
484     /* ss2 */
485     ss->ss2.surface_format = MFX_SURFACE_PLANAR_420_8;
486     ss->ss2.interleave_chroma = 1;
487     ss->ss2.pitch = w_pitch - 1;
488     ss->ss2.half_pitch_for_chroma = 0;
489     gen7_gpe_set_surface2_tiling(ss, tiling);
490     /* ss3: UV offset for interleave mode */
491     ss->ss3.x_offset_for_cb = obj_surface->x_cb_offset;
492     ss->ss3.y_offset_for_cb = obj_surface->y_cb_offset;
493 }
494
495 void
496 gen7_gpe_surface2_setup(VADriverContextP ctx,
497                         struct i965_gpe_context *gpe_context,
498                         struct object_surface *obj_surface,
499                         unsigned long binding_table_offset,
500                         unsigned long surface_state_offset)
501 {
502     struct gen7_surface_state2 *ss;
503     dri_bo *bo;
504
505     bo = gpe_context->surface_state_binding_table.bo;
506     dri_bo_map(bo, 1);
507     assert(bo->virtual);
508
509     ss = (struct gen7_surface_state2 *)((char *)bo->virtual + surface_state_offset);
510     gen7_gpe_set_surface2_state(ctx, obj_surface, ss);
511     dri_bo_emit_reloc(bo,
512                       I915_GEM_DOMAIN_RENDER, 0,
513                       0,
514                       surface_state_offset + offsetof(struct gen7_surface_state2, ss0),
515                       obj_surface->bo);
516
517     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
518     dri_bo_unmap(bo);
519 }
520
521 static void
522 gen7_gpe_set_media_rw_surface_state(VADriverContextP ctx,
523                                     struct object_surface *obj_surface,
524                                     struct gen7_surface_state *ss)
525 {
526     int w, h, w_pitch;
527     unsigned int tiling, swizzle;
528
529     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
530     w = obj_surface->orig_width;
531     h = obj_surface->orig_height;
532     w_pitch = obj_surface->width;
533
534     memset(ss, 0, sizeof(*ss));
535     /* ss0 */
536     ss->ss0.surface_type = I965_SURFACE_2D;
537     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
538     /* ss1 */
539     ss->ss1.base_addr = obj_surface->bo->offset;
540     /* ss2 */
541     ss->ss2.width = w / 4 - 1;  /* in DWORDs for media read & write message */
542     ss->ss2.height = h - 1;
543     /* ss3 */
544     ss->ss3.pitch = w_pitch - 1;
545     gen7_gpe_set_surface_tiling(ss, tiling);
546 }
547
548 static void
549 gen75_gpe_set_media_chroma_surface_state(VADriverContextP ctx,
550                                     struct object_surface *obj_surface,
551                                     struct gen7_surface_state *ss)
552 {
553     int w, h, w_pitch;
554     unsigned int tiling, swizzle;
555     int cbcr_offset;
556
557     dri_bo_get_tiling(obj_surface->bo, &tiling, &swizzle);
558     w = obj_surface->orig_width;
559     h = obj_surface->orig_height;
560     w_pitch = obj_surface->width;
561
562     cbcr_offset = obj_surface->height * obj_surface->width;
563     memset(ss, 0, sizeof(*ss));
564     /* ss0 */
565     ss->ss0.surface_type = I965_SURFACE_2D;
566     ss->ss0.surface_format = I965_SURFACEFORMAT_R8_UNORM;
567     /* ss1 */
568     ss->ss1.base_addr = obj_surface->bo->offset + cbcr_offset;
569     /* ss2 */
570     ss->ss2.width = w / 4 - 1;  /* in DWORDs for media read & write message */
571     ss->ss2.height = (obj_surface->height / 2) -1;
572     /* ss3 */
573     ss->ss3.pitch = w_pitch - 1;
574     gen7_gpe_set_surface_tiling(ss, tiling);
575 }
576
577 void
578 gen7_gpe_media_rw_surface_setup(VADriverContextP ctx,
579                                 struct i965_gpe_context *gpe_context,
580                                 struct object_surface *obj_surface,
581                                 unsigned long binding_table_offset,
582                                 unsigned long surface_state_offset)
583 {
584     struct gen7_surface_state *ss;
585     dri_bo *bo;
586
587     bo = gpe_context->surface_state_binding_table.bo;
588     dri_bo_map(bo, True);
589     assert(bo->virtual);
590
591     ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
592     gen7_gpe_set_media_rw_surface_state(ctx, obj_surface, ss);
593     dri_bo_emit_reloc(bo,
594                       I915_GEM_DOMAIN_RENDER, 0,
595                       0,
596                       surface_state_offset + offsetof(struct gen7_surface_state, ss1),
597                       obj_surface->bo);
598
599     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
600     dri_bo_unmap(bo);
601 }
602
603 void
604 gen75_gpe_media_chroma_surface_setup(VADriverContextP ctx,
605                                 struct i965_gpe_context *gpe_context,
606                                 struct object_surface *obj_surface,
607                                 unsigned long binding_table_offset,
608                                 unsigned long surface_state_offset)
609 {
610     struct gen7_surface_state *ss;
611     dri_bo *bo;
612     int cbcr_offset;
613
614         assert(obj_surface->fourcc == VA_FOURCC('N', 'V', '1', '2'));
615     bo = gpe_context->surface_state_binding_table.bo;
616     dri_bo_map(bo, True);
617     assert(bo->virtual);
618
619     cbcr_offset = obj_surface->height * obj_surface->width;
620     ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
621     gen75_gpe_set_media_chroma_surface_state(ctx, obj_surface, ss);
622     dri_bo_emit_reloc(bo,
623                       I915_GEM_DOMAIN_RENDER, 0,
624                       cbcr_offset,
625                       surface_state_offset + offsetof(struct gen7_surface_state, ss1),
626                       obj_surface->bo);
627
628     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
629     dri_bo_unmap(bo);
630 }
631
632
633 static void
634 gen7_gpe_set_buffer_surface_state(VADriverContextP ctx,
635                                   struct i965_buffer_surface *buffer_surface,
636                                   struct gen7_surface_state *ss)
637 {
638     int num_entries;
639
640     assert(buffer_surface->bo);
641     num_entries = buffer_surface->num_blocks * buffer_surface->size_block / buffer_surface->pitch;
642
643     memset(ss, 0, sizeof(*ss));
644     /* ss0 */
645     ss->ss0.surface_type = I965_SURFACE_BUFFER;
646     /* ss1 */
647     ss->ss1.base_addr = buffer_surface->bo->offset;
648     /* ss2 */
649     ss->ss2.width = ((num_entries - 1) & 0x7f);
650     ss->ss2.height = (((num_entries - 1) >> 7) & 0x3fff);
651     /* ss3 */
652     ss->ss3.depth = (((num_entries - 1) >> 21) & 0x3f);
653     ss->ss3.pitch = buffer_surface->pitch - 1;
654 }
655
656 void
657 gen7_gpe_buffer_suface_setup(VADriverContextP ctx,
658                              struct i965_gpe_context *gpe_context,
659                              struct i965_buffer_surface *buffer_surface,
660                              unsigned long binding_table_offset,
661                              unsigned long surface_state_offset)
662 {
663     struct gen7_surface_state *ss;
664     dri_bo *bo;
665
666     bo = gpe_context->surface_state_binding_table.bo;
667     dri_bo_map(bo, 1);
668     assert(bo->virtual);
669
670     ss = (struct gen7_surface_state *)((char *)bo->virtual + surface_state_offset);
671     gen7_gpe_set_buffer_surface_state(ctx, buffer_surface, ss);
672     dri_bo_emit_reloc(bo,
673                       I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
674                       0,
675                       surface_state_offset + offsetof(struct gen7_surface_state, ss1),
676                       buffer_surface->bo);
677
678     *((unsigned int *)((char *)bo->virtual + binding_table_offset)) = surface_state_offset;
679     dri_bo_unmap(bo);
680 }