mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 09:10:11 +01:00
intel/mda: Handle non-contiguous object versions in mda.tar files
Allow archives to have interleaved entries where different object versions don't appear together. This gives more flexibility to the drivers when producing the mda.tar files. Acked-by: Kenneth Graunke <kenneth@whitecape.org> Acked-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29146>
This commit is contained in:
parent
38b462e09a
commit
ceb1baf939
1 changed files with 93 additions and 38 deletions
|
|
@ -187,60 +187,115 @@ parse_mesa_archive(void *mem_ctx, const char *filename)
|
|||
tar_reader tr = {0};
|
||||
tar_reader_init_from_bytes(&tr, ma->contents.data, ma->contents.len);
|
||||
|
||||
object *cur_object = NULL;
|
||||
|
||||
tar_reader_entry entry = {0};
|
||||
|
||||
{
|
||||
if (!tar_reader_next(&tr, &entry) || entry.error) {
|
||||
fprintf(stderr, "mda: wrong archive, missing mesa.txt\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *mesa_txt = slice_to_cstr(ma, entry.name);
|
||||
if (strcmp(mesa_txt, "mesa.txt")) {
|
||||
fprintf(stderr, "mda: wrong archive, missing mesa.txt\n");
|
||||
return NULL;
|
||||
bool found_mesa_txt = false;
|
||||
while (tar_reader_next(&tr, &entry)) {
|
||||
slice fullpath;
|
||||
if (!slice_is_empty(entry.prefix)) {
|
||||
char *fullpath_str = ralloc_asprintf(ma, "%.*s/%.*s",
|
||||
SLICE_FMT(entry.prefix),
|
||||
SLICE_FMT(entry.name));
|
||||
fullpath = slice_from_cstr(fullpath_str);
|
||||
} else {
|
||||
fullpath = entry.name;
|
||||
}
|
||||
|
||||
slice mda_mesa_txt = slice_from_cstr("mda/mesa.txt");
|
||||
if (slice_equal(fullpath, mda_mesa_txt)) {
|
||||
ma->info = slice_to_cstr(ma, entry.contents);
|
||||
found_mesa_txt = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_mesa_txt) {
|
||||
fprintf(stderr, "mda: wrong archive, missing mesa.txt\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Now that we found mesa. Reset header. */
|
||||
tar_reader_init_from_bytes(&tr, ma->contents.data, ma->contents.len);
|
||||
|
||||
struct hash_table *lookup = slice_hash_table_create(ma);
|
||||
|
||||
while (tar_reader_next(&tr, &entry)) {
|
||||
slice prefix = entry.prefix;
|
||||
slice name = entry.name;
|
||||
|
||||
slice_cut_result cut = slice_cut(name, '/');
|
||||
slice version_name;
|
||||
if (cut.found) {
|
||||
name = cut.before;
|
||||
version_name = cut.after;
|
||||
slice fullpath;
|
||||
if (!slice_is_empty(entry.prefix)) {
|
||||
char *fullpath_str = ralloc_asprintf(ma, "%.*s/%.*s",
|
||||
SLICE_FMT(entry.prefix),
|
||||
SLICE_FMT(entry.name));
|
||||
fullpath = slice_from_cstr(fullpath_str);
|
||||
} else {
|
||||
version_name = slice_from_cstr("");
|
||||
fullpath = entry.name;
|
||||
}
|
||||
|
||||
assert(prefix.len > 4);
|
||||
assert(slice_starts_with(prefix, slice_from_cstr("mda/")));
|
||||
prefix = slice_strip_prefix(prefix, slice_from_cstr("mda/"));
|
||||
/* Ignore directory entries. */
|
||||
if (slice_is_empty(entry.contents))
|
||||
continue;
|
||||
|
||||
if (!cur_object || !slice_equal(prefix, cur_object->prefix) || !slice_equal(name, cur_object->name)) {
|
||||
/* Already processed this before. */
|
||||
if (slice_equal_cstr(fullpath, "mda/mesa.txt"))
|
||||
continue;
|
||||
|
||||
/* Normalize path: strip leading "mda/" if present */
|
||||
slice mda_prefix = slice_from_cstr("mda/");
|
||||
fullpath = slice_strip_prefix(fullpath, mda_prefix);
|
||||
|
||||
slice_cut_result first_cut = slice_cut(fullpath, '/');
|
||||
if (!first_cut.found)
|
||||
continue;
|
||||
|
||||
slice prefix_normalized = first_cut.before;
|
||||
slice_cut_result second_cut = slice_cut(first_cut.after, '/');
|
||||
|
||||
slice key_slice, object_name, version_name;
|
||||
|
||||
if (second_cut.found) {
|
||||
/* Normal format: "0/OBJECT-NAME/version-name". */
|
||||
object_name = second_cut.before;
|
||||
version_name = second_cut.after;
|
||||
key_slice = slice_substr_to(fullpath,
|
||||
second_cut.before.data + second_cut.before.len - fullpath.data);
|
||||
} else {
|
||||
/* Single version format: "0/SPIRV". */
|
||||
object_name = first_cut.after;
|
||||
version_name = slice_from_cstr("binary");
|
||||
key_slice = fullpath;
|
||||
}
|
||||
|
||||
struct hash_entry *hash_entry = slice_hash_table_search(lookup, key_slice);
|
||||
int obj_index = hash_entry ? (intptr_t)hash_entry->data : -1;
|
||||
object *obj;
|
||||
|
||||
if (obj_index == -1) {
|
||||
ma->objects = rerzalloc(ma, ma->objects, object, ma->objects_count, ma->objects_count + 1);
|
||||
cur_object = &ma->objects[ma->objects_count++];
|
||||
cur_object->prefix = prefix;
|
||||
cur_object->name = name;
|
||||
cur_object->ma = ma;
|
||||
cur_object->fullname = slice_from_cstr(ralloc_asprintf(ma, "%.*s/%.*s/%.*s", SLICE_FMT(ma->filename), SLICE_FMT(prefix), SLICE_FMT(name)));
|
||||
obj_index = ma->objects_count++;
|
||||
obj = &ma->objects[obj_index];
|
||||
obj->prefix = prefix_normalized;
|
||||
obj->name = object_name;
|
||||
obj->ma = ma;
|
||||
char *fullname_str = ralloc_asprintf(ma, "%.*s/%.*s/%.*s",
|
||||
SLICE_FMT(ma->filename),
|
||||
SLICE_FMT(prefix_normalized),
|
||||
SLICE_FMT(object_name));
|
||||
obj->fullname = slice_from_cstr(fullname_str);
|
||||
obj->versions = NULL;
|
||||
obj->versions_count = 0;
|
||||
|
||||
slice_hash_table_insert(lookup, key_slice, (void *)(intptr_t)obj_index);
|
||||
} else {
|
||||
obj = &ma->objects[obj_index];
|
||||
}
|
||||
|
||||
/* Add version to object (same for new or existing) */
|
||||
cur_object->versions = rerzalloc(ma, cur_object->versions, content,
|
||||
cur_object->versions_count, cur_object->versions_count + 1);
|
||||
int s = cur_object->versions_count++;
|
||||
obj->versions = rerzalloc(ma, obj->versions, content,
|
||||
obj->versions_count, obj->versions_count + 1);
|
||||
int s = obj->versions_count++;
|
||||
|
||||
cur_object->versions[s].name = version_name;
|
||||
cur_object->versions[s].data = entry.contents;
|
||||
char *version_fullname_str = ralloc_asprintf(ma, "%.*s/%.*s", SLICE_FMT(cur_object->fullname), SLICE_FMT(version_name));
|
||||
cur_object->versions[s].fullname = slice_from_cstr(version_fullname_str);
|
||||
obj->versions[s].name = version_name;
|
||||
obj->versions[s].data = entry.contents;
|
||||
char *version_fullname_str = ralloc_asprintf(ma, "%.*s/%.*s", SLICE_FMT(obj->fullname), SLICE_FMT(version_name));
|
||||
obj->versions[s].fullname = slice_from_cstr(version_fullname_str);
|
||||
}
|
||||
|
||||
return ma;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue