void *
anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
{
- if (batch->next + num_dwords * 4 > batch->end) {
- VkResult result = batch->extend_cb(batch, batch->user_data);
+ uint32_t size = num_dwords * 4;
+ if (batch->next + size > batch->end) {
+ VkResult result = batch->extend_cb(batch, size, batch->user_data);
if (result != VK_SUCCESS) {
anv_batch_set_error(batch, result);
return NULL;
return p;
}
+/* Ensure enough contiguous space is available */
+VkResult
+anv_batch_emit_ensure_space(struct anv_batch *batch, uint32_t size)
+{
+ if (batch->next + size > batch->end) {
+ VkResult result = batch->extend_cb(batch, size, batch->user_data);
+ if (result != VK_SUCCESS) {
+ anv_batch_set_error(batch, result);
+ return result;
+ }
+ }
+
+ assert(batch->next + size <= batch->end);
+
+ return VK_SUCCESS;
+}
+
struct anv_address
anv_batch_address(struct anv_batch *batch, void *batch_location)
{
assert(size % 4 == 0);
if (batch->next + size > batch->end) {
- VkResult result = batch->extend_cb(batch, batch->user_data);
+ VkResult result = batch->extend_cb(batch, size, batch->user_data);
if (result != VK_SUCCESS) {
anv_batch_set_error(batch, result);
return;
}
static VkResult
-anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
+anv_cmd_buffer_chain_batch(struct anv_batch *batch, uint32_t size, void *_data)
{
+ /* The caller should not need that much space. Otherwise it should split
+ * its commands.
+ */
+ assert(size <= ANV_MAX_CMD_BUFFER_BATCH_SIZE);
+
struct anv_cmd_buffer *cmd_buffer = _data;
struct anv_batch_bo *new_bbo = NULL;
+ /* Amount of reserved space at the end of the batch to account for the
+ * chaining instruction.
+ */
+ const uint32_t batch_padding = GFX8_MI_BATCH_BUFFER_START_length * 4;
/* Cap reallocation to chunk. */
- uint32_t alloc_size = MIN2(cmd_buffer->total_batch_size,
- ANV_MAX_CMD_BUFFER_BATCH_SIZE);
+ uint32_t alloc_size = MIN2(
+ MAX2(cmd_buffer->total_batch_size, size + batch_padding),
+ ANV_MAX_CMD_BUFFER_BATCH_SIZE);
VkResult result = anv_batch_bo_create(cmd_buffer, alloc_size, &new_bbo);
if (result != VK_SUCCESS)
list_addtail(&new_bbo->link, &cmd_buffer->batch_bos);
- anv_batch_bo_start(new_bbo, batch, GFX8_MI_BATCH_BUFFER_START_length * 4);
+ anv_batch_bo_start(new_bbo, batch, batch_padding);
return VK_SUCCESS;
}
/* This callback is called (with the associated user data) in the event
* that the batch runs out of space.
*/
- VkResult (*extend_cb)(struct anv_batch *, void *);
+ VkResult (*extend_cb)(struct anv_batch *, uint32_t, void *);
void * user_data;
/**
};
void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords);
+VkResult anv_batch_emit_ensure_space(struct anv_batch *batch, uint32_t size);
void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other);
struct anv_address anv_batch_address(struct anv_batch *batch, void *batch_location);