コード例 #1
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_0_SelfContain(
    ppoPREPROCESSOR     PP,
    ppoINPUT_STREAM     *IS,
    ppoTOKEN            *Head,
    ppoTOKEN            *End,
    gctBOOL             *AnyExpanationHappened,
    gctBOOL             *MatchCase,
    ppoTOKEN            *ID)
{
    gceSTATUS status = gcvSTATUS_INVALID_DATA;

    ppoTOKEN id = gcvNULL;

    gctBOOL inhs = gcvFALSE;

    gcmONERROR(
        (*IS)->GetToken(PP, IS, &id, !ppvICareWhiteSpace)
        );

    gcmASSERT(id && id->type == ppvTokenType_ID);

    *ID = id;

    gcmTRACE(gcvLEVEL_VERBOSE, "ME : Begin to process %s.", id->poolString);

    gcmONERROR(
        ppoHIDE_SET_LIST_ContainSelf(PP, id, &inhs)
        );

    if (inhs == gcvTRUE)
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : self-contain.",id->poolString);

        *Head = id;
        *End  = id;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvTRUE;

        return gcvSTATUS_OK;
    }
    else
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : not self-contain.",id->poolString);

        *Head = gcvNULL;
        *End  = gcvNULL;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvFALSE;

        return gcvSTATUS_OK;
    }
OnError:
    if (id != gcvNULL)
    {
        gcmVERIFY_OK(ppoTOKEN_Destroy(PP, id));
        id = gcvNULL;
    }
    return status;
}
コード例 #2
0
/*******************************************************************************
**
**  gcoBUFFER_Destroy
**
**  Destroy an gcoBUFFER object.
**
**  INPUT:
**
**      gcoBUFFER Buffer
**          Pointer to an gcoBUFFER object to delete.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoBUFFER_Destroy(
    IN gcoBUFFER Buffer
    )
{
    gceSTATUS status;

    gcmHEADER_ARG("Buffer=0x%x", Buffer);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Buffer, gcvOBJ_BUFFER);

    /* Commit buffer before destroying it. */
    if (Buffer->size != 0)
    {
        /* Commit the command buffers. */
        gcmONERROR(gcoHARDWARE_Commit());

        /* Stall the hardware. */
        gcmONERROR(gcoHARDWARE_Stall());
    }

    /* Free all associated objects. */
    gcmONERROR(gcoBUFFER_FreeObjects(Buffer));

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #3
0
static gceSTATUS
_Print(
	_VGContext * Context,
	gctCONST_STRING Format,
	...
	)
{
	char buffer[256];
	gctUINT offset = 0;
	gceSTATUS status;

	gcmONERROR(
		gcoOS_PrintStrVSafe(buffer, gcmSIZEOF(buffer),
							&offset,
							Format,
							(gctPOINTER) (&Format + 1)));

	gcmONERROR(
		gcoPROFILER_Write(Context->hal,
                          offset,
                          buffer));

	return gcvSTATUS_OK;

OnError:
	return status;
}
コード例 #4
0
/*******************************************************************************
**
**  gcoBUFFER_Write
**
**  Copy a number of bytes into the buffer.
**
**  INPUT:
**
**      gcoBUFFER Buffer
**          Pointer to an gcoBUFFER object.
**
**      gctCONST_POINTER Data
**          Pointer to a buffer that contains the data to be copied.
**
**      IN gctSIZE_T Bytes
**          Number of bytes to copy.
**
**      IN gctBOOL Aligned
**          gcvTRUE if the data needs to be aligned to 64-bit.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoBUFFER_Write(
    IN gcoBUFFER Buffer,
    IN gctCONST_POINTER Data,
    IN gctSIZE_T Bytes,
    IN gctBOOL Aligned
    )
{
    gceSTATUS status;
    gcoCMDBUF reserve;

    gcmHEADER_ARG("Buffer=0x%x Data=0x%x Bytes=%lu Aligned=%d",
                  Buffer, Data, Bytes, Aligned);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Buffer, gcvOBJ_BUFFER);
    gcmDEBUG_VERIFY_ARGUMENT(Data != gcvNULL);
    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);

    /* Reserve data in the buffer. */
    gcmONERROR(gcoBUFFER_Reserve(Buffer, Bytes, Aligned, &reserve));

    /* Write data into the buffer. */
    gcmONERROR(gcoOS_MemCopy(reserve->lastReserve, Data, Bytes));

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return status. */
    gcmFOOTER();
    return status;
}
コード例 #5
0
gceSTATUS
gcoQUEUE_Destroy(
    IN gcoQUEUE Queue
    )
{
    gceSTATUS status;

    gcmHEADER_ARG("Queue=0x%x", Queue);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);

#ifndef __QNXNTO__
    /* Free any records in the queue. */
    while (Queue->head != gcvNULL)
    {
        gcsQUEUE_PTR record;

        /* Unlink the first record from the queue. */
        record      = Queue->head;
        Queue->head = record->next;

        gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, record));
    }

    /* Free any records in the free list. */
    while (Queue->freeList != gcvNULL)
    {
        gcsQUEUE_PTR record;

        /* Unlink the first record from the queue. */
        record          = Queue->freeList;
        Queue->freeList = record->next;

        gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, record));
    }
#else
    /* Free any records in the queue. */
    if ( Queue->records )
    {
        gcmVERIFY_OK(gcoOS_FreeNonPagedMemory(gcvNULL,
                                              BUFFER_SIZE,
                                              gcvNULL,
                                              Queue->records));
    }
#endif

    /* Free the queue. */
    gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, Queue));

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #6
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_4_NoRealArg(
                                        ppoPREPROCESSOR     PP,
                                        ppoINPUT_STREAM     *IS,
                                        ppoTOKEN            *Head,
                                        ppoTOKEN            *End,
                                        gctBOOL             *AnyExpanationHappened,
                                        gctBOOL             *MatchCase,
                                        ppoTOKEN            ID
                                        )
{
    gceSTATUS status;

    ppoTOKEN id = ID;

    ppoTOKEN ahead = gcvNULL;

    gcmONERROR(
        (*IS)->GetToken(PP, IS, &ahead, !ppvICareWhiteSpace)
        );

    if (ahead->poolString != PP->keyword->lpara)
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : %s, no real arg.", id->poolString);

        *Head = id;
        *End  = id;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvTRUE;

        gcmONERROR(
            ppoINPUT_STREAM_UnGetToken(PP, (ppoINPUT_STREAM *)IS, ahead));

        gcmONERROR(ppoTOKEN_Destroy(PP, ahead));

        return gcvSTATUS_OK;
    }
    else
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : %s, real arg.", id->poolString);

        *MatchCase = gcvFALSE;
        *AnyExpanationHappened = gcvFALSE;

        gcmONERROR(
            ppoINPUT_STREAM_UnGetToken(PP, IS, ahead)
            );

        return gcvSTATUS_OK;
    }
OnError:
    if (ahead != gcvNULL)
    {
        gcmVERIFY_OK(ppoTOKEN_Destroy(PP, ahead));
        ahead = gcvNULL;
    }
	return status;
}
コード例 #7
0
/**
 *
 * @param Hal - Hardware abstraction layer object
 * @param Size - Size of the surface in bits
 * @param Pool - To allocate from which pool
 * @param Node - returned allocated video node
 * @return  - result of the process
 */
static gceSTATUS AllocVideoNode(
        IN gcoHAL Hal,
        IN OUT gctUINT_PTR Size,
        IN OUT gcePOOL *Pool,
        IN gceSURF_TYPE surftype,
        OUT gcuVIDMEM_NODE_PTR *Node) {
    gcsHAL_INTERFACE iface;
    gceSTATUS status;

    gcmASSERT(Pool != gcvNULL);
    gcmASSERT(Size != gcvNULL);
    gcmASSERT(Node != gcvNULL);

    iface.command = gcvHAL_ALLOCATE_LINEAR_VIDEO_MEMORY;
    iface.u.AllocateLinearVideoMemory.bytes = *Size;
    iface.u.AllocateLinearVideoMemory.alignment = 64;
    iface.u.AllocateLinearVideoMemory.pool = *Pool;
    iface.u.AllocateLinearVideoMemory.type = surftype;

    /* Call kernel API. */
    gcmONERROR(gcoHAL_Call(Hal, &iface));

    /* Get allocated node in video memory. */
    *Node = iface.u.AllocateLinearVideoMemory.node;
    *Pool = iface.u.AllocateLinearVideoMemory.pool;
    *Size = iface.u.AllocateLinearVideoMemory.bytes;

OnError:

    return status;
}
コード例 #8
0
/**
 *  Use for  getting the physical and logical address
 * @param Hal Hardware abstraction layer object
 * @param Node video node
 * @param Address physical address
 * @param Memory logical address
 * @return result of the process
 */
