summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/vc4/vc4_cl.h
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2016-10-26 12:46:58 -0700
committerEric Anholt <[email protected]>2017-06-30 12:25:45 -0700
commit4cef255872e8467aabce52938038a9d2bf27d9b2 (patch)
tree967db9b8853e6a5fb2b9609aafea981cc1b3cffc /src/gallium/drivers/vc4/vc4_cl.h
parent7f80a9ff1312406dcffae88bf6dcaaf99ca9e3a1 (diff)
vc4: Start using the pack header.
This slightly inflates the size of the generated code, in exchange for getting us some convenient tools. before: 4389 0 0 4389 1125 src/gallium/drivers/vc4/.libs/vc4_draw.o 808 0 0 808 328 src/gallium/drivers/vc4/.libs/vc4_emit.o after: 4449 0 0 4449 1161 src/gallium/drivers/vc4/.libs/vc4_draw.o 988 0 0 988 3dc src/gallium/drivers/vc4/.libs/vc4_emit.o
Diffstat (limited to 'src/gallium/drivers/vc4/vc4_cl.h')
-rw-r--r--src/gallium/drivers/vc4/vc4_cl.h63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_cl.h b/src/gallium/drivers/vc4/vc4_cl.h
index 74bf8cfcaaa..bec177cd03b 100644
--- a/src/gallium/drivers/vc4/vc4_cl.h
+++ b/src/gallium/drivers/vc4/vc4_cl.h
@@ -40,6 +40,27 @@ struct vc4_job;
*/
struct vc4_cl_out;
+/** A reference to a BO used in the CL packing functions */
+struct vc4_cl_reloc {
+ struct vc4_bo *bo;
+ uint32_t offset;
+};
+
+/* We don't call anything that packs a reloc yet, so don't implement it. */
+static inline void cl_pack_emit_reloc(void *cl, const struct vc4_cl_reloc *reloc)
+{
+ abort();
+}
+
+/* We don't use the data arg yet */
+#define __gen_user_data void
+#define __gen_address_type struct vc4_cl_reloc
+#define __gen_address_offset(reloc) ((reloc)->offset)
+#define __gen_emit_reloc cl_pack_emit_reloc
+
+#include "kernel/vc4_packet.h"
+#include "broadcom/cle/v3d_packet_v21_pack.h"
+
struct vc4_cl {
void *base;
struct vc4_cl_out *next;
@@ -205,4 +226,46 @@ cl_aligned_reloc(struct vc4_job *job, struct vc4_cl *cl,
void cl_ensure_space(struct vc4_cl *cl, uint32_t size);
+#define cl_packet_header(packet) V3D21_ ## packet ## _header
+#define cl_packet_length(packet) V3D21_ ## packet ## _length
+#define cl_packet_pack(packet) V3D21_ ## packet ## _pack
+#define cl_packet_struct(packet) V3D21_ ## packet
+
+static inline void *
+cl_get_emit_space(struct vc4_cl_out **cl, size_t size)
+{
+ void *addr = *cl;
+ cl_advance(cl, size);
+ return addr;
+}
+
+/* Macro for setting up an emit of a CL struct. A temporary unpacked struct
+ * is created, which you get to set fields in of the form:
+ *
+ * cl_emit(bcl, FLAT_SHADE_FLAGS, flags) {
+ * .flags.flat_shade_flags = 1 << 2,
+ * }
+ *
+ * or default values only can be emitted with just:
+ *
+ * cl_emit(bcl, FLAT_SHADE_FLAGS, flags);
+ *
+ * The trick here is that we make a for loop that will execute the body
+ * (either the block or the ';' after the macro invocation) exactly once.
+ * Also, *dst is actually of the wrong type, it's the
+ * uint8_t[cl_packet_length()] in the CL, not a cl_packet_struct(packet).
+ */
+#define cl_emit(cl_out, packet, name) \
+ for (struct cl_packet_struct(packet) name = { \
+ cl_packet_header(packet) \
+ }, \
+ *_dst = cl_get_emit_space(cl_out, cl_packet_length(packet)); \
+ __builtin_expect(_dst != NULL, 1); \
+ ({ \
+ cl_packet_pack(packet)(NULL, (uint8_t *)_dst, &name); \
+ VG(VALGRIND_CHECK_MEM_IS_DEFINED(_dst, \
+ cl_packet_length(packet))); \
+ _dst = NULL; \
+ })) \
+
#endif /* VC4_CL_H */