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