VkResult
tu_cs_add_entries(struct tu_cs *cs, struct tu_cs *target);
+/**
+ * Get the size of the command packets emitted since the last call to
+ * tu_cs_add_entry.
+ */
+static inline uint32_t
+tu_cs_get_size(const struct tu_cs *cs)
+{
+ return cs->cur - cs->start;
+}
+
+/**
+ * Return true if there is no command packet emitted since the last call to
+ * tu_cs_add_entry.
+ */
+static inline uint32_t
+tu_cs_is_empty(const struct tu_cs *cs)
+{
+ return tu_cs_get_size(cs) == 0;
+}
+
/**
* Discard all entries. This allows \a cs to be reused while keeping the
* existing BOs and command packets intact.
return (~0x6996 >> val) & 1;
}
+/**
+ * Get the size of the remaining space in the current BO.
+ */
+static inline uint32_t
+tu_cs_get_space(const struct tu_cs *cs)
+{
+ return cs->end - cs->cur;
+}
+
+static inline void
+tu_cs_reserve(struct tu_cs *cs, uint32_t reserved_size)
+{
+ if (cs->mode != TU_CS_MODE_GROW) {
+ assert(tu_cs_get_space(cs) >= reserved_size);
+ assert(cs->reserved_end == cs->end);
+ return;
+ }
+
+ if (tu_cs_get_space(cs) >= reserved_size &&
+ cs->entry_count < cs->entry_capacity) {
+ cs->reserved_end = cs->cur + reserved_size;
+ return;
+ }
+
+ VkResult result = tu_cs_reserve_space(cs, reserved_size);
+ /* TODO: set this error in tu_cs and use it */
+ assert(result == VK_SUCCESS);
+}
+
/**
* Emit a type-4 command packet header into a command stream.
*/
static inline void
tu_cs_emit_pkt4(struct tu_cs *cs, uint16_t regindx, uint16_t cnt)
{
+ tu_cs_reserve(cs, cnt + 1);
tu_cs_emit(cs, CP_TYPE4_PKT | cnt | (tu_odd_parity_bit(cnt) << 7) |
((regindx & 0x3ffff) << 8) |
((tu_odd_parity_bit(regindx) << 27)));
static inline void
tu_cs_emit_pkt7(struct tu_cs *cs, uint8_t opcode, uint16_t cnt)
{
+ tu_cs_reserve(cs, cnt + 1);
tu_cs_emit(cs, CP_TYPE7_PKT | cnt | (tu_odd_parity_bit(cnt) << 15) |
((opcode & 0x7f) << 16) |
((tu_odd_parity_bit(opcode) << 23)));
/* Helpers for bracketing a large sequence of commands of unknown size inside
* a CP_COND_REG_EXEC packet.
*/
-
-struct tu_cond_exec_state {
- uint32_t *dword_ptr;
- uint32_t max_dwords;
-};
-
-static inline VkResult
-tu_cond_exec_start(struct tu_device *dev, struct tu_cs *cs,
- struct tu_cond_exec_state *state,
- uint32_t condition, uint32_t max_dwords)
+static inline void
+tu_cond_exec_start(struct tu_cs *cs, uint32_t cond_flags)
{
- /* Reserve enough space so that both the condition packet and the actual
- * condition will fit in the same IB.
- */
- VkResult result = tu_cs_reserve_space(cs, max_dwords + 3);
- if (result != VK_SUCCESS)
- return result;
+ assert(cs->mode == TU_CS_MODE_GROW);
+ assert(!cs->cond_flags && cond_flags);
- state->max_dwords = max_dwords;
tu_cs_emit_pkt7(cs, CP_COND_REG_EXEC, 2);
- tu_cs_emit(cs, condition);
- state->dword_ptr = cs->cur;
+ tu_cs_emit(cs, cond_flags);
+
+ cs->cond_flags = cond_flags;
+ cs->cond_dwords = cs->cur;
+
/* Emit dummy DWORD field here */
tu_cs_emit(cs, CP_COND_REG_EXEC_1_DWORDS(0));
-
- return VK_SUCCESS;
}
+#define CP_COND_EXEC_0_RENDER_MODE_GMEM \
+ (CP_COND_REG_EXEC_0_MODE(RENDER_MODE) | CP_COND_REG_EXEC_0_GMEM)
+#define CP_COND_EXEC_0_RENDER_MODE_SYSMEM \
+ (CP_COND_REG_EXEC_0_MODE(RENDER_MODE) | CP_COND_REG_EXEC_0_SYSMEM)
static inline void
-tu_cond_exec_end(struct tu_cs *cs, struct tu_cond_exec_state *state)
+tu_cond_exec_end(struct tu_cs *cs)
{
+ assert(cs->cond_flags);
+
+ cs->cond_flags = 0;
/* Subtract one here to account for the DWORD field itself. */
- uint32_t actual_dwords = cs->cur - state->dword_ptr - 1;
- assert(actual_dwords <= state->max_dwords);
- *state->dword_ptr = actual_dwords;
+ *cs->cond_dwords = cs->cur - cs->cond_dwords - 1;
}
#define fd_reg_pair tu_reg_value
STATIC_ASSERT(count > 0); \
STATIC_ASSERT(count <= 16); \
\
- uint32_t *p = cs->cur; \
- *p++ = CP_TYPE4_PKT | count | \
- (tu_odd_parity_bit(count) << 7) | \
- ((regs[0].reg & 0x3ffff) << 8) | \
- ((tu_odd_parity_bit(regs[0].reg) << 27)); \
- \
+ tu_cs_emit_pkt4((cs), regs[0].reg, count); \
+ uint32_t *p = (cs)->cur; \
__ONE_REG( 0, regs); \
__ONE_REG( 1, regs); \
__ONE_REG( 2, regs); \
__ONE_REG(13, regs); \
__ONE_REG(14, regs); \
__ONE_REG(15, regs); \
- cs->cur = p; \
+ (cs)->cur = p; \
} while (0)
#endif /* TU_CS_H */