summaryrefslogtreecommitdiff
path: root/lib/mesa/src/compiler/nir
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2019-03-19 10:27:46 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2019-03-19 10:27:46 +0000
commita988de479ce31ffa1664f490948214a8c1330f0b (patch)
tree1af96f5f773113b852eafb76b3ea2ba681593835 /lib/mesa/src/compiler/nir
parentac56959ac8d064e01c0b38fd2ee6851e022aaf02 (diff)
Import Mesa 18.3.5
Diffstat (limited to 'lib/mesa/src/compiler/nir')
-rw-r--r--lib/mesa/src/compiler/nir/nir_gather_xfb_info.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/lib/mesa/src/compiler/nir/nir_gather_xfb_info.c b/lib/mesa/src/compiler/nir/nir_gather_xfb_info.c
index 7e441adc0..a5258f79a 100644
--- a/lib/mesa/src/compiler/nir/nir_gather_xfb_info.c
+++ b/lib/mesa/src/compiler/nir/nir_gather_xfb_info.c
@@ -32,7 +32,11 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
unsigned *offset,
const struct glsl_type *type)
{
- if (glsl_type_is_array(type) || glsl_type_is_matrix(type)) {
+ /* If this type contains a 64-bit value, align to 8 bytes */
+ if (glsl_type_contains_64bit(type))
+ *offset = ALIGN_POT(*offset, 8);
+
+ if (glsl_type_is_array_or_matrix(type) && !var->data.compact) {
unsigned length = glsl_get_length(type);
const struct glsl_type *child_type = glsl_get_array_element(type);
for (unsigned i = 0; i < length; i++)
@@ -57,32 +61,43 @@ add_var_xfb_outputs(nir_xfb_info *xfb,
assert(var->data.stream < NIR_MAX_XFB_STREAMS);
xfb->streams_written |= (1 << var->data.stream);
- unsigned comp_slots = glsl_get_component_slots(type);
- unsigned attrib_slots = DIV_ROUND_UP(comp_slots, 4);
- assert(attrib_slots == glsl_count_attribute_slots(type, false));
-
- /* Ensure that we don't have, for instance, a dvec2 with a location_frac
- * of 2 which would make it crass a location boundary even though it
- * fits in a single slot. However, you can have a dvec3 which crosses
- * the slot boundary with a location_frac of 2.
- */
- assert(DIV_ROUND_UP(var->data.location_frac + comp_slots, 4) == attrib_slots);
+ unsigned comp_slots;
+ if (var->data.compact) {
+ /* This only happens for clip/cull which are float arrays */
+ assert(glsl_without_array(type) == glsl_float_type());
+ assert(var->data.location == VARYING_SLOT_CLIP_DIST0 ||
+ var->data.location == VARYING_SLOT_CLIP_DIST1);
+ comp_slots = glsl_get_length(type);
+ } else {
+ comp_slots = glsl_get_component_slots(type);
+
+ unsigned attrib_slots = DIV_ROUND_UP(comp_slots, 4);
+ assert(attrib_slots == glsl_count_attribute_slots(type, false));
+
+ /* Ensure that we don't have, for instance, a dvec2 with a
+ * location_frac of 2 which would make it crass a location boundary
+ * even though it fits in a single slot. However, you can have a
+ * dvec3 which crosses the slot boundary with a location_frac of 2.
+ */
+ assert(DIV_ROUND_UP(var->data.location_frac + comp_slots, 4) ==
+ attrib_slots);
+ }
assert(var->data.location_frac + comp_slots <= 8);
uint8_t comp_mask = ((1 << comp_slots) - 1) << var->data.location_frac;
- assert(attrib_slots <= 2);
- for (unsigned s = 0; s < attrib_slots; s++) {
+ while (comp_mask) {
nir_xfb_output_info *output = &xfb->outputs[xfb->output_count++];
output->buffer = var->data.xfb_buffer;
- output->offset = *offset + s * 16;
+ output->offset = *offset;
output->location = *location;
- output->component_mask = (comp_mask >> (s * 4)) & 0xf;
+ output->component_mask = comp_mask & 0xf;
+ *offset += util_bitcount(output->component_mask) * 4;
(*location)++;
+ comp_mask >>= 4;
}
- *offset += comp_slots * 4;
}
}