예제 #1
0
static void
create_frag_shader(void)
{
   /* This shader samples the currently bound depth texture, then compares
    * that value to the current fragment Z value to produce a shade of red
    * indicating error/difference.
    *
    * E.g:  gl_FragColor = scale * abs(texture.Z - fragment.Z);
    *
    * Note that we have to be pretty careful with converting gl_FragCoord
    * into a 2D texture coordinate.  There's a -0.5 bias and scale factor.
    */
   static const char *text_2d =
      "uniform sampler2D zTex; \n"
      "uniform float sizeScale; \n"
      "uniform float errorScale; \n"
      "void main() \n"
      "{ \n"
      "   vec2 coord = (gl_FragCoord.xy - vec2(0.5)) / sizeScale; \n"
      "   vec4 z = texture2D(zTex, coord); \n"
      "   float diff = errorScale * abs(z.r - gl_FragCoord.z); \n"
      "   //gl_FragColor = vec4(gl_FragCoord.z, 0, 0, 0); \n"
      "   //gl_FragColor = z; \n"
      "   gl_FragColor = vec4(diff, 0, 0, 0); \n"
      "   gl_FragDepth = gl_FragCoord.z; \n"
      "} \n";
   static const char *text_rect =
      "#extension GL_ARB_texture_rectangle: require \n"
      "uniform sampler2DRect zTex; \n"
      "uniform float sizeScale; \n"
      "uniform float errorScale; \n"
      "void main() \n"
      "{ \n"
      "   vec2 coord = gl_FragCoord.xy; \n"
      "   vec4 z = texture2DRect(zTex, coord); \n"
      "   float diff = errorScale * abs(z.r - gl_FragCoord.z); \n"
      "   //gl_FragColor = vec4(gl_FragCoord.z, 0, 0, 0); \n"
      "   //gl_FragColor = z; \n"
      "   gl_FragColor = vec4(diff, 0, 0, 0); \n"
      "   gl_FragDepth = gl_FragCoord.z; \n"
      "} \n";
   GLuint fs;
   GLint zTex, errorScale, sizeScale;

   if (TexTarget == GL_TEXTURE_2D)
      fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, text_2d);
   else
      fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, text_rect);

   assert(fs);

   ShaderProg = piglit_link_simple_program(0, fs);
   assert(ShaderProg);

   piglit_UseProgram(ShaderProg);

   zTex = piglit_GetUniformLocation(ShaderProg, "zTex");
   piglit_Uniform1i(zTex, 0);  /* unit 0 */

   errorScale = piglit_GetUniformLocation(ShaderProg, "errorScale");
   piglit_Uniform1f(errorScale, ErrorScale);

   sizeScale = piglit_GetUniformLocation(ShaderProg, "sizeScale");
   piglit_Uniform1f(sizeScale, (float) (SIZE - 1));

   piglit_UseProgram(0);
}
예제 #2
0
/** Test drawing with GLSL shaders */
static GLboolean
test_glsl_arrays(void)
{
   static const char *vertShaderText =
      "attribute vec4 color, pos; \n"
      "varying vec4 colorVar; \n"
      "void main() \n"
      "{ \n"
      "   colorVar = color; \n"
      "   gl_Position = gl_ModelViewProjectionMatrix * pos; \n"
      "} \n";

   static const char *fragShaderText =
      "varying vec4 colorVar; \n"
      "void main() \n"
      "{ \n"
      "   gl_FragColor = colorVar; \n"
      "} \n";

   static const GLfloat expected[4] = {0.5, 0.0, 0.5, 1.0};
   GLuint buf;
   GLboolean p, pass = GL_TRUE;
   GLint posAttrib, colorAttrib;
   GLuint vertShader, fragShader, program;

   buf = setup_vbo();
   glBindBufferARB(GL_ARRAY_BUFFER_ARB, buf);

   vertShader = piglit_compile_shader_text(GL_VERTEX_SHADER, vertShaderText);
   fragShader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fragShaderText);
   program = piglit_link_simple_program(vertShader, fragShader);

   glUseProgram(program);

   /*
    * Draw with compiler-assigned attribute locations
    */
   {
      posAttrib = glGetAttribLocation(program, "pos");
      colorAttrib = glGetAttribLocation(program, "color");

      if (0)
         printf("%s: GLSL posAttrib = %d  colorAttrib = %d\n",
                TestName, posAttrib, colorAttrib);

      glVertexAttribPointerARB(posAttrib, 2, GL_FLOAT, GL_FALSE,
                               2 * sizeof(GLfloat), (void *) 0);
      glVertexAttribPointerARB(colorAttrib, 3, GL_FLOAT, GL_FALSE,
                               3 * sizeof(GLfloat),
                               (void *) (8 * sizeof(GLfloat)));
      glEnableVertexAttribArrayARB(posAttrib);
      glEnableVertexAttribArrayARB(colorAttrib);

      glClear(GL_COLOR_BUFFER_BIT);
      glDrawArrays(GL_QUADS, 0, 4);

      p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, expected);
      piglit_present_results();
      if (!p) {
         printf("%s: failed when drawing with ", TestName);
         printf("compiler-assigned attribute locations\n");
         pass = GL_FALSE;
      }

      glDisableVertexAttribArrayARB(posAttrib);
      glDisableVertexAttribArrayARB(colorAttrib);
   }

   /*
    * Draw with user-defined attribute bindings, not using 0.
    */
   {
      posAttrib = 5;
      colorAttrib = 7;

      glBindAttribLocation(program, posAttrib, "pos");
      glBindAttribLocation(program, colorAttrib, "color");

      glLinkProgram(program);

      glVertexAttribPointerARB(posAttrib, 2, GL_FLOAT, GL_FALSE,
                               2 * sizeof(GLfloat), (void *) 0);
      glVertexAttribPointerARB(colorAttrib, 3, GL_FLOAT, GL_FALSE,
                               3 * sizeof(GLfloat),
                               (void *) (8 * sizeof(GLfloat)));
      glEnableVertexAttribArrayARB(posAttrib);
      glEnableVertexAttribArrayARB(colorAttrib);

      glClear(GL_COLOR_BUFFER_BIT);
      glDrawArrays(GL_QUADS, 0, 4);

      p = piglit_probe_pixel_rgba(piglit_width/2, piglit_height/2, expected);
      piglit_present_results();
      if (!p) {
         printf("%s: failed when drawing with ", TestName);
         printf("user-assigned attribute locations\n");
         pass = GL_FALSE;
      }

      glDisableVertexAttribArrayARB(posAttrib);
      glDisableVertexAttribArrayARB(colorAttrib);
   }

   glDeleteShader(vertShader);
   glDeleteProgram(program);
   glDeleteBuffersARB(1, &buf);

   return pass;
}
예제 #3
0
static void
test_error_cases(bool *pass)
{
	GLenum props[] = {GL_NAME_LENGTH};
	GLenum props_invalid[] = {GL_NAME_LENGTH, GL_TRUE, GL_TYPE};
	GLenum props_error[] = {GL_NAME_LENGTH, GL_OFFSET, GL_TYPE};
	int values[10];
	GLuint shader;
	bool prg_tst;

	/* test using an unexisting program ID */
	glGetProgramResourceiv(1337, GL_UNIFORM, 0, 1, props, 10, NULL, values);
	prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "Invalid program (undefined ID)");

	/* test using a shader ID */
	shader = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_empty);
	glGetProgramResourceIndex(shader, GL_UNIFORM, "resource");
	prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "Invalid program (call on shader)");

	/* invalid index. This is unspecified but let's check it is consistent
	 * with GetProgramResourceName.
	 */
	glGetProgramResourceiv(prog_std, GL_UNIFORM, 1337, 0, props, 10, NULL,
			       values);
	prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "Invalid index");

	/* test propcount == 0 */
	glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 0, props, 10, NULL,
			       values);
	prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "<propcount> == 0");

	/* test propcount < 0 */
	glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, -1, props, 10, NULL,
			       values);
	prg_tst = piglit_check_gl_error(GL_INVALID_VALUE);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "<propcount> < 0");

	/* one invalid property */
	glGetProgramResourceiv(prog_std, GL_UNIFORM, 0, 3, props_invalid, 10,
			       NULL, values);
	prg_tst = piglit_check_gl_error(GL_INVALID_ENUM);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "prop == GL_TRUE");

	/* property not acceptable for one program interface */
	glGetProgramResourceiv(prog_std, GL_PROGRAM_INPUT, 0, 3, props_error,
			       10, NULL, values);
	prg_tst = piglit_check_gl_error(GL_INVALID_OPERATION);
	*pass = *pass && prg_tst;
	piglit_report_subtest_result(prg_tst ? PIGLIT_PASS : PIGLIT_FAIL,
				     "GL_OFFSET on GL_PROGRAM_INPUT");
}
예제 #4
0
static GLboolean
do_test(const struct test_desc *test)
{
	GLuint vs;
	GLuint progs[2];
	GLuint bufs[NUM_BUFFERS];
	float initial_xfb_buffer_contents[XFB_BUFFER_SIZE];
	GLboolean pass = GL_TRUE;
	int i;
	int num_varyings = test->mode == NO_VARYINGS ? 0 : test->num_buffers;
	GLint max_separate_attribs;

	glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
		      &max_separate_attribs);
	printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n",
	       max_separate_attribs);

	printf("Compile vertex shader\n");
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
	if (test->mode == NOT_A_PROGRAM) {
		printf("Create a program and then delete it\n");
		progs[0] = glCreateProgram();
		glDeleteProgram(progs[0]);
	} else {
		progs[0] = glCreateProgram();
		glAttachShader(progs[0], vs);
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	printf("Setup transform feedback for %i varyings in %s mode\n",
	       num_varyings,
	       test->buffer_mode == GL_INTERLEAVED_ATTRIBS
	       ? "interleaved" : "separate");
	glTransformFeedbackVaryings(progs[0], num_varyings,
				    varyings, test->buffer_mode);

	if (test->mode == NOT_A_PROGRAM) {
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	}

	printf("Link program\n");
	glLinkProgram(progs[0]);
	pass = piglit_link_check_status(progs[0]) && pass;

	if (test->mode == USEPROG_ACTIVE || test->mode == LINK_OTHER_ACTIVE) {
		printf("Prepare 2nd program\n");
		progs[1] = glCreateProgram();
		glAttachShader(progs[1], vs);
	}
	if (test->mode == USEPROG_ACTIVE) {
		printf("Link 2nd program\n");
		glLinkProgram(progs[1]);
		pass = piglit_link_check_status(progs[1]) && pass;
	}

	if (test->mode == SKIP_USE_PROGRAM) {
		printf("Don't use program\n");
	} else {
		printf("Use program\n");
		glUseProgram(progs[0]);
	}

	printf("Prepare %i buffers\n", test->num_buffers);
	glGenBuffers(test->num_buffers, bufs);
	memset(initial_xfb_buffer_contents, 0,
	       sizeof(initial_xfb_buffer_contents));
	for (i = 0; i < test->num_buffers; ++i) {
		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
			     sizeof(initial_xfb_buffer_contents),
			     initial_xfb_buffer_contents, GL_STREAM_READ);
	}

	switch (test->mode) {
	case BIND_MAX:
		do_bind(test, bufs[0], max_separate_attribs);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	case BIND_BAD_SIZE:
	case BIND_BAD_OFFSET:
		do_bind(test, bufs[0], 0);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	default:
		break;
	}

	for (i = 0; i < test->num_buffers; ++i) {
		if (test->mode == UNBOUND_BUFFER && i == test->param) {
			printf("Don't bind buffer %i\n", i);
		} else {
			do_bind(test, bufs[i], i);
		}
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	if (test->mode == END_INACTIVE) {
		printf("EndTransformFeedback\n");
		glEndTransformFeedback();
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		return pass;
	}

	printf("BeginTransformFeedback\n");
	glBeginTransformFeedback(GL_POINTS);
	switch (test->mode) {
	case UNBOUND_BUFFER:
	case NO_VARYINGS:
	case SKIP_USE_PROGRAM:
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	default:
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		break;
	}

	switch (test->mode) {
	case BEGIN_ACTIVE:
		printf("BeginTransformFeedback\n");
		glBeginTransformFeedback(GL_POINTS);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case USEPROG_ACTIVE:
		printf("Use new program\n");
		glUseProgram(progs[1]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case LINK_CURRENT_ACTIVE:
		printf("Link current program\n");
		glLinkProgram(progs[0]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case LINK_OTHER_ACTIVE:
		printf("Link 2nd program\n");
		glLinkProgram(progs[1]);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		break;
	case BIND_ACTIVE:
		do_bind(test, bufs[0], 0);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	default:
		break;
	}

	return pass;
}
예제 #5
0
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint fs;
	GLuint save_index = 0xaaaaaaaa;
	const GLchar *one_uniform = "a";
	const GLchar *uniform_names[] = {"a", "b", "c"};
	bool found_index[3] = {false, false, false};
	GLuint indices[3], index;
	int i;

	piglit_require_extension("GL_ARB_uniform_buffer_object");

	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_shader_text);
	if (!fs) {
		printf("Failed to compile FS:\n%s", frag_shader_text);
		piglit_report_result(PIGLIT_FAIL);
	}

	prog = piglit_link_simple_program(0, fs);
	if (!prog)
		piglit_report_result(PIGLIT_FAIL);

	/* From the GL_ARB_uniform_buffer_object spec:
	 *
	 *     "The error INVALID_VALUE is generated by GetUniformIndices,
	 *      GetActiveUniformsiv, GetActiveUniformName, GetUniformBlockIndex,
	 *      GetActiveUniformBlockiv, GetActiveUniformBlockName, and
	 *      UniformBlockBinding if <program> is not a value generated by GL.
	 *
	 *      ...
	 *
	 *      The error INVALID_VALUE is generated by GetUniformIndices and
	 *      GetActiveUniformsiv if <uniformCount> is less than zero.
	 *
	 *      ...
	 *
	 *     "If an error occurs, nothing is written to <uniformIndices>."
	 */
	index = save_index;
	glGetUniformIndices(prog, -1, &one_uniform, &index);
	if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
		pass = false;
	} else if (index != save_index) {
		printf("Bad program uniform index: 0x%08x\n", index);
		printf("  Expected 0x%08x\n", save_index);
		pass = false;
	}

	index = save_index;
	glGetUniformIndices(0xd0d0, 1, &one_uniform, &index);
	if (!piglit_check_gl_error(GL_INVALID_VALUE)) {
		pass = false;
	} else if (index != save_index) {
		printf("Bad program uniform index: 0x%08x\n", index);
		printf("  Expected 0x%08x\n", save_index);
		pass = false;
	}

	glGetUniformIndices(prog, 3, uniform_names, indices);
	if (!piglit_check_gl_error(0))
		piglit_report_result(PIGLIT_FAIL);

	for (i = 0; i < 3; i++) {
		printf("%s: index %d\n", uniform_names[i], indices[i]);
		if (indices[i] < 0 || indices[i] > 2 ||
		    found_index[indices[i]]) {
			printf("Expected consecutive numbers starting from 0\n");
			pass = false;
		}
		found_index[indices[i]] = true;
	}

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint pipe;
	GLuint vs_prog;
	GLuint active_prog;
	GLuint unlinked_prog;
	GLuint shader;
	unsigned glsl_version;
	char *source;

	piglit_require_extension("GL_ARB_separate_shader_objects");

	glsl_version = pick_a_glsl_version();

	glGenProgramPipelines(1, &pipe);
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	glBindProgramPipeline(pipe);

	(void)!asprintf(&source, vs_code_template, glsl_version);
	vs_prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1,
					 (const GLchar *const *) &source);
	pass = piglit_link_check_status(vs_prog) && pass;

	/* First, make a valid program active.
	 */
	glActiveShaderProgram(pipe, vs_prog);
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* Next, try to make an invalid program active and verify that the
	 * correct error is generated.  Also make sure the old program is
	 * still active.
	 *
	 * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of
	 * the OpenGL 4.4 spec says:
	 *
	 *     "An INVALID_VALUE error is generated if program is not zero and
	 *     is not the name of either a program or shader object."
	 */
	glActiveShaderProgram(pipe, ~vs_prog);
	pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;

	glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog);
	if (active_prog != vs_prog) {
		printf("glActiveShaderProgram with an invalid program name "
		       "changed the active program state.\n");
		pass = false;
	} else {
		glActiveShaderProgram(pipe, vs_prog);
	}

	/* Try the same thing with a valid shader object (that is not part of
	 * a linked program).  Verify that the correct error is generated, and
	 * make sure the old program is still active.
	 *
	 * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of
	 * the OpenGL 4.4 spec says:
	 *
	 *     "An INVALID_OPERATION error is generated if program is the name
	 *     of a shader object."
	 */
	shader = piglit_compile_shader_text(GL_VERTEX_SHADER, source);
	glActiveShaderProgram(pipe, shader);
	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog);
	if (active_prog != vs_prog) {
		printf("glActiveShaderProgram with a shader object "
		       "changed the active program state.\n");
		pass = false;
	} else {
		glActiveShaderProgram(pipe, vs_prog);
	}

	/* Finally, try the same thing with a valid program that is not
	 * linked.  Verify that the correct error is generated, and make sure
	 * the old program is still active.
	 *
	 * Section 7.4 (Program Pipeline Objects) under ActiveShaderProgram of
	 * the OpenGL 4.4 spec says:
	 *
	 *     "An INVALID_OPERATION error is generated if program is not zero
	 *     and has not been linked, or was last linked unsuccessfully."
	 */
	unlinked_prog = glCreateShaderProgramv(GL_VERTEX_SHADER, 1,
					       (const GLchar *const *) &invalid_code);

	glActiveShaderProgram(pipe, unlinked_prog);
	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	glGetProgramPipelineiv(pipe, GL_ACTIVE_PROGRAM, (GLint *) &active_prog);
	if (active_prog != vs_prog) {
		printf("glActiveShaderProgram with an unlinked program "
		       "changed the active program state.\n");
		pass = false;
	} else {
		glActiveShaderProgram(pipe, vs_prog);
	}


	free(source);
	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
