summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2019-02-22 08:50:58 -0800
committerChia-I Wu <[email protected]>2019-03-11 10:02:13 -0700
commit949ce2745d9006efab131cf3c447328143f23241 (patch)
tree72ed9993aadae0474d0d7866c52ab16ebd5bce78
parentf9b34622cd00e1738637b31b0b2a93f10c201b92 (diff)
turnip: preliminary support for tu_CmdDraw
-rw-r--r--src/freedreno/vulkan/tu_cmd_buffer.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index 913d5566787..7a7e4fd8599 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -332,6 +332,20 @@ tu6_msaa_samples(uint32_t samples)
}
}
+static enum a4xx_index_size
+tu6_index_size(VkIndexType type)
+{
+ switch (type) {
+ case VK_INDEX_TYPE_UINT16:
+ return INDEX4_SIZE_16_BIT;
+ case VK_INDEX_TYPE_UINT32:
+ return INDEX4_SIZE_32_BIT;
+ default:
+ unreachable("invalid VkIndexType");
+ return INDEX4_SIZE_8_BIT;
+ }
+}
+
static void
tu6_emit_marker(struct tu_cmd_buffer *cmd, struct tu_cs *cs)
{
@@ -2261,11 +2275,80 @@ tu6_bind_draw_states(struct tu_cmd_buffer *cmd,
}
static void
+tu6_emit_draw_direct(struct tu_cmd_buffer *cmd,
+ struct tu_cs *cs,
+ const struct tu_draw_info *draw)
+{
+
+ const enum pc_di_primtype primtype = cmd->state.pipeline->ia.primtype;
+
+ tu_cs_emit_pkt4(cs, REG_A6XX_VFD_INDEX_OFFSET, 2);
+ tu_cs_emit(cs, draw->vertex_offset);
+ tu_cs_emit(cs, draw->first_instance);
+
+ /* TODO hw binning */
+ if (draw->indexed) {
+ const enum a4xx_index_size index_size =
+ tu6_index_size(cmd->state.index_type);
+ const uint32_t index_bytes =
+ (cmd->state.index_type == VK_INDEX_TYPE_UINT32) ? 4 : 2;
+ const struct tu_buffer *buf = cmd->state.index_buffer;
+ const VkDeviceSize offset = buf->bo_offset + cmd->state.index_offset +
+ index_bytes * draw->first_index;
+ const uint32_t size = index_bytes * draw->count;
+
+ const uint32_t cp_draw_indx =
+ CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(primtype) |
+ CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(DI_SRC_SEL_DMA) |
+ CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(index_size) |
+ CP_DRAW_INDX_OFFSET_0_VIS_CULL(IGNORE_VISIBILITY) | 0x2000;
+
+ tu_cs_emit_pkt7(cs, CP_DRAW_INDX_OFFSET, 7);
+ tu_cs_emit(cs, cp_draw_indx);
+ tu_cs_emit(cs, draw->instance_count);
+ tu_cs_emit(cs, draw->count);
+ tu_cs_emit(cs, 0x0); /* XXX */
+ tu_cs_emit_qw(cs, buf->bo->iova + offset);
+ tu_cs_emit(cs, size);
+ } else {
+ const uint32_t cp_draw_indx =
+ CP_DRAW_INDX_OFFSET_0_PRIM_TYPE(primtype) |
+ CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(DI_SRC_SEL_AUTO_INDEX) |
+ CP_DRAW_INDX_OFFSET_0_VIS_CULL(IGNORE_VISIBILITY) | 0x2000;
+
+ tu_cs_emit_pkt7(cs, CP_DRAW_INDX_OFFSET, 3);
+ tu_cs_emit(cs, cp_draw_indx);
+ tu_cs_emit(cs, draw->instance_count);
+ tu_cs_emit(cs, draw->count);
+ }
+}
+
+static void
tu_draw(struct tu_cmd_buffer *cmd, const struct tu_draw_info *draw)
{
struct tu_cs *cs = &cmd->draw_cs;
tu6_bind_draw_states(cmd, cs, draw);
+
+ VkResult result = tu_cs_reserve_space(cmd->device, cs, 32);
+ if (result != VK_SUCCESS) {
+ cmd->record_result = result;
+ return;
+ }
+
+ if (draw->indirect) {
+ tu_finishme("indirect draw");
+ return;
+ }
+
+ /* TODO tu6_emit_marker should pick different regs depending on cs */
+ tu6_emit_marker(cmd, cs);
+ tu6_emit_draw_direct(cmd, cs, draw);
+ tu6_emit_marker(cmd, cs);
+
+ cmd->wait_for_idle = true;
+
+ tu_cs_sanity_check(cs);
}
void