/*******************************************************************************
**
**  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;
}
Пример #2
0
gceSTATUS
gcoOS_DisplayBufferRegions(
    IN HALNativeDisplayType Display,
    IN HALNativeWindowType Window,
    IN gctINT NumRects,
    IN gctINT_PTR Rects
    )
{
    screen_buffer_t buf[gcdDISPLAY_BACK_BUFFERS];
    int rc;
    gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER_ARG("Display=0x%x Window=0x%x NumRects=%d", Display, Window, NumRects);

    rc = screen_get_window_property_pv((screen_window_t)Window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)buf);
    if (rc) {
        goto OnError;
    }

    rc = screen_post_window((screen_window_t)Window, buf[0], NumRects, Rects, 0);
    if (rc) {
        goto OnError;
    }

    gcmFOOTER_NO();
    return status;

OnError:
    status = gcvSTATUS_INVALID_ARGUMENT;
    gcmFOOTER();
    return status;
}
/*******************************************************************************
**
**  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;
}
/* Write data to profile. */
gceSTATUS
gcoPROFILER_Write(
    IN gcoHAL Hal,
    IN gctSIZE_T ByteCount,
    IN gctCONST_POINTER Data
    )
{
    gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER_ARG("ByteCount=%lu Data=0x%x", ByteCount, Data);

    /* Check if already destroyed. */
   	if (gcPLS.hal->profiler.enable)
    {
        if (gcPLS.hal->profiler.useSocket)
        {
            status = gcoOS_Send(gcvNULL,
                                gcPLS.hal->profiler.sockFd,
                                ByteCount, Data, 0);
        }
        else
        {
            status = gcoOS_Write(gcvNULL,
                                 gcPLS.hal->profiler.file,
                                 ByteCount, Data);
        }
    }

    gcmFOOTER();
    return status;
}
gceSTATUS glfCompactNamedObjectList(
	IN glsCONTEXT_PTR Context,
	IN glsNAMEDOBJECTLIST_PTR List
	)
{
	gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER_ARG("Context=0x%x List=0x%x", Context, List);

	do
	{
		gceSTATUS last;

		glsNAMEDOBJECT_PTR wrapper = List->freeList;
		while (wrapper)
		{
			glsNAMEDOBJECT_PTR temp = wrapper;
			wrapper = wrapper->next;

			gcmCHECK_STATUS(gcmOS_SAFE_FREE(gcvNULL, temp));
		}

		List->freeList = gcvNULL;
	}
	while (gcvFALSE);

    gcmFOOTER();

	return status;
}
/* Flush data out. */
gceSTATUS
gcoPROFILER_Flush(
    IN gcoHAL Hal
    )
{
    gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER();

   	if (gcPLS.hal->profiler.enable)
    {
        if (gcPLS.hal->profiler.useSocket)
        {
            status = gcoOS_WaitForSend(gcvNULL,
                                       gcPLS.hal->profiler.sockFd,
                                       0, 50000);
        }
        else
        {
            status = gcoOS_Flush(gcvNULL,
                                 gcPLS.hal->profiler.file);
        }
	}

    gcmFOOTER();
    return status;
}
Пример #7
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;
}
gceSTATUS vgsMEMORYMANAGER_Construct(
    IN gcoOS Os,
	IN gctUINT ItemSize,
	IN gctUINT Granularity,
	OUT vgsMEMORYMANAGER_PTR * Manager
	)
{
	gceSTATUS status;
	vgsMEMORYMANAGER_PTR manager = gcvNULL;

    gcmHEADER_ARG("Os=0x%x ItemSize=0x%x Granularity=0x%x Manager=0x%x",
        Os, ItemSize, Granularity, Manager);

	gcmVERIFY_ARGUMENT(ItemSize > 0);
	gcmVERIFY_ARGUMENT(Granularity > 0);
	gcmVERIFY_ARGUMENT(Manager != gcvNULL);

	do
	{
		gctUINT itemSize;
		gctUINT allocationSize;

		/* Allocate the memory manager structure. */
		gcmERR_BREAK(gcoOS_Allocate(
			Os,
			gcmSIZEOF(vgsMEMORYMANAGER),
			(gctPOINTER *) &manager
			));

		/* Determine the size of the item. */
		itemSize = gcmSIZEOF(vgsMEMORYITEM) + ItemSize;

		/* Determine the allocation size. */
		allocationSize = gcmSIZEOF(vgsMEMORYITEM) + Granularity * itemSize;

		/* Initialize the structure. */
		manager->os             = Os;
		manager->allocationSize = allocationSize;
		manager->itemCount      = Granularity;
		manager->itemSize       = itemSize;
		manager->firstAllocated = gcvNULL;
		manager->firstFree      = gcvNULL;

#if vgvVALIDATE_MEMORY_MANAGER
		manager->allocatedCount       = 0;
		manager->maximumAllocated     = 0;
		manager->allocatedBufferCount = 0;
#endif

		/* Set the result pointer. */
		* Manager = manager;
	}
	while (gcvNULL);

    gcmFOOTER();

	/* Return status. */
	return status;
}
Пример #9
0
static gceSTATUS _DeleteBuffer(
    IN glsCONTEXT_PTR Context,
    IN gctPOINTER Object
    )
{
    gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER_ARG("Context=0x%x Object=0x%x", Context, Object);

    do
    {
        /* Cast the object. */
        glsBUFFER_PTR object = (glsBUFFER_PTR) Object;

        /* Clear bindings. */
        _ClearBindings(Object);

        /* Clear mapping */
        _ClearMapping(Object);

        /* Destroy index object. */
        if (object->index)
        {
            gcoINDEX_Destroy(object->index);
            object->index = gcvNULL;
        }

        /* Destroy stream object. */
        if (object->stream)
        {
            gcoSTREAM_Destroy(object->stream);
            object->stream = gcvNULL;
        }

#if gcdUSE_TRIANGLE_STRIP_PATCH
        if (object->subCount > 0)
        {
            GLint i;

            for (i = 0; i < object->subCount; i++)
            {
                gcoINDEX_Destroy(object->subs[i].patchIndex);
                object->subs[i].patchIndex  = gcvNULL;
            }

            object->subCount = 0;
        }
#endif
        /* Reset the fields. */
        object->size = 0;
        object->usage = GL_STATIC_DRAW;
    }
    while (gcvFALSE);

    gcmFOOTER();

    return status;
}
gceSTATUS glfDeleteNamedObject(
	IN glsCONTEXT_PTR Context,
	IN glsNAMEDOBJECTLIST_PTR List,
	gctUINT32 Name
	)
{
	gceSTATUS status = gcvSTATUS_OK;
    gcmHEADER_ARG("Context=0x%x List=0x%x Name=%u",
                    Context, List, Name);

	do
	{
		/* Determine the hash table index. */
		gctUINT32 index = Name % glvNAMEDOBJECT_HASHTABLE_SIZE;

		/* Shortcut to the table entry. */
		glsNAMEDOBJECT_PTR* entry = &List->hashTable[index];

		/* Keep history. */
		glsNAMEDOBJECT_PTR prev = gcvNULL;

		/* Search from the beginning. */
		glsNAMEDOBJECT_PTR curr = *entry;

		/* Search collided object list. */
		while (curr)
        {
            if (curr->name == Name)
            {
                /* Remove the wrapper from the list of allocated objects. */
                if (prev)
                {
                    prev->next = curr->next;
                }
                else
                {
                    *entry = curr->next;
                }

                glfDereferenceNamedObject(Context, curr);

                break;
            }

            /* The current becomes history. */
            prev = curr;

            /* Move to the next one. */
            curr = curr->next;
        }
	}
	while (gcvFALSE);

    gcmFOOTER();

	return status;
}
Пример #11
0
static gceSTATUS _CreateBuffer(
    IN glsCONTEXT_PTR Context,
    IN gctUINT32 Buffer,
    OUT glsNAMEDOBJECT_PTR * Wrapper
    )
{
    gceSTATUS status;

    gcmHEADER_ARG("Context=0x%x Buffer=%u Wrapper=0x%x",
                  Context, Buffer, Wrapper);

    do
    {
        glsBUFFER_PTR object;
        glsCONTEXT_PTR shared;

        /* Map shared context. */
#if gcdRENDER_THREADS
        shared = (Context->shared != gcvNULL) ? Context->shared : Context;
#else
        shared = Context;
#endif

        /* Attempt to allocate a new buffer. */
        gcmERR_BREAK(glfCreateNamedObject(
            Context,
            &shared->bufferList,
            Buffer,
            _DeleteBuffer,
            Wrapper
            ));

        /* Get a pointer to the new buffer. */
        object = (glsBUFFER_PTR) (*Wrapper)->object;

        /* Init the buffer to the defaults. */
        gcoOS_ZeroMemory(object, sizeof(glsBUFFER));
        object->usage = GL_STATIC_DRAW;
        object->mapped = gcvFALSE;
        object->bufferMapPointer = gcvNULL;

#if gcdUSE_TRIANGLE_STRIP_PATCH
        object->stripPatchDirty = gcvTRUE;
        object->subCount        = 0;

        gcoOS_ZeroMemory(object->subs, sizeof(object->subs));
#endif
    }
    while (gcvFALSE);

    gcmFOOTER();

    /* Return result. */
    return status;
}
Пример #12
0
/*******************************************************************************
**
**  gcoDUMP_AddSurface
**
**  Allocate a surface.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**      gctINT32 Width, Height
**          Width and height of the surface.
**
**      gceSURF_FORMAT PixelFormat
**          Pixel format for the surface.
**
**      gctUINT32 Address
**          Physical address to be used as a handle for the surface.
**
**      gctSIZE_T ByteCount
**          Number of bytes inside the surface.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_AddSurface(
    IN gcoDUMP Dump,
    IN gctINT32 Width,
    IN gctINT32 Height,
    IN gceSURF_FORMAT PixelFormat,
    IN gctUINT32 Address,
    IN gctSIZE_T ByteCount
    )
{
    gceSTATUS status;
    gcsDUMP_SURFACE surface;

    gcmHEADER_ARG("Dump=0x%x Width=%d Height=%d PixelFormat=%d Address=%x "
                  "ByteCount=%d",
                  Dump, Width, Height, PixelFormat, Address, ByteCount);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);
    gcmVERIFY_ARGUMENT(ByteCount > 0);

    if (Dump->file == gcvNULL)
    {
        /* There is no open dump file. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    do
    {
        /* Write the data record. */
        surface.type    = gcvTAG_SURFACE;
        surface.address = Address;
        surface.width   = (gctINT16) Width;
        surface.height  = (gctINT16) Height;
        surface.format  = PixelFormat;
        surface.length  = ByteCount;

        gcmERR_BREAK(
            gcoOS_Write(gcvNULL, Dump->file, sizeof(surface), &surface));

        /* Update the frame length. */
        Dump->frameLength += sizeof(surface);

        /* Update the file length. */
        Dump->length += sizeof(surface);
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #13
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;
}
Пример #14
0
/*******************************************************************************
**
**  gcoDUMP_DumpData
**
**  Dump data the file.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**      gceDUMP_TAG Type
**          Type of data.
**
**      gctUINT32 Address
**          Physical address to be used as a handle for the data.
**
**      gctSIZE_T ByteCount
**          Number of bytes to write.
**
**      gctCONST_POINTER Data
**          Pointer to the data to write.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_DumpData(
    IN gcoDUMP Dump,
    IN gceDUMP_TAG Type,
    IN gctUINT32 Address,
    IN gctSIZE_T ByteCount,
    IN gctCONST_POINTER Data
    )
{
    gceSTATUS status;
    gcsDUMP_DATA header;

    gcmHEADER_ARG("Dump=0x%x Type=%d Address=%x ByteCount=%d Data=0x%x",
                    Dump, Type, Address, ByteCount, Data);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);
    gcmVERIFY_ARGUMENT(ByteCount > 0);
    gcmVERIFY_ARGUMENT(Data != gcvNULL);

    if (Dump->file == gcvNULL)
    {
        /* There is no open dump file. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    do
    {
        /* Write the data record. */
        header.type    = Type;
        header.length  = ByteCount;
        header.address = Address;

        gcmERR_BREAK(
            gcoOS_Write(gcvNULL, Dump->file, sizeof(header), &header));

        /* Write the data. */
        gcmERR_BREAK(gcoOS_Write(gcvNULL, Dump->file, ByteCount, Data));

        /* Update the frame length. */
        Dump->frameLength += sizeof(header) + ByteCount;

        /* Update the file length. */
        Dump->length += sizeof(header) + ByteCount;
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #15
0
/*******************************************************************************
**
**  gcoDUMP_FrameEnd
**
**  Mark the end of a frame.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_FrameEnd(
    IN gcoDUMP Dump
    )
{
    gceSTATUS status;
    gcsDUMP_DATA header;
    gctUINT32 pos;

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

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);

    if (Dump->file == gcvNULL)
    {
        /* There is no open dump file. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    do
    {
        /* Get the current position. */
        gcmERR_BREAK(gcoOS_GetPos(gcvNULL, Dump->file, &pos));

        /* Seek to the beginning of the frame. */
        gcmERR_BREAK(gcoOS_SetPos(gcvNULL, Dump->file, Dump->frameStart));

        /* Make sure we got the right byte count. */
        gcmASSERT(pos - Dump->frameStart == Dump->frameLength + sizeof(header));

        /* Update the frame header. */
        header.type    = gcvTAG_FRAME;
        header.length  = Dump->frameLength;
        header.address = ++ Dump->frameCount;

        gcmERR_BREAK(gcoOS_Write(gcvNULL, Dump->file, sizeof(header), &header));

        /* Seek to the end of the file. */
        gcmERR_BREAK(gcoOS_SetPos(gcvNULL, Dump->file, pos));

        /* Mark the frame as ended. */
        Dump->frameStart = 0;
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #16
0
gceSTATUS
gcoOS_SetDisplayVirtual(
    IN HALNativeDisplayType Display,
    IN HALNativeWindowType Window,
    IN gctUINT Offset,
    IN gctINT X,
    IN gctINT Y
    )
{
    screen_buffer_t buf[gcdDISPLAY_BACK_BUFFERS];
    int rc;
    int rects[4];
    gceSTATUS status = gcvSTATUS_OK;

    gcmHEADER_ARG("Display=0x%x Window=0x%x Offset=%u X=%d Y=%d", Display, Window, Offset, X, Y);

    rects[0] = 0;
    rects[1] = 0;

    rc = screen_get_window_property_pv((screen_window_t)Window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)buf);
    if (rc)
    {
        goto OnError;
    }

    rc = screen_get_window_property_iv((screen_window_t)Window, SCREEN_PROPERTY_BUFFER_SIZE, &rects[2]);
    if (rc)
    {
        goto OnError;
    }

    rc = screen_post_window((screen_window_t)Window, buf[0], 1, rects, 0);
    if (rc)
    {
        goto OnError;
    }

    _ReleaseWindowInfoNode(Window);

    gcmFOOTER_NO();
    return status;

