diff mbox

[1/2] arb_uniform_buffer_object: Add AoA support to random test generation script

Message ID 1442749451-22117-1-git-send-email-t_arceri@yahoo.com.au
State New
Headers show

Commit Message

'Timothy Arceri' via Patchwork Forward Sept. 20, 2015, 11:44 a.m. UTC
Cc: Ian Romanick <ian.d.romanick@intel.com>
---

 Hi Ian,

 I know these scripts haven't yet been committed to piglit yet but didn't
 know what else to do with it. I thought sending it here would at least reduce
 the chance of me losing it.

 Tim

 .../random_ubo-arb_uniform_buffer_object.py        |   7 +-
 generated_tests/random_ubo.py                      | 225 +++++++++++++--------
 2 files changed, 147 insertions(+), 85 deletions(-)

Comments

Ilia Mirkin Sept. 20, 2015, 5:24 p.m. UTC | #1
On Sun, Sep 20, 2015 at 7:44 AM, Timothy Arceri <t_arceri@yahoo.com.au> wrote:
>  Hi Ian,
>
>  I know these scripts haven't yet been committed to piglit yet but didn't
>  know what else to do with it. I thought sending it here would at least reduce
>  the chance of me losing it.
>
>  Tim

I also have some patches for the script to fix a few minor (but
show-stopping) bugs in its fp64 support. This definitely has to exist
somewhere. Running randomized tests as part of piglit is suboptimal,
but at least having the script available in the repo might make sense.
A whole separate repo seems like overkill.

Ian, what do you think?

  -ilia
diff mbox

Patch

diff --git a/generated_tests/random_ubo-arb_uniform_buffer_object.py b/generated_tests/random_ubo-arb_uniform_buffer_object.py
index 915963f..d9cdb5d 100644
--- a/generated_tests/random_ubo-arb_uniform_buffer_object.py
+++ b/generated_tests/random_ubo-arb_uniform_buffer_object.py
@@ -64,7 +64,7 @@  def do_test(requirements, packing):
         blocks,
         packing,
         130,
-        ["GL_ARB_uniform_buffer_object"]))
+        ["GL_ARB_uniform_buffer_object","GL_ARB_arrays_of_arrays"]))
 
     file.close()
 
@@ -115,6 +115,11 @@  all_requirements.append([["struct", "array", "struct"]])
 all_requirements.append([["array", "struct", "struct"]])
 all_requirements.append([["array", "struct", "array", "struct"]])
 
+all_requirements.append([["struct", "array", "array", "struct"]])
+all_requirements.append([["struct", "array", "array", "array", "struct"]])
+all_requirements.append([["array", "array", "struct", "array"]])
+all_requirements.append([["struct", "array", "array", "array"]])
+
 for p in all_packing:
     for r in all_requirements:
         do_test(r, p)
diff --git a/generated_tests/random_ubo.py b/generated_tests/random_ubo.py
index 33359f6..f6952d3 100644
--- a/generated_tests/random_ubo.py
+++ b/generated_tests/random_ubo.py
@@ -141,7 +141,6 @@  def array_elements(type):
     # Is there a better way to do this?
     return int(type.split("[")[1].split("]")[0])
 
-
 def basic_machine_units(type):
     """Return the size in 'basic machine units' of a scalar type."""
     if type in ["float", "bool", "int", "uint"]:
@@ -158,9 +157,27 @@  def array_base_type(type):
     if not isarray(type):
         raise Exception("Non-array type {}".format(type))
 
-    # XXX This will need changes for arrays-of-arrays.
+    return type[:type.index("[")] + type[type.index("]")+1:]
+
+def without_array(type):
+    """Return the type of an element with all arrays removed."""
+    if not isarray(type):
+        raise Exception("Non-array type {}".format(type))
+
     return type.split("[")[0]
 
