static int adreno_drawctxt_wait_global(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret = 0; /* Needs to hold the device mutex */ BUG_ON(!mutex_is_locked(&device->mutex)); if (!_kgsl_context_get(context)) { ret = -EINVAL; goto done; } /* * If the context is invalid then return immediately - we may end up * waiting for a timestamp that will never come */ if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) { kgsl_context_put(context); goto done; } trace_adreno_drawctxt_wait_start(KGSL_MEMSTORE_GLOBAL, timestamp); ret = kgsl_add_event(device, &device->global_events, timestamp, global_wait_callback, (void *) drawctxt); if (ret) { kgsl_context_put(context); goto done; } kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (timeout) { ret = (int) wait_event_timeout(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout)); if (ret == 0) ret = -ETIMEDOUT; else if (ret > 0) ret = 0; } else { wait_event(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp)); } kgsl_mutex_lock(&device->mutex, &device->mutex_owner); if (ret) kgsl_cancel_events_timestamp(device, &device->global_events, timestamp); done: trace_adreno_drawctxt_wait_done(KGSL_MEMSTORE_GLOBAL, timestamp, ret); return ret; }
int adreno_drawctxt_wait_global(struct adreno_device *adreno_dev, struct kgsl_context *context, uint32_t timestamp, unsigned int timeout) { struct kgsl_device *device = &adreno_dev->dev; struct adreno_context *drawctxt = ADRENO_CONTEXT(context); int ret = 0; BUG_ON(!mutex_is_locked(&device->mutex)); if (!_kgsl_context_get(context)) { ret = -EINVAL; goto done; } if (drawctxt->state == ADRENO_CONTEXT_STATE_INVALID) { kgsl_context_put(context); goto done; } trace_adreno_drawctxt_wait_start(KGSL_MEMSTORE_GLOBAL, timestamp); ret = kgsl_add_event(device, KGSL_MEMSTORE_GLOBAL, timestamp, global_wait_callback, drawctxt, NULL); if (ret) { kgsl_context_put(context); goto done; } mutex_unlock(&device->mutex); if (timeout) { ret = (int) wait_event_timeout(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp), msecs_to_jiffies(timeout)); if (ret == 0) ret = -ETIMEDOUT; else if (ret > 0) ret = 0; } else { wait_event(drawctxt->waiting, _check_global_timestamp(device, drawctxt, timestamp)); } mutex_lock(&device->mutex); if (ret) kgsl_cancel_events_timestamp(device, NULL, timestamp); done: trace_adreno_drawctxt_wait_done(KGSL_MEMSTORE_GLOBAL, timestamp, ret); return ret; }
static int _add_fence_event(struct kgsl_device *device, struct kgsl_context *context, unsigned int timestamp) { struct kgsl_fence_event_priv *event; int ret; event = kmalloc(sizeof(*event), GFP_KERNEL); if (event == NULL) return -ENOMEM; /* * Increase the refcount for the context to keep it through the * callback */ _kgsl_context_get(context); event->context = context; event->timestamp = timestamp; event->context = context; ret = kgsl_add_event(device, context->id, timestamp, kgsl_fence_event_cb, event, context->dev_priv); if (ret) { kgsl_context_put(context); kfree(event); } return ret; }
static void global_wait_callback(struct kgsl_device *device, void *priv, u32 id, u32 timestamp, u32 type) { struct adreno_context *drawctxt = priv; wake_up_all(&drawctxt->waiting); kgsl_context_put(&drawctxt->base); }
static inline void kgsl_fence_event_cb(struct kgsl_device *device, void *priv, u32 context_id, u32 timestamp) { struct kgsl_fence_event_priv *ev = priv; kgsl_sync_timeline_signal(ev->context->timeline, ev->timestamp); kgsl_context_put(ev->context); kfree(ev); }
static void kgsl_fence_event_cb(struct kgsl_device *device, struct kgsl_context *context, void *priv, int result) { struct kgsl_fence_event_priv *ev = priv; kgsl_sync_timeline_signal(ev->context->timeline, ev->timestamp); kgsl_context_put(ev->context); kfree(ev); }
static void global_wait_callback(struct kgsl_device *device, struct kgsl_context *context, void *priv, int result) { struct adreno_context *drawctxt = priv; wake_up_all(&drawctxt->waiting); kgsl_context_put(&drawctxt->base); }
static inline void kgsl_fence_event_cb(struct kgsl_device *device, void *priv, u32 context_id, u32 timestamp, u32 type) { struct kgsl_fence_event_priv *ev = priv; /* Signal time timeline for every event type */ kgsl_sync_timeline_signal(ev->context->timeline, timestamp); kgsl_context_put(ev->context); kfree(ev); }
static unsigned int kgsl_sync_get_timestamp( struct kgsl_sync_timeline *ktimeline, enum kgsl_timestamp_type type) { unsigned int ret = 0; struct kgsl_context *context = kgsl_context_get(ktimeline->device, ktimeline->context_id); if (context) ret = kgsl_readtimestamp(ktimeline->device, context, type); kgsl_context_put(context); return ret; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) return ret; trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); /* Set the new context */ ret = adreno_context_restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }
int adreno_setproperty_compat(struct kgsl_device_private *dev_priv, enum kgsl_property_type type, void __user *value, unsigned int sizebytes) { int status = -EINVAL; struct kgsl_device *device = dev_priv->device; switch (type) { case KGSL_PROP_PWR_CONSTRAINT: { struct kgsl_device_constraint_compat constraint32; struct kgsl_device_constraint constraint; struct kgsl_context *context; if (sizebytes != sizeof(constraint32)) break; if (copy_from_user(&constraint32, value, sizeof(constraint32))) { status = -EFAULT; break; } /* Populate the real constraint type from the compat */ constraint.type = constraint32.type; constraint.context_id = constraint32.context_id; constraint.data = compat_ptr(constraint32.data); constraint.size = (size_t)constraint32.size; context = kgsl_context_get_owner(dev_priv, constraint.context_id); if (context == NULL) break; status = adreno_set_constraint(device, context, &constraint); kgsl_context_put(context); } break; default: /* * Call adreno_setproperty in case the property type was * KGSL_PROP_PWRCTRL */ status = device->ftbl->setproperty(dev_priv, type, value, sizebytes); } return status; }
void adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; if (drawctxt) { if (flags & KGSL_CONTEXT_SAVE_GMEM) /* Set the flag in context so that the save is done * when this context is switched out. */ drawctxt->flags |= CTXT_FLAGS_GMEM_SAVE; else /* Remove GMEM saving flag from the context */ drawctxt->flags &= ~CTXT_FLAGS_GMEM_SAVE; } /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) { if (adreno_dev->gpudev->ctxt_draw_workaround && adreno_is_a225(adreno_dev)) adreno_dev->gpudev->ctxt_draw_workaround( adreno_dev, drawctxt); return; } KGSL_CTXT_INFO(device, "from %d to %d flags %d\n", adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : 0, drawctxt ? drawctxt->base.id : 0, flags); /* Save the old context */ adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active); /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) { kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = NULL; } /* Get a refcount to the new instance */ if (drawctxt) _kgsl_context_get(&drawctxt->base); /* Set the new context */ adreno_dev->gpudev->ctxt_restore(adreno_dev, drawctxt); adreno_dev->drawctxt_active = drawctxt; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_ringbuffer *rb, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; struct kgsl_pagetable *new_pt; int ret = 0; /* We always expect a valid rb */ BUG_ON(!rb); /* already current? */ if (rb->drawctxt_active == drawctxt) return ret; trace_adreno_drawctxt_switch(rb, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; new_pt = drawctxt->base.proc_priv->pagetable; } else { /* No context - set the default pagetable and thats it. */ new_pt = device->mmu.defaultpagetable; } ret = adreno_iommu_set_pt(rb, new_pt); if (ret) { KGSL_DRV_ERR(device, "Failed to set pagetable on rb %d\n", rb->id); return ret; } /* Put the old instance of the active drawctxt */ if (rb->drawctxt_active) kgsl_context_put(&rb->drawctxt_active->base); rb->drawctxt_active = drawctxt; /* Set the new context */ adreno_context_restore(rb); return 0; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; char fence_name[sizeof(fence->name)] = {}; unsigned int cur; priv.fence_fd = -1; if (len != sizeof(priv)) return -EINVAL; kgsl_mutex_lock(&device->mutex, &device->mutex_owner); context = kgsl_context_get_owner(owner, context_id); if (context == NULL) goto unlock; pt = kgsl_sync_pt_create(context->timeline, context, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto unlock; } snprintf(fence_name, sizeof(fence_name), "%s-pid-%d-ctx-%d-ts-%d", device->name, current->group_leader->pid, context_id, timestamp); fence = sync_fence_create(fence_name, pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto unlock; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n", priv.fence_fd); ret = priv.fence_fd; goto unlock; } sync_fence_install(fence, priv.fence_fd); /* * If the timestamp hasn't expired yet create an event to trigger it. * Otherwise, just signal the fence - there is no reason to go through * the effort of creating a fence we don't need. */ cur = kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED); if (timestamp_cmp(cur, timestamp) >= 0) kgsl_sync_timeline_signal(context->timeline, cur); else { ret = _add_fence_event(device, context, timestamp); if (ret) goto unlock; } kgsl_context_put(context); /* Unlock the mutex before copying to user */ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto out; } return 0; unlock: kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); out: if (priv.fence_fd >= 0) put_unused_fd(priv.fence_fd); if (fence) sync_fence_put(fence); kgsl_context_put(context); return ret; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_fence_event_priv *event; struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; char fence_name[sizeof(fence->name)] = {}; priv.fence_fd = -1; if (len != sizeof(priv)) return -EINVAL; event = kzalloc(sizeof(*event), GFP_KERNEL); if (event == NULL) return -ENOMEM; kgsl_mutex_lock(&device->mutex, &device->mutex_owner); context = kgsl_context_get_owner(owner, context_id); if (context == NULL) goto unlock; event->context = context; event->timestamp = timestamp; pt = kgsl_sync_pt_create(context->timeline, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto unlock; } snprintf(fence_name, sizeof(fence_name), "%s-pid-%d-ctx-%d-ts-%d", device->name, current->group_leader->pid, context_id, timestamp); fence = sync_fence_create(fence_name, pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto unlock; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "Unable to get a file descriptor: %d\n", priv.fence_fd); ret = priv.fence_fd; goto unlock; } /* Unlock the mutex before copying to user */ kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto out; } /* * Hold the context ref-count for the event - it will get released in * the callback */ ret = kgsl_add_event(device, &context->events, timestamp, kgsl_fence_event_cb, event); if (ret) goto out; sync_fence_install(fence, priv.fence_fd); return 0; unlock: kgsl_mutex_unlock(&device->mutex, &device->mutex_owner); out: if (priv.fence_fd >= 0) put_unused_fd(priv.fence_fd); if (fence) sync_fence_put(fence); kgsl_context_put(context); kfree(event); return ret; }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; if (drawctxt) { /* * Handle legacy gmem / save restore flag on each IB. * Userspace sets to guard IB sequences that require * gmem to be saved and clears it at the end of the * sequence. */ if (flags & KGSL_CONTEXT_SAVE_GMEM) /* Set the flag in context so that the save is done * when this context is switched out. */ set_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); else /* Remove GMEM saving flag from the context */ clear_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); } /* already current? */ if (adreno_dev->drawctxt_active == drawctxt) { if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); /* Get a refcount to the new instance */ if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); /* Set the new context */ ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { /* * No context - set the default pagetable and thats it. * If there isn't a current context, the kgsl_mmu_setstate * will use the CPU path so we don't need to give * it a valid context id. */ ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } /* Put the old instance of the active drawctxt */ if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }
int kgsl_add_fence_event(struct kgsl_device *device, u32 context_id, u32 timestamp, void __user *data, int len, struct kgsl_device_private *owner) { struct kgsl_fence_event_priv *event; struct kgsl_timestamp_event_fence priv; struct kgsl_context *context; struct sync_pt *pt; struct sync_fence *fence = NULL; int ret = -EINVAL; if (len != sizeof(priv)) return -EINVAL; context = kgsl_find_context(owner, context_id); if (context == NULL) return -EINVAL; event = kzalloc(sizeof(*event), GFP_KERNEL); if (event == NULL) return -ENOMEM; event->context = context; event->timestamp = timestamp; kgsl_context_get(context); pt = kgsl_sync_pt_create(context->timeline, timestamp); if (pt == NULL) { KGSL_DRV_ERR(device, "kgsl_sync_pt_create failed\n"); ret = -ENOMEM; goto fail_pt; } fence = sync_fence_create("kgsl-fence", pt); if (fence == NULL) { /* only destroy pt when not added to fence */ kgsl_sync_pt_destroy(pt); KGSL_DRV_ERR(device, "sync_fence_create failed\n"); ret = -ENOMEM; goto fail_fence; } priv.fence_fd = get_unused_fd_flags(0); if (priv.fence_fd < 0) { KGSL_DRV_ERR(device, "invalid fence fd\n"); ret = -EINVAL; goto fail_fd; } sync_fence_install(fence, priv.fence_fd); if (copy_to_user(data, &priv, sizeof(priv))) { ret = -EFAULT; goto fail_copy_fd; } ret = kgsl_add_event(device, context_id, timestamp, kgsl_fence_event_cb, event, owner); if (ret) goto fail_event; return 0; fail_event: fail_copy_fd: /* clean up sync_fence_install */ put_unused_fd(priv.fence_fd); fail_fd: /* clean up sync_fence_create */ sync_fence_put(fence); fail_fence: fail_pt: kgsl_context_put(context); kfree(event); return ret; }
/** * adreno_drawctxt_create - create a new adreno draw context * @dev_priv: the owner of the context * @flags: flags for the context (passed from user space) * * Create and return a new draw context for the 3D core. */ struct kgsl_context * adreno_drawctxt_create(struct kgsl_device_private *dev_priv, uint32_t *flags) { struct adreno_context *drawctxt; struct kgsl_device *device = dev_priv->device; struct adreno_device *adreno_dev = ADRENO_DEVICE(device); int ret; drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL); if (drawctxt == NULL) return ERR_PTR(-ENOMEM); ret = kgsl_context_init(dev_priv, &drawctxt->base); if (ret != 0) { kfree(drawctxt); return ERR_PTR(ret); } drawctxt->bin_base_offset = 0; drawctxt->timestamp = 0; *flags &= (KGSL_CONTEXT_PREAMBLE | KGSL_CONTEXT_NO_GMEM_ALLOC | KGSL_CONTEXT_PER_CONTEXT_TS | KGSL_CONTEXT_USER_GENERATED_TS | KGSL_CONTEXT_NO_FAULT_TOLERANCE | KGSL_CONTEXT_TYPE_MASK); if (*flags & KGSL_CONTEXT_PREAMBLE) drawctxt->flags |= CTXT_FLAGS_PREAMBLE; if (*flags & KGSL_CONTEXT_NO_GMEM_ALLOC) drawctxt->flags |= CTXT_FLAGS_NOGMEMALLOC; if (*flags & KGSL_CONTEXT_PER_CONTEXT_TS) drawctxt->flags |= CTXT_FLAGS_PER_CONTEXT_TS; if (*flags & KGSL_CONTEXT_USER_GENERATED_TS) { if (!(*flags & KGSL_CONTEXT_PER_CONTEXT_TS)) { ret = -EINVAL; goto err; } drawctxt->flags |= CTXT_FLAGS_USER_GENERATED_TS; } if (*flags & KGSL_CONTEXT_NO_FAULT_TOLERANCE) drawctxt->flags |= CTXT_FLAGS_NO_FAULT_TOLERANCE; drawctxt->type = (*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT; ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt); if (ret) goto err; kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, ref_wait_ts), KGSL_INIT_REFTIMESTAMP); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, ts_cmp_enable), 0); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp), 0); kgsl_sharedmem_writel(device, &device->memstore, KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp), 0); return &drawctxt->base; err: kgsl_context_put(&drawctxt->base); return ERR_PTR(ret); }
int adreno_drawctxt_switch(struct adreno_device *adreno_dev, struct adreno_context *drawctxt, unsigned int flags) { struct kgsl_device *device = &adreno_dev->dev; int ret = 0; if (drawctxt) { if (flags & KGSL_CONTEXT_SAVE_GMEM) set_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); else clear_bit(ADRENO_CONTEXT_GMEM_SAVE, &drawctxt->priv); } if (adreno_dev->drawctxt_active == drawctxt) { if (drawctxt && drawctxt->ops->draw_workaround) ret = drawctxt->ops->draw_workaround(adreno_dev, drawctxt); return ret; } trace_adreno_drawctxt_switch(adreno_dev->drawctxt_active, drawctxt, flags); if (adreno_dev->drawctxt_active) { ret = context_save(adreno_dev, adreno_dev->drawctxt_active); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d save: %d\n", adreno_dev->drawctxt_active->base.id, ret); return ret; } } if (drawctxt) { if (!_kgsl_context_get(&drawctxt->base)) return -EINVAL; ret = kgsl_mmu_setstate(&device->mmu, drawctxt->base.proc_priv->pagetable, adreno_dev->drawctxt_active ? adreno_dev->drawctxt_active->base.id : KGSL_CONTEXT_INVALID); ret = drawctxt->ops->restore(adreno_dev, drawctxt); if (ret) { KGSL_DRV_ERR(device, "Error in GPU context %d restore: %d\n", drawctxt->base.id, ret); return ret; } } else { ret = kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable, adreno_dev->drawctxt_active->base.id); } if (adreno_dev->drawctxt_active) kgsl_context_put(&adreno_dev->drawctxt_active->base); adreno_dev->drawctxt_active = drawctxt; return 0; }