Home | History | Annotate | Download | only in perf_tests
      1 //
      2 // Copyright (c) 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 #include "BufferSubData.h"
      8 
      9 #include <cassert>
     10 #include <sstream>
     11 
     12 #include "shader_utils.h"
     13 
     14 namespace
     15 {
     16 
     17 GLfloat *GetFloatData(GLint componentCount)
     18 {
     19     static GLfloat vertices2[] =
     20     {
     21         1, 2,
     22         0, 0,
     23         2, 0,
     24     };
     25 
     26     static GLfloat vertices3[] =
     27     {
     28         1, 2, 1,
     29         0, 0, 1,
     30         2, 0, 1,
     31     };
     32 
     33     static GLfloat vertices4[] =
     34     {
     35         1, 2, 1, 3,
     36         0, 0, 1, 3,
     37         2, 0, 1, 3,
     38     };
     39 
     40     switch (componentCount)
     41     {
     42       case 2: return vertices2;
     43       case 3: return vertices3;
     44       case 4: return vertices4;
     45       default: return NULL;
     46     }
     47 }
     48 
     49 template <class T>
     50 GLsizeiptr GetNormalizedData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
     51 {
     52     GLsizeiptr triDataSize = sizeof(T) * numElements;
     53     data->resize(triDataSize);
     54 
     55     T *destPtr = reinterpret_cast<T*>(data->data());
     56 
     57     for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
     58     {
     59         GLfloat scaled = floatData[dataIndex] * 0.25f;
     60         destPtr[dataIndex] = static_cast<T>(scaled * static_cast<GLfloat>(std::numeric_limits<T>::max()));
     61     }
     62 
     63     return triDataSize;
     64 }
     65 
     66 template <class T>
     67 GLsizeiptr GetIntData(GLsizeiptr numElements, GLfloat *floatData, std::vector<uint8_t> *data)
     68 {
     69     GLsizeiptr triDataSize = sizeof(T) * numElements;
     70     data->resize(triDataSize);
     71 
     72     T *destPtr = reinterpret_cast<T*>(data->data());
     73 
     74     for (GLsizeiptr dataIndex = 0; dataIndex < numElements; dataIndex++)
     75     {
     76         destPtr[dataIndex] = static_cast<T>(floatData[dataIndex]);
     77     }
     78 
     79     return triDataSize;
     80 }
     81 
     82 GLsizeiptr GetVertexData(GLenum type, GLint componentCount, GLboolean normalized, std::vector<uint8_t> *data)
     83 {
     84     GLsizeiptr triDataSize = 0;
     85     GLfloat *floatData = GetFloatData(componentCount);
     86 
     87     if (type == GL_FLOAT)
     88     {
     89         triDataSize = sizeof(GLfloat) * componentCount * 3;
     90         data->resize(triDataSize);
     91         memcpy(data->data(), floatData, triDataSize);
     92     }
     93     else if (normalized == GL_TRUE)
     94     {
     95         GLsizeiptr numElements = componentCount * 3;
     96 
     97         switch (type)
     98         {
     99           case GL_BYTE:           triDataSize = GetNormalizedData<GLbyte>(numElements, floatData, data); break;
    100           case GL_SHORT:          triDataSize = GetNormalizedData<GLshort>(numElements, floatData, data); break;
    101           case GL_INT:            triDataSize = GetNormalizedData<GLint>(numElements, floatData, data); break;
    102           case GL_UNSIGNED_BYTE:  triDataSize = GetNormalizedData<GLubyte>(numElements, floatData, data); break;
    103           case GL_UNSIGNED_SHORT: triDataSize = GetNormalizedData<GLushort>(numElements, floatData, data); break;
    104           case GL_UNSIGNED_INT:   triDataSize = GetNormalizedData<GLuint>(numElements, floatData, data); break;
    105           default: assert(0);
    106         }
    107     }
    108     else
    109     {
    110         GLsizeiptr numElements = componentCount * 3;
    111 
    112         switch (type)
    113         {
    114           case GL_BYTE:           triDataSize = GetIntData<GLbyte>(numElements, floatData, data); break;
    115           case GL_SHORT:          triDataSize = GetIntData<GLshort>(numElements, floatData, data); break;
    116           case GL_INT:            triDataSize = GetIntData<GLint>(numElements, floatData, data); break;
    117           case GL_UNSIGNED_BYTE:  triDataSize = GetIntData<GLubyte>(numElements, floatData, data); break;
    118           case GL_UNSIGNED_SHORT: triDataSize = GetIntData<GLushort>(numElements, floatData, data); break;
    119           case GL_UNSIGNED_INT:   triDataSize = GetIntData<GLuint>(numElements, floatData, data); break;
    120           default: assert(0);
    121         }
    122     }
    123 
    124     return triDataSize;
    125 }
    126 
    127 }
    128 
    129 std::string BufferSubDataParams::name() const
    130 {
    131     std::stringstream strstr;
    132 
    133     strstr << "BufferSubData - " << BenchmarkParams::name() << " - ";
    134 
    135     if (vertexNormalized)
    136     {
    137         strstr << "Norm";
    138     }
    139 
    140     switch (vertexType)
    141     {
    142       case GL_FLOAT: strstr << "Float"; break;
    143       case GL_INT: strstr << "Int"; break;
    144       case GL_BYTE: strstr << "Byte"; break;
    145       case GL_SHORT: strstr << "Short"; break;
    146       case GL_UNSIGNED_INT: strstr << "UInt"; break;
    147       case GL_UNSIGNED_BYTE: strstr << "UByte"; break;
    148       case GL_UNSIGNED_SHORT: strstr << "UShort"; break;
    149       default: strstr << "UNKNOWN FORMAT (" << vertexType << ")"; break;
    150     }
    151 
    152     strstr << vertexComponentCount;
    153 
    154     strstr << " - " << updateSize << "b updates (per " << updatesEveryNFrames << ") - ";
    155     strstr << (bufferSize >> 10) << "k buffer - ";
    156     strstr << iterations << " updates";
    157 
    158     return strstr.str();
    159 }
    160 
    161 BufferSubDataBenchmark::BufferSubDataBenchmark(const BufferSubDataParams &params)
    162     : SimpleBenchmark(params.name(), 1280, 720, 2, params.requestedRenderer),
    163       mProgram(0),
    164       mBuffer(0),
    165       mUpdateData(NULL),
    166       mNumTris(0),
    167       mParams(params)
    168 {
    169     mDrawIterations = mParams.iterations;
    170 
    171     assert(mParams.vertexComponentCount > 1);
    172     assert(mParams.iterations > 0);
    173 }
    174 
    175 bool BufferSubDataBenchmark::initializeBenchmark()
    176 {
    177     const std::string vs = SHADER_SOURCE
    178     (
    179         attribute vec2 vPosition;
    180         uniform float uScale;
    181         uniform float uOffset;
    182         void main()
    183         {
    184             gl_Position = vec4(vPosition * vec2(uScale) - vec2(uOffset), 0, 1);
    185         }
    186     );
    187 
    188     const std::string fs = SHADER_SOURCE
    189     (
    190         precision mediump float;
    191         void main()
    192         {
    193             gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    194         }
    195     );
    196 
    197     mProgram = CompileProgram(vs, fs);
    198     if (!mProgram)
    199     {
    200         return false;
    201     }
    202 
    203     // Use the program object
    204     glUseProgram(mProgram);
    205 
    206     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    207 
    208 
    209     std::vector<uint8_t> zeroData(mParams.bufferSize);
    210     memset(zeroData.data(), 0, zeroData.size());
    211 
    212     glGenBuffers(1, &mBuffer);
    213     glBindBuffer(GL_ARRAY_BUFFER, mBuffer);
    214     glBufferData(GL_ARRAY_BUFFER, mParams.bufferSize, zeroData.data(), GL_DYNAMIC_DRAW);
    215 
    216     glVertexAttribPointer(0, mParams.vertexComponentCount, mParams.vertexType,
    217                           mParams.vertexNormalized, 0, 0);
    218     glEnableVertexAttribArray(0);
    219 
    220     if (mParams.updateSize > 0)
    221     {
    222         mUpdateData = new uint8_t[mParams.updateSize];
    223     }
    224 
    225     std::vector<uint8_t> data;
    226     GLsizei triDataSize = GetVertexData(mParams.vertexType,
    227                                         mParams.vertexComponentCount,
    228                                         mParams.vertexNormalized, &data);
    229 
    230     mNumTris = mParams.updateSize / triDataSize;
    231     for (int i = 0, offset = 0; i < mNumTris; ++i)
    232     {
    233         memcpy(mUpdateData + offset, data.data(), triDataSize);
    234         offset += triDataSize;
    235     }
    236 
    237     if (mParams.updateSize == 0)
    238     {
    239         mNumTris = 1;
    240         glBufferSubData(GL_ARRAY_BUFFER, 0, data.size(), data.data());
    241     }
    242 
    243     // Set the viewport
    244     glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
    245 
    246     GLfloat scale = 0.5f;
    247     GLfloat offset = 0.5f;
    248 
    249     if (mParams.vertexNormalized == GL_TRUE)
    250     {
    251         scale = 2.0f;
    252         offset = 0.5f;
    253     }
    254 
    255     glUniform1f(glGetUniformLocation(mProgram, "uScale"), scale);
    256     glUniform1f(glGetUniformLocation(mProgram, "uOffset"), offset);
    257 
    258     GLenum glErr = glGetError();
    259     if (glErr != GL_NO_ERROR)
    260     {
    261         return false;
    262     }
    263 
    264     return true;
    265 }
    266 
    267 void BufferSubDataBenchmark::destroyBenchmark()
    268 {
    269     glDeleteProgram(mProgram);
    270     glDeleteBuffers(1, &mBuffer);
    271     delete[] mUpdateData;
    272 }
    273 
    274 void BufferSubDataBenchmark::beginDrawBenchmark()
    275 {
    276     // Clear the color buffer
    277     glClear(GL_COLOR_BUFFER_BIT);
    278 }
    279 
    280 void BufferSubDataBenchmark::drawBenchmark()
    281 {
    282     for (unsigned int it = 0; it < mParams.iterations; it++)
    283     {
    284         if (mParams.updateSize > 0 && ((mNumFrames % mParams.updatesEveryNFrames) == 0))
    285         {
    286             glBufferSubData(GL_ARRAY_BUFFER, 0, mParams.updateSize, mUpdateData);
    287         }
    288 
    289         glDrawArrays(GL_TRIANGLES, 0, 3 * mNumTris);
    290     }
    291 }
    292