/* Free command buffer for context, either immediately or queued for when the * GPU is finished with it. */ static int gpu_context_free_buffer(struct etna_ctx *ctx, struct etna_context_info *ctx_info, bool queued) { int rv; if(queued) { rv = etna_queue_free_contiguous(ctx->queue, ctx_info->bytes, ctx_info->physical, ctx_info->logical); } else { rv = viv_free_contiguous(ctx->conn, ctx_info->bytes, ctx_info->physical, ctx_info->logical); } if(rv != ETNA_OK) { #ifdef DEBUG fprintf(stderr, "Error releasing contiguous host memory for context (%i)\n", rv); #endif return rv; } ctx_info->bytes = ctx_info->physical = 0; ctx_info->logical = NULL; return ETNA_OK; }
int etna_bo_del(struct viv_conn *conn, struct etna_bo *mem, struct etna_queue *queue) { int rv = ETNA_OK; if(mem == NULL) return ETNA_OK; switch(mem->bo_type) { case ETNA_BO_TYPE_VIDMEM: if(mem->logical != NULL) { if((rv = etna_bo_unlock(conn, mem, queue)) != ETNA_OK) { printf("etna: Warning: could not unlock memory\n"); } } if(queue) { if((rv = etna_queue_free_vidmem(queue, mem->node)) != ETNA_OK) { printf("etna: Warning: could not queue free video memory\n"); } } else { if((rv = viv_free_vidmem(conn, mem->node)) != ETNA_OK) { printf("etna: Warning: could not free video memory\n"); } } break; case ETNA_BO_TYPE_VIDMEM_EXTERNAL: if((rv = etna_bo_unlock(conn, mem, queue)) != ETNA_OK) { printf("etna: Warning: could not unlock memory\n"); } break; case ETNA_BO_TYPE_USERMEM: if(queue) { rv = etna_queue_unmap_user_memory(queue, mem->logical, mem->size, mem->usermem_info, mem->address); } else { rv = viv_unmap_user_memory(conn, mem->logical, mem->size, mem->usermem_info, mem->address); } break; case ETNA_BO_TYPE_CONTIGUOUS: if(queue) { rv = etna_queue_free_contiguous(queue, mem->size, mem->address, mem->logical); } else { rv = viv_free_contiguous(conn, mem->size, mem->address, mem->logical); } break; case ETNA_BO_TYPE_PHYSICAL: if(munmap(mem->logical, mem->size) < 0) { rv = ETNA_OUT_OF_MEMORY; } break; } ETNA_FREE(mem); return rv; }
int etna_free(struct etna_ctx *ctx) { if(ctx == NULL) return ETNA_INVALID_ADDR; /* Free kernel command queue */ etna_queue_free(ctx->queue); #ifdef GCABI_HAVE_CONTEXT /* Free context buffer */ gpu_context_free_buffer(ctx, &ctx->ctx_info, false); #endif /* Free command buffers */ for(int x=0; x<NUM_COMMAND_BUFFERS; ++x) { viv_free_contiguous(ctx->conn, ctx->cmdbufi[x].bytes, (viv_addr_t)ctx->cmdbufi[x].physical, VIV_TO_PTR(ctx->cmdbufi[x].logical)); ETNA_FREE(ctx->cmdbuf[x]); } ETNA_FREE(ctx); return ETNA_OK; }