OnError:
    status = gcvSTATUS_INVALID_ARGUMENT;
    gcmFOOTER();
    return status;
}
gceSTATUS vgsMEMORYMANAGER_Destroy(
	IN vgsMEMORYMANAGER_PTR Manager
	)
{
	gceSTATUS status;
	vgsMEMORYITEM_PTR current;
	vgsMEMORYITEM_PTR next;

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

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

	/* Assume success. */
	status = gcvSTATUS_OK;

	/* Everything has to be freed. */
#if vgvVALIDATE_MEMORY_MANAGER
	gcmASSERT(Manager->allocatedCount == 0);
#endif

	/* Destroy all allocated buffers. */
	while (Manager->firstAllocated)
	{
		/* Get the current buffer. */
		current = Manager->firstAllocated;

		/* Get the next buffer. */
		next = current->next;

		/* Free the current. */
		gcmERR_BREAK(gcoOS_Free(Manager->os, current));

		/* Advance to the next one. */
		Manager->firstAllocated = next;
	}

	/* Success? */
	if (gcmIS_SUCCESS(status))
	{
		status = gcoOS_Free(Manager->os, Manager);
	}

    gcmFOOTER();
	/* Return status. */
	return status;
}
Пример #18
0
/*******************************************************************************
**
**  gcoDUMP_Delete
**
**  Mark an address as deleted.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**      gctUINT32 Address
**          Physical address to delete.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_Delete(
    IN gcoDUMP Dump,
    IN gctUINT32 Address
    )
{
    gceSTATUS status;
    gcsDUMP_DATA header;

    gcmHEADER_ARG("Dump=0x%x Address=%x", Dump, Address);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);

    if (Dump->file == gcvNULL)
    {
        /* There is no open dump file. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    do
    {
        /* Write the delete record. */
        header.type    = gcvTAG_DELETE;
        header.length  = 0;
        header.address = Address;

        gcmERR_BREAK(
            gcoOS_Write(gcvNULL, Dump->file, sizeof(header), &header));

        /* Update the frame length. */
        Dump->frameLength += sizeof(header);

        /* Update the file length. */
        Dump->length += sizeof(header);
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #19
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;
}
Пример #20
0
/*******************************************************************************
**
**  gcoDUMP_FrameBegin
**
**  Mark the beginning of a frame.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_FrameBegin(
    IN gcoDUMP Dump
    )
{
    gceSTATUS status;
    gcsDUMP_DATA header;

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

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);

    if ( (Dump->file == gcvNULL) || (Dump->frameStart != 0) )
    {
        /* There is no open dump file. */
        gcmFOOTER_NO();
        return gcvSTATUS_OK;
    }

    do
    {
        /* Get the current position. */
        gcmERR_BREAK(gcoOS_GetPos(gcvNULL, Dump->file, &Dump->frameStart));

        /* Write the frame header. */
        header.type    = gcvTAG_FRAME;
        header.length  = Dump->frameLength = 0;
        header.address = 0;

        gcmERR_BREAK(gcoOS_Write(gcvNULL, Dump->file, sizeof(header), &header));

        /* Update the file length. */
        Dump->length += sizeof(header);
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #21
0
gceSTATUS
gcoOS_GetNextDisplayInfoEx(
    IN HALNativeDisplayType Display,
    IN HALNativeWindowType Window,
    IN gctUINT DisplayInfoSize,
    OUT halDISPLAY_INFO * DisplayInfo
    )
{
    int rc;
    gceSTATUS status = gcvSTATUS_OK;
    screen_buffer_t buf[gcdDISPLAY_BACK_BUFFERS];

    gcmHEADER_ARG("Display=0x%x Window=0x%x DisplayInfoSize=%u", Display, Window, DisplayInfoSize);

    if ((Window == gcvNULL) || (DisplayInfoSize != sizeof(halDISPLAY_INFO)))
    {
        goto OnError;
    }

    rc = screen_get_window_property_pv((screen_window_t)Window, SCREEN_PROPERTY_RENDER_BUFFERS, (void**)buf);
    if (rc)
    {
        goto OnError;
    }

    rc = screen_post_window((screen_window_t)Window, buf[0], 0, NULL, 0);
    if (rc)
    {
        goto OnError;
    }

    status = gcoOS_GetDisplayInfoEx(Display, Window, DisplayInfoSize, DisplayInfo);

    gcmFOOTER_ARG("*DisplayInfo=0x%x", *DisplayInfo);
    return status;

OnError:
    status = gcvSTATUS_INVALID_ARGUMENT;
    gcmFOOTER();
    return status;
}
gceSTATUS glfDestroyNamedObjectList(
	IN glsCONTEXT_PTR Context,
	IN glsNAMEDOBJECTLIST_PTR List
	)
{
    gceSTATUS status = gcvSTATUS_OK;
    gcmHEADER_ARG("Context=0x%x List=0x%x", Context, List);

	do
	{
		gceSTATUS last;
		gctINT i;

		/* Free all objects in the free list. */
		gcmCHECK_STATUS(glfCompactNamedObjectList(Context, List));

		/* Free all existing objects. */
		for (i = 0; i < glvNAMEDOBJECT_HASHTABLE_SIZE; i++)
		{
			glsNAMEDOBJECT_PTR wrapper = List->hashTable[i];
			while (wrapper)
			{
				glsNAMEDOBJECT_PTR temp = wrapper;
				wrapper = wrapper->next;

                gcmCHECK_STATUS((*temp->deleteObject)(Context, temp->object));
                gcmCHECK_STATUS(gcmOS_SAFE_FREE(gcvNULL, temp));
			}
		}
	}
	while (gcvFALSE);

    gcmFOOTER();

    return status;
}
Пример #23
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;
}
gceSTATUS
gcoPROFILER_Initialize(
	IN gcoHAL Hal
	)
{
    gceSTATUS status = gcvSTATUS_OK;
    char* fileName;
    char* filter = gcvNULL;
    gctSTRING portName;
    gctINT port;
	gcsHAL_INTERFACE iface;

    gcmHEADER();

    /* Check if already initialized. */
   	if (gcPLS.hal->profiler.enable)
    {
        gcPLS.hal->profiler.enable++;
        gcmFOOTER();
        return status;
    }

	/* Get profile setting. */
	iface.command = gcvHAL_GET_PROFILE_SETTING;

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

	if (gcmIS_ERROR(status) || !iface.u.GetProfileSetting.enable)
	{
    	gcPLS.hal->profiler.enable = 0;
        status = gcvSTATUS_GENERIC_IO;

        gcmFOOTER();
        return status;
	}

	gcmVERIFY_OK(gcoOS_ZeroMemory(&gcPLS.hal->profiler, gcmSIZEOF(gcPLS.hal->profiler)));

    gcoOS_GetEnv(gcvNULL,
                 "VP_COUNTER_FILTER",
                 &filter);

    /* Enable/Disable specific counters. */
    if ((filter != gcvNULL))
    {
        gctSIZE_T bitsLen;
        gcoOS_StrLen(filter, &bitsLen);
        if (bitsLen > 2)
        {
            gcPLS.hal->profiler.enableHal = (filter[2] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableHal = gcvTRUE;
        }

        if (bitsLen > 3)
        {
            gcPLS.hal->profiler.enableHW = (filter[3] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableHW = gcvTRUE;
        }

        if (bitsLen > 8)
        {
            gcPLS.hal->profiler.enableSH = (filter[8] == '1');
        }
        else
        {
            gcPLS.hal->profiler.enableSH = gcvTRUE;
        }
    }
    else
    {
        gcPLS.hal->profiler.enableHal = gcvTRUE;
        gcPLS.hal->profiler.enableHW = gcvTRUE;
        gcPLS.hal->profiler.enableSH = gcvTRUE;
    }

	gcoOS_GetEnv(gcvNULL,
				 "VPROFILER_OUTPUT",
				 &fileName);

    gcPLS.hal->profiler.useSocket = gcvFALSE;
	if (fileName && *fileName != '\0' && *fileName != ' ')
	{
        /* Extract port info. */
        gcoOS_StrFindReverse(fileName, ':', &portName);

        if (portName)
        {
            gcoOS_StrToInt(portName + 1, &port);

            if (port > 0)
            {
                /*status = gcoOS_Socket(gcvNULL, AF_INET, SOCK_STREAM, 0, &gcPLS.hal->profiler.sockFd);*/
                status = gcoOS_Socket(gcvNULL, 2, 1, 0, &gcPLS.hal->profiler.sockFd);

                if (gcmIS_SUCCESS(status))
                {
                    *portName = '\0';
                    status = gcoOS_Connect(gcvNULL,
                            gcPLS.hal->profiler.sockFd, fileName, port);
                    *portName = ':';

                    if (gcmIS_SUCCESS(status))
	                {
                        gcPLS.hal->profiler.useSocket = gcvTRUE;
                    }
                }
            }
        }
	}
    else
    {
		fileName = iface.u.GetProfileSetting.fileName;
    }

    if (! gcPLS.hal->profiler.useSocket)
	{
		status = gcoOS_Open(gcvNULL,
							fileName,
#ifdef gcdNEW_PROFILER_FILE
							gcvFILE_CREATE,
#else
							gcvFILE_CREATETEXT,
#endif
							&gcPLS.hal->profiler.file);
	}

    if (gcmIS_ERROR(status))
	{
    	gcPLS.hal->profiler.enable = 0;
        status = gcvSTATUS_GENERIC_IO;

        gcmFOOTER();
        return status;
	}

    gcPLS.hal->profiler.enable = 1;
	gcoOS_GetTime(&gcPLS.hal->profiler.frameStart);
	gcPLS.hal->profiler.frameStartTimeusec = gcPLS.hal->profiler.frameStart;
	gcPLS.hal->profiler.prevVSInstCount = 0;
	gcPLS.hal->profiler.prevVSBranchInstCount = 0;
	gcPLS.hal->profiler.prevVSTexInstCount = 0;
	gcPLS.hal->profiler.prevVSVertexCount = 0;
	gcPLS.hal->profiler.prevPSInstCount = 0;
	gcPLS.hal->profiler.prevPSBranchInstCount = 0;
	gcPLS.hal->profiler.prevPSTexInstCount = 0;
	gcPLS.hal->profiler.prevPSPixelCount = 0;

#if gcdNEW_PROFILER_FILE
    gcmWRITE_CONST(VPHEADER);
    gcmWRITE_BUFFER(4, "VP12");
#else
	gcmWRITE_STRING("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<VProfile>\n");
#endif

    /* Success. */
    gcmFOOTER();
    return status;
}
Пример #25
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;
}
Пример #26
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;
}
Пример #27
0
/*******************************************************************************
**
**  gcoDUMP_Control
**
**  Control dumping.
**
**  INPUT:
**
**      gcoDUMP Dump
**          Pointer to a gcoDUMP object.
**
**      gctSTRING FileName
**          If 'FileName' is not gcvNULL, it points to the filename to be used for
**          capturing all data.  If 'FileName' is gcvNULL, turn off any current
**          capturing.
**
**  OUTPUT:
**
**      Nothing.
*/
gceSTATUS
gcoDUMP_Control(
    IN gcoDUMP Dump,
    IN gctSTRING FileName
    )
{
    gceSTATUS status = gcvSTATUS_OK;
    gcsDUMP_FILE header;
    gctUINT32 pos;

    gcmHEADER_ARG("Dump=0x%x FileName=0x%x", Dump, FileName);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Dump, gcvOBJ_DUMP);

    do
    {
        if (FileName != gcvNULL)
        {
            /* Need to create a new dump file. */
            if (Dump->file == gcvNULL)
            {
                /* Create the dump file. */
                gcmERR_BREAK(gcoOS_Open(gcvNULL,
                                    FileName,
                                    gcvFILE_CREATE,
                                    &Dump->file));

                /* Write the file header. */
                header.signature   = gcvDUMP_FILE_SIGNATURE;
                header.length      = Dump->length     = 0;
                header.frames      = Dump->frameCount = 0;

                gcmERR_BREAK(gcoOS_Write(gcvNULL,
                                     Dump->file,
                                     sizeof(header),
                                     &header));

                /* Frame is not yet started. */
                Dump->frameStart = 0;
            }
        }
        else
        {
            /* Need to close any current dump file. */
            if (Dump->file != gcvNULL)
            {
                /* Close any open frame. */
                if (Dump->frameStart != 0)
                {
                    gcoDUMP_FrameEnd(Dump);
                    gcoDUMP_FrameBegin(Dump);
                }

                /* Get the current position. */
                gcmERR_BREAK(gcoOS_GetPos(gcvNULL, Dump->file, &pos));

                /* Seek to the beginnnig of the file. */
                gcmERR_BREAK(gcoOS_SetPos(gcvNULL, Dump->file, 0));

                /* Make sure we have the correct size. */
                gcmASSERT(pos == Dump->length + sizeof(header));

                /* Update the file header. */
                header.signature = gcvDUMP_FILE_SIGNATURE;
                header.length    = Dump->length;
                header.frames    = Dump->frameCount;

                gcmERR_BREAK(gcoOS_Write(gcvNULL,
                                     Dump->file,
                                     sizeof(header),
                                     &header));

                /* Seek to the end of the file. */
                gcmERR_BREAK(gcoOS_SetPos(gcvNULL, Dump->file, pos));

                /* Close the file. */
                gcmERR_BREAK(gcoOS_Close(gcvNULL, Dump->file));

                /* Mark the file as closed. */
                Dump->file = gcvNULL;
            }
        }
    }
    while (gcvFALSE);

    /* Return the status. */
    gcmFOOTER();
    return status;
}
Пример #28
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;
}
Пример #29
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;
}
Пример #30
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;
}