Exemple #1
0
static int getProgramParameters(ShaderProgram *shader)
{
	ORIG_GL(glGetProgramiv)(shader->programHandle,
	                        GL_GEOMETRY_VERTICES_OUT_EXT,
	                        &shader->geoVerticesOut);
	ORIG_GL(glGetProgramiv)(shader->programHandle,
	                        GL_GEOMETRY_INPUT_TYPE_EXT,
	                        &shader->geoInputType);
	ORIG_GL(glGetProgramiv)(shader->programHandle,
	                        GL_GEOMETRY_OUTPUT_TYPE_EXT,
	                        &shader->geoOutputType);
	return glError();
}
Exemple #2
0
/* TODO: error checking */
static void printProgramInfoLog(GLhandleARB shader)
{
	int length;
	GLcharARB *log;

	ORIG_GL(glGetProgramiv)(shader, GL_INFO_LOG_LENGTH, &length);
	if (length > 1) {
		if (!(log = (GLcharARB*)malloc(length*sizeof(GLcharARB)))) {
			dbgPrint(DBGLVL_ERROR, "Allocation of mem for GLSL info log failed\n");
			exit(1);
		}
		ORIG_GL(glGetProgramInfoLog)(shader, length, NULL, log);
		dbgPrint(DBGLVL_INFO, "PROGRAM INFOLOG:\n%s\n", log);
		free(log);
	}
}
Exemple #3
0
int setSavedGLState(int target)
{
	int error;

DMARK	/* restore original gl state */
	ORIG_GL(glPopAttrib)();
	error = glError();
	if (error) {
		return error;
	}

	/* save original gl state */
	error = saveGLState();
	if (error) {
		return error;
	}

	/* FIXME CHECK AGAIN!!!! 	*/
#if 0
	/* disable everything that could interfere when writting the debug result to
	 * the debug buffer and setup draw and read buffer.
	 */
	error = setDbgRenderState(target);
	if (error) {
		return error;
	}
#endif
	return DBG_NO_ERROR;
}
Exemple #4
0
/* TODO: error checking */
static void freeDbgShader(void)
{
	if (g.dbgShaderHandle != -1) {
		ORIG_GL(glDeleteProgram)(g.dbgShaderHandle);
		glError();
		g.dbgShaderHandle = -1;
	}
}
Exemple #5
0
void APIENTRY glEnd(void)
{
#if 0
	/* HAZARD maximally dangerous. this relies upon the fact that the debuglib is already loaded
	   (sure, this here lib is loaded by it) to grab the correct address of the opengl32.dll
	   glEnd. We do this because the contents of OrigglEnd are, as a matter of fact, f****d
	   in the head and we end up in a totally wrong memory segment. This might have to do
	   something with improper relocation of all the library goo, but we do not know. yet. */
	HANDLE lib = LoadLibraryA("debuglib.dll");
	dbgPrint(DBGLVL_DEBUG, "using special glEnd: 0x%x\n", OrigglEnd);
	dbgPrint(DBGLVL_DEBUG, "origglend = 0x%x\n", *((GetProcAddress(lib, "OrigglEnd"))));
	(*((GetProcAddress(lib, "OrigglEnd"))))();
	(*((GetProcAddress(lib, "OrigglGetError"))))();
	FreeLibrary(lib);
#endif
	ORIG_GL(glEnd)();
	setErrorCode(ORIG_GL(glGetError)());
}
Exemple #6
0
static int getUniform(GLuint progHandle, ActiveUniform *u)
{
	int error;

	allocateUniformStorage(u);
	if (!u->value) {
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}
	if (isIntType(u->type)) {
		ORIG_GL(glGetUniformiv)(progHandle, u->location, u->value);
	} else if (isUIntType(u->type)) {
		ORIG_GL(glGetUniformuivEXT)(progHandle, u->location, u->value);
	} else {
		ORIG_GL(glGetUniformfv)(progHandle, u->location, u->value);
	}
	error = glError();
	if (error) {
		free(u->value);
		return error;
	}
	return DBG_NO_ERROR;
}
Exemple #7
0
/*
 *	SHM IN:
 *		fname    : *
 *		operation: DBG_GET_SHADER_CODE
 *	SHM out:
 *		fname    : *
 *		result   : DBG_ERROR_CODE
 */
