struct ac_vs_output_info *outinfo)
{
struct radeon_winsys *ws = cmd_buffer->device->ws;
- uint64_t va = ws->buffer_get_va(shader->bo);
+ uint64_t va = ws->buffer_get_va(shader->bo) + shader->bo_offset;
unsigned export_count;
ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
struct ac_es_output_info *outinfo)
{
struct radeon_winsys *ws = cmd_buffer->device->ws;
- uint64_t va = ws->buffer_get_va(shader->bo);
+ uint64_t va = ws->buffer_get_va(shader->bo) + shader->bo_offset;
ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
radv_emit_prefetch(cmd_buffer, va, shader->code_size);
struct radv_shader_variant *shader)
{
struct radeon_winsys *ws = cmd_buffer->device->ws;
- uint64_t va = ws->buffer_get_va(shader->bo);
+ uint64_t va = ws->buffer_get_va(shader->bo) + shader->bo_offset;
uint32_t rsrc2 = shader->rsrc2;
ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
struct radv_shader_variant *shader)
{
struct radeon_winsys *ws = cmd_buffer->device->ws;
- uint64_t va = ws->buffer_get_va(shader->bo);
+ uint64_t va = ws->buffer_get_va(shader->bo) + shader->bo_offset;
ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
radv_emit_prefetch(cmd_buffer, va, shader->code_size);
S_028B90_CNT(MIN2(gs_num_invocations, 127)) |
S_028B90_ENABLE(gs_num_invocations > 0));
- va = ws->buffer_get_va(gs->bo);
+ va = ws->buffer_get_va(gs->bo) + gs->bo_offset;
ws->cs_add_buffer(cmd_buffer->cs, gs->bo, 8);
radv_emit_prefetch(cmd_buffer, va, gs->code_size);
assert (pipeline->shaders[MESA_SHADER_FRAGMENT]);
ps = pipeline->shaders[MESA_SHADER_FRAGMENT];
-
- va = ws->buffer_get_va(ps->bo);
+ va = ws->buffer_get_va(ps->bo) + ps->bo_offset;
ws->cs_add_buffer(cmd_buffer->cs, ps->bo, 8);
radv_emit_prefetch(cmd_buffer, va, ps->code_size);
cmd_buffer->state.emitted_compute_pipeline = pipeline;
compute_shader = pipeline->shaders[MESA_SHADER_COMPUTE];
- va = ws->buffer_get_va(compute_shader->bo);
+ va = ws->buffer_get_va(compute_shader->bo) + compute_shader->bo_offset;
ws->cs_add_buffer(cmd_buffer->cs, compute_shader->bo, 8);
radv_emit_prefetch(cmd_buffer, va, compute_shader->code_size);
else
device->alloc = physical_device->instance->alloc;
+ mtx_init(&device->shader_slab_mutex, mtx_plain);
+ list_inithead(&device->shader_slabs);
+
for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i];
uint32_t qfi = queue_create->queueFamilyIndex;
VkPipelineCache pc = radv_pipeline_cache_to_handle(device->mem_cache);
radv_DestroyPipelineCache(radv_device_to_handle(device), pc, NULL);
+ radv_destroy_shader_slabs(device);
+
vk_free(&device->alloc, device);
}
if (!p_atomic_dec_zero(&variant->ref_count))
return;
- device->ws->buffer_destroy(variant->bo);
+ mtx_lock(&device->shader_slab_mutex);
+ list_del(&variant->slab_list);
+ mtx_unlock(&device->shader_slab_mutex);
+
free(variant);
}
S_00B848_DX10_CLAMP(1) |
S_00B848_FLOAT_MODE(variant->config.float_mode);
- variant->bo = device->ws->buffer_create(device->ws, binary->code_size, 256,
- RADEON_DOMAIN_VRAM, RADEON_FLAG_CPU_ACCESS);
-
- void *ptr = device->ws->buffer_map(variant->bo);
+ void *ptr = radv_alloc_shader_memory(device, variant);
memcpy(ptr, binary->code, binary->code_size);
- device->ws->buffer_unmap(variant->bo);
-
-
}
static struct radv_shader_variant *radv_shader_variant_create(struct radv_device *device,
return result;
}
+
+void *radv_alloc_shader_memory(struct radv_device *device,
+ struct radv_shader_variant *shader)
+{
+ mtx_lock(&device->shader_slab_mutex);
+ list_for_each_entry(struct radv_shader_slab, slab, &device->shader_slabs, slabs) {
+ uint64_t offset = 0;
+ list_for_each_entry(struct radv_shader_variant, s, &slab->shaders, slab_list) {
+ if (s->bo_offset - offset >= shader->code_size) {
+ shader->bo = slab->bo;
+ shader->bo_offset = offset;
+ list_addtail(&shader->slab_list, &s->slab_list);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr + offset;
+ }
+ offset = align_u64(s->bo_offset + s->code_size, 256);
+ }
+ if (slab->size - offset >= shader->code_size) {
+ shader->bo = slab->bo;
+ shader->bo_offset = offset;
+ list_addtail(&shader->slab_list, &slab->shaders);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr + offset;
+ }
+ }
+
+ mtx_unlock(&device->shader_slab_mutex);
+ struct radv_shader_slab *slab = calloc(1, sizeof(struct radv_shader_slab));
+
+ slab->size = 256 * 1024;
+ slab->bo = device->ws->buffer_create(device->ws, slab->size, 256,
+ RADEON_DOMAIN_VRAM, 0);
+ slab->ptr = (char*)device->ws->buffer_map(slab->bo);
+ list_inithead(&slab->shaders);
+
+ mtx_lock(&device->shader_slab_mutex);
+ list_add(&slab->slabs, &device->shader_slabs);
+
+ shader->bo = slab->bo;
+ shader->bo_offset = 0;
+ list_add(&shader->slab_list, &slab->shaders);
+ mtx_unlock(&device->shader_slab_mutex);
+ return slab->ptr;
+}
+
+void radv_destroy_shader_slabs(struct radv_device *device)
+{
+ list_for_each_entry_safe(struct radv_shader_slab, slab, &device->shader_slabs, slabs) {
+ device->ws->buffer_destroy(slab->bo);
+ free(slab);
+ }
+ mtx_destroy(&device->shader_slab_mutex);
+}
if (!variant)
return NULL;
+ variant->code_size = entry->code_size;
variant->config = entry->config;
variant->info = entry->variant_info;
variant->rsrc1 = entry->rsrc1;
variant->code_size = entry->code_size;
variant->ref_count = 1;
- variant->bo = device->ws->buffer_create(device->ws, entry->code_size, 256,
- RADEON_DOMAIN_VRAM, RADEON_FLAG_CPU_ACCESS);
-
- void *ptr = device->ws->buffer_map(variant->bo);
+ void *ptr = radv_alloc_shader_memory(device, variant);
memcpy(ptr, entry->code, entry->code_size);
- device->ws->buffer_unmap(variant->bo);
entry->variant = variant;
}
struct radv_pipeline_cache * mem_cache;
uint32_t image_mrt_offset_counter;
+
+ struct list_head shader_slabs;
+ mtx_t shader_slab_mutex;
};
struct radv_device_memory {
stage = __builtin_ffs(__tmp) - 1, __tmp; \
__tmp &= ~(1 << (stage)))
+
+struct radv_shader_slab {
+ struct list_head slabs;
+ struct list_head shaders;
+ struct radeon_winsys_bo *bo;
+ uint64_t size;
+ char *ptr;
+};
+
struct radv_shader_variant {
uint32_t ref_count;
struct radeon_winsys_bo *bo;
+ uint64_t bo_offset;
struct ac_shader_config config;
struct ac_shader_variant_info info;
unsigned rsrc1;
unsigned rsrc2;
uint32_t code_size;
+
+ struct list_head slab_list;
};
+
+void *radv_alloc_shader_memory(struct radv_device *device,
+ struct radv_shader_variant *shader);
+
+void radv_destroy_shader_slabs(struct radv_device *device);
+
struct radv_depth_stencil_state {
uint32_t db_depth_control;
uint32_t db_stencil_control;