Esempio n. 1
0
/**
 * Test glBegin(GL_TRIANGLE/LINE_STRIP), glPrimitiveRestartNV(), glEnd().
 */
static bool
test_begin_end(GLenum primMode)
{
   const GLfloat x0 = 0.0, x1 = piglit_width - 10.0, dx = 20.0;
   const GLfloat y0 = 0.5 * piglit_height - 10.0, y1 = y0 + 20.0, dy = 20.0;
   GLfloat x, y;
   GLint vert;
   bool pass;

   piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

   glClear(GL_COLOR_BUFFER_BIT);

   glColor4fv(green);

   if (primMode == GL_TRIANGLE_STRIP) {
      /* Draw a tri-strip across the window, using restart to actually render
       * a series of quads/boxes.
       */
      glBegin(GL_TRIANGLE_STRIP);
      vert = 0;
      for (x = x0; x <= x1; x += dx) {
         for (y = y0; y <= y1; y += dy) {
            glVertex2f(x, y);
         }

         vert++;
         if (vert % 2 == 0)
            glPrimitiveRestartNV();
      }
      glEnd();
   }
   else {
      /* Draw a line strip across the window, using restart to actually render
       * a series of disconnected lines.
       */
      glLineWidth(5.0);
      glBegin(GL_LINE_STRIP);
      vert = 0;
      for (x = x0; x <= x1; x += dx) {
         y = 0.5 * piglit_height;

         glVertex2f(x, y);

         vert++;
         if (vert % 2 == 0)
            glPrimitiveRestartNV();
      }
      glEnd();
   }

   glFinish();

   pass = check_rendering();
   if (!pass) {
      fprintf(stderr, "%s: failure drawing with glBegin(%s) / glEnd()\n",
              TestName,
              (primMode == GL_TRIANGLE_STRIP
               ? "GL_TRIANGLE_STRIP" : "GL_LINE_STRIP"));
   }

   piglit_present_results();

   return pass;
}
Esempio n. 2
0
/**
 * Test glDrawElements() with glPrimitiveRestartIndexNV().
 */