void restoreActiveShader(void)
{
	int error;

	ORIG_GL(glUseProgram)(g.storedShader.programHandle);
	error = glError();
	if (error) {
		setErrorCode(error);
		return;
	}
	freeShaderProgram(&g.storedShader);
	setErrorCode(DBG_NO_ERROR);
}
Exemple #8
0
int saveGLState(void)
{
	int error;

DMARK	/* save original gl state */
	ORIG_GL(glPushAttrib)(GL_ALL_ATTRIB_BITS);
	error = glError();
	if (error) {
		return error;
	}

	/*glPushClientAttrib*/

	return DBG_NO_ERROR;
}
Exemple #9
0
static int getCurrentShader(ShaderProgram *shader)
{
	int haveGeometryShader = checkGLExtensionSupported("GL_EXT_geometry_shader4");
	int error;

	/* get handle of currently active GLSL shader program */
	ORIG_GL(glGetIntegerv)(GL_CURRENT_PROGRAM, (GLint*)&shader->programHandle);
	error = glError();
	if (error) {
		return error;
	}

	if (shader->programHandle == 0) {
		return 0;
	}

	/* get attached shader objects */
	error = getShaderObjects(shader);
	if (error) {
		return error;
	}

	/* get active uniforms and attributes */
	error = getActiveUniforms(shader);
	if (error) {
		return error;
	}
	error = getActiveAttributes(shader);
	if (error) {
		return error;
	}

	/* if geometry shader is supported, get program parameters */
	if (haveGeometryShader) {
		error = getProgramParameters(shader);
		if (error) {
			return error;
		}
	} else {
		shader->geoVerticesOut = 0;
		shader->geoOutputType = GL_NONE;
		shader->geoInputType = GL_NONE;
	}

	return DBG_NO_ERROR;
}
Exemple #10
0
/* TODO: error checking */
static int attachShaderObject(GLint programHandle, GLenum type, const char *src)
{
	GLint shader, status;
	int error;

	dbgPrint(DBGLVL_COMPILERINFO,
	         "ATTACH SHADER: %s\n-----------------\n%s\n--------------\n",
	         lookupEnum(type), src);

	shader = ORIG_GL(glCreateShader)(type);
	error = glError();
	if (error) {
		return error;
	}
	ORIG_GL(glShaderSource)(shader, 1, (void*)&src, NULL);
	error = glError();
	if (error) {
		return error;
	}
	ORIG_GL(glCompileShader)(shader);
	 error = glError();
	if (error) {
		return error;
	}
	ORIG_GL(glGetShaderiv)(shader, GL_COMPILE_STATUS, &status);
	error = glError();
	if (error) {
		return error;
	}
	printShaderInfoLog(shader);
	error = glError();
	if (error) {
		return error;
	}
	if (!status) {
		dbgPrint(DBGLVL_ERROR, "DBG SHADER COMPILATION for %s failed!\n", lookupEnum(type));
		return DBG_ERROR_DBG_SHADER_COMPILE_FAILED;
	}
	ORIG_GL(glAttachShader)(programHandle, shader);
	error = glError();
	if (error) {
		return error;
	}
	ORIG_GL(glDeleteShader)(shader);
	error = glError();
	if (error) {
		return error;
	}
	return DBG_NO_ERROR;
}
Exemple #11
0
static int getActiveAttributes(ShaderProgram *shader)
{
	GLint maxLength;
	char *name = NULL;
	int i, error;

	ORIG_GL(glGetProgramiv)(shader->programHandle, GL_ACTIVE_ATTRIBUTES,
	                        &shader->numAttributes);
	ORIG_GL(glGetProgramiv)(shader->programHandle,
	                        GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength);
	error = glError();
	if (error) {
		shader->numAttributes = 0;
		return error;
	}

	if (!(name = (char*)malloc(maxLength*sizeof(char)))) {
		dbgPrint(DBGLVL_ERROR, "Allocation failed: attrib name\n");
		shader->numAttributes = 0;
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}

	dbgPrint(DBGLVL_INFO, "ACTIVE ATTRIBS: %i\n", shader->numAttributes);
	if (!(shader->attributes = (ActiveAttribute*)malloc(shader->numAttributes*
	                                              sizeof(ActiveAttribute)))) {
		dbgPrint(DBGLVL_ERROR, "Allocation failed: attributes\n");
		shader->numAttributes = 0;
		free(name);
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}

	for (i = 0; i < shader->numAttributes; i++) {
		ActiveAttribute *a = &shader->attributes[i];
		ORIG_GL(glGetActiveAttrib)(shader->programHandle, i, maxLength, NULL,
		                           &a->size, &a->type, name);
		error = glError();
		if (error) {
			shader->numAttributes = i;
			free(name);
			return error;
		}

		if (!(a->name = strdup(name))) {
			dbgPrint(DBGLVL_ERROR, "Allocation failed: attribute name\n");
			shader->numAttributes = i;
			free(name);
			return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
		}
		if (!strncmp(a->name, "gl_", 3)) {
			a->builtin = 1;
			a->location = -1;
		} else {
			a->builtin = 0;
			a->location = ORIG_GL(glGetAttribLocation)(shader->programHandle,
													   a->name);
			error = glError();
			if (error) {
				shader->numAttributes = i + 1;
				free(name);
				return error;
			}
		}
		dbgPrint(DBGLVL_INFO, "SAVED ATTRIB: %s size=%i type=%s, location=%i\n",
		         a->name, a->size, lookupEnum(a->type), a->location);
	}
	free(name);
	return DBG_NO_ERROR;
}
Exemple #12
0
static int getActiveUniforms(ShaderProgram *shader)
{
	GLint maxLength;
	char *name = NULL;
	int i, error, numBaseUniforms, n;
	ActiveUniform *baseUniforms = NULL;

	ORIG_GL(glGetProgramiv)(shader->programHandle, GL_ACTIVE_UNIFORMS,
	                        &numBaseUniforms);
	ORIG_GL(glGetProgramiv)(shader->programHandle, GL_ACTIVE_UNIFORM_MAX_LENGTH,
	                        &maxLength);
	error = glError();
	if (error) {
		shader->numUniforms = 0;
		return error;
	}

	if (!(name = (char*)malloc(maxLength*sizeof(char)))) {
		dbgPrint(DBGLVL_ERROR, "Allocation failed: uniform name\n");
		shader->numUniforms = 0;
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}

	dbgPrint(DBGLVL_INFO, "ACTIVE UNIFORMS: %i\n", numBaseUniforms);

	if (!(baseUniforms = (ActiveUniform*)malloc(numBaseUniforms*sizeof(ActiveUniform)))) {
		dbgPrint(DBGLVL_ERROR, "Allocation failed: base uniforms\n");
		shader->numUniforms = 0;
		free(name);
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}

	shader->numUniforms = 0;

	for (i = 0; i < numBaseUniforms; i++) {
		ActiveUniform *u = &baseUniforms[i];
		ORIG_GL(glGetActiveUniform)(shader->programHandle, i, maxLength, NULL,
		                            &u->size, &u->type, name);
		error = glError();
		if (error) {
			free(name);
			free(baseUniforms);
			shader->numUniforms = 0;
			return error;
		}
		dbgPrint(DBGLVL_INFO, "FOUND UNIFORM: %s size=%i type=%s\n",
				name, u->size, lookupEnum(u->type));
		if (!strncmp(name, "gl_", 3)) {
			u->builtin = 1;
		} else {
			if (!(u->name = strdup(name))) {
				dbgPrint(DBGLVL_ERROR, "Allocation failed: uniform name\n");
				free(name);
				free(baseUniforms);
				shader->numUniforms = 0;
				return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
			}
			u->builtin = 0;
			shader->numUniforms += u->size;
		}
	}

	free(name);

	if (!(shader->uniforms = (ActiveUniform*)malloc(shader->numUniforms*sizeof(ActiveUniform)))) {
		dbgPrint(DBGLVL_ERROR, "Allocation failed: uniforms\n");
		shader->numUniforms = 0;
		free(baseUniforms);
		return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
	}

	n = 0;
	for (i = 0; i < numBaseUniforms; i++) {
		ActiveUniform *bu = &baseUniforms[i];
		if (!bu->builtin) {

			if (bu->size == 1) {
				ActiveUniform *u = &shader->uniforms[n];
				u->type = bu->type;
				u->size = 1;
				u->builtin = 0;
				u->value = NULL;
				if (!(u->name = strdup(bu->name))) {
					dbgPrint(DBGLVL_ERROR, "Allocation failed: uniform name\n");
					free(baseUniforms);
					shader->numUniforms = n;
					return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
				}
				u->location = ORIG_GL(glGetUniformLocation)(shader->programHandle,
							u->name);
				error = glError();
				if (error) {
					free(baseUniforms);
					free(u->name);
					shader->numUniforms = n;
					return error;
				}
				dbgPrint(DBGLVL_INFO, "SAVE UNIFORM: %s size=%i type=%s location=%i\n",
				         u->name, u->size, lookupEnum(u->type), u->location);
				error = getUniform(shader->programHandle, u);
				if (error) {
					free(u->name);
					free(baseUniforms);
					shader->numUniforms = n;
					return error;
				}
				n++;
			} else {
				int j;
				for (j = 0; j < bu->size; j++) {
					ActiveUniform *u = &shader->uniforms[n];
					u->type = bu->type;
					u->size = 1;
					u->builtin = 0;
					u->value = NULL;
					if (asprintf(&u->name, "%s[%i]", bu->name, j) < 0) {
						dbgPrint(DBGLVL_ERROR, "Allocation failed: uniform name\n");
						free(baseUniforms);
						shader->numUniforms = n;
						return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
					}
					u->location = ORIG_GL(glGetUniformLocation)(shader->programHandle,
							u->name);
					error = glError();
					if (error) {
						free(baseUniforms);
						free(u->name);
						shader->numUniforms = n;
						return error;
					}
					dbgPrint(DBGLVL_INFO, "SAVE UNIFORM: %s size=%i type=%s location=%i\n",
							u->name, u->size, lookupEnum(u->type), u->location);
					error = getUniform(shader->programHandle, u);
					if (error) {
						free(u->name);
						free(baseUniforms);
						shader->numUniforms = n;
						return error;
					}
					n++;
				}
			}
		}
	}
	free(baseUniforms);
	return DBG_NO_ERROR;
}
Exemple #13
0
static int setUniform(GLint progHandle, ActiveUniform *u)
{
	int error;
	GLint location;

	dbgPrint(DBGLVL_INFO, "setUniform(%i, %s)\n",  progHandle, u->name);

	/* handle the special case of a uninitialized sampler uniform */
	if (isSamplerType(u->type)) {
		GLint numTexUnits, maxTexCoords, maxCombinedTextureImageUnits;
		ORIG_GL(glGetIntegerv)(GL_MAX_TEXTURE_COORDS, &maxTexCoords);
		ORIG_GL(glGetIntegerv)(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
				&maxCombinedTextureImageUnits);
		numTexUnits = maxTexCoords > maxCombinedTextureImageUnits ?
			maxTexCoords : maxCombinedTextureImageUnits;
		if (((GLint*)u->value)[0] < 0 || ((GLint*)u->value)[0] >= numTexUnits) {
			dbgPrint(DBGLVL_INFO,
					"Sampler \"%s\" seems to be uninitialized (%i/%i/%i); ignoring\n",
					u->name, ((GLint*)u->value)[0], maxTexCoords,
					maxCombinedTextureImageUnits);
			return DBG_NO_ERROR;
		}
	}

	location = ORIG_GL(glGetUniformLocation)(progHandle, u->name);
	error = glError();
	if (error) {
		return error;
	}
	if (location < 0) {
		dbgPrint(DBGLVL_INFO, "HMM, A UNIFORM NAMED \"%s\" IS NOT KNOWN TO "
		                      "THE PROGRAM\n", u->name);
		return DBG_NO_ERROR;
	}
	if (isMatrixType(u->type)) {
		switch (u->type) {
			case GL_FLOAT_MAT2:
				ORIG_GL(glUniformMatrix2fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT2x3:
				ORIG_GL(glUniformMatrix2x3fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT2x4:
				ORIG_GL(glUniformMatrix2x4fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT3:
				ORIG_GL(glUniformMatrix3fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT3x2:
				ORIG_GL(glUniformMatrix3x2fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT3x4:
				ORIG_GL(glUniformMatrix3x4fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT4:
				ORIG_GL(glUniformMatrix4fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT4x2:
				ORIG_GL(glUniformMatrix4x2fv)(location, u->size, 0, u->value);
				break;
			case GL_FLOAT_MAT4x3:
				ORIG_GL(glUniformMatrix4x3fv)(location, u->size, 0, u->value);
				break;
		}
	} else if (isIntType(u->type)) {
		switch (uniformNumElements(u)) {
			case 1:
				ORIG_GL(glUniform1iv)(location, u->size, u->value);
				break;
			case 2:
				ORIG_GL(glUniform2iv)(location, u->size, u->value);
				break;
			case 3:
				ORIG_GL(glUniform3iv)(location, u->size, u->value);
				break;
			case 4:
				ORIG_GL(glUniform4iv)(location, u->size, u->value);
				break;
		}
	} else if (isUIntType(u->type)) {
		switch (uniformNumElements(u)) {
			case 1:
				ORIG_GL(glUniform1uivEXT)(location, u->size, u->value);
				break;
			case 2:
				ORIG_GL(glUniform2uivEXT)(location, u->size, u->value);
				break;
			case 3:
				ORIG_GL(glUniform3uivEXT)(location, u->size, u->value);
				break;
			case 4:
				ORIG_GL(glUniform4uivEXT)(location, u->size, u->value);
				break;
		}
	} else { /* float type */
		switch (uniformNumElements(u)) {
			case 1:
				ORIG_GL(glUniform1fv)(location, u->size, u->value);
				break;
			case 2:
				ORIG_GL(glUniform2fv)(location, u->size, u->value);
				break;
			case 3:
				ORIG_GL(glUniform3fv)(location, u->size, u->value);
				break;
			case 4:
				ORIG_GL(glUniform4fv)(location, u->size, u->value);
				break;
		}
	}

	error = glError();
	if (error) {
		return error;
	} else {
		return DBG_NO_ERROR;
	}
}
Exemple #14
0
int restoreGLState(void)
{
DMARK	/* restore original gl state */
	ORIG_GL(glPopAttrib)();
	return glError();
}
Exemple #15
0
int loadDbgShader(const char* vshader, const char *gshader, const char *fshader,
                  int target, int forcePointPrimitiveMode)
{
	int haveGeometryShader = checkGLExtensionSupported("GL_EXT_geometry_shader4");
	GLint status;
	int i, error;

	freeDbgShader();

	g.dbgShaderHandle = ORIG_GL(glCreateProgram)();
	error = glError();
	if (error) {
		return error;
	}

	dbgPrint(DBGLVL_COMPILERINFO, "SET DBG SHADER: %p, %p, %p %i\n",
	         vshader, gshader, fshader, target);

	if (vshader) {
		error = attachShaderObject(g.dbgShaderHandle, GL_VERTEX_SHADER, vshader);
		if (error) {
			freeDbgShader();
			return error;
		}
	}
	if (gshader && target != DBG_TARGET_VERTEX_SHADER) {
		error = attachShaderObject(g.dbgShaderHandle, GL_GEOMETRY_SHADER_EXT,
		                           gshader);
		if (error) {
			freeDbgShader();
			return error;
		}
	}
	if (fshader) {
		error = attachShaderObject(g.dbgShaderHandle, GL_FRAGMENT_SHADER,
		                           fshader);
		if (error) {
			freeDbgShader();
			return error;
		}
	}

	/* copy execution environment of previous active shader */
	/* pre-link part */
	if (g.storedShader.programHandle == 0) {
		dbgPrint(DBGLVL_ERROR, "STORE CURRENTLY ACTIVE SHADER BEFORE SETTING DBG SHADER!\n");
		freeDbgShader();
		return DBG_ERROR_NO_STORED_SHADER;
	}

	for (i = 0; i < g.storedShader.numAttributes; i++) {
		ActiveAttribute *a = &g.storedShader.attributes[i];
		if (!a->builtin) {
			/* glGetAttribLocation is not allowed before link

			int location;
			if (haveOpenGL_2_0_GLSL) {
				location = ORIG_GL(glGetAttribLocation)(g.dbgShaderHandle, a->name);
				if (location != -1) {
					ORIG_GL(glBindAttribLocation)(g.dbgShaderHandle, a->location,
							a->name);
				}
			} else {
				location = ORIG_GL(glGetAttribLocationARB)(g.dbgShaderHandle, a->name);
				if (location != -1) {
					ORIG_GL(glBindAttribLocationARB)(g.dbgShaderHandle, a->location,
							a->name);
				}
			}
			*/
			ORIG_GL(glBindAttribLocation)(g.dbgShaderHandle, a->location,
				a->name);

			error = glError();
			if (error) {
				freeDbgShader();
				return error;
			}
			dbgPrint(DBGLVL_INFO, "BINDATTRIBLOCATION: %s -> %i\n", a->name, a->location);
		}
	}


	/* if geometry shader is supported, set program parameters */
	if (haveGeometryShader && gshader) {
		DMARK
		dbgPrint(DBGLVL_INFO, "SET PROGRAM PARAMETERS: "
				"GL_GEOMETRY_VERTICES_OUT_EXT=%i "
				"GL_GEOMETRY_INPUT_TYPE_EXT=%s "
				"GL_GEOMETRY_OUTPUT_TYPE_EXT=%s\n",
				g.storedShader.geoVerticesOut,
				lookupEnum(g.storedShader.geoInputType),
				lookupEnum(g.storedShader.geoOutputType));
		ORIG_GL(glProgramParameteriEXT)(g.dbgShaderHandle,
										GL_GEOMETRY_VERTICES_OUT_EXT,
										g.storedShader.geoVerticesOut);
		ORIG_GL(glProgramParameteriEXT)(g.dbgShaderHandle,
										GL_GEOMETRY_INPUT_TYPE_EXT,
										g.storedShader.geoInputType);
		if (forcePointPrimitiveMode) {
			ORIG_GL(glProgramParameteriEXT)(g.dbgShaderHandle,
											GL_GEOMETRY_OUTPUT_TYPE_EXT,
											GL_POINTS);
		} else {
			ORIG_GL(glProgramParameteriEXT)(g.dbgShaderHandle,
											GL_GEOMETRY_OUTPUT_TYPE_EXT,
											g.storedShader.geoOutputType);
		}
		error = glError();
		if (error) {
			freeDbgShader();
			return error;
		}
	}

	/* TODO: other state (point size, geometry shader, etc.) !!! */

	/* if debug target is vertex or geometry shader, force varyings active that
	 * are used in transform feedback
	*/
	if (target == DBG_TARGET_GEOMETRY_SHADER ||
	    target == DBG_TARGET_VERTEX_SHADER) {
		switch (getTFBVersion()) {
			case TFBVersion_NV:
				ORIG_GL(glActiveVaryingNV)(g.dbgShaderHandle, "dbgResult"/*TODO*/);
				error = glError();
				if (error) {
					freeDbgShader();
					return error;
				}
				break;
			case TFBVersion_EXT:
				{
					const char* dbgTFBVaryings[] = {"dbgResult"};
					ORIG_GL(glTransformFeedbackVaryingsEXT)(g.dbgShaderHandle, 1, dbgTFBVaryings, GL_SEPARATE_ATTRIBS_EXT);
					error = glError();
					if (error) {
						freeDbgShader();
						return error;
					}
				}
				break;
			default:
				dbgPrint(DBGLVL_ERROR, "Unknown TFB version!\n");
				return DBG_ERROR_INVALID_OPERATION;
		}
	}

	/* link debug shader */
	ORIG_GL(glLinkProgram)(g.dbgShaderHandle);
	ORIG_GL(glGetProgramiv)(g.dbgShaderHandle, GL_LINK_STATUS, &status);
	error = glError();
	if (error) {
		freeDbgShader();
		return error;
	}

	printProgramInfoLog(g.dbgShaderHandle);
	if (!status) {
		dbgPrint(DBGLVL_ERROR, "LINKING DBG SHADER FAILED!\n");
		freeDbgShader();
		return DBG_ERROR_DBG_SHADER_LINK_FAILED;
	}

	/* if debug target is vertex or geometry shader, specify varyings that
	 * are used in transform feedback
	*/
	if (target == DBG_TARGET_GEOMETRY_SHADER ||
	    target == DBG_TARGET_VERTEX_SHADER) {
		GLint location;

		switch (getTFBVersion()) {
			case TFBVersion_NV:
				{
					location = ORIG_GL(glGetVaryingLocationNV)(g.dbgShaderHandle, "dbgResult"/*TODO*/);
					if (location < 0) {
						dbgPrint(DBGLVL_ERROR, "dbgResult NOT ACTIVE VARYING\n");
						freeDbgShader();
						return DBG_ERROR_VARYING_INACTIVE;
					}
					ORIG_GL(glTransformFeedbackVaryingsNV)(g.dbgShaderHandle, 1, &location, GL_SEPARATE_ATTRIBS_NV);
					error = glError();
					if (error) {
						freeDbgShader();
						return error;
					}
				}
				break;
			case TFBVersion_EXT:
				/* nothing to be done, the EXT extension requires to specify the
				 * transform feedback varying outputs *befor* linking the shader
				 */
				break;
			default:
				return DBG_ERROR_INVALID_OPERATION;
		}
	}

	/* activate debug shader */
	ORIG_GL(glUseProgram)(g.dbgShaderHandle);
	error = glError();
	if (error) {
		freeDbgShader();
		return error;
	}

	/* copy execution environment of previous active shader */
	/* post-link part */
	for (i = 0; i < g.storedShader.numUniforms; i++) {
		ActiveUniform *u = &g.storedShader.uniforms[i];
		if (!u->builtin) {
			error = setUniform(g.dbgShaderHandle, u);
			if (error) {
				freeDbgShader();
				return error;
			}
		}
	}

	/* TODO: other state (GL_EXT_bindable_uniform etc.) !!! */

	return DBG_NO_ERROR;
}
Exemple #16
0
static int getShaderObjects(ShaderProgram *shader)
{
	GLuint *objects;
	int i, error;

	/* determine number of attached shader objects */
    ORIG_GL(glGetProgramiv)(shader->programHandle, GL_ATTACHED_SHADERS,
	                        &shader->numObjects);
	error = glError();
	if (error) {
		return error;
	}

    if (!(objects = (GLuint*) malloc(shader->numObjects * sizeof(GLuint)))) {
        dbgPrint(DBGLVL_ERROR, "not enough memory for temp. object handles\n");
        return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
    }
    if (!(shader->objects = (ShaderObject*) malloc(shader->numObjects *
	                                              sizeof(ShaderObject)))) {
        dbgPrint(DBGLVL_ERROR, "not enough memory for objects\n");
		free(objects);
        return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
    }

	/* get attached shader objects */
	ORIG_GL(glGetAttachedShaders)(shader->programHandle, shader->numObjects, NULL,
	        objects);
	error = glError();
	if (error) {
		free(objects);
		return error;
	}

	/* for each shader object: get source and type */
    for (i = 0; i < shader->numObjects; i++) {

		shader->objects[i].handle = objects[i];

	 	ORIG_GL(glGetShaderiv)(shader->objects[i].handle, GL_SHADER_SOURCE_LENGTH,
		        &shader->objects[i].srcLength);
		ORIG_GL(glGetShaderiv)(shader->objects[i].handle, GL_SHADER_TYPE,
				&shader->objects[i].type);
		error = glError();
		if (error) {
			free(objects);
			return error;
		}

		if (!(shader->objects[i].src =
					(char*)malloc((shader->objects[i].srcLength + 1)*sizeof(char)))) {
			dbgPrint(DBGLVL_ERROR, "not enough memory for src string\n");
			free(objects);
			return DBG_ERROR_MEMORY_ALLOCATION_FAILED;
		}

	 	ORIG_GL(glGetShaderSource)(shader->objects[i].handle,
		                           shader->objects[i].srcLength,
		                           NULL, shader->objects[i].src);
		error = glError();
		if (error) {
			free(objects);
			return error;
		}
    }
	free(objects);
	return DBG_NO_ERROR;
}
Exemple #17
0
static int getShaderResources(ShaderProgram *shader, struct TBuiltInResource *resources)
{
	ORIG_GL(glGetIntegerv)(GL_MAX_LIGHTS, &resources->maxLights);
	ORIG_GL(glGetIntegerv)(GL_MAX_CLIP_PLANES, &resources->maxClipPlanes);
	ORIG_GL(glGetIntegerv)(GL_MAX_TEXTURE_UNITS, &resources->maxTextureUnits);
	ORIG_GL(glGetIntegerv)(GL_MAX_TEXTURE_COORDS, &resources->maxTextureCoords);
	ORIG_GL(glGetIntegerv)(GL_MAX_VERTEX_ATTRIBS, &resources->maxVertexAttribs);
	ORIG_GL(glGetIntegerv)(GL_MAX_VERTEX_UNIFORM_COMPONENTS,
	                       &resources->maxVertexUniformComponents);
	ORIG_GL(glGetIntegerv)(GL_MAX_VARYING_FLOATS, &resources->maxVaryingFloats);
	ORIG_GL(glGetIntegerv)(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
	                       &resources->maxVertexTextureImageUnits);
	ORIG_GL(glGetIntegerv)(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
	                       &resources->maxCombinedTextureImageUnits);
	ORIG_GL(glGetIntegerv)(GL_MAX_TEXTURE_IMAGE_UNITS,
	                       &resources->maxTextureImageUnits);
	ORIG_GL(glGetIntegerv)(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS,
	                       &resources->maxFragmentUniformComponents);
	ORIG_GL(glGetIntegerv)(GL_MAX_DRAW_BUFFERS, &resources->maxDrawBuffers);

	resources->framebufferObjectsSupported =
		checkGLExtensionSupported("GL_EXT_framebuffer_object");

	resources->geoShaderSupported =
	    checkGLExtensionSupported("GL_EXT_geometry_shader4");

	resources->transformFeedbackSupported = getTFBVersion() != TFBVersion_None;

	resources->geoVerticesOut = shader->geoVerticesOut;
	resources->geoInputType = shader->geoInputType;
	resources->geoOutputType = shader->geoOutputType;

	switch (shader->geoInputType) {
		case GL_POINTS:
			resources->geoVerticesIn = 1;
			break;
		case GL_LINES:
			resources->geoVerticesIn = 2;
			break;
		case GL_LINES_ADJACENCY_EXT:
			resources->geoVerticesIn = 4;
			break;
		case GL_TRIANGLES:
			resources->geoVerticesIn = 3;
			break;
		case GL_TRIANGLES_ADJACENCY_EXT:
			resources->geoVerticesIn = 6;
			break;
		default:
			return DBG_ERROR_INVALID_VALUE;
	}

	return glError();
}