예제 #7
0
파일: textureSize.c 프로젝트: nobled/piglit
int
generate_GLSL(enum shader_target test_stage)
{
	int vs, fs;

	static char *vs_code;
	static char *fs_code;
	char *lod_arg;
	static const char *zeroes[3] = { "", "0, ", "0, 0, " };

	const int size = sampler_size();

	/* The GLSL 1.40 sampler2DRect/samplerBuffer samplers don't
	 * take a lod argument.
	 */
	if (sampler.target == GL_TEXTURE_RECTANGLE ||
	    sampler.target == GL_TEXTURE_BUFFER)
		lod_arg = "";
	else
		lod_arg = ", lod";

	switch (test_stage) {
	case VS:
		asprintf(&vs_code,
			 "#version %d\n"
			 "#define ivec1 int\n"
			 "uniform int lod;\n"
			 "uniform %s tex;\n"
			 "in vec4 vertex;\n"
			 "flat out ivec%d size;\n"
			 "void main()\n"
			 "{\n"
			 "    size = textureSize(tex%s);\n"
			 "    gl_Position = vertex;\n"
			 "}\n",
			 shader_version, sampler.name, size, lod_arg);
		asprintf(&fs_code,
			 "#version %d\n"
			 "#define ivec1 int\n"
			 "#define vec1 float\n"
			 "flat in ivec%d size;\n"
			 "void main()\n"
			 "{\n"
			 "    gl_FragColor = vec4(0.01 * size,%s 1);\n"
			 "}\n",
			 shader_version, size, zeroes[3 - size]);
		break;
	case FS:
		asprintf(&vs_code,
			 "#version %d\n"
			 "in vec4 vertex;\n"
			 "void main()\n"
			 "{\n"
			 "    gl_Position = vertex;\n"
			 "}\n",
			 shader_version);
		asprintf(&fs_code,
			 "#version %d\n"
			 "#define ivec1 int\n"
			 "uniform int lod;\n"
			 "uniform %s tex;\n"
			 "void main()\n"
			 "{\n"
			 "    ivec%d size = textureSize(tex%s);\n"
			 "    gl_FragColor = vec4(0.01 * size,%s 1);\n"
			 "}\n",
			 shader_version, sampler.name, size, lod_arg,
			 zeroes[3 - size]);
		break;
	default:
		assert(!"Should not get here.");
		break;
	}

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);

	if (!vs || !fs)
		return 0;

	return piglit_link_simple_program(vs, fs);
}
예제 #8
0
/**
 * Generate a vertex or fragment shader to test the given set of
 * varyings.
 */
static GLint
get_shader(bool is_vs, unsigned glsl_version, int num_varyings,
	   struct varying_desc *varyings, enum test_array_type array_type)
{
	GLuint shader;
	char *full_text = malloc(1000 * 100 + num_varyings);
	char *text = full_text;
	unsigned i, j, k, l, m;
	const char *varying_keyword;
	unsigned offset = 0;
	GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;
	bool fp64 = false;

	if (glsl_version >= 130) {
		if (is_vs)
			varying_keyword = "out";
		else
			varying_keyword = "in";
	} else {
		varying_keyword = "varying";
	}

	text += sprintf(text, "#version %u\n", glsl_version);
	if (array_type == ARRAYS_OF_ARRAYS)
		text += sprintf(text, "#extension GL_ARB_arrays_of_arrays: enable\n");
	for (i = 0; i < num_varyings; ++i) {
		const char *opt_flat_keyword = "";
		if (!fp64 && varyings[i].type->base == BASE_TYPE_DOUBLE) {
			text += sprintf(text, "#extension GL_ARB_gpu_shader_fp64: enable\n");
			fp64 = true;
		}
		if (varyings[i].type->base != BASE_TYPE_FLOAT)
			opt_flat_keyword = "flat ";
		if (varyings[i].two_dim_array_elems != 0) {
			text += sprintf(text, "%s%s %s var%03u[%u][%u];\n",
					opt_flat_keyword, varying_keyword,
					varyings[i].type->name, i,
					outer_dim_size,
					varyings[i].two_dim_array_elems);
		} else if (varyings[i].one_dim_array_elems != 0) {
			text += sprintf(text, "%s%s %s var%03u[%u];\n",
					opt_flat_keyword, varying_keyword,
					varyings[i].type->name, i,
					varyings[i].one_dim_array_elems);
		} else {
			text += sprintf(text, "%s%s %s var%03u;\n",
					opt_flat_keyword, varying_keyword,
					varyings[i].type->name, i);
		}
	}
	if (glsl_version >= 150 && is_vs) {
		text += sprintf(text, "in vec4 piglit_vertex;\n");
		text += sprintf(text, "#define gl_Vertex piglit_vertex\n");
	}
	text += sprintf(text, "uniform int i;\n");
	text += sprintf(text,
			"\n"
			"void main()\n"
			"{\n");
	if (is_vs)
		text += sprintf(text, "  gl_Position = gl_Vertex;\n");
	else
		text += sprintf(text, "  bool failed = false;\n");
	for (i = 0; i < num_varyings; ++i) {
		unsigned array_loop_bound;
		unsigned outer_array_loop_bound = 1;
		const char *base_type_name
			= get_base_type_name(varyings[i].type->base);
		if (varyings[i].two_dim_array_elems != 0) {
			outer_array_loop_bound = outer_dim_size;
			array_loop_bound = varyings[i].two_dim_array_elems;
		} else {
			array_loop_bound = varyings[i].one_dim_array_elems;
		}
		if (array_loop_bound == 0)
			array_loop_bound = 1;
		for (j = 0; j < outer_array_loop_bound; ++j) {
			for (k = 0; k < array_loop_bound; ++k) {
				for (l = 0; l < varyings[i].type->num_cols; ++l) {
					for (m = 0; m < varyings[i].type->num_rows; ++m) {
						text += sprintf(text, "  ");
						if (!is_vs)
							text += sprintf(text, "failed = failed || ");
						text += sprintf(text, "var%03u", i);
						if (varyings[i].two_dim_array_elems)
							text += sprintf(text, "[%u]", j);
						if (varyings[i].one_dim_array_elems || varyings[i].two_dim_array_elems)
							text += sprintf(text, "[%u]", k);
						if (varyings[i].type->num_cols > 1)
							text += sprintf(text, "[%u]", l);
						if (varyings[i].type->num_rows > 1)
							text += sprintf(text, "[%u]", m);
						if (is_vs)
							text += sprintf(text, " = ");
						else
							text += sprintf(text, " != ");
						text += sprintf(text, "%s(i + %u);\n",
								base_type_name,
								offset++);
					}
				}
			}
		}
	}
	if (!is_vs) {
		text += sprintf(text,
				"  if (failed)\n"
				"    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"  else\n"
				"    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n");
	}
	text += sprintf(text, "}\n");

