Path: blob/main_old/samples/tex_redef_microbench/TexRedefMicroBench.cpp
1694 views
//1// Copyright 2014 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56// Based on Hello_Triangle.c from7// Book: OpenGL(R) ES 2.0 Programming Guide8// Authors: Aaftab Munshi, Dan Ginsburg, Dave Shreiner9// ISBN-10: 032150279510// ISBN-13: 978032150279711// Publisher: Addison-Wesley Professional12// URLs: http://safari.informit.com/978032156383513// http://www.opengles-book.com1415#include "SampleApplication.h"1617#include "texture_utils.h"18#include "util/shader_utils.h"1920#include <cstring>21#include <iostream>2223// This sample demonstrates the differences in rendering efficiency when24// drawing with already-created textures whose dimensions have been altered25// versus drawing with newly created textures.26//27// In order to support GL's per-level texture creation semantics over the28// D3D API in particular, which requires textures' full mip chains to be29// created at texture object creation time, ANGLE maintains copies of the30// constituent texture images in system memory until the texture is used in31// a draw call, at which time, if the texture passes GL's mip completeness32// rules, the D3D texture is created and the contents of the texture are33// uploaded. Once the texture is created, redefinition of the dimensions or34// format of the texture is costly-- a new D3D texture needs to be created,35// and ANGLE may need to read the contents back into system memory.36//37// Creating an entirely new texture also requires that a new D3D texture be38// created, but any overhead associated with tracking the already-present39// texture images is eliminated, as it's a novel texture. This sample40// demonstrates the contrast in draw call time between these two situations.41//42// The resizing & creation of a new texture is delayed until several frames43// after startup, to eliminate draw time differences caused by caching of44// rendering state subsequent to the first frame.4546class TexRedefBenchSample : public SampleApplication47{48public:49TexRedefBenchSample(int argc, char **argv)50: SampleApplication("Microbench", argc, argv, 2, 0, 1280, 1280),51mPixelsResize(nullptr),52mPixelsNewTex(nullptr),53mTimeFrame(false),54mFrameCount(0)55{}5657void defineSquareTexture2D(GLuint texId,58GLsizei baseDimension,59GLenum format,60GLenum type,61void *data)62{63glBindTexture(GL_TEXTURE_2D, texId);64GLsizei curDim = baseDimension;65GLuint level = 0;6667while (curDim >= 1)68{69glTexImage2D(GL_TEXTURE_2D, level, format, curDim, curDim, 0, format, type, data);70curDim /= 2;71level++;72}73}7475void createPixelData()76{77mPixelsResize = new GLubyte[512 * 512 * 4];78mPixelsNewTex = new GLubyte[512 * 512 * 4];79GLubyte *pixPtr0 = mPixelsResize;80GLubyte *pixPtr1 = mPixelsNewTex;81GLubyte zeroPix[] = {0, 192, 192, 255};82GLubyte onePix[] = {192, 0, 0, 255};83for (int i = 0; i < 512 * 512; ++i)84{85memcpy(pixPtr0, zeroPix, 4 * sizeof(GLubyte));86memcpy(pixPtr1, onePix, 4 * sizeof(GLubyte));87pixPtr0 += 4;88pixPtr1 += 4;89}90}9192bool initialize() override93{94constexpr char kVS[] = R"(attribute vec4 a_position;95attribute vec2 a_texCoord;96varying vec2 v_texCoord;97void main()98{99gl_Position = a_position;100v_texCoord = a_texCoord;101})";102103constexpr char kFS[] = R"(precision mediump float;104varying vec2 v_texCoord;105uniform sampler2D s_texture;106void main()107{108gl_FragColor = texture2D(s_texture, v_texCoord);109})";110111mProgram = CompileProgram(kVS, kFS);112if (!mProgram)113{114return false;115}116117// Get the attribute locations118mPositionLoc = glGetAttribLocation(mProgram, "a_position");119mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");120121// Get the sampler location122mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");123124// Generate texture IDs, and create texture 0125glGenTextures(3, mTextureIds);126127createPixelData();128defineSquareTexture2D(mTextureIds[0], 256, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsResize);129130glClearColor(0.0f, 0.0f, 0.0f, 0.0f);131132return true;133}134135void destroy() override136{137glDeleteProgram(mProgram);138139delete[] mPixelsResize;140delete[] mPixelsNewTex;141}142143void draw() override144{145GLfloat vertices[] = {146-0.5f, 0.5f, 0.0f, // Position 01470.0f, 0.0f, // TexCoord 0148-0.5f, -0.5f, 0.0f, // Position 11490.0f, 1.0f, // TexCoord 11500.5f, -0.5f, 0.0f, // Position 21511.0f, 1.0f, // TexCoord 21520.5f, 0.5f, 0.0f, // Position 31531.0f, 0.0f // TexCoord 3154};155GLushort indices[] = {0, 1, 2, 0, 2, 3};156157// Set the viewport158glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());159160// Clear the color buffer161glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);162163// Use the program object164glUseProgram(mProgram);165166// Load the vertex position167glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), vertices);168// Load the texture coordinate169glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),170vertices + 3);171172glEnableVertexAttribArray(mPositionLoc);173glEnableVertexAttribArray(mTexCoordLoc);174175// Bind the texture176glActiveTexture(GL_TEXTURE0);177glBindTexture(GL_TEXTURE_2D, mTextureIds[0]);178179// Set the texture sampler to texture unit to 0180glUniform1i(mSamplerLoc, 0);181182// We delay timing of texture resize/creation until after the first frame, as183// caching optimizations will reduce draw time for subsequent frames for reasons184// unreleated to texture creation. mTimeFrame is set to true on the fifth frame.185if (mTimeFrame)186{187mOrigTimer.start();188}189190glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);191192if (mTimeFrame)193{194mOrigTimer.stop();195// This timer indicates draw time for an already-created texture resident on the GPU,196// which needs no updates. It will be faster than the other draws.197std::cout << "Original texture draw: " << mOrigTimer.getElapsedTime() * 1000 << "msec"198<< std::endl;199200glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);201202// Now, change the texture dimensions of the original texture203mResizeDefineTimer.start();204defineSquareTexture2D(mTextureIds[0], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsResize);205mResizeDefineTimer.stop();206207mResizeDrawTimer.start();208glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);209mResizeDrawTimer.stop();210// This timer indicates draw time for a texture which has already been used in a draw,211// causing the underlying resource to be allocated, and then resized, requiring resource212// reallocation and related overhead.213std::cout << "Resized texture definition: "214<< mResizeDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;215std::cout << "Resized texture draw: " << mResizeDrawTimer.getElapsedTime() * 1000216<< "msec" << std::endl;217218glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);219220// Create texure at same dimensions we resized previous texture to221mNewTexDefineTimer.start();222defineSquareTexture2D(mTextureIds[1], 512, GL_RGBA, GL_UNSIGNED_BYTE, mPixelsNewTex);223mNewTexDefineTimer.stop();224225mNewTexDrawTimer.start();226glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);227mNewTexDrawTimer.stop();228// This timer indicates draw time for a texture newly created this frame. The underlying229// resource will need to be created, but because it has not previously been used, there230// is no already-resident texture object to manage. This draw is expected to be faster231// than the resized texture draw.232std::cout << "Newly created texture definition: "233<< mNewTexDefineTimer.getElapsedTime() * 1000 << "msec" << std::endl;234std::cout << "Newly created texture draw: " << mNewTexDrawTimer.getElapsedTime() * 1000235<< "msec" << std::endl;236}237238if (mFrameCount == 5)239mTimeFrame = true;240else241mTimeFrame = false;242243mFrameCount++;244}245246private:247// Handle to a program object248GLuint mProgram;249250// Attribute locations251GLint mPositionLoc;252GLint mTexCoordLoc;253254// Sampler location255GLint mSamplerLoc;256257// Texture handle258GLuint mTextureIds[2]; // 0: texture created, then resized259// 1: texture newly created with TexImage260261// Texture pixel data262GLubyte *mPixelsResize;263GLubyte *mPixelsNewTex;264265Timer mOrigTimer;266Timer mResizeDrawTimer;267Timer mResizeDefineTimer;268Timer mNewTexDrawTimer;269Timer mNewTexDefineTimer;270bool mTimeFrame;271unsigned int mFrameCount;272};273274int main(int argc, char **argv)275{276TexRedefBenchSample app(argc, argv);277return app.run();278}279280281