diff options
| author | José Fonseca <jfonseca@vmware.com> | 2009-10-25 09:09:23 +0000 | 
|---|---|---|
| committer | José Fonseca <jfonseca@vmware.com> | 2009-10-25 09:53:49 +0000 | 
| commit | 47d241be9ff89b65b978dd4fe4ea7473e07fa2c4 (patch) | |
| tree | ba8344b150ff7b4e7e00060dcf7708f692b7e7dd | |
| parent | abff4214ef870f26d5c64adac1235b9e9438a51e (diff) | |
llvmpipe: New function to unpack rgba8 formats into 4 x u8n AoS.
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_format.h | 19 | ||||
| -rw-r--r-- | src/gallium/drivers/llvmpipe/lp_bld_format_aos.c | 141 | 
2 files changed, 148 insertions, 12 deletions
| diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format.h b/src/gallium/drivers/llvmpipe/lp_bld_format.h index 8b08c016c0..fa560576be 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format.h +++ b/src/gallium/drivers/llvmpipe/lp_bld_format.h @@ -49,24 +49,19 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc,                              LLVMValueRef *swizzled); -/** - * Unpack a pixel into its RGBA components. - * - * @param packed integer. - * - * @return RGBA in a 4 floats vector. - */  LLVMValueRef  lp_build_unpack_rgba_aos(LLVMBuilderRef builder,                           const struct util_format_description *desc,                           LLVMValueRef packed); -/** - * Pack a pixel. - * - * @param rgba 4 float vector with the unpacked components. - */ +LLVMValueRef +lp_build_unpack_rgba8_aos(LLVMBuilderRef builder, +                          const struct util_format_description *desc, +                          struct lp_type type, +                          LLVMValueRef packed); + +  LLVMValueRef  lp_build_pack_rgba_aos(LLVMBuilderRef builder,                         const struct util_format_description *desc, diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c index 0591d77860..5836e0173f 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c @@ -25,12 +25,34 @@   *   **************************************************************************/ +/** + * @file + * AoS pixel format manipulation. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#include "util/u_cpu_detect.h"  #include "util/u_format.h" +#include "lp_bld_type.h" +#include "lp_bld_const.h" +#include "lp_bld_logic.h" +#include "lp_bld_swizzle.h"  #include "lp_bld_format.h" +/** + * Unpack a single pixel into its RGBA components. + * + * @param packed integer. + * + * @return RGBA in a 4 floats vector. + * + * XXX: This is mostly for reference and testing -- operating a single pixel at + * a time is rarely if ever needed. + */  LLVMValueRef  lp_build_unpack_rgba_aos(LLVMBuilderRef builder,                           const struct util_format_description *desc, @@ -148,6 +170,125 @@ lp_build_unpack_rgba_aos(LLVMBuilderRef builder,  } +/** + * Take a vector with packed pixels and unpack into a rgba8 vector. + * + * Formats with bit depth smaller than 32bits are accepted, but they must be + * padded to 32bits. + */ +LLVMValueRef +lp_build_unpack_rgba8_aos(LLVMBuilderRef builder, +                          const struct util_format_description *desc, +                          struct lp_type type, +                          LLVMValueRef packed) +{ +   struct lp_build_context bld; +   bool rgba8; +   LLVMValueRef res; +   unsigned i; + +   lp_build_context_init(&bld, builder, type); + +   /* FIXME: Support more formats */ +   assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH); +   assert(desc->block.width == 1); +   assert(desc->block.height == 1); +   assert(desc->block.bits <= 32); + +   assert(!type.floating); +   assert(!type.fixed); +   assert(type.norm); +   assert(type.width == 8); +   assert(type.length % 4 == 0); + +   rgba8 = TRUE; +   for(i = 0; i < 4; ++i) { +      assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED || +             desc->channel[i].type == UTIL_FORMAT_TYPE_VOID); +      if(desc->channel[0].size != 8) +         rgba8 = FALSE; +   } + +   if(rgba8) { +      /* +       * The pixel is already in a rgba8 format variant. All it is necessary +       * is to swizzle the channels. +       */ + +      unsigned char swizzles[4]; +      boolean zeros[4]; /* bitwise AND mask */ +      boolean ones[4]; /* bitwise OR mask */ +      boolean swizzles_needed = FALSE; +      boolean zeros_needed = FALSE; +      boolean ones_needed = FALSE; + +      for(i = 0; i < 4; ++i) { +         enum util_format_swizzle swizzle = desc->swizzle[i]; + +         /* Initialize with the no-op case */ +         swizzles[i] = util_cpu_caps.little_endian ? 3 - i : i; +         zeros[i] = TRUE; +         ones[i] = FALSE; + +         switch (swizzle) { +         case UTIL_FORMAT_SWIZZLE_X: +         case UTIL_FORMAT_SWIZZLE_Y: +         case UTIL_FORMAT_SWIZZLE_Z: +         case UTIL_FORMAT_SWIZZLE_W: +            if(swizzle != swizzles[i]) { +               swizzles[i] = swizzle; +               swizzles_needed = TRUE; +            } +            break; +         case UTIL_FORMAT_SWIZZLE_0: +            zeros[i] = FALSE; +            zeros_needed = TRUE; +            break; +         case UTIL_FORMAT_SWIZZLE_1: +            ones[i] = TRUE; +            ones_needed = TRUE; +            break; +         case UTIL_FORMAT_SWIZZLE_NONE: +            assert(0); +            break; +         } +      } + +      res = packed; + +      if(swizzles_needed) +         res = lp_build_swizzle1_aos(&bld, res, swizzles); + +      if(zeros_needed) { +         /* Mask out zero channels */ +         LLVMValueRef mask = lp_build_const_mask_aos(type, zeros); +         res = LLVMBuildAnd(builder, res, mask, ""); +      } + +      if(ones_needed) { +         /* Or one channels */ +         LLVMValueRef mask = lp_build_const_mask_aos(type, ones); +         res = LLVMBuildOr(builder, res, mask, ""); +      } +   } +   else { +      /* FIXME */ +      assert(0); +      res = lp_build_undef(type); +   } + +   return res; +} + + +/** + * Pack a single pixel. + * + * @param rgba 4 float vector with the unpacked components. + * + * XXX: This is mostly for reference and testing -- operating a single pixel at + * a time is rarely if ever needed. + */  LLVMValueRef  lp_build_pack_rgba_aos(LLVMBuilderRef builder,                         const struct util_format_description *desc, | 
