[Mesa-dev] [PATCH 05/29] mesa: Consider internal base format in _mesa_format_convert
Iago Toral
itoral at igalia.com
Wed Nov 19 23:42:55 PST 2014
On Wed, 2014-11-19 at 11:43 -0800, Jason Ekstrand wrote:
> A couple of specific comments are below. More generally, why are you
> only considering the base format on two cases? Do we never use it for
> anything else?
I thought about that too but when I looked at the original code it
seemed that it only cared for the base format in these two scenarios, so
I thought that maybe the conversions cases that could be affected are
all handled in those two paths. I'll check again though, just in case I
missed something.
> On Tue, Nov 18, 2014 at 1:23 AM, Iago Toral Quiroga
> <itoral at igalia.com> wrote:
> Add a dst_internal_format parameter to _mesa_format_convert,
> that represents
> the base internal format for texture/pixel uploads, so we can
> do the right
> thing when the driver has selected a different internal format
> for the target
> dst format.
> ---
> src/mesa/main/format_utils.c | 65
> +++++++++++++++++++++++++++++++++++++++++++-
> src/mesa/main/format_utils.h | 2 +-
> 2 files changed, 65 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/main/format_utils.c
> b/src/mesa/main/format_utils.c
> index fc59e86..5964689 100644
> --- a/src/mesa/main/format_utils.c
> +++ b/src/mesa/main/format_utils.c
> @@ -303,7 +303,7 @@ _mesa_compute_component_mapping(GLenum
> inFormat, GLenum outFormat, GLubyte *map)
> void
> _mesa_format_convert(void *void_dst, uint32_t dst_format,
> size_t dst_stride,
> void *void_src, uint32_t src_format,
> size_t src_stride,
> - size_t width, size_t height)
> + size_t width, size_t height, GLenum
> dst_internal_format)
> {
> uint8_t *dst = (uint8_t *)void_dst;
> uint8_t *src = (uint8_t *)void_src;
> @@ -422,6 +422,36 @@ _mesa_format_convert(void *void_dst,
> uint32_t dst_format, size_t dst_stride,
> if (src_array_format.as_uint && dst_array_format.as_uint)
> {
> assert(src_array_format.normalized ==
> dst_array_format.normalized);
>
> + /* If the base format of our dst is not the same as the
> provided base
> + * format it means that we are converting to a
> different format
> + * than the one originally requested by the client.
> This can happen when
> + * the internal base format requested is not supported
> by the driver.
> + * In this case we need to consider the requested
> internal base format to
> + * compute the correct swizzle operation from src to
> dst. We will do this
> + * by computing the swizzle transform
> src->rgba->base->rgba->dst instead
> + * of src->rgba->dst.
> + */
> + 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;
>
>
> Let's put an extra line here so it doesn't get confused with the below
> if statement
>
>
> + if (dst_internal_format !=
> _mesa_get_format_base_format(dst_mesa_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);
> + _mesa_compute_component_mapping(dst_internal_format,
> GL_RGBA, base2rgba);
> +
> + for (i = 0; i < 4; i++) {
> + if (base2rgba[i] > MESA_FORMAT_SWIZZLE_W)
> + swizzle[i] = base2rgba[i];
> + else
> + swizzle[i] =
> src2rgba[rgba2base[base2rgba[i]]];
>
>
> This doesn't work for composing three swizzles. If you get a ZERO or
> ONE in rgba2base, you'll read the wrong memory from src2rgba.
Actually, the problem is worse, because the mapping written by
_mesa_compute_component_mapping is a 6-component mapping and we are
passing a 4-component array. I'll fix this.
>
>
> + }
> + memcpy(src2rgba, swizzle, sizeof(src2rgba));
> + }
> +
> + /* Compute src2dst from src2rgba */
> for (i = 0; i < 4; i++) {
> if (rgba2dst[i] > MESA_FORMAT_SWIZZLE_W) {
> src2dst[i] = rgba2dst[i];
> @@ -539,9 +569,42 @@ _mesa_format_convert(void *void_dst,
> uint32_t dst_format, size_t dst_stride,
> src += src_stride;
> }
> } else {
> + /* For some conversions, doing src->rgba->dst is not
> enough and we
> + * need to consider the base internal format. In
> these cases a
> + * swizzle operation is required to match the
> semantics of the base
> + * internal format requested:
> src->rgba->swizzle->rgba->dst.
> + *
> + * We can detect these cases by checking if the
> swizzle transform
> + * for base->rgba->base is 0123. If it is not, then
> we need
> + * to do the swizzle operation (need_convert =
> true).
> + */
> + GLubyte rgba2base[4], base2rgba[4], map[4];
> + bool need_convert = false;
> + 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;
>
>
> Blank line again
>
>
>
> + if (dst_internal_format !=
> + _mesa_get_format_base_format(dst_mesa_format)) {
> + _mesa_compute_component_mapping(GL_RGBA,
> dst_internal_format,
> + base2rgba);
> +
> _mesa_compute_component_mapping(dst_internal_format, GL_RGBA,
> + rgba2base);
> + for (i = 0; i < 4; ++i) {
> + map[i] = base2rgba[rgba2base[i]];
> + if (map[i] != i)
> + need_convert = true;
> + }
> + }
> +
> for (row = 0; row < height; ++row) {
> _mesa_unpack_rgba_row(src_format, width,
> src, tmp_float + row *
> width);
> + if (need_convert)
> + _mesa_swizzle_and_convert(tmp_float + row *
> width, GL_FLOAT, 4,
> + tmp_float + row *
> width, GL_FLOAT, 4,
> + map, false, width);
> src += src_stride;
> }
> }
> diff --git a/src/mesa/main/format_utils.h
> b/src/mesa/main/format_utils.h
> index 4237ad3..29ab4a0 100644
> --- a/src/mesa/main/format_utils.h
> +++ b/src/mesa/main/format_utils.h
> @@ -158,6 +158,6 @@ _mesa_compute_component_mapping(GLenum
> inFormat, GLenum outFormat, GLubyte *map)
> void
> _mesa_format_convert(void *void_dst, uint32_t dst_format,
> size_t dst_stride,
> void *void_src, uint32_t src_format,
> size_t src_stride,
> - size_t width, size_t height);
> + size_t width, size_t height, GLenum
> dst_internal_format);
>
> #endif
> --
> 1.9.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
>
More information about the mesa-dev
mailing list