Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/samples/tex_redef_microbench/TexRedefMicroBench.cpp
1694 views
1
//
2
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
3
// Use of this source code is governed by a BSD-style license that can be
4
// found in the LICENSE file.
5
//
6
7
// Based on Hello_Triangle.c from
8
// Book: OpenGL(R) ES 2.0 Programming Guide
9
// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10
// ISBN-10: 0321502795
11
// ISBN-13: 9780321502797
12
// Publisher: Addison-Wesley Professional
13
// URLs: http://safari.informit.com/9780321563835
14
// http://www.opengles-book.com
15
16
#include "SampleApplication.h"
17
18
#include "texture_utils.h"
19
#include "util/shader_utils.h"
20
21
#include <cstring>
22
#include <iostream>
23
24
// This sample demonstrates the differences in rendering efficiency when
25
// drawing with already-created textures whose dimensions have been altered
26
// versus drawing with newly created textures.
27
//
28
// In order to support GL's per-level texture creation semantics over the
29
// D3D API in particular, which requires textures' full mip chains to be
30
// created at texture object creation time, ANGLE maintains copies of the
31
// constituent texture images in system memory until the texture is used in
32
// a draw call, at which time, if the texture passes GL's mip completeness
33
// rules, the D3D texture is created and the contents of the texture are
34
// uploaded. Once the texture is created, redefinition of the dimensions or
35
// format of the texture is costly-- a new D3D texture needs to be created,
36
// and ANGLE may need to read the contents back into system memory.
37
//
38
// Creating an entirely new texture also requires that a new D3D texture be
39
// created, but any overhead associated with tracking the already-present
40
// texture images is eliminated, as it's a novel texture. This sample
41
// demonstrates the contrast in draw call time between these two situations.
42
//
43
// The resizing & creation of a new texture is delayed until several frames
44
// after startup, to eliminate draw time differences caused by caching of
45
// rendering state subsequent to the first frame.
46
47
class TexRedefBenchSample : public SampleApplication
48
{
49
public:
50
TexRedefBenchSample(int argc, char **argv)
51
: SampleApplication("Microbench", argc, argv, 2, 0, 1280, 1280),
52
mPixelsResize(nullptr),
53
mPixelsNewTex(nullptr),
54
mTimeFrame(false),
55
mFrameCount(0)
56
{}
57
58
void defineSquareTexture2D(GLuint texId,
59
GLsizei baseDimension,
60
GLenum format,
61
GLenum type,
62
void *data)
63
{
64
glBindTexture(GL_TEXTURE_2D, texId);
65
GLsizei curDim = baseDimension;
66
GLuint level = 0;
67
68
while (curDim >= 1)
69
{
70
glTexImage2D(GL_TEXTURE_2D, level, format, curDim, curDim, 0, format, type, data);
71
curDim /= 2;
72
level++;
73
}
74
}
75
76
void createPixelData()
77
{
78
mPixelsResize = new GLubyte[512 * 512 * 4];
79
mPixelsNewTex = new GLubyte[512 * 512 * 4];
80
GLubyte *pixPtr0 = mPixelsResize;
81
GLubyte *pixPtr1 = mPixelsNewTex;
82
GLubyte zeroPix[] = {0, 192, 192, 255};
83
GLubyte onePix[] = {192, 0, 0, 255};
84
for (int i = 0; i < 512 * 512; ++i)
85
{
86
memcpy(pixPtr0, zeroPix, 4 * sizeof(GLubyte));
87
memcpy(pixPtr1, onePix, 4 * sizeof(GLubyte));
88
pixPtr0 += 4;
89
pixPtr1 += 4;
90
}
91
}
92
93
bool initialize() override
94
{
95
constexpr char kVS[] = R"(attribute vec4 a_position;
96
attribute vec2 a_texCoord;
97
varying vec2 v_texCoord;
98
void main()
99
{
100
gl_Position = a_position;
101
v_texCoord = a_texCoord;
102
})";
103
104
constexpr char kFS[] = R"(precision mediump float;
105
varying vec2 v_texCoord;
106
uniform sampler2D s_texture;
107
void main()
108
{
109
gl_FragColor = texture2D(s_texture, v_texCoord);
110
})";
111
112
mProgram = CompileProgram(kVS, kFS);
113
if (!mProgram)
114
{
115
return false;
116
}
117
118
// Get the attribute locations
119
mPositionLoc = glGetAttribLocation(mProgram, "a_position");
120
mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");
121
122
// Get the sampler location
123
mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");
124
125
// Generate texture IDs, and create texture 0
126
glGenTextures(3, mTextureIds);
127
128
createPixelData();
129
defineSquareTexture2D(mTextureIds[0], 256, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsResize);
130
131
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
132
133
return true;
134
}
135
136
void destroy() override
137
{
138
glDeleteProgram(mProgram);
139
140
delete[] mPixelsResize;
141
delete[] mPixelsNewTex;
142
}
143
144
void draw() override
145
{
146
GLfloat vertices[] = {
147
-0.5f, 0.5f, 0.0f, // Position 0
148
0.0f, 0.0f, // TexCoord 0
149
-0.5f, -0.5f, 0.0f, // Position 1
150
0.0f, 1.0f, // TexCoord 1
151
0.5f, -0.5f, 0.0f, // Position 2
152
1.0f, 1.0f, // TexCoord 2
153
0.5f, 0.5f, 0.0f, // Position 3
154
1.0f, 0.0f // TexCoord 3
155
};
156
GLushort indices[] = {0, 1, 2, 0, 2, 3};
157
158
// Set the viewport
159
glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
160
161
// Clear the color buffer
162
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
163
164
// Use the program object
165
glUseProgram(mProgram);
166
167
// Load the vertex position
168
glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);
169
// Load the texture coordinate
170
glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
171
vertices + 3);
172
173
glEnableVertexAttribArray(mPositionLoc);
174
glEnableVertexAttribArray(mTexCoordLoc);
175
176
// Bind the texture
177
glActiveTexture(GL_TEXTURE0);
178
glBindTexture(GL_TEXTURE_2D, mTextureIds[0]);
179
180
// Set the texture sampler to texture unit to 0
181
glUniform1i(mSamplerLoc, 0);
182
183
// We delay timing of texture resize/creation until after the first frame, as
184
// caching optimizations will reduce draw time for subsequent frames for reasons
185
// unreleated to texture creation. mTimeFrame is set to true on the fifth frame.
186
if (mTimeFrame)
187
{
188
mOrigTimer.start();
189
}
190
191
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
192
193
if (mTimeFrame)
194
{
195
mOrigTimer.stop();
196
// This timer indicates draw time for an already-created texture resident on the GPU,
197
// which needs no updates. It will be faster than the other draws.
198
std::cout << "Original texture draw: " << mOrigTimer.getElapsedTime() * 1000 << "msec"
199
<< std::endl;
200
201
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
202
203
// Now, change the texture dimensions of the original texture
204
mResizeDefineTimer.start();
205
defineSquareTexture2D(mTextureIds[0], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsResize);
206
mResizeDefineTimer.stop();
207
208
mResizeDrawTimer.start();
209
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
210
mResizeDrawTimer.stop();
211
// This timer indicates draw time for a texture which has already been used in a draw,
212
// causing the underlying resource to be allocated, and then resized, requiring resource
213
// reallocation and related overhead.
214
std::cout << "Resized texture definition: "
215
<< mResizeDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;
216
std::cout << "Resized texture draw: " << mResizeDrawTimer.getElapsedTime() * 1000
217
<< "msec" << std::endl;
218
219
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
220
221
// Create texure at same dimensions we resized previous texture to
222
mNewTexDefineTimer.start();
223
defineSquareTexture2D(mTextureIds[1], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsNewTex);
224
mNewTexDefineTimer.stop();
225
226
mNewTexDrawTimer.start();
227
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
228
mNewTexDrawTimer.stop();
229
// This timer indicates draw time for a texture newly created this frame. The underlying
230
// resource will need to be created, but because it has not previously been used, there
231
// is no already-resident texture object to manage. This draw is expected to be faster
232
// than the resized texture draw.
233
std::cout << "Newly created texture definition: "
234
<< mNewTexDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;
235
std::cout << "Newly created texture draw: " << mNewTexDrawTimer.getElapsedTime() * 1000
236
<< "msec" << std::endl;
237
}
238
239
if (mFrameCount == 5)
240
mTimeFrame = true;
241
else
242
mTimeFrame = false;
243
244
mFrameCount++;
245
}
246
247
private:
248
// Handle to a program object
249
GLuint mProgram;
250
251
// Attribute locations
252
GLint mPositionLoc;
253
GLint mTexCoordLoc;
254
255
// Sampler location
256
GLint mSamplerLoc;
257
258
// Texture handle
259
GLuint mTextureIds[2]; // 0: texture created, then resized
260
// 1: texture newly created with TexImage
261
262
// Texture pixel data
263
GLubyte *mPixelsResize;
264
GLubyte *mPixelsNewTex;
265
266
Timer mOrigTimer;
267
Timer mResizeDrawTimer;
268
Timer mResizeDefineTimer;
269
Timer mNewTexDrawTimer;
270
Timer mNewTexDefineTimer;
271
bool mTimeFrame;
272
unsigned int mFrameCount;
273
};
274
275
int main(int argc, char **argv)
276
{
277
TexRedefBenchSample app(argc, argv);
278
return app.run();
279
}
280
281