lavapipe: move uniform inline functions to shader struct

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21778>
This commit is contained in:
Mike Blumenkrantz 2023-03-06 15:08:06 -05:00 committed by Marge Bot
parent 7718d7f31a
commit f2765cd6d6
4 changed files with 28 additions and 27 deletions

View file

@ -281,19 +281,20 @@ update_inline_shader_state(struct rendering_state *state, enum pipe_shader_type
state->inlines_dirty[sh] = false;
if (!state->pipeline[is_compute]->shaders[stage].inlines.can_inline)
return;
struct lvp_shader *shader = &state->pipeline[is_compute]->shaders[stage];
struct lvp_pipeline *pipeline = state->pipeline[is_compute];
/* these buffers have already been flushed in llvmpipe, so they're safe to read */
nir_shader *base_nir = pipeline->shaders[stage].pipeline_nir->nir;
nir_shader *base_nir = shader->pipeline_nir->nir;
if (stage == PIPE_SHADER_TESS_EVAL && state->tess_ccw)
base_nir = pipeline->shaders[stage].tess_ccw->nir;
nir_shader *nir = nir_shader_clone(pipeline->shaders[stage].pipeline_nir->nir, base_nir);
base_nir = shader->tess_ccw->nir;
nir_shader *nir = nir_shader_clone(shader->pipeline_nir->nir, base_nir);
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
unsigned ssa_alloc = impl->ssa_alloc;
unsigned count = pipeline->shaders[stage].inlines.count[0];
unsigned count = shader->inlines.count[0];
if (count && pcbuf_dirty) {
unsigned push_size = get_pcbuf_size(state, sh);
for (unsigned i = 0; i < count; i++) {
unsigned offset = pipeline->shaders[stage].inlines.uniform_offsets[0][i];
unsigned offset = shader->inlines.uniform_offsets[0][i];
if (offset < push_size) {
memcpy(&inline_uniforms[i], &state->push_constants[offset], sizeof(uint32_t));
} else {
@ -308,12 +309,12 @@ update_inline_shader_state(struct rendering_state *state, enum pipe_shader_type
}
}
}
NIR_PASS_V(nir, lvp_inline_uniforms, pipeline, inline_uniforms, 0);
NIR_PASS_V(nir, lvp_inline_uniforms, shader, inline_uniforms, 0);
}
if (constbuf_dirty) {
struct pipe_box box = {0};
u_foreach_bit(slot, pipeline->shaders[stage].inlines.can_inline) {
unsigned count = pipeline->shaders[stage].inlines.count[slot];
u_foreach_bit(slot, shader->inlines.can_inline) {
unsigned count = shader->inlines.count[slot];
struct pipe_constant_buffer *cbuf = &state->const_buffer[sh][slot - 1];
struct pipe_resource *pres = cbuf->buffer;
box.x = cbuf->buffer_offset;
@ -321,22 +322,22 @@ update_inline_shader_state(struct rendering_state *state, enum pipe_shader_type
struct pipe_transfer *xfer;
uint8_t *map = state->pctx->buffer_map(state->pctx, pres, 0, PIPE_MAP_READ, &box, &xfer);
for (unsigned i = 0; i < count; i++) {
unsigned offset = pipeline->shaders[stage].inlines.uniform_offsets[slot][i];
unsigned offset = shader->inlines.uniform_offsets[slot][i];
memcpy(&inline_uniforms[i], map + offset, sizeof(uint32_t));
}
state->pctx->buffer_unmap(state->pctx, xfer);
NIR_PASS_V(nir, lvp_inline_uniforms, pipeline, inline_uniforms, slot);
NIR_PASS_V(nir, lvp_inline_uniforms, shader, inline_uniforms, slot);
}
}
lvp_shader_optimize(nir);
impl = nir_shader_get_entrypoint(nir);
void *shader_state;
if (ssa_alloc - impl->ssa_alloc < ssa_alloc / 2 &&
!pipeline->shaders[stage].inlines.must_inline) {
!shader->inlines.must_inline) {
/* not enough change; don't inline further */
pipeline->shaders[stage].inlines.can_inline = 0;
shader->inlines.can_inline = 0;
ralloc_free(nir);
pipeline->shaders[sh].shader_cso = lvp_pipeline_compile(pipeline, nir_shader_clone(NULL, pipeline->shaders[stage].pipeline_nir->nir));
pipeline->shaders[sh].shader_cso = lvp_pipeline_compile(pipeline, nir_shader_clone(NULL, shader->pipeline_nir->nir));
shader_state = pipeline->shaders[sh].shader_cso;
} else {
shader_state = lvp_pipeline_compile(pipeline, nir);

View file

@ -129,7 +129,7 @@ process_node(nir_cf_node *node, nir_loop_info *info,
}
bool
lvp_find_inlinable_uniforms(struct lvp_pipeline *pipeline, nir_shader *nir)
lvp_find_inlinable_uniforms(struct lvp_shader *shader, nir_shader *nir)
{
bool ret = false;
struct set *stores = _mesa_set_create(nir, _mesa_hash_pointer, _mesa_key_pointer_equal);
@ -138,7 +138,7 @@ lvp_find_inlinable_uniforms(struct lvp_pipeline *pipeline, nir_shader *nir)
nir_metadata_require(function->impl, nir_metadata_loop_analysis, nir_var_all);
foreach_list_typed(nir_cf_node, node, node, &function->impl->body)
process_node(node, NULL, (uint32_t*)pipeline->shaders[nir->info.stage].inlines.uniform_offsets, pipeline->shaders[nir->info.stage].inlines.count, stores);
process_node(node, NULL, (uint32_t*)shader->inlines.uniform_offsets, shader->inlines.count, stores);
}
}
const unsigned threshold = 5;
@ -152,21 +152,21 @@ lvp_find_inlinable_uniforms(struct lvp_pipeline *pipeline, nir_shader *nir)
}
if (counter >= threshold) {
uint8_t new_num[PIPE_MAX_CONSTANT_BUFFERS];
memcpy(new_num, pipeline->shaders[nir->info.stage].inlines.count, sizeof(new_num));
memcpy(new_num, shader->inlines.count, sizeof(new_num));
uint32_t *uni_offsets =
(uint32_t *) pipeline->shaders[nir->info.stage].inlines.uniform_offsets;
(uint32_t *) shader->inlines.uniform_offsets;
if (nir_collect_src_uniforms(src, 0, uni_offsets, new_num,
PIPE_MAX_CONSTANT_BUFFERS, UINT_MAX)) {
ret = true;
memcpy(pipeline->shaders[nir->info.stage].inlines.count, new_num, sizeof(new_num));
memcpy(shader->inlines.count, new_num, sizeof(new_num));
}
}
}
for (unsigned i = 0; i < PIPE_MAX_CONSTANT_BUFFERS; i++) {
if (pipeline->shaders[nir->info.stage].inlines.count[i]) {
pipeline->shaders[nir->info.stage].inlines.can_inline |= BITFIELD_BIT(i);
if (shader->inlines.count[i]) {
shader->inlines.can_inline |= BITFIELD_BIT(i);
break;
}
}
@ -174,9 +174,9 @@ lvp_find_inlinable_uniforms(struct lvp_pipeline *pipeline, nir_shader *nir)
}
void
lvp_inline_uniforms(nir_shader *nir, const struct lvp_pipeline *pipeline, const uint32_t *uniform_values, uint32_t ubo)
lvp_inline_uniforms(nir_shader *nir, const struct lvp_shader *shader, const uint32_t *uniform_values, uint32_t ubo)
{
if (!pipeline->shaders[nir->info.stage].inlines.can_inline)
if (!shader->inlines.can_inline)
return;
nir_foreach_function(function, nir) {
@ -199,8 +199,8 @@ lvp_inline_uniforms(nir_shader *nir, const struct lvp_pipeline *pipeline, const
intr->dest.ssa.bit_size == 32) {
int num_components = intr->dest.ssa.num_components;
uint32_t offset = nir_src_as_uint(intr->src[1]);
const unsigned num_uniforms = pipeline->shaders[nir->info.stage].inlines.count[ubo];
const unsigned *uniform_dw_offsets = pipeline->shaders[nir->info.stage].inlines.uniform_offsets[ubo];
const unsigned num_uniforms = shader->inlines.count[ubo];
const unsigned *uniform_dw_offsets = shader->inlines.uniform_offsets[ubo];
if (num_components == 1) {
/* Just replace the uniform load to constant load. */

View file

@ -516,7 +516,7 @@ lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
nir_function_impl *impl = nir_shader_get_entrypoint(nir);
if (impl->ssa_alloc > 100) //skip for small shaders
shader->inlines.must_inline = lvp_find_inlinable_uniforms(pipeline, nir);
shader->inlines.must_inline = lvp_find_inlinable_uniforms(shader, nir);
shader->pipeline_nir = ralloc(NULL, struct lvp_pipeline_nir);
shader->pipeline_nir->nir = nir;
shader->pipeline_nir->ref_cnt = 1;

View file

@ -635,9 +635,9 @@ lvp_shader_optimize(nir_shader *nir);
void *
lvp_pipeline_compile_stage(struct lvp_pipeline *pipeline, nir_shader *nir);
bool
lvp_find_inlinable_uniforms(struct lvp_pipeline *pipeline, nir_shader *nir);
lvp_find_inlinable_uniforms(struct lvp_shader *shader, nir_shader *nir);
void
lvp_inline_uniforms(nir_shader *nir, const struct lvp_pipeline *pipeline, const uint32_t *uniform_values, uint32_t ubo);
lvp_inline_uniforms(nir_shader *nir, const struct lvp_shader *shader, const uint32_t *uniform_values, uint32_t ubo);
void *
lvp_pipeline_compile(struct lvp_pipeline *pipeline, nir_shader *base_nir);
#ifdef __cplusplus