/**
* Formats with sub-sampled channels.
*
- * This is for formats like YV12 where there is less than one sample per
+ * This is for formats like YVYU where there is less than one sample per
* pixel.
*/
UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3,
*/
UTIL_FORMAT_LAYOUT_RGTC = 5,
+ /**
+ * Ericsson Texture Compression
+ */
+ UTIL_FORMAT_LAYOUT_ETC = 6,
+
/**
* Everything else that doesn't fit in any of the above layouts.
*/
- UTIL_FORMAT_LAYOUT_OTHER = 6
+ UTIL_FORMAT_LAYOUT_OTHER = 7
};
UTIL_FORMAT_SWIZZLE_W = 3,
UTIL_FORMAT_SWIZZLE_0 = 4,
UTIL_FORMAT_SWIZZLE_1 = 5,
- UTIL_FORMAT_SWIZZLE_NONE = 6
+ UTIL_FORMAT_SWIZZLE_NONE = 6,
+ UTIL_FORMAT_SWIZZLE_MAX = 7 /**< Number of enums counter (must be last) */
};
struct util_format_channel_description
{
- unsigned type:6;
+ unsigned type:5; /**< UTIL_FORMAT_TYPE_x */
unsigned normalized:1;
- unsigned size:9;
+ unsigned pure_integer:1;
+ unsigned size:9; /**< bits per channel */
};
/**
* 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_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
- (*pack_8unorm)(uint8_t *dst, unsigned dst_stride,
- const uint8_t *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*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_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_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 and non-integer formats.
*/
void
- (*unpack_float)(float *dst, unsigned dst_stride,
+ (*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_UINT.
+ * Note: strides are in bytes.
+ *
+ * Only defined for stencil formats.
+ */
+ void
+ (*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Pack pixels from S8_UINT.
+ * Note: strides are in bytes.
+ *
+ * Only defined for stencil formats.
+ */
+ void
+ (*pack_s_8uint)(uint8_t *dst, unsigned dst_stride,
const uint8_t *src, unsigned src_stride,
unsigned width, unsigned height);
+ /**
+ * Unpack pixel blocks to R32G32B32A32_UINT.
+ * Note: strides are in bytes.
+ *
+ * Only defined for INT formats.
+ */
+ void
+ (*unpack_rgba_uint)(unsigned *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ void
+ (*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride,
+ const unsigned *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ /**
+ * Unpack pixel blocks to R32G32B32A32_SINT.
+ * Note: strides are in bytes.
+ *
+ * Only defined for INT formats.
+ */
+ void
+ (*unpack_rgba_sint)(signed *dst, unsigned dst_stride,
+ const uint8_t *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
+ void
+ (*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride,
+ const int *src, unsigned src_stride,
+ unsigned width, unsigned height);
+
/**
- * Pack pixel blocks from R32G32B32A32_FLOAT.
+ * Fetch a single pixel (i, j) from a block.
+ *
+ * Only defined for unsigned (pure) integer formats.
*/
void
- (*pack_float)(uint8_t *dst, unsigned dst_stride,
- const float *src, unsigned src_stride,
- unsigned width, unsigned height);
+ (*fetch_rgba_uint)(uint32_t *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
/**
* Fetch a single pixel (i, j) from a block.
+ *
+ * Only defined for signed (pure) integer formats.
*/
void
- (*fetch_float)(float *dst,
- const uint8_t *src,
- unsigned i, unsigned j);
+ (*fetch_rgba_sint)(int32_t *dst,
+ const uint8_t *src,
+ unsigned i, unsigned j);
};
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)
{
}
static INLINE boolean
+util_format_is_srgb(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB;
+}
+
+static INLINE boolean
+util_format_has_depth(const struct util_format_description *desc)
+{
+ return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
+ desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE;
+}
+
+static INLINE boolean
+util_format_has_stencil(const struct util_format_description *desc)
+{
+ return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS &&
+ desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE;
+}
+
+static INLINE boolean
util_format_is_depth_or_stencil(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
return FALSE;
}
- return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE;
+ return util_format_has_depth(desc) ||
+ util_format_has_stencil(desc);
}
-static INLINE boolean
+static INLINE boolean
util_format_is_depth_and_stencil(enum pipe_format format)
{
const struct util_format_description *desc = util_format_description(format);
return FALSE;
}
- if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) {
- return FALSE;
+ return util_format_has_depth(desc) &&
+ util_format_has_stencil(desc);
+}
+
+
+/**
+ * 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;
}
+}
- return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE &&
- desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE;
+
+/**
+ * Checks if color mask covers every channel for the specified format
+ *
+ * @param desc a format description to check colormask with
+ * @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA
+ */
+static INLINE boolean
+util_format_colormask_full(const struct util_format_description *desc, unsigned colormask)
+{
+ return (~colormask & util_format_colormask(desc)) == 0;
}
+
+boolean
+util_format_is_float(enum pipe_format format);
+
+
+boolean
+util_format_is_rgb_no_alpha(enum pipe_format format);
+
+
+boolean
+util_format_is_luminance(enum pipe_format format);
+
+
+boolean
+util_format_is_luminance_alpha(enum pipe_format format);
+
+
+boolean
+util_format_is_intensity(enum pipe_format format);
+
+boolean
+util_format_is_pure_integer(enum pipe_format format);
+
+boolean
+util_format_is_pure_sint(enum pipe_format format);
+
+boolean
+util_format_is_pure_uint(enum pipe_format format);
+
+/**
+ * Whether the format is a simple array format where all channels
+ * are of the same type and can be loaded from memory as a vector
+ */
+boolean
+util_format_is_array(const struct util_format_description *desc);
+
+/**
+ * Check if the src format can be blitted to the destination format with
+ * a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not
+ * the reverse.
+ */
+boolean
+util_is_format_compatible(const struct util_format_description *src_desc,
+ const struct util_format_description *dst_desc);
+
+/**
+ * Whether the format is supported by Gallium for the given bindings.
+ * This covers S3TC textures and floating-point render targets.
+ */
+boolean
+util_format_is_supported(enum pipe_format format, unsigned bind);
+
/**
* Whether this format is a rgab8 variant.
*
}
}
+/**
+ * Given a linear RGB colorspace format, return the corresponding 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;
+ }
+}
+
+/**
+ * Given an sRGB format, return the corresponding linear colorspace format.
+ * For non sRGB formats, return the format unchanged.
+ */
+static INLINE enum pipe_format
+util_format_linear(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_L8_SRGB:
+ return PIPE_FORMAT_L8_UNORM;
+ case PIPE_FORMAT_L8A8_SRGB:
+ return PIPE_FORMAT_L8A8_UNORM;
+ case PIPE_FORMAT_R8G8B8_SRGB:
+ return PIPE_FORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ return PIPE_FORMAT_A8B8G8R8_UNORM;
+ case PIPE_FORMAT_X8B8G8R8_SRGB:
+ return PIPE_FORMAT_X8B8G8R8_UNORM;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ case PIPE_FORMAT_X8R8G8B8_SRGB:
+ return PIPE_FORMAT_X8R8G8B8_UNORM;
+ case PIPE_FORMAT_DXT1_SRGB:
+ return PIPE_FORMAT_DXT1_RGB;
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return PIPE_FORMAT_DXT1_RGBA;
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return PIPE_FORMAT_DXT3_RGBA;
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return PIPE_FORMAT_DXT5_RGBA;
+ default:
+ return format;
+ }
+}
+
/**
* Return the number of components stored.
* Formats with block size != 1x1 will always have 1 component (the block).
return desc->nr_channels;
}
+/**
+ * Return the index of the first non-void channel
+ * -1 if no non-void channels
+ */
+static INLINE int
+util_format_get_first_non_void_channel(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description(format);
+ int i;
+
+ for (i = 0; i < 4; i++)
+ if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
+ break;
+
+ if (i == 4)
+ return -1;
+
+ return i;
+}
+
/*
* Format access functions.
*/
void *dst, unsigned dst_stride,
unsigned x, unsigned y, unsigned w, unsigned h);
+void
+util_format_read_4ui(enum pipe_format format,
+ unsigned *dst, unsigned dst_stride,
+ const void *src, unsigned src_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_write_4ui(enum pipe_format format,
+ const unsigned int *src, unsigned src_stride,
+ void *dst, unsigned dst_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_read_4i(enum pipe_format format,
+ int *dst, unsigned dst_stride,
+ const void *src, unsigned src_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_write_4i(enum pipe_format format,
+ const int *src, unsigned src_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 src_x, unsigned src_y,
unsigned width, unsigned height);
+/*
+ * Swizzle operations.
+ */
+
+/* Compose two sets of swizzles.
+ * If V is a 4D vector and the function parameters represent functions that
+ * swizzle vector components, this holds:
+ * swz2(swz1(V)) = dst(V)
+ */
+void util_format_compose_swizzles(const unsigned char swz1[4],
+ const unsigned char swz2[4],
+ unsigned char dst[4]);
+
+void util_format_swizzle_4f(float *dst, const float *src,
+ const unsigned char swz[4]);
+
+void util_format_unswizzle_4f(float *dst, const float *src,
+ const unsigned char swz[4]);
+
#ifdef __cplusplus
} // extern "C" {
#endif