lima/ppir: Add gl_FragCoord handling
authorAndreas Baierl <ichgeh@imkreisrum.de>
Fri, 26 Apr 2019 13:06:13 +0000 (15:06 +0200)
committerQiang Yu <yuq825@gmail.com>
Mon, 29 Apr 2019 02:46:44 +0000 (02:46 +0000)
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 <ichgeh@imkreisrum.de>
Reviewed-by: Qiang Yu <yuq825@gmail.com>
src/gallium/drivers/lima/ir/pp/codegen.c
src/gallium/drivers/lima/ir/pp/nir.c
src/gallium/drivers/lima/ir/pp/node.c
src/gallium/drivers/lima/ir/pp/node_to_instr.c
src/gallium/drivers/lima/ir/pp/ppir.h
src/gallium/drivers/lima/lima_program.c
src/gallium/drivers/lima/lima_screen.c

index 23d9a7aa41b677d25bfa713ea9457347ec711417..93fd5628669fc73034983f21b493643a0c66ad5b 100644 (file)
@@ -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);
index a962a2b776f90dcf4bd1e6cf6dfda0d3bb201c7d..008a5225edcb09fe37b8fa142d965619064667ef 100644 (file)
@@ -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);
index 0f4cacb33a1c90301cda2a39b6cfe21996060caf..5abf263768ec9c29c8b7098d5b0775d3dfefdb00 100644 (file)
@@ -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,
index 26d2c9868f6b1a7ce114ab41afa7359f87e7cb57..b38fa3aa73336bf86e87e505b0e7dedc8e36bd2c 100644 (file)
@@ -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;
index feb348951145229f6cd2f25b3773838294facd85..60901018a5826af5dd213c5786c14a9e77fda220 100644 (file)
@@ -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,
 
index 72f3a6f10ad6aef9879bcff56c3d09834f219620..98416471e6758af658dc54549b32a11ffc28564e 100644 (file)
@@ -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);
index cd9639b41e2645e8bc2b475ae0722da7e08a092e..29dfc16c7ac6d05f7daf2a475ad2636b65f6bfab 100644 (file)
@@ -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: