adreno源码系列adreno_ringbuffer
Posted bubbleben
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了adreno源码系列adreno_ringbuffer相关的知识,希望对你有一定的参考价值。
int adreno_ringbuffer_init(struct adreno_device *adreno_dev)
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
int i;
int status = -ENOMEM;
if (!adreno_is_a3xx(adreno_dev))
unsigned int priv =
KGSL_MEMDESC_RANDOM | KGSL_MEMDESC_PRIVILEGED;
if (IS_ERR_OR_NULL(device->scratch))
// 分配kgsl_device全局共享的大小为4k名称为scratch的内存
device->scratch = kgsl_allocate_global(device,
PAGE_SIZE, 0, 0, priv, "scratch");
if (IS_ERR(device->scratch))
return PTR_ERR(device->scratch);
if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
// 支持抢占: rb最多为4个
adreno_dev->num_ringbuffers =
ARRAY_SIZE(adreno_dev->ringbuffers);
else
// 不支持抢占:只有1个rb
adreno_dev->num_ringbuffers = 1;
for (i = 0; i < adreno_dev->num_ringbuffers; i++)
// 初始化每个rb
status = _adreno_ringbuffer_init(adreno_dev, i);
if (status)
adreno_ringbuffer_close(adreno_dev);
return status;
// adreno_device->cur_rb记录第一个rb
adreno_dev->cur_rb = &(adreno_dev->ringbuffers[0]);
if (ADRENO_FEATURE(adreno_dev, ADRENO_PREEMPTION))
const struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
struct adreno_preemption *preempt = &adreno_dev->preempt;
int ret;
timer_setup(&preempt->timer, adreno_preemption_timer, 0);
ret = gpudev->preemption_init(adreno_dev);
WARN(ret, "adreno GPU preemption is disabled\\n");
return 0;
1. _adreno_ringbuffer_init
static int _adreno_ringbuffer_init(struct adreno_device *adreno_dev,
int id)
struct kgsl_device *device = KGSL_DEVICE(adreno_dev);
// 根据id获取指定adreno_ringbuffer
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffers[id];
unsigned int priv = 0;
/*
* Allocate mem for storing RB pagetables and commands to
* switch pagetable
*/
if (IS_ERR_OR_NULL(rb->pagetable_desc))
// 分配adreno_ringbuffer全局共享的大小为4k偏移为16k名称为pagetable_desc的内存
rb->pagetable_desc = kgsl_allocate_global(device, PAGE_SIZE,
SZ_16K, 0, KGSL_MEMDESC_PRIVILEGED, "pagetable_desc");
if (IS_ERR(rb->pagetable_desc))
return PTR_ERR(rb->pagetable_desc);
/* allocate a chunk of memory to create user profiling IB1s */
if (IS_ERR_OR_NULL(rb->profile_desc))
// 分配adreno_ringbuffer全局共享的大小为4k名称为profile_desc的内存
rb->profile_desc = kgsl_allocate_global(device, PAGE_SIZE,
0, KGSL_MEMFLAGS_GPUREADONLY, 0, "profile_desc");
if (ADRENO_FEATURE(adreno_dev, ADRENO_APRIV))
priv |= KGSL_MEMDESC_PRIVILEGED;
if (IS_ERR_OR_NULL(rb->buffer_desc))
// 分配adreno_ringbuffer全局共享的大小为32k偏移为4k名称为ringbuffer的内存
rb->buffer_desc = kgsl_allocate_global(device, KGSL_RB_SIZE,
SZ_4K, KGSL_MEMFLAGS_GPUREADONLY, priv, "ringbuffer");
if (IS_ERR(rb->buffer_desc))
return PTR_ERR(rb->buffer_desc);
if (!list_empty(&rb->events.group))
return 0;
rb->id = id;
// 将当前rb添加到kgsl_device的event_groups链表上
// kgsl_event_group读取时间戳的方法:_rb_readtimestamp
kgsl_add_event_group(device, &rb->events, NULL, _rb_readtimestamp, rb,
"rb_events-%d", id);
// 初始化rb的入队时间为0
rb->timestamp = 0;
init_waitqueue_head(&rb->ts_expire_waitq);
spin_lock_init(&rb->preempt_lock);
return 0;
以上是关于adreno源码系列adreno_ringbuffer的主要内容,如果未能解决你的问题,请参考以下文章