sctx->shader_pointers_dirty &= ~compute_mask;
}
+/* BINDLESS */
+
+struct si_bindless_descriptor_slab
+{
+ struct pb_slab base;
+ struct r600_resource *buffer;
+ struct si_bindless_descriptor *entries;
+};
+
+bool si_bindless_descriptor_can_reclaim_slab(void *priv,
+ struct pb_slab_entry *entry)
+{
+ /* Do not allow to reclaim any bindless descriptors for now because the
+ * GPU might be using them. This should be improved later on.
+ */
+ return false;
+}
+
+struct pb_slab *si_bindless_descriptor_slab_alloc(void *priv, unsigned heap,
+ unsigned entry_size,
+ unsigned group_index)
+{
+ struct si_context *sctx = priv;
+ struct si_screen *sscreen = sctx->screen;
+ struct si_bindless_descriptor_slab *slab;
+
+ slab = CALLOC_STRUCT(si_bindless_descriptor_slab);
+ if (!slab)
+ return NULL;
+
+ /* Create a buffer in VRAM for 1024 bindless descriptors. */
+ slab->buffer = (struct r600_resource *)
+ pipe_buffer_create(&sscreen->b.b, 0,
+ PIPE_USAGE_DEFAULT, 64 * 1024);
+ if (!slab->buffer)
+ goto fail;
+
+ slab->base.num_entries = slab->buffer->bo_size / entry_size;
+ slab->base.num_free = slab->base.num_entries;
+ slab->entries = CALLOC(slab->base.num_entries, sizeof(*slab->entries));
+ if (!slab->entries)
+ goto fail_buffer;
+
+ LIST_INITHEAD(&slab->base.free);
+
+ for (unsigned i = 0; i < slab->base.num_entries; ++i) {
+ struct si_bindless_descriptor *desc = &slab->entries[i];
+
+ desc->entry.slab = &slab->base;
+ desc->entry.group_index = group_index;
+ desc->buffer = slab->buffer;
+ desc->offset = i * entry_size;
+
+ LIST_ADDTAIL(&desc->entry.head, &slab->base.free);
+ }
+
+ /* Add the descriptor to the per-context list. */
+ util_dynarray_append(&sctx->bindless_descriptors,
+ struct r600_resource *, slab->buffer);
+
+ return &slab->base;
+
+fail_buffer:
+ r600_resource_reference(&slab->buffer, NULL);
+fail:
+ FREE(slab);
+ return NULL;
+}
+
+void si_bindless_descriptor_slab_free(void *priv, struct pb_slab *pslab)
+{
+ struct si_context *sctx = priv;
+ struct si_bindless_descriptor_slab *slab =
+ (struct si_bindless_descriptor_slab *)pslab;
+
+ /* Remove the descriptor from the per-context list. */
+ util_dynarray_delete_unordered(&sctx->bindless_descriptors,
+ struct r600_resource *, slab->buffer);
+
+ r600_resource_reference(&slab->buffer, NULL);
+ FREE(slab->entries);
+ FREE(slab);
+}
+
/* INIT/DEINIT/UPLOAD */
/* GFX9 has only 4KB of CE, while previous chips had 32KB. In order
r600_resource_reference(&sctx->last_trace_buf, NULL);
radeon_clear_saved_cs(&sctx->last_gfx);
+ pb_slabs_deinit(&sctx->bindless_descriptor_slabs);
+ util_dynarray_fini(&sctx->bindless_descriptors);
+
FREE(sctx);
}
sctx->tm = si_create_llvm_target_machine(sscreen);
+ /* Create a slab allocator for all bindless descriptors. */
+ if (!pb_slabs_init(&sctx->bindless_descriptor_slabs, 6, 6, 1, sctx,
+ si_bindless_descriptor_can_reclaim_slab,
+ si_bindless_descriptor_slab_alloc,
+ si_bindless_descriptor_slab_free))
+ goto fail;
+
+ util_dynarray_init(&sctx->bindless_descriptors, NULL);
+
return &sctx->b.b;
fail:
fprintf(stderr, "radeonsi: Failed to create a context.\n");
#include "si_shader.h"
+#include "util/u_dynarray.h"
+
#ifdef PIPE_ARCH_BIG_ENDIAN
#define SI_BIG_ENDIAN 1
#else
uint32_t index;
};
+struct si_bindless_descriptor
+{
+ struct pb_slab_entry entry;
+ struct r600_resource *buffer;
+ unsigned offset;
+};
+
struct si_context {
struct r600_common_context b;
struct blitter_context *blitter;
/* Precomputed IA_MULTI_VGT_PARAM */
union si_vgt_param_key ia_multi_vgt_param_key;
unsigned ia_multi_vgt_param[SI_NUM_VGT_PARAM_STATES];
+
+ /* Slab allocator for bindless descriptors. */
+ struct pb_slabs bindless_descriptor_slabs;
+
+ /* Bindless descriptors. */
+ struct util_dynarray bindless_descriptors;
};
/* cik_sdma.c */
#include "si_pm4.h"
#include "radeon/r600_pipe_common.h"
+#include "pipebuffer/pb_slab.h"
+
#define SI_NUM_GRAPHICS_SHADERS (PIPE_SHADER_TESS_EVAL+1)
#define SI_NUM_SHADERS (PIPE_SHADER_COMPUTE+1)
uint64_t new_active_mask);
void si_set_active_descriptors_for_shader(struct si_context *sctx,
struct si_shader_selector *sel);
+bool si_bindless_descriptor_can_reclaim_slab(void *priv,
+ struct pb_slab_entry *entry);
+struct pb_slab *si_bindless_descriptor_slab_alloc(void *priv, unsigned heap,
+ unsigned entry_size,
+ unsigned group_index);
+void si_bindless_descriptor_slab_free(void *priv, struct pb_slab *pslab);
/* si_state.c */
struct si_shader_selector;