From bec2598d283fffe493b2b764863ca801a4f35e8e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 7 Oct 2013 16:21:57 -0700 Subject: arb_shader_atomic_counters: Import common helper functions. --- tests/all.tests | 3 + tests/spec/CMakeLists.txt | 1 + .../arb_shader_atomic_counters/CMakeLists.gl.txt | 13 + .../spec/arb_shader_atomic_counters/CMakeLists.txt | 1 + tests/spec/arb_shader_atomic_counters/common.c | 302 +++++++++++++++++++++ tests/spec/arb_shader_atomic_counters/common.h | 90 ++++++ 6 files changed, 410 insertions(+) create mode 100644 tests/spec/arb_shader_atomic_counters/CMakeLists.gl.txt create mode 100644 tests/spec/arb_shader_atomic_counters/CMakeLists.txt create mode 100644 tests/spec/arb_shader_atomic_counters/common.c create mode 100644 tests/spec/arb_shader_atomic_counters/common.h diff --git a/tests/all.tests b/tests/all.tests index abe247ef7..e1907d6c9 100644 --- a/tests/all.tests +++ b/tests/all.tests @@ -3165,6 +3165,9 @@ add_shader_test_dir(spec, os.path.join(generatedTestDir, 'spec'), recursive=True) import_glsl_parser_tests(profile.tests, generatedTestDir, ['spec']) +arb_shader_atomic_counters = Group() +spec['ARB_shader_atomic_counters'] = arb_shader_atomic_counters + profile.tests['hiz'] = hiz profile.tests['fast_color_clear'] = fast_color_clear profile.tests['glean'] = glean diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt index 18b846d61..011fd632c 100644 --- a/tests/spec/CMakeLists.txt +++ b/tests/spec/CMakeLists.txt @@ -24,6 +24,7 @@ add_subdirectory (amd_seamless_cubemap_per_texture) add_subdirectory (amd_vertex_shader_layer) add_subdirectory (arb_separate_shader_objects) add_subdirectory (arb_shader_texture_lod/execution) +add_subdirectory (arb_shader_atomic_counters) add_subdirectory (arb_shader_objects) add_subdirectory (arb_shading_language_420pack/execution) add_subdirectory (arb_sync) diff --git a/tests/spec/arb_shader_atomic_counters/CMakeLists.gl.txt b/tests/spec/arb_shader_atomic_counters/CMakeLists.gl.txt new file mode 100644 index 000000000..b204c0247 --- /dev/null +++ b/tests/spec/arb_shader_atomic_counters/CMakeLists.gl.txt @@ -0,0 +1,13 @@ +include_directories( + ${GLEXT_INCLUDE_DIR} + ${OPENGL_INCLUDE_PATH} + ${piglit_SOURCE_DIR}/tests/util +) + +link_libraries ( + piglitutil_${piglit_target_api} + ${OPENGL_gl_LIBRARY} + ${OPENGL_glu_LIBRARY} +) + +# vim: ft=cmake: diff --git a/tests/spec/arb_shader_atomic_counters/CMakeLists.txt b/tests/spec/arb_shader_atomic_counters/CMakeLists.txt new file mode 100644 index 000000000..144a306f4 --- /dev/null +++ b/tests/spec/arb_shader_atomic_counters/CMakeLists.txt @@ -0,0 +1 @@ +piglit_include_target_api() diff --git a/tests/spec/arb_shader_atomic_counters/common.c b/tests/spec/arb_shader_atomic_counters/common.c new file mode 100644 index 000000000..638d5afa8 --- /dev/null +++ b/tests/spec/arb_shader_atomic_counters/common.c @@ -0,0 +1,302 @@ +/* + * Copyright © 2013 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 common.c + * + * Common utility functions for the ARB_shader_atomic_counters tests. + */ + +#include "common.h" + +bool +atomic_counters_probe_buffer(unsigned base, unsigned count, + const uint32_t *expected) +{ + uint32_t *p = glMapBufferRange( + GL_ATOMIC_COUNTER_BUFFER, base * sizeof(uint32_t), + count * sizeof(uint32_t), GL_MAP_READ_BIT); + unsigned i; + + if (!p) { + printf("Couldn't map atomic counter buffer for read-back.\n"); + return false; + } + + for (i = 0; i < count; ++i) { + if (p[i] != expected[i]) { + printf("Probe value at (%i)\n", i); + printf(" Expected: 0x%08x\n", expected[i]); + printf(" Observed: 0x%08x\n", p[i]); + glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); + return false; + } + } + + glUnmapBuffer(GL_ATOMIC_COUNTER_BUFFER); + return true; +} + +bool +atomic_counters_compile(GLuint prog, GLuint stage, const char *src) +{ + GLuint shader = glCreateShader(stage); + int status, log_size; + char *log; + + glShaderSource(shader, 1, (const GLchar **)&src, NULL); + glCompileShader(shader); + + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + + if (status) { + glAttachShader(prog, shader); + } else { + glGetShaderiv(prog, GL_INFO_LOG_LENGTH, &log_size); + log = malloc(log_size); + glGetShaderInfoLog(prog, log_size, NULL, log); + + printf("Failed to compile shader: %s\n", log); + printf("source:\n%s", src); + + free(log); + } + + glDeleteShader(shader); + + return status; +} + +bool +atomic_counters_link(GLuint prog) +{ + int status; + + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if (!status) { + glLinkProgram(prog); + glGetProgramiv(prog, GL_LINK_STATUS, &status); + } + + return status; +} + +bool +atomic_counters_draw_point(GLuint prog, unsigned buf_size, + const uint32_t *buf) +{ + /* Initialize the atomic counter buffer. */ + glBufferData(GL_ATOMIC_COUNTER_BUFFER, + buf_size * sizeof(uint32_t), + buf, GL_STATIC_DRAW); + + /* Link and set the current shader program. */ + atomic_counters_link(prog); + glUseProgram(prog); + + /* Draw. */ + glClearColor(0.5, 0.5, 0.5, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + glVertexAttrib4f(0, 0, 0, 0, 1); + glDrawArrays(GL_POINTS, 0, 1); + + return piglit_check_gl_error(GL_NO_ERROR); +} + +bool +atomic_counters_draw_rect(GLuint prog, unsigned buf_size, const uint32_t *buf) +{ + /* Initialize the atomic counter buffer. */ + glBufferData(GL_ATOMIC_COUNTER_BUFFER, + buf_size * sizeof(uint32_t), + buf, GL_STATIC_DRAW); + + /* Set current shader program. */ + glLinkProgram(prog); + glUseProgram(prog); + + /* Draw. */ + glClearColor(0.5, 0.5, 0.5, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + piglit_draw_rect(-1, -1, 2, 2); + + return piglit_check_gl_error(GL_NO_ERROR); +} + +bool +atomic_counters_draw_patch(GLuint prog, unsigned buf_size, + const uint32_t *buf) +{ + + const GLfloat verts[3][4] = { { 0.0, 0.0, 0.0, 1.0 }, + { 1.0, 0.0, 0.0, 1.0 }, + { 0.0, 1.0, 0.0, 1.0 } }; + GLuint vao, vbo; + + /* Initialize the atomic counter buffer. */ + glBufferData(GL_ATOMIC_COUNTER_BUFFER, + buf_size * sizeof(uint32_t), + buf, GL_STATIC_DRAW); + + /* Set current shader program. */ + glLinkProgram(prog); + glUseProgram(prog); + + /* Initialize a vertex array object and a vertex buffer object. */ + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); + + /* Set up the current vertex attributes. */ + glVertexAttribPointer(PIGLIT_ATTRIB_POS, 4, GL_FLOAT, + GL_FALSE, 0, 0); + glEnableVertexAttribArray(PIGLIT_ATTRIB_POS); + + /* Draw. */ + glClearColor(0.5, 0.5, 0.5, 0.5); + glClear(GL_COLOR_BUFFER_BIT); + + glDrawArrays(GL_PATCHES, 0, 3); + + /* Clean up. */ + glDisableVertexAttribArray(PIGLIT_ATTRIB_POS); + glDeleteBuffers(1, &vbo); + glDeleteVertexArrays(1, &vao); + + return piglit_check_gl_error(GL_NO_ERROR); +} + +bool +atomic_counters_supported(GLenum shader_stage) +{ + int n = 0; + + switch (shader_stage) { + case GL_NONE: + case GL_FRAGMENT_SHADER: + return true; + + case GL_VERTEX_SHADER: + glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &n); + return n; + + case GL_GEOMETRY_SHADER: + if (piglit_is_extension_supported("GL_ARB_geometry_shader4")) + glGetIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTERS, &n); + return n; + + case GL_TESS_CONTROL_SHADER: + if (piglit_is_extension_supported("GL_ARB_tesselation_shader")) + glGetIntegerv(GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS, &n); + return n; + + case GL_TESS_EVALUATION_SHADER: + if (piglit_is_extension_supported("GL_ARB_tesselation_shader")) + glGetIntegerv(GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS, + &n); + return n; + + default: + assert(!"Unreachable"); + } +} + +struct atomic_counters_limits +atomic_counters_get_limits() +{ + struct atomic_counters_limits ls = { 0 }; + + piglit_require_extension("GL_ARB_shader_atomic_counters"); + + glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, + &ls.fragment_counters); + glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, + &ls.vertex_counters); + glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTERS, + &ls.combined_counters); + glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, + &ls.fragment_buffers); + glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, + &ls.vertex_buffers); + glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, + &ls.combined_buffers); + glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, + &ls.bindings); + glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, + &ls.uniform_components); + + return ls; +} + +static char * +iterate_template(const char *template, unsigned n) +{ + char *ss; + int i, ret; + + ss = strdup(""); + assert(ss); + + for (i = 0; i < n; ++i) { + char *s, *tmp = ss; + + ret = asprintf(&s, template, i); + assert(ret >= 0); + + ret = asprintf(&ss, "%s%s", tmp, s); + assert(ret >= 0); + + free(tmp); + free(s); + } + + return ss; +} + +/** + * Generate source code by substituting the first occurrence of "%s" + * in \a src_template with \a n copies of \a decl_template and the + * second occurrence of "%s" with \a n copies of \a insn_template. + */ +char * +atomic_counters_generate_source(const char *src_template, + const char *decl_template, + const char *insn_template, unsigned n) +{ + char *decls = iterate_template(decl_template, n); + char *insns = iterate_template(insn_template, n); + char *src; + int ret; + + ret = asprintf(&src, src_template, decls, insns); + assert(ret); + + free(decls); + free(insns); + + return src; +} + diff --git a/tests/spec/arb_shader_atomic_counters/common.h b/tests/spec/arb_shader_atomic_counters/common.h new file mode 100644 index 000000000..f9772daf9 --- /dev/null +++ b/tests/spec/arb_shader_atomic_counters/common.h @@ -0,0 +1,90 @@ +/* + * Copyright © 2013 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 common.c + * + * Common utility functions for the ARB_shader_atomic_counters tests. + */ + +#ifndef __PIGLIT_ARB_SHADER_ATOMIC_COUNTERS_COMMON_H__ +#define __PIGLIT_ARB_SHADER_ATOMIC_COUNTERS_COMMON_H__ + +#include "piglit-util-gl-common.h" + +bool +atomic_counters_probe_buffer(unsigned base, unsigned count, + const uint32_t *expected); + +bool +atomic_counters_compile(GLuint prog, GLuint stage, const char *src); + +bool +atomic_counters_link(GLuint prog); + +bool +atomic_counters_draw_point(GLuint prog, unsigned buf_size, + const uint32_t *buf); + +bool +atomic_counters_draw_rect(GLuint prog, unsigned buf_size, + const uint32_t *buf); + +bool +atomic_counters_draw_patch(GLuint prog, unsigned buf_size, + const uint32_t *buf); + +bool +atomic_counters_supported(GLenum shader_stage); + +char * +atomic_counters_generate_source(const char *src_template, const char *decl_template, + const char *insn_template, unsigned n); + +struct atomic_counters_limits { + int fragment_counters; + int vertex_counters; + int combined_counters; + int fragment_buffers; + int vertex_buffers; + int combined_buffers; + int bindings; + int uniform_components; +}; + +struct atomic_counters_limits +atomic_counters_get_limits(); + +#define atomic_counters_subtest(status, shader_stage, name, func, ...) do { \ + if (atomic_counters_supported(shader_stage)) { \ + if (func(__VA_ARGS__)) { \ + piglit_report_subtest_result(PIGLIT_PASS, name); \ + } else { \ + piglit_report_subtest_result(PIGLIT_FAIL, name); \ + *status = PIGLIT_FAIL; \ + } \ + } else { \ + piglit_report_subtest_result(PIGLIT_SKIP, name); \ + } \ + } while (0) + +#endif -- cgit v1.2.3