gallivm: Implement TXD.
authorJosé Fonseca <jfonseca@vmware.com>
Tue, 4 May 2010 09:06:46 +0000 (10:06 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 4 May 2010 09:08:10 +0000 (10:08 +0100)
src/gallium/auxiliary/gallivm/lp_bld_sample.h
src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi.h
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/drivers/llvmpipe/lp_tex_sample.c

index 8ceb20473d57099988f9c1c86b94fba4dbb8f1c8..40f2b571f796e312220cf79faa07be55a231eceb 100644 (file)
@@ -173,6 +173,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
                     unsigned unit,
                     unsigned num_coords,
                     const LLVMValueRef *coords,
+                    const LLVMValueRef *ddx,
+                    const LLVMValueRef *ddy,
                     LLVMValueRef lodbias,
                     LLVMValueRef *texel);
 
index 54c0ad7ce4397ec82a99e6e0f8e05d04a5af88d7..59279232717bdd11dbc8b65a7d7542485bddcb1c 100644 (file)
@@ -913,6 +913,8 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
                       LLVMValueRef s,
                       LLVMValueRef t,
                       LLVMValueRef r,
+                      const LLVMValueRef *ddx,
+                      const LLVMValueRef *ddy,
                       LLVMValueRef shader_lod_bias,
                       LLVMValueRef width,
                       LLVMValueRef height,
@@ -936,12 +938,6 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
                                            bld->static_state->max_lod);
 
       LLVMValueRef index0 = LLVMConstInt(LLVMInt32Type(), 0, 0);
-      LLVMValueRef index1 = LLVMConstInt(LLVMInt32Type(), 1, 0);
-      LLVMValueRef index2 = LLVMConstInt(LLVMInt32Type(), 2, 0);
-
-      LLVMValueRef s0, s1, s2;
-      LLVMValueRef t0, t1, t2;
-      LLVMValueRef r0, r1, r2;
       LLVMValueRef dsdx, dsdy, dtdx, dtdy, drdx, drdy;
       LLVMValueRef rho, lod;
 
