anv/hasvk: track robustness per pipeline stage

And split them into UBO and SSBO

v2 (Lionel):
 - Get rid of robustness fields in anv_shader_bin
v3 (Lionel):
 - Do not pass unused parameters around

Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17545>
This commit is contained in:
Lionel Landwerlin
2022-06-21 18:06:04 -07:00
parent c4ec60e87d
commit 9934613c74
19 changed files with 252 additions and 228 deletions

View File

@@ -237,10 +237,17 @@ struct brw_sampler_prog_key_data {
enum gfx6_gather_sampler_wa gfx6_gather_wa[BRW_MAX_SAMPLERS];
};
enum brw_robustness_flags {
BRW_ROBUSTNESS_UBO = BITFIELD_BIT(0),
BRW_ROBUSTNESS_SSBO = BITFIELD_BIT(1),
};
struct brw_base_prog_key {
unsigned program_string_id;
bool robust_buffer_access;
enum brw_robustness_flags robust_flags:2;
unsigned padding:22;
/**
* Apply workarounds for SIN and COS input range problems.
@@ -248,7 +255,6 @@ struct brw_base_prog_key {
* avoid precision issues.
*/
bool limit_trig_input_range;
unsigned padding:16;
struct brw_sampler_prog_key_data tex;
};

View File

