[Piglit] [PATCH] polygon-mode: replace memcmp() with better pixel probing
Jose Fonseca
jfonseca at vmware.com
Wed Jan 25 06:17:53 PST 2012
I see. Looks good then.
Jose
----- Original Message -----
> Hi Jose,
>
> I'm pretty sure I've got this right.
>
> GL_QUADs drawn with polygon mode = GL_LINE should not render the
> diagonal line. Similarly, GL_POLYGONs drawn in GL_LINE mode should
> not draw any interior edges (that was broken in Gallium until I fixed
> it last summer). I verified this w/ NVIDIA's driver too.
>
> So the only case which should touch the center pixel in the quad
> should be the GL_FILL case. If the driver mistakenly does draw the
> diagonal in GL_LINE mode, we'll detect the primitive as being filled
> and the test will fail. That's what we want.
>
> -Brian
>
>
> On Wed, Jan 25, 2012 at 4:54 AM, Jose Fonseca <jfonseca at vmware.com>
> wrote:
> > Brian,
> >
> > I think the center probe is unreliable: imagine we request a filled
> > rectangle, the implementation draws two triangles in wireframe
> > mode as
> >
> > +-----+
> > + /|
> > + / |
> > + / |
> > + / |
> > +/ |
> > +-----+
> >
> > IIUC, the
> >
> > probe_region(cx, cy, expectedColor)
> >
> > call will incorrectly interpret the colored center point (due to
> > the diagonal) as a filled rectangle.
> >
> > Jose
> >
> >
> > ----- Original Message -----
> >> Previously, we compared the reference image and the test image
> >> with
> >> memcmp(). That failed when the driver used different drawing
> >> paths
> >> for glPolygonMode() vs. regular filled/line/point drawing.
> >>
> >> The new test examines the rendering with 3x3-pixel probes to
> >> determine if
> >> a polygon was drawn filled, outlined or as points.
> >> ---
> >> tests/general/polygon-mode.c | 162
> >> ++++++++++++++++++++++++++++++++++++------
> >> 1 files changed, 140 insertions(+), 22 deletions(-)
> >>
> >> diff --git a/tests/general/polygon-mode.c
> >> b/tests/general/polygon-mode.c
> >> index 217ff2b..fdd95cc 100644
> >> --- a/tests/general/polygon-mode.c
> >> +++ b/tests/general/polygon-mode.c
> >> @@ -34,6 +34,8 @@
> >> int piglit_width = 500, piglit_height = 100;
> >> int piglit_window_mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE;
> >>
> >> +static float ortho_left = -1, ortho_right = 8, ortho_bottom = -2,
> >> ortho_top = 2;
> >> +
> >> static const char *TestName = "polygon-mode";
> >>
> >> #define VERTS 16
> >> @@ -119,16 +121,117 @@ get_prim_mode(GLenum mode)
> >> }
> >>
> >>
> >> +static void
> >> +obj_pos_to_win_pos(float x, float y, int *wx, int *wy)
> >> +{
> >> + float ortho_width = ortho_right - ortho_left;
> >> + float ortho_height = ortho_top - ortho_bottom;
> >> + *wx = (int) ((x - ortho_left) / ortho_width * piglit_width);
> >> + *wy = (int) ((y - ortho_bottom) / ortho_height *
> >> piglit_height);
> >> +}
> >> +
> >> +
> >> +/**
> >> + * Probe a 3x3 pixel region to see if any of the pixels matches
> >> the
> >> + * expected color.
> >> + */
> >> +static GLboolean
> >> +probe_region(float px, float py, const GLfloat expectedColor[4])
> >> +{
> >> + GLfloat img[3][3][4];
> >> + int i, j;
> >> + int wx, wy;
> >> +
> >> + obj_pos_to_win_pos(px, py, &wx, &wy);
> >> +
> >> + glReadPixels(wx-1, wy-1, 3, 3, GL_RGBA, GL_FLOAT, img);
> >> +
> >> + /* see if any of the pixels matches the expected color */
> >> + for (i = 0; i < 3; i++) {
> >> + for (j = 0; j < 3; j++) {
> >> + if (img[i][j][0] == expectedColor[0] &&
> >> + img[i][j][1] == expectedColor[1] &&
> >> + img[i][j][2] == expectedColor[2] &&
> >> + img[i][j][3] == expectedColor[3]) {
> >> + return GL_TRUE;
> >> + }
> >> + }
> >> + }
> >> +
> >> + return GL_FALSE;
> >> +}
> >> +
> >> +
> >> +/**
> >> + * Examine the pixels drawn by a rect using the four vertex
> >> positions
> >> + * and determine if it was drawn filled, outlined, or as four
> >> points.
> >> + * \return GL_FILL, GL_LINE, GL_POINT or GL_NONE
> >> + */
> >> +static GLenum
> >> +identify_primitive(const GLfloat positions[4][2],
> >> + const GLfloat expectedColor[4])
> >> +{
> >> + /* center */
> >> + float cx = (positions[0][0] + positions[2][0]) / 2.0;
> >> + float cy = (positions[0][1] + positions[2][1]) / 2.0;
> >> + /* left edge */
> >> + float lx = positions[0][0];
> >> + float ly = cy;
> >> + /* right edge */
> >> + float rx = positions[2][0];
> >> + float ry = cy;
> >> + /* bottom edge */
> >> + float bx = cx;
> >> + float by = positions[0][1];
> >> + /* bottom edge */
> >> + float tx = cx;
> >> + float ty = positions[2][1];
> >> +
> >> + /* probe center */
> >> + if (probe_region(cx, cy, expectedColor))
> >> + return GL_FILL;
> >> +
> >> + /* probe left edge */
> >> + if (probe_region(lx, ly, expectedColor)) {
> >> + /* and bottom edge */
> >> + if (probe_region(bx, by, expectedColor)) {
> >> + /* and right edge */
> >> + if (probe_region(rx, ry, expectedColor)) {
> >> + /* and top edge */
> >> + if (probe_region(tx, ty, expectedColor)) {
> >> + return GL_LINE;
> >> + }
> >> + }
> >> + }
> >> + }
> >> +
> >> + /* probe lower-left corner */
> >> + if (probe_region(lx, by, expectedColor)) {
> >> + /* probe lower-right corner */
> >> + if (probe_region(rx, by, expectedColor)) {
> >> + /* probe top-left corner */
> >> + if (probe_region(lx, ty, expectedColor)) {
> >> + /* probe top-right corner */
> >> + if (probe_region(rx, ty, expectedColor)) {
> >> + return GL_POINT;
> >> + }
> >> + }
> >> + }
> >> + }
> >> +
> >> + return GL_NONE;
> >> +}
> >> +
> >> +
> >> +
> >> static GLboolean
> >> test_combo(GLenum frontMode, GLenum backMode)
> >> {
> >> GLenum frontPrim = get_prim_mode(frontMode);
> >> GLenum backPrim = get_prim_mode(backMode);
> >> - GLubyte *ref, *test;
> >> GLboolean pass = GL_TRUE;
> >> -
> >> - ref = malloc(piglit_width * piglit_height * 4);
> >> - test = malloc(piglit_width * piglit_height * 4);
> >> + GLenum expectedPrims[4];
> >> + int i;
> >>
> >> /* Draw reference image */
> >> glClear(GL_COLOR_BUFFER_BIT);
> >> @@ -137,33 +240,48 @@ test_combo(GLenum frontMode, GLenum
> >> backMode)
> >> glDrawArrays(backPrim, 4, 4);
> >> glDrawArrays(frontPrim, 8, 4);
> >> glDrawArrays(backPrim, 12, 4);
> >> - glReadPixels(0, 0, piglit_width, piglit_height,
> >> - GL_RGBA, GL_UNSIGNED_BYTE, ref);
> >> +
> >> + /* determine what kind of primitives were drawn */
> >> + for (i = 0; i < 4; i++) {
> >> + bool err = false;
> >> + expectedPrims[i] = identify_primitive(&Positions[4 * i],
> >> Colors[4 * i]);
> >> + if (i & 1) {
> >> + if (expectedPrims[i] != backMode) {
> >> + err = true;
> >> + }
> >> + }
> >> + else {
> >> + if (expectedPrims[i] != frontMode) {
> >> + err = true;
> >> + }
> >> + }
> >> + if (err) {
> >> + /* we didn't get the expected reference primitive */
> >> + fprintf(stderr,
> >> + "%s: reference drawing failed for frontPrim=%s,
> >> backPrim=%s\n",
> >> + TestName, get_mode_str(frontMode),
> >> get_mode_str(backMode));
> >> + return GL_FALSE;
> >> + }
> >> + }
> >>
> >> /* Draw test image */
> >> glClear(GL_COLOR_BUFFER_BIT);
> >> glPolygonMode(GL_FRONT, frontMode);
> >> glPolygonMode(GL_BACK, backMode);
> >> glDrawArrays(GL_QUADS, 0, 16);
> >> - glReadPixels(0, 0, piglit_width, piglit_height,
> >> - GL_RGBA, GL_UNSIGNED_BYTE, test);
> >> -
> >> - /*
> >> - * This assumes that there are generally no rasterization
> >> differences
> >> - * between the normal rendering paths vs. when glPolygonMode
> >> is
> >> in effect.
> >> - * If that's not true, we'll need a different comparision
> >> method.
> >> - */
> >> - if (memcmp(ref, test, piglit_width * piglit_height * 4)) {
> >> - fprintf(stderr, "%s: glPolygonMode(front=%s, back=%s)
> >> failed\n",
> >> - TestName, get_mode_str(frontMode),
> >> get_mode_str(backMode));
> >> - pass = GL_FALSE;
> >> +
> >> + /* check that these prims match the reference prims */
> >> + for (i = 0; i < 4; i++) {
> >> + GLenum prim = identify_primitive(&Positions[4 * i],
> >> Colors[4 *
> >> i]);
> >> + if (prim != expectedPrims[i]) {
> >> + fprintf(stderr, "%s: glPolygonMode(front=%s, back=%s)
> >> failed\n",
> >> + TestName, get_mode_str(frontMode),
> >> get_mode_str(backMode));
> >> + pass = GL_FALSE;
> >> + }
> >> }
> >>
> >> glutSwapBuffers();
> >>
> >> - free(ref);
> >> - free(test);
> >> -
> >> return pass;
> >> }
> >>
> >> @@ -222,7 +340,7 @@ piglit_init(int argc, char **argv)
> >> {
> >> glMatrixMode(GL_PROJECTION);
> >> glLoadIdentity();
> >> - glOrtho(-1, 8, -2, 2, -1, 1);
> >> + glOrtho(ortho_left, ortho_right, ortho_bottom, ortho_top, -1,
> >> 1);
> >>
> >> glMatrixMode(GL_MODELVIEW);
> >> glLoadIdentity();
> >> --
> >> 1.7.1
> >>
> >> _______________________________________________
> >> Piglit mailing list
> >> Piglit at lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/piglit
> >>
> > _______________________________________________
> > Piglit mailing list
> > Piglit at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/piglit
>
More information about the Piglit
mailing list