/******************************************************************************* ** ** gckKERNEL_AllocateLinearMemory ** ** Function walks all required memory pools and allocates the requested ** amount of video memory. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** ** gcePOOL * Pool ** Pointer the desired memory pool. ** ** gctSIZE_T Bytes ** Number of bytes to allocate. ** ** gctSIZE_T Alignment ** Required buffer alignment. ** ** gceSURF_TYPE Type ** Surface type. ** ** OUTPUT: ** ** gcePOOL * Pool ** Pointer to the actual pool where the memory was allocated. ** ** gcuVIDMEM_NODE_PTR * Node ** Allocated node. */ gceSTATUS gckKERNEL_AllocateLinearMemory( IN gckKERNEL Kernel, IN OUT gcePOOL * Pool, IN gctSIZE_T Bytes, IN gctSIZE_T Alignment, IN gceSURF_TYPE Type, OUT gcuVIDMEM_NODE_PTR * Node ) { gcePOOL pool; gceSTATUS status; gckVIDMEM videoMemory; /* Get initial pool. */ switch (pool = *Pool) { case gcvPOOL_DEFAULT: case gcvPOOL_LOCAL: pool = gcvPOOL_LOCAL_INTERNAL; break; case gcvPOOL_UNIFIED: pool = gcvPOOL_SYSTEM; break; default: break; } do { /* Verify the number of bytes to allocate. */ if (Bytes == 0) { status = gcvSTATUS_INVALID_ARGUMENT; break; } if (pool == gcvPOOL_VIRTUAL) { /* Create a gcuVIDMEM_NODE for virtual memory. */ gcmkERR_BREAK(gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Node)); /* Success. */ break; } else { /* Get pointer to gckVIDMEM object for pool. */ status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory); if (status == gcvSTATUS_OK) { /* Allocate memory. */ status = gckVIDMEM_AllocateLinear(Kernel, videoMemory, Bytes, Alignment, Type, Node); if (status == gcvSTATUS_OK) { /* Memory allocated. */ break; } } } if (pool == gcvPOOL_LOCAL_INTERNAL) { /* Advance to external memory. */ pool = gcvPOOL_LOCAL_EXTERNAL; } else if (pool == gcvPOOL_LOCAL_EXTERNAL) { /* Advance to contiguous system memory. */ pool = gcvPOOL_SYSTEM; } else if (pool == gcvPOOL_SYSTEM) { /* Advance to virtual memory. */ pool = gcvPOOL_VIRTUAL; } else { /* Out of pools. */ break; } } /* Loop only for multiple selection pools. */ while ((*Pool == gcvPOOL_DEFAULT) || (*Pool == gcvPOOL_LOCAL) || (*Pool == gcvPOOL_UNIFIED) ); if (gcmIS_SUCCESS(status)) { /* Return pool used for allocation. */ *Pool = pool; } /* Return status. */ return status; }
/******************************************************************************* ** ** _AllocateMemory ** ** Private function to walk all required memory pools to allocate the requested ** amount of video memory. ** ** INPUT: ** ** gckKERNEL Kernel ** Pointer to an gckKERNEL object. ** ** gcsHAL_INTERFACE * Interface ** Pointer to a gcsHAL_INTERFACE structure that defines the command to ** be dispatched. ** ** OUTPUT: ** ** gcsHAL_INTERFACE * Interface ** Pointer to a gcsHAL_INTERFACE structure that receives any data to be ** returned. */ static gceSTATUS _AllocateMemory( IN gckKERNEL Kernel, IN OUT gcePOOL * Pool, IN gctSIZE_T Bytes, IN gctSIZE_T Alignment, IN gceSURF_TYPE Type, #ifdef __QNXNTO__ IN gctHANDLE Handle, #endif OUT gcuVIDMEM_NODE_PTR * Node ) { gcePOOL pool; gceSTATUS status; gckVIDMEM videoMemory; gcmkVERIFY_ARGUMENT(Pool != gcvNULL); /* Get initial pool. */ switch (pool = *Pool) { case gcvPOOL_DEFAULT: case gcvPOOL_LOCAL: pool = gcvPOOL_LOCAL_INTERNAL; break; case gcvPOOL_UNIFIED: pool = gcvPOOL_SYSTEM; break; default: break; } do { /* Verify the number of bytes to allocate. */ if (Bytes == 0) { gcmkERR_BREAK(gcvSTATUS_INVALID_ARGUMENT); } if (pool == gcvPOOL_VIRTUAL) { /* Create a gcuVIDMEM_NODE for virtual memory. */ #ifdef __QNXNTO__ gcmkERR_BREAK( gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Handle, Node)); #else gcmkERR_BREAK( gckVIDMEM_ConstructVirtual(Kernel, gcvFALSE, Bytes, Node)); #endif /* Success. */ break; } else if (pool == gcvPOOL_CONTIGUOUS) { /* Create a gcuVIDMEM_NODE for contiguous memory. */ #ifdef __QNXNTO__ status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, Handle, Node); #else status = gckVIDMEM_ConstructVirtual(Kernel, gcvTRUE, Bytes, Node); #endif if (gcmIS_SUCCESS(status)) { /* Memory allocated. */ break; } } else { /* Get pointer to gckVIDMEM object for pool. */ status = gckKERNEL_GetVideoMemoryPool(Kernel, pool, &videoMemory); if (gcmIS_SUCCESS(status)) { /* Allocate memory. */ status = gckVIDMEM_AllocateLinear(videoMemory, Bytes, Alignment, Type, #ifdef __QNXNTO__ Handle, #endif Node); if (gcmIS_SUCCESS(status)) { /* Memory allocated. */ (*Node)->VidMem.pool = pool; break; } } } if (pool == gcvPOOL_LOCAL_INTERNAL) { /* Advance to external memory. */ pool = gcvPOOL_LOCAL_EXTERNAL; } else if (pool == gcvPOOL_LOCAL_EXTERNAL) { /* Advance to contiguous system memory. */ pool = gcvPOOL_SYSTEM; } else if (pool == gcvPOOL_SYSTEM) { /* Advance to contiguous memory. */ pool = gcvPOOL_CONTIGUOUS; } else if ((pool == gcvPOOL_CONTIGUOUS) && (Type != gcvSURF_TILE_STATUS) ) { static int count= 1; /* Advance to virtual memory. */ if (count == 1) { gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_KERNEL, "Try to allocate virtual memory!\n"); count = 0; } pool = gcvPOOL_VIRTUAL; } else { /* Out of pools. */ break; } } /* Loop only for multiple selection pools. */ while ((*Pool == gcvPOOL_DEFAULT) || (*Pool == gcvPOOL_LOCAL) || (*Pool == gcvPOOL_UNIFIED) ); if (gcmIS_SUCCESS(status)) { /* Return pool used for allocation. */ *Pool = pool; } /* Return status. */ return status; }