+def arrays_of_arrays_size(type):
+    """Return the total number of elements in an array of arrays."""
+    if not isarray(type):
+        raise Exception("Non-array type {}".format(type))
+
+    size = 1
+    base_type = type
+    while (isarray(base_type)):
+        size = size * array_elements(base_type)
+        base_type = array_base_type(base_type)
+
+    return size
 
 def vector_base_type(type):
     """Return the type of an element from a vector."""
@@ -188,7 +205,7 @@  def iterate_structures(fields, types_seen=[], types_yielded=[]):
     """
     for (type, name) in fields:
         if isarray(type):
-            type = array_base_type(type)
+            type = without_array(type)
 
         if not isstructure(type):
             continue
@@ -351,7 +368,7 @@  def generate_layouts(fields, required_layouts, allow_row_major_structure):
     layouts = []
     for ((type, name), lay) in zip(fields, required_layouts):
         if isarray(type):
-            type = array_base_type(type)
+            type = without_array(type)
 
         if lay:
             layouts.append(lay)
@@ -407,6 +424,60 @@  def fields_to_glsl_struct(type):
 
     return structure_template.render(struct_name=type, fields=struct_types[type])
 
+def iterate_struct_array_recursive(field_type,
+                                   name_from_API,
+                                   name_from_shader,
+                                   packing,
+                                   offset,
+                                   row_major,
+                                   field_row_major,
+                                   explicit_layout):
+
+    astride = packing.array_stride(field_type, field_row_major)
+    array_member_align = packing.base_alignment(field_type, field_row_major)
+
+    element_t = array_base_type(field_type)
+
+    for i in xrange(array_elements(field_type)):
+        name_from_API_with_index = "{}[{}]".format(name_from_API, i)
+        name_from_shader_with_index = "{}[{}]".format(name_from_shader, i)
+
+        if isarray(element_t):
+            inner_aoa_size = arrays_of_arrays_size(element_t)
+            o = align(offset, array_member_align) + (astride * i * inner_aoa_size)
+
+            for x in iterate_struct_array_recursive(element_t,
+                                                    name_from_API_with_index,
+                                                    name_from_shader_with_index,
+                                                    packing,
+                                                    o,
+                                                    row_major,
+                                                    field_row_major,
+                                                    explicit_layout):
+                yield x
+
+                a = packing.base_alignment(x.GLSL_type, row_major)
+                o = align(o, a) + packing.size(x.GLSL_type, row_major)
+        else:
+            o = align(offset, array_member_align) + (astride * i)
+            yield block_member(
+                name_from_shader_with_index,
+                name_from_API_with_index,
+                element_t,
+                explicit_layout,
+                o,
+                field_row_major)
+            for x in iterate_all_recursive(struct_types[element_t],
+                                           None,
+                                           name_from_API_with_index,
+                                           name_from_shader_with_index,
+                                           packing,
+                                           o,
+                                           field_row_major):
+                yield x
+
+                a = packing.base_alignment(x.GLSL_type, row_major)
+                o = align(o, a) + packing.size(x.GLSL_type, row_major)
 
 def iterate_all_recursive(fields,
                           field_layouts,
@@ -483,7 +554,7 @@  def iterate_all_recursive(fields,
             field_row_major = row_major
 
         if isarray(field_type):
-            base_type = array_base_type(field_type)
+            base_type = without_array(field_type)
 
             if isstructure(base_type):
                 yield block_member(
@@ -494,40 +565,15 @@  def iterate_all_recursive(fields,
                     offset,
                     field_row_major)
 
-                astride = packing.array_stride(field_type, field_row_major)
-                array_member_align = packing.base_alignment(
-                    field_type,
-                    field_row_major)
-
-                for i in xrange(array_elements(field_type)):
-                    name_from_API_with_index = "{}[{}]".format(
-                        name_from_API,
-                        i)
-                    name_from_shader_with_index = "{}[{}]".format(
-                        name_from_shader,
-                        i)
-
-                    o = align(offset, array_member_align) + (astride * i)
-
-                    yield block_member(
-                        name_from_shader_with_index,
-                        name_from_API_with_index,
-                        base_type,
-                        explicit_layout,
-                        o,
-                        field_row_major)
-
-                    for x in iterate_all_recursive(struct_types[base_type],
-                                                   None,
-                                                   name_from_API_with_index,
-                                                   name_from_shader_with_index,
-                                                   packing,
-                                                   o,
-                                                   field_row_major):
-                        yield x
-
-                        a = packing.base_alignment(x.GLSL_type, row_major)
-                        o = align(o, a) + packing.size(x.GLSL_type, row_major)
+                for x in iterate_struct_array_recursive(field_type,
+                                           name_from_API,
+                                           name_from_shader,
+                                           packing,
+                                           offset,
+                                           row_major,
+                                           field_row_major,
+                                           explicit_layout):
+                    yield x
 
             elif ismatrix(base_type):
                 yield block_member(
@@ -709,19 +755,25 @@  def generate_test_vectors(fields,
         a = packing.base_alignment(m.GLSL_type, m.row_major)
 
         if isarray(m.GLSL_type):
+            size = array_elements(m.GLSL_type)
             base_type = array_base_type(m.GLSL_type)
             astride = packing.array_stride(m.GLSL_type, m.row_major)
             name = m.API_name + "[0]"
+            while(isarray(base_type)):
+                size = array_elements(base_type)
+                base_type = array_base_type(base_type)
+                name = name + "[0]"
         else:
             base_type = m.GLSL_type
             astride = 0
             name = m.API_name
+            size = m.size
 
         if ismatrix(base_type):
             test_vectors.append((
                     name,
                     m.API_type, 
-                    m.size,
+                    size,
                     align(m.offset, a),
                     astride,
                     packing.matrix_stride(base_type, m.row_major),
@@ -730,7 +782,7 @@  def generate_test_vectors(fields,
             test_vectors.append((
                     name,
                     m.API_type, 
-                    m.size,
+                    size,
                     align(m.offset, a),
                     astride,
                     0,
@@ -862,6 +914,44 @@  def bit_exact_data(raw_data, type):
     else:
         return raw_data
 
+def generate_array_data_pairs(name, api_name, element_type, row_major, offset, packing, setters, checkers):
+    base_type = array_base_type(element_type)
+
+    astride = packing.array_stride(element_type, row_major)
+
+    for i in xrange(array_elements(element_type)):
+
+        name_with_index = "{}[{}]".format(name, i)
+        api_name_with_index = "{}[{}]".format(api_name, i)
+
+        if isarray(base_type):
+            offset = offset + (i * arrays_of_arrays_size(base_type) * astride)
+            generate_array_data_pairs(name_with_index, api_name_with_index, base_type, row_major, offset, packing, setters, checkers)
+        else:
+            offset = offset + (i * astride)
+            raw_data = random_data(base_type, name_with_index, offset)
+            setters.append(
+                (fudge_type_for_setter(base_type),
+                api_name_with_index,
+                bit_exact_data(raw_data, base_type)))
+
+            data = raw_data.split(" ")
+
+            if isscalar(base_type):
+                checkers.append(scalar_derp(base_type,
+                                            name_with_index,
+                                            offset,
+                                            data[0]))
+            elif isvector(base_type):
+                checkers.extend(vector_derp(base_type,
+                                            name_with_index,
+                                            offset,
+                                            data))
+            elif ismatrix(base_type):
+                checkers.extend(matrix_derp(base_type,
+                                            name_with_index,
+                                            offset,
+                                            data))
 
 def generate_data_pairs(uniform_blocks, packing):
     """Return GLSL code to test values and shader_runner code to set them.
