<div dir="ltr">These nits have been incorporated into my local branch (<a href="http://cgit.freedesktop.org/~ldeks/piglit/?h=gl-1.0-glean">http://cgit.freedesktop.org/~ldeks/piglit/?h=gl-1.0-glean</a>).<br><br>Thanks for the help.<br><br>Laura<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Oct 13, 2014 at 7:58 PM, Dylan Baker <span dir="ltr"><<a href="mailto:baker.dylan.c@gmail.com" target="_blank">baker.dylan.c@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Monday, October 13, 2014 02:21:34 PM Laura Ekstrand wrote:<br>
> ---<br>
>  tests/spec/gl-1.0/CMakeLists.gl.txt |   1 +<br>
>  tests/spec/gl-1.0/blend.c           | 786 ++++++++++++++++++++++++++++++++++++<br>
>  2 files changed, 787 insertions(+)<br>
>  create mode 100644 tests/spec/gl-1.0/blend.c<br>
><br>
> diff --git a/tests/spec/gl-1.0/CMakeLists.gl.txt b/tests/spec/gl-1.0/CMakeLists.gl.txt<br>
> index e5bb33f..f5f8c48 100644<br>
> --- a/tests/spec/gl-1.0/CMakeLists.gl.txt<br>
> +++ b/tests/spec/gl-1.0/CMakeLists.gl.txt<br>
> @@ -20,5 +20,6 @@ piglit_add_executable (gl-1.0-long-dlist long-dlist.c)<br>
>  piglit_add_executable (gl-1.0-rendermode-feedback rendermode-feedback.c)<br>
>  piglit_add_executable (gl-1.0-swapbuffers-behavior swapbuffers-behavior.c)<br>
>  piglit_add_executable (gl-1.0-polygon-line-aa polygon-line-aa.c)<br>
> +piglit_add_executable (gl-1.0-blend-func blend.c)<br>
><br>
>  # vim: ft=cmake:<br>
> diff --git a/tests/spec/gl-1.0/blend.c b/tests/spec/gl-1.0/blend.c<br>
> new file mode 100644<br>
> index 0000000..4812f5d<br>
> --- /dev/null<br>
> +++ b/tests/spec/gl-1.0/blend.c<br>
> @@ -0,0 +1,786 @@<br>
> +/*  BEGIN_COPYRIGHT -*- glean -*-<br>
> + *<br>
> + *  Copyright (C) 1999  Allen Akin   All Rights Reserved.<br>
> + *<br>
> + *  Permission is hereby granted, free of charge, to any person<br>
> + *  obtaining a copy of this software and associated documentation<br>
> + *  files (the "Software"), to deal in the Software without<br>
> + *  restriction, including without limitation the rights to use,<br>
> + *  copy, modify, merge, publish, distribute, sublicense, and/or<br>
> + *  sell copies of the Software, and to permit persons to whom the<br>
> + *  Software is furnished to do so, subject to the following<br>
> + *  conditions:<br>
> + *<br>
> + *  The above copyright notice and this permission notice shall be<br>
> + *  included in all copies or substantial portions of the<br>
> + *  Software.<br>
> + *<br>
> + *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY<br>
> + *  KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE<br>
> + *  WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR<br>
> + *  PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ALLEN AKIN BE<br>
> + *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN<br>
> + *  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF<br>
> + *  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER<br>
> + *  DEALINGS IN THE SOFTWARE.<br>
> +<br>
> + *  END_COPYRIGHT<br>
> + */<br>
> +<br>
> +/*<br>
> + * Copyright 2014 Intel Corporation<br>
> + *<br>
> + * Permission is hereby granted, free of charge, to any person obtaining a<br>
> + * copy of this software and associated documentation files (the "Software"),<br>
> + * to deal in the Software without restriction, including without limitation<br>
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
> + * and/or sell copies of the Software, and to permit persons to whom the<br>
> + * Software is furnished to do so, subject to the following conditions:<br>
> + *<br>
> + * The above copyright notice and this permission notice (including the next<br>
> + * paragraph) shall be included in all copies or substantial portions of the<br>
> + * Software.<br>
> + *<br>
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
> + * IN THE SOFTWARE.<br>
> + */<br>
<br>
</div></div>Since both licenses are MIT you could just add "Copyright Intel..."<br>
below the original copyright date rather than having two copies of the<br>
license.<br>
<div><div class="h5"><br>
> +<br>
> +/** @file blend.c<br>
> + *<br>
> + *  Test blending functions.<br>
> + *<br>
> + *   This test checks all combinations of source and destination<br>
> + *   blend factors for the GL_FUNC_ADD blend equation.  It operates<br>
> + *   on all RGB or RGBA drawing surface configurations that support<br>
> + *   the creation of windows.<br>
> + *<br>
> + *   Note that a common cause of failures for this test is small errors<br>
> + *   introduced when an implementation scales color values incorrectly;<br>
> + *   for example, converting an 8-bit color value to float by<br>
> + *   dividing by 256 rather than 255, or computing a blending result<br>
> + *   by shifting a double-width intermediate value rather than scaling<br>
> + *   it.  Also, please note that the OpenGL spec requires that when<br>
> + *   converting from floating-point colors to integer form, the result<br>
> + *   must be rounded to the nearest integer, not truncated.<br>
> + *   [1.2.1, 2.13.9]<br>
> + *<br>
> + *   The test reports two error measurements.  The first (readback) is<br>
> + *   the error detected when reading back raw values that were written<br>
> + *   to the framebuffer.  The error in this case should be very close<br>
> + *   to zero, since the values are carefully constructed so that they<br>
> + *   can be represented accurately in the framebuffer.  The second<br>
> + *   (blending) is the error detected in the result of the blending<br>
> + *   computation.  For the test to pass, these errors must both be<br>
> + *   no greater than one least-significant bit in the framebuffer<br>
> + *   representation of a color.<br>
> + */<br>
> +<br>
> +#include "piglit-util-gl.h"<br>
> +<br>
> +#include <assert.h><br>
> +#include <math.h><br>
> +#include <stdlib.h><br>
> +#include <stdio.h><br>
> +<br>
> +#define ELEMENTS(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))<br>
> +<br>
> +#define HUGE_STEP 1000<br>
> +<br>
> +/*<br>
> + * We will check each pair of blend factors<br>
> + * for each pixel in a square image of this<br>
> + * dimension, so if you make it too large,<br>
> + * the tests may take quite a while to run.<br>
> + */<br>
> +#define drawing_size 32<br>
> +#define img_width drawing_size<br>
> +#define img_height drawing_size<br>
> +<br>
> +PIGLIT_GL_TEST_CONFIG_BEGIN<br>
> +<br>
> +     config.supports_gl_compat_version = 10;<br>
> +<br>
> +     config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;<br>
> +<br>
> +PIGLIT_GL_TEST_CONFIG_END<br>
> +<br>
> +static GLenum src_factors[] = {<br>
> +     GL_ZERO,<br>
> +     GL_ONE,<br>
> +     GL_DST_COLOR,<br>
> +     GL_ONE_MINUS_DST_COLOR,<br>
> +     GL_SRC_ALPHA,<br>
> +     GL_ONE_MINUS_SRC_ALPHA,<br>
> +     GL_DST_ALPHA,<br>
> +     GL_ONE_MINUS_DST_ALPHA,<br>
> +     GL_SRC_ALPHA_SATURATE,<br>
> +     GL_CONSTANT_COLOR,<br>
> +     GL_ONE_MINUS_CONSTANT_COLOR,<br>
> +     GL_CONSTANT_ALPHA,<br>
> +     GL_ONE_MINUS_CONSTANT_ALPHA<br>
> +};<br>
> +static GLenum dst_factors[] = {<br>
> +     GL_ZERO,<br>
> +     GL_ONE,<br>
> +     GL_SRC_COLOR,<br>
> +     GL_ONE_MINUS_SRC_COLOR,<br>
> +     GL_SRC_ALPHA,<br>
> +     GL_ONE_MINUS_SRC_ALPHA,<br>
> +     GL_DST_ALPHA,<br>
> +     GL_ONE_MINUS_DST_ALPHA,<br>
> +     GL_CONSTANT_COLOR,<br>
> +     GL_ONE_MINUS_CONSTANT_COLOR,<br>
> +     GL_CONSTANT_ALPHA,<br>
> +     GL_ONE_MINUS_CONSTANT_ALPHA<br>
> +};<br>
> +static GLenum operators[] = {<br>
> +     GL_FUNC_ADD,<br>
> +     GL_FUNC_SUBTRACT,<br>
> +     GL_FUNC_REVERSE_SUBTRACT,<br>
> +     GL_MIN,<br>
> +     GL_MAX<br>
> +};<br>
> +<br>
> +struct image {<br>
> +     GLuint name;<br>
> +     GLfloat *data;<br>
> +};<br>
> +<br>
> +static struct image dst_img;      /* Image #1 */<br>
> +static struct image src_img;      /* Image #2 */<br>
> +static struct image exp_img;      /* The expected blending result */<br>
> +<br>
> +static bool have_sep_func, have_blend_equation;<br>
> +static bool have_blend_equation_sep, have_blend_color;<br>
> +<br>
> +/* A bright, semi-transparent blue */<br>
> +static const GLfloat constant_color[4] = {0.25, 0.0, 1.0, 0.75};<br>
> +<br>
> +/* Our random image data factory. */<br>
> +GLfloat*<br>
> +random_image_data() {<br>
> +     /* I guess we don't have to delete this because piglit just quits after a<br>
> +      * test and dumps its data. */<br>
> +     int i;<br>
> +     GLfloat *img = malloc(4*img_width*img_height*sizeof(GLfloat));<br>
> +     for (i = 0; i < 4*img_width*img_height; ++i) {<br>
> +             img[i] = (float) rand() / RAND_MAX;<br>
> +     }<br>
> +     return img;<br>
> +} /* random_image_data */<br>
> +<br>
> +/* Our solid color fill data factory. */<br>
> +GLfloat*<br>
> +color_fill_data(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {<br>
> +     int i, j;<br>
> +     GLfloat *img = malloc(4*img_width*img_height*sizeof(GLfloat));<br>
> +     for (j = 0; j < img_height; ++j) { /* j = vertical, i = horizontal */<br>
> +             for (i = 0; i < img_width; ++i) {<br>
> +                     img[4*(img_width*j + i) + 0] = r;<br>
> +                     img[4*(img_width*j + i) + 1] = g;<br>
> +                     img[4*(img_width*j + i) + 2] = b;<br>
> +                     img[4*(img_width*j + i) + 3] = a;<br>
> +             }<br>
> +     }<br>
> +     return img;<br>
> +} /* color_fill_data */<br>
> +<br>
> +static void<br>
> +image_init(struct image *image) {<br>
> +     glGenTextures(1, &image->name);<br>
> +     glBindTexture(GL_TEXTURE_2D, image->name);<br>
> +     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,<br>
> +                      img_width, img_height, 0, GL_RGBA, GL_FLOAT, image->data);<br>
> +     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);<br>
> +     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);<br>
> +} /* image_init */<br>
> +<br>
> +<br>
> +void<br>
> +piglit_init(int argc, char **argv) {<br>
> +<br>
> +     srand(0);<br>
> +<br>
> +     /* Fill src and dst with randomness. */<br>
> +     dst_img.data = random_image_data();<br>
> +     src_img.data = random_image_data();<br>
> +<br>
> +     /* Fill exp_img with constant_color. */<br>
> +     /*<br>
> +      * You can use this as a check to make sure the test is working<br>
> +      * properly.<br>
> +      */<br>
> +     exp_img.data = color_fill_data(constant_color[0],<br>
> +                                                               constant_color[1],<br>
> +                                                               constant_color[2],<br>
> +                                                               constant_color[3]);<br>
> +<br>
> +     image_init(&dst_img);<br>
> +     image_init(&src_img);<br>
> +     image_init(&exp_img);<br>
> +} /* piglit_init */<br>
> +<br>
> +bool<br>
> +needs_blend_color(const GLenum func) {<br>
> +     switch (func) {<br>
> +     case GL_CONSTANT_COLOR:<br>
> +     case GL_ONE_MINUS_CONSTANT_COLOR:<br>
> +     case GL_CONSTANT_ALPHA:<br>
> +     case GL_ONE_MINUS_CONSTANT_ALPHA:<br>
> +             return true;<br>
> +     default:<br>
> +             return false;<br>
> +     }<br>
> +}<br>
> +<br>
> +/* Function that verifies GL's blending behavior. */<br>
> +static void<br>
> +apply_blend(GLenum src_factor_rgb, GLenum src_factor_a,<br>
> +        GLenum dst_factor_rgb, GLenum dst_factor_a,<br>
> +        GLenum op_rgb, GLenum op_a,<br>
> +        float* dst, const float* src,<br>
> +        const GLfloat constant_color[4])<br>
> +{<br>
> +     float sf[4], df[4];<br>
> +<br>
> +     if (op_rgb != GL_MIN && op_rgb != GL_MAX) {<br>
> +             /* Src RGB term */<br>
> +             switch (src_factor_rgb) {<br>
> +             case GL_ZERO:<br>
> +                     sf[0] = sf[1] = sf[2] = 0.0;<br>
> +                     break;<br>
> +             case GL_ONE:<br>
> +                     sf[0] = sf[1] = sf[2] = 1.0;<br>
> +                     break;<br>
> +             case GL_DST_COLOR:<br>
> +                     sf[0] = dst[0];<br>
> +                     sf[1] = dst[1];<br>
> +                     sf[2] = dst[2];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_COLOR:<br>
> +                     sf[0] = 1.0 - dst[0];<br>
> +                     sf[1] = 1.0 - dst[1];<br>
> +                     sf[2] = 1.0 - dst[2];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA:<br>
> +                     sf[0] = sf[1] = sf[2] = src[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_ALPHA:<br>
> +                     sf[0] = sf[1] = sf[2] = 1.0 - src[3];<br>
> +                     break;<br>
> +             case GL_DST_ALPHA:<br>
> +                     sf[0] = sf[1] = sf[2] = dst[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_ALPHA:<br>
> +                     sf[0] = sf[1] = sf[2] = 1.0 - dst[3];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA_SATURATE: {<br>
> +                     float f = 1.0 - dst[3];<br>
> +                     if (src[3] < f)<br>
> +                             f = src[3];<br>
> +                     sf[0] = sf[1] = sf[2] = f;<br>
> +                     }<br>
> +                     break;<br>
> +             case GL_CONSTANT_COLOR:<br>
> +                     sf[0] = constant_color[0];<br>
> +                     sf[1] = constant_color[1];<br>
> +                     sf[2] = constant_color[2];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_COLOR:<br>
> +                     sf[0] = 1.0 - constant_color[0];<br>
> +                     sf[1] = 1.0 - constant_color[1];<br>
> +                     sf[2] = 1.0 - constant_color[2];<br>
> +                     break;<br>
> +             case GL_CONSTANT_ALPHA:<br>
> +                     sf[0] =<br>
> +                     sf[1] =<br>
> +                     sf[2] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_ALPHA:<br>
> +                     sf[0] =<br>
> +                     sf[1] =<br>
> +                     sf[2] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             default:<br>
> +                     sf[0] = sf[1] = sf[2] = 0.0;<br>
> +                     abort();<br>
> +                     break;<br>
> +             }<br>
> +<br>
> +             /* Dest RGB term */<br>
> +             switch (dst_factor_rgb) {<br>
> +             case GL_ZERO:<br>
> +                     df[0] = df[1] = df[2] = 0.0;<br>
> +                     break;<br>
> +             case GL_ONE:<br>
> +                     df[0] = df[1] = df[2] = 1.0;<br>
> +                     break;<br>
> +             case GL_SRC_COLOR:<br>
> +                     df[0] = src[0];<br>
> +                     df[1] = src[1];<br>
> +                     df[2] = src[2];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_COLOR:<br>
> +                     df[0] = 1.0 - src[0];<br>
> +                     df[1] = 1.0 - src[1];<br>
> +                     df[2] = 1.0 - src[2];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA:<br>
> +                     df[0] = df[1] = df[2] = src[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_ALPHA:<br>
> +                     df[0] = df[1] = df[2] = 1.0 - src[3];<br>
> +                     break;<br>
> +             case GL_DST_ALPHA:<br>
> +                     df[0] = df[1] = df[2] = dst[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_ALPHA:<br>
> +                     df[0] = df[1] = df[2] = 1.0 - dst[3];<br>
> +                     break;<br>
> +             case GL_CONSTANT_COLOR:<br>
> +                     df[0] = constant_color[0];<br>
> +                     df[1] = constant_color[1];<br>
> +                     df[2] = constant_color[2];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_COLOR:<br>
> +                     df[0] = 1.0 - constant_color[0];<br>
> +                     df[1] = 1.0 - constant_color[1];<br>
> +                     df[2] = 1.0 - constant_color[2];<br>
> +                     break;<br>
> +             case GL_CONSTANT_ALPHA:<br>
> +                     df[0] =<br>
> +                     df[1] =<br>
> +                     df[2] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_ALPHA:<br>
> +                     df[0] =<br>
> +                     df[1] =<br>
> +                     df[2] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             default:<br>
> +                     df[0] = df[1] = df[2] = 0.0;<br>
> +                     abort();<br>
> +                     break;<br>
> +             }<br>
> +     }<br>
> +<br>
> +     if (op_a != GL_MIN && op_a != GL_MAX) {<br>
> +             /* Src Alpha term */<br>
> +             switch (src_factor_a) {<br>
> +             case GL_ZERO:<br>
> +                     sf[3] = 0.0;<br>
> +                     break;<br>
> +             case GL_ONE:<br>
> +                     sf[3] = 1.0;<br>
> +                     break;<br>
> +             case GL_DST_COLOR:<br>
> +                     sf[3] = dst[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_COLOR:<br>
> +                     sf[3] = 1.0 - dst[3];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA:<br>
> +                     sf[3] = src[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_ALPHA:<br>
> +                     sf[3] = 1.0 - src[3];<br>
> +                     break;<br>
> +             case GL_DST_ALPHA:<br>
> +                     sf[3] = dst[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_ALPHA:<br>
> +                     sf[3] = 1.0 - dst[3];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA_SATURATE:<br>
> +                     sf[3] = 1.0;<br>
> +                     break;<br>
> +             case GL_CONSTANT_COLOR:<br>
> +                     sf[3] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_COLOR:<br>
> +                     sf[3] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             case GL_CONSTANT_ALPHA:<br>
> +                     sf[3] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_ALPHA:<br>
> +                     sf[3] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             default:<br>
> +                     sf[3] = 0.0;<br>
> +                     abort();<br>
> +                     break;<br>
> +             }<br>
> +<br>
> +             /* Dst Alpha term */<br>
> +             switch (dst_factor_a) {<br>
> +             case GL_ZERO:<br>
> +                     df[3] = 0.0;<br>
> +                     break;<br>
> +             case GL_ONE:<br>
> +                     df[3] = 1.0;<br>
> +                     break;<br>
> +             case GL_SRC_COLOR:<br>
> +                     df[3] = src[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_COLOR:<br>
> +                     df[3] = 1.0 - src[3];<br>
> +                     break;<br>
> +             case GL_SRC_ALPHA:<br>
> +                     df[3] = src[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_SRC_ALPHA:<br>
> +                     df[3] = 1.0 - src[3];<br>
> +                     break;<br>
> +             case GL_DST_ALPHA:<br>
> +                     df[3] = dst[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_DST_ALPHA:<br>
> +                     df[3] = 1.0 - dst[3];<br>
> +                     break;<br>
> +             case GL_CONSTANT_COLOR:<br>
> +                     df[3] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_COLOR:<br>
> +                     df[3] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             case GL_CONSTANT_ALPHA:<br>
> +                     df[3] = constant_color[3];<br>
> +                     break;<br>
> +             case GL_ONE_MINUS_CONSTANT_ALPHA:<br>
> +                     df[3] = 1.0 - constant_color[3];<br>
> +                     break;<br>
> +             default:<br>
> +                     df[3] = 0.0;<br>
> +                     abort();<br>
> +                     break;<br>
> +             }<br>
> +     }<br>
> +<br>
> +     switch (op_rgb) {<br>
> +     case GL_FUNC_ADD:<br>
> +             dst[0] = CLAMP(src[0] * sf[0] + dst[0] * df[0], 0.0f, 1.0f);<br>
> +             dst[1] = CLAMP(src[1] * sf[1] + dst[1] * df[1], 0.0f, 1.0f);<br>
> +             dst[2] = CLAMP(src[2] * sf[2] + dst[2] * df[2], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_FUNC_SUBTRACT:<br>
> +             dst[0] = CLAMP(src[0] * sf[0] - dst[0] * df[0], 0.0f, 1.0f);<br>
> +             dst[1] = CLAMP(src[1] * sf[1] - dst[1] * df[1], 0.0f, 1.0f);<br>
> +             dst[2] = CLAMP(src[2] * sf[2] - dst[2] * df[2], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_FUNC_REVERSE_SUBTRACT:<br>
> +             dst[0] = CLAMP(dst[0] * df[0] - src[0] * sf[0], 0.0f, 1.0f);<br>
> +             dst[1] = CLAMP(dst[1] * df[1] - src[1] * sf[1], 0.0f, 1.0f);<br>
> +             dst[2] = CLAMP(dst[2] * df[2] - src[2] * sf[2], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_MIN:<br>
> +             dst[0] = MIN2(src[0], dst[0]);<br>
> +             dst[1] = MIN2(src[1], dst[1]);<br>
> +             dst[2] = MIN2(src[2], dst[2]);<br>
> +             break;<br>
> +     case GL_MAX:<br>
> +             dst[0] = MAX2(src[0], dst[0]);<br>
> +             dst[1] = MAX2(src[1], dst[1]);<br>
> +             dst[2] = MAX2(src[2], dst[2]);<br>
> +             break;<br>
> +        default:<br>
> +             abort();<br>
> +        }<br>
> +<br>
> +     switch (op_a) {<br>
> +     case GL_FUNC_ADD:<br>
> +             dst[3] = CLAMP(src[3] * sf[3] + dst[3] * df[3], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_FUNC_SUBTRACT:<br>
> +             dst[3] = CLAMP(src[3] * sf[3] - dst[3] * df[3], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_FUNC_REVERSE_SUBTRACT:<br>
> +             dst[3] = CLAMP(dst[3] * df[3] - src[3] * sf[3], 0.0f, 1.0f);<br>
> +             break;<br>
> +     case GL_MIN:<br>
> +             dst[3] = MIN2(src[3], dst[3]);<br>
> +             break;<br>
> +     case GL_MAX:<br>
> +             dst[3] = MAX2(src[3], dst[3]);<br>
> +             break;<br>
> +        default:<br>
> +             abort();<br>
> +        }<br>
> +<br>
> +} /* apply_blend */<br>
> +<br>
> +<br>
> +/* Test for one set of factor levels */<br>
> +bool<br>
> +run_factor_set(GLenum src_factor_rgb, GLenum src_factor_a,<br>
> +                  GLenum dst_factor_rgb, GLenum dst_factor_a,<br>
> +                  GLenum op_rgb, GLenum op_a,<br>
> +                  const GLfloat constant_color[4])<br>
> +{<br>
> +     int i, j;<br>
> +     bool pass = true;<br>
> +<br>
> +     glDisable(GL_DITHER);<br>
> +     glClear(GL_COLOR_BUFFER_BIT);<br>
> +<br>
> +     /* Send dst image to the framebuffer. */<br>
> +     glDisable(GL_BLEND);<br>
> +     piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);<br>
> +     glEnable(GL_TEXTURE_2D);<br>
> +     glBindTexture(GL_TEXTURE_2D, <a href="http://dst_img.name" target="_blank">dst_img.name</a>);<br>
> +     piglit_draw_rect_tex(0, 0, img_width, img_height, 0, 0, 1, 1);<br>
> +     pass &= piglit_check_gl_error(GL_NO_ERROR);<br>
> +<br>
> +     /*<br>
> +      * Read back the contents of the framebuffer, and measure any<br>
> +      * difference from what was actually written.  We can't tell<br>
> +      * whether errors occurred when writing or when reading back,<br>
> +      * but at least we can report anything unusual.<br>
> +      */<br>
> +     pass &= piglit_probe_image_rgba(0, 0, img_width, img_height, dst_img.data);<br>
> +<br>
> +     /*<br>
> +      * Now apply the blending<br>
> +      * operation to both the framebuffer and a copy in the image<br>
> +      * ``expected''.  Note that a fresh source alpha must be<br>
> +      * generated here, because the range of source alpha values is<br>
> +      * not limited by the range of alpha values that can be<br>
> +      * represented in the framebuffer.  Save the source pixels in<br>
> +      * the image ``src'' so we can diagnose any problems we find<br>
> +      * later.<br>
> +      */<br>
> +<br>
> +     /* Configure the appropriate blending settings */<br>
> +     if (have_sep_func)<br>
> +             glBlendFuncSeparate(src_factor_rgb, dst_factor_rgb,<br>
> +                                    src_factor_a, dst_factor_a);<br>
> +     else<br>
> +             glBlendFunc(src_factor_rgb, dst_factor_rgb);<br>
> +<br>
> +     if (have_blend_equation_sep)<br>
> +             glBlendEquationSeparate(op_rgb, op_a);<br>
> +     else if (have_blend_equation)<br>
> +             glBlendEquation(op_rgb);<br>
> +<br>
> +<br>
> +     /* Send src to the framebuffer and let GL blend it with dst */<br>
> +     glEnable(GL_BLEND);<br>
> +     glBindTexture(GL_TEXTURE_2D, <a href="http://src_img.name" target="_blank">src_img.name</a>);<br>
> +     piglit_draw_rect_tex(0, 0, img_width, img_height, 0, 0, 1, 1);<br>
> +     glDisable(GL_TEXTURE_2D);<br>
> +     glDisable(GL_BLEND);<br>
> +     pass &= piglit_check_gl_error(GL_NO_ERROR);<br>
> +<br>
> +     /* Compute the appropriate expected. */<br>
> +     for (j = 0; j < img_height; ++j) {<br>
> +             for (i = 0; i < img_width; ++i) {<br>
> +<br>
> +                     int idx = 4*(img_width*j + i);<br>
> +<br>
> +                     /* Initialize expected with dst data. */<br>
> +                     exp_img.data[idx + 0] = dst_img.data[idx + 0];<br>
> +                     exp_img.data[idx + 1] = dst_img.data[idx + 1];<br>
> +                     exp_img.data[idx + 2] = dst_img.data[idx + 2];<br>
> +                     exp_img.data[idx + 3] = dst_img.data[idx + 3];<br>
> +<br>
> +                     /* Apply the blending. */<br>
> +                     apply_blend(src_factor_rgb, src_factor_a,<br>
> +                                dst_factor_rgb, dst_factor_a,<br>
> +                                op_rgb, op_a,<br>
> +                                &exp_img.data[idx], &src_img.data[idx], constant_color);<br>
> +             }<br>
> +     }<br>
> +<br>
> +     /*<br>
> +      * Compare the image in the framebuffer to the<br>
> +      * computed image (``expected'') to see if any pixels are<br>
> +      * outside the expected tolerance range.<br>
> +      */<br>
> +     pass &= piglit_probe_image_rgba(0, 0, img_width, img_height, exp_img.data);<br>
> +<br>
> +<br>
> +     return pass;<br>
> +} /* run_factor_set */<br>
> +<br>
> +/**<br>
> + * Run the whole suite of blend tests<br>
> + * Not a full factorial test, that would take too long.<br>
> + * Tests all add blending permutations.<br>
> + * Tests about 1/3 of subtract blending.<br>
> + * Skips most max and min tests.<br>
> + */<br>
> +bool<br>
> +run_all_factor_sets() {<br>
> +     bool pass = true;<br>
> +     int gl_version = piglit_get_gl_version();<br>
> +     int counter = 0; /* Number of tests we have done. */<br>
> +     int step;<br>
> +     int op, opa;<br>
> +     int sf, sfa, df, dfa;<br>
> +<br>
> +     unsigned num_src_factors_sep, num_dst_factors_sep;<br>
> +     unsigned num_operators_rgb, num_operators_a;<br>
> +<br>
> +     /* Find out what kind of GL blending capability we have. */<br>
> +     have_sep_func = false;<br>
> +     have_blend_equation = false;<br>
> +     have_blend_equation_sep = false;<br>
> +     have_blend_color = false;<br>
> +     if (gl_version >= 14)<br>
> +     {<br>
> +             have_blend_equation = true;<br>
> +<br>
> +             if (piglit_is_extension_supported("GL_EXT_blend_func_separate")) {<br>
> +                     have_sep_func = true;<br>
> +             }<br>
> +<br>
> +             if (piglit_is_extension_supported("GL_EXT_blend_color")) {<br>
> +                     have_blend_color = true;<br>
> +             }<br>
> +     }<br>
> +     else if (piglit_is_extension_supported("GL_EXT_blend_subtract") &&<br>
> +              piglit_is_extension_supported("GL_EXT_blend_min_max")) {<br>
> +             have_blend_equation = true;<br>
> +     }<br>
> +<br>
> +     if (gl_version >= 20) {<br>
> +             have_blend_equation_sep = true;<br>
> +     }<br>
> +     else if (piglit_is_extension_supported("GL_EXT_blend_equation_separate")) {<br>
> +             have_blend_equation_sep = true;<br>
> +     }<br>
> +<br>
> +     if (have_blend_color) {<br>
> +             /* Just one blend color setting for all tests */<br>
> +             /* A bright, semi-transparent blue */<br>
> +             glBlendColor(constant_color[0], constant_color[1],<br>
> +                                      constant_color[2], constant_color[3]);<br>
> +     }<br>
> +<br>
> +     if (have_sep_func) {<br>
> +             num_src_factors_sep = ELEMENTS(src_factors);<br>
> +             num_dst_factors_sep = ELEMENTS(dst_factors);<br>
> +     }<br>
> +     else {<br>
> +             num_src_factors_sep = 1;<br>
> +             num_dst_factors_sep = 1;<br>
> +     }<br>
> +<br>
> +     if (have_blend_equation) {<br>
> +             num_operators_rgb = ELEMENTS(operators);<br>
> +             num_operators_a = ELEMENTS(operators);<br>
> +     }<br>
> +     else {<br>
> +             num_operators_rgb = 1; /* just ADD */<br>
> +             num_operators_a = 1; /* just ADD */<br>
> +     }<br>
> +<br>
> +     for (op = 0; op < num_operators_rgb; ++op) {<br>
> +             for (opa = 0; opa < num_operators_a; ++opa) {<br>
> +                     if (operators[op] == GL_FUNC_ADD && operators[opa] == GL_FUNC_ADD) {<br>
> +                             /* test _all_ blend term combinations */<br>
> +                             step = 1;<br>
> +                     }<br>
> +                     else if (operators[op] == GL_MIN || operators[op] == GL_MAX ||<br>
> +                              operators[opa] == GL_MIN || operators[opa] == GL_MAX) {<br>
> +                             /* blend terms are N/A so only do one iteration of loops */<br>
> +                             step = HUGE_STEP;<br>
> +                     }<br>
> +                     else {<br>
> +                             /* subtract modes: do every 3rd blend term for speed */<br>
> +                             step = 3;<br>
> +                     }<br>
> +<br>
> +                     for (sf = 0; sf < ELEMENTS(src_factors); sf += step) {<br>
> +                             for (sfa = 0; sfa < num_src_factors_sep; sfa += step) {<br>
> +                                     for (df = 0; df < ELEMENTS(dst_factors); df += step) {<br>
> +                                             for (dfa = 0; dfa < num_dst_factors_sep; dfa += step) {<br>
> +<br>
> +                                                     GLenum src_rgb, src_a, dst_rgb, dst_a;<br>
> +<br>
> +                                                     if (have_sep_func) {<br>
> +                                                             src_rgb = src_factors[sf];<br>
> +                                                             src_a = src_factors[sfa];<br>
> +                                                             dst_rgb = dst_factors[df];<br>
> +                                                             dst_a = dst_factors[dfa];<br>
> +                                                     }<br>
> +                                                     else {<br>
> +                                                             src_rgb = src_a = src_factors[sf];<br>
> +                                                             dst_rgb = dst_a = dst_factors[df];<br>
> +                                                     }<br>
> +<br>
> +                                                     /* skip test if blend color used, but not supported. */<br>
> +                                                     if (!have_blend_color<br>
> +                                                             && (needs_blend_color(src_rgb) ||<br>
> +                                                                     needs_blend_color(src_a) ||<br>
> +                                                                     needs_blend_color(dst_rgb) ||<br>
> +                                                                     needs_blend_color(dst_a)))<br>
> +                                                             continue;<br>
> +<br>
> +                                                     counter++; /* Increment counter so that tests are numbered starting from 1. */<br>
> +<br>
> +                                                     /* For verification purposes, this prints every test<br>
> +                                                      * configuration as it runs.*/<br>
> +                                                     /*<br>
> +                                                      * printf("%i: %s, %s, %s, %s, %s, %s\n", counter,<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(src_rgb),<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(src_a),<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(dst_rgb),<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(dst_a),<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(operators[op]),<br>
> +                                                      *                                                                 piglit_get_gl_enum_name(operators[opa]));<br>
> +                                                      */<br>
> +<br>
> +                                                     pass &= run_factor_set(src_rgb, src_a, dst_rgb, dst_a, operators[op], operators[opa], constant_color);<br>
> +                                             }<br>
> +                                     }<br>
> +                             }<br>
> +                     }<br>
> +             }<br>
> +     }<br>
> +<br>
> +     printf("\nRan %i tests.\n", counter);<br>
> +     return pass;<br>
> +} /* run_all_factor_sets */<br>
> +<br>
> +enum piglit_result<br>
> +piglit_display(void)<br>
> +{<br>
> +     bool pass = true;<br>
> +<br>
> +     pass &= run_all_factor_sets();<br>
> +<br>
> +     if (!piglit_automatic) {<br>
> +             /*<br>
> +              * Draw our three images, separated by some space.<br>
> +              * This will show only the results of the last test.<br>
> +              */<br>
> +<br>
> +             /* Draw dst */<br>
> +             glEnable(GL_TEXTURE_2D);<br>
> +             glBindTexture(GL_TEXTURE_2D, <a href="http://dst_img.name" target="_blank">dst_img.name</a>);<br>
> +             piglit_draw_rect_tex(0, 0, img_width, img_height, 0, 0, 1, 1);<br>
> +<br>
> +             /* Draw src */<br>
> +             glBindTexture(GL_TEXTURE_2D, <a href="http://src_img.name" target="_blank">src_img.name</a>);<br>
> +             piglit_draw_rect_tex(img_width + 2, 0, img_width, img_height, 0, 0, 1, 1);<br>
> +<br>
> +             /* Draw exp */<br>
> +             glBindTexture(GL_TEXTURE_2D, <a href="http://exp_img.name" target="_blank">exp_img.name</a>);<br>
> +             /* Have to resend the texture to GL to update GL's copy */<br>
> +             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,<br>
> +                              img_width, img_height, 0, GL_RGBA, GL_FLOAT, exp_img.data);<br>
> +             piglit_draw_rect_tex(2*(img_width + 2), 0, img_width, img_height, 0, 0, 1, 1);<br>
> +             glDisable(GL_TEXTURE_2D);<br>
> +<br>
> +             piglit_present_results();<br>
> +     }<br>
> +<br>
> +<br>
> +     return pass ? PIGLIT_PASS : PIGLIT_FAIL;<br>
> +} /* piglit_display */<br>
> --<br>
> 2.1.0<br>
><br>
</div></div>> _______________________________________________<br>
> Piglit mailing list<br>
> <a href="mailto:Piglit@lists.freedesktop.org">Piglit@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</blockquote></div><br></div>