From 678ebda8b7df114f278f619f88ab2a0a5cf0eb48 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Sat, 14 Sep 2019 11:00:16 -0700 Subject: [PATCH] lima/ppir: add support for indirect load of uniforms and varyings Utgard PP supports indirect load of uniforms and varyings, so let's enable it. Reviewed-by: Qiang Yu Signed-off-by: Vasily Khoruzhick --- src/gallium/drivers/lima/ir/pp/codegen.c | 21 ++++++++++++++------- src/gallium/drivers/lima/ir/pp/disasm.c | 2 +- src/gallium/drivers/lima/ir/pp/lower.c | 9 ++++++--- src/gallium/drivers/lima/ir/pp/nir.c | 13 ++++++++++++- src/gallium/drivers/lima/ir/pp/node.c | 19 +++++++++++++++++++ src/gallium/drivers/lima/lima_screen.c | 8 ++++++++ 6 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c index 8dac09bd471..47e25d3f886 100644 --- a/src/gallium/drivers/lima/ir/pp/codegen.c +++ b/src/gallium/drivers/lima/ir/pp/codegen.c @@ -65,7 +65,13 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code) int alignment = num_components == 3 ? 3 : num_components - 1; f->imm.alignment = alignment; - f->imm.offset_vector = 0xf; + + if (load->num_src) { + index = ppir_target_get_src_reg_index(&load->src); + f->imm.offset_vector = index >> 2; + f->imm.offset_scalar = index & 0x3; + } else + f->imm.offset_vector = 0xf; if (alignment == 3) f->imm.index = load->index >> 2; @@ -134,13 +140,14 @@ static void ppir_codegen_encode_uniform(ppir_node *node, void *code) assert(0); } - int num_components = load->num_components; - int alignment = num_components == 4 ? 2 : num_components - 1; - - f->alignment = alignment; + /* Uniforms are always aligned to vec4 boundary */ + f->alignment = 2; + f->index = load->index; - /* TODO: uniform can be also combined like varying */ - f->index = load->index << (2 - alignment); + if (load->num_src) { + f->offset_en = 1; + f->offset_reg = ppir_target_get_src_reg_index(&load->src); + } } static unsigned shift_to_op(int shift) diff --git a/src/gallium/drivers/lima/ir/pp/disasm.c b/src/gallium/drivers/lima/ir/pp/disasm.c index 1f7dc0a5a80..04035a6373a 100644 --- a/src/gallium/drivers/lima/ir/pp/disasm.c +++ b/src/gallium/drivers/lima/ir/pp/disasm.c @@ -318,7 +318,7 @@ print_uniform(void *code, unsigned offset) } if (uniform->offset_en) { - printf(" "); + printf("+"); print_source_scalar(uniform->offset_reg, NULL, false, false); } } diff --git a/src/gallium/drivers/lima/ir/pp/lower.c b/src/gallium/drivers/lima/ir/pp/lower.c index 3b3f6dd5915..c0070480a68 100644 --- a/src/gallium/drivers/lima/ir/pp/lower.c +++ b/src/gallium/drivers/lima/ir/pp/lower.c @@ -96,9 +96,12 @@ static bool ppir_lower_load(ppir_block *block, ppir_node *node) return true; } - assert(ppir_node_has_single_src_succ(node) || ppir_node_is_root(node)); - ppir_node *succ = ppir_node_first_succ(node); - if (dest->type != ppir_target_register) { + /* load can have multiple successors in case if we duplicated load node + * that has load node in source + */ + if ((ppir_node_has_single_src_succ(node) || ppir_node_is_root(node)) && + dest->type != ppir_target_register) { + ppir_node *succ = ppir_node_first_succ(node); switch (succ->type) { case ppir_node_type_alu: case ppir_node_type_branch: { diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index 78ac3efd48b..c254035b3fb 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -319,6 +319,12 @@ static ppir_node *ppir_emit_intrinsic(ppir_block *block, nir_instr *ni) lnode->num_components = instr->num_components; lnode->index = nir_intrinsic_base(instr) * 4 + nir_intrinsic_component(instr); + if (nir_src_is_const(instr->src[0])) + lnode->index += (uint32_t)(nir_src_as_float(instr->src[0]) * 4); + else { + lnode->num_src = 1; + ppir_node_add_src(block->comp, &lnode->node, &lnode->src, instr->src, 1); + } return &lnode->node; case nir_intrinsic_load_frag_coord: @@ -360,7 +366,12 @@ static ppir_node *ppir_emit_intrinsic(ppir_block *block, nir_instr *ni) lnode->num_components = instr->num_components; lnode->index = nir_intrinsic_base(instr); - lnode->index += (uint32_t)nir_src_as_float(instr->src[0]); + if (nir_src_is_const(instr->src[0])) + lnode->index += (uint32_t)nir_src_as_float(instr->src[0]); + else { + lnode->num_src = 1; + ppir_node_add_src(block->comp, &lnode->node, &lnode->src, instr->src, 1); + } return &lnode->node; diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index 5428a7b37f4..29627c71ca0 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -703,6 +703,25 @@ ppir_node_clone_load(ppir_block *block, ppir_node *node) ppir_dest *dest = ppir_node_get_dest(node); new_lnode->dest = *dest; + ppir_src *src = ppir_node_get_src(node, 0); + if (src) { + new_lnode->num_src = 1; + switch (src->type) { + case ppir_target_ssa: + ppir_node_target_assign(&new_lnode->src, src->node); + ppir_node_add_dep(&new_lnode->node, src->node, ppir_dep_src); + break; + case ppir_target_register: + new_lnode->src.type = src->type; + new_lnode->src.reg = src->reg; + new_lnode->src.node = NULL; + break; + default: + /* Load nodes can't consume pipeline registers */ + assert(0); + } + } + return &new_lnode->node; } diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index 3c1288c897f..8db8b7071ee 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -229,6 +229,14 @@ get_fragment_shader_param(struct lima_screen *screen, case PIPE_SHADER_CAP_MAX_TEMPS: return 256; /* need investigate */ + case PIPE_SHADER_CAP_INDIRECT_INPUT_ADDR: + case PIPE_SHADER_CAP_INDIRECT_CONST_ADDR: + return 1; + + case PIPE_SHADER_CAP_INDIRECT_TEMP_ADDR: + case PIPE_SHADER_CAP_INDIRECT_OUTPUT_ADDR: + return 0; + default: return 0; } -- 2.30.2