summaryrefslogtreecommitdiff
path: root/tests/bugs
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-11-24 18:27:14 +0100
committerMarek Olšák <maraeo@gmail.com>2010-11-24 18:32:58 +0100
commit5b11a9bcc5df6a948b2f0f214f1c4b3dc4a9b72f (patch)
treee51c92fcbfea7cf1e3e1aa4e50b507d3dcaf8403 /tests/bugs
parenta5b8fc11770c2d782d17f6921254eaf5bd8ab960 (diff)
r300-hiz-bug: new test for a HiZ bug that's currently in r300g
Diffstat (limited to 'tests/bugs')
-rw-r--r--tests/bugs/CMakeLists.txt1
-rw-r--r--tests/bugs/r300-hiz-bug.c243
2 files changed, 244 insertions, 0 deletions
diff --git a/tests/bugs/CMakeLists.txt b/tests/bugs/CMakeLists.txt
index 2757d59e0..b6908f8dc 100644
--- a/tests/bugs/CMakeLists.txt
+++ b/tests/bugs/CMakeLists.txt
@@ -26,6 +26,7 @@ add_executable (fdo9833 fdo9833.c)
add_executable (fdo10370 fdo10370.c)
add_executable (fdo14575 fdo14575.c)
add_executable (r300-readcache r300-readcache.c)
+add_executable (r300-hiz-bug r300-hiz-bug.c)
add_executable (tex1d-2dborder tex1d-2dborder.c)
add_executable (fdo20701 fdo20701.c)
add_executable (point-sprite point-sprite.c)
diff --git a/tests/bugs/r300-hiz-bug.c b/tests/bugs/r300-hiz-bug.c
new file mode 100644
index 000000000..cb7c44feb
--- /dev/null
+++ b/tests/bugs/r300-hiz-bug.c
@@ -0,0 +1,243 @@
+/*
+ * Copyright © 2010 Marek Olšák <maraeo@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Marek Olšák <maraeo@gmail.com>
+ *
+ */
+
+/** @file r300-hiz-bug.c
+ *
+ * Tests that two overlapping triangles are rendered correctly.
+ */
+
+#include "piglit-util.h"
+#include "piglit-framework.h"
+
+int piglit_width = 400; /* Do not change the size! */
+int piglit_height = 400;
+int piglit_window_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;
+
+/* approximately 1-pixel tolerance on edges */
+static float dist_eps = 1.0f / 400;
+
+enum {
+ INSIDE,
+ EDGE,
+ OUTSIDE
+};
+
+int tri_point_intersect_2d(const float v0[2],
+ const float v1[2],
+ const float v2[2],
+ const float p[2])
+{
+ float n0[2];
+ float n1[2];
+ float n2[3];
+ float l0, l1, l2;
+ float c0, c1, c2;
+ float d0, d1, d2;
+
+ /* compute edge normals */
+ n0[0] = v1[1] - v0[1];
+ n0[1] = v0[0] - v1[0];
+
+ n1[0] = v2[1] - v1[1];
+ n1[1] = v1[0] - v2[0];
+
+ n2[0] = v0[1] - v2[1];
+ n2[1] = v2[0] - v0[0];
+
+ /* compute inverse lengths of the normals */
+ l0 = 1 / sqrt(n0[0]*n0[0] + n0[1]*n0[1]);
+ l1 = 1 / sqrt(n1[0]*n1[0] + n1[1]*n1[1]);
+ l2 = 1 / sqrt(n2[0]*n2[0] + n2[1]*n2[1]);
+
+ /* normalize the normals */
+ n0[0] *= l0;
+ n0[1] *= l0;
+ n1[0] *= l1;
+ n1[1] *= l1;
+ n2[0] *= l2;
+ n2[1] *= l2;
+
+ /* compute negative dot products between normals and vertices
+ * to get ray equations in the form nx*x + ny*y + c = 0. */
+ c0 = - n0[0]*v0[0] - n0[1]*v0[1];
+ c1 = - n1[0]*v1[0] - n1[1]*v1[1];
+ c2 = - n2[0]*v2[0] - n2[1]*v2[1];
+
+ /* compute the distances between the point and the edges. */
+ d0 = n0[0]*p[0] + n0[1]*p[1] + c0;
+ d1 = n1[0]*p[0] + n1[1]*p[1] + c1;
+ d2 = n2[0]*p[0] + n2[1]*p[1] + c2;
+
+ /* the point is inside the triangle */
+ if (d0 < -dist_eps && d1 < -dist_eps && d2 < -dist_eps) {
+ return INSIDE;
+ }
+
+ /* the point is outside the triangle */
+ if (d0 > dist_eps || d1 > dist_eps || d2 > dist_eps) {
+ return OUTSIDE;
+ }
+
+ return EDGE;
+}
+
+GLboolean pix_equal(int x, int y, const float probe[3], const float expected[3])
+{
+ int i;
+ GLboolean ret = GL_TRUE;
+
+ for (i = 0; i < 3; i++) {
+ if (fabs(probe[i] - expected[i]) > 0.01) {
+ ret = GL_FALSE;
+ break;
+ }
+ }
+
+ if (!ret) {
+ printf("Probe at (%i,%i)\n", x, y);
+ printf(" Expected: %f %f %f\n", expected[0], expected[1], expected[2]);
+ printf(" Observed: %f %f %f\n", probe[0], probe[1], probe[2]);
+ }
+ return ret;
+}
+
+enum piglit_result piglit_display()
+{
+ const float bg[3] = {0.3, 0.3, 0.3};
+ const float c1[3] = {1.0, 0.3, 0.3};
+ const float v11[3] = {0.1, 0.9, -1.0};
+ const float v12[3] = {0.1, 0.1, -1.0};
+ const float v13[3] = {0.9, 0.5, 1.0};
+ const float c2[3] = {0.0, 1.0, 1.0};
+ const float v21[3] = {0.9, 0.9, 0.0};
+ const float v22[3] = {0.1, 0.5, 0.0};
+ const float v23[3] = {0.9, 0.1, 0.0};
+ float *pix;
+ int res = PIGLIT_SUCCESS;
+ int i,j;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glBegin (GL_TRIANGLES);
+ glColor3fv(c1);
+ glVertex3fv(v11);
+ glVertex3fv(v12);
+ glVertex3fv(v13);
+ glEnd();
+
+ glBegin (GL_TRIANGLES);
+ glColor3fv(c2);
+ glVertex3fv(v21);
+ glVertex3fv(v22);
+ glVertex3fv(v23);
+ glEnd();
+
+ glFlush();
+
+ pix = malloc(piglit_width * piglit_height * 12);
+ glReadPixels(0, 0, piglit_width, piglit_height, GL_RGB, GL_FLOAT, pix);
+
+ /* check pixels */
+ for (j = 0; j < piglit_height; j++) {
+ for (i = 0; i < piglit_width; i++) {
+ float *px = &pix[(j*piglit_width + i) * 3];
+ float p[2];
+ int t1_intersect, t2_intersect;
+
+ p[0] = i / (float)(piglit_width-1);
+ p[1] = j / (float)(piglit_height-1);
+
+ t1_intersect = tri_point_intersect_2d(v11, v12, v13, p);
+ t2_intersect = tri_point_intersect_2d(v21, v22, v23, p);
+
+ if (t1_intersect == EDGE || t2_intersect == EDGE) {
+ //printf(" ");
+ continue;
+ }
+
+ if (t1_intersect == INSIDE) {
+ if (t2_intersect == INSIDE) {
+ if (fabs(p[0] - 0.5) < dist_eps) {
+ //printf(" ");
+ continue;
+ }
+ if (p[0] < 0.5) {
+ //printf("2");
+ if (!pix_equal(i, j, px, c2))
+ res = PIGLIT_FAILURE;
+ } else {
+ //printf("1");
+ if (!pix_equal(i, j, px, c1))
+ res = PIGLIT_FAILURE;
+ }
+ } else {
+ //printf("1");
+ if (!pix_equal(i, j, px, c1))
+ res = PIGLIT_FAILURE;
+ }
+ } else {
+ if (t2_intersect == INSIDE) {
+ //printf("2");
+ if (!pix_equal(i, j, px, c2))
+ res = PIGLIT_FAILURE;
+ } else {
+ //printf("0");
+ if (!pix_equal(i, j, px, bg))
+ res = PIGLIT_FAILURE;
+ }
+ }
+
+ /*if (i == piglit_width-1)
+ printf("\n");*/
+ }
+ }
+
+ free(pix);
+ return res;
+}
+
+static void reshape(int w, int h)
+{
+ glViewport(0, 0, w, h);
+}
+
+void piglit_init(int argc, char**argv)
+{
+ glutReshapeFunc(reshape);
+
+ glClearColor(0.3, 0.3, 0.3, 0.3);
+ glClearDepth(1);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_DEPTH_TEST);
+ glReadBuffer(GL_FRONT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1);
+
+ printf("First the red triangle is drawn, then the blue one.\n");
+}