fd/replay+rddecompiler: Add option to clear wrbufs at start

It's useful to clear buffers at the start of sequences to view the
delta, this adds that functionality to wrbufs with a fixed clear
value of 0xDEADBEEF.

Signed-off-by: Mark Collins <mark@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28253>
This commit is contained in:
Mark Collins 2024-03-18 11:16:16 +00:00 committed by Marge Bot
parent 694ed34673
commit fc9e718a86
2 changed files with 31 additions and 4 deletions

View file

@ -50,6 +50,7 @@ struct wrbuf {
uint64_t iova;
uint64_t size;
uint64_t clear;
const char *name;
};
@ -180,10 +181,11 @@ rd_write_wrbuffer(FILE *out, struct wrbuf *wrbuf)
{
uint32_t name_len = strlen(wrbuf->name) + 1;
struct rd_section section = {.type = RD_WRBUFFER,
.size = (uint32_t)(sizeof(uint32_t) * 2) + name_len};
.size = (uint32_t)(sizeof(uint64_t) * 3) + name_len};
fwrite(&section, sizeof(section), 1, out);
fwrite(&wrbuf->iova, sizeof(uint64_t), 1, out);
fwrite(&wrbuf->size, sizeof(uint64_t), 1, out);
fwrite(&wrbuf->clear, sizeof(uint64_t), 1, out);
fwrite(wrbuf->name, sizeof(char), name_len, out);
}
@ -407,13 +409,22 @@ gpu_print(struct replay_context *ctx, struct cmdstream *_cs, uint64_t iova,
end_ib();
}
/* This function is used to read a buffer from the GPU into a file.
* The buffer can optionally be cleared to 0xdeadbeef at the start
* of the cmdstream by setting the clear parameter to true.
*
* Note: Unlike gpu_print, this function isn't sequenced, it will
* read the state of the buffer at the end of the cmdstream, not
* at the point of the call.
*/
static void
gpu_read_into_file(struct replay_context *ctx, struct cmdstream *_cs,
uint64_t iova, uint64_t size, const char *name)
uint64_t iova, uint64_t size, bool clear, const char *name)
{
struct wrbuf *wrbuf = (struct wrbuf *) calloc(1, sizeof(struct wrbuf));
wrbuf->iova = iova;
wrbuf->size = size;
wrbuf->clear = clear;
wrbuf->name = strdup(name);
assert(wrbuf->iova != 0);

View file

@ -1323,9 +1323,25 @@ override_cmdstream(struct device *dev, struct cmdstream *cs,
uint64_t *p = (uint64_t *)ps.buf;
wrbuf->iova = p[0];
wrbuf->size = p[1];
int name_len = ps.sz - (2 * sizeof(uint64_t));
bool clear = p[2];
int name_len = ps.sz - (3 * sizeof(uint64_t));
wrbuf->name = calloc(sizeof(char), name_len);
memcpy(wrbuf->name, (char*)(p + 2), name_len); // includes null terminator
memcpy(wrbuf->name, (char*)(p + 3), name_len); // includes null terminator
if (clear) {
struct buffer *buf = device_get_buffer(dev, wrbuf->iova);
assert(buf);
uint64_t offset = wrbuf->iova - buf->iova;
uint64_t end = MIN2(offset + wrbuf->size, buf->size);
while (offset < end) {
static const uint64_t clear_value = 0xdeadbeefdeadbeef;
memcpy(buf->map + offset, &clear_value,
MIN2(sizeof(clear_value), end - offset));
offset += sizeof(clear_value);
}
}
break;
}
default: