vulkan/util: meson build - add wayland client include
[mesa.git] / src / intel / blorp / blorp_clear.c
index dde116fa2609422d4ef9a52b262c091302fbae68..657f5970d489e49d7c271d2ad4f1225233c0d01d 100644 (file)
@@ -38,38 +38,62 @@ struct brw_blorp_const_color_prog_key
 {
    enum blorp_shader_type shader_type; /* Must be BLORP_SHADER_TYPE_CLEAR */
    bool use_simd16_replicated_data;
+   bool clear_rgb_as_red;
    bool pad[3];
 };
 
 static bool
-blorp_params_get_clear_kernel(struct blorp_context *blorp,
+blorp_params_get_clear_kernel(struct blorp_batch *batch,
                               struct blorp_params *params,
-                              bool use_replicated_data)
+                              bool use_replicated_data,
+                              bool clear_rgb_as_red)
 {
+   struct blorp_context *blorp = batch->blorp;
+
    const struct brw_blorp_const_color_prog_key blorp_key = {
       .shader_type = BLORP_SHADER_TYPE_CLEAR,
       .use_simd16_replicated_data = use_replicated_data,
+      .clear_rgb_as_red = clear_rgb_as_red,
    };
 
-   if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key),
+   if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
                             &params->wm_prog_kernel, &params->wm_prog_data))
       return true;
 
    void *mem_ctx = ralloc_context(NULL);
 
    nir_builder b;
-   nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT, NULL);
-   b.shader->info.name = ralloc_strdup(b.shader, "BLORP-clear");
+   blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT, "BLORP-clear");
 
    nir_variable *v_color =
       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
+   nir_ssa_def *color = nir_load_var(&b, v_color);
+
+   if (clear_rgb_as_red) {
+      nir_variable *frag_coord =
+         nir_variable_create(b.shader, nir_var_shader_in,
+                             glsl_vec4_type(), "gl_FragCoord");
+      frag_coord->data.location = VARYING_SLOT_POS;
+
+      nir_ssa_def *pos = nir_f2i32(&b, nir_load_var(&b, frag_coord));
+      nir_ssa_def *comp = nir_umod(&b, nir_channel(&b, pos, 0),
+                                       nir_imm_int(&b, 3));
+      nir_ssa_def *color_component =
+         nir_bcsel(&b, nir_ieq(&b, comp, nir_imm_int(&b, 0)),
+                       nir_channel(&b, color, 0),
+                       nir_bcsel(&b, nir_ieq(&b, comp, nir_imm_int(&b, 1)),
+                                     nir_channel(&b, color, 1),
+                                     nir_channel(&b, color, 2)));
+
+      nir_ssa_def *u = nir_ssa_undef(&b, 1, 32);
+      color = nir_vec4(&b, color_component, u, u, u);
+   }
 
    nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out,
                                                   glsl_vec4_type(),
                                                   "gl_FragColor");
    frag_color->data.location = FRAG_RESULT_COLOR;
-
-   nir_copy_var(&b, frag_color, v_color);
+   nir_store_var(&b, frag_color, color, 0xf);
 
    struct brw_wm_prog_key wm_key;
    brw_blorp_init_wm_prog_key(&wm_key);
@@ -80,7 +104,7 @@ blorp_params_get_clear_kernel(struct blorp_context *blorp,
                        &prog_data);
 
    bool result =
-      blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key),
+      blorp->upload_shader(batch, &blorp_key, sizeof(blorp_key),
                            program, prog_data.base.program_size,
                            &prog_data.base, sizeof(prog_data),
                            &params->wm_prog_kernel, &params->wm_prog_data);
@@ -102,9 +126,10 @@ struct layer_offset_vs_key {
  * vertex shader.
  */
 static bool
-blorp_params_get_layer_offset_vs(struct blorp_context *blorp,
+blorp_params_get_layer_offset_vs(struct blorp_batch *batch,
                                  struct blorp_params *params)
 {
+   struct blorp_context *blorp = batch->blorp;
    struct layer_offset_vs_key blorp_key = {
       .shader_type = BLORP_SHADER_TYPE_LAYER_OFFSET_VS,
    };
@@ -112,15 +137,14 @@ blorp_params_get_layer_offset_vs(struct blorp_context *blorp,
    if (params->wm_prog_data)
       blorp_key.num_inputs = params->wm_prog_data->num_varying_inputs;
 
-   if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key),
+   if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
                             &params->vs_prog_kernel, &params->vs_prog_data))
       return true;
 
    void *mem_ctx = ralloc_context(NULL);
 
    nir_builder b;
-   nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_VERTEX, NULL);
-   b.shader->info.name = ralloc_strdup(b.shader, "BLORP-layer-offset-vs");
+   blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_VERTEX, "BLORP-layer-offset-vs");
 
    const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
 
