From c960323a81456b05570ed9647f19207e7733aa11 Mon Sep 17 00:00:00 2001 From: Andreas Baierl Date: Fri, 26 Apr 2019 15:06:13 +0200 Subject: [PATCH] lima/ppir: Add gl_FragCoord handling Treat gl_FragCoord variable as a system value and lower the w component with a nir pass. Add the necessary bits for correct codegen. Signed-off-by: Andreas Baierl Reviewed-by: Qiang Yu --- src/gallium/drivers/lima/ir/pp/codegen.c | 9 ++++++++- src/gallium/drivers/lima/ir/pp/nir.c | 11 +++++++++++ src/gallium/drivers/lima/ir/pp/node.c | 7 +++++++ src/gallium/drivers/lima/ir/pp/node_to_instr.c | 3 ++- src/gallium/drivers/lima/ir/pp/ppir.h | 1 + src/gallium/drivers/lima/lima_program.c | 1 + src/gallium/drivers/lima/lima_screen.c | 3 +++ 7 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c index 23d9a7aa41b..93fd5628669 100644 --- a/src/gallium/drivers/lima/ir/pp/codegen.c +++ b/src/gallium/drivers/lima/ir/pp/codegen.c @@ -54,7 +54,9 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code) int num_components = load->num_components; if (num_components) { - assert(node->op == ppir_op_load_varying || node->op == ppir_op_load_coords); + assert(node->op == ppir_op_load_varying || + node->op == ppir_op_load_coords || + node->op == ppir_op_load_fragcoord); f->imm.dest = index >> 2; f->imm.mask = dest->write_mask << (index & 0x3); @@ -67,6 +69,11 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code) f->imm.index = load->index >> 2; else f->imm.index = load->index >> alignment; + + if (node->op == ppir_op_load_fragcoord) { + f->imm.source_type = 2; + f->imm.perspective = 3; + } } else { assert(node->op == ppir_op_load_coords); diff --git a/src/gallium/drivers/lima/ir/pp/nir.c b/src/gallium/drivers/lima/ir/pp/nir.c index a962a2b776f..008a5225edc 100644 --- a/src/gallium/drivers/lima/ir/pp/nir.c +++ b/src/gallium/drivers/lima/ir/pp/nir.c @@ -224,6 +224,17 @@ static ppir_node *ppir_emit_intrinsic(ppir_block *block, nir_instr *ni) lnode->index = nir_intrinsic_base(instr) * 4 + nir_intrinsic_component(instr); return &lnode->node; + case nir_intrinsic_load_frag_coord: + if (!instr->dest.is_ssa) + mask = u_bit_consecutive(0, instr->num_components); + + lnode = ppir_node_create_dest(block, ppir_op_load_fragcoord, &instr->dest, mask); + if (!lnode) + return NULL; + + lnode->num_components = instr->num_components; + return &lnode->node; + case nir_intrinsic_load_uniform: if (!instr->dest.is_ssa) mask = u_bit_consecutive(0, instr->num_components); diff --git a/src/gallium/drivers/lima/ir/pp/node.c b/src/gallium/drivers/lima/ir/pp/node.c index 0f4cacb33a1..5abf263768e 100644 --- a/src/gallium/drivers/lima/ir/pp/node.c +++ b/src/gallium/drivers/lima/ir/pp/node.c @@ -238,6 +238,13 @@ const ppir_op_info ppir_op_infos[] = { PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END }, }, + [ppir_op_load_fragcoord] = { + .name = "ld_fragcoord", + .type = ppir_node_type_load, + .slots = (int []) { + PPIR_INSTR_SLOT_VARYING, PPIR_INSTR_SLOT_END + }, + }, [ppir_op_load_uniform] = { .name = "ld_uni", .type = ppir_node_type_load, diff --git a/src/gallium/drivers/lima/ir/pp/node_to_instr.c b/src/gallium/drivers/lima/ir/pp/node_to_instr.c index 26d2c9868f6..b38fa3aa733 100644 --- a/src/gallium/drivers/lima/ir/pp/node_to_instr.c +++ b/src/gallium/drivers/lima/ir/pp/node_to_instr.c @@ -238,7 +238,8 @@ static bool ppir_do_node_to_instr(ppir_block *block, ppir_node *node) load->dest.type = ppir_target_pipeline; load->dest.pipeline = ppir_pipeline_reg_uniform; } - else if (node->op == ppir_op_load_varying) { + else if (node->op == ppir_op_load_varying || + node->op == ppir_op_load_fragcoord) { /* delay the load varying dup to scheduler */ if (!create_new_instr(block, node)) return false; diff --git a/src/gallium/drivers/lima/ir/pp/ppir.h b/src/gallium/drivers/lima/ir/pp/ppir.h index feb34895114..60901018a58 100644 --- a/src/gallium/drivers/lima/ir/pp/ppir.h +++ b/src/gallium/drivers/lima/ir/pp/ppir.h @@ -98,6 +98,7 @@ typedef enum { ppir_op_load_uniform, ppir_op_load_varying, ppir_op_load_coords, + ppir_op_load_fragcoord, ppir_op_load_texture, ppir_op_load_temp, diff --git a/src/gallium/drivers/lima/lima_program.c b/src/gallium/drivers/lima/lima_program.c index 72f3a6f10ad..98416471e67 100644 --- a/src/gallium/drivers/lima/lima_program.c +++ b/src/gallium/drivers/lima/lima_program.c @@ -124,6 +124,7 @@ lima_program_optimize_fs_nir(struct nir_shader *s) { bool progress; + NIR_PASS_V(s, nir_lower_fragcoord_wtrans); NIR_PASS_V(s, nir_lower_io, nir_var_all, type_size, 0); NIR_PASS_V(s, nir_lower_regs_to_ssa); NIR_PASS_V(s, nir_lower_bool_to_float); diff --git a/src/gallium/drivers/lima/lima_screen.c b/src/gallium/drivers/lima/lima_screen.c index cd9639b41e2..29dfc16c7ac 100644 --- a/src/gallium/drivers/lima/lima_screen.c +++ b/src/gallium/drivers/lima/lima_screen.c @@ -114,6 +114,9 @@ lima_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_HALF_INTEGER: return 1; + case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: + return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: -- 2.30.2