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
swizzle_to_scs(GLenum swizzle)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
gen7_set_surface_tiling(struct gen7_surface_state * surf,uint32_t tiling)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
gen7_set_surface_msaa(struct gen7_surface_state * surf,unsigned num_samples,enum intel_msaa_layout layout)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
gen7_set_surface_mcs_info(struct brw_context * brw,struct gen7_surface_state * surf,uint32_t surf_offset,const struct intel_mipmap_tree * mcs_mt,bool is_render_target)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
gen7_check_surface_setup(struct gen7_surface_state * surf,bool is_render_target)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
gen7_update_buffer_texture_surface(struct gl_context * ctx,unsigned unit,uint32_t * binding_table,unsigned surf_index)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
gen7_update_texture_surface(struct gl_context * ctx,unsigned unit,uint32_t * binding_table,unsigned surf_index)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       surf->ss0.cube_pos_x = 1;
333       surf->ss0.cube_pos_y = 1;
334       surf->ss0.cube_pos_z = 1;
335       surf->ss0.cube_neg_x = 1;
336       surf->ss0.cube_neg_y = 1;
337       surf->ss0.cube_neg_z = 1;
338    }
339 
340    surf->ss0.is_array = depth > 1 && tObj->Target != GL_TEXTURE_3D;
341 
342    gen7_set_surface_tiling(surf, intelObj->mt->region->tiling);
343 
344    /* ss0 remaining fields:
345     * - vert_line_stride (exists on gen6 but we ignore it)
346     * - vert_line_stride_ofs (exists on gen6 but we ignore it)
347     * - surface_array_spacing
348     * - render_cache_read_write (exists on gen6 but ignored here)
349     */
350 
351    surf->ss1.base_addr =
352       intelObj->mt->region->bo->offset + intelObj->mt->offset; /* reloc */
353 
354    surf->ss2.width = width - 1;
355    surf->ss2.height = height - 1;
356 
357    surf->ss3.pitch = (intelObj->mt->region->pitch * intelObj->mt->cpp) - 1;
358    surf->ss3.depth = depth - 1;
359 
360    /* ss4: ignored? */
361 
362    surf->ss5.mip_count = intelObj->_MaxLevel - tObj->BaseLevel;
363    surf->ss5.min_lod = 0;
364 
365    /* ss5 remaining fields:
366     * - x_offset (N/A for textures?)
367     * - y_offset (ditto)
368     * - cache_control
369     */
370 
371    if (brw->intel.is_haswell) {
372       /* Handling GL_ALPHA as a surface format override breaks 1.30+ style
373        * texturing functions that return a float, as our code generation always
374        * selects the .x channel (which would always be 0).
375        */
376       const bool alpha_depth = tObj->DepthMode == GL_ALPHA &&
377          (firstImage->_BaseFormat == GL_DEPTH_COMPONENT ||
378           firstImage->_BaseFormat == GL_DEPTH_STENCIL);
379 
380       const int swizzle =
381          unlikely(alpha_depth) ? SWIZZLE_XYZW : brw_get_texture_swizzle(tObj);
382 
383       surf->ss7.shader_channel_select_r = swizzle_to_scs(GET_SWZ(swizzle, 0));
384       surf->ss7.shader_channel_select_g = swizzle_to_scs(GET_SWZ(swizzle, 1));
385       surf->ss7.shader_channel_select_b = swizzle_to_scs(GET_SWZ(swizzle, 2));
386       surf->ss7.shader_channel_select_a = swizzle_to_scs(GET_SWZ(swizzle, 3));
387    }
388 
389    /* Emit relocation to surface contents */
390    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
391 			   binding_table[surf_index] +
392 			   offsetof(struct gen7_surface_state, ss1),
393 			   intelObj->mt->region->bo, intelObj->mt->offset,
394 			   I915_GEM_DOMAIN_SAMPLER, 0);
395 
396    gen7_check_surface_setup(surf, false /* is_render_target */);
397 }
398 
399 /**
400  * Create the constant buffer surface.  Vertex/fragment shader constants will
401  * be read from this buffer with Data Port Read instructions/messages.
402  */
403 void
gen7_create_constant_surface(struct brw_context * brw,drm_intel_bo * bo,uint32_t offset,int width,uint32_t * out_offset)404 gen7_create_constant_surface(struct brw_context *brw,
405 			     drm_intel_bo *bo,
406 			     uint32_t offset,
407 			     int width,
408 			     uint32_t *out_offset)
409 {
410    const GLint w = width - 1;
411    struct gen7_surface_state *surf;
412 
413    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
414 			  sizeof(*surf), 32, out_offset);
415    memset(surf, 0, sizeof(*surf));
416 
417    surf->ss0.surface_type = BRW_SURFACE_BUFFER;
418    surf->ss0.surface_format = BRW_SURFACEFORMAT_R32G32B32A32_FLOAT;
419 
420    surf->ss0.render_cache_read_write = 1;
421 
422    assert(bo);
423    surf->ss1.base_addr = bo->offset + offset; /* reloc */
424 
425    surf->ss2.width = w & 0x7f;            /* bits 6:0 of size or width */
426    surf->ss2.height = (w >> 7) & 0x1fff;  /* bits 19:7 of size or width */
427    surf->ss3.depth = (w >> 20) & 0x7f;    /* bits 26:20 of size or width */
428    surf->ss3.pitch = (16 - 1); /* stride between samples */
429    gen7_set_surface_tiling(surf, I915_TILING_NONE); /* tiling now allowed */
430 
431    if (brw->intel.is_haswell) {
432       surf->ss7.shader_channel_select_r = HSW_SCS_RED;
433       surf->ss7.shader_channel_select_g = HSW_SCS_GREEN;
434       surf->ss7.shader_channel_select_b = HSW_SCS_BLUE;
435       surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA;
436    }
437 
438    /* Emit relocation to surface contents.  Section 5.1.1 of the gen4
439     * bspec ("Data Cache") says that the data cache does not exist as
440     * a separate cache and is just the sampler cache.
441     */
442    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
443 			   (*out_offset +
444 			    offsetof(struct gen7_surface_state, ss1)),
445 			   bo, offset,
446 			   I915_GEM_DOMAIN_SAMPLER, 0);
447 
448    gen7_check_surface_setup(surf, false /* is_render_target */);
449 }
450 
451 static void
gen7_update_null_renderbuffer_surface(struct brw_context * brw,unsigned unit)452 gen7_update_null_renderbuffer_surface(struct brw_context *brw, unsigned unit)
453 {
454    /* From the Ivy bridge PRM, Vol4 Part1 p62 (Surface Type: Programming
455     * Notes):
456     *
457     *     A null surface is used in instances where an actual surface is not
458     *     bound. When a write message is generated to a null surface, no
459     *     actual surface is written to. When a read message (including any
460     *     sampling engine message) is generated to a null surface, the result
461     *     is all zeros. Note that a null surface type is allowed to be used
462     *     with all messages, even if it is not specificially indicated as
463     *     supported. All of the remaining fields in surface state are ignored
464     *     for null surfaces, with the following exceptions: Width, Height,
465     *     Depth, LOD, and Render Target View Extent fields must match the
466     *     depth buffer’s corresponding state for all render target surfaces,
467     *     including null.
468     */
469    struct intel_context *intel = &brw->intel;
470    struct gl_context *ctx = &intel->ctx;
471    struct gen7_surface_state *surf;
472 
473    /* _NEW_BUFFERS */
474    const struct gl_framebuffer *fb = ctx->DrawBuffer;
475 
476    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
477 			  sizeof(*surf), 32, &brw->wm.surf_offset[unit]);
478    memset(surf, 0, sizeof(*surf));
479 
480    surf->ss0.surface_type = BRW_SURFACE_NULL;
481    surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
482 
483    surf->ss2.width = fb->Width - 1;
484    surf->ss2.height = fb->Height - 1;
485 
486    /* From the Ivy bridge PRM, Vol4 Part1 p65 (Tiled Surface: Programming Notes):
487     *
488     *     If Surface Type is SURFTYPE_NULL, this field must be TRUE.
489     */
490    gen7_set_surface_tiling(surf, I915_TILING_Y);
491 
492    gen7_check_surface_setup(surf, true /* is_render_target */);
493 }
494 
495 /**
496  * Sets up a surface state structure to point at the given region.
497  * While it is only used for the front/back buffer currently, it should be
498  * usable for further buffers when doing ARB_draw_buffer support.
499  */
500 static void
gen7_update_renderbuffer_surface(struct brw_context * brw,struct gl_renderbuffer * rb,unsigned int unit)501 gen7_update_renderbuffer_surface(struct brw_context *brw,
502 				 struct gl_renderbuffer *rb,
503 				 unsigned int unit)
504 {
505    struct intel_context *intel = &brw->intel;
506    struct gl_context *ctx = &intel->ctx;
507    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
508    struct intel_region *region = irb->mt->region;
509    struct gen7_surface_state *surf;
510    uint32_t tile_x, tile_y;
511    gl_format rb_format = intel_rb_format(irb);
512 
513    surf = brw_state_batch(brw, AUB_TRACE_SURFACE_STATE,
514 			  sizeof(*surf), 32, &brw->wm.surf_offset[unit]);
515    memset(surf, 0, sizeof(*surf));
516 
517    /* Render targets can't use IMS layout */
518    assert(irb->mt->msaa_layout != INTEL_MSAA_LAYOUT_IMS);
519 
520    if (irb->mt->align_h == 4)
521       surf->ss0.vertical_alignment = 1;
522    if (irb->mt->align_w == 8)
523       surf->ss0.horizontal_alignment = 1;
524 
525    switch (rb_format) {
526    case MESA_FORMAT_SARGB8:
527       /* _NEW_BUFFERS
528        *
529        * Without GL_EXT_framebuffer_sRGB we shouldn't bind sRGB surfaces to the
530        * blend/update as sRGB.
531        */
532       if (ctx->Color.sRGBEnabled)
533 	 surf->ss0.surface_format = brw_format_for_mesa_format(rb_format);
534       else
535 	 surf->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
536       break;
537    default:
538       assert(brw_render_target_supported(intel, rb));
539       surf->ss0.surface_format = brw->render_target_format[rb_format];
540       if (unlikely(!brw->format_supported_as_render_target[rb_format])) {
541 	 _mesa_problem(ctx, "%s: renderbuffer format %s unsupported\n",
542 		       __FUNCTION__, _mesa_get_format_name(rb_format));
543       }
544        break;
545    }
546 
547    surf->ss0.surface_type = BRW_SURFACE_2D;
548    surf->ss0.surface_array_spacing = irb->mt->array_spacing_lod0 ?
549       GEN7_SURFACE_ARYSPC_LOD0 : GEN7_SURFACE_ARYSPC_FULL;
550 
551    /* reloc */
552    surf->ss1.base_addr = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
553    surf->ss1.base_addr += region->bo->offset; /* reloc */
554 
555    assert(brw->has_surface_tile_offset);
556    /* Note that the low bits of these fields are missing, so
557     * there's the possibility of getting in trouble.
558     */
559    assert(tile_x % 4 == 0);
560    assert(tile_y % 2 == 0);
561    surf->ss5.x_offset = tile_x / 4;
562    surf->ss5.y_offset = tile_y / 2;
563 
564    surf->ss2.width = rb->Width - 1;
565    surf->ss2.height = rb->Height - 1;
566    gen7_set_surface_tiling(surf, region->tiling);
567    surf->ss3.pitch = (region->pitch * region->cpp) - 1;
568 
569    gen7_set_surface_msaa(surf, irb->mt->num_samples, irb->mt->msaa_layout);
570 
571    if (irb->mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
572       gen7_set_surface_mcs_info(brw, surf, brw->wm.surf_offset[unit],
573                                 irb->mt->mcs_mt, true /* is_render_target */);
574    }
575 
576    if (intel->is_haswell) {
577       surf->ss7.shader_channel_select_r = HSW_SCS_RED;
578       surf->ss7.shader_channel_select_g = HSW_SCS_GREEN;
579       surf->ss7.shader_channel_select_b = HSW_SCS_BLUE;
580       surf->ss7.shader_channel_select_a = HSW_SCS_ALPHA;
581    }
582 
583    drm_intel_bo_emit_reloc(brw->intel.batch.bo,
584 			   brw->wm.surf_offset[unit] +
585 			   offsetof(struct gen7_surface_state, ss1),
586 			   region->bo,
587 			   surf->ss1.base_addr - region->bo->offset,
588 			   I915_GEM_DOMAIN_RENDER,
589 			   I915_GEM_DOMAIN_RENDER);
590 
591    gen7_check_surface_setup(surf, true /* is_render_target */);
592 }
593 
594 void
gen7_init_vtable_surface_functions(struct brw_context * brw)595 gen7_init_vtable_surface_functions(struct brw_context *brw)
596 {
597    struct intel_context *intel = &brw->intel;
598 
599    intel->vtbl.update_texture_surface = gen7_update_texture_surface;
600    intel->vtbl.update_renderbuffer_surface = gen7_update_renderbuffer_surface;
601    intel->vtbl.update_null_renderbuffer_surface =
602       gen7_update_null_renderbuffer_surface;
603    intel->vtbl.create_constant_surface = gen7_create_constant_surface;
604 }
605