[Mesa-dev] [PATCH 2/9] radv: refactor indirect draws with radv_draw_info
Samuel Pitoiset
samuel.pitoiset at gmail.com
Tue Oct 17 09:03:33 UTC 2017
Indirect draws with a count buffer will be refactored in a
separate patch.
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
---
src/amd/vulkan/radv_cmd_buffer.c | 217 ++++++++++++++++++++++++++-------------
1 file changed, 143 insertions(+), 74 deletions(-)
diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c
index f0abafad3b..1cacdda767 100644
--- a/src/amd/vulkan/radv_cmd_buffer.c
+++ b/src/amd/vulkan/radv_cmd_buffer.c
@@ -2869,6 +2869,45 @@ radv_cs_emit_draw_indexed_packet(struct radv_cmd_buffer *cmd_buffer,
radeon_emit(cmd_buffer->cs, V_0287F0_DI_SRC_SEL_DMA);
}
+static void
+radv_cs_emit_indirect_draw_packet(struct radv_cmd_buffer *cmd_buffer,
+ bool indexed,
+ uint32_t draw_count,
+ uint64_t count_va,
+ uint32_t stride)
+{
+ struct radeon_winsys_cs *cs = cmd_buffer->cs;
+ unsigned di_src_sel = indexed ? V_0287F0_DI_SRC_SEL_DMA
+ : V_0287F0_DI_SRC_SEL_AUTO_INDEX;
+ bool draw_id_enable = cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id;
+ uint32_t base_reg = cmd_buffer->state.pipeline->graphics.vtx_base_sgpr;
+ assert(base_reg);
+
+ if (draw_count == 1 && !count_va && !draw_id_enable) {
+ radeon_emit(cs, PKT3(indexed ? PKT3_DRAW_INDEX_INDIRECT :
+ PKT3_DRAW_INDIRECT, 3, false));
+ radeon_emit(cs, 0);
+ radeon_emit(cs, (base_reg - SI_SH_REG_OFFSET) >> 2);
+ radeon_emit(cs, ((base_reg + 4) - SI_SH_REG_OFFSET) >> 2);
+ radeon_emit(cs, di_src_sel);
+ } else {
+ radeon_emit(cs, PKT3(indexed ? PKT3_DRAW_INDEX_INDIRECT_MULTI :
+ PKT3_DRAW_INDIRECT_MULTI,
+ 8, false));
+ radeon_emit(cs, 0);
+ radeon_emit(cs, (base_reg - SI_SH_REG_OFFSET) >> 2);
+ radeon_emit(cs, ((base_reg + 4) - SI_SH_REG_OFFSET) >> 2);
+ radeon_emit(cs, (((base_reg + 8) - SI_SH_REG_OFFSET) >> 2) |
+ S_2C3_DRAW_INDEX_ENABLE(draw_id_enable) |
+ S_2C3_COUNT_INDIRECT_ENABLE(!!count_va));
+ radeon_emit(cs, draw_count); /* count */
+ radeon_emit(cs, count_va); /* count_addr */
+ radeon_emit(cs, count_va >> 32);
+ radeon_emit(cs, stride); /* stride */
+ radeon_emit(cs, di_src_sel);
+ }
+}
+
struct radv_draw_info {
/**
* Number of vertices.
@@ -2899,6 +2938,13 @@ struct radv_draw_info {
* Whether it's an indexed draw.
*/
bool indexed;
+
+ /**
+ * Indirect draw parameters resource.
+ */
+ struct radv_buffer *indirect;
+ uint64_t indirect_offset;
+ uint32_t stride;
};
static void
@@ -2906,15 +2952,16 @@ radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer,
const struct radv_draw_info *info)
{
struct radv_cmd_state *state = &cmd_buffer->state;
+ struct radeon_winsys *ws = cmd_buffer->device->ws;
struct radv_device *device = cmd_buffer->device;
struct radeon_winsys_cs *cs = cmd_buffer->cs;
radv_cmd_buffer_flush_state(cmd_buffer, info->indexed,
- info->instance_count > 1, false,
- info->count);
+ info->instance_count > 1, info->indirect,
+ info->indirect ? 0 : info->count);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(device->ws, cs,
- 26 * MAX_VIEWS);
+ 31 * MAX_VIEWS);
if (info->indexed) {
if (device->physical_device->rad_info.chip_class >= GFX9) {
@@ -2924,49 +2971,93 @@ radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer,
radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0));
radeon_emit(cs, state->index_type);
}
+
+ if (info->indirect) {
+ uint64_t index_va = cmd_buffer->state.index_va;
+
+ radeon_emit(cs, PKT3(PKT3_INDEX_BASE, 1, 0));
+ radeon_emit(cs, index_va);
+ radeon_emit(cs, index_va >> 32);
+
+ radeon_emit(cs, PKT3(PKT3_INDEX_BUFFER_SIZE, 0, 0));
+ radeon_emit(cs, state->max_index_count);
+ }
}
- assert(cmd_buffer->state.pipeline->graphics.vtx_base_sgpr);
- radeon_set_sh_reg_seq(cs, state->pipeline->graphics.vtx_base_sgpr,
- state->pipeline->graphics.vtx_emit_num);
- radeon_emit(cs, info->vertex_offset);
- radeon_emit(cs, info->first_instance);
- if (state->pipeline->graphics.vtx_emit_num == 3)
- radeon_emit(cs, 0);
+ if (info->indirect) {
+ uint64_t va = radv_buffer_get_va(info->indirect->bo);
- radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
- radeon_emit(cmd_buffer->cs, info->instance_count);
+ va += info->indirect->offset + info->indirect_offset;
- if (info->indexed) {
- int index_size = state->index_type ? 4 : 2;
- uint64_t index_va;
+ ws->cs_add_buffer(cs, info->indirect->bo, 8);
- index_va = state->index_va;
- index_va += info->first_index * index_size;
+ radeon_emit(cs, PKT3(PKT3_SET_BASE, 2, 0));
+ radeon_emit(cs, 1);
+ radeon_emit(cs, va);
+ radeon_emit(cs, va >> 32);
if (!state->subpass->view_mask) {
- radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va,
- info->count);
+ radv_cs_emit_indirect_draw_packet(cmd_buffer,
+ info->indexed,
+ info->count,
+ 0 /* count_va */,
+ info->stride);
} else {
unsigned i;
for_each_bit(i, state->subpass->view_mask) {
radv_emit_view_index(cmd_buffer, i);
+ radv_cs_emit_indirect_draw_packet(cmd_buffer,
+ info->indexed,
+ info->count,
+ 0 /* count_va */,
+ info->stride);
+ }
+ }
+ } else {
+ assert(cmd_buffer->state.pipeline->graphics.vtx_base_sgpr);
+ radeon_set_sh_reg_seq(cs, state->pipeline->graphics.vtx_base_sgpr,
+ state->pipeline->graphics.vtx_emit_num);
+ radeon_emit(cs, info->vertex_offset);
+ radeon_emit(cs, info->first_instance);
+ if (state->pipeline->graphics.vtx_emit_num == 3)
+ radeon_emit(cs, 0);
+
+ radeon_emit(cmd_buffer->cs, PKT3(PKT3_NUM_INSTANCES, 0, 0));
+ radeon_emit(cmd_buffer->cs, info->instance_count);
+
+ if (info->indexed) {
+ int index_size = state->index_type ? 4 : 2;
+ uint64_t index_va;
+
+ index_va = state->index_va;
+ index_va += info->first_index * index_size;
+
+ if (!state->subpass->view_mask) {
radv_cs_emit_draw_indexed_packet(cmd_buffer,
index_va,
info->count);
+ } else {
+ unsigned i;
+ for_each_bit(i, state->subpass->view_mask) {
+ radv_emit_view_index(cmd_buffer, i);
+
+ radv_cs_emit_draw_indexed_packet(cmd_buffer,
+ index_va,
+ info->count);
+ }
}
- }
- } else {
- if (!state->subpass->view_mask) {
- radv_cs_emit_draw_packet(cmd_buffer, info->count);
} else {
- unsigned i;
- for_each_bit(i, state->subpass->view_mask) {
- radv_emit_view_index(cmd_buffer, i);
-
- radv_cs_emit_draw_packet(cmd_buffer,
- info->count);
+ if (!state->subpass->view_mask) {
+ radv_cs_emit_draw_packet(cmd_buffer, info->count);
+ } else {
+ unsigned i;
+ for_each_bit(i, state->subpass->view_mask) {
+ radv_emit_view_index(cmd_buffer, i);
+
+ radv_cs_emit_draw_packet(cmd_buffer,
+ info->count);
+ }
}
}
}
@@ -3014,45 +3105,6 @@ void radv_CmdDrawIndexed(
radv_emit_draw_packets(cmd_buffer, &info);
}
-static void
-radv_cs_emit_indirect_draw_packet(struct radv_cmd_buffer *cmd_buffer,
- bool indexed,
- uint32_t draw_count,
- uint64_t count_va,
- uint32_t stride)
-{
- struct radeon_winsys_cs *cs = cmd_buffer->cs;
- unsigned di_src_sel = indexed ? V_0287F0_DI_SRC_SEL_DMA
- : V_0287F0_DI_SRC_SEL_AUTO_INDEX;
- bool draw_id_enable = cmd_buffer->state.pipeline->shaders[MESA_SHADER_VERTEX]->info.info.vs.needs_draw_id;
- uint32_t base_reg = cmd_buffer->state.pipeline->graphics.vtx_base_sgpr;
- assert(base_reg);
-
- if (draw_count == 1 && !count_va && !draw_id_enable) {
- radeon_emit(cs, PKT3(indexed ? PKT3_DRAW_INDEX_INDIRECT :
- PKT3_DRAW_INDIRECT, 3, false));
- radeon_emit(cs, 0);
- radeon_emit(cs, (base_reg - SI_SH_REG_OFFSET) >> 2);
- radeon_emit(cs, ((base_reg + 4) - SI_SH_REG_OFFSET) >> 2);
- radeon_emit(cs, di_src_sel);
- } else {
- radeon_emit(cs, PKT3(indexed ? PKT3_DRAW_INDEX_INDIRECT_MULTI :
- PKT3_DRAW_INDIRECT_MULTI,
- 8, false));
- radeon_emit(cs, 0);
- radeon_emit(cs, (base_reg - SI_SH_REG_OFFSET) >> 2);
- radeon_emit(cs, ((base_reg + 4) - SI_SH_REG_OFFSET) >> 2);
- radeon_emit(cs, (((base_reg + 8) - SI_SH_REG_OFFSET) >> 2) |
- S_2C3_DRAW_INDEX_ENABLE(draw_id_enable) |
- S_2C3_COUNT_INDIRECT_ENABLE(!!count_va));
- radeon_emit(cs, draw_count); /* count */
- radeon_emit(cs, count_va); /* count_addr */
- radeon_emit(cs, count_va >> 32);
- radeon_emit(cs, stride); /* stride */
- radeon_emit(cs, di_src_sel);
- }
-}
-
static void
radv_emit_indirect_draw(struct radv_cmd_buffer *cmd_buffer,
VkBuffer _buffer,
@@ -3164,24 +3216,41 @@ radv_cmd_draw_indexed_indirect_count(
void radv_CmdDrawIndirect(
VkCommandBuffer commandBuffer,
- VkBuffer buffer,
+ VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
- radv_cmd_draw_indirect_count(commandBuffer, buffer, offset,
- VK_NULL_HANDLE, 0, drawCount, stride);
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
+ struct radv_draw_info info = {};
+
+ info.count = drawCount;
+ info.indirect = buffer;
+ info.indirect_offset = offset;
+ info.stride = stride;
+
+ radv_emit_draw_packets(cmd_buffer, &info);
}
void radv_CmdDrawIndexedIndirect(
VkCommandBuffer commandBuffer,
- VkBuffer buffer,
+ VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
- radv_cmd_draw_indexed_indirect_count(commandBuffer, buffer, offset,
- VK_NULL_HANDLE, 0, drawCount, stride);
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
+ struct radv_draw_info info = {};
+
+ info.indexed = true;
+ info.count = drawCount;
+ info.indirect = buffer;
+ info.indirect_offset = offset;
+ info.stride = stride;
+
+ radv_emit_draw_packets(cmd_buffer, &info);
}
void radv_CmdDrawIndirectCountAMD(
--
2.14.2
More information about the mesa-dev
mailing list