	shader = piglit_compile_shader_text(shader_type, full_text);

	free(full_text);

	return shader;
}
예제 #9
0
void
piglit_init(int argc, char **argv)
{
	enum piglit_result result = PIGLIT_PASS;
	GLint prog;
	GLint fs;
	GLint vs;
	GLenum err;

	if (piglit_get_gl_version() < 20) {
		printf("Requires OpenGL 2.0\n");
		piglit_report_result(PIGLIT_SKIP);
	}

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);

	prog = piglit_link_simple_program(vs, fs);
	glUseProgram(prog);

	/* There shouldn't be any GL errors, but clear them all just to be
	 * sure.
	 */
	while (glGetError() != 0)
		/* empty */ ;

	glBegin(GL_TRIANGLE_STRIP);
	glUseProgram(0);
	glEnd();

	err = glGetError();
	if (err != GL_INVALID_OPERATION) {
		printf("Unexpected OpenGL error state 0x%04x for "
		       "glUseProgram(0) "
		       "inside glBegin/glEnd pair (expected 0x%04x).\n",
		       err, GL_INVALID_OPERATION);
		result = PIGLIT_FAIL;
	}

	while (glGetError() != 0)
		/* empty */ ;

	/* Try again, but re-use the same program.  This should still generate
	 * an error even though it's a no-op.
	 */
	glUseProgram(prog);

	glBegin(GL_TRIANGLE_STRIP);
	glUseProgram(prog);
	glEnd();

	err = glGetError();
	if (err != GL_INVALID_OPERATION) {
		printf("Unexpected OpenGL error state 0x%04x for "
		       "glUseProgram(prog) "
		       "inside glBegin/glEnd pair (expected 0x%04x).\n",
		       err, GL_INVALID_OPERATION);
		result = PIGLIT_FAIL;
	}

	piglit_report_result(result);
}
예제 #10
0
void piglit_init(int argc, char **argv)
{
	GLuint vs;
	GLuint *readback;
	GLuint buffer[BUFFER_SIZE];
	GLuint expected[BUFFER_SIZE];
	int i;
	bool pass = true;
	GLint input_index;
	GLuint prog;
	GLuint xfb_buf, vbo;
	GLuint verts[4] = { 0, 1, 2, 3 };
	const char *varying = "o";

	piglit_require_GLSL_version(140);
	piglit_require_gl_version(30);
	piglit_require_transform_feedback();
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);

	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glTransformFeedbackVaryings(prog, 1, &varying, GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog))
		piglit_report_result(PIGLIT_FAIL);
	glGenBuffers(1, &xfb_buf);
	if (!piglit_check_gl_error(0))
		piglit_report_result(PIGLIT_FAIL);

	input_index = glGetAttribLocation(prog, "i");

	glUseProgram(prog);

	if (piglit_get_gl_version() >= 31) {
                GLuint vao;
                glGenVertexArrays(1, &vao);
                glBindVertexArray(vao);
        }

	glGenBuffers(1, &vbo);
	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glBufferData(GL_ARRAY_BUFFER,
		     4 * sizeof(GLuint), verts, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, vbo);
	glVertexAttribIPointer(input_index, 1, GL_UNSIGNED_INT,
			       sizeof(GLuint), 0);
	glEnableVertexAttribArray(input_index);
	pass = piglit_check_gl_error(0) && pass;

	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfb_buf);
	memset(buffer, 0xd0, sizeof(buffer));
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(buffer), buffer,
		     GL_STREAM_READ);
	glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfb_buf,
			  0,
			  sizeof(buffer));
	glBeginTransformFeedback(GL_POINTS);
	glDrawArrays(GL_POINTS, 0, ARRAY_SIZE(verts));
	glEndTransformFeedback();

	readback = glMapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);

	/* Check output */
	for (i = 0; i < BUFFER_SIZE; ++i) {
		if (verts[i] != readback[i]) {
			printf("readback[%u]: %u, expected: %u\n", i,
			       readback[i], expected[i]);
			pass = false;
		}
	}

	/* Note that rasterization occurred, but the results were
	 * undefined due to gl_Position not being written.  We do want
	 * to have rasterization occur (as opposed to just transform
	 * feedback) just to make sure the GPU didn't wedge or
	 * anything.
	 */

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
예제 #11
0
static GLboolean
test_uniform_funcs(void)
{
   static const char *signedFragText =
      "uniform int value1; \n"
      "uniform ivec2 value2; \n"
      "uniform ivec3 value3; \n"
      "uniform ivec4 value4; \n"
      "void main() \n"
      "{ \n"
      "   vec4 t = vec4(value4); \n"
      "   t += vec4(value3, 0.0); \n"
      "   t += vec4(value2, 0.0, 0.0); \n"
      "   t += vec4(value1, 0.0, 0.0, 0.0); \n"
      " gl_FragColor = 0.01 * t; \n"
      "} \n";

   static const char *unsignedFragText =
      "#extension GL_EXT_gpu_shader4: enable \n"
      "uniform unsigned int value1; \n"
      "uniform uvec2 value2; \n"
      "uniform uvec3 value3; \n"
      "uniform uvec4 value4; \n"
      "void main() \n"
      "{ \n"
      "   vec4 t = vec4(value4); \n"
      "   t += vec4(value3, 0.0); \n"
      "   t += vec4(value2, 0.0, 0.0); \n"
      "   t += vec4(value1, 0.0, 0.0, 0.0); \n"
      " gl_FragColor = 0.01 * t; \n"
      "} \n";


   GLint vals[4], loc1, loc2, loc3, loc4;
   GLuint shader;

   /*
    * Signed integer tests.
    */
   shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, signedFragText);
   assert(shader);

   Program = piglit_link_simple_program(0, shader);
   assert(Program);

   glUseProgram(Program);
   check_error(__FILE__, __LINE__);

   loc1 = glGetUniformLocation(Program, "value1");
   assert(loc1 >= 0);

   loc2 = glGetUniformLocation(Program, "value2");
   assert(loc2 >= 0);

   loc3 = glGetUniformLocation(Program, "value3");
   assert(loc3 >= 0);

   loc4 = glGetUniformLocation(Program, "value4");
   assert(loc4 >= 0);

   check_error(__FILE__, __LINE__);

   gen_values(vals, 1, SIGNED);
   glUniform1iARB(loc1, vals[0]);
   if (!check_uniform(vals, 1, SIGNED, loc1, "glUniform1iARB"))
      return GL_FALSE;

   gen_values(vals, 2, SIGNED);
   glUniform2iARB(loc2, vals[0], vals[1]);
   if (!check_uniform(vals, 2, SIGNED, loc2, "glUniform2iARB"))
      return GL_FALSE;

   gen_values(vals, 3, SIGNED);
   glUniform3iARB(loc3, vals[0], vals[1], vals[2]);
   if (!check_uniform(vals, 3, SIGNED, loc3, "glUniform3iARB"))
      return GL_FALSE;

   gen_values(vals, 4, SIGNED);
   glUniform4iARB(loc4, vals[0], vals[1], vals[2], vals[3]);
   if (!check_uniform(vals, 4, SIGNED, loc4, "glUniform4iARB"))
      return GL_FALSE;


   /*
    * Unsigned integer tests.
    */
   shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, unsignedFragText);
   assert(shader);

   Program = piglit_link_simple_program(0, shader);
   assert(Program);

   glUseProgram(Program);
   check_error(__FILE__, __LINE__);

   loc1 = glGetUniformLocation(Program, "value1");
   assert(loc1 >= 0);

   loc2 = glGetUniformLocation(Program, "value2");
   assert(loc2 >= 0);

   loc3 = glGetUniformLocation(Program, "value3");
   assert(loc3 >= 0);

   loc4 = glGetUniformLocation(Program, "value4");
   assert(loc4 >= 0);

   check_error(__FILE__, __LINE__);

   gen_values(vals, 1, UNSIGNED);
   glUniform1uiEXT(loc1, vals[0]);
   if (!check_uniform(vals, 1, UNSIGNED, loc1, "glUniform1uiEXT"))
      return GL_FALSE;

   gen_values(vals, 2, UNSIGNED);
   glUniform2uiEXT(loc2, vals[0], vals[1]);
   if (!check_uniform(vals, 2, UNSIGNED, loc2, "glUniform2uiEXT"))
      return GL_FALSE;

   gen_values(vals, 3, UNSIGNED);
   glUniform3uiEXT(loc3, vals[0], vals[1], vals[2]);
   if (!check_uniform(vals, 3, UNSIGNED, loc3, "glUniform3uiEXT"))
      return GL_FALSE;

   gen_values(vals, 4, UNSIGNED);
   glUniform4uiEXT(loc4, vals[0], vals[1], vals[2], vals[3]);
   if (!check_uniform(vals, 4, UNSIGNED, loc4, "glUniform4uiEXT"))
      return GL_FALSE;

   return GL_TRUE;
}
예제 #12
0
파일: position.c 프로젝트: nobled/piglit
void piglit_init(int argc, char **argv)
{
	GLuint vs;
	unsigned i;
	float data[BUF_FLOATS];

	for (i = 0; i < BUF_FLOATS; i++) {
		data[i] = DEFAULT_VALUE;
	}

	/* Parse params. */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "discard")) {
			discard = GL_TRUE;
		} else if (!strcmp(argv[i], "offset")) {
			/* BindBufferOffset only exists in the EXT specification */
			piglit_require_extension("GL_EXT_transform_feedback");
			offset = OFFSET;
		} else if (!strcmp(argv[i], "range")) {
			offset = OFFSET;
			range = MAX_RANGE-7;
		} else if (!strcmp(argv[i], "render")) {
			test = RENDER;
		} else if (!strcmp(argv[i], "primgen")) {
			test = PRIMGEN;
		} else if (!strcmp(argv[i], "primwritten")) {
			test = PRIMWRITTEN;
		}
	}

	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

	/* Check the driver. */
	if (piglit_get_gl_version() < 15) {
		fprintf(stderr, "OpenGL 1.5 required.\n");
		piglit_report_result(PIGLIT_SKIP);
	}
	piglit_require_GLSL();
	piglit_require_transform_feedback();

	/* Create shaders. */
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
	prog = piglit_CreateProgram();
	piglit_AttachShader(prog, vs);
	piglit_TransformFeedbackVaryings(prog, 1, varyings, GL_INTERLEAVED_ATTRIBS_EXT);
	piglit_LinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		piglit_DeleteProgram(prog);
		piglit_report_result(PIGLIT_FAIL);
	}

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vspassthrough);
	prog_passthrough = piglit_CreateProgram();
	piglit_AttachShader(prog_passthrough, vs);
	piglit_TransformFeedbackVaryings(prog_passthrough, 1, varyings, GL_INTERLEAVED_ATTRIBS_EXT);
	piglit_LinkProgram(prog_passthrough);
	if (!piglit_link_check_status(prog_passthrough)) {
		piglit_DeleteProgram(prog_passthrough);
		piglit_report_result(PIGLIT_FAIL);
	}

	/* Set up the transform feedback buffer. */
	glGenBuffers(1, &buf);
	glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, buf);
	glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER_EXT,
		     BUF_FLOATS*sizeof(float), data, GL_STREAM_READ);

	assert(glGetError() == 0);

	if (range) {
		puts("Testing BindBufferRange.");
		piglit_BindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER_EXT,
				     0, buf, offset*sizeof(float), range*sizeof(float));
	} else if (offset) {
		puts("Testing BindBufferOffset.");
		glBindBufferOffsetEXT(GL_TRANSFORM_FEEDBACK_BUFFER_EXT,
				      0, buf, offset*sizeof(float));
	} else {
		puts("Testing BindBufferBase.");
		piglit_BindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER_EXT, 0, buf);
	}

	if (!range) {
		range = MAX_RANGE;
	} else {
		range = MAX_RANGE/2; /* just one primitive is going to be written */
	}

	assert(glGetError() == 0);

	glClearColor(0.2, 0.2, 0.2, 1.0);
	glEnableClientState(GL_VERTEX_ARRAY);
}
예제 #13
0
void
piglit_init(int argc, char **argv)
{
	static const float uniform_data[4] = {
		12.0, 0.5, 3.14169, 42.0
	};
	GLint vs;
	GLint fs;
	unsigned i;
	union data_blob buffer[16];

	piglit_require_vertex_shader();
	piglit_require_fragment_shader();

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);

	prog = piglit_link_simple_program(vs, fs);

	piglit_UseProgram(prog);

	base_location = piglit_GetUniformLocation(prog, "c");
	if (base_location < 0) {
		printf("Could not get location of `c'.\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	for (i = 0; i < 4; i++) {
		char name[5];

		name[0] = 'c';
		name[1] = '[';
		name[2] = '0' + i;
		name[3] = ']';
		name[4] = '\0';
		array_location[i] = piglit_GetUniformLocation(prog, name);
		if (array_location[i] < 0) {
			printf("Could not get location of `%s'.\n", name);
			piglit_report_result(PIGLIT_FAIL);
		}
	}

	/* From page 80 of the OpenGL 2.1 spec:
	 *
	 *     The first element of a uniform array is identified using the
	 *     name of the uniform array appended with "[0]". Except if the
	 *     last part of the string name indicates a uniform array, then
	 *     the location of the first element of that array can be
	 *     retrieved by either using the name of the uniform array, or the
	 *     name of the uniform array appended with "[0]".
	 */
	if (base_location != array_location[0]) {
		printf("Locations of `c' = %d and `c[0]' = %d, but they "
		       "should be the same.\n",
		       base_location, array_location[0]);
		piglit_report_result(PIGLIT_FAIL);
	}

	piglit_Uniform1fv(base_location, 4, uniform_data);

	/* From page 264 of the OpenGL 2.1 spec:
	 *
	 *     In order to query the values of an array of uniforms, a
	 *     GetUniform* command needs to be issued for each array element.
	 *
	 * This means that querying using the location of 'array' is the same
	 * as 'array[0]'.
	 */
	printf("Getting array element 0 from base location...\n");
	for (i = 0; i < ARRAY_SIZE(buffer); i++) {
		buffer[i].u = 0xdeadbeef;
	}

	piglit_GetUniformfv(prog, base_location, (GLfloat *) buffer);
	validate_buffer(buffer, ARRAY_SIZE(buffer), uniform_data[0]);

	printf("Getting one array element at a time...\n");
	for (i = 0; i < 4; i++) {
		unsigned j;
		for (j = 0; j < ARRAY_SIZE(buffer); j++) {
			buffer[j].u = 0xdeadbeef;
		}

		piglit_GetUniformfv(prog, array_location[i],
				    (GLfloat *) buffer);
		validate_buffer(buffer, ARRAY_SIZE(buffer), uniform_data[i]);
	}

	piglit_report_result(PIGLIT_PASS);
}
예제 #14
0
static GLboolean
do_test(const struct test_desc *test)
{
	GLuint vs;
	GLuint progs[2] = { 0 };
	GLuint pipes[2];
	GLuint bufs[NUM_BUFFERS];
	float initial_xfb_buffer_contents[XFB_BUFFER_SIZE];
	GLboolean pass = GL_TRUE;
	int i;
	int num_varyings = test->mode == NO_VARYINGS ? 0 : test->num_buffers;
	GLint max_separate_attribs;
	char* vstext_sep;

	if (test->mode == USEPROGSTAGE_ACTIVE
	    || test->mode == USEPROGSTAGE_NOACTIVE
	    || test->mode == BIND_PIPELINE) {
		piglit_require_extension("GL_ARB_separate_shader_objects");

		if (piglit_get_gl_version() >= 32)
			asprintf(&vstext_sep, vstext_sep_template, 150);
		else
			asprintf(&vstext_sep, vstext_sep_template, 110);
	}

	glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS,
		      &max_separate_attribs);
	printf("MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTIBS=%i\n",
	       max_separate_attribs);

	printf("Compile vertex shader\n");
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
	if (test->mode == USEPROGSTAGE_ACTIVE
	    || test->mode == USEPROGSTAGE_NOACTIVE
	    || test->mode == BIND_PIPELINE) {
		/* Note, we can't use glCreateShaderProgramv because the setup
		 * of transform feedback must be done before linking
		 */
		vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext_sep);
		progs[0] = glCreateProgram();
		glProgramParameteri(progs[0], GL_PROGRAM_SEPARABLE, GL_TRUE);
		glAttachShader(progs[0], vs);
	} else if (test->mode == NOT_A_PROGRAM) {
		printf("Create a program and then delete it\n");
		progs[0] = glCreateProgram();
		glDeleteProgram(progs[0]);
	} else {
		progs[0] = glCreateProgram();
		glAttachShader(progs[0], vs);
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	printf("Setup transform feedback for %i varyings in %s mode\n",
	       num_varyings,
	       test->buffer_mode == GL_INTERLEAVED_ATTRIBS
	       ? "interleaved" : "separate");
	glTransformFeedbackVaryings(progs[0], num_varyings,
				    varyings, test->buffer_mode);

	if (test->mode == NOT_A_PROGRAM) {
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	}

	printf("Link program\n");
	glLinkProgram(progs[0]);
	pass = piglit_link_check_status(progs[0]) && pass;

	if (test->mode == USEPROGSTAGE_ACTIVE
	    || test->mode == USEPROGSTAGE_NOACTIVE
	    || test->mode == BIND_PIPELINE) {
		printf("Create 2nd program for the pipeline\n");
		progs[1] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1,
						  (const char **) &vstext_sep);
		pass = piglit_link_check_status(progs[1]) && pass;
	}

	if (test->mode == USEPROG_ACTIVE || test->mode == LINK_OTHER_ACTIVE) {
		printf("Prepare 2nd program\n");
		progs[1] = glCreateProgram();
		glAttachShader(progs[1], vs);
	}
	if (test->mode == USEPROG_ACTIVE) {
		printf("Link 2nd program\n");
		glLinkProgram(progs[1]);
		pass = piglit_link_check_status(progs[1]) && pass;
	}

	if (test->mode == USEPROGSTAGE_ACTIVE
	    || test->mode == USEPROGSTAGE_NOACTIVE
	    || test->mode == BIND_PIPELINE) {
		printf("Use pipeline\n");
		glGenProgramPipelines(2, pipes);
		glUseProgramStages(pipes[0], GL_VERTEX_SHADER_BIT, progs[0]);
		glUseProgramStages(pipes[1], GL_VERTEX_SHADER_BIT, progs[1]);
		glBindProgramPipeline(pipes[0]);
	} else if (test->mode == SKIP_USE_PROGRAM) {
		printf("Don't use program\n");
	} else {
		printf("Use program\n");
		glUseProgram(progs[0]);
	}

	printf("Prepare %i buffers\n", test->num_buffers);
	glGenBuffers(test->num_buffers, bufs);
	memset(initial_xfb_buffer_contents, 0,
	       sizeof(initial_xfb_buffer_contents));
	for (i = 0; i < test->num_buffers; ++i) {
		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufs[i]);
		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER,
			     sizeof(initial_xfb_buffer_contents),
			     initial_xfb_buffer_contents, GL_STREAM_READ);
	}

	switch (test->mode) {
	case BIND_MAX:
		do_bind(test, bufs[0], max_separate_attribs);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	case BIND_BAD_SIZE:
	case BIND_BAD_OFFSET:
		do_bind(test, bufs[0], 0);
		pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;
		return pass;
	default:
		break;
	}

	for (i = 0; i < test->num_buffers; ++i) {
		if (test->mode == UNBOUND_BUFFER && i == test->param) {
			printf("Don't bind buffer %i\n", i);
		} else {
			do_bind(test, bufs[i], i);
		}
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	if (test->mode == END_INACTIVE) {
		printf("EndTransformFeedback\n");
		glEndTransformFeedback();
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		return pass;
	}

	printf("BeginTransformFeedback\n");
	glBeginTransformFeedback(GL_POINTS);
	switch (test->mode) {
	case UNBOUND_BUFFER:
	case NO_VARYINGS:
	case SKIP_USE_PROGRAM:
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	default:
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		break;
	}

	switch (test->mode) {
	case BEGIN_ACTIVE:
		printf("BeginTransformFeedback\n");
		glBeginTransformFeedback(GL_POINTS);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case USEPROG_ACTIVE:
		printf("Use new program\n");
		glUseProgram(progs[1]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case LINK_CURRENT_ACTIVE:
		printf("Link current program\n");
		glLinkProgram(progs[0]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case LINK_OTHER_ACTIVE:
		printf("Link 2nd program\n");
		glLinkProgram(progs[1]);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		break;
	case BIND_ACTIVE:
		do_bind(test, bufs[0], 0);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case USEPROGSTAGE_ACTIVE:
		printf("Use new program stage\n");
		glUseProgramStages(pipes[0], GL_VERTEX_SHADER_BIT, progs[1]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	case USEPROGSTAGE_NOACTIVE:
		printf("Use new program stage\n");
		glUseProgramStages(pipes[1], GL_VERTEX_SHADER_BIT, progs[1]);
		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
		break;
	case BIND_PIPELINE:
		printf("Bind a new pipeline\n");
		glBindProgramPipeline(pipes[1]);
		pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
		break;
	default:
		break;
	}

	return pass;
}
예제 #15
0
enum piglit_result
piglit_display(void)
{
	GLuint vs, fs;
	bool pass = true;
	GLuint prog;
	float green[] = {0.0, 1.0, 0.0, 0.0};
	GLint status;

	/* Initial buffer clear. */
	glClearColor(1.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
	prog = piglit_link_simple_program(vs, fs);

	if (!vs || !fs || !prog)
		piglit_report_result(PIGLIT_FAIL);

	piglit_DeleteShader(vs);
	piglit_DeleteShader(fs);
	piglit_UseProgram(prog);
	piglit_DeleteProgram(prog);

	/* Since the program is in use, it should be flagged for
	 * deletion but not deleted.
	 */
	piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status);
	if (!piglit_check_gl_error(0))
		piglit_report_result(PIGLIT_FAIL);
	if (status != GL_TRUE) {
		fprintf(stderr,
			"GL_DELETE_STATUS when deleted reported non-true %d\n",
			status);
		pass = false;
	}

	/* Sanity check: deleting didn't already unbind our shader program. */
	piglit_draw_rect(-1, -1, 2, 2);
	pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height,
				      green) && pass;

	glClearColor(1.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	/* The main test: Can we still draw after a clear with a
	 * delete program?
	 */
	piglit_draw_rect(-1, -1, 2, 2);
	pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height,
				      green) && pass;

	/* The program should still report being deleted. */
	piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status);
	if (!piglit_check_gl_error(0))
		piglit_report_result(PIGLIT_FAIL);
	if (status != GL_TRUE) {
		fprintf(stderr,
			"GL_DELETE_STATUS after a clear reported non-true %d\n",
			status);
		pass = false;
	}

	/* Now, disable the program and it should be finally deleted. */
	piglit_UseProgram(0);

	piglit_GetProgramiv(prog, GL_DELETE_STATUS, &status);
	pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
void piglit_init(int argc, char **argv)
{
	GLint max_draw_buffers;
	GLuint prog;
	GLuint vs;
	GLuint fs;
	GLint loc;

	piglit_require_gl_version(30);

	/* This test needs some number of draw buffers, so make sure the
	 * implementation isn't broken.  This enables the test to generate a
	 * useful failure message.
	 */
	glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
	if (max_draw_buffers < 8) {
		fprintf(stderr,
			"OpenGL 3.0 requires GL_MAX_DRAW_BUFFERS >= 8.  "
			"Only got %d!\n",
			max_draw_buffers);
		piglit_report_result(PIGLIT_FAIL);
	}

	prog = glCreateProgram();
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	/* First, verify that the program will link without making any
	 * location assignments through the API.
	 */
	printf("Basic test...\n");

	glAttachShader(prog, vs);
	glAttachShader(prog, fs);
	glLinkProgram(prog);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (!piglit_link_check_status(prog)) {
		piglit_report_result(PIGLIT_FAIL);
	}

	/* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says:
	 *
	 *     "Assigned bindings for variables that do not exist are
	 *     ignored."
	 */
	printf("Binding `unicorn' to a non-conflicting location...\n");

	glBindFragDataLocation(prog, 0, "v");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
	glBindFragDataLocation(prog, 1, "unicorn");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glLinkProgram(prog);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (!piglit_link_check_status(prog)) {
		fprintf(stderr,
			"Linking failed when it should have been "
			"successful.\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	loc = glGetFragDataLocation(prog, "unicorn");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (loc != -1) {
		fprintf(stderr, "Expected location = -1, got %d\n", loc);
		piglit_report_result(PIGLIT_FAIL);
	}

	printf("Binding `unicorn' to a conflicting location...\n");

	glBindFragDataLocation(prog, 0, "v");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
	glBindFragDataLocation(prog, 0, "unicorn");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	glLinkProgram(prog);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (!piglit_link_check_status(prog)) {
		fprintf(stderr,
			"Linking failed when it should have been "
			"successful.\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	loc = glGetFragDataLocation(prog, "unicorn");
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	if (loc != -1) {
		fprintf(stderr, "Expected location = -1, got %d\n", loc);
		piglit_report_result(PIGLIT_FAIL);
	}

	piglit_report_result(PIGLIT_PASS);
}
static void
generate_and_display_drawbuffers(int count)
{
	GLuint tex[MAX_TARGETS], fb, fs, vs, prog;
	GLenum attachments[MAX_TARGETS], status;
	char *fs_count_source;
	int i;
	int colors_uniform;

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	for (i = 0; i < count; i++) {
		tex[i] = attach_texture(i);
		attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status);
		piglit_report_result(PIGLIT_SKIP);
	}

	glDrawBuffersARB(count, attachments);

	/* Clear all to red so we see if the shader rendering happens. */
	glClearColor(1.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	/* Build the shader that writes different color to each buffer. */
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);

	fs_count_source = malloc(strlen(fs_source) + 5);
	sprintf(fs_count_source, fs_source, count);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_count_source);
	free(fs_count_source);

	prog = piglit_link_simple_program(vs, fs);
	glUseProgram(prog);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);

	colors_uniform = glGetUniformLocation(prog, "colors");
	glUniform4fv(colors_uniform, MAX_TARGETS, (GLfloat *) colors);

	/* Now render to all the color buffers. */
	piglit_draw_rect(-1, -1, 2, 2);

	/* OK, now draw each of these textures to the winsys framebuffer. */
	glUseProgram(0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_TEXTURE_2D);
	/* draw row of boxes, each with the color from texture/target[i] */
	for (i = 0; i < count; i++) {
		glBindTexture(GL_TEXTURE_2D, tex[i]);
		piglit_draw_rect_tex(16 * i, 16 * (count - 1),
				     16, 16,
				     0, 0,
				     1, 1);
	}
	glDisable(GL_TEXTURE_2D);

	for (i = 0; i < count; i++) {
		glDeleteTextures(1, &tex[i]);
	}
	glDeleteFramebuffersEXT(1, &fb);
}
예제 #18
0
void
piglit_init(int argc, char **argv)
{
	enum piglit_result result = PIGLIT_PASS;
	GLenum err;
	GLint ok;
	GLuint prog;
	GLuint vs;

	if (piglit_get_gl_version() < 20) {
		printf("Requires OpenGL 2.0\n");
		piglit_report_result(PIGLIT_SKIP);
	}

	piglit_require_extension("GL_EXT_separate_shader_objects");

	printf("Trying shader with unresolved external symbol...\n");
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, bad_vs_text);
	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glLinkProgram(prog);
	glDeleteShader(vs);

	ok = piglit_link_check_status_quiet(prog);
	if (ok) {
		fprintf(stderr,
			"Linking with unresolved symbol succeeded when it "
			"should have failed.\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	/* There shouldn't be any GL errors, but clear them all just to be
	 * sure.
	 */
	while (glGetError() != 0)
		/* empty */ ;

	/* The specified program is not linked.  This should generate
	 * the error GL_INVALID_OPERATION.
	 */
	glActiveProgramEXT(prog);

	err = glGetError();
	if (err != GL_INVALID_OPERATION) {
		printf("Unexpected OpenGL error state 0x%04x for "
		       "glActiveProgramEXT called with\n"
		       "an unlinked shader program (expected 0x%04x).\n",
		       err, GL_INVALID_OPERATION);
		result = PIGLIT_FAIL;
	}

	glDeleteProgram(prog);
	glUseProgram(0);

	/* Try again with a shader program that could be linked but wasn't.
	 */
	printf("Trying unlinked, valid shader...\n");
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, good_vs_text);
	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glDeleteShader(vs);

	/* There shouldn't be any GL errors, but clear them all just to be
	 * sure.
	 */
	while (glGetError() != 0)
		/* empty */ ;

	/* The specified program is not linked.  This should generate
	 * the error GL_INVALID_OPERATION.
	 */
	glActiveProgramEXT(prog);

	err = glGetError();
	if (err != GL_INVALID_OPERATION) {
		printf("Unexpected OpenGL error state 0x%04x for "
		       "glActiveProgramEXT called with\n"
		       "an unlinked shader program (expected 0x%04x).\n",
		       err, GL_INVALID_OPERATION);
		result = PIGLIT_FAIL;
	}

	glDeleteProgram(prog);
	glUseProgram(0);

	piglit_report_result(result);
}
예제 #19
0
bool
do_test(const struct test *tests, unsigned num_tests)
{
	bool pass = true;
	unsigned i;

	for (i = 0; i < num_tests; i++) {
		GLint vert =
			piglit_compile_shader_text(GL_VERTEX_SHADER,
						   tests[i].code);
		GLint prog = piglit_link_simple_program(vert, 0);
		GLint num_attr;
		unsigned visited_count[64];
		unsigned j;
		bool shader_dumped = false;

		memset(visited_count, 0, sizeof(visited_count));

		/* From page 93 (page 109 of the PDF) says:
		 *
		 *     "An attribute variable (either conventional or generic)
		 *     is considered active if it is determined by the
		 *     compiler and linker that the attribute may be accessed
		 *     when the shader is executed. Attribute variables that
		 *     are declared in a vertex shader but never used will not
		 *     count against the limit. In cases where the compiler
		 *     and linker cannot make a conclusive determination, an
		 *     attribute will be considered active."
		 *
		 * Compare the set of active attributes against the list of
		 * expected active attributes.
		 */
		piglit_GetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &num_attr);

		for (j = 0; j < num_attr; j++) {
			const struct attribute *attr;
			char name_buf[256];
			int attr_idx;
			GLsizei name_len;
			GLint size;
			GLenum type;

			glGetActiveAttrib(prog, j,
					  sizeof(name_buf),
					  &name_len,
					  &size,
					  &type,
					  name_buf);
			attr_idx = find_attrib(tests[i].attributes, name_buf);

			/* If the named attribute is not in the list for the
			 * test, then it must not be active.
			 */
			if (attr_idx < 0) {
				DUMP_SHADER(tests[i].code);
				fprintf(stderr,
					"Attribute `%s' should not be active "
					"but is.\n", name_buf);
				pass = false;
				continue;
			}

			attr = &tests[i].attributes[attr_idx];
			if (visited_count[attr_idx] != 0) {
				DUMP_SHADER(tests[i].code);
				fprintf(stderr,
					"Attribute `%s' listed multiple times "
					"in active list.\n", name_buf);
				pass = false;
			} else if (attr->size != size) {
				DUMP_SHADER(tests[i].code);
				fprintf(stderr,
					"Attribute `%s' should have size %d, "
					"but had size %d.\n",
					name_buf, attr->size, size);
				pass = false;
			} else if (attr->type != type) {
				DUMP_SHADER(tests[i].code);
				fprintf(stderr,
					"Attribute `%s' should have type "
					"0x%04x, but had type 0x%04x.\n",
					name_buf, attr->type, type);
				pass = false;
			}

			visited_count[attr_idx]++;
		}

		for (j = 0; tests[i].attributes[j].name != NULL; j++) {
			if (tests[i].attributes[j].must_be_active
			    && visited_count[j] == 0) {
				DUMP_SHADER(tests[i].code);
				fprintf(stderr,
					"Attribute `%s' should have been "
					"active but wasn't.\n",
					tests[i].attributes[j].name);
				pass = false;
			}
		}
	}

	return pass;
}
예제 #20
0
static void
generate_and_display_drawbuffers(int count)
{
	GLuint tex[16], fb, fs, vs, prog;
	GLenum attachments[16], status, error;
	char *fs_count_source;
	int i;

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	for (i = 0; i < count; i++) {
		tex[i] = attach_texture(i);
		attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status);
		piglit_report_result(PIGLIT_SKIP);
	}

	glDrawBuffersARB(count, attachments);

	/* Clear all to red so we see if the shader rendering happens. */
	glClearColor(1.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	/* Build the shader that spams green to all outputs. */
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);

	fs_count_source = malloc(strlen(fs_source) + 5);
	sprintf(fs_count_source, fs_source, count);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_count_source);
	free(fs_count_source);

	prog = piglit_link_simple_program(vs, fs);
	glUseProgram(prog);

	error = glGetError();
	if (error) {
		fprintf(stderr, "glUseProgram error: 0x%x\n", error);
		piglit_report_result(PIGLIT_FAIL);
	}

	/* Now render to all the color buffers. */
	piglit_draw_rect(-1, -1, 2, 2);

	/* OK, now draw each of these textures to the winsys framebuffer. */
	glUseProgram(0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_TEXTURE_2D);
	for (i = 0; i < count; i++) {
		glBindTexture(GL_TEXTURE_2D, tex[i]);
		piglit_draw_rect_tex(16 * i, 16 * (count - 1),
				     16, 16,
				     0, 0,
				     1, 1);
	}
	glDisable(GL_TEXTURE_2D);

	for (i = 0; i < count; i++) {
		glDeleteTextures(1, &tex[i]);
	}
	glDeleteFramebuffersEXT(1, &fb);
}
예제 #21
0
enum piglit_result
piglit_display(void)
{
	const char *vs_ubo_template =
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"varying vec4 vary;"
		"\n"
		"layout(std140) uniform ubo {\n"
		"	vec4 v[%d];\n"
		"};\n"
		"uniform int i;\n"
		"\n"
		"void main() {\n"
		"	gl_Position = gl_Vertex;\n"
		"	vary = v[i];\n"
		"}\n";

	const char *fs_template =
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"varying vec4 vary;"
		"\n"
		"void main() {\n"
		"	gl_FragColor = vary;\n"
		"}\n";

	const char *vs_template =
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"void main() {\n"
		"	gl_Position = gl_Vertex;\n"
		"}\n";

	const char *fs_ubo_template =
		"#extension GL_ARB_uniform_buffer_object : enable\n"
		"\n"
		"layout(std140) uniform ubo {\n"
		"	vec4 v[%d];\n"
		"};\n"
		"uniform int i;\n"
		"\n"
		"void main() {\n"
		"	gl_FragColor = v[i];\n"
		"}\n";

	char *vs_source, *fs_source;
	GLint max_size, vec4s, i_location;
	GLuint vs, fs, prog, bo;
	GLenum target;
	float *data;
	size_t size;
	bool pass = true;
	bool may_link_fail;
	const float green[4] = { 0, 1, 0, 0 };
	int test_index;

	piglit_require_extension("GL_ARB_uniform_buffer_object");

	glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &max_size);
	printf("Max uniform block size: %d\n", max_size);
	vec4s = max_size / 4 / 4;

	switch (mode) {
	case VS:
		target = GL_VERTEX_SHADER;
		may_link_fail = false;
		test_index = vec4s - 1;
		break;
	case VS_EXCEED:
		target = GL_VERTEX_SHADER;
		may_link_fail = true;
		vec4s++;
		test_index = vec4s - 2;
		break;
	case FS:
		target = GL_FRAGMENT_SHADER;
		may_link_fail = false;
		test_index = vec4s - 1;
		break;
	case FS_EXCEED:
		target = GL_FRAGMENT_SHADER;
		may_link_fail = true;
		vec4s++;
		test_index = vec4s - 2;
		break;
	default:
		assert(false);
		target = GL_NONE;
		may_link_fail = false;
	}

	switch (target) {
	case GL_VERTEX_SHADER:
		(void)!asprintf(&vs_source, vs_ubo_template, vec4s);
		(void)!asprintf(&fs_source, "%s", fs_template);
		printf("Testing VS with uniform block vec4 v[%d]\n", vec4s);
		break;
	case GL_FRAGMENT_SHADER:
		(void)!asprintf(&vs_source, "%s", vs_template);
		(void)!asprintf(&fs_source, fs_ubo_template, vec4s);
		printf("Testing FS with uniform block vec4 v[%d]\n", vec4s);
		break;
	default:
		piglit_report_result(PIGLIT_FAIL);
	}

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);

	prog = glCreateProgram();
	glAttachShader(prog, vs);
	glAttachShader(prog, fs);
	glLinkProgram(prog);

	if (may_link_fail) {
		if (!piglit_link_check_status_quiet(prog)) {
			printf("Failed to link with uniform block vec4 "
			       "v[%d]\n", vec4s);
			piglit_report_result(PIGLIT_PASS);
		}
	} else {
		if (!piglit_link_check_status_quiet(prog)) {
			fprintf(stderr,
				"Failed to link with uniform block vec4 "
				"v[%d]\n", vec4s);
			return PIGLIT_FAIL;
		}
	}

	size = vec4s * 4 * sizeof(float);
	glGenBuffers(1, &bo);
	glBindBuffer(GL_UNIFORM_BUFFER, bo);
	glBufferData(GL_UNIFORM_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
	data = glMapBuffer(GL_UNIFORM_BUFFER, GL_READ_WRITE);
	memset(data, 0, size);

	/* The whole uniform buffer will be zeros, except for the
	 * entry at v[test_index] which will be green.
	 */
	data[test_index * 4 + 0] = green[0];
	data[test_index * 4 + 1] = green[1];
	data[test_index * 4 + 2] = green[2];
	data[test_index * 4 + 3] = green[3];
	glUnmapBuffer(GL_UNIFORM_BUFFER);

	glUseProgram(prog);
	i_location = glGetUniformLocation(prog, "i");
	glUniform1i(i_location, test_index);

	glUniformBlockBinding(prog, 0, 0);
	glBindBufferBase(GL_UNIFORM_BUFFER, 0, bo);
	piglit_draw_rect(-1, -1, 2, 2);

	pass = piglit_probe_rect_rgba(0, 0, piglit_width, piglit_height, green);

	glDeleteProgram(prog);

	piglit_present_results();

	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
}
예제 #22
0
파일: simple.c 프로젝트: RAOF/piglit
/**
 * Generate a vertex or fragment shader to test the given set of
 * varyings.
 */
