gallivm: implement support for SQRT opcode
authorBrian Paul <brianp@vmware.com>
Fri, 1 Feb 2013 18:16:22 +0000 (11:16 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 4 Feb 2013 16:33:44 +0000 (09:33 -0700)
src/gallium/auxiliary/gallivm/lp_bld_limits.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c

index 30bed1ba31fd293792f69c426075b8d3a7a5def1..29bb9e3974fc8325505c0fbf020470b736e1deaa 100644 (file)
@@ -110,6 +110,8 @@ gallivm_get_shader_param(enum pipe_shader_cap param)
       return 1;
    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
       return PIPE_MAX_SAMPLERS;
+   case PIPE_SHADER_CAP_TGSI_SQRT_SUPPORTED:
+      return 1;
    default:
       return 0;
    }
index 489884906cc042774420038c1907f0a2bac39db1..f9bd2c689859036b268d6c6118c4c99fdbbb5735 100644 (file)
@@ -309,6 +309,8 @@ struct lp_build_tgsi_context
     * should compute 1 / sqrt (src0.x) */
    struct lp_build_tgsi_action rsq_action;
 
+   struct lp_build_tgsi_action sqrt_action;
+
    const struct tgsi_shader_info *info;
 
    lp_build_emit_fetch_fn emit_fetch_funcs[TGSI_FILE_COUNT];
index 8159bebc89bfd9236e2e9e44ea52a825cccbd8b3..41ddd9923f463a25d19349190a9bce6526afd3aa 100644 (file)
@@ -648,6 +648,26 @@ const struct lp_build_tgsi_action rsq_action = {
 
 };
 
+/* TGSI_OPCODE_SQRT */
+
+static void
+sqrt_emit(
+   const struct lp_build_tgsi_action * action,
+   struct lp_build_tgsi_context * bld_base,
+   struct lp_build_emit_data * emit_data)
+{
+   if (bld_base->sqrt_action.emit) {
+      bld_base->sqrt_action.emit(&bld_base->sqrt_action, bld_base, emit_data);
+   } else {
+      emit_data->output[emit_data->chan] = bld_base->base.undef;
+   }
+}
+
+const struct lp_build_tgsi_action sqrt_action = {
+   scalar_unary_fetch_args,     /* fetch_args */
+   sqrt_emit    /* emit */
+};
+
 /* TGSI_OPCODE_SCS */
 static void
 scs_emit(
@@ -839,6 +859,7 @@ lp_set_default_actions(struct lp_build_tgsi_context * bld_base)
    bld_base->op_actions[TGSI_OPCODE_LIT] = lit_action;
    bld_base->op_actions[TGSI_OPCODE_LOG] = log_action;
    bld_base->op_actions[TGSI_OPCODE_RSQ] = rsq_action;
+   bld_base->op_actions[TGSI_OPCODE_SQRT] = sqrt_action;
    bld_base->op_actions[TGSI_OPCODE_POW] = pow_action;
    bld_base->op_actions[TGSI_OPCODE_SCS] = scs_action;
    bld_base->op_actions[TGSI_OPCODE_XPD] = xpd_action;
@@ -1322,6 +1343,17 @@ recip_sqrt_emit_cpu(
                                                          emit_data->args[0]);
 }
 
+static void
+sqrt_emit_cpu(
+   const struct lp_build_tgsi_action * action,
+   struct lp_build_tgsi_context * bld_base,
+   struct lp_build_emit_data * emit_data)
+{
+   emit_data->output[emit_data->chan] = lp_build_sqrt(&bld_base->base,
+                                                      emit_data->args[0]);
+}
+
+
 /* TGSI_OPCODE_ROUND (CPU Only) */
 static void
 round_emit_cpu(
@@ -1665,6 +1697,7 @@ lp_set_default_actions_cpu(
    bld_base->op_actions[TGSI_OPCODE_TRUNC].emit = trunc_emit_cpu;
 
    bld_base->rsq_action.emit = recip_sqrt_emit_cpu;
+   bld_base->sqrt_action.emit = sqrt_emit_cpu;
 
    bld_base->op_actions[TGSI_OPCODE_UADD].emit = uadd_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_UDIV].emit = udiv_emit_cpu;