Esempio n. 1
0
/**
 * As above, but 3D interpolation of 8 values.
 */
static INLINE float
lerp_3d(float a, float b, float c,
        float v000, float v100, float v010, float v110,
        float v001, float v101, float v011, float v111)
{
   const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
   const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
   return lerp(c, temp0, temp1);
}
Esempio n. 2
0
/**
 * Bilinear interpolation of two source rows.
 * GLubyte pixels.
 */
static void
resample_linear_row_ub(GLint srcWidth, GLint dstWidth,
                       const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
                       GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
{
   const GLubyte (*srcColor0)[4] = (const GLubyte (*)[4]) srcBuffer0;
   const GLubyte (*srcColor1)[4] = (const GLubyte (*)[4]) srcBuffer1;
   GLubyte (*dstColor)[4] = (GLubyte (*)[4]) dstBuffer;
   const GLfloat dstWidthF = (GLfloat) dstWidth;
   GLint dstCol;

   for (dstCol = 0; dstCol < dstWidth; dstCol++) {
      const GLfloat srcCol = (dstCol * srcWidth) / dstWidthF;
      GLint srcCol0 = IFLOOR(srcCol);
      GLint srcCol1 = srcCol0 + 1;
      GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
      GLfloat red, green, blue, alpha;

      ASSERT(srcCol0 >= 0);
      ASSERT(srcCol0 < srcWidth);
      ASSERT(srcCol1 <= srcWidth);

      if (srcCol1 == srcWidth) {
         /* last column fudge */
         srcCol1--;
         colWeight = 0.0;
      }

      if (flip) {
         srcCol0 = srcWidth - 1 - srcCol0;
         srcCol1 = srcWidth - 1 - srcCol1;
      }

      red = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
                    srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
      green = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
                    srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
      blue = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
                    srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
      alpha = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
                    srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
      
      dstColor[dstCol][RCOMP] = IFLOOR(red);
      dstColor[dstCol][GCOMP] = IFLOOR(green);
      dstColor[dstCol][BCOMP] = IFLOOR(blue);
      dstColor[dstCol][ACOMP] = IFLOOR(alpha);
   }
}
Esempio n. 3
0
/**
 * Bilinear interpolation of two source rows.  floating point pixels.
 */
static void
resample_linear_row_float(GLint srcWidth, GLint dstWidth,
                          const GLvoid *srcBuffer0, const GLvoid *srcBuffer1,
                          GLvoid *dstBuffer, GLboolean flip, GLfloat rowWeight)
{
   const GLfloat (*srcColor0)[4] = (const GLfloat (*)[4]) srcBuffer0;
   const GLfloat (*srcColor1)[4] = (const GLfloat (*)[4]) srcBuffer1;
   GLfloat (*dstColor)[4] = (GLfloat (*)[4]) dstBuffer;
   GLint dstCol;

   for (dstCol = 0; dstCol < dstWidth; dstCol++) {
      const GLfloat srcCol = (dstCol + 0.5F) / dstWidth * srcWidth - 0.5F;
      GLint srcCol0 = MAX2(0, IFLOOR(srcCol));
      GLint srcCol1 = srcCol0 + 1;
      GLfloat colWeight = srcCol - srcCol0; /* fractional part of srcCol */
      GLfloat red, green, blue, alpha;

      assert(srcCol0 < srcWidth);
      assert(srcCol1 <= srcWidth);

      if (srcCol1 == srcWidth) {
         /* last column fudge */
         srcCol1--;
         colWeight = 0.0;
      }

      if (flip) {
         srcCol0 = srcWidth - 1 - srcCol0;
         srcCol1 = srcWidth - 1 - srcCol1;
      }

      red = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][RCOMP], srcColor0[srcCol1][RCOMP],
                    srcColor1[srcCol0][RCOMP], srcColor1[srcCol1][RCOMP]);
      green = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][GCOMP], srcColor0[srcCol1][GCOMP],
                    srcColor1[srcCol0][GCOMP], srcColor1[srcCol1][GCOMP]);
      blue = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][BCOMP], srcColor0[srcCol1][BCOMP],
                    srcColor1[srcCol0][BCOMP], srcColor1[srcCol1][BCOMP]);
      alpha = lerp_2d(colWeight, rowWeight,
                    srcColor0[srcCol0][ACOMP], srcColor0[srcCol1][ACOMP],
                    srcColor1[srcCol0][ACOMP], srcColor1[srcCol1][ACOMP]);
      
      dstColor[dstCol][RCOMP] = red;
      dstColor[dstCol][GCOMP] = green;
      dstColor[dstCol][BCOMP] = blue;
      dstColor[dstCol][ACOMP] = alpha;
   }
}
Esempio n. 4
0
/**
 * Common code for sampling 1D/2D/cube textures.
 * Could probably extend for 3D...
 */
