import MesaDemos version 6.5.2

This commit is contained in:
matthieu 2007-03-03 11:59:27 +00:00
parent fe3d26ad6d
commit 2f8f3de5e4
8 changed files with 823 additions and 78 deletions

View File

@ -25,6 +25,7 @@ PROGS = \
fire \ fire \
fogcoord \ fogcoord \
fplight \ fplight \
fslight \
gamma \ gamma \
gearbox \ gearbox \
gears \ gears \
@ -47,6 +48,7 @@ PROGS = \
renormal \ renormal \
shadowtex \ shadowtex \
singlebuffer \ singlebuffer \
streaming_rect \
spectex \ spectex \
spriteblast \ spriteblast \
stex3d \ stex3d \

View File

@ -454,6 +454,7 @@ static void usage(void)
int main( int argc, char *argv[] ) int main( int argc, char *argv[] )
{ {
glutInit(&argc, argv);
glutInitWindowPosition(0, 0); glutInitWindowPosition(0, 0);
glutInitWindowSize(600, 500); glutInitWindowSize(600, 500);
glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );

334
dist/Mesa/progs/demos/fslight.c vendored Normal file
View File

@ -0,0 +1,334 @@
/**
* Test OpenGL 2.0 vertex/fragment shaders.
* Brian Paul
* 1 November 2006
*
* Based on ARB version by:
* Michal Krol
* 20 February 2006
*
* Based on the original demo by:
* Brian Paul
* 17 April 2003
*/
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <GL/glext.h>
static GLfloat diffuse[4] = { 0.5f, 0.5f, 1.0f, 1.0f };
static GLfloat specular[4] = { 0.8f, 0.8f, 0.8f, 1.0f };
static GLfloat lightPos[4] = { 0.0f, 10.0f, 20.0f, 1.0f };
static GLfloat delta = 1.0f;
static GLuint fragShader;
static GLuint vertShader;
static GLuint program;
static GLint uLightPos;
static GLint uDiffuse;
static GLint uSpecular;
static GLint win = 0;
static GLboolean anim = GL_TRUE;
static GLboolean wire = GL_FALSE;
static GLboolean pixelLight = GL_TRUE;
static GLint t0 = 0;
static GLint frames = 0;
static GLfloat xRot = 0.0f, yRot = 0.0f;
static PFNGLCREATESHADERPROC glCreateShader_func = NULL;
static PFNGLSHADERSOURCEPROC glShaderSource_func = NULL;
static PFNGLGETSHADERSOURCEPROC glGetShaderSource_func = NULL;
static PFNGLCOMPILESHADERPROC glCompileShader_func = NULL;
static PFNGLCREATEPROGRAMPROC glCreateProgram_func = NULL;
static PFNGLDELETEPROGRAMPROC glDeleteProgram_func = NULL;
static PFNGLDELETESHADERPROC glDeleteShader_func = NULL;
static PFNGLATTACHSHADERPROC glAttachShader_func = NULL;
static PFNGLLINKPROGRAMPROC glLinkProgram_func = NULL;
static PFNGLUSEPROGRAMPROC glUseProgram_func = NULL;
static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_func = NULL;
static PFNGLISPROGRAMPROC glIsProgram_func = NULL;
static PFNGLISSHADERPROC glIsShader_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform3fv_func = NULL;
static PFNGLUNIFORM3FVPROC glUniform4fv_func = NULL;
static void
normalize(GLfloat *dst, const GLfloat *src)
{
GLfloat len = sqrtf(src[0] * src[0] + src[1] * src[1] + src[2] * src[2]);
dst[0] = src[0] / len;
dst[1] = src[1] / len;
dst[2] = src[2] / len;
}
static void
Redisplay(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (pixelLight) {
GLfloat vec[3];
glUseProgram_func(program);
normalize(vec, lightPos);
glUniform3fv_func(uLightPos, 1, vec);
glDisable(GL_LIGHTING);
}
else {
glUseProgram_func(0);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHTING);
}
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glutSolidSphere(2.0, 10, 5);
glPopMatrix();
glutSwapBuffers();
frames++;
if (anim) {
GLint t = glutGet(GLUT_ELAPSED_TIME);
if (t - t0 >= 5000) {
GLfloat seconds =(GLfloat)(t - t0) / 1000.0f;
GLfloat fps = frames / seconds;
printf("%d frames in %6.3f seconds = %6.3f FPS\n",
frames, seconds, fps);
t0 = t;
frames = 0;
}
}
}
static void
Idle(void)
{
lightPos[0] += delta;
if (lightPos[0] > 25.0f || lightPos[0] < -25.0f)
delta = -delta;
glutPostRedisplay();
}
static void
Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
static void
CleanUp(void)
{
glDeleteShader_func(fragShader);
glDeleteShader_func(vertShader);
glDeleteProgram_func(program);
glutDestroyWindow(win);
}
static void
Key(unsigned char key, int x, int y)
{
(void) x;
(void) y;
switch(key) {
case ' ':
case 'a':
anim = !anim;
if (anim)
glutIdleFunc(Idle);
else
glutIdleFunc(NULL);
break;
case 'x':
lightPos[0] -= 1.0f;
break;
case 'X':
lightPos[0] += 1.0f;
break;
case 'w':
wire = !wire;
if (wire)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
break;
case 'p':
pixelLight = !pixelLight;
if (pixelLight)
printf("Per-pixel lighting\n");
else
printf("Conventional lighting\n");
break;
case 27:
CleanUp();
exit(0);
break;
}
glutPostRedisplay();
}
static void
SpecialKey(int key, int x, int y)
{
const GLfloat step = 3.0f;
(void) x;
(void) y;
switch(key) {
case GLUT_KEY_UP:
xRot -= step;
break;
case GLUT_KEY_DOWN:
xRot += step;
break;
case GLUT_KEY_LEFT:
yRot -= step;
break;
case GLUT_KEY_RIGHT:
yRot += step;
break;
}
glutPostRedisplay();
}
static void
Init(void)
{
static const char *fragShaderText =
"uniform vec3 lightPos;\n"
"uniform vec4 diffuse;\n"
"uniform vec4 specular;\n"
"varying vec3 normal;\n"
"void main() {\n"
" // Compute dot product of light direction and normal vector\n"
" float dotProd = max(dot(lightPos, normalize(normal)), 0.0);\n"
" // Compute diffuse and specular contributions\n"
" gl_FragColor = diffuse * dotProd + specular * pow(dotProd, 20.0);\n"
"}\n";
static const char *vertShaderText =
"varying vec3 normal;\n"
"void main() {\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" normal = gl_NormalMatrix * gl_Normal;\n"
"}\n";
const char *version;
version = (const char *) glGetString(GL_VERSION);
if (version[0] != '2' || version[1] != '.') {
printf("Warning: this program expects OpenGL 2.0\n");
/*exit(1);*/
}
glCreateShader_func = (PFNGLCREATESHADERPROC) glutGetProcAddress("glCreateShader");
glDeleteShader_func = (PFNGLDELETESHADERPROC) glutGetProcAddress("glDeleteShader");
glDeleteProgram_func = (PFNGLDELETEPROGRAMPROC) glutGetProcAddress("glDeleteProgram");
glShaderSource_func = (PFNGLSHADERSOURCEPROC) glutGetProcAddress("glShaderSource");
glGetShaderSource_func = (PFNGLGETSHADERSOURCEPROC) glutGetProcAddress("glGetShaderSource");
glCompileShader_func = (PFNGLCOMPILESHADERPROC) glutGetProcAddress("glCompileShader");
glCreateProgram_func = (PFNGLCREATEPROGRAMPROC) glutGetProcAddress("glCreateProgram");
glAttachShader_func = (PFNGLATTACHSHADERPROC) glutGetProcAddress("glAttachShader");
glLinkProgram_func = (PFNGLLINKPROGRAMPROC) glutGetProcAddress("glLinkProgram");
glUseProgram_func = (PFNGLUSEPROGRAMPROC) glutGetProcAddress("glUseProgram");
glGetUniformLocation_func = (PFNGLGETUNIFORMLOCATIONPROC) glutGetProcAddress("glGetUniformLocation");
glIsProgram_func = (PFNGLISPROGRAMPROC) glutGetProcAddress("glIsProgram");
glIsShader_func = (PFNGLISSHADERPROC) glutGetProcAddress("glIsShader");
glUniform3fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform3fv");
glUniform4fv_func = (PFNGLUNIFORM3FVPROC) glutGetProcAddress("glUniform4fv");
fragShader = glCreateShader_func(GL_FRAGMENT_SHADER);
glShaderSource_func(fragShader, 1, &fragShaderText, NULL);
glCompileShader_func(fragShader);
vertShader = glCreateShader_func(GL_VERTEX_SHADER);
glShaderSource_func(vertShader, 1, &vertShaderText, NULL);
glCompileShader_func(vertShader);
program = glCreateProgram_func();
glAttachShader_func(program, fragShader);
glAttachShader_func(program, vertShader);
glLinkProgram_func(program);
glUseProgram_func(program);
uLightPos = glGetUniformLocation_func(program, "lightPos");
uDiffuse = glGetUniformLocation_func(program, "diffuse");
uSpecular = glGetUniformLocation_func(program, "specular");
glUniform4fv_func(uDiffuse, 1, diffuse);
glUniform4fv_func(uSpecular, 1, specular);
glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);
printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
printf("Press p to toggle between per-pixel and per-vertex lighting\n");
/* test glGetShaderSource() */
{
GLsizei len = strlen(fragShaderText) + 1;
GLsizei lenOut;
GLchar *src =(GLchar *) malloc(len * sizeof(GLchar));
glGetShaderSource_func(fragShader, 0, NULL, src);
glGetShaderSource_func(fragShader, len, &lenOut, src);
assert(len == lenOut + 1);
assert(strcmp(src, fragShaderText) == 0);
free(src);
}
assert(glIsProgram_func(program));
assert(glIsShader_func(fragShader));
assert(glIsShader_func(vertShader));
}
int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition( 0, 0);
glutInitWindowSize(200, 200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutSpecialFunc(SpecialKey);
glutDisplayFunc(Redisplay);
if (anim)
glutIdleFunc(Idle);
Init();
glutMainLoop();
return 0;
}

