summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_lower_io.c
diff options
context:
space:
mode:
authorTimothy Arceri <timothy.arceri@collabora.com>2016-07-19 15:40:14 +1000
committerTimothy Arceri <timothy.arceri@collabora.com>2016-07-21 09:10:53 +1000
commitcba6657d8ba57fddf72bbe3c96e8aee997a1527d (patch)
treeb0ffc5b382721d2e1509a2c3f986a70409e80546 /src/compiler/nir/nir_lower_io.c
parentad5dd39984467b29d20e03ec8bd26f6f1d2e97ad (diff)
nir: add doubles component packing support
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>
Diffstat (limited to 'src/compiler/nir/nir_lower_io.c')
-rw-r--r--src/compiler/nir/nir_lower_io.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index 4d191feb53e..bf8296f5b12 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -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];