asahi: implement rba2 semantics for vbo

Different APIs have different robustness requirements for VBOs. Add a knob to
select the desired robustness so we can implement rba2 in honeykrisp.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29742>
This commit is contained in:
Alyssa Rosenzweig
2024-06-07 22:32:11 -04:00
parent d035976c00
commit 38c36990b6
5 changed files with 61 additions and 13 deletions

View File

@@ -61,6 +61,9 @@ struct agx_vs_prolog_key {
/* If !hw and the draw call is indexed, the index size */
uint8_t sw_index_size_B;
/* Robustness settings for the vertex fetch */
struct agx_robustness robustness;
};
struct agx_fs_prolog_key {

View File

@@ -11,6 +11,11 @@
#include "util/u_math.h"
#include "shader_enums.h"
struct ctx {
struct agx_attribute *attribs;
struct agx_robustness rs;
};
static bool
is_rgb10_a2(const struct util_format_description *desc)
{
@@ -109,7 +114,8 @@ pass(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
if (intr->intrinsic != nir_intrinsic_load_input)
return false;
struct agx_attribute *attribs = data;
struct ctx *ctx = data;
struct agx_attribute *attribs = ctx->attribs;
b->cursor = nir_instr_remove(&intr->instr);
nir_src *offset_src = nir_get_io_offset_src(intr);
@@ -190,14 +196,12 @@ pass(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
* before the load. That is faster than the 4 cmpsel required after the load,
* and it avoids waiting on the load which should help prolog performance.
*
* TODO: Plumb through soft fault information to skip this.
* TODO: Optimize.
*
* TODO: Add a knob for robustBufferAccess2 semantics.
* TODO: We always clamp to handle null descriptors. Maybe optimize?
*/
bool robust = true;
if (robust) {
el = nir_umin(b, el, bounds);
}
nir_def *oob = nir_ult(b, bounds, el);
el = nir_bcsel(b, oob, nir_imm_int(b, 0), el);
nir_def *base = nir_load_vbo_base_agx(b, buf_handle);
@@ -228,6 +232,12 @@ pass(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
b, interchange_comps, interchange_register_size, base, stride_offset_el,
.format = interchange_format, .base = shift);
/* TODO: Optimize per above */
if (ctx->rs.level >= AGX_ROBUSTNESS_D3D) {
nir_def *zero = nir_imm_zero(b, memory->num_components, memory->bit_size);
memory = nir_bcsel(b, oob, zero, memory);
}
unsigned dest_size = intr->def.bit_size;
/* Unpack but do not convert non-native non-array formats */
@@ -290,9 +300,12 @@ pass(struct nir_builder *b, nir_intrinsic_instr *intr, void *data)
}
bool
agx_nir_lower_vbo(nir_shader *shader, struct agx_attribute *attribs)
agx_nir_lower_vbo(nir_shader *shader, struct agx_attribute *attribs,
struct agx_robustness robustness)
{
assert(shader->info.stage == MESA_SHADER_VERTEX);
struct ctx ctx = {.attribs = attribs, .rs = robustness};
return nir_shader_intrinsics_pass(
shader, pass, nir_metadata_block_index | nir_metadata_dominance, attribs);
shader, pass, nir_metadata_block_index | nir_metadata_dominance, &ctx);
}

View File

@@ -33,7 +33,30 @@ struct agx_attribute {
bool instanced : 1;
};
bool agx_nir_lower_vbo(nir_shader *shader, struct agx_attribute *attribs);
enum agx_robustness_level {
/* No robustness */
AGX_ROBUSTNESS_DISABLED,
/* Invalid load/store must not fault, but undefined value/effect */
AGX_ROBUSTNESS_GLES,
/* Invalid load/store access something from the array (or 0) */
AGX_ROBUSTNESS_GL,
/* Invalid loads return 0 and invalid stores are dropped */
AGX_ROBUSTNESS_D3D,
};
struct agx_robustness {
enum agx_robustness_level level;
/* Whether hardware "soft fault" is enabled. */
bool soft_fault;
};
bool agx_nir_lower_vbo(nir_shader *shader, struct agx_attribute *attribs,
struct agx_robustness rs);
bool agx_vbo_supports_format(enum pipe_format format);
#ifdef __cplusplus

View File

@@ -56,7 +56,8 @@ agx_nir_lower_poly_stipple(nir_shader *s)
}
static bool
lower_vbo(nir_shader *s, const struct agx_velem_key *key)
lower_vbo(nir_shader *s, const struct agx_velem_key *key,
const struct agx_robustness rs)
{
struct agx_attribute out[AGX_MAX_VBUFS];
@@ -69,7 +70,7 @@ lower_vbo(nir_shader *s, const struct agx_velem_key *key)
};
}
return agx_nir_lower_vbo(s, out);
return agx_nir_lower_vbo(s, out, rs);
}
static int
@@ -166,7 +167,7 @@ agx_nir_vs_prolog(nir_builder *b, const void *key_)
nir_export_agx(b, nir_load_instance_id(b), .base = 6 * 2);
/* Now lower the resulting program using the key */
lower_vbo(b->shader, key->attribs);
lower_vbo(b->shader, key->attribs, key->robustness);
if (!key->hw) {
agx_nir_lower_index_buffer(b->shader, key->sw_index_size_B, false);

View File

@@ -2213,6 +2213,14 @@ agx_update_vs(struct agx_context *ctx, unsigned index_size_B)
struct agx_fast_link_key link_key = {
.prolog.vs.hw = key.hw,
.prolog.vs.sw_index_size_B = key.hw ? 0 : index_size_B,
/* TODO: We could optimize this */
.prolog.vs.robustness =
{
.level = AGX_ROBUSTNESS_GL,
.soft_fault = false,
},
.main = ctx->vs,
};