/* Prepare the compiled binary for upload */
if (binary.size) {
- state->bo = panfrost_bo_create(dev, binary.size, PAN_BO_EXECUTE);
+ state->bo = panfrost_bo_create(dev, binary.size,
+ PAN_BO_EXECUTE, "Shader binary");
memcpy(state->bo->ptr.cpu, binary.data, binary.size);
}
PAN_BO_EXECUTE,
PAN_BO_ACCESS_PRIVATE |
PAN_BO_ACCESS_READ |
- PAN_BO_ACCESS_FRAGMENT);
+ PAN_BO_ACCESS_FRAGMENT, "Blend shader");
}
struct panfrost_shader_state *ss = panfrost_get_shader_state(ctx, PIPE_SHADER_FRAGMENT);
(pan_is_bifrost(device) ? 0 : MALI_MIDGARD_TEXTURE_LENGTH) +
panfrost_estimate_texture_payload_size(device, &iview);
- so->bo = panfrost_bo_create(device, size, 0);
+ so->bo = panfrost_bo_create(device, size, 0, "Texture view");
struct panfrost_ptr payload = so->bo->ptr;
void *tex = pan_is_bifrost(device) ?
/* Allocate a bo for the query results to be stored */
if (!query->bo) {
- query->bo = panfrost_bo_create(dev, size, 0);
+ query->bo = panfrost_bo_create(dev, size, 0,
+ "Occlusion query result");
}
/* Default to 0 if nothing at all drawn. */
struct panfrost_bo *
panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
- uint32_t create_flags, uint32_t access_flags)
+ uint32_t create_flags, uint32_t access_flags,
+ const char *label)
{
struct panfrost_bo *bo;
bo = panfrost_bo_create(pan_device(batch->ctx->base.screen), size,
- create_flags);
+ create_flags, label);
panfrost_batch_add_bo(batch, bo, access_flags);
/* panfrost_batch_add_bo() has retained a reference and
PAN_BO_ACCESS_PRIVATE |
PAN_BO_ACCESS_RW |
PAN_BO_ACCESS_VERTEX_TILER |
- PAN_BO_ACCESS_FRAGMENT);
+ PAN_BO_ACCESS_FRAGMENT, "Polygon list");
if (init_polygon_list) {
PAN_BO_ACCESS_PRIVATE |
PAN_BO_ACCESS_RW |
PAN_BO_ACCESS_VERTEX_TILER |
- PAN_BO_ACCESS_FRAGMENT);
+ PAN_BO_ACCESS_FRAGMENT,
+ "Thread local storage");
}
return batch->scratchpad;
PAN_BO_INVISIBLE,
PAN_BO_ACCESS_PRIVATE |
PAN_BO_ACCESS_RW |
- PAN_BO_ACCESS_VERTEX_TILER);
+ PAN_BO_ACCESS_VERTEX_TILER,
+ "Workgroup shared memory");
}
return batch->shared_memory;
struct panfrost_bo *
panfrost_batch_create_bo(struct panfrost_batch *batch, size_t size,
- uint32_t create_flags, uint32_t access_flags);
+ uint32_t create_flags, uint32_t access_flags,
+ const char *label);
void
panfrost_flush_all_batches(struct panfrost_context *ctx);
return NULL;
}
if (rsc->image.layout.crc_mode == PAN_IMAGE_CRC_OOB)
- rsc->image.crc.bo = panfrost_bo_create(dev, rsc->image.layout.crc_size, 0);
+ rsc->image.crc.bo = panfrost_bo_create(dev, rsc->image.layout.crc_size, 0, "CRC data");
rsc->modifier_constant = true;
panfrost_resource_setup(dev, so, modifier, template->format);
+ /* Guess a label based on the bind */
+ unsigned bind = template->bind;
+ const char *label =
+ (bind & PIPE_BIND_INDEX_BUFFER) ? "Index buffer" :
+ (bind & PIPE_BIND_SCANOUT) ? "Scanout" :
+ (bind & PIPE_BIND_DISPLAY_TARGET) ? "Display target" :
+ (bind & PIPE_BIND_SHARED) ? "Shared resource" :
+ (bind & PIPE_BIND_RENDER_TARGET) ? "Render target" :
+ (bind & PIPE_BIND_DEPTH_STENCIL) ? "Depth/stencil buffer" :
+ (bind & PIPE_BIND_SAMPLER_VIEW) ? "Texture" :
+ (bind & PIPE_BIND_VERTEX_BUFFER) ? "Vertex buffer" :
+ (bind & PIPE_BIND_CONSTANT_BUFFER) ? "Constant buffer" :
+ (bind & PIPE_BIND_GLOBAL) ? "Global memory" :
+ (bind & PIPE_BIND_SHADER_BUFFER) ? "Shader buffer" :
+ (bind & PIPE_BIND_SHADER_IMAGE) ? "Shader image" :
+ "Other resource";
+
/* We create a BO immediately but don't bother mapping, since we don't
* care to map e.g. FBOs which the CPU probably won't touch */
so->image.data.bo =
- panfrost_bo_create(dev, so->image.layout.data_size, PAN_BO_DELAY_MMAP);
+ panfrost_bo_create(dev, so->image.layout.data_size, PAN_BO_DELAY_MMAP, label);
if (drm_is_afbc(so->image.layout.modifier))
panfrost_resource_init_afbc_headers(so);
*/
if (!(bo->flags & PAN_BO_SHARED))
newbo = panfrost_bo_create(dev, bo->size,
- flags);
+ flags, bo->label);
if (newbo) {
if (copy_resource)
panfrost_resource_setup(dev, prsrc, DRM_FORMAT_MOD_LINEAR,
prsrc->image.layout.format);
if (prsrc->image.layout.data_size > bo->size) {
+ const char *label = bo->label;
panfrost_bo_unreference(bo);
bo = prsrc->image.data.bo =
- panfrost_bo_create(dev, prsrc->image.layout.data_size, 0);
+ panfrost_bo_create(dev, prsrc->image.layout.data_size, 0, label);
assert(bo);
}
static struct panfrost_bo *
panfrost_bo_alloc(struct panfrost_device *dev, size_t size,
- uint32_t flags)
+ uint32_t flags, const char *label)
{
struct drm_panfrost_create_bo create_bo = { .size = size };
struct panfrost_bo *bo;
bo->gem_handle = create_bo.handle;
bo->flags = flags;
bo->dev = dev;
+ bo->label = label;
return bo;
}
static struct panfrost_bo *
panfrost_bo_cache_fetch(struct panfrost_device *dev,
- size_t size, uint32_t flags, bool dontwait)
+ size_t size, uint32_t flags, const char *label,
+ bool dontwait)
{
pthread_mutex_lock(&dev->bo_cache.lock);
struct list_head *bucket = pan_bucket(dev, size);
}
/* Let's go! */
bo = entry;
+ bo->label = label;
break;
}
pthread_mutex_unlock(&dev->bo_cache.lock);
panfrost_bo_cache_evict_stale_bos(dev);
pthread_mutex_unlock(&dev->bo_cache.lock);
+ /* Update the label to help debug BO cache memory usage issues */
+ bo->label = "Unused (BO cache)";
+
return true;
}
struct panfrost_bo *
panfrost_bo_create(struct panfrost_device *dev, size_t size,
- uint32_t flags)
+ uint32_t flags, const char *label)
{
struct panfrost_bo *bo;
* and if that fails too, we try one more time to allocate from the
* cache, but this time we accept to wait.
*/
- bo = panfrost_bo_cache_fetch(dev, size, flags, true);
+ bo = panfrost_bo_cache_fetch(dev, size, flags, label, true);
if (!bo)
- bo = panfrost_bo_alloc(dev, size, flags);
+ bo = panfrost_bo_alloc(dev, size, flags, label);
if (!bo)
- bo = panfrost_bo_cache_fetch(dev, size, flags, false);
+ bo = panfrost_bo_cache_fetch(dev, size, flags, label, false);
if (!bo)
fprintf(stderr, "BO creation failed\n");
* when the BO is idle.
*/
uint32_t gpu_access;
+
+ /* Human readable description of the BO for debugging. */
+ const char *label;
};
bool
panfrost_bo_unreference(struct panfrost_bo *bo);
struct panfrost_bo *
panfrost_bo_create(struct panfrost_device *dev, size_t size,
- uint32_t flags);
+ uint32_t flags, const char *label);
void
panfrost_bo_mmap(struct panfrost_bo *bo);
struct panfrost_bo *
assert(!shader_info.sysvals.sysval_count);
dev->indirect_dispatch.bin =
- panfrost_bo_create(dev, binary.size, PAN_BO_EXECUTE);
+ panfrost_bo_create(dev, binary.size, PAN_BO_EXECUTE,
+ "Indirect dispatch shader");
memcpy(dev->indirect_dispatch.bin->ptr.cpu, binary.data, binary.size);
util_dynarray_fini(&binary);
panfrost_bo_create(dev,
MALI_RENDERER_STATE_LENGTH +
MALI_LOCAL_STORAGE_LENGTH,
- 0);
+ 0, "Indirect dispatch descriptors");
mali_ptr address = dev->indirect_dispatch.bin->ptr.gpu;
if (!pan_is_bifrost(dev))
MALI_LOCAL_STORAGE_LENGTH;
dev->indirect_draw_shaders.states =
- panfrost_bo_create(dev, state_bo_size, 0);
+ panfrost_bo_create(dev, state_bo_size, 0, "Indirect draw states");
/* Prepare the thread storage descriptor now since it's invariant. */
void *tsd = dev->indirect_draw_shaders.states->ptr.cpu +
*/
dev->indirect_draw_shaders.varying_heap =
panfrost_bo_create(dev, 512 * 1024 * 1024,
- PAN_BO_INVISIBLE | PAN_BO_GROWABLE);
+ PAN_BO_INVISIBLE | PAN_BO_GROWABLE,
+ "Indirect draw varying heap");
out:
pthread_mutex_unlock(&dev->indirect_draw_shaders.lock);
* fragment/vertex+tiler pools separate.
*/
struct panfrost_bo *bo = panfrost_bo_create(pool->dev, bo_sz,
- pool->create_flags);
+ pool->create_flags, "Pool memory");
if (pool->owned)
util_dynarray_append(&pool->bos, struct panfrost_bo *, bo);
* shared across batches/contextes */
dev->tiler_heap = panfrost_bo_create(dev, 4096 * 4096,
- PAN_BO_INVISIBLE | PAN_BO_GROWABLE);
+ PAN_BO_INVISIBLE | PAN_BO_GROWABLE, "Tiler heap");
pthread_mutex_init(&dev->submit_lock, NULL);
panfrost_upload_sample_positions(struct panfrost_device *dev)
{
STATIC_ASSERT(sizeof(sample_position_lut) < 4096);
- dev->sample_positions = panfrost_bo_create(dev, 4096, 0);
+ dev->sample_positions = panfrost_bo_create(dev, 4096, 0, "Sample positions");
memcpy(dev->sample_positions->ptr.cpu, sample_position_lut,
sizeof(sample_position_lut));