static bool
test_draw_by_index(VBO_CFG vbo_cfg, bool one_by_one, GLenum primMode, GLenum indexType)
{
#define NUM_VERTS 48
#define NUM_ELEMS (NUM_VERTS * 5 / 4)
   GLfloat verts[NUM_VERTS+2][2];
   GLubyte indices[sizeof(GLuint) * NUM_ELEMS];
   GLfloat x, dx;
   GLuint restart_index;
   GLuint num_elems;
   bool pass = true;
   const char *typeStr = NULL, *primStr = NULL;
   GLuint vbo1, vbo2;
   bool create_vbo1 = false;
   bool create_vbo2 = false;
   uintptr_t index_offset = 0;
   uintptr_t vbo_data_size = sizeof(verts) + sizeof(indices);
   GLuint i, j;

   if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_INDEX_ONLY)) {
      create_vbo1 = true;
   }

   if ((vbo_cfg == VBO_INDEX_ONLY) || (vbo_cfg == VBO_SEPARATE_VERTEX_AND_INDEX)) {
      create_vbo2 = true;
   }

   if ((vbo_cfg == DISABLE_VBO) || (vbo_cfg == VBO_VERTEX_ONLY)) {
      index_offset = (uintptr_t) indices;
   } else if (vbo_cfg == VBO_COMBINED_VERTEX_AND_INDEX) {
      index_offset = sizeof(verts);
   } else {
      index_offset = 0;
   }

   switch (indexType) {
   case GL_UNSIGNED_BYTE:
      restart_index = 255;
      typeStr = "GL_UNSIGNED_BYTE";
      break;
   case GL_UNSIGNED_SHORT:
      restart_index = 1000;
      typeStr = "GL_UNSIGNED_SHORT";
      break;
   case GL_UNSIGNED_INT:
      restart_index = 1000 * 1000;
      typeStr = "GL_UNSIGNED_INT";
      break;
   default:
      assert(0);
      restart_index = 0;
   }

   x = 0.0;
   dx = 20.0;

   if (primMode == GL_TRIANGLE_STRIP) {
      const GLfloat y = 0.5 * piglit_height - 10.0, dy = 20.0;
      for (i = 0; i < NUM_VERTS / 2; i++) {
         verts[i*2+0][0] = x;
         verts[i*2+0][1] = y;
         verts[i*2+1][0] = x;
         verts[i*2+1][1] = y + dy;
         x += dx;
      }

      /* setup elements to draw series of squares w/ tri strip */
      for (i = j = 0; i < NUM_VERTS; i++) {
         write_index_value(indices, indexType, j, i);
         j++;
         if (i > 0 && i % 4 == 3) {
            write_index_value(indices, indexType, j, restart_index);
            j++;
         }
      }

      num_elems = j;
      primStr = "GL_TRIANGLE_STRIP";
   }
   else {
      const GLfloat y = 0.5 * piglit_height;

      assert(primMode == GL_LINE_STRIP);

      glLineWidth(5.0);

      for (i = 0; i < NUM_VERTS; i++) {
         verts[i][0] = x;
         verts[i][1] = y;
         x += dx;
      }

      /* setup elements to draw series of disjoint lines w/ line strip */
      for (i = j = 0; i < NUM_VERTS / 2; i++) {
         write_index_value(indices, indexType, j, i);
         j++;
         if (i > 0 && i % 2 == 1) {
            write_index_value(indices, indexType, j, restart_index);
            j++;
         }
      }

      num_elems = j;
      primStr = "GL_LINE_STRIP";
   }

   assert(num_elems <= NUM_ELEMS);

   /* debug */
   if (0) {
      for (i = 0; i < num_elems; i++)
         printf("%2d: %d\n", i, read_index_value(indices, indexType, i));
   }

   piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);

   glClear(GL_COLOR_BUFFER_BIT);

   glColor4fv(green);

   if (create_vbo1) {
      glGenBuffers(1, &vbo1);
      glBindBuffer(GL_ARRAY_BUFFER, vbo1);
      glBufferData(GL_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW);
   }

   if (create_vbo2) {
      glGenBuffers(1, &vbo2);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, vbo_data_size, NULL, GL_STATIC_DRAW);
   } else {
      vbo2 = vbo1;
   }

   if (create_vbo1) {
      /* Load vertex data into VBO */
      glBindBuffer(GL_ARRAY_BUFFER, vbo1);
      glBufferSubData(GL_ARRAY_BUFFER,
                      0, sizeof(verts),
                      verts);
      glVertexPointer(2, GL_FLOAT, 0, (void *)0);
   } else {
      glVertexPointer(2, GL_FLOAT, 0, (void *)verts);
   }

   if ((vbo_cfg != DISABLE_VBO) && (vbo_cfg != VBO_VERTEX_ONLY)) {
      /* Load index data into VBO */
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo2);
      glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                      index_offset, type_array_size(indexType, num_elems),
                      indices);
   }

   glEnableClientState(GL_VERTEX_ARRAY);
   pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

   enable_restart(restart_index);

   /* Draw */
   if (one_by_one) {
      do_ArrayElement(primMode, num_elems, indexType, indices);
   } else {
      glDrawElements(primMode, num_elems, indexType, (void*) index_offset);
   }

   disable_restart();

   glDisableClientState(GL_VERTEX_ARRAY);

   if (vbo_cfg != DISABLE_VBO) {
      glBindBuffer(GL_ARRAY_BUFFER, 0);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
   }

   if (create_vbo1) {
      glDeleteBuffers(1, &vbo1);
   }

   if (create_vbo2) {
      glDeleteBuffers(1, &vbo2);
   }

   if (!check_rendering()) {
      fprintf(stderr, "%s: failure drawing with %s(%s, %s), %s\n",
              TestName,
              one_by_one ? "glArrayElement" : "glDrawElements",
              primStr, typeStr,
              vbo_cfg_names[vbo_cfg]);
      pass = false;
   }

   piglit_present_results();

   return pass;
