llvmpipe: New function to unpack rgba8 formats into 4 x u8n AoS.

This commit is contained in:
José Fonseca 2009-10-25 09:09:23 +00:00
parent abff4214ef
commit 47d241be9f
2 changed files with 148 additions and 12 deletions

View file

@ -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,

View file

@ -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,