Path: blob/main_old/src/tests/perf_tests/BufferSubData.cpp
1693 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//5// BufferSubDataBenchmark:6// Performance test for ANGLE buffer updates.7//89#include <sstream>1011#include "ANGLEPerfTest.h"12#include "test_utils/draw_call_perf_utils.h"1314using namespace angle;1516namespace17{18constexpr unsigned int kIterationsPerStep = 4;1920struct BufferSubDataParams final : public RenderTestParams21{22BufferSubDataParams()23{24// Common default values25majorVersion = 2;26minorVersion = 0;27windowWidth = 512;28windowHeight = 512;29updateSize = 32000;30bufferSize = 40000;31iterationsPerStep = kIterationsPerStep;32updateRate = 1;33}3435std::string story() const override;3637GLboolean vertexNormalized;38GLenum vertexType;39GLint vertexComponentCount;40unsigned int updateRate;4142// static parameters43GLsizeiptr updateSize;44GLsizeiptr bufferSize;45};4647std::ostream &operator<<(std::ostream &os, const BufferSubDataParams ¶ms)48{49os << params.backendAndStory().substr(1);50return os;51}5253class BufferSubDataBenchmark : public ANGLERenderTest,54public ::testing::WithParamInterface<BufferSubDataParams>55{56public:57BufferSubDataBenchmark();5859void initializeBenchmark() override;60void destroyBenchmark() override;61void drawBenchmark() override;6263private:64GLuint mProgram;65GLuint mBuffer;66uint8_t *mUpdateData;67int mNumTris;68};6970GLfloat *GetFloatData(GLint componentCount)71{72static GLfloat vertices2[] = {731, 2, 0, 0, 2, 0,74};7576static GLfloat vertices3[] = {771, 2, 1, 0, 0, 1, 2, 0, 1,78};7980static GLfloat vertices4[] = {811, 2, 1, 3, 0, 0, 1, 3, 2, 0, 1, 3,82};8384switch (componentCount)85{86case 2:87return vertices2;88case 3:89return vertices3;90case 4:91return vertices4;92default:93return nullptr;94}95}9697template <class T>98GLsizeiptr GetNormalizedData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)99{100GLsizeiptr triDataSize = sizeof(T) * numElements;101data->resize(triDataSize);102103T *destPtr = reinterpret_cast<T *>(data->data());104105for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)106{107GLfloat scaled = floatData[dataIndex] * 0.25f;108destPtr[dataIndex] =109static_cast<T>(scaled * static_cast<GLfloat>(std::numeric_limits<T>::max()));110}111112return triDataSize;113}114115template <class T>116GLsizeiptr GetIntData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)117{118GLsizeiptr triDataSize = sizeof(T) * numElements;119data->resize(triDataSize);120121T *destPtr = reinterpret_cast<T *>(data->data());122123for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)124{125destPtr[dataIndex] = static_cast<T>(floatData[dataIndex]);126}127128return triDataSize;129}130131GLsizeiptr GetVertexData(GLenum type,132GLint componentCount,133GLboolean normalized,134std::vector<uint8_t> *data)135{136GLsizeiptr triDataSize = 0;137GLfloat *floatData = GetFloatData(componentCount);138139if (type == GL_FLOAT)140{141triDataSize = sizeof(GLfloat) * componentCount * 3;142data->resize(triDataSize);143memcpy(data->data(), floatData, triDataSize);144}145else if (normalized == GL_TRUE)146{147GLsizeiptr numElements = componentCount * 3;148149switch (type)150{151case GL_BYTE:152triDataSize = GetNormalizedData<GLbyte>(numElements, floatData, data);153break;154case GL_SHORT:155triDataSize = GetNormalizedData<GLshort>(numElements, floatData, data);156break;157case GL_INT:158triDataSize = GetNormalizedData<GLint>(numElements, floatData, data);159break;160case GL_UNSIGNED_BYTE:161triDataSize = GetNormalizedData<GLubyte>(numElements, floatData, data);162break;163case GL_UNSIGNED_SHORT:164triDataSize = GetNormalizedData<GLushort>(numElements, floatData, data);165break;166case GL_UNSIGNED_INT:167triDataSize = GetNormalizedData<GLuint>(numElements, floatData, data);168break;169default:170assert(0);171}172}173else174{175GLsizeiptr numElements = componentCount * 3;176177switch (type)178{179case GL_BYTE:180triDataSize = GetIntData<GLbyte>(numElements, floatData, data);181break;182case GL_SHORT:183triDataSize = GetIntData<GLshort>(numElements, floatData, data);184break;185case GL_INT:186triDataSize = GetIntData<GLint>(numElements, floatData, data);187break;188case GL_UNSIGNED_BYTE:189triDataSize = GetIntData<GLubyte>(numElements, floatData, data);190break;191case GL_UNSIGNED_SHORT:192triDataSize = GetIntData<GLushort>(numElements, floatData, data);193break;194case GL_UNSIGNED_INT:195triDataSize = GetIntData<GLuint>(numElements, floatData, data);196break;197default:198assert(0);199}200}201202return triDataSize;203}204205std::string BufferSubDataParams::story() const206{207std::stringstream strstr;208209strstr << RenderTestParams::story();210211if (vertexNormalized)212{213strstr << "_norm";214}215216switch (vertexType)217{218case GL_FLOAT:219strstr << "_float";220break;221case GL_INT:222strstr << "_int";223break;224case GL_BYTE:225strstr << "_byte";226break;227case GL_SHORT:228strstr << "_short";229break;230case GL_UNSIGNED_INT:231strstr << "_uint";232break;233case GL_UNSIGNED_BYTE:234strstr << "_ubyte";235break;236case GL_UNSIGNED_SHORT:237strstr << "_ushort";238break;239default:240strstr << "_vunk_" << vertexType << "_";241break;242}243244strstr << vertexComponentCount;245strstr << "_every" << updateRate;246247return strstr.str();248}249250BufferSubDataBenchmark::BufferSubDataBenchmark()251: ANGLERenderTest("BufferSubData", GetParam()),252mProgram(0),253mBuffer(0),254mUpdateData(nullptr),255mNumTris(0)256{}257258void BufferSubDataBenchmark::initializeBenchmark()259{260const auto ¶ms = GetParam();261262ASSERT_LT(1, params.vertexComponentCount);263264mProgram = SetupSimpleScaleAndOffsetProgram();265ASSERT_NE(0u, mProgram);266267if (params.vertexNormalized == GL_TRUE)268{269GLfloat scale = 2.0f;270GLfloat offset = -0.5f;271glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);272glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);273}274275glClearColor(0.0f, 0.0f, 0.0f, 0.0f);276277std::vector<uint8_t> zeroData(params.bufferSize);278memset(&zeroData[0], 0, zeroData.size());279280glGenBuffers(1, &mBuffer);281glBindBuffer(GL_ARRAY_BUFFER, mBuffer);282glBufferData(GL_ARRAY_BUFFER, params.bufferSize, &zeroData[0], GL_DYNAMIC_DRAW);283284glVertexAttribPointer(0, params.vertexComponentCount, params.vertexType,285params.vertexNormalized, 0, 0);286glEnableVertexAttribArray(0);287288if (params.updateSize > 0)289{290mUpdateData = new uint8_t[params.updateSize];291}292293std::vector<uint8_t> data;294GLsizei triDataSize = static_cast<GLsizei>(GetVertexData(295params.vertexType, params.vertexComponentCount, params.vertexNormalized, &data));296297mNumTris = static_cast<int>(params.updateSize / triDataSize);298for (int i = 0, offset = 0; i < mNumTris; ++i)299{300memcpy(mUpdateData + offset, &data[0], triDataSize);301offset += triDataSize;302}303304if (params.updateSize == 0)305{306mNumTris = 1;307glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), &data[0]);308}309310// Set the viewport311glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());312313ASSERT_GL_NO_ERROR();314}315316void BufferSubDataBenchmark::destroyBenchmark()317{318glDeleteProgram(mProgram);319glDeleteBuffers(1, &mBuffer);320SafeDeleteArray(mUpdateData);321}322323void BufferSubDataBenchmark::drawBenchmark()324{325glClear(GL_COLOR_BUFFER_BIT);326327const auto ¶ms = GetParam();328329for (unsigned int it = 0; it < params.iterationsPerStep; it++)330{331if (params.updateSize > 0 && ((getNumStepsPerformed() % params.updateRate) == 0))332{333glBufferSubData(GL_ARRAY_BUFFER, 0, params.updateSize, mUpdateData);334}335336glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris);337}338339ASSERT_GL_NO_ERROR();340}341342BufferSubDataParams BufferUpdateD3D11Params()343{344BufferSubDataParams params;345params.eglParameters = egl_platform::D3D11();346params.vertexType = GL_FLOAT;347params.vertexComponentCount = 4;348params.vertexNormalized = GL_FALSE;349return params;350}351352BufferSubDataParams BufferUpdateOpenGLOrGLESParams()353{354BufferSubDataParams params;355params.eglParameters = egl_platform::OPENGL_OR_GLES();356params.vertexType = GL_FLOAT;357params.vertexComponentCount = 4;358params.vertexNormalized = GL_FALSE;359return params;360}361362BufferSubDataParams BufferUpdateVulkanParams()363{364BufferSubDataParams params;365params.eglParameters = egl_platform::VULKAN();366params.vertexType = GL_FLOAT;367params.vertexComponentCount = 4;368params.vertexNormalized = GL_FALSE;369return params;370}371372TEST_P(BufferSubDataBenchmark, Run)373{374run();375}376377ANGLE_INSTANTIATE_TEST(BufferSubDataBenchmark,378BufferUpdateD3D11Params(),379BufferUpdateOpenGLOrGLESParams(),380BufferUpdateVulkanParams());381382} // namespace383384385