mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 20:00:11 +01:00
gallium: Make sure we return is_unorm/is_snorm for compressed formats.
The util helpers were looking for a non-void channels in a non-mixed format and returning its snorm/unorm state. However, compressed formats don't have non-void channels, so they always returned false. V3D wants to use util_format_is_[su]norm for its border color clamping workarounds, so fix the functions to return the right answer for these. This now means that we ignore .is_mixed. I could retain the is_mixed check, but it doesn't seem like a useful feature -- the only code I could find that might care is freedreno's blit, which has some notes about how things are wonky in this area anyway. Reviewed-by: <Roland Scheidegger sroland@vmware.com>
This commit is contained in:
parent
104c7883e7
commit
08f4a904b3
5 changed files with 101 additions and 24 deletions
|
|
@ -149,45 +149,25 @@ util_format_is_pure_uint(enum pipe_format format)
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns true if all non-void channels are normalized signed.
|
||||
* Returns true if the format contains normalized signed channels.
|
||||
*/
|
||||
boolean
|
||||
util_format_is_snorm(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
int i;
|
||||
|
||||
if (desc->is_mixed)
|
||||
return FALSE;
|
||||
|
||||
i = util_format_get_first_non_void_channel(format);
|
||||
if (i == -1)
|
||||
return FALSE;
|
||||
|
||||
return desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED &&
|
||||
!desc->channel[i].pure_integer &&
|
||||
desc->channel[i].normalized;
|
||||
return desc->is_snorm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all non-void channels are normalized unsigned.
|
||||
* Returns true if the format contains normalized unsigned channels.
|
||||
*/
|
||||
boolean
|
||||
util_format_is_unorm(enum pipe_format format)
|
||||
{
|
||||
const struct util_format_description *desc = util_format_description(format);
|
||||
int i;
|
||||
|
||||
if (desc->is_mixed)
|
||||
return FALSE;
|
||||
|
||||
i = util_format_get_first_non_void_channel(format);
|
||||
if (i == -1)
|
||||
return FALSE;
|
||||
|
||||
return desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED &&
|
||||
!desc->channel[i].pure_integer &&
|
||||
desc->channel[i].normalized;
|
||||
return desc->is_unorm;
|
||||
}
|
||||
|
||||
boolean
|
||||
|
|
|
|||
|
|
@ -177,6 +177,16 @@ struct util_format_description
|
|||
*/
|
||||
unsigned is_mixed:1;
|
||||
|
||||
/**
|
||||
* Whether the format contains UNORM channels
|
||||
*/
|
||||
unsigned is_unorm:1;
|
||||
|
||||
/**
|
||||
* Whether the format contains SNORM channels
|
||||
*/
|
||||
unsigned is_snorm:1;
|
||||
|
||||
/**
|
||||
* Input channel description, in the order XYZW.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -187,6 +187,26 @@ class Format:
|
|||
return True
|
||||
return False
|
||||
|
||||
def is_compressed(self):
|
||||
for channel in self.le_channels:
|
||||
if channel.type != VOID:
|
||||
return False
|
||||
return True
|
||||
|
||||
def is_unorm(self):
|
||||
# Non-compressed formats all have unorm or srgb in their name.
|
||||
for keyword in ['_UNORM', '_SRGB']:
|
||||
if keyword in self.name:
|
||||
return True
|
||||
|
||||
# All the compressed formats in GLES3.2 and GL4.6 ("Table 8.14: Generic
|
||||
# and specific compressed internal formats.") that aren't snorm for
|
||||
# border colors are unorm, other than BPTC_*_FLOAT.
|
||||
return self.is_compressed() and not ('FLOAT' in self.name or self.is_snorm())
|
||||
|
||||
def is_snorm(self):
|
||||
return '_SNORM' in self.name
|
||||
|
||||
def is_pot(self):
|
||||
return is_pot(self.block_size())
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ def write_format_table(formats):
|
|||
print(" %s,\t/* is_array */" % (bool_map(format.is_array()),))
|
||||
print(" %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),))
|
||||
print(" %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),))
|
||||
print(" %s,\t/* is_unorm */" % (bool_map(format.is_unorm()),))
|
||||
print(" %s,\t/* is_snorm */" % (bool_map(format.is_snorm()),))
|
||||
u_format_pack.print_channels(format, do_channel_array)
|
||||
u_format_pack.print_channels(format, do_swizzle_array)
|
||||
print(" %s," % (colorspace_map(format.colorspace),))
|
||||
|
|
|
|||
|
|
@ -668,6 +668,47 @@ test_format_pack_s_8uint(const struct util_format_description *format_desc,
|
|||
}
|
||||
|
||||
|
||||
/* Touch-test that the unorm/snorm flags are set up right by codegen. */
|
||||
static boolean
|
||||
test_format_norm_flags(const struct util_format_description *format_desc)
|
||||
{
|
||||
boolean success = TRUE;
|
||||
|
||||
#define FORMAT_CASE(format, unorm, snorm) \
|
||||
case format: \
|
||||
success = (format_desc->is_unorm == unorm && \
|
||||
format_desc->is_snorm == snorm); \
|
||||
break
|
||||
|
||||
switch (format_desc->format) {
|
||||
FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_UNORM, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SRGB, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_R8G8B8A8_SNORM, FALSE, TRUE);
|
||||
FORMAT_CASE(PIPE_FORMAT_R32_FLOAT, FALSE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_X8Z24_UNORM, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_S8X24_UINT, FALSE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_DXT1_RGB, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_ETC2_RGB8, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_ETC2_R11_SNORM, FALSE, TRUE);
|
||||
FORMAT_CASE(PIPE_FORMAT_ASTC_4x4, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_BPTC_RGBA_UNORM, TRUE, FALSE);
|
||||
FORMAT_CASE(PIPE_FORMAT_BPTC_RGB_FLOAT, FALSE, FALSE);
|
||||
default:
|
||||
success = !(format_desc->is_unorm && format_desc->is_snorm);
|
||||
break;
|
||||
}
|
||||
#undef FORMAT_CASE
|
||||
|
||||
if (!success) {
|
||||
printf("FAILED: %s (unorm %s, snorm %s)\n",
|
||||
format_desc->short_name,
|
||||
format_desc->is_unorm ? "yes" : "no",
|
||||
format_desc->is_snorm ? "yes" : "no");
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef boolean
|
||||
(*test_func_t)(const struct util_format_description *format_desc,
|
||||
const struct util_format_test_case *test);
|
||||
|
|
@ -698,6 +739,22 @@ test_one_func(const struct util_format_description *format_desc,
|
|||
return success;
|
||||
}
|
||||
|
||||
static boolean
|
||||
test_format_metadata(const struct util_format_description *format_desc,
|
||||
boolean (*func)(const struct util_format_description *format_desc),
|
||||
const char *suffix)
|
||||
{
|
||||
boolean success = TRUE;
|
||||
|
||||
printf("Testing util_format_%s_%s ...\n", format_desc->short_name, suffix);
|
||||
fflush(stdout);
|
||||
|
||||
if (!func(format_desc)) {
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static boolean
|
||||
test_all(void)
|
||||
|
|
@ -724,6 +781,11 @@ test_all(void)
|
|||
} \
|
||||
}
|
||||
|
||||
# define TEST_FORMAT_METADATA(name) \
|
||||
if (!test_format_metadata(format_desc, &test_format_##name, #name)) { \
|
||||
success = FALSE; \
|
||||
} \
|
||||
|
||||
TEST_ONE_FUNC(fetch_rgba_float);
|
||||
TEST_ONE_FUNC(pack_rgba_float);
|
||||
TEST_ONE_FUNC(unpack_rgba_float);
|
||||
|
|
@ -737,7 +799,10 @@ test_all(void)
|
|||
TEST_ONE_FUNC(unpack_s_8uint);
|
||||
TEST_ONE_FUNC(pack_s_8uint);
|
||||
|
||||
TEST_FORMAT_METADATA(norm_flags);
|
||||
|
||||
# undef TEST_ONE_FUNC
|
||||
# undef TEST_ONE_FORMAT
|
||||
}
|
||||
|
||||
return success;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue