asahi: Split vertex/fragment pipeline binds

Although these are similar data structures, they are not identical and
trying to cover both in the same struct is causing problems with
aliasing. Split them out to get a more accurate representation.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17198>
This commit is contained in:
Alyssa Rosenzweig
2022-05-23 12:27:39 -04:00
parent 0fa5b05e91
commit 651e4677ca
3 changed files with 36 additions and 28 deletions
+21 -11
View File
@@ -461,11 +461,8 @@
<!--- Command to bind a vertex pipeline, followed by subcommands. Counts are
specified in 32-bit word units. Intepretation per-shader stage. -->
<struct name="Bind pipeline" size="24">
<field name="Tag" size="32" start="0:0" type="hex" default="0x4000002e">
<value name="AGX_BIND_PIPELINE_VERTEX" value="0x4000002e"/>
<value name="AGX_BIND_PIPELINE_FRAGMENT" value="0x800000"/>
</field>
<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"/>
@@ -476,15 +473,28 @@
<field name="Input count" size="8" start="1:16" type="uint" default="0"/>
<field name="Padding 1" size="8" start="1:24" type="hex" default="0x0"/>
<field name="Pipeline" size="32" start="2:0" type="address"/>
<!-- Overlaps -->
<field name="FS Varyings" size="32" start="3:0" type="address"/>
<field name="VS Output count 1" size="8" start="3:0" type="uint" default="0"/>
<field name="VS Output count 2" size="8" start="3:8" type="uint" default="0"/>
<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>
<struct name="Bind fragment pipeline" size="24">
<field name="Tag" size="32" start="0:0" type="hex" default="0x800000"/>
<!-- 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="Input count" size="8" start="1:16" type="uint" default="0"/>
<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="Varyings" size="32" start="3:0" type="address"/>
<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>
+8 -8
View File
@@ -422,14 +422,14 @@ agxdecode_record(uint64_t va, size_t size, bool verbose)
assert(size == AGX_SET_INDEX_LENGTH);
DUMP_CL(SET_INDEX, map, "Set index");
} else if (tag == 0x800000) {
assert(size == (AGX_BIND_PIPELINE_LENGTH - 4));
assert(size == (AGX_BIND_FRAGMENT_PIPELINE_LENGTH - 4));
agx_unpack(agxdecode_dump_stream, map, BIND_PIPELINE, cmd);
agx_unpack(agxdecode_dump_stream, map, BIND_FRAGMENT_PIPELINE, cmd);
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
/* TODO: parse */
if (cmd.fs_varyings) {
uint8_t *map = agxdecode_fetch_gpu_mem(cmd.fs_varyings, 128);
if (cmd.varyings) {
uint8_t *map = agxdecode_fetch_gpu_mem(cmd.varyings, 128);
hexdump(agxdecode_dump_stream, map, 128, false);
DUMP_CL(VARYING_HEADER, map, "Varying header:");
@@ -441,7 +441,7 @@ agxdecode_record(uint64_t va, size_t size, bool verbose)
}
}
DUMP_UNPACKED(BIND_PIPELINE, cmd, "Bind fragment pipeline\n");
DUMP_UNPACKED(BIND_FRAGMENT_PIPELINE, cmd, "Bind fragment pipeline\n");
} else if (size == 0) {
pipeline_base = va;
} else {
@@ -459,10 +459,10 @@ agxdecode_cmd(const uint8_t *map, bool 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_PIPELINE, cmd);
agx_unpack(agxdecode_dump_stream, map, BIND_VERTEX_PIPELINE, cmd);
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
DUMP_UNPACKED(BIND_PIPELINE, cmd, "Bind vertex pipeline\n");
return AGX_BIND_PIPELINE_LENGTH;
DUMP_UNPACKED(BIND_VERTEX_PIPELINE, cmd, "Bind vertex pipeline\n");
return AGX_BIND_VERTEX_PIPELINE_LENGTH;
} else if (map[3] == 0x61) {
DUMP_CL(DRAW, map, "Draw");
return AGX_DRAW_LENGTH;
+7 -9
View File
@@ -1359,17 +1359,16 @@ agx_build_store_pipeline(struct agx_context *ctx, uint32_t code,
static uint64_t
demo_launch_fragment(struct agx_context *ctx, struct agx_pool *pool, uint32_t pipeline, uint32_t varyings, unsigned input_count)
{
struct agx_ptr t = agx_pool_alloc_aligned(pool, AGX_BIND_PIPELINE_LENGTH, 64);
struct agx_ptr t = agx_pool_alloc_aligned(pool, AGX_BIND_FRAGMENT_PIPELINE_LENGTH, 64);
unsigned tex_count = ctx->stage[PIPE_SHADER_FRAGMENT].texture_count;
agx_pack(t.cpu, BIND_PIPELINE, cfg) {
cfg.tag = AGX_BIND_PIPELINE_FRAGMENT;
agx_pack(t.cpu, BIND_FRAGMENT_PIPELINE, cfg) {
cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8);
cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4);
cfg.more_than_4_textures = tex_count >= 4;
cfg.input_count = input_count;
cfg.pipeline = pipeline;
cfg.fs_varyings = varyings;
cfg.varyings = varyings;
};
return t.gpu;
@@ -1502,18 +1501,17 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
bool is_lines, bool is_points)
{
unsigned tex_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
agx_pack(out, BIND_PIPELINE, cfg) {
cfg.tag = AGX_BIND_PIPELINE_VERTEX;
agx_pack(out, BIND_VERTEX_PIPELINE, cfg) {
cfg.pipeline = pipeline_vertex;
cfg.vs_output_count_1 = ctx->vs->info.varyings.nr_slots;
cfg.vs_output_count_2 = ctx->vs->info.varyings.nr_slots;
cfg.output_count_1 = ctx->vs->info.varyings.nr_slots;
cfg.output_count_2 = ctx->vs->info.varyings.nr_slots;
cfg.groups_of_8_immediate_textures = DIV_ROUND_UP(tex_count, 8);
cfg.groups_of_4_samplers = DIV_ROUND_UP(tex_count, 4);
cfg.more_than_4_textures = tex_count >= 4;
}
out += AGX_BIND_PIPELINE_LENGTH;
out += AGX_BIND_VERTEX_PIPELINE_LENGTH;
struct agx_pool *pool = &ctx->batch->pool;
bool reads_tib = ctx->fs->info.reads_tib;