nir_var_shader_temp |
nir_var_function_temp |
nir_var_mem_ssbo |
- nir_var_mem_shared);
+ nir_var_mem_shared |
+ nir_var_mem_global);
continue;
}
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
switch (intrin->intrinsic) {
- case nir_intrinsic_barrier:
+ case nir_intrinsic_control_barrier:
+ case nir_intrinsic_group_memory_barrier:
case nir_intrinsic_memory_barrier: {
clear_unused_for_modes(&unused_writes, nir_var_shader_out |
nir_var_mem_ssbo |
- nir_var_mem_shared);
+ nir_var_mem_shared |
+ nir_var_mem_global);
break;
}
- case nir_intrinsic_scoped_memory_barrier: {
+ case nir_intrinsic_memory_barrier_buffer:
+ clear_unused_for_modes(&unused_writes, nir_var_mem_ssbo |
+ nir_var_mem_global);
+ break;
+
+ case nir_intrinsic_memory_barrier_shared:
+ clear_unused_for_modes(&unused_writes, nir_var_mem_shared);
+ break;
+
+ case nir_intrinsic_memory_barrier_tcs_patch:
+ clear_unused_for_modes(&unused_writes, nir_var_shader_out);
+ break;
+
+ case nir_intrinsic_scoped_barrier: {
if (nir_intrinsic_memory_semantics(intrin) & NIR_MEMORY_RELEASE) {
clear_unused_for_modes(&unused_writes,
nir_intrinsic_memory_modes(intrin));
case nir_intrinsic_store_deref: {
nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
+
+ if (nir_intrinsic_access(intrin) & ACCESS_VOLATILE) {
+ /* Consider a volatile write to also be a sort of read. This
+ * prevents us from deleting a non-volatile write just before a
+ * volatile write thanks to a non-volatile write afterwards. It's
+ * quite the corner case, but this should be safer and more
+ * predictable for the programmer than allowing two non-volatile
+ * writes to be combined with a volatile write between them.
+ */
+ clear_unused_for_read(&unused_writes, dst);
+ break;
+ }
+
nir_component_mask_t mask = nir_intrinsic_write_mask(intrin);
progress |= update_unused_writes(&unused_writes, intrin, dst, mask);
break;
nir_deref_instr *src = nir_src_as_deref(intrin->src[1]);
nir_deref_instr *dst = nir_src_as_deref(intrin->src[0]);
+ if (nir_intrinsic_dst_access(intrin) & ACCESS_VOLATILE) {
+ clear_unused_for_read(&unused_writes, src);
+ clear_unused_for_read(&unused_writes, dst);
+ break;
+ }
+
/* Self-copy is removed. */
if (nir_compare_derefs(src, dst) & nir_derefs_equal_bit) {
nir_instr_remove(instr);
if (progress) {
nir_metadata_preserve(impl, nir_metadata_block_index |
nir_metadata_dominance);
+ } else {
+ nir_metadata_preserve(impl, nir_metadata_all);
}
return progress;