• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 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 
24 #include "util/ralloc.h"
25 
26 #include "main/macros.h" /* Needed for MAX3 and MAX2 for format_rgb9e5 */
27 #include "util/format_rgb9e5.h"
28 #include "util/format_srgb.h"
29 
30 #include "blorp_priv.h"
31 #include "compiler/brw_eu_defines.h"
32 
33 #include "blorp_nir_builder.h"
34 
35 #define FILE_DEBUG_FLAG DEBUG_BLORP
36 
37 #pragma pack(push, 1)
38 struct brw_blorp_const_color_prog_key
39 {
40    enum blorp_shader_type shader_type; /* Must be BLORP_SHADER_TYPE_CLEAR */
41    bool use_simd16_replicated_data;
42    bool clear_rgb_as_red;
43 };
44 #pragma pack(pop)
45 
46 static bool
blorp_params_get_clear_kernel(struct blorp_batch * batch,struct blorp_params * params,bool use_replicated_data,bool clear_rgb_as_red)47 blorp_params_get_clear_kernel(struct blorp_batch *batch,
48                               struct blorp_params *params,
49                               bool use_replicated_data,
50                               bool clear_rgb_as_red)
51 {
52    struct blorp_context *blorp = batch->blorp;
53 
54    const struct brw_blorp_const_color_prog_key blorp_key = {
55       .shader_type = BLORP_SHADER_TYPE_CLEAR,
56       .use_simd16_replicated_data = use_replicated_data,
57       .clear_rgb_as_red = clear_rgb_as_red,
58    };
59 
60    if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
61                             &params->wm_prog_kernel, &params->wm_prog_data))
62       return true;
63 
64    void *mem_ctx = ralloc_context(NULL);
65 
66    nir_builder b;
67    blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT,
68                          blorp_shader_type_to_name(blorp_key.shader_type));
69 
70    nir_variable *v_color =
71       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
72    nir_ssa_def *color = nir_load_var(&b, v_color);
73 
74    if (clear_rgb_as_red) {
75       nir_ssa_def *pos = nir_f2i32(&b, nir_load_frag_coord(&b));
76       nir_ssa_def *comp = nir_umod(&b, nir_channel(&b, pos, 0),
77                                        nir_imm_int(&b, 3));
78       nir_ssa_def *color_component =
79          nir_bcsel(&b, nir_ieq_imm(&b, comp, 0),
80                        nir_channel(&b, color, 0),
81                        nir_bcsel(&b, nir_ieq_imm(&b, comp, 1),
82                                      nir_channel(&b, color, 1),
83                                      nir_channel(&b, color, 2)));
84 
85       nir_ssa_def *u = nir_ssa_undef(&b, 1, 32);
86       color = nir_vec4(&b, color_component, u, u, u);
87    }
88 
89    nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
90                                                   glsl_vec4_type(),
91                                                   "gl_FragColor");
92    frag_color->data.location = FRAG_RESULT_COLOR;
93    nir_store_var(&b, frag_color, color, 0xf);
94 
95    struct brw_wm_prog_key wm_key;
96    brw_blorp_init_wm_prog_key(&wm_key);
97 
98    struct brw_wm_prog_data prog_data;
99    const unsigned *program =
100       blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, use_replicated_data,
101                        &prog_data);
102 
103    bool result =
104       blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
105                            &blorp_key, sizeof(blorp_key),
106                            program, prog_data.base.program_size,
107                            &prog_data.base, sizeof(prog_data),
108                            &params->wm_prog_kernel, &params->wm_prog_data);
109 
110    ralloc_free(mem_ctx);
111    return result;
112 }
113 
114 #pragma pack(push, 1)
115 struct layer_offset_vs_key {
116    enum blorp_shader_type shader_type;
117    unsigned num_inputs;
118 };
119 #pragma pack(pop)
120 
121 /* In the case of doing attachment clears, we are using a surface state that
122  * is handed to us so we can't set (and don't even know) the base array layer.
123  * In order to do a layered clear in this scenario, we need some way of adding
124  * the base array layer to the instance id.  Unfortunately, our hardware has
125  * no real concept of "base instance", so we have to do it manually in a
126  * vertex shader.
127  */
128 static bool
blorp_params_get_layer_offset_vs(struct blorp_batch * batch,struct blorp_params * params)129 blorp_params_get_layer_offset_vs(struct blorp_batch *batch,
130                                  struct blorp_params *params)
131 {
132    struct blorp_context *blorp = batch->blorp;
133    struct layer_offset_vs_key blorp_key = {
134       .shader_type = BLORP_SHADER_TYPE_LAYER_OFFSET_VS,
135    };
136 
137    if (params->wm_prog_data)
138       blorp_key.num_inputs = params->wm_prog_data->num_varying_inputs;
139 
140    if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
141                             &params->vs_prog_kernel, &params->vs_prog_data))
142       return true;
143 
144    void *mem_ctx = ralloc_context(NULL);
145 
146    nir_builder b;
147    blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_VERTEX,
148                          blorp_shader_type_to_name(blorp_key.shader_type));
149 
150    const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
151 
152    /* First we deal with the header which has instance and base instance */
153    nir_variable *a_header = nir_variable_create(b.shader, nir_var_shader_in,
154                                                 uvec4_type, "header");
155    a_header->data.location = VERT_ATTRIB_GENERIC0;
156 
157    nir_variable *v_layer = nir_variable_create(b.shader, nir_var_shader_out,
158                                                glsl_int_type(), "layer_id");
159    v_layer->data.location = VARYING_SLOT_LAYER;
160 
161    /* Compute the layer id */
162    nir_ssa_def *header = nir_load_var(&b, a_header);
163    nir_ssa_def *base_layer = nir_channel(&b, header, 0);
164    nir_ssa_def *instance = nir_channel(&b, header, 1);
165    nir_store_var(&b, v_layer, nir_iadd(&b, instance, base_layer), 0x1);
166 
167    /* Then we copy the vertex from the next slot to VARYING_SLOT_POS */
168    nir_variable *a_vertex = nir_variable_create(b.shader, nir_var_shader_in,
169                                                 glsl_vec4_type(), "a_vertex");
170    a_vertex->data.location = VERT_ATTRIB_GENERIC1;
171 
172    nir_variable *v_pos = nir_variable_create(b.shader, nir_var_shader_out,
173                                              glsl_vec4_type(), "v_pos");
174    v_pos->data.location = VARYING_SLOT_POS;
175 
176    nir_copy_var(&b, v_pos, a_vertex);
177 
178    /* Then we copy everything else */
179    for (unsigned i = 0; i < blorp_key.num_inputs; i++) {
180       nir_variable *a_in = nir_variable_create(b.shader, nir_var_shader_in,
181                                                uvec4_type, "input");
182       a_in->data.location = VERT_ATTRIB_GENERIC2 + i;
183 
184       nir_variable *v_out = nir_variable_create(b.shader, nir_var_shader_out,
185                                                 uvec4_type, "output");
186       v_out->data.location = VARYING_SLOT_VAR0 + i;
187 
188       nir_copy_var(&b, v_out, a_in);
189    }
190 
191    struct brw_vs_prog_data vs_prog_data;
192    memset(&vs_prog_data, 0, sizeof(vs_prog_data));
193 
194    const unsigned *program =
195       blorp_compile_vs(blorp, mem_ctx, b.shader, &vs_prog_data);
196 
197    bool result =
198       blorp->upload_shader(batch, MESA_SHADER_VERTEX,
199                            &blorp_key, sizeof(blorp_key),
200                            program, vs_prog_data.base.base.program_size,
201                            &vs_prog_data.base.base, sizeof(vs_prog_data),
202                            &params->vs_prog_kernel, &params->vs_prog_data);
203 
204    ralloc_free(mem_ctx);
205    return result;
206 }
207 
208 /* The x0, y0, x1, and y1 parameters must already be populated with the render
209  * area of the framebuffer to be cleared.
210  */
211 static void
get_fast_clear_rect(const struct isl_device * dev,const struct isl_surf * aux_surf,unsigned * x0,unsigned * y0,unsigned * x1,unsigned * y1)212 get_fast_clear_rect(const struct isl_device *dev,
213                     const struct isl_surf *aux_surf,
214                     unsigned *x0, unsigned *y0,
215                     unsigned *x1, unsigned *y1)
216 {
217    unsigned int x_align, y_align;
218    unsigned int x_scaledown, y_scaledown;
219 
220    /* Only single sampled surfaces need to (and actually can) be resolved. */
221    if (aux_surf->usage == ISL_SURF_USAGE_CCS_BIT) {
222       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
223        * Target(s)", beneath the "Fast Color Clear" bullet (p327):
224        *
225        *     Clear pass must have a clear rectangle that must follow
226        *     alignment rules in terms of pixels and lines as shown in the
227        *     table below. Further, the clear-rectangle height and width
228        *     must be multiple of the following dimensions. If the height
229        *     and width of the render target being cleared do not meet these
230        *     requirements, an MCS buffer can be created such that it
231        *     follows the requirement and covers the RT.
232        *
233        * The alignment size in the table that follows is related to the
234        * alignment size that is baked into the CCS surface format but with X
235        * alignment multiplied by 16 and Y alignment multiplied by 32.
236        */
237       x_align = isl_format_get_layout(aux_surf->format)->bw;
238       y_align = isl_format_get_layout(aux_surf->format)->bh;
239 
240       x_align *= 16;
241 
242       /* The line alignment requirement for Y-tiled is halved at SKL and again
243        * at TGL.
244        */
245       if (dev->info->gen >= 12)
246          y_align *= 8;
247       else if (dev->info->gen >= 9)
248          y_align *= 16;
249       else
250          y_align *= 32;
251 
252       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
253        * Target(s)", beneath the "Fast Color Clear" bullet (p327):
254        *
255        *     In order to optimize the performance MCS buffer (when bound to
256        *     1X RT) clear similarly to MCS buffer clear for MSRT case,
257        *     clear rect is required to be scaled by the following factors
258        *     in the horizontal and vertical directions:
259        *
260        * The X and Y scale down factors in the table that follows are each
261        * equal to half the alignment value computed above.
262        */
263       x_scaledown = x_align / 2;
264       y_scaledown = y_align / 2;
265 
266       if (ISL_DEV_IS_HASWELL(dev)) {
267          /* From BSpec: 3D-Media-GPGPU Engine > 3D Pipeline > Pixel > Pixel
268           * Backend > MCS Buffer for Render Target(s) [DevIVB+] > Table "Color
269           * Clear of Non-MultiSampled Render Target Restrictions":
270           *
271           *   Clear rectangle must be aligned to two times the number of
272           *   pixels in the table shown below due to 16x16 hashing across the
273           *   slice.
274           *
275           * This restriction is only documented to exist on HSW GT3 but
276           * empirical evidence suggests that it's also needed GT2.
277           */
278          x_align *= 2;
279          y_align *= 2;
280       }
281    } else {
282       assert(aux_surf->usage == ISL_SURF_USAGE_MCS_BIT);
283 
284       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
285        * Target(s)", beneath the "MSAA Compression" bullet (p326):
286        *
287        *     Clear pass for this case requires that scaled down primitive
288        *     is sent down with upper left co-ordinate to coincide with
289        *     actual rectangle being cleared. For MSAA, clear rectangle’s
290        *     height and width need to as show in the following table in
291        *     terms of (width,height) of the RT.
292        *
293        *     MSAA  Width of Clear Rect  Height of Clear Rect
294        *      2X     Ceil(1/8*width)      Ceil(1/2*height)
295        *      4X     Ceil(1/8*width)      Ceil(1/2*height)
296        *      8X     Ceil(1/2*width)      Ceil(1/2*height)
297        *     16X         width            Ceil(1/2*height)
298        *
299        * The text "with upper left co-ordinate to coincide with actual
300        * rectangle being cleared" is a little confusing--it seems to imply
301        * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
302        * feed the pipeline using the rectangle (x,y) to
303        * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
304        * the number of samples.  Experiments indicate that this is not
305        * quite correct; actually, what the hardware appears to do is to
306        * align whatever rectangle is sent down the pipeline to the nearest
307        * multiple of 2x2 blocks, and then scale it up by a factor of N
308        * horizontally and 2 vertically.  So the resulting alignment is 4
309        * vertically and either 4 or 16 horizontally, and the scaledown
310        * factor is 2 vertically and either 2 or 8 horizontally.
311        */
312       switch (aux_surf->format) {
313       case ISL_FORMAT_MCS_2X:
314       case ISL_FORMAT_MCS_4X:
315          x_scaledown = 8;
316          break;
317       case ISL_FORMAT_MCS_8X:
318          x_scaledown = 2;
319          break;
320       case ISL_FORMAT_MCS_16X:
321          x_scaledown = 1;
322          break;
323       default:
324          unreachable("Unexpected MCS format for fast clear");
325       }
326       y_scaledown = 2;
327       x_align = x_scaledown * 2;
328       y_align = y_scaledown * 2;
329    }
330 
331    *x0 = ROUND_DOWN_TO(*x0,  x_align) / x_scaledown;
332    *y0 = ROUND_DOWN_TO(*y0, y_align) / y_scaledown;
333    *x1 = ALIGN(*x1, x_align) / x_scaledown;
334    *y1 = ALIGN(*y1, y_align) / y_scaledown;
335 }
336 
337 void
blorp_fast_clear(struct blorp_batch * batch,const struct blorp_surf * surf,enum isl_format format,struct isl_swizzle swizzle,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1)338 blorp_fast_clear(struct blorp_batch *batch,
339                  const struct blorp_surf *surf,
340                  enum isl_format format, struct isl_swizzle swizzle,
341                  uint32_t level, uint32_t start_layer, uint32_t num_layers,
342                  uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
343 {
344    struct blorp_params params;
345    blorp_params_init(&params);
346    params.num_layers = num_layers;
347 
348    params.x0 = x0;
349    params.y0 = y0;
350    params.x1 = x1;
351    params.y1 = y1;
352 
353    memset(&params.wm_inputs.clear_color, 0xff, 4*sizeof(float));
354    params.fast_clear_op = ISL_AUX_OP_FAST_CLEAR;
355 
356    get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf,
357                        &params.x0, &params.y0, &params.x1, &params.y1);
358 
359    if (!blorp_params_get_clear_kernel(batch, &params, true, false))
360       return;
361 
362    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
363                                start_layer, format, true);
364    params.num_samples = params.dst.surf.samples;
365 
366    /* If a swizzle was provided, we need to swizzle the clear color so that
367     * the hardware color format conversion will work properly.
368     */
369    params.dst.clear_color =
370       isl_color_value_swizzle_inv(params.dst.clear_color, swizzle);
371 
372    batch->blorp->exec(batch, &params);
373 }
374 
375 void
blorp_clear(struct blorp_batch * batch,const struct blorp_surf * surf,enum isl_format format,struct isl_swizzle swizzle,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,union isl_color_value clear_color,const bool color_write_disable[4])376 blorp_clear(struct blorp_batch *batch,
377             const struct blorp_surf *surf,
378             enum isl_format format, struct isl_swizzle swizzle,
379             uint32_t level, uint32_t start_layer, uint32_t num_layers,
380             uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
381             union isl_color_value clear_color,
382             const bool color_write_disable[4])
383 {
384    struct blorp_params params;
385    blorp_params_init(&params);
386 
387    /* Manually apply the clear destination swizzle.  This way swizzled clears
388     * will work for swizzles which we can't normally use for rendering and it
389     * also ensures that they work on pre-Haswell hardware which can't swizlle
390     * at all.
391     */
392    clear_color = isl_color_value_swizzle_inv(clear_color, swizzle);
393    swizzle = ISL_SWIZZLE_IDENTITY;
394 
395    bool clear_rgb_as_red = false;
396    if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
397       clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
398       format = ISL_FORMAT_R32_UINT;
399    } else if (format == ISL_FORMAT_L8_UNORM_SRGB) {
400       clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
401       format = ISL_FORMAT_R8_UNORM;
402    } else if (format == ISL_FORMAT_A4B4G4R4_UNORM) {
403       /* Broadwell and earlier cannot render to this format so we need to work
404        * around it by swapping the colors around and using B4G4R4A4 instead.
405        */
406       const struct isl_swizzle ARGB = ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE);
407       clear_color = isl_color_value_swizzle_inv(clear_color, ARGB);
408       format = ISL_FORMAT_B4G4R4A4_UNORM;
409    } else if (isl_format_get_layout(format)->bpb % 3 == 0) {
410       clear_rgb_as_red = true;
411       if (format == ISL_FORMAT_R8G8B8_UNORM_SRGB) {
412          clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
413          clear_color.f32[1] = util_format_linear_to_srgb_float(clear_color.f32[1]);
414          clear_color.f32[2] = util_format_linear_to_srgb_float(clear_color.f32[2]);
415       }
416    }
417 
418    memcpy(&params.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4);
419 
420    bool use_simd16_replicated_data = true;
421 
422    /* From the SNB PRM (Vol4_Part1):
423     *
424     *     "Replicated data (Message Type = 111) is only supported when
425     *      accessing tiled memory.  Using this Message Type to access linear
426     *      (untiled) memory is UNDEFINED."
427     */
428    if (surf->surf->tiling == ISL_TILING_LINEAR)
429       use_simd16_replicated_data = false;
430 
431    /* Replicated clears don't work yet before gen6 */
432    if (batch->blorp->isl_dev->info->gen < 6)
433       use_simd16_replicated_data = false;
434 
435    /* Constant color writes ignore everyting in blend and color calculator
436     * state.  This is not documented.
437     */
438    if (color_write_disable) {
439       for (unsigned i = 0; i < 4; i++) {
440          params.color_write_disable[i] = color_write_disable[i];
441          if (color_write_disable[i])
442             use_simd16_replicated_data = false;
443       }
444    }
445 
446    if (!blorp_params_get_clear_kernel(batch, &params,
447                                       use_simd16_replicated_data,
448                                       clear_rgb_as_red))
449       return;
450 
451    if (!blorp_ensure_sf_program(batch, &params))
452       return;
453 
454    while (num_layers > 0) {
455       brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
456                                   start_layer, format, true);
457       params.dst.view.swizzle = swizzle;
458 
459       params.x0 = x0;
460       params.y0 = y0;
461       params.x1 = x1;
462       params.y1 = y1;
463 
464       if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
465          assert(params.dst.surf.samples == 1);
466          assert(num_layers == 1);
467          params.x0 += params.dst.tile_x_sa;
468          params.y0 += params.dst.tile_y_sa;
469          params.x1 += params.dst.tile_x_sa;
470          params.y1 += params.dst.tile_y_sa;
471       }
472 
473       /* The MinLOD and MinimumArrayElement don't work properly for cube maps.
474        * Convert them to a single slice on gen4.
475        */
476       if (batch->blorp->isl_dev->info->gen == 4 &&
477           (params.dst.surf.usage & ISL_SURF_USAGE_CUBE_BIT)) {
478          blorp_surf_convert_to_single_slice(batch->blorp->isl_dev, &params.dst);
479       }
480 
481       if (clear_rgb_as_red) {
482          surf_fake_rgb_with_red(batch->blorp->isl_dev, &params.dst);
483          params.x0 *= 3;
484          params.x1 *= 3;
485       }
486 
487       if (isl_format_is_compressed(params.dst.surf.format)) {
488          blorp_surf_convert_to_uncompressed(batch->blorp->isl_dev, &params.dst,
489                                             NULL, NULL, NULL, NULL);
490                                             //&dst_x, &dst_y, &dst_w, &dst_h);
491       }
492 
493       if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
494          /* Either we're on gen4 where there is no multisampling or the
495           * surface is compressed which also implies no multisampling.
496           * Therefore, sa == px and we don't need to do a conversion.
497           */
498          assert(params.dst.surf.samples == 1);
499          params.x0 += params.dst.tile_x_sa;
500          params.y0 += params.dst.tile_y_sa;
501          params.x1 += params.dst.tile_x_sa;
502          params.y1 += params.dst.tile_y_sa;
503       }
504 
505       params.num_samples = params.dst.surf.samples;
506 
507       /* We may be restricted on the number of layers we can bind at any one
508        * time.  In particular, Sandy Bridge has a maximum number of layers of
509        * 512 but a maximum 3D texture size is much larger.
510        */
511       params.num_layers = MIN2(params.dst.view.array_len, num_layers);
512 
513       const unsigned max_image_width = 16 * 1024;
514       if (params.dst.surf.logical_level0_px.width > max_image_width) {
515          /* Clearing an RGB image as red multiplies the surface width by 3
516           * so it may now be too wide for the hardware surface limits.  We
517           * have to break the clear up into pieces in order to clear wide
518           * images.
519           */
520          assert(clear_rgb_as_red);
521          assert(params.dst.surf.dim == ISL_SURF_DIM_2D);
522          assert(params.dst.surf.tiling == ISL_TILING_LINEAR);
523          assert(params.dst.surf.logical_level0_px.depth == 1);
524          assert(params.dst.surf.logical_level0_px.array_len == 1);
525          assert(params.dst.surf.levels == 1);
526          assert(params.dst.surf.samples == 1);
527          assert(params.dst.tile_x_sa == 0 || params.dst.tile_y_sa == 0);
528          assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE);
529 
530          /* max_image_width rounded down to a multiple of 3 */
531          const unsigned max_fake_rgb_width = (max_image_width / 3) * 3;
532          const unsigned cpp =
533             isl_format_get_layout(params.dst.surf.format)->bpb / 8;
534 
535          params.dst.surf.logical_level0_px.width = max_fake_rgb_width;
536          params.dst.surf.phys_level0_sa.width = max_fake_rgb_width;
537 
538          uint32_t orig_x0 = params.x0, orig_x1 = params.x1;
539          uint64_t orig_offset = params.dst.addr.offset;
540          for (uint32_t x = orig_x0; x < orig_x1; x += max_fake_rgb_width) {
541             /* Offset to the surface.  It's easy because we're linear */
542             params.dst.addr.offset = orig_offset + x * cpp;
543 
544             params.x0 = 0;
545             params.x1 = MIN2(orig_x1 - x, max_image_width);
546 
547             batch->blorp->exec(batch, &params);
548          }
549       } else {
550          batch->blorp->exec(batch, &params);
551       }
552 
553       start_layer += params.num_layers;
554       num_layers -= params.num_layers;
555    }
556 }
557 
558 static bool
blorp_clear_stencil_as_rgba(struct blorp_batch * batch,const struct blorp_surf * surf,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,uint8_t stencil_mask,uint8_t stencil_value)559 blorp_clear_stencil_as_rgba(struct blorp_batch *batch,
560                             const struct blorp_surf *surf,
561                             uint32_t level, uint32_t start_layer,
562                             uint32_t num_layers,
563                             uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
564                             uint8_t stencil_mask, uint8_t stencil_value)
565 {
566    /* We only support separate W-tiled stencil for now */
567    if (surf->surf->format != ISL_FORMAT_R8_UINT ||
568        surf->surf->tiling != ISL_TILING_W)
569       return false;
570 
571    /* Stencil mask support would require piles of shader magic */
572    if (stencil_mask != 0xff)
573       return false;
574 
575    if (surf->surf->samples > 1) {
576       /* Adjust x0, y0, x1, and y1 to be in units of samples */
577       assert(surf->surf->msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED);
578       struct isl_extent2d msaa_px_size_sa =
579          isl_get_interleaved_msaa_px_size_sa(surf->surf->samples);
580 
581       x0 *= msaa_px_size_sa.w;
582       y0 *= msaa_px_size_sa.h;
583       x1 *= msaa_px_size_sa.w;
584       y1 *= msaa_px_size_sa.h;
585    }
586 
587    /* W-tiles and Y-tiles have the same layout as far as cache lines are
588     * concerned: both are 8x8 cache lines laid out Y-major.  The difference is
589     * entirely in how the data is arranged withing the cache line.  W-tiling
590     * is 8x8 pixels in a swizzled pattern while Y-tiling is 16B by 4 rows
591     * regardless of image format size.  As long as everything is aligned to 8,
592     * we can just treat the W-tiled image as Y-tiled, ignore the layout
593     * difference within a cache line, and blast out data.
594     */
595    if (x0 % 8 != 0 || y0 % 8 != 0 || x1 % 8 != 0 || y1 % 8 != 0)
596       return false;
597 
598    struct blorp_params params;
599    blorp_params_init(&params);
600 
601    if (!blorp_params_get_clear_kernel(batch, &params, true, false))
602       return false;
603 
604    memset(&params.wm_inputs.clear_color, stencil_value,
605           sizeof(params.wm_inputs.clear_color));
606 
607    /* The Sandy Bridge PRM Vol. 4 Pt. 2, section 2.11.2.1.1 has the
608     * following footnote to the format table:
609     *
610     *    128 BPE Formats cannot be Tiled Y when used as render targets
611     *
612     * We have to use RGBA16_UINT on SNB.
613     */
614    enum isl_format wide_format;
615    if (ISL_DEV_GEN(batch->blorp->isl_dev) <= 6) {
616       wide_format = ISL_FORMAT_R16G16B16A16_UINT;
617 
618       /* For RGBA16_UINT, we need to mask the stencil value otherwise, we risk
619        * clamping giving us the wrong values
620        */
621       for (unsigned i = 0; i < 4; i++)
622          params.wm_inputs.clear_color[i] &= 0xffff;
623    } else {
624       wide_format = ISL_FORMAT_R32G32B32A32_UINT;
625    }
626 
627    for (uint32_t a = 0; a < num_layers; a++) {
628       uint32_t layer = start_layer + a;
629 
630       brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
631                                   layer, ISL_FORMAT_UNSUPPORTED, true);
632 
633       if (surf->surf->samples > 1)
634          blorp_surf_fake_interleaved_msaa(batch->blorp->isl_dev, &params.dst);
635 
636       /* Make it Y-tiled */
637       blorp_surf_retile_w_to_y(batch->blorp->isl_dev, &params.dst);
638 
639       unsigned wide_Bpp =
640          isl_format_get_layout(wide_format)->bpb / 8;
641 
642       params.dst.view.format = params.dst.surf.format = wide_format;
643       assert(params.dst.surf.logical_level0_px.width % wide_Bpp == 0);
644       params.dst.surf.logical_level0_px.width /= wide_Bpp;
645       assert(params.dst.tile_x_sa % wide_Bpp == 0);
646       params.dst.tile_x_sa /= wide_Bpp;
647 
648       params.x0 = params.dst.tile_x_sa + x0 / (wide_Bpp / 2);
649       params.y0 = params.dst.tile_y_sa + y0 / 2;
650       params.x1 = params.dst.tile_x_sa + x1 / (wide_Bpp / 2);
651       params.y1 = params.dst.tile_y_sa + y1 / 2;
652 
653       batch->blorp->exec(batch, &params);
654    }
655 
656    return true;
657 }
658 
659 void
blorp_clear_depth_stencil(struct blorp_batch * batch,const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,float depth_value,uint8_t stencil_mask,uint8_t stencil_value)660 blorp_clear_depth_stencil(struct blorp_batch *batch,
661                           const struct blorp_surf *depth,
662                           const struct blorp_surf *stencil,
663                           uint32_t level, uint32_t start_layer,
664                           uint32_t num_layers,
665                           uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
666                           bool clear_depth, float depth_value,
667                           uint8_t stencil_mask, uint8_t stencil_value)
668 {
669    if (!clear_depth && blorp_clear_stencil_as_rgba(batch, stencil, level,
670                                                    start_layer, num_layers,
671                                                    x0, y0, x1, y1,
672                                                    stencil_mask,
673                                                    stencil_value))
674       return;
675 
676    struct blorp_params params;
677    blorp_params_init(&params);
678 
679    params.x0 = x0;
680    params.y0 = y0;
681    params.x1 = x1;
682    params.y1 = y1;
683 
684    if (ISL_DEV_GEN(batch->blorp->isl_dev) == 6) {
685       /* For some reason, Sandy Bridge gets occlusion queries wrong if we
686        * don't have a shader.  In particular, it records samples even though
687        * we disable statistics in 3DSTATE_WM.  Give it the usual clear shader
688        * to work around the issue.
689        */
690       if (!blorp_params_get_clear_kernel(batch, &params, false, false))
691          return;
692    }
693 
694    while (num_layers > 0) {
695       params.num_layers = num_layers;
696 
697       if (stencil_mask) {
698          brw_blorp_surface_info_init(batch->blorp, &params.stencil, stencil,
699                                      level, start_layer,
700                                      ISL_FORMAT_UNSUPPORTED, true);
701          params.stencil_mask = stencil_mask;
702          params.stencil_ref = stencil_value;
703 
704          params.dst.surf.samples = params.stencil.surf.samples;
705          params.dst.surf.logical_level0_px =
706             params.stencil.surf.logical_level0_px;
707          params.dst.view = params.stencil.view;
708 
709          params.num_samples = params.stencil.surf.samples;
710 
711          /* We may be restricted on the number of layers we can bind at any
712           * one time.  In particular, Sandy Bridge has a maximum number of
713           * layers of 512 but a maximum 3D texture size is much larger.
714           */
715          if (params.stencil.view.array_len < params.num_layers)
716             params.num_layers = params.stencil.view.array_len;
717       }
718 
719       if (clear_depth) {
720          brw_blorp_surface_info_init(batch->blorp, &params.depth, depth,
721                                      level, start_layer,
722                                      ISL_FORMAT_UNSUPPORTED, true);
723          params.z = depth_value;
724          params.depth_format =
725             isl_format_get_depth_format(depth->surf->format, false);
726 
727          params.dst.surf.samples = params.depth.surf.samples;
728          params.dst.surf.logical_level0_px =
729             params.depth.surf.logical_level0_px;
730          params.dst.view = params.depth.view;
731 
732          params.num_samples = params.depth.surf.samples;
733 
734          /* We may be restricted on the number of layers we can bind at any
735           * one time.  In particular, Sandy Bridge has a maximum number of
736           * layers of 512 but a maximum 3D texture size is much larger.
737           */
738          if (params.depth.view.array_len < params.num_layers)
739             params.num_layers = params.depth.view.array_len;
740       }
741 
742       batch->blorp->exec(batch, &params);
743 
744       start_layer += params.num_layers;
745       num_layers -= params.num_layers;
746    }
747 }
748 
749 bool
blorp_can_hiz_clear_depth(const struct gen_device_info * devinfo,const struct isl_surf * surf,enum isl_aux_usage aux_usage,uint32_t level,uint32_t layer,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1)750 blorp_can_hiz_clear_depth(const struct gen_device_info *devinfo,
751                           const struct isl_surf *surf,
752                           enum isl_aux_usage aux_usage,
753                           uint32_t level, uint32_t layer,
754                           uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
755 {
756    /* This function currently doesn't support any gen prior to gen8 */
757    assert(devinfo->gen >= 8);
758 
759    if (devinfo->gen == 8 && surf->format == ISL_FORMAT_R16_UNORM) {
760       /* Apply the D16 alignment restrictions. On BDW, HiZ has an 8x4 sample
761        * block with the following property: as the number of samples increases,
762        * the number of pixels representable by this block decreases by a factor
763        * of the sample dimensions. Sample dimensions scale following the MSAA
764        * interleaved pattern.
765        *
766        * Sample|Sample|Pixel
767        * Count |Dim   |Dim
768        * ===================
769        *    1  | 1x1  | 8x4
770        *    2  | 2x1  | 4x4
771        *    4  | 2x2  | 4x2
772        *    8  | 4x2  | 2x2
773        *   16  | 4x4  | 2x1
774        *
775        * Table: Pixel Dimensions in a HiZ Sample Block Pre-SKL
776        */
777       const struct isl_extent2d sa_block_dim =
778          isl_get_interleaved_msaa_px_size_sa(surf->samples);
779       const uint8_t align_px_w = 8 / sa_block_dim.w;
780       const uint8_t align_px_h = 4 / sa_block_dim.h;
781 
782       /* Fast depth clears clear an entire sample block at a time. As a result,
783        * the rectangle must be aligned to the dimensions of the encompassing
784        * pixel block for a successful operation.
785        *
786        * Fast clears can still work if the upper-left corner is aligned and the
787        * bottom-rigtht corner touches the edge of a depth buffer whose extent
788        * is unaligned. This is because each miplevel in the depth buffer is
789        * padded by the Pixel Dim (similar to a standard compressed texture).
790        * In this case, the clear rectangle could be padded by to match the full
791        * depth buffer extent but to support multiple clearing techniques, we
792        * chose to be unaware of the depth buffer's extent and thus don't handle
793        * this case.
794        */
795       if (x0 % align_px_w || y0 % align_px_h ||
796           x1 % align_px_w || y1 % align_px_h)
797          return false;
798    } else if (aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT) {
799       /* We have to set the WM_HZ_OP::FullSurfaceDepthandStencilClear bit
800        * whenever we clear an uninitialized HIZ buffer (as some drivers
801        * currently do). However, this bit seems liable to clear 16x8 pixels in
802        * the ZCS on Gen12 - greater than the slice alignments for depth
803        * buffers.
804        */
805       assert(surf->image_alignment_el.w % 16 != 0 ||
806              surf->image_alignment_el.h % 8 != 0);
807 
808       /* This is the hypothesis behind some corruption that was seen with the
809        * amd_vertex_shader_layer-layered-depth-texture-render piglit test.
810        *
811        * From the Compressed Depth Buffers section of the Bspec, under the
812        * Gen12 texture performant and ZCS columns:
813        *
814        *    Update with clear at either 16x8 or 8x4 granularity, based on
815        *    fs_clr or otherwise.
816        *
817        * There are a number of ways to avoid full surface CCS clears that
818        * overlap other slices, but for now we choose to disable fast-clears
819        * when an initializing clear could hit another miplevel.
820        *
821        * NOTE: Because the CCS compresses the depth buffer and not a version
822        * of it that has been rearranged with different alignments (like Gen8+
823        * HIZ), we have to make sure that the x0 and y0 are at least 16x8
824        * aligned in the context of the entire surface.
825        */
826       uint32_t slice_x0, slice_y0;
827       isl_surf_get_image_offset_el(surf, level,
828                                    surf->dim == ISL_SURF_DIM_3D ? 0 : layer,
829                                    surf->dim == ISL_SURF_DIM_3D ? layer: 0,
830                                    &slice_x0, &slice_y0);
831       const bool max_x1_y1 =
832          x1 == minify(surf->logical_level0_px.width, level) &&
833          y1 == minify(surf->logical_level0_px.height, level);
834       const uint32_t haligned_x1 = ALIGN(x1, surf->image_alignment_el.w);
835       const uint32_t valigned_y1 = ALIGN(y1, surf->image_alignment_el.h);
836       const bool unaligned = (slice_x0 + x0) % 16 || (slice_y0 + y0) % 8 ||
837                              (max_x1_y1 ? haligned_x1 % 16 || valigned_y1 % 8 :
838                               x1 % 16 || y1 % 8);
839       const bool partial_clear = x0 > 0 || y0 > 0 || !max_x1_y1;
840       const bool multislice_surf = surf->levels > 1 ||
841                                    surf->logical_level0_px.depth > 1 ||
842                                    surf->logical_level0_px.array_len > 1;
843 
844       if (unaligned && (partial_clear || multislice_surf))
845          return false;
846    }
847 
848    return isl_aux_usage_has_hiz(aux_usage);
849 }
850 
851 static bool
blorp_can_clear_full_surface(const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,bool clear_stencil)852 blorp_can_clear_full_surface(const struct blorp_surf *depth,
853                              const struct blorp_surf *stencil,
854                              uint32_t level,
855                              uint32_t x0, uint32_t y0,
856                              uint32_t x1, uint32_t y1,
857                              bool clear_depth,
858                              bool clear_stencil)
859 {
860    uint32_t width = 0, height = 0;
861    if (clear_stencil) {
862       width = minify(stencil->surf->logical_level0_px.width, level);
863       height = minify(stencil->surf->logical_level0_px.height, level);
864    }
865 
866    if (clear_depth && !(width || height)) {
867       width = minify(depth->surf->logical_level0_px.width, level);
868       height = minify(depth->surf->logical_level0_px.height, level);
869    }
870 
871    return x0 == 0 && y0 == 0 && width == x1 && height == y1;
872 }
873 
874 void
blorp_hiz_clear_depth_stencil(struct blorp_batch * batch,const struct blorp_surf * depth,const struct blorp_surf * stencil,uint32_t level,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,float depth_value,bool clear_stencil,uint8_t stencil_value)875 blorp_hiz_clear_depth_stencil(struct blorp_batch *batch,
876                               const struct blorp_surf *depth,
877                               const struct blorp_surf *stencil,
878                               uint32_t level,
879                               uint32_t start_layer, uint32_t num_layers,
880                               uint32_t x0, uint32_t y0,
881                               uint32_t x1, uint32_t y1,
882                               bool clear_depth, float depth_value,
883                               bool clear_stencil, uint8_t stencil_value)
884 {
885    struct blorp_params params;
886    blorp_params_init(&params);
887 
888    /* This requires WM_HZ_OP which only exists on gen8+ */
889    assert(ISL_DEV_GEN(batch->blorp->isl_dev) >= 8);
890 
891    params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
892    /* From BSpec: 3DSTATE_WM_HZ_OP_BODY >> Full Surface Depth and Stencil Clear
893     *
894     *    "Software must set this only when the APP requires the entire Depth
895     *    surface to be cleared."
896     */
897    params.full_surface_hiz_op =
898       blorp_can_clear_full_surface(depth, stencil, level, x0, y0, x1, y1,
899                                    clear_depth, clear_stencil);
900    params.num_layers = 1;
901 
902    params.x0 = x0;
903    params.y0 = y0;
904    params.x1 = x1;
905    params.y1 = y1;
906 
907    for (uint32_t l = 0; l < num_layers; l++) {
908       const uint32_t layer = start_layer + l;
909       if (clear_stencil) {
910          brw_blorp_surface_info_init(batch->blorp, &params.stencil, stencil,
911                                      level, layer,
912                                      ISL_FORMAT_UNSUPPORTED, true);
913          params.stencil_mask = 0xff;
914          params.stencil_ref = stencil_value;
915          params.num_samples = params.stencil.surf.samples;
916       }
917 
918       if (clear_depth) {
919          /* If we're clearing depth, we must have HiZ */
920          assert(depth && isl_aux_usage_has_hiz(depth->aux_usage));
921 
922          brw_blorp_surface_info_init(batch->blorp, &params.depth, depth,
923                                      level, layer,
924                                      ISL_FORMAT_UNSUPPORTED, true);
925          params.depth.clear_color.f32[0] = depth_value;
926          params.depth_format =
927             isl_format_get_depth_format(depth->surf->format, false);
928          params.num_samples = params.depth.surf.samples;
929       }
930 
931       batch->blorp->exec(batch, &params);
932    }
933 }
934 
935 /* Given a depth stencil attachment, this function performs a fast depth clear
936  * on a depth portion and a regular clear on the stencil portion. When
937  * performing a fast depth clear on the depth portion, the HiZ buffer is simply
938  * tagged as cleared so the depth clear value is not actually needed.
939  */
940 void
blorp_gen8_hiz_clear_attachments(struct blorp_batch * batch,uint32_t num_samples,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_depth,bool clear_stencil,uint8_t stencil_value)941 blorp_gen8_hiz_clear_attachments(struct blorp_batch *batch,
942                                  uint32_t num_samples,
943                                  uint32_t x0, uint32_t y0,
944                                  uint32_t x1, uint32_t y1,
945                                  bool clear_depth, bool clear_stencil,
946                                  uint8_t stencil_value)
947 {
948    assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
949 
950    struct blorp_params params;
951    blorp_params_init(&params);
952    params.num_layers = 1;
953    params.hiz_op = ISL_AUX_OP_FAST_CLEAR;
954    params.x0 = x0;
955    params.y0 = y0;
956    params.x1 = x1;
957    params.y1 = y1;
958    params.num_samples = num_samples;
959    params.depth.enabled = clear_depth;
960    params.stencil.enabled = clear_stencil;
961    params.stencil_ref = stencil_value;
962    batch->blorp->exec(batch, &params);
963 }
964 
965 /** Clear active color/depth/stencili attachments
966  *
967  * This function performs a clear operation on the currently bound
968  * color/depth/stencil attachments.  It is assumed that any information passed
969  * in here is valid, consistent, and in-bounds relative to the currently
970  * attached depth/stencil.  The binding_table_offset parameter is the 32-bit
971  * offset relative to surface state base address where pre-baked binding table
972  * that we are to use lives.  If clear_color is false, binding_table_offset
973  * must point to a binding table with one entry which is a valid null surface
974  * that matches the currently bound depth and stencil.
975  */
976 void
blorp_clear_attachments(struct blorp_batch * batch,uint32_t binding_table_offset,enum isl_format depth_format,uint32_t num_samples,uint32_t start_layer,uint32_t num_layers,uint32_t x0,uint32_t y0,uint32_t x1,uint32_t y1,bool clear_color,union isl_color_value color_value,bool clear_depth,float depth_value,uint8_t stencil_mask,uint8_t stencil_value)977 blorp_clear_attachments(struct blorp_batch *batch,
978                         uint32_t binding_table_offset,
979                         enum isl_format depth_format,
980                         uint32_t num_samples,
981                         uint32_t start_layer, uint32_t num_layers,
982                         uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
983                         bool clear_color, union isl_color_value color_value,
984                         bool clear_depth, float depth_value,
985                         uint8_t stencil_mask, uint8_t stencil_value)
986 {
987    struct blorp_params params;
988    blorp_params_init(&params);
989 
990    assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
991 
992    params.x0 = x0;
993    params.y0 = y0;
994    params.x1 = x1;
995    params.y1 = y1;
996 
997    params.use_pre_baked_binding_table = true;
998    params.pre_baked_binding_table_offset = binding_table_offset;
999 
1000    params.num_layers = num_layers;
1001    params.num_samples = num_samples;
1002 
1003    if (clear_color) {
1004       params.dst.enabled = true;
1005 
1006       memcpy(&params.wm_inputs.clear_color, color_value.f32, sizeof(float) * 4);
1007 
1008       /* Unfortunately, without knowing whether or not our destination surface
1009        * is tiled or not, we have to assume it may be linear.  This means no
1010        * SIMD16_REPDATA for us. :-(
1011        */
1012       if (!blorp_params_get_clear_kernel(batch, &params, false, false))
1013          return;
1014    }
1015 
1016    if (clear_depth) {
1017       params.depth.enabled = true;
1018 
1019       params.z = depth_value;
1020       params.depth_format = isl_format_get_depth_format(depth_format, false);
1021    }
1022 
1023    if (stencil_mask) {
1024       params.stencil.enabled = true;
1025 
1026       params.stencil_mask = stencil_mask;
1027       params.stencil_ref = stencil_value;
1028    }
1029 
1030    if (!blorp_params_get_layer_offset_vs(batch, &params))
1031       return;
1032 
1033    params.vs_inputs.base_layer = start_layer;
1034 
1035    batch->blorp->exec(batch, &params);
1036 }
1037 
1038 void
blorp_ccs_resolve(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t level,uint32_t start_layer,uint32_t num_layers,enum isl_format format,enum isl_aux_op resolve_op)1039 blorp_ccs_resolve(struct blorp_batch *batch,
1040                   struct blorp_surf *surf, uint32_t level,
1041                   uint32_t start_layer, uint32_t num_layers,
1042                   enum isl_format format,
1043                   enum isl_aux_op resolve_op)
1044 {
1045    struct blorp_params params;
1046 
1047    blorp_params_init(&params);
1048    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf,
1049                                level, start_layer, format, true);
1050 
1051    /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
1052     *
1053     *     A rectangle primitive must be scaled down by the following factors
1054     *     with respect to render target being resolved.
1055     *
1056     * The scaledown factors in the table that follows are related to the block
1057     * size of the CCS format.  For IVB and HSW, we divide by two, for BDW we
1058     * multiply by 8 and 16. On Sky Lake, we multiply by 8.
1059     */
1060    const struct isl_format_layout *aux_fmtl =
1061       isl_format_get_layout(params.dst.aux_surf.format);
1062    assert(aux_fmtl->txc == ISL_TXC_CCS);
1063 
1064    unsigned x_scaledown, y_scaledown;
1065    if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 12) {
1066       x_scaledown = aux_fmtl->bw * 8;
1067       y_scaledown = aux_fmtl->bh * 4;
1068    } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 9) {
1069       x_scaledown = aux_fmtl->bw * 8;
1070       y_scaledown = aux_fmtl->bh * 8;
1071    } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
1072       x_scaledown = aux_fmtl->bw * 8;
1073       y_scaledown = aux_fmtl->bh * 16;
1074    } else {
1075       x_scaledown = aux_fmtl->bw / 2;
1076       y_scaledown = aux_fmtl->bh / 2;
1077    }
1078    params.x0 = params.y0 = 0;
1079    params.x1 = minify(params.dst.surf.logical_level0_px.width, level);
1080    params.y1 = minify(params.dst.surf.logical_level0_px.height, level);
1081    params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown;
1082    params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown;
1083 
1084    if (batch->blorp->isl_dev->info->gen >= 10) {
1085       assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1086              resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE ||
1087              resolve_op == ISL_AUX_OP_AMBIGUATE);
1088    } else if (batch->blorp->isl_dev->info->gen >= 9) {
1089       assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE ||
1090              resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE);
1091    } else {
1092       /* Broadwell and earlier do not have a partial resolve */
1093       assert(resolve_op == ISL_AUX_OP_FULL_RESOLVE);
1094    }
1095    params.fast_clear_op = resolve_op;
1096    params.num_layers = num_layers;
1097 
1098    /* Note: there is no need to initialize push constants because it doesn't
1099     * matter what data gets dispatched to the render target.  However, we must
1100     * ensure that the fragment shader delivers the data using the "replicated
1101     * color" message.
1102     */
1103 
1104    if (!blorp_params_get_clear_kernel(batch, &params, true, false))
1105       return;
1106 
1107    batch->blorp->exec(batch, &params);
1108 }
1109 
1110 static nir_ssa_def *
blorp_nir_bit(nir_builder * b,nir_ssa_def * src,unsigned bit)1111 blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit)
1112 {
1113    return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)),
1114                       nir_imm_int(b, 1));
1115 }
1116 
1117 #pragma pack(push, 1)
1118 struct blorp_mcs_partial_resolve_key
1119 {
1120    enum blorp_shader_type shader_type;
1121    bool indirect_clear_color;
1122    bool int_format;
1123    uint32_t num_samples;
1124 };
1125 #pragma pack(pop)
1126 
1127 static bool
blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch * batch,struct blorp_params * params)1128 blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch *batch,
1129                                             struct blorp_params *params)
1130 {
1131    struct blorp_context *blorp = batch->blorp;
1132    const struct blorp_mcs_partial_resolve_key blorp_key = {
1133       .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE,
1134       .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL,
1135       .int_format = isl_format_has_int_channel(params->dst.view.format),
1136       .num_samples = params->num_samples,
1137    };
1138 
1139    if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
1140                             &params->wm_prog_kernel, &params->wm_prog_data))
1141       return true;
1142 
1143    void *mem_ctx = ralloc_context(NULL);
1144 
1145    nir_builder b;
1146    blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT,
1147                          blorp_shader_type_to_name(blorp_key.shader_type));
1148 
1149    nir_variable *v_color =
1150       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
1151 
1152    nir_variable *frag_color =
1153       nir_variable_create(b.shader, nir_var_shader_out,
1154                           glsl_vec4_type(), "gl_FragColor");
1155    frag_color->data.location = FRAG_RESULT_COLOR;
1156 
1157    /* Do an MCS fetch and check if it is equal to the magic clear value */
1158    nir_ssa_def *mcs =
1159       blorp_nir_txf_ms_mcs(&b, nir_f2i32(&b, nir_load_frag_coord(&b)),
1160                                nir_load_layer_id(&b));
1161    nir_ssa_def *is_clear =
1162       blorp_nir_mcs_is_clear_color(&b, mcs, blorp_key.num_samples);
1163 
1164    /* If we aren't the clear value, discard. */
1165    nir_intrinsic_instr *discard =
1166       nir_intrinsic_instr_create(b.shader, nir_intrinsic_discard_if);
1167    discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear));
1168    nir_builder_instr_insert(&b, &discard->instr);
1169 
1170    nir_ssa_def *clear_color = nir_load_var(&b, v_color);
1171    if (blorp_key.indirect_clear_color && blorp->isl_dev->info->gen <= 8) {
1172       /* Gen7-8 clear colors are stored as single 0/1 bits */
1173       clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),
1174                                  blorp_nir_bit(&b, clear_color, 30),
1175                                  blorp_nir_bit(&b, clear_color, 29),
1176                                  blorp_nir_bit(&b, clear_color, 28));
1177 
1178       if (!blorp_key.int_format)
1179          clear_color = nir_i2f32(&b, clear_color);
1180    }
1181    nir_store_var(&b, frag_color, clear_color, 0xf);
1182 
1183    struct brw_wm_prog_key wm_key;
1184    brw_blorp_init_wm_prog_key(&wm_key);
1185    wm_key.base.tex.compressed_multisample_layout_mask = 1;
1186    wm_key.base.tex.msaa_16 = blorp_key.num_samples == 16;
1187    wm_key.multisample_fbo = true;
1188 
1189    struct brw_wm_prog_data prog_data;
1190    const unsigned *program =
1191       blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, false,
1192                        &prog_data);
1193 
1194    bool result =
1195       blorp->upload_shader(batch, MESA_SHADER_FRAGMENT,
1196                            &blorp_key, sizeof(blorp_key),
1197                            program, prog_data.base.program_size,
1198                            &prog_data.base, sizeof(prog_data),
1199                            &params->wm_prog_kernel, &params->wm_prog_data);
1200 
1201    ralloc_free(mem_ctx);
1202    return result;
1203 }
1204 
1205 void
blorp_mcs_partial_resolve(struct blorp_batch * batch,struct blorp_surf * surf,enum isl_format format,uint32_t start_layer,uint32_t num_layers)1206 blorp_mcs_partial_resolve(struct blorp_batch *batch,
1207                           struct blorp_surf *surf,
1208                           enum isl_format format,
1209                           uint32_t start_layer, uint32_t num_layers)
1210 {
1211    struct blorp_params params;
1212    blorp_params_init(&params);
1213 
1214    assert(batch->blorp->isl_dev->info->gen >= 7);
1215 
1216    params.x0 = 0;
1217    params.y0 = 0;
1218    params.x1 = surf->surf->logical_level0_px.width;
1219    params.y1 = surf->surf->logical_level0_px.height;
1220 
1221    brw_blorp_surface_info_init(batch->blorp, &params.src, surf, 0,
1222                                start_layer, format, false);
1223    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, 0,
1224                                start_layer, format, true);
1225 
1226    params.num_samples = params.dst.surf.samples;
1227    params.num_layers = num_layers;
1228    params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL;
1229 
1230    memcpy(&params.wm_inputs.clear_color,
1231           surf->clear_color.f32, sizeof(float) * 4);
1232 
1233    if (!blorp_params_get_mcs_partial_resolve_kernel(batch, &params))
1234       return;
1235 
1236    batch->blorp->exec(batch, &params);
1237 }
1238 
1239 /** Clear a CCS to the "uncompressed" state
1240  *
1241  * This pass is the CCS equivalent of a "HiZ resolve".  It sets the CCS values
1242  * for a given layer/level of a surface to 0x0 which is the "uncompressed"
1243  * state which tells the sampler to go look at the main surface.
1244  */
1245 void
blorp_ccs_ambiguate(struct blorp_batch * batch,struct blorp_surf * surf,uint32_t level,uint32_t layer)1246 blorp_ccs_ambiguate(struct blorp_batch *batch,
1247                     struct blorp_surf *surf,
1248                     uint32_t level, uint32_t layer)
1249 {
1250    if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 10) {
1251       /* On gen10 and above, we have a hardware resolve op for this */
1252       return blorp_ccs_resolve(batch, surf, level, layer, 1,
1253                                surf->surf->format, ISL_AUX_OP_AMBIGUATE);
1254    }
1255 
1256    struct blorp_params params;
1257    blorp_params_init(&params);
1258 
1259    assert(ISL_DEV_GEN(batch->blorp->isl_dev) >= 7);
1260 
1261    const struct isl_format_layout *aux_fmtl =
1262       isl_format_get_layout(surf->aux_surf->format);
1263    assert(aux_fmtl->txc == ISL_TXC_CCS);
1264 
1265    params.dst = (struct brw_blorp_surface_info) {
1266       .enabled = true,
1267       .addr = surf->aux_addr,
1268       .view = {
1269          .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1270          .format = ISL_FORMAT_R32G32B32A32_UINT,
1271          .base_level = 0,
1272          .base_array_layer = 0,
1273          .levels = 1,
1274          .array_len = 1,
1275          .swizzle = ISL_SWIZZLE_IDENTITY,
1276       },
1277    };
1278 
1279    uint32_t z = 0;
1280    if (surf->surf->dim == ISL_SURF_DIM_3D) {
1281       z = layer;
1282       layer = 0;
1283    }
1284 
1285    uint32_t offset_B, x_offset_el, y_offset_el;
1286    isl_surf_get_image_offset_el(surf->aux_surf, level, layer, z,
1287                                 &x_offset_el, &y_offset_el);
1288    isl_tiling_get_intratile_offset_el(surf->aux_surf->tiling, aux_fmtl->bpb,
1289                                       surf->aux_surf->row_pitch_B,
1290                                       x_offset_el, y_offset_el,
1291                                       &offset_B, &x_offset_el, &y_offset_el);
1292    params.dst.addr.offset += offset_B;
1293 
1294    const uint32_t width_px =
1295       minify(surf->aux_surf->logical_level0_px.width, level);
1296    const uint32_t height_px =
1297       minify(surf->aux_surf->logical_level0_px.height, level);
1298    const uint32_t width_el = DIV_ROUND_UP(width_px, aux_fmtl->bw);
1299    const uint32_t height_el = DIV_ROUND_UP(height_px, aux_fmtl->bh);
1300 
1301    struct isl_tile_info ccs_tile_info;
1302    isl_surf_get_tile_info(surf->aux_surf, &ccs_tile_info);
1303 
1304    /* We're going to map it as a regular RGBA32_UINT surface.  We need to
1305     * downscale a good deal.  We start by computing the area on the CCS to
1306     * clear in units of Y-tiled cache lines.
1307     */
1308    uint32_t x_offset_cl, y_offset_cl, width_cl, height_cl;
1309    if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
1310       /* From the Sky Lake PRM Vol. 12 in the section on planes:
1311        *
1312        *    "The Color Control Surface (CCS) contains the compression status
1313        *    of the cache-line pairs. The compression state of the cache-line
1314        *    pair is specified by 2 bits in the CCS.  Each CCS cache-line
1315        *    represents an area on the main surface of 16x16 sets of 128 byte
1316        *    Y-tiled cache-line-pairs. CCS is always Y tiled."
1317        *
1318        * Each 2-bit surface element in the CCS corresponds to a single
1319        * cache-line pair in the main surface.  This means that 16x16 el block
1320        * in the CCS maps to a Y-tiled cache line.  Fortunately, CCS layouts
1321        * are calculated with a very large alignment so we can round up to a
1322        * whole cache line without worrying about overdraw.
1323        */
1324 
1325       /* On Broadwell and above, a CCS tile is the same as a Y tile when
1326        * viewed at the cache-line granularity.  Fortunately, the horizontal
1327        * and vertical alignment requirements of the CCS are such that we can
1328        * align to an entire cache line without worrying about crossing over
1329        * from one LOD to another.
1330        */
1331       const uint32_t x_el_per_cl = ccs_tile_info.logical_extent_el.w / 8;
1332       const uint32_t y_el_per_cl = ccs_tile_info.logical_extent_el.h / 8;
1333       assert(surf->aux_surf->image_alignment_el.w % x_el_per_cl == 0);
1334       assert(surf->aux_surf->image_alignment_el.h % y_el_per_cl == 0);
1335 
1336       assert(x_offset_el % x_el_per_cl == 0);
1337       assert(y_offset_el % y_el_per_cl == 0);
1338       x_offset_cl = x_offset_el / x_el_per_cl;
1339       y_offset_cl = y_offset_el / y_el_per_cl;
1340       width_cl = DIV_ROUND_UP(width_el, x_el_per_cl);
1341       height_cl = DIV_ROUND_UP(height_el, y_el_per_cl);
1342    } else {
1343       /* On gen7, the CCS tiling is not so nice.  However, there we are
1344        * guaranteed that we only have a single level and slice so we don't
1345        * have to worry about it and can just align to a whole tile.
1346        */
1347       assert(surf->aux_surf->logical_level0_px.depth == 1);
1348       assert(surf->aux_surf->logical_level0_px.array_len == 1);
1349       assert(x_offset_el == 0 && y_offset_el == 0);
1350       const uint32_t width_tl =
1351          DIV_ROUND_UP(width_el, ccs_tile_info.logical_extent_el.w);
1352       const uint32_t height_tl =
1353          DIV_ROUND_UP(height_el, ccs_tile_info.logical_extent_el.h);
1354       x_offset_cl = 0;
1355       y_offset_cl = 0;
1356       width_cl = width_tl * 8;
1357       height_cl = height_tl * 8;
1358    }
1359 
1360    /* We're going to use a RGBA32 format so as to write data as quickly as
1361     * possible.  A y-tiled cache line will then be 1x4 px.
1362     */
1363    const uint32_t x_offset_rgba_px = x_offset_cl;
1364    const uint32_t y_offset_rgba_px = y_offset_cl * 4;
1365    const uint32_t width_rgba_px = width_cl;
1366    const uint32_t height_rgba_px = height_cl * 4;
1367 
1368    ASSERTED bool ok =
1369       isl_surf_init(batch->blorp->isl_dev, &params.dst.surf,
1370                     .dim = ISL_SURF_DIM_2D,
1371                     .format = ISL_FORMAT_R32G32B32A32_UINT,
1372                     .width = width_rgba_px + x_offset_rgba_px,
1373                     .height = height_rgba_px + y_offset_rgba_px,
1374                     .depth = 1,
1375                     .levels = 1,
1376                     .array_len = 1,
1377                     .samples = 1,
1378                     .row_pitch_B = surf->aux_surf->row_pitch_B,
1379                     .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
1380                     .tiling_flags = ISL_TILING_Y0_BIT);
1381    assert(ok);
1382 
1383    params.x0 = x_offset_rgba_px;
1384    params.y0 = y_offset_rgba_px;
1385    params.x1 = x_offset_rgba_px + width_rgba_px;
1386    params.y1 = y_offset_rgba_px + height_rgba_px;
1387 
1388    /* A CCS value of 0 means "uncompressed." */
1389    memset(&params.wm_inputs.clear_color, 0,
1390           sizeof(params.wm_inputs.clear_color));
1391 
1392    if (!blorp_params_get_clear_kernel(batch, &params, true, false))
1393       return;
1394 
1395    batch->blorp->exec(batch, &params);
1396 }
1397