View File

@ -29,33 +29,32 @@ static GLboolean ScaleAndBias = GL_FALSE;
static GLboolean Benchmark = GL_FALSE; static GLboolean Benchmark = GL_FALSE;
static GLubyte *TempImage = NULL; static GLubyte *TempImage = NULL;
#if 0 #define COMBO 1
#if COMBO == 0
#define ReadFormat ImgFormat #define ReadFormat ImgFormat
#define ReadType GL_UNSIGNED_BYTE #define ReadType GL_UNSIGNED_BYTE
#endif #elif COMBO == 1
#if 1
static GLenum ReadFormat = GL_RGBA; static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_UNSIGNED_BYTE; static GLenum ReadType = GL_UNSIGNED_BYTE;
#endif #elif COMBO == 2
#if 0
static GLenum ReadFormat = GL_RGB; static GLenum ReadFormat = GL_RGB;
static GLenum ReadType = GL_UNSIGNED_BYTE; static GLenum ReadType = GL_UNSIGNED_BYTE;
#endif #elif COMBO == 3
#if 0
static GLenum ReadFormat = GL_RGB; static GLenum ReadFormat = GL_RGB;
static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5; static GLenum ReadType = GL_UNSIGNED_SHORT_5_6_5;
#endif #elif COMBO == 4
#if 0
static GLenum ReadFormat = GL_RGBA; static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV; static GLenum ReadType = GL_UNSIGNED_SHORT_1_5_5_5_REV;
#endif #elif COMBO == 5
#if 0
static GLenum ReadFormat = GL_BGRA; static GLenum ReadFormat = GL_BGRA;
static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1; static GLenum ReadType = GL_UNSIGNED_SHORT_5_5_5_1;
#endif #elif COMBO == 6
#if 0
static GLenum ReadFormat = GL_BGRA; static GLenum ReadFormat = GL_BGRA;
static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV; static GLenum ReadType = GL_UNSIGNED_SHORT_4_4_4_4_REV;
#elif COMBO == 7
static GLenum ReadFormat = GL_RGBA;
static GLenum ReadType = GL_HALF_FLOAT_ARB;
#undef GL_OES_read_format
#endif #endif
@ -313,8 +312,10 @@ Init( GLboolean ciMode )
Reset(); Reset();
/* allocate an extra 1KB in case we're tinkering with pack alignment */ /* allocate large TempImage to store and image data type, plus an
TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * sizeof(GLubyte) * extra 1KB in case we're tinkering with pack alignment.
*/
TempImage = (GLubyte *) malloc(ImgWidth * ImgHeight * 4 * 4
+ 1000); + 1000);
assert(TempImage); assert(TempImage);
} }

