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 glReadPixels speed.
2432001f49Smrg * XXX also read into a PBO?
2532001f49Smrg * XXX also read from FBOs?
2632001f49Smrg *
2732001f49Smrg * Brian Paul
2832001f49Smrg * 23 Sep 2009
2932001f49Smrg */
3032001f49Smrg
3132001f49Smrg#include <string.h>
3232001f49Smrg#include <assert.h>
3332001f49Smrg#include "glmain.h"
3432001f49Smrg#include "common.h"
3532001f49Smrg
3632001f49Smrgint WinWidth = 1000, WinHeight = 1000;
3732001f49Smrg
3832001f49Smrgstatic GLuint VBO;
3932001f49Smrg
4032001f49Smrgstatic const GLboolean DrawPoint = GL_TRUE;
4132001f49Smrgstatic const GLboolean BufferSubDataInHalves = GL_TRUE;
4232001f49Smrg
4332001f49Smrgstatic const GLfloat Vertex0[2] = { 0.0, 0.0 };
4432001f49Smrg
4532001f49Smrgstatic GLenum HaveDepthStencil;
4632001f49Smrg
4732001f49Smrgstatic GLenum ReadFormat, ReadType;
4832001f49Smrgstatic GLint ReadWidth, ReadHeight;
4932001f49Smrgstatic GLvoid *ReadBuffer;
5032001f49Smrg
5132001f49Smrg
5232001f49Smrg/** Called from test harness/main */
5332001f49Smrgvoid
5432001f49SmrgPerfInit(void)
5532001f49Smrg{
5632001f49Smrg   /* setup VBO */
5732001f49Smrg   glGenBuffersARB(1, &VBO);
5832001f49Smrg   glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
5932001f49Smrg   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vertex0), Vertex0, GL_STATIC_DRAW_ARB);
6032001f49Smrg   glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
6132001f49Smrg   glEnableClientState(GL_VERTEX_ARRAY);
6232001f49Smrg
6332001f49Smrg   glPixelStorei(GL_PACK_ALIGNMENT, 1);
6432001f49Smrg
6532001f49Smrg   HaveDepthStencil = PerfExtensionSupported("GL_EXT_packed_depth_stencil");
6632001f49Smrg
6732001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
6832001f49Smrg   glEnable(GL_DEPTH_TEST);
6932001f49Smrg   glEnable(GL_STENCIL_TEST);
7032001f49Smrg}
7132001f49Smrg
7232001f49Smrg
7332001f49Smrgstatic void
7432001f49SmrgReadPixels(unsigned count)
7532001f49Smrg{
7632001f49Smrg   unsigned i;
7732001f49Smrg   for (i = 0; i < count; i++) {
7832001f49Smrg      /* read from random pos */
7932001f49Smrg      GLint x, y;
8032001f49Smrg
8132001f49Smrg      x = WinWidth - ReadWidth;
8232001f49Smrg      y = WinHeight - ReadHeight;
8332001f49Smrg      if (x > 0)
8432001f49Smrg         x = rand() % x;
8532001f49Smrg      if (y > 0)
8632001f49Smrg         y = rand() % y;
8732001f49Smrg
8832001f49Smrg      if (DrawPoint)
8932001f49Smrg         glDrawArrays(GL_POINTS, 0, 1);
9032001f49Smrg
9132001f49Smrg      glReadPixels(x, y, ReadWidth, ReadHeight,
9232001f49Smrg                   ReadFormat, ReadType, ReadBuffer);
9332001f49Smrg   }
9432001f49Smrg   glFinish();
9532001f49Smrg}
9632001f49Smrg
9732001f49Smrg
9832001f49Smrgstatic const GLsizei Sizes[] = {
9932001f49Smrg   10,
10032001f49Smrg   100,
10132001f49Smrg   500,
10232001f49Smrg   1000,
10332001f49Smrg   0
10432001f49Smrg};
10532001f49Smrg
10632001f49Smrg
10732001f49Smrgstatic const struct {
10832001f49Smrg   GLenum format;
10932001f49Smrg   GLenum type;
11032001f49Smrg   const char *name;
11132001f49Smrg   GLuint pixel_size;
11232001f49Smrg} DstFormats[] = {
11332001f49Smrg   { GL_RGBA, GL_UNSIGNED_BYTE,           "RGBA/ubyte", 4 },
11432001f49Smrg   { GL_BGRA, GL_UNSIGNED_BYTE,           "BGRA/ubyte", 4 },
11532001f49Smrg   { GL_RGB, GL_UNSIGNED_SHORT_5_6_5,     "RGB/565", 2 },
11632001f49Smrg   { GL_LUMINANCE, GL_UNSIGNED_BYTE,      "L/ubyte", 1 },
11732001f49Smrg   { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, "Z/uint", 4 },
11832001f49Smrg   { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, "Z+S/uint", 4 },
11932001f49Smrg   { 0, 0, NULL, 0 }
12032001f49Smrg};
12132001f49Smrg
12232001f49Smrg
12332001f49Smrg
12432001f49Smrg/** Called from test harness/main */
12532001f49Smrgvoid
12632001f49SmrgPerfNextRound(void)
12732001f49Smrg{
12832001f49Smrg}
12932001f49Smrg
13032001f49Smrg
13132001f49Smrg/** Called from test harness/main */
13232001f49Smrgvoid
13332001f49SmrgPerfDraw(void)
13432001f49Smrg{
13532001f49Smrg   double rate, mbPerSec;
13632001f49Smrg   int fmt, sz;
13732001f49Smrg
13832001f49Smrg   /* loop over formats */
13932001f49Smrg   for (fmt = 0; DstFormats[fmt].format; fmt++) {
14032001f49Smrg      ReadFormat = DstFormats[fmt].format;
14132001f49Smrg      ReadType = DstFormats[fmt].type;
14232001f49Smrg
14332001f49Smrg      /* loop over sizes */
14432001f49Smrg      for (sz = 0; Sizes[sz]; sz++) {
14532001f49Smrg         int imgSize;
14632001f49Smrg
14732001f49Smrg         ReadWidth = ReadHeight = Sizes[sz];
14832001f49Smrg         imgSize = ReadWidth * ReadHeight * DstFormats[fmt].pixel_size;
14932001f49Smrg         ReadBuffer = malloc(imgSize);
15032001f49Smrg
15132001f49Smrg         if (ReadFormat == GL_DEPTH_STENCIL_EXT && !HaveDepthStencil) {
15232001f49Smrg            rate = 0.0;
15332001f49Smrg            mbPerSec = 0.0;
15432001f49Smrg         }
15532001f49Smrg         else {
15632001f49Smrg            rate = PerfMeasureRate(ReadPixels);
15732001f49Smrg            mbPerSec = rate * imgSize / (1024.0 * 1024.0);
15832001f49Smrg         }
15932001f49Smrg
16032001f49Smrg         perf_printf("glReadPixels(%d x %d, %s): %.1f images/sec, %.1f Mpixels/sec\n",
16132001f49Smrg                     ReadWidth, ReadHeight,
16232001f49Smrg                     DstFormats[fmt].name, rate, mbPerSec);
16332001f49Smrg
16432001f49Smrg         free(ReadBuffer);
16532001f49Smrg      }
16632001f49Smrg   }
16732001f49Smrg
16832001f49Smrg   exit(0);
16932001f49Smrg}
170