}
assert(total_push_regs <= 64);
- /* The Skylake PRM contains the following restriction:
- *
- * "The driver must ensure The following case does not occur
- * without a flush to the 3D engine: 3DSTATE_CONSTANT_* with
- * buffer 3 read length equal to zero committed followed by a
- * 3DSTATE_CONSTANT_* with buffer 0 read length not equal to
- * zero committed."
- *
- * To avoid this, we program the buffers in the highest slots.
- * This way, slot 0 is only used if slot 3 is also used.
- */
- int n = 3;
+ int n = 0;
- for (int i = 3; i >= 0; i--) {
+ if (push_constant_range.length > 0)
+ map->push_ranges[n++] = push_constant_range;
+
+ for (int i = 0; i < 4; i++) {
const struct brw_ubo_range *ubo_range = &prog_data->ubo_ranges[i];
if (ubo_range->length == 0)
continue;
const struct anv_pipeline_binding *binding =
&map->surface_to_descriptor[ubo_range->block];
- map->push_ranges[n--] = (struct anv_push_range) {
+ map->push_ranges[n++] = (struct anv_push_range) {
.set = binding->set,
.index = binding->index,
.dynamic_offset_index = binding->dynamic_offset_index,
.length = ubo_range->length,
};
}
-
- if (push_constant_range.length > 0)
- map->push_ranges[n--] = push_constant_range;
} else {
/* For Ivy Bridge, the push constants packets have a different
* rule that would require us to iterate in the other direction
&pipeline->shaders[stage]->bind_map;
#if GEN_GEN >= 8 || GEN_IS_HASWELL
+ unsigned buffer_count = 0;
for (unsigned i = 0; i < 4; i++) {
const struct anv_push_range *range = &bind_map->push_ranges[i];
- if (range->length == 0)
- continue;
+ if (range->length > 0)
+ buffer_count++;
+ }
+
+ /* The Skylake PRM contains the following restriction:
+ *
+ * "The driver must ensure The following case does not occur
+ * without a flush to the 3D engine: 3DSTATE_CONSTANT_* with
+ * buffer 3 read length equal to zero committed followed by a
+ * 3DSTATE_CONSTANT_* with buffer 0 read length not equal to
+ * zero committed."
+ *
+ * To avoid this, we program the buffers in the highest slots.
+ * This way, slot 0 is only used if slot 3 is also used.
+ */
+ assert(buffer_count <= 4);
+ const unsigned shift = 4 - buffer_count;
+ for (unsigned i = 0; i < buffer_count; i++) {
+ const struct anv_push_range *range = &bind_map->push_ranges[i];
+
+ /* At this point we only have non-empty ranges */
+ assert(range->length > 0);
struct anv_address addr;
switch (range->set) {
}
}
- c.ConstantBody.ReadLength[i] = range->length;
- c.ConstantBody.Buffer[i] =
+ c.ConstantBody.ReadLength[i + shift] = range->length;
+ c.ConstantBody.Buffer[i + shift] =
anv_address_add(addr, range->start * 32);
}
#else