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:
Jason Ekstrand 2018-06-28 22:44:24 -07:00
parent 3a5ed18c51
commit 70ce880434
3 changed files with 99 additions and 17 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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) {