mesa: Replace the float[4] unpack code with util/format's.

The gallium drivers lose 10-15k of binary by not having this duplicated
unpack code, but classic i965 gains 215k of binary by pulling in
u_format's pack/unpack code.  The cost to classic will go down as we drop
more of the duplicated code.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6297>
This commit is contained in:
Eric Anholt 2019-11-07 10:37:54 -08:00 committed by Marge Bot
parent 83f97cd0be
commit 13ae72aaae
4 changed files with 9 additions and 166 deletions

View file

@ -25,15 +25,19 @@
#ifndef FORMAT_UNPACK_H
#define FORMAT_UNPACK_H
#include "util/format/u_format.h"
#include "formats.h"
#ifdef __cplusplus
extern "C" {
#endif
extern void
static inline void
_mesa_unpack_rgba_row(mesa_format format, uint32_t n,
const void *src, float dst[][4]);
const void *src, float dst[][4])
{
util_format_unpack_rgba(format, dst, src, n);
}
extern void
_mesa_unpack_ubyte_rgba_row(mesa_format format, uint32_t n,

View file

@ -68,136 +68,6 @@ for f in formats:
rgb_formats.append(f)
%>
/* float unpacking functions */
%for f in rgb_formats:
%if f.name in ('MESA_FORMAT_R9G9B9E5_FLOAT', 'MESA_FORMAT_R11G11B10_FLOAT'):
<% continue %>
%elif f.is_int() and not f.is_normalized():
<% continue %>
%elif f.is_compressed():
<% continue %>
%endif
static inline void
unpack_float_${f.short_name()}(const void *void_src, float dst[4])
{
${f.datatype()} *src = (${f.datatype()} *)void_src;
%if f.layout == parser.PACKED:
%for c in f.channels:
%if c.type != 'x':
${c.datatype()} ${c.name} = UNPACK(*src, ${c.shift}, ${c.size});
%endif
%endfor
%elif f.layout == parser.ARRAY:
%for (i, c) in enumerate(f.channels):
%if c.type != 'x':
${c.datatype()} ${c.name} = src[${i}];
%endif
%endfor
%else:
<% assert False %>
%endif
%for i in range(4):
<% s = f.swizzle[i] %>
%if 0 <= s and s <= parser.Swizzle.SWIZZLE_W:
<% c = f.channels[s] %>
%if c.type == parser.UNSIGNED:
%if f.colorspace == 'srgb' and c.name in 'rgb':
<% assert c.size == 8 %>
dst[${i}] = util_format_srgb_8unorm_to_linear_float(${c.name});
%else:
dst[${i}] = _mesa_unorm_to_float(${c.name}, ${c.size});
%endif
%elif c.type == parser.SIGNED:
dst[${i}] = _mesa_snorm_to_float(${c.name}, ${c.size});
%elif c.type == parser.FLOAT:
%if c.size == 32:
dst[${i}] = ${c.name};
%elif c.size == 16:
dst[${i}] = _mesa_half_to_float(${c.name});
%else:
<% assert False %>
%endif
%else:
<% assert False %>
%endif
%elif s == parser.Swizzle.SWIZZLE_ZERO:
dst[${i}] = 0.0f;
%elif s == parser.Swizzle.SWIZZLE_ONE:
dst[${i}] = 1.0f;
%else:
<% assert False %>
%endif
%endfor
}
%endfor
static void
unpack_float_r9g9b9e5_float(const void *src, float dst[4])
{
rgb9e5_to_float3(*(const uint32_t *)src, dst);
dst[3] = 1.0f;
}
static void
unpack_float_r11g11b10_float(const void *src, float dst[4])
{
r11g11b10f_to_float3(*(const uint32_t *)src, dst);
dst[3] = 1.0f;
}
static void
unpack_float_ycbcr(const void *src, float dst[][4], uint32_t n)
{
uint32_t i;
for (i = 0; i < n; i++) {
const uint16_t *src0 = ((const uint16_t *) src) + i * 2; /* even */
const uint16_t *src1 = src0 + 1; /* odd */
const uint8_t y0 = (*src0 >> 8) & 0xff; /* luminance */
const uint8_t cb = *src0 & 0xff; /* chroma U */
const uint8_t y1 = (*src1 >> 8) & 0xff; /* luminance */
const uint8_t cr = *src1 & 0xff; /* chroma V */
const uint8_t y = (i & 1) ? y1 : y0; /* choose even/odd luminance */
float r = 1.164F * (y - 16) + 1.596F * (cr - 128);
float g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
float b = 1.164F * (y - 16) + 2.018F * (cb - 128);
r *= (1.0F / 255.0F);
g *= (1.0F / 255.0F);
b *= (1.0F / 255.0F);
dst[i][0] = CLAMP(r, 0.0F, 1.0F);
dst[i][1] = CLAMP(g, 0.0F, 1.0F);
dst[i][2] = CLAMP(b, 0.0F, 1.0F);
dst[i][3] = 1.0F;
}
}
static void
unpack_float_ycbcr_rev(const void *src, float dst[][4], uint32_t n)
{
uint32_t i;
for (i = 0; i < n; i++) {
const uint16_t *src0 = ((const uint16_t *) src) + i * 2; /* even */
const uint16_t *src1 = src0 + 1; /* odd */
const uint8_t y0 = *src0 & 0xff; /* luminance */
const uint8_t cr = (*src0 >> 8) & 0xff; /* chroma V */
const uint8_t y1 = *src1 & 0xff; /* luminance */
const uint8_t cb = (*src1 >> 8) & 0xff; /* chroma U */
const uint8_t y = (i & 1) ? y1 : y0; /* choose even/odd luminance */
float r = 1.164F * (y - 16) + 1.596F * (cr - 128);
float g = 1.164F * (y - 16) - 0.813F * (cr - 128) - 0.391F * (cb - 128);
float b = 1.164F * (y - 16) + 2.018F * (cb - 128);
r *= (1.0F / 255.0F);
g *= (1.0F / 255.0F);
b *= (1.0F / 255.0F);
dst[i][0] = CLAMP(r, 0.0F, 1.0F);
dst[i][1] = CLAMP(g, 0.0F, 1.0F);
dst[i][2] = CLAMP(b, 0.0F, 1.0F);
dst[i][3] = 1.0F;
}
}
/* ubyte packing functions */
%for f in rgb_formats:
@ -305,38 +175,6 @@ unpack_int_${f.short_name()}(const void *void_src, uint32_t dst[4])
%endfor
void
_mesa_unpack_rgba_row(mesa_format format, uint32_t n,
const void *src, float dst[][4])
{
uint8_t *s = (uint8_t *)src;
uint32_t i;
switch (format) {
%for f in rgb_formats:
%if f.is_compressed():
<% continue %>
%elif f.is_int() and not f.is_normalized():
<% continue %>
%endif
case ${f.name}:
for (i = 0; i < n; ++i) {
unpack_float_${f.short_name()}(s, dst[i]);
s += ${f.block_size() // 8};
}
break;
%endfor
case MESA_FORMAT_YCBCR:
unpack_float_ycbcr(src, dst, n);
break;
case MESA_FORMAT_YCBCR_REV:
unpack_float_ycbcr_rev(src, dst, n);
break;
default:
unreachable("bad format");
}
}
void
_mesa_unpack_ubyte_rgba_row(mesa_format format, uint32_t n,
const void *src, uint8_t dst[][4])

View file

@ -55,7 +55,8 @@
#include "glformats.h"
#include "format_utils.h"
#include "format_pack.h"
#include "format_unpack.h"
#include "util/format/u_format.h"
/**
* Flip the 8 bits in each byte of the given array.

View file

@ -38,7 +38,7 @@ test(
executable(
'main_test',
[files_main_test, main_dispatch_h],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium],
dependencies : [idep_gtest, dep_clock, dep_dl, dep_thread, idep_mesautil],
link_with : [libmesa_classic, link_main_test],
),