readpixels.c revision 32001f49
1/*
2 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22/**
23 * Measure glReadPixels speed.
24 * XXX also read into a PBO?
25 * XXX also read from FBOs?
26 *
27 * Brian Paul
28 * 23 Sep 2009
29 */
30
31#include <string.h>
32#include <assert.h>
33#include "glmain.h"
34#include "common.h"
35
36int WinWidth = 1000, WinHeight = 1000;
37
38static GLuint VBO;
39
40static const GLboolean DrawPoint = GL_TRUE;
41static const GLboolean BufferSubDataInHalves = GL_TRUE;
42
43static const GLfloat Vertex0[2] = { 0.0, 0.0 };
44
45static GLenum HaveDepthStencil;
46
47static GLenum ReadFormat, ReadType;
48static GLint ReadWidth, ReadHeight;
49static GLvoid *ReadBuffer;
50
51
52/** Called from test harness/main */
53void
54PerfInit(void)
55{
56   /* setup VBO */
57   glGenBuffersARB(1, &VBO);
58   glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
59   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vertex0), Vertex0, GL_STATIC_DRAW_ARB);
60   glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
61   glEnableClientState(GL_VERTEX_ARRAY);
62
63   glPixelStorei(GL_PACK_ALIGNMENT, 1);
64
65   HaveDepthStencil = PerfExtensionSupported("GL_EXT_packed_depth_stencil");
66
67   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
68   glEnable(GL_DEPTH_TEST);
69   glEnable(GL_STENCIL_TEST);
70}
71
72
73static void
74ReadPixels(unsigned count)
75{
76   unsigned i;
77   for (i = 0; i < count; i++) {
78      /* read from random pos */
79      GLint x, y;
80
81      x = WinWidth - ReadWidth;
82      y = WinHeight - ReadHeight;
83      if (x > 0)
84         x = rand() % x;
85      if (y > 0)
86         y = rand() % y;
87
88      if (DrawPoint)
89         glDrawArrays(GL_POINTS, 0, 1);
90
91      glReadPixels(x, y, ReadWidth, ReadHeight,
92                   ReadFormat, ReadType, ReadBuffer);
93   }
94   glFinish();
95}
96
97
98static const GLsizei Sizes[] = {
99   10,
100   100,
101   500,
102   1000,
103   0
104};
105
106
107static const struct {
108   GLenum format;
109   GLenum type;
110   const char *name;
111   GLuint pixel_size;
112} DstFormats[] = {
113   { GL_RGBA, GL_UNSIGNED_BYTE,           "RGBA/ubyte", 4 },
114   { GL_BGRA, GL_UNSIGNED_BYTE,           "BGRA/ubyte", 4 },
115   { GL_RGB, GL_UNSIGNED_SHORT_5_6_5,     "RGB/565", 2 },
116   { GL_LUMINANCE, GL_UNSIGNED_BYTE,      "L/ubyte", 1 },
117   { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, "Z/uint", 4 },
118   { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, "Z+S/uint", 4 },
119   { 0, 0, NULL, 0 }
120};
121
122
123
124/** Called from test harness/main */
125void
126PerfNextRound(void)
127{
128}
129
130
131/** Called from test harness/main */
132void
133PerfDraw(void)
134{
135   double rate, mbPerSec;
136   int fmt, sz;
137
138   /* loop over formats */
139   for (fmt = 0; DstFormats[fmt].format; fmt++) {
140      ReadFormat = DstFormats[fmt].format;
141      ReadType = DstFormats[fmt].type;
142
143      /* loop over sizes */
144      for (sz = 0; Sizes[sz]; sz++) {
145         int imgSize;
146
147         ReadWidth = ReadHeight = Sizes[sz];
148         imgSize = ReadWidth * ReadHeight * DstFormats[fmt].pixel_size;
149         ReadBuffer = malloc(imgSize);
150
151         if (ReadFormat == GL_DEPTH_STENCIL_EXT && !HaveDepthStencil) {
152            rate = 0.0;
153            mbPerSec = 0.0;
154         }
155         else {
156            rate = PerfMeasureRate(ReadPixels);
157            mbPerSec = rate * imgSize / (1024.0 * 1024.0);
158         }
159
160         perf_printf("glReadPixels(%d x %d, %s): %.1f images/sec, %.1f Mpixels/sec\n",
161                     ReadWidth, ReadHeight,
162                     DstFormats[fmt].name, rate, mbPerSec);
163
164         free(ReadBuffer);
165      }
166   }
167
168   exit(0);
169}
170