Commit 15141eeb authored by Luca Barbieri's avatar Luca Barbieri Committed by Marek Olšák

New testsuite for ARB_color_buffer_float (v2)

This in an updated version of the test I posted, now split into 8 tests
sharing a common header file.

It now features testing of multiple render targets and fog.

Test output logs and results on GeForce 8xxx, GTX 2xx or ideally GTX 4xx
with the proprietary drivers would be really welcome.

The files are put in "spec/arb_color_buffer_float" with the idea of
starting a convention of writing testsuites for each new extension
to be implemented in Mesa, putting it in "spec/<extension_name>".

The tests now fail on any bugs in the default mode.
If "-xfail" is passed, then known bugs on ATI and nVidia will be ignored,
and all tests will then succeed.

The driver bugs don't seem due (solely) to hardware limitations, but may
be due to software fallbacks being improperly implemented.

There are two areas where the specification seems unclear, as far as I
understand it.

I'm not sure what the process to ask for clarification is, and suggestions
would be welcome here.

This first issue is whether, when fragment clamping is set to FIXED_ONLY
and the FBO has some fixed-point and some floating-point buffers attached,
gl_FragData[n] is never clamped, or is clamped only for the fixed point
buffers.

Note that while blending on fixed-point clamps the color anyway, alpha
test and polygon smoothing happen before blending, and should be affected
by whether gl_FragData[n] is clamped or not.

From the OpenGL 4.1 spec, it seems that the intent is that fragment
clamping does not depend on the target, especially because it can be
bound dynamically due to user-defined varyings.

None of the hardware I have access to supports such dishomogeneous FBOs,
so I have no idea what the proprietary drivers do.

Current nVidia cards might shed light on this.

The second issue is whether disabling fragment clamping disables the
clamping done before fog application in fragment shaders with ARB_fog_*
options (or whether this is undefined)

This happens in the fixed pipeline, but making it happen for shaders too
would contradict the rationale of adding ARB_fog_* to shaders, which
is to avoid recompilation.

All the hardware I have access to has fixed function fog (all existing
Radeons seem to have it), and here the disabling applies to fragment
programs too, as a "naive" implementation would result in.

