lima/ppir: add lod-bias support
[mesa.git] / src / gallium / drivers / lima / ir / pp / codegen.c
index 09cf5e623bd9cbb546af45c194283ce36133a23c..76db5628ffc22c9aadf14c3e6c9f196a4e549e0c 100644 (file)
@@ -53,42 +53,70 @@ static void ppir_codegen_encode_varying(ppir_node *node, void *code)
    int index = ppir_target_get_dest_reg_index(dest);
    int num_components = load->num_components;
 
-   if (num_components) {
+   if (node->op != ppir_op_load_coords_reg) {
       assert(node->op == ppir_op_load_varying ||
              node->op == ppir_op_load_coords ||
-             node->op == ppir_op_load_fragcoord);
+             node->op == ppir_op_load_fragcoord ||
+             node->op == ppir_op_load_pointcoord ||
+             node->op == ppir_op_load_frontface);
 
       f->imm.dest = index >> 2;
       f->imm.mask = dest->write_mask << (index & 0x3);
 
       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;
       else
          f->imm.index = load->index >> alignment;
 
-      if (node->op == ppir_op_load_fragcoord) {
-         f->imm.source_type = 2;
-         f->imm.perspective = 3;
+      switch (node->op) {
+         case ppir_op_load_fragcoord:
+            f->imm.source_type = 2;
+            f->imm.perspective = 3;
+            break;
+         case ppir_op_load_pointcoord:
+            f->imm.source_type = 3;
+            break;
+         case ppir_op_load_frontface:
+            f->imm.source_type = 3;
+            f->imm.perspective = 1;
+            break;
+         case ppir_op_load_coords:
+            /* num_components == 3 implies cubemap as we don't support 3D textures */
+            f->imm.source_type = num_components == 3 ? 2 : 0;
+            break;
+         default:
+            break;
       }
    }
-   else {
-      assert(node->op == ppir_op_load_coords);
-
+   else {  /* node->op == ppir_op_load_coords_reg */
       f->reg.dest = index >> 2;
       f->reg.mask = dest->write_mask << (index & 0x3);
 
-      f->reg.source_type = 1;
-
-      ppir_src *src = &load->src;
-      index = ppir_target_get_src_reg_index(src);
-      f->reg.source = index >> 2;
-      f->reg.negate = src->negate;
-      f->reg.absolute = src->absolute;
-      f->reg.swizzle = encode_swizzle(src->swizzle, index & 0x3, 0);
+      if (load->num_src) {
+         /* num_components == 3 implies cubemap as we don't support 3D textures */
+         if (num_components == 3) {
+            f->reg.source_type = 2;
+            f->reg.perspective = 1;
+         } else {
+            f->reg.source_type = 1;
+         }
+         ppir_src *src = &load->src;
+         index = ppir_target_get_src_reg_index(src);
+         f->reg.source = index >> 2;
+         f->reg.negate = src->negate;
+         f->reg.absolute = src->absolute;
+         f->reg.swizzle = encode_swizzle(src->swizzle, index & 0x3, 0);
+      }
    }
 }
 
@@ -98,8 +126,25 @@ static void ppir_codegen_encode_texld(ppir_node *node, void *code)
    ppir_load_texture_node *ldtex = ppir_node_to_load_texture(node);
 
    f->index = ldtex->sampler;
-   f->lod_bias_en = 0;
-   f->type = ppir_codegen_sampler_type_2d;
+
+   f->lod_bias_en = ldtex->lod_bias_en;
+   f->explicit_lod = ldtex->explicit_lod;
+   if (ldtex->lod_bias_en)
+      ppir_target_get_src_reg_index(&ldtex->lod_bias);
+
+   switch (ldtex->sampler_dim) {
+   case GLSL_SAMPLER_DIM_2D:
+   case GLSL_SAMPLER_DIM_RECT:
+   case GLSL_SAMPLER_DIM_EXTERNAL:
+      f->type = ppir_codegen_sampler_type_2d;
+      break;
+   case GLSL_SAMPLER_DIM_CUBE:
+      f->type = ppir_codegen_sampler_type_cube;
+      break;
+   default:
+      break;
+   }
+
    f->offset_en = 0;
    f->unknown_2 = 0x39001;
 }
@@ -120,13 +165,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)
@@ -155,6 +201,7 @@ static void ppir_codegen_encode_vec_mul(ppir_node *node, void *code)
       f->op = shift_to_op(alu->shift);
       break;
    case ppir_op_mov:
+   case ppir_op_store_color:
       f->op = ppir_codegen_vec4_mul_op_mov;
       break;
    case ppir_op_max:
@@ -230,6 +277,9 @@ static void ppir_codegen_encode_scl_mul(ppir_node *node, void *code)
    case ppir_op_mov:
       f->op = ppir_codegen_float_mul_op_mov;
       break;
