mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-21 18:40:42 +01:00
asahi: Express VDM commands according to PowerVR
Piles of unknown bits go away, as we find they're either "field present" bits or block types. And yep, the block type enum lines up between AGX and RGX. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18421>
This commit is contained in:
parent
80d8273705
commit
6f5c8d0e24
4 changed files with 246 additions and 103 deletions
|
|
@ -129,13 +129,13 @@ agx_ppp_fini(uint8_t **out, struct agx_ppp_update *ppp)
|
|||
assert(ppp->gpu_base < (1ull << 40));
|
||||
assert(size_words < (1ull << 24));
|
||||
|
||||
agx_pack(*out, RECORD, cfg) {
|
||||
agx_pack(*out, PPP_STATE, cfg) {
|
||||
cfg.pointer_hi = (ppp->gpu_base >> 32);
|
||||
cfg.pointer_lo = (uint32_t) ppp->gpu_base;
|
||||
cfg.size_words = size_words;
|
||||
};
|
||||
|
||||
*out += AGX_RECORD_LENGTH;
|
||||
*out += AGX_PPP_STATE_LENGTH;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -554,45 +554,19 @@
|
|||
<field name="Unk 7" size="16" start="6:16" type="hex" default="0x0"/> <!-- garbage? -->
|
||||
</struct>
|
||||
|
||||
<!-- VDM commands start -->
|
||||
<!-- VDM commands start. VDM commands are padded out to 8b alignment. -->
|
||||
<enum name="VDM Block Type">
|
||||
<value name="PPP State Update" value="0"/>
|
||||
<value name="VDM State Update" value="2"/>
|
||||
<value name="Index List" value="3"/>
|
||||
<value name="Stream terminate" value="6"/>
|
||||
</enum>
|
||||
|
||||
<!--- Command to bind a vertex pipeline, followed by subcommands. Counts are
|
||||
specified in 32-bit word units. Intepretation per-shader stage. -->
|
||||
<struct name="Bind vertex pipeline" size="24">
|
||||
<field name="Tag" size="32" start="0:0" type="hex" default="0x4000002e"/>
|
||||
<!-- 4 if more than 32 textures bound -->
|
||||
<field name="Unk 1" size="4" start="1:0" type="hex" default="0x2"/>
|
||||
<field name="Groups of 8 immediate textures" start="1:4" size="3" type="uint"/>
|
||||
<field name="Groups of 4 samplers" start="1:9" size="3" type="uint"/>
|
||||
<!-- When more than 48 textures bound, switches to 0x8, unk1 switches to
|
||||
0x6, and some funny sort of bindless access(?) is used in the shader -->
|
||||
<field name="Unk 2" size="4" start="1:12" type="hex" default="0x1"/>
|
||||
<field name="Padding 1" size="8" start="1:24" type="hex" default="0x0"/>
|
||||
<field name="Pipeline" size="32" start="2:0" type="address"/>
|
||||
<field name="Output count 1" size="8" start="3:0" type="uint" default="0"/>
|
||||
<field name="Output count 2" size="8" start="3:8" type="uint" default="0"/>
|
||||
<field name="Padding 2" size="16" start="3:16" type="hex" default="0x0"/>
|
||||
<field name="More than 4 textures" start="4:0" size="1" type="bool"/>
|
||||
<field name="Unk 3" size="32" start="5:0" type="address"/> <!-- C020000 -->
|
||||
</struct>
|
||||
|
||||
<!-- Subcommands are packed inside sized records -->
|
||||
<struct name="Record" size="8">
|
||||
<field name="Pointer (hi)" size="8" start="0:0" type="hex"/>
|
||||
<field name="Size (words)" size="8" start="0:8" type="uint"/>
|
||||
<field name="Tag" size="16" start="0:16" type="hex" default="0x0000"/>
|
||||
<field name="Pointer (lo)" size="32" start="0:32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<!--- Command to issue a direct non-indexed draw -->
|
||||
<struct name="Draw" size="16">
|
||||
<field name="Unk" size="8" start="0:0" type="hex" default="0x0"/>
|
||||
<field name="Primitive" size="8" start="0:8" type="Primitive"/>
|
||||
<field name="Unk 2" size="8" start="0:16" type="hex" default="0xc0"/>
|
||||
<field name="Command" size="8" start="0:24" type="hex" default="0x61"/>
|
||||
<field name="Vertex count" size="32" start="1:0" type="uint"/>
|
||||
<field name="Instance count" size="32" start="2:0" type="uint"/> <!-- must be nonzero -->
|
||||
<field name="Vertex start" size="32" start="3:0" type="uint"/>
|
||||
<struct name="PPP State" size="8">
|
||||
<field name="Pointer (hi)" size="8" start="0" type="hex"/>
|
||||
<field name="Size (words)" size="8" start="8" type="uint"/>
|
||||
<field name="Block Type" size="3" start="29" type="VDM Block Type" default="PPP State Update"/>
|
||||
<field name="Pointer (lo)" size="32" start="32" type="address"/>
|
||||
</struct>
|
||||
|
||||
<enum name="Index size">
|
||||
|
|
@ -601,21 +575,90 @@
|
|||
<value name="U32" value="2"/>
|
||||
</enum>
|
||||
|
||||
<struct name="Indexed draw" size="32">
|
||||
<field name="Unk 1" size="8" start="0:0" type="hex" default="0x1"/>
|
||||
<field name="Command" size="8" start="0:24" type="hex" default="0x40"/>
|
||||
<field name="Restart index" size="32" start="1:0" type="hex"/>
|
||||
<field name="Primitive" size="8" start="2:8" type="Primitive"/>
|
||||
<field name="Restart enable" size="1" start="2:16" type="bool"/> <!-- Metal sets this bit for strips -->
|
||||
<field name="Index size" size="3" start="2:17" type="Index size"/>
|
||||
<field name="Unk 2c" size="4" start="2:20" type="hex" default="0xF"/>
|
||||
<field name="Draw Command" size="8" start="2:24" type="hex" default="0x61"/>
|
||||
<field name="Index buffer lo" size="32" start="3:0" type="hex"/>
|
||||
<field name="Index buffer hi" size="8" start="2:0" type="hex"/>
|
||||
<field name="Index count" size="32" start="4:0" type="uint"/>
|
||||
<field name="Instance count" size="32" start="5:0" type="uint"/>
|
||||
<field name="Base vertex" size="32" start="6:0" type="uint"/>
|
||||
<field name="Index buffer size" size="32" start="7:0" type="uint" modifier="shr(2)"/>
|
||||
<struct name="VDM State" size="4">
|
||||
<field name="Restart index present" size="1" start="0" type="bool"/>
|
||||
<field name="Vertex shader word 0 present" size="1" start="1" type="bool"/>
|
||||
<field name="Vertex shader word 1 present" size="1" start="2" type="bool"/>
|
||||
<field name="Vertex outputs present" size="1" start="3" type="bool"/>
|
||||
<field name="Vertex unknown present" size="1" start="5" type="bool"/>
|
||||
<field name="Block Type" size="3" start="29" type="VDM Block Type" default="VDM State Update"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM State Restart Index" size="4">
|
||||
<field name="Value" size="32" start="0" type="hex"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM State Vertex Shader Word 0" size="4">
|
||||
<!-- 4 if more than 32 textures bound -->
|
||||
<field name="Unk 1" size="4" start="0" type="hex" default="0x2"/>
|
||||
<field name="Groups of 8 immediate textures" start="4" size="3" type="uint"/>
|
||||
<field name="Groups of 4 samplers" start="9" size="3" type="uint"/>
|
||||
<!-- When more than 48 textures bound, switches to 0x8, unk1 switches to
|
||||
0x6, and some funny sort of bindless access(?) is used in the shader -->
|
||||
<field name="Unk 2" size="4" start="12" type="hex" default="0x1"/>
|
||||
<field name="Padding 1" size="8" start="24" type="hex" default="0x0"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM State Vertex Shader Word 1" size="4">
|
||||
<field name="Pipeline" size="32" start="0" type="address"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM State Vertex Outputs" size="4">
|
||||
<field name="Output count 1" size="8" start="0" type="uint" default="0"/>
|
||||
<field name="Output count 2" size="8" start="8" type="uint" default="0"/>
|
||||
<field name="Padding 2" size="16" start="16" type="hex" default="0x0"/>
|
||||
</struct>
|
||||
|
||||
<struct name="VDM State Vertex Unknown" size="4">
|
||||
<!-- XXX Probably not? -->
|
||||
<field name="More than 4 textures" start="0" size="1" type="bool"/>
|
||||
</struct>
|
||||
|
||||
<!--- Command to issue a direct non-indexed draw -->
|
||||
<struct name="Index List" size="4">
|
||||
<field name="Index buffer hi" size="8" start="0" type="hex"/>
|
||||
<field name="Primitive" size="8" start="8" type="Primitive"/>
|
||||
<!-- Metal sets this bit for strips, probably wrong though -->
|
||||
<field name="Restart enable" size="1" start="16" type="bool"/>
|
||||
<field name="Index size" size="3" start="17" type="Index size"/>
|
||||
|
||||
<!-- XXX: Might be backwards, not sure how to check that -->
|
||||
<field name="Index buffer present" size="1" start="20" type="bool"/>
|
||||
<field name="Index buffer size present" size="1" start="21" type="bool"/>
|
||||
|
||||
<!-- XXX: Might be mixed up, not sure how to check that -->
|
||||
<field name="Index count present" size="1" start="22" type="bool" default="true"/>
|
||||
<field name="Instance count present" size="1" start="23" type="bool" default="true"/>
|
||||
<field name="Start present" size="1" start="24" type="bool" default="true"/>
|
||||
|
||||
<field name="Block Type" size="3" start="29" type="VDM Block Type" default="Index List"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Index List: Buffer lo" size="4">
|
||||
<!-- Index buffer lsb -->
|
||||
<field name="Buffer lo" size="32" start="0" type="hex"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Index List: Count" size="4">
|
||||
<!-- Vertex count for non-indexed, index count for index count -->
|
||||
<field name="Count" size="32" start="0" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Index List: Instances" size="4">
|
||||
<field name="Count" size="32" start="0" type="uint"/> <!-- must be nonzero -->
|
||||
</struct>
|
||||
|
||||
<struct name="Index List: Start" size="4">
|
||||
<!-- Base vertex for indexed draws -->
|
||||
<field name="Start" size="32" start="0" type="uint"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Index List: Buffer size" size="4">
|
||||
<field name="Size" size="32" start="0" type="uint" modifier="shr(2)"/>
|
||||
</struct>
|
||||
|
||||
<struct name="Stream Terminate" size="8">
|
||||
<field name="Block Type" size="3" start="29" type="VDM Block Type" default="Stream Terminate"/>
|
||||
</struct>
|
||||
|
||||
<!-- VDM commands end -->
|
||||
|
|
|
|||
|
|
@ -464,24 +464,19 @@ static unsigned
|
|||
agxdecode_cmd(const uint8_t *map, bool verbose)
|
||||
{
|
||||
if (map[0] == 0x02 && map[1] == 0x10 && map[2] == 0x00 && map[3] == 0x00) {
|
||||
/* XXX: This is a CDM command not a VDM one */
|
||||
agx_unpack(agxdecode_dump_stream, map, LAUNCH, cmd);
|
||||
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
|
||||
DUMP_UNPACKED(LAUNCH, cmd, "Launch\n");
|
||||
return AGX_LAUNCH_LENGTH;
|
||||
} else if (map[0] == 0x2E && map[1] == 0x00 && map[2] == 0x00 && map[3] == 0x40) {
|
||||
agx_unpack(agxdecode_dump_stream, map, BIND_VERTEX_PIPELINE, cmd);
|
||||
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
|
||||
DUMP_UNPACKED(BIND_VERTEX_PIPELINE, cmd, "Bind vertex pipeline\n");
|
||||
return AGX_BIND_VERTEX_PIPELINE_LENGTH;
|
||||
} else if (map[3] == 0x40) {
|
||||
DUMP_CL(INDEXED_DRAW, map, "Indexed Draw");
|
||||
return AGX_INDEXED_DRAW_LENGTH;
|
||||
} else if (map[3] == 0x61) {
|
||||
DUMP_CL(DRAW, map, "Draw");
|
||||
return AGX_DRAW_LENGTH;
|
||||
} else if (map[2] == 0x00 && map[3] == 0x00) {
|
||||
/* No need to explicitly dump the record */
|
||||
agx_unpack(agxdecode_dump_stream, map, RECORD, cmd);
|
||||
}
|
||||
|
||||
/* Bits 29-31 contain the block type */
|
||||
enum agx_vdm_block_type block_type = (map[3] >> 5);
|
||||
|
||||
switch (block_type) {
|
||||
case AGX_VDM_BLOCK_TYPE_PPP_STATE_UPDATE: {
|
||||
agx_unpack(agxdecode_dump_stream, map, PPP_STATE, cmd);
|
||||
|
||||
uint64_t address = (((uint64_t) cmd.pointer_hi) << 32) | cmd.pointer_lo;
|
||||
struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(address);
|
||||
|
|
@ -489,15 +484,74 @@ agxdecode_cmd(const uint8_t *map, bool verbose)
|
|||
if (mem)
|
||||
agxdecode_record(address, cmd.size_words * 4, verbose);
|
||||
else
|
||||
DUMP_UNPACKED(RECORD, cmd, "Non-existant record (XXX)\n");
|
||||
DUMP_UNPACKED(PPP_STATE, cmd, "Non-existant record (XXX)\n");
|
||||
|
||||
return AGX_RECORD_LENGTH;
|
||||
} else if (map[1] == 0 && map[2] == 0 && map[3] == 0xC0 && map[4] == 0x00) {
|
||||
ASSERTED unsigned zero[4] = { 0 };
|
||||
assert(memcmp(map + 4, zero, sizeof(zero)) == 0);
|
||||
return AGX_PPP_STATE_LENGTH;
|
||||
}
|
||||
|
||||
case AGX_VDM_BLOCK_TYPE_VDM_STATE_UPDATE: {
|
||||
size_t length = AGX_VDM_STATE_LENGTH;
|
||||
agx_unpack(agxdecode_dump_stream, map, VDM_STATE, hdr);
|
||||
map += AGX_VDM_STATE_LENGTH;
|
||||
|
||||
#define VDM_PRINT(header_name, STRUCT_NAME, human) \
|
||||
if (hdr.header_name##_present) { \
|
||||
DUMP_CL(VDM_STATE_##STRUCT_NAME, map, human); \
|
||||
map += AGX_VDM_STATE_##STRUCT_NAME##_LENGTH; \
|
||||
length += AGX_VDM_STATE_##STRUCT_NAME##_LENGTH; \
|
||||
}
|
||||
|
||||
VDM_PRINT(restart_index, RESTART_INDEX, "Restart index");
|
||||
VDM_PRINT(vertex_shader_word_0, VERTEX_SHADER_WORD_0, "Vertex shader word 0");
|
||||
|
||||
if (hdr.vertex_shader_word_1_present) {
|
||||
agx_unpack(agxdecode_dump_stream, map, VDM_STATE_VERTEX_SHADER_WORD_1,
|
||||
word_1);
|
||||
fprintf(agxdecode_dump_stream, "Pipeline %X\n", (uint32_t) word_1.pipeline);
|
||||
agxdecode_stateful(word_1.pipeline, "Pipeline", agxdecode_pipeline, verbose);
|
||||
}
|
||||
|
||||
VDM_PRINT(vertex_shader_word_1, VERTEX_SHADER_WORD_1, "Vertex shader word 1");
|
||||
VDM_PRINT(vertex_outputs, VERTEX_OUTPUTS, "Vertex outputs");
|
||||
VDM_PRINT(vertex_unknown, VERTEX_UNKNOWN, "Vertex unknown");
|
||||
|
||||
#undef VDM_PRINT
|
||||
return ALIGN_POT(length, 8);
|
||||
}
|
||||
|
||||
case AGX_VDM_BLOCK_TYPE_INDEX_LIST: {
|
||||
size_t length = AGX_INDEX_LIST_LENGTH;
|
||||
agx_unpack(agxdecode_dump_stream, map, INDEX_LIST, hdr);
|
||||
DUMP_UNPACKED(INDEX_LIST, hdr, "Index List\n");
|
||||
map += AGX_INDEX_LIST_LENGTH;
|
||||
|
||||
#define IDX_PRINT(header_name, STRUCT_NAME, human) \
|
||||
if (hdr.header_name##_present) { \
|
||||
DUMP_CL(INDEX_LIST_##STRUCT_NAME, map, human); \
|
||||
map += AGX_INDEX_LIST_##STRUCT_NAME##_LENGTH; \
|
||||
length += AGX_INDEX_LIST_##STRUCT_NAME##_LENGTH; \
|
||||
}
|
||||
|
||||
IDX_PRINT(index_buffer, BUFFER_LO, "Index buffer");
|
||||
IDX_PRINT(index_buffer_size, BUFFER_SIZE, "Index buffer size");
|
||||
IDX_PRINT(index_count, COUNT, "Index count");
|
||||
IDX_PRINT(instance_count, INSTANCES, "Instance count");
|
||||
IDX_PRINT(start, START, "Start");
|
||||
|
||||
#undef IDX_PRINT
|
||||
return ALIGN_POT(length, 8);
|
||||
}
|
||||
|
||||
case AGX_VDM_BLOCK_TYPE_STREAM_TERMINATE: {
|
||||
DUMP_CL(STREAM_TERMINATE, map, "Stream Terminate");
|
||||
return STATE_DONE;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf(agxdecode_dump_stream, "Unknown VDM block type: %u\n",
|
||||
block_type);
|
||||
hexdump(agxdecode_dump_stream, map, 8, false);
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1512,18 +1512,40 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
|
|||
#define IS_DIRTY(ST) !!(ctx->dirty & AGX_DIRTY_##ST)
|
||||
|
||||
if (IS_DIRTY(VS)) {
|
||||
unsigned tex_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
|
||||
agx_pack(out, BIND_VERTEX_PIPELINE, cfg) {
|
||||
cfg.pipeline = agx_build_pipeline(ctx, ctx->vs, PIPE_SHADER_VERTEX);
|
||||
cfg.output_count_1 = ctx->vs->info.varyings.vs.nr_index;
|
||||
cfg.output_count_2 = cfg.output_count_1;
|
||||
agx_pack(out, VDM_STATE, cfg) {
|
||||
cfg.vertex_shader_word_0_present = true;
|
||||
cfg.vertex_shader_word_1_present = true;
|
||||
cfg.vertex_outputs_present = true;
|
||||
cfg.vertex_unknown_present = true;
|
||||
}
|
||||
out += AGX_VDM_STATE_LENGTH;
|
||||
|
||||
unsigned tex_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
|
||||
agx_pack(out, VDM_STATE_VERTEX_SHADER_WORD_0, cfg) {
|
||||
cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8);
|
||||
cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4);
|
||||
}
|
||||
out += AGX_VDM_STATE_VERTEX_SHADER_WORD_0_LENGTH;
|
||||
|
||||
agx_pack(out, VDM_STATE_VERTEX_SHADER_WORD_1, cfg) {
|
||||
cfg.pipeline = agx_build_pipeline(ctx, ctx->vs, PIPE_SHADER_VERTEX);
|
||||
}
|
||||
out += AGX_VDM_STATE_VERTEX_SHADER_WORD_1_LENGTH;
|
||||
|
||||
agx_pack(out, VDM_STATE_VERTEX_OUTPUTS, cfg) {
|
||||
cfg.output_count_1 = ctx->vs->info.varyings.vs.nr_index;
|
||||
cfg.output_count_2 = cfg.output_count_1;
|
||||
}
|
||||
out += AGX_VDM_STATE_VERTEX_OUTPUTS_LENGTH;
|
||||
|
||||
agx_pack(out, VDM_STATE_VERTEX_UNKNOWN, cfg) {
|
||||
cfg.more_than_4_textures = tex_count >= 4;
|
||||
}
|
||||
out += AGX_VDM_STATE_VERTEX_UNKNOWN_LENGTH;
|
||||
|
||||
out += AGX_BIND_VERTEX_PIPELINE_LENGTH;
|
||||
/* Pad up to a multiple of 8 bytes */
|
||||
memset(out, 0, 4);
|
||||
out += 4;
|
||||
}
|
||||
|
||||
struct agx_pool *pool = &ctx->batch->pool;
|
||||
|
|
@ -1793,39 +1815,63 @@ agx_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
|
|||
|
||||
enum agx_primitive prim = agx_primitive_for_pipe(info->mode);
|
||||
unsigned idx_size = info->index_size;
|
||||
uint64_t ib = idx_size ? agx_index_buffer_ptr(batch, draws, info) : 0;
|
||||
|
||||
if (idx_size) {
|
||||
uint64_t ib = agx_index_buffer_ptr(batch, draws, info);
|
||||
|
||||
/* Index sizes are encoded logarithmically */
|
||||
STATIC_ASSERT(__builtin_ctz(1) == AGX_INDEX_SIZE_U8);
|
||||
STATIC_ASSERT(__builtin_ctz(2) == AGX_INDEX_SIZE_U16);
|
||||
STATIC_ASSERT(__builtin_ctz(4) == AGX_INDEX_SIZE_U32);
|
||||
assert((idx_size == 1) || (idx_size == 2) || (idx_size == 4));
|
||||
|
||||
agx_pack(out, INDEXED_DRAW, cfg) {
|
||||
cfg.restart_index = info->restart_index;
|
||||
cfg.primitive = prim;
|
||||
agx_pack(out, VDM_STATE, cfg) cfg.restart_index_present = true;
|
||||
out += AGX_VDM_STATE_LENGTH;
|
||||
|
||||
agx_pack(out, VDM_STATE_RESTART_INDEX, cfg) {
|
||||
cfg.value = info->restart_index;
|
||||
}
|
||||
out += AGX_VDM_STATE_RESTART_INDEX_LENGTH;
|
||||
}
|
||||
|
||||
agx_pack(out, INDEX_LIST, cfg) {
|
||||
cfg.primitive = prim;
|
||||
cfg.index_count_present = true;
|
||||
cfg.instance_count_present = true;
|
||||
cfg.start_present = true;
|
||||
|
||||
if (idx_size) {
|
||||
cfg.restart_enable = info->primitive_restart;
|
||||
cfg.index_size = __builtin_ctz(idx_size);
|
||||
cfg.index_buffer_lo = (ib & BITFIELD_MASK(32));
|
||||
cfg.index_buffer_hi = (ib >> 32);
|
||||
cfg.index_buffer_size = ALIGN_POT(draws->count * idx_size, 4);
|
||||
cfg.index_count = draws->count;
|
||||
cfg.instance_count = info->instance_count;
|
||||
cfg.base_vertex = draws->index_bias;
|
||||
};
|
||||
cfg.index_size = __builtin_ctz(idx_size);
|
||||
cfg.index_buffer_present = true;
|
||||
cfg.index_buffer_size_present = true;
|
||||
}
|
||||
}
|
||||
out += AGX_INDEX_LIST_LENGTH;
|
||||
|
||||
out += AGX_INDEXED_DRAW_LENGTH;
|
||||
} else {
|
||||
agx_pack(out, DRAW, cfg) {
|
||||
cfg.primitive = prim;
|
||||
cfg.vertex_start = draws->start;
|
||||
cfg.vertex_count = draws->count;
|
||||
cfg.instance_count = info->instance_count;
|
||||
};
|
||||
if (idx_size) {
|
||||
agx_pack(out, INDEX_LIST_BUFFER_LO, cfg) {
|
||||
cfg.buffer_lo = ib & BITFIELD_MASK(32);
|
||||
}
|
||||
out += AGX_INDEX_LIST_BUFFER_LO_LENGTH;
|
||||
}
|
||||
|
||||
out += AGX_DRAW_LENGTH;
|
||||
agx_pack(out, INDEX_LIST_COUNT, cfg) cfg.count = draws->count;
|
||||
out += AGX_INDEX_LIST_COUNT_LENGTH;
|
||||
|
||||
agx_pack(out, INDEX_LIST_INSTANCES, cfg) cfg.count = info->instance_count;
|
||||
out += AGX_INDEX_LIST_INSTANCES_LENGTH;
|
||||
|
||||
agx_pack(out, INDEX_LIST_START, cfg) {
|
||||
cfg.start = idx_size ? draws->index_bias : draws->start;
|
||||
}
|
||||
out += AGX_INDEX_LIST_START_LENGTH;
|
||||
|
||||
if (idx_size) {
|
||||
agx_pack(out, INDEX_LIST_BUFFER_SIZE, cfg) {
|
||||
cfg.size = ALIGN_POT(draws->count * idx_size, 4);
|
||||
}
|
||||
out += AGX_INDEX_LIST_BUFFER_SIZE_LENGTH;
|
||||
}
|
||||
|
||||
batch->encoder_current = out;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue