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.h278
1 files changed, 278 insertions, 0 deletions
diff --git a/src/venus/vkr_cs.h b/src/venus/vkr_cs.h
new file mode 100644
index 00000000..d39474ca
--- /dev/null
+++ b/src/venus/vkr_cs.h
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2021 Google LLC
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef VKR_CS_H
+#define VKR_CS_H
+
+#include "vkr_common.h"
+
+#define VKR_CS_DECODER_TEMP_POOL_MAX_SIZE (64u * 1024 * 1024)
+
+struct iovec;
+
+struct vkr_cs_encoder {
+ bool *fatal_error;
+
+ struct {
+ const struct iovec *iov;
+ int iov_count;
+ size_t offset;
+ size_t size;
+
+ int cached_index;
+ size_t cached_offset;
+ } stream;
+
+ size_t remaining_size;
+ int next_iov;
+ uint8_t *cur;
+ const uint8_t *end;
+};
+
+struct vkr_cs_decoder_saved_state {
+ const uint8_t *cur;
+ const uint8_t *end;
+
+ uint32_t pool_buffer_count;
+ uint8_t *pool_reset_to;
+};
+
+struct vkr_cs_decoder_temp_pool {
+ uint8_t **buffers;
+ uint32_t buffer_count;
+ uint32_t buffer_max;
+ size_t total_size;
+
+ uint8_t *reset_to;
+
+ uint8_t *cur;
+ const uint8_t *end;
+};
+
+struct vkr_cs_decoder {
+ const struct util_hash_table_u64 *object_table;
+
+ bool fatal_error;
+ struct vkr_cs_decoder_temp_pool temp_pool;
+
+ struct vkr_cs_decoder_saved_state saved_states[1];
+ uint32_t saved_state_count;
+
+ const uint8_t *cur;
+ const uint8_t *end;
+};
+
+static inline void
+vkr_cs_encoder_init(struct vkr_cs_encoder *enc, bool *fatal_error)
+{
+ memset(enc, 0, sizeof(*enc));
+ enc->fatal_error = fatal_error;
+}
+
+static inline void
+vkr_cs_encoder_set_fatal(const struct vkr_cs_encoder *enc)
+{
+ *enc->fatal_error = true;
+}
+
+void
+vkr_cs_encoder_set_stream(struct vkr_cs_encoder *enc,
+ const struct iovec *iov,
+ int iov_count,
+ size_t offset,
+ size_t size);
+
+void
+vkr_cs_encoder_seek_stream(struct vkr_cs_encoder *enc, size_t pos);
+
+void
+vkr_cs_encoder_write_internal(struct vkr_cs_encoder *enc,
+ size_t size,
+ const void *val,
+ size_t val_size);
+
+static inline void
+vkr_cs_encoder_write(struct vkr_cs_encoder *enc,
+ size_t size,
+ const void *val,
+ size_t val_size)
+{
+ assert(val_size <= size);
+
+ if (unlikely(size > (size_t)(enc->end - enc->cur))) {
+ vkr_cs_encoder_write_internal(enc, size, val, val_size);
+ return;
+ }
+
+ /* we should not rely on the compiler to optimize away memcpy... */
+ memcpy(enc->cur, val, val_size);
+ enc->cur += size;
+}
+
+void
+vkr_cs_decoder_init(struct vkr_cs_decoder *dec,
+ const struct util_hash_table_u64 *object_table);
+
+void
+vkr_cs_decoder_fini(struct vkr_cs_decoder *dec);
+
+void
+vkr_cs_decoder_reset(struct vkr_cs_decoder *dec);
+
+static inline void
+vkr_cs_decoder_set_fatal(const struct vkr_cs_decoder *dec)
+{
+ ((struct vkr_cs_decoder *)dec)->fatal_error = true;
+}
+
+static inline bool
+vkr_cs_decoder_get_fatal(const struct vkr_cs_decoder *dec)
+{
+ return dec->fatal_error;
+}
+
+static inline void
+vkr_cs_decoder_set_stream(struct vkr_cs_decoder *dec, const void *data, size_t size)
+{
+ dec->cur = data;
+ dec->end = dec->cur + size;
+}
+
+static inline bool
+vkr_cs_decoder_has_command(const struct vkr_cs_decoder *dec)
+{
+ return dec->cur < dec->end;
+}
+
+bool
+vkr_cs_decoder_push_state(struct vkr_cs_decoder *dec);
+
+void
+vkr_cs_decoder_pop_state(struct vkr_cs_decoder *dec);
+
+static inline bool
+vkr_cs_decoder_peek_internal(const struct vkr_cs_decoder *dec,
+ size_t size,
+ void *val,
+ size_t val_size)
+{
+ assert(val_size <= size);
+
+ if (unlikely(size > (size_t)(dec->end - dec->cur))) {
+ vkr_cs_decoder_set_fatal(dec);
+ memset(val, 0, val_size);
+ return false;
+ }
+
+ /* we should not rely on the compiler to optimize away memcpy... */
+ memcpy(val, dec->cur, val_size);
+ return true;
+}
+
+static inline void
+vkr_cs_decoder_read(struct vkr_cs_decoder *dec, size_t size, void *val, size_t val_size)
+{
+ if (vkr_cs_decoder_peek_internal(dec, size, val, val_size))
+ dec->cur += size;
+}
+
+static inline void
+vkr_cs_decoder_peek(const struct vkr_cs_decoder *dec,
+ size_t size,
+ void *val,
+ size_t val_size)
+{
+ vkr_cs_decoder_peek_internal(dec, size, val, val_size);
+}
+
+static inline struct vkr_object *
+vkr_cs_decoder_lookup_object(const struct vkr_cs_decoder *dec,
+ vkr_object_id id,
+ VkObjectType type)
+{
+ struct vkr_object *obj;
+
+ if (!id)
+ return NULL;
+
+ obj = util_hash_table_get_u64((struct util_hash_table_u64 *)dec->object_table, id);
+ if (!obj || obj->type != type)
+ vkr_cs_decoder_set_fatal(dec);
+
+ return obj;
+}
+
+static inline void
+vkr_cs_decoder_reset_temp_pool(struct vkr_cs_decoder *dec)
+{
+ struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool;
+ pool->cur = pool->reset_to;
+}
+
+bool
+vkr_cs_decoder_alloc_temp_internal(struct vkr_cs_decoder *dec, size_t size);
+
+static inline void *
+vkr_cs_decoder_alloc_temp(struct vkr_cs_decoder *dec, size_t size)
+{
+ struct vkr_cs_decoder_temp_pool *pool = &dec->temp_pool;
+
+ if (unlikely(size > (size_t)(pool->end - pool->cur))) {
+ if (!vkr_cs_decoder_alloc_temp_internal(dec, size)) {
+ vkr_cs_decoder_set_fatal(dec);
+ return NULL;
+ }
+ }
+
+ /* 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;
+ assert(size <= (size_t)(pool->end - pool->cur));
+
+ void *ptr = pool->cur;
+ pool->cur += size;
+ return ptr;
+}
+
+static inline bool
+vkr_cs_handle_indirect_id(VkObjectType type)
+{
+ /* Dispatchable handles may or may not have enough bits to store
+ * vkr_object_id. Non-dispatchable handles always have enough bits to
+ * store vkr_object_id.
+ *
+ * This should compile to a constant after inlining.
+ */
+ switch (type) {
+ case VK_OBJECT_TYPE_INSTANCE:
+ case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
+ case VK_OBJECT_TYPE_DEVICE:
+ case VK_OBJECT_TYPE_QUEUE:
+ case VK_OBJECT_TYPE_COMMAND_BUFFER:
+ return sizeof(VkInstance) < sizeof(vkr_object_id);
+ default:
+ return false;
+ }
+}
+
+static inline vkr_object_id
+vkr_cs_handle_load_id(const void **handle, VkObjectType type)
+{
+ const vkr_object_id *p = vkr_cs_handle_indirect_id(type)
+ ? *(const vkr_object_id **)handle
+ : (const vkr_object_id *)handle;
+ return *p;
+}
+
+static inline void
+vkr_cs_handle_store_id(void **handle, vkr_object_id id, VkObjectType type)
+{
+ vkr_object_id *p = vkr_cs_handle_indirect_id(type) ? *(vkr_object_id **)handle
+ : (vkr_object_id *)handle;
+ *p = id;
+}
+
+#endif /* VKR_CS_H */