Newer
Older
for (U32 i = 0; i < count; ++i)
{
//allocate render targets and textures
if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
{
LL_WARNS() << "Failed to allocate render target." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
}
dest[i].bindTarget();
dest[i].clear();
dest[i].flush();
if (!texHolder.bind(i))
{
// can use a dummy value mDummyTexUnit = new LLTexUnit(-1);
LL_WARNS() << "Failed to bind tex unit." << LL_ENDL;
// abandon the benchmark test
delete[] pixels;
return -1.f;
}
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA, res,res,GL_RGBA, GL_UNSIGNED_BYTE, pixels);
}
davep
committed
delete [] pixels;
//make a dummy triangle to draw with
LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STATIC_DRAW_ARB);
if (!buff->allocateBuffer(3, 0, true))
{
LL_WARNS() << "Failed to allocate buffer during benchmark." << LL_ENDL;
// abandon the benchmark test
return -1.f;
}
LLStrider<LLVector3> v;
LLStrider<LLVector2> tc;
if (! buff->getVertexStrider(v))
LL_WARNS() << "GL LLVertexBuffer::getVertexStrider() returned false, "
<< "buff->getMappedData() is"
<< (buff->getMappedData()? " not" : "")
<< " NULL" << LL_ENDL;
// abandon the benchmark test
return -1.f;
Graham Linden
committed
// generate dummy triangle
v[0].set(-1, 1, 0);
v[1].set(-1, -3, 0);
v[2].set(3, 1, 0);
// ensure matched pair of bind() and unbind() calls
class ShaderBinder
{
public:
ShaderBinder(LLGLSLShader& shader):
mShader(shader)
{
mShader.bind();
}
~ShaderBinder()
{
mShader.unbind();
}
private:
LLGLSLShader& mShader;
};
ShaderBinder binder(gBenchmarkProgram);
David Parks
committed
buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
glFinish();
for (S32 c = -1; c < samples; ++c)
{
LLTimer timer;
timer.start();
for (U32 i = 0; i < count; ++i)
{
dest[i].bindTarget();
texHolder.bind(i);
buff->drawArrays(LLRender::TRIANGLES, 0, 3);
dest[i].flush();
}
//wait for current batch of copies to finish
F32 time = timer.getElapsedTimeF32();
if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
{
//store result in gigabytes per second
F32 gb = (F32) ((F64) (res*res*8*count))/(1000000000);
F32 gbps = gb/time;
results.push_back(gbps);
}
}
std::sort(results.begin(), results.end());
F32 gbps = results[results.size()/2];
LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers" << LL_ENDL;
davep
committed
#if LL_DARWIN
if (gbps > 512.f)
{
LL_WARNS() << "Memory bandwidth is improbably high and likely incorrect; discarding result." << LL_ENDL;
davep
committed
//OSX is probably lying, discard result
return -1.f;
davep
committed
}
#endif
F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
David Parks
committed
F64 samples_drawn = res*res*count*samples;
F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
gbps = samples_sec*8;
David Parks
committed
LL_INFOS() << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query" << LL_ENDL;
return gbps;