#include "pipe/p_format.h"
#include "util/u_debug.h"
-#include "util/u_format_s3tc.h"
#ifdef __cplusplus
extern "C" {
*/
unsigned is_mixed:1;
- /**
- * Whether the pack/unpack functions actually work.
- *
- * Call util_format_is_supported instead of using this directly.
- */
- unsigned is_supported:1;
-
/**
* Input channel description.
*
/**
* Unpack pixel blocks to R8G8B8A8_UNORM.
+ * Note: strides are in bytes.
+ *
+ * Only defined for non-depth-stencil formats.
*/
void
- (*unpack_8unorm)(uint8_t *dst, unsigned dst_stride,
- const uint8_t *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*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.
+ * Note: strides are in bytes.
+ *
+ * Only defined for non-depth-stencil formats.
*/
void
- (*pack_8unorm)(uint8_t *dst, unsigned dst_stride,
- const uint8_t *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Fetch a single pixel (i, j) from a block.
+ *
+ * XXX: Only defined for a very few select formats.
+ */
+ void
+ (*fetch_rgba_8unorm)(uint8_t *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
/**
* Unpack pixel blocks to R32G32B32A32_FLOAT.
+ * Note: strides are in bytes.
+ *
+ * Only defined for non-depth-stencil formats.
*/
void
- (*unpack_float)(float *dst, unsigned dst_stride,
- const uint8_t *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*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.
+ * Note: strides are in bytes.
+ *
+ * Only defined for non-depth-stencil formats.
*/
void
- (*pack_float)(uint8_t *dst, unsigned dst_stride,
- const float *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*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_float)(float *dst,
- const uint8_t *src,
- unsigned i, unsigned j);
+ (*fetch_rgba_float)(float *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
+
+ /**
+ * Unpack pixels to Z32_UNORM.
+ * Note: strides are in bytes.
+ *
+ * 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.
+ * Note: strides are in bytes.
+ *
+ * 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.
+ * Note: strides are in bytes.
+ *
+ * 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.
+ * Note: strides are in bytes.
+ *
+ * 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.
+ * Note: strides are in bytes.
+ *
+ * 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.
+ * Note: strides are in bytes.
+ *
+ * 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);
+
};
assert(desc);
if (!desc) {
- return "???";
+ return "PIPE_FORMAT_???";
}
return desc->name;
}
+static INLINE const char *
+util_format_short_name(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(desc);
+ if (!desc) {
+ return "???";
+ }
+
+ return desc->short_name;
+}
+
+/**
+ * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info.
+ */
+static INLINE boolean
+util_format_is_plain(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ if (!format) {
+ return FALSE;
+ }
+
+ return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE;
+}
+
+static INLINE boolean
+util_format_is_compressed(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+
+ assert(desc);
+ if (!desc) {
+ return FALSE;
+ }
+
+ switch (desc->layout) {
+ case UTIL_FORMAT_LAYOUT_S3TC:
+ case UTIL_FORMAT_LAYOUT_RGTC:
+ /* XXX add other formats in the future */
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
static INLINE boolean
util_format_is_s3tc(enum pipe_format format)
{
desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
}
+
+/**
+ * Give the RGBA colormask of the channels that can be represented in this
+ * format.
+ *
+ * That is, the channels whose values are preserved.
+ */
+static INLINE unsigned
+util_format_colormask(const struct util_format_description *desc)
+{
+ unsigned colormask;
+ unsigned chan;
+
+ switch (desc->colorspace) {
+ case UTIL_FORMAT_COLORSPACE_RGB:
+ case UTIL_FORMAT_COLORSPACE_SRGB:
+ case UTIL_FORMAT_COLORSPACE_YUV:
+ colormask = 0;
+ for (chan = 0; chan < 4; ++chan) {
+ if (desc->swizzle[chan] < 4) {
+ colormask |= (1 << chan);
+ }
+ }
+ return colormask;
+ case UTIL_FORMAT_COLORSPACE_ZS:
+ return 0;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+
/**
* Whether this format is a rgab8 variant.
*
}
}
+/**
+ * Return the matching SRGB format, or PIPE_FORMAT_NONE if none.
+ */
+static INLINE enum pipe_format
+util_format_srgb(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_L8_UNORM:
+ return PIPE_FORMAT_L8_SRGB;
+ case PIPE_FORMAT_L8A8_UNORM:
+ return PIPE_FORMAT_L8A8_SRGB;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ return PIPE_FORMAT_R8G8B8_SRGB;
+ case PIPE_FORMAT_A8B8G8R8_UNORM:
+ return PIPE_FORMAT_A8B8G8R8_SRGB;
+ case PIPE_FORMAT_X8B8G8R8_UNORM:
+ return PIPE_FORMAT_X8B8G8R8_SRGB;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ return PIPE_FORMAT_B8G8R8A8_SRGB;
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return PIPE_FORMAT_B8G8R8X8_SRGB;
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return PIPE_FORMAT_A8R8G8B8_SRGB;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ return PIPE_FORMAT_X8R8G8B8_SRGB;
+ case PIPE_FORMAT_DXT1_RGB:
+ return PIPE_FORMAT_DXT1_SRGB;
+ case PIPE_FORMAT_DXT1_RGBA:
+ return PIPE_FORMAT_DXT1_SRGBA;
+ case PIPE_FORMAT_DXT3_RGBA:
+ return PIPE_FORMAT_DXT3_SRGBA;
+ case PIPE_FORMAT_DXT5_RGBA:
+ return PIPE_FORMAT_DXT5_SRGBA;
+ default:
+ return PIPE_FORMAT_NONE;
+ }
+}
+
/**
* Return the number of components stored.
* Formats with block size != 1x1 will always have 1 component (the block).
* Format access functions.
*/
-static INLINE boolean
-util_format_is_supported(enum pipe_format format)
-{
- const struct util_format_description *desc = util_format_description(format);
-
- if(!desc)
- return FALSE;
-
- if(desc->layout == UTIL_FORMAT_LAYOUT_S3TC)
- util_format_s3tc_init();
-
- return desc->is_supported;
-}
-
void
util_format_read_4f(enum pipe_format format,
float *dst, unsigned dst_stride,
void *dst, unsigned dst_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
+/*
+ * Generic format conversion;
+ */
+
+boolean
+util_format_fits_8unorm(const struct util_format_description *format_desc);
+
+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