1 /*
2  * Copyright � 2014 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
21  * DEALINGS IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Eric Anholt <eric@anholt.net>
25  *    Keith Packard <keithp@keithp.com>
26  *    Xiang Haihao <haihao.xiang@intel.com>
27  *    Zhao Yakui <yakui.zhao@intel.com>
28  *
29  */
30 
31 /*
32  * Most of rendering codes are ported from intel-driver/src/i965_render.c
33  */
34 
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <assert.h>
39 #include <math.h>
40 
41 #include <va/va.h>
42 #include <va/va_backend.h>
43 #include <va/va_drmcommon.h>
44 
45 #include "media_drv_defines.h"
46 
47 #include "media_drv_util.h"
48 #include "media_drv_driver.h"
49 #include "media_drv_render.h"
50 #include "media_drv_surface.h"
51 #include "media_drv_init.h"
52 
53 #include "media_drv_batchbuffer.h"
54 #include "media_render_common.h"
55 
56 #define SF_KERNEL_NUM_GRF       16
57 #define SF_MAX_THREADS          1
58 
59 
60 /* Programs for Haswell */
61 static const uint32_t ps_kernel_static_gen7_haswell[][4] = {
62 #include "shaders/render/exa_wm_src_affine.g7b"
63 #include "shaders/render/exa_wm_src_sample_planar.g7b.haswell"
64 #include "shaders/render/exa_wm_yuv_color_balance.g7b.haswell"
65 #include "shaders/render/exa_wm_yuv_rgb.g7b"
66 #include "shaders/render/exa_wm_write.g7b"
67 };
68 
69 static const uint32_t ps_subpic_kernel_static_haswell[][4] = {
70 #include "shaders/render/exa_wm_src_affine.g7b"
71 #include "shaders/render/exa_wm_src_sample_argb.g7b"
72 #include "shaders/render/exa_wm_write.g7b"
73 };
74 
75 #define RENDER_SURFACE_STATE_SIZE      sizeof(struct gen7_surface_state)
76 
77 #define RENDER_SURFACE_STATE_OFFSET(index)     (RENDER_SURFACE_STATE_SIZE * index)
78 #define RENDER_BINDING_TABLE_OFFSET            RENDER_SURFACE_STATE_OFFSET(MAX_RENDER_SURFACES)
79 
80 #define DEFAULT_BRIGHTNESS      0
81 #define DEFAULT_CONTRAST        10
82 #define DEFAULT_HUE             0
83 #define DEFAULT_SATURATION      10
84 
85 #define URB_CS_ENTRY_SIZE     4
86 
87 
88 static struct media_render_kernel render_kernels_gen7_haswell[] = {
89     {
90         "PS",
91         PS_KERNEL,
92         ps_kernel_static_gen7_haswell,
93         sizeof(ps_kernel_static_gen7_haswell),
94         NULL
95     },
96     {
97         "PS_SUBPIC",
98         PS_SUBPIC_KERNEL,
99         ps_subpic_kernel_static_haswell,
100         sizeof(ps_subpic_kernel_static_haswell),
101         NULL
102     }
103 
104 };
105 
106 static float yuv_to_rgb_bt601[3][4] = {
107 {1.164,        0,        1.596,        -0.06275,},
108 {1.164,        -0.392,   -0.813,       -0.50196,},
109 {1.164,        2.017,    0,            -0.50196,},
110 };
111 
112 static float yuv_to_rgb_bt709[3][4] = {
113 {1.164,        0,        1.793,        -0.06275,},
114 {1.164,        -0.213,   -0.533,       -0.50196,},
115 {1.164,        2.112,    0,            -0.50196,},
116 };
117 
118 static float yuv_to_rgb_smpte_240[3][4] = {
119 {1.164,        0,        1.794,        -0.06275,},
120 {1.164,        -0.258,   -0.5425,      -0.50196,},
121 {1.164,        2.078,    0,            -0.50196,},
122 };
123 
124 
125 static void
i965_render_cc_viewport(VADriverContextP ctx)126 i965_render_cc_viewport(VADriverContextP ctx)
127 {
128     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
129     struct media_render_state *render_state = &drv_ctx->render_state;
130     struct i965_cc_viewport *cc_viewport;
131 
132     dri_bo_map(render_state->cc.viewport, 1);
133     assert(render_state->cc.viewport->virtual);
134     cc_viewport = render_state->cc.viewport->virtual;
135     memset(cc_viewport, 0, sizeof(*cc_viewport));
136 
137     cc_viewport->min_depth = -1.e35;
138     cc_viewport->max_depth = 1.e35;
139 
140     dri_bo_unmap(render_state->cc.viewport);
141 }
142 
143 static void
gen7_render_set_surface_tiling(struct gen7_surface_state * ss,uint32_t tiling)144 gen7_render_set_surface_tiling(struct gen7_surface_state *ss, uint32_t tiling)
145 {
146    switch (tiling) {
147    case I915_TILING_NONE:
148       ss->ss0.tiled_surface = 0;
149       ss->ss0.tile_walk = 0;
150       break;
151    case I915_TILING_X:
152       ss->ss0.tiled_surface = 1;
153       ss->ss0.tile_walk = I965_TILEWALK_XMAJOR;
154       break;
155    case I915_TILING_Y:
156       ss->ss0.tiled_surface = 1;
157       ss->ss0.tile_walk = I965_TILEWALK_YMAJOR;
158       break;
159    }
160 }
161 
162 /* Set "Shader Channel Select" */
163 static void
gen7_render_set_surface_scs(struct gen7_surface_state * ss)164 gen7_render_set_surface_scs(struct gen7_surface_state *ss)
165 {
166     ss->ss7.shader_chanel_select_r = RENDER_HSW_SCS_RED;
167     ss->ss7.shader_chanel_select_g = RENDER_HSW_SCS_GREEN;
168     ss->ss7.shader_chanel_select_b = RENDER_HSW_SCS_BLUE;
169     ss->ss7.shader_chanel_select_a = RENDER_HSW_SCS_ALPHA;
170 }
171 
172 static void
gen7_render_set_surface_state(struct gen7_surface_state * ss,dri_bo * bo,unsigned long offset,int width,int height,int pitch,int format,unsigned int flags)173 gen7_render_set_surface_state(
174     struct gen7_surface_state *ss,
175     dri_bo                    *bo,
176     unsigned long              offset,
177     int                        width,
178     int                        height,
179     int                        pitch,
180     int                        format,
181     unsigned int               flags
182 )
183 {
184     unsigned int tiling;
185     unsigned int swizzle;
186 
187     memset(ss, 0, sizeof(*ss));
188 
189     ss->ss0.surface_type = I965_SURFACE_2D;
190     ss->ss0.surface_format = format;
191 
192     ss->ss1.base_addr = bo->offset + offset;
193 
194     ss->ss2.width = width - 1;
195     ss->ss2.height = height - 1;
196 
197     ss->ss3.pitch = pitch - 1;
198 
199     dri_bo_get_tiling(bo, &tiling, &swizzle);
200     gen7_render_set_surface_tiling(ss, tiling);
201 }
202 
203 
204 static void
i965_render_src_surface_state(VADriverContextP ctx,int index,dri_bo * region,unsigned long offset,int w,int h,int pitch,int format,unsigned int flags)205 i965_render_src_surface_state(
206     VADriverContextP ctx,
207     int              index,
208     dri_bo          *region,
209     unsigned long    offset,
210     int              w,
211     int              h,
212     int              pitch,
213     int              format,
214     unsigned int     flags
215 )
216 {
217     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
218     struct media_render_state *render_state = &drv_ctx->render_state;
219     void *ss;
220     dri_bo *ss_bo = render_state->wm.surface_state_binding_table_bo;
221 
222     assert(index < MAX_RENDER_SURFACES);
223 
224     dri_bo_map(ss_bo, 1);
225     assert(ss_bo->virtual);
226     ss = (char *)ss_bo->virtual + RENDER_SURFACE_STATE_OFFSET(index);
227 
228         gen7_render_set_surface_state(ss,
229                                       region, offset,
230                                       w, h,
231                                       pitch, format, flags);
232         gen7_render_set_surface_scs(ss);
233         dri_bo_emit_reloc(ss_bo,
234                           I915_GEM_DOMAIN_SAMPLER, 0,
235                           offset,
236                           RENDER_SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
237                           region);
238 
239     ((unsigned int *)((char *)ss_bo->virtual + RENDER_BINDING_TABLE_OFFSET))[index] = RENDER_SURFACE_STATE_OFFSET(index);
240     dri_bo_unmap(ss_bo);
241     render_state->wm.sampler_count++;
242 }
243 
244 static void
i965_render_src_surfaces_state(VADriverContextP ctx,struct object_surface * obj_surface,unsigned int flags)245 i965_render_src_surfaces_state(
246     VADriverContextP ctx,
247     struct object_surface *obj_surface,
248     unsigned int     flags
249 )
250 {
251     int region_pitch;
252     int rw, rh;
253     dri_bo *region;
254 
255     region_pitch = obj_surface->width;
256     rw = obj_surface->orig_width;
257     rh = obj_surface->orig_height;
258     region = obj_surface->bo;
259 
260     i965_render_src_surface_state(ctx, 1, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM, flags);     /* Y */
261     i965_render_src_surface_state(ctx, 2, region, 0, rw, rh, region_pitch, I965_SURFACEFORMAT_R8_UNORM, flags);
262 
263     if (obj_surface->fourcc == VA_FOURCC_Y800) /* single plane for grayscale */
264         return;
265 
266     if (obj_surface->fourcc == VA_FOURCC_NV12) {
267         i965_render_src_surface_state(ctx, 3, region,
268                                       region_pitch * obj_surface->y_cb_offset,
269                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
270                                       I965_SURFACEFORMAT_R8G8_UNORM, flags); /* UV */
271         i965_render_src_surface_state(ctx, 4, region,
272                                       region_pitch * obj_surface->y_cb_offset,
273                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
274                                       I965_SURFACEFORMAT_R8G8_UNORM, flags);
275     } else {
276         i965_render_src_surface_state(ctx, 3, region,
277                                       region_pitch * obj_surface->y_cb_offset,
278                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
279                                       I965_SURFACEFORMAT_R8_UNORM, flags); /* U */
280         i965_render_src_surface_state(ctx, 4, region,
281                                       region_pitch * obj_surface->y_cb_offset,
282                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
283                                       I965_SURFACEFORMAT_R8_UNORM, flags);
284         i965_render_src_surface_state(ctx, 5, region,
285                                       region_pitch * obj_surface->y_cr_offset,
286                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
287                                       I965_SURFACEFORMAT_R8_UNORM, flags); /* V */
288         i965_render_src_surface_state(ctx, 6, region,
289                                       region_pitch * obj_surface->y_cr_offset,
290                                       obj_surface->cb_cr_width, obj_surface->cb_cr_height, obj_surface->cb_cr_pitch,
291                                       I965_SURFACEFORMAT_R8_UNORM, flags);
292     }
293 }
294 
295 static void
i965_render_dest_surface_state(VADriverContextP ctx,int index)296 i965_render_dest_surface_state(VADriverContextP ctx, int index)
297 {
298     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
299     struct media_render_state *render_state = &drv_ctx->render_state;
300     void *ss;
301     dri_bo *ss_bo = render_state->wm.surface_state_binding_table_bo;
302     struct region *dest_region = render_state->draw_region;
303     int format;
304     assert(index < MAX_RENDER_SURFACES);
305 
306     if (dest_region->cpp == 2) {
307         format = I965_SURFACEFORMAT_B5G6R5_UNORM;
308     } else {
309         format = I965_SURFACEFORMAT_B8G8R8A8_UNORM;
310     }
311 
312     dri_bo_map(ss_bo, 1);
313     assert(ss_bo->virtual);
314     ss = (char *)ss_bo->virtual + RENDER_SURFACE_STATE_OFFSET(index);
315 
316         gen7_render_set_surface_state(ss,
317                                       dest_region->bo, 0,
318                                       dest_region->width, dest_region->height,
319                                       dest_region->pitch, format, 0);
320         gen7_render_set_surface_scs(ss);
321         dri_bo_emit_reloc(ss_bo,
322                           I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
323                           0,
324                           RENDER_SURFACE_STATE_OFFSET(index) + offsetof(struct gen7_surface_state, ss1),
325                           dest_region->bo);
326 
327     ((unsigned int *)((char *)ss_bo->virtual + RENDER_BINDING_TABLE_OFFSET))[index] = RENDER_SURFACE_STATE_OFFSET(index);
328     dri_bo_unmap(ss_bo);
329 }
330 
331 static void
i965_fill_vertex_buffer(VADriverContextP ctx,float tex_coords[4],float vid_coords[4])332 i965_fill_vertex_buffer(
333     VADriverContextP ctx,
334     float tex_coords[4], /* [(u1,v1);(u2,v2)] */
335     float vid_coords[4]  /* [(x1,y1);(x2,y2)] */
336 )
337 {
338     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
339     float vb[12];
340 
341     enum { X1, Y1, X2, Y2 };
342 
343     static const unsigned int g_rotation_indices[][6] = {
344         [VA_ROTATION_NONE] = { X2, Y2, X1, Y2, X1, Y1 },
345         [VA_ROTATION_90]   = { X2, Y1, X2, Y2, X1, Y2 },
346         [VA_ROTATION_180]  = { X1, Y1, X2, Y1, X2, Y2 },
347         [VA_ROTATION_270]  = { X1, Y2, X1, Y1, X2, Y1 },
348     };
349 
350     const unsigned int * const rotation_indices =
351         g_rotation_indices[drv_ctx->rotation_attrib->value];
352 
353     vb[0]  = tex_coords[rotation_indices[0]]; /* bottom-right corner */
354     vb[1]  = tex_coords[rotation_indices[1]];
355     vb[2]  = vid_coords[X2];
356     vb[3]  = vid_coords[Y2];
357 
358     vb[4]  = tex_coords[rotation_indices[2]]; /* bottom-left corner */
359     vb[5]  = tex_coords[rotation_indices[3]];
360     vb[6]  = vid_coords[X1];
361     vb[7]  = vid_coords[Y2];
362 
363     vb[8]  = tex_coords[rotation_indices[4]]; /* top-left corner */
364     vb[9]  = tex_coords[rotation_indices[5]];
365     vb[10] = vid_coords[X1];
366     vb[11] = vid_coords[Y1];
367 
368     dri_bo_subdata(drv_ctx->render_state.vb.vertex_buffer, 0, sizeof(vb), vb);
369 }
370 
371 static void
i965_render_upload_vertex(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect)372 i965_render_upload_vertex(
373     VADriverContextP   ctx,
374     struct object_surface *obj_surface,
375     const VARectangle *src_rect,
376     const VARectangle *dst_rect
377 )
378 {
379     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
380     struct media_render_state *render_state = &drv_ctx->render_state;
381     struct region *dest_region = render_state->draw_region;
382     float tex_coords[4], vid_coords[4];
383     int width, height;
384 
385     width  = obj_surface->orig_width;
386     height = obj_surface->orig_height;
387 
388     tex_coords[0] = (float)src_rect->x / width;
389     tex_coords[1] = (float)src_rect->y / height;
390     tex_coords[2] = (float)(src_rect->x + src_rect->width) / width;
391     tex_coords[3] = (float)(src_rect->y + src_rect->height) / height;
392 
393     vid_coords[0] = dest_region->x + dst_rect->x;
394     vid_coords[1] = dest_region->y + dst_rect->y;
395     vid_coords[2] = vid_coords[0] + dst_rect->width;
396     vid_coords[3] = vid_coords[1] + dst_rect->height;
397 
398     i965_fill_vertex_buffer(ctx, tex_coords, vid_coords);
399 }
400 
401 #define PI  3.1415926
402 
403 static void
i965_render_upload_constants(VADriverContextP ctx,struct object_surface * obj_surface,unsigned int flags)404 i965_render_upload_constants(VADriverContextP ctx,
405                              struct object_surface *obj_surface,
406                              unsigned int flags)
407 {
408     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
409     struct media_render_state *render_state = &drv_ctx->render_state;
410     unsigned short *constant_buffer;
411     float *color_balance_base;
412     float contrast = (float)drv_ctx->contrast_attrib->value / DEFAULT_CONTRAST;
413     float brightness = (float)drv_ctx->brightness_attrib->value / 255; /* YUV is float in the shader */
414     float hue = (float)drv_ctx->hue_attrib->value / 180 * PI;
415     float saturation = (float)drv_ctx->saturation_attrib->value / DEFAULT_SATURATION;
416     float *yuv_to_rgb;
417     unsigned int color_flag;
418 
419     dri_bo_map(render_state->curbe.bo, 1);
420     assert(render_state->curbe.bo->virtual);
421     constant_buffer = render_state->curbe.bo->virtual;
422 
423     if (obj_surface->subsampling == SUBSAMPLE_YUV400) {
424         assert(obj_surface->fourcc == VA_FOURCC_Y800);
425 
426         constant_buffer[0] = 2;
427     } else {
428         if (obj_surface->fourcc == VA_FOURCC_NV12)
429             constant_buffer[0] = 1;
430         else
431             constant_buffer[0] = 0;
432     }
433 
434     if (drv_ctx->contrast_attrib->value == DEFAULT_CONTRAST &&
435         drv_ctx->brightness_attrib->value == DEFAULT_BRIGHTNESS &&
436         drv_ctx->hue_attrib->value == DEFAULT_HUE &&
437         drv_ctx->saturation_attrib->value == DEFAULT_SATURATION)
438         constant_buffer[1] = 1; /* skip color balance transformation */
439     else
440         constant_buffer[1] = 0;
441 
442     color_balance_base = (float *)constant_buffer + 4;
443     *color_balance_base++ = contrast;
444     *color_balance_base++ = brightness;
445     *color_balance_base++ = cos(hue) * contrast * saturation;
446     *color_balance_base++ = sin(hue) * contrast * saturation;
447 
448     color_flag = flags & VA_SRC_COLOR_MASK;
449     yuv_to_rgb = (float *)constant_buffer + 8;
450     if (color_flag == VA_SRC_BT709)
451         memcpy(yuv_to_rgb, yuv_to_rgb_bt709, sizeof(yuv_to_rgb_bt709));
452     else if (color_flag == VA_SRC_SMPTE_240)
453         memcpy(yuv_to_rgb, yuv_to_rgb_smpte_240, sizeof(yuv_to_rgb_smpte_240));
454     else
455         memcpy(yuv_to_rgb, yuv_to_rgb_bt601, sizeof(yuv_to_rgb_bt601));
456 
457     dri_bo_unmap(render_state->curbe.bo);
458 }
459 
460 
461 static void
i965_render_drawing_rectangle(VADriverContextP ctx)462 i965_render_drawing_rectangle(VADriverContextP ctx)
463 {
464     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
465     struct media_render_state *render_state = &drv_ctx->render_state;
466     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
467     struct region *dest_region = render_state->draw_region;
468 
469     BEGIN_BATCH(batch, 4);
470     OUT_BATCH(batch, RCMD_DRAWING_RECTANGLE | 2);
471     OUT_BATCH(batch, 0x00000000);
472     OUT_BATCH(batch, (dest_region->width - 1) | (dest_region->height - 1) << 16);
473     OUT_BATCH(batch, 0x00000000);
474 
475     ADVANCE_BATCH(batch);
476 }
477 
478 static void
i965_clear_dest_region(VADriverContextP ctx)479 i965_clear_dest_region(VADriverContextP ctx)
480 {
481     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
482     struct media_render_state *render_state = &drv_ctx->render_state;
483     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
484     struct region *dest_region = render_state->draw_region;
485     unsigned int blt_cmd, br13;
486     int pitch;
487 
488     blt_cmd = XY_COLOR_BLT_CMD;
489     br13 = 0xf0 << 16;
490     pitch = dest_region->pitch;
491 
492     if (dest_region->cpp == 4) {
493         br13 |= BR13_8888;
494         blt_cmd |= (XY_COLOR_BLT_WRITE_RGB | XY_COLOR_BLT_WRITE_ALPHA);
495     } else {
496         assert(dest_region->cpp == 2);
497         br13 |= BR13_565;
498     }
499 
500     if (dest_region->tiling != I915_TILING_NONE) {
501         blt_cmd |= XY_COLOR_BLT_DST_TILED;
502         pitch /= 4;
503     }
504 
505     br13 |= pitch;
506 
507     media_batchbuffer_start_atomic_blt(batch, 0x1000);
508     __BEGIN_BATCH(batch, 6, I915_EXEC_BLT);
509 
510     OUT_BATCH(batch, blt_cmd);
511     OUT_BATCH(batch, br13);
512     OUT_BATCH(batch, (dest_region->y << 16) | (dest_region->x));
513     OUT_BATCH(batch, ((dest_region->y + dest_region->height) << 16) |
514               (dest_region->x + dest_region->width));
515     OUT_RELOC(batch, dest_region->bo,
516               I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
517               0);
518     OUT_BATCH(batch, 0x0);
519     ADVANCE_BATCH(batch);
520     media_batchbuffer_end_atomic(batch);
521 }
522 /*
523  * for GEN7
524  */
525 static void
gen7_render_initialize(VADriverContextP ctx)526 gen7_render_initialize(VADriverContextP ctx)
527 {
528     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
529     struct media_render_state *render_state = &drv_ctx->render_state;
530     dri_bo *bo;
531 
532     /* VERTEX BUFFER */
533     dri_bo_unreference(render_state->vb.vertex_buffer);
534     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
535                       "vertex buffer",
536                       4096,
537                       4096);
538     assert(bo);
539     render_state->vb.vertex_buffer = bo;
540 
541     /* WM */
542     dri_bo_unreference(render_state->wm.surface_state_binding_table_bo);
543     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
544                       "surface state & binding table",
545                       (SURFACE_STATE_PADDED_SIZE + sizeof(unsigned int)) * MAX_RENDER_SURFACES,
546                       4096);
547     assert(bo);
548     render_state->wm.surface_state_binding_table_bo = bo;
549 
550     dri_bo_unreference(render_state->wm.sampler);
551     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
552                       "sampler state",
553                       MAX_SAMPLERS * sizeof(struct gen7_sampler_state),
554                       4096);
555     assert(bo);
556     render_state->wm.sampler = bo;
557     render_state->wm.sampler_count = 0;
558 
559     /* COLOR CALCULATOR */
560     dri_bo_unreference(render_state->cc.state);
561     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
562                       "color calc state",
563                       sizeof(struct gen6_color_calc_state),
564                       4096);
565     assert(bo);
566     render_state->cc.state = bo;
567 
568     /* CC VIEWPORT */
569     dri_bo_unreference(render_state->cc.viewport);
570     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
571                       "cc viewport",
572                       sizeof(struct i965_cc_viewport),
573                       4096);
574     assert(bo);
575     render_state->cc.viewport = bo;
576 
577     /* BLEND STATE */
578     dri_bo_unreference(render_state->cc.blend);
579     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
580                       "blend state",
581                       sizeof(struct gen6_blend_state),
582                       4096);
583     assert(bo);
584     render_state->cc.blend = bo;
585 
586     /* DEPTH & STENCIL STATE */
587     dri_bo_unreference(render_state->cc.depth_stencil);
588     bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
589                       "depth & stencil state",
590                       sizeof(struct gen6_depth_stencil_state),
591                       4096);
592     assert(bo);
593     render_state->cc.depth_stencil = bo;
594 }
595 
596 static void
gen7_render_color_calc_state(VADriverContextP ctx)597 gen7_render_color_calc_state(VADriverContextP ctx)
598 {
599     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
600     struct media_render_state *render_state = &drv_ctx->render_state;
601     struct gen6_color_calc_state *color_calc_state;
602 
603     dri_bo_map(render_state->cc.state, 1);
604     assert(render_state->cc.state->virtual);
605     color_calc_state = render_state->cc.state->virtual;
606     memset(color_calc_state, 0, sizeof(*color_calc_state));
607     color_calc_state->constant_r = 1.0;
608     color_calc_state->constant_g = 0.0;
609     color_calc_state->constant_b = 1.0;
610     color_calc_state->constant_a = 1.0;
611     dri_bo_unmap(render_state->cc.state);
612 }
613 
614 static void
gen7_render_blend_state(VADriverContextP ctx)615 gen7_render_blend_state(VADriverContextP ctx)
616 {
617     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
618     struct media_render_state *render_state = &drv_ctx->render_state;
619     struct gen6_blend_state *blend_state;
620 
621     dri_bo_map(render_state->cc.blend, 1);
622     assert(render_state->cc.blend->virtual);
623     blend_state = render_state->cc.blend->virtual;
624     memset(blend_state, 0, sizeof(*blend_state));
625     blend_state->blend1.logic_op_enable = 1;
626     blend_state->blend1.logic_op_func = 0xc;
627     blend_state->blend1.pre_blend_clamp_enable = 1;
628     dri_bo_unmap(render_state->cc.blend);
629 }
630 
631 static void
gen7_render_depth_stencil_state(VADriverContextP ctx)632 gen7_render_depth_stencil_state(VADriverContextP ctx)
633 {
634     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
635     struct media_render_state *render_state = &drv_ctx->render_state;
636     struct gen6_depth_stencil_state *depth_stencil_state;
637 
638     dri_bo_map(render_state->cc.depth_stencil, 1);
639     assert(render_state->cc.depth_stencil->virtual);
640     depth_stencil_state = render_state->cc.depth_stencil->virtual;
641     memset(depth_stencil_state, 0, sizeof(*depth_stencil_state));
642     dri_bo_unmap(render_state->cc.depth_stencil);
643 }
644 
645 static void
gen7_render_sampler(VADriverContextP ctx)646 gen7_render_sampler(VADriverContextP ctx)
647 {
648     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
649     struct media_render_state *render_state = &drv_ctx->render_state;
650     struct gen7_sampler_state *sampler_state;
651     int i;
652 
653     assert(render_state->wm.sampler_count > 0);
654     assert(render_state->wm.sampler_count <= MAX_SAMPLERS);
655 
656     dri_bo_map(render_state->wm.sampler, 1);
657     assert(render_state->wm.sampler->virtual);
658     sampler_state = render_state->wm.sampler->virtual;
659     for (i = 0; i < render_state->wm.sampler_count; i++) {
660         memset(sampler_state, 0, sizeof(*sampler_state));
661         sampler_state->ss0.min_filter = I965_MAPFILTER_LINEAR;
662         sampler_state->ss0.mag_filter = I965_MAPFILTER_LINEAR;
663         sampler_state->ss3.r_wrap_mode = I965_TEXCOORDMODE_CLAMP;
664         sampler_state->ss3.s_wrap_mode = I965_TEXCOORDMODE_CLAMP;
665         sampler_state->ss3.t_wrap_mode = I965_TEXCOORDMODE_CLAMP;
666         sampler_state++;
667     }
668 
669     dri_bo_unmap(render_state->wm.sampler);
670 }
671 
672 
673 static void
gen7_render_setup_states(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect,unsigned int flags)674 gen7_render_setup_states(
675     VADriverContextP   ctx,
676     struct object_surface *obj_surface,
677     const VARectangle *src_rect,
678     const VARectangle *dst_rect,
679     unsigned int       flags
680 )
681 {
682     i965_render_dest_surface_state(ctx, 0);
683     i965_render_src_surfaces_state(ctx, obj_surface, flags);
684     gen7_render_sampler(ctx);
685     i965_render_cc_viewport(ctx);
686     gen7_render_color_calc_state(ctx);
687     gen7_render_blend_state(ctx);
688     gen7_render_depth_stencil_state(ctx);
689     i965_render_upload_constants(ctx, obj_surface, flags);
690     i965_render_upload_vertex(ctx, obj_surface, src_rect, dst_rect);
691 }
692 
693 
694 static void
gen7_emit_invarient_states(VADriverContextP ctx)695 gen7_emit_invarient_states(VADriverContextP ctx)
696 {
697     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
698     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
699 
700     BEGIN_BATCH(batch, 1);
701     OUT_BATCH(batch, RCMD_PIPELINE_SELECT | PIPELINE_SELECT_3D);
702     ADVANCE_BATCH(batch);
703 
704     BEGIN_BATCH(batch, 4);
705     OUT_BATCH(batch, GEN6_3DSTATE_MULTISAMPLE | (4 - 2));
706     OUT_BATCH(batch, GEN6_3DSTATE_MULTISAMPLE_PIXEL_LOCATION_CENTER |
707               GEN6_3DSTATE_MULTISAMPLE_NUMSAMPLES_1); /* 1 sample/pixel */
708     OUT_BATCH(batch, 0);
709     OUT_BATCH(batch, 0);
710     ADVANCE_BATCH(batch);
711 
712     BEGIN_BATCH(batch, 2);
713     OUT_BATCH(batch, GEN6_3DSTATE_SAMPLE_MASK | (2 - 2));
714     OUT_BATCH(batch, 1);
715     ADVANCE_BATCH(batch);
716 
717     /* Set system instruction pointer */
718     BEGIN_BATCH(batch, 2);
719     OUT_BATCH(batch, RCMD_STATE_SIP | 0);
720     OUT_BATCH(batch, 0);
721     ADVANCE_BATCH(batch);
722 }
723 
724 static void
gen7_emit_state_base_address(VADriverContextP ctx)725 gen7_emit_state_base_address(VADriverContextP ctx)
726 {
727     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
728     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
729     struct media_render_state *render_state = &drv_ctx->render_state;
730 
731     OUT_BATCH(batch, RCMD_STATE_BASE_ADDRESS | (10 - 2));
732     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* General state base address */
733     OUT_RELOC(batch, render_state->wm.surface_state_binding_table_bo, I915_GEM_DOMAIN_INSTRUCTION, 0, BASE_ADDRESS_MODIFY); /* Surface state base address */
734     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Dynamic state base address */
735     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Indirect object base address */
736     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Instruction base address */
737     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* General state upper bound */
738     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Dynamic state upper bound */
739     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Indirect object upper bound */
740     OUT_BATCH(batch, BASE_ADDRESS_MODIFY); /* Instruction access upper bound */
741 }
742 
743 static void
gen7_emit_viewport_state_pointers(VADriverContextP ctx)744 gen7_emit_viewport_state_pointers(VADriverContextP ctx)
745 {
746     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
747     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
748     struct media_render_state *render_state = &drv_ctx->render_state;
749 
750     BEGIN_BATCH(batch, 2);
751     OUT_BATCH(batch, GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_CC | (2 - 2));
752     OUT_RELOC(batch,
753               render_state->cc.viewport,
754               I915_GEM_DOMAIN_INSTRUCTION, 0,
755               0);
756     ADVANCE_BATCH(batch);
757 
758     BEGIN_BATCH(batch, 2);
759     OUT_BATCH(batch, GEN7_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CL | (2 - 2));
760     OUT_BATCH(batch, 0);
761     ADVANCE_BATCH(batch);
762 }
763 
764 static void
gen7_emit_urb(VADriverContextP ctx)765 gen7_emit_urb(VADriverContextP ctx)
766 {
767     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
768     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
769     unsigned int num_urb_entries = 32;
770 
771     if (IS_HASWELL(drv_ctx->drv_data.device_id))
772         num_urb_entries = 64;
773 
774     BEGIN_BATCH(batch, 2);
775     OUT_BATCH(batch, GEN7_3DSTATE_PUSH_CONSTANT_ALLOC_PS | (2 - 2));
776     OUT_BATCH(batch, 8); /* in 1KBs */
777     ADVANCE_BATCH(batch);
778 
779     BEGIN_BATCH(batch, 2);
780     OUT_BATCH(batch, GEN7_3DSTATE_URB_VS | (2 - 2));
781     OUT_BATCH(batch,
782               (num_urb_entries << GEN7_URB_ENTRY_NUMBER_SHIFT) |
783               (2 - 1) << GEN7_URB_ENTRY_SIZE_SHIFT |
784               (1 << GEN7_URB_STARTING_ADDRESS_SHIFT));
785    ADVANCE_BATCH(batch);
786 
787    BEGIN_BATCH(batch, 2);
788    OUT_BATCH(batch, GEN7_3DSTATE_URB_GS | (2 - 2));
789    OUT_BATCH(batch,
790              (0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
791              (1 << GEN7_URB_STARTING_ADDRESS_SHIFT));
792    ADVANCE_BATCH(batch);
793 
794    BEGIN_BATCH(batch, 2);
795    OUT_BATCH(batch, GEN7_3DSTATE_URB_HS | (2 - 2));
796    OUT_BATCH(batch,
797              (0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
798              (2 << GEN7_URB_STARTING_ADDRESS_SHIFT));
799    ADVANCE_BATCH(batch);
800 
801    BEGIN_BATCH(batch, 2);
802    OUT_BATCH(batch, GEN7_3DSTATE_URB_DS | (2 - 2));
803    OUT_BATCH(batch,
804              (0 << GEN7_URB_ENTRY_SIZE_SHIFT) |
805              (2 << GEN7_URB_STARTING_ADDRESS_SHIFT));
806    ADVANCE_BATCH(batch);
807 }
808 
809 static void
gen7_emit_cc_state_pointers(VADriverContextP ctx)810 gen7_emit_cc_state_pointers(VADriverContextP ctx)
811 {
812     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
813     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
814     struct media_render_state *render_state = &drv_ctx->render_state;
815 
816     BEGIN_BATCH(batch, 2);
817     OUT_BATCH(batch, GEN6_3DSTATE_CC_STATE_POINTERS | (2 - 2));
818     OUT_RELOC(batch,
819               render_state->cc.state,
820               I915_GEM_DOMAIN_INSTRUCTION, 0,
821               1);
822     ADVANCE_BATCH(batch);
823 
824     BEGIN_BATCH(batch, 2);
825     OUT_BATCH(batch, GEN7_3DSTATE_BLEND_STATE_POINTERS | (2 - 2));
826     OUT_RELOC(batch,
827               render_state->cc.blend,
828               I915_GEM_DOMAIN_INSTRUCTION, 0,
829               1);
830     ADVANCE_BATCH(batch);
831 
832     BEGIN_BATCH(batch, 2);
833     OUT_BATCH(batch, GEN7_3DSTATE_DEPTH_STENCIL_STATE_POINTERS | (2 - 2));
834     OUT_RELOC(batch,
835               render_state->cc.depth_stencil,
836               I915_GEM_DOMAIN_INSTRUCTION, 0,
837               1);
838     ADVANCE_BATCH(batch);
839 }
840 
841 static void
gen7_emit_sampler_state_pointers(VADriverContextP ctx)842 gen7_emit_sampler_state_pointers(VADriverContextP ctx)
843 {
844     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
845     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
846     struct media_render_state *render_state = &drv_ctx->render_state;
847 
848     BEGIN_BATCH(batch, 2);
849     OUT_BATCH(batch, GEN7_3DSTATE_SAMPLER_STATE_POINTERS_PS | (2 - 2));
850     OUT_RELOC(batch,
851               render_state->wm.sampler,
852               I915_GEM_DOMAIN_INSTRUCTION, 0,
853               0);
854     ADVANCE_BATCH(batch);
855 }
856 
857 static void
gen7_emit_binding_table(VADriverContextP ctx)858 gen7_emit_binding_table(VADriverContextP ctx)
859 {
860     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
861     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
862 
863     BEGIN_BATCH(batch, 2);
864     OUT_BATCH(batch, GEN7_3DSTATE_BINDING_TABLE_POINTERS_PS | (2 - 2));
865     OUT_BATCH(batch, RENDER_BINDING_TABLE_OFFSET);
866     ADVANCE_BATCH(batch);
867 }
868 
869 static void
gen7_emit_depth_buffer_state(VADriverContextP ctx)870 gen7_emit_depth_buffer_state(VADriverContextP ctx)
871 {
872     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
873     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
874 
875     BEGIN_BATCH(batch, 7);
876     OUT_BATCH(batch, GEN7_3DSTATE_DEPTH_BUFFER | (7 - 2));
877     OUT_BATCH(batch,
878               (I965_DEPTHFORMAT_D32_FLOAT << 18) |
879               (I965_SURFACE_NULL << 29));
880     OUT_BATCH(batch, 0);
881     OUT_BATCH(batch, 0);
882     OUT_BATCH(batch, 0);
883     OUT_BATCH(batch, 0);
884     OUT_BATCH(batch, 0);
885     ADVANCE_BATCH(batch);
886 
887     BEGIN_BATCH(batch, 3);
888     OUT_BATCH(batch, GEN7_3DSTATE_CLEAR_PARAMS | (3 - 2));
889     OUT_BATCH(batch, 0);
890     OUT_BATCH(batch, 0);
891     ADVANCE_BATCH(batch);
892 }
893 
894 static void
gen7_emit_drawing_rectangle(VADriverContextP ctx)895 gen7_emit_drawing_rectangle(VADriverContextP ctx)
896 {
897     i965_render_drawing_rectangle(ctx);
898 }
899 
900 static void
gen7_emit_vs_state(VADriverContextP ctx)901 gen7_emit_vs_state(VADriverContextP ctx)
902 {
903     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
904     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
905 
906     /* disable VS constant buffer */
907     OUT_BATCH(batch, GEN6_3DSTATE_CONSTANT_VS | (7 - 2));
908     OUT_BATCH(batch, 0);
909     OUT_BATCH(batch, 0);
910     OUT_BATCH(batch, 0);
911     OUT_BATCH(batch, 0);
912     OUT_BATCH(batch, 0);
913     OUT_BATCH(batch, 0);
914 
915     OUT_BATCH(batch, GEN6_3DSTATE_VS | (6 - 2));
916     OUT_BATCH(batch, 0); /* without VS kernel */
917     OUT_BATCH(batch, 0);
918     OUT_BATCH(batch, 0);
919     OUT_BATCH(batch, 0);
920     OUT_BATCH(batch, 0); /* pass-through */
921 }
922 
923 static void
gen7_emit_bypass_state(VADriverContextP ctx)924 gen7_emit_bypass_state(VADriverContextP ctx)
925 {
926     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
927     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
928 
929     /* bypass GS */
930     BEGIN_BATCH(batch, 7);
931     OUT_BATCH(batch, GEN6_3DSTATE_CONSTANT_GS | (7 - 2));
932     OUT_BATCH(batch, 0);
933     OUT_BATCH(batch, 0);
934     OUT_BATCH(batch, 0);
935     OUT_BATCH(batch, 0);
936     OUT_BATCH(batch, 0);
937     OUT_BATCH(batch, 0);
938     ADVANCE_BATCH(batch);
939 
940     BEGIN_BATCH(batch, 7);
941     OUT_BATCH(batch, GEN6_3DSTATE_GS | (7 - 2));
942     OUT_BATCH(batch, 0); /* without GS kernel */
943     OUT_BATCH(batch, 0);
944     OUT_BATCH(batch, 0);
945     OUT_BATCH(batch, 0);
946     OUT_BATCH(batch, 0);
947     OUT_BATCH(batch, 0); /* pass-through */
948     ADVANCE_BATCH(batch);
949 
950     BEGIN_BATCH(batch, 2);
951     OUT_BATCH(batch, GEN7_3DSTATE_BINDING_TABLE_POINTERS_GS | (2 - 2));
952     OUT_BATCH(batch, 0);
953     ADVANCE_BATCH(batch);
954 
955     /* disable HS */
956     BEGIN_BATCH(batch, 7);
957     OUT_BATCH(batch, GEN7_3DSTATE_CONSTANT_HS | (7 - 2));
958     OUT_BATCH(batch, 0);
959     OUT_BATCH(batch, 0);
960     OUT_BATCH(batch, 0);
961     OUT_BATCH(batch, 0);
962     OUT_BATCH(batch, 0);
963     OUT_BATCH(batch, 0);
964     ADVANCE_BATCH(batch);
965 
966     BEGIN_BATCH(batch, 7);
967     OUT_BATCH(batch, GEN7_3DSTATE_HS | (7 - 2));
968     OUT_BATCH(batch, 0);
969     OUT_BATCH(batch, 0);
970     OUT_BATCH(batch, 0);
971     OUT_BATCH(batch, 0);
972     OUT_BATCH(batch, 0);
973     OUT_BATCH(batch, 0);
974     ADVANCE_BATCH(batch);
975 
976     BEGIN_BATCH(batch, 2);
977     OUT_BATCH(batch, GEN7_3DSTATE_BINDING_TABLE_POINTERS_HS | (2 - 2));
978     OUT_BATCH(batch, 0);
979     ADVANCE_BATCH(batch);
980 
981     /* Disable TE */
982     BEGIN_BATCH(batch, 4);
983     OUT_BATCH(batch, GEN7_3DSTATE_TE | (4 - 2));
984     OUT_BATCH(batch, 0);
985     OUT_BATCH(batch, 0);
986     OUT_BATCH(batch, 0);
987     ADVANCE_BATCH(batch);
988 
989     /* Disable DS */
990     BEGIN_BATCH(batch, 7);
991     OUT_BATCH(batch, GEN7_3DSTATE_CONSTANT_DS | (7 - 2));
992     OUT_BATCH(batch, 0);
993     OUT_BATCH(batch, 0);
994     OUT_BATCH(batch, 0);
995     OUT_BATCH(batch, 0);
996     OUT_BATCH(batch, 0);
997     OUT_BATCH(batch, 0);
998     ADVANCE_BATCH(batch);
999 
1000     BEGIN_BATCH(batch, 6);
1001     OUT_BATCH(batch, GEN7_3DSTATE_DS | (6 - 2));
1002     OUT_BATCH(batch, 0);
1003     OUT_BATCH(batch, 0);
1004     OUT_BATCH(batch, 0);
1005     OUT_BATCH(batch, 0);
1006     OUT_BATCH(batch, 0);
1007     ADVANCE_BATCH(batch);
1008 
1009     BEGIN_BATCH(batch, 2);
1010     OUT_BATCH(batch, GEN7_3DSTATE_BINDING_TABLE_POINTERS_DS | (2 - 2));
1011     OUT_BATCH(batch, 0);
1012     ADVANCE_BATCH(batch);
1013 
1014     /* Disable STREAMOUT */
1015     BEGIN_BATCH(batch, 3);
1016     OUT_BATCH(batch, GEN7_3DSTATE_STREAMOUT | (3 - 2));
1017     OUT_BATCH(batch, 0);
1018     OUT_BATCH(batch, 0);
1019     ADVANCE_BATCH(batch);
1020 }
1021 
1022 static void
gen7_emit_clip_state(VADriverContextP ctx)1023 gen7_emit_clip_state(VADriverContextP ctx)
1024 {
1025     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1026     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1027 
1028     OUT_BATCH(batch, GEN6_3DSTATE_CLIP | (4 - 2));
1029     OUT_BATCH(batch, 0);
1030     OUT_BATCH(batch, 0); /* pass-through */
1031     OUT_BATCH(batch, 0);
1032 }
1033 
1034 static void
gen7_emit_sf_state(VADriverContextP ctx)1035 gen7_emit_sf_state(VADriverContextP ctx)
1036 {
1037     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1038     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1039 
1040     BEGIN_BATCH(batch, 14);
1041     OUT_BATCH(batch, GEN7_3DSTATE_SBE | (14 - 2));
1042     OUT_BATCH(batch,
1043               (1 << GEN7_SBE_NUM_OUTPUTS_SHIFT) |
1044               (1 << GEN7_SBE_URB_ENTRY_READ_LENGTH_SHIFT) |
1045               (0 << GEN7_SBE_URB_ENTRY_READ_OFFSET_SHIFT));
1046     OUT_BATCH(batch, 0);
1047     OUT_BATCH(batch, 0);
1048     OUT_BATCH(batch, 0); /* DW4 */
1049     OUT_BATCH(batch, 0);
1050     OUT_BATCH(batch, 0);
1051     OUT_BATCH(batch, 0);
1052     OUT_BATCH(batch, 0);
1053     OUT_BATCH(batch, 0); /* DW9 */
1054     OUT_BATCH(batch, 0);
1055     OUT_BATCH(batch, 0);
1056     OUT_BATCH(batch, 0);
1057     OUT_BATCH(batch, 0);
1058     ADVANCE_BATCH(batch);
1059 
1060     BEGIN_BATCH(batch, 7);
1061     OUT_BATCH(batch, GEN6_3DSTATE_SF | (7 - 2));
1062     OUT_BATCH(batch, 0);
1063     OUT_BATCH(batch, GEN6_3DSTATE_SF_CULL_NONE);
1064     OUT_BATCH(batch, 2 << GEN6_3DSTATE_SF_TRIFAN_PROVOKE_SHIFT);
1065     OUT_BATCH(batch, 0);
1066     OUT_BATCH(batch, 0);
1067     OUT_BATCH(batch, 0);
1068     ADVANCE_BATCH(batch);
1069 }
1070 
1071 static void
gen7_emit_wm_state(VADriverContextP ctx,int kernel)1072 gen7_emit_wm_state(VADriverContextP ctx, int kernel)
1073 {
1074     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1075     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1076     struct media_render_state *render_state = &drv_ctx->render_state;
1077     unsigned int max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_IVB;
1078     unsigned int num_samples = 0;
1079 
1080     if (IS_HASWELL(drv_ctx->drv_data.device_id)) {
1081         max_threads_shift = GEN7_PS_MAX_THREADS_SHIFT_HSW;
1082         num_samples = 1 << GEN7_PS_SAMPLE_MASK_SHIFT_HSW;
1083     }
1084 
1085     BEGIN_BATCH(batch, 3);
1086     OUT_BATCH(batch, GEN6_3DSTATE_WM | (3 - 2));
1087     OUT_BATCH(batch,
1088               GEN7_WM_DISPATCH_ENABLE |
1089               GEN7_WM_PERSPECTIVE_PIXEL_BARYCENTRIC);
1090     OUT_BATCH(batch, 0);
1091     ADVANCE_BATCH(batch);
1092 
1093     BEGIN_BATCH(batch, 7);
1094     OUT_BATCH(batch, GEN6_3DSTATE_CONSTANT_PS | (7 - 2));
1095     OUT_BATCH(batch, URB_CS_ENTRY_SIZE);
1096     OUT_BATCH(batch, 0);
1097     OUT_RELOC(batch,
1098               render_state->curbe.bo,
1099               I915_GEM_DOMAIN_INSTRUCTION, 0,
1100               0);
1101     OUT_BATCH(batch, 0);
1102     OUT_BATCH(batch, 0);
1103     OUT_BATCH(batch, 0);
1104     ADVANCE_BATCH(batch);
1105 
1106     BEGIN_BATCH(batch, 8);
1107     OUT_BATCH(batch, GEN7_3DSTATE_PS | (8 - 2));
1108     OUT_RELOC(batch,
1109               render_state->render_kernels[kernel].bo,
1110               I915_GEM_DOMAIN_INSTRUCTION, 0,
1111               0);
1112     OUT_BATCH(batch,
1113               (1 << GEN7_PS_SAMPLER_COUNT_SHIFT) |
1114               (5 << GEN7_PS_BINDING_TABLE_ENTRY_COUNT_SHIFT));
1115     OUT_BATCH(batch, 0); /* scratch space base offset */
1116     OUT_BATCH(batch,
1117               ((drv_ctx->render_state.max_wm_threads - 1) << max_threads_shift) | num_samples |
1118               GEN7_PS_PUSH_CONSTANT_ENABLE |
1119               GEN7_PS_ATTRIBUTE_ENABLE |
1120               GEN7_PS_16_DISPATCH_ENABLE);
1121     OUT_BATCH(batch,
1122               (6 << GEN7_PS_DISPATCH_START_GRF_SHIFT_0));
1123     OUT_BATCH(batch, 0); /* kernel 1 pointer */
1124     OUT_BATCH(batch, 0); /* kernel 2 pointer */
1125     ADVANCE_BATCH(batch);
1126 }
1127 
1128 static void
gen7_emit_vertex_element_state(VADriverContextP ctx)1129 gen7_emit_vertex_element_state(VADriverContextP ctx)
1130 {
1131     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1132     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1133 
1134     /* Set up our vertex elements, sourced from the single vertex buffer. */
1135     OUT_BATCH(batch, RCMD_VERTEX_ELEMENTS | (5 - 2));
1136     /* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
1137     OUT_BATCH(batch, (0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) |
1138               GEN6_VE0_VALID |
1139               (I965_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1140               (0 << VE0_OFFSET_SHIFT));
1141     OUT_BATCH(batch, (I965_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1142               (I965_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1143               (I965_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1144               (I965_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
1145     /* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
1146     OUT_BATCH(batch, (0 << GEN6_VE0_VERTEX_BUFFER_INDEX_SHIFT) |
1147               GEN6_VE0_VALID |
1148               (I965_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
1149               (8 << VE0_OFFSET_SHIFT));
1150     OUT_BATCH(batch, (I965_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
1151               (I965_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
1152               (I965_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
1153               (I965_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT));
1154 }
1155 
1156 static void
gen7_emit_vertices(VADriverContextP ctx)1157 gen7_emit_vertices(VADriverContextP ctx)
1158 {
1159     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1160     struct media_render_state *render_state = &drv_ctx->render_state;
1161     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1162 
1163     BEGIN_BATCH(batch, 5);
1164     OUT_BATCH(batch, RCMD_VERTEX_BUFFERS | (5 - 2));
1165     OUT_BATCH(batch,
1166               (0 << GEN6_VB0_BUFFER_INDEX_SHIFT) |
1167               GEN6_VB0_VERTEXDATA |
1168               GEN7_VB0_ADDRESS_MODIFYENABLE |
1169               ((4 * 4) << VB0_BUFFER_PITCH_SHIFT));
1170     OUT_RELOC(batch, render_state->vb.vertex_buffer, I915_GEM_DOMAIN_VERTEX, 0, 0);
1171     OUT_RELOC(batch, render_state->vb.vertex_buffer, I915_GEM_DOMAIN_VERTEX, 0, 12 * 4);
1172     OUT_BATCH(batch, 0);
1173     ADVANCE_BATCH(batch);
1174 
1175     BEGIN_BATCH(batch, 7);
1176     OUT_BATCH(batch, RCMD_3DPRIMITIVE | (7 - 2));
1177     OUT_BATCH(batch,
1178               _3DPRIM_RECTLIST |
1179               GEN7_3DPRIM_VERTEXBUFFER_ACCESS_SEQUENTIAL);
1180     OUT_BATCH(batch, 3); /* vertex count per instance */
1181     OUT_BATCH(batch, 0); /* start vertex offset */
1182     OUT_BATCH(batch, 1); /* single instance */
1183     OUT_BATCH(batch, 0); /* start instance location */
1184     OUT_BATCH(batch, 0);
1185     ADVANCE_BATCH(batch);
1186 }
1187 
1188 static void
gen7_render_emit_states(VADriverContextP ctx,int kernel)1189 gen7_render_emit_states(VADriverContextP ctx, int kernel)
1190 {
1191     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1192     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1193 
1194     media_batchbuffer_start_atomic(batch, 0x1000);
1195     media_batchbuffer_emit_mi_flush(batch);
1196     gen7_emit_invarient_states(ctx);
1197     gen7_emit_state_base_address(ctx);
1198     gen7_emit_viewport_state_pointers(ctx);
1199     gen7_emit_urb(ctx);
1200     gen7_emit_cc_state_pointers(ctx);
1201     gen7_emit_sampler_state_pointers(ctx);
1202     gen7_emit_bypass_state(ctx);
1203     gen7_emit_vs_state(ctx);
1204     gen7_emit_clip_state(ctx);
1205     gen7_emit_sf_state(ctx);
1206     gen7_emit_wm_state(ctx, kernel);
1207     gen7_emit_binding_table(ctx);
1208     gen7_emit_depth_buffer_state(ctx);
1209     gen7_emit_drawing_rectangle(ctx);
1210     gen7_emit_vertex_element_state(ctx);
1211     gen7_emit_vertices(ctx);
1212     media_batchbuffer_end_atomic(batch);
1213 }
1214 
1215 static void
i965_subpic_render_src_surfaces_state(VADriverContextP ctx,struct object_surface * obj_surface)1216 i965_subpic_render_src_surfaces_state(VADriverContextP ctx,
1217                                       struct object_surface *obj_surface)
1218 {
1219     dri_bo *subpic_region;
1220     unsigned int index = obj_surface->subpic_render_idx;
1221     struct object_subpic *obj_subpic = obj_surface->obj_subpic[index];
1222     struct object_image *obj_image = obj_subpic->obj_image;
1223 
1224     subpic_region = obj_image->bo;
1225     /*subpicture surface*/
1226     i965_render_src_surface_state(ctx, 1, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format, 0);
1227     i965_render_src_surface_state(ctx, 2, subpic_region, 0, obj_subpic->width, obj_subpic->height, obj_subpic->pitch, obj_subpic->format, 0);
1228 
1229 }
1230 
1231 static void
gen7_subpicture_render_blend_state(VADriverContextP ctx)1232 gen7_subpicture_render_blend_state(VADriverContextP ctx)
1233 {
1234     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1235     struct media_render_state *render_state = &drv_ctx->render_state;
1236     struct gen6_blend_state *blend_state;
1237 
1238     dri_bo_unmap(render_state->cc.state);
1239     dri_bo_map(render_state->cc.blend, 1);
1240     assert(render_state->cc.blend->virtual);
1241     blend_state = render_state->cc.blend->virtual;
1242     memset(blend_state, 0, sizeof(*blend_state));
1243     blend_state->blend0.dest_blend_factor = I965_BLENDFACTOR_INV_SRC_ALPHA;
1244     blend_state->blend0.source_blend_factor = I965_BLENDFACTOR_SRC_ALPHA;
1245     blend_state->blend0.blend_func = I965_BLENDFUNCTION_ADD;
1246     blend_state->blend0.blend_enable = 1;
1247     blend_state->blend1.post_blend_clamp_enable = 1;
1248     blend_state->blend1.pre_blend_clamp_enable = 1;
1249     blend_state->blend1.clamp_range = 0; /* clamp range [0, 1] */
1250     dri_bo_unmap(render_state->cc.blend);
1251 }
1252 
1253 static void
i965_subpic_render_upload_constants(VADriverContextP ctx,struct object_surface * obj_surface)1254 i965_subpic_render_upload_constants(VADriverContextP ctx,
1255                                     struct object_surface *obj_surface)
1256 {
1257     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1258     struct media_render_state *render_state = &drv_ctx->render_state;
1259     float *constant_buffer;
1260     float global_alpha = 1.0;
1261     unsigned int index = obj_surface->subpic_render_idx;
1262     struct object_subpic *obj_subpic = obj_surface->obj_subpic[index];
1263 
1264     if (obj_subpic->flags & VA_SUBPICTURE_GLOBAL_ALPHA) {
1265         global_alpha = obj_subpic->global_alpha;
1266     }
1267 
1268     dri_bo_map(render_state->curbe.bo, 1);
1269 
1270     assert(render_state->curbe.bo->virtual);
1271     constant_buffer = render_state->curbe.bo->virtual;
1272     *constant_buffer = global_alpha;
1273 
1274     dri_bo_unmap(render_state->curbe.bo);
1275 }
1276 
1277 static void
i965_subpic_render_upload_vertex(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * output_rect)1278 i965_subpic_render_upload_vertex(VADriverContextP ctx,
1279                                  struct object_surface *obj_surface,
1280                                  const VARectangle *output_rect)
1281 {
1282     unsigned int index = obj_surface->subpic_render_idx;
1283     struct object_subpic     *obj_subpic   = obj_surface->obj_subpic[index];
1284     float tex_coords[4], vid_coords[4];
1285     VARectangle dst_rect;
1286 
1287     if (obj_subpic->flags & VA_SUBPICTURE_DESTINATION_IS_SCREEN_COORD)
1288         dst_rect = obj_subpic->dst_rect;
1289     else {
1290         const float sx  = (float)output_rect->width  / obj_surface->orig_width;
1291         const float sy  = (float)output_rect->height / obj_surface->orig_height;
1292         dst_rect.x      = output_rect->x + sx * obj_subpic->dst_rect.x;
1293         dst_rect.y      = output_rect->y + sy * obj_subpic->dst_rect.y;
1294         dst_rect.width  = sx * obj_subpic->dst_rect.width;
1295         dst_rect.height = sy * obj_subpic->dst_rect.height;
1296     }
1297 
1298     tex_coords[0] = (float)obj_subpic->src_rect.x / obj_subpic->width;
1299     tex_coords[1] = (float)obj_subpic->src_rect.y / obj_subpic->height;
1300     tex_coords[2] = (float)(obj_subpic->src_rect.x + obj_subpic->src_rect.width) / obj_subpic->width;
1301     tex_coords[3] = (float)(obj_subpic->src_rect.y + obj_subpic->src_rect.height) / obj_subpic->height;
1302 
1303     vid_coords[0] = dst_rect.x;
1304     vid_coords[1] = dst_rect.y;
1305     vid_coords[2] = (float)(dst_rect.x + dst_rect.width);
1306     vid_coords[3] = (float)(dst_rect.y + dst_rect.height);
1307 
1308     i965_fill_vertex_buffer(ctx, tex_coords, vid_coords);
1309 }
1310 
1311 static void
gen7_subpicture_render_setup_states(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect)1312 gen7_subpicture_render_setup_states(
1313     VADriverContextP   ctx,
1314     struct object_surface *obj_surface,
1315     const VARectangle *src_rect,
1316     const VARectangle *dst_rect
1317 )
1318 {
1319     i965_render_dest_surface_state(ctx, 0);
1320     i965_subpic_render_src_surfaces_state(ctx, obj_surface);
1321     gen7_render_sampler(ctx);
1322     i965_render_cc_viewport(ctx);
1323     gen7_render_color_calc_state(ctx);
1324     gen7_subpicture_render_blend_state(ctx);
1325     gen7_render_depth_stencil_state(ctx);
1326     i965_subpic_render_upload_constants(ctx, obj_surface);
1327     i965_subpic_render_upload_vertex(ctx, obj_surface, dst_rect);
1328 }
1329 
1330 static void
gen7_render_put_surface(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect,unsigned int flags)1331 gen7_render_put_surface(
1332     VADriverContextP   ctx,
1333     struct object_surface *obj_surface,
1334     const VARectangle *src_rect,
1335     const VARectangle *dst_rect,
1336     unsigned int       flags
1337 )
1338 {
1339     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1340     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1341 
1342     gen7_render_initialize(ctx);
1343     gen7_render_setup_states(ctx, obj_surface, src_rect, dst_rect, flags);
1344     i965_clear_dest_region(ctx);
1345     gen7_render_emit_states(ctx, PS_KERNEL);
1346     media_batchbuffer_flush(batch);
1347 }
1348 
1349 static void
gen7_render_put_subpicture(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect)1350 gen7_render_put_subpicture(
1351     VADriverContextP   ctx,
1352     struct object_surface *obj_surface,
1353     const VARectangle *src_rect,
1354     const VARectangle *dst_rect
1355 )
1356 {
1357     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1358     MEDIA_BATCH_BUFFER *batch = drv_ctx->render_batch;
1359 
1360     gen7_render_initialize(ctx);
1361     gen7_subpicture_render_setup_states(ctx, obj_surface, src_rect, dst_rect);
1362     gen7_render_emit_states(ctx, PS_SUBPIC_KERNEL);
1363     media_batchbuffer_flush(batch);
1364 }
1365 
1366 
1367 
1368 void
media_render_put_surface(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect,unsigned int flags)1369 media_render_put_surface(
1370     VADriverContextP   ctx,
1371     struct object_surface *obj_surface,
1372     const VARectangle *src_rect,
1373     const VARectangle *dst_rect,
1374     unsigned int       flags
1375 )
1376 {
1377     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1378     struct media_render_state *render_state = &drv_ctx->render_state;
1379 
1380     if (render_state->render_put_surface)
1381         render_state->render_put_surface(ctx, obj_surface, src_rect, dst_rect, flags);
1382 
1383     return;
1384 }
1385 
1386 void
media_render_put_subpicture(VADriverContextP ctx,struct object_surface * obj_surface,const VARectangle * src_rect,const VARectangle * dst_rect)1387 media_render_put_subpicture(
1388     VADriverContextP   ctx,
1389     struct object_surface *obj_surface,
1390     const VARectangle *src_rect,
1391     const VARectangle *dst_rect
1392 )
1393 {
1394     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1395     struct media_render_state *render_state = &drv_ctx->render_state;
1396 
1397     if (render_state->render_put_subpicture)
1398         render_state->render_put_subpicture(ctx, obj_surface, src_rect, dst_rect);
1399 }
1400 
1401 static void
genx_render_terminate(VADriverContextP ctx)1402 genx_render_terminate(VADriverContextP ctx)
1403 {
1404     int i;
1405     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1406     struct media_render_state *render_state = &drv_ctx->render_state;
1407 
1408     dri_bo_unreference(render_state->curbe.bo);
1409     render_state->curbe.bo = NULL;
1410 
1411     for (i = 0; i < sizeof(render_kernels_gen7_haswell) / sizeof(struct media_render_kernel); i++) {
1412         struct media_render_kernel *kernel = &render_state->render_kernels[i];
1413 
1414         dri_bo_unreference(kernel->bo);
1415         kernel->bo = NULL;
1416     }
1417 
1418     dri_bo_unreference(render_state->vb.vertex_buffer);
1419     render_state->vb.vertex_buffer = NULL;
1420     dri_bo_unreference(render_state->vs.state);
1421     render_state->vs.state = NULL;
1422     dri_bo_unreference(render_state->sf.state);
1423     render_state->sf.state = NULL;
1424     dri_bo_unreference(render_state->wm.sampler);
1425     render_state->wm.sampler = NULL;
1426     dri_bo_unreference(render_state->wm.state);
1427     render_state->wm.state = NULL;
1428     dri_bo_unreference(render_state->wm.surface_state_binding_table_bo);
1429     dri_bo_unreference(render_state->cc.viewport);
1430     render_state->cc.viewport = NULL;
1431     dri_bo_unreference(render_state->cc.state);
1432     render_state->cc.state = NULL;
1433     dri_bo_unreference(render_state->cc.blend);
1434     render_state->cc.blend = NULL;
1435     dri_bo_unreference(render_state->cc.depth_stencil);
1436     render_state->cc.depth_stencil = NULL;
1437 
1438     if (render_state->draw_region) {
1439         dri_bo_unreference(render_state->draw_region->bo);
1440         free(render_state->draw_region);
1441         render_state->draw_region = NULL;
1442     }
1443 }
1444 
1445 bool
media_drv_gen75_render_init(VADriverContextP ctx)1446 media_drv_gen75_render_init(VADriverContextP ctx)
1447 {
1448     MEDIA_DRV_CONTEXT *drv_ctx = (MEDIA_DRV_CONTEXT *) (ctx->pDriverData);
1449     struct media_render_state *render_state = &drv_ctx->render_state;
1450     int i;
1451 
1452     /* kernel */
1453 
1454     if (IS_HASWELL (drv_ctx->drv_data.device_id)) {
1455         memcpy(render_state->render_kernels, render_kernels_gen7_haswell,
1456                sizeof(render_state->render_kernels));
1457         render_state->render_put_surface = gen7_render_put_surface;
1458         render_state->render_put_subpicture = gen7_render_put_subpicture;
1459     } else {
1460         return false;
1461     }
1462 
1463     if (IS_HSW_GT1 (drv_ctx->drv_data.device_id))
1464     {
1465         render_state->max_wm_threads = 102;
1466     }
1467     else if (IS_HSW_GT2 (drv_ctx->drv_data.device_id))
1468     {
1469         render_state->max_wm_threads = 204;
1470     }
1471     else if (IS_HSW_GT3 (drv_ctx->drv_data.device_id))
1472     {
1473         render_state->max_wm_threads = 408;
1474     }
1475     render_state->render_terminate = genx_render_terminate;
1476 
1477     for (i = 0; i < sizeof(render_kernels_gen7_haswell) / sizeof(struct media_render_kernel); i++) {
1478         struct media_render_kernel *kernel = &render_state->render_kernels[i];
1479 
1480         if (!kernel->size)
1481             continue;
1482 
1483         kernel->bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr, kernel->name,
1484                                   kernel->size, 0x1000);
1485         assert(kernel->bo);
1486         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
1487     }
1488 
1489     /* constant buffer */
1490     render_state->curbe.bo = dri_bo_alloc(drv_ctx->drv_data.bufmgr,
1491                       "constant buffer",
1492                       4096, 64);
1493     assert(render_state->curbe.bo);
1494 
1495     return true;
1496 }
1497