diff --git a/src/compiler/glsl_types.h b/src/compiler/glsl_types.h index 85028726622..733c8dbf49c 100644 --- a/src/compiler/glsl_types.h +++ b/src/compiler/glsl_types.h @@ -466,6 +466,11 @@ struct glsl_struct_field { */ unsigned precision:2; + /** + * Pixel local storage qualifier + */ + unsigned pixel_local_storage:2; + /** * Memory qualifiers, applicable to buffer variables defined in shader * storage buffer objects (SSBOs) diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 92da79df5f4..c62f63c1421 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -256,6 +256,9 @@ nir_shader_add_variable(nir_shader *shader, nir_variable *var) case nir_var_mem_node_payload: case nir_var_mem_node_payload_in: case nir_var_mem_global: + case nir_var_mem_pixel_local_in: + case nir_var_mem_pixel_local_out: + case nir_var_mem_pixel_local_inout: break; default: diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 623b5d07953..77bd9868674 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -448,7 +448,7 @@ typedef struct nir_variable { * * :c:struct:`nir_variable_mode` */ - unsigned mode : 21; + unsigned mode : 24; /** * Is the variable read-only? diff --git a/src/compiler/nir/nir_defines.h b/src/compiler/nir/nir_defines.h index 4c4f78c8c9d..ec4af3009e2 100644 --- a/src/compiler/nir/nir_defines.h +++ b/src/compiler/nir/nir_defines.h @@ -76,18 +76,21 @@ typedef enum { nir_var_mem_task_payload = (1 << 11), nir_var_mem_node_payload = (1 << 12), nir_var_mem_node_payload_in = (1 << 13), + nir_var_mem_pixel_local_in = (1 << 14), + nir_var_mem_pixel_local_out = (1 << 15), + nir_var_mem_pixel_local_inout = (1 << 16), - nir_var_function_in = (1 << 14), - nir_var_function_out = (1 << 15), - nir_var_function_inout = (1 << 16), + nir_var_function_in = (1 << 17), + nir_var_function_out = (1 << 18), + nir_var_function_inout = (1 << 19), /* Generic modes intentionally come last. See encode_dref_modes() in * nir_serialize.c for more details. */ - nir_var_shader_temp = (1 << 17), - nir_var_function_temp = (1 << 18), - nir_var_mem_shared = (1 << 19), - nir_var_mem_global = (1 << 20), + nir_var_shader_temp = (1 << 20), + nir_var_function_temp = (1 << 21), + nir_var_mem_shared = (1 << 22), + nir_var_mem_global = (1 << 23), nir_var_mem_generic = (nir_var_shader_temp | nir_var_function_temp | @@ -105,7 +108,13 @@ typedef enum { nir_var_mem_shared | nir_var_mem_global | nir_var_mem_push_const | nir_var_mem_task_payload | nir_var_shader_out | nir_var_system_value, - nir_num_variable_modes = 21, + + /* modes that can serve as fragment shader outputs */ + nir_var_any_pixel_local = nir_var_mem_pixel_local_in | + nir_var_mem_pixel_local_out | + nir_var_mem_pixel_local_inout, + + nir_num_variable_modes = 24, nir_var_all = (1 << nir_num_variable_modes) - 1, } nir_variable_mode; MESA_DEFINE_CPP_ENUM_BITFIELD_OPERATORS(nir_variable_mode) diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index eb88ac91409..0456213f43c 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -514,6 +514,9 @@ gather_intrinsic_info(nir_intrinsic_instr *instr, nir_shader *shader) } if (nir_intrinsic_writes_external_memory(instr)) shader->info.writes_memory = true; + if (shader->info.stage == MESA_SHADER_FRAGMENT && + nir_deref_mode_is_one_of(deref, nir_var_any_pixel_local)) + shader->info.fs.accesses_pixel_local_storage = true; break; } case nir_intrinsic_image_deref_load: @@ -1049,6 +1052,7 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint) shader->info.vs.double_inputs = 0; } if (shader->info.stage == MESA_SHADER_FRAGMENT) { + shader->info.fs.accesses_pixel_local_storage = false; shader->info.fs.uses_sample_qualifier = false; shader->info.fs.uses_discard = false; shader->info.fs.color_is_dual_source = false; diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c index 7204d6cf547..d0add266ab4 100644 --- a/src/compiler/nir/nir_print.c +++ b/src/compiler/nir/nir_print.c @@ -752,6 +752,12 @@ get_variable_mode_str(nir_variable_mode mode, bool want_local_global_mode) return "push_const"; case nir_var_mem_constant: return "constant"; + case nir_var_mem_pixel_local_in: + return "pixel_local_in"; + case nir_var_mem_pixel_local_out: + return "pixel_local_out"; + case nir_var_mem_pixel_local_inout: + return "pixel_local"; case nir_var_image: return "image"; case nir_var_shader_temp: @@ -1054,6 +1060,11 @@ print_deref_link(const nir_deref_instr *instr, bool whole_chain, print_state *st case nir_deref_type_struct: fprintf(fp, "%s%s", is_parent_pointer ? "->" : ".", glsl_get_struct_elem_name(parent->type, instr->strct.index)); + if (whole_chain && + parent->type->fields.structure[instr->strct.index].pixel_local_storage) { + fprintf(fp, " (%s)", + util_format_short_name(parent->type->fields.structure[instr->strct.index].image_format)); + } break; case nir_deref_type_array: diff --git a/src/compiler/nir/nir_validate.c b/src/compiler/nir/nir_validate.c index 94081846a77..a42254d2f85 100644 --- a/src/compiler/nir/nir_validate.c +++ b/src/compiler/nir/nir_validate.c @@ -2284,6 +2284,9 @@ nir_validate_shader(nir_shader *shader, const char *when) nir_var_mem_global | nir_var_mem_push_const | nir_var_mem_constant | + nir_var_mem_pixel_local_in | + nir_var_mem_pixel_local_out | + nir_var_mem_pixel_local_inout | nir_var_image; if (mesa_shader_stage_is_callable(shader->info.stage)) diff --git a/src/compiler/shader_info.h b/src/compiler/shader_info.h index db7fc2fc21e..b082a6fc1ea 100644 --- a/src/compiler/shader_info.h +++ b/src/compiler/shader_info.h @@ -459,6 +459,11 @@ typedef struct shader_info { bool sample_interlock_ordered:1; bool sample_interlock_unordered:1; + /** + * whether this shader has pixel_local_storage load/store instructions + */ + bool accesses_pixel_local_storage:1; + /** * Flags whether NIR's base types on the FS color outputs should be * ignored.