static GLint
get_shader(bool is_vs, unsigned glsl_version, int num_varyings,
	   struct varying_desc *varyings)
{
	GLuint shader;
	char *full_text = malloc(1000 * 100 + num_varyings);
	char *text = full_text;
	unsigned i, j, k, l;
	const char *varying_keyword;
	unsigned offset = 0;
	GLenum shader_type = is_vs ? GL_VERTEX_SHADER : GL_FRAGMENT_SHADER;

	if (glsl_version >= 130) {
		if (is_vs)
			varying_keyword = "out";
		else
			varying_keyword = "in";
	} else {
		varying_keyword = "varying";
	}

	text += sprintf(text, "#version %u\n", glsl_version);
	text += sprintf(text, "uniform int i;\n");
	for (i = 0; i < num_varyings; ++i) {
		const char *opt_flat_keyword = "";
		if (varyings[i].type->base != BASE_TYPE_FLOAT)
			opt_flat_keyword = "flat ";
		if (varyings[i].array_elems != 0) {
			text += sprintf(text, "%s%s %s var%u[%u];\n",
					opt_flat_keyword, varying_keyword,
					varyings[i].type->name, i,
					varyings[i].array_elems);
		} else {
			text += sprintf(text, "%s%s %s var%u;\n",
					opt_flat_keyword, varying_keyword,
					varyings[i].type->name, i);
		}
	}
	text += sprintf(text,
			"\n"
			"void main()\n"
			"{\n");
	if (is_vs)
		text += sprintf(text, "  gl_Position = gl_Vertex;\n");
	else
		text += sprintf(text, "  bool failed = false;\n");
	for (i = 0; i < num_varyings; ++i) {
		unsigned array_loop_bound = varyings[i].array_elems;
		const char *base_type_name
			= get_base_type_name(varyings[i].type->base);
		if (array_loop_bound == 0)
			array_loop_bound = 1;
		for (j = 0; j < array_loop_bound; ++j) {
			for (k = 0; k < varyings[i].type->num_cols; ++k) {
				for (l = 0; l < varyings[i].type->num_rows; ++l) {
					text += sprintf(text, "  ");
					if (!is_vs)
						text += sprintf(text, "if (");
					text += sprintf(text, "var%u", i);
					if (varyings[i].array_elems)
						text += sprintf(text, "[%u]", j);
					if (varyings[i].type->num_cols > 1)
						text += sprintf(text, "[%u]", k);
					if (varyings[i].type->num_rows > 1)
						text += sprintf(text, "[%u]", l);
					if (is_vs)
						text += sprintf(text, " = ");
					else
						text += sprintf(text, " != ");
					text += sprintf(text, "%s(i + %u)",
							base_type_name,
							offset++);
					if (is_vs) {
						text += sprintf(text, ";\n");
					} else {
						text += sprintf(text,
								")\n"
								"    failed = true;\n");
					}
				}
			}
		}
	}
	if (!is_vs) {
		text += sprintf(text,
				"  if (failed)\n"
				"    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
				"  else\n"
				"    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n");
	}
	text += sprintf(text, "}\n");

