aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-08-20 13:59:26 -0700
committerAlyssa Rosenzweig <[email protected]>2019-08-21 08:40:54 -0700
commit2208eb9b728ae359e323a923f06688e2ae182918 (patch)
treed5dcf38a8d05c7fdbaaefef34365849eec314fbd /src
parentb233012d445836c9be9be2a0e2b2e87af34b5fc7 (diff)
pan/decode: Validate swizzles against format
We want to make sure we don't access a component in the swizzle that doesn't exist in the format, since that is (as far as I know) undefined. Signed-off-by: Alyssa Rosenzweig <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/panfrost/pandecode/decode.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c
index a0c5f94defb..e4c1f8f7bc2 100644
--- a/src/panfrost/pandecode/decode.c
+++ b/src/panfrost/pandecode/decode.c
@@ -1365,6 +1365,71 @@ pandecode_midgard_blend_mrt(void *descs, int job_no, int rt_no)
return shader;
}
+/* Attributes and varyings have descriptor records, which contain information
+ * about their format and ordering with the attribute/varying buffers. We'll
+ * want to validate that the combinations specified are self-consistent.
+ */
+
+/* Extracts the number of components associated with a Mali format */
+
+static unsigned
+pandecode_format_component_count(enum mali_format fmt)
+{
+ /* Mask out the format class */
+ unsigned top = fmt & 0b11100000;
+
+ switch (top) {
+ case MALI_FORMAT_SNORM:
+ case MALI_FORMAT_UINT:
+ case MALI_FORMAT_UNORM:
+ case MALI_FORMAT_SINT:
+ return ((fmt >> 3) & 3) + 1;
+ default:
+ /* TODO: Validate */
+ return 4;
+ }
+}
+
+/* Extracts a mask of accessed components from a 12-bit Mali swizzle */
+
+static unsigned
+pandecode_access_mask_from_channel_swizzle(unsigned swizzle)
+{
+ unsigned mask = 0;
+ assert(MALI_CHANNEL_RED == 0);
+
+ for (unsigned c = 0; c < 4; ++c) {
+ enum mali_channel chan = (swizzle >> (3*c)) & 0x7;
+
+ if (chan <= MALI_CHANNEL_ALPHA)
+ mask |= (1 << chan);
+ }
+
+ return mask;
+}
+
+/* Validates that a (format, swizzle) pair is valid, in the sense that the
+ * swizzle doesn't access any components that are undefined in the format.
+ * Returns whether the swizzle is trivial (doesn't do any swizzling) and can be
+ * omitted */
+
+static bool
+pandecode_validate_format_swizzle(enum mali_format fmt, unsigned swizzle)
+{
+ unsigned nr_comp = pandecode_format_component_count(fmt);
+ unsigned access_mask = pandecode_access_mask_from_channel_swizzle(swizzle);
+ unsigned valid_mask = (1 << nr_comp) - 1;
+ unsigned invalid_mask = ~valid_mask;
+
+ if (access_mask & invalid_mask) {
+ pandecode_msg("XXX: invalid components accessed\n");
+ return false;
+ }
+
+ /* TODO: Trivial swizzle check */
+ return false;
+}
+
static int
pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_postfix *v, bool varying, char *suffix)
{
@@ -1423,7 +1488,17 @@ pandecode_attribute_meta(int job_no, int count, const struct mali_vertex_tiler_p
if (attr_meta->index > max_index)
max_index = attr_meta->index;
- pandecode_swizzle(attr_meta->swizzle);
+
+ /* Check the swizzle/format, and if they match and the swizzle
+ * is simple enough, we can avoid printing the swizzle since
+ * it's just noise */
+
+ bool trivial_swizzle = pandecode_validate_format_swizzle(
+ attr_meta->format, attr_meta->swizzle);
+
+ if (!trivial_swizzle)
+ pandecode_swizzle(attr_meta->swizzle);
+
pandecode_prop("format = %s", pandecode_format(attr_meta->format));
if (attr_meta->unknown1 != 0x2) {