summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/util/u_format.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util/u_format.h')
-rw-r--r--src/gallium/auxiliary/util/u_format.h225
1 files changed, 205 insertions, 20 deletions
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index e8fa0022b5..5e3dc694be 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -56,15 +56,23 @@ enum util_format_layout {
*
* This is for formats like YV12 where there is less than one sample per
* pixel.
- *
- * XXX: This could actually b
*/
UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
/**
- * An unspecified compression algorithm.
+ * S3 Texture Compression formats.
+ */
+ UTIL_FORMAT_LAYOUT_S3TC = 4,
+
+ /**
+ * Red-Green Texture Compression formats.
+ */
+ UTIL_FORMAT_LAYOUT_RGTC = 5,
+
+ /**
+ * Everything else that doesn't fit in any of the above layouts.
*/
- UTIL_FORMAT_LAYOUT_COMPRESSED = 4
+ UTIL_FORMAT_LAYOUT_OTHER = 6
};
@@ -120,9 +128,15 @@ struct util_format_channel_description
struct util_format_description
{
enum pipe_format format;
+
const char *name;
/**
+ * Short name, striped of the prefix, lower case.
+ */
+ const char *short_name;
+
+ /**
* Pixel block dimensions.
*/
struct util_format_block block;
@@ -140,6 +154,15 @@ struct util_format_description
unsigned is_array:1;
/**
+ * Whether the pixel format can be described as a bitfield structure.
+ *
+ * In particular:
+ * - pixel depth must be 8, 16, or 32 bits;
+ * - all channels must be unsigned, signed, or void
+ */
+ unsigned is_bitmask:1;
+
+ /**
* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID).
*/
unsigned is_mixed:1;
@@ -166,6 +189,117 @@ struct util_format_description
* Colorspace transformation.
*/
enum util_format_colorspace colorspace;
+
+ /**
+ * Unpack pixel blocks to R8G8B8A8_UNORM.
+ *
+ * Only defined for non-depth-stencil formats.
+ */
+ void
+ (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixel blocks from R8G8B8A8_UNORM.
+ *
+ * Only defined for non-depth-stencil formats.
+ */
+ void
+ (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Unpack pixel blocks to R32G32B32A32_FLOAT.
+ *
+ * Only defined for non-depth-stencil formats.
+ */
+ void
+ (*unpack_rgba_float)(float *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixel blocks from R32G32B32A32_FLOAT.
+ *
+ * Only defined for non-depth-stencil formats.
+ */
+ void
+ (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride,
+ const float *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Fetch a single pixel (i, j) from a block.
+ *
+ * Only defined for non-depth-stencil formats.
+ */
+ void
+ (*fetch_rgba_float)(float *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
+
+ /**
+ * Unpack pixels to Z32_UNORM.
+ *
+ * Only defined for depth formats.
+ */
+ void
+ (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixels from Z32_FLOAT.
+ *
+ * Only defined for depth formats.
+ */
+ void
+ (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride,
+ const uint32_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Unpack pixels to Z32_FLOAT.
+ *
+ * Only defined for depth formats.
+ */
+ void
+ (*unpack_z_float)(float *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixels from Z32_FLOAT.
+ *
+ * Only defined for depth formats.
+ */
+ void
+ (*pack_z_float)(uint8_t *dst, unsigned dst_stride,
+ const float *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Unpack pixels to S8_USCALED.
+ *
+ * Only defined for stencil formats.
+ */
+ void
+ (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixels from S8_USCALED.
+ *
+ * Only defined for stencil formats.
+ */
+ void
+ (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
};
@@ -186,8 +320,8 @@ util_format_name(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return "???";
}
@@ -195,16 +329,16 @@ util_format_name(enum pipe_format format)
}
static INLINE boolean
-util_format_is_compressed(enum pipe_format format)
+util_format_is_s3tc(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return FALSE;
}
- return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE;
+ return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE;
}
static INLINE boolean
@@ -212,8 +346,8 @@ util_format_is_depth_or_stencil(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return FALSE;
}
@@ -225,8 +359,8 @@ util_format_is_depth_and_stencil(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return FALSE;
}
@@ -238,6 +372,34 @@ util_format_is_depth_and_stencil(enum pipe_format format)
desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
}
+/**
+ * Whether this format is a rgab8 variant.
+ *
+ * That is, any format that matches the
+ *
+ * PIPE_FORMAT_?8?8?8?8_UNORM
+ */
+static INLINE boolean
+util_format_is_rgba8_variant(const struct util_format_description *desc)
+{
+ unsigned chan;
+
+ if(desc->block.width != 1 ||
+ desc->block.height != 1 ||
+ desc->block.bits != 32)
+ return FALSE;
+
+ for(chan = 0; chan < 4; ++chan) {
+ if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED &&
+ desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID)
+ return FALSE;
+ if(desc->channel[chan].size != 8)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/**
* Return total bits needed for the pixel format per block.
@@ -247,8 +409,8 @@ util_format_get_blocksizebits(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return 0;
}
@@ -273,8 +435,8 @@ util_format_get_blockwidth(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return 1;
}
@@ -286,8 +448,8 @@ util_format_get_blockheight(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
- assert(format);
- if (!format) {
+ assert(desc);
+ if (!desc) {
return 1;
}
@@ -400,6 +562,16 @@ util_format_has_alpha(enum pipe_format format)
}
}
+/**
+ * Return the number of components stored.
+ * Formats with block size != 1x1 will always have 1 component (the block).
+ */
+static INLINE unsigned
+util_format_get_nr_components(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ return desc->nr_channels;
+}
/*
* Format access functions.
@@ -429,6 +601,19 @@ util_format_write_4ub(enum pipe_format format,
void *dst, unsigned dst_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
+/*
+ * Generic format conversion;
+ */
+
+void
+util_format_translate(enum pipe_format dst_format,
+ void *dst, unsigned dst_stride,
+ unsigned dst_x, unsigned dst_y,
+ enum pipe_format src_format,
+ const void *src, unsigned src_stride,
+ unsigned src_x, unsigned src_y,
+ unsigned width, unsigned height);
+
#ifdef __cplusplus
} // extern "C" {
#endif