	shader = piglit_compile_shader_text(shader_type, full_text);

	free(full_text);

	return shader;
}
예제 #23
0
파일: fbo-rg.c 프로젝트: Zoxc/piglit
static GLboolean
render_and_check_textures(GLenum internal_format)
{
    GLuint rgba_fb;
    GLuint other_fb;
    float rgba_image[4 * 64 * 64];
    float other_image[4 * 64 * 64];
    GLboolean has_green;
    GLuint vs;
    GLuint fs;
    GLint scale_loc;
    GLint bias_loc;
    float scale;
    float bias;

    piglit_require_extension("GL_EXT_framebuffer_object");
    piglit_require_extension("GL_ARB_texture_rg");

    has_green = GL_FALSE;
    scale = 1.0;
    bias = 0.0;
    switch (internal_format) {
    case GL_RG:
    case GL_RG8:
    case GL_RG16:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_RED:
    case GL_R8:
    case GL_R16:
        break;

    case GL_RG16F:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_R16F:
        piglit_require_extension("GL_ARB_half_float_pixel");
    /* FALLTHROUGH */
    case GL_RG32F:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_R32F:
        scale = 511.0;
        piglit_require_extension("GL_ARB_texture_float");
        break;

    case GL_RG_INTEGER:
    case GL_RG8I:
    case GL_RG16I:
    case GL_RG32I:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_R8I:
    case GL_R16I:
    case GL_R32I:
        bias = -100.0;
        scale = 511.0;
        piglit_require_extension("GL_EXT_texture_integer");
        break;

    case GL_RG8UI:
    case GL_RG16UI:
    case GL_RG32UI:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_R16UI:
    case GL_R32UI:
        scale = 511.0;
        piglit_require_extension("GL_EXT_texture_integer");
        break;

    case GL_RG_SNORM:
    case GL_RG8_SNORM:
    case GL_RG16_SNORM:
        has_green = GL_TRUE;
    /* FALLTHROUGH */
    case GL_RED_SNORM:
    case GL_R8_SNORM:
    case GL_R16_SNORM:
        scale = 0.5;
        bias = -0.5;
        piglit_require_extension("GL_EXT_texture_snorm");
        break;
    default:
        fprintf(stderr, "invalid format 0x%04x\n", internal_format);
        piglit_report_result(PIGLIT_FAIL);
        break;
    }

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE,
                          2 * sizeof(GLfloat), positions);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE,
                          4 * sizeof(GLfloat), colors);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert_code);
    fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag_code);
    fbo_program = piglit_link_simple_program(vs, fs);

    glBindAttribLocation(fbo_program, 0, "position");
    glBindAttribLocation(fbo_program, 1, "color");
    glLinkProgram(fbo_program);
    if (!piglit_link_check_status(fbo_program))
        piglit_report_result(PIGLIT_FAIL);

    scale_loc = glGetUniformLocation(fbo_program, "scale");
    if (scale_loc < 0) {
        fprintf(stderr,
                "couldn't get uniform location for \"scale\"\n");
        piglit_report_result(PIGLIT_FAIL);
    }

    bias_loc = glGetUniformLocation(fbo_program, "bias");
    if (bias_loc < 0) {
        fprintf(stderr,
                "couldn't get uniform location for \"bias\"\n");
        piglit_report_result(PIGLIT_FAIL);
    }

    glUseProgram(fbo_program);
    glUniform1f(scale_loc, scale);
    glUniform1f(bias_loc, bias);

    /* Draw the reference image to the RGBA texture.
     */
    rgba_fb = create_fbo(64, 64, GL_RGBA);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, rgba_fb);
    glViewport(0, 0, 64, 64);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
            GL_COLOR_ATTACHMENT0_EXT,
            GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
            (GLint *) &rgba_tex);
    glBindTexture(GL_TEXTURE_2D, rgba_tex);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, rgba_image);


    /* Draw the comparison image to the other texture.
     */
    other_fb = create_fbo(64, 64, internal_format);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, other_fb);
    glViewport(0, 0, 64, 64);
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT,
            GL_COLOR_ATTACHMENT0_EXT,
            GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
            (GLint *) &other_tex);
    glBindTexture(GL_TEXTURE_2D, other_tex);
    glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, other_image);

    glUseProgram(0);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
    glViewport(0, 0, piglit_width, piglit_height);

    return compare_texture(rgba_image, other_image,
                           internal_format, GL_RGBA,
                           64 * 64, has_green);
}
예제 #24
0
void
piglit_init(int argc, char **argv)
{
	GLuint vs_spiral, gs_spiral, vs_ref_main, vs_test_main, gs_test_main,
		gs_layout, fs_main, vao, element_buf;
	GLint max_gs_out_vertices, max_gs_out_components;
	int max_testable_vertices;
	char *text, *endptr;

	/* parse args */
	if (argc != 2)
		print_usage_and_exit(argv[0]);
	endptr = NULL;
	num_vertices = strtol(argv[1], &endptr, 0);
	if (endptr != argv[1] + strlen(argv[1]))
		print_usage_and_exit(argv[0]);

	/* Figure out the maximum number of vertices we can test. */
	glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &max_gs_out_vertices);
	glGetIntegerv(GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS,
		      &max_gs_out_components);
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
	max_testable_vertices = MIN2(max_gs_out_vertices,
				     max_gs_out_components / 4);

	/* If num_vertices == 0, test the maximum possible number of
	 * vertices.  Otherwise ensure that the requested number is
	 * supported by the implementation.
	 */
	if (num_vertices == 0)
		num_vertices = max_testable_vertices;
	else if (num_vertices > max_testable_vertices) {
		printf("Can't test more than %d vertices\n",
		       max_testable_vertices);
		piglit_report_result(PIGLIT_SKIP);
	}

	/* Compile shaders */
	vs_spiral = piglit_compile_shader_text(GL_VERTEX_SHADER, spiral_text);
	gs_spiral = piglit_compile_shader_text(GL_GEOMETRY_SHADER,
					       spiral_text);
	vs_ref_main = piglit_compile_shader_text(GL_VERTEX_SHADER,
						 vs_ref_text);
	vs_test_main = piglit_compile_shader_text(GL_VERTEX_SHADER,
						  vs_test_text);
	gs_test_main = piglit_compile_shader_text(GL_GEOMETRY_SHADER,
						  gs_test_text);
	asprintf(&text, gs_layout_template, num_vertices);
	gs_layout = piglit_compile_shader_text(GL_GEOMETRY_SHADER, text);
	free(text);
	fs_main = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);

	prog_ref = glCreateProgram();
	glAttachShader(prog_ref, vs_ref_main);
	glAttachShader(prog_ref, vs_spiral);
	glAttachShader(prog_ref, fs_main);
	glLinkProgram(prog_ref);
	if (!piglit_link_check_status(prog_ref))
		piglit_report_result(PIGLIT_FAIL);

	prog_test = glCreateProgram();
	glAttachShader(prog_test, vs_test_main);
	glAttachShader(prog_test, gs_test_main);
	glAttachShader(prog_test, gs_spiral);
	glAttachShader(prog_test, gs_layout);
	glAttachShader(prog_test, fs_main);
	glLinkProgram(prog_test);
	if (!piglit_link_check_status(prog_test))
		piglit_report_result(PIGLIT_FAIL);

	glDeleteShader(vs_spiral);
	glDeleteShader(gs_spiral);
	glDeleteShader(vs_ref_main);
	glDeleteShader(vs_test_main);
	glDeleteShader(gs_test_main);
	glDeleteShader(gs_layout);
	glDeleteShader(fs_main);

	/* Various other GL objects needed by the test */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glGenBuffers(1, &element_buf);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buf);

	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
}
예제 #25
0
파일: getuniform-02.c 프로젝트: RAOF/piglit
void
piglit_init(int argc, char **argv)
{
   GLuint vs, prog;
   GLint numUniforms, i;
   GLint expectedNum = 7;
   GLint loc_f1, loc_f2, loc_sa, loc_sd, loc_v1;
   GLfloat v[4];
   static const GLfloat vVals[4] = {30.0, 31.0, 32.0, 33.0};
   
   piglit_require_vertex_shader();
   piglit_require_fragment_shader();

   vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
   prog = piglit_link_simple_program(vs, 0);

   glUseProgram(prog);

   glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numUniforms);
   if (numUniforms != expectedNum) {
      printf("%s: incorrect number of uniforms (found %d, expected %d)\n",
             TestName, numUniforms, expectedNum);
      piglit_report_result(PIGLIT_FAIL);
   }

   /* check types, sizes */
   for (i = 0; i < numUniforms; i++) {
      GLcharARB name[100];
      GLsizei len;
      GLint size, expectedSize;
      GLenum type, expectedType;
      GLint loc;

      glGetActiveUniform(prog,
				 i, sizeof(name), &len, &size, &type, name);
      loc = glGetUniformLocation(prog, name);

      if (loc < 0) {
         printf("%s: bad uniform location for %s: %d\n", TestName, name, loc);
         piglit_report_result(PIGLIT_FAIL);
      }

      if (!piglit_automatic) {
         printf("%d: %s loc=%d size=%d type=0x%x\n", i, name, loc, size, type);
      }

      /* OpenGL ES 3.0 and OpenGL 4.2 require that the "[0]" be appended to
       * the name.  Earlier versions of the spec are ambiguous.  Accept either
       * name.
       */
      if (strcmp(name, "v") == 0 || strcmp(name, "v[0]") == 0) {
         expectedType = GL_FLOAT_VEC4_ARB;
         expectedSize = 3;
      }
      else {
         expectedType = GL_FLOAT;
         expectedSize = 1;
      }

      if (type != expectedType) {
         printf("%s: wrong type for 'v' (found 0x%x, expected 0x%x)\n",
                TestName, type, expectedType);
         piglit_report_result(PIGLIT_FAIL);
      }

      if (size != expectedSize) {
         printf("%s: wrong size for 'v' (found %d, expected %d)\n",
                TestName, size, expectedSize);
         piglit_report_result(PIGLIT_FAIL);
      }
   }

   /* Check setting/getting values */

   loc_f1 = glGetUniformLocation(prog, "f1");
   loc_f2 = glGetUniformLocation(prog, "f2");
   loc_sa = glGetUniformLocation(prog, "s.a");
   loc_sd = glGetUniformLocation(prog, "s.d");
   loc_v1 = glGetUniformLocation(prog, "v[1]");

   glUniform1f(loc_f1, 5.0);
   glUniform1f(loc_f2, 10.0);
   glUniform1f(loc_sa, 15.0);
   glUniform1f(loc_sd, 20.0);
   glUniform4fv(loc_v1, 1, vVals);

   glGetUniformfv(prog, loc_f1, v);
   if (v[0] != 5.0) {
      printf("%s: wrong value for f1 (found %f, expected %f)\n",
             TestName, v[0], 5.0);
      piglit_report_result(PIGLIT_FAIL);
   }

   glGetUniformfv(prog, loc_f2, v);
   if (v[0] != 10.0) {
      printf("%s: wrong value for f2 (found %f, expected %f)\n",
             TestName, v[0], 10.0);
      piglit_report_result(PIGLIT_FAIL);
   }

   glGetUniformfv(prog, loc_sa, v);
   if (v[0] != 15.0) {
      printf("%s: wrong value for s.a (found %f, expected %f)\n",
             TestName, v[0], 15.0);
      piglit_report_result(PIGLIT_FAIL);
   }

   glGetUniformfv(prog, loc_sd, v);
   if (v[0] != 20.0) {
      printf("%s: wrong value for s.d (found %f, expected %f)\n",
             TestName, v[0], 20.0);
      piglit_report_result(PIGLIT_FAIL);
   }

   glGetUniformfv(prog, loc_v1, v);
   if (v[0] != 30.0 ||
       v[1] != 31.0 ||
       v[2] != 32.0 ||
       v[3] != 33.0) {
      printf("%s: wrong value for v[1] (found %g,%g,%g,%g, expected %g,%g,%g,%g)\n",
             TestName, v[0], v[1], v[2], v[3], 30.0, 31.0, 32.0, 33.0);
      piglit_report_result(PIGLIT_FAIL);
   }

   piglit_report_result(PIGLIT_PASS);
}
예제 #26
0
void
piglit_init(int argc, char **argv)
{
	GLint vs, fs, gs, tes, tcs;
	GLuint pipe;
	GLint prog_vs, prog_fs, prog_gs, prog_tcs, prog_tes, prog_tess;
	GLint prog_vs_fs, prog_vs_gs;
	GLint separable;
	int version;

	char *vs_source, *fs_source, *gs_source, *te_source, *tc_source;

	const bool has_tess = piglit_get_gl_version() >= 40
		|| piglit_is_extension_supported("GL_ARB_tessellation_shader");
	const bool has_geo =
		piglit_get_gl_version() >= 32;

	piglit_require_extension("GL_ARB_separate_shader_objects");

	if (piglit_get_gl_version() >= 40)
		version = 400;
	else if (piglit_get_gl_version() >= 32)
		version = 150;
	else
		version = 120;

	pass = true;

	/* create the shader program */
	asprintf(&vs_source, vs_source_template, version);
	asprintf(&fs_source, fs_source_template, version);
	asprintf(&gs_source, gs_source_template, version);
	asprintf(&te_source, te_source_template, version);
	asprintf(&tc_source, tc_source_template, version);

	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
	pass = (fs != 0) && (vs != 0) && pass;
	if (has_geo) {
		gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gs_source);
		pass = (gs != 0) && pass;
	}
	if (has_tess) {
		tes = piglit_compile_shader_text(GL_TESS_EVALUATION_SHADER,
						 te_source);
		tcs = piglit_compile_shader_text(GL_TESS_CONTROL_SHADER,
						 tc_source);
		pass = (tes != 0) && (tcs != 0) && pass;
	}

	free(vs_source);
	free(fs_source);
	free(gs_source);
	free(te_source);
	free(tc_source);

	prog_vs = create_prog(vs, 0);
	prog_fs = create_prog(fs, 0);
	prog_vs_fs = create_prog(vs, fs);
	if (has_geo) {
		prog_gs = create_prog(gs, 0);
		prog_vs_gs = create_prog(vs, gs);
	}
	if (has_tess) {
		prog_tcs = create_prog(tcs, 0);
		prog_tes = create_prog(tes, 0);
		prog_tess = create_prog(tcs, tes);
	}

	/* Setup or compilation failure. Stop here */
	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	if (!pass) {
		piglit_report_result(PIGLIT_FAIL);
		return;
	}

	if (!piglit_automatic) {
		if (has_tess && has_geo) {
			printf("INFO: ALL stages supported: running all "
			       "test\n");
		} else {
			if (!has_tess)
				printf("INFO: GL_ARB_tessellation_shader / "
				       "OpenGL 4.0 not supported: tesselation "
				       "test disabled\n");
			if (!has_geo)
				printf("INFO: OpenGL 3.2 not "
				       "supported: geometry test disabled\n");
		}
	}

	/* Create the pipeline */
	glGenProgramPipelines(1, &pipe);

	build_and_validate_pipe(pipe, true, 
				"VS/FS program, single glUseProgramStages "
				"call",
				GL_ALL_SHADER_BITS, prog_vs_fs,
				0, 0,
				0, 0,
				0, 0,
				0, 0);

	build_and_validate_pipe(pipe, true, 
				"VS/FS program, multiple glUseProgramStages "
				"calls",
				GL_FRAGMENT_SHADER_BIT, prog_vs_fs,
				GL_VERTEX_SHADER_BIT, prog_vs_fs,
				0, 0,
				0, 0,
				0, 0);

	build_and_validate_pipe(pipe, true, 
				"program per pipeline stage",
				GL_VERTEX_SHADER_BIT, prog_vs,
				GL_FRAGMENT_SHADER_BIT, prog_fs,
				(has_geo) ? GL_GEOMETRY_SHADER_BIT : 0,
				prog_gs,
				(has_tess) ? GL_TESS_CONTROL_SHADER_BIT : 0,
				prog_tcs,
				(has_tess) ? GL_TESS_EVALUATION_SHADER_BIT : 0,
				prog_tes);

	/* Section 2.11.11 (Shader Execution), subpart "Validation" of the
	 * OpenGL 4.1 spec says:
	 *
	 *     "If the current set of active program objects cannot be
	 *     executed, no primitives are processed and the error
	 *     INVALID_OPERATION will be generated.  This error is generated
	 *     by any command that transfers vertices to the GL if:
	 *
	 *     ...
	 *
	 *     - One program object is active for at least two shader stages
	 *       and a second program is active for a shader stage between two
	 *       stages for which the first program was active."
	 */
	if (has_geo)
		build_and_validate_pipe(pipe, false, 
					"GS splitting a VS/FS pipeline",
					GL_ALL_SHADER_BITS, prog_vs_fs,
					GL_GEOMETRY_SHADER_BIT, prog_gs,
					0, 0,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP,
					     "GS splitting a VS/FS pipeline");

	if (has_tess)
		build_and_validate_pipe(pipe, false, 
					"TCS splitting a VS/GS pipeline",
					GL_ALL_SHADER_BITS, prog_vs_gs,
					GL_TESS_CONTROL_SHADER_BIT, prog_tcs,
					0, 0,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP,
					     "TCS splitting a VS/GS pipeline");

	if (has_tess)
		build_and_validate_pipe(pipe, false, 
					"TES splitting a VS/GS program",
					GL_ALL_SHADER_BITS, prog_vs_gs,
					GL_FRAGMENT_SHADER_BIT, prog_fs,
					GL_TESS_EVALUATION_SHADER_BIT, prog_tes,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP,
					     "TES splitting a VS/GS program");

	/* Section 2.11.11 (Shader Execution), subpart "Validation" of the
	 * OpenGL 4.1 spec says:
	 *
	 *     "If the current set of active program objects cannot be
	 *     executed, no primitives are processed and the error
	 *     INVALID_OPERATION will be generated.  This error is generated
	 *     by any command that transfers vertices to the GL if:
	 *
	 *     ...
	 *
	 *     - There is an active program for tessellation control,
	 *       tessellation evaluation, or geometry stages with
	 *       corresponding executable shader, but there is no active
	 *       program with executable vertex shader."
	 */
	if (has_geo)
		build_and_validate_pipe(pipe, false, 
					"GS without VS",
					GL_FRAGMENT_SHADER_BIT, prog_fs,
					GL_GEOMETRY_SHADER_BIT, prog_gs,
					0, 0,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP, "GS without VS");

	if (has_tess)
		build_and_validate_pipe(pipe, false, 
					"TES/TCS without VS",
					GL_ALL_SHADER_BITS, prog_tess,
					GL_FRAGMENT_SHADER_BIT, prog_fs,
					0, 0,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP, "TES/TCS without VS");

	/* Section 2.11.11 (Shader Execution), subpart "Validation" of the
	 * OpenGL 4.1 spec says:
	 *
	 *     "If the current set of active program objects cannot be
	 *     executed, no primitives are processed and the error
	 *     INVALID_OPERATION will be generated.  This error is generated
	 *     by any command that transfers vertices to the GL if:
	 *
	 *     - A program object is active for at least one, but not all of
	 *       the shader stages that were present when the program was
	 *       linked."
	 */
	build_and_validate_pipe(pipe, false, 
				"Only VS from a VS/FS program",
				GL_FRAGMENT_SHADER_BIT, prog_fs,
				GL_VERTEX_SHADER_BIT, prog_vs_fs,
				0, 0,
				0, 0,
				0, 0);

	if (has_geo)
		build_and_validate_pipe(pipe, false, 
					"Only GS from a VS/GS program",
					GL_FRAGMENT_SHADER_BIT, prog_fs,
					GL_GEOMETRY_SHADER_BIT, prog_vs_gs,
					GL_VERTEX_SHADER_BIT, prog_vs,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP,
					     "Only GS from a VS/GS program");

	if (has_tess)
		build_and_validate_pipe(pipe, false, 
					"Only TES from TES/TCS program",
					GL_FRAGMENT_SHADER_BIT, prog_fs,
					GL_TESS_EVALUATION_SHADER_BIT, prog_tess,
					GL_VERTEX_SHADER_BIT, prog_vs,
					0, 0,
					0, 0);
	else
		piglit_report_subtest_result(PIGLIT_SKIP,
					     "Only TES from TES/TCS program");

	/* Section 2.11.11 (Shader Execution), subpart "Validation" of the
	 * OpenGL 4.1 spec says:
	 *
	 *     "If the current set of active program objects cannot be
	 *     executed, no primitives are processed and the error
	 *     INVALID_OPERATION will be generated.  This error is generated
	 *     by any command that transfers vertices to the GL if:
	 *
	 *     ...
	 *
	 *     - There is no current unified program object and the current
	 *       program pipeline object includes a program object that was
	 *       relinked since being applied to the pipeline object via
	 *       UseProgramStages with the PROGRAM_SEPARABLE parameter set to
	 *       FALSE."
	 */
	build_and_validate_pipe(pipe, true, 
				"Relink attached VS without "
				"GL_PROGRAM_SEPARABLE (sanity pre-test)",
				GL_FRAGMENT_SHADER_BIT, prog_fs,
				GL_VERTEX_SHADER_BIT, prog_vs,
				0, 0,
				0, 0,
				0, 0);

	glGetProgramiv(prog_vs, GL_PROGRAM_SEPARABLE, &separable);
	if (!separable) {
		printf("Error: %d was not a separable program\n", prog_vs);
		pass = false;
	}

	glProgramParameteri(prog_vs, GL_PROGRAM_SEPARABLE, GL_FALSE);

	glGetProgramiv(prog_vs, GL_PROGRAM_SEPARABLE, &separable);

	/* NOTE: This check /may/ need to be moved after the call to
	 * glLinkProgram.  There has been some discussion as to whether this
	 * is supposed to be "latched" state.
	 */
	if (separable) {
		printf("Error: fail to remove separable flags of program %d\n",
		       prog_vs);
		pass = false;
	}

	glLinkProgram(prog_vs);
	pass = piglit_link_check_status(prog_vs) && pass;
	validate_pipe(pipe, GL_FALSE,
		      "Relink attached VS without GL_PROGRAM_SEPARABLE");

	piglit_present_results();

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}
예제 #27
0
static enum piglit_result
test(void)
{
	static const GLfloat dest_color[4] = { 0.75, 0.25, 0.25, 0.5 };
	static const GLfloat test_color[4] = { 1.0, 0.25, 0.75, 0.25 };
	static const GLfloat test_color1[4] = { 0.5, 0.5, 0.5, 0.5 };
	GLfloat expected[4];
	GLuint prog;
	GLuint vs;
	GLuint fs;
	int i, j, k, o;

	if (max_ds_buffers > 1) {
		printf("Test only supports 1 dual source blending color buffer\n");
		max_ds_buffers = 1;
	}

	prog = glCreateProgram();
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);

	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
	glAttachShader(prog, vs);
	glAttachShader(prog, fs);
	piglit_check_gl_error(GL_NO_ERROR);

	glBindFragDataLocationIndexed(prog, 0, 0, "col0");
	glBindFragDataLocationIndexed(prog, 0, 1, "col1");

	create_fbo();

	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

	glLinkProgram(prog);
	glUseProgram(prog);

	uniform_src0 = glGetUniformLocation(prog, "src0");
	uniform_src1 = glGetUniformLocation(prog, "src1");

	/* Setup blend modes and compute expected result color.
	 * We only test two simple blending modes.  A more elaborate
	 * test would exercise a much wider variety of modes.
	 */

	for (o = 0; o < ARRAY_SIZE(operators); o++) {
		for (i = 0; i < ARRAY_SIZE(srcFactors); i++) {
			for (j = 0; j < ARRAY_SIZE(dstFactors); j++) {
				blend_expected(expected, test_color, test_color1,
					       dest_color, srcFactors[i],
					       dstFactors[j], operators[o]);

				blend(test_color, test_color1, dest_color,
				      srcFactors[i], dstFactors[j],
				      operators[o]);
				for (k = 0; k < max_ds_buffers; k++) {
					glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + k);
					check_error(__LINE__);

					if (!piglit_probe_pixel_rgba(5, 5, expected)) {
						printf("For src/dst %d %d %d\n", i, j, o);
						return PIGLIT_FAIL;
					}
				}
			}
		}
	}
	return PIGLIT_PASS;
}
예제 #28
0
static void
generate_and_display_drawbuffers(int count)
{
	GLuint tex[16], fb, fs, vs, prog;
	GLenum attachments[16], status;
	int i;
	char fs_output_line[256];
	char fs_full_source[1024];

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	for (i = 0; i < count; i++) {
		tex[i] = attach_texture(i);
		attachments[i] = GL_COLOR_ATTACHMENT0 + i;
	}

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
		fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status);
		piglit_report_result(PIGLIT_SKIP);
	}

	glDrawBuffersARB(count, attachments);

	/* Clear all to 0.25 so we see if the shader rendering happens. */
	glClearColor(clear_value, clear_value, clear_value, clear_value);
	glClear(GL_COLOR_BUFFER_BIT);

	/* Build the shader that spams green to all outputs. */
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);

	strcpy(fs_full_source, fs_source_start);
		
	for (i = 0; i < count; i++) {
		sprintf(fs_output_line, fs_source_output, i, output_values[i * 4], 
				output_values[(i * 4) + 1], output_values[(i * 4) + 2], 
				output_values[(i * 4) + 3]);
		
		strcat(fs_full_source, fs_output_line);
	}
	
	strcat(fs_full_source, fs_source_end);

	assert(strlen(fs_full_source) + 1 < sizeof(fs_full_source) / sizeof(fs_full_source[0]));
	
	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_full_source);

	prog = piglit_link_simple_program(vs, fs);
	glUseProgram(prog);

	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);
	glBlendEquation(GL_FUNC_ADD);

	/* Now render to all the color buffers. */
	piglit_draw_rect(-1, -1, 2, 2);

	glDisable(GL_BLEND);
	
	/* OK, now draw each of these textures to the winsys framebuffer. */
	glUseProgram(0);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_TEXTURE_2D);
	for (i = 0; i < count; i++) {
		glBindTexture(GL_TEXTURE_2D, tex[i]);
		piglit_draw_rect_tex(16 * i, 16 * (count - 1),
					 16, 16,
					 0, 0,
					 1, 1);
	}
	glDisable(GL_TEXTURE_2D);

	for (i = 0; i < count; i++) {
		glDeleteTextures(1, &tex[i]);
	}
	glDeleteFramebuffersEXT(1, &fb);
}
예제 #29
0
void
piglit_init(int argc, char **argv)
{
	GLuint tex, fb;
	GLenum status;
	int i, dim;
	GLuint fs, prog, loc_tex;

        for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "-inplace") == 0)
			in_place_probing = GL_TRUE;
		else if (strcmp(argv[i], "-nobias") == 0)
			no_bias = GL_TRUE;
		else if (strcmp(argv[i], "-nolod") == 0)
			no_lod = GL_TRUE;
		else if (strcmp(argv[i], "-GL_ARB_shader_texture_lod") == 0)
			ARB_shader_texture_lod = GL_TRUE;
        }

	piglit_require_extension("GL_EXT_framebuffer_object");
	if (piglit_get_gl_version() < 14)
		piglit_report_result(PIGLIT_SKIP);

	if (ARB_shader_texture_lod) {
		piglit_require_GLSL();
		piglit_require_extension("GL_ARB_shader_texture_lod");

		fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fscode);
		prog = piglit_link_simple_program(0, fs);
		glUseProgram(prog);
		loc_tex = glGetUniformLocation(prog, "tex");
		loc_lod = glGetUniformLocation(prog, "lod");
		glUniform1i(loc_tex, 0);

		puts("Testing GL_ARB_shader_texture_lod.");
	}

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);

	for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) {
		glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA,
			     dim, dim,
			     0,
			     GL_RGBA, GL_UNSIGNED_BYTE, NULL);
	}
	assert(glGetError() == 0);

	glBindTexture(GL_TEXTURE_2D, 0);
	glDisable(GL_TEXTURE_2D);

	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);

	for (i = 0, dim = TEX_WIDTH; dim >0; i++, dim /= 2) {
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
					  GL_COLOR_ATTACHMENT0_EXT,
					  GL_TEXTURE_2D,
					  tex,
					  i);


		status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
		if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
			fprintf(stderr, "FBO incomplete\n");
			piglit_report_result(PIGLIT_SKIP);
		}

		glClearColor(colors[i][0],
			     colors[i][1],
			     colors[i][2],
			     0.0);
		glClear(GL_COLOR_BUFFER_BIT);

		assert(glGetError() == 0);
	}

	glDeleteFramebuffersEXT(1, &fb);
	glBindTexture(GL_TEXTURE_2D, tex);

	glViewport(0, 0, piglit_width, piglit_height);

	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);

	glEnable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
