From 29276dbea7d316c914d72f986dc4005f084034ab Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 18 Nov 2025 17:24:22 -0800 Subject: [PATCH 1/7] blorp: fix argument indentation I'm sorry, but I have OCD and the rest of the file is nicely aligned. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp.c | 10 +++++----- src/intel/blorp/blorp_blit.c | 14 +++++++------- src/intel/blorp/blorp_clear.c | 28 +++++++++++++-------------- src/intel/blorp/blorp_genX_exec_brw.h | 2 +- src/intel/blorp/blorp_priv.h | 8 ++++---- 5 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/intel/blorp/blorp.c b/src/intel/blorp/blorp.c index 4c43d7cde35..1f3ee2ef567 100644 --- a/src/intel/blorp/blorp.c +++ b/src/intel/blorp/blorp.c @@ -144,10 +144,10 @@ blorp_batch_finish(struct blorp_batch *batch) void blorp_surface_info_init(struct blorp_batch *batch, - struct blorp_surface_info *info, - const struct blorp_surf *surf, - unsigned int level, float layer, - enum isl_format format, bool is_dest) + struct blorp_surface_info *info, + const struct blorp_surf *surf, + unsigned int level, float layer, + enum isl_format format, bool is_dest) { struct blorp_context *blorp = batch->blorp; memset(info, 0, sizeof(*info)); @@ -282,7 +282,7 @@ blorp_hiz_op(struct blorp_batch *batch, struct blorp_surf *surf, const uint32_t layer = start_layer + a; blorp_surface_info_init(batch, ¶ms.depth, surf, level, - layer, surf->surf->format, true); + layer, surf->surf->format, true); /* Align the rectangle primitive to 8x4 pixels. * diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index c85f511a5aa..badc280fc8f 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -48,7 +48,7 @@ struct blorp_blit_vars { static void blorp_blit_vars_init(nir_builder *b, struct blorp_blit_vars *v, - const struct blorp_blit_prog_key *key) + const struct blorp_blit_prog_key *key) { #define LOAD_INPUT(name, type)\ v->v_##name = BLORP_CREATE_NIR_INPUT(b->shader, name, type); @@ -1179,8 +1179,8 @@ convert_color(struct nir_builder *b, nir_def *color, */ static nir_shader * blorp_build_nir_shader(struct blorp_context *blorp, - struct blorp_batch *batch, void *mem_ctx, - const struct blorp_blit_prog_key *key) + struct blorp_batch *batch, void *mem_ctx, + const struct blorp_blit_prog_key *key) { const struct intel_device_info *devinfo = blorp->isl_dev->info; @@ -2580,9 +2580,9 @@ blorp_blit(struct blorp_batch *batch, } blorp_surface_info_init(batch, ¶ms.src, src_surf, src_level, - src_layer, src_format, false); + src_layer, src_format, false); blorp_surface_info_init(batch, ¶ms.dst, dst_surf, dst_level, - dst_layer, dst_format, true); + dst_layer, dst_format, true); params.src.view.swizzle = src_swizzle; params.dst.view.swizzle = dst_swizzle; @@ -2994,9 +2994,9 @@ blorp_copy(struct blorp_batch *batch, } blorp_surface_info_init(batch, ¶ms.src, src_surf, src_level, - src_layer, ISL_FORMAT_UNSUPPORTED, false); + src_layer, ISL_FORMAT_UNSUPPORTED, false); blorp_surface_info_init(batch, ¶ms.dst, dst_surf, dst_level, - dst_layer, ISL_FORMAT_UNSUPPORTED, true); + dst_layer, ISL_FORMAT_UNSUPPORTED, true); struct blorp_blit_prog_key key = { .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_COPY), diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c index 0313c1b717d..4449555bddc 100644 --- a/src/intel/blorp/blorp_clear.c +++ b/src/intel/blorp/blorp_clear.c @@ -494,7 +494,7 @@ fast_clear_surf(struct blorp_batch *batch, return; blorp_surface_info_init(batch, ¶ms.dst, surf, level, - start_layer, format, true); + start_layer, format, true); /* BSpec: 46969 (r45602): * @@ -776,7 +776,7 @@ blorp_clear(struct blorp_batch *batch, assert(num_layers > 0); while (num_layers > 0) { blorp_surface_info_init(batch, ¶ms.dst, surf, level, - start_layer, format, true); + start_layer, format, true); params.dst.view.swizzle = swizzle; params.x0 = x0; @@ -961,7 +961,7 @@ blorp_clear_stencil_as_rgba(struct blorp_batch *batch, uint32_t layer = start_layer + a; blorp_surface_info_init(batch, ¶ms.dst, surf, level, - layer, ISL_FORMAT_UNSUPPORTED, true); + layer, ISL_FORMAT_UNSUPPORTED, true); if (surf->surf->samples > 1) blorp_surf_fake_interleaved_msaa(batch->blorp->isl_dev, ¶ms.dst); @@ -1033,8 +1033,8 @@ blorp_clear_depth_stencil(struct blorp_batch *batch, if (stencil_mask) { blorp_surface_info_init(batch, ¶ms.stencil, stencil, - level, start_layer, - ISL_FORMAT_UNSUPPORTED, true); + level, start_layer, + ISL_FORMAT_UNSUPPORTED, true); params.stencil_mask = stencil_mask; params.stencil_ref = stencil_value; @@ -1055,8 +1055,8 @@ blorp_clear_depth_stencil(struct blorp_batch *batch, if (clear_depth) { blorp_surface_info_init(batch, ¶ms.depth, depth, - level, start_layer, - ISL_FORMAT_UNSUPPORTED, true); + level, start_layer, + ISL_FORMAT_UNSUPPORTED, true); params.z = depth_value; params.depth_format = isl_format_get_depth_format(depth->surf->format, false); @@ -1144,8 +1144,8 @@ blorp_hiz_clear_depth_stencil(struct blorp_batch *batch, const uint32_t layer = start_layer + l; if (clear_stencil) { blorp_surface_info_init(batch, ¶ms.stencil, stencil, - level, layer, - ISL_FORMAT_UNSUPPORTED, true); + level, layer, + ISL_FORMAT_UNSUPPORTED, true); params.stencil_mask = 0xff; params.stencil_ref = stencil_value; params.num_samples = params.stencil.surf.samples; @@ -1156,8 +1156,8 @@ blorp_hiz_clear_depth_stencil(struct blorp_batch *batch, assert(depth && isl_aux_usage_has_hiz(depth->aux_usage)); blorp_surface_info_init(batch, ¶ms.depth, depth, - level, layer, - ISL_FORMAT_UNSUPPORTED, true); + level, layer, + ISL_FORMAT_UNSUPPORTED, true); params.depth.clear_color.f32[0] = depth_value; params.depth_format = isl_format_get_depth_format(depth->surf->format, false); @@ -1301,7 +1301,7 @@ blorp_ccs_resolve(struct blorp_batch *batch, assert(false); } blorp_surface_info_init(batch, ¶ms.dst, surf, - level, start_layer, format, true); + level, start_layer, format, true); /* From the TGL PRM, Volume 2d: 3DSTATE_PS_BODY, * @@ -1502,9 +1502,9 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch, params.y1 = surf->surf->logical_level0_px.height; blorp_surface_info_init(batch, ¶ms.src, surf, 0, - start_layer, format, false); + start_layer, format, false); blorp_surface_info_init(batch, ¶ms.dst, surf, 0, - start_layer, format, true); + start_layer, format, true); params.num_samples = params.dst.surf.samples; params.num_layers = num_layers; diff --git a/src/intel/blorp/blorp_genX_exec_brw.h b/src/intel/blorp/blorp_genX_exec_brw.h index ccdfbfd16a9..a2b438d1d1f 100644 --- a/src/intel/blorp/blorp_genX_exec_brw.h +++ b/src/intel/blorp/blorp_genX_exec_brw.h @@ -1319,7 +1319,7 @@ blorp_emit_null_surface_state(struct blorp_batch *batch, static uint32_t blorp_setup_binding_table(struct blorp_batch *batch, - const struct blorp_params *params) + const struct blorp_params *params) { const struct isl_device *isl_dev = batch->blorp->isl_dev; uint32_t surface_offsets[2], bind_offset = 0; diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index 8689b81999e..6335b77535b 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -101,10 +101,10 @@ struct blorp_surface_info void blorp_surface_info_init(struct blorp_batch *batch, - struct blorp_surface_info *info, - const struct blorp_surf *surf, - unsigned int level, float layer, - enum isl_format format, bool is_dest); + struct blorp_surface_info *info, + const struct blorp_surf *surf, + unsigned int level, float layer, + enum isl_format format, bool is_dest); void blorp_surf_convert_to_single_slice(const struct isl_device *isl_dev, struct blorp_surface_info *info); From 13255013ef4095b5714e0c47b6b99a878f987043 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Tue, 18 Nov 2025 17:29:25 -0800 Subject: [PATCH 2/7] blorp: replace magic '2' with BLORP_NUM_BT_ENTRIES If we ever add more entries, things won't explode. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp_genX_exec_brw.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/intel/blorp/blorp_genX_exec_brw.h b/src/intel/blorp/blorp_genX_exec_brw.h index a2b438d1d1f..25843e67a29 100644 --- a/src/intel/blorp/blorp_genX_exec_brw.h +++ b/src/intel/blorp/blorp_genX_exec_brw.h @@ -1322,8 +1322,8 @@ blorp_setup_binding_table(struct blorp_batch *batch, const struct blorp_params *params) { const struct isl_device *isl_dev = batch->blorp->isl_dev; - uint32_t surface_offsets[2], bind_offset = 0; - void *surface_maps[2]; + uint32_t surface_offsets[BLORP_NUM_BT_ENTRIES], bind_offset = 0; + void *surface_maps[BLORP_NUM_BT_ENTRIES]; if (params->use_pre_baked_binding_table) { bind_offset = params->pre_baked_binding_table_offset; From 330cbf04e01a924572474ed82b530eb39ccd1095 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 19 Nov 2025 10:26:25 -0800 Subject: [PATCH 3/7] blorp: reorganize struct blorp_params When I first looked at this struct, my tiny little brain felt overwhelmed. - Add some white spaces in order to group the parameters into "logical" groups so it's easier to reason about everything. - Change the parameter order just a little bit - without breaking the logical groups - so the struct size decreases by 1.7% to 1864 bytes. - Add a comment explaining what the void * pointers point to. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp_priv.h | 42 ++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index 6335b77535b..c86237f8f0b 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -238,39 +238,49 @@ enum blorp_shader_pipeline { struct blorp_params { enum blorp_op op; + uint32_t x0; uint32_t y0; uint32_t x1; uint32_t y1; float z; - uint8_t stencil_mask; - uint8_t stencil_ref; - struct blorp_surface_info depth; - struct blorp_surface_info stencil; - uint32_t depth_format; + struct blorp_surface_info src; struct blorp_surface_info dst; - enum isl_aux_op hiz_op; + struct blorp_surface_info depth; + struct blorp_surface_info stencil; + + uint32_t depth_format; + uint8_t stencil_mask; + uint8_t stencil_ref; + bool full_surface_hiz_op; - enum isl_aux_op fast_clear_op; uint8_t color_write_disable; + enum isl_aux_op fast_clear_op; + enum isl_aux_op hiz_op; + struct blorp_wm_inputs wm_inputs; struct blorp_vs_inputs vs_inputs; - bool dst_clear_color_as_input; + unsigned num_samples; unsigned num_draw_buffers; unsigned num_layers; - uint32_t vs_prog_kernel; - void *vs_prog_data; - uint32_t sf_prog_kernel; - void *sf_prog_data; - uint32_t wm_prog_kernel; - void *wm_prog_data; - uint32_t cs_prog_kernel; - void *cs_prog_data; + bool dst_clear_color_as_input; bool use_pre_baked_binding_table; uint32_t pre_baked_binding_table_offset; + + uint32_t vs_prog_kernel; + uint32_t sf_prog_kernel; + uint32_t wm_prog_kernel; + uint32_t cs_prog_kernel; + + /* These are pointers to struct {brw,elk}_stage_prog_data. */ + void *vs_prog_data; + void *sf_prog_data; + void *wm_prog_data; + void *cs_prog_data; + enum blorp_shader_type shader_type; enum blorp_shader_pipeline shader_pipeline; }; From 2a662f7c073fc13b5c8f1bd5ae302a29dcb64565 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 8 Dec 2025 15:19:58 -0800 Subject: [PATCH 4/7] intel/blorp: blorp_blit_vars_init() doesn't need 'key' Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp_blit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index badc280fc8f..30acdaee36b 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -47,8 +47,7 @@ struct blorp_blit_vars { }; static void -blorp_blit_vars_init(nir_builder *b, struct blorp_blit_vars *v, - const struct blorp_blit_prog_key *key) +blorp_blit_vars_init(nir_builder *b, struct blorp_blit_vars *v) { #define LOAD_INPUT(name, type)\ v->v_##name = BLORP_CREATE_NIR_INPUT(b->shader, name, type); @@ -1227,7 +1226,7 @@ blorp_build_nir_shader(struct blorp_context *blorp, blorp_nir_init_shader(&b, blorp, mem_ctx, stage, NULL); struct blorp_blit_vars v; - blorp_blit_vars_init(&b, &v, key); + blorp_blit_vars_init(&b, &v); dst_pos = compute ? blorp_blit_get_cs_dst_coords(&b, key, &v) : From ae58744319d3b58befd2148eb37ecc06637d0381 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 17 Dec 2025 15:58:23 -0800 Subject: [PATCH 5/7] intel/blorp: add BLORP_OP_FAST_CLEAR Function fast_clear_surf() was forgetting to set params.op, which meant that it became BLORP_OP_BLIT. Set its own parameter, while keeping the Vulkan behavior the same. I want to use params.op to better differentiate code that runs on blorp_blit.c and code that runs on blorp_clear.c. See my next commits. TODO: check with the fast clear experts if we really want to keep the Vulkan behavior like that. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp.h | 1 + src/intel/blorp/blorp_clear.c | 1 + src/intel/vulkan/genX_blorp_exec.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h index 33f75835e71..b7543da9db5 100644 --- a/src/intel/blorp/blorp.h +++ b/src/intel/blorp/blorp.h @@ -51,6 +51,7 @@ enum blorp_op { BLORP_OP_MCS_AMBIGUATE, BLORP_OP_MCS_COLOR_CLEAR, BLORP_OP_MCS_PARTIAL_RESOLVE, + BLORP_OP_FAST_CLEAR, BLORP_OP_SLOW_COLOR_CLEAR, BLORP_OP_SLOW_DEPTH_CLEAR, }; diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c index 4449555bddc..c8881b0dedd 100644 --- a/src/intel/blorp/blorp_clear.c +++ b/src/intel/blorp/blorp_clear.c @@ -449,6 +449,7 @@ fast_clear_surf(struct blorp_batch *batch, { struct blorp_params params; blorp_params_init(¶ms); + params.op = BLORP_OP_FAST_CLEAR; params.num_layers = num_layers; assert((batch->flags & BLORP_BATCH_USE_COMPUTE) == 0); diff --git a/src/intel/vulkan/genX_blorp_exec.c b/src/intel/vulkan/genX_blorp_exec.c index d11c519554f..98f01a22415 100644 --- a/src/intel/vulkan/genX_blorp_exec.c +++ b/src/intel/vulkan/genX_blorp_exec.c @@ -515,6 +515,7 @@ get_color_aux_op(const struct blorp_params *params) /* The remaining operations are considered regular draws. */ case BLORP_OP_SLOW_COLOR_CLEAR: + case BLORP_OP_FAST_CLEAR: case BLORP_OP_BLIT: case BLORP_OP_COPY: assert(params->fast_clear_op == ISL_AUX_OP_NONE); From 1c33e9a3118e98889278807087251307f1530043 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 17 Dec 2025 14:37:29 -0800 Subject: [PATCH 6/7] intel/blorp: unionize blorp_params->wm_inputs We have two distinct code paths sharing blorp_params->wm_inputs for different purposes: the code from blorp_blit.c and the code from blorp_clear.c. While blorp_blit.c uses most of the parameters (all except clear_color), blorp_clear.c only uses clear_color and bounds_rect. Split the parameters in two structs: one for blits and the other for clears. This not only helps save some space in the shader inputs, but it also organizes things so it's more clear which parameters are used by what. In addition, my plan is to later add struct blorp_wm_inputs_indirect, which won't share anything that the others use, and would otherwise grow the struct even more. This change would reduce the size of struct blorp_wm_inputs from 96 to 80, but we have to add padding due to the assertion that compares it to cs_prog_data->push.cross_thread.size. Still good, though. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp_blit.c | 52 +++++++++++++----------- src/intel/blorp/blorp_clear.c | 50 ++++++++++++++--------- src/intel/blorp/blorp_genX_exec_brw.h | 29 +++++++++----- src/intel/blorp/blorp_priv.h | 58 +++++++++++++++++++++++++-- 4 files changed, 130 insertions(+), 59 deletions(-) diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 30acdaee36b..8e325da23ab 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -50,7 +50,7 @@ static void blorp_blit_vars_init(nir_builder *b, struct blorp_blit_vars *v) { #define LOAD_INPUT(name, type)\ - v->v_##name = BLORP_CREATE_NIR_INPUT(b->shader, name, type); + v->v_##name = BLORP_CREATE_NIR_INPUT(b->shader, blit.name, type); LOAD_INPUT(bounds_rect, glsl_vec4_type()) LOAD_INPUT(rect_grid, glsl_vec4_type()) @@ -1551,6 +1551,8 @@ blorp_get_blit_kernel_fs(struct blorp_batch *batch, void *mem_ctx = ralloc_context(NULL); nir_shader *nir = blorp_build_nir_shader(blorp, batch, mem_ctx, key); + assert(blorp_op_type_is_blit(params->op)); + nir->info.name = ralloc_strdup(nir, blorp_shader_type_to_name(key->base.shader_type)); @@ -1585,6 +1587,8 @@ blorp_get_blit_kernel_cs(struct blorp_batch *batch, nir_shader *nir = blorp_build_nir_shader(blorp, batch, mem_ctx, prog_key); + assert(blorp_op_type_is_blit(params->op)); + nir->info.name = ralloc_strdup(nir, "BLORP-gpgpu-blit"); blorp_set_cs_dims(nir, prog_key->local_y); @@ -1956,16 +1960,16 @@ try_blorp_blit(struct blorp_batch *batch, /* Round floating point values to nearest integer to avoid "off by one texel" * kind of errors when blitting. */ - params->x0 = params->wm_inputs.bounds_rect.x0 = round(coords->x.dst0); - params->y0 = params->wm_inputs.bounds_rect.y0 = round(coords->y.dst0); - params->x1 = params->wm_inputs.bounds_rect.x1 = round(coords->x.dst1); - params->y1 = params->wm_inputs.bounds_rect.y1 = round(coords->y.dst1); + params->x0 = params->wm_inputs.blit.bounds_rect.x0 = round(coords->x.dst0); + params->y0 = params->wm_inputs.blit.bounds_rect.y0 = round(coords->y.dst0); + params->x1 = params->wm_inputs.blit.bounds_rect.x1 = round(coords->x.dst1); + params->y1 = params->wm_inputs.blit.bounds_rect.y1 = round(coords->y.dst1); - blorp_setup_coord_transform(¶ms->wm_inputs.coord_transform[0], + blorp_setup_coord_transform(¶ms->wm_inputs.blit.coord_transform[0], coords->x.src0, coords->x.src1, coords->x.dst0, coords->x.dst1, coords->x.mirror); - blorp_setup_coord_transform(¶ms->wm_inputs.coord_transform[1], + blorp_setup_coord_transform(¶ms->wm_inputs.blit.coord_transform[1], coords->y.src0, coords->y.src1, coords->y.dst0, coords->y.dst1, coords->y.mirror); @@ -2133,10 +2137,10 @@ try_blorp_blit(struct blorp_batch *batch, batch->blorp->isl_dev->info->ver <= 6) { /* Gfx4-5 don't support non-normalized texture coordinates */ key->src_coords_normalized = true; - params->wm_inputs.src_inv_size[0] = + params->wm_inputs.blit.src_inv_size[0] = 1.0f / u_minify(params->src.surf.logical_level0_px.width, params->src.view.base_level); - params->wm_inputs.src_inv_size[1] = + params->wm_inputs.blit.src_inv_size[1] = 1.0f / u_minify(params->src.surf.logical_level0_px.height, params->src.view.base_level); } @@ -2198,23 +2202,23 @@ try_blorp_blit(struct blorp_batch *batch, if (params->src.tile_x_sa || params->src.tile_y_sa) { assert(key->need_src_offset); surf_get_intratile_offset_px(¶ms->src, - ¶ms->wm_inputs.src_offset.x, - ¶ms->wm_inputs.src_offset.y); + ¶ms->wm_inputs.blit.src_offset.x, + ¶ms->wm_inputs.blit.src_offset.y); } if (params->dst.tile_x_sa || params->dst.tile_y_sa) { assert(key->need_dst_offset); surf_get_intratile_offset_px(¶ms->dst, - ¶ms->wm_inputs.dst_offset.x, - ¶ms->wm_inputs.dst_offset.y); - params->x0 += params->wm_inputs.dst_offset.x; - params->y0 += params->wm_inputs.dst_offset.y; - params->x1 += params->wm_inputs.dst_offset.x; - params->y1 += params->wm_inputs.dst_offset.y; + ¶ms->wm_inputs.blit.dst_offset.x, + ¶ms->wm_inputs.blit.dst_offset.y); + params->x0 += params->wm_inputs.blit.dst_offset.x; + params->y0 += params->wm_inputs.blit.dst_offset.y; + params->x1 += params->wm_inputs.blit.dst_offset.x; + params->y1 += params->wm_inputs.blit.dst_offset.y; } /* For some texture types, we need to pass the layer through the sampler. */ - params->wm_inputs.src_z = params->src.z_offset; + params->wm_inputs.blit.src_z = params->src.z_offset; const bool compute = key->base.shader_pipeline == BLORP_SHADER_PIPELINE_COMPUTE; @@ -2614,10 +2618,10 @@ blorp_blit(struct blorp_batch *batch, key.x_scale = 2.0f; key.y_scale = params.src.surf.samples / key.x_scale; - params.wm_inputs.rect_grid.x1 = + params.wm_inputs.blit.rect_grid.x1 = u_minify(params.src.surf.logical_level0_px.width, src_level) * key.x_scale - 1.0f; - params.wm_inputs.rect_grid.y1 = + params.wm_inputs.blit.rect_grid.y1 = u_minify(params.src.surf.logical_level0_px.height, src_level) * key.y_scale - 1.0f; @@ -3089,10 +3093,10 @@ blorp_copy(struct blorp_batch *batch, params.x1 = dst_x + dst_width; params.y0 = dst_y; params.y1 = dst_y + dst_height; - params.wm_inputs.coord_transform[0].offset = dst_x - (float)src_x; - params.wm_inputs.coord_transform[1].offset = dst_y - (float)src_y; - params.wm_inputs.coord_transform[0].multiplier = 1.0f; - params.wm_inputs.coord_transform[1].multiplier = 1.0f; + params.wm_inputs.blit.coord_transform[0].offset = dst_x - (float)src_x; + params.wm_inputs.blit.coord_transform[1].offset = dst_y - (float)src_y; + params.wm_inputs.blit.coord_transform[0].multiplier = 1.0f; + params.wm_inputs.blit.coord_transform[1].multiplier = 1.0f; batch->blorp->exec(batch, ¶ms); return; diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c index c8881b0dedd..5122902fce8 100644 --- a/src/intel/blorp/blorp_clear.c +++ b/src/intel/blorp/blorp_clear.c @@ -90,8 +90,10 @@ blorp_params_get_clear_kernel_fs(struct blorp_batch *batch, blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_FRAGMENT, blorp_shader_type_to_name(blorp_key.base.shader_type)); + assert(blorp_op_type_is_clear(params->op)); + nir_variable *v_color = - BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type()); + BLORP_CREATE_NIR_INPUT(b.shader, clear.clear_color, glsl_vec4_type()); nir_def *color = nir_load_var(&b, v_color); if (clear_rgb_as_red) { @@ -149,16 +151,19 @@ blorp_params_get_clear_kernel_cs(struct blorp_batch *batch, nir_builder b; blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_COMPUTE, "BLORP-gpgpu-clear"); + + assert(blorp_op_type_is_clear(params->op)); + blorp_set_cs_dims(b.shader, blorp_key.local_y); nir_def *dst_pos = nir_load_global_invocation_id(&b, 32); nir_variable *v_color = - BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type()); + BLORP_CREATE_NIR_INPUT(b.shader, clear.clear_color, glsl_vec4_type()); nir_def *color = nir_load_var(&b, v_color); nir_variable *v_bounds_rect = - BLORP_CREATE_NIR_INPUT(b.shader, bounds_rect, glsl_vec4_type()); + BLORP_CREATE_NIR_INPUT(b.shader, clear.bounds_rect, glsl_vec4_type()); nir_def *bounds_rect = nir_load_var(&b, v_bounds_rect); nir_def *in_bounds = blorp_check_in_bounds(&b, bounds_rect, dst_pos); @@ -475,7 +480,8 @@ fast_clear_surf(struct blorp_batch *batch, * Pixel shader's color output is treated as Clear Value, value * should be a constant. */ - memcpy(¶ms.wm_inputs.clear_color, &clear_color, 4 * sizeof(float)); + memcpy(¶ms.wm_inputs.clear.clear_color, &clear_color, + 4 * sizeof(float)); } else { /* BSpec: 2423 (r153658): * @@ -483,7 +489,7 @@ fast_clear_surf(struct blorp_batch *batch, * value of 0xFFFFFFFF in all channels of the render target write * message The replicated color message should be used. */ - memset(¶ms.wm_inputs.clear_color, 0xff, 4 * sizeof(float)); + memset(¶ms.wm_inputs.clear.clear_color, 0xff, 4 * sizeof(float)); } params.fast_clear_op = ISL_AUX_OP_FAST_CLEAR; @@ -743,7 +749,8 @@ blorp_clear(struct blorp_batch *batch, } } - memcpy(¶ms.wm_inputs.clear_color, clear_color.f32, sizeof(float) * 4); + memcpy(¶ms.wm_inputs.clear.clear_color, clear_color.f32, + sizeof(float) * 4); bool use_simd16_replicated_data = true; @@ -786,10 +793,10 @@ blorp_clear(struct blorp_batch *batch, params.y1 = y1; if (compute) { - params.wm_inputs.bounds_rect.x0 = x0; - params.wm_inputs.bounds_rect.y0 = y0; - params.wm_inputs.bounds_rect.x1 = x1; - params.wm_inputs.bounds_rect.y1 = y1; + params.wm_inputs.clear.bounds_rect.x0 = x0; + params.wm_inputs.clear.bounds_rect.y0 = y0; + params.wm_inputs.clear.bounds_rect.x1 = x1; + params.wm_inputs.clear.bounds_rect.y1 = y1; } if (params.dst.tile_x_sa || params.dst.tile_y_sa) { @@ -935,8 +942,8 @@ blorp_clear_stencil_as_rgba(struct blorp_batch *batch, if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false)) return false; - memset(¶ms.wm_inputs.clear_color, stencil_value, - sizeof(params.wm_inputs.clear_color)); + memset(¶ms.wm_inputs.clear.clear_color, stencil_value, + sizeof(params.wm_inputs.clear.clear_color)); /* The Sandy Bridge PRM Vol. 4 Pt. 2, section 2.11.2.1.1 has the * following footnote to the format table: @@ -953,7 +960,7 @@ blorp_clear_stencil_as_rgba(struct blorp_batch *batch, * clamping giving us the wrong values */ for (unsigned i = 0; i < 4; i++) - params.wm_inputs.clear_color[i] &= 0xffff; + params.wm_inputs.clear.clear_color[i] &= 0xffff; } else { wide_format = ISL_FORMAT_R32G32B32A32_UINT; } @@ -1243,7 +1250,8 @@ blorp_clear_attachments(struct blorp_batch *batch, params.dst.enabled = true; params.op = BLORP_OP_SLOW_COLOR_CLEAR; - memcpy(¶ms.wm_inputs.clear_color, color_value.f32, sizeof(float) * 4); + memcpy(¶ms.wm_inputs.clear.clear_color, color_value.f32, + sizeof(float) * 4); /* Unfortunately, without knowing whether or not our destination surface * is tiled or not, we have to assume it may be linear. This means no @@ -1438,8 +1446,10 @@ blorp_params_get_mcs_partial_resolve_kernel(struct blorp_batch *batch, blorp_nir_init_shader(&b, blorp, mem_ctx, MESA_SHADER_FRAGMENT, blorp_shader_type_to_name(blorp_key.base.shader_type)); + assert(blorp_op_type_is_clear(params->op)); + nir_variable *v_color = - BLORP_CREATE_NIR_INPUT(b.shader, clear_color, glsl_vec4_type()); + BLORP_CREATE_NIR_INPUT(b.shader, clear.clear_color, glsl_vec4_type()); nir_variable *frag_color = nir_variable_create(b.shader, nir_var_shader_out, @@ -1511,7 +1521,7 @@ blorp_mcs_partial_resolve(struct blorp_batch *batch, params.num_layers = num_layers; params.dst_clear_color_as_input = surf->clear_color_addr.buffer != NULL; - memcpy(¶ms.wm_inputs.clear_color, + memcpy(¶ms.wm_inputs.clear.clear_color, surf->clear_color.f32, sizeof(float) * 4); if (!blorp_params_get_mcs_partial_resolve_kernel(batch, ¶ms)) @@ -1616,8 +1626,8 @@ blorp_mcs_ambiguate(struct blorp_batch *batch, params.num_layers = params.dst.view.array_len; const uint64_t pixel = get_mcs_ambiguate_pixel(surf->surf->samples); - params.wm_inputs.clear_color[0] = pixel & 0xFFFFFFFF; - params.wm_inputs.clear_color[1] = pixel >> 32; + params.wm_inputs.clear.clear_color[0] = pixel & 0xFFFFFFFF; + params.wm_inputs.clear.clear_color[1] = pixel >> 32; if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false)) return; @@ -1775,8 +1785,8 @@ blorp_ccs_ambiguate(struct blorp_batch *batch, params.y1 = y_offset_rgba_px + height_rgba_px; /* A CCS value of 0 means "uncompressed." */ - memset(¶ms.wm_inputs.clear_color, 0, - sizeof(params.wm_inputs.clear_color)); + memset(¶ms.wm_inputs.clear.clear_color, 0, + sizeof(params.wm_inputs.clear.clear_color)); if (!blorp_params_get_clear_kernel(batch, ¶ms, false, true, false)) return; diff --git a/src/intel/blorp/blorp_genX_exec_brw.h b/src/intel/blorp/blorp_genX_exec_brw.h index 25843e67a29..3be69678c2f 100644 --- a/src/intel/blorp/blorp_genX_exec_brw.h +++ b/src/intel/blorp/blorp_genX_exec_brw.h @@ -2051,20 +2051,23 @@ blorp_xy_block_copy_blt(struct blorp_batch *batch, unsigned dst_x0 = params->x0; unsigned dst_x1 = params->x1; - unsigned src_x0 = - dst_x0 - params->wm_inputs.coord_transform[0].offset; - ASSERTED unsigned src_x1 = - dst_x1 - params->wm_inputs.coord_transform[0].offset; + unsigned src_x0 = dst_x0; + ASSERTED unsigned src_x1 = dst_x1; unsigned dst_y0 = params->y0; unsigned dst_y1 = params->y1; - unsigned src_y0 = - dst_y0 - params->wm_inputs.coord_transform[1].offset; - ASSERTED unsigned src_y1 = - dst_y1 - params->wm_inputs.coord_transform[1].offset; + unsigned src_y0 = dst_y0; + ASSERTED unsigned src_y1 = dst_y1; assert(src_x1 - src_x0 == dst_x1 - dst_x0); assert(src_y1 - src_y0 == dst_y1 - dst_y0); + if (blorp_op_type_is_blit(params->op)) { + src_x0 = dst_x0 - params->wm_inputs.blit.coord_transform[0].offset; + src_x1 = dst_x1 - params->wm_inputs.blit.coord_transform[0].offset; + src_y0 = dst_y0 - params->wm_inputs.blit.coord_transform[1].offset; + src_y1 = dst_y1 - params->wm_inputs.blit.coord_transform[1].offset; + } + const struct isl_surf *src_surf = ¶ms->src.surf; const struct isl_surf *dst_surf = ¶ms->dst.surf; @@ -2242,9 +2245,13 @@ blorp_xy_fast_color_blit(struct blorp_batch *batch, blt.DestinationXOffset = params->dst.tile_x_sa; blt.DestinationYOffset = params->dst.tile_y_sa; - isl_color_value_pack((union isl_color_value *) - params->wm_inputs.clear_color, - params->dst.view.format, blt.FillColor); + if (blorp_op_type_is_clear(params->op)) { + isl_color_value_pack((union isl_color_value *) + params->wm_inputs.clear.clear_color, + params->dst.view.format, blt.FillColor); + } else { + memset(blt.FillColor, 0, sizeof(blt.FillColor)); + } #if GFX_VERx10 >= 125 blt.DestinationSurfaceType = xy_bcb_surf_dim(dst_surf); diff --git a/src/intel/blorp/blorp_priv.h b/src/intel/blorp/blorp_priv.h index c86237f8f0b..fd6c96040a4 100644 --- a/src/intel/blorp/blorp_priv.h +++ b/src/intel/blorp/blorp_priv.h @@ -164,10 +164,9 @@ struct blorp_surf_offset { uint32_t y; }; -struct blorp_wm_inputs +/* Parameters used in blorp_blit.c. */ +struct blorp_wm_inputs_blit { - uint32_t clear_color[4]; - struct blorp_bounds_rect bounds_rect; struct blorp_rect_grid rect_grid; struct blorp_coord_transform coord_transform[2]; @@ -182,11 +181,25 @@ struct blorp_wm_inputs * for which the setting has no effect. Use the z-coordinate instead. */ float src_z; +}; + +/* Parameters used in blorp_clear.c. */ +struct blorp_wm_inputs_clear { + uint32_t clear_color[4]; + struct blorp_bounds_rect bounds_rect; +}; + +struct blorp_wm_inputs +{ + union { + struct blorp_wm_inputs_blit blit; + struct blorp_wm_inputs_clear clear; + }; /* Note: Pad out to an integral number of registers when extending, but * make sure subgroup_id is the last 32-bit item. */ - /* uint32_t pad[?]; */ + uint32_t pad[4]; uint32_t subgroup_id; }; @@ -519,6 +532,43 @@ blorp_params_get_layer_offset_vs(struct blorp_batch *batch, return batch->blorp->compiler->params_get_layer_offset_vs(batch, params); } +/* This means: blorp_params->wm_inputs.blit should be used. */ +static inline bool +blorp_op_type_is_blit(enum blorp_op op) +{ + switch (op) { + case BLORP_OP_BLIT: + case BLORP_OP_COPY: + return true; + default: + return false; + } +} + +/* This means: blorp_params->wm_inputs.clear should be used. */ +static inline bool +blorp_op_type_is_clear(enum blorp_op op) +{ + switch (op) { + case BLORP_OP_CCS_AMBIGUATE: + case BLORP_OP_CCS_COLOR_CLEAR: + case BLORP_OP_CCS_PARTIAL_RESOLVE: + case BLORP_OP_CCS_RESOLVE: + case BLORP_OP_HIZ_AMBIGUATE: + case BLORP_OP_HIZ_CLEAR: + case BLORP_OP_HIZ_RESOLVE: + case BLORP_OP_MCS_AMBIGUATE: + case BLORP_OP_MCS_COLOR_CLEAR: + case BLORP_OP_MCS_PARTIAL_RESOLVE: + case BLORP_OP_FAST_CLEAR: + case BLORP_OP_SLOW_COLOR_CLEAR: + case BLORP_OP_SLOW_DEPTH_CLEAR: + return true; + default: + return false; + } +} + /** \} */ #ifdef __cplusplus From 72c461d3d9025bc3bc7009db651b81abc27f4797 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Wed, 17 Dec 2025 16:44:31 -0800 Subject: [PATCH 7/7] intel/blorp: add blorp_shaders.cl This gives us the infrastructure that allows us to slowly migrate pieces of blorp shaders from NIR to OpenCL, which, IMHO, are much easier to read. We can't fully migrate everything due to all the conditional building we do with these shaders, but I'm sure we'll find opportunities to replace some NIR with OpenCL eventually. The conversion of blorp_check_in_bounds() serves as the first example. I also plan to have the shaders from the new indirect copy extension be OpenCL shaders (mixed with some NIR as well), so having this patch merged now will reduce the diff for the extension later. Thanks to Alyssa Rosenzweig for her help here. Signed-off-by: Paulo Zanoni --- src/intel/blorp/blorp_blit.c | 6 +++-- src/intel/blorp/blorp_clear.c | 4 ++- src/intel/blorp/blorp_nir_builder.h | 21 --------------- src/intel/blorp/blorp_shaders.cl | 38 ++++++++++++++++++++++++++ src/intel/blorp/meson.build | 41 +++++++++++++++++++++++++++-- 5 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 src/intel/blorp/blorp_shaders.cl diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 8e325da23ab..458af08f43e 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -25,6 +25,7 @@ #include "compiler/nir/nir_format_convert.h" #include "blorp_priv.h" +#include "blorp_shaders.h" #include "dev/intel_debug.h" #include "dev/intel_device_info.h" @@ -1285,8 +1286,9 @@ blorp_build_nir_shader(struct blorp_context *blorp, nir_if *bounds_if = NULL; if (key->use_kill) { nir_def *bounds_rect = nir_load_var(&b, v.v_bounds_rect); - nir_def *in_bounds = blorp_check_in_bounds(&b, bounds_rect, - dst_pos); + nir_def *in_bounds = + blorp_check_in_bounds(&b, bounds_rect, + nir_channels(&b, dst_pos, 0x3)); if (!compute) nir_discard_if(&b, nir_inot(&b, in_bounds)); else diff --git a/src/intel/blorp/blorp_clear.c b/src/intel/blorp/blorp_clear.c index 5122902fce8..859ac175da9 100644 --- a/src/intel/blorp/blorp_clear.c +++ b/src/intel/blorp/blorp_clear.c @@ -29,6 +29,7 @@ #include "util/u_math.h" #include "blorp_priv.h" +#include "blorp_shaders.h" #include "dev/intel_debug.h" #include "dev/intel_device_info.h" @@ -165,7 +166,8 @@ blorp_params_get_clear_kernel_cs(struct blorp_batch *batch, nir_variable *v_bounds_rect = BLORP_CREATE_NIR_INPUT(b.shader, clear.bounds_rect, glsl_vec4_type()); nir_def *bounds_rect = nir_load_var(&b, v_bounds_rect); - nir_def *in_bounds = blorp_check_in_bounds(&b, bounds_rect, dst_pos); + nir_def *in_bounds = + blorp_check_in_bounds(&b, bounds_rect, nir_channels(&b, dst_pos, 0x3)); if (clear_rgb_as_red) { nir_def *comp = nir_umod_imm(&b, nir_channel(&b, dst_pos, 0), 3); diff --git a/src/intel/blorp/blorp_nir_builder.h b/src/intel/blorp/blorp_nir_builder.h index 1dbd29b73b8..e3702cbbe78 100644 --- a/src/intel/blorp/blorp_nir_builder.h +++ b/src/intel/blorp/blorp_nir_builder.h @@ -107,24 +107,3 @@ blorp_nir_mcs_is_clear_color(nir_builder *b, UNREACHABLE("Invalid sample count"); } } - -static inline nir_def * -blorp_check_in_bounds(nir_builder *b, - nir_def *bounds_rect, - nir_def *pos) -{ - nir_def *x0 = nir_channel(b, bounds_rect, 0); - nir_def *x1 = nir_channel(b, bounds_rect, 1); - nir_def *y0 = nir_channel(b, bounds_rect, 2); - nir_def *y1 = nir_channel(b, bounds_rect, 3); - - nir_def *c0 = nir_uge(b, nir_channel(b, pos, 0), x0); - nir_def *c1 = nir_ult(b, nir_channel(b, pos, 0), x1); - nir_def *c2 = nir_uge(b, nir_channel(b, pos, 1), y0); - nir_def *c3 = nir_ult(b, nir_channel(b, pos, 1), y1); - - nir_def *in_bounds = - nir_iand(b, nir_iand(b, c0, c1), nir_iand(b, c2, c3)); - - return in_bounds; -} diff --git a/src/intel/blorp/blorp_shaders.cl b/src/intel/blorp/blorp_shaders.cl new file mode 100644 index 00000000000..212f8323b3d --- /dev/null +++ b/src/intel/blorp/blorp_shaders.cl @@ -0,0 +1,38 @@ +/* + * Copyright © 2025 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "compiler/libcl/libcl.h" +#include "compiler/nir/nir_defines.h" +#include "compiler/shader_enums.h" + +bool +blorp_check_in_bounds(uint4 bounds_rect, uint2 pos) +{ + uint x0 = bounds_rect[0]; + uint x1 = bounds_rect[1]; + uint y0 = bounds_rect[2]; + uint y1 = bounds_rect[3]; + + return pos.x >= x0 && pos.x < x1 && + pos.y >= y0 && pos.y < y1; +} diff --git a/src/intel/blorp/meson.build b/src/intel/blorp/meson.build index bf4e2c4b093..1b82cc5ce1f 100644 --- a/src/intel/blorp/meson.build +++ b/src/intel/blorp/meson.build @@ -1,6 +1,37 @@ # Copyright © 2017 Intel Corporation # SPDX-License-Identifier: MIT +blorp_shader_files = files( + 'blorp_shaders.cl', +) + +blorp_shaders_spv = custom_target( + input : blorp_shader_files, + output : 'blorp_shaders.spv', + command : [ + prog_mesa_clc, '-o', '@OUTPUT@', '--depfile', '@DEPFILE@', + blorp_shader_files, '--', + '-I' + join_paths(meson.project_source_root(), 'include'), + '-I' + join_paths(meson.project_source_root(), 'src/compiler/libcl'), + '-I' + join_paths(meson.project_source_root(), 'src'), + '-I' + join_paths(meson.current_source_dir(), '.'), + cl_args, + ], + depends : [gen_cl_xml_pack], + depfile : 'blorp_shaders.h.d', +) + +blorp_shaders = custom_target( + input : blorp_shaders_spv, + output : ['blorp_shaders.cpp', 'blorp_shaders.h'], + command : [prog_vtn_bindgen2, blorp_shaders_spv, '@OUTPUT0@', '@OUTPUT1@'], +) + +idep_blorp_shaders = declare_dependency( + sources : [blorp_shaders], + include_directories : include_directories('.'), +) + files_libblorp = files( 'blorp.c', 'blorp.h', @@ -26,7 +57,10 @@ libblorp = static_library( include_directories : [inc_include, inc_src, inc_intel, inc_intel_compiler], c_args : [no_override_init_args], gnu_symbol_visibility : 'hidden', - dependencies : [idep_nir_headers, idep_genxml, idep_mesautil, idep_intel_dev], + dependencies : [ + idep_nir_headers, idep_genxml, idep_mesautil, idep_intel_dev, + idep_blorp_shaders + ], build_by_default: false, ) @@ -41,7 +75,10 @@ if with_intel_elk include_directories : [inc_include, inc_src, inc_intel], c_args : [no_override_init_args], gnu_symbol_visibility : 'hidden', - dependencies : [idep_nir_headers, idep_genxml, idep_mesautil, idep_intel_dev], + dependencies : [ + idep_nir_headers, idep_genxml, idep_mesautil, idep_intel_dev, + idep_blorp_shaders + ], build_by_default: true, # FIXME XXX )