mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2024-11-27 12:14:10 +08:00
asahi: Fix BIND_PIPELINE sizing and alignment
Fix a bug in BIND_PIPELINE XML reported by Dougall, which cleans up a bit of both decoder and driver. Instead of... * 17 bytes BIND_PIPELINE (17) * An unused 8 byte record (25) * A set of N 8 byte records (25 + 8 * N) * Oops, 1 byte too many! One just disappeared (24 + 8 * N) It seems to instead be * 24 bytes BIND_PIPELINE (24) * A set of N 8 byte records (24 + 8 * N) without the sentinel record. These means the 8 byte records themselves are shuffled, with the high byte of the pointers split from the low word, but that's less gross than an off-by-one. It's still not clear what the last 8 bytes of the BIND_VERTEX_PIPELINE structure mean, or the last 4 byte of the BIND_FRAGMENT_PIPELINE structure which seems to be a bit shorter. Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13784>
This commit is contained in:
parent
3b108393a2
commit
81d22da6de
@ -398,9 +398,8 @@
|
||||
</struct>
|
||||
|
||||
<!--- Command to bind a vertex pipeline, followed by subcommands. Counts are
|
||||
specified in 32-bit word units. Intepretation per-shader stage.
|
||||
Probably actually 17 bytes. -->
|
||||
<struct name="Bind pipeline" size="16">
|
||||
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"/>
|
||||
@ -418,13 +417,16 @@
|
||||
<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="Padding 2" size="16" start="3:16" type="hex" default="0x0"/>
|
||||
|
||||
<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="Size (words)" size="8" start="0:0" type="uint"/>
|
||||
<field name="Tag" size="16" start="0:8" type="hex" default="0x0000"/>
|
||||
<field name="Data" size="40" start="0:24" type="address"/>
|
||||
<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 -->
|
||||
|
@ -354,7 +354,7 @@ agxdecode_record(uint64_t va, size_t size, bool verbose)
|
||||
assert(size == AGX_CULL_LENGTH);
|
||||
DUMP_CL(CULL, map, "Cull");
|
||||
} else if (tag == 0x800000) {
|
||||
assert(size == (AGX_BIND_PIPELINE_LENGTH + 4));
|
||||
assert(size == (AGX_BIND_PIPELINE_LENGTH - 4));
|
||||
|
||||
agx_unpack(agxdecode_dump_stream, map, BIND_PIPELINE, cmd);
|
||||
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
|
||||
@ -394,35 +394,24 @@ agxdecode_cmd(const uint8_t *map, bool verbose)
|
||||
agx_unpack(agxdecode_dump_stream, map, BIND_PIPELINE, cmd);
|
||||
agxdecode_stateful(cmd.pipeline, "Pipeline", agxdecode_pipeline, verbose);
|
||||
DUMP_UNPACKED(BIND_PIPELINE, cmd, "Bind vertex pipeline\n");
|
||||
|
||||
/* Random unaligned null byte, it's pretty awful.. */
|
||||
if (map[AGX_BIND_PIPELINE_LENGTH]) {
|
||||
fprintf(agxdecode_dump_stream, "Unk unaligned %X\n",
|
||||
map[AGX_BIND_PIPELINE_LENGTH]);
|
||||
}
|
||||
|
||||
return AGX_BIND_PIPELINE_LENGTH + 1;
|
||||
} else if (map[1] == 0xc0 && map[2] == 0x61) {
|
||||
DUMP_CL(DRAW, map - 1, "Draw");
|
||||
return AGX_BIND_PIPELINE_LENGTH;
|
||||
} else if (map[2] == 0xc0 && map[3] == 0x61) {
|
||||
DUMP_CL(DRAW, map, "Draw");
|
||||
return AGX_DRAW_LENGTH;
|
||||
} else if (map[1] == 0x00 && map[2] == 0x00) {
|
||||
} else if (map[2] == 0x00 && map[3] == 0x00) {
|
||||
/* No need to explicitly dump the record */
|
||||
agx_unpack(agxdecode_dump_stream, map, RECORD, cmd);
|
||||
|
||||
/* XXX: Why? */
|
||||
if (pipeline_base && ((cmd.data >> 32) == 0)) {
|
||||
cmd.data |= pipeline_base & 0xFF00000000ull;
|
||||
}
|
||||
|
||||
struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(cmd.data);
|
||||
uint64_t address = (((uint64_t) cmd.pointer_hi) << 32) | cmd.pointer_lo;
|
||||
struct agx_bo *mem = agxdecode_find_mapped_gpu_mem_containing(address);
|
||||
|
||||
if (mem)
|
||||
agxdecode_record(cmd.data, cmd.size_words * 4, verbose);
|
||||
agxdecode_record(address, cmd.size_words * 4, verbose);
|
||||
else
|
||||
DUMP_UNPACKED(RECORD, cmd, "Non-existant record (XXX)\n");
|
||||
|
||||
return AGX_RECORD_LENGTH;
|
||||
} else if (map[0] == 0 && map[1] == 0 && map[2] == 0xC0 && map[3] == 0x00) {
|
||||
} 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 STATE_DONE;
|
||||
|
@ -1432,9 +1432,13 @@ agx_push_record(uint8_t **out, unsigned size_words, uint64_t ptr)
|
||||
assert(ptr < (1ull << 40));
|
||||
assert(size_words < (1ull << 24));
|
||||
|
||||
uint64_t value = (size_words | (ptr << 24));
|
||||
memcpy(*out, &value, sizeof(value));
|
||||
*out += sizeof(value);
|
||||
agx_pack(*out, RECORD, cfg) {
|
||||
cfg.pointer_hi = (ptr >> 32);
|
||||
cfg.pointer_lo = (uint32_t) ptr;
|
||||
cfg.size_words = size_words;
|
||||
};
|
||||
|
||||
*out += AGX_RECORD_LENGTH;
|
||||
}
|
||||
|
||||
static uint8_t *
|
||||
@ -1451,17 +1455,11 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
|
||||
cfg.texture_count = ctx->stage[PIPE_SHADER_VERTEX].texture_count;
|
||||
}
|
||||
|
||||
/* yes, it's really 17 bytes */
|
||||
out += AGX_BIND_PIPELINE_LENGTH;
|
||||
*(out++) = 0x0;
|
||||
|
||||
struct agx_pool *pool = &ctx->batch->pool;
|
||||
struct agx_ptr zero = agx_pool_alloc_aligned(pool, 16, 256);
|
||||
memset(zero.cpu, 0, 16);
|
||||
|
||||
bool reads_tib = ctx->fs->info.reads_tib;
|
||||
|
||||
agx_push_record(&out, 0, zero.gpu);
|
||||
agx_push_record(&out, 5, demo_interpolation(ctx->fs, pool));
|
||||
agx_push_record(&out, 5, demo_launch_fragment(ctx, pool, pipeline_fragment, varyings, ctx->fs->info.varyings.nr_descs));
|
||||
agx_push_record(&out, 4, demo_linkage(ctx->vs, pool));
|
||||
@ -1480,7 +1478,7 @@ agx_encode_state(struct agx_context *ctx, uint8_t *out,
|
||||
agx_push_record(&out, 3, demo_unk12(pool));
|
||||
agx_push_record(&out, 2, agx_pool_upload(pool, ctx->rast->cull, sizeof(ctx->rast->cull)));
|
||||
|
||||
return (out - 1); // XXX: alignment fixup, or something
|
||||
return out;
|
||||
}
|
||||
|
||||
static enum agx_primitive
|
||||
|
Loading…
Reference in New Issue
Block a user