Again, current nVidia cards might shed light on this.
parent cd3167f1
......@@ -9,6 +9,7 @@ add_subdirectory (glslparsertest)
add_subdirectory (asmparsertest)
add_subdirectory (shaders)
add_subdirectory (texturing)
add_subdirectory (spec)
IF(OPENGL_egl_LIBRARY)
add_subdirectory (egl)
......
add_subdirectory (arb_color_buffer_float)
include_directories(
${OPENGL_INCLUDE_PATH}
${GLUT_INCLUDE_DIR}
${piglit_SOURCE_DIR}/tests/spec/arb_color_buffer_float
${piglit_SOURCE_DIR}/tests/util
${GLEW_INCLUDE_DIR}
)
link_directories (
${piglit_SOURCE_DIR}/tests/spec/arb_color_buffer_float
${piglit_SOURCE_DIR}/tests/util
)
link_libraries (
piglitutil
${OPENGL_gl_LIBRARY}
${OPENGL_glu_LIBRARY}
${GLUT_glut_LIBRARY}
${TIFF_LIBRARY}
${GLEW_glew_LIBRARY}
)
add_executable (arb_color_buffer_float-getteximage getteximage.c)
add_executable (arb_color_buffer_float-queries queries.c)
add_executable (arb_color_buffer_float-readpixels readpixels.c)
add_executable (arb_color_buffer_float-probepixel probepixel.c)
add_executable (arb_color_buffer_float-drawpixels drawpixels.c)
add_executable (arb_color_buffer_float-clear clear.c)
add_executable (arb_color_buffer_float-render render.c)
add_executable (arb_color_buffer_float-mrt mrt.c)
/*
* Copyright © 2010 Luca Barbieri
*
* 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.
*
*/
/** @file spec/arb_color_buffer_float/clear.c
*
* Tests that vertex and fragment color clamping do not affect glClear as
* specified by ARB_color_buffer_float
*/
/*
* (modify second paragraph, p. 216, removing clamp of clear color)
* void ClearColor(float r, float g, float b, float a);
* sets the clear value for the color buffers in RGBA mode.
*
* Fixed-point RGBA
* color buffers are cleared to a color values derived by taking the
* clear color, clamping to [0,1], and converting to fixed-point
* according to the rules of section 2.14.9.
*/
#include "common.h"
GLboolean test()
{
GLboolean pass = GL_TRUE;
for(vert_clamp = 0; vert_clamp < 3; ++vert_clamp)
{
for(frag_clamp = 0; frag_clamp < 3; ++frag_clamp)
{
GLboolean cpass;
printf("glClear of fbo for float texture with vertex clamp %s and fragment clamp %s (expecting no clamping)\n", clamp_strings[vert_clamp], clamp_strings[frag_clamp]);
glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, clamp_enums[vert_clamp]);
glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, clamp_enums[frag_clamp]);
glClearColor(pixels[0], pixels[1], pixels[2], pixels[3]);
glClear(GL_COLOR_BUFFER_BIT);
expected = fixed ? clamped_pixels : pixels;
cpass = piglit_probe_pixel_rgba(0, 0, expected);
GLboolean opass = cpass;
if(!cpass && ati_driver && format == GL_RGBA16F_ARB)
{
printf("ATI driver known *** MAJOR BUG ***: they always clamp clears for fp16 targets!\n");
opass = GL_TRUE;
}
pass = opass && pass;
}
}
return pass;
}
unsigned init()
{
return TEST_SRT;
}
/*
* Copyright © 2010 Luca Barbieri
*
* 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.
*
*/
/** @file spec/arb_color_buffer_float/common.h
*
* Common test framework for GL_ARB_color_buffer_float
*
* NOTE: both ATI and nVidia proprietary drivers are seriously broken, in
* different ways!
*/
#include "piglit-util.h"
int piglit_width = 128;
int piglit_height = 128;
int piglit_window_mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE;
/* use small values for pixels[0..3], so that the 0.01 tolerance is met for fp16 */
float pixels[] = {
7, -2.75, -0.25, 0.75,
0.0, 1.0, 2.0, -1.0,
0.5, 9.0 / 8.0, -156, 390,
234, -86, -21.5, 46.5,
};
float clamped_pixels[16];
float pixels_mul_2[16];
float clamped_pixels_mul_2[16];
float pixels_plus_half[16];
float clamped_pixels_plus_half[16];
float clamped_pixels_plus_half_clamped[16];
const char* clamp_strings[] = {"TRUE", "FIXED_ONLY", "FALSE"};
GLenum clamp_enums[] = {GL_TRUE, GL_FIXED_ONLY_ARB, GL_FALSE};
const char* mrt_mode_strings[] = {"single target", "homogeneous framebuffer", "dishomogeneous framebuffer"};
static inline float clamp(float f)
{
if(f >= 0.0f && f <= 1.0f)
return f;
else if(f > 0.0f)
return 1.0f;
else
return 0.0f;
}
unsigned ati_driver;
unsigned nvidia_driver;
char test_name[4096];
float observed[16];
unsigned vert_clamp, frag_clamp, read_clamp;
float* expected;
float* expected1;
GLuint tex, tex1, fb;
GLenum status;
unsigned error;
int fbo_width = 2;
int fbo_height = 2;
#define TEST_NO_RT 0
#define TEST_SRT 1
#define TEST_MRT 2
#define TEST_SRT_MRT 3
int test_mode = TEST_SRT;
GLenum format;
const char* format_name;
GLboolean fixed;
GLboolean fixed0, fixed1;
unsigned mrt_mode;
GLboolean test();
GLboolean run_test()
{
GLboolean pass = GL_TRUE;
fixed = fixed0 = format == GL_RGBA8;
fixed1 = -1;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, format,
2, 2, 0,
GL_RGBA, GL_FLOAT, pixels);
error = glGetError();
if(error)
{
printf("GL error after glTexImage2D 0x%04X\n", error);
return GL_FALSE;
}
if(test_mode)
{
glBindTexture(GL_TEXTURE_2D, 0);
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glViewport(0, 0, fbo_width, fbo_height);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D,
tex,
0);
error = glGetError();
if(error)
{
printf("GL error after FBO 0x%04X\n", error);
return GL_FALSE;
}
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);
}
}
if(test_mode <= TEST_SRT)
{
glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE);
pass = test();
}
else
{
unsigned mrt_modes = GLEW_ARB_draw_buffers ? (GLEW_ARB_texture_float ? 3 : 2) : 1;
unsigned first_mrt_mode = (test_mode == TEST_MRT) ? 1 : 0;
for(mrt_mode = first_mrt_mode; mrt_mode < mrt_modes; ++mrt_mode)
{
fixed1 = fixed;
if(mrt_mode)
{
GLenum bufs[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
unsigned format1;
if(mrt_mode == 1)
format1 = format;
else
{
format1 = fixed0 ? GL_RGBA32F_ARB : GL_RGBA8;
fixed1 = !fixed0;
fixed = GL_FALSE;
}
glGenTextures(1, &tex1);
glBindTexture(GL_TEXTURE_2D, tex1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, format1,
2, 2, 0,
GL_RGBA, GL_FLOAT, pixels);
error = glGetError();
if(error)
{
printf("GL error after second glTexImage2D 0x%04X\n", error);
return GL_FALSE;
}
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT1_EXT,
GL_TEXTURE_2D,
tex1,
0);
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
if(mrt_mode == 2)
printf("Dishomogeneous framebuffer is incomplete, skipping dishomogeneous tests (status = 0x%04x)\n", status);
else
{
printf("Framebuffer is incomplete (status = 0x%04x)\n", status);
pass = GL_FALSE;
}
goto skip_mrt;
}
glDrawBuffers(2, bufs);
error = glGetError();
if(error)
{
printf("GL error after second glDrawBuffers 0x%04X\n", error);
return GL_FALSE;
}
}
glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE);
pass = test() && pass;
skip_mrt:
if(mrt_mode)
{
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
GL_COLOR_ATTACHMENT1_EXT,
GL_TEXTURE_2D,
0,
0);
glDeleteTextures(1, &tex1);
}
}
}
glDeleteTextures(1, &tex);
tex = 0;
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
if(fb)
{
glDeleteFramebuffersEXT(1, &fb);
fb = 0;
}
error = glGetError();
if(error)
{
printf("GL error after test 0x%04X\n", error);
return GL_FALSE;
}
return pass;
}
enum piglit_result
piglit_display(void)
{
GLboolean pass = GL_TRUE;
unsigned error;
printf("Testing 8-bit fixed-point FBO\n");
format = GL_RGBA8;
format_name = "un8";
pass = run_test() && pass;
if(GLEW_ARB_texture_float)
{
printf("\n\n\nTesting 32-bit floating point FBO\n");
format = GL_RGBA32F_ARB;
format_name = "f32";
pass = run_test() && pass;
printf("\n\n\nTesting 16-bit floating point FBO\n");
format = GL_RGBA16F_ARB;
format_name = "f16";
pass = run_test() && pass;
}
else
printf("\n\n\nSkipping floating point FBO tests because of no ARB_texture_float.\n");
error = glGetError();
if(error)
{
printf("GL error at end 0x%04X\n", error);
return GL_FALSE;
}
return pass ? PIGLIT_SUCCESS : PIGLIT_FAILURE;
}
unsigned init();
void
piglit_init(int argc, char **argv)
{
int i;
GLboolean distinguish_xfails = GL_FALSE;
(void)i;
/* displaying thousands of single-pixel floating point results isn't really useful, or even doable */
piglit_automatic = GL_TRUE;
piglit_require_extension("GL_ARB_color_buffer_float");
test_mode = init();
if(test_mode != TEST_NO_RT)
piglit_require_extension("GL_EXT_framebuffer_object");
for(i = 1; i < argc; ++i)
{
if(!strcmp(argv[i], "-xfail"))
distinguish_xfails = GL_TRUE;
}
/* current ATI drivers are broken */
if(!strcmp((char*)glGetString(GL_VENDOR), "ATI Technologies Inc."))
ati_driver = 1;
/* current nVidia drivers are broken at least on GeForce 7xxx */
if(!strcmp((char*)glGetString(GL_VENDOR), "NVIDIA Corporation"))
nvidia_driver = 1;
if(ati_driver || nvidia_driver)
{
/* print both so users don't think either driver is better */
printf("Notice: the ATI proprietary driver does NOT conform to the GL_ARB_color_buffer_float specification! (tested version was 10.6 on cypress, on Linux x86)\n");
printf("Notice: the nVidia proprietary driver does NOT conform to the GL_ARB_color_buffer_float specification! (tested version was 256.44 on nv49, on Linux x86)\n");
printf("Notice: the nVidia and ATI proprietary drivers are both nonconformant, in different ways!\n\n\n");
}
if(!distinguish_xfails)
ati_driver = nvidia_driver = 0;
for(i = 0; i < sizeof(pixels) / sizeof(pixels[0]); ++i)
{
clamped_pixels[i] = clamp(pixels[i]);
pixels_mul_2[i] = pixels[i] * 2.0f;
clamped_pixels_mul_2[i] = clamped_pixels[i] * 2.0f;
pixels_plus_half[i] = pixels[i] + 0.5f;
clamped_pixels_plus_half[i] = clamped_pixels[i] + 0.5f;
clamped_pixels_plus_half_clamped[i] = clamp(clamped_pixels_plus_half[i]);
}
}
GLboolean compare_arrays(float* expected, float* observed, int length)
{
GLboolean pass = GL_TRUE;
unsigned i;
for(i = 0; i < length; ++i)
{
if(fabs(expected[i] - observed[i]) > 0.01)
{
printf("At %i Expected: %f Observed: %f\n", i, expected[i], observed[i]);
pass = GL_FALSE;
}
}
return pass;
}
/*
* Copyright © 2010 Luca Barbieri
*
* 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.
*
*/
/** @file spec/arb_color_buffer_float/drawpixels.c
*
* Tests that fragment color clamping affects glDrawPixels as specified by
* ARB_color_buffer_float
*/
/* 6. What control should apply to DrawPixels RGBA components?
* RESOLVED: The fragment color clamp control.
*/
#include "common.h"
GLboolean test()
{
GLboolean pass = GL_TRUE;
for(frag_clamp = 0; frag_clamp < 3; ++frag_clamp)
{
GLboolean cpass = GL_TRUE;
unsigned clamped = clamp_enums[frag_clamp] == GL_TRUE || (clamp_enums[frag_clamp] == GL_FIXED_ONLY_ARB && fixed);
printf("glDrawPixels of fbo for float texture with fragment clamp %s (expecting %sclamping)\n", clamp_strings[frag_clamp], clamped ? "" : "no ");
glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, clamp_enums[frag_clamp]);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glWindowPos2fARB(0, 0);
glDrawPixels(2, 2, GL_RGBA, GL_FLOAT, pixels);
expected = ((clamped || fixed) ? clamped_pixels : pixels);
unsigned x, y;
for(y = 0; y < 2; ++y)
for(x = 0; x < 2; ++x)
cpass = piglit_probe_pixel_rgba(x, y, expected + 8 * y + 4 * x) && cpass;
GLboolean opass = cpass;
if(!cpass && nvidia_driver && clamped)
{
printf("nVidia driver known *** MAJOR BUG ***: they don't clamp glDrawPixels!\n");
opass = GL_TRUE;
}
pass = opass && pass;
}
return pass;
}
unsigned init()
{
piglit_require_extension("GL_ARB_window_pos");
return TEST_SRT;
}
/*
* Copyright © 2010 Luca Barbieri
*
* 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.
*
*/
/** @file spec/arb_color_buffer_float/getteximage.c
*
* Tests that read color clamping doesn't affect glGetTexImage as
* specified by ARB_color_buffer_float
*/
#include "common.h"
GLboolean test()
{
GLboolean pass = GL_TRUE;
for(read_clamp = 0; read_clamp < 3; ++read_clamp)
{
printf("glGetTexImage of %s texture with read clamp %s (expecting %sclamping)\n", format_name, clamp_strings[read_clamp], fixed ? "" : "no ");
glClampColorARB(GL_CLAMP_READ_COLOR_ARB, clamp_enums[read_clamp]);
memset(observed, 0, sizeof(observed));
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, observed);
expected = fixed ? clamped_pixels : pixels;
pass = compare_arrays(expected, observed, 16);
}
return pass;
}
unsigned init()
{
return TEST_NO_RT;
}
/*
* Copyright © 2010 Luca Barbieri
*
* 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.
*
*/
/** @file spec/arb_color_buffer_float/mrt.c
*
* Tests that fragment color clamping affects MRT rendering as
* specified by ARB_color_buffer_float and OpenGL 4.1
*
* Note that the specification is not fully clear here.
* It *seems* to mean that clamping does *not* depend on the target framebuffer type,
* but rather the data type of the shader variable and whether there is *any* floating-point
* buffer in case of GL_FIXED_ONLY clamping.
*
* On ATI Radeon HD 58xx, dishomogeneous framebuffers are incomplete.
* TODO: what happens on GeForce 8xxx, GTX 2xx and GTX 4xx?
*/
/* If clamp is TRUE, fragment color
* clamping is enabled; if clamp is FALSE, fragment color clamping is disabled. If
* clamp is FIXED_ONLY, fragment color clamping is enabled if all enabled color
* buffers have fixed-point components.
*
* If fragment color clamping is enabled
* and the color buffer has an unsigned normalized fixed-point, signed normalized
* fixed-point, or floating-point format, the final fragment color, fragment data, or
* varying out variable values written by a fragment shader are clamped to the range
* [0, 1]. Only user-defined varying out variables declared as a floating-point type are
* clamped and may be converted. If fragment color clamping is disabled, or the color
* buffer has an integer format, the final fragment color, fragment data, or varying out
* variable values are not modified.
*/
#include "common.h"
const char *mrt_vp_string =
"!!ARBvp1.0\n" "MOV result.position, vertex.position;\n"
"MOV result.texcoord[0], {7, -2.75, -0.25, 0.75};\n"
"MOV result.texcoord[1], {7, -2.75, -0.25, 0.75};\n" "END\n";
const char *mrt_fp_string =
"!!ARBfp1.0\n" "OPTION ARB_draw_buffers;\n"
"MOV result.color[0], fragment.texcoord[0];\n"
"MOV result.color[1], fragment.texcoord[1];\n" "END\n";
unsigned mrt_vp;
unsigned mrt_fp;
GLboolean
test()
{
GLboolean pass = GL_TRUE;
for(frag_clamp = 0; frag_clamp < 3; ++frag_clamp)
{
GLboolean cpass = GL_TRUE;
GLboolean clamped = clamp_enums[frag_clamp] == GL_TRUE || (clamp_enums[frag_clamp] == GL_FIXED_ONLY_ARB && fixed);
printf("MRT rendering in %s mode with fragment clamp %s (expecting %sclamping)\n", mrt_mode_strings[mrt_mode], clamp_strings[frag_clamp], clamped ? "" : "no ");
glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, clamp_enums[frag_clamp]);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, mrt_vp);
glEnable(GL_VERTEX_PROGRAM_ARB);
glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, mrt_fp);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
glClearColor(0.5, 0.5, 0.5, 0.5);
glClear(GL_COLOR_BUFFER_BIT);
piglit_draw_rect(-1, -1, 1, 1);
glDisable(GL_VERTEX_PROGRAM_ARB);
glDisable(GL_FRAGMENT_PROGRAM_ARB);
expected = (clamped || fixed0) ? clamped_pixels : pixels;
expected1 = (clamped || fixed1) ? clamped_pixels : pixels;
glReadBuffer(GL_COLOR_ATTACHMENT0);
printf("Probing buffer 0 (%s)\n", fixed ? "fixed point" : "floating point");
cpass = piglit_probe_pixel_rgba(0, 0, expected) && cpass;