/* * Copyright © 2012 Intel Corporation * * 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 minmax.c * Verify that minimum value requirements for implementation limits are * satisfied. */ #include #include "piglit-util-gl.h" PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 10; config.window_visual = PIGLIT_GL_VISUAL_RGB; PIGLIT_GL_TEST_CONFIG_END /* These are all the formats that are required to be color-renderable by the * OpenGL 3.0 spec. */ static const GLenum valid_formats[] = { GL_RGBA32F, GL_RGBA16, GL_RGBA16F, GL_RGBA8, GL_SRGB8_ALPHA8, GL_R11F_G11F_B10F, GL_RG32F, GL_RG16, GL_RG16F, GL_RG8, GL_R32F, GL_R16, GL_R16F, GL_R8, GL_ALPHA8, }; static const GLenum valid_integer_formats[] = { GL_RGBA32I, GL_RGBA32UI, GL_RGBA16I, GL_RGBA16UI, GL_RGBA8I, GL_RGBA8UI, GL_RG32I, GL_RG32UI, GL_RG16I, GL_RG16UI, GL_RG8I, GL_RG8UI, GL_R32I, GL_R32UI, GL_R16I, GL_R16UI, GL_R8I, GL_R8UI, }; static const GLenum valid_depth_formats[] = { GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT32F, }; static const GLenum valid_targets_with_tms[] = { GL_RENDERBUFFER, GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_2D_MULTISAMPLE_ARRAY, }; enum piglit_result piglit_display(void) { return PIGLIT_FAIL; } static bool try(GLenum target, GLenum format, GLint max_samples, const char *max_samples_name) { bool pass = true; GLint *buffer; int buffer_size_in_elements = 0; size_t buffer_size_in_bytes; unsigned i; GLint previous; glGetInternalformativ(target, format, GL_NUM_SAMPLE_COUNTS, 1, &buffer_size_in_elements); pass = piglit_check_gl_error(0) && pass; /* The GL_ARB_internalformat_query spec says: * * "Add new table 6.X Internalformat-specific Implementation * Dependent Values after 6.52" * * Minimum * Get Value Type Get Command Value * --------- ---- ----------- ------- * SAMPLES 0*xZ+ GetInternalformativ fn1 * NUM_SAMPLE_COUNTS Z+ GetInternalformativ 1 * * fn1: see section 6.X." */ if (buffer_size_in_elements < 1) { fprintf(stderr, "GL_NUM_SAMPLE_COUNTS is %d for %s/%s\n", buffer_size_in_elements, piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); return false; } buffer_size_in_bytes = buffer_size_in_elements * sizeof(GLint); buffer = malloc(buffer_size_in_bytes); /* Try GL_SAMPLES */ glGetInternalformativ(target, format, GL_SAMPLES, buffer_size_in_elements, buffer); pass = piglit_check_gl_error(0) && pass; /* The GL_ARB_internalformat_query spec says: * * "- SAMPLES: The sample counts supported for this and * are written into , in descending * order. Only positive values are returned." * * We take "positive" to mean greater than zero. Zero isn't a valid * sample count for multisampling. It's the special value used to * request non-multisampling. */ previous = INT_MAX; for (i = 0; i < buffer_size_in_elements; i++) { if (buffer[i] <= 0) { fprintf(stderr, "Invalid sample count [%u] = %d returned " "for %s/%s\n", i, buffer[i], piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); pass = false; } if (previous == buffer[i]) { fprintf(stderr, "Duplicate values [%u] = [%u] = %d returned " "for %s/%s\n", i - 1, i, buffer[i], piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); pass = false; } if (previous < buffer[i]) { fprintf(stderr, "Values not in descending order " "([%u] = %d) < ([%u] = %d) returned " "for %s/%s\n", i - 1, previous, i, buffer[i], piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); pass = false; } previous = buffer[i]; } /* The GL_ARB_internalformat_query spec says: * * "The maximum value in SAMPLES is guaranteed to be at least the * lowest of the following: * * - The value of GetIntegerv(MAX_INTEGER_SAMPLES), if * is a signed or unsigned integer format. * - The value of GetIntegerv(MAX_DEPTH_TEXTURE_SAMPLES), if * is a depth/stencil-renderable format and * is TEXTURE_2D_MULTISAMPLE or * TEXTURE_2D_MULTISAMPLE_ARRAY. * - The value of GetIntegerv(MAX_COLOR_TEXTURE_SAMPLES), if * is a color-renderable format and * is TEXTURE_2D_MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY. * - The value of GetIntegerv(MAX_SAMPLES)." * * Separate tests will verify the values for GL_MAX_*_SAMPLES. */ if (buffer[0] < max_samples) { fprintf(stderr, "GL_SAMPLES (%d) smaller than %s (%d) " "for %s/%s\n", buffer[0], max_samples_name, max_samples, piglit_get_gl_enum_name(target), piglit_get_gl_enum_name(format)); pass = false; } free(buffer); return pass; } void piglit_init(int argc, char **argv) { bool pass = true; unsigned i; const bool tms_supported = piglit_is_extension_supported("GL_ARB_texture_multisample"); GLint max_samples; piglit_require_extension("GL_ARB_framebuffer_object"); piglit_require_extension("GL_ARB_internalformat_query"); /* ARB_internalformat_query2 redefines and extend this * extension. That extension have their own tests*/ piglit_require_not_extension("GL_ARB_internalformat_query2"); /* Need GL 3 or extensions to support the valid_formats[] above */ if (piglit_get_gl_version() < 30) { piglit_require_extension("GL_ARB_texture_rg"); piglit_require_extension("GL_ARB_texture_float"); } glGetIntegerv(GL_MAX_SAMPLES, &max_samples); for (i = 0; i < ARRAY_SIZE(valid_formats); i++) { pass = try(GL_RENDERBUFFER, valid_formats[i], max_samples, "GL_MAX_SAMPLES") && pass; } if (!tms_supported) { for (i = 0; i < ARRAY_SIZE(valid_depth_formats); i++) { pass = try(GL_RENDERBUFFER, valid_depth_formats[i], max_samples, "GL_MAX_SAMPLES") && pass; } /* The OpenGL 3.1 spec says: * * "The error INVALID_OPERATION may be generated if * internalformat is a signed or unsigned integer format, * samples is greater than one, and the implementation * does not support multisampled integer renderbuffers * (see “Required Renderbuffer Formats” below)." * * In OpenGL 3.2 or ARB_texture_multisample the query * GL_MAX_INTEGER_SAMPLES is used to determine the maximum * number of samples for integer buffers. This is checked in * the other code path. */ for (i = 0; i < ARRAY_SIZE(valid_integer_formats); i++) { pass = try(GL_RENDERBUFFER, valid_integer_formats[i], 1, "one") && pass; } } else { for (i = 0; i < ARRAY_SIZE(valid_targets_with_tms); i++) { const char *max_samples_name; unsigned j; if (valid_targets_with_tms[i] == GL_RENDERBUFFER) { glGetIntegerv(GL_MAX_SAMPLES, &max_samples); max_samples_name = "GL_MAX_SAMPLES"; } else { glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &max_samples); max_samples_name = "GL_MAX_COLOR_TEXTURE_SAMPLES"; } for (j = 0; j < ARRAY_SIZE(valid_formats); j++) { pass = try(valid_targets_with_tms[i], valid_formats[j], max_samples, max_samples_name) && pass; } if (valid_targets_with_tms[i] == GL_RENDERBUFFER) { glGetIntegerv(GL_MAX_SAMPLES, &max_samples); max_samples_name = "GL_MAX_SAMPLES"; } else { glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &max_samples); max_samples_name = "GL_MAX_DEPTH_TEXTURE_SAMPLES"; } for (j = 0; j < ARRAY_SIZE(valid_depth_formats); j++) { pass = try(valid_targets_with_tms[i], valid_depth_formats[j], max_samples, max_samples_name) && pass; } glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &max_samples); max_samples_name = "GL_MAX_INTEGER_SAMPLES"; for (j = 0; j < ARRAY_SIZE(valid_integer_formats); j++) { pass = try(valid_targets_with_tms[i], valid_integer_formats[j], max_samples, max_samples_name) && pass; } } } piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL); }