static gceSTATUS LockVideoNode(
        IN gcoHAL Hal,
        IN gcuVIDMEM_NODE_PTR Node,
        IN Bool cacheable,
        OUT gctUINT32 *Address,
        OUT gctPOINTER *Memory) {
    gceSTATUS status;
    gcsHAL_INTERFACE iface;

    gcmASSERT(Address != gcvNULL);
    gcmASSERT(Memory != gcvNULL);
    gcmASSERT(Node != gcvNULL);

    iface.command = gcvHAL_LOCK_VIDEO_MEMORY;
    iface.u.LockVideoMemory.node = Node;
    iface.u.LockVideoMemory.cacheable = cacheable;
    /* Call kernel API. */
    gcmONERROR(gcoHAL_Call(Hal, &iface));

    /* Get allocated node in video memory. */
    *Address = iface.u.LockVideoMemory.address;
    *Memory = iface.u.LockVideoMemory.memory;

OnError:

    return status;
}
コード例 #9
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList_MergePastingTokenName(
    ppoPREPROCESSOR     PP,
    ppoTOKEN            InHead,
    ppoTOKEN            InReplaceList,
    OUT sltPOOL_STRING * PoolString
    )
{
    gceSTATUS status;

    gctSIZE_T size;

    gctSIZE_T newSize = 0;

    char newString[256];

    ppoTOKEN tmprplst = InReplaceList;

    newString[0] = '\0';

    gcmONERROR(gcoOS_StrLen(InHead->poolString, &newSize));
    gcmONERROR(gcoOS_StrCatSafe(newString,256,InHead->poolString));

    while(tmprplst)
    {
        gcmONERROR(gcoOS_StrLen(tmprplst->poolString, &size));

        newSize += size;
        if(newSize + 1 > 256)
            return gcvSTATUS_TOO_COMPLEX;

        gcmONERROR(gcoOS_StrCatSafe(newString,256,tmprplst->poolString));

        tmprplst = (ppoTOKEN)tmprplst->inputStream.base.node.prev;
    }

    status = sloCOMPILER_AllocatePoolString(PP->compiler,
        newString,
        PoolString);

OnError:
    return status;
}
コード例 #10
0
gceSTATUS
gcoQUEUE_Commit(
    IN gcoQUEUE Queue
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gcsHAL_INTERFACE iface;

    gcmHEADER_ARG("Queue=0x%x", Queue);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);

    if (Queue->head != gcvNULL)
    {
        /* Initialize event commit command. */
        iface.command       = gcvHAL_EVENT_COMMIT;
        iface.u.Event.queue = Queue->head;

        /* Send command to kernel. */
        gcmONERROR(
            gcoOS_DeviceControl(gcvNULL,
                                IOCTL_GCHAL_INTERFACE,
                                &iface, gcmSIZEOF(iface),
                                &iface, gcmSIZEOF(iface)));

        /* Test for error. */
        gcmONERROR(iface.status);

        /* Free any records in the queue. */
        gcmONERROR(gcoQUEUE_Free(Queue));
    }

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #11
0
static gceSTATUS
gcoBUFFER_FreeObjects(
    IN gcoBUFFER Buffer
    )
{
    gceSTATUS status;
    gctUINT i;

    gcmHEADER_ARG("Buffer=0x%x", Buffer);

    /* Roll back all command buffers. */
    for (i = 0; i < gcmCOUNTOF(Buffer->commandBuffers); i += 1)
    {
        if (Buffer->commandBuffers[i] != gcvNULL)
        {
            /* Destroy command buffer. */
            gcmONERROR(gcoCMDBUF_Destroy(Buffer->commandBuffers[i]));
            Buffer->commandBuffers[i] = gcvNULL;
        }

        if (Buffer->signal[i] != gcvNULL)
        {
            /* Destroy signal. */
            gcmONERROR(gcoOS_DestroySignal(gcvNULL, Buffer->signal[i]));
            Buffer->signal[i] = gcvNULL;
        }
    }

    /* Free the object memory. */
    gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, Buffer));

    /* Success. */
    gcmFOOTER();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #12
0
/**
 *
 * @param Hal
 * @param Node
 * @return
 */
static gceSTATUS UnlockVideoNode(
	IN gcoHAL Hal,
	IN gcuVIDMEM_NODE_PTR Node,
	IN gceSURF_TYPE surftype) {

	gcsHAL_INTERFACE iface;
	gceSTATUS status;

	gcmASSERT(Node != gcvNULL);

	iface.command = gcvHAL_UNLOCK_VIDEO_MEMORY;
	iface.u.UnlockVideoMemory.node = Node;
	iface.u.UnlockVideoMemory.type = surftype;
	iface.u.UnlockVideoMemory.asynchroneous = gcvTRUE;

	/* Call the kernel. */
	gcmONERROR(gcoOS_DeviceControl(
				gcvNULL,
				IOCTL_GCHAL_INTERFACE,
				&iface, gcmSIZEOF(iface),
				&iface, gcmSIZEOF(iface)
	));

	/* Success? */
	gcmONERROR(iface.status);

	/* Do we need to schedule an event for the unlock? */
	if (iface.u.UnlockVideoMemory.asynchroneous)
	{
		iface.u.UnlockVideoMemory.asynchroneous = gcvFALSE;
		gcmONERROR(gcoHAL_ScheduleEvent(Hal, &iface));
	}

OnError:
    /* Call kernel API. */
    return gcvSTATUS_FALSE;

}
コード例 #13
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_1_NotMacroSymbol(
    ppoPREPROCESSOR     PP,
    ppoINPUT_STREAM     *IS,
    ppoTOKEN            *Head,
    ppoTOKEN            *End,
    gctBOOL             *AnyExpanationHappened,
    gctBOOL             *MatchCase,
    ppoTOKEN            ID,
    ppoMACRO_SYMBOL     *MS
    )
{

    gceSTATUS status = gcvSTATUS_INVALID_DATA;

    ppoTOKEN id = ID;

    ppoMACRO_SYMBOL ms = gcvNULL;

    gcmONERROR(
        ppoMACRO_MANAGER_GetMacroSymbol(PP, PP->macroManager, id->poolString, &ms)
        );

    *MS = ms;

    if (ms == gcvNULL)
    {
        gcmTRACE(gcvLEVEL_VERBOSE,"ME : %s is not defined.",id->poolString);

        *Head = id;
        *End  = id;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvTRUE;

        return gcvSTATUS_OK;
    }
    else
    {
        gcmTRACE(gcvLEVEL_VERBOSE,"ME : %s is defined.",id->poolString);

        *Head = gcvNULL;
        *End  = gcvNULL;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvFALSE;

        return gcvSTATUS_OK;
    }
OnError:
	return status;
}
コード例 #14
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand(
                            ppoPREPROCESSOR     PP,
                            ppoINPUT_STREAM     *IS,
                            ppoTOKEN            *Head,
                            ppoTOKEN            *End,
                            gctBOOL             *AnyExpanationHappened)
{
    gceSTATUS status = gcvSTATUS_INVALID_DATA;
    ppoTOKEN *headtail = gcvNULL;
    ppoTOKEN *expanded_headtail = gcvNULL;
    gctBOOL match_case = gcvFALSE;
    ppoTOKEN id = gcvNULL;
    ppoMACRO_SYMBOL ms = gcvNULL;
    gctPOINTER pointer = gcvNULL;

    if ((*IS) == gcvNULL)
    {
        *AnyExpanationHappened  = gcvFALSE;
        *Head       = gcvNULL;
        *End        = gcvNULL;

        return gcvSTATUS_OK;
    }

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_0_SelfContain(PP, IS, Head, End, AnyExpanationHappened, &match_case, &id)
        );

    if (match_case == gcvTRUE) return gcvSTATUS_OK;

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_1_NotMacroSymbol(PP, IS, Head, End, AnyExpanationHappened, &match_case, id, &ms)
        );

    if (match_case == gcvTRUE)  return gcvSTATUS_OK;


    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_2_NoFormalArgs(PP, IS, Head, End, AnyExpanationHappened, &match_case, id, ms)
        );

    if (match_case == gcvTRUE)  return gcvSTATUS_OK;

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_3_NoMoreTokenInIS(PP, IS, Head, End, AnyExpanationHappened, &match_case, id)
        );

    if (match_case == gcvTRUE)  return gcvSTATUS_OK;

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_4_NoRealArg(PP, IS, Head, End, AnyExpanationHappened, &match_case, id)
        );

    if (match_case == gcvTRUE)  return gcvSTATUS_OK;

    status = sloCOMPILER_Allocate(
        PP->compiler,
        sizeof(ppoTOKEN)*2*(ms->argc),
        &pointer
        );

    if (gcmIS_ERROR(status))
        return status;

    headtail = pointer;

    gcoOS_MemFill((gctPOINTER)headtail, 0, sizeof(ppoTOKEN) * 2 * (ms->argc));

    gcmONERROR(sloCOMPILER_Allocate(
        PP->compiler,
        sizeof(ppoTOKEN)*2*(ms->argc),
        (void*)&expanded_headtail));

    gcoOS_MemFill((gctPOINTER)expanded_headtail, 0, sizeof(ppoTOKEN) * 2 * (ms->argc));

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_5_BufferRealArgs(PP, IS, headtail, id, ms)
        );

    if (match_case == gcvTRUE)  return gcvSTATUS_OK;

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_6_ExpandHeadTail(PP, IS, headtail, expanded_headtail, id, ms)
        );

    gcmONERROR(
        ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList(PP, IS, Head, End, AnyExpanationHappened,expanded_headtail, id, ms)
        );

    gcmONERROR(
        sloCOMPILER_Free(PP->compiler, headtail)
        );

    gcmONERROR(
        sloCOMPILER_Free(PP->compiler, expanded_headtail)
        );

    return gcvSTATUS_OK;

