mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 02:38:04 +02:00
anv: Add state setup support for shader constants
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
3a5ed18c51
commit
70ce880434
3 changed files with 99 additions and 17 deletions
|
|
@ -32,6 +32,8 @@ struct apply_pipeline_layout_state {
|
|||
struct anv_pipeline_layout *layout;
|
||||
bool add_bounds_checks;
|
||||
|
||||
bool uses_constants;
|
||||
uint8_t constants_offset;
|
||||
struct {
|
||||
BITSET_WORD *used;
|
||||
uint8_t *surface_offsets;
|
||||
|
|
@ -100,6 +102,10 @@ get_used_bindings_block(nir_block *block,
|
|||
add_deref_src_binding(state, intrin->src[0]);
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_constant:
|
||||
state->uses_constants = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -172,6 +178,33 @@ lower_res_reindex_intrinsic(nir_intrinsic_instr *intrin,
|
|||
nir_instr_remove(&intrin->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
lower_load_constant(nir_intrinsic_instr *intrin,
|
||||
struct apply_pipeline_layout_state *state)
|
||||
{
|
||||
nir_builder *b = &state->builder;
|
||||
|
||||
b->cursor = nir_before_instr(&intrin->instr);
|
||||
|
||||
nir_ssa_def *index = nir_imm_int(b, state->constants_offset);
|
||||
nir_ssa_def *offset = nir_iadd(b, nir_ssa_for_src(b, intrin->src[0], 1),
|
||||
nir_imm_int(b, nir_intrinsic_base(intrin)));
|
||||
|
||||
nir_intrinsic_instr *load_ubo =
|
||||
nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_ubo);
|
||||
load_ubo->num_components = intrin->num_components;
|
||||
load_ubo->src[0] = nir_src_for_ssa(index);
|
||||
load_ubo->src[1] = nir_src_for_ssa(offset);
|
||||
nir_ssa_dest_init(&load_ubo->instr, &load_ubo->dest,
|
||||
intrin->dest.ssa.num_components,
|
||||
intrin->dest.ssa.bit_size, NULL);
|
||||
nir_builder_instr_insert(b, &load_ubo->instr);
|
||||
|
||||
nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
|
||||
nir_src_for_ssa(&load_ubo->dest.ssa));
|
||||
nir_instr_remove(&intrin->instr);
|
||||
}
|
||||
|
||||
static void
|
||||
lower_tex_deref(nir_tex_instr *tex, nir_tex_src_type deref_src_type,
|
||||
unsigned *base_index,
|
||||
|
|
@ -285,6 +318,9 @@ apply_pipeline_layout_block(nir_block *block,
|
|||
case nir_intrinsic_vulkan_resource_reindex:
|
||||
lower_res_reindex_intrinsic(intrin, state);
|
||||
break;
|
||||
case nir_intrinsic_load_constant:
|
||||
lower_load_constant(intrin, state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -343,6 +379,9 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline,
|
|||
get_used_bindings_block(block, &state);
|
||||
}
|
||||
|
||||
if (state.uses_constants)
|
||||
map->surface_count++;
|
||||
|
||||
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
||||
struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
||||
|
||||
|
|
@ -365,6 +404,14 @@ anv_nir_apply_pipeline_layout(struct anv_pipeline *pipeline,
|
|||
unsigned surface = 0;
|
||||
unsigned sampler = 0;
|
||||
unsigned image = 0;
|
||||
|
||||
if (state.uses_constants) {
|
||||
state.constants_offset = surface;
|
||||
map->surface_to_descriptor[surface].set =
|
||||
ANV_DESCRIPTOR_SET_SHADER_CONSTANTS;
|
||||
surface++;
|
||||
}
|
||||
|
||||
for (uint32_t set = 0; set < layout->num_sets; set++) {
|
||||
struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
|
||||
|
||||
|
|
|
|||
|
|
@ -1570,6 +1570,7 @@ anv_descriptor_set_destroy(struct anv_device *device,
|
|||
struct anv_descriptor_pool *pool,
|
||||
struct anv_descriptor_set *set);
|
||||
|
||||
#define ANV_DESCRIPTOR_SET_SHADER_CONSTANTS (UINT8_MAX - 1)
|
||||
#define ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS UINT8_MAX
|
||||
|
||||
struct anv_pipeline_binding {
|
||||
|
|
|
|||
|
|
@ -2031,6 +2031,26 @@ emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
|
|||
|
||||
bt_map[bias + s] = surface_state.offset + state_offset;
|
||||
continue;
|
||||
} else if (binding->set == ANV_DESCRIPTOR_SET_SHADER_CONSTANTS) {
|
||||
struct anv_state surface_state =
|
||||
anv_cmd_buffer_alloc_surface_state(cmd_buffer);
|
||||
|
||||
struct anv_address constant_data = {
|
||||
.bo = &pipeline->device->dynamic_state_pool.block_pool.bo,
|
||||
.offset = pipeline->shaders[stage]->constant_data.offset,
|
||||
};
|
||||
unsigned constant_data_size =
|
||||
pipeline->shaders[stage]->constant_data_size;
|
||||
|
||||
const enum isl_format format =
|
||||
anv_isl_format_for_descriptor_type(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
anv_fill_buffer_surface_state(cmd_buffer->device,
|
||||
surface_state, format,
|
||||
constant_data, constant_data_size, 1);
|
||||
|
||||
bt_map[bias + s] = surface_state.offset + state_offset;
|
||||
add_surface_reloc(cmd_buffer, surface_state, constant_data);
|
||||
continue;
|
||||
}
|
||||
|
||||
const struct anv_descriptor *desc =
|
||||
|
|
@ -2384,30 +2404,44 @@ cmd_buffer_flush_push_constants(struct anv_cmd_buffer *cmd_buffer,
|
|||
const struct anv_pipeline_binding *binding =
|
||||
&bind_map->surface_to_descriptor[surface];
|
||||
|
||||
const struct anv_descriptor *desc =
|
||||
anv_descriptor_for_binding(&gfx_state->base, binding);
|
||||
|
||||
struct anv_address read_addr;
|
||||
uint32_t read_len;
|
||||
if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
|
||||
if (binding->set == ANV_DESCRIPTOR_SET_SHADER_CONSTANTS) {
|
||||
struct anv_address constant_data = {
|
||||
.bo = &pipeline->device->dynamic_state_pool.block_pool.bo,
|
||||
.offset = pipeline->shaders[stage]->constant_data.offset,
|
||||
};
|
||||
unsigned constant_data_size =
|
||||
pipeline->shaders[stage]->constant_data_size;
|
||||
|
||||
read_len = MIN2(range->length,
|
||||
DIV_ROUND_UP(desc->buffer_view->range, 32) - range->start);
|
||||
read_addr = anv_address_add(desc->buffer_view->address,
|
||||
DIV_ROUND_UP(constant_data_size, 32) - range->start);
|
||||
read_addr = anv_address_add(constant_data,
|
||||
range->start * 32);
|
||||
} else {
|
||||
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||
const struct anv_descriptor *desc =
|
||||
anv_descriptor_for_binding(&gfx_state->base, binding);
|
||||
|
||||
uint32_t dynamic_offset =
|
||||
dynamic_offset_for_binding(&gfx_state->base, binding);
|
||||
uint32_t buf_offset =
|
||||
MIN2(desc->offset + dynamic_offset, desc->buffer->size);
|
||||
uint32_t buf_range =
|
||||
MIN2(desc->range, desc->buffer->size - buf_offset);
|
||||
if (desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) {
|
||||
read_len = MIN2(range->length,
|
||||
DIV_ROUND_UP(desc->buffer_view->range, 32) - range->start);
|
||||
read_addr = anv_address_add(desc->buffer_view->address,
|
||||
range->start * 32);
|
||||
} else {
|
||||
assert(desc->type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
|
||||
|
||||
read_len = MIN2(range->length,
|
||||
DIV_ROUND_UP(buf_range, 32) - range->start);
|
||||
read_addr = anv_address_add(desc->buffer->address,
|
||||
buf_offset + range->start * 32);
|
||||
uint32_t dynamic_offset =
|
||||
dynamic_offset_for_binding(&gfx_state->base, binding);
|
||||
uint32_t buf_offset =
|
||||
MIN2(desc->offset + dynamic_offset, desc->buffer->size);
|
||||
uint32_t buf_range =
|
||||
MIN2(desc->range, desc->buffer->size - buf_offset);
|
||||
|
||||
read_len = MIN2(range->length,
|
||||
DIV_ROUND_UP(buf_range, 32) - range->start);
|
||||
read_addr = anv_address_add(desc->buffer->address,
|
||||
buf_offset + range->start * 32);
|
||||
}
|
||||
}
|
||||
|
||||
if (read_len > 0) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue