diff options
author | Jerome Glisse <jglisse@redhat.com> | 2012-10-24 18:59:36 -0400 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2012-10-24 14:47:59 -0400 |
commit | 30d8ae33220575af708dde9c411e297922f87a09 (patch) | |
tree | 381ac6aacb34da7ffa854d3d92e1685b647f9701 | |
parent | fb4cc9ec04c171b74d482bee54f52909d92a1a55 (diff) |
add msaa test case
Signed-off-by: Jerome Glisse <jglisse@redhat.com>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | glgears-box-msaa.c | 541 |
2 files changed, 542 insertions, 1 deletions
@@ -2,7 +2,7 @@ CC = gcc CFLAGS = -I . -g -O0 -Wall -std=c99 -lGL -lGLU -lm -D_BSD_SOURCE TARGETS = amd-gpu-name glgears glgears-box glgears-box-cstrealloc \ - gltransformfeedback glclear-depth + gltransformfeedback glclear-depth glgears-box-msaa all: $(TARGETS) diff --git a/glgears-box-msaa.c b/glgears-box-msaa.c new file mode 100644 index 0000000..ce18baa --- /dev/null +++ b/glgears-box-msaa.c @@ -0,0 +1,541 @@ +/* + * Copyright (C) 1999-2001 Brian Paul 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 + * BRIAN PAUL 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. + */ +/* + * This is a port of the infamous "glxgears" demo to straight EGL + * Port by Dane Rushton 10 July 2005 + * + * No command line options. + * Program runs for 5 seconds then exits, outputing framerate to console + */ +#define MAXFRAME 5 +#define PFINISH 1 +#define NSAMPLE 4 + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#define GL_GLEXT_PROTOTYPES +#include <GL/glew.h> +#include <GL/glut.h> + +static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0; +static GLint gear1, gear2, gear3; +static GLfloat angle = 0.0; +static GLfloat cube_rot = 0.0; +static GLuint msaa_fbo, gears_fbo, gears_tex; +static GLuint win_width = 1024; +static GLuint win_height = 512; +static GLuint frames = 0; +static GLuint renderbuffers[8]; +static GLuint nrenderbuffers = 0; + +void generate_simple_fbo(unsigned width, unsigned height) +{ + GLuint fb; + GLenum status; + unsigned color, stencil, depth, packed; + + color = stencil = depth = packed = 1; + + /* texture */ + glGenTextures(1, &gears_tex); + glBindTexture(GL_TEXTURE_2D, gears_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gears_tex, 0); + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + fprintf(stderr, + "Framebuffer %s color, %s stencil (%s) was not " + "complete: 0x%04x\n", + color ? "with" : "without", + stencil ? "with" : "without", + packed ? "packed" : "separate", + status); + exit(1); + } + status = glGetError(); + if (status != GL_NO_ERROR) { + fprintf(stderr, "%d Unexpected GL error: 0x%x\n", __LINE__, status); + exit(1); + } + gears_fbo = fb; + glClearColor(0.2, 0.4, 0.6, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + + glGenFramebuffers(1, &fb); + glBindFramebuffer(GL_FRAMEBUFFER, fb); + if (color) { + glGenRenderbuffers(1, &renderbuffers[nrenderbuffers]); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, NSAMPLE, GL_RGBA, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + nrenderbuffers++; + } + + if (stencil) { + const GLenum format = (packed) + ? GL_DEPTH24_STENCIL8 + : GL_STENCIL_INDEX8; + const GLenum attachment = (packed) + ? GL_DEPTH_STENCIL_ATTACHMENT + : GL_STENCIL_ATTACHMENT; + + glGenRenderbuffers(1, &renderbuffers[nrenderbuffers]); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, NSAMPLE, format, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + nrenderbuffers++; + } + status = glGetError(); + if (status != GL_NO_ERROR) { + fprintf(stderr, "%d Unexpected GL error: 0x%x %s\n", __LINE__, status, gluErrorString(status)); + exit(1); + } + + if (!packed && depth) { + glGenRenderbuffers(1, &renderbuffers[nrenderbuffers]); + glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, NSAMPLE, GL_DEPTH_COMPONENT24, width, height); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffers[nrenderbuffers]); + nrenderbuffers++; + } + + status = glGetError(); + if (status != GL_NO_ERROR) { + fprintf(stderr, "%d Unexpected GL error: 0x%x %s\n", __LINE__, status, gluErrorString(status)); + exit(1); + } + + /* All of the possible combinations that we can generate are required + * to be supported by all OpenGL 3.0 implementations, with one + * exception. As far as I can tell, implementations are not required + * to support separate depth and stencil. That one option is handled + * specially. + */ + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE + && !(status == GL_FRAMEBUFFER_UNSUPPORTED && stencil && !packed)) { + fprintf(stderr, + "Framebuffer %s color, %s stencil (%s) was not " + "complete: 0x%04x\n", + color ? "with" : "without", + stencil ? "with" : "without", + packed ? "packed" : "separate", + status); + exit(1); + } + + if (status == GL_FRAMEBUFFER_UNSUPPORTED) { + glDeleteRenderbuffers(nrenderbuffers, renderbuffers); + glDeleteFramebuffers(1, &fb); + fprintf(stderr, "Unsupported framebuffer\n"); + exit(1); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + msaa_fbo = fb; +} + +/* + * Draw a gear wheel. You'll probably want to call this function when + * building a display list since we do a lot of trig here. + * + * Input: inner_radius - radius of hole at center + * outer_radius - radius at center of teeth + * width - width of gear + * teeth - number of teeth + * tooth_depth - depth of tooth + */ +static void gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, + GLint teeth, GLfloat tooth_depth) +{ + GLint i; + GLfloat r0, r1, r2; + GLfloat angle, da; + GLfloat u, v, len; + + r0 = inner_radius; + r1 = outer_radius - tooth_depth / 2.0; + r2 = outer_radius + tooth_depth / 2.0; + + da = 2.0 * M_PI / teeth / 4.0; + + glShadeModel(GL_FLAT); + + glNormal3f(0.0, 0.0, 1.0); + + /* draw front face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + if (i < teeth) { + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + } + } + glEnd(); + + /* draw front sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + } + glEnd(); + + glNormal3f(0.0, 0.0, -1.0); + + /* draw back face */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + if (i < teeth) { + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + } + } + glEnd(); + + /* draw back sides of teeth */ + glBegin(GL_QUADS); + da = 2.0 * M_PI / teeth / 4.0; + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + -width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + } + glEnd(); + + /* draw outward faces of teeth */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i < teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + + glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5); + glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5); + u = r2 * cos(angle + da) - r1 * cos(angle); + v = r2 * sin(angle + da) - r1 * sin(angle); + len = sqrt(u * u + v * v); + u /= len; + v /= len; + glNormal3f(v, -u, 0.0); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5); + glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + width * 0.5); + glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), + -width * 0.5); + u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da); + v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da); + glNormal3f(v, -u, 0.0); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + width * 0.5); + glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), + -width * 0.5); + glNormal3f(cos(angle), sin(angle), 0.0); + } + + glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5); + glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5); + + glEnd(); + + glShadeModel(GL_SMOOTH); + + /* draw inside radius cylinder */ + glBegin(GL_QUAD_STRIP); + for (i = 0; i <= teeth; i++) { + angle = i * 2.0 * M_PI / teeth; + glNormal3f(-cos(angle), -sin(angle), 0.0); + glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5); + glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5); + } + glEnd(); +} + +static void draw_gear(void) +{ + glBindFramebuffer(GL_FRAMEBUFFER, msaa_fbo); +#if PFINISH + fprintf(stderr, "EE CLEAR FBO -------------------------------------------------\n"); +#endif + glClearColor(0.5, 0.5, 0.8, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#if PFINISH + glFinish(); + fprintf(stderr, "EE CLEAR FBO _________________________________________________\n"); +#endif + +#if PFINISH + fprintf(stderr, "EE DRAW FBO --------------------------------------------------\n"); +#endif + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(view_roty, 0.0, 1.0, 0.0); + glRotatef(view_rotz, 0.0, 0.0, 1.0); + + glPushMatrix(); + glTranslatef(-3.0, -2.0, 0.0); + glRotatef(angle, 0.0, 0.0, 1.0); + glCallList(gear1); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(3.1, -2.0, 0.0); + glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0); + glCallList(gear2); + glPopMatrix(); + + glPushMatrix(); + glTranslatef(-3.1, 4.2, 0.0); + glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0); + glCallList(gear3); + glPopMatrix(); + + glPopMatrix(); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#if PFINISH + glFinish(); + fprintf(stderr, "EE DRAW FBO __________________________________________________\n"); +#endif +} + +static void draw_cube(void) +{ + static const GLfloat texcoords[4][2] = { + { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 } + }; + static const GLfloat vertices[4][2] = { + { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } + }; + static const GLfloat xforms[6][4] = { + { 0, 0, 1, 0 }, + { 90, 0, 1, 0 }, + { 180, 0, 1, 0 }, + { 270, 0, 1, 0 }, + { 90, 1, 0, 0 }, + { -90, 1, 0, 0 } + }; + static const GLfloat mat[4] = { 1.0, 1.0, 0.5, 1.0 }; + float ar; + GLint i, j; + +#if PFINISH + fprintf(stderr, "EE CLEAR -----------------------------------------------------\n"); +#endif + glClearColor(0.8, 0.5, 0.5, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#if PFINISH + glFinish(); + fprintf(stderr, "EE CLEAR _____________________________________________________\n"); +#endif + +#if PFINISH + fprintf(stderr, "EE DRAW ------------------------------------------------------\n"); +#endif + ar = (float)win_width / win_height; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1.0, 1.0, 5.0, 60.0); + glMatrixMode(GL_MODELVIEW); + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, gears_tex); + + glPushMatrix(); + glRotatef(view_rotx, 1.0, 0.0, 0.0); + glRotatef(15, 1, 0, 0); + glRotatef(cube_rot, 0, 1, 0); + glScalef(4, 4, 4); + + for (i = 0; i < 6; i++) { + glPushMatrix(); + glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]); + glTranslatef(0, 0, 1.1); + glBegin(GL_POLYGON); + glNormal3f(0, 0, 1); + for (j = 0; j < 4; j++) { + glTexCoord2fv(texcoords[j]); + glVertex2fv(vertices[j]); + } + glEnd(); + glPopMatrix(); + } + glPopMatrix(); + + glDisable(GL_TEXTURE_2D); +#if PFINISH + glFinish(); + fprintf(stderr, "EE DRAW ______________________________________________________\n"); +#endif +} + +static void draw(void) +{ + glEnable(GL_MULTISAMPLE); + draw_gear(); + glDisable(GL_MULTISAMPLE); + + /* resolve */ +#if PFINISH + fprintf(stderr, "EE RESOLVE ---------------------------------------------------\n"); +#endif + glBindFramebuffer(GL_READ_FRAMEBUFFER, msaa_fbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gears_fbo); + glBlitFramebuffer(0, 0, 512, 512, + 0, 0, 512, 512, + GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#if PFINISH + glFinish(); + fprintf(stderr, "EE RESOLVE ___________________________________________________\n"); +#endif + + draw_cube(); + glutSwapBuffers(); + frames++; + if (frames >= MAXFRAME) { + glFinish(); + exit(0); + } +} + +static void idle(void) +{ + static double t0 = -1.; + double dt, t; + + t = glutGet(GLUT_ELAPSED_TIME) / 1000.0; + if (t0 < 0.0) + t0 = t; + dt = t - t0; + t0 = t; + + angle += 70.0 * dt; /* 70 degrees per second */ + angle = fmod(angle, 360.0); /* prevents eventual overflow */ + cube_rot = fmod(cube_rot + 15.0 * dt, 360.0); /* 15 deg/sec */ + + glutPostRedisplay(); +} + +/* new window size or exposure */ +static void reshape(int width, int height) +{ + GLfloat h = (GLfloat) height / (GLfloat) width; + + glViewport(0, 0, (GLint) width, (GLint) height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -40.0); + + win_width = width; + win_height = height; +} + +static void init(void) +{ + static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 }; + static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 }; + static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 }; + static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 }; + + glLightfv(GL_LIGHT0, GL_POSITION, pos); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + + /* make the gears */ + gear1 = glGenLists(1); + glNewList(gear1, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red); + gear(1.0, 4.0, 1.0, 20, 0.7); + glEndList(); + + gear2 = glGenLists(1); + glNewList(gear2, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green); + gear(0.5, 2.0, 2.0, 10, 0.7); + glEndList(); + + gear3 = glGenLists(1); + glNewList(gear3, GL_COMPILE); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue); + gear(1.3, 2.0, 0.5, 10, 0.7); + glEndList(); + + generate_simple_fbo(512, 512); + + glEnable(GL_NORMALIZE); +} + +int main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE | GLUT_STENCIL); + glutInitWindowSize(win_width, win_height); + glutCreateWindow("glgears"); + + GLenum err = glewInit(); + if (GLEW_OK != err) { + fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); + return -1; + } + + glutIdleFunc(idle); + glutReshapeFunc(reshape); + glutDisplayFunc(draw); + + init(); + reshape(win_width, win_height); + glutMainLoop(); + return 0; +} |