struct anv_pipeline_layout *layout;
bool add_bounds_checks;
+ bool uses_constants;
+ uint8_t constants_offset;
struct {
BITSET_WORD *used;
uint8_t *surface_offsets;
add_deref_src_binding(state, intrin->src[0]);
break;
+ case nir_intrinsic_load_constant:
+ state->uses_constants = true;
+ break;
+
default:
break;
}
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,
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;
}
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;
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;
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 =
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) {