aboutsummaryrefslogtreecommitdiff
path: root/src/venus/vkr_cs.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/venus/vkr_cs.h')
-rw-r--r--src/venus/vkr_cs.h39
1 files changed, 30 insertions, 9 deletions
diff --git a/src/venus/vkr_cs.h b/src/venus/vkr_cs.h
index d39474ca..4e2daa6b 100644
--- a/src/venus/vkr_cs.h
+++ b/src/venus/vkr_cs.h
@@ -8,7 +8,12 @@
#include "vkr_common.h"
-#define VKR_CS_DECODER_TEMP_POOL_MAX_SIZE (64u * 1024 * 1024)
+/* This is to avoid integer overflows and to catch bogus allocations (e.g.,
+ * the guest driver encodes an uninitialized value). In practice, the largest
+ * allocations we've seen are from vkGetPipelineCacheData and are dozens of
+ * MBs.
+ */
+#define VKR_CS_DECODER_TEMP_POOL_MAX_SIZE (1u * 1024 * 1024 * 1024)
struct iovec;
@@ -16,6 +21,7 @@ struct vkr_cs_encoder {
bool *fatal_error;
struct {
+ const struct vkr_resource_attachment *attachment;
const struct iovec *iov;
int iov_count;
size_t offset;
@@ -39,6 +45,14 @@ struct vkr_cs_decoder_saved_state {
uint8_t *pool_reset_to;
};
+/*
+ * We usually need many small allocations during decoding. Those allocations
+ * are suballocated from the temp pool.
+ *
+ * After a command is decoded, vkr_cs_decoder_reset_temp_pool is called to
+ * reset pool->cur. After an entire command stream is decoded,
+ * vkr_cs_decoder_gc_temp_pool is called to garbage collect pool->buffers.
+ */
struct vkr_cs_decoder_temp_pool {
uint8_t **buffers;
uint32_t buffer_count;
@@ -52,7 +66,7 @@ struct vkr_cs_decoder_temp_pool {
};
struct vkr_cs_decoder {
- const struct util_hash_table_u64 *object_table;
+ const struct hash_table *object_table;
bool fatal_error;
struct vkr_cs_decoder_temp_pool temp_pool;
@@ -79,8 +93,7 @@ vkr_cs_encoder_set_fatal(const struct vkr_cs_encoder *enc)
void
vkr_cs_encoder_set_stream(struct vkr_cs_encoder *enc,
- const struct iovec *iov,
- int iov_count,
+ const struct vkr_resource_attachment *att,
size_t offset,
size_t size);
@@ -112,8 +125,7 @@ vkr_cs_encoder_write(struct vkr_cs_encoder *enc,
}
void
-vkr_cs_decoder_init(struct vkr_cs_decoder *dec,
- const struct util_hash_table_u64 *object_table);
+vkr_cs_decoder_init(struct vkr_cs_decoder *dec, const struct hash_table *object_table);
void
vkr_cs_decoder_fini(struct vkr_cs_decoder *dec);
@@ -161,6 +173,7 @@ vkr_cs_decoder_peek_internal(const struct vkr_cs_decoder *dec,
assert(val_size <= size);
if (unlikely(size > (size_t)(dec->end - dec->cur))) {
+ vkr_log("failed to peek %zu bytes", size);
vkr_cs_decoder_set_fatal(dec);
memset(val, 0, val_size);
return false;
@@ -197,9 +210,16 @@ vkr_cs_decoder_lookup_object(const struct vkr_cs_decoder *dec,
if (!id)
return NULL;
- obj = util_hash_table_get_u64((struct util_hash_table_u64 *)dec->object_table, id);
- if (!obj || obj->type != type)
+ const struct hash_entry *entry =
+ _mesa_hash_table_search((struct hash_table *)dec->object_table, &id);
+ obj = likely(entry) ? entry->data : NULL;
+ if (unlikely(!obj || obj->type != type)) {
+ if (obj)
+ vkr_log("object %" PRIu64 " has type %d, not %d", id, obj->type, type);
+ else
+ vkr_log("failed to look up object %" PRIu64, id);
vkr_cs_decoder_set_fatal(dec);
+ }
return obj;
}
@@ -221,6 +241,7 @@ vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size)
if (unlikely(size > (size_t)(pool->end - pool->cur))) {
if (!vkr_cs_decoder_alloc_temp_internal(dec, size)) {
+ vkr_log("failed to suballocate %zu bytes from the temp pool", size);
vkr_cs_decoder_set_fatal(dec);
return NULL;
}
@@ -229,7 +250,7 @@ vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size)
/* align to 64-bit after we know size is at most
* VKR_CS_DECODER_TEMP_POOL_MAX_SIZE and cannot overflow
*/
- size = (size + 7) & ~7;
+ size = align64(size, 8);
assert(size <= (size_t)(pool->end - pool->cur));
void *ptr = pool->cur;