132001f49Smrg/*
232001f49Smrg * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
332001f49Smrg *
432001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a
532001f49Smrg * copy of this software and associated documentation files (the "Software"),
632001f49Smrg * to deal in the Software without restriction, including without limitation
732001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
832001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the
932001f49Smrg * Software is furnished to do so, subject to the following conditions:
1032001f49Smrg *
1132001f49Smrg * The above copyright notice and this permission notice shall be included
1232001f49Smrg * in all copies or substantial portions of the Software.
1332001f49Smrg *
1432001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1532001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1632001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1732001f49Smrg * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1832001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1932001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2032001f49Smrg */
2132001f49Smrg
2232001f49Smrg/**
2332001f49Smrg * Measure rate of binding/switching between FBO targets.
2432001f49Smrg * Create two framebuffer objects for rendering to two textures.
2532001f49Smrg * Ping pong between texturing from one and drawing into the other.
2632001f49Smrg *
2732001f49Smrg * Brian Paul
2832001f49Smrg * 22 Sep 2009
2932001f49Smrg */
3032001f49Smrg
3132001f49Smrg#include <string.h>
3232001f49Smrg#include "glmain.h"
3332001f49Smrg#include "common.h"
3432001f49Smrg
3532001f49Smrgint WinWidth = 100, WinHeight = 100;
3632001f49Smrg
3732001f49Smrgstatic GLuint VBO;
3832001f49Smrg
3932001f49Smrgstatic GLuint FBO[2], Tex[2];
4032001f49Smrg
4132001f49Smrgstatic const GLsizei TexSize = 512;
4232001f49Smrg
4332001f49Smrgstatic const GLboolean DrawPoint = GL_TRUE;
4432001f49Smrg
4532001f49Smrgstruct vertex
4632001f49Smrg{
4732001f49Smrg   GLfloat x, y, s, t;
4832001f49Smrg};
4932001f49Smrg
5032001f49Smrgstatic const struct vertex vertices[1] = {
5132001f49Smrg   { 0.0, 0.0, 0.5, 0.5 },
5232001f49Smrg};
5332001f49Smrg
5432001f49Smrg#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
5532001f49Smrg
5632001f49Smrg
5732001f49Smrg/** Called from test harness/main */
5832001f49Smrgvoid
5932001f49SmrgPerfInit(void)
6032001f49Smrg{
6132001f49Smrg   const GLenum filter = GL_LINEAR;
6232001f49Smrg   GLenum stat;
6332001f49Smrg   int i;
6432001f49Smrg
6532001f49Smrg   if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
6632001f49Smrg      perf_printf("fboswitch: GL_EXT_framebuffer_object not supported\n");
6732001f49Smrg      exit(0);
6832001f49Smrg   }
6932001f49Smrg
7032001f49Smrg   /* setup VBO */
7132001f49Smrg   glGenBuffersARB(1, &VBO);
7232001f49Smrg   glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
7332001f49Smrg   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices),
7432001f49Smrg                   vertices, GL_STATIC_DRAW_ARB);
7532001f49Smrg
7632001f49Smrg   glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
7732001f49Smrg   glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
7832001f49Smrg   glEnableClientState(GL_VERTEX_ARRAY);
7932001f49Smrg   glEnableClientState(GL_TEXTURE_COORD_ARRAY);
8032001f49Smrg
8132001f49Smrg   glGenFramebuffersEXT(2, FBO);
8232001f49Smrg   glGenTextures(2, Tex);
8332001f49Smrg
8432001f49Smrg   for (i = 0; i < 2; i++) {
8532001f49Smrg      /* setup texture */
8632001f49Smrg      glBindTexture(GL_TEXTURE_2D, Tex[i]);
8732001f49Smrg      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
8832001f49Smrg                   TexSize, TexSize, 0,
8932001f49Smrg                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
9032001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
9132001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
9232001f49Smrg
9332001f49Smrg
9432001f49Smrg      /* setup fbo */
9532001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER, FBO[i]);
9632001f49Smrg      glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
9732001f49Smrg                                GL_COLOR_ATTACHMENT0_EXT,
9832001f49Smrg                                GL_TEXTURE_2D, Tex[i], 0/*level*/);
9932001f49Smrg      stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
10032001f49Smrg      if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
10132001f49Smrg         perf_printf("fboswitch: Error: incomplete FBO!\n");
10232001f49Smrg         exit(1);
10332001f49Smrg      }
10432001f49Smrg
10532001f49Smrg      /* clear the FBO */
10632001f49Smrg      glClear(GL_COLOR_BUFFER_BIT);
10732001f49Smrg   }
10832001f49Smrg
10932001f49Smrg   glEnable(GL_TEXTURE_2D);
11032001f49Smrg}
11132001f49Smrg
11232001f49Smrg
11332001f49Smrgstatic void
11432001f49SmrgFBOBind(unsigned count)
11532001f49Smrg{
11632001f49Smrg   unsigned i;
11732001f49Smrg   for (i = 1; i < count; i++) {
11832001f49Smrg      const GLuint dst = i & 1;
11932001f49Smrg      const GLuint src = 1 - dst;
12032001f49Smrg
12132001f49Smrg      /* bind src texture */
12232001f49Smrg      glBindTexture(GL_TEXTURE_2D, Tex[src]);
12332001f49Smrg
12432001f49Smrg      /* bind dst fbo */
12532001f49Smrg      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO[dst]);
12632001f49Smrg      glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
12732001f49Smrg
12832001f49Smrg      /* draw something */
12932001f49Smrg      if (DrawPoint)
13032001f49Smrg         glDrawArrays(GL_POINTS, 0, 1);
13132001f49Smrg   }
13232001f49Smrg   glFinish();
13332001f49Smrg}
13432001f49Smrg
13532001f49Smrg
13632001f49Smrg/** Called from test harness/main */
13732001f49Smrgvoid
13832001f49SmrgPerfNextRound(void)
13932001f49Smrg{
14032001f49Smrg}
14132001f49Smrg
14232001f49Smrg
14332001f49Smrg/** Called from test harness/main */
14432001f49Smrgvoid
14532001f49SmrgPerfDraw(void)
14632001f49Smrg{
14732001f49Smrg   double rate;
14832001f49Smrg
14932001f49Smrg   rate = PerfMeasureRate(FBOBind);
15032001f49Smrg   perf_printf("  FBO Binding: %1.f binds/sec\n", rate);
15132001f49Smrg
15232001f49Smrg   exit(0);
15332001f49Smrg}
154