OnError:
	if (headtail != gcvNULL)
	{
		gcmVERIFY_OK(sloCOMPILER_Free(PP->compiler, headtail));
		headtail = gcvNULL;
	}

	if (expanded_headtail != gcvNULL)
	{
		gcmVERIFY_OK(sloCOMPILER_Free(PP->compiler, expanded_headtail));
		expanded_headtail = gcvNULL;
	}
	return status;
}
コード例 #15
0
/*******************************************************************************
**
**  gcoBUFFER_Construct
**
**  Construct a new gcoBUFFER object.
**
**  INPUT:
**
**      gcoHAL Hal
**          Pointer to a gcoHAL object.
**
**      gcoHARDWARE Hardware
**          Pointer to a gcoHARDWARE object.
**
**      gckCONTEXT Context
**          Pointer to a gckCONTEXT object.
**
**      gctSIZE_T MaxSize
**          Maximum size of buffer.
**
**  OUTPUT:
**
**      gcoBUFFER * Buffer
**          Pointer to a variable that will hold the the gcoBUFFER object
**          pointer.
*/
gceSTATUS
gcoBUFFER_Construct(
    IN gcoHAL Hal,
    IN gcoHARDWARE Hardware,
    IN gckCONTEXT Context,
    IN gctSIZE_T MaxSize,
    OUT gcoBUFFER * Buffer
    )
{
    gceSTATUS status;
    gcoBUFFER buffer = gcvNULL;
    gctUINT i = 0;
    gctPOINTER pointer = gcvNULL;

    gcmHEADER_ARG("Hal=0x%x Hardware=0x%x Context=0x%x MaxSize=%lu",
                  Hal, Hardware, Context, MaxSize);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Hal, gcvOBJ_HAL);
    gcmVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
    gcmDEBUG_VERIFY_ARGUMENT(Buffer != gcvNULL);

    /***************************************************************************
    ** Allocate and reset the gcoBUFFER object.
    */

    gcmONERROR(gcoOS_Allocate(
        gcvNULL, gcmSIZEOF(struct _gcoBUFFER), &pointer
        ));

    buffer = pointer;

    /* Initialize the gcoBUFFER object. */
    buffer->object.type = gcvOBJ_BUFFER;
    buffer->hal         = Hal;
    buffer->context     = Context;

    /* Maximum size of buffer. */
    buffer->size    = 0;
    buffer->maxSize = MaxSize;

    /* Zero the command buffers. */
    for (i = 0; i < gcmCOUNTOF(buffer->commandBuffers); ++i)
    {
        buffer->commandBuffers[i] = gcvNULL;
        buffer->signal[i]         = gcvNULL;
    }


    /***************************************************************************
    ** Query alignment.
    */

    gcmONERROR(gcoHARDWARE_QueryCommandBuffer(
        &buffer->info.alignment,
        &buffer->info.reservedHead,
        &buffer->info.reservedTail
        ));

    buffer->totalReserved
        = buffer->info.reservedHead
        + buffer->info.reservedTail
        + buffer->info.alignment;


    /***************************************************************************
    ** Initialize the command buffers.
    */

    for (i = 0; i < gcdCMD_BUFFERS; ++i)
    {
        /* Construct a command buffer. */
        gcmONERROR(gcoCMDBUF_Construct(
            gcvNULL,
            gcvNULL,
            buffer->maxSize,
            &buffer->info,
            &buffer->commandBuffers[i]
            ));

        /* Create the signal. */
        gcmONERROR(gcoOS_CreateSignal(
            gcvNULL, gcvFALSE, &buffer->signal[i]
            ));

        gcmTRACE_ZONE(
            gcvLEVEL_INFO, gcvZONE_SIGNAL,
            "%s(%d): buffer %d signal created 0x%08X",
            __FUNCTION__, __LINE__,
            i, buffer->signal[i]
            );

        /* Mark the buffer as available. */
        gcmONERROR(gcoOS_Signal(
            gcvNULL, buffer->signal[i], gcvTRUE\
            ));
    }

    /* Number of buffers initialized. */
    buffer->count = gcdCMD_BUFFERS;

    /* Grab the first command buffer. */
    buffer->currentCommandBuffer = gcvNULL;
    gcmONERROR(gcoBUFFER_GetCMDBUF(buffer));

    /* Return pointer to the gcoBUFFER object. */
    *Buffer = buffer;

    /* Success. */
    gcmFOOTER_ARG("*Buffer=0x%x", *Buffer);
    return gcvSTATUS_OK;

OnError:
    if (buffer != gcvNULL)
    {
        gcmVERIFY_OK(gcoBUFFER_FreeObjects(buffer));
    }

    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #16
0
/*******************************************************************************
**
**  gcoCMDBUF_Destroy
**
**  Destroy a gcoCMDBUF object.
**
**  INPUT:
**
**      gcoCMDBUF CommandBuffer
**          Pointer to an gcoCMDBUF object.
**
**  OUTPUT:
**
**      None.
*/
gceSTATUS
gcoCMDBUF_Destroy(
    IN gcoCMDBUF CommandBuffer
    )
{
    gceSTATUS status;
    gcsHAL_INTERFACE iface;

    gcmHEADER_ARG("CommandBuffer=0x%x", CommandBuffer);

    /* Verify the object. */
    gcmVERIFY_OBJECT(CommandBuffer, gcvOBJ_COMMANDBUFFER);

    if (CommandBuffer->logical != gcvNULL)
    {
        /* Use events to free the buffer. */
        iface.command = gcvHAL_FREE_CONTIGUOUS_MEMORY;
        iface.u.FreeContiguousMemory.bytes    = CommandBuffer->bytes;
        iface.u.FreeContiguousMemory.physical = CommandBuffer->physical;
        iface.u.FreeContiguousMemory.logical  = CommandBuffer->logical;

        /* Send event. */
        gcmONERROR(gcoHARDWARE_CallEvent(&iface));

        /* Reset the buffer pointer. */
        CommandBuffer->logical = gcvNULL;
    }

#if gcdSECURE_USER
    if (CommandBuffer->hintArray != gcvNULL)
    {
#ifdef __QNXNTO__
        gcmONERROR(gcoOS_FreeNonPagedMemory(
            gcvNULL,
            CommandBuffer->hintArraySize,
            gcvNULL,
            CommandBuffer->hintArray
            ));
#else
        gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, CommandBuffer->hintArray));
#endif

        CommandBuffer->hintArray =
        CommandBuffer->hintArrayTail = gcvNULL;
    }
#endif

    /* Free the gcoCMDBUF object. */
#ifdef __QNXNTO__
    gcmONERROR(gcoOS_FreeNonPagedMemory(
        gcvNULL, gcmSIZEOF(struct _gcoCMDBUF), gcvNULL, CommandBuffer
        ));
#else
    gcmONERROR(gcmOS_SAFE_FREE(gcvNULL, CommandBuffer));