@@ -952,30 +948,20 @@ lp_build_lod_selector(struct lp_build_sample_context *bld,
        * dtdy = abs(t[2] - t[0]);
        * drdx = abs(r[1] - r[0]);
        * drdy = abs(r[2] - r[0]);
-       * XXX we're assuming a four-element quad in 2x2 layout here.
        */
-      s0 = LLVMBuildExtractElement(bld->builder, s, index0, "s0");
-      s1 = LLVMBuildExtractElement(bld->builder, s, index1, "s1");
-      s2 = LLVMBuildExtractElement(bld->builder, s, index2, "s2");
-      dsdx = LLVMBuildSub(bld->builder, s1, s0, "");
+      dsdx = LLVMBuildExtractElement(bld->builder, ddx[0], index0, "dsdx");
       dsdx = lp_build_abs(float_bld, dsdx);
-      dsdy = LLVMBuildSub(bld->builder, s2, s0, "");
+      dsdy = LLVMBuildExtractElement(bld->builder, ddy[0], index0, "dsdy");
       dsdy = lp_build_abs(float_bld, dsdy);
       if (dims > 1) {
-         t0 = LLVMBuildExtractElement(bld->builder, t, index0, "t0");
-         t1 = LLVMBuildExtractElement(bld->builder, t, index1, "t1");
-         t2 = LLVMBuildExtractElement(bld->builder, t, index2, "t2");
-         dtdx = LLVMBuildSub(bld->builder, t1, t0, "");
+         dtdx = LLVMBuildExtractElement(bld->builder, ddx[1], index0, "dsdx");
          dtdx = lp_build_abs(float_bld, dtdx);
-         dtdy = LLVMBuildSub(bld->builder, t2, t0, "");
+         dtdy = LLVMBuildExtractElement(bld->builder, ddy[1], index0, "dtdy");
          dtdy = lp_build_abs(float_bld, dtdy);
          if (dims > 2) {
-            r0 = LLVMBuildExtractElement(bld->builder, r, index0, "r0");
-            r1 = LLVMBuildExtractElement(bld->builder, r, index1, "r1");
-            r2 = LLVMBuildExtractElement(bld->builder, r, index2, "r2");
-            drdx = LLVMBuildSub(bld->builder, r1, r0, "");
+            drdx = LLVMBuildExtractElement(bld->builder, ddx[2], index0, "dsdx");
             drdx = lp_build_abs(float_bld, drdx);
-            drdy = LLVMBuildSub(bld->builder, r2, r0, "");
+            drdy = LLVMBuildExtractElement(bld->builder, ddy[2], index0, "drdy");
             drdy = lp_build_abs(float_bld, drdy);
          }
       }
@@ -1596,6 +1582,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
                         LLVMValueRef s,
                         LLVMValueRef t,
                         LLVMValueRef r,
+                        const LLVMValueRef *ddx,
+                        const LLVMValueRef *ddy,
                         LLVMValueRef lodbias,
                         LLVMValueRef width,
                         LLVMValueRef height,
@@ -1634,7 +1622,8 @@ lp_build_sample_general(struct lp_build_sample_context *bld,
       /* Need to compute lod either to choose mipmap levels or to
        * distinguish between minification/magnification with one mipmap level.
        */
-      lod = lp_build_lod_selector(bld, s, t, r, lodbias, width, height, depth);
+      lod = lp_build_lod_selector(bld, s, t, r, ddx, ddy, lodbias,
+                                  width, height, depth);
    }
 
    /*
@@ -2092,6 +2081,8 @@ lp_build_sample_soa(LLVMBuilderRef builder,
                     unsigned unit,
                     unsigned num_coords,
                     const LLVMValueRef *coords,
+                    const LLVMValueRef *ddx,
+                    const LLVMValueRef *ddy,
                     LLVMValueRef lodbias,
                     LLVMValueRef *texel)
 {
@@ -2159,7 +2150,7 @@ lp_build_sample_soa(LLVMBuilderRef builder,
                                     row_stride_array, data_array, texel);
    }
    else {
-      lp_build_sample_general(&bld, unit, s, t, r, lodbias,
+      lp_build_sample_general(&bld, unit, s, t, r, ddx, ddy, lodbias,
                               width, height, depth,
                               width_vec, height_vec, depth_vec,
                               row_stride_array, img_stride_array,
index 2eac5da6c69e651de30f37bb7063a91a9e87937b..4ca730a98a07aef9da79a79e9f646f37e4a79a86 100644 (file)
@@ -45,6 +45,9 @@ struct lp_build_context;
 struct lp_build_mask_context;
 
 
+#define LP_BLD_SAMPLER_EXPLICIT_DERIVATIVES 1
+
+
 /**
  * Sampler code generation interface.
  *
@@ -65,6 +68,8 @@ struct lp_build_sampler_soa
                         unsigned unit,
                         unsigned num_coords,
                         const LLVMValueRef *coords,
+                        const LLVMValueRef *ddx,
+                        const LLVMValueRef *ddy,
                         LLVMValueRef lodbias,
                         LLVMValueRef *texel);
 };
index e699e44a24e67e019c723d5422ec77bea249f8cb..6659cff8706aa67eca83d7e5d6569882b070200f 100644 (file)
@@ -592,18 +592,26 @@ emit_store(
  * High-level instruction translators.
  */
 
+enum tex_modifier {
+   TEX_MODIFIER_NONE = 0,
+   TEX_MODIFIER_PROJECTED,
+   TEX_MODIFIER_LOD_BIAS,
+   TEX_MODIFIER_EXPLICIT_LOD,
+   TEX_MODIFIER_EXPLICIT_DERIV
+};
 
 static void
 emit_tex( struct lp_build_tgsi_soa_context *bld,
           const struct tgsi_full_instruction *inst,
-          boolean apply_lodbias,
-          boolean projected,
+          enum tex_modifier modifier,
           LLVMValueRef *texel)
 {
-   const uint unit = inst->Src[1].Register.Index;
+   unsigned unit;
    LLVMValueRef lodbias;
    LLVMValueRef oow = NULL;
    LLVMValueRef coords[3];
+   LLVMValueRef ddx[3];
+   LLVMValueRef ddy[3];
    unsigned num_coords;
    unsigned i;
 
@@ -635,29 +643,45 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
       return;
    }
 
-   if(apply_lodbias)
+   /* FIXME: Treat TEX_MODIFIER_EXPLICIT_LOD correctly */
+   if (modifier == TEX_MODIFIER_LOD_BIAS || TEX_MODIFIER_EXPLICIT_LOD)
       lodbias = emit_fetch( bld, inst, 0, 3 );
    else
       lodbias = bld->base.zero;
 
-   if (projected) {
+   if (modifier == TEX_MODIFIER_PROJECTED) {
       oow = emit_fetch( bld, inst, 0, 3 );
       oow = lp_build_rcp(&bld->base, oow);
    }
 
    for (i = 0; i < num_coords; i++) {
       coords[i] = emit_fetch( bld, inst, 0, i );
-      if (projected)
+      if (modifier == TEX_MODIFIER_PROJECTED)
          coords[i] = lp_build_mul(&bld->base, coords[i], oow);
    }
    for (i = num_coords; i < 3; i++) {
       coords[i] = bld->base.undef;
    }
 
+   if (modifier == TEX_MODIFIER_EXPLICIT_DERIV) {
+      for (i = 0; i < num_coords; i++) {
+         ddx[i] = emit_fetch( bld, inst, 1, i );
+         ddy[i] = emit_fetch( bld, inst, 2, i );
+      }
+      unit = inst->Src[3].Register.Index;
+   }  else {
+      for (i = 0; i < num_coords; i++) {
+         ddx[i] = emit_ddx( bld, coords[i] );
+         ddy[i] = emit_ddy( bld, coords[i] );
+      }
+      unit = inst->Src[1].Register.Index;
+   }
+
    bld->sampler->emit_fetch_texel(bld->sampler,
                                   bld->base.builder,
                                   bld->base.type,
-                                  unit, num_coords, coords, lodbias,
+                                  unit, num_coords, coords,
+                                  ddx, ddy, lodbias,
                                   texel);
 }
 
@@ -1361,12 +1385,11 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_TEX:
-      emit_tex( bld, inst, FALSE, FALSE, dst0 );
+      emit_tex( bld, inst, TEX_MODIFIER_NONE, dst0 );
       break;
 
    case TGSI_OPCODE_TXD:
-      /* FIXME */
-      return FALSE;
+      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_DERIV, dst0 );
       break;
 
    case TGSI_OPCODE_UP2H:
@@ -1468,7 +1491,7 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_TXB:
-      emit_tex( bld, inst, TRUE, FALSE, dst0 );
+      emit_tex( bld, inst, TEX_MODIFIER_LOD_BIAS, dst0 );
       break;
 
    case TGSI_OPCODE_NRM:
@@ -1573,11 +1596,11 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_TXL:
-      emit_tex( bld, inst, TRUE, FALSE, dst0 );
+      emit_tex( bld, inst, TEX_MODIFIER_EXPLICIT_LOD, dst0 );
       break;
 
    case TGSI_OPCODE_TXP:
-      emit_tex( bld, inst, FALSE, TRUE, dst0 );
+      emit_tex( bld, inst, TEX_MODIFIER_PROJECTED, dst0 );
       break;
 
    case TGSI_OPCODE_BRK:
index 74b7393e4ecd18c20f78a7e7eaeda886b931adb3..3f788e598fc5e9aa5f0ee91ddd2cc9676eaf746e 100644 (file)
@@ -170,6 +170,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base,
                                      unsigned unit,
                                      unsigned num_coords,
                                      const LLVMValueRef *coords,
+                                     const LLVMValueRef *ddx,
+                                     const LLVMValueRef *ddy,
                                      LLVMValueRef lodbias,
                                      LLVMValueRef *texel)
 {
@@ -182,9 +184,8 @@ lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base,
                        &sampler->dynamic_state.base,
                        type,
                        unit,
-                       num_coords,
-                       coords,
-                       lodbias,
+                       num_coords, coords,
+                       ddx, ddy, lodbias,
                        texel);
 }