@@ -7732,7 +7732,7 @@ brw_compile_fs(const struct brw_compiler *compiler,
NIR_PASS(_, nir, brw_nir_move_interpolation_to_top);
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
brw_nir_populate_wm_prog_data(nir, compiler->devinfo, key, prog_data,
params->mue_map);
@@ -8094,7 +8094,7 @@ brw_compile_cs(const struct brw_compiler *compiler,
NIR_PASS(_, shader, nir_opt_dce);
brw_postprocess_nir(shader, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
v[simd] = std::make_unique<fs_visitor>(compiler, &params->base,
&key->base,
@@ -8217,7 +8217,7 @@ compile_single_bs(const struct brw_compiler *compiler,
const unsigned max_dispatch_width = 16;
brw_nir_apply_key(shader, compiler, &key->base, max_dispatch_width);
brw_postprocess_nir(shader, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
brw_simd_selection_state simd_state{
.mem_ctx = params->base.mem_ctx,

View File

@@ -328,7 +328,7 @@ brw_compile_task(const struct brw_compiler *compiler,
NIR_PASS(_, shader, brw_nir_lower_simd, dispatch_width);
brw_postprocess_nir(shader, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
v[simd] = std::make_unique<fs_visitor>(compiler, &params->base,
&key->base,
@@ -1488,7 +1488,7 @@ brw_compile_mesh(const struct brw_compiler *compiler,
NIR_PASS(_, shader, brw_nir_lower_simd, dispatch_width);
brw_postprocess_nir(shader, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
v[simd] = std::make_unique<fs_visitor>(compiler, &params->base,
&key->base,

View File

@@ -1458,7 +1458,7 @@ get_mem_access_size_align(nir_intrinsic_op intrin, uint8_t bytes,
static void
brw_vectorize_lower_mem_access(nir_shader *nir,
const struct brw_compiler *compiler,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
bool progress = false;
const bool is_scalar = compiler->scalar_stage[nir->info.stage];
@@ -1472,10 +1472,10 @@ brw_vectorize_lower_mem_access(nir_shader *nir,
.robust_modes = (nir_variable_mode)0,
};
if (robust_buffer_access) {
options.robust_modes = nir_var_mem_ubo | nir_var_mem_ssbo |
nir_var_mem_global;
}
if (robust_flags & BRW_ROBUSTNESS_UBO)
options.robust_modes |= nir_var_mem_ubo | nir_var_mem_global;
if (robust_flags & BRW_ROBUSTNESS_SSBO)
options.robust_modes |= nir_var_mem_ssbo | nir_var_mem_global;
OPT(nir_opt_load_store_vectorize, &options);
@@ -1550,7 +1550,7 @@ nir_shader_has_local_variables(const nir_shader *nir)
void
brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler,
bool debug_enabled,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
const struct intel_device_info *devinfo = compiler->devinfo;
const bool is_scalar = compiler->scalar_stage[nir->info.stage];
@@ -1590,7 +1590,7 @@ brw_postprocess_nir(nir_shader *nir, const struct brw_compiler *compiler,
brw_nir_optimize(nir, compiler);
}
brw_vectorize_lower_mem_access(nir, compiler, robust_buffer_access);
brw_vectorize_lower_mem_access(nir, compiler, robust_flags);
if (OPT(nir_lower_int64))
brw_nir_optimize(nir, compiler);

View File

@@ -216,7 +216,7 @@ bool brw_nir_cleanup_resource_intel(nir_shader *shader);
void brw_postprocess_nir(nir_shader *nir,
const struct brw_compiler *compiler,
bool debug_enabled,
bool robust_buffer_access);
enum brw_robustness_flags robust_flags);
bool brw_nir_clamp_image_1d_2d_array_sizes(nir_shader *shader);

View File

@@ -1316,7 +1316,7 @@ brw_compile_tes(const struct brw_compiler *compiler,
brw_nir_lower_tes_inputs(nir, input_vue_map);
brw_nir_lower_vue_outputs(nir);
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
brw_compute_vue_map(devinfo, &prog_data->base.vue_map,
nir->info.outputs_written,

View File

@@ -2556,7 +2556,7 @@ brw_compile_vs(const struct brw_compiler *compiler,
brw_nir_lower_vs_inputs(nir, params->edgeflag_is_last, key->gl_attrib_wa_flags);
brw_nir_lower_vue_outputs(nir);
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
prog_data->base.clip_distance_mask =
((1 << nir->info.clip_distance_array_size) - 1);

View File

@@ -616,7 +616,7 @@ brw_compile_gs(const struct brw_compiler *compiler,
brw_nir_lower_vue_inputs(nir, &c.input_vue_map);
brw_nir_lower_vue_outputs(nir);
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
prog_data->base.clip_distance_mask =
((1 << nir->info.clip_distance_array_size) - 1);

View File

@@ -388,7 +388,7 @@ brw_compile_tcs(const struct brw_compiler *compiler,
brw_nir_lower_patch_vertices_in(nir, key->input_vertices);
brw_postprocess_nir(nir, compiler, debug_enabled,
key->base.robust_buffer_access);
key->base.robust_flags);
bool has_primitive_id =
BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID);

View File

@@ -58,9 +58,9 @@ bool anv_nir_lower_ycbcr_textures(nir_shader *shader,
static inline nir_address_format
anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
if (robust_buffer_access)
if (robust_flags & BRW_ROBUSTNESS_SSBO)
return nir_address_format_64bit_bounded_global;
else
return nir_address_format_64bit_global_32bit_offset;
@@ -68,9 +68,9 @@ anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
static inline nir_address_format
anv_nir_ubo_addr_format(const struct anv_physical_device *pdevice,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
if (robust_buffer_access)
if (robust_flags & BRW_ROBUSTNESS_UBO)
return nir_address_format_64bit_bounded_global;
else
return nir_address_format_64bit_global_32bit_offset;
@@ -80,7 +80,7 @@ bool anv_nir_lower_ubo_loads(nir_shader *shader);
void anv_nir_apply_pipeline_layout(nir_shader *shader,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
bool independent_sets,
const struct anv_pipeline_sets_layout *layout,
struct anv_pipeline_bind_map *map,
@@ -89,7 +89,7 @@ void anv_nir_apply_pipeline_layout(nir_shader *shader,
void anv_nir_compute_push_layout(nir_shader *nir,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
bool fragment_dynamic,
struct brw_stage_prog_data *prog_data,
struct anv_pipeline_bind_map *map,

View File

@@ -1843,7 +1843,7 @@ add_push_entry(struct anv_pipeline_push_map *push_map,
void
anv_nir_apply_pipeline_layout(nir_shader *shader,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
bool independent_sets,
const struct anv_pipeline_sets_layout *layout,
struct anv_pipeline_bind_map *map,
@@ -1867,8 +1867,8 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
.desc_addr_format = bindless_stage ?
nir_address_format_64bit_global_32bit_offset :
nir_address_format_32bit_index_offset,
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_buffer_access),
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_flags),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_flags),
.lowered_instrs = _mesa_pointer_set_create(mem_ctx),
.has_independent_sets = independent_sets,
};

View File

@@ -31,7 +31,7 @@
void
anv_nir_compute_push_layout(nir_shader *nir,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
bool fragment_dynamic,
struct brw_stage_prog_data *prog_data,
struct anv_pipeline_bind_map *map,
@@ -88,7 +88,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
has_const_ubo && nir->info.stage != MESA_SHADER_COMPUTE &&
!brw_shader_stage_requires_bindless_resources(nir->info.stage);
if (push_ubo_ranges && robust_buffer_access) {
if (push_ubo_ranges && (robust_flags & BRW_ROBUSTNESS_UBO)) {
/* We can't on-the-fly adjust our push ranges because doing so would
* mess up the layout in the shader. When robustBufferAccess is
* enabled, we push a mask into the shader indicating which pushed
@@ -233,7 +233,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
if (push_constant_range.length > 0)
map->push_ranges[n++] = push_constant_range;
if (robust_buffer_access) {
if (robust_flags & BRW_ROBUSTNESS_UBO) {
const uint32_t push_reg_mask_offset =
offsetof(struct anv_push_constants, push_reg_mask[nir->info.stage]);
assert(push_reg_mask_offset >= push_start);
@@ -266,7 +266,8 @@ anv_nir_compute_push_layout(nir_shader *nir,
};
/* We only bother to shader-zero pushed client UBOs */
if (binding->set < MAX_SETS && robust_buffer_access) {
if (binding->set < MAX_SETS &&
(robust_flags & BRW_ROBUSTNESS_UBO)) {
prog_data->zero_push_reg |= BITFIELD64_RANGE(range_start_reg,
ubo_range->length);
}

View File

@@ -134,6 +134,7 @@ anv_nir_lower_set_vtx_and_prim_count(nir_shader *nir)
static nir_shader *
anv_shader_stage_to_nir(struct anv_device *device,
const VkPipelineShaderStageCreateInfo *stage_info,
enum brw_robustness_flags robust_flags,
void *mem_ctx)
{
const struct anv_physical_device *pdevice = device->physical;
@@ -205,10 +206,8 @@ anv_shader_stage_to_nir(struct anv_device *device,
.workgroup_memory_explicit_layout = true,
.fragment_shading_rate = pdevice->info.ver >= 11,
},
.ubo_addr_format =
anv_nir_ubo_addr_format(pdevice, device->robust_buffer_access),
.ssbo_addr_format =
anv_nir_ssbo_addr_format(pdevice, device->robust_buffer_access),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_flags),
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_flags),
.phys_ssbo_addr_format = nir_address_format_64bit_global,
.push_const_addr_format = nir_address_format_logical,
@@ -378,57 +377,116 @@ void anv_DestroyPipeline(
vk_free2(&device->vk.alloc, pAllocator, pipeline);
}
static void
populate_base_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
struct brw_base_prog_key *key)
struct anv_pipeline_stage {
gl_shader_stage stage;
struct vk_pipeline_robustness_state rstate;
const VkPipelineShaderStageCreateInfo *info;
unsigned char shader_sha1[20];
uint32_t source_hash;
union brw_any_prog_key key;
struct {
gl_shader_stage stage;
unsigned char sha1[20];
} cache_key;
nir_shader *nir;
struct {
nir_shader *nir;
struct anv_shader_bin *bin;
} imported;
struct anv_push_descriptor_info push_desc_info;
enum gl_subgroup_size subgroup_size_type;
enum brw_robustness_flags robust_flags;
struct anv_pipeline_binding surface_to_descriptor[256];
struct anv_pipeline_binding sampler_to_descriptor[256];
struct anv_pipeline_bind_map bind_map;
bool uses_bt_for_push_descs;
enum anv_dynamic_push_bits dynamic_push_values;
union brw_any_prog_data prog_data;
uint32_t num_stats;
struct brw_compile_stats stats[3];
char *disasm[3];
VkPipelineCreationFeedback feedback;
uint32_t feedback_idx;
const unsigned *code;
struct anv_shader_bin *bin;
};
static enum brw_robustness_flags
anv_get_robust_flags(const struct vk_pipeline_robustness_state *rstate)
{
key->robust_buffer_access = robust_buffer_acccess;
key->limit_trig_input_range =
return
((rstate->storage_buffers !=
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT) ?
BRW_ROBUSTNESS_SSBO : 0) |
((rstate->uniform_buffers !=
VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT) ?
BRW_ROBUSTNESS_UBO : 0);
}
static void
populate_base_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
stage->key.base.robust_flags = anv_get_robust_flags(&stage->rstate);
stage->key.base.limit_trig_input_range =
device->physical->instance->limit_trig_input_range;
}
static void
populate_vs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
struct brw_vs_prog_key *key)
populate_vs_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
}
static void
populate_tcs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
unsigned input_vertices,
struct brw_tcs_prog_key *key)
populate_tcs_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device,
unsigned input_vertices)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
key->input_vertices = input_vertices;
stage->key.tcs.input_vertices = input_vertices;
}
static void
populate_tes_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
struct brw_tes_prog_key *key)
populate_tes_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
}
static void
populate_gs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
struct brw_gs_prog_key *key)
populate_gs_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
}
static bool
@@ -485,23 +543,21 @@ pipeline_has_coarse_pixel(const BITSET_WORD *dynamic,
}
static void
populate_task_prog_key(const struct anv_device *device,
bool robust_buffer_access,
struct brw_task_prog_key *key)
populate_task_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_access, &key->base);
populate_base_prog_key(stage, device);
}
static void
populate_mesh_prog_key(const struct anv_device *device,
bool robust_buffer_access,
struct brw_mesh_prog_key *key)
populate_mesh_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_access, &key->base);
populate_base_prog_key(stage, device);
}
static uint32_t
@@ -520,19 +576,20 @@ rp_color_mask(const struct vk_render_pass_state *rp)
}
static void
populate_wm_prog_key(const struct anv_graphics_base_pipeline *pipeline,
bool robust_buffer_acccess,
populate_wm_prog_key(struct anv_pipeline_stage *stage,
const struct anv_graphics_base_pipeline *pipeline,
const BITSET_WORD *dynamic,
const struct vk_multisample_state *ms,
const struct vk_fragment_shading_rate_state *fsr,
const struct vk_render_pass_state *rp,
struct brw_wm_prog_key *key)
const struct vk_render_pass_state *rp)
{
const struct anv_device *device = pipeline->base.device;
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
struct brw_wm_prog_key *key = &stage->key.wm;
/* We set this to 0 here and set to the actual value before we call
* brw_compile_fs.
@@ -607,76 +664,27 @@ wm_prog_data_dynamic(const struct brw_wm_prog_data *prog_data)
}
static void
populate_cs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
struct brw_cs_prog_key *key)
populate_cs_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(stage, device);
}
static void
populate_bs_prog_key(const struct anv_device *device,
bool robust_buffer_access,
uint32_t ray_flags,
struct brw_bs_prog_key *key)
populate_bs_prog_key(struct anv_pipeline_stage *stage,
const struct anv_device *device,
uint32_t ray_flags)
{
memset(key, 0, sizeof(*key));
memset(&stage->key, 0, sizeof(stage->key));
populate_base_prog_key(device, robust_buffer_access, &key->base);
populate_base_prog_key(stage, device);
key->pipeline_ray_flags = ray_flags;
stage->key.bs.pipeline_ray_flags = ray_flags;
stage->key.bs.pipeline_ray_flags = ray_flags;
}
struct anv_pipeline_stage {
gl_shader_stage stage;
const VkPipelineShaderStageCreateInfo *info;
unsigned char shader_sha1[20];
uint32_t source_hash;
union brw_any_prog_key key;
struct {
gl_shader_stage stage;
unsigned char sha1[20];
} cache_key;
nir_shader *nir;
struct {
nir_shader *nir;
struct anv_shader_bin *bin;
} imported;
struct anv_push_descriptor_info push_desc_info;
enum gl_subgroup_size subgroup_size_type;
struct anv_pipeline_binding surface_to_descriptor[256];
struct anv_pipeline_binding sampler_to_descriptor[256];
struct anv_pipeline_bind_map bind_map;
bool uses_bt_for_push_descs;
enum anv_dynamic_push_bits dynamic_push_values;
union brw_any_prog_data prog_data;
uint32_t num_stats;
struct brw_compile_stats stats[3];
char *disasm[3];
VkPipelineCreationFeedback feedback;
uint32_t feedback_idx;
const unsigned *code;
struct anv_shader_bin *bin;
};
static void
anv_stage_write_shader_hash(struct anv_pipeline_stage *stage,
const VkPipelineShaderStageCreateInfo *sinfo)
@@ -827,7 +835,8 @@ anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
return nir;
}
nir = anv_shader_stage_to_nir(pipeline->device, stage->info, mem_ctx);
nir = anv_shader_stage_to_nir(pipeline->device, stage->info,
stage->key.base.robust_flags, mem_ctx);
if (nir) {
anv_device_upload_nir(pipeline->device, cache, nir, stage->shader_sha1);
return nir;
@@ -980,14 +989,14 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
NIR_PASS_V(nir, anv_nir_apply_pipeline_layout,
pdevice, pipeline->device->robust_buffer_access,
pdevice, stage->key.base.robust_flags,
layout->independent_sets,
layout, &stage->bind_map, &push_map, mem_ctx);
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo,
anv_nir_ubo_addr_format(pdevice, pipeline->device->robust_buffer_access));
anv_nir_ubo_addr_format(pdevice, stage->key.base.robust_flags));
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ssbo,
anv_nir_ssbo_addr_format(pdevice, pipeline->device->robust_buffer_access));
anv_nir_ssbo_addr_format(pdevice, stage->key.base.robust_flags));
/* First run copy-prop to get rid of all of the vec() that address
* calculations often create and then constant-fold so that, when we
@@ -1044,7 +1053,7 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
stage->dynamic_push_values = anv_nir_compute_dynamic_push_bits(nir);
NIR_PASS_V(nir, anv_nir_compute_push_layout,
pdevice, pipeline->device->robust_buffer_access,
pdevice, stage->key.base.robust_flags,
anv_graphics_pipeline_stage_fragment_dynamic(stage),
prog_data, &stage->bind_map, &push_map, mem_ctx);
@@ -1660,6 +1669,13 @@ anv_graphics_pipeline_skip_shader_compile(struct anv_graphics_base_pipeline *pip
return stages[stage].info == NULL;
}
static enum brw_robustness_flags
anv_device_get_robust_flags(const struct anv_device *device)
{
return device->robust_buffer_access ?
(BRW_ROBUSTNESS_UBO | BRW_ROBUSTNESS_SSBO) : 0;
}
static void
anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state,
@@ -1674,27 +1690,20 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline *pipeline,
const struct anv_device *device = pipeline->base.device;
switch (stages[s].stage) {
case MESA_SHADER_VERTEX:
populate_vs_prog_key(device,
pipeline->base.device->robust_buffer_access,
&stages[s].key.vs);
populate_vs_prog_key(&stages[s], device);
break;
case MESA_SHADER_TESS_CTRL:
populate_tcs_prog_key(device,
pipeline->base.device->robust_buffer_access,
populate_tcs_prog_key(&stages[s],
device,
BITSET_TEST(state->dynamic,
MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS) ?
0 : state->ts->patch_control_points,
&stages[s].key.tcs);
0 : state->ts->patch_control_points);
break;
case MESA_SHADER_TESS_EVAL:
populate_tes_prog_key(device,
pipeline->base.device->robust_buffer_access,
&stages[s].key.tes);
populate_tes_prog_key(&stages[s], device);
break;
case MESA_SHADER_GEOMETRY:
populate_gs_prog_key(device,
pipeline->base.device->robust_buffer_access,
&stages[s].key.gs);
populate_gs_prog_key(&stages[s], device);
break;
case MESA_SHADER_FRAGMENT: {
/* Assume rasterization enabled in any of the following case :
@@ -1709,25 +1718,20 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_base_pipeline *pipeline,
state->rs == NULL ||
!state->rs->rasterizer_discard_enable ||
BITSET_TEST(state->dynamic, MESA_VK_DYNAMIC_RS_RASTERIZER_DISCARD_ENABLE);
populate_wm_prog_key(pipeline,
pipeline->base.device->robust_buffer_access,
populate_wm_prog_key(&stages[s],
pipeline,
state->dynamic,
raster_enabled ? state->ms : NULL,
state->fsr, state->rp,
&stages[s].key.wm);
state->fsr, state->rp);
break;
}
case MESA_SHADER_TASK:
populate_task_prog_key(device,
pipeline->base.device->robust_buffer_access,
&stages[s].key.task);
populate_task_prog_key(&stages[s], device);
break;
case MESA_SHADER_MESH:
populate_mesh_prog_key(device,
pipeline->base.device->robust_buffer_access,
&stages[s].key.mesh);
populate_mesh_prog_key(&stages[s], device);
break;
default:
@@ -2081,6 +2085,8 @@ anv_graphics_pipeline_compile(struct anv_graphics_base_pipeline *pipeline,
stages[stage].feedback_idx = shader_count++;
anv_stage_write_shader_hash(&stages[stage], stages[stage].info);
stages[stage].robust_flags = anv_device_get_robust_flags(device);
}
/* Prepare shader keys for all shaders in pipeline->base.active_stages
@@ -2455,6 +2461,7 @@ done:
struct anv_pipeline_stage *stage = &stages[s];
pipeline->feedback_index[s] = stage->feedback_idx;
pipeline->robust_flags[s] = stage->robust_flags;
}
pipeline_feedback->duration = os_time_get_nano() - pipeline_start;
@@ -2508,7 +2515,7 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
struct anv_shader_bin *bin = NULL;
populate_cs_prog_key(device, device->robust_buffer_access, &stage.key.cs);
populate_cs_prog_key(&stage, device);
const bool skip_cache_lookup =
(pipeline->base.flags & VK_PIPELINE_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR);
@@ -2913,6 +2920,7 @@ anv_graphics_pipeline_import_lib(struct anv_graphics_base_pipeline *pipeline,
stages[s].stage = s;
stages[s].feedback_idx = shader_count + lib->base.feedback_index[s];
stages[s].robust_flags = lib->base.robust_flags[s];
/* Always import the shader sha1, this will be used for cache lookup. */
memcpy(stages[s].shader_sha1, lib->retained_shaders[s].shader_sha1,
@@ -3437,13 +3445,12 @@ anv_pipeline_init_ray_tracing_stages(struct anv_ray_tracing_pipeline *pipeline,
pipeline->base.active_stages |= sinfo->stage;
populate_bs_prog_key(pipeline->base.device,
pipeline->base.device->robust_buffer_access,
ray_flags,
&stages[i].key.bs);
anv_stage_write_shader_hash(&stages[i], sinfo);
populate_bs_prog_key(&stages[i],
pipeline->base.device,
ray_flags);
if (stages[i].stage != MESA_SHADER_INTERSECTION) {
anv_pipeline_hash_ray_tracing_shader(pipeline, &stages[i],
stages[i].cache_key.sha1);

View File

@@ -3458,6 +3458,10 @@ struct anv_graphics_base_pipeline {
*/
uint32_t feedback_index[ANV_GRAPHICS_SHADER_STAGE_COUNT];
/* Robustness flags used shaders
*/
enum brw_robustness_flags robust_flags[ANV_GRAPHICS_SHADER_STAGE_COUNT];
/* True if at the time the fragment shader was compiled, it didn't have all
* the information to avoid BRW_WM_MSAA_FLAG_ENABLE_DYNAMIC.
*/

View File

@@ -2677,12 +2677,12 @@ cmd_buffer_flush_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer,
#endif
/* Compute robust pushed register access mask for each stage. */
if (cmd_buffer->device->robust_buffer_access) {
anv_foreach_stage(stage, dirty_stages) {
if (!anv_pipeline_has_stage(pipeline, stage))
continue;
anv_foreach_stage(stage, dirty_stages) {
if (!anv_pipeline_has_stage(pipeline, stage))
continue;
const struct anv_shader_bin *shader = pipeline->base.shaders[stage];
const struct anv_shader_bin *shader = pipeline->base.shaders[stage];
if (shader->prog_data->zero_push_reg) {
const struct anv_pipeline_bind_map *bind_map = &shader->bind_map;
struct anv_push_constants *push = &gfx_state->base.push_constants;

View File

@@ -38,10 +38,10 @@ bool anv_nir_lower_ycbcr_textures(nir_shader *shader,
static inline nir_address_format
anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
if (pdevice->has_a64_buffer_access) {
if (robust_buffer_access)
if (robust_flags & BRW_ROBUSTNESS_SSBO)
return nir_address_format_64bit_bounded_global;
else
return nir_address_format_64bit_global_32bit_offset;
@@ -52,10 +52,10 @@ anv_nir_ssbo_addr_format(const struct anv_physical_device *pdevice,
static inline nir_address_format
anv_nir_ubo_addr_format(const struct anv_physical_device *pdevice,
bool robust_buffer_access)
enum brw_robustness_flags robust_flags)
{
if (pdevice->has_a64_buffer_access) {
if (robust_buffer_access)
if (robust_flags & BRW_ROBUSTNESS_UBO)
return nir_address_format_64bit_bounded_global;
else
return nir_address_format_64bit_global_32bit_offset;
@@ -68,13 +68,13 @@ bool anv_nir_lower_ubo_loads(nir_shader *shader);
void anv_nir_apply_pipeline_layout(nir_shader *shader,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
const struct anv_pipeline_layout *layout,
struct anv_pipeline_bind_map *map);
void anv_nir_compute_push_layout(nir_shader *nir,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
struct brw_stage_prog_data *prog_data,
struct anv_pipeline_bind_map *map,
void *mem_ctx);

View File

@@ -1234,7 +1234,7 @@ compare_binding_infos(const void *_a, const void *_b)
void
anv_nir_apply_pipeline_layout(nir_shader *shader,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
const struct anv_pipeline_layout *layout,
struct anv_pipeline_bind_map *map)
{
@@ -1243,8 +1243,8 @@ anv_nir_apply_pipeline_layout(nir_shader *shader,
struct apply_pipeline_layout_state state = {
.pdevice = pdevice,
.layout = layout,
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_buffer_access),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_buffer_access),
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_flags),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_flags),
.lowered_instrs = _mesa_pointer_set_create(mem_ctx),
};

View File

@@ -31,7 +31,7 @@
void
anv_nir_compute_push_layout(nir_shader *nir,
const struct anv_physical_device *pdevice,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
struct brw_stage_prog_data *prog_data,
struct anv_pipeline_bind_map *map,
void *mem_ctx)
@@ -77,7 +77,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
has_const_ubo && nir->info.stage != MESA_SHADER_COMPUTE &&
!brw_shader_stage_requires_bindless_resources(nir->info.stage);
if (push_ubo_ranges && robust_buffer_access) {
if (push_ubo_ranges && (robust_flags & BRW_ROBUSTNESS_UBO)) {
/* We can't on-the-fly adjust our push ranges because doing so would
* mess up the layout in the shader. When robustBufferAccess is
* enabled, we push a mask into the shader indicating which pushed
@@ -180,7 +180,7 @@ anv_nir_compute_push_layout(nir_shader *nir,
if (push_constant_range.length > 0)
map->push_ranges[n++] = push_constant_range;
if (robust_buffer_access) {
if (robust_flags & BRW_ROBUSTNESS_UBO) {
const uint32_t push_reg_mask_offset =
offsetof(struct anv_push_constants, push_reg_mask[nir->info.stage]);
assert(push_reg_mask_offset >= push_start);
@@ -212,7 +212,8 @@ anv_nir_compute_push_layout(nir_shader *nir,
};
/* We only bother to shader-zero pushed client UBOs */
if (binding->set < MAX_SETS && robust_buffer_access) {
if (binding->set < MAX_SETS &&
(robust_flags & BRW_ROBUSTNESS_UBO)) {
prog_data->zero_push_reg |= BITFIELD64_RANGE(range_start_reg,
ubo_range->length);
}

View File

@@ -48,6 +48,7 @@
static nir_shader *
anv_shader_stage_to_nir(struct anv_device *device,
const VkPipelineShaderStageCreateInfo *stage_info,
enum brw_robustness_flags robust_flags,
void *mem_ctx)
{
const struct anv_physical_device *pdevice = device->physical;
@@ -111,10 +112,8 @@ anv_shader_stage_to_nir(struct anv_device *device,
.vk_memory_model_device_scope = true,
.workgroup_memory_explicit_layout = true,
},
.ubo_addr_format =
anv_nir_ubo_addr_format(pdevice, device->robust_buffer_access),
.ssbo_addr_format =
anv_nir_ssbo_addr_format(pdevice, device->robust_buffer_access),
.ubo_addr_format = anv_nir_ubo_addr_format(pdevice, robust_flags),
.ssbo_addr_format = anv_nir_ssbo_addr_format(pdevice, robust_flags),
.phys_ssbo_addr_format = nir_address_format_64bit_global,
.push_const_addr_format = nir_address_format_logical,
@@ -263,10 +262,10 @@ populate_sampler_prog_key(const struct intel_device_info *devinfo,
static void
populate_base_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
struct brw_base_prog_key *key)
{
key->robust_buffer_access = robust_buffer_acccess;
key->robust_flags = robust_flags;
key->limit_trig_input_range =
device->physical->instance->limit_trig_input_range;
@@ -275,12 +274,12 @@ populate_base_prog_key(const struct anv_device *device,
static void
populate_vs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
struct brw_vs_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
/* XXX: Handle vertex input work-arounds */
@@ -289,40 +288,40 @@ populate_vs_prog_key(const struct anv_device *device,
static void
populate_tcs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
unsigned input_vertices,
struct brw_tcs_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
key->input_vertices = input_vertices;
}
static void
populate_tes_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
struct brw_tes_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
}
static void
populate_gs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
bool robust_flags,
struct brw_gs_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
}
static void
populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
const BITSET_WORD *dynamic,
const struct vk_multisample_state *ms,
const struct vk_render_pass_state *rp,
@@ -332,7 +331,7 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
/* We set this to 0 here and set to the actual value before we call
* brw_compile_fs.
@@ -379,22 +378,22 @@ populate_wm_prog_key(const struct anv_graphics_pipeline *pipeline,
static void
populate_cs_prog_key(const struct anv_device *device,
bool robust_buffer_acccess,
enum brw_robustness_flags robust_flags,
struct brw_cs_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_acccess, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
}
static void
populate_bs_prog_key(const struct anv_device *device,
bool robust_buffer_access,
enum brw_robustness_flags robust_flags,
struct brw_bs_prog_key *key)
{
memset(key, 0, sizeof(*key));
populate_base_prog_key(device, robust_buffer_access, &key->base);
populate_base_prog_key(device, robust_flags, &key->base);
}
struct anv_pipeline_stage {
@@ -445,9 +444,6 @@ anv_pipeline_hash_graphics(struct anv_graphics_pipeline *pipeline,
if (layout)
_mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
const bool rba = pipeline->base.device->vk.enabled_features.robustBufferAccess;
_mesa_sha1_update(&ctx, &rba, sizeof(rba));
for (uint32_t s = 0; s < ANV_GRAPHICS_SHADER_STAGE_COUNT; s++) {
if (stages[s].info) {
_mesa_sha1_update(&ctx, stages[s].shader_sha1,
@@ -507,7 +503,8 @@ anv_pipeline_stage_get_nir(struct anv_pipeline *pipeline,
return nir;
}
nir = anv_shader_stage_to_nir(pipeline->device, stage->info, mem_ctx);
nir = anv_shader_stage_to_nir(pipeline->device, stage->info,
stage->key.base.robust_flags, mem_ctx);
if (nir) {
anv_device_upload_nir(pipeline->device, cache, nir, stage->shader_sha1);
return nir;
@@ -575,15 +572,13 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
/* Apply the actual pipeline layout to UBOs, SSBOs, and textures */
NIR_PASS_V(nir, anv_nir_apply_pipeline_layout,
pdevice, pipeline->device->robust_buffer_access,
pdevice, stage->key.base.robust_flags,
layout, &stage->bind_map);
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ubo,
anv_nir_ubo_addr_format(pdevice,
pipeline->device->robust_buffer_access));
anv_nir_ubo_addr_format(pdevice, stage->key.base.robust_flags));
NIR_PASS(_, nir, nir_lower_explicit_io, nir_var_mem_ssbo,
anv_nir_ssbo_addr_format(pdevice,
pipeline->device->robust_buffer_access));
anv_nir_ssbo_addr_format(pdevice, stage->key.base.robust_flags));
/* First run copy-prop to get rid of all of the vec() that address
* calculations often create and then constant-fold so that, when we
@@ -616,7 +611,7 @@ anv_pipeline_lower_nir(struct anv_pipeline *pipeline,
}
NIR_PASS_V(nir, anv_nir_compute_push_layout,
pdevice, pipeline->device->robust_buffer_access,
pdevice, stage->key.base.robust_flags,
prog_data, &stage->bind_map, mem_ctx);
if (gl_shader_stage_uses_workgroup(nir->info.stage)) {
@@ -1093,6 +1088,13 @@ anv_pipeline_add_executables(struct anv_pipeline *pipeline,
}
}
static enum brw_robustness_flags
anv_device_get_robust_flags(const struct anv_device *device)
{
return device->robust_buffer_access ?
(BRW_ROBUSTNESS_UBO | BRW_ROBUSTNESS_SSBO) : 0;
}
static void
anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline,
const struct vk_graphics_pipeline_state *state,
@@ -1107,31 +1109,32 @@ anv_graphics_pipeline_init_keys(struct anv_graphics_pipeline *pipeline,
vk_pipeline_hash_shader_stage(stages[s].info, NULL, stages[s].shader_sha1);
const struct anv_device *device = pipeline->base.device;
enum brw_robustness_flags robust_flags = anv_device_get_robust_flags(device);
switch (stages[s].stage) {
case MESA_SHADER_VERTEX:
populate_vs_prog_key(device,
pipeline->base.device->robust_buffer_access,
robust_flags,
&stages[s].key.vs);
break;
case MESA_SHADER_TESS_CTRL:
populate_tcs_prog_key(device,
pipeline->base.device->robust_buffer_access,
robust_flags,
state->ts->patch_control_points,
&stages[s].key.tcs);
break;
case MESA_SHADER_TESS_EVAL:
populate_tes_prog_key(device,
pipeline->base.device->robust_buffer_access,
robust_flags,
&stages[s].key.tes);
break;
case MESA_SHADER_GEOMETRY:
populate_gs_prog_key(device,
pipeline->base.device->robust_buffer_access,
robust_flags,
&stages[s].key.gs);
break;
case MESA_SHADER_FRAGMENT: {
populate_wm_prog_key(pipeline,
pipeline->base.device->robust_buffer_access,
robust_flags,
state->dynamic, state->ms, state->rp,
&stages[s].key.wm);
break;
@@ -1510,7 +1513,9 @@ anv_pipeline_compile_cs(struct anv_compute_pipeline *pipeline,
struct anv_shader_bin *bin = NULL;
populate_cs_prog_key(device, device->robust_buffer_access, &stage.key.cs);
populate_cs_prog_key(device,
anv_device_get_robust_flags(device),
&stage.key.cs);
ANV_FROM_HANDLE(anv_pipeline_layout, layout, info->layout);