@@ -893,38 +983,7 @@  def generate_data_pairs(uniform_blocks, packing):
 
             if m.API_type:
                 if isarray(m.GLSL_type):
-                    base_type = array_base_type(m.GLSL_type)
-
-                    astride = packing.array_stride(m.GLSL_type, m.row_major)
-
-                    for i in xrange(array_elements(m.GLSL_type)):
-
-                        name = "{}[{}]".format(m.GLSL_name, i)
-                        offset = m.offset + (i * astride)
-
-                        raw_data = random_data(base_type, m.GLSL_name, offset)
-                        setters.append(
-                            (fudge_type_for_setter(base_type),
-                             "{}[{}]".format(m.API_name, i),
-                             bit_exact_data(raw_data, base_type)))
-
-                        data = raw_data.split(" ")
-
-                        if isscalar(base_type):
-                            checkers.append(scalar_derp(base_type,
-                                                        name,
-                                                        offset,
-                                                        data[0]))
-                        elif isvector(base_type):
-                            checkers.extend(vector_derp(base_type,
-                                                        name,
-                                                        offset,
-                                                        data))
-                        elif ismatrix(base_type):
-                            checkers.extend(matrix_derp(base_type,
-                                                        name,
-                                                        offset,
-                                                        data))
+                    generate_array_data_pairs(m.GLSL_name, m.API_name, m.GLSL_type, m.row_major, m.offset, packing, setters, checkers)
                 else:
                     raw_data = random_data(m.GLSL_type, m.GLSL_name, m.offset)
                     setters.append((fudge_type_for_setter(m.GLSL_type),
@@ -969,7 +1028,7 @@  def pretty_format_type_data(packing, type, offset, row_major):
     if isarray(type):
         astride = packing.array_stride(type, row_major)
 
-        base_type = array_base_type(type)
+        base_type = without_array(type)
         if ismatrix(base_type) and row_major:
             if row_major:
                 row_major_str = "yes"
@@ -1009,13 +1068,12 @@  def pretty_format_member(m, packing):
     # If the name ends in an array subscript, emit a special line to note that
     # the following fields are the contents of an element of an array of
     # structures.
-
     if m.GLSL_name[-1] == "]":
         n = m.struct_nesting() + 1
         indent = "//  " + ("  " * n)
 
-        return "{indent}[{index}".format(indent=indent,
-                                         index=m.GLSL_name.split("[")[-1])
+        return "{indent}{index}".format(indent=indent,
+                                         index=m.GLSL_name[m.GLSL_name.index("["):])
 
     # Strip off everything before the last period.
     name = m.GLSL_name.split(".")[-1]
@@ -1337,8 +1395,8 @@  class packing_rules(object):
         size, in bytes, of the entire data type.  This will include padded
         after the data element as required by the GLSL specification.
         """
-        if "[" in type:
-            return self.array_stride(type, row_major) * array_elements(type)
+        if isarray(type):
+            return self.array_stride(type, row_major) * arrays_of_arrays_size(type)
 
         if type in ["float", "bool", "int", "uint"]:
             return 4
@@ -1484,7 +1542,7 @@  class std140_packing_rules(packing_rules):
                 return max(16, self.base_alignment("vec{}".format(c), False))
 
     def array_stride(self, type, row_major):
-        base_type = array_base_type(type)
+        base_type = without_array(type)
 
         if not isstructure(base_type):
             # (4) If the member is an array of scalars or vectors, the base
@@ -1547,7 +1605,7 @@  class unique_name_dict:
         form.  All other type names are unmodified.
         """
         if isarray(type):
-            t = array_base_type(type)
+            t = without_array(type)
         else:
             t = type
 
@@ -1577,7 +1635,7 @@  class unique_name_dict:
         (indexed by "type") of (base_name, 1).
         """
         if isarray(type):
-            t = array_base_type(type)
+            t = without_array(type)
         else:
             t = type
 
@@ -1690,8 +1748,7 @@  class block_member(object):
         self.row_major = row_major
 
         if isarray(GLSL_type):
-            base_type = array_base_type(GLSL_type)
-
+            base_type = without_array(GLSL_type)
             if isstructure(base_type):
                 self.API_type = None
             else: