/*********************************************************************************** Function Name : NamedItemDelRef Inputs : gc, psNamesArray, psNamedItem Outputs : - Returns : - Description : Decrements the reference counter of the given named item. Deletes the item if its refcount drops to zero. ************************************************************************************/ IMG_INTERNAL IMG_VOID NamedItemDelRef(GLES2Context *gc, GLES2NamesArray *psNamesArray, GLES2NamedItem* psNamedItem) { GLES2_TIME_START(GLES2_TIMER_NAMES_ARRAY); LOCK_NAMES_ARRAY(psNamesArray); GLES_ASSERT(psNamedItem->ui32Name); GLES_ASSERT(psNamedItem->ui32RefCount > 0); if(psNamedItem->ui32RefCount == 1) { /* The item must be deleted. Remove it from the list */ psNamedItem->ui32RefCount = 0; RemoveItemFromList(psNamesArray, psNamedItem); } else if(psNamedItem->ui32RefCount > 1) { /* Simply decrement the reference count */ psNamedItem->ui32RefCount--; psNamedItem = IMG_NULL; } UNLOCK_NAMES_ARRAY(psNamesArray); GLES2_TIME_STOP(GLES2_TIMER_NAMES_ARRAY); /* Delete the data if its refcount dropped to zero */ if(psNamedItem) { psNamesArray->pfnFree(gc, psNamedItem, IMG_FALSE); } }
/** * Generate a texture access instruction. * * @param gen reference to code generator object * @param op instruction opcode * @param prec precision modifier * @param target texture target to use * @param dst destination * @param src texture coordinate vector * @param sampler texture sampler variable to access texture memory * @param offset offset for sampler array */ void GlesGenInstTex(ShaderProgramGenerator * gen, Opcode op, Precision prec, TextureTarget target, const DstReg * dst, const SrcReg * src, ProgVar * sampler, GLsizeiptr offset) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(dst); GLES_ASSERT(src); GLES_ASSERT(sampler); gen->instructionCount++; if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstTex)); InitInstTex(&inst->tex, op, prec, target, dst, src, sampler, offset); AppendInst(gen->currentList->tail, inst); }
/** * Generate an extended swizzle (SWZ) instruction. * * @param gen reference to code generator object * @param op instruction opcode * @param prec precision flags for instruction * @param dst destination * @param src source operand * @param optionX swizzle selector for x coordinate * @param optionY swizzle selector for y coordinate * @param optionZ swizzle selector for z coordinate * @param optionW swizzle selector for w coordinate */ void GlesGenInstSwizzle(ShaderProgramGenerator * gen, Opcode op, Precision prec, const DstReg * dst, SrcRef src, ExtSwizzleOption optionX, ExtSwizzleOption optionY, ExtSwizzleOption optionZ, ExtSwizzleOption optionW) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(dst); GLES_ASSERT(src.base); gen->instructionCount++; if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstSwizzle)); InitInstSwizzle(&inst->swizzle, op, prec, dst, src, optionX, optionY, optionZ, optionW); AppendInst(gen->currentList->tail, inst); }
/** * Generate a branch or subroutine call instruction. * * @param gen reference to code generator object * @param op instruction opcode * @param target branch target * @param cond branch condition * @param selectX selector for 1st condition flag * @param selectY selector for 2nd condition flag * @param selectZ selector for 3rd condition flag * @param selectW selector for 4th condition flag */ void GlesGenInstBranch(ShaderProgramGenerator * gen, Opcode op, Label * target, Cond cond, GLubyte selectX, GLubyte selectY, GLubyte selectZ, GLubyte selectW) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(target); gen->instructionCount++; if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstBranch)); InitInstBranch(&inst->branch, op, target, cond, selectX, selectY, selectZ, selectW); AppendInst(gen->currentList->tail, inst); }
/** * Generate a binary instruction. * * @param gen reference to code generator object * @param op instruction opcode * @param prec precision flags for instruction * @param dst destination * @param arg0 source operand 0 * @param arg1 source operand 1 * @param arg2 source operand 2 */ void GlesGenInstTernary(ShaderProgramGenerator * gen, Opcode op, Precision prec, const DstReg * dst, const SrcReg * arg0, const SrcReg * arg1, const SrcReg * arg2) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(dst); GLES_ASSERT(arg0); GLES_ASSERT(arg1); GLES_ASSERT(arg2); gen->instructionCount++; if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstTernary)); InitInstTernary(&inst->ternary, op, prec, dst, arg0, arg1, arg2); AppendInst(gen->currentList->tail, inst); }
/** * Append an instruction to a basic block. * * @param block basic block to which instruction should be appended to * @param inst instruction to append */ static GLES_INLINE void AppendInst(Block * block, Inst * inst) { GLES_ASSERT(!inst->base.prev); GLES_ASSERT(!inst->base.next); if (!block->first) { GLES_ASSERT(!block->last); block->first = block->last = inst; } else { GLES_ASSERT(block->last); block->last->base.next = inst; inst->base.prev = block->last; block->last = inst; } }
/** * Generate an conditional instruction. * * @param gen reference to code generator object * @param op instruction opcode * @param cond branch condition * @param selectX selector for 1st condition flag * @param selectY selector for 2nd condition flag * @param selectZ selector for 3rd condition flag * @param selectW selector for 4th condition flag */ void GlesGenInstCond(struct ShaderProgramGenerator * gen, Opcode op, Cond cond, GLubyte selectX, GLubyte selectY, GLubyte selectZ, GLubyte selectW) { Inst * inst; GLES_ASSERT(gen); /* this is a special case, since an IF with a constant condition will be removed */ if (cond != CondT && cond != CondF) { gen->instructionCount++; } if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstCond)); InitInstCond(&inst->cond, op, cond, selectX, selectY, selectZ, selectW); AppendInst(gen->currentList->tail, inst); }
/** * Terminate a for loop * * @param compiler reference to compiler object * * @return GL_TRUE if successful, otherwise GL_FALSE */ GLboolean GlesCreateStmntEndFor(Compiler * compiler) { GLES_ASSERT(compiler->currentLoop); compiler->currentLoop = compiler->currentLoop->outer; GlesGenInstBase(&compiler->generator, OpcodeENDREP); return GL_TRUE; }
void GlesDeleteShader(State * state, Shader * shader) { GLES_ASSERT(shader - state->shaders >= 0 && shader - state->shaders < GLES_MAX_SHADERS); FreeShaderSource(shader); FreeShaderIntermediate(shader); GlesLogDeInit(&shader->log); GlesUnbindObject(state->shaderFreeList, GLES_MAX_SHADERS, shader - state->shaders); }
static void InitShader(Shader * shader, GLenum shaderType) { GLES_ASSERT(shaderType == GL_FRAGMENT_SHADER || shaderType == GL_VERTEX_SHADER); GlesLogInit(&shader->log); shader->type = shaderType; shader->attachmentCount = 0; shader->isDeleted = GL_FALSE; shader->text = NULL; shader->length = 0; shader->il = NULL; shader->size = 0; }
/*********************************************************************************** Function Name : NamedItemDelRefByName Inputs : gc, psNamesArray, ui32Num, ui32Name Outputs : - Returns : - Description : Decreases the refcount of a list of items given their names. The objects are deleted if their refcount drops to zero. The names are removed from the list whether the objects are deleted or not. The array ui32Name must have length ui32Num. Names that do not match an object in the array are ignored silently. ************************************************************************************/ IMG_INTERNAL IMG_VOID NamedItemDelRefByName(GLES2Context *gc, GLES2NamesArray *psNamesArray, IMG_UINT32 ui32Num, const IMG_UINT32 ui32Name[/*ui32Num*/]) { IMG_UINT32 i; GLES2NamedItem *psNamedItem, *psNext, *psDeadMan = IMG_NULL; GLES2_TIME_START(GLES2_TIMER_NAMES_ARRAY); LOCK_NAMES_ARRAY(psNamesArray); for(i=0; i < ui32Num; ++i) { psNamedItem = LookupItemByName(psNamesArray, ui32Name[i]); if(psNamedItem) { GLES_ASSERT(psNamedItem->ui32RefCount > 0); /* Remove the name from the list even if the object is not going to be deleted */ RemoveItemFromList(psNamesArray, psNamedItem); if(psNamedItem->ui32RefCount == 1) { /* The item must be deleted. Append it to the list of dead items */ psNamedItem->ui32RefCount = 0; psNamedItem->psNext = psDeadMan; psDeadMan = psNamedItem; } else if(psNamedItem->ui32RefCount > 1) { psNamedItem->ui32RefCount--; } } } UNLOCK_NAMES_ARRAY(psNamesArray); GLES2_TIME_STOP(GLES2_TIMER_NAMES_ARRAY); while(psDeadMan) { psNext = psDeadMan->psNext; if(psDeadMan->bGeneratedButUnused) { GLES2Free(gc, psDeadMan); } else { psNamesArray->pfnFree(gc, psDeadMan, IMG_FALSE); } psDeadMan = psNext; } }
/** * Generate an instruction that takes a vector argument but does not * have any result register. * * @param gen reference to code generator object * @param op instruction opcode * @param src source operand */ void GlesGenInstSrc(struct ShaderProgramGenerator * gen, Opcode op, const SrcReg * src) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(src); gen->instructionCount++; if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstSrc)); InitInstSrc(&inst->src, op, src); AppendInst(gen->currentList->tail, inst); }
/** * Generate a RET instruction in the resulting instruction stream. * * For functions with a return type of void, the return value has to be NULL. * For functions with a non-void return type, the type of the return value * has to match the return type. * * @param compiler reference to compiler object * @param expr reference to result value; can be NULL * * @return GL_TRUE if generation of return instruction sequence was * successful, otherwise GL_FALSE. */ GLboolean GlesCreateStmntReturn(Compiler * compiler, Expression * expr) { GLES_ASSERT(compiler->currentFunction); GLES_ASSERT(compiler->currentFunction->base.type->base.kind == TypeFunction); if (compiler->currentFunction->base.type->func.returnType->base.kind != TypeVoid) { /* need a result */ Expression * resultExpr; if (!expr) { /* Function declared with a return value but return statement has no argument. */ GlesCompileError(compiler, ErrS0038); return GL_FALSE; } if (!GlesTypeMatches(expr->base.type, compiler->currentFunction->base.type->func.returnType)) { /* Return type of function definition must match return type of function declaration. */ GlesCompileError(compiler, ErrS0042); return GL_FALSE; } resultExpr = GlesCreateExprReference(compiler, compiler->currentFunction->base.type->func.returnType, compiler->currentFunction->result, NULL, 0); /* assign result value to result variable */ GlesCreateExprAssign(compiler, resultExpr, expr); } else if (expr) { /* Function declared void but return statement has an argument */ GlesCompileError(compiler, ErrS0039); return GL_FALSE; } GlesGenInstCond(&compiler->generator, OpcodeRET, CondT, 0, 0, 0, 0); return GL_TRUE; }
/** * Create a new instruction sequence basic block. * * @param gen reference to compiler object * * @return a newly generated block appended to the current list of blocks */ Block * GlesCreateBlock(ShaderProgramGenerator * gen) { Block * result; if (!gen->currentList) { return NULL; } result = GlesMemoryPoolAllocate(gen->result->memory, sizeof(Block)); result->id = gen->result->numBlocks++; result->prev = gen->currentList->tail; if (gen->currentList->tail) { GLES_ASSERT(gen->currentList->head); gen->currentList->tail->next = result; } else { GLES_ASSERT(!gen->currentList->head); gen->currentList->head = result; } gen->currentList->tail = result; return result; }
/*********************************************************************************** Function Name : RemoveItemFromList Inputs : psNamedItem Outputs : - Returns : - Description : Removes a named item from the linked list of the hash table. This function updates the linked list appropriately. This function does NOT free the memory used by the item. ************************************************************************************/ static IMG_VOID RemoveItemFromList(GLES2NamesArray* psNamesArray, GLES2NamedItem* psNamedItem) { IMG_UINT32 ui32Position; GLES2NamedItem *psPrev; ui32Position = BucketForName(psNamedItem->ui32Name); GLES_ASSERT(ui32Position < GLES2_DEFAULT_NAMES_ARRAY_SIZE); psPrev = psNamesArray->apsEntry[ui32Position]; if(psPrev) { if(psPrev == psNamedItem) { /* The list starts with the element we are removing */ psNamesArray->apsEntry[ui32Position] = psNamedItem->psNext; } else { /* The list didn't start with the element we are removing */ while(psPrev && psPrev->psNext != psNamedItem) { psPrev = psPrev->psNext; } if(psPrev) { psPrev->psNext = psNamedItem->psNext; } else { /* The item was not in the names array. Maybe its name was removed previously */ return; } } } else { /* The item was not in the names array. Maybe its name was removed previously */ return; } if(!psNamedItem->bGeneratedButUnused) { /* The item was succesfully removed from the names array */ psNamesArray->ui32NumItems--; } }
/** * Generate a base instruction. * * @param gen reference to code generator object * @param op instruction opcode */ void GlesGenInstBase(ShaderProgramGenerator * gen, Opcode op) { Inst * inst; GLES_ASSERT(gen); if (!gen->currentList) { return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstBase)); InitInstBase(&inst->base, InstKindBase, op); AppendInst(gen->currentList->tail, inst); }
/** * Generate memory access instruction (only used in low level IL). * * @param gen reference to code generator object * @param op instruction opcode * @param dst destination * @param src source operand * @param index index to use, can be NULL * @param offset constant offset to apply */ void GlesGenInstMemory(ShaderProgramGenerator * gen, Opcode op, const DstReg * dst, const SrcReg * src, const SrcReg * index, GLsizeiptr offset) { Inst * inst; GLES_ASSERT(gen); GLES_ASSERT(dst); if (!gen->currentList) { /* * Code generation is currently suppressed; keep track of violation of * constant expressions. */ gen->constViolation |= gen->constExpression; return; } inst = GlesMemoryPoolAllocate(gen->result->memory, sizeof(InstMemory)); InitInstMemory(&inst->memory, op, dst, src, index, offset); AppendInst(gen->currentList->tail, inst); }
/** * Calculate the number of iterations. * * @param initial reference to the initial value of the loop index variable * @param boundary reference to the boundary value for the loop index * @param increment reference to the increment value for the loop index * @param condition the condition operation used in the loop condition clause * * @return the number of iterations, or ~0 if the loop is not valid. */ static GLint CalcNumIterations(Expression * initial, Expression * boundary, Expression * increment, Cond condition) { if (initial->base.type->base.kind == TypeInt) { return CalcNumIterationsInt(initial->constant.value[0].intValue[0], boundary->constant.value[0].intValue[0], increment->constant.value[0].intValue[0], condition); } else { GLES_ASSERT(initial->base.type->base.kind == TypeFloat); return CalcNumIterationsFloat(initial->constant.value[0].floatValue[0], boundary->constant.value[0].floatValue[0], increment->constant.value[0].floatValue[0], condition); } }
/*********************************************************************************** Function Name : LookupItemByName Inputs : psNamesArray, ui32Name Outputs : - Returns : The item with the given name or IMG_NULL of no item with that name exists in the names array. Description : The hash table implementation uses a chained list to resolve collisions. The names array must have been locked previously. ************************************************************************************/ static GLES2NamedItem* LookupItemByName(const GLES2NamesArray* psNamesArray, IMG_UINT32 ui32Name) { IMG_UINT32 ui32Position; GLES2NamedItem *psNamedItem; ui32Position = BucketForName(ui32Name); GLES_ASSERT(ui32Position < GLES2_DEFAULT_NAMES_ARRAY_SIZE); psNamedItem = psNamesArray->apsEntry[ui32Position]; /* Iterate the list until we find the end or the item */ while(psNamedItem && psNamedItem->ui32Name != ui32Name) { psNamedItem = psNamedItem->psNext; } return psNamedItem; }
/** * Insert the contents of the given list of instructions blocks at the * current point in the overall instruction sequence. * * @param gen reference to compiler object * @param list reference to list of blocks to insert */ void GlesInsertBlockList(struct ShaderProgramGenerator * gen, BlockList * list) { GLES_ASSERT(gen->currentList != list); while (list->head) { Block * block = list->head; list->head = block->next; block->next = NULL; block->prev = gen->currentList->tail; if (gen->currentList->tail) { gen->currentList->tail->next = block; } else { gen->currentList->head = block; } gen->currentList->tail = block; } list->tail = NULL; }
/* OES_shader_source */ GL_API void GL_APIENTRY glCompileShader (GLuint shader) { State * state = GLES_GET_STATE(); Shader * shaderObject = GlesGetShaderObject(state, shader); if (!shaderObject) { return; } GlesLogClear(&shaderObject->log); if (!state->compiler) { state->compiler = GlesCompilerCreate(state); if (!state->compiler) { GlesRecordOutOfMemory(state); return; } } shaderObject->isCompiled = GlesCompileShader(state->compiler, shaderObject); GLES_ASSERT(shaderObject->isCompiled == (shaderObject->il != NULL)); }
/*********************************************************************************** Function Name : CreateSharedState Inputs : gc, psShareContext Outputs : - Returns : Success Description : Initialises the data shared between contexts. ************************************************************************************/ static IMG_BOOL CreateSharedState(GLES2Context *gc, GLES2Context *psShareContext) { GLES2ContextSharedState *psSharedState; GLES2NameType aeNameType[GLES2_MAX_SHAREABLE_NAMETYPE] = { GLES2_NAMETYPE_TEXOBJ, GLES2_NAMETYPE_PROGRAM, GLES2_NAMETYPE_BUFOBJ, GLES2_NAMETYPE_RENDERBUFFER, GLES2_NAMETYPE_FRAMEBUFFER }; IMG_UINT32 i; /* * Init shared structures unless we're sharing them * with another context, in which they are already initialized. */ if(!gc->psSharedState) { if(psShareContext) { /* Get the shared state from the other context */ GLES_ASSERT(psShareContext->psSharedState); /* *** START CRITICAL SECTION *** */ PVRSRVLockMutex(psShareContext->psSharedState->hPrimaryLock); gc->psSharedState = psShareContext->psSharedState; gc->psSharedState->ui32RefCount++; PVRSRVUnlockMutex(psShareContext->psSharedState->hPrimaryLock); /* *** END CRITICAL SECTION *** */ } else { PVRSRV_ERROR eError; /* Create shared state */ psSharedState = GLES2Calloc(gc, sizeof(GLES2ContextSharedState)); if(!psSharedState) { return IMG_FALSE; } gc->psSharedState = psSharedState; psSharedState->ui32RefCount = 1; eError = PVRSRVCreateMutex(&psSharedState->hPrimaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: PVRSRVCreateMutex failed on hPrimaryLock (%d)", eError)); GLES2Free(gc, psSharedState); return IMG_FALSE; } eError = PVRSRVCreateMutex(&psSharedState->hSecondaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: PVRSRVCreateMutex failed on hSecondaryLock (%d)", eError)); eError = PVRSRVDestroyMutex(psSharedState->hPrimaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hPrimaryLock (%d)", eError)); } GLES2Free(gc, psSharedState); return IMG_FALSE; } eError = PVRSRVCreateMutex(&psSharedState->hTertiaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: PVRSRVCreateMutex failed on hTertiaryLock (%d)", eError)); eError = PVRSRVDestroyMutex(psSharedState->hSecondaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hSecondaryLock (%d)", eError)); } eError = PVRSRVDestroyMutex(psSharedState->hPrimaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hPrimaryLock (%d)", eError)); } GLES2Free(gc, psSharedState); return IMG_FALSE; } eError = PVRSRVCreateMutex(&psSharedState->hFlushListLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: PVRSRVCreateMutex failed on hFlushListLock (%d)", eError)); eError = PVRSRVDestroyMutex(psSharedState->hTertiaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hTertiaryLock (%d)", eError)); } eError = PVRSRVDestroyMutex(psSharedState->hSecondaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hSecondaryLock (%d)", eError)); } eError = PVRSRVDestroyMutex(psSharedState->hPrimaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: PVRSRVDestroyMutex failed on hPrimaryLock (%d)", eError)); } GLES2Free(gc, psSharedState); return IMG_FALSE; } /* Initialize the texture manager. * Make sure that gc->psSharedState points to the right place before calling this */ psSharedState->psTextureManager = CreateTextureManager(gc); if(!psSharedState->psTextureManager) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: Couldn't initialise the texture manager")); FreeContextSharedState(gc); return IMG_FALSE; } /* Initialize the USSE code variant manager */ if(!KRM_Initialize(&psSharedState->sUSEShaderVariantKRM, KRM_TYPE_3D, IMG_TRUE, psSharedState->hSecondaryLock, gc->ps3DDevData, gc->psSysContext->sHWInfo.sMiscInfo.hOSGlobalEvent, ReclaimUSEShaderVariantMemKRM, IMG_TRUE, DestroyUSECodeVariantGhostKRM)) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: Couldn't initialise the USSE code variant manager")); FreeContextSharedState(gc); return IMG_FALSE; } /* Initialize the TA kick buffer object manager */ if(!KRM_Initialize(&psSharedState->sBufferObjectKRM, KRM_TYPE_TA, IMG_TRUE, psSharedState->hSecondaryLock, gc->ps3DDevData, gc->psSysContext->sHWInfo.sMiscInfo.hOSGlobalEvent, ReclaimBufferObjectMemKRM, IMG_TRUE, DestroyBufferObjectGhostKRM)) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: Couldn't initialise the TA kick buffer object manager")); FreeContextSharedState(gc); return IMG_FALSE; } /* Initialize the code memory heaps */ psSharedState->psUSEVertexCodeHeap = UCH_CodeHeapCreate(gc->ps3DDevData, UCH_USE_CODE_HEAP_TYPE, gc->psSysContext->hUSEVertexHeap, psSharedState->hSecondaryLock); if(!psSharedState->psUSEVertexCodeHeap) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: Failed to create USSE vertex code heap!\n")); FreeContextSharedState(gc); return IMG_FALSE; } psSharedState->psUSEFragmentCodeHeap = UCH_CodeHeapCreate(gc->ps3DDevData, UCH_USE_CODE_HEAP_TYPE, gc->psSysContext->hUSEFragmentHeap, psSharedState->hSecondaryLock); if(!psSharedState->psUSEFragmentCodeHeap) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: Failed to create USSE fragment code heap!\n")); FreeContextSharedState(gc); return IMG_FALSE; } psSharedState->psPDSFragmentCodeHeap = UCH_CodeHeapCreate(gc->ps3DDevData, UCH_PDS_CODE_HEAP_TYPE, gc->psSysContext->hPDSFragmentHeap, psSharedState->hSecondaryLock); if(!psSharedState->psPDSFragmentCodeHeap) { PVR_DPF((PVR_DBG_ERROR, "CreateSharedState: Failed to create PDS fragment code heap!\n")); FreeContextSharedState(gc); return IMG_FALSE; } /* Initialize the shareable names arrays */ for(i = 0; i < GLES2_MAX_SHAREABLE_NAMETYPE; ++i) { psSharedState->apsNamesArray[i] = CreateNamesArray(gc, aeNameType[i], psSharedState->hPrimaryLock); if(!psSharedState->apsNamesArray[i]) { PVR_DPF((PVR_DBG_ERROR,"CreateSharedState: Couldn't create names array %d", i)); FreeContextSharedState(gc); return IMG_FALSE; } } } } GLES_ASSERT(gc->psSharedState); return IMG_TRUE; }
/*********************************************************************************** Function Name : InsertNamedItem Inputs : psNamesArray, psNamedItem Outputs : - Returns : IMG_TRUE if successfull. IMG_FALSE otherwise. Description : Inserts a new named item in the names array. The item and its name must be unique in the names array. Its refcount is initialized automatically when it is inserted. ************************************************************************************/ IMG_INTERNAL IMG_BOOL InsertNamedItem(GLES2NamesArray *psNamesArray, GLES2NamedItem* psNamedItemToInsert) { IMG_UINT32 ui32Position, ui32Name; GLES2NamedItem *psNamedItem, *psPrev = IMG_NULL; IMG_BOOL bResult = IMG_TRUE; __GLES2_GET_CONTEXT_RETURN(IMG_FALSE); if(!psNamedItemToInsert || !psNamedItemToInsert->ui32Name) { return IMG_FALSE; } GLES2_TIME_START(GLES2_TIMER_NAMES_ARRAY); psNamedItemToInsert->ui32RefCount = 1; psNamedItemToInsert->psNext = IMG_NULL; ui32Name = psNamedItemToInsert->ui32Name; ui32Position = BucketForName(ui32Name); GLES_ASSERT(ui32Position < GLES2_DEFAULT_NAMES_ARRAY_SIZE); LOCK_NAMES_ARRAY(psNamesArray); /* * When we insert an item we make sure that its name is unique. * It's slightly slower than simply inserting it at the front of the list, * but we can sleep better at night. */ psNamedItem = psNamesArray->apsEntry[ui32Position]; if(!psNamedItem) { if(psNamesArray->bGeneratedOnly && !psNamedItemToInsert->bGeneratedButUnused) { /* There should have been a duplicate bGeneratedButUnused name. This must be a user-supplied name */ bResult = IMG_FALSE; } else { /* The list is empty. The name is necessarily unique */ psNamesArray->apsEntry[ui32Position] = psNamedItemToInsert; } } else { /* The list is not empty. Check that the name is unique */ while(psNamedItem && psNamedItem->ui32Name != ui32Name) { psPrev = psNamedItem; psNamedItem = psNamedItem->psNext; } /* Did we stop because we found a duplicate name? */ if(psNamedItem) { if(psNamedItem->bGeneratedButUnused) { if(psPrev) { psPrev->psNext = psNamedItemToInsert; psNamedItemToInsert->psNext = psNamedItem->psNext; } else { psNamesArray->apsEntry[ui32Position] = psNamedItemToInsert; } GLES2Free(gc, psNamedItem); } else { /* Yes, there's a duplicate. Do not insert. */ bResult = IMG_FALSE; } } else { if(psNamesArray->bGeneratedOnly && !psNamedItemToInsert->bGeneratedButUnused) { /* There should have been a duplicate bGeneratedButUnused name. This must be a user-supplied name */ bResult = IMG_FALSE; } else { /* No. There are no duplicates :) Insert as requested */ psPrev->psNext = psNamedItemToInsert; } } } if(bResult && !psNamedItemToInsert->bGeneratedButUnused) { /* The item was really inserted */ psNamesArray->ui32NumItems++; } /* If the insertion fails, then this named item's RefCount is set back to 0 */ if (!bResult) { psNamedItemToInsert->ui32RefCount = 0; } UNLOCK_NAMES_ARRAY(psNamesArray); GLES2_TIME_STOP(GLES2_TIMER_NAMES_ARRAY); return bResult; }
/** * while is currently not supported. * * @param compiler reference to compiler object * * @return GL_FALSE to indicate failure */ GLboolean GlesCreateStmntEndWhile(Compiler * compiler) { GLES_ASSERT(GL_FALSE); return GL_FALSE; }
/*********************************************************************************** Function Name : InitContext Inputs : gc, psShareContext, psMode Outputs : - Returns : Success Description : Initialises a context - may setup shared name tables from a sharecontext. Also sets up default framebuffer ************************************************************************************/ static IMG_BOOL InitContext(GLES2Context *gc, GLES2Context *psShareContext, EGLcontextMode *psMode) { #if defined(GLES2_EXTENSION_VERTEX_ARRAY_OBJECT) GLES2NameType aeNameType[GLES2_MAX_UNSHAREABLE_NAMETYPE] = { GLES2_NAMETYPE_VERARROBJ }; #endif /* defined(GLES2_EXTENSION_VERTEX_ARRAY_OBJECT) */ IMG_UINT32 i, j; GLES_ASSERT(gc); GetApplicationHints(&gc->sAppHints, psMode); #if defined(FIX_HW_BRN_26922) if(!AllocateBRN26922Mem(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: AllocateBRN26922Mem failed")); goto FAILED_AllocateBRN26922Mem; } #endif /* defined(FIX_HW_BRN_26922) */ if(!CreateSharedState(gc, psShareContext)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateSharedState failed")); goto FAILED_CreateSharedState; } #if defined(GLES2_EXTENSION_VERTEX_ARRAY_OBJECT) /* Initialize the unshareable names arrays */ for (i = 0; i < GLES2_MAX_UNSHAREABLE_NAMETYPE; i++) { gc->apsNamesArray[i] = CreateNamesArray(gc, aeNameType[i], (PVRSRV_MUTEX_HANDLE)0); if(!gc->apsNamesArray[i]) { PVR_DPF((PVR_DBG_ERROR,"InitContext: Couldn't create unshareable names array %d", i)); DestroyNamesArray(gc, gc->apsNamesArray[i]); return IMG_FALSE; } } #endif /* defined(GLES2_EXTENSION_VERTEX_ARRAY_OBJECT) */ if(GLES2ALLOCDEVICEMEM(gc->ps3DDevData, gc->psSysContext->hSyncInfoHeap, PVRSRV_MEM_WRITE | PVRSRV_MEM_READ | PVRSRV_MEM_NO_SYNCOBJ | PVRSRV_MEM_CACHE_CONSISTENT, 4, 0, &gc->sKRMTAStatusUpdate.psMemInfo) != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "InitContext: Failed to create TA sync object")); goto FAILED_TASync; } gc->sKRMTAStatusUpdate.ui32StatusValue = 1; PVRSRVMemSet(gc->sKRMTAStatusUpdate.psMemInfo->pvLinAddr, 0, 4); if(!HashTableCreate(gc, &gc->sProgram.sPDSFragmentVariantHashTable, STATEHASH_LOG2TABLESIZE, STATEHASH_MAXNUMENTRIES, DestroyHashedPDSVariant)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: HashTableCreate failed")); goto FAILED_CreateHashTable; } if(!CreateTextureState(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateTextureState failed")); goto FAILED_CreateTextureState; } if(!CreateProgramState(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateProgramState failed")); goto FAILED_CreateProgramState; } if(!CreateBufObjState(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateBufObjState failed")); goto FAILED_CreateBufObjState; } if(!CreateFrameBufferState(gc, psMode)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateRenderBufferState failed")); goto FAILED_CreateFrameBufferState; } if(!CreateVertexArrayObjectState(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: CreateVertexArrayObjectState failed")); goto FAILED_CreateVertexArrayObjectState; } /* Initialise the TA kick VAO manager */ if(!KRM_Initialize(&gc->sVAOKRM, KRM_TYPE_TA, IMG_FALSE, 0, /* PVRSRV_MUTEX_HANDLE */ gc->ps3DDevData, gc->psSysContext->sHWInfo.sMiscInfo.hOSGlobalEvent, ReclaimVAOMemKRM, IMG_TRUE, DestroyVAOGhostKRM)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: Couldn't initialise the TA kick VAO manager")); goto FAILED_CreateVertexArrayObjectState; } if(!InitSpecialUSECodeBlocks(gc)) { PVR_DPF((PVR_DBG_ERROR,"InitContext: InitSpecialUSECodeBlocks failed")); goto FAILED_InitSpecialUSECodeBlocks; } gc->sState.sRaster.ui32ColorMask = GLES2_COLORMASK_ALL; gc->sState.sRaster.sClearColor.fRed = GLES2_Zero; gc->sState.sRaster.sClearColor.fGreen = GLES2_Zero; gc->sState.sRaster.sClearColor.fBlue = GLES2_Zero; gc->sState.sRaster.sClearColor.fAlpha = GLES2_Zero; gc->sState.sRaster.ui32BlendFactor = ((GLES2_BLENDFACTOR_ONE << GLES2_BLENDFACTOR_RGBSRC_SHIFT) | (GLES2_BLENDFACTOR_ONE << GLES2_BLENDFACTOR_ALPHASRC_SHIFT) | (GLES2_BLENDFACTOR_ZERO << GLES2_BLENDFACTOR_RGBDST_SHIFT) | (GLES2_BLENDFACTOR_ZERO << GLES2_BLENDFACTOR_ALPHADST_SHIFT)); gc->sState.sRaster.ui32BlendEquation = (GLES2_BLENDFUNC_ADD << GLES2_BLENDFUNC_RGB_SHIFT) | (GLES2_BLENDFUNC_ADD << GLES2_BLENDFUNC_ALPHA_SHIFT); gc->sState.sRaster.sBlendColor.fRed = GLES2_Zero; gc->sState.sRaster.sBlendColor.fGreen = GLES2_Zero; gc->sState.sRaster.sBlendColor.fBlue = GLES2_Zero; gc->sState.sRaster.sBlendColor.fAlpha = GLES2_Zero; gc->sState.sLine.fWidth = GLES2_One; gc->sState.sPolygon.eCullMode = GL_BACK; gc->sState.sPolygon.eFrontFaceDirection = GL_CCW; gc->sState.sPolygon.factor.fVal = GLES2_Zero; gc->sState.sPolygon.fUnits = GLES2_Zero; gc->sState.sStencil.ui32FFStencil = EURASIA_ISPC_SCMP_ALWAYS | EURASIA_ISPC_SOP1_KEEP | EURASIA_ISPC_SOP2_KEEP | EURASIA_ISPC_SOP3_KEEP | (GLES2_MAX_STENCIL_VALUE << EURASIA_ISPC_SCMPMASK_SHIFT) | (GLES2_MAX_STENCIL_VALUE << EURASIA_ISPC_SWMASK_SHIFT); gc->sState.sStencil.ui32BFStencil = EURASIA_ISPC_SCMP_ALWAYS | EURASIA_ISPC_SOP1_KEEP | EURASIA_ISPC_SOP2_KEEP | EURASIA_ISPC_SOP3_KEEP | (GLES2_MAX_STENCIL_VALUE << EURASIA_ISPC_SCMPMASK_SHIFT) | (GLES2_MAX_STENCIL_VALUE << EURASIA_ISPC_SWMASK_SHIFT); gc->sState.sStencil.ui32FFStencilRef = (0 << EURASIA_ISPA_SREF_SHIFT); gc->sState.sStencil.ui32BFStencilRef = (0 << EURASIA_ISPA_SREF_SHIFT); gc->sState.sStencil.ui32Clear = 0; gc->sState.sStencil.ui32FFStencilCompareMaskIn = GLES2_MAX_STENCIL_VALUE; gc->sState.sStencil.ui32BFStencilCompareMaskIn = GLES2_MAX_STENCIL_VALUE; gc->sState.sStencil.ui32FFStencilWriteMaskIn = GLES2_MAX_STENCIL_VALUE; gc->sState.sStencil.ui32BFStencilWriteMaskIn = GLES2_MAX_STENCIL_VALUE; gc->sState.sStencil.i32FFStencilRefIn = 0; gc->sState.sStencil.i32BFStencilRefIn = 0; gc->sState.sStencil.ui32MaxFBOStencilVal = GLES2_MAX_STENCIL_VALUE; gc->sState.sMultisample.bSampleCoverageInvert = IMG_FALSE; gc->sState.sMultisample.fSampleCoverageValue = GLES2_One; gc->sState.sDepth.ui32TestFunc = EURASIA_ISPA_DCMPMODE_LT; gc->sState.sDepth.fClear = GLES2_One; gc->ui32Enables = GLES2_DITHER_ENABLE; gc->sState.sClientPixel.ui32UnpackAlignment = 4; gc->sState.sClientPixel.ui32PackAlignment = 4; gc->ui32DirtyState = GLES2_DIRTYFLAG_ALL; gc->ui32EmitMask = GLES2_EMITSTATE_ALL; /* * Set up attrib array default values */ for (i=0; i < GLES2_MAX_VERTEX_ATTRIBS; ++i) { GLES2AttribArrayPointerState *psAPState = &(gc->sVAOMachine.sDefaultVAO.asVAOState[AP_VERTEX_ATTRIB0 + i]); psAPState->ui32StreamTypeSize = GLES2_STREAMTYPE_FLOAT | (4 << GLES2_STREAMSIZE_SHIFT); gc->sVAOMachine.asAttribPointer[AP_VERTEX_ATTRIB0 + i].psState = psAPState; gc->sVAOMachine.asAttribPointer[AP_VERTEX_ATTRIB0 + i].ui32Size = 16; gc->sVAOMachine.asAttribPointer[AP_VERTEX_ATTRIB0 + i].ui32Stride = 16; gc->sVAOMachine.asCurrentAttrib[AP_VERTEX_ATTRIB0 + i].fX = GLES2_Zero; gc->sVAOMachine.asCurrentAttrib[AP_VERTEX_ATTRIB0 + i].fY = GLES2_Zero; gc->sVAOMachine.asCurrentAttrib[AP_VERTEX_ATTRIB0 + i].fZ = GLES2_Zero; gc->sVAOMachine.asCurrentAttrib[AP_VERTEX_ATTRIB0 + i].fW = GLES2_One; } for(i=0; i < GLES2_HINT_NUMHINTS; i++) { gc->sState.sHints.eHint[i] = GL_DONT_CARE; } j = 0; for(i=0; i < CBUF_NUM_TA_BUFFERS; i++) { IMG_UINT32 ui32Size; IMG_HANDLE hMemHeap; switch(i) { case CBUF_TYPE_PDS_VERT_BUFFER: { hMemHeap = gc->psSysContext->hPDSVertexHeap; ui32Size = gc->sAppHints.ui32DefaultPDSVertBufferSize; break; } case CBUF_TYPE_VERTEX_DATA_BUFFER: { hMemHeap = gc->psSysContext->hGeneralHeap; ui32Size = gc->sAppHints.ui32DefaultVertexBufferSize; break; } case CBUF_TYPE_INDEX_DATA_BUFFER: { hMemHeap = gc->psSysContext->hGeneralHeap; ui32Size = gc->sAppHints.ui32DefaultIndexBufferSize; break; } case CBUF_TYPE_VDM_CTRL_BUFFER: { hMemHeap = gc->psSysContext->hGeneralHeap; ui32Size = gc->sAppHints.ui32DefaultVDMBufferSize; break; } case CBUF_TYPE_PDS_VERT_SECONDARY_PREGEN_BUFFER: { PVR_DPF((PVR_DBG_MESSAGE,"InitContext: ignoring buffer type CBUF_TYPE_PDS_VERT_SECONDARY_PREGEN_BUFFER")); hMemHeap = gc->psSysContext->hPDSVertexHeap; ui32Size = 4; break; } case CBUF_TYPE_MTE_COPY_PREGEN_BUFFER: { hMemHeap = gc->psSysContext->hPDSVertexHeap; if(gc->sAppHints.bEnableStaticMTECopy) { ui32Size = ((gc->sAppHints.ui32DefaultPregenMTECopyBufferSize / GLES2_ALIGNED_MTE_COPY_PROG_SIZE) * GLES2_ALIGNED_MTE_COPY_PROG_SIZE); } else { PVR_DPF((PVR_DBG_WARNING,"InitContext: ignoring buffer type CBUF_TYPE_MTE_COPY_PREGEN_BUFFER")); ui32Size = 4; } break; } case CBUF_TYPE_PDS_AUXILIARY_PREGEN_BUFFER: { /* Unused */ gc->apsBuffers[i] = IMG_NULL; continue; } default: { PVR_DPF((PVR_DBG_ERROR,"InitContext: Invalid buffer type")); goto FAILED_CBUF_CreateBuffer; } } gc->apsBuffers[i] = CBUF_CreateBuffer(gc->ps3DDevData, i, hMemHeap, gc->psSysContext->hSyncInfoHeap, gc->psSysContext->sHWInfo.sMiscInfo.hOSGlobalEvent, ui32Size); if(!gc->apsBuffers[i]) { PVR_DPF((PVR_DBG_ERROR,"InitContext: Failed to create buffer %u",i)); goto FAILED_CBUF_CreateBuffer; } /* Point the TA Kick status update to the device memory reserved for status updates in the buffer */ gc->sKickTA.asTAStatusUpdate[j].hKernelMemInfo = gc->apsBuffers[i]->psStatusUpdateMemInfo->hKernelMemInfo; gc->sKickTA.asTAStatusUpdate[j].sCtlStatus.sStatusDevAddr.uiAddr = gc->apsBuffers[i]->psStatusUpdateMemInfo->sDevVAddr.uiAddr; /* set the read offset pointer in the buffer */ gc->apsBuffers[i]->pui32ReadOffset = (IMG_UINT32*)gc->apsBuffers[i]->psStatusUpdateMemInfo->pvLinAddr; j++; if(i == CBUF_TYPE_MTE_COPY_PREGEN_BUFFER) { if(gc->sAppHints.bEnableStaticMTECopy) { if(SetupMTEPregenBuffer(gc) != GLES2_NO_ERROR) { PVR_DPF((PVR_DBG_ERROR,"InitContext: Failed to fill pregen buffer %u",i)); goto FAILED_CBUF_CreateBuffer; } } } } gc->sKickTA.sKickTACommon.ui32NumTAStatusVals = j; /* Setup 3D status val sync */ gc->sKickTA.sKickTACommon.ui32Num3DStatusVals = 2; if(BuildExtensionString(gc) != IMG_TRUE) { goto FAILED_BuildExtensionString; } #if defined(SGX_FEATURE_SW_VDM_CONTEXT_SWITCH) gc->sSmallKickTA.ui32NumIndicesThisTA = 0; gc->sSmallKickTA.ui32NumPrimitivesThisTA = 0; gc->sSmallKickTA.ui32NumIndicesThisFrame = 0; gc->sSmallKickTA.ui32NumPrimitivesThisFrame = 0; /* Default value to ensure no TA splitting on the first frame */ gc->sSmallKickTA.ui32KickThreshold = 0xFFFFFFFF; #endif #if defined(DEBUG) if(gc->sAppHints.bDumpShaderAnalysis) { gc->pShaderAnalysisHandle = OpenShaderAnalysisFile(); } #endif /* defined(DEBUG) */ PDUMP_STRING_CONTINUOUS((gc, "PDump from OpenGL ES 2.0 driver, version %s. HW variant %s, %d\n",PVRVERSION_STRING, pszRenderer, SGX_CORE_REV)); return IMG_TRUE; /* Clean up any memory */ FAILED_BuildExtensionString: FAILED_CBUF_CreateBuffer: for(i=0; i < CBUF_NUM_TA_BUFFERS; i++) { if(gc->apsBuffers[i]) { CBUF_DestroyBuffer(gc->ps3DDevData, gc->apsBuffers[i]); } } FAILED_InitSpecialUSECodeBlocks: FreeVertexArrayObjectState(gc); FAILED_CreateVertexArrayObjectState: FreeFrameBufferState(gc); FAILED_CreateFrameBufferState: FreeBufObjState(gc); FAILED_CreateBufObjState: FreeProgramState(gc); FAILED_CreateProgramState: FreeTextureState(gc); FAILED_CreateTextureState: HashTableDestroy(gc, &gc->sProgram.sPDSFragmentVariantHashTable); FAILED_CreateHashTable: GLES2FREEDEVICEMEM(gc->ps3DDevData, gc->sKRMTAStatusUpdate.psMemInfo); FAILED_TASync: FreeContextSharedState(gc); FAILED_CreateSharedState: #if defined(FIX_HW_BRN_26922) FreeBRN26922Mem(gc); FAILED_AllocateBRN26922Mem: #endif /* defined(FIX_HW_BRN_26922) */ return IMG_FALSE; }
/*********************************************************************************** Function Name : FreeContextSharedState Inputs : gc Outputs : - Returns : Success. Description : Frees the data structures that are shared between multiple contexts. ************************************************************************************/ static IMG_VOID FreeContextSharedState(GLES2Context *gc) { IMG_UINT32 i; IMG_INT32 j; IMG_BOOL bDoFree = IMG_FALSE; GLES2ContextSharedState *psSharedState = gc->psSharedState; /* Frame buffer objects must be deleted first so that their attachments (renderbuffer/texture) can be removed safely */ GLES2NameType aeNameType[GLES2_MAX_SHAREABLE_NAMETYPE] = { GLES2_NAMETYPE_FRAMEBUFFER, GLES2_NAMETYPE_TEXOBJ, GLES2_NAMETYPE_PROGRAM, GLES2_NAMETYPE_BUFOBJ, GLES2_NAMETYPE_RENDERBUFFER }; /* Silently ignore NULL */ if(!psSharedState) { return; } /* *** CRITICAL SECTION *** */ PVRSRVLockMutex(psSharedState->hPrimaryLock); GLES_ASSERT(psSharedState->ui32RefCount > 0); if(psSharedState->ui32RefCount == 1) { bDoFree = IMG_TRUE; } psSharedState->ui32RefCount--; PVRSRVUnlockMutex(psSharedState->hPrimaryLock); /* *** END OF CRITICAL SECTION *** */ /* This was the last reference to this shared state. Time to free it for good */ if(bDoFree) { PVRSRV_ERROR eError; /* Make the managers wait for the resources in their lists */ KRM_WaitForAllResources(&psSharedState->psTextureManager->sKRM, GLES2_DEFAULT_WAIT_RETRIES); KRM_WaitForAllResources(&psSharedState->sUSEShaderVariantKRM, GLES2_DEFAULT_WAIT_RETRIES); /* Destroy all the shareable resources */ for(i = 0; i < GLES2_MAX_SHAREABLE_NAMETYPE; ++i) { j = aeNameType[i]; if (j < GLES2_MAX_SHAREABLE_NAMETYPE) { if(psSharedState->apsNamesArray[j]) { DestroyNamesArray(gc, psSharedState->apsNamesArray[j]); } } } /* Free the texture manager _after_ destroying the textures so the active list is empty */ /* XXX: Does the above comment still apply? --DavidG Oct2006 */ if(psSharedState->psTextureManager) { ReleaseTextureManager(gc, psSharedState->psTextureManager); } /* Destroy the USSE code variant manager _before_ destroying the heaps since it uses them */ KRM_Destroy(gc, &psSharedState->sUSEShaderVariantKRM); /* Destroy the TA kick buffer object manager */ KRM_Destroy(gc, &psSharedState->sBufferObjectKRM); /* Free the code heaps _after_ destroying the shaders and programs so the heaps are empty */ if(psSharedState->psUSEVertexCodeHeap) { UCH_CodeHeapDestroy(psSharedState->psUSEVertexCodeHeap); } if(psSharedState->psUSEFragmentCodeHeap) { UCH_CodeHeapDestroy(psSharedState->psUSEFragmentCodeHeap); } if(psSharedState->psPDSFragmentCodeHeap) { UCH_CodeHeapDestroy(psSharedState->psPDSFragmentCodeHeap); } if(psSharedState->psSequentialStaticIndicesMemInfo) { GLES2FREEDEVICEMEM(gc->ps3DDevData, psSharedState->psSequentialStaticIndicesMemInfo); } if(psSharedState->psLineStripStaticIndicesMemInfo) { GLES2FREEDEVICEMEM(gc->ps3DDevData, psSharedState->psLineStripStaticIndicesMemInfo); } if (psSharedState->hFlushListLock) { eError = PVRSRVDestroyMutex(psSharedState->hFlushListLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeContextSharedState: PVRSRVDestroyMutex failed on hFlushListLock (%d)", eError)); } } if (psSharedState->hTertiaryLock) { eError = PVRSRVDestroyMutex(psSharedState->hTertiaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeContextSharedState: PVRSRVDestroyMutex failed on hTertiaryLock (%d)", eError)); } } if (psSharedState->hSecondaryLock) { eError = PVRSRVDestroyMutex(psSharedState->hSecondaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeContextSharedState: PVRSRVDestroyMutex failed on hSecondaryLock (%d)", eError)); } } if (psSharedState->hPrimaryLock) { eError = PVRSRVDestroyMutex(psSharedState->hPrimaryLock); if (eError != PVRSRV_OK) { PVR_DPF((PVR_DBG_ERROR, "FreeContextSharedState: PVRSRVDestroyMutex failed on hPrimaryLock (%d)", eError)); } } /* Clear for safety */ GLES2MemSet(psSharedState, 0, sizeof(GLES2ContextSharedState)); GLES2Free(gc, psSharedState); } gc->psSharedState = IMG_NULL; }
/** * do-while is currently not supported. * * @param compiler reference to compiler object * * @return GL_FALSE to indicate failure */ GLboolean GlesCreateStmntEndDo(Compiler * compiler, Expression * cond) { GLES_ASSERT(GL_FALSE); return GL_FALSE; }
Symbol * GlesSymbolCreate(struct MemoryPool * pool, Scope * scope, const char * name, GLsizei length, GLsizei hash, Type * type, Qualifier qualifier) { GLsizeiptr size; Symbol * symbol; switch (qualifier) { case QualifierConstant: /* constant value */ case QualifierVariable: /* general variable */ case QualifierAttrib: /* vertex attrib */ case QualifierUniform: /* uniform value */ case QualifierVarying: /* varying value */ size = sizeof(SymbolVariable); break; case QualifierField: /* struct member */ size = sizeof(SymbolField); break; case QualifierFunction: /* user-defined function */ size = sizeof(SymbolFunction); break; case QualifierParameterIn: /* input parameter */ case QualifierParameterOut: /* output parameter */ case QualifierParameterInOut: /* input/output parameter */ size = sizeof(SymbolParameter); break; case QualifierTypeName: /* type name */ case QualifierPosition: /* gl_Position variable */ case QualifierPointSize: /* gl_PointSize */ case QualifierFragCoord: /* gl_FragCoord */ case QualifierFrontFacing: /* gl_FrontFacing */ case QualifierFragColor: /* gl_FragColor */ case QualifierFragData: /* gl_FragData */ case QualifierPointCoord: /* gl_PointCoord */ size = sizeof(SymbolBase); break; default: GLES_ASSERT(GL_FALSE); return NULL; } symbol = (Symbol *) GlesMemoryPoolAllocate(pool, size); symbol->base.name = (char *) GlesMemoryPoolAllocate(pool, length); GlesMemcpy(symbol->base.name, name, length); symbol->base.length = length; symbol->base.type = type; symbol->base.qualifier = qualifier; symbol->base.scope = scope; /*implied: symbol->base.next = NULL;*/ if (hash == ~0) { hash = GlesSymbolHash(name, length); } symbol->base.next = scope->buckets[hash]; scope->buckets[hash] = symbol; return symbol; }