DECLEXPORT(void) STATE_APIENTRY crStateAttachShader(GLuint program, GLuint shader) { CRGLSLProgram *pProgram = crStateGetProgramObj(program); CRGLSLShader *pShader; if (!pProgram) { crWarning("Unknown program %d", program); return; } if (crHashtableSearch(pProgram->currentState.attachedShaders, shader)) { /*shader already attached to this program*/ return; } pShader = crStateGetShaderObj(shader); if (!pShader) { crWarning("Unknown shader %d", shader); return; } pShader->refCount++; crHashtableAdd(pProgram->currentState.attachedShaders, shader, pShader); }
DECLEXPORT(GLuint) STATE_APIENTRY crStateGetShaderHWID(GLuint id) { CRGLSLShader *pShader = crStateGetShaderObj(id); #ifdef IN_GUEST CRASSERT(!pShader || pShader->hwid == id); #endif return pShader ? pShader->hwid : 0; }
DECLEXPORT(void) STATE_APIENTRY crStateCompileShader(GLuint shader) { CRGLSLShader *pShader = crStateGetShaderObj(shader); if (!pShader) { crWarning("Unknown shader %d", shader); return; } pShader->compiled = GL_TRUE; }
DECLEXPORT(GLuint) STATE_APIENTRY crStateCreateShader(GLuint hwid, GLenum type) { CRGLSLShader *pShader; CRContext *g = GetCurrentContext(); GLuint stateId = hwid; #ifdef IN_GUEST CRASSERT(!crStateGetShaderObj(stateId)); #else /* the proogram and shader names must not intersect because DeleteObjectARB must distinguish between them * see crStateDeleteObjectARB * this is why use programs table for shader keys allocation */ stateId = crHashtableAllocKeys(g->glsl.programs, 1); if (!stateId) { crWarning("failed to allocate program key"); return 0; } Assert((pShader = crStateGetShaderObj(stateId)) == NULL); #endif pShader = (CRGLSLShader *) crAlloc(sizeof(*pShader)); if (!pShader) { crWarning("crStateCreateShader: Out of memory!"); return 0; } pShader->id = stateId; pShader->hwid = hwid; pShader->type = type; pShader->source = NULL; pShader->compiled = GL_FALSE; pShader->deleted = GL_FALSE; pShader->refCount = 0; crHashtableAdd(g->glsl.shaders, stateId, pShader); return stateId; }
DECLEXPORT(GLuint) STATE_APIENTRY crStateCreateShader(GLuint hwid, GLenum type) { CRGLSLShader *pShader; CRContext *g = GetCurrentContext(); GLuint stateId = hwid; #ifdef IN_GUEST CRASSERT(!crStateGetShaderObj(stateId)); #else /* the id may not necesserily be hwid after save state restoration */ while ((pShader = crStateGetShaderObj(stateId)) != NULL) { GLuint newStateId = stateId + 7; crDebug("Shader object %d already exists, generating a new one, %d", stateId, newStateId); stateId = newStateId; } #endif pShader = (CRGLSLShader *) crAlloc(sizeof(*pShader)); if (!pShader) { crWarning("crStateCreateShader: Out of memory!"); return 0; } pShader->id = stateId; pShader->hwid = hwid; pShader->type = type; pShader->source = NULL; pShader->compiled = GL_FALSE; pShader->deleted = GL_FALSE; pShader->refCount = 0; crHashtableAdd(g->glsl.shaders, stateId, pShader); return stateId; }
DECLEXPORT(void) STATE_APIENTRY crStateDeleteShader(GLuint shader) { CRGLSLShader *pShader = crStateGetShaderObj(shader); if (!pShader) { crWarning("Unknown shader %d", shader); return; } pShader->deleted = GL_TRUE; if (0==pShader->refCount) { CRContext *g = GetCurrentContext(); crHashtableDelete(g->glsl.shaders, shader, crStateFreeGLSLShader); } }
static void crStateFakeDecRefCountCB(unsigned long key, void *data1, void *data2) { CRGLSLShader *pShader = (CRGLSLShader *) data1; CRContext *ctx = (CRContext*) data2; CRGLSLShader *pRealShader; (void) key; pRealShader = crStateGetShaderObj(pShader->id); if (pRealShader) { crStateShaderDecRefCount(pRealShader); } else { crWarning("crStateFakeDecRefCountCB: NULL pRealShader"); } }
DECLEXPORT(void) STATE_APIENTRY crStateDeleteShader(GLuint shader) { CRGLSLShader *pShader = crStateGetShaderObj(shader); if (!pShader) { crWarning("Unknown shader %d", shader); return; } pShader->deleted = GL_TRUE; if (0==pShader->refCount) { CRContext *g = GetCurrentContext(); crHashtableDelete(g->glsl.shaders, shader, crStateFreeGLSLShader); /* since we use programs table for key allocation key allocation, we need to * free the key in the programs table. * See comment in crStateCreateShader */ crHashtableDelete(g->glsl.programs, shader, crStateDbgCheckNoProgramOfId); } }