void
piglit_init(int argc, char **argv)
{
	bool pass = true;
	GLuint vs = 0, gs = 0;
	int i;

	prog = glCreateProgram();
	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vstext);
	gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gstext);
	glAttachShader(prog, vs);
	glAttachShader(prog, gs);

	/* check that invalid_varying_names fail to link */
	for (i = 0; i < ARRAY_SIZE(invalid_varying_names); i++) {
		glTransformFeedbackVaryings(prog,
					    1,
					    &invalid_varying_names[i],
					    GL_INTERLEAVED_ATTRIBS);
		glLinkProgram(prog);
		if (piglit_link_check_status_quiet(prog)) {
			printf("%s is not valid but it was allowed.\n",
				invalid_varying_names[i]);
			pass = false;
		}
	}

	/* check that valid_varying_names link properly */
	glTransformFeedbackVaryings(prog,
				    ARRAY_SIZE(valid_varying_names),
				    valid_varying_names,
				    GL_INTERLEAVED_ATTRIBS);
	glLinkProgram(prog);
	if (!piglit_link_check_status(prog)) {
		glDeleteProgram(prog);
		printf("Transform feedback varyings failed to link properly"
			" with valid names.\n");
		piglit_report_result(PIGLIT_FAIL);
	}

	glUseProgram(prog);

	for (i = 0; i < ARRAY_SIZE(valid_varying_names); i++) {
		char varName[50];
		GLsizei nameLength = 0, varSize = 0;
		GLenum varType = GL_NONE;
		glGetTransformFeedbackVarying(  prog,
						i,
						sizeof(varName),
						&nameLength,
						&varSize,
						&varType,
						varName);
		printf("Name: %s\t\tType: %s\n",
			varName, piglit_get_gl_enum_name(varType));
	}

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
}