ralloc_free(shader);
}
+static bool
+is_shared_consts(struct ir3_compiler *compiler,
+ struct ir3_const_state *const_state,
+ struct ir3_register *reg)
+{
+ if (const_state->shared_consts_enable && reg->flags & IR3_REG_CONST) {
+ uint32_t min_const_reg = regid(compiler->shared_consts_base_offset, 0);
+ uint32_t max_const_reg =
+ regid(compiler->shared_consts_base_offset +
+ compiler->shared_consts_size, 0);
+ return reg->num >= min_const_reg && min_const_reg < max_const_reg;
+ }
+
+ return false;
+}
+
static void
collect_reg_info(struct ir3_instruction *instr, struct ir3_register *reg,
struct ir3_info *info)
return;
}
+ /* Shared consts don't need to be included into constlen. */
+ if (is_shared_consts(v->compiler, ir3_const_state(v), reg))
+ return;
+
if (!(reg->flags & IR3_REG_R)) {
repeat = 0;
}
compiler->has_dp2acc = dev_info->a6xx.has_dp2acc;
compiler->has_dp4acc = dev_info->a6xx.has_dp4acc;
+
+ compiler->shared_consts_base_offset = 504;
+ compiler->shared_consts_size = 8;
+ compiler->geom_shared_consts_size_quirk = 16;
} else {
compiler->max_const_pipeline = 512;
compiler->max_const_geom = 512;
bool has_preamble;
bool push_ubo_with_preamble;
+
+ /* Where the shared consts start in constants file, in vec4's. */
+ uint16_t shared_consts_base_offset;
+
+ /* The size of shared consts for CS and FS(in vec4's).
+ * Also the size that is actually used on geometry stages (on a6xx).
+ */
+ uint64_t shared_consts_size;
+
+ /* Found on a6xx for geometry stages, that is different from
+ * actually used shared consts.
+ *
+ * TODO: Keep an eye on this for next gens.
+ */
+ uint64_t geom_shared_consts_size_quirk;
};
struct ir3_compiler_options {
v->api_wavesize = shader->api_wavesize;
v->real_wavesize = shader->real_wavesize;
- if (!v->binning_pass)
+ if (!v->binning_pass) {
v->const_state = rzalloc_size(v, sizeof(*v->const_state));
+ v->const_state->shared_consts_enable = shader->shared_consts_enable;
+ }
return v;
}
uint32_t trimmed = 0;
STATIC_ASSERT(MESA_SHADER_STAGES <= 8 * sizeof(trimmed));
+ bool shared_consts_enable =
+ ir3_const_state(variants[MESA_SHADER_VERTEX])->shared_consts_enable;
+
+ /* Use a hw quirk for geometry shared consts, not matched with actual
+ * shared consts size (on a6xx).
+ */
+ uint32_t shared_consts_size_geom = shared_consts_enable ?
+ compiler->geom_shared_consts_size_quirk : 0;
+
+ uint32_t shared_consts_size = shared_consts_enable ?
+ compiler->shared_consts_size : 0;
+
+ uint32_t safe_shared_consts_size = shared_consts_enable ?
+ ALIGN_POT(MAX2(DIV_ROUND_UP(shared_consts_size_geom, 4),
+ DIV_ROUND_UP(shared_consts_size, 5)), 4) : 0;
+
/* There are two shared limits to take into account, the geometry limit on
* a6xx and the total limit. The frag limit on a6xx only matters for a
* single stage, so it's always satisfied with the first variant.
if (compiler->gen >= 6) {
trimmed |=
trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_GEOMETRY,
- compiler->max_const_geom, compiler->max_const_safe);
+ compiler->max_const_geom - shared_consts_size_geom,
+ compiler->max_const_safe - safe_shared_consts_size);
}
trimmed |=
trim_constlens(constlens, MESA_SHADER_VERTEX, MESA_SHADER_FRAGMENT,
- compiler->max_const_pipeline, compiler->max_const_safe);
+ compiler->max_const_pipeline - shared_consts_size,
+ compiler->max_const_safe - safe_shared_consts_size);
return trimmed;
}
shader->num_reserved_user_consts = options->reserved_user_consts;
shader->api_wavesize = options->api_wavesize;
shader->real_wavesize = options->real_wavesize;
+ shader->shared_consts_enable = options->shared_consts_enable;
shader->nir = nir;
ir3_disk_cache_init_shader_key(compiler, shader);
/* State of ubo access lowered to push consts: */
struct ir3_ubo_analysis_state ubo_state;
+ bool shared_consts_enable;
};
/**
* recompiles for GL NOS that doesn't actually apply to the shader.
*/
struct ir3_shader_key key_mask;
+
+ bool shared_consts_enable;
};
/**
/* Given a variant, calculate the maximum constlen it can have.
*/
-
static inline unsigned
ir3_max_const(const struct ir3_shader_variant *v)
{
const struct ir3_compiler *compiler = v->compiler;
+ bool shared_consts_enable = ir3_const_state(v)->shared_consts_enable;
+
+ /* Shared consts size for CS and FS matches with what's acutally used,
+ * but the size of shared consts for geomtry stages doesn't.
+ * So we use a hw quirk for geometry shared consts.
+ */
+ uint32_t shared_consts_size = shared_consts_enable ?
+ compiler->shared_consts_size : 0;
+
+ uint32_t shared_consts_size_geom = shared_consts_enable ?
+ compiler->geom_shared_consts_size_quirk : 0;
+
+ uint32_t safe_shared_consts_size = shared_consts_enable ?
+ ALIGN_POT(MAX2(DIV_ROUND_UP(shared_consts_size_geom, 4),
+ DIV_ROUND_UP(shared_consts_size, 5)), 4) : 0;
if ((v->type == MESA_SHADER_COMPUTE) ||
(v->type == MESA_SHADER_KERNEL)) {
- return compiler->max_const_compute;
+ return compiler->max_const_compute - shared_consts_size;
} else if (v->key.safe_constlen) {
- return compiler->max_const_safe;
+ return compiler->max_const_safe - safe_shared_consts_size;
} else if (v->type == MESA_SHADER_FRAGMENT) {
- return compiler->max_const_frag;
+ return compiler->max_const_frag - shared_consts_size;
} else {
- return compiler->max_const_geom;
+ return compiler->max_const_geom - shared_consts_size_geom;
}
}
struct ir3_shader_options {
unsigned reserved_user_consts;
enum ir3_wavesize_option api_wavesize, real_wavesize;
+ bool shared_consts_enable;
};
struct ir3_shader *