OSDN Git Service

1e5af959512c5d66ea351016665c2bd560f6f833
[android-x86/external-mesa.git] / src / mesa / drivers / dri / i965 / gen7_wm_surface_state.c
1 /*
2  * Copyright © 2011 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 #include "main/mtypes.h"
24 #include "main/samplerobj.h"
25 #include "program/prog_parameter.h"
26
27 #include "intel_mipmap_tree.h"
28 #include "intel_batchbuffer.h"
29 #include "intel_tex.h"
30 #include "intel_fbo.h"
31 #include "intel_buffer_objects.h"
32
33 #include "brw_context.h"
34 #include "brw_state.h"
35 #include "brw_defines.h"
36 #include "brw_wm.h"
37
38 /**
39  * Convert an swizzle enumeration (i.e. SWIZZLE_X) to one of the Gen7.5+
40  * "Shader Channel Select" enumerations (i.e. HSW_SCS_RED)
41  */
42 static unsigned
43 swizzle_to_scs(GLenum swizzle)
44 {
45    switch (swizzle) {
46    case SWIZZLE_X:
47       return HSW_SCS_RED;
48    case SWIZZLE_Y:
49       return HSW_SCS_GREEN;
50    case SWIZZLE_Z:
51       return HSW_SCS_BLUE;
52    case SWIZZLE_W:
53       return HSW_SCS_ALPHA;
54    case SWIZZLE_ZERO:
55       return HSW_SCS_ZERO;
56    case SWIZZLE_ONE:
57       return HSW_SCS_ONE;
58    }
59
60    assert(!"Should not get here: invalid swizzle mode");
61    return HSW_SCS_ZERO;
62 }
63
64 void
65 gen7_set_surface_tiling(struct gen7_surface_state *surf, uint32_t tiling)
66 {
67    switch (tiling) {
68    case I915_TILING_NONE:
69       surf->ss0.tiled_surface = 0;
70       surf->ss0.tile_walk = 0;
71       break;
72    case I915_TILING_X:
73       surf->ss0.tiled_surface = 1;
74       surf->ss0.tile_walk = BRW_TILEWALK_XMAJOR;
75       break;
76    case I915_TILING_Y:
77       surf->ss0.tiled_surface = 1;
78       surf->ss0.tile_walk = BRW_TILEWALK_YMAJOR;
79       break;
80    }
81 }
82
83
84 void
85 gen7_set_surface_msaa(struct gen7_surface_state *surf, unsigned num_samples,
86                       enum intel_msaa_layout layout)
87 {
88    if (num_samples > 4)
89       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_8;
90    else if (num_samples > 1)
91       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_4;
92    else
93       surf->ss4.num_multisamples = GEN7_SURFACE_MULTISAMPLECOUNT_1;
94
95    surf->ss4.multisampled_surface_storage_format =
96       layout == INTEL_MSAA_LAYOUT_IMS ?
97       GEN7_SURFACE_MSFMT_DEPTH_STENCIL :
98       GEN7_SURFACE_MSFMT_MSS;
99 }
100
101
102 void
103 gen7_set_surface_mcs_info(struct brw_context *brw,
104                           struct gen7_surface_state *surf,
105                           uint32_t surf_offset,
106                           const struct intel_mipmap_tree *mcs_mt,
107                           bool is_render_target)
108 {
109    /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
110     *
111     *     "The MCS surface must be stored as Tile Y."
112     */
113    assert(mcs_mt->region->tiling == I915_TILING_Y);
114
115    /* Compute the pitch in units of tiles.  To do this we need to divide the
116     * pitch in bytes by 128, since a single Y-tile is 128 bytes wide.
117     */
118    unsigned pitch_bytes = mcs_mt->region->pitch * mcs_mt->cpp;
119    unsigned pitch_tiles = pitch_bytes / 128;
120
121    /* The upper 20 bits of surface state DWORD 6 are the upper 20 bits of the
122     * GPU address of the MCS buffer; the lower 12 bits contain other control
123     * information.  Since buffer addresses are always on 4k boundaries (and
124     * thus have their lower 12 bits zero), we can use an ordinary reloc to do
125     * the necessary address translation.
126     */
127    assert ((mcs_mt->region->bo->offset & 0xfff) == 0);
128    surf->ss6.mcs_enabled.mcs_enable = 1;
129    surf->ss6.mcs_enabled.mcs_surface_pitch = pitch_tiles - 1;
130    surf->ss6.mcs_enabled.mcs_base_address = mcs_mt->region->bo->offset >> 12;
131    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
132                            surf_offset +
133                            offsetof(struct gen7_surface_state, ss6),
134                            mcs_mt->region->bo,
135                            surf->ss6.raw_data & 0xfff,
136                            is_render_target ? I915_GEM_DOMAIN_RENDER
137                            : I915_GEM_DOMAIN_SAMPLER,
138                            is_render_target ? I915_GEM_DOMAIN_RENDER : 0);
139 }
140
141
142 void
143 gen7_check_surface_setup(struct gen7_surface_state *surf,
144                          bool is_render_target)
145 {
146    bool is_multisampled =
147       surf->ss4.num_multisamples != GEN7_SURFACE_MULTISAMPLECOUNT_1;
148    /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
149     * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Surface Array
150     * Spacing:
151     *
152     *   If Multisampled Surface Storage Format is MSFMT_MSS and Number of
153     *   Multisamples is not MULTISAMPLECOUNT_1, this field must be set to
154     *   ARYSPC_LOD0.
155     */
156    if (surf->ss4.multisampled_surface_storage_format == GEN7_SURFACE_MSFMT_MSS
157        && is_multisampled)
158       assert(surf->ss0.surface_array_spacing == GEN7_SURFACE_ARYSPC_LOD0);
159
160    /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
161     * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
162     * Surface Storage Format:
163     *
164     *   All multisampled render target surfaces must have this field set to
165     *   MSFMT_MSS.
166     *
167     * But also:
168     *
169     *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
170     */
171    if (is_render_target && is_multisampled) {
172       assert(surf->ss4.multisampled_surface_storage_format ==
173              GEN7_SURFACE_MSFMT_MSS);
174    }
175
176    /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
177     * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
178     * Surface Storage Format:
179     *
180     *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
181     *   is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
182     *   field must be set to MSFMT_MSS.
183     */
184    if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 &&
185        surf->ss2.width >= 8192) {
186       assert(surf->ss4.multisampled_surface_storage_format ==
187              GEN7_SURFACE_MSFMT_MSS);
188    }
189
190    /* From the Graphics BSpec: vol5c Shared Functions [SNB+] > State >
191     * SURFACE_STATE > SURFACE_STATE for most messages [DevIVB]: Multisampled
192     * Surface Storage Format:
193     *
194     *   If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
195     *   ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number of
196     *   Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is >
197     *   8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.This field
198     *   must be set to MSFMT_DEPTH_STENCIL if Surface Format is one of the
199     *   following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
200     *   R24_UNORM_X8_TYPELESS.
201     *
202     * But also:
203     *
204     *   This field is ignored if Number of Multisamples is MULTISAMPLECOUNT_1.
205     */
206    uint32_t depth = surf->ss3.depth + 1;
207    uint32_t height = surf->ss2.height + 1;
208    if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_8 &&
209        depth * height > 4194304) {
210       assert(surf->ss4.multisampled_surface_storage_format ==
211              GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
212    }
213    if (surf->ss4.num_multisamples == GEN7_SURFACE_MULTISAMPLECOUNT_4 &&
214        depth * height > 8388608) {
215       assert(surf->ss4.multisampled_surface_storage_format ==
216              GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
217    }
218    if (is_multisampled) {
219       switch (surf->ss0.surface_format) {
220       case BRW_SURFACEFORMAT_I24X8_UNORM:
221       case BRW_SURFACEFORMAT_L24X8_UNORM:
222       case BRW_SURFACEFORMAT_A24X8_UNORM:
223       case BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS:
224          assert(surf->ss4.multisampled_surface_storage_format ==
225                 GEN7_SURFACE_MSFMT_DEPTH_STENCIL);
226       }
227    }
228 }
229
230
231 static void
232 gen7_update_buffer_texture_surface(struct gl_context *ctx,
233                                    unsigned unit,
234                                    uint32_t *binding_table,
235                                    unsigned surf_index)
236 {
237    struct brw_context *brw = brw_context(ctx);
238    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
239    struct gen7_surface_state *surf;
240    struct intel_buffer_object *intel_obj =
241       intel_buffer_object(tObj->BufferObject);
242    drm_intel_bo *bo = intel_obj ? intel_obj->buffer : NULL;
243    gl_format format = tObj->_BufferObjectFormat;
244    int texel_size = _mesa_get_format_bytes(format);
245
246    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
247                           sizeof(*surf), 32, &binding_table[surf_index]);
248    memset(surf, 0, sizeof(*surf));
249
250    surf->ss0.surface_type = BRW_SURFACE_BUFFER;
251    surf->ss0.surface_format = brw_format_for_mesa_format(format);
252
253    surf->ss0.render_cache_read_write = 1;
254
255    if (surf->ss0.surface_format == 0 && format != MESA_FORMAT_RGBA_FLOAT32) {
256       _mesa_problem(NULL, "bad format %s for texture buffer\n",
257                     _mesa_get_format_name(format));
258    }
259
260    if (bo) {
261       surf->ss1.base_addr = bo->offset; /* reloc */
262
263       /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
264        * bspec ("Data Cache") says that the data cache does not exist as
265        * a separate cache and is just the sampler cache.
266        */
267       drm_intel_bo_emit_reloc(brw->intel.batch.bo,
268                               (binding_table[surf_index] +
269                                offsetof(struct gen7_surface_state, ss1)),
270                               bo, 0,
271                               I915_GEM_DOMAIN_SAMPLER, 0);
272
273       int w = intel_obj->Base.Size / texel_size;
274       surf->ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
275       surf->ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
276       surf->ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
277       surf->ss3.pitch = texel_size - 1;
278 } else {
279       surf->ss1.base_addr = 0;
280       surf->ss2.width = 0;
281       surf->ss2.height = 0;
282       surf->ss3.depth = 0;
283       surf->ss3.pitch = 0;
284    }
285
286    gen7_set_surface_tiling(surf, I915_TILING_NONE);
287
288    gen7_check_surface_setup(surf, false /* is_render_target */);
289 }
290
291 static void
292 gen7_update_texture_surface(struct gl_context *ctx,
293                             unsigned unit,
294                             uint32_t *binding_table,
295                             unsigned surf_index)
296 {
297    struct brw_context *brw = brw_context(ctx);
298    struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current;
299    struct intel_texture_object *intelObj = intel_texture_object(tObj);
300    struct intel_mipmap_tree *mt = intelObj->mt;
301    struct gl_texture_image *firstImage = tObj->Image[0][tObj->BaseLevel];
302    struct gl_sampler_object *sampler = _mesa_get_samplerobj(ctx, unit);
303    struct gen7_surface_state *surf;
304    int width, height, depth;
305
306    if (tObj->Target == GL_TEXTURE_BUFFER) {
307       gen7_update_buffer_texture_surface(ctx, unit, binding_table, surf_index);
308       return;
309    }
310
311    /* We don't support MSAA for textures. */
312    assert(!mt->array_spacing_lod0);
313    assert(mt->num_samples <= 1);
314
315    intel_miptree_get_dimensions_for_image(firstImage, &width, &height, &depth);
316
317    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
318                           sizeof(*surf), 32, &binding_table[surf_index]);
319    memset(surf, 0, sizeof(*surf));
320
321    if (mt->align_h == 4)
322       surf->ss0.vertical_alignment = 1;
323    if (mt->align_w == 8)
324       surf->ss0.horizontal_alignment = 1;
325
326    surf->ss0.surface_type = translate_tex_target(tObj->Target);
327    surf->ss0.surface_format = translate_tex_format(mt->format,
328                                                    firstImage->InternalFormat,
329                                                    tObj->DepthMode,
330                                                    sampler->sRGBDecode);
331    if (tObj->Target == GL_TEXTURE_CUBE_MAP ||
332        tObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) {
333       surf->ss0.cube_pos_x = 1;
334       surf->ss0.cube_pos_y = 1;
335       surf->ss0.cube_pos_z = 1;
336       surf->ss0.cube_neg_x = 1;
337       surf->ss0.cube_neg_y = 1;
338       surf->ss0.cube_neg_z = 1;
339    }
340
341    surf->ss0.is_array = depth > 1 && tObj->Target != GL_TEXTURE_3D;
342
343    gen7_set_surface_tiling(surf, intelObj->mt->region->tiling);
344
345    /* ss0 remaining fields:
346     * - vert_line_stride (exists on gen6 but we ignore it)
347     * - vert_line_stride_ofs (exists on gen6 but we ignore it)
348     * - surface_array_spacing
349     * - render_cache_read_write (exists on gen6 but ignored here)
350     */
351
352    surf->ss1.base_addr =
353       intelObj->mt->region->bo->offset + intelObj->mt->offset; /* reloc */
354
355    surf->ss2.width = width - 1;
356    surf->ss2.height = height - 1;
357
358    surf->ss3.pitch = (intelObj->mt->region->pitch * intelObj->mt->cpp) - 1;
359    surf->ss3.depth = depth - 1;
360
361    /* ss4: ignored? */
362
363    surf->ss5.mip_count = intelObj->_MaxLevel - tObj->BaseLevel;
364    surf->ss5.min_lod = 0;
365
366    /* ss5 remaining fields:
367     * - x_offset (N/A for textures?)
368     * - y_offset (ditto)
369     * - cache_control
370     */
371
372    if (brw->intel.is_haswell) {
373       /* Handling GL_ALPHA as a surface format override breaks 1.30+ style
374        * texturing functions that return a float, as our code generation always
375        * selects the .x channel (which would always be 0).
376        */
377       const bool alpha_depth = tObj->DepthMode == GL_ALPHA &&
378          (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
379           firstImage->_BaseFormat == GL_DEPTH_STENCIL);
380
381       const int swizzle =
382          unlikely(alpha_depth) ? SWIZZLE_XYZW : brw_get_texture_swizzle(tObj);
383
384       surf->ss7.shader_channel_select_r = swizzle_to_scs(GET_SWZ(swizzle, 0));
385       surf->ss7.shader_channel_select_g = swizzle_to_scs(GET_SWZ(swizzle, 1));
386       surf->ss7.shader_channel_select_b = swizzle_to_scs(GET_SWZ(swizzle, 2));
387       surf->ss7.shader_channel_select_a = swizzle_to_scs(GET_SWZ(swizzle, 3));
388    }
389
390    /* Emit relocation to surface contents */
391    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
392                            binding_table[surf_index] +
393                            offsetof(struct gen7_surface_state, ss1),
394                            intelObj->mt->region->bo, intelObj->mt->offset,
395                            I915_GEM_DOMAIN_SAMPLER, 0);
396
397    gen7_check_surface_setup(surf, false /* is_render_target */);
398 }
399
400 /**
401  * Create the constant buffer surface.  Vertex/fragment shader constants will
402  * be read from this buffer with Data Port Read instructions/messages.
403  */
404 static void
405 gen7_create_constant_surface(struct brw_context *brw,
406                              drm_intel_bo *bo,
407                              uint32_t offset,
408                              int width,
409                              uint32_t *out_offset)
410 {
411    const GLint w = width - 1;
412    struct gen7_surface_state *surf;
413
414    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
415                           sizeof(*surf), 32, out_offset);
416    memset(surf, 0, sizeof(*surf));
417
418    surf->ss0.surface_type = BRW_SURFACE_BUFFER;
419    surf->ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
420
421    surf->ss0.render_cache_read_write = 1;
422
423    assert(bo);
424    surf->ss1.base_addr = bo->offset + offset; /* reloc */
425
426    surf->ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
427    surf->ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
428    surf->ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
429    surf->ss3.pitch = (16 - 1); /* stride between samples */
430    gen7_set_surface_tiling(surf, I915_TILING_NONE); /* tiling now allowed */
431
432    if (brw->intel.is_haswell) {
433       surf->ss7.shader_channel_select_r = HSW_SCS_RED;
434       surf->ss7.shader_channel_select_g = HSW_SCS_GREEN;
435       surf->ss7.shader_channel_select_b = HSW_SCS_BLUE;
436       surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA;
437    }
438
439    /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
440     * bspec ("Data Cache") says that the data cache does not exist as
441     * a separate cache and is just the sampler cache.
442     */
443    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
444                            (*out_offset +
445                             offsetof(struct gen7_surface_state, ss1)),
446                            bo, offset,
447                            I915_GEM_DOMAIN_SAMPLER, 0);
448
449    gen7_check_surface_setup(surf, false /* is_render_target */);
450 }
451
452 static void
453 gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
454 {
455    /* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming
456     * Notes):
457     *
458     *     A null surface is used in instances where an actual surface is not
459     *     bound. When a write message is generated to a null surface, no
460     *     actual surface is written to. When a read message (including any
461     *     sampling engine message) is generated to a null surface, the result
462     *     is all zeros. Note that a null surface type is allowed to be used
463     *     with all messages, even if it is not specificially indicated as
464     *     supported. All of the remaining fields in surface state are ignored
465     *     for null surfaces, with the following exceptions: Width, Height,
466     *     Depth, LOD, and Render Target View Extent fields must match the
467     *     depth buffer’s corresponding state for all render target surfaces,
468     *     including null.
469     */
470    struct intel_context *intel = &brw->intel;
471    struct gl_context *ctx = &intel->ctx;
472    struct gen7_surface_state *surf;
473
474    /* _NEW_BUFFERS */
475    const struct gl_framebuffer *fb = ctx->DrawBuffer;
476
477    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
478                           sizeof(*surf), 32, &brw->wm.surf_offset[unit]);
479    memset(surf, 0, sizeof(*surf));
480
481    surf->ss0.surface_type = BRW_SURFACE_NULL;
482    surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
483
484    surf->ss2.width = fb->Width - 1;
485    surf->ss2.height = fb->Height - 1;
486
487    /* From the Ivy bridge PRM, Vol4 Part1 p65 (Tiled Surface: Programming Notes):
488     *
489     *     If Surface Type is SURFTYPE_NULL, this field must be TRUE.
490     */
491    gen7_set_surface_tiling(surf, I915_TILING_Y);
492
493    gen7_check_surface_setup(surf, true /* is_render_target */);
494 }
495
496 /**
497  * Sets up a surface state structure to point at the given region.
498  * While it is only used for the front/back buffer currently, it should be
499  * usable for further buffers when doing ARB_draw_buffer support.
500  */
501 static void
502 gen7_update_renderbuffer_surface(struct brw_context *brw,
503                                  struct gl_renderbuffer *rb,
504                                  unsigned int unit)
505 {
506    struct intel_context *intel = &brw->intel;
507    struct gl_context *ctx = &intel->ctx;
508    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
509    struct intel_region *region = irb->mt->region;
510    struct gen7_surface_state *surf;
511    uint32_t tile_x, tile_y;
512    gl_format rb_format = intel_rb_format(irb);
513
514    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
515                           sizeof(*surf), 32, &brw->wm.surf_offset[unit]);
516    memset(surf, 0, sizeof(*surf));
517
518    /* Render targets can't use IMS layout */
519    assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
520
521    if (irb->mt->align_h == 4)
522       surf->ss0.vertical_alignment = 1;
523    if (irb->mt->align_w == 8)
524       surf->ss0.horizontal_alignment = 1;
525
526    switch (rb_format) {
527    case MESA_FORMAT_SARGB8:
528       /* _NEW_BUFFERS
529        *
530        * Without GL_EXT_framebuffer_sRGB we shouldn't bind sRGB surfaces to the
531        * blend/update as sRGB.
532        */
533       if (ctx->Color.sRGBEnabled)
534          surf->ss0.surface_format = brw_format_for_mesa_format(rb_format);
535       else
536          surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
537       break;
538    default:
539       assert(brw_render_target_supported(intel, rb));
540       surf->ss0.surface_format = brw->render_target_format[rb_format];
541       if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
542          _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
543                        __FUNCTION__, _mesa_get_format_name(rb_format));
544       }
545        break;
546    }
547
548    surf->ss0.surface_type = BRW_SURFACE_2D;
549    surf->ss0.surface_array_spacing = irb->mt->array_spacing_lod0 ?
550       GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;
551
552    /* reloc */
553    surf->ss1.base_addr = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
554    surf->ss1.base_addr += region->bo->offset; /* reloc */
555
556    assert(brw->has_surface_tile_offset);
557    /* Note that the low bits of these fields are missing, so
558     * there's the possibility of getting in trouble.
559     */
560    assert(tile_x % 4 == 0);
561    assert(tile_y % 2 == 0);
562    surf->ss5.x_offset = tile_x / 4;
563    surf->ss5.y_offset = tile_y / 2;
564
565    surf->ss2.width = rb->Width - 1;
566    surf->ss2.height = rb->Height - 1;
567    gen7_set_surface_tiling(surf, region->tiling);
568    surf->ss3.pitch = (region->pitch * region->cpp) - 1;
569
570    gen7_set_surface_msaa(surf, irb->mt->num_samples, irb->mt->msaa_layout);
571
572    if (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
573       gen7_set_surface_mcs_info(brw, surf, brw->wm.surf_offset[unit],
574                                 irb->mt->mcs_mt, true /* is_render_target */);
575    }
576
577    if (intel->is_haswell) {
578       surf->ss7.shader_channel_select_r = HSW_SCS_RED;
579       surf->ss7.shader_channel_select_g = HSW_SCS_GREEN;
580       surf->ss7.shader_channel_select_b = HSW_SCS_BLUE;
581       surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA;
582    }
583
584    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
585                            brw->wm.surf_offset[unit] +
586                            offsetof(struct gen7_surface_state, ss1),
587                            region->bo,
588                            surf->ss1.base_addr - region->bo->offset,
589                            I915_GEM_DOMAIN_RENDER,
590                            I915_GEM_DOMAIN_RENDER);
591
592    gen7_check_surface_setup(surf, true /* is_render_target */);
593 }
594
595 void
596 gen7_init_vtable_surface_functions(struct brw_context *brw)
597 {
598    struct intel_context *intel = &brw->intel;
599
600    intel->vtbl.update_texture_surface = gen7_update_texture_surface;
601    intel->vtbl.update_renderbuffer_surface = gen7_update_renderbuffer_surface;
602    intel->vtbl.update_null_renderbuffer_surface =
603       gen7_update_null_renderbuffer_surface;
604    intel->vtbl.create_constant_surface = gen7_create_constant_surface;
605 }