From 70ce8804341479aba8115784d8dad1166315e402 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 28 Jun 2018 22:44:24 -0700 Subject: [PATCH] anv: Add state setup support for shader constants Reviewed-by: Timothy Arceri Reviewed-by: Iago Toral Quiroga Reviewed-by: Kenneth Graunke --- .../vulkan/anv_nir_apply_pipeline_layout.c | 47 ++++++++++++ src/intel/vulkan/anv_private.h | 1 + src/intel/vulkan/genX_cmd_buffer.c | 72 ++++++++++++++----- 3 files changed, 101 insertions(+), 19 deletions(-) diff --git a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c index 37a54b2efff..c287a005bd6 100644 --- a/src/intel/vulkan/anv_nir_apply_pipeline_layout.c +++ b/src/intel/vulkan/anv_nir_apply_pipeline_layout.c @@ -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; diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index f82b88df7a0..139c48b7e46 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -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 { diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 611311904e6..6832bb669f8 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -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); - - 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); + const struct anv_descriptor *desc = + anv_descriptor_for_binding(&gfx_state->base, binding); + + 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); + + 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) { -- 2.30.2