Home | History | Annotate | Download | only in blorp
      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 
     29 #include "blorp_priv.h"
     30 #include "brw_defines.h"
     31 
     32 #include "compiler/nir/nir_builder.h"
     33 
     34 #define FILE_DEBUG_FLAG DEBUG_BLORP
     35 
     36 struct brw_blorp_const_color_prog_key
     37 {
     38    enum blorp_shader_type shader_type; /* Must be BLORP_SHADER_TYPE_CLEAR */
     39    bool use_simd16_replicated_data;
     40    bool pad[3];
     41 };
     42 
     43 static void
     44 blorp_params_get_clear_kernel(struct blorp_context *blorp,
     45                               struct blorp_params *params,
     46                               bool use_replicated_data)
     47 {
     48    const struct brw_blorp_const_color_prog_key blorp_key = {
     49       .shader_type = BLORP_SHADER_TYPE_CLEAR,
     50       .use_simd16_replicated_data = use_replicated_data,
     51    };
     52 
     53    if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key),
     54                             &params->wm_prog_kernel, &params->wm_prog_data))
     55       return;
     56 
     57    void *mem_ctx = ralloc_context(NULL);
     58 
     59    nir_builder b;
     60    nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT, NULL);
     61    b.shader->info->name = ralloc_strdup(b.shader, "BLORP-clear");
     62 
     63    nir_variable *v_color =
     64       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
     65 
     66    nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
     67                                                   glsl_vec4_type(),
     68                                                   "gl_FragColor");
     69    frag_color->data.location = FRAG_RESULT_COLOR;
     70 
     71    nir_copy_var(&b, frag_color, v_color);
     72 
     73    struct brw_wm_prog_key wm_key;
     74    brw_blorp_init_wm_prog_key(&wm_key);
     75 
     76    struct brw_wm_prog_data prog_data;
     77    unsigned program_size;
     78    const unsigned *program =
     79       blorp_compile_fs(blorp, mem_ctx, b.shader, &wm_key, use_replicated_data,
     80                        &prog_data, &program_size);
     81 
     82    blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key),
     83                         program, program_size,
     84                         &prog_data.base, sizeof(prog_data),
     85                         &params->wm_prog_kernel, &params->wm_prog_data);
     86 
     87    ralloc_free(mem_ctx);
     88 }
     89 
     90 struct layer_offset_vs_key {
     91    enum blorp_shader_type shader_type;
     92    unsigned num_inputs;
     93 };
     94 
     95 /* In the case of doing attachment clears, we are using a surface state that
     96  * is handed to us so we can't set (and don't even know) the base array layer.
     97  * In order to do a layered clear in this scenario, we need some way of adding
     98  * the base array layer to the instance id.  Unfortunately, our hardware has
     99  * no real concept of "base instance", so we have to do it manually in a
    100  * vertex shader.
    101  */
    102 static void
    103 blorp_params_get_layer_offset_vs(struct blorp_context *blorp,
    104                                  struct blorp_params *params)
    105 {
    106    struct layer_offset_vs_key blorp_key = {
    107       .shader_type = BLORP_SHADER_TYPE_LAYER_OFFSET_VS,
    108    };
    109 
    110    if (params->wm_prog_data)
    111       blorp_key.num_inputs = params->wm_prog_data->num_varying_inputs;
    112 
    113    if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key),
    114                             &params->vs_prog_kernel, &params->vs_prog_data))
    115       return;
    116 
    117    void *mem_ctx = ralloc_context(NULL);
    118 
    119    nir_builder b;
    120    nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_VERTEX, NULL);
    121    b.shader->info->name = ralloc_strdup(b.shader, "BLORP-layer-offset-vs");
    122 
    123    const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
    124 
    125    /* First we deal with the header which has instance and base instance */
    126    nir_variable *a_header = nir_variable_create(b.shader, nir_var_shader_in,
    127                                                 uvec4_type, "header");
    128    a_header->data.location = VERT_ATTRIB_GENERIC0;
    129 
    130    nir_variable *v_layer = nir_variable_create(b.shader, nir_var_shader_out,
    131                                                glsl_int_type(), "layer_id");
    132    v_layer->data.location = VARYING_SLOT_LAYER;
    133 
    134    /* Compute the layer id */
    135    nir_ssa_def *header = nir_load_var(&b, a_header);
    136    nir_ssa_def *base_layer = nir_channel(&b, header, 0);
    137    nir_ssa_def *instance = nir_channel(&b, header, 1);
    138    nir_store_var(&b, v_layer, nir_iadd(&b, instance, base_layer), 0x1);
    139 
    140    /* Then we copy the vertex from the next slot to VARYING_SLOT_POS */
    141    nir_variable *a_vertex = nir_variable_create(b.shader, nir_var_shader_in,
    142                                                 glsl_vec4_type(), "a_vertex");
    143    a_vertex->data.location = VERT_ATTRIB_GENERIC1;
    144 
    145    nir_variable *v_pos = nir_variable_create(b.shader, nir_var_shader_out,
    146                                              glsl_vec4_type(), "v_pos");
    147    v_pos->data.location = VARYING_SLOT_POS;
    148 
    149    nir_copy_var(&b, v_pos, a_vertex);
    150 
    151    /* Then we copy everything else */
    152    for (unsigned i = 0; i < blorp_key.num_inputs; i++) {
    153       nir_variable *a_in = nir_variable_create(b.shader, nir_var_shader_in,
    154                                                uvec4_type, "input");
    155       a_in->data.location = VERT_ATTRIB_GENERIC2 + i;
    156 
    157       nir_variable *v_out = nir_variable_create(b.shader, nir_var_shader_out,
    158                                                 uvec4_type, "output");
    159       v_out->data.location = VARYING_SLOT_VAR0 + i;
    160 
    161       nir_copy_var(&b, v_out, a_in);
    162    }
    163 
    164    struct brw_vs_prog_data vs_prog_data;
    165    memset(&vs_prog_data, 0, sizeof(vs_prog_data));
    166 
    167    unsigned program_size;
    168    const unsigned *program =
    169       blorp_compile_vs(blorp, mem_ctx, b.shader, &vs_prog_data, &program_size);
    170 
    171    blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key),
    172                         program, program_size,
    173                         &vs_prog_data.base.base, sizeof(vs_prog_data),
    174                         &params->vs_prog_kernel, &params->vs_prog_data);
    175 
    176    ralloc_free(mem_ctx);
    177 }
    178 
    179 /* The x0, y0, x1, and y1 parameters must already be populated with the render
    180  * area of the framebuffer to be cleared.
    181  */
    182 static void
    183 get_fast_clear_rect(const struct isl_device *dev,
    184                     const struct isl_surf *aux_surf,
    185                     unsigned *x0, unsigned *y0,
    186                     unsigned *x1, unsigned *y1)
    187 {
    188    unsigned int x_align, y_align;
    189    unsigned int x_scaledown, y_scaledown;
    190 
    191    /* Only single sampled surfaces need to (and actually can) be resolved. */
    192    if (aux_surf->usage == ISL_SURF_USAGE_CCS_BIT) {
    193       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
    194        * Target(s)", beneath the "Fast Color Clear" bullet (p327):
    195        *
    196        *     Clear pass must have a clear rectangle that must follow
    197        *     alignment rules in terms of pixels and lines as shown in the
    198        *     table below. Further, the clear-rectangle height and width
    199        *     must be multiple of the following dimensions. If the height
    200        *     and width of the render target being cleared do not meet these
    201        *     requirements, an MCS buffer can be created such that it
    202        *     follows the requirement and covers the RT.
    203        *
    204        * The alignment size in the table that follows is related to the
    205        * alignment size that is baked into the CCS surface format but with X
    206        * alignment multiplied by 16 and Y alignment multiplied by 32.
    207        */
    208       x_align = isl_format_get_layout(aux_surf->format)->bw;
    209       y_align = isl_format_get_layout(aux_surf->format)->bh;
    210 
    211       x_align *= 16;
    212 
    213       /* SKL+ line alignment requirement for Y-tiled are half those of the prior
    214        * generations.
    215        */
    216       if (dev->info->gen >= 9)
    217          y_align *= 16;
    218       else
    219          y_align *= 32;
    220 
    221       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
    222        * Target(s)", beneath the "Fast Color Clear" bullet (p327):
    223        *
    224        *     In order to optimize the performance MCS buffer (when bound to
    225        *     1X RT) clear similarly to MCS buffer clear for MSRT case,
    226        *     clear rect is required to be scaled by the following factors
    227        *     in the horizontal and vertical directions:
    228        *
    229        * The X and Y scale down factors in the table that follows are each
    230        * equal to half the alignment value computed above.
    231        */
    232       x_scaledown = x_align / 2;
    233       y_scaledown = y_align / 2;
    234 
    235       /* From BSpec: 3D-Media-GPGPU Engine > 3D Pipeline > Pixel > Pixel
    236        * Backend > MCS Buffer for Render Target(s) [DevIVB+] > Table "Color
    237        * Clear of Non-MultiSampled Render Target Restrictions":
    238        *
    239        *   Clear rectangle must be aligned to two times the number of
    240        *   pixels in the table shown below due to 16x16 hashing across the
    241        *   slice.
    242        */
    243       x_align *= 2;
    244       y_align *= 2;
    245    } else {
    246       assert(aux_surf->usage == ISL_SURF_USAGE_MCS_BIT);
    247 
    248       /* From the Ivy Bridge PRM, Vol2 Part1 11.7 "MCS Buffer for Render
    249        * Target(s)", beneath the "MSAA Compression" bullet (p326):
    250        *
    251        *     Clear pass for this case requires that scaled down primitive
    252        *     is sent down with upper left co-ordinate to coincide with
    253        *     actual rectangle being cleared. For MSAA, clear rectangles
    254        *     height and width need to as show in the following table in
    255        *     terms of (width,height) of the RT.
    256        *
    257        *     MSAA  Width of Clear Rect  Height of Clear Rect
    258        *      2X     Ceil(1/8*width)      Ceil(1/2*height)
    259        *      4X     Ceil(1/8*width)      Ceil(1/2*height)
    260        *      8X     Ceil(1/2*width)      Ceil(1/2*height)
    261        *     16X         width            Ceil(1/2*height)
    262        *
    263        * The text "with upper left co-ordinate to coincide with actual
    264        * rectangle being cleared" is a little confusing--it seems to imply
    265        * that to clear a rectangle from (x,y) to (x+w,y+h), one needs to
    266        * feed the pipeline using the rectangle (x,y) to
    267        * (x+Ceil(w/N),y+Ceil(h/2)), where N is either 2 or 8 depending on
    268        * the number of samples.  Experiments indicate that this is not
    269        * quite correct; actually, what the hardware appears to do is to
    270        * align whatever rectangle is sent down the pipeline to the nearest
    271        * multiple of 2x2 blocks, and then scale it up by a factor of N
    272        * horizontally and 2 vertically.  So the resulting alignment is 4
    273        * vertically and either 4 or 16 horizontally, and the scaledown
    274        * factor is 2 vertically and either 2 or 8 horizontally.
    275        */
    276       switch (aux_surf->format) {
    277       case ISL_FORMAT_MCS_2X:
    278       case ISL_FORMAT_MCS_4X:
    279          x_scaledown = 8;
    280          break;
    281       case ISL_FORMAT_MCS_8X:
    282          x_scaledown = 2;
    283          break;
    284       case ISL_FORMAT_MCS_16X:
    285          x_scaledown = 1;
    286          break;
    287       default:
    288          unreachable("Unexpected MCS format for fast clear");
    289       }
    290       y_scaledown = 2;
    291       x_align = x_scaledown * 2;
    292       y_align = y_scaledown * 2;
    293    }
    294 
    295    *x0 = ROUND_DOWN_TO(*x0,  x_align) / x_scaledown;
    296    *y0 = ROUND_DOWN_TO(*y0, y_align) / y_scaledown;
    297    *x1 = ALIGN(*x1, x_align) / x_scaledown;
    298    *y1 = ALIGN(*y1, y_align) / y_scaledown;
    299 }
    300 
    301 void
    302 blorp_fast_clear(struct blorp_batch *batch,
    303                  const struct blorp_surf *surf, enum isl_format format,
    304                  uint32_t level, uint32_t start_layer, uint32_t num_layers,
    305                  uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
    306 {
    307    struct blorp_params params;
    308    blorp_params_init(&params);
    309    params.num_layers = num_layers;
    310 
    311    params.x0 = x0;
    312    params.y0 = y0;
    313    params.x1 = x1;
    314    params.y1 = y1;
    315 
    316    memset(&params.wm_inputs.clear_color, 0xff, 4*sizeof(float));
    317    params.fast_clear_op = BLORP_FAST_CLEAR_OP_CLEAR;
    318 
    319    get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf,
    320                        &params.x0, &params.y0, &params.x1, &params.y1);
    321 
    322    blorp_params_get_clear_kernel(batch->blorp, &params, true);
    323 
    324    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
    325                                start_layer, format, true);
    326    params.num_samples = params.dst.surf.samples;
    327 
    328    batch->blorp->exec(batch, &params);
    329 }
    330 
    331 static union isl_color_value
    332 swizzle_color_value(union isl_color_value src, struct isl_swizzle swizzle)
    333 {
    334    union isl_color_value dst = { .u32 = { 0, } };
    335 
    336    /* We assign colors in ABGR order so that the first one will be taken in
    337     * RGBA precedence order.  According to the PRM docs for shader channel
    338     * select, this matches Haswell hardware behavior.
    339     */
    340    if ((unsigned)(swizzle.a - ISL_CHANNEL_SELECT_RED) < 4)
    341       dst.u32[swizzle.a - ISL_CHANNEL_SELECT_RED] = src.u32[3];
    342    if ((unsigned)(swizzle.b - ISL_CHANNEL_SELECT_RED) < 4)
    343       dst.u32[swizzle.b - ISL_CHANNEL_SELECT_RED] = src.u32[2];
    344    if ((unsigned)(swizzle.g - ISL_CHANNEL_SELECT_RED) < 4)
    345       dst.u32[swizzle.g - ISL_CHANNEL_SELECT_RED] = src.u32[1];
    346    if ((unsigned)(swizzle.r - ISL_CHANNEL_SELECT_RED) < 4)
    347       dst.u32[swizzle.r - ISL_CHANNEL_SELECT_RED] = src.u32[0];
    348 
    349    return dst;
    350 }
    351 
    352 void
    353 blorp_clear(struct blorp_batch *batch,
    354             const struct blorp_surf *surf,
    355             enum isl_format format, struct isl_swizzle swizzle,
    356             uint32_t level, uint32_t start_layer, uint32_t num_layers,
    357             uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
    358             union isl_color_value clear_color,
    359             const bool color_write_disable[4])
    360 {
    361    struct blorp_params params;
    362    blorp_params_init(&params);
    363 
    364    params.x0 = x0;
    365    params.y0 = y0;
    366    params.x1 = x1;
    367    params.y1 = y1;
    368 
    369    /* Manually apply the clear destination swizzle.  This way swizzled clears
    370     * will work for swizzles which we can't normally use for rendering and it
    371     * also ensures that they work on pre-Haswell hardware which can't swizlle
    372     * at all.
    373     */
    374    clear_color = swizzle_color_value(clear_color, swizzle);
    375    swizzle = ISL_SWIZZLE_IDENTITY;
    376 
    377    if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
    378       clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
    379       format = ISL_FORMAT_R32_UINT;
    380    } else if (format == ISL_FORMAT_A4B4G4R4_UNORM) {
    381       /* Broadwell and earlier cannot render to this format so we need to work
    382        * around it by swapping the colors around and using B4G4R4A4 instead.
    383        */
    384       const struct isl_swizzle ARGB = ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE);
    385       clear_color = swizzle_color_value(clear_color, ARGB);
    386       format = ISL_FORMAT_B4G4R4A4_UNORM;
    387    }
    388 
    389    memcpy(&params.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4);
    390 
    391    bool use_simd16_replicated_data = true;
    392 
    393    /* From the SNB PRM (Vol4_Part1):
    394     *
    395     *     "Replicated data (Message Type = 111) is only supported when
    396     *      accessing tiled memory.  Using this Message Type to access linear
    397     *      (untiled) memory is UNDEFINED."
    398     */
    399    if (surf->surf->tiling == ISL_TILING_LINEAR)
    400       use_simd16_replicated_data = false;
    401 
    402    /* Constant color writes ignore everyting in blend and color calculator
    403     * state.  This is not documented.
    404     */
    405    if (color_write_disable) {
    406       for (unsigned i = 0; i < 4; i++) {
    407          params.color_write_disable[i] = color_write_disable[i];
    408          if (color_write_disable[i])
    409             use_simd16_replicated_data = false;
    410       }
    411    }
    412 
    413    blorp_params_get_clear_kernel(batch->blorp, &params,
    414                                  use_simd16_replicated_data);
    415 
    416    while (num_layers > 0) {
    417       brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
    418                                   start_layer, format, true);
    419       params.dst.view.swizzle = swizzle;
    420 
    421       params.num_samples = params.dst.surf.samples;
    422 
    423       /* We may be restricted on the number of layers we can bind at any one
    424        * time.  In particular, Sandy Bridge has a maximum number of layers of
    425        * 512 but a maximum 3D texture size is much larger.
    426        */
    427       params.num_layers = MIN2(params.dst.view.array_len, num_layers);
    428       batch->blorp->exec(batch, &params);
    429 
    430       start_layer += params.num_layers;
    431       num_layers -= params.num_layers;
    432    }
    433 }
    434 
    435 void
    436 blorp_clear_depth_stencil(struct blorp_batch *batch,
    437                           const struct blorp_surf *depth,
    438                           const struct blorp_surf *stencil,
    439                           uint32_t level, uint32_t start_layer,
    440                           uint32_t num_layers,
    441                           uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
    442                           bool clear_depth, float depth_value,
    443                           uint8_t stencil_mask, uint8_t stencil_value)
    444 {
    445    struct blorp_params params;
    446    blorp_params_init(&params);
    447 
    448    params.x0 = x0;
    449    params.y0 = y0;
    450    params.x1 = x1;
    451    params.y1 = y1;
    452 
    453    while (num_layers > 0) {
    454       params.num_layers = num_layers;
    455 
    456       if (stencil_mask) {
    457          brw_blorp_surface_info_init(batch->blorp, &params.stencil, stencil,
    458                                      level, start_layer,
    459                                      ISL_FORMAT_UNSUPPORTED, true);
    460          params.stencil_mask = stencil_mask;
    461          params.stencil_ref = stencil_value;
    462 
    463          params.dst.surf.samples = params.stencil.surf.samples;
    464          params.dst.surf.logical_level0_px =
    465             params.stencil.surf.logical_level0_px;
    466          params.dst.view = params.depth.view;
    467 
    468          params.num_samples = params.stencil.surf.samples;
    469 
    470          /* We may be restricted on the number of layers we can bind at any
    471           * one time.  In particular, Sandy Bridge has a maximum number of
    472           * layers of 512 but a maximum 3D texture size is much larger.
    473           */
    474          if (params.stencil.view.array_len < params.num_layers)
    475             params.num_layers = params.stencil.view.array_len;
    476       }
    477 
    478       if (clear_depth) {
    479          brw_blorp_surface_info_init(batch->blorp, &params.depth, depth,
    480                                      level, start_layer,
    481                                      ISL_FORMAT_UNSUPPORTED, true);
    482          params.z = depth_value;
    483          params.depth_format =
    484             isl_format_get_depth_format(depth->surf->format, false);
    485 
    486          params.dst.surf.samples = params.depth.surf.samples;
    487          params.dst.surf.logical_level0_px =
    488             params.depth.surf.logical_level0_px;
    489          params.dst.view = params.depth.view;
    490 
    491          params.num_samples = params.depth.surf.samples;
    492 
    493          /* We may be restricted on the number of layers we can bind at any
    494           * one time.  In particular, Sandy Bridge has a maximum number of
    495           * layers of 512 but a maximum 3D texture size is much larger.
    496           */
    497          if (params.depth.view.array_len < params.num_layers)
    498             params.num_layers = params.depth.view.array_len;
    499       }
    500 
    501       batch->blorp->exec(batch, &params);
    502 
    503       start_layer += params.num_layers;
    504       num_layers -= params.num_layers;
    505    }
    506 }
    507 
    508 bool
    509 blorp_can_hiz_clear_depth(uint8_t gen, enum isl_format format,
    510                           uint32_t num_samples,
    511                           uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1)
    512 {
    513    /* This function currently doesn't support any gen prior to gen8 */
    514    assert(gen >= 8);
    515 
    516    if (gen == 8 && format == ISL_FORMAT_R16_UNORM) {
    517       /* Apply the D16 alignment restrictions. On BDW, HiZ has an 8x4 sample
    518        * block with the following property: as the number of samples increases,
    519        * the number of pixels representable by this block decreases by a factor
    520        * of the sample dimensions. Sample dimensions scale following the MSAA
    521        * interleaved pattern.
    522        *
    523        * Sample|Sample|Pixel
    524        * Count |Dim   |Dim
    525        * ===================
    526        *    1  | 1x1  | 8x4
    527        *    2  | 2x1  | 4x4
    528        *    4  | 2x2  | 4x2
    529        *    8  | 4x2  | 2x2
    530        *   16  | 4x4  | 2x1
    531        *
    532        * Table: Pixel Dimensions in a HiZ Sample Block Pre-SKL
    533        */
    534       const struct isl_extent2d sa_block_dim =
    535          isl_get_interleaved_msaa_px_size_sa(num_samples);
    536       const uint8_t align_px_w = 8 / sa_block_dim.w;
    537       const uint8_t align_px_h = 4 / sa_block_dim.h;
    538 
    539       /* Fast depth clears clear an entire sample block at a time. As a result,
    540        * the rectangle must be aligned to the dimensions of the encompassing
    541        * pixel block for a successful operation.
    542        *
    543        * Fast clears can still work if the upper-left corner is aligned and the
    544        * bottom-rigtht corner touches the edge of a depth buffer whose extent
    545        * is unaligned. This is because each miplevel in the depth buffer is
    546        * padded by the Pixel Dim (similar to a standard compressed texture).
    547        * In this case, the clear rectangle could be padded by to match the full
    548        * depth buffer extent but to support multiple clearing techniques, we
    549        * chose to be unaware of the depth buffer's extent and thus don't handle
    550        * this case.
    551        */
    552       if (x0 % align_px_w || y0 % align_px_h ||
    553           x1 % align_px_w || y1 % align_px_h)
    554          return false;
    555    }
    556    return true;
    557 }
    558 
    559 /* Given a depth stencil attachment, this function performs a fast depth clear
    560  * on a depth portion and a regular clear on the stencil portion. When
    561  * performing a fast depth clear on the depth portion, the HiZ buffer is simply
    562  * tagged as cleared so the depth clear value is not actually needed.
    563  */
    564 void
    565 blorp_gen8_hiz_clear_attachments(struct blorp_batch *batch,
    566                                  uint32_t num_samples,
    567                                  uint32_t x0, uint32_t y0,
    568                                  uint32_t x1, uint32_t y1,
    569                                  bool clear_depth, bool clear_stencil,
    570                                  uint8_t stencil_value)
    571 {
    572    assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
    573 
    574    struct blorp_params params;
    575    blorp_params_init(&params);
    576    params.num_layers = 1;
    577    params.hiz_op = BLORP_HIZ_OP_DEPTH_CLEAR;
    578    params.x0 = x0;
    579    params.y0 = y0;
    580    params.x1 = x1;
    581    params.y1 = y1;
    582    params.num_samples = num_samples;
    583    params.depth.enabled = clear_depth;
    584    params.stencil.enabled = clear_stencil;
    585    params.stencil_ref = stencil_value;
    586    batch->blorp->exec(batch, &params);
    587 }
    588 
    589 /** Clear active color/depth/stencili attachments
    590  *
    591  * This function performs a clear operation on the currently bound
    592  * color/depth/stencil attachments.  It is assumed that any information passed
    593  * in here is valid, consistent, and in-bounds relative to the currently
    594  * attached depth/stencil.  The binding_table_offset parameter is the 32-bit
    595  * offset relative to surface state base address where pre-baked binding table
    596  * that we are to use lives.  If clear_color is false, binding_table_offset
    597  * must point to a binding table with one entry which is a valid null surface
    598  * that matches the currently bound depth and stencil.
    599  */
    600 void
    601 blorp_clear_attachments(struct blorp_batch *batch,
    602                         uint32_t binding_table_offset,
    603                         enum isl_format depth_format,
    604                         uint32_t num_samples,
    605                         uint32_t start_layer, uint32_t num_layers,
    606                         uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1,
    607                         bool clear_color, union isl_color_value color_value,
    608                         bool clear_depth, float depth_value,
    609                         uint8_t stencil_mask, uint8_t stencil_value)
    610 {
    611    struct blorp_params params;
    612    blorp_params_init(&params);
    613 
    614    assert(batch->flags & BLORP_BATCH_NO_EMIT_DEPTH_STENCIL);
    615 
    616    params.x0 = x0;
    617    params.y0 = y0;
    618    params.x1 = x1;
    619    params.y1 = y1;
    620 
    621    params.use_pre_baked_binding_table = true;
    622    params.pre_baked_binding_table_offset = binding_table_offset;
    623 
    624    params.num_layers = num_layers;
    625    params.num_samples = num_samples;
    626 
    627    if (clear_color) {
    628       params.dst.enabled = true;
    629 
    630       memcpy(&params.wm_inputs.clear_color, color_value.f32, sizeof(float) * 4);
    631 
    632       /* Unfortunately, without knowing whether or not our destination surface
    633        * is tiled or not, we have to assume it may be linear.  This means no
    634        * SIMD16_REPDATA for us. :-(
    635        */
    636       blorp_params_get_clear_kernel(batch->blorp, &params, false);
    637    }
    638 
    639    if (clear_depth) {
    640       params.depth.enabled = true;
    641 
    642       params.z = depth_value;
    643       params.depth_format = isl_format_get_depth_format(depth_format, false);
    644    }
    645 
    646    if (stencil_mask) {
    647       params.stencil.enabled = true;
    648 
    649       params.stencil_mask = stencil_mask;
    650       params.stencil_ref = stencil_value;
    651    }
    652 
    653    blorp_params_get_layer_offset_vs(batch->blorp, &params);
    654    params.vs_inputs.base_layer = start_layer;
    655 
    656    batch->blorp->exec(batch, &params);
    657 }
    658 
    659 void
    660 blorp_ccs_resolve(struct blorp_batch *batch,
    661                   struct blorp_surf *surf, uint32_t level, uint32_t layer,
    662                   enum isl_format format,
    663                   enum blorp_fast_clear_op resolve_op)
    664 {
    665    struct blorp_params params;
    666    blorp_params_init(&params);
    667 
    668    /* Layered and mipmapped fast clear is only available from Gen8 onwards. */
    669    assert(ISL_DEV_GEN(batch->blorp->isl_dev) >= 8 ||
    670           (level == 0 && layer == 0));
    671 
    672    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf,
    673                                level, layer, format, true);
    674 
    675    /* From the Ivy Bridge PRM, Vol2 Part1 11.9 "Render Target Resolve":
    676     *
    677     *     A rectangle primitive must be scaled down by the following factors
    678     *     with respect to render target being resolved.
    679     *
    680     * The scaledown factors in the table that follows are related to the block
    681     * size of the CCS format.  For IVB and HSW, we divide by two, for BDW we
    682     * multiply by 8 and 16. On Sky Lake, we multiply by 8.
    683     */
    684    const struct isl_format_layout *aux_fmtl =
    685       isl_format_get_layout(params.dst.aux_surf.format);
    686    assert(aux_fmtl->txc == ISL_TXC_CCS);
    687 
    688    unsigned x_scaledown, y_scaledown;
    689    if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 9) {
    690       x_scaledown = aux_fmtl->bw * 8;
    691       y_scaledown = aux_fmtl->bh * 8;
    692    } else if (ISL_DEV_GEN(batch->blorp->isl_dev) >= 8) {
    693       x_scaledown = aux_fmtl->bw * 8;
    694       y_scaledown = aux_fmtl->bh * 16;
    695    } else {
    696       x_scaledown = aux_fmtl->bw / 2;
    697       y_scaledown = aux_fmtl->bh / 2;
    698    }
    699    params.x0 = params.y0 = 0;
    700    params.x1 = minify(params.dst.aux_surf.logical_level0_px.width, level);
    701    params.y1 = minify(params.dst.aux_surf.logical_level0_px.height, level);
    702    params.x1 = ALIGN(params.x1, x_scaledown) / x_scaledown;
    703    params.y1 = ALIGN(params.y1, y_scaledown) / y_scaledown;
    704 
    705    if (batch->blorp->isl_dev->info->gen >= 9) {
    706       assert(resolve_op == BLORP_FAST_CLEAR_OP_RESOLVE_FULL ||
    707              resolve_op == BLORP_FAST_CLEAR_OP_RESOLVE_PARTIAL);
    708    } else {
    709       /* Broadwell and earlier do not have a partial resolve */
    710       assert(resolve_op == BLORP_FAST_CLEAR_OP_RESOLVE_FULL);
    711    }
    712    params.fast_clear_op = resolve_op;
    713 
    714    /* Note: there is no need to initialize push constants because it doesn't
    715     * matter what data gets dispatched to the render target.  However, we must
    716     * ensure that the fragment shader delivers the data using the "replicated
    717     * color" message.
    718     */
    719 
    720    blorp_params_get_clear_kernel(batch->blorp, &params, true);
    721 
    722    batch->blorp->exec(batch, &params);
    723 }
    724