nir: add doubles component packing support
authorTimothy Arceri <timothy.arceri@collabora.com>
Tue, 19 Jul 2016 05:40:14 +0000 (15:40 +1000)
committerTimothy Arceri <timothy.arceri@collabora.com>
Wed, 20 Jul 2016 23:10:53 +0000 (09:10 +1000)
This makes sure we give the correct driver location
for doubles when using component packing. Specifically
it handles packing a dvec3 with a double which is the
only packing scenario allowed which spans across two
locations.

Acked-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Alejandro PiƱeiro <apinheiro@igalia.com>
src/compiler/nir/nir_lower_io.c

index 4d191feb53ed6f3246918e07eb513e0aed416d2f..bf8296f5b12b553f7cd7a5769449b09b4efcbc1a 100644 (file)
@@ -74,6 +74,26 @@ nir_assign_var_locations(struct exec_list *var_list, unsigned *size,
          if (locations[idx][var->data.index] == -1) {
             var->data.driver_location = location;
             locations[idx][var->data.index] = location;
+
+            /* A dvec3 can be packed with a double we need special handling
+             * for this as we are packing across two locations.
+             */
+            if (glsl_get_base_type(var->type) == GLSL_TYPE_DOUBLE &&
+                glsl_get_vector_elements(var->type) == 3) {
+               /* Hack around type_size functions that expect vectors to be
+                * padded out to vec4. If a float type is the same size as a
+                * double then the type size is padded to vec4, otherwise
+                * set the offset to two doubles which offsets the location
+                * past the first two components in dvec3 which were stored at
+                * the previous location.
+                */
+               unsigned dsize = type_size(glsl_double_type());
+               unsigned offset =
+                  dsize == type_size(glsl_float_type()) ? dsize : dsize * 2;
+
+               locations[idx + 1][var->data.index] = location + offset;
+            }
+
             location += type_size(var->type);
          } else {
             var->data.driver_location = locations[idx][var->data.index];