diff --git a/src/compiler/nir/nir_opt_load_store_vectorize.c b/src/compiler/nir/nir_opt_load_store_vectorize.c index 2d8f6326165..66fe634a31a 100644 --- a/src/compiler/nir/nir_opt_load_store_vectorize.c +++ b/src/compiler/nir/nir_opt_load_store_vectorize.c @@ -1066,6 +1066,9 @@ is_strided_vector(const struct glsl_type *type) static bool can_vectorize(struct vectorize_ctx *ctx, struct entry *first, struct entry *second) { + if ((first->access | second->access) & ACCESS_KEEP_SCALAR) + return false; + if (!(get_variable_mode(first) & ctx->options->modes) || !(get_variable_mode(second) & ctx->options->modes)) return false; diff --git a/src/compiler/shader_enums.h b/src/compiler/shader_enums.h index 33bb4760c8f..45dda151689 100644 --- a/src/compiler/shader_enums.h +++ b/src/compiler/shader_enums.h @@ -1145,6 +1145,19 @@ enum gl_access_qualifier * on AGX, used for some internal shaders. */ ACCESS_IN_BOUNDS_AGX = (1 << 14), + + /** + * Disallow vectorization. + * + * On some hw (AMD), sparse buffer loads return 0 for all components if + * a sparse load starts on a non-resident page, crosses the page boundary, + * and ends on a resident page. Sometimes we want it to return 0 only for + * the portion of the load that's non-resident, and load values for + * the portion that's resident. The workaround is to scalarize such loads + * and disallow vectorization. This is used by an internal copy_buffer + * shader where the API wants to copy all bytes that are resident. + */ + ACCESS_KEEP_SCALAR = (1 << 15), }; /**