322
dist/Mesa/progs/demos/streaming_rect.c vendored Normal file
View File

@ -0,0 +1,322 @@
/*
* GL_ARB_multitexture demo
*
* Command line options:
* -info print GL implementation information
*
*
* Brian Paul November 1998 This program is in the public domain.
* Modified on 12 Feb 2002 for > 2 texture units.
*/
#define GL_GLEXT_PROTOTYPES
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include "readtex.h"
#define ANIMATE 10
#define PBO 11
#define QUIT 100
static GLboolean Animate = GL_TRUE;
static GLboolean use_pbo = 1;
static GLboolean whole_rect = 1;
static GLfloat Drift = 0.0;
static GLfloat drift_increment = 1/255.0;
static GLfloat Xrot = 20.0, Yrot = 30.0;
static GLuint Width = 1024;
static GLuint Height = 512;
static void Idle( void )
{
if (Animate) {
Drift += drift_increment;
if (Drift >= 1.0)
Drift = 0.0;
glutPostRedisplay();
}
}
static int max( int a, int b ) { return a > b ? a : b; }
static int min( int a, int b ) { return a < b ? a : b; }
static void DrawObject()
{
GLint size = Width * Height * 4;
if (use_pbo) {
/* XXX: This is extremely important - semantically makes the buffer
* contents undefined, but in practice means that the driver can
* release the old copy of the texture and allocate a new one
* without waiting for outstanding rendering to complete.
*/
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT, size, NULL, GL_STREAM_DRAW_ARB);
{
char *image = glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, GL_WRITE_ONLY_ARB);
printf("char %d\n", (unsigned char)(Drift * 255));
memset(image, size, (unsigned char)(Drift * 255));
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT);
}
/* BGRA is required for most hardware paths:
*/
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, NULL);
}
else {
static char *image = NULL;
if (image == NULL)
image = malloc(size);
memset(image, size, (unsigned char)(Drift * 255));
/* BGRA should be the fast path for regular uploads as well.
*/
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, Width, Height, 0,
GL_BGRA, GL_UNSIGNED_BYTE, image);
}
{
int x,y,w,h;
if (whole_rect) {
x = y = 0;
w = Width;
h = Height;
}
else {
x = y = 0;
w = min(10, Width);
h = min(10, Height);
}
glBegin(GL_QUADS);
glTexCoord2f( x, y);
glVertex2f( x, y );
glTexCoord2f( x, y + h);
glVertex2f( x, y + h);
glTexCoord2f( x + w + .5, y + h);
glVertex2f( x + w, y + h );
glTexCoord2f( x + w, y + .5);
glVertex2f( x + w, y );
glEnd();
}
}
static void Display( void )
{
static GLint T0 = 0;
static GLint Frames = 0;
GLint t;
glClear( GL_COLOR_BUFFER_BIT );
glPushMatrix();
DrawObject();
glPopMatrix();
glutSwapBuffers();
Frames++;
t = glutGet(GLUT_ELAPSED_TIME);
if (t - T0 >= 1000) {
GLfloat seconds = (t - T0) / 1000.0;
GLfloat fps = Frames / seconds;
printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
drift_increment = 2.2 * seconds / Frames;
T0 = t;
Frames = 0;
}
}
static void Reshape( int width, int height )
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
/* glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 ); */
gluOrtho2D( 0, width, height, 0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef(0.375, 0.375, 0);
}
static void ModeMenu(int entry)
{
if (entry==ANIMATE) {
Animate = !Animate;
}
else if (entry==PBO) {
use_pbo = !use_pbo;
}
else if (entry==QUIT) {
exit(0);
}
glutPostRedisplay();
}
static void Key( unsigned char key, int x, int y )
{
(void) x;
(void) y;
switch (key) {
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
static void SpecialKey( int key, int x, int y )
{
float step = 3.0;
(void) x;
(void) y;
switch (key) {
case GLUT_KEY_UP:
Xrot += step;
break;
case GLUT_KEY_DOWN:
Xrot -= step;
break;
case GLUT_KEY_LEFT:
Yrot += step;
break;
case GLUT_KEY_RIGHT:
Yrot -= step;
break;
}
glutPostRedisplay();
}
static void Init( int argc, char *argv[] )
{
const char *exten = (const char *) glGetString(GL_EXTENSIONS);
GLuint texObj, DrawPBO;
GLint size;
if (!strstr(exten, "GL_ARB_multitexture")) {
printf("Sorry, GL_ARB_multitexture not supported by this renderer.\n");
exit(1);
}
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
printf("%d x %d max texture size\n", size, size);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* allocate two texture objects */
glGenTextures(1, &texObj);
/* setup the texture objects */
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texObj);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenBuffersARB(1, &DrawPBO);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_EXT, DrawPBO);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_EXT,
Width * Height * 4, NULL, GL_STREAM_DRAW);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glEnable(GL_TEXTURE_RECTANGLE_ARB);
glShadeModel(GL_SMOOTH);
glClearColor(0.3, 0.3, 0.4, 1.0);
if (argc > 1 && strcmp(argv[1], "-info")==0) {
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
}
}
int main( int argc, char *argv[] )
{
GLint i;
glutInit( &argc, argv );
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-w") == 0) {
Width = atoi(argv[i+1]);
if (Width <= 0) {
printf("Error, bad width\n");
exit(1);
}
i++;
}
else if (strcmp(argv[i], "-h") == 0) {
Height = atoi(argv[i+1]);
if (Height <= 0) {
printf("Error, bad height\n");
exit(1);
}
i++;
}
}
glutInitWindowSize( Width, Height );
glutInitWindowPosition( 0, 0 );
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
glutCreateWindow(argv[0] );
Init( argc, argv );
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutSpecialFunc( SpecialKey );
glutDisplayFunc( Display );
glutIdleFunc( Idle );
glutCreateMenu(ModeMenu);
glutAddMenuEntry("Toggle Animation", ANIMATE);
glutAddMenuEntry("Toggle PBO", PBO);
glutAddMenuEntry("Quit", QUIT);
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutMainLoop();
return 0;
}