+   case ppir_op_sel_cond:
+      f->op = ppir_codegen_float_mul_op_mov;
+      break;
    case ppir_op_max:
       f->op = ppir_codegen_float_mul_op_max;
       break;
@@ -294,6 +344,7 @@ static void ppir_codegen_encode_vec_add(ppir_node *node, void *code)
       f->op = ppir_codegen_vec4_acc_op_add;
       break;
    case ppir_op_mov:
+   case ppir_op_store_color:
       f->op = ppir_codegen_vec4_acc_op_mov;
       break;
    case ppir_op_sum3:
@@ -334,6 +385,12 @@ static void ppir_codegen_encode_vec_add(ppir_node *node, void *code)
    case ppir_op_min:
       f->op = ppir_codegen_vec4_acc_op_min;
       break;
+   case ppir_op_ddx:
+      f->op = ppir_codegen_vec4_acc_op_dFdx;
+      break;
+   case ppir_op_ddy:
+      f->op = ppir_codegen_vec4_acc_op_dFdy;
+      break;
    default:
       break;
    }
@@ -410,6 +467,12 @@ static void ppir_codegen_encode_scl_add(ppir_node *node, void *code)
    case ppir_op_select:
       f->op = ppir_codegen_float_acc_op_sel;
       break;
+   case ppir_op_ddx:
+      f->op = ppir_codegen_float_acc_op_dFdx;
+      break;
+   case ppir_op_ddy:
+      f->op = ppir_codegen_float_acc_op_dFdy;
+      break;
    default:
       break;
    }
@@ -528,6 +591,7 @@ static void ppir_codegen_encode_branch(ppir_node *node, void *code)
    ppir_codegen_field_branch *b = code;
    ppir_branch_node *branch;
    ppir_instr *target_instr;
+   ppir_block *target;
    if (node->op == ppir_op_discard) {
       ppir_codegen_encode_discard(node, code);
       return;
@@ -537,14 +601,35 @@ static void ppir_codegen_encode_branch(ppir_node *node, void *code)
    branch = ppir_node_to_branch(node);
 
    b->branch.unknown_0 = 0x0;
-   b->branch.arg0_source = ppir_target_get_src_reg_index(&branch->src[0]);
-   b->branch.arg1_source = ppir_target_get_src_reg_index(&branch->src[1]);
-   b->branch.cond_gt = branch->cond_gt;
-   b->branch.cond_eq = branch->cond_eq;
-   b->branch.cond_lt = branch->cond_lt;
    b->branch.unknown_1 = 0x0;
 
-   target_instr = list_first_entry(&branch->target->instr_list, ppir_instr, list);
+   if (branch->num_src == 2) {
+      b->branch.arg0_source = get_scl_reg_index(&branch->src[0], 0);
+      b->branch.arg1_source = get_scl_reg_index(&branch->src[1], 0);
+      b->branch.cond_gt = branch->cond_gt;
+      b->branch.cond_eq = branch->cond_eq;
+      b->branch.cond_lt = branch->cond_lt;
+   } else if (branch->num_src == 0) {
+      /* Unconditional branch */
+      b->branch.arg0_source = 0;
+      b->branch.arg1_source = 0;
+      b->branch.cond_gt = true;
+      b->branch.cond_eq = true;
+      b->branch.cond_lt = true;
+   } else {
+      assert(false);
+   }
+
+   target = branch->target;
+   while (list_is_empty(&target->instr_list)) {
+      if (!target->list.next)
+         break;
+      target = LIST_ENTRY(ppir_block, target->list.next, list);
+   }
+
+   assert(!list_is_empty(&target->instr_list));
+
+   target_instr = list_first_entry(&target->instr_list, ppir_instr, list);
    b->branch.target = target_instr->offset - node->instr->offset;
    b->branch.next_count = target_instr->encode_size;
 }
@@ -642,6 +727,18 @@ static int encode_instr(ppir_instr *instr, void *code, void *last_code)
    if (instr->slots[PPIR_INSTR_SLOT_TEXLD])
       ctrl->sync = true;
 
+   if (instr->slots[PPIR_INSTR_SLOT_ALU_VEC_ADD]) {
+      ppir_node *node = instr->slots[PPIR_INSTR_SLOT_ALU_VEC_ADD];
+      if (node->op == ppir_op_ddx || node->op == ppir_op_ddy)
+         ctrl->sync = true;
+   }
+
+   if (instr->slots[PPIR_INSTR_SLOT_ALU_SCL_ADD]) {
+      ppir_node *node = instr->slots[PPIR_INSTR_SLOT_ALU_SCL_ADD];
+      if (node->op == ppir_op_ddx || node->op == ppir_op_ddy)
+         ctrl->sync = true;
+   }
+
    for (int i = 0; i < 2; i++) {
       if (instr->constant[i].num) {
          uint16_t output[4] = {0};