#undef NUM_VERTS
}
Esempio n. 3
0
static bool
test_format(int width, int height, GLfloat *image, GLenum requested_format)
{
	GLubyte *compressed_image;
	GLenum format2;
	int x, y, w, h;
	GLuint tex;
	bool pass = true;
	GLuint expected_size;
	GLint is_compressed;
	GLint compressed_size;
	GLint format;

	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
	glPixelStorei(GL_UNPACK_ROW_LENGTH, width);

	/* Setup initial texture */
	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, requested_format, width, height, 0,
		     GL_RGBA, GL_FLOAT, image);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	pass = check_rendering(width, height) && pass;

	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED,
				 &is_compressed);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT,
				 &format);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
				 &compressed_size);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	if (!is_compressed) {
		printf("Image was not compressed\n");
		pass = false;
	}

	if (format != requested_format) {
		printf("Internal Format mismatch. Found: 0x%04x Expected: 0x%04x\n",
		       format, requested_format);
		pass = false;
	}

	expected_size = piglit_compressed_image_size(requested_format, width,
			height);

	if (compressed_size != expected_size) {
		printf("Compressed image size mismatch. Found: %u Expected: %u\n",
		       compressed_size, expected_size);
		pass = false;
	}

	/* Use GL_TEXTURE_COMPRESSED_IMAGE_SIZE even if it wasn't what we
	 * expected to avoid corruption due to under-allocated buffer.
	 */
	compressed_image = malloc(compressed_size);

	/* Read back the compressed image data */
	glGetCompressedTexImage(GL_TEXTURE_2D, 0, compressed_image);

	/* Try texsubimage on 4-texel boundary - should work */
	x = 20;
	y = 12;
	w = 16;
	h = 8;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glTexSubImage2D(GL_TEXTURE_2D, 0,
			x, y, w, h,
			GL_RGBA, GL_FLOAT, image);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	pass = check_rendering(width, height) && pass;

	/* Try texsubimage on non 4-texel boundary - should not work */
	x = 10;
	y = 11;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glTexSubImage2D(GL_TEXTURE_2D, 0,
			x, y, w, h,
			GL_RGBA, GL_FLOAT, image);

	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	/* Try compressed subimage on 4-texel boundary - should work */
	x = 12;
	y = 8;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, x, y));

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	pass = check_rendering(width, height) && pass;

	/* Try compressed subimage on non 4-texel boundary - should not work */
	x = 14;
	y = 9;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, 0, 0));

	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	/* Try compressed subimage with size not a multiple of 4 -
	 * should not work
	 */
	x = 8;
	y = 8;
	w = 14;
	h = 10;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, 4, 4),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, x, y));
	/* Note, we can get either of these errors depending on the order
	 * in which glCompressedTexSubImage parameters are checked.
	 * INVALID_OPERATION for the bad size or INVALID_VALUE for the
	 * wrong compressed image size.
	 */
	pass = check_gl_error2(GL_INVALID_OPERATION, GL_INVALID_VALUE) && pass;

	/* Try compressed subimage with invalid offset - should not work */
	x = -3;
	y = 8;
	w = 4;
	h = 4;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, 0, 0));

	pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;

	/* Try compressed subimage with too large of image - should not work */
	x = 16;
	y = 8;
	w = width * 2;
	h = height * 2;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, x, y));

	pass = piglit_check_gl_error(GL_INVALID_VALUE) && pass;

	/* Try compressed subimage with different format - should not work */
	if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
		format2 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
	else
		format2 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
	x = 4;
	y = 4;
	w = 4;
	h = 4;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format2,
				  piglit_compressed_image_size(format2, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format2, width, x, y));

	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	/* Try zero-sized subimage - should not be an error */
	x = 4;
	y = 4;
	w = 0;
	h = 0;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 0,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, x, y));

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;


	/* Try CompressedTexSubImage into level 1 (which is missing) */
	x = 0;
	y = 0;
	w = 4;
	h = 4;
	glPixelStorei(GL_UNPACK_SKIP_PIXELS, x);
	glPixelStorei(GL_UNPACK_SKIP_ROWS, y);
	glCompressedTexSubImage2D(GL_TEXTURE_2D, 1,
				  x, y, w, h,
				  format,
				  piglit_compressed_image_size(format, w, h),
				  compressed_image +
				  piglit_compressed_pixel_offset(format, width, x, y));

	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;

	/* Try CompressedTexImage of size zero - should not be an erorr */
	w = 0;
	h = 0;
	glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
			       piglit_compressed_image_size(format, w, h),
			       compressed_image);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;

	/* Try CompressedTexImage with size which is a not a multiple of the
         * block size - should not be an erorr
         */
	w = width - 1;
	h = height - 1;
	glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0,
			       piglit_compressed_image_size(format, w, h),
			       compressed_image);

	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
	pass = check_rendering(width, height) && pass;

	glDeleteTextures(1, &tex);

	free(compressed_image);

	return pass;
}