#define CS_GPR(n) (0x2600 + (n) * 8)
+/* This is only really practical on haswell and above because it requires
+ * MI math in order to get it correct.
+ */
+#if GEN_GEN >= 8 || GEN_IS_HASWELL
static void
-anv_cmd_predicated_ccs_resolve(struct anv_cmd_buffer *cmd_buffer,
- const struct anv_image *image,
- VkImageAspectFlagBits aspect,
- uint32_t level, uint32_t array_layer,
- enum isl_aux_op resolve_op,
- enum anv_fast_clear_type fast_clear_supported)
+anv_cmd_compute_resolve_predicate(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ VkImageAspectFlagBits aspect,
+ uint32_t level, uint32_t array_layer,
+ enum isl_aux_op resolve_op,
+ enum anv_fast_clear_type fast_clear_supported)
{
- const uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
struct anv_address fast_clear_type_addr =
anv_image_get_fast_clear_type_addr(cmd_buffer->device, image, aspect);
-#if GEN_GEN >= 9
/* Name some registers */
const int image_fc_reg = MI_ALU_REG0;
const int fc_imm_reg = MI_ALU_REG1;
return;
}
-#else /* GEN_GEN <= 8 */
+ /* We use the first half of src0 for the actual predicate. Set the second
+ * half of src0 and all of src1 to 0 as the predicate operation will be
+ * doing an implicit src0 != src1.
+ */
+ emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC0 + 4, 0);
+ emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC1 , 0);
+ emit_lri(&cmd_buffer->batch, MI_PREDICATE_SRC1 + 4, 0);
+
+ anv_batch_emit(&cmd_buffer->batch, GENX(MI_PREDICATE), mip) {
+ mip.LoadOperation = LOAD_LOADINV;
+ mip.CombineOperation = COMBINE_SET;
+ mip.CompareOperation = COMPARE_SRCS_EQUAL;
+ }
+}
+#endif /* GEN_GEN >= 8 || GEN_IS_HASWELL */
+
+#if GEN_GEN <= 8
+static void
+anv_cmd_simple_resolve_predicate(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ VkImageAspectFlagBits aspect,
+ uint32_t level, uint32_t array_layer,
+ enum isl_aux_op resolve_op,
+ enum anv_fast_clear_type fast_clear_supported)
+{
+ struct anv_address fast_clear_type_addr =
+ anv_image_get_fast_clear_type_addr(cmd_buffer->device, image, aspect);
+
+ /* This only works for partial resolves and only when the clear color is
+ * all or nothing. On the upside, this emits less command streamer code
+ * and works on Ivybridge and Bay Trail.
+ */
assert(resolve_op == ISL_AUX_OP_PARTIAL_RESOLVE);
assert(fast_clear_supported != ANV_FAST_CLEAR_ANY);
sdi.Address = fast_clear_type_addr;
sdi.ImmediateData = 0;
}
-#endif
/* We use the first half of src0 for the actual predicate. Set the second
* half of src0 and all of src1 to 0 as the predicate operation will be
mip.CombineOperation = COMBINE_SET;
mip.CompareOperation = COMPARE_SRCS_EQUAL;
}
+}
+#endif /* GEN_GEN <= 8 */
+
+static void
+anv_cmd_predicated_ccs_resolve(struct anv_cmd_buffer *cmd_buffer,
+ const struct anv_image *image,
+ VkImageAspectFlagBits aspect,
+ uint32_t level, uint32_t array_layer,
+ enum isl_aux_op resolve_op,
+ enum anv_fast_clear_type fast_clear_supported)
+{
+ const uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
+
+#if GEN_GEN >= 9
+ anv_cmd_compute_resolve_predicate(cmd_buffer, image,
+ aspect, level, array_layer,
+ resolve_op, fast_clear_supported);
+#else /* GEN_GEN <= 8 */
+ anv_cmd_simple_resolve_predicate(cmd_buffer, image,
+ aspect, level, array_layer,
+ resolve_op, fast_clear_supported);
+#endif
/* CCS_D only supports full resolves and BLORP will assert on us if we try
* to do a partial resolve on a CCS_D surface.