vulkan/wsi: Use the interface from the real modifiers extension
[mesa.git] / src / freedreno / vulkan / tu_cs.h
index 43835d147f640d1e054f21bd89a06fa04863a6cd..e5c47d005bead3e102e8cc61bc1528aedd273ece 100644 (file)
 #include "registers/adreno_pm4.xml.h"
 
 void
-tu_cs_init(struct tu_cs *cs, uint32_t initial_size);
+tu_cs_init(struct tu_cs *cs, enum tu_cs_mode mode, uint32_t initial_size);
+
+void
+tu_cs_init_external(struct tu_cs *cs, uint32_t *start, uint32_t *end);
 
 void
 tu_cs_finish(struct tu_device *dev, struct tu_cs *cs);
@@ -39,6 +42,22 @@ tu_cs_begin(struct tu_cs *cs);
 void
 tu_cs_end(struct tu_cs *cs);
 
+VkResult
+tu_cs_begin_sub_stream(struct tu_device *dev,
+                       struct tu_cs *cs,
+                       uint32_t size,
+                       struct tu_cs *sub_cs);
+
+VkResult
+tu_cs_alloc(struct tu_device *dev,
+            struct tu_cs *cs,
+            uint32_t count,
+            uint32_t size,
+            struct ts_cs_memory *memory);
+
+struct tu_cs_entry
+tu_cs_end_sub_stream(struct tu_cs *cs, struct tu_cs *sub_cs);
+
 VkResult
 tu_cs_reserve_space(struct tu_device *dev,
                     struct tu_cs *cs,
@@ -47,13 +66,40 @@ tu_cs_reserve_space(struct tu_device *dev,
 void
 tu_cs_reset(struct tu_device *dev, struct tu_cs *cs);
 
+VkResult
+tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target);
+
+/**
+ * Discard all entries.  This allows \a cs to be reused while keeping the
+ * existing BOs and command packets intact.
+ */
+static inline void
+tu_cs_discard_entries(struct tu_cs *cs)
+{
+   assert(cs->mode == TU_CS_MODE_GROW);
+   cs->entry_count = 0;
+}
+
+/**
+ * Get the size needed for tu_cs_emit_call.
+ */
+static inline uint32_t
+tu_cs_get_call_size(const struct tu_cs *cs)
+{
+   assert(cs->mode == TU_CS_MODE_GROW);
+   /* each CP_INDIRECT_BUFFER needs 4 dwords */
+   return cs->entry_count * 4;
+}
+
 /**
  * Assert that we did not exceed the reserved space.
  */
 static inline void
-tu_cs_reserve_space_assert(struct tu_cs *cs)
+tu_cs_sanity_check(const struct tu_cs *cs)
 {
+   assert(cs->start <= cs->cur);
    assert(cs->cur <= cs->reserved_end);
+   assert(cs->reserved_end <= cs->end);
 }
 
 /**
@@ -62,11 +108,22 @@ tu_cs_reserve_space_assert(struct tu_cs *cs)
 static inline void
 tu_cs_emit(struct tu_cs *cs, uint32_t value)
 {
-   assert(cs->cur < cs->end);
+   assert(cs->cur < cs->reserved_end);
    *cs->cur = value;
    ++cs->cur;
 }
 
+/**
+ * Emit an array of uint32_t into a command stream, without boundary checking.
+ */
+static inline void
+tu_cs_emit_array(struct tu_cs *cs, const uint32_t *values, uint32_t length)
+{
+   assert(cs->cur + length <= cs->reserved_end);
+   memcpy(cs->cur, values, sizeof(uint32_t) * length);
+   cs->cur += length;
+}
+
 static inline unsigned
 tu_odd_parity_bit(unsigned val)
 {
@@ -122,16 +179,32 @@ tu_cs_emit_write_reg(struct tu_cs *cs, uint16_t reg, uint32_t value)
    tu_cs_emit(cs, value);
 }
 
+/**
+ * Emit a CP_INDIRECT_BUFFER command packet.
+ */
 static inline void
-tu_cs_emit_ib(struct tu_cs *cs, const struct tu_cs *target)
+tu_cs_emit_ib(struct tu_cs *cs, const struct tu_cs_entry *entry)
 {
-   for (uint32_t i = 0; i < target->entry_count; i++) {
-      const struct tu_cs_entry *entry = target->entries + i;
+   assert(entry->bo);
+   assert(entry->size && entry->offset + entry->size <= entry->bo->size);
+   assert(entry->size % sizeof(uint32_t) == 0);
+   assert(entry->offset % sizeof(uint32_t) == 0);
+
+   tu_cs_emit_pkt7(cs, CP_INDIRECT_BUFFER, 3);
+   tu_cs_emit_qw(cs, entry->bo->iova + entry->offset);
+   tu_cs_emit(cs, entry->size / sizeof(uint32_t));
+}
 
-      tu_cs_emit_pkt7(cs, CP_INDIRECT_BUFFER, 3);
-      tu_cs_emit_qw(cs, entry->bo->iova + entry->offset);
-      tu_cs_emit(cs, entry->size / sizeof(uint32_t));
-   }
+/**
+ * Emit a CP_INDIRECT_BUFFER command packet for each entry in the target
+ * command stream.
+ */
+static inline void
+tu_cs_emit_call(struct tu_cs *cs, const struct tu_cs *target)
+{
+   assert(target->mode == TU_CS_MODE_GROW);
+   for (uint32_t i = 0; i < target->entry_count; i++)
+      tu_cs_emit_ib(cs, target->entries + i);
 }
 
 #endif /* TU_CS_H */