[Mesa-dev] [PATCH 15/29] mesa: Let _mesa_get_format_base_format also handle mesa_array_format
Iago Toral Quiroga
itoral at igalia.com
Tue Nov 18 01:23:56 PST 2014
When we needed the base format for a mesa_array_format we had to find
the matching mesa_format first. This is expensive because it requires
to loop through all existing mesa formats until we find the right match.
We can resolve the base format of an array format directly by looking
at its swizzle information. Also, we can have _mesa_get_format_base_format
accept an uint32_t which can pack either a mesa_format or a mesa_array_format
and resolve the base format for either type. This way clients do not need to
check if they have a mesa_format or a mesa_array_format and call different
functions depending on the case.
Another reason to resolve the base format for array formats directly is that
we don't have matching mesa_format enums for every possible array format, so
for some GL format/type combinations we will produce array formats that don't
have a corresponding mesa format, in which case we would not be able to
find the base format. Example format=GL_RGB, type=GL_UNSIGNED_SHORT. This type
would map to something like MESA_FORMAT_RGB_UNORM16, but we don't have that.
---
src/mesa/main/format_utils.c | 12 ++------
src/mesa/main/formats.c | 69 ++++++++++++++++++++++++++++++++++++++++++--
src/mesa/main/formats.h | 2 +-
src/mesa/main/readpix.c | 7 +----
4 files changed, 71 insertions(+), 19 deletions(-)
diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c
index 97c125c..6648876 100644
--- a/src/mesa/main/format_utils.c
+++ b/src/mesa/main/format_utils.c
@@ -341,12 +341,7 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
* this path in these scenarios but in the future we may want to enable
* it for specific combinations that are known to work.
*/
- mesa_format dst_mesa_format;
- if (dst_format & MESA_ARRAY_FORMAT_BIT)
- dst_mesa_format = _mesa_format_from_array_format(dst_format);
- else
- dst_mesa_format = dst_format;
- if (_mesa_get_format_base_format(dst_mesa_format) == dst_internal_format) {
+ if (_mesa_get_format_base_format(dst_format) == dst_internal_format) {
/* Handle the cases where we can directly unpack */
if (!(src_format & MESA_ARRAY_FORMAT_BIT)) {
if (dst_array_format.as_uint == RGBA8888_FLOAT.as_uint) {
@@ -449,7 +444,7 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
* by computing the swizzle transform src->rgba->base->rgba->dst instead
* of src->rgba->dst.
*/
- if (dst_internal_format != _mesa_get_format_base_format(dst_mesa_format)) {
+ if (dst_internal_format != _mesa_get_format_base_format(dst_format)) {
/* Compute src2rgba as src->rgba->base->rgba */
uint8_t rgba2base[4], base2rgba[4], swizzle[4];
_mesa_compute_component_mapping(GL_RGBA, dst_internal_format, rgba2base);
@@ -593,8 +588,7 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride,
*/
GLubyte rgba2base[4], base2rgba[4], map[4];
bool need_convert = false;
- if (dst_internal_format !=
- _mesa_get_format_base_format(dst_mesa_format)) {
+ if (dst_internal_format != _mesa_get_format_base_format(dst_format)) {
_mesa_compute_component_mapping(GL_RGBA, dst_internal_format,
base2rgba);
_mesa_compute_component_mapping(dst_internal_format, GL_RGBA,
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index 7464d89..8917f6d 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -214,17 +214,80 @@ _mesa_get_format_datatype(mesa_format format)
return info->DataType;
}
+static GLenum
+get_base_format_for_array_format(mesa_array_format format)
+{
+ switch (format.num_channels) {
+ case 4:
+ /* FIXME: RGBX formats have 4 channels, but their base format is GL_RGB.
+ * This is not really a problem for now because we only create array
+ * formats from GL format/type combinations, and these cannot specify
+ * RGBX formats.
+ */
+ return GL_RGBA;
+ case 3:
+ return GL_RGB;
+ case 2:
+ if (format.swizzle_x == 0 &&
+ format.swizzle_y == 0 &&
+ format.swizzle_z == 0 &&
+ format.swizzle_w == 1)
+ return GL_LUMINANCE_ALPHA;
+ if (format.swizzle_x == 1 &&
+ format.swizzle_y == 1 &&
+ format.swizzle_z == 1 &&
+ format.swizzle_w == 0)
+ return GL_LUMINANCE_ALPHA;
+ if (format.swizzle_x == 0 &&
+ format.swizzle_y == 1 &&
+ format.swizzle_z == 4 &&
+ format.swizzle_w == 5)
+ return GL_RG;
+ if (format.swizzle_x == 1 &&
+ format.swizzle_y == 0 &&
+ format.swizzle_z == 4 &&
+ format.swizzle_w == 5)
+ return GL_RG;
+ break;
+ case 1:
+ if (format.swizzle_x == 0 &&
+ format.swizzle_y == 0 &&
+ format.swizzle_z == 0 &&
+ format.swizzle_w == 5)
+ return GL_LUMINANCE;
+ if (format.swizzle_x == 0 &&
+ format.swizzle_y == 0 &&
+ format.swizzle_z == 0 &&
+ format.swizzle_w == 0)
+ return GL_INTENSITY;
+ if (format.swizzle_x <= MESA_FORMAT_SWIZZLE_W)
+ return GL_RED;
+ if (format.swizzle_y <= MESA_FORMAT_SWIZZLE_W)
+ return GL_GREEN;
+ if (format.swizzle_z <= MESA_FORMAT_SWIZZLE_W)
+ return GL_BLUE;
+ if (format.swizzle_w <= MESA_FORMAT_SWIZZLE_W)
+ return GL_ALPHA;
+ break;
+ }
+ assert(!"Unsupported format");
+}
/**
* Return the basic format for the given type. The result will be one of
* GL_RGB, GL_RGBA, GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_INTENSITY,
* GL_YCBCR_MESA, GL_DEPTH_COMPONENT, GL_STENCIL_INDEX, GL_DEPTH_STENCIL.
+ * This functions accepts a mesa_format or a mesa_array_format.
*/
GLenum
-_mesa_get_format_base_format(mesa_format format)
+_mesa_get_format_base_format(uint32_t format)
{
- const struct gl_format_info *info = _mesa_get_format_info(format);
- return info->BaseFormat;
+ if (!(format & MESA_ARRAY_FORMAT_BIT)) {
+ const struct gl_format_info *info = _mesa_get_format_info(format);
+ return info->BaseFormat;
+ } else {
+ return get_base_format_for_array_format((mesa_array_format) format);
+ }
}
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index 092a1a2..aebfd0f 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -532,7 +532,7 @@ extern GLenum
_mesa_get_format_datatype(mesa_format format);
extern GLenum
-_mesa_get_format_base_format(mesa_format format);
+_mesa_get_format_base_format(uint32_t format);
extern void
_mesa_get_format_block_size(mesa_format format, GLuint *bw, GLuint *bh);
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 8f4894e..b779a5b 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -430,12 +430,7 @@ read_rgba_pixels( struct gl_context *ctx,
GLboolean dst_is_integer = _mesa_is_enum_format_integer(format);
int dst_stride = _mesa_image_row_stride(packing, width, format, type);
uint32_t dst_format = _mesa_format_from_format_and_type(format, type);
- mesa_format dst_mesa_format;
- if (dst_format & MESA_ARRAY_FORMAT_BIT)
- dst_mesa_format = _mesa_format_from_array_format(dst_format);
- else
- dst_mesa_format = dst_format;
- GLenum dst_base_format = _mesa_get_format_base_format(dst_mesa_format);
+ GLenum dst_base_format = _mesa_get_format_base_format(dst_format);
GLubyte *dst = (GLubyte *)
_mesa_image_address2d(packing, pixels, width, height,
format, type, 0, 0);
--
1.9.1
More information about the mesa-dev
mailing list