static void
sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
                         const float s[QUAD_SIZE],
                         const float t[QUAD_SIZE],
                         const float p[QUAD_SIZE],
                         boolean computeLambda,
                         float lodbias,
                         float rgba[NUM_CHANNELS][QUAD_SIZE],
                         const unsigned faces[4])
{
   const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
   const struct softpipe_context *sp = samp->sp;
   const uint unit = samp->unit;
   const struct pipe_texture *texture = sp->texture[unit];
   const struct pipe_sampler_state *sampler = sp->sampler[unit];
   const uint compare_func = sampler->compare_func;
   unsigned level0, level1, j, imgFilter;
   int width, height;
   float levelBlend;

   choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
                        &level0, &level1, &levelBlend, &imgFilter);

   assert(sampler->normalized_coords);

   width = texture->width[level0];
   height = texture->height[level0];

   assert(width > 0);

   switch (imgFilter) {
   case PIPE_TEX_FILTER_NEAREST:
      {
         int x[4], y[4];
         nearest_texcoord_4(sampler->wrap_s, s, width, x);
         nearest_texcoord_4(sampler->wrap_t, t, height, y);

         for (j = 0; j < QUAD_SIZE; j++) {
            get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
               shadow_compare(compare_func, rgba, p, j);
            }

            if (level0 != level1) {
               /* get texels from second mipmap level and blend */
               float rgba2[4][4];
               unsigned c;
               x[j] /= 2;
               y[j] /= 2;
               get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
                         rgba2, j);
               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
                  shadow_compare(compare_func, rgba2, p, j);
               }

               for (c = 0; c < NUM_CHANNELS; c++) {
                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
               }
            }
         }
      }
      break;
   case PIPE_TEX_FILTER_LINEAR:
   case PIPE_TEX_FILTER_ANISO:
      {
         int x0[4], y0[4], x1[4], y1[4];
         float xw[4], yw[4]; /* weights */

         linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
         linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);

         for (j = 0; j < QUAD_SIZE; j++) {
            float tx[4][4]; /* texels */
            int c;
            get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
            get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
            get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
            get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
            if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
               shadow_compare(compare_func, tx, p, 0);
               shadow_compare(compare_func, tx, p, 1);
               shadow_compare(compare_func, tx, p, 2);
               shadow_compare(compare_func, tx, p, 3);
            }

            /* interpolate R, G, B, A */
            for (c = 0; c < 4; c++) {
               rgba[c][j] = lerp_2d(xw[j], yw[j],
                                    tx[c][0], tx[c][1],
                                    tx[c][2], tx[c][3]);
            }

            if (level0 != level1) {
               /* get texels from second mipmap level and blend */
               float rgba2[4][4];
               x0[j] /= 2;
               y0[j] /= 2;
               x1[j] /= 2;
               y1[j] /= 2;
               get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
               get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
               get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
               get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
               if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
                  shadow_compare(compare_func, tx, p, 0);
                  shadow_compare(compare_func, tx, p, 1);
                  shadow_compare(compare_func, tx, p, 2);
                  shadow_compare(compare_func, tx, p, 3);
               }

               /* interpolate R, G, B, A */
               for (c = 0; c < 4; c++) {
                  rgba2[c][j] = lerp_2d(xw[j], yw[j],
                                        tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
               }

               for (c = 0; c < NUM_CHANNELS; c++) {
                  rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
               }
            }
         }
      }
      break;
   default:
      assert(0);
   }
}