Well, as prompted by my other thread about FBO and AA, I’ve started to more seriously investigate the speed of glCopyTexImage2D. I’ve modified some code I found on the net, and put some timing in.
I’m hoping to verify that my results are right, and to gather some stats from other peoples machines.
My machine is:
P4 2.4B (533mhz FSB)
1gb ram
Asus Geforce 6800GT 128mb (so slower ram then a full GT)
Software:
Windows XP SP2
Nvidia 78.01 drivers
VSYNC, AA and AF are all OFF
And if I run the program below in 1280x1024 (maximized, not fullscreen, havent tried that) I get the following:
CopyTime: 0.001271 = 2815.384809MB/s, Frame: 0.003100
CopyTime: 0.001290 = 2773.318703MB/s, Frame: 0.003103
CopyTime: 0.001266 = 2827.193310MB/s, Frame: 0.003038
CopyTime: 0.001271 = 2814.765973MB/s, Frame: 0.003051
CopyTime: 0.001299 = 2754.233572MB/s, Frame: 0.003636
CopyTime: 0.001271 = 2814.765973MB/s, Frame: 0.003053
CopyTime: 0.001280 = 2794.498191MB/s, Frame: 0.003076
CopyTime: 0.001288 = 2778.734027MB/s, Frame: 0.003117
CopyTime: 0.001287 = 2780.544089MB/s, Frame: 0.003077
CopyTime: 0.001267 = 2823.453731MB/s, Frame: 0.003038
CopyTime: 0.001288 = 2778.734027MB/s, Frame: 0.003076
CopyTime: 0.001281 = 2792.670176MB/s, Frame: 0.003089
CopyTime: 0.002794 = 1280.334444MB/s, Frame: 0.004620
CopyTime: 0.001282 = 2791.452911MB/s, Frame: 0.003012
CopyTime: 0.001266 = 2826.569272MB/s, Frame: 0.003053
CopyTime: 0.001276 = 2804.288509MB/s, Frame: 0.003073
CopyTime: 0.001284 = 2787.200450MB/s, Frame: 0.003108
CopyTime: 0.001286 = 2781.147716MB/s, Frame: 0.003095
CopyTime: 0.001282 = 2791.452911MB/s, Frame: 0.003247
CopyTime: 0.001262 = 2834.075168MB/s, Frame: 0.002991
CopyTime: 0.001279 = 2798.161666MB/s, Frame: 0.003062
CopyTime: 0.001280 = 2795.718368MB/s, Frame: 0.003100
CopyTime: 0.001281 = 2792.061284MB/s, Frame: 0.003066
CopyTime: 0.001284 = 2786.593941MB/s, Frame: 0.003089
Heres the source code:
// console.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <GL/glut.h>
#include <GL/glext.h>
#include <stdio.h>
#include <assert.h>
#include "TimeCounter.h"
int imageWinWidth = 256;
int imageWinHeight = 256;
void reshape(int w, int h)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(0.0, 1.0, 1.0, 0.0, 1.0, 100.0);
gluLookAt(0.0,0.0,0.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glutPostRedisplay();
imageWinWidth = w;
imageWinHeight = h;
}
void myIdle(void)
{
glutPostRedisplay();
}
void keyboard (unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
default:
break;
}
}
void MouseFunc( int button, int state, int x, int y)
{
switch(button) {
case GLUT_LEFT_BUTTON :
break;
case GLUT_RIGHT_BUTTON :
break;
}
}
unsigned int texture(0);
void render_redirect(void)
{
TimeCounter wholeframe;
// draw a scene. the results are being
// written into the associated texture,'tex'
glClearColor(0.0, 0.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f( 1.0, 1.0, 1.0, 1.0);
glLineWidth(5.0);
glBegin(GL_LINES);
glColor4f( 1.0, 1.0, 1.0, 1.0);
glVertex3f( 0.0, 0.0, -1.0);
glVertex3f( 1.0, 1.0, -1.0);
glEnd();
if(!texture)
{
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glFinish();
TimeCounter copytime;
glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, 0, 0, imageWinWidth, imageWinHeight, 0);
float fS(imageWinWidth), fT(imageWinHeight);
float fW(1), fH(1);
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(0,0,-1);
glTexCoord2f(fS,0);
glVertex3f(fW,0,-1);
glTexCoord2f(fS,fT);
glVertex3f(fW,fH,-1);
glTexCoord2f(0,fT);
glVertex3f(0,fH,-1);
glEnd();
glFinish();
copytime.Tick();
glDisable(GL_TEXTURE_RECTANGLE_ARB);
wholeframe.Tick();
printf("CopyTime: %f = %fMB/s, Frame: %f
", copytime.GetTimeStep(), float(imageWinWidth*imageWinHeight*3)/1048576.0f*1.0f/copytime.GetTimeStep(), wholeframe.GetTimeStep());
glutSwapBuffers();
}
int _tmain(int argc, _TCHAR* argv[])
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(imageWinWidth, imageWinHeight);
glutCreateWindow("copytest");
glutDisplayFunc(render_redirect);
glutIdleFunc(myIdle);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(MouseFunc);
glutMainLoop();
return 0;
}
And heres TimeCounter’s source
class TimeCounter
{
public:
TimeCounter();
void Reset();
void Tick();
float GetTotalTime();
float GetTimeStep();
protected:
// time tracking variables
float m_Frequency, m_LastStep;
__int64 m_Start, m_StartFrame, m_Last;
};
#include "stdafx.h"
#include "windows.h"
#include "TimeCounter.h"
#pragma warning(disable : 4244) // disable __int64 conversion warning
TimeCounter::TimeCounter() : m_Frequency(0), m_LastStep(0), m_Start(0),
m_StartFrame(0), m_Last(0)
{
// get the timer frequency
__int64 frequency;
if(!QueryPerformanceFrequency( (LARGE_INTEGER*) &frequency))
return;
// assign it to the float version, frequency will fit in a float easily!
m_Frequency = frequency;
// reset ourself
Reset();
}
void TimeCounter::Reset()
{
// get the "last" time
// QueryPerformanceCounter( (LARGE_INTEGER*) &m_Last);
// we got the frequency, get a start time
QueryPerformanceCounter((LARGE_INTEGER*) &m_Start);
m_LastStep = m_Last = m_StartFrame = m_Start;
}
void TimeCounter::Tick()
{
// get the time
QueryPerformanceCounter( (LARGE_INTEGER*) &m_Last);
// Store the difference between the 2 values
m_LastStep = (float)(m_Last-m_StartFrame)/m_Frequency;
// save the current time as the start of the next time frame.
m_StartFrame = m_Last;
}
float TimeCounter::GetTotalTime()
{
// return the time so the app start is 0...
return (float) ((m_Last-m_Start)/m_Frequency);
}
float TimeCounter::GetTimeStep()
{
return m_LastStep;
}
Others, post your results here, with hardware & software configuration.
Heres the source and binary zipped up
And heres glut!
Note: My results above might be wrong, so feel free to correct me