Convert format bitfields to shifts and masks.

The memory layout of bitfields depends on the ABI.
This commit is contained in:
Michel Dänzer 2007-11-06 10:17:59 +01:00
parent 0ab2c84ce9
commit 4f79dbd5aa
2 changed files with 52 additions and 62 deletions

View file

@ -42,11 +42,10 @@
#define PIPE_FORMAT_LAYOUT_RGBAZS 0
#define PIPE_FORMAT_LAYOUT_YCBCR 1
struct pipe_format_header
static INLINE uint pf_layout(uint f) /**< PIPE_FORMAT_LAYOUT_ */
{
uint layout : 2; /**< PIPE_FORMAT_LAYOUT_ */
uint padding : 30;
};
return f & 0x3;
}
/**
* RGBAZS Format Layout.
@ -75,16 +74,14 @@ struct pipe_format_header
#define PIPE_FORMAT_TYPE_SSCALED 5
/**
* In a nutshell, this bitfield contains instructions how to unpack
* a given format to a full-blown 4-component vector suitable for FS.
* Because the destination vector is assumed to be RGBA FLOAT, we
* need to know how to swizzle and expand components from the source
* vector.
* Let's take U_A1_R5_G5_B5 as an example. SwizzleX is A, sizeX
* Let's take U_A1_R5_G5_B5 as an example. X swizzle is A, X size
* is 1 bit and type is UNORM. So we take the most significant bit
* from source vector, convert 0 to 0.0 and 1 to 1.0 and save it
* in the last component of the destination RGBA component.
* Next, swizzleY is R, sizeY is 5 and type is UNORM. We normalize
* Next, Y swizzle is R, Y size is 5 and type is UNORM. We normalize
* those 5 bits into [0.0; 1.0] range and put it into second
* component of the destination vector. Rinse and repeat for
* components Z and W.
@ -93,21 +90,23 @@ struct pipe_format_header
* If any swizzle is 0 or 1, the corresponding destination component
* should be filled with 0.0 and 1.0, respectively.
*/
struct pipe_format_rgbazs
typedef uint pipe_format_rgbazs_t;
static INLINE uint pf_get(pipe_format_rgbazs_t f, uint shift, uint mask)
{
uint layout : 2; /**< PIPE_FORMAT_LAYOUT_RGBAZS */
uint swizzleX : 3; /**< PIPE_FORMAT_COMP_ */
uint swizzleY : 3; /**< PIPE_FORMAT_COMP_ */
uint swizzleZ : 3; /**< PIPE_FORMAT_COMP_ */
uint swizzleW : 3; /**< PIPE_FORMAT_COMP_ */
uint sizeX : 3; /**< Size of X - 1 */
uint sizeY : 3; /**< Size of Y - 1 */
uint sizeZ : 3; /**< Size of Z - 1 */
uint sizeW : 3; /**< Size of W - 1 */
uint exp8 : 2; /**< Scale size by 8 ^ exp8 */
uint type : 3; /**< PIPE_FORMAT_TYPE_ */
uint padding : 1;
};
return (f >> shift) & mask;
}
#define pf_swizzle_x(f) pf_get(f, 2, 0x7) /**< PIPE_FORMAT_COMP_ */
#define pf_swizzle_y(f) pf_get(f, 5, 0x7) /**< PIPE_FORMAT_COMP_ */
#define pf_swizzle_z(f) pf_get(f, 8, 0x7) /**< PIPE_FORMAT_COMP_ */
#define pf_swizzle_w(f) pf_get(f, 11, 0x7) /**< PIPE_FORMAT_COMP_ */
#define pf_size_x(f) pf_get(f, 14, 0x7) /**< Size of X - 1 */
#define pf_size_y(f) pf_get(f, 17, 0x7) /**< Size of Y - 1 */
#define pf_size_z(f) pf_get(f, 20, 0x7) /**< Size of Z - 1 */
#define pf_size_w(f) pf_get(f, 23, 0x7) /**< Size of W - 1 */
#define pf_exp8(f) pf_get(f, 26, 0x3) /**< Scale size by 8 ^ exp8 */
#define pf_type(f) pf_get(f, 28, 0xf) /**< PIPE_FORMAT_TYPE_ */
/**
* Helper macro to encode the above structure into a 32-bit value.
@ -179,15 +178,10 @@ struct pipe_format_rgbazs
*/
/**
* This bitfields is simple. It only contains a flag that indicates whether the
* format is reversed or not.
* This only contains a flag that indicates whether the format is reversed or
* not.
*/
struct pipe_format_ycbcr
{
uint layout : 2; /**< PIPE_FORMAT_LAYOUT_YCBCR */
uint reversed : 1;
uint padding : 29;
};
typedef uint pipe_format_ycbcr_t;
/**
* Helper macro to encode the above structure into a 32-bit value.
@ -196,13 +190,10 @@ struct pipe_format_ycbcr
(PIPE_FORMAT_LAYOUT_YCBCR << 0) |\
((REV) << 2) )
union pipe_format
static INLINE uint pf_rev(pipe_format_ycbcr_t f)
{
uint value32;
struct pipe_format_header header;
struct pipe_format_rgbazs rgbazs;
struct pipe_format_ycbcr ycbcr;
};
return (f >> 2) & 0x1;
}
/**
* Texture/surface image formats (preliminary)

View file

@ -45,32 +45,32 @@
static GLuint
format_bits(
struct pipe_format_rgbazs info,
pipe_format_rgbazs_t info,
GLuint comp )
{
GLuint size;
if (info.swizzleX == comp) {
size = info.sizeX;
if (pf_swizzle_x(info) == comp) {
size = pf_size_x(info);
}
else if (info.swizzleY == comp) {
size = info.sizeY;
else if (pf_swizzle_y(info) == comp) {
size = pf_size_y(info);
}
else if (info.swizzleZ == comp) {
size = info.sizeZ;
else if (pf_swizzle_z(info) == comp) {
size = pf_size_z(info);
}
else if (info.swizzleW == comp) {
size = info.sizeW;
else if (pf_swizzle_w(info) == comp) {
size = pf_size_w(info);
}
else {
size = 0;
}
return size << (info.exp8 * 3);
return size << (pf_exp8(info) * 3);
}
static GLuint
format_max_bits(
struct pipe_format_rgbazs info )
pipe_format_rgbazs_t info )
{
GLuint size = format_bits( info, PIPE_FORMAT_COMP_R );
@ -84,7 +84,7 @@ format_max_bits(
static GLuint
format_size(
struct pipe_format_rgbazs info )
pipe_format_rgbazs_t info )
{
return
format_bits( info, PIPE_FORMAT_COMP_R ) +
@ -103,13 +103,10 @@ st_get_format_info(
GLuint format,
struct pipe_format_info *pinfo )
{
union pipe_format fmt;
if (pf_layout(format) == PIPE_FORMAT_LAYOUT_RGBAZS) {
pipe_format_rgbazs_t info;
fmt.value32 = format;
if (fmt.header.layout == PIPE_FORMAT_LAYOUT_RGBAZS) {
struct pipe_format_rgbazs info;
info = fmt.rgbazs;
info = format;
#if 0
printf(
@ -129,20 +126,20 @@ st_get_format_info(
size = format_max_bits( info );
if (size == 8) {
if (info.type == PIPE_FORMAT_TYPE_UNORM)
if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
pinfo->datatype = GL_UNSIGNED_BYTE;
else
pinfo->datatype = GL_BYTE;
}
else if (size == 16) {
if (info.type == PIPE_FORMAT_TYPE_UNORM)
if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
pinfo->datatype = GL_UNSIGNED_SHORT;
else
pinfo->datatype = GL_SHORT;
}
else {
assert( size <= 32 );
if (info.type == PIPE_FORMAT_TYPE_UNORM)
if (pf_type(info) == PIPE_FORMAT_TYPE_UNORM)
pinfo->datatype = GL_UNSIGNED_INT;
else
pinfo->datatype = GL_INT;
@ -161,8 +158,10 @@ st_get_format_info(
pinfo->size = format_size( info ) / 8;
/* Luminance & Intensity bits */
if( info.swizzleX == PIPE_FORMAT_COMP_R && info.swizzleY == PIPE_FORMAT_COMP_R && info.swizzleZ == PIPE_FORMAT_COMP_R ) {
if( info.swizzleW == PIPE_FORMAT_COMP_R ) {
if( pf_swizzle_x(info) == PIPE_FORMAT_COMP_R &&
pf_swizzle_y(info) == PIPE_FORMAT_COMP_R &&
pf_swizzle_z(info) == PIPE_FORMAT_COMP_R ) {
if( pf_swizzle_w(info) == PIPE_FORMAT_COMP_R ) {
pinfo->luminance_bits = 0;
pinfo->intensity_bits = pinfo->red_bits;
}
@ -190,11 +189,11 @@ st_get_format_info(
}
}
else {
struct pipe_format_ycbcr info;
pipe_format_ycbcr_t info;
assert( fmt.header.layout == PIPE_FORMAT_LAYOUT_YCBCR );
assert( pf_layout(format) == PIPE_FORMAT_LAYOUT_YCBCR );
info = fmt.ycbcr;
info = format;
/* TODO */
assert( 0 );