#endif

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #17
0
/*******************************************************************************
**
**  gcoCMDBUF_Construct
**
**  Construct a new gcoCMDBUF object.
**
**  INPUT:
**
**      gcoOS Os
**          Pointer to a gcoOS object.
**
**      gcoHARDWARE Hardware
**          Pointer to a gcoHARDWARE object.
**
**      gctSIZE_T Bytes
**          Number of bytes for the buffer.
**
**      gcsCOMMAND_BUFFER_PTR Info
**          Alignment and head/tail information.
**
**  OUTPUT:
**
**      gcoCMDBUF * CommandBuffer
**          Pointer to a variable that will hold the the gcoCMDBUF object
**          pointer.
*/
gceSTATUS
gcoCMDBUF_Construct(
    IN gcoOS Os,
    IN gcoHARDWARE Hardware,
    IN gctSIZE_T Bytes,
    IN gcsCOMMAND_INFO_PTR Info,
    OUT gcoCMDBUF * CommandBuffer
    )
{
    gceSTATUS status;
    gcoCMDBUF commandBuffer = gcvNULL;
    gctSIZE_T objectSize;

#ifdef __QNXNTO__
    gctPHYS_ADDR physical;
#else
    gctPOINTER pointer = gcvNULL;
#endif

    gcmHEADER_ARG("Bytes=%lu Info=0x%x", Bytes, Info);

    /* Verify the arguments. */
    gcmDEBUG_VERIFY_ARGUMENT(Bytes > 0);
    gcmDEBUG_VERIFY_ARGUMENT(CommandBuffer != gcvNULL);

    /* Set the size of the object. */
    objectSize = gcmSIZEOF(struct _gcoCMDBUF);

    /* Allocate the gcoCMDBUF object. */
#ifdef __QNXNTO__
    /* gcoCMDBUF object needs to be accessible from the kernel; to avoid
       copying of the data for each access, allocate the object from the
       kernel non-paged memory. */
    gcmONERROR(gcoOS_AllocateNonPagedMemory(
        gcvNULL, gcvTRUE, &objectSize, &physical, (gctPOINTER *) &commandBuffer
        ));
#else
    /* Currently in most OS we are able to access the user-side data from
       the kernel by simple memory mapping, therefore here we allocate the
       object from the cached user memory. */
    gcmONERROR(gcoOS_Allocate(gcvNULL, objectSize, &pointer));

    commandBuffer = pointer;
#endif

    /* Reset the command buffer object. */
    gcmONERROR(gcoOS_ZeroMemory(commandBuffer, objectSize));

    /* Initialize the gcoCMDBUF object. */
    commandBuffer->object.type = gcvOBJ_COMMANDBUFFER;
    commandBuffer->bytes       = Bytes;

    /* Allocate the physical buffer for the command. */
    gcmONERROR(gcoOS_AllocateContiguous(
        gcvNULL, gcvTRUE,
        &commandBuffer->bytes,
        &commandBuffer->physical,
        &commandBuffer->logical
        ));

    /* Initialize command buffer. */
    commandBuffer->free = commandBuffer->bytes;

#if gcdSECURE_USER
    /* Determine the size of the state array. */
    commandBuffer->hintArraySize = Bytes;

    /* Allocate the state array. */
#ifdef __QNXNTO__
    gcmONERROR(gcoOS_AllocateNonPagedMemory(
        gcvNULL, gcvTRUE,
        &commandBuffer->hintArraySize,
        &physical,
        (gctPOINTER *) &commandBuffer->hintArray
        ));
#else
    gcmONERROR(gcoOS_Allocate(
        gcvNULL,
        commandBuffer->hintArraySize,
        &pointer
        ));

    commandBuffer->hintArray = pointer;
#endif

    /* Initialize the state array tail pointer. */
    commandBuffer->hintArrayTail = commandBuffer->hintArray;
#endif

    /* Return pointer to the gcoCMDBUF object. */
    *CommandBuffer = commandBuffer;

    /* Success. */
    gcmFOOTER_ARG("*CommandBuffer=0x%x", *CommandBuffer);
    return gcvSTATUS_OK;

OnError:
    /* Roll back. */
    if (commandBuffer != gcvNULL)
    {
        if (commandBuffer->logical != gcvNULL)
        {
            gcmVERIFY_OK(gcoOS_FreeContiguous(
                gcvNULL,
                commandBuffer->physical,
                commandBuffer->logical,
                commandBuffer->bytes
                ));
        }

#if gcdSECURE_USER
        if (commandBuffer->hintArray != gcvNULL)
        {
#ifdef __QNXNTO__
            gcmVERIFY_OK(gcoOS_FreeNonPagedMemory(
                gcvNULL,
                commandBuffer->hintArraySize,
                gcvNULL,
                commandBuffer->hintArray
                ));
#else
            gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, commandBuffer->hintArray));
#endif
        }
#endif

#ifdef __QNXNTO__
        gcmVERIFY_OK(gcoOS_FreeNonPagedMemory(
            gcvNULL, objectSize, gcvNULL, commandBuffer
            ));
#else
        gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, commandBuffer));
#endif
    }

    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #18
