radv: refactor indirect draws with radv_draw_info
Indirect draws with a count buffer will be refactored in a separate patch. Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
This commit is contained in:
parent
03afa95d9f
commit
75dfab24a2
|
@ -2950,6 +2950,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.
|
||||
|
@ -2980,6 +3019,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
|
||||
|
@ -2987,16 +3033,48 @@ 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->indirect) {
|
||||
uint64_t va = radv_buffer_get_va(info->indirect->bo);
|
||||
|
||||
va += info->indirect->offset + info->indirect_offset;
|
||||
|
||||
ws->cs_add_buffer(cs, info->indirect->bo, 8);
|
||||
|
||||
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_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(state->pipeline->graphics.vtx_base_sgpr);
|
||||
radeon_set_sh_reg_seq(cs, state->pipeline->graphics.vtx_base_sgpr,
|
||||
state->pipeline->graphics.vtx_emit_num);
|
||||
|
@ -3016,7 +3094,8 @@ radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer,
|
|||
index_va += info->first_index * index_size;
|
||||
|
||||
if (!state->subpass->view_mask) {
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va,
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer,
|
||||
index_va,
|
||||
info->count);
|
||||
} else {
|
||||
unsigned i;
|
||||
|
@ -3041,6 +3120,7 @@ radv_emit_draw_packets(struct radv_cmd_buffer *cmd_buffer,
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(cs->cdw <= cdw_max);
|
||||
radv_cmd_buffer_after_draw(cmd_buffer);
|
||||
|
@ -3085,45 +3165,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 = radv_get_vertex_shader(cmd_buffer->state.pipeline)->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,
|
||||
|
@ -3217,24 +3258,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(
|
||||
|
|
Loading…
Reference in New Issue