Beispiel #1
0
/* Switch to next buffer, optionally wait for it to be available */
static int switch_next_buffer(struct etna_ctx *ctx)
{
    int next_buf_id = (ctx->cur_buf + 1) % NUM_COMMAND_BUFFERS;
#if 0
    fprintf(stderr, "Switching to new buffer %i\n", next_buf_id);
#endif
    if(viv_user_signal_wait(ctx->conn, ctx->cmdbufi[next_buf_id].sig_id, VIV_WAIT_INDEFINITE) != 0)
    {
#ifdef DEBUG
        fprintf(stderr, "Error waiting for command buffer sync signal\n");
#endif
        return ETNA_INTERNAL_ERROR;
    }
    clear_buffer(ctx->cmdbuf[next_buf_id]);
    ctx->cur_buf = next_buf_id;
    ctx->buf = VIV_TO_PTR(ctx->cmdbuf[next_buf_id]->logical);
    ctx->offset = ctx->cmdbuf[next_buf_id]->offset / 4;
#ifdef DEBUG
    fprintf(stderr, "Switched to command buffer %i\n", ctx->cur_buf);
#endif
    return ETNA_OK;
}
Beispiel #2
0
/** Finish building context buffer.
 * final_pipe is the current pipe at the end of the context buffer.
 */
static int gpu_context_build_end(struct etna_ctx *ctx, enum etna_pipe final_pipe)
{
    if(ctx->cur_buf != ETNA_CTX_BUFFER)
        return ETNA_INTERNAL_ERROR;
    /* If closing pipe of context is different from entry pipe, add a switch
     * command, as we want the context to end in the entry pipe. The kernel
     * will handle switching to the entry pipe only when this is a new context.
     */
    if(final_pipe != GCCTX(ctx)->entryPipe)
    {
        etna_set_pipe(ctx, GCCTX(ctx)->entryPipe);
    }
    /* Set current size -- finishing up context before flush
     * will add space for a LINK command and inUse flag.
     */
    GCCTX(ctx)->bufferSize = ctx->offset * 4;

    /* Switch back to stored buffer */
    ctx->cur_buf = ctx->stored_buf;
    ctx->buf = VIV_TO_PTR(ctx->cmdbuf[ctx->cur_buf]->logical);
    ctx->offset = ctx->cmdbuf[ctx->cur_buf]->offset / 4;
    return ETNA_OK;
}
Beispiel #3
0
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;
}