[Mesa-dev] [PATCH 7/8] st/mesa: add support for hw atomics to glsl->tgsi. (v3)
Nicolai Hähnle
nhaehnle at gmail.com
Tue Nov 7 16:37:30 UTC 2017
On 07.11.2017 07:31, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> This adds support for creating the hw atomic tgsi from
> the glsl codepaths.
>
> v2: drop the atomic index and move to backend.
> v3: drop buffer decls. (Marek)
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 101 ++++++++++++++++++++++++-----
> 1 file changed, 86 insertions(+), 15 deletions(-)
>
> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> index 54e1961..6256f1c 100644
> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
> @@ -152,6 +152,13 @@ find_array_type(struct inout_decl *decls, unsigned count, unsigned array_id)
> return GLSL_TYPE_ERROR;
> }
>
> +struct hwatomic_decl {
> + unsigned location;
> + unsigned binding;
> + unsigned size;
> + unsigned array_id;
> +};
> +
> struct glsl_to_tgsi_visitor : public ir_visitor {
> public:
> glsl_to_tgsi_visitor();
> @@ -176,6 +183,9 @@ public:
> unsigned num_outputs;
> unsigned num_output_arrays;
>
> + struct hwatomic_decl atomic_info[PIPE_MAX_HW_ATOMIC_BUFFERS];
> + unsigned num_atomics;
> + unsigned num_atomic_arrays;
> int num_address_regs;
> uint32_t samplers_used;
> glsl_base_type sampler_types[PIPE_MAX_SAMPLERS];
> @@ -3206,24 +3216,64 @@ glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
> exec_node *param = ir->actual_parameters.get_head();
> ir_dereference *deref = static_cast<ir_dereference *>(param);
> ir_variable *location = deref->variable_referenced();
> -
> - st_src_reg buffer(
> - PROGRAM_BUFFER, location->data.binding, GLSL_TYPE_ATOMIC_UINT);
> -
> + bool has_hw_atomics = st_context(ctx)->has_hw_atomics;
> /* Calculate the surface offset */
> st_src_reg offset;
> unsigned array_size = 0, base = 0;
> uint16_t index = 0;
> + st_src_reg resource;
>
> get_deref_offsets(deref, &array_size, &base, &index, &offset, false);
>
> - if (offset.file != PROGRAM_UNDEFINED) {
> - emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(offset),
> - offset, st_src_reg_for_int(ATOMIC_COUNTER_SIZE));
> - emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(offset),
> - offset, st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE));
> + if (has_hw_atomics) {
> + variable_storage *entry = find_variable_storage(location);
> + st_src_reg buffer(PROGRAM_HW_ATOMIC, 0, GLSL_TYPE_ATOMIC_UINT, location->data.binding);
> +
> + if (!entry) {
> + entry = new(mem_ctx) variable_storage(location, PROGRAM_HW_ATOMIC,
> + num_atomics);
> + _mesa_hash_table_insert(this->variables, location, entry);
> +
> + atomic_info[num_atomics].location = location->data.location;
> + atomic_info[num_atomics].binding = location->data.binding;
> + atomic_info[num_atomics].size = location->type->arrays_of_arrays_size();
> + atomic_info[num_atomics].array_id = 0;
> + num_atomics++;
> + }
> +
> + if (offset.file != PROGRAM_UNDEFINED) {
> + if (atomic_info[entry->index].array_id == 0) {
> + num_atomic_arrays++;
> + atomic_info[entry->index].array_id = num_atomic_arrays;
> + }
> + buffer.array_id = atomic_info[entry->index].array_id;
> + }
> +
> + buffer.index = index;
> + buffer.index += location->data.offset / ATOMIC_COUNTER_SIZE;
> + buffer.has_index2 = true;
Similar to patch 2, I'm concerned here about the range of index. I don't
think this is quite the right approach.'m not sure this is entirely the
right approach.
Cheers,
Nicolai
> +
> + if (offset.file != PROGRAM_UNDEFINED) {
> + buffer.reladdr = ralloc(mem_ctx, st_src_reg);
> + *buffer.reladdr = offset;
> + emit_arl(ir, sampler_reladdr, offset);
> + }
> + offset = st_src_reg_for_int(0);
> +
> + resource = buffer;
> } else {
> - offset = st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE);
> + st_src_reg buffer(PROGRAM_BUFFER, location->data.binding,
> + GLSL_TYPE_ATOMIC_UINT);
> +
> + if (offset.file != PROGRAM_UNDEFINED) {
> + emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(offset),
> + offset, st_src_reg_for_int(ATOMIC_COUNTER_SIZE));
> + emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(offset),
> + offset, st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE));
> + } else {
> + offset = st_src_reg_for_int(location->data.offset + index * ATOMIC_COUNTER_SIZE);
> + }
> + resource = buffer;
> }
>
> ir->return_deref->accept(this);
> @@ -3286,7 +3336,7 @@ glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
> inst = emit_asm(ir, opcode, dst, offset, data, data2);
> }
>
> - inst->resource = buffer;
> + inst->resource = resource;
> }
>
> void
> @@ -4384,10 +4434,13 @@ glsl_to_tgsi_visitor::glsl_to_tgsi_visitor()
> array_sizes = NULL;
> max_num_arrays = 0;
> next_array = 0;
> + num_atomic_arrays = 0;
> num_inputs = 0;
> num_outputs = 0;
> num_input_arrays = 0;
> num_output_arrays = 0;
> + num_atomics = 0;
> + num_atomic_arrays = 0;
> num_immediates = 0;
> num_address_regs = 0;
> samplers_used = 0;
> @@ -5305,6 +5358,7 @@ struct st_translate {
> struct ureg_src buffers[PIPE_MAX_SHADER_BUFFERS];
> struct ureg_src images[PIPE_MAX_SHADER_IMAGES];
> struct ureg_src systemValues[SYSTEM_VALUE_MAX];
> + struct ureg_src hw_atomics[PIPE_MAX_HW_ATOMIC_BUFFERS];
> struct ureg_src shared_memory;
> unsigned *array_sizes;
> struct inout_decl *input_decls;
> @@ -5646,6 +5700,11 @@ translate_src(struct st_translate *t, const st_src_reg *src_reg)
> src = t->systemValues[src_reg->index];
> break;
>
> + case PROGRAM_HW_ATOMIC:
> + src = ureg_src_array_register(TGSI_FILE_HW_ATOMIC, src_reg->index,
> + src_reg->array_id);
> + break;
> +
> default:
> assert(!"unknown src register file");
> return ureg_src_undef();
> @@ -5801,6 +5860,8 @@ compile_tgsi_instruction(struct st_translate *t,
> src[0] = t->shared_memory;
> } else if (inst->resource.file == PROGRAM_BUFFER) {
> src[0] = t->buffers[inst->resource.index];
> + } else if (inst->resource.file == PROGRAM_HW_ATOMIC) {
> + src[0] = translate_src(t, &inst->resource);
> } else if (inst->resource.file == PROGRAM_CONSTANT) {
> assert(inst->resource.has_index2);
> src[0] = ureg_src_register(TGSI_FILE_CONSTBUF, inst->resource.index);
> @@ -6502,10 +6563,20 @@ st_translate_program(
> {
> struct gl_program *prog = program->prog;
>
> - for (i = 0; i < prog->info.num_abos; i++) {
> - unsigned index = prog->sh.AtomicBuffers[i]->Binding;
> - assert(index < frag_const->MaxAtomicBuffers);
> - t->buffers[index] = ureg_DECL_buffer(ureg, index, true);
> + if (!st_context(ctx)->has_hw_atomics) {
> + for (i = 0; i < prog->info.num_abos; i++) {
> + unsigned index = prog->sh.AtomicBuffers[i]->Binding;
> + assert(index < frag_const->MaxAtomicBuffers);
> + t->buffers[index] = ureg_DECL_buffer(ureg, index, true);
> + }
> + } else {
> + for (i = 0; i < program->num_atomics; i++) {
> + struct hwatomic_decl *ainfo = &program->atomic_info[i];
> + gl_uniform_storage *uni_storage = &prog->sh.data->UniformStorage[ainfo->location];
> + int base = uni_storage->offset / ATOMIC_COUNTER_SIZE;
> + ureg_DECL_hw_atomic(ureg, base, base + ainfo->size, ainfo->binding,
> + ainfo->array_id);
> + }
> }
>
> assert(prog->info.num_ssbos <= frag_const->MaxShaderStorageBlocks);
>
--
Lerne, wie die Welt wirklich ist,
Aber vergiss niemals, wie sie sein sollte.
More information about the mesa-dev
mailing list