r600g: upload translated indices via the uploader
[mesa.git] / src / gallium / drivers / llvmpipe / lp_bld_interp.c
index 2a374f8c3909014f4d1a8e717cfce48c3d9362ed..45ddf547bf0f5f7327b3aafa30181f6c43f7b6a2 100644 (file)
@@ -127,13 +127,14 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
             LLVMValueRef dady_ptr)
 {
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
-   LLVMBuilderRef builder = coeff_bld->builder;
+   struct gallivm_state *gallivm = coeff_bld->gallivm;
+   LLVMBuilderRef builder = gallivm->builder;
    LLVMValueRef zero = LLVMConstNull(coeff_bld->elem_type);
    LLVMValueRef one = LLVMConstReal(coeff_bld->elem_type, 1.0);
-   LLVMValueRef i0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-   LLVMValueRef i1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-   LLVMValueRef i2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-   LLVMValueRef i3 = LLVMConstInt(LLVMInt32Type(), 3, 0);
+   LLVMValueRef i0 = lp_build_const_int32(gallivm, 0);
+   LLVMValueRef i1 = lp_build_const_int32(gallivm, 1);
+   LLVMValueRef i2 = lp_build_const_int32(gallivm, 2);
+   LLVMValueRef i3 = lp_build_const_int32(gallivm, 3);
    unsigned attrib;
    unsigned chan;
 
@@ -144,7 +145,8 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
       const unsigned interp = bld->interp[attrib];
       for (chan = 0; chan < NUM_CHANNELS; ++chan) {
          if (mask & (1 << chan)) {
-            LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
+            LLVMValueRef index = lp_build_const_int32(gallivm,
+                                      attrib * NUM_CHANNELS + chan);
             LLVMValueRef a0 = zero;
             LLVMValueRef dadx = zero;
             LLVMValueRef dady = zero;
@@ -206,7 +208,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
             dadq2 = LLVMBuildFAdd(builder, dadq, dadq, "");
 
             /*
-             * a = a0 + x * dadx + y * dady
+             * a = a0 + (x * dadx + y * dady)
              */
 
             if (attrib == 0 && chan == 0) {
@@ -219,11 +221,11 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
                a = a0;
                if (interp != LP_INTERP_CONSTANT &&
                    interp != LP_INTERP_FACING) {
-                  LLVMValueRef tmp;
-                  tmp = LLVMBuildFMul(builder, bld->x, dadx, "");
-                  a = LLVMBuildFAdd(builder, a, tmp, "");
-                  tmp = LLVMBuildFMul(builder, bld->y, dady, "");
-                  a = LLVMBuildFAdd(builder, a, tmp, "");
+                  LLVMValueRef ax, ay, axy;
+                  ax = LLVMBuildFMul(builder, bld->x, dadx, "");
+                  ay = LLVMBuildFMul(builder, bld->y, dady, "");
+                  axy = LLVMBuildFAdd(builder, ax, ay, "");
+                  a = LLVMBuildFAdd(builder, a, axy, "");
                }
             }
 
@@ -231,7 +233,7 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
              * a = {a, a, a, a}
              */
 
-            a = lp_build_broadcast(builder, coeff_bld->vec_type, a);
+            a = lp_build_broadcast(gallivm, coeff_bld->vec_type, a);
 
             /*
              * Compute the attrib values on the upper-left corner of each quad.
@@ -272,17 +274,22 @@ coeffs_init(struct lp_build_interp_soa_context *bld,
  * This is called when we move from one quad to the next.
  */
 static void
-attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
+attribs_update(struct lp_build_interp_soa_context *bld,
+               struct gallivm_state *gallivm,
+               int quad_index,
+               int start,
+               int end)
 {
+   LLVMBuilderRef builder = gallivm->builder;
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
-   LLVMValueRef shuffle = lp_build_const_int_vec(coeff_bld->type, quad_index);
+   LLVMValueRef shuffle = lp_build_const_int_vec(gallivm, coeff_bld->type, quad_index);
    LLVMValueRef oow = NULL;
    unsigned attrib;
    unsigned chan;
 
    assert(quad_index < 4);
 
-   for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+   for(attrib = start; attrib < end; ++attrib) {
       const unsigned mask = bld->mask[attrib];
       const unsigned interp = bld->interp[attrib];
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
@@ -305,7 +312,7 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
                 * Broadcast the attribute value for this quad into all elements
                 */
 
-               a = LLVMBuildShuffleVector(coeff_bld->builder,
+               a = LLVMBuildShuffleVector(builder,
                                           a, coeff_bld->undef, shuffle, "");
 
                /*
@@ -350,6 +357,14 @@ attribs_update(struct lp_build_interp_soa_context *bld, int quad_index)
                }
 #endif
 
+               if (attrib == 0 && chan == 2) {
+                  /* FIXME: Depth values can exceed 1.0, due to the fact that
+                   * setup interpolation coefficients refer to (0,0) which causes
+                   * precision loss. So we must clamp to 1.0 here to avoid artifacts
+                   */
+                  a = lp_build_min(coeff_bld, a, coeff_bld->one);
+               }
+
                attrib_name(a, attrib, chan, "");
             }
             bld->attribs[attrib][chan] = a;
@@ -369,10 +384,11 @@ pos_init(struct lp_build_interp_soa_context *bld,
          LLVMValueRef x0,
          LLVMValueRef y0)
 {
+   LLVMBuilderRef builder = bld->coeff_bld.gallivm->builder;
    struct lp_build_context *coeff_bld = &bld->coeff_bld;
 
-   bld->x = LLVMBuildSIToFP(coeff_bld->builder, x0, coeff_bld->elem_type, "");
-   bld->y = LLVMBuildSIToFP(coeff_bld->builder, y0, coeff_bld->elem_type, "");
+   bld->x = LLVMBuildSIToFP(builder, x0, coeff_bld->elem_type, "");
+   bld->y = LLVMBuildSIToFP(builder, y0, coeff_bld->elem_type, "");
 }
 
 
@@ -381,6 +397,7 @@ pos_init(struct lp_build_interp_soa_context *bld,
  */
 void
 lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
+                         struct gallivm_state *gallivm,
                          unsigned num_inputs,
                          const struct lp_shader_input *inputs,
                          LLVMBuilderRef builder,
@@ -406,7 +423,7 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
    /* XXX: we don't support interpolating into any other types */
    assert(memcmp(&coeff_type, &type, sizeof coeff_type) == 0);
 
-   lp_build_context_init(&bld->coeff_bld, builder, coeff_type);
+   lp_build_context_init(&bld->coeff_bld, gallivm, coeff_type);
 
    /* For convenience */
    bld->pos = bld->attribs[0];
@@ -434,8 +451,6 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
    pos_init(bld, x0, y0);
 
    coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
-
-   attribs_update(bld, 0);
 }
 
 
@@ -443,10 +458,22 @@ lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
  * Advance the position and inputs to the given quad within the block.
  */
 void
-lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld,
-                           int quad_index)
+lp_build_interp_soa_update_inputs(struct lp_build_interp_soa_context *bld,
+                                  struct gallivm_state *gallivm,
+                                  int quad_index)
+{
+   assert(quad_index < 4);
+
+   attribs_update(bld, gallivm, quad_index, 1, bld->num_attribs);
+}
+
+void
+lp_build_interp_soa_update_pos(struct lp_build_interp_soa_context *bld,
+                                  struct gallivm_state *gallivm,
+                                  int quad_index)
 {
    assert(quad_index < 4);
 
-   attribs_update(bld, quad_index);
+   attribs_update(bld, gallivm, quad_index, 0, 1);
 }
+