0
static gceSTATUS
gcoBUFFER_GetCMDBUF(
    IN gcoBUFFER Buffer
    )
{
    gceSTATUS status;
    gcoCMDBUF command;
    gctSIZE_T index;
    gcePIPE_SELECT entryPipe;

    gcmHEADER_ARG("Buffer=0x%x", Buffer);

    /* Determine the next command buffer. */
    if (Buffer->currentCommandBuffer == gcvNULL)
    {
        /* First time - get the first buffer. */
        index = 0;

        /* Select 3D pipe for the first buffer. */
        entryPipe = gcvPIPE_3D;
    }
    else
    {
        /* Get current entry pipe. */
        entryPipe = Buffer->currentCommandBuffer->entryPipe;

        /* Determine the next command buffer index. */
        index = (Buffer->currentCommandBufferIndex + 1) % Buffer->count;
    }

    /* Test if command buffer is available. */
    status = gcoOS_WaitSignal(gcvNULL,
                              Buffer->signal[index],
                              0);

    if (status == gcvSTATUS_TIMEOUT)
    {
        if (Buffer->count < gcdMAX_CMD_BUFFERS)
        {
            do
            {
                if (Buffer->commandBuffers[Buffer->count] == gcvNULL)
                {
                    /* Construct a command buffer. */
                    gcmERR_BREAK(gcoCMDBUF_Construct(
                        gcvNULL,
                        gcvNULL,
                        Buffer->maxSize,
                        &Buffer->info,
                        &Buffer->commandBuffers[Buffer->count]));
                }

                if (Buffer->signal[Buffer->count] == gcvNULL)
                {
                    /* Create the signal. */
                    gcmERR_BREAK(gcoOS_CreateSignal(
                        gcvNULL,
                        gcvFALSE,
                        &Buffer->signal[Buffer->count]));

                    gcmTRACE_ZONE(
                        gcvLEVEL_INFO, gcvZONE_SIGNAL,
                        "%s(%d): buffer %d signal created 0x%08X",
                        __FUNCTION__, __LINE__,
                        Buffer->count, Buffer->signal[Buffer->count]);
                }

                /* Mark the buffer as available. */
                gcmERR_BREAK(gcoOS_Signal(gcvNULL,
                                          Buffer->signal[Buffer->count],
                                          gcvTRUE));

                /* Use the new buffer. */
                index          = Buffer->count;
                Buffer->count += 1;

                gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_BUFFER,
                              "Using %lu command buffers.",
                              Buffer->count);
            }
            while (gcvFALSE);
        }

        /* Wait for buffer to become available. */
        gcmONERROR(gcoOS_WaitSignal(gcvNULL,
                                    Buffer->signal[index],
                                    gcPLS.hal->timeOut));
    }
    else
    {
        gcmONERROR(status);
    }

    /* Select new command buffer. */
    Buffer->currentCommandBufferIndex = index;
    Buffer->currentCommandBuffer      = Buffer->commandBuffers[index];

    /* Grab pointer to current command buffer. */
    command = Buffer->currentCommandBuffer;

    /* Set the entry pipe. */
    command->entryPipe = entryPipe;

    /* Reset command buffer. */
    command->startOffset = 0;
    command->offset      = Buffer->info.reservedHead;
    command->free        = command->bytes - Buffer->totalReserved;

    /* Succees. */
    gcmFOOTER_ARG("currentCommandBufferIndex=%d",
                  Buffer->currentCommandBufferIndex);
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #19
0
gceSTATUS
gcoQUEUE_Construct(
    IN gcoOS Os,
    OUT gcoQUEUE * Queue
    )
{
    gcoQUEUE queue = gcvNULL;
    gceSTATUS status;
#ifdef __QNXNTO__
    gctSIZE_T allocationSize;
    gctPHYS_ADDR physAddr;
#endif
    gctPOINTER pointer = gcvNULL;

    gcmHEADER();

    /* Verify the arguments. */
    gcmVERIFY_ARGUMENT(Queue != gcvNULL);

    /* Create the queue. */
    gcmONERROR(
        gcoOS_Allocate(gcvNULL,
                       gcmSIZEOF(struct _gcoQUEUE),
                       &pointer));
    queue = pointer;

    /* Initialize the object. */
    queue->object.type = gcvOBJ_QUEUE;

    /* Nothing in the queue yet. */
    queue->head = queue->tail = gcvNULL;

    queue->recordCount = 0;

#ifdef __QNXNTO__
    /* Allocate buffer of records. */
    allocationSize = BUFFER_SIZE;
    physAddr = 0;
    gcmONERROR(
        gcoOS_AllocateNonPagedMemory(gcvNULL,
                                     gcvTRUE,
                                     &allocationSize,
                                     &physAddr,
                                     (gctPOINTER *) &queue->records));
    queue->freeBytes = allocationSize;
    queue->offset = 0;
#else
    queue->freeList = gcvNULL;
#endif

    /* Return gcoQUEUE pointer. */
    *Queue = queue;

    /* Success. */
    gcmFOOTER_ARG("*Queue=0x%x", *Queue);
    return gcvSTATUS_OK;

OnError:
    if (queue != gcvNULL)
    {
        /* Roll back. */
        gcmVERIFY_OK(gcmOS_SAFE_FREE(gcvNULL, queue));
    }

    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #20
0
ファイル: gc_egl.c プロジェクト: Astralix/hardware_drivers
VEGLThreadData
veglGetThreadData(
    void
    )
{
    gcsTLS_PTR tls = gcvNULL;
    gceSTATUS status;
#if gcdENABLE_VG
    gctINT32 i;
#endif
    gcmHEADER();

    gcmONERROR(gcoOS_GetTLS(&tls));

    if (tls->context == gcvNULL)
    {
        gctPOINTER pointer = gcvNULL;
        VEGLThreadData thread;

        gcmONERROR(gcoOS_Allocate(
            gcvNULL, gcmSIZEOF(struct eglThreadData), &pointer
            ));

        gcmONERROR(gcoOS_ZeroMemory(
            pointer, gcmSIZEOF(struct eglThreadData)
            ));

        /* Initialize TLS record. */
        tls->context    = pointer;
        tls->destructor = _DestroyThreadData;

        /* Cast the pointer. */
        thread = (VEGLThreadData) pointer;

        /* Initialize the thread data. */
        thread->error             = EGL_SUCCESS;
        thread->api               = EGL_OPENGL_ES_API;
        thread->lastClient        = 1;
		thread->worker = gcvNULL;

        tls->currentType           = gcvHARDWARE_3D;
#if veglUSE_HAL_DUMP
        /* Get the gcoDUMP object. */
        gcmONERROR(gcoHAL_GetDump(thread->hal, &thread->dump));
#endif

#if gcdENABLE_VG
        gcmONERROR(gcoHAL_QueryChipCount(gcvNULL, &thread->chipCount));

        for (i = 0; i < thread->chipCount; i++)
        {
            gcmONERROR(gcoHAL_QueryChipLimits(gcvNULL, i, &thread->chipLimits[i]));
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            thread->maxWidth =
                gcmMAX(thread->maxWidth, (gctINT32)thread->chipLimits[i].maxWidth);

            thread->maxHeight =
                gcmMAX(thread->maxHeight, (gctINT32)thread->chipLimits[i].maxHeight);

            thread->maxSamples =
                gcmMAX(thread->maxSamples, (gctINT32)thread->chipLimits[i].maxSamples);
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            /* Query VAA support. */
            if (gcoHAL_QueryChipFeature(gcvNULL, i, gcvFEATURE_VAA))
            {
                thread->vaa = gcvTRUE;
                break;
            }
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            if (gcoHAL_QueryChipFeature(gcvNULL, i, gcvFEATURE_PIPE_VG))
            {
                thread->openVGpipe = _IsHWVGDriverAvailable(thread);
                break;
            }
        }
#else
        /* Query the hardware identity. */
        gcmONERROR(gcoHAL_QueryChipIdentity(
            gcvNULL,
            &thread->chipModel,
            gcvNULL, gcvNULL, gcvNULL
            ));

        /* Query the hardware capabilities. */
        gcmONERROR(gcoHAL_QueryTargetCaps(
            gcvNULL,
            (gctUINT32_PTR) &thread->maxWidth,
            (gctUINT32_PTR) &thread->maxHeight,
            gcvNULL,
            (gctUINT32_PTR) &thread->maxSamples
            ));

        /* Query VAA support. */
        thread->vaa
            =  gcoHAL_IsFeatureAvailable(gcvNULL, gcvFEATURE_VAA)
            == gcvSTATUS_TRUE;

        /* Query OpenVG pipe support. */
        thread->openVGpipe
            =  gcoHAL_IsFeatureAvailable(gcvNULL, gcvFEATURE_PIPE_VG)
            == gcvSTATUS_TRUE;
#endif

        gcmTRACE_ZONE(
            gcvLEVEL_VERBOSE, gcdZONE_EGL_API,
            "%s(%d): maxWidth=%d maxHeight=%d maxSamples=%d vaa=%d openVG=%d",
            __FUNCTION__, __LINE__,
            thread->maxWidth, thread->maxHeight, thread->maxSamples,
            thread->vaa, thread->openVGpipe
            );
    }
コード例 #21
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList(
    ppoPREPROCESSOR     PP,
    ppoINPUT_STREAM     *IS,
    ppoTOKEN            *Head,
    ppoTOKEN            *End,
    gctBOOL             *AnyExpanationHappened,
    ppoTOKEN            *ExpandedHeadTail,
    ppoTOKEN            ID,
    ppoMACRO_SYMBOL     MS
    )
{

    ppoTOKEN id = ID;

    ppoMACRO_SYMBOL ms = MS;

    ppoTOKEN replacement_list = gcvNULL;

    ppoTOKEN *expandedheadtail = ExpandedHeadTail;

    gceSTATUS status = gcvSTATUS_INVALID_DATA;

    gctBOOL pasting = gcvFALSE;

    gcmTRACE(gcvLEVEL_VERBOSE, "ME : begin to expand replacement-list.");

    ppoTOKEN_ColonTokenList(
        PP,
        ms->replacementList,
        __FILE__,
        __LINE__,
        "ppoPREPROCESSOR_MacroExpand : Colon the replacement list.",
        &replacement_list
        );

    while(replacement_list)
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : add to rp-list %s's hs.", replacement_list->poolString);

        ppoHIDE_SET_AddHS(PP, replacement_list, id->poolString);

        if (replacement_list->type == ppvTokenType_ID)
        {
            gctINT whereisarg = -1;

            ppoTOKEN search_formal_arg = ms->argv;

            status = ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList_GetPositionOfNode(
                PP,
                replacement_list,
                &whereisarg,
                &search_formal_arg);

            if(status != gcvSTATUS_OK) return status;

            gcmTRACE(gcvLEVEL_VERBOSE,
                "ME : find the position(%d) in argv to rp-list %s's hs.",
                whereisarg,
                replacement_list->poolString);

            gcmASSERT(whereisarg < ms->argc);

            if(search_formal_arg)
            {
                ppoTOKEN tmphead = gcvNULL;
                ppoTOKEN tmpend  = gcvNULL;

                if(expandedheadtail[whereisarg*2 + 1])
                {
                    (expandedheadtail[whereisarg*2 + 1])->inputStream.base.node.prev = gcvNULL;
                }

                gcmTRACE(gcvLEVEL_VERBOSE, "ME : rp-list node : %s, is a formal arg.", replacement_list->poolString);

                ppoTOKEN_ColonTokenList(
                    PP,
                    expandedheadtail[whereisarg*2],
                    __FILE__,
                    __LINE__,
                    "ppoPREPROCESSOR_MacroExpand : Creat a list of the tokenlist expanded out by the actual arguments.",
                    &tmphead
                    );

                tmpend = tmphead;

                gcmTRACE(gcvLEVEL_VERBOSE, "ME : add hs to output nodes.");

                while(tmpend)
                {
                    ppoHIDE_SET_LIST_Append(
                        PP,
                        tmpend,
                        id);

                    ppoHIDE_SET_AddHS(PP, tmpend, id->poolString);

                    if(tmpend->inputStream.base.node.prev == gcvNULL)
                    {
                        break;
                    }

                    tmpend = (ppoTOKEN)tmpend->inputStream.base.node.prev;
                }


                gcmTRACE(gcvLEVEL_VERBOSE,
                    "ME : replacementList : add the expanded node to output.",
                    replacement_list->poolString);

                if(pasting)
                {
                    status = ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList_MergePastingTokenName(
                        PP,
                        (*End),
                        tmphead,
                        &(*End)->poolString
                        );

                    pasting = gcvFALSE;
                }
                else
                {
                    status = ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList_AddToOut(
                        PP,
                        tmphead,
                        tmpend,
                        Head,
                        End
                        );
                }

                if(status != gcvSTATUS_OK) return status;


                do
                {
                    ppoTOKEN tmp = replacement_list;

                    replacement_list = (ppoTOKEN)replacement_list->inputStream.base.node.prev;

                    gcmONERROR(ppoTOKEN_Destroy(PP, tmp));
                }
                while(gcvFALSE);

                continue;

            }/*not found in argv*/
            else
            {
                gcmTRACE(
                    gcvLEVEL_VERBOSE,
                    "ME : replacementList node: %s,inputStream not a formal arg.",
                    replacement_list->poolString);
            }
        }/*if(replacementList->type == ppvTokenType_ID)*/
        else
        {
            if(pasting)
            {
                status = ppoPREPROCESSOR_MacroExpand_7_ParseReplacementList_MergePastingTokenName(
                    PP,
                    (*End),
                    replacement_list,
                    &(*End)->poolString
                    );

                pasting = gcvFALSE;
                replacement_list = (ppoTOKEN)replacement_list->inputStream.base.node.prev;
                continue;
            }
            else if(replacement_list->poolString == PP->keyword->sharp &&
                (ppoTOKEN)replacement_list->inputStream.base.node.prev != gcvNULL)
            {
                ppoTOKEN tmprplst = replacement_list;
                tmprplst = (ppoTOKEN)tmprplst->inputStream.base.node.prev;

                /* ## */
                if(tmprplst->poolString == PP->keyword->sharp &&
                    tmprplst->inputStream.base.node.prev != gcvNULL)
                {
                    replacement_list = (ppoTOKEN)tmprplst->inputStream.base.node.prev;
                    pasting = gcvTRUE;
                    continue;
                }
            }
        }

        gcmTRACE(gcvLEVEL_VERBOSE,
            "ME : node in replacementList(%s0,not an ID or not a formal arg.",
            replacement_list->poolString);
        do
        {
            ppoTOKEN tmprplst = replacement_list;

            if( (*Head) == gcvNULL )
            {
                *Head = replacement_list;
                *End  = replacement_list;
            }
            else
            {
                (*End)->inputStream.base.node.prev = (void *)replacement_list;

                replacement_list->inputStream.base.node.next    = (void *)(*End);

                (*End) = replacement_list;
            }

            replacement_list = (ppoTOKEN)tmprplst->inputStream.base.node.prev;
        }
        while(gcvFALSE);

    }/*while(replacementList)*/

    if(*End)
    {
        (*End)->inputStream.base.node.prev = gcvNULL;
    }

    *AnyExpanationHappened = gcvTRUE;

    return gcvSTATUS_OK;

OnError:
	return status;
}
コード例 #22
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_2_NoFormalArgs(
    ppoPREPROCESSOR     PP,
    ppoINPUT_STREAM     *IS,
    ppoTOKEN            *Head,
    ppoTOKEN            *End,
    gctBOOL             *AnyExpanationHappened,
    gctBOOL             *MatchCase,
    ppoTOKEN            ID,
    ppoMACRO_SYMBOL     MS)
{
    gceSTATUS status = gcvSTATUS_INVALID_DATA;

    ppoTOKEN id = ID;

    ppoMACRO_SYMBOL ms = MS;

    ppoTOKEN replacement_list = gcvNULL;

    gcmHEADER_ARG("PP=0x%x IS=0x%x Head=0x%x End=0x%x AnyExpanationHappened=0x%x MatchCase=0x%x ID=0x%x MS=0x%x",
                  PP, IS, Head, End, AnyExpanationHappened, MatchCase, ID, MS);

    gcmASSERT(ms != gcvNULL);

    if (ms->argc == 0)
    {
        gcmTRACE(gcvLEVEL_VERBOSE, "ME : macro %s has no arg(s).",id->poolString);

        if (ms->replacementList == gcvNULL)
        {
            gcmTRACE(gcvLEVEL_VERBOSE, "ME : macro %s, has no replacement-list.",id->poolString);

            *Head = gcvNULL;
            *End  = gcvNULL;
            *AnyExpanationHappened = gcvTRUE;
            *MatchCase = gcvTRUE;

            status = ppoTOKEN_Destroy(PP,id);

            if (gcmIS_SUCCESS(status))
            {
                gcmFOOTER_ARG("*Head=0x%x *End=0x%x *AnyExpanationHappened=%d *MatchCase=%d",
                              *Head, *End, *AnyExpanationHappened, *MatchCase);
                return gcvSTATUS_OK;
            }
            else
            {
                gcmFOOTER();
                return status;
            }
        }

        gcmTRACE(gcvLEVEL_VERBOSE, "ME : macro %s, has replacement-list.",id->poolString);

        gcmTRACE(gcvLEVEL_VERBOSE, "ME : macro %s, colon replacement-list.",id->poolString);

        gcmONERROR(ppoTOKEN_ColonTokenList(
            PP,
            ms->replacementList,
            __FILE__,
            __LINE__,
            "ME : colon replacementList",
            &replacement_list)
            );

        *Head = replacement_list;

        gcmTRACE(gcvLEVEL_VERBOSE, "ME : macro %s, add hs.",id->poolString);

        while(replacement_list)
        {
            gcmASSERT(replacement_list->hideSet == gcvNULL);

            ppoHIDE_SET_LIST_Append(
                PP,
                replacement_list,
                id);

            ppoHIDE_SET_AddHS(PP, replacement_list, id->poolString);

            if((void*)replacement_list->inputStream.base.node.prev == gcvNULL)
            {
                *End = replacement_list;
            }

            replacement_list = (ppoTOKEN)replacement_list->inputStream.base.node.prev;
        }

        *AnyExpanationHappened = gcvTRUE;

        *MatchCase = gcvTRUE;

        status = ppoTOKEN_Destroy(PP,id);

        if (gcmIS_SUCCESS(status))
        {
            gcmFOOTER_ARG("*Head=0x%x *End=0x%x *AnyExpanationHappened=%d *MatchCase=%d",
                          *Head, *End, *AnyExpanationHappened, *MatchCase);
            return gcvSTATUS_OK;
        }
        else
        {
            gcmFOOTER();
            return status;
        }

    }
    else/*if (ms->argc == 0)*/
    {
        *Head   = gcvNULL;
        *End    = gcvNULL;
        *AnyExpanationHappened = gcvFALSE;
        *MatchCase = gcvFALSE;

        gcmFOOTER_ARG("*Head=0x%x *End=0x%x *AnyExpanationHappened=%d *MatchCase=%d",
                      *Head, *End, *AnyExpanationHappened, *MatchCase);
        return gcvSTATUS_OK;
    }

OnError:
    gcmFOOTER();
	return status;
}
コード例 #23
0
/*******************************************************************************
**
**  gcoBUFFER_Reserve
**
**  Reserve a number of bytes in the buffer.
**
**  INPUT:
**
**      gcoBUFFER Buffer
**          Pointer to an gcoBUFFER object.
**
**      gctSIZE_T Bytes
**          Number of bytes to reserve.
**
**      gctBOOL Aligned
**          gcvTRUE if the data needs to be aligned to 64-bit.
**
**  OUTPUT:
**
**      gctUINT32_PTR ** AddressHints
**          Pointer to a variable that receives the current position in the
**          state hint array.  gcvNULL is allowed.
**
**      gctPOINTER * Memory
**          Pointer to a variable that will hold the address of location in the
**          buffer that has been reserved.
*/
gceSTATUS
gcoBUFFER_Reserve(
    IN gcoBUFFER Buffer,
    IN gctSIZE_T Bytes,
    IN gctBOOL Aligned,
    OUT gcoCMDBUF * Reserve
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gcoCMDBUF current;
    gctSIZE_T alignBytes, bytes;
    gctUINT offset;

    gcmHEADER_ARG("Buffer=0x%x Bytes=%lu Aligned=%d Reserve=0x%x",
                  Buffer, Bytes, Aligned, Reserve);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Buffer, gcvOBJ_BUFFER);
    gcmDEBUG_VERIFY_ARGUMENT(Reserve != gcvNULL);

    /* Get the current command buffer. */
    current = Buffer->currentCommandBuffer;

    /* Compute the number of aligned bytes. */
    alignBytes = Aligned
               ? ( gcmALIGN(current->offset, Buffer->info.alignment)
                 - current->offset
                 )
               : 0;

    /* Compute the number of required bytes. */
    bytes = Bytes + alignBytes;

    if (bytes > current->free)
    {
        gcsHAL_INTERFACE iface;

        if (bytes > Buffer->maxSize - Buffer->totalReserved)
        {
            /* This just won't fit! */
            gcmFATAL("FATAL: Command of %lu bytes is too big!", Bytes);
            gcmONERROR(gcvSTATUS_OUT_OF_MEMORY);
        }

        /* Sent event to signal when command buffer completes. */
        iface.command            = gcvHAL_SIGNAL;
        iface.u.Signal.signal    = Buffer->signal
                                   [Buffer->currentCommandBufferIndex];
        iface.u.Signal.auxSignal = gcvNULL;
        iface.u.Signal.process   = gcoOS_GetCurrentProcessID();
        iface.u.Signal.fromWhere = gcvKERNEL_COMMAND;

        /* Send event. */
        gcmONERROR(
            gcoHARDWARE_CallEvent(&iface));

        /* Commit current command buffer. */
        gcmONERROR(
            gcoHARDWARE_Commit());

        /* Grab a new command buffer. */
        gcmONERROR(
            gcoBUFFER_GetCMDBUF(Buffer));

        /* Get the pointer. */
        current = Buffer->currentCommandBuffer;

        /* Calculate total bytes again. */
        alignBytes = 0;
        bytes      = Bytes;
    }

    gcmASSERT(current != gcvNULL);
    gcmASSERT(bytes   <= current->free);

    /* Determine the data offset. */
    offset = current->offset + alignBytes;

    /* Update the last reserved location. */
    current->lastReserve = (gctUINT8_PTR) current->logical + offset;
    current->lastOffset  = offset;

    /* Adjust command buffer size. */
    current->offset += bytes;
    current->free   -= bytes;

    /* Set the result. */
    * Reserve = current;

    /* Success. */
    gcmFOOTER();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #24
0
gceSTATUS
ppoPREPROCESSOR_MacroExpand_5_BufferRealArgs(
    ppoPREPROCESSOR     PP,
    ppoINPUT_STREAM     *IS,
    ppoTOKEN            *HeadTail,
    ppoTOKEN            ID,
    ppoMACRO_SYMBOL     MS
    )
{
    gceSTATUS status;

    ppoTOKEN id = ID;

    ppoMACRO_SYMBOL ms = MS;

    ppoTOKEN ahead = gcvNULL;

    gctINT real_argc;

    gcmONERROR(
        (*IS)->GetToken(PP, IS, &ahead, !ppvICareWhiteSpace)
        );

    gcmTRACE(gcvLEVEL_VERBOSE, "ME : %s, buffer real-arg(s).", id->poolString);

    real_argc = 0;

    while (ahead->poolString != PP->keyword->rpara)
    {
        gcmONERROR(ppoTOKEN_Destroy(PP, ahead));
        ahead = gcvNULL;

        if (real_argc < ms->argc)
        {
            gcmTRACE(gcvLEVEL_VERBOSE, "ME : %s, buffer the %dth arg.", id->poolString, real_argc);

            ppoPREPROCESSOR_BufferActualArgs(
                PP,
                IS,
                &(HeadTail[real_argc*2]),
                &(HeadTail[real_argc*2+1])
                );

            gcmASSERT(
                ((HeadTail[real_argc*2] == gcvNULL) && (HeadTail[real_argc*2 + 1] == gcvNULL))
                ||
                ((HeadTail[real_argc*2] != gcvNULL) && (HeadTail[real_argc*2 + 1] != gcvNULL))
                );

            ++ real_argc;
        }
        else
        {
            ppoTOKEN no_use_head = gcvNULL;
            ppoTOKEN no_use_end  = gcvNULL;

            ppoPREPROCESSOR_BufferActualArgs(
                PP,
                IS,
                &no_use_head,
                &no_use_end
                );

            ++ real_argc;
        }

        if (*IS)
        {
            (*IS)->GetToken(PP, IS, &ahead, !ppvICareWhiteSpace);
        }
        else
        {
            ppoPREPROCESSOR_Report(
                PP,
                slvREPORT_ERROR,
                "unexpected end of file when expand the macro %s.",
                id->poolString);

            return gcvSTATUS_INVALID_DATA;
        }

        if (ahead->poolString != PP->keyword->rpara &&
            ahead->poolString != PP->keyword->comma)
        {

            if(ahead->poolString == PP->keyword->eof)
            {

                ppoPREPROCESSOR_Report(
                    PP,
                    slvREPORT_ERROR,
                    " unexpected end of file when expand the macro %s.",
                    id->poolString);
            }
            else
            {
                ppoPREPROCESSOR_Report(
                    PP,
                    slvREPORT_ERROR,
                    " unexpected token when expand the macro %s.",
                    id->poolString);
            }

            gcmONERROR(
                ppoTOKEN_Destroy(PP, id)
                );

            gcmONERROR(
                ppoTOKEN_Destroy(PP, ahead)
                );

            return gcvSTATUS_INVALID_DATA;
        }
    }/*while (ahead->poolString != PP->keyword->rpara)*/

    gcmONERROR(
        ppoTOKEN_Destroy(PP, ahead)
        );
    ahead = gcvNULL;

    if(real_argc < ms->argc)
    {
        ppoPREPROCESSOR_Report(
            PP,
            slvREPORT_WARN,
            "not enough actual parameters for macro '%s'.",
            id->poolString);
    }

    if(real_argc > ms->argc)
    {

        ppoPREPROCESSOR_Report(
            PP,
            slvREPORT_ERROR,
            "too many actual parameters for macro '%s'.",
            id->poolString);
    }

    gcmTRACE(gcvLEVEL_VERBOSE, "ME : %s,finish real-arg(s)-buffering.", id->poolString);

    return gcvSTATUS_OK;
OnError:
    if (ahead != gcvNULL)
    {
        gcmVERIFY_OK(ppoTOKEN_Destroy(PP, ahead));
        ahead = gcvNULL;
    }
	return status;
}
コード例 #25
0
gceSTATUS
gcoQUEUE_AppendEvent(
    IN gcoQUEUE Queue,
    IN gcsHAL_INTERFACE * Interface
    )
{
    gceSTATUS status;
    gcsQUEUE_PTR record = gcvNULL;
#ifdef __QNXNTO__
    gctSIZE_T allocationSize;
    gctPHYS_ADDR physAddr;
#else
    gctPOINTER pointer = gcvNULL;
#endif

    gcmHEADER_ARG("Queue=0x%x Interface=0x%x", Queue, Interface);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);
    gcmVERIFY_ARGUMENT(Interface != gcvNULL);

    /* Allocate record. */
#ifdef __QNXNTO__
    allocationSize = gcmSIZEOF(gcsQUEUE);
    if (Queue->freeBytes < allocationSize)
    {
        gctSIZE_T recordsSize = BUFFER_SIZE;
        gcsQUEUE_PTR prevRecords = Queue->records;
        gcsHAL_INTERFACE iface;

        /* Allocate new set of records. */
        gcmONERROR(
            gcoOS_AllocateNonPagedMemory(gcvNULL,
                                         gcvTRUE,
                                         &recordsSize,
                                         &physAddr,
                                         (gctPOINTER *) &Queue->records));
        Queue->freeBytes = recordsSize;
        Queue->offset = 0;

        if ( Queue->freeBytes < allocationSize )
        {
            gcmFOOTER_ARG("status=%d", gcvSTATUS_DATA_TOO_LARGE);
            return gcvSTATUS_DATA_TOO_LARGE;
        }

        /* Schedule to free Queue->records,
         * hence not unmapping currently scheduled events immediately. */
        iface.command = gcvHAL_FREE_NON_PAGED_MEMORY;
        iface.u.FreeNonPagedMemory.bytes = BUFFER_SIZE;
        iface.u.FreeNonPagedMemory.physical = 0;
        iface.u.FreeNonPagedMemory.logical = prevRecords;

        gcmONERROR(
            gcoQUEUE_AppendEvent(Queue, &iface));
    }

    record = (gcsQUEUE_PTR)((gctUINT32)Queue->records + Queue->offset);
    Queue->offset += allocationSize;
    Queue->freeBytes -= allocationSize;
#else
    /* Check if we have records on the free list. */
    if (Queue->freeList != gcvNULL)
    {
        /* Allocate from hte free list. */
        record          = Queue->freeList;
        Queue->freeList = record->next;
    }
    else
    {
        gcmONERROR(gcoOS_Allocate(gcvNULL,
                       gcmSIZEOF(gcsQUEUE),
                                  &pointer));
        record = pointer;
    }
#endif

    /* Initialize record. */
    record->next  = gcvNULL;
    gcoOS_MemCopy(&record->iface, Interface, gcmSIZEOF(record->iface));

    if (Queue->head == gcvNULL)
    {
        /* Initialize queue. */
        Queue->head = record;
    }
    else
    {
        /* Append record to end of queue. */
        Queue->tail->next = record;
    }

    /* Mark end of queue. */
    Queue->tail = record;

    /* update count */
    Queue->recordCount++;

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
#ifndef __QNXNTO__
    if (pointer != gcvNULL)
    {
        /* Put record on free list. */
        record->next    = Queue->freeList;
        Queue->freeList = record;
    }
#endif

    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #26
0
/*******************************************************************************
**
**  gcoHAL_Construct
**
**  Construct a new gcoHAL object.
**
**  INPUT:
**
**      gctPOINTER Context
**          Pointer to a context that can be used by the platform specific
**          functions.
**
**      gcoOS Os
**          Pointer to an gcoOS object.
**
**  OUTPUT:
**
**      gcoHAL * Hal
**          Pointer to a variable that will hold the gcoHAL object pointer.
*/
gceSTATUS
gcoHAL_Construct(
    IN gctPOINTER Context,
    IN gcoOS Os,
    OUT gcoHAL * Hal
    )
{
    gctBOOL created = gcvFALSE;
    gcoHAL hal = gcPLS.hal;
    gceSTATUS status;
    gctPOINTER pointer = gcvNULL;
    gctBOOL separated3D = gcvFALSE;
    gctBOOL separated2D = gcvFALSE;
    gcsHAL_INTERFACE iface;
    gctINT32 i;

    gcmHEADER_ARG("Context=0x%x OS=0x%x", Context, Os);

    /* Verify the arguments. */
    gcmDEBUG_VERIFY_ARGUMENT(Hal != gcvNULL);

    if (hal == gcvNULL)
    {
        /* Create the gcoHAL object. */
        gcmONERROR(gcoOS_Allocate(gcvNULL,
                                  gcmSIZEOF(struct _gcoHAL),
                                  &pointer));
        hal     = pointer;
        created = gcvTRUE;

        gcoOS_ZeroMemory(hal, gcmSIZEOF(struct _gcoHAL));

        /* Initialize the object. */
        hal->object.type = gcvOBJ_HAL;

        /* Zero the gco2D, gco3D, and gcoDUMP objects. */
        hal->dump      = gcvNULL;
        hal->reference = gcvNULL;

        /* Initialize timeOut value */
        hal->timeOut     = gcdGPU_TIMEOUT;

        /* Query the kernel version number. */
        iface.command = gcvHAL_VERSION;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        /* Test if versions match. */
        if ((iface.u.Version.major != gcvVERSION_MAJOR)
        ||  (iface.u.Version.minor != gcvVERSION_MINOR)
        ||  (iface.u.Version.patch != gcvVERSION_PATCH)
        ||  (iface.u.Version.build != gcvVERSION_BUILD)
        )
        {
            gcmPRINT("HAL user version %d.%d.%d build %u %s %s",
                     gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                     gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
            gcmPRINT("HAL kernel version %d.%d.%d build %u",
                     iface.u.Version.major, iface.u.Version.minor,
                     iface.u.Version.patch, iface.u.Version.build);

            gcmONERROR(gcvSTATUS_VERSION_MISMATCH);
        }

#if gcmIS_DEBUG(gcdDEBUG_TRACE)
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL user version %d.%d.%d build %u %s %s",
                  gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                  gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL kernel version %d.%d.%d build %u",
                  iface.u.Version.major, iface.u.Version.minor,
                  iface.u.Version.patch, iface.u.Version.build);
#endif

        /* Query chip info */
        iface.command = gcvHAL_CHIP_INFO;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        hal->chipCount = iface.u.ChipInfo.count;

        for (i = 0; i < hal->chipCount; i++)
        {
            hal->chipTypes[i] = iface.u.ChipInfo.types[i];

            switch (hal->chipTypes[i])
            {
            case gcvHARDWARE_3D:
                separated3D = gcvTRUE;
                break;
            case gcvHARDWARE_2D:
                separated2D = gcvTRUE;
                break;
            default:
                break;
            }
        }

        hal->separated3D2D = (separated3D && separated2D);

#if VIVANTE_PROFILER
        hal->profiler.enable = 0;
#endif

        /* Create reference. */
        gcmONERROR(gcoOS_AtomConstruct(Os, &hal->reference));
    }
コード例 #27
0
/*******************************************************************************
**
**  gcoBUFFER_Commit
**
**  Commit the command buffer to the hardware.
**
**  INPUT:
**
**      gcoBUFFER Buffer
**          Pointer to a gcoBUFFER object.
**
**      gcePIPE_SELECT CurrentPipe
**          Current graphics pipe.
**
**      gcsSTATE_DELTA_PTR StateDelta
**          Pointer to the state delta.
**
**      gcoQUEUE Queue
**          Pointer to a gcoQUEUE object.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoBUFFER_Commit(
    IN gcoBUFFER Buffer,
    IN gcePIPE_SELECT CurrentPipe,
    IN gcsSTATE_DELTA_PTR StateDelta,
    IN gcoQUEUE Queue
    )
{
    gcsHAL_INTERFACE iface;
    gceSTATUS status;
    gcoCMDBUF current;

    gcmHEADER_ARG("Buffer=0x%x Queue=0x%x",
                  Buffer, Queue);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Buffer, gcvOBJ_BUFFER);
    gcmVERIFY_OBJECT(Queue, gcvOBJ_QUEUE);

    /* Grab current command buffer. */
    current = Buffer->currentCommandBuffer;

    if (current == gcvNULL)
    {
        /* No command buffer, done. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    if (current->offset - current->startOffset <= Buffer->info.reservedHead)
    {
        /* Commit the event queue. */
        status = gcoQUEUE_Commit(Queue);
        gcmFOOTER();
        return status;
    }

    /* Make sure the tail got aligned properly. */
    current->offset = gcmALIGN(current->offset, Buffer->info.alignment);

    if (gcPLS.hal->dump != gcvNULL)
    {
        /* Dump the command buffer. */
        gcmVERIFY_OK(
            gcoDUMP_DumpData(gcPLS.hal->dump,
                             gcvTAG_COMMAND,
                             0,
                             current->offset
                             - current->startOffset
                             - Buffer->info.reservedHead,
                             (gctUINT8_PTR) current->logical
                             + current->startOffset
                             + Buffer->info.reservedHead));
    }

    /* The current pipe becomes the exit pipe for the current command buffer. */
    current->exitPipe = CurrentPipe;

    /* Send command and context buffer to hardware. */
    iface.command = gcvHAL_COMMIT;
    iface.u.Commit.context       =
#ifndef VIVANTE_NO_3D
        (current->using2D && !current->using3D) ? gcvNULL : Buffer->context;
#else
        gcvNULL;
#endif

    iface.u.Commit.commandBuffer = current;
    iface.u.Commit.delta         = StateDelta;
    iface.u.Commit.queue         = Queue->head;

    /* Call kernel service. */
    gcmONERROR(
        gcoOS_DeviceControl(gcvNULL,
                            IOCTL_GCHAL_INTERFACE,
                            &iface, gcmSIZEOF(iface),
                            &iface, gcmSIZEOF(iface)));

    gcmONERROR(iface.status);

    /* Free the event queue. */
    gcmONERROR(gcoQUEUE_Free(Queue));

    /* Advance the offset for next commit. */
    current->startOffset = current->offset + Buffer->info.reservedTail;

    if (current->bytes - current->startOffset > Buffer->totalReserved)
    {
        /* Adjust buffer offset and size. */
        current->offset = current->startOffset + Buffer->info.reservedHead;
        current->free   = current->bytes - current->offset
                        - Buffer->info.alignment
                        - Buffer->info.reservedTail;
    }
    else
    {
        /* Buffer is full. */
        current->startOffset = current->bytes;
        current->offset      = current->bytes;
        current->free        = 0;
    }

    /* The exit pipe becomes the entry pipe for the next command buffer. */
    current->entryPipe = current->exitPipe;

#if gcdSECURE_USER
    /* Reset the state array tail. */
    current->hintArrayTail = current->hintArray;
#endif

    /* Reset usage flags. */
    current->using2D         = gcvFALSE;
    current->using3D         = gcvFALSE;
    current->usingFilterBlit = gcvFALSE;
    current->usingPalette    = gcvFALSE;

    /* Success. */
    gcmFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
コード例 #28
0
static gceSTATUS
_DuplicateBufferData(
    glsCONTEXT_PTR Context,
    glsBUFFER_PTR  Buffer,
    gctBOOL ArrayToElement
    )
{
    gceSTATUS  status = gcvSTATUS_OK;
    gctPOINTER address = gcvNULL;
    gctBOOL streamLocked = gcvFALSE;
    gctBOOL indexLocked  = gcvFALSE;

    gcmASSERT(Context != gcvNULL);
    gcmASSERT(Buffer  != gcvNULL);

    if (Buffer->size <= 0)
    {
        return status;
    }

    if (ArrayToElement)
    {
        if (Buffer->stream == gcvNULL)
        {
            return status;
        }

        /* Construct an index object if not present. */
        if (!Buffer->index)
        {
            gcmONERROR(gcoINDEX_Construct(Context->hal, &Buffer->index));
        }

        /* Get memory of array buffer. */
        gcmONERROR(gcoSTREAM_Lock(Buffer->stream, &address, gcvNULL));

        if (address != gcvNULL)
        {
            streamLocked = gcvTRUE;

            /* Upload to index. */
            gcmONERROR(gcoINDEX_Upload(Buffer->index, address, Buffer->size));
        }
    }
    else
    {
        if (Buffer->index == gcvNULL)
        {
            return status;
        }

        /* Construct a stream if no present. */
        if (Buffer->stream == gcvNULL)
        {
            gcmONERROR(gcoSTREAM_Construct(Context->hal, &Buffer->stream));
        }

        /* Reserve enough memory. */
        gcmONERROR(gcoSTREAM_Reserve(Buffer->stream, Buffer->size));

        /* Get memory of index buffer. */
        gcmONERROR(gcoINDEX_Lock(Buffer->index, gcvNULL, &address));

        if (address != gcvNULL)
        {
            indexLocked = gcvTRUE;

            /* Upload data into stream. */
            gcmONERROR(gcoSTREAM_Upload(Buffer->stream,
                                        address,
                                        0,
                                        Buffer->size,
                                        Buffer->usage == GL_DYNAMIC_DRAW));
        }
    }

#if gcdUSE_TRIANGLE_STRIP_PATCH
    Buffer->stripPatchDirty = gcvTRUE;
#endif

OnError:
    /* Unlock the stream object. */
    if (streamLocked)
    {
        gcmVERIFY_OK(gcoSTREAM_Unlock(Buffer->stream));
    }

    /* Unlock the index object. */
    if (indexLocked)
    {
        gcmVERIFY_OK(gcoINDEX_Unlock(Buffer->index));
    }

    return status;
}