@@ -170,7 +194,7 @@ blorp_params_get_layer_offset_vs(struct blorp_context *blorp,
       blorp_compile_vs(blorp, mem_ctx, b.shader, &vs_prog_data);
 
    bool result =
-      blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key),
+      blorp->upload_shader(batch, &blorp_key, sizeof(blorp_key),
                            program, vs_prog_data.base.base.program_size,
                            &vs_prog_data.base.base, sizeof(vs_prog_data),
                            &params->vs_prog_kernel, &params->vs_prog_data);
@@ -327,7 +351,7 @@ blorp_fast_clear(struct blorp_batch *batch,
    get_fast_clear_rect(batch->blorp->isl_dev, surf->aux_surf,
                        &params.x0, &params.y0, &params.x1, &params.y1);
 
-   if (!blorp_params_get_clear_kernel(batch->blorp, &params, true))
+   if (!blorp_params_get_clear_kernel(batch, &params, true, false))
       return;
 
    brw_blorp_surface_info_init(batch->blorp, &params.dst, surf, level,
@@ -378,6 +402,7 @@ blorp_clear(struct blorp_batch *batch,
    clear_color = swizzle_color_value(clear_color, swizzle);
    swizzle = ISL_SWIZZLE_IDENTITY;
 
+   bool clear_rgb_as_red = false;
    if (format == ISL_FORMAT_R9G9B9E5_SHAREDEXP) {
       clear_color.u32[0] = float3_to_rgb9e5(clear_color.f32);
       format = ISL_FORMAT_R32_UINT;
@@ -391,6 +416,13 @@ blorp_clear(struct blorp_batch *batch,
       const struct isl_swizzle ARGB = ISL_SWIZZLE(ALPHA, RED, GREEN, BLUE);
       clear_color = swizzle_color_value(clear_color, ARGB);
       format = ISL_FORMAT_B4G4R4A4_UNORM;
+   } else if (isl_format_get_layout(format)->bpb % 3 == 0) {
+      clear_rgb_as_red = true;
+      if (format == ISL_FORMAT_R8G8B8_UNORM_SRGB) {
+         clear_color.f32[0] = util_format_linear_to_srgb_float(clear_color.f32[0]);
+         clear_color.f32[1] = util_format_linear_to_srgb_float(clear_color.f32[1]);
+         clear_color.f32[2] = util_format_linear_to_srgb_float(clear_color.f32[2]);
+      }
    }
 
    memcpy(&params.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4);
@@ -421,11 +453,12 @@ blorp_clear(struct blorp_batch *batch,
       }
    }
 
-   if (!blorp_params_get_clear_kernel(batch->blorp, &params,
-                                      use_simd16_replicated_data))
+   if (!blorp_params_get_clear_kernel(batch, &params,
+                                      use_simd16_replicated_data,
+                                      clear_rgb_as_red))
       return;
 
-   if (!blorp_ensure_sf_program(batch->blorp, &params))
+   if (!blorp_ensure_sf_program(batch, &params))
       return;
 
    while (num_layers > 0) {
@@ -438,6 +471,15 @@ blorp_clear(struct blorp_batch *batch,
       params.x1 = x1;
       params.y1 = y1;
 
+      if (params.dst.tile_x_sa || params.dst.tile_y_sa) {
+         assert(params.dst.surf.samples == 1);
+         assert(num_layers == 1);
+         params.x0 += params.dst.tile_x_sa;
+         params.y0 += params.dst.tile_y_sa;
+         params.x1 += params.dst.tile_x_sa;
+         params.y1 += params.dst.tile_y_sa;
+      }
+
       /* The MinLOD and MinimumArrayElement don't work properly for cube maps.
        * Convert them to a single slice on gen4.
        */
@@ -446,6 +488,12 @@ blorp_clear(struct blorp_batch *batch,
          blorp_surf_convert_to_single_slice(batch->blorp->isl_dev, &params.dst);
       }
 
+      if (clear_rgb_as_red) {
+         surf_fake_rgb_with_red(batch->blorp->isl_dev, &params.dst);
+         params.x0 *= 3;
+         params.x1 *= 3;
+      }
+
       if (isl_format_is_compressed(params.dst.surf.format)) {
          blorp_surf_convert_to_uncompressed(batch->blorp->isl_dev, &params.dst,
                                             NULL, NULL, NULL, NULL);
@@ -471,7 +519,46 @@ blorp_clear(struct blorp_batch *batch,
        * 512 but a maximum 3D texture size is much larger.
        */
       params.num_layers = MIN2(params.dst.view.array_len, num_layers);
-      batch->blorp->exec(batch, &params);
+
+      const unsigned max_image_width = 16 * 1024;
+      if (params.dst.surf.logical_level0_px.width > max_image_width) {
+         /* Clearing an RGB image as red multiplies the surface width by 3
+          * so it may now be too wide for the hardware surface limits.  We
+          * have to break the clear up into pieces in order to clear wide
+          * images.
+          */
+         assert(clear_rgb_as_red);
+         assert(params.dst.surf.dim == ISL_SURF_DIM_2D);
+         assert(params.dst.surf.tiling == ISL_TILING_LINEAR);
+         assert(params.dst.surf.logical_level0_px.depth == 1);
+         assert(params.dst.surf.logical_level0_px.array_len == 1);
+         assert(params.dst.surf.levels == 1);
+         assert(params.dst.surf.samples == 1);
+         assert(params.dst.tile_x_sa == 0 || params.dst.tile_y_sa == 0);
+         assert(params.dst.aux_usage == ISL_AUX_USAGE_NONE);
+
+         /* max_image_width rounded down to a multiple of 3 */
+         const unsigned max_fake_rgb_width = (max_image_width / 3) * 3;
+         const unsigned cpp =
+            isl_format_get_layout(params.dst.surf.format)->bpb / 8;
+
+         params.dst.surf.logical_level0_px.width = max_fake_rgb_width;
+         params.dst.surf.phys_level0_sa.width = max_fake_rgb_width;
+
+         uint32_t orig_x0 = params.x0, orig_x1 = params.x1;
+         uint64_t orig_offset = params.dst.addr.offset;
+         for (uint32_t x = orig_x0; x < orig_x1; x += max_fake_rgb_width) {
+            /* Offset to the surface.  It's easy because we're linear */
+            params.dst.addr.offset = orig_offset + x * cpp;
+
+            params.x0 = 0;
+            params.x1 = MIN2(orig_x1 - x, max_image_width);
+
+            batch->blorp->exec(batch, &params);
+         }
+      } else {
+         batch->blorp->exec(batch, &params);
+      }
 
       start_layer += params.num_layers;
       num_layers -= params.num_layers;
@@ -502,7 +589,7 @@ blorp_clear_depth_stencil(struct blorp_batch *batch,
        * we disable statistics in 3DSTATE_WM.  Give it the usual clear shader
        * to work around the issue.
        */
-      if (!blorp_params_get_clear_kernel(batch->blorp, &params, false))
+      if (!blorp_params_get_clear_kernel(batch, &params, false, false))
          return;
    }
 
@@ -742,7 +829,7 @@ blorp_clear_attachments(struct blorp_batch *batch,
        * is tiled or not, we have to assume it may be linear.  This means no
        * SIMD16_REPDATA for us. :-(
        */
-      if (!blorp_params_get_clear_kernel(batch->blorp, &params, false))
+      if (!blorp_params_get_clear_kernel(batch, &params, false, false))
          return;
    }
 
@@ -760,7 +847,7 @@ blorp_clear_attachments(struct blorp_batch *batch,
       params.stencil_ref = stencil_value;
    }
 
-   if (!blorp_params_get_layer_offset_vs(batch->blorp, &params))
+   if (!blorp_params_get_layer_offset_vs(batch, &params))
       return;
 
    params.vs_inputs.base_layer = start_layer;
@@ -827,36 +914,48 @@ blorp_ccs_resolve(struct blorp_batch *batch,
     * color" message.
     */
 
-   if (!blorp_params_get_clear_kernel(batch->blorp, &params, true))
+   if (!blorp_params_get_clear_kernel(batch, &params, true, false))
       return;
 
    batch->blorp->exec(batch, &params);
 }
 
+static nir_ssa_def *
+blorp_nir_bit(nir_builder *b, nir_ssa_def *src, unsigned bit)
+{
+   return nir_iand(b, nir_ushr(b, src, nir_imm_int(b, bit)),
+                      nir_imm_int(b, 1));
+}
+
 struct blorp_mcs_partial_resolve_key
 {
    enum blorp_shader_type shader_type;
+   bool indirect_clear_color;
+   bool int_format;
    uint32_t num_samples;
 };
 
 static bool
-blorp_params_get_mcs_partial_resolve_kernel(struct blorp_context *blorp,
+blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch *batch,
                                             struct blorp_params *params)
 {
+   struct blorp_context *blorp = batch->blorp;
    const struct blorp_mcs_partial_resolve_key blorp_key = {
       .shader_type = BLORP_SHADER_TYPE_MCS_PARTIAL_RESOLVE,
+      .indirect_clear_color = params->dst.clear_color_addr.buffer != NULL,
+      .int_format = isl_format_has_int_channel(params->dst.view.format),
       .num_samples = params->num_samples,
    };
 
-   if (blorp->lookup_shader(blorp, &blorp_key, sizeof(blorp_key),
+   if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
                             &params->wm_prog_kernel, &params->wm_prog_data))
       return true;
 
    void *mem_ctx = ralloc_context(NULL);
 
    nir_builder b;
-   nir_builder_init_simple_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT, NULL);
-   b.shader->info.name = ralloc_strdup(b.shader, "BLORP-mcs-partial-resolve");
+   blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_FRAGMENT,
+                         "BLORP-mcs-partial-resolve");
 
    nir_variable *v_color =
       BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type());
@@ -879,7 +978,18 @@ blorp_params_get_mcs_partial_resolve_kernel(struct blorp_context *blorp,
    discard->src[0] = nir_src_for_ssa(nir_inot(&b, is_clear));
    nir_builder_instr_insert(&b, &discard->instr);
 
-   nir_copy_var(&b, frag_color, v_color);
+   nir_ssa_def *clear_color = nir_load_var(&b, v_color);
+   if (blorp_key.indirect_clear_color && blorp->isl_dev->info->gen <= 8) {
+      /* Gen7-8 clear colors are stored as single 0/1 bits */
+      clear_color = nir_vec4(&b, blorp_nir_bit(&b, clear_color, 31),
+                                 blorp_nir_bit(&b, clear_color, 30),
+                                 blorp_nir_bit(&b, clear_color, 29),
+                                 blorp_nir_bit(&b, clear_color, 28));
+
+      if (!blorp_key.int_format)
+         clear_color = nir_i2f32(&b, clear_color);
+   }
+   nir_store_var(&b, frag_color, clear_color, 0xf);
 
    struct brw_wm_prog_key wm_key;
    brw_blorp_init_wm_prog_key(&wm_key);
@@ -893,7 +1003,7 @@ blorp_params_get_mcs_partial_resolve_kernel(struct blorp_context *blorp,
                        &prog_data);
 
    bool result =
-      blorp->upload_shader(blorp, &blorp_key, sizeof(blorp_key),
+      blorp->upload_shader(batch, &blorp_key, sizeof(blorp_key),
                            program, prog_data.base.program_size,
                            &prog_data.base, sizeof(prog_data),
                            &params->wm_prog_kernel, &params->wm_prog_data);
@@ -925,11 +1035,12 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch,
 
    params.num_samples = params.dst.surf.samples;
    params.num_layers = num_layers;
+   params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL;
 
    memcpy(&params.wm_inputs.clear_color,
           surf->clear_color.f32, sizeof(float) * 4);
 
-   if (!blorp_params_get_mcs_partial_resolve_kernel(batch->blorp, &params))
+   if (!blorp_params_get_mcs_partial_resolve_kernel(batch, &params))
       return;
 
    batch->blorp->exec(batch, &params);
@@ -979,7 +1090,7 @@ blorp_ccs_ambiguate(struct blorp_batch *batch,
    isl_surf_get_image_offset_el(surf->aux_surf, level, layer, z,
                                 &x_offset_el, &y_offset_el);
    isl_tiling_get_intratile_offset_el(surf->aux_surf->tiling, aux_fmtl->bpb,
-                                      surf->aux_surf->row_pitch,
+                                      surf->aux_surf->row_pitch_B,
                                       x_offset_el, y_offset_el,
                                       &offset_B, &x_offset_el, &y_offset_el);
    params.dst.addr.offset += offset_B;
@@ -1068,7 +1179,7 @@ blorp_ccs_ambiguate(struct blorp_batch *batch,
                     .levels = 1,
                     .array_len = 1,
                     .samples = 1,
-                    .row_pitch = surf->aux_surf->row_pitch,
+                    .row_pitch_B = surf->aux_surf->row_pitch_B,
                     .usage = ISL_SURF_USAGE_RENDER_TARGET_BIT,
                     .tiling_flags = ISL_TILING_Y0_BIT);
    assert(ok);
@@ -1082,7 +1193,7 @@ blorp_ccs_ambiguate(struct blorp_batch *batch,
    memset(&params.wm_inputs.clear_color, 0,
           sizeof(params.wm_inputs.clear_color));
 
-   if (!blorp_params_get_clear_kernel(batch->blorp, &params, true))
+   if (!blorp_params_get_clear_kernel(batch, &params, true, false))
       return;
 
    batch->blorp->exec(batch, &params);