/* * Copyright (C) 2009 VMware, Inc. * Copyright (C) 2017 Advanced Micro Devices, Inc. * All Rights Reserved. * * 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 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 * VMWARE 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. */ #include "common.h" #include #include "piglit-util-gl.h" static bool is_compat; PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 0; config.supports_gl_core_version = 32; for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "-compat")) { config.supports_gl_compat_version = 10; config.supports_gl_core_version = 0; is_compat = true; break; } } puts(config.supports_gl_core_version ? "Using Core profile." : "Using Compatibility profile."); config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_STENCIL; PIGLIT_GL_TEST_CONFIG_END static GLuint prog[2], uniform_loc, tex[8], ubo[4], tbo[8]; static bool indexed; static GLenum enable_enum; void piglit_init(int argc, char **argv) { static const unsigned indices[4] = {0, 1, 2, 3}; GLuint vao, ebo; piglit_require_gl_version(30); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); } static void get_vs_text(char *s, unsigned num_vbos, unsigned num_tbos, bool is_second) { unsigned i; sprintf(s, "#version %u\n", num_tbos ? 140 : 130); strcat(s, "#extension GL_ARB_explicit_attrib_location : require\n"); for (i = 0; i < num_vbos; i++) { sprintf(s + strlen(s), "layout (location = %u) in vec4 v%u;\n", i, i); } strcat(s, "void main() {\n" " gl_Position = vec4(0.0)"); for (i = 0; i < num_vbos; i++) sprintf(s + strlen(s), " + v%u", i); if (is_second) strcat(s, " + vec4(0.5)"); strcat(s, ";\n}\n"); } static void get_fs_text(char *s, unsigned num_ubos, unsigned num_textures, unsigned num_tbos, unsigned num_images, unsigned num_imgbos, bool is_second) { unsigned i; sprintf(s, "#version %u\n", num_tbos ? 140 : 130); strcat(s, "#extension GL_ARB_uniform_buffer_object : require\n"); if (num_images || num_imgbos) strcat(s, "#extension GL_ARB_shader_image_load_store : require\n"); sprintf(s + strlen(s), "uniform int index = 0;\n" "uniform vec4 u[%u];\n", is_second ? 240 : 1); for (i = 0; i < num_textures; i++) sprintf(s + strlen(s), "uniform sampler2D s%u;\n", i); for (i = 0; i < num_tbos; i++) sprintf(s + strlen(s), "uniform samplerBuffer sb%u;\n", i); for (i = 0; i < num_images; i++) sprintf(s + strlen(s), "layout(rgba8) readonly uniform image2D i%u;\n", i); for (i = 0; i < num_imgbos; i++) sprintf(s + strlen(s), "layout(rgba8) readonly uniform imageBuffer ib%u;\n", i); for (i = 0; i < num_ubos; i++) sprintf(s + strlen(s), "uniform ub%u { vec4 ubu%u[10]; };\n", i, i); strcat(s, "void main() {\n"); strcat(s, " gl_FragData[0] = u[index]"); for (i = 0; i < num_textures; i++) sprintf(s + strlen(s), " + texture(s%u, u[0].xy)", i); for (i = 0; i < num_tbos; i++) sprintf(s + strlen(s), " + texelFetch(sb%u, int(u[0].x))", i); for (i = 0; i < num_images; i++) sprintf(s + strlen(s), " + imageLoad(i%u, ivec2(u[0].xy))", i); for (i = 0; i < num_imgbos; i++) sprintf(s + strlen(s), " + imageLoad(ib%u, int(u[0].x))", i); for (i = 0; i < num_ubos; i++) sprintf(s + strlen(s), " + ubu%u[index]", i); if (is_second) strcat(s, " + vec4(0.5)"); strcat(s, ";\n}\n"); } static void setup_shaders_and_resources(unsigned num_vbos, unsigned num_ubos, unsigned num_textures, unsigned num_tbos, unsigned num_images, unsigned num_imgbos) { const unsigned max = 16; char vs[4096], fs[4096]; unsigned p, i; assert(num_vbos <= max); assert(num_ubos <= max); assert(num_textures <= max); assert(num_tbos <= max); for (i = 0; i < max; i++) glDisableVertexAttribArray(i); /* Create two programs in case we want to test program changes. */ for (p = 0; p < 2; p++) { get_vs_text(vs, num_vbos, num_tbos, p); get_fs_text(fs, num_ubos, num_textures, num_tbos, num_images, num_imgbos, p); prog[p] = piglit_build_simple_program(vs, fs); /* Assign texture units to samplers. */ glUseProgram(prog[p]); for (i = 0; i < num_textures; i++) { char sampler[20]; int loc; snprintf(sampler, sizeof(sampler), "s%u", i); loc = glGetUniformLocation(prog[p], sampler); assert(loc >= 0); glUniform1i(loc, i); } /* Assign texture units to samplers. */ for (i = 0; i < num_tbos; i++) { char sampler[20]; int loc; snprintf(sampler, sizeof(sampler), "sb%u", i); loc = glGetUniformLocation(prog[p], sampler); assert(loc >= 0); glUniform1i(loc, num_textures + i); } for (i = 0; i < num_images; i++) { char name[20]; int loc; snprintf(name, sizeof(name), "i%u", i); loc = glGetUniformLocation(prog[p], name); assert(loc >= 0); glUniform1i(loc, i); } for (i = 0; i < num_imgbos; i++) { char name[20]; int loc; snprintf(name, sizeof(name), "ib%u", i); loc = glGetUniformLocation(prog[p], name); assert(loc >= 0); glUniform1i(loc, num_images + i); } /* Assign UBO slots to uniform blocks. */ for (i = 0; i < num_ubos; i++) { char block[20]; int index; snprintf(block, sizeof(block), "ub%u", i); index = glGetUniformBlockIndex(prog[p], block); assert(index != GL_INVALID_INDEX); glUniformBlockBinding(prog[p], index, i); } } glUseProgram(prog[0]); for (i = 0; i < num_ubos; i++) { static const float data[10*4]; GLuint ub; glGenBuffers(1, &ub); glBindBuffer(GL_UNIFORM_BUFFER, ub); glBufferData(GL_UNIFORM_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, i, ub); /* Save the last UBOs for testing UBO changes. */ ubo[i % 4] = ub; } /* setup VBO w/ vertex data, we need a different buffer in each attrib */ for (i = 0; i < num_vbos; i++) { /* Vertex positions are all zeroed - we want all primitives * to be culled. */ static const float vertices[4][3]; GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(i, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); glEnableVertexAttribArray(i); } for (i = 0; i < MAX2(num_textures, num_images); i++) { glActiveTexture(GL_TEXTURE0 + i); /* Save the last texture IDs for testing texture changes. */ tex[i % 8] = piglit_rgbw_texture(GL_RGBA8, 4, 4, false, true, GL_UNSIGNED_BYTE); } for (i = 0; i < MAX2(num_tbos, num_imgbos); i++) { static const float data[10*4]; GLuint buf, tb; glGenBuffers(1, &buf); glBindBuffer(GL_TEXTURE_BUFFER, buf); glBufferData(GL_TEXTURE_BUFFER, sizeof(data), data, GL_STATIC_DRAW); glActiveTexture(GL_TEXTURE0 + num_textures + i); glGenTextures(1, &tb); glBindTexture(GL_TEXTURE_BUFFER, tb); glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA8, buf); /* Save the last TBOs for testing UBO changes. */ tbo[i % 8] = tb; } glActiveTexture(GL_TEXTURE0); } static void draw(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } else { for (i = 0; i < count; i++) glDrawArrays(GL_TRIANGLES, 0, 3); } } static void draw_shader_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glUseProgram(prog[i & 1]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glUseProgram(prog[i & 1]); glDrawArrays(GL_TRIANGLES, 0, 3); } } glUseProgram(prog[0]); } static void draw_uniform_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glUniform4f(uniform_loc, i & 1, 0, 0, 0); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glUniform4f(uniform_loc, i & 1, 0, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_one_texture_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_2D, tex[i & 1]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_2D, tex[i & 1]); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_many_texture_change(unsigned count) { unsigned i,j; if (indexed) { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, tex[(i + j) % 8]); } glActiveTexture(GL_TEXTURE0); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_2D, tex[(i + j) % 8]); } glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_one_tbo_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_BUFFER, tbo[i & 1]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glBindTexture(GL_TEXTURE_BUFFER, tbo[i & 1]); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_many_tbo_change(unsigned count) { unsigned i,j; if (indexed) { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_BUFFER, tbo[(i + j) % 8]); } glActiveTexture(GL_TEXTURE0); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) { glActiveTexture(GL_TEXTURE0 + j); glBindTexture(GL_TEXTURE_BUFFER, tbo[(i + j) % 8]); } glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_one_img_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glBindImageTexture(0, tex[i & 1], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glBindImageTexture(0, tex[i & 1], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_many_img_change(unsigned count) { unsigned i,j; if (indexed) { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) glBindImageTexture(0, tex[(i + j) % 8], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) glBindImageTexture(0, tex[(i + j) % 8], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_one_imgbo_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glBindImageTexture(0, tbo[i & 1], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glBindImageTexture(0, tbo[i & 1], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_many_imgbo_change(unsigned count) { unsigned i,j; if (indexed) { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) glBindImageTexture(0, tbo[(i + j) % 8], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glActiveTexture(GL_TEXTURE0); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { for (j = 0; j < 8; j++) glBindImageTexture(0, tbo[(i + j) % 8], 0, false, 0, GL_READ_ONLY, GL_RGBA8); glActiveTexture(GL_TEXTURE0); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_one_ubo_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo[i & 1]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo[i & 1]); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_many_ubo_change(unsigned count) { unsigned i,j; if (indexed) { for (i = 0; i < count; i++) { for (j = 0; j < 4; j++) glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo[(i + j) % 4]); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { for (j = 0; j < 4; j++) glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo[(i + j) % 4]); glDrawArrays(GL_TRIANGLES, 0, 3); } } } static void draw_state_change(unsigned count) { unsigned i; PFNGLENABLEPROC enable = glEnable; PFNGLDISABLEPROC disable = glDisable; GLenum glenum = enable_enum; if (is_compat && enable_enum == GL_PRIMITIVE_RESTART) { enable = glEnableClientState; disable = glDisableClientState; glenum = GL_PRIMITIVE_RESTART_NV; } if (indexed) { for (i = 0; i < count; i++) { if (i & 1) enable(glenum); else disable(glenum); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { if (i & 1) enable(glenum); else disable(glenum); glDrawArrays(GL_TRIANGLES, 0, 3); } } disable(glenum); } static void draw_scissor_change(unsigned count) { unsigned i; glEnable(GL_SCISSOR_TEST); if (indexed) { for (i = 0; i < count; i++) { if (i & 1) glScissor(0, 0, piglit_width / 2, piglit_height / 2); else glScissor(0, 0, piglit_width, piglit_height); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { if (i & 1) glScissor(0, 0, piglit_width / 2, piglit_height / 2); else glScissor(0, 0, piglit_width, piglit_height); glDrawArrays(GL_TRIANGLES, 0, 3); } } glDisable(GL_SCISSOR_TEST); } static void draw_viewport_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { if (i & 1) glViewport(0, 0, piglit_width / 2, piglit_height / 2); else glViewport(0, 0, piglit_width, piglit_height); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { if (i & 1) glViewport(0, 0, piglit_width / 2, piglit_height / 2); else glViewport(0, 0, piglit_width, piglit_height); glDrawArrays(GL_TRIANGLES, 0, 3); } } glViewport(0, 0, piglit_width, piglit_height); } static void draw_vertex_attrib_change(unsigned count) { unsigned i; if (indexed) { for (i = 0; i < count; i++) { if (i & 1) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); else glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); } } else { for (i = 0; i < count; i++) { if (i & 1) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); else glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(float), NULL); glDrawArrays(GL_TRIANGLES, 0, 3); } } } #define COLOR_RESET "\033[0m" #define COLOR_RED "\033[31m" #define COLOR_GREEN "\033[1;32m" #define COLOR_YELLOW "\033[1;33m" #define COLOR_CYAN "\033[1;36m" static double perf_run(const char *call, unsigned num_vbos, unsigned num_ubos, unsigned num_textures, unsigned num_tbos, unsigned num_images, unsigned num_imgbos, const char *change, perf_rate_func f, double base_rate) { static unsigned test_index; test_index++; double rate = perf_measure_rate(f, 0.5); double ratio = base_rate ? rate / base_rate : 1; printf(" %3u, %s (%2u VBO| %u UBO| %2u %s) w/ %s change,%*s" COLOR_CYAN "%5u" COLOR_RESET ", %s%.1f%%" COLOR_RESET "\n", test_index, call, num_vbos, num_ubos, num_textures ? num_textures : num_tbos ? num_tbos : num_images ? num_images : num_imgbos, num_textures ? "Tex" : num_tbos ? "TBO" : num_images ? "Img" : num_imgbos ? "ImB" : " ", change, MAX2(36 - (int)strlen(change) - (int)strlen(call), 0), "", (unsigned)(rate / 1000), base_rate == 0 ? COLOR_RESET : ratio > 0.7 ? COLOR_GREEN : ratio > 0.4 ? COLOR_YELLOW : COLOR_RED, 100 * ratio); return rate; } struct enable_state_t { GLenum enable; const char *name; }; static struct enable_state_t enable_states[] = { {GL_PRIMITIVE_RESTART, "primitive restart enable"}, {GL_BLEND, "blend enable"}, {GL_DEPTH_TEST, "depth enable"}, {GL_DEPTH_CLAMP, "depth clamp enable"}, {GL_STENCIL_TEST, "stencil enable"}, {GL_SCISSOR_TEST, "scissor enable"}, {GL_MULTISAMPLE, "MSAA enable"}, {GL_SAMPLE_MASK, "sample mask enable"}, {GL_SAMPLE_ALPHA_TO_COVERAGE, "alpha-to-coverage enable"}, {GL_SAMPLE_SHADING, "sample shading enable"}, {GL_CULL_FACE, "cull face enable"}, {GL_CLIP_DISTANCE0, "clip distance enable"}, }; static void perf_draw_variant(const char *call, bool is_indexed) { double base_rate = 0; indexed = is_indexed; /* Test different shader resource usage without state changes. */ unsigned num_ubos = 0; unsigned num_textures = 0; unsigned num_tbos = 0; unsigned num_images = 0; unsigned num_imgbos = 0; unsigned num_vbos; for (num_vbos = 1; num_vbos <= 16; num_vbos *= 4) { setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); double rate = perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "no state", draw, base_rate); if (num_vbos == 1) base_rate = rate; } num_vbos = 1; num_ubos = 0; num_textures = 16; setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "no state", draw, base_rate); /* Test state changes. */ num_ubos = 8; num_textures = 8; for (num_vbos = 1; num_vbos <= 16; num_vbos *= 16) { setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "no state", draw, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "shader program", draw_shader_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "vertex attrib", draw_vertex_attrib_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "1 texture", draw_one_texture_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "8 textures", draw_many_texture_change, base_rate); if (!is_compat) { num_textures = 0; num_tbos = 8; setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "1 TBO", draw_one_tbo_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "8 TBOs", draw_many_tbo_change, base_rate); num_tbos = 0; num_images = 8; setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "1 image", draw_one_img_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "8 images", draw_many_img_change, base_rate); num_images = 0; num_imgbos = 8; setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "1 image buffer", draw_one_imgbo_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "8 image buffers", draw_many_imgbo_change, base_rate); num_imgbos = 0; num_textures = 8; num_tbos = 0; setup_shaders_and_resources(num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos); } perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "1 UBO", draw_one_ubo_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "8 UBOs", draw_many_ubo_change, base_rate); glUseProgram(prog[0]); uniform_loc = glGetUniformLocation(prog[0], "u"); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "few uniforms / 1", draw_uniform_change, base_rate); glUseProgram(prog[1]); uniform_loc = glGetUniformLocation(prog[1], "u"); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "many uniforms / 1", draw_uniform_change, base_rate); glUseProgram(prog[0]); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "scissor", draw_scissor_change, base_rate); perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, "viewport", draw_viewport_change, base_rate); for (int state = 0; state < ARRAY_SIZE(enable_states); state++) { enable_enum = enable_states[state].enable; perf_run(call, num_vbos, num_ubos, num_textures, num_tbos, num_images, num_imgbos, enable_states[state].name, draw_state_change, base_rate); } } } /** Called from test harness/main */ enum piglit_result piglit_display(void) { puts(" #, Test name , Thousands draws/s, Difference vs the 1st"); perf_draw_variant("DrawElements", true); perf_draw_variant("DrawArrays", false); exit(0); return PIGLIT_SKIP; }