summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2015-12-03 11:29:34 -0700
committerBrian Paul <brianp@vmware.com>2016-02-02 10:06:35 -0700
commit126f1772c197f4b4027ce0130ed46aea013e3656 (patch)
tree7ff08e02e4789f3a0b32abdf3b8e6ed407310ad5
parentfca1062e8bdeaff6bedcd43fba718a0f78aa3c77 (diff)
downloadmesa-demos-126f1772c197f4b4027ce0130ed46aea013e3656.zip
mesa-demos-126f1772c197f4b4027ce0130ed46aea013e3656.tar.xz
perf: add new glsl-compile-time test program
Generates large shaders and measures the time to compile, link and draw.
-rw-r--r--src/perf/CMakeLists.txt1
-rw-r--r--src/perf/Makefile.am2
-rw-r--r--src/perf/glsl-compile-time.c314
3 files changed, 317 insertions, 0 deletions
diff --git a/src/perf/CMakeLists.txt b/src/perf/CMakeLists.txt
index 68b6875..66a291f 100644
--- a/src/perf/CMakeLists.txt
+++ b/src/perf/CMakeLists.txt
@@ -25,6 +25,7 @@ set (targets
fbobind
fill
genmipmap
+ glsl-compile-time
readpixels
swapbuffers
teximage
diff --git a/src/perf/Makefile.am b/src/perf/Makefile.am
index 5363c58..f0031fe 100644
--- a/src/perf/Makefile.am
+++ b/src/perf/Makefile.am
@@ -48,6 +48,7 @@ bin_PROGRAMS = \
fbobind \
fill \
genmipmap \
+ glsl-compile-time \
readpixels \
swapbuffers \
teximage \
@@ -57,3 +58,4 @@ bin_PROGRAMS = \
endif
glslstateschange_LDADD = libperf.la ../util/libutil.la
+glsl_compile_time_LDADD = ../util/libutil.la
diff --git a/src/perf/glsl-compile-time.c b/src/perf/glsl-compile-time.c
new file mode 100644
index 0000000..917073c
--- /dev/null
+++ b/src/perf/glsl-compile-time.c
@@ -0,0 +1,314 @@
+/**
+ * Test compilation, link, draw time for very large shaders.
+ * Command line arguments:
+ * -v verbose output (print shader code)
+ * -c N generate shaders of complexity N
+ * -n N generate and draw with N shader programs
+ *
+ * Brian Paul
+ * 3 Dec 2015
+ */
+
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glew.h>
+#include "glut_wrap.h"
+#include "shaderutil.h"
+
+
+#define MAX_PROGRAMS 10000
+
+static int Win;
+static int WinWidth = 400, WinHeight = 400;
+static int verbose = 0;
+static int num_shaders = 1;
+static int complexity = 5;
+static int programs[MAX_PROGRAMS];
+
+static const float u1_val[4] = {.1, .2, .3, .4};
+static const float u2_val[4] = {.6, .7, .8, .9};
+
+static const char *VS_code =
+ "void main()\n"
+ "{\n"
+ " gl_Position = ftransform();\n"
+ "}\n";
+
+static const float coords[3][4] = {
+ {0, 0.1, 0, 1},
+ {0, 0, 0, 1},
+ {0, -0.1, 0, 1}
+};
+
+#define NUM_POINTS (sizeof(coords) / sizeof(coords[0]))
+
+
+
+struct dynamic_string {
+ char *buffer;
+ unsigned len;
+ unsigned buffer_size;
+};
+
+
+static void
+append_string(struct dynamic_string *ds, const char *s)
+{
+ int l = strlen(s);
+ if (ds->len + l >= ds->buffer_size) {
+ /* grow buffer */
+ int newsize = ds->buffer_size + l + 4096;
+ char *newbuf = malloc(newsize);
+ assert(newbuf);
+ if (ds->buffer)
+ strcpy(newbuf, ds->buffer);
+ free(ds->buffer);
+ ds->buffer = newbuf;
+ ds->buffer_size = newsize;
+ }
+ strcpy(ds->buffer + ds->len, s);
+ ds->len += l;
+ assert(strlen(ds->buffer) == ds->len);
+}
+
+
+/**
+ * Index is a term put into the shader code to make each shader a little
+ * different.
+ */
+static char *
+gen_large_shader(int num_functions, int index)
+{
+ int i;
+ struct dynamic_string ds = {0};
+ char s[100];
+
+ append_string(&ds, "#version 120\n");
+ append_string(&ds, "\nuniform vec4 u1, u2;\n\n");
+
+ for (i = 0; i < num_functions; i++) {
+ snprintf(s, sizeof(s), "vec4 func%d(vec4 a, float b)\n", i);
+ append_string(&ds, s);
+ append_string(&ds, "{\n");
+ if (i == 0) {
+ append_string(&ds, " return a * b;\n");
+ }
+ else {
+ snprintf(s, sizeof(s),
+ " vec4 s = a * func%d(a, float(%d)) + vec4(b);\n",
+ i-1, index);
+ append_string(&ds, s);
+
+ snprintf(s, sizeof(s),
+ " vec4 t = a / func%d(a, 3.0) - vec4(b);\n", i-1);
+ append_string(&ds, s);
+
+ if (i & 1) {
+ append_string(&ds, " vec4 u = max(s, t);\n");
+ }
+ else {
+ /* use a conditional */
+ append_string(&ds, " vec4 u = min(s, t);\n");
+ append_string(&ds, " if (s.x > t.x) {\n");
+ snprintf(s, sizeof(s), " u = vec4(%d);\n", i);
+ append_string(&ds, s);
+ append_string(&ds, " }\n");
+ }
+
+ append_string(&ds, " return u;\n");
+ }
+
+ append_string(&ds, "}\n\n");
+ }
+
+ append_string(&ds, "void main()\n");
+ append_string(&ds, "{\n");
+ snprintf(s, sizeof(s), " gl_FragColor = func%d(u1, u2.x);\n", i-1);
+ append_string(&ds, s);
+ append_string(&ds, "}\n");
+
+ return ds.buffer;
+}
+
+
+static void
+Draw(void)
+{
+ int t0, t1;
+ int i;
+ int fixed_func_time = 0, glsl_time_1 = 0, glsl_time_2 = 0;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ for (i = 0; i < num_shaders; i++) {
+ UseProgram(0);
+ t0 = glutGet(GLUT_ELAPSED_TIME);
+ glDrawArrays(GL_POINTS, 0, NUM_POINTS);
+ glFinish();
+ t1 = glutGet(GLUT_ELAPSED_TIME);
+ fixed_func_time += t1 - t0;
+
+ UseProgram(programs[i]);
+ t0 = glutGet(GLUT_ELAPSED_TIME);
+ glDrawArrays(GL_POINTS, 0, NUM_POINTS);
+ glFinish();
+ t1 = glutGet(GLUT_ELAPSED_TIME);
+ glsl_time_1 += t1 - t0;
+
+ t0 = glutGet(GLUT_ELAPSED_TIME);
+ glDrawArrays(GL_POINTS, 0, NUM_POINTS);
+ glFinish();
+ t1 = glutGet(GLUT_ELAPSED_TIME);
+ glsl_time_2 += t1 - t0;
+ }
+
+ printf("Time to draw fixed-function points: %d ms\n", fixed_func_time);
+ printf("Time to draw 1st GLSL shader points: %d ms\n", glsl_time_1);
+ printf("Time to draw 2st GLSL shader points: %d ms\n", glsl_time_2);
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -15.0);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ if (key == 27) {
+ glutDestroyWindow(Win);
+ exit(0);
+ }
+ glutPostRedisplay();
+}
+
+
+static GLuint
+create_shader_program(const char *fs_code,
+ int *compile_time, int *link_time)
+{
+ GLuint fragShader;
+ GLuint vertShader;
+ GLuint program;
+ GLint u1_loc, u2_loc;
+ GLint t0, t1, t2;
+
+ vertShader = CompileShaderText(GL_VERTEX_SHADER, VS_code);
+
+ t0 = glutGet(GLUT_ELAPSED_TIME);
+ fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fs_code);
+ t1 = glutGet(GLUT_ELAPSED_TIME);
+ program = LinkShaders(vertShader, fragShader);
+ t2 = glutGet(GLUT_ELAPSED_TIME);
+
+ UseProgram(program);
+ u1_loc = glGetUniformLocation(program, "u1");
+ u2_loc = glGetUniformLocation(program, "u2");
+ glUniform4fv(u1_loc, 1, u1_val);
+ glUniform4fv(u2_loc, 1, u2_val);
+ UseProgram(0);
+
+ *compile_time = t1 - t0;
+ *link_time = t2 - t1;
+
+ assert(glGetError() == GL_NO_ERROR);
+
+ return program;
+}
+
+
+static void
+Init(void)
+{
+ GLuint vbo;
+ int i, compile_time, link_time, total_compile_time, total_link_time;
+
+ if (!ShadersSupported())
+ exit(1);
+
+ printf("Shader complexity: %d\n", complexity);
+ printf("Num shaders: %d\n", num_shaders);
+
+ total_compile_time = total_link_time = 0;
+
+ /* create the shader programs */
+ for (i = 0; i < num_shaders; i++) {
+ char *fs_code = gen_large_shader(complexity, i);
+
+ if (verbose && i==0) {
+ printf("Shader[0] code:\n%s\n", fs_code);
+ }
+
+ programs[i] = create_shader_program(fs_code, &compile_time, &link_time);
+ total_compile_time += compile_time;
+ total_link_time += link_time;
+
+ free(fs_code);
+ }
+
+ printf("Total glCompileShader() time: %d ms\n", total_compile_time);
+ printf("Total glLinkProgram() time: %d ms\n", total_link_time);
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(coords), coords, GL_STATIC_DRAW);
+ glVertexPointer(4, GL_FLOAT, 0, NULL);
+ glEnable(GL_VERTEX_ARRAY);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+
+ glutInit(&argc, argv);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ Win = glutCreateWindow(argv[0]);
+ glewInit();
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Draw);
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-v") == 0) {
+ verbose = 1;
+ }
+ else if (strcmp(argv[i], "-c") == 0) {
+ i++;
+ complexity = atoi(argv[i]);
+ }
+ else if (strcmp(argv[i], "-n") == 0) {
+ i++;
+ num_shaders = atoi(argv[i]);
+ }
+ else {
+ printf("unexpected option: %s\n", argv[i]);
+ exit(1);
+ }
+ }
+
+ Init();
+
+ glutMainLoop();
+ return 0;
+}