View File

@ -38,8 +38,8 @@
#include <GL/glut.h> #include <GL/glut.h>
static GLsizei MaxSize = 1024; static GLsizei MaxSize = 2048;
static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0; static GLsizei TexWidth = 1024, TexHeight = 1024, TexBorder = 0;
static GLboolean ScaleAndBias = GL_FALSE; static GLboolean ScaleAndBias = GL_FALSE;
static GLboolean SubImage = GL_FALSE; static GLboolean SubImage = GL_FALSE;
static GLdouble DownloadRate = 0.0; /* texels/sec */ static GLdouble DownloadRate = 0.0; /* texels/sec */
@ -47,6 +47,32 @@ static GLdouble DownloadRate = 0.0; /* texels/sec */
static GLuint Mode = 0; static GLuint Mode = 0;
/* Try and avoid L2 cache effects by cycling through a small number of
* textures.
*
* At the initial size of 1024x1024x4 == 4mbyte, say 8 textures will
* keep us out of most caches at 32mb total.
*
* This turns into a fairly interesting question of what exactly you
* expect to be in cache in normal usage, and what you think should be
* outside. There's no rules for this, no reason to favour one usage
* over another except what the application you care about happens to
* resemble most closely.
*
* - Should the client texture image be in L2 cache? Has it just been
* generated or read from disk?
* - Does the application really use >1 texture, or is it constantly
* updating one image in-place?
*
* Different answers will favour different texture upload mechanisms.
* To upload an image that is purely outside of cache, a DMA-based
* upload will probably win, whereas for small, in-cache textures,
* copying looks good.
*/
#define NR_TEXOBJ 4
static GLuint TexObj[NR_TEXOBJ];
struct FormatRec { struct FormatRec {
GLenum Format; GLenum Format;
GLenum Type; GLenum Type;
@ -116,25 +142,57 @@ TypeStr(GLenum type)
} }
} }
/* On x86, there is a performance cliff for memcpy to texture memory
* for sources below 64 byte alignment. We do our best with this in
* the driver, but it is better if the images are correctly aligned to
* start with:
*/
#define ALIGN (1<<12)
static unsigned align(unsigned value, unsigned a)
{
return (value + a - 1) & ~(a-1);
}
static int MIN2(int a, int b)
{
return a < b ? a : b;
}
static void static void
MeasureDownloadRate(void) MeasureDownloadRate(void)
{ {
const int w = TexWidth + 2 * TexBorder; const int w = TexWidth + 2 * TexBorder;
const int h = TexHeight + 2 * TexBorder; const int h = TexHeight + 2 * TexBorder;
const int bytes = w * h * BytesPerTexel(Format); const int image_bytes = align(w * h * BytesPerTexel(Format), ALIGN);
const int bytes = image_bytes * NR_TEXOBJ;
GLubyte *orig_texImage, *orig_getImage;
GLubyte *texImage, *getImage; GLubyte *texImage, *getImage;
GLdouble t0, t1, time; GLdouble t0, t1, time;
int count; int count;
int i; int i;
int offset = 0;
GLdouble total = 0; /* ints will tend to overflow */
texImage = (GLubyte *) malloc(bytes); printf("allocating %d bytes for %d %dx%d images\n",
getImage = (GLubyte *) malloc(bytes); bytes, NR_TEXOBJ, w, h);
if (!texImage || !getImage) {
orig_texImage = (GLubyte *) malloc(bytes + ALIGN);
orig_getImage = (GLubyte *) malloc(image_bytes + ALIGN);
if (!orig_texImage || !orig_getImage) {
DownloadRate = 0.0; DownloadRate = 0.0;
return; return;
} }
printf("alloc %p %p\n", orig_texImage, orig_getImage);
texImage = (GLubyte *)align((unsigned)orig_texImage, ALIGN);
getImage = (GLubyte *)align((unsigned)orig_getImage, ALIGN);
for (i = 1; !(((unsigned)texImage) & i); i<<=1)
;
printf("texture image alignment: %d bytes (%p)\n", i, texImage);
for (i = 0; i < bytes; i++) { for (i = 0; i < bytes; i++) {
texImage[i] = i & 0xff; texImage[i] = i & 0xff;
} }
@ -166,16 +224,50 @@ MeasureDownloadRate(void)
count = 0; count = 0;
t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001; t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
do { do {
int img = count%NR_TEXOBJ;
GLubyte *img_ptr = texImage + img * image_bytes;
glBindTexture(GL_TEXTURE_2D, TexObj[img]);
if (SubImage && count > 0) { if (SubImage && count > 0) {
glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h, /* Only update a portion of the image each iteration. This
* is presumably why you'd want to use texsubimage, otherwise
* you may as well just call teximage again.
*
* A bigger question is whether to use a pointer that moves
* with each call, ie does the incoming data come from L2
* cache under normal circumstances, or is it pulled from
* uncached memory?
*
* There's a good argument to say L2 cache, ie you'd expect
* the data to have been recently generated. It's possible
* that it could have come from a file read, which may or may
* not have gone through the cpu.
*/
glTexSubImage2D(GL_TEXTURE_2D, 0,
-TexBorder,
-TexBorder + offset * h/8,
w,
h/8,
FormatTable[Format].Format, FormatTable[Format].Format,
FormatTable[Format].Type, texImage); FormatTable[Format].Type,
#if 1
texImage /* likely in L2$ */
#else
img_ptr + offset * bytes/8 /* unlikely in L2$ */
#endif
);
offset += 1;
offset %= 8;
total += w * h / 8;
} }
else { else {
glTexImage2D(GL_TEXTURE_2D, 0, glTexImage2D(GL_TEXTURE_2D, 0,
FormatTable[Format].IntFormat, w, h, TexBorder, FormatTable[Format].IntFormat, w, h, TexBorder,
FormatTable[Format].Format, FormatTable[Format].Format,
FormatTable[Format].Type, texImage); FormatTable[Format].Type,
img_ptr);
total += w*h;
} }
/* draw a tiny polygon to force texture into texram */ /* draw a tiny polygon to force texture into texram */
@ -192,25 +284,12 @@ MeasureDownloadRate(void)
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
printf("w*h=%d count=%d time=%f\n", w*h, count, time); printf("total texels=%f time=%f\n", total, time);
DownloadRate = w * h * count / time; DownloadRate = total / time;
#if 0
if (!ScaleAndBias) {
/* verify texture readback */
glGetTexImage(GL_TEXTURE_2D, 0,
FormatTable[Format].Format,
FormatTable[Format].Type, getImage);
for (i = 0; i < w * h; i++) {
if (texImage[i] != getImage[i]) {
printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
}
}
}
#endif
free(texImage); free(orig_texImage);
free(getImage); free(orig_getImage);
{ {
GLint err = glGetError(); GLint err = glGetError();

View File

@ -4,7 +4,7 @@
* See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions. * See Mesa/include/GL/osmesa.h for documentation of the OSMesa functions.
* *
* If you want to render BIG images you'll probably have to increase * If you want to render BIG images you'll probably have to increase
* MAX_WIDTH and MAX_HEIGHT in src/config.h. * MAX_WIDTH and MAX_Height in src/config.h.
* *
* This program is in the public domain. * This program is in the public domain.
* *
@ -27,8 +27,8 @@
#define SAVE_TARGA #define SAVE_TARGA
#define WIDTH 400 static int Width = 400;
#define HEIGHT 400 static int Height = 400;
static void static void
@ -175,10 +175,10 @@ write_targa(const char *filename, const GLubyte *buffer, int width, int height)
fputc (0x00, f); fputc (0x00, f);
fputc (0x00, f); /* Y-origin of Image */ fputc (0x00, f); /* Y-origin of Image */
fputc (0x00, f); fputc (0x00, f);
fputc (WIDTH & 0xff, f); /* Image Width */ fputc (Width & 0xff, f); /* Image Width */
fputc ((WIDTH>>8) & 0xff, f); fputc ((Width>>8) & 0xff, f);
fputc (HEIGHT & 0xff, f); /* Image Height */ fputc (Height & 0xff, f); /* Image Height */
fputc ((HEIGHT>>8) & 0xff, f); fputc ((Height>>8) & 0xff, f);
fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */ fputc (0x18, f); /* Pixel Depth, 0x18 => 24 Bits */
fputc (0x20, f); /* Image Descriptor */ fputc (0x20, f); /* Image Descriptor */
fclose(f); fclose(f);
@ -248,36 +248,43 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
OSMesaContext ctx;
void *buffer; void *buffer;
int i;
char *filename = NULL; char *filename = NULL;
if (argc < 2) {
fprintf(stderr, "Usage:\n");
fprintf(stderr, " osdemo filename [width height]\n");
return 0;
}
filename = argv[1];
if (argc == 4) {
Width = atoi(argv[2]);
Height = atoi(argv[3]);
}
/* Create an RGBA-mode context */ /* Create an RGBA-mode context */
#if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305
/* specify Z, stencil, accum sizes */ /* specify Z, stencil, accum sizes */
OSMesaContext ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL ); ctx = OSMesaCreateContextExt( OSMESA_RGBA, 16, 0, 0, NULL );
#else #else
OSMesaContext ctx = OSMesaCreateContext( OSMESA_RGBA, NULL ); ctx = OSMesaCreateContext( OSMESA_RGBA, NULL );
#endif #endif
if (!ctx) { if (!ctx) {
printf("OSMesaCreateContext failed!\n"); printf("OSMesaCreateContext failed!\n");
return 0; return 0;
} }
for (i = 1; i < argc; i++) {
if (argv[i][0] != '-')
filename = argv[i];
}
/* Allocate the image buffer */ /* Allocate the image buffer */
buffer = malloc( WIDTH * HEIGHT * 4 * sizeof(GLubyte) ); buffer = malloc( Width * Height * 4 * sizeof(GLubyte) );
if (!buffer) { if (!buffer) {
printf("Alloc image buffer failed!\n"); printf("Alloc image buffer failed!\n");
return 0; return 0;
} }
/* Bind the buffer to the context and make it current */ /* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, WIDTH, HEIGHT )) { if (!OSMesaMakeCurrent( ctx, buffer, GL_UNSIGNED_BYTE, Width, Height )) {
printf("OSMesaMakeCurrent failed!\n"); printf("OSMesaMakeCurrent failed!\n");
return 0; return 0;
} }
@ -295,9 +302,9 @@ main(int argc, char *argv[])
if (filename != NULL) { if (filename != NULL) {
#ifdef SAVE_TARGA #ifdef SAVE_TARGA
write_targa(filename, buffer, WIDTH, HEIGHT); write_targa(filename, buffer, Width, Height);
#else #else
write_ppm(filename, buffer, WIDTH, HEIGHT); write_ppm(filename, buffer, Width, Height);
#endif #endif
} }
else { else {

View File

@ -1,8 +1,8 @@
/* /*
* Mesa 3-D graphics library * Mesa 3-D graphics library
* Version: 6.1 * Version: 6.5.2
* *
* Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -32,6 +32,7 @@
*/ */
#define GL_GLEXT_PROTOTYPES
#define GLX_GLXEXT_PROTOTYPES #define GLX_GLXEXT_PROTOTYPES
#include <GL/gl.h> #include <GL/gl.h>
#include <GL/glx.h> #include <GL/glx.h>
@ -50,7 +51,7 @@ static int ScrNum;
static GLXContext Context; static GLXContext Context;
static Window Win[2]; /* Win[0] = source, Win[1] = dest */ static Window Win[2]; /* Win[0] = source, Win[1] = dest */
static GLint Width[2], Height[2]; static GLint Width[2], Height[2];
static GLboolean TestClipping = GL_FALSE;
static GLfloat Angle = 0.0; static GLfloat Angle = 0.0;
static GLboolean DrawFront = GL_FALSE; static GLboolean DrawFront = GL_FALSE;
@ -123,7 +124,7 @@ Redraw(void)
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glShadeModel(GL_FLAT); glShadeModel(GL_FLAT);
glClearColor(0.5, 0.5, 0.5, 1.0); glClearColor(0.5, 0.5, 0.5, 0.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
/* draw blue quad */ /* draw blue quad */
@ -150,22 +151,18 @@ Redraw(void)
return; return;
} }
/* raster pos setup */
glViewport(0, 0, Width[1], Height[1]);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
glRasterPos2f(-1, -1);
/* copy the image between windows */ /* copy the image between windows */
glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR); glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glPopMatrix(); if (TestClipping) {
glMatrixMode(GL_MODELVIEW); glWindowPos2iARB(-2, -2);
glPopMatrix(); glCopyPixels(-2, -2, Width[0] + 4, Height[0] + 4, GL_COLOR);
}
else {
glWindowPos2iARB(0, 0);
glCopyPixels(0, 0, Width[0], Height[0], GL_COLOR);
}
if (DrawFront) if (DrawFront)
glFinish(); glFinish();
@ -309,6 +306,8 @@ Init(void)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
if (argc > 1 && strcmp(argv[1], "-clip") == 0)
TestClipping = GL_TRUE;
Init(); Init();
EventLoop(); EventLoop();
return 0; return 0;