Merge remote branch 'origin/gallium-0.2' into gallium-0.2

This commit is contained in:
Ben Skeggs
2008-10-27 15:40:33 +11:00
116 changed files with 11861 additions and 7804 deletions
+2
View File
@@ -70,12 +70,14 @@ platform = env['platform']
# derived options
x86 = machine == 'x86'
ppc = machine == 'ppc'
gcc = platform in ('linux', 'freebsd', 'darwin')
msvc = platform in ('windows', 'winddk')
Export([
'debug',
'x86',
'ppc',
'dri',
'llvm',
'platform',
+2 -1
View File
@@ -24,6 +24,7 @@ _machine_map = {
'i486': 'x86',
'i586': 'x86',
'i686': 'x86',
'ppc' : 'ppc',
'x86_64': 'x86_64',
}
if 'PROCESSOR_ARCHITECTURE' in os.environ:
@@ -56,7 +57,7 @@ def AddOptions(opts):
opts.Add(BoolOption('profile', 'profile build', 'no'))
#opts.Add(BoolOption('quiet', 'quiet command lines', 'no'))
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'x86', 'x86_64')))
allowed_values=('generic', 'ppc', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', default_platform,
allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince')))
opts.Add(BoolOption('llvm', 'use LLVM', 'no'))
+1 -1
View File
@@ -24,7 +24,7 @@ OPT_FLAGS = -O3
SDK = /opt/cell/sdk/usr
CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -mabi=altivec -maltivec \
CFLAGS = $(OPT_FLAGS) -Wall -Winline -fPIC -m32 -std=c99 -mabi=altivec -maltivec \
-I. -I$(SDK)/include \
-DGALLIUM_CELL -DUSE_XSHM
+3 -8
View File
@@ -55,20 +55,15 @@ SRC_DIRS := glx/x11 egl $(SRC_DIRS)
# Directories
ifeq ($(USING_EGL), 1)
SRC_DIRS = egl glx/x11 gallium mesa glu glut/glx glw
SRC_DIRS = egl glx/x11 gallium mesa glu glut/glx glw
PROGRAM_DIRS = egl xdemos
else
SRC_DIRS = glx/x11 gallium mesa glu glut/glx glw
PROGRAM_DIRS = xdemos
endif
# EGL directories
EGL_DRIVERS_DIRS = demo dri xdri
EGL_DRIVERS_DIRS = demo glx
DRIVER_DIRS =
WINDOW_SYSTEM = dri
GALLIUM_WINSYS_DIRS = drm egl_xlib
GALLIUM_WINSYS_DIRS = drm
# gamma are missing because they have not been converted to use the new
# interface.
+27 -15
View File
@@ -83,23 +83,23 @@ Similarly, textures are tiled and brought into local store as needed.
<H2>Status</H2>
<p>
As of September 2008, the driver supports smooth/flat shaded triangle rendering
with Z testing and simple texture mapping.
Simple demos like gears run successfully.
To test texture mapping, try progs/demos/texcyl (press right mouse button for
rendering options).
As of October 2008, the driver runs quite a few OpenGL demos.
Features that work include:
</p>
<ul>
<li>Point/line/triangle rendering, glDrawPixels
<li>2D, NPOT and cube texture maps with nearest/linear/mipmap filtering
<li>Dynamic SPU code generation for fragment shaders, but not complete
<li>Dynamic SPU code generation for fragment ops (blend, Z-test, etc), but not complete
<li>Dynamic PPU/PPC code generation for vertex shaders, but not complete
</ul>
<p>
Performance has recently improved with the addition of PPC code generation
for vertex shaders, but the code quality isn't too great yet.
</p>
<p>
Runtime/dynamic code generation is being done for per-fragment
operations (Z test, blend, etc) and for fragment programs (though only a
few opcodes are implemented now).
</p>
<p>
In general, however, the driver is rather slow because all vertex
transformation is being done by an interpreter running on the PPU.
Programs with many vertices or complex vertex shaders will run especially
slow.
This will be addressed in the future.
Another bottleneck is SwapBuffers. It may be the limiting factor for
many simple GL tests.
</p>
@@ -114,8 +114,20 @@ more of the following debug options:
<li><b>checker</b> - use a different background clear color for each SPU.
This lets you see which SPU is rendering which screen tiles.
<li><b>sync</b> - wait/synchronize after each DMA transfer
<li><b>asm</b> - print generated SPU assembly code to stdout
<li><b>fragops</b> - emit fragment ops debug messages
<li><b>fragopfallback</b> - don't use codegen for fragment ops
<li><b>cmd</b> - print SPU commands as their received
<li><b>cache</b> - print texture cache statistics when program exits
</ul>
<p>
Note that some of these options may only work for linux-cell-debug builds.
</p>
<p>
If the GALLIUM_NOPPC env var is set, PPC code generation will not be used
and vertex shaders will be run with the TGSI interpreter.
</p>
<p>
If the GALLIUM_NOCELL env var is set, the softpipe driver will be used
intead of the Cell driver.
+1 -1
View File
@@ -45,7 +45,7 @@ static GLint uTexture;
static GLuint SphereList, RectList, CurList;
static GLint win = 0;
static GLboolean anim = 0*GL_TRUE;
static GLboolean anim = GL_TRUE;
static GLboolean wire = GL_FALSE;
static GLboolean pixelLight = GL_TRUE;
+87 -17
View File
@@ -9,6 +9,9 @@
#include <GL/glut.h>
#include "readtex.h"
#define TEST_CLAMP 0
#define TEST_MIPMAPS 0
#define MAX_TEXTURES 8
@@ -16,7 +19,8 @@ static int Win;
static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
static GLboolean Anim = GL_TRUE;
static GLboolean Blend = GL_FALSE;
static GLboolean MipMap = 1+GL_FALSE;
static GLuint Filter = 0;
static GLboolean Clamp = GL_FALSE;
static GLuint NumTextures;
static GLuint Textures[MAX_TEXTURES];
@@ -32,6 +36,22 @@ static const char *DefaultFiles[] = {
};
#define NUM_FILTERS 5
static
struct filter {
GLenum min, mag;
const char *name;
} FilterModes[NUM_FILTERS] = {
{ GL_NEAREST, GL_NEAREST, "Nearest,Nearest" },
{ GL_LINEAR, GL_LINEAR, "Linear,Linear" },
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST, "NearestMipmapNearest,Nearest" },
{ GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR, "LinearMipmapNearest,Linear" },
{ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, "LinearMipmapLinear,Linear" }
};
static void
Idle(void)
{
@@ -58,10 +78,17 @@ DrawTextures(void)
glBindTexture(GL_TEXTURE_2D, Textures[i]);
glBegin(GL_POLYGON);
#if TEST_CLAMP
glTexCoord2f( -0.5, -0.5 ); glVertex2f( -ar, -1.0 );
glTexCoord2f( 1.5, -0.5 ); glVertex2f( ar, -1.0 );
glTexCoord2f( 1.5, 1.5 ); glVertex2f( ar, 1.0 );
glTexCoord2f( -0.5, 1.5 ); glVertex2f( -ar, 1.0 );
#else
glTexCoord2f( 0.0, 0.0 ); glVertex2f( -ar, -1.0 );
glTexCoord2f( 1.0, 0.0 ); glVertex2f( ar, -1.0 );
glTexCoord2f( 1.0, 1.0 ); glVertex2f( ar, 1.0 );
glTexCoord2f( 0.0, 1.0 ); glVertex2f( -ar, 1.0 );
#endif
glEnd();
glPopMatrix();
@@ -137,19 +164,23 @@ Randomize(void)
static void
SetTexFilters(void)
SetTexParams(void)
{
GLuint i;
for (i = 0; i < NumTextures; i++) {
glBindTexture(GL_TEXTURE_2D, Textures[i]);
if (MipMap) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
FilterModes[Filter].min);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
FilterModes[Filter].mag);
if (Clamp) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
}
}
@@ -163,6 +194,7 @@ Key(unsigned char key, int x, int y)
(void) y;
switch (key) {
case 'a':
case ' ':
Anim = !Anim;
if (Anim)
glutIdleFunc(Idle);
@@ -172,12 +204,19 @@ Key(unsigned char key, int x, int y)
case 'b':
Blend = !Blend;
break;
case 'm':
MipMap = !MipMap;
SetTexFilters();
case 'f':
Filter = (Filter + 1) % NUM_FILTERS;
SetTexParams();
break;
case 'r':
Randomize();
break;
#if TEST_CLAMP
case 'c':
Clamp = !Clamp;
SetTexParams();
break;
#endif
case 'z':
Zrot -= step;
break;
@@ -190,9 +229,9 @@ Key(unsigned char key, int x, int y)
break;
}
printf("Blend=%s MipMap=%s\n",
printf("Blend=%s Filter=%s\n",
Blend ? "Y" : "n",
MipMap ? "Y" : "n");
FilterModes[Filter].name);
glutPostRedisplay();
}
@@ -231,15 +270,46 @@ LoadTextures(GLuint n, const char *files[])
glGenTextures(n, Textures);
SetTexParams();
for (i = 0; i < n; i++) {
GLint w, h;
glBindTexture(GL_TEXTURE_2D, Textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
#if TEST_MIPMAPS
{
static const GLubyte color[9][4] = {
{255, 0, 0},
{0, 255, 0},
{0, 0, 255},
{0, 255, 255},
{255, 0, 255},
{255, 255, 0},
{255, 128, 255},
{128, 128, 128},
{64, 64, 64}
};
GLubyte image[256*256*4];
int i, level;
w = h = 256;
for (level = 0; level <= 8; level++) {
for (i = 0; i < w * h; i++) {
image[i*4+0] = color[level][0];
image[i*4+1] = color[level][1];
image[i*4+2] = color[level][2];
image[i*4+3] = color[level][3];
}
printf("Load level %d: %d x %d\n", level, w>>level, h>>level);
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, w>>level, h>>level, 0,
GL_RGBA, GL_UNSIGNED_BYTE, image);
}
}
#else
if (!LoadRGBMipmaps2(files[i], GL_TEXTURE_2D, GL_RGB, &w, &h)) {
printf("Error: couldn't load %s\n", files[i]);
exit(1);
}
#endif
TexAspect[i] = (float) w / (float) h;
printf("Loaded %s\n", files[i]);
}
@@ -277,7 +347,7 @@ Usage(void)
printf("Keys:\n");
printf(" a - toggle animation\n");
printf(" b - toggle blending\n");
printf(" m - toggle mipmapping\n");
printf(" f - change texture filter mode\n");
printf(" r - randomize\n");
printf(" ESC - exit\n");
}
@@ -288,7 +358,7 @@ main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitWindowPosition(0, 0);
glutInitWindowSize(400, 400);
glutInitWindowSize(700, 700);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
+4
View File
@@ -97,6 +97,7 @@ SOURCES = \
tri-query.c \
tri-scissor-tri.c \
tri-stencil.c \
tri-tex.c \
tri-tex-3d.c \
tri-tri.c \
tri-unfilled-edgeflag.c \
@@ -126,8 +127,11 @@ SOURCES = \
vp-line-clip.c \
vp-tri.c \
vp-tri-swap.c \
vp-tri-tex.c \
vp-tri-imm.c \
vp-tri-cb.c \
vp-tri-cb-pos.c \
vp-tri-cb-tex.c \
vp-unfilled.c
PROGS = $(SOURCES:%.c=%)
+168
View File
@@ -0,0 +1,168 @@
/*
* Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that (i) the above copyright notices and this permission notice appear in
* all copies of the software and related documentation, and (ii) the name of
* Silicon Graphics may not be used in any advertising or
* publicity relating to the software without the specific, prior written
* permission of Silicon Graphics.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
* ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/glut.h>
GLenum doubleBuffer;
static void Init(void)
{
fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
glClearColor(0.0, 0.0, 1.0, 0.0);
#define SIZE 32
{
GLubyte tex2d[SIZE][SIZE][3];
GLint s, t;
for (s = 0; s < SIZE; s++) {
for (t = 0; t < SIZE; t++) {
#if 0
tex2d[t][s][0] = (s < SIZE/2) ? 0 : 255;
tex2d[t][s][1] = (t < SIZE/2) ? 0 : 255;
tex2d[t][s][2] = 0;
#else
tex2d[t][s][0] = s*255/(SIZE-1);
tex2d[t][s][1] = t*255/(SIZE-1);
tex2d[t][s][2] = 0;
#endif
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3, SIZE, SIZE, 0,
GL_RGB, GL_UNSIGNED_BYTE, tex2d);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
}
static void Reshape(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); */
glMatrixMode(GL_MODELVIEW);
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(1);
default:
return;
}
glutPostRedisplay();
}
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glTexCoord2f(1,-1);
glVertex3f( 0.9, -0.9, -0.0);
glTexCoord2f(1,1);
glVertex3f( 0.9, 0.9, -0.0);
glTexCoord2f(-1,0);
glVertex3f(-0.9, 0.0, -0.0);
glEnd();
glFlush();
if (doubleBuffer) {
glutSwapBuffers();
}
}
static GLenum Args(int argc, char **argv)
{
GLint i;
doubleBuffer = GL_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
} else {
fprintf(stderr, "%s (Bad option).\n", argv[i]);
return GL_FALSE;
}
}
return GL_TRUE;
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
if (Args(argc, argv) == GL_FALSE) {
exit(1);
}
glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
type = GLUT_RGB | GLUT_ALPHA;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
if (glutCreateWindow("First Tri") == GL_FALSE) {
exit(1);
}
Init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
return 0;
}
+7 -10
View File
@@ -57,16 +57,13 @@ static void Reshape(int width, int height)
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
glutDestroyWindow(win);
exit(0);
default:
return;
}
glutPostRedisplay();
switch (key) {
case 27:
exit(0);
default:
glutPostRedisplay();
return;
}
}
static void Draw(void)
+156
View File
@@ -0,0 +1,156 @@
/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
GLenum doubleBuffer;
static void Init(void)
{
GLint errno;
GLuint prognum;
static const char *prog1 =
"!!ARBvp1.0\n"
"PARAM Emission = state.material.emission; \n"
"PARAM Ambient = state.material.ambient; \n"
"PARAM Diffuse = state.material.diffuse; \n"
"PARAM Specular = state.material.specular; \n"
"DP4 result.position.x, Ambient, vertex.position;\n"
"DP4 result.position.y, Diffuse, vertex.position;\n"
"DP4 result.position.z, Specular, vertex.position;\n"
"DP4 result.position.w, Emission, vertex.position;\n"
"MOV result.color, vertex.color;\n"
"END\n";
const float Ambient[4] = { 0.0, 1.0, 0.0, 0.0 };
const float Diffuse[4] = { 1.0, 0.0, 0.0, 0.0 };
const float Specular[4] = { 0.0, 0.0, 1.0, 0.0 };
const float Emission[4] = { 0.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission);
glGenProgramsARB(1, &prognum);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(prog1), (const GLubyte *) prog1);
assert(glIsProgramARB(prognum));
errno = glGetError();
printf("glGetError = %d\n", errno);
if (errno != GL_NO_ERROR)
{
GLint errorpos;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
printf("errorpos: %d\n", errorpos);
printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
}
glEnable(GL_VERTEX_PROGRAM_NV);
}
static void Reshape(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); */
glMatrixMode(GL_MODELVIEW);
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(1);
default:
return;
}
glutPostRedisplay();
}
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glColor3f(0,0,.7);
glVertex3f( 0.9, -0.9, -0.0);
glColor3f(.8,0,0);
glVertex3f( 0.9, 0.9, -0.0);
glColor3f(0,.9,0);
glVertex3f(-0.9, 0.0, -0.0);
glEnd();
glFlush();
if (doubleBuffer) {
glutSwapBuffers();
}
}
static GLenum Args(int argc, char **argv)
{
GLint i;
doubleBuffer = GL_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
} else {
fprintf(stderr, "%s (Bad option).\n", argv[i]);
return GL_FALSE;
}
}
return GL_TRUE;
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
if (Args(argc, argv) == GL_FALSE) {
exit(1);
}
glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
type = GLUT_RGB | GLUT_ALPHA;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
if (glutCreateWindow("First Tri") == GL_FALSE) {
exit(1);
}
Init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
return 0;
}
+189
View File
@@ -0,0 +1,189 @@
/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
GLenum doubleBuffer;
static void Init(void)
{
GLint errno;
GLuint prognum;
static const char *prog1 =
"!!ARBvp1.0\n"
"PARAM Emission = state.material.emission; \n"
"PARAM Ambient = state.material.ambient; \n"
"PARAM Diffuse = state.material.diffuse; \n"
"PARAM Specular = state.material.specular; \n"
"DP4 result.position.x, Ambient, vertex.position;\n"
"DP4 result.position.y, Diffuse, vertex.position;\n"
"DP4 result.position.z, Specular, vertex.position;\n"
"DP4 result.position.w, Emission, vertex.position;\n"
"MOV result.texcoord[0], vertex.texcoord[0];\n"
"END\n";
const float Ambient[4] = { 0.0, 1.0, 0.0, 0.0 };
const float Diffuse[4] = { 1.0, 0.0, 0.0, 0.0 };
const float Specular[4] = { 0.0, 0.0, 1.0, 0.0 };
const float Emission[4] = { 0.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission);
glGenProgramsARB(1, &prognum);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(prog1), (const GLubyte *) prog1);
assert(glIsProgramARB(prognum));
errno = glGetError();
printf("glGetError = %d\n", errno);
if (errno != GL_NO_ERROR)
{
GLint errorpos;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
printf("errorpos: %d\n", errorpos);
printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
}
glEnable(GL_VERTEX_PROGRAM_NV);
#define SIZE 32
{
GLubyte tex2d[SIZE][SIZE][3];
GLint s, t;
for (s = 0; s < SIZE; s++) {
for (t = 0; t < SIZE; t++) {
#if 0
tex2d[t][s][0] = (s < SIZE/2) ? 0 : 255;
tex2d[t][s][1] = (t < SIZE/2) ? 0 : 255;
tex2d[t][s][2] = 0;
#else
tex2d[t][s][0] = s*255/(SIZE-1);
tex2d[t][s][1] = t*255/(SIZE-1);
tex2d[t][s][2] = 0;
#endif
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3, SIZE, SIZE, 0,
GL_RGB, GL_UNSIGNED_BYTE, tex2d);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
}
static void Reshape(int width, int height)
{
glViewport(0, 0, (GLint)width, (GLint)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
/* glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); */
glMatrixMode(GL_MODELVIEW);
}
static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(1);
default:
return;
}
glutPostRedisplay();
}
static void Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLES);
glTexCoord2f(1,-1);
glVertex3f( 0.9, -0.9, -0.0);
glTexCoord2f(1,1);
glVertex3f( 0.9, 0.9, -0.0);
glTexCoord2f(-1,0);
glVertex3f(-0.9, 0.0, -0.0);
glEnd();
glFlush();
if (doubleBuffer) {
glutSwapBuffers();
}
}
static GLenum Args(int argc, char **argv)
{
GLint i;
doubleBuffer = GL_FALSE;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-sb") == 0) {
doubleBuffer = GL_FALSE;
} else if (strcmp(argv[i], "-db") == 0) {
doubleBuffer = GL_TRUE;
} else {
fprintf(stderr, "%s (Bad option).\n", argv[i]);
return GL_FALSE;
}
}
return GL_TRUE;
}
int main(int argc, char **argv)
{
GLenum type;
glutInit(&argc, argv);
if (Args(argc, argv) == GL_FALSE) {
exit(1);
}
glutInitWindowPosition(0, 0); glutInitWindowSize( 250, 250);
type = GLUT_RGB | GLUT_ALPHA;
type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
glutInitDisplayMode(type);
if (glutCreateWindow("First Tri") == GL_FALSE) {
exit(1);
}
Init();
glutReshapeFunc(Reshape);
glutKeyboardFunc(Key);
glutDisplayFunc(Draw);
glutMainLoop();
return 0;
}
+137
View File
@@ -0,0 +1,137 @@
/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
static void Init( void )
{
GLint errno;
GLuint prognum;
static const char *prog1 =
"!!ARBvp1.0\n"
"MOV result.texcoord[0], vertex.texcoord[0];\n"
"MOV result.position, vertex.position;\n"
"END\n";
glGenProgramsARB(1, &prognum);
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
strlen(prog1), (const GLubyte *) prog1);
assert(glIsProgramARB(prognum));
errno = glGetError();
printf("glGetError = %d\n", errno);
if (errno != GL_NO_ERROR)
{
GLint errorpos;
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
printf("errorpos: %d\n", errorpos);
printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
}
#define SIZE 32
{
GLubyte tex2d[SIZE][SIZE][3];
GLint s, t;
for (s = 0; s < SIZE; s++) {
for (t = 0; t < SIZE; t++) {
#if 0
tex2d[t][s][0] = (s < SIZE/2) ? 0 : 255;
tex2d[t][s][1] = (t < SIZE/2) ? 0 : 255;
tex2d[t][s][2] = 0;
#else
tex2d[t][s][0] = s*255/(SIZE-1);
tex2d[t][s][1] = t*255/(SIZE-1);
tex2d[t][s][2] = 0;
#endif
}
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3, SIZE, SIZE, 0,
GL_RGB, GL_UNSIGNED_BYTE, tex2d);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
}
}
static void Display( void )
{
glClearColor(0.3, 0.3, 0.3, 1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_VERTEX_PROGRAM_NV);
glBegin(GL_TRIANGLES);
glTexCoord2f(1,-1);
glVertex3f( 0.9, -0.9, -0.0);
glTexCoord2f(1,1);
glVertex3f( 0.9, 0.9, -0.0);
glTexCoord2f(-1,0);
glVertex3f(-0.9, 0.0, -0.0);
glEnd();
glFlush();
}
static void Reshape( int width, int height )
{
glViewport( 0, 0, width, height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
/*glTranslatef( 0.0, 0.0, -15.0 );*/
}
static void Key( unsigned char key, int x, int y )
{
(void) x;
(void) y;
switch (key) {
case 27:
exit(0);
break;
}
glutPostRedisplay();
}
int main( int argc, char *argv[] )
{
glutInit( &argc, argv );
glutInitWindowPosition( 0, 0 );
glutInitWindowSize( 250, 250 );
glutInitDisplayMode( GLUT_DEPTH | GLUT_RGB | GLUT_SINGLE );
glutCreateWindow(argv[0]);
glutReshapeFunc( Reshape );
glutKeyboardFunc( Key );
glutDisplayFunc( Display );
Init();
glutMainLoop();
return 0;
}
+11
View File
@@ -155,6 +155,17 @@ static void Init( void )
printf("errorpos: %d\n", errorpos);
printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
}
{
const float Ambient[4] = { 0.0, 1.0, 0.0, 0.0 };
const float Diffuse[4] = { 1.0, 0.0, 0.0, 0.0 };
const float Specular[4] = { 0.0, 0.0, 1.0, 0.0 };
const float Emission[4] = { 0.0, 0.0, 0.0, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission);
}
}
+11
View File
@@ -0,0 +1,11 @@
!!ARBvp1.0
PARAM Emission = state.material.emission;
PARAM Ambient = state.material.ambient;
PARAM Diffuse = state.material.diffuse;
PARAM Specular = state.material.specular;
DP4 result.position.x, Ambient, vertex.position;
DP4 result.position.y, Diffuse, vertex.position;
DP4 result.position.z, Specular, vertex.position;
DP4 result.position.w, Emission, vertex.position;
MOV result.color, vertex.color;
END
+1
View File
@@ -175,6 +175,7 @@ def generate(env):
machine = env['machine']
platform = env['platform']
x86 = env['machine'] == 'x86'
ppc = env['machine'] == 'ppc'
gcc = env['platform'] in ('linux', 'freebsd', 'darwin')
msvc = env['platform'] in ('windows', 'winddk', 'wince')
+1
View File
@@ -40,6 +40,7 @@ C_SOURCES = \
draw_vs_aos_machine.c \
draw_vs_exec.c \
draw_vs_llvm.c \
draw_vs_ppc.c \
draw_vs_sse.c
+1
View File
@@ -38,6 +38,7 @@ draw = env.ConvenienceLibrary(
'draw_vs_aos_machine.c',
'draw_vs_exec.c',
'draw_vs_llvm.c',
'draw_vs_ppc.c',
'draw_vs_sse.c',
'draw_vs_varient.c'
])
+4 -1
View File
@@ -85,7 +85,10 @@ draw_create_vertex_shader(struct draw_context *draw,
if (!vs) {
vs = draw_create_vs_sse( draw, shader );
if (!vs) {
vs = draw_create_vs_exec( draw, shader );
vs = draw_create_vs_ppc( draw, shader );
if (!vs) {
vs = draw_create_vs_exec( draw, shader );
}
}
}
+4
View File
@@ -157,6 +157,10 @@ struct draw_vertex_shader *
draw_create_vs_sse(struct draw_context *draw,
const struct pipe_shader_state *templ);
struct draw_vertex_shader *
draw_create_vs_ppc(struct draw_context *draw,
const struct pipe_shader_state *templ);
struct draw_vertex_shader *
draw_create_vs_llvm(struct draw_context *draw,
const struct pipe_shader_state *templ);
+1 -1
View File
@@ -338,7 +338,7 @@ static void emit_store_R32G32B32A32( struct aos_compilation *cp,
struct x86_reg dst_ptr,
struct x86_reg dataXMM )
{
sse_movaps(cp->func, dst_ptr, dataXMM);
sse_movups(cp->func, dst_ptr, dataXMM);
}
static void emit_store_R32G32B32( struct aos_compilation *cp,
+1 -3
View File
@@ -46,7 +46,6 @@
struct exec_vertex_shader {
struct draw_vertex_shader base;
struct tgsi_exec_machine *machine;
const struct tgsi_token *machine_tokens;
};
static struct exec_vertex_shader *exec_vertex_shader( struct draw_vertex_shader *vs )
@@ -66,12 +65,11 @@ vs_exec_prepare( struct draw_vertex_shader *shader,
/* Specify the vertex program to interpret/execute.
* Avoid rebinding when possible.
*/
if (evs->machine_tokens != shader->state.tokens) {
if (evs->machine->Tokens != shader->state.tokens) {
tgsi_exec_machine_bind_shader(evs->machine,
shader->state.tokens,
PIPE_MAX_SAMPLERS,
NULL /*samplers*/ );
evs->machine_tokens = shader->state.tokens;
}
}
+274
View File
@@ -0,0 +1,274 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
* Brian Paul
*/
#include "util/u_math.h"
#include "util/u_memory.h"
#include "pipe/p_config.h"
#include "draw_vs.h"
#if defined(PIPE_ARCH_PPC)
#include "pipe/p_shader_tokens.h"
#include "draw_private.h"
#include "draw_context.h"
#include "rtasm/rtasm_cpu.h"
#include "rtasm/rtasm_ppc.h"
#include "tgsi/tgsi_ppc.h"
#include "tgsi/tgsi_parse.h"
typedef void (PIPE_CDECL *codegen_function) (float (*inputs)[4][4],
float (*outputs)[4][4],
float (*temps)[4][4],
float (*immeds)[4][4],
float (*consts)[4],
const float *builtins);
#if 0
const struct tgsi_exec_vector *input,
struct tgsi_exec_vector *output,
float (*constant)[4], /* 3 */
struct tgsi_exec_vector *temporary, /* 4 */
float (*immediates)[4], /* 5 */
const float (*aos_input)[4], /* 6 */
uint num_inputs, /* 7 */
uint input_stride, /* 8 */
float (*aos_output)[4], /* 9 */
uint num_outputs, /* 10 */
uint output_stride ); /* 11 */
#endif
struct draw_ppc_vertex_shader {
struct draw_vertex_shader base;
struct ppc_function ppc_program;
codegen_function func;
struct tgsi_exec_machine *machine;
};
static void
vs_ppc_prepare( struct draw_vertex_shader *base,
struct draw_context *draw )
{
}
/* Simplified vertex shader interface for the pt paths. Given the
* complexity of code-generating all the above operations together,
* it's time to try doing all the other stuff separately.
*/
static void
vs_ppc_run_linear( struct draw_vertex_shader *base,
const float (*input)[4],
float (*output)[4],
const float (*constants)[4],
unsigned count,
unsigned input_stride,
unsigned output_stride )
{
struct draw_ppc_vertex_shader *shader = (struct draw_ppc_vertex_shader *)base;
struct tgsi_exec_machine *machine = shader->machine;
unsigned int i;
#define MAX_VERTICES 4
/* loop over verts */
for (i = 0; i < count; i += MAX_VERTICES) {
const uint max_vertices = MIN2(MAX_VERTICES, count - i);
float inputs_soa[PIPE_MAX_SHADER_INPUTS][4][4] ALIGN16_ATTRIB;
float outputs_soa[PIPE_MAX_SHADER_OUTPUTS][4][4] ALIGN16_ATTRIB;
float temps_soa[TGSI_EXEC_NUM_TEMPS][4][4] ALIGN16_ATTRIB;
uint attr;
/* convert (up to) four input verts to SoA format */
for (attr = 0; attr < base->info.num_inputs; attr++) {
const float *vIn = (const float *) input;
uint vert;
for (vert = 0; vert < max_vertices; vert++) {
#if 0
if (attr==0)
printf("Input v%d a%d: %f %f %f %f\n",
vert, attr, vIn[0], vIn[1], vIn[2], vIn[3]);
#endif
inputs_soa[attr][0][vert] = vIn[attr * 4 + 0];
inputs_soa[attr][1][vert] = vIn[attr * 4 + 1];
inputs_soa[attr][2][vert] = vIn[attr * 4 + 2];
inputs_soa[attr][3][vert] = vIn[attr * 4 + 3];
vIn += input_stride / 4;
}
}
/* run compiled shader
*/
#if 0
shader->func(machine->Inputs,
machine->Outputs,
(float (*)[4])constants,
machine->Temps,
(float (*)[4])shader->base.immediates,
input,
base->info.num_inputs,
input_stride,
output,
base->info.num_outputs,
output_stride );
#else
shader->func(inputs_soa, outputs_soa, temps_soa,
(float (*)[4][4]) shader->base.immediates,
(float (*)[4]) constants,
ppc_builtin_constants);
/*output[0][0] = input[0][0] * 0.5;*/
#endif
/* convert (up to) four output verts from SoA back to AoS format */
for (attr = 0; attr < base->info.num_outputs; attr++) {
float *vOut = (float *) output;
uint vert;
for (vert = 0; vert < max_vertices; vert++) {
vOut[attr * 4 + 0] = outputs_soa[attr][0][vert];
vOut[attr * 4 + 1] = outputs_soa[attr][1][vert];
vOut[attr * 4 + 2] = outputs_soa[attr][2][vert];
vOut[attr * 4 + 3] = outputs_soa[attr][3][vert];
#if 0
if (attr==0)
printf("Output v%d a%d: %f %f %f %f\n",
vert, attr, vOut[0], vOut[1], vOut[2], vOut[3]);
#endif
vOut += output_stride / 4;
}
}
/* advance to next group of four input/output verts */
input = (const float (*)[4])((const char *)input + input_stride * max_vertices);
output = (float (*)[4])((char *)output + output_stride * max_vertices);
}
}
static void
vs_ppc_delete( struct draw_vertex_shader *base )
{
struct draw_ppc_vertex_shader *shader = (struct draw_ppc_vertex_shader *)base;
ppc_release_func( &shader->ppc_program );
align_free( (void *) shader->base.immediates );
FREE( (void*) shader->base.state.tokens );
FREE( shader );
}
struct draw_vertex_shader *
draw_create_vs_ppc(struct draw_context *draw,
const struct pipe_shader_state *templ)
{
struct draw_ppc_vertex_shader *vs;
vs = CALLOC_STRUCT( draw_ppc_vertex_shader );
if (vs == NULL)
return NULL;
/* we make a private copy of the tokens */
vs->base.state.tokens = tgsi_dup_tokens(templ->tokens);
if (!vs->base.state.tokens)
goto fail;
tgsi_scan_shader(templ->tokens, &vs->base.info);
vs->base.draw = draw;
#if 0
if (1)
vs->base.create_varient = draw_vs_varient_aos_ppc;
else
#endif
vs->base.create_varient = draw_vs_varient_generic;
vs->base.prepare = vs_ppc_prepare;
vs->base.run_linear = vs_ppc_run_linear;
vs->base.delete = vs_ppc_delete;
vs->base.immediates = align_malloc(TGSI_EXEC_NUM_IMMEDIATES * 4 * 4 *
sizeof(float), 16);
vs->machine = &draw->vs.machine;
ppc_init_func( &vs->ppc_program, 2000 ); /* XXX fix limit */
if (!tgsi_emit_ppc( (struct tgsi_token *) vs->base.state.tokens,
&vs->ppc_program,
(float (*)[4])vs->base.immediates,
TRUE ))
goto fail;
vs->func = (codegen_function) ppc_get_func( &vs->ppc_program );
if (!vs->func) {
goto fail;
}
return &vs->base;
fail:
/*
debug_error("tgsi_emit_ppc() failed, falling back to interpreter\n");
*/
ppc_release_func( &vs->ppc_program );
FREE(vs);
return NULL;
}
#else /* PIPE_ARCH_PPC */
struct draw_vertex_shader *
draw_create_vs_ppc( struct draw_context *draw,
const struct pipe_shader_state *templ )
{
return (void *) 0;
}
#endif /* PIPE_ARCH_PPC */
+1
View File
@@ -7,6 +7,7 @@ C_SOURCES = \
rtasm_cpu.c \
rtasm_execmem.c \
rtasm_x86sse.c \
rtasm_ppc.c \
rtasm_ppc_spe.c
include ../../Makefile.template
+1
View File
@@ -6,6 +6,7 @@ rtasm = env.ConvenienceLibrary(
'rtasm_cpu.c',
'rtasm_execmem.c',
'rtasm_x86sse.c',
'rtasm_ppc.c',
'rtasm_ppc_spe.c',
])
+606 -47
View File
@@ -23,10 +23,19 @@
/**
* PPC code generation.
* For reference, see http://www.power.org/resources/reading/PowerISA_V2.05.pdf
* ABI info: http://www.cs.utsa.edu/~whaley/teach/cs6463FHPO/LEC/lec12_ho.pdf
*
* Other PPC refs:
* http://www-01.ibm.com/chips/techlib/techlib.nsf/techdocs/852569B20050FF778525699600719DF2
* http://www.ibm.com/developerworks/eserver/library/es-archguide-v2.html
* http://www.freescale.com/files/product/doc/MPCFPE32B.pdf
*
* \author Brian Paul
*/
#include <stdio.h>
#include "util/u_memory.h"
#include "pipe/p_debug.h"
#include "rtasm_ppc.h"
@@ -35,40 +44,148 @@
void
ppc_init_func(struct ppc_function *p, unsigned max_inst)
{
p->store = align_malloc(max_inst * PPC_INST_SIZE, 16);
p->num_inst = 0;
p->max_inst = max_inst;
p->vec_used = ~0;
uint i;
p->store = align_malloc(max_inst * PPC_INST_SIZE, 16);
p->num_inst = 0;
p->max_inst = max_inst;
p->reg_used = 0x0;
p->fp_used = 0x0;
p->vec_used = 0x0;
/* only allow using gp registers 3..12 for now */
for (i = 0; i < 3; i++)
ppc_reserve_register(p, i);
for (i = 12; i < PPC_NUM_REGS; i++)
ppc_reserve_register(p, i);
}
void
ppc_release_func(struct ppc_function *p)
{
assert(p->num_inst <= p->max_inst);
if (p->store != NULL) {
align_free(p->store);
}
p->store = NULL;
assert(p->num_inst <= p->max_inst);
if (p->store != NULL) {
align_free(p->store);
}
p->store = NULL;
}
void (*ppc_get_func(struct ppc_function *p))(void)
{
#if 0
DUMP_END();
if (DISASSEM && p->store)
debug_printf("disassemble %p %p\n", p->store, p->csr);
if (p->store == p->error_overflow)
return (void (*)(void)) NULL;
else
#endif
return (void (*)(void)) p->store;
}
void
ppc_dump_func(const struct ppc_function *p)
{
uint i;
for (i = 0; i < p->num_inst; i++) {
debug_printf("%3u: 0x%08x\n", i, p->store[i]);
}
}
/**
* Alloate a vector register.
* Mark a register as being unavailable.
*/
int
ppc_reserve_register(struct ppc_function *p, int reg)
{
assert(reg < PPC_NUM_REGS);
p->reg_used |= (1 << reg);
return reg;
}
/**
* Allocate a general purpose register.
* \return register index or -1 if none left.
*/
int
ppc_allocate_vec_register(struct ppc_function *p, int reg)
ppc_allocate_register(struct ppc_function *p)
{
unsigned i;
for (i = 0; i < PPC_NUM_REGS; i++) {
const uint64_t mask = 1 << i;
if ((p->reg_used & mask) == 0) {
p->reg_used |= mask;
return i;
}
}
return -1;
}
/**
* Mark the given general purpose register as "unallocated".
*/
void
ppc_release_register(struct ppc_function *p, int reg)
{
assert(reg < PPC_NUM_REGS);
assert(p->reg_used & (1 << reg));
p->reg_used &= ~(1 << reg);
}
/**
* Allocate a floating point register.
* \return register index or -1 if none left.
*/
int
ppc_allocate_fp_register(struct ppc_function *p)
{
unsigned i;
for (i = 0; i < PPC_NUM_FP_REGS; i++) {
const uint64_t mask = 1 << i;
if ((p->fp_used & mask) == 0) {
p->fp_used |= mask;
return i;
}
}
return -1;
}
/**
* Mark the given floating point register as "unallocated".
*/
void
ppc_release_fp_register(struct ppc_function *p, int reg)
{
assert(reg < PPC_NUM_FP_REGS);
assert(p->fp_used & (1 << reg));
p->fp_used &= ~(1 << reg);
}
/**
* Allocate a vector register.
* \return register index or -1 if none left.
*/
int
ppc_allocate_vec_register(struct ppc_function *p)
{
unsigned i;
for (i = 0; i < PPC_NUM_VEC_REGS; i++) {
const uint64_t mask = 1 << i;
if ((p->vec_used & mask) != 0) {
p->vec_used &= ~mask;
if ((p->vec_used & mask) == 0) {
p->vec_used |= mask;
return i;
}
}
return -1;
}
@@ -80,9 +197,8 @@ void
ppc_release_vec_register(struct ppc_function *p, int reg)
{
assert(reg < PPC_NUM_VEC_REGS);
assert((p->vec_used & (1 << reg)) == 0);
p->vec_used |= (1 << reg);
assert(p->vec_used & (1 << reg));
p->vec_used &= ~(1 << reg);
}
@@ -98,31 +214,6 @@ union vx_inst {
} inst;
};
union vxr_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned vD:5;
unsigned vA:5;
unsigned vB:5;
unsigned rC:1;
unsigned op2:10;
} inst;
};
union va_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned vD:5;
unsigned vA:5;
unsigned vB:5;
unsigned vC:5;
unsigned op2:6;
} inst;
};
static inline void
emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
{
@@ -136,6 +227,19 @@ emit_vx(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
assert(p->num_inst <= p->max_inst);
};
union vxr_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned vD:5;
unsigned vA:5;
unsigned vB:5;
unsigned rC:1;
unsigned op2:10;
} inst;
};
static inline void
emit_vxr(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
{
@@ -150,6 +254,19 @@ emit_vxr(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB)
assert(p->num_inst <= p->max_inst);
};
union va_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned vD:5;
unsigned vA:5;
unsigned vB:5;
unsigned vC:5;
unsigned op2:6;
} inst;
};
static inline void
emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC)
{
@@ -165,6 +282,189 @@ emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC)
};
union i_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned li:24;
unsigned aa:1;
unsigned lk:1;
} inst;
};
static INLINE void
emit_i(struct ppc_function *p, uint op, uint li, uint aa, uint lk)
{
union i_inst inst;
inst.inst.op = op;
inst.inst.li = li;
inst.inst.aa = aa;
inst.inst.lk = lk;
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
}
union xl_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned bo:5;
unsigned bi:5;
unsigned unused:3;
unsigned bh:2;
unsigned op2:10;
unsigned lk:1;
} inst;
};
static INLINE void
emit_xl(struct ppc_function *p, uint op, uint bo, uint bi, uint bh,
uint op2, uint lk)
{
union xl_inst inst;
inst.inst.op = op;
inst.inst.bo = bo;
inst.inst.bi = bi;
inst.inst.unused = 0x0;
inst.inst.bh = bh;
inst.inst.op2 = op2;
inst.inst.lk = lk;
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
}
static INLINE void
dump_xl(const char *name, uint inst)
{
union xl_inst i;
i.bits = inst;
debug_printf("%s = 0x%08x\n", name, inst);
debug_printf(" op: %d 0x%x\n", i.inst.op, i.inst.op);
debug_printf(" bo: %d 0x%x\n", i.inst.bo, i.inst.bo);
debug_printf(" bi: %d 0x%x\n", i.inst.bi, i.inst.bi);
debug_printf(" unused: %d 0x%x\n", i.inst.unused, i.inst.unused);
debug_printf(" bh: %d 0x%x\n", i.inst.bh, i.inst.bh);
debug_printf(" op2: %d 0x%x\n", i.inst.op2, i.inst.op2);
debug_printf(" lk: %d 0x%x\n", i.inst.lk, i.inst.lk);
}
union x_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned vrs:5;
unsigned ra:5;
unsigned rb:5;
unsigned op2:10;
unsigned unused:1;
} inst;
};
static INLINE void
emit_x(struct ppc_function *p, uint op, uint vrs, uint ra, uint rb, uint op2)
{
union x_inst inst;
inst.inst.op = op;
inst.inst.vrs = vrs;
inst.inst.ra = ra;
inst.inst.rb = rb;
inst.inst.op2 = op2;
inst.inst.unused = 0x0;
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
}
union d_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned rt:5;
unsigned ra:5;
unsigned si:16;
} inst;
};
static inline void
emit_d(struct ppc_function *p, uint op, uint rt, uint ra, int si)
{
union d_inst inst;
assert(si >= -32768);
assert(si <= 32767);
inst.inst.op = op;
inst.inst.rt = rt;
inst.inst.ra = ra;
inst.inst.si = (unsigned) (si & 0xffff);
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
};
union a_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned frt:5;
unsigned fra:5;
unsigned frb:5;
unsigned unused:5;
unsigned op2:5;
unsigned rc:1;
} inst;
};
static inline void
emit_a(struct ppc_function *p, uint op, uint frt, uint fra, uint frb, uint op2,
uint rc)
{
union a_inst inst;
inst.inst.op = op;
inst.inst.frt = frt;
inst.inst.fra = fra;
inst.inst.frb = frb;
inst.inst.unused = 0x0;
inst.inst.op2 = op2;
inst.inst.rc = rc;
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
};
union xo_inst {
uint32_t bits;
struct {
unsigned op:6;
unsigned rt:5;
unsigned ra:5;
unsigned rb:5;
unsigned oe:1;
unsigned op2:9;
unsigned rc:1;
} inst;
};
static INLINE void
emit_xo(struct ppc_function *p, uint op, uint rt, uint ra, uint rb, uint oe,
uint op2, uint rc)
{
union xo_inst inst;
inst.inst.op = op;
inst.inst.rt = rt;
inst.inst.ra = ra;
inst.inst.rb = rb;
inst.inst.oe = oe;
inst.inst.op2 = op2;
inst.inst.rc = rc;
p->store[p->num_inst++] = inst.bits;
assert(p->num_inst <= p->max_inst);
}
/**
** float vector arithmetic
@@ -172,7 +472,7 @@ emit_va(struct ppc_function *p, uint op2, uint vD, uint vA, uint vB, uint vC)
/** vector float add */
void
ppc_vaddfp(struct ppc_function *p,uint vD, uint vA, uint vB)
ppc_vaddfp(struct ppc_function *p, uint vD, uint vA, uint vB)
{
emit_vx(p, 10, vD, vA, vB);
}
@@ -198,11 +498,11 @@ ppc_vmaxfp(struct ppc_function *p, uint vD, uint vA, uint vB)
emit_vx(p, 1034, vD, vA, vB);
}
/** vector float mult add */
/** vector float mult add: vD = vA * vB + vC */
void
ppc_vmaddfp(struct ppc_function *p, uint vD, uint vA, uint vB, uint vC)
{
emit_va(p, 46, vD, vA, vB, vC);
emit_va(p, 46, vD, vA, vC, vB); /* note arg order */
}
/** vector float compare greater than */
@@ -282,13 +582,34 @@ ppc_vrfiz(struct ppc_function *p, uint vD, uint vB)
emit_vx(p, 586, vD, 0, vB);
}
/** vector store: store vR at mem[vA+vB] */
void
ppc_stvx(struct ppc_function *p, uint vR, uint vA, uint vB)
{
emit_x(p, 31, vR, vA, vB, 231);
}
/** vector load: vR = mem[vA+vB] */
void
ppc_lvx(struct ppc_function *p, uint vR, uint vA, uint vB)
{
emit_x(p, 31, vR, vA, vB, 103);
}
/** load vector element word: vR = mem_word[ra+rb] */
void
ppc_lvewx(struct ppc_function *p, uint vr, uint ra, uint rb)
{
emit_x(p, 31, vr, ra, rb, 71);
}
/**
** bitwise operations
** vector bitwise operations
**/
/** vector and */
void
ppc_vand(struct ppc_function *p, uint vD, uint vA, uint vB)
@@ -324,6 +645,22 @@ ppc_vxor(struct ppc_function *p, uint vD, uint vA, uint vB)
emit_vx(p, 1220, vD, vA, vB);
}
/** Pseudo-instruction: vector move */
void
ppc_vmove(struct ppc_function *p, uint vD, uint vA)
{
ppc_vor(p, vD, vA, vA);
}
/** Set vector register to {0,0,0,0} */
void
ppc_vzero(struct ppc_function *p, uint vr)
{
ppc_vxor(p, vr, vr, vr);
}
/**
** Vector shuffle / select / splat / etc
@@ -363,3 +700,225 @@ ppc_vspltw(struct ppc_function *p, uint vD, uint vB, uint imm)
{
emit_vx(p, 652, vD, imm, vB);
}
/** vector splat signed immediate word */
void
ppc_vspltisw(struct ppc_function *p, uint vD, int imm)
{
assert(imm >= -16);
assert(imm < 15);
emit_vx(p, 908, vD, imm, 0);
}
/** vector shift left word: vD[word] = vA[word] << (vB[word] & 0x1f) */
void
ppc_vslw(struct ppc_function *p, uint vD, uint vA, uint vB)
{
emit_vx(p, 388, vD, vA, vB);
}
/**
** integer arithmetic
**/
/** rt = ra + imm */
void
ppc_addi(struct ppc_function *p, uint rt, uint ra, int imm)
{
emit_d(p, 14, rt, ra, imm);
}
/** rt = ra + (imm << 16) */
void
ppc_addis(struct ppc_function *p, uint rt, uint ra, int imm)
{
emit_d(p, 15, rt, ra, imm);
}
/** rt = ra + rb */
void
ppc_add(struct ppc_function *p, uint rt, uint ra, uint rb)
{
emit_xo(p, 31, rt, ra, rb, 0, 266, 0);
}
/** rt = ra AND ra */
void
ppc_and(struct ppc_function *p, uint rt, uint ra, uint rb)
{
emit_x(p, 31, ra, rt, rb, 28); /* note argument order */
}
/** rt = ra AND imm */
void
ppc_andi(struct ppc_function *p, uint rt, uint ra, int imm)
{
emit_d(p, 28, ra, rt, imm); /* note argument order */
}
/** rt = ra OR ra */
void
ppc_or(struct ppc_function *p, uint rt, uint ra, uint rb)
{
emit_x(p, 31, ra, rt, rb, 444); /* note argument order */
}
/** rt = ra OR imm */
void
ppc_ori(struct ppc_function *p, uint rt, uint ra, int imm)
{
emit_d(p, 24, ra, rt, imm); /* note argument order */
}
/** rt = ra XOR ra */
void
ppc_xor(struct ppc_function *p, uint rt, uint ra, uint rb)
{
emit_x(p, 31, ra, rt, rb, 316); /* note argument order */
}
/** rt = ra XOR imm */
void
ppc_xori(struct ppc_function *p, uint rt, uint ra, int imm)
{
emit_d(p, 26, ra, rt, imm); /* note argument order */
}
/** pseudo instruction: move: rt = ra */
void
ppc_mr(struct ppc_function *p, uint rt, uint ra)
{
ppc_or(p, rt, ra, ra);
}
/** pseudo instruction: load immediate: rt = imm */
void
ppc_li(struct ppc_function *p, uint rt, int imm)
{
ppc_addi(p, rt, 0, imm);
}
/** rt = imm << 16 */
void
ppc_lis(struct ppc_function *p, uint rt, int imm)
{
ppc_addis(p, rt, 0, imm);
}
/** rt = imm */
void
ppc_load_int(struct ppc_function *p, uint rt, int imm)
{
ppc_lis(p, rt, (imm >> 16)); /* rt = imm >> 16 */
ppc_ori(p, rt, rt, (imm & 0xffff)); /* rt = rt | (imm & 0xffff) */
}
/**
** integer load/store
**/
/** store rs at memory[(ra)+d],
* then update ra = (ra)+d
*/
void
ppc_stwu(struct ppc_function *p, uint rs, uint ra, int d)
{
emit_d(p, 37, rs, ra, d);
}
/** store rs at memory[(ra)+d] */
void
ppc_stw(struct ppc_function *p, uint rs, uint ra, int d)
{
emit_d(p, 36, rs, ra, d);
}
/** Load rt = mem[(ra)+d]; then zero set high 32 bits to zero. */
void
ppc_lwz(struct ppc_function *p, uint rt, uint ra, int d)
{
emit_d(p, 32, rt, ra, d);
}
/**
** Float (non-vector) arithmetic
**/
/** add: frt = fra + frb */
void
ppc_fadd(struct ppc_function *p, uint frt, uint fra, uint frb)
{
emit_a(p, 63, frt, fra, frb, 21, 0);
}
/** sub: frt = fra - frb */
void
ppc_fsub(struct ppc_function *p, uint frt, uint fra, uint frb)
{
emit_a(p, 63, frt, fra, frb, 20, 0);
}
/** convert to int: rt = (int) ra */
void
ppc_fctiwz(struct ppc_function *p, uint rt, uint fra)
{
emit_x(p, 63, rt, 0, fra, 15);
}
/** store frs at mem[(ra)+offset] */
void
ppc_stfs(struct ppc_function *p, uint frs, uint ra, int offset)
{
emit_d(p, 52, frs, ra, offset);
}
/** store frs at mem[(ra)+(rb)] */
void
ppc_stfiwx(struct ppc_function *p, uint frs, uint ra, uint rb)
{
emit_x(p, 31, frs, ra, rb, 983);
}
/** load frt = mem[(ra)+offset] */
void
ppc_lfs(struct ppc_function *p, uint frt, uint ra, int offset)
{
emit_d(p, 48, frt, ra, offset);
}
/**
** branch instructions
**/
/** BLR: Branch to link register (p. 35) */
void
ppc_blr(struct ppc_function *p)
{
emit_i(p, 18, 0, 0, 1);
}
/** Branch Conditional to Link Register (p. 36) */
void
ppc_bclr(struct ppc_function *p, uint condOp, uint branchHint, uint condReg)
{
emit_xl(p, 19, condOp, condReg, branchHint, 16, 0);
}
/** Pseudo instruction: return from subroutine */
void
ppc_return(struct ppc_function *p)
{
ppc_bclr(p, BRANCH_COND_ALWAYS, BRANCH_HINT_SUB_RETURN, 0);
}
+146 -3
View File
@@ -36,27 +36,47 @@
#define PPC_INST_SIZE 4 /**< 4 bytes / instruction */
#define PPC_NUM_REGS 32
#define PPC_NUM_FP_REGS 32
#define PPC_NUM_VEC_REGS 32
/** Stack pointer register */
#define PPC_REG_SP 1
/** Branch conditions */
#define BRANCH_COND_ALWAYS 0x14 /* binary 1z1zz (z=ignored) */
/** Branch hints */
#define BRANCH_HINT_SUB_RETURN 0x0 /* binary 00 */
struct ppc_function
{
uint32_t *store; /**< instruction buffer */
uint num_inst;
uint max_inst;
uint32_t vec_used; /** used/free vector registers bitmask */
uint32_t reg_used; /** used/free general-purpose registers bitmask */
uint32_t fp_used; /** used/free floating point registers bitmask */
uint32_t vec_used; /** used/free vector registers bitmask */
};
extern void ppc_init_func(struct ppc_function *p, unsigned max_inst);
extern void ppc_release_func(struct ppc_function *p);
extern void (*ppc_get_func( struct ppc_function *p ))( void );
extern void ppc_dump_func(const struct ppc_function *p);
extern int ppc_allocate_vec_register(struct ppc_function *p, int reg);
extern int ppc_reserve_register(struct ppc_function *p, int reg);
extern int ppc_allocate_register(struct ppc_function *p);
extern void ppc_release_register(struct ppc_function *p, int reg);
extern int ppc_allocate_fp_register(struct ppc_function *p);
extern void ppc_release_fp_register(struct ppc_function *p, int reg);
extern int ppc_allocate_vec_register(struct ppc_function *p);
extern void ppc_release_vec_register(struct ppc_function *p, int reg);
/**
** float vector arithmetic
**/
@@ -126,9 +146,22 @@ extern void
ppc_vrfiz(struct ppc_function *p, uint vD, uint vB);
/** vector store: store vR at mem[vA+vB] */
extern void
ppc_stvx(struct ppc_function *p, uint vR, uint vA, uint vB);
/** vector load: vR = mem[vA+vB] */
extern void
ppc_lvx(struct ppc_function *p, uint vR, uint vA, uint vB);
/** load vector element word: vR = mem_word[vA+vB] */
extern void
ppc_lvewx(struct ppc_function *p, uint vR, uint vA, uint vB);
/**
** bitwise operations
** vector bitwise operations
**/
@@ -152,6 +185,15 @@ ppc_vnor(struct ppc_function *p, uint vD, uint vA, uint vB);
extern void
ppc_vxor(struct ppc_function *p, uint vD, uint vA, uint vB);
/** Pseudo-instruction: vector move */
extern void
ppc_vmove(struct ppc_function *p, uint vD, uint vA);
/** Set vector register to {0,0,0,0} */
extern void
ppc_vzero(struct ppc_function *p, uint vr);
/**
** Vector shuffle / select / splat / etc
@@ -177,5 +219,106 @@ ppc_vsplthw(struct ppc_function *p, uint vD, uint vB, uint imm);
extern void
ppc_vspltw(struct ppc_function *p, uint vD, uint vB, uint imm);
/** vector splat signed immediate word */
extern void
ppc_vspltisw(struct ppc_function *p, uint vD, int imm);
/** vector shift left word: vD[word] = vA[word] << (vB[word] & 0x1f) */
extern void
ppc_vslw(struct ppc_function *p, uint vD, uint vA, uint vB);
/**
** scalar arithmetic
**/
extern void
ppc_add(struct ppc_function *p, uint rt, uint ra, uint rb);
extern void
ppc_addi(struct ppc_function *p, uint rt, uint ra, int imm);
extern void
ppc_and(struct ppc_function *p, uint rt, uint ra, uint rb);
extern void
ppc_andi(struct ppc_function *p, uint rt, uint ra, int imm);
extern void
ppc_or(struct ppc_function *p, uint rt, uint ra, uint rb);
extern void
ppc_ori(struct ppc_function *p, uint rt, uint ra, int imm);
extern void
ppc_xor(struct ppc_function *p, uint rt, uint ra, uint rb);
extern void
ppc_xori(struct ppc_function *p, uint rt, uint ra, int imm);
extern void
ppc_mr(struct ppc_function *p, uint rt, uint ra);
extern void
ppc_li(struct ppc_function *p, uint rt, int imm);
extern void
ppc_lis(struct ppc_function *p, uint rt, int imm);
extern void
ppc_load_int(struct ppc_function *p, uint rt, int imm);
/**
** scalar load/store
**/
extern void
ppc_stwu(struct ppc_function *p, uint rs, uint ra, int d);
extern void
ppc_stw(struct ppc_function *p, uint rs, uint ra, int d);
extern void
ppc_lwz(struct ppc_function *p, uint rs, uint ra, int d);
/**
** Float (non-vector) arithmetic
**/
extern void
ppc_fadd(struct ppc_function *p, uint frt, uint fra, uint frb);
extern void
ppc_fsub(struct ppc_function *p, uint frt, uint fra, uint frb);
extern void
ppc_fctiwz(struct ppc_function *p, uint rt, uint ra);
extern void
ppc_stfs(struct ppc_function *p, uint frs, uint ra, int offset);
extern void
ppc_stfiwx(struct ppc_function *p, uint frs, uint ra, uint rb);
/**
** branch instructions
**/
extern void
ppc_blr(struct ppc_function *p);
void
ppc_bclr(struct ppc_function *p, uint condOp, uint branchHint, uint condReg);
extern void
ppc_return(struct ppc_function *p);
#endif /* RTASM_PPC_H */
+1
View File
@@ -11,6 +11,7 @@ C_SOURCES = \
tgsi_info.c \
tgsi_iterate.c \
tgsi_parse.c \
tgsi_ppc.c \
tgsi_scan.c \
tgsi_sse2.c \
tgsi_text.c \
+1
View File
@@ -12,6 +12,7 @@ tgsi = env.ConvenienceLibrary(
'tgsi_parse.c',
'tgsi_sanity.c',
'tgsi_scan.c',
'tgsi_ppc.c',
'tgsi_sse2.c',
'tgsi_text.c',
'tgsi_transform.c',
+910
View File
@@ -0,0 +1,910 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
/**
* TGSI to PowerPC code generation.
*/
#include "pipe/p_config.h"
#if defined(PIPE_ARCH_PPC)
#include "pipe/p_debug.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sse.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_exec.h"
#include "tgsi_ppc.h"
#include "rtasm/rtasm_ppc.h"
/**
* Since it's pretty much impossible to form PPC vector immediates, load
* them from memory here:
*/
const float ppc_builtin_constants[] ALIGN16_ATTRIB = {
1.0f, -128.0f, 128.0, 0.0
};
#define FOR_EACH_CHANNEL( CHAN )\
for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
((INST).FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
FOR_EACH_CHANNEL( CHAN )\
IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
#define CHAN_X 0
#define CHAN_Y 1
#define CHAN_Z 2
#define CHAN_W 3
#define TEMP_ONE_I TGSI_EXEC_TEMP_ONE_I
#define TEMP_ONE_C TGSI_EXEC_TEMP_ONE_C
#define TEMP_R0 TGSI_EXEC_TEMP_R0
#define TEMP_ADDR TGSI_EXEC_TEMP_ADDR
/**
* Context/state used during code gen.
*/
struct gen_context
{
struct ppc_function *f;
int inputs_reg; /**< GP register pointing to input params */
int outputs_reg; /**< GP register pointing to output params */
int temps_reg; /**< GP register pointing to temporary "registers" */
int immed_reg; /**< GP register pointing to immediates buffer */
int const_reg; /**< GP register pointing to constants buffer */
int builtins_reg; /**< GP register pointint to built-in constants */
int one_vec; /**< vector register with {1.0, 1.0, 1.0, 1.0} */
int bit31_vec; /**< vector register with {1<<31, 1<<31, 1<<31, 1<<31} */
};
/**
* Load the given vector register with {value, value, value, value}.
* The value must be in the ppu_builtin_constants[] array.
* We wouldn't need this if there was a simple way to load PPC vector
* registers with immediate values!
*/
static void
load_constant_vec(struct gen_context *gen, int dst_vec, float value)
{
uint pos;
for (pos = 0; pos < Elements(ppc_builtin_constants); pos++) {
if (ppc_builtin_constants[pos] == value) {
int offset_reg = ppc_allocate_register(gen->f);
int offset = pos * 4;
ppc_li(gen->f, offset_reg, offset);
/* Load 4-byte word into vector register.
* The vector slot depends on the effective address we load from.
* We know that our builtins start at a 16-byte boundary so we
* know that 'swizzle' tells us which vector slot will have the
* loaded word. The other vector slots will be undefined.
*/
ppc_lvewx(gen->f, dst_vec, gen->builtins_reg, offset_reg);
/* splat word[pos % 4] across the vector reg */
ppc_vspltw(gen->f, dst_vec, dst_vec, pos % 4);
ppc_release_register(gen->f, offset_reg);
return;
}
}
assert(0 && "Need to add new constant to ppc_builtin_constants array");
}
/**
* Return index of vector register containing {1.0, 1.0, 1.0, 1.0}.
*/
static int
gen_one_vec(struct gen_context *gen)
{
if (gen->one_vec < 0) {
gen->one_vec = ppc_allocate_vec_register(gen->f);
load_constant_vec(gen, gen->one_vec, 1.0f);
}
return gen->one_vec;
}
/**
* Return index of vector register containing {1<<31, 1<<31, 1<<31, 1<<31}.
*/
static int
gen_get_bit31_vec(struct gen_context *gen)
{
if (gen->bit31_vec < 0) {
gen->bit31_vec = ppc_allocate_vec_register(gen->f);
ppc_vspltisw(gen->f, gen->bit31_vec, -1);
ppc_vslw(gen->f, gen->bit31_vec, gen->bit31_vec, gen->bit31_vec);
}
return gen->bit31_vec;
}
/**
* Register fetch, put result in 'dst_vec'.
*/
static void
emit_fetch(struct gen_context *gen,
unsigned dst_vec,
const struct tgsi_full_src_register *reg,
const unsigned chan_index)
{
uint swizzle = tgsi_util_get_full_src_register_extswizzle(reg, chan_index);
switch (swizzle) {
case TGSI_EXTSWIZZLE_X:
case TGSI_EXTSWIZZLE_Y:
case TGSI_EXTSWIZZLE_Z:
case TGSI_EXTSWIZZLE_W:
switch (reg->SrcRegister.File) {
case TGSI_FILE_INPUT:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->SrcRegister.Index * 4 + swizzle) * 16;
ppc_li(gen->f, offset_reg, offset);
ppc_lvx(gen->f, dst_vec, gen->inputs_reg, offset_reg);
ppc_release_register(gen->f, offset_reg);
}
break;
case TGSI_FILE_TEMPORARY:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->SrcRegister.Index * 4 + swizzle) * 16;
ppc_li(gen->f, offset_reg, offset);
ppc_lvx(gen->f, dst_vec, gen->temps_reg, offset_reg);
ppc_release_register(gen->f, offset_reg);
}
break;
case TGSI_FILE_IMMEDIATE:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->SrcRegister.Index * 4 + swizzle) * 16;
ppc_li(gen->f, offset_reg, offset);
ppc_lvx(gen->f, dst_vec, gen->immed_reg, offset_reg);
ppc_release_register(gen->f, offset_reg);
}
break;
case TGSI_FILE_CONSTANT:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->SrcRegister.Index * 4 + swizzle) * 4;
ppc_li(gen->f, offset_reg, offset);
/* Load 4-byte word into vector register.
* The vector slot depends on the effective address we load from.
* We know that our constants start at a 16-byte boundary so we
* know that 'swizzle' tells us which vector slot will have the
* loaded word. The other vector slots will be undefined.
*/
ppc_lvewx(gen->f, dst_vec, gen->const_reg, offset_reg);
/* splat word[swizzle] across the vector reg */
ppc_vspltw(gen->f, dst_vec, dst_vec, swizzle);
ppc_release_register(gen->f, offset_reg);
}
break;
default:
assert( 0 );
}
break;
case TGSI_EXTSWIZZLE_ZERO:
ppc_vzero(gen->f, dst_vec);
break;
case TGSI_EXTSWIZZLE_ONE:
{
int one_vec = gen_one_vec(gen);
ppc_vmove(gen->f, dst_vec, one_vec);
}
break;
default:
assert( 0 );
}
{
uint sign_op = tgsi_util_get_full_src_register_sign_mode(reg, chan_index);
if (sign_op != TGSI_UTIL_SIGN_KEEP) {
int bit31_vec = gen_get_bit31_vec(gen);
switch (sign_op) {
case TGSI_UTIL_SIGN_CLEAR:
/* vec = vec & ~bit31 */
ppc_vandc(gen->f, dst_vec, dst_vec, bit31_vec);
break;
case TGSI_UTIL_SIGN_SET:
/* vec = vec | bit31 */
ppc_vor(gen->f, dst_vec, dst_vec, bit31_vec);
break;
case TGSI_UTIL_SIGN_TOGGLE:
/* vec = vec ^ bit31 */
ppc_vxor(gen->f, dst_vec, dst_vec, bit31_vec);
break;
default:
assert(0);
}
}
}
}
#define FETCH( GEN, INST, DST_VEC, SRC_REG, CHAN ) \
emit_fetch( GEN, DST_VEC, &(INST).FullSrcRegisters[SRC_REG], CHAN )
/**
* Register store. Store 'src_vec' at location indicated by 'reg'.
*/
static void
emit_store(struct gen_context *gen,
unsigned src_vec,
const struct tgsi_full_dst_register *reg,
const struct tgsi_full_instruction *inst,
unsigned chan_index)
{
switch (reg->DstRegister.File) {
case TGSI_FILE_OUTPUT:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->DstRegister.Index * 4 + chan_index) * 16;
ppc_li(gen->f, offset_reg, offset);
ppc_stvx(gen->f, src_vec, gen->outputs_reg, offset_reg);
ppc_release_register(gen->f, offset_reg);
}
break;
case TGSI_FILE_TEMPORARY:
{
int offset_reg = ppc_allocate_register(gen->f);
int offset = (reg->DstRegister.Index * 4 + chan_index) * 16;
ppc_li(gen->f, offset_reg, offset);
ppc_stvx(gen->f, src_vec, gen->temps_reg, offset_reg);
ppc_release_register(gen->f, offset_reg);
}
break;
#if 0
case TGSI_FILE_ADDRESS:
emit_addrs(
func,
xmm,
reg->DstRegister.Index,
chan_index );
break;
#endif
default:
assert( 0 );
}
#if 0
switch( inst->Instruction.Saturate ) {
case TGSI_SAT_NONE:
break;
case TGSI_SAT_ZERO_ONE:
/* assert( 0 ); */
break;
case TGSI_SAT_MINUS_PLUS_ONE:
assert( 0 );
break;
}
#endif
}
#define STORE( GEN, INST, XMM, INDEX, CHAN )\
emit_store( GEN, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN )
static void
emit_scalar_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
int v1 = ppc_allocate_vec_register(gen->f);
uint chan_index;
FETCH(gen, *inst, v0, 0, CHAN_X);
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_RSQ:
/* v1 = 1.0 / sqrt(v0) */
ppc_vrsqrtefp(gen->f, v1, v0);
break;
case TGSI_OPCODE_RCP:
/* v1 = 1.0 / v0 */
ppc_vrefp(gen->f, v1, v0);
break;
default:
assert(0);
}
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
STORE(gen, *inst, v1, 0, chan_index);
}
ppc_release_vec_register(gen->f, v0);
ppc_release_vec_register(gen->f, v1);
}
static void
emit_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
uint chan_index;
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
FETCH(gen, *inst, 0, 0, chan_index); /* v0 = srcreg[0] */
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
/* turn off the most significant bit of each vector float word */
{
int v1 = ppc_allocate_vec_register(gen->f);
ppc_vspltisw(gen->f, v1, -1); /* v1 = {-1, -1, -1, -1} */
ppc_vslw(gen->f, v1, v1, v1); /* v1 = {1<<31, 1<<31, 1<<31, 1<<31} */
ppc_vandc(gen->f, v0, v0, v1); /* v0 = v0 & ~v1 */
ppc_release_vec_register(gen->f, v1);
}
break;
case TGSI_OPCODE_FLOOR:
ppc_vrfim(gen->f, v0, v0); /* v0 = floor(v0) */
break;
case TGSI_OPCODE_FRAC:
{
int v1 = ppc_allocate_vec_register(gen->f);
ppc_vrfim(gen->f, v1, v0); /* v1 = floor(v0) */
ppc_vsubfp(gen->f, v0, v0, v1); /* v0 = v0 - v1 */
ppc_release_vec_register(gen->f, v1);
}
break;
case TGSI_OPCODE_EXPBASE2:
ppc_vexptefp(gen->f, v0, v0); /* v0 = 2^v0 */
break;
case TGSI_OPCODE_LOGBASE2:
/* XXX this may be broken! */
ppc_vlogefp(gen->f, v0, v0); /* v0 = log2(v0) */
break;
case TGSI_OPCODE_MOV:
/* nothing */
break;
default:
assert(0);
}
STORE(gen, *inst, v0, 0, chan_index); /* store v0 */
}
ppc_release_vec_register(gen->f, v0);
}
static void
emit_binop(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
int v1 = ppc_allocate_vec_register(gen->f);
int v2 = ppc_allocate_vec_register(gen->f);
uint chan_index;
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
FETCH(gen, *inst, v0, 0, chan_index); /* v0 = srcreg[0] */
FETCH(gen, *inst, v1, 1, chan_index); /* v1 = srcreg[1] */
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ADD:
ppc_vaddfp(gen->f, v2, v0, v1);
break;
case TGSI_OPCODE_SUB:
ppc_vsubfp(gen->f, v2, v0, v1);
break;
case TGSI_OPCODE_MUL:
ppc_vxor(gen->f, v2, v2, v2); /* v2 = {0, 0, 0, 0} */
ppc_vmaddfp(gen->f, v2, v0, v1, v2); /* v2 = v0 * v1 + v0 */
break;
case TGSI_OPCODE_MIN:
ppc_vminfp(gen->f, v2, v0, v1);
break;
case TGSI_OPCODE_MAX:
ppc_vmaxfp(gen->f, v2, v0, v1);
break;
default:
assert(0);
}
STORE(gen, *inst, v2, 0, chan_index); /* store v2 */
}
ppc_release_vec_register(gen->f, v0);
ppc_release_vec_register(gen->f, v1);
ppc_release_vec_register(gen->f, v2);
}
/**
* Vector comparisons, resulting in 1.0 or 0.0 values.
*/
static void
emit_inequality(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
int v1 = ppc_allocate_vec_register(gen->f);
int v2 = ppc_allocate_vec_register(gen->f);
uint chan_index;
boolean complement = FALSE;
int one_vec = gen_one_vec(gen);
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
FETCH(gen, *inst, v0, 0, chan_index); /* v0 = srcreg[0] */
FETCH(gen, *inst, v1, 1, chan_index); /* v1 = srcreg[1] */
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_SNE:
complement = TRUE;
/* fall-through */
case TGSI_OPCODE_SEQ:
ppc_vcmpeqfpx(gen->f, v2, v0, v1); /* v2 = v0 == v1 ? ~0 : 0 */
break;
case TGSI_OPCODE_SGE:
complement = TRUE;
/* fall-through */
case TGSI_OPCODE_SLT:
ppc_vcmpgtfpx(gen->f, v2, v1, v0); /* v2 = v1 > v0 ? ~0 : 0 */
break;
case TGSI_OPCODE_SLE:
complement = TRUE;
/* fall-through */
case TGSI_OPCODE_SGT:
ppc_vcmpgtfpx(gen->f, v2, v0, v1); /* v2 = v0 > v1 ? ~0 : 0 */
break;
default:
assert(0);
}
/* v2 is now {0,0,0,0} or {~0,~0,~0,~0} */
if (complement)
ppc_vandc(gen->f, v2, one_vec, v2); /* v2 = one_vec & ~v2 */
else
ppc_vand(gen->f, v2, one_vec, v2); /* v2 = one_vec & v2 */
STORE(gen, *inst, v2, 0, chan_index); /* store v2 */
}
ppc_release_vec_register(gen->f, v0);
ppc_release_vec_register(gen->f, v1);
ppc_release_vec_register(gen->f, v2);
}
static void
emit_dotprod(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
int v1 = ppc_allocate_vec_register(gen->f);
int v2 = ppc_allocate_vec_register(gen->f);
uint chan_index;
ppc_vxor(gen->f, v2, v2, v2); /* v2 = {0, 0, 0, 0} */
FETCH(gen, *inst, v0, 0, CHAN_X); /* v0 = src0.XXXX */
FETCH(gen, *inst, v1, 1, CHAN_X); /* v1 = src1.XXXX */
ppc_vmaddfp(gen->f, v2, v0, v1, v2); /* v2 = v0 * v1 + v2 */
FETCH(gen, *inst, v0, 0, CHAN_Y); /* v0 = src0.YYYY */
FETCH(gen, *inst, v1, 1, CHAN_Y); /* v1 = src1.YYYY */
ppc_vmaddfp(gen->f, v2, v0, v1, v2); /* v2 = v0 * v1 + v2 */
FETCH(gen, *inst, v0, 0, CHAN_Z); /* v0 = src0.ZZZZ */
FETCH(gen, *inst, v1, 1, CHAN_Z); /* v1 = src1.ZZZZ */
ppc_vmaddfp(gen->f, v2, v0, v1, v2); /* v2 = v0 * v1 + v2 */
if (inst->Instruction.Opcode == TGSI_OPCODE_DP4) {
FETCH(gen, *inst, v0, 0, CHAN_W); /* v0 = src0.WWWW */
FETCH(gen, *inst, v1, 1, CHAN_W); /* v1 = src1.WWWW */
ppc_vmaddfp(gen->f, v2, v0, v1, v2); /* v2 = v0 * v1 + v2 */
}
else if (inst->Instruction.Opcode == TGSI_OPCODE_DPH) {
FETCH(gen, *inst, v1, 1, CHAN_W); /* v1 = src1.WWWW */
ppc_vaddfp(gen->f, v2, v2, v1); /* v2 = v2 + v1 */
}
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
STORE(gen, *inst, v2, 0, chan_index); /* store v2 */
}
ppc_release_vec_register(gen->f, v0);
ppc_release_vec_register(gen->f, v1);
ppc_release_vec_register(gen->f, v2);
}
static void
emit_triop(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int v0 = ppc_allocate_vec_register(gen->f);
int v1 = ppc_allocate_vec_register(gen->f);
int v2 = ppc_allocate_vec_register(gen->f);
int v3 = ppc_allocate_vec_register(gen->f);
uint chan_index;
FOR_EACH_DST0_ENABLED_CHANNEL(*inst, chan_index) {
FETCH(gen, *inst, v0, 0, chan_index); /* v0 = srcreg[0] */
FETCH(gen, *inst, v1, 1, chan_index); /* v1 = srcreg[1] */
FETCH(gen, *inst, v2, 2, chan_index); /* v2 = srcreg[2] */
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MAD:
ppc_vmaddfp(gen->f, v3, v0, v1, v2); /* v3 = v0 * v1 + v2 */
break;
case TGSI_OPCODE_LRP:
ppc_vsubfp(gen->f, v3, v1, v2); /* v3 = v1 - v2 */
ppc_vmaddfp(gen->f, v3, v0, v3, v2); /* v3 = v0 * v3 + v2 */
break;
default:
assert(0);
}
STORE(gen, *inst, v3, 0, chan_index); /* store v3 */
}
ppc_release_vec_register(gen->f, v0);
ppc_release_vec_register(gen->f, v1);
ppc_release_vec_register(gen->f, v2);
ppc_release_vec_register(gen->f, v3);
}
/** Approximation for vr = pow(va, vb) */
static void
ppc_vec_pow(struct ppc_function *f, int vr, int va, int vb)
{
/* pow(a,b) ~= exp2(log2(a) * b) */
int t_vec = ppc_allocate_vec_register(f);
int zero_vec = ppc_allocate_vec_register(f);
ppc_vzero(f, zero_vec);
ppc_vlogefp(f, t_vec, va); /* t = log2(va) */
ppc_vmaddfp(f, t_vec, t_vec, vb, zero_vec); /* t = t * vb */
ppc_vexptefp(f, vr, t_vec); /* vr = 2^t */
ppc_release_vec_register(f, t_vec);
ppc_release_vec_register(f, zero_vec);
}
static void
emit_lit(struct gen_context *gen, struct tgsi_full_instruction *inst)
{
int one_vec = gen_one_vec(gen);
/* Compute X */
if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_X)) {
STORE(gen, *inst, one_vec, 0, CHAN_X);
}
/* Compute Y, Z */
if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y) ||
IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
int x_vec = ppc_allocate_vec_register(gen->f);
int zero_vec = ppc_allocate_vec_register(gen->f);
FETCH(gen, *inst, x_vec, 0, CHAN_X); /* x_vec = src[0].x */
ppc_vzero(gen->f, zero_vec); /* zero = {0,0,0,0} */
ppc_vmaxfp(gen->f, x_vec, x_vec, zero_vec); /* x_vec = max(x_vec, 0) */
if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Y)) {
STORE(gen, *inst, x_vec, 0, CHAN_Y); /* store Y */
}
if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_Z)) {
int y_vec = ppc_allocate_vec_register(gen->f);
int z_vec = ppc_allocate_vec_register(gen->f);
int w_vec = ppc_allocate_vec_register(gen->f);
int pow_vec = ppc_allocate_vec_register(gen->f);
int pos_vec = ppc_allocate_vec_register(gen->f);
int p128_vec = ppc_allocate_vec_register(gen->f);
int n128_vec = ppc_allocate_vec_register(gen->f);
FETCH(gen, *inst, y_vec, 0, CHAN_Y); /* y_vec = src[0].y */
ppc_vmaxfp(gen->f, y_vec, y_vec, zero_vec); /* y_vec = max(y_vec, 0) */
FETCH(gen, *inst, w_vec, 0, CHAN_W); /* w_vec = src[0].w */
/* clamp Y to [-128, 128] */
load_constant_vec(gen, p128_vec, 128.0f);
load_constant_vec(gen, n128_vec, -128.0f);
ppc_vmaxfp(gen->f, y_vec, y_vec, n128_vec); /* y = max(y, -128) */
ppc_vminfp(gen->f, y_vec, y_vec, p128_vec); /* y = min(y, 128) */
/* if temp.x > 0
* z = pow(tmp.y, tmp.w)
* else
* z = 0.0
*/
ppc_vec_pow(gen->f, pow_vec, y_vec, w_vec); /* pow = pow(y, w) */
ppc_vcmpgtfpx(gen->f, pos_vec, x_vec, zero_vec); /* pos = x > 0 */
ppc_vand(gen->f, z_vec, pow_vec, pos_vec); /* z = pow & pos */
STORE(gen, *inst, z_vec, 0, CHAN_Z); /* store Z */
ppc_release_vec_register(gen->f, y_vec);
ppc_release_vec_register(gen->f, z_vec);
ppc_release_vec_register(gen->f, w_vec);
ppc_release_vec_register(gen->f, pow_vec);
ppc_release_vec_register(gen->f, pos_vec);
ppc_release_vec_register(gen->f, p128_vec);
ppc_release_vec_register(gen->f, n128_vec);
}
ppc_release_vec_register(gen->f, x_vec);
ppc_release_vec_register(gen->f, zero_vec);
}
/* Compute W */
if (IS_DST0_CHANNEL_ENABLED(*inst, CHAN_W)) {
STORE(gen, *inst, one_vec, 0, CHAN_W);
}
}
static int
emit_instruction(struct gen_context *gen,
struct tgsi_full_instruction *inst)
{
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_ABS:
case TGSI_OPCODE_FLOOR:
case TGSI_OPCODE_FRAC:
case TGSI_OPCODE_EXPBASE2:
case TGSI_OPCODE_LOGBASE2:
emit_unaryop(gen, inst);
break;
case TGSI_OPCODE_RSQ:
case TGSI_OPCODE_RCP:
emit_scalar_unaryop(gen, inst);
break;
case TGSI_OPCODE_ADD:
case TGSI_OPCODE_SUB:
case TGSI_OPCODE_MUL:
case TGSI_OPCODE_MIN:
case TGSI_OPCODE_MAX:
emit_binop(gen, inst);
break;
case TGSI_OPCODE_SEQ:
case TGSI_OPCODE_SNE:
case TGSI_OPCODE_SLT:
case TGSI_OPCODE_SGT:
case TGSI_OPCODE_SLE:
case TGSI_OPCODE_SGE:
emit_inequality(gen, inst);
break;
case TGSI_OPCODE_MAD:
case TGSI_OPCODE_LRP:
emit_triop(gen, inst);
break;
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
emit_dotprod(gen, inst);
break;
case TGSI_OPCODE_LIT:
emit_lit(gen, inst);
break;
case TGSI_OPCODE_END:
/* normal end */
return 1;
default:
return 0;
}
return 1;
}
static void
emit_declaration(
struct ppc_function *func,
struct tgsi_full_declaration *decl )
{
if( decl->Declaration.File == TGSI_FILE_INPUT ) {
#if 0
unsigned first, last, mask;
unsigned i, j;
first = decl->DeclarationRange.First;
last = decl->DeclarationRange.Last;
mask = decl->Declaration.UsageMask;
for( i = first; i <= last; i++ ) {
for( j = 0; j < NUM_CHANNELS; j++ ) {
if( mask & (1 << j) ) {
switch( decl->Declaration.Interpolate ) {
case TGSI_INTERPOLATE_CONSTANT:
emit_coef_a0( func, 0, i, j );
emit_inputs( func, 0, i, j );
break;
case TGSI_INTERPOLATE_LINEAR:
emit_tempf( func, 0, 0, TGSI_SWIZZLE_X );
emit_coef_dadx( func, 1, i, j );
emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y );
emit_coef_dady( func, 3, i, j );
emit_mul( func, 0, 1 ); /* x * dadx */
emit_coef_a0( func, 4, i, j );
emit_mul( func, 2, 3 ); /* y * dady */
emit_add( func, 0, 4 ); /* x * dadx + a0 */
emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */
emit_inputs( func, 0, i, j );
break;
case TGSI_INTERPOLATE_PERSPECTIVE:
emit_tempf( func, 0, 0, TGSI_SWIZZLE_X );
emit_coef_dadx( func, 1, i, j );
emit_tempf( func, 2, 0, TGSI_SWIZZLE_Y );
emit_coef_dady( func, 3, i, j );
emit_mul( func, 0, 1 ); /* x * dadx */
emit_tempf( func, 4, 0, TGSI_SWIZZLE_W );
emit_coef_a0( func, 5, i, j );
emit_rcp( func, 4, 4 ); /* 1.0 / w */
emit_mul( func, 2, 3 ); /* y * dady */
emit_add( func, 0, 5 ); /* x * dadx + a0 */
emit_add( func, 0, 2 ); /* x * dadx + y * dady + a0 */
emit_mul( func, 0, 4 ); /* (x * dadx + y * dady + a0) / w */
emit_inputs( func, 0, i, j );
break;
default:
assert( 0 );
break;
}
}
}
}
#endif
}
}
static void
emit_prologue(struct ppc_function *func)
{
/* XXX set up stack frame */
}
static void
emit_epilogue(struct ppc_function *func)
{
ppc_return(func);
/* XXX restore prev stack frame */
}
/**
* Translate a TGSI vertex/fragment shader to PPC code.
*
* \param tokens the TGSI input shader
* \param func the output PPC code/function
* \param immediates buffer to place immediates, later passed to PPC func
* \return TRUE for success, FALSE if translation failed
*/
boolean
tgsi_emit_ppc(const struct tgsi_token *tokens,
struct ppc_function *func,
float (*immediates)[4],
boolean do_swizzles )
{
static int use_ppc_asm = -1;
struct tgsi_parse_context parse;
/*boolean instruction_phase = FALSE;*/
unsigned ok = 1;
uint num_immediates = 0;
struct gen_context gen;
if (use_ppc_asm < 0) {
/* If GALLIUM_NOPPC is set, don't use PPC codegen */
use_ppc_asm = !debug_get_bool_option("GALLIUM_NOPPC", FALSE);
}
if (!use_ppc_asm)
return FALSE;
util_init_math();
gen.f = func;
gen.inputs_reg = ppc_reserve_register(func, 3); /* first function param */
gen.outputs_reg = ppc_reserve_register(func, 4); /* second function param */
gen.temps_reg = ppc_reserve_register(func, 5); /* ... */
gen.immed_reg = ppc_reserve_register(func, 6);
gen.const_reg = ppc_reserve_register(func, 7);
gen.builtins_reg = ppc_reserve_register(func, 8);
gen.one_vec = -1;
gen.bit31_vec = -1;
emit_prologue(func);
tgsi_parse_init( &parse, tokens );
while (!tgsi_parse_end_of_tokens(&parse) && ok) {
tgsi_parse_token(&parse);
switch (parse.FullToken.Token.Type) {
case TGSI_TOKEN_TYPE_DECLARATION:
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
emit_declaration(func, &parse.FullToken.FullDeclaration );
}
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
ok = emit_instruction(&gen, &parse.FullToken.FullInstruction);
if (!ok) {
debug_printf("failed to translate tgsi opcode %d to PPC (%s)\n",
parse.FullToken.FullInstruction.Instruction.Opcode,
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
/* splat each immediate component into a float[4] vector for SoA */
{
const uint size = parse.FullToken.FullImmediate.Immediate.Size - 1;
float *imm = (float *) immediates;
uint i;
assert(size <= 4);
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
for (i = 0; i < size; i++) {
const float value =
parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
imm[num_immediates * 4 + 0] =
imm[num_immediates * 4 + 1] =
imm[num_immediates * 4 + 2] =
imm[num_immediates * 4 + 3] = value;
num_immediates++;
}
}
break;
default:
ok = 0;
assert( 0 );
}
}
emit_epilogue(func);
tgsi_parse_free( &parse );
return ok;
}
#endif /* PIPE_ARCH_PPC */
@@ -25,36 +25,27 @@
*
**************************************************************************/
#ifndef TGSI_PPC_H
#define TGSI_PPC_H
#ifndef SPU_DEBUG_H
#define SPU_DEBUG_H
/* Set to 0 to disable all extraneous debugging code */
#define DEBUG 1
#if DEBUG
extern boolean Debug;
extern boolean force_fragment_ops_fallback;
/* These debug macros use the unusual construction ", ##__VA_ARGS__"
* which expands to the expected comma + args if variadic arguments
* are supplied, but swallows the comma if there are no variadic
* arguments (which avoids syntax errors that would otherwise occur).
*/
#define DEBUG_PRINTF(format,...) \
if (Debug) \
printf("SPU %u: " format, spu.init.id, ##__VA_ARGS__)
#define D_PRINTF(flag, format,...) \
if (spu.init.debug_flags & (flag)) \
printf("SPU %u: " format, spu.init.id, ##__VA_ARGS__)
#else
#define DEBUG_PRINTF(...)
#define D_PRINTF(...)
#if defined __cplusplus
extern "C" {
#endif
struct tgsi_token;
struct ppc_function;
#endif /* SPU_DEBUG_H */
extern const float ppc_builtin_constants[];
boolean
tgsi_emit_ppc(const struct tgsi_token *tokens,
struct ppc_function *function,
float (*immediates)[4],
boolean do_swizzles);
#if defined __cplusplus
}
#endif
#endif /* TGSI_PPC_H */
+51 -19
View File
@@ -64,10 +64,13 @@
#define ROUNDUP16(k) (((k) + 0xf) & ~0xf)
#define CELL_MAX_SPUS 6
#define CELL_MAX_SPUS 8
#define CELL_MAX_SAMPLERS 4
#define CELL_MAX_TEXTURE_LEVELS 12 /* 2k x 2k */
#define CELL_MAX_CONSTANTS 32 /**< number of float[4] constants */
#define CELL_MAX_WIDTH 1024 /**< max framebuffer width */
#define CELL_MAX_HEIGHT 1024 /**< max framebuffer width */
#define TILE_SIZE 32
@@ -96,34 +99,67 @@
#define CELL_CMD_STATE_FRAGMENT_PROGRAM 19
#define CELL_CMD_STATE_ATTRIB_FETCH 20
#define CELL_CMD_STATE_FS_CONSTANTS 21
#define CELL_CMD_VS_EXECUTE 22
#define CELL_CMD_FLUSH_BUFFER_RANGE 23
#define CELL_CMD_STATE_RASTERIZER 22
#define CELL_CMD_VS_EXECUTE 23
#define CELL_CMD_FLUSH_BUFFER_RANGE 24
#define CELL_CMD_FENCE 25
/** Command/batch buffers */
#define CELL_NUM_BUFFERS 4
#define CELL_BUFFER_SIZE (4*1024) /**< 16KB would be the max */
#define CELL_BUFFER_STATUS_FREE 10
#define CELL_BUFFER_STATUS_USED 20
/** Debug flags */
#define CELL_DEBUG_CHECKER (1 << 0)
#define CELL_DEBUG_ASM (1 << 1)
#define CELL_DEBUG_SYNC (1 << 2)
#define CELL_DEBUG_FRAGMENT_OPS (1 << 3)
#define CELL_DEBUG_FRAGMENT_OP_FALLBACK (1 << 4)
#define CELL_DEBUG_CMD (1 << 5)
#define CELL_DEBUG_CACHE (1 << 6)
/** Max instructions for doing per-fragment operations */
#define SPU_MAX_FRAGMENT_OPS_INSTS 64
#define CELL_FENCE_IDLE 0
#define CELL_FENCE_EMITTED 1
#define CELL_FENCE_SIGNALLED 2
struct cell_fence
{
/** There's a 16-byte status qword per SPU */
volatile uint status[CELL_MAX_SPUS][4];
};
/**
* Fence command sent to SPUs. In response, the SPUs will write
* CELL_FENCE_STATUS_SIGNALLED back to the fence status word in main memory.
*/
struct cell_command_fence
{
uint64_t opcode; /**< CELL_CMD_FENCE */
struct cell_fence *fence;
};
/**
* Command to specify per-fragment operations state and generated code.
* Note that the dsa, blend, blend_color fields are really only needed
* for the fallback/C per-pixel code. They're not used when we generate
* dynamic SPU fragment code (which is the normal case).
*/
struct cell_command_fragment_ops
{
uint64_t opcode; /**< CELL_CMD_STATE_FRAGMENT_OPS */
struct pipe_depth_stencil_alpha_state dsa;
struct pipe_blend_state blend;
struct pipe_blend_color blend_color;
unsigned code[SPU_MAX_FRAGMENT_OPS_INSTS];
};
@@ -147,13 +183,23 @@ struct cell_command_fragment_program
*/
struct cell_command_framebuffer
{
uint64_t opcode; /**< CELL_CMD_FRAMEBUFFER */
uint64_t opcode; /**< CELL_CMD_STATE_FRAMEBUFFER */
int width, height;
void *color_start, *depth_start;
enum pipe_format color_format, depth_format;
};
/**
* Tell SPUs about rasterizer state.
*/
struct cell_command_rasterizer
{
uint64_t opcode; /**< CELL_CMD_STATE_RASTERIZER */
struct pipe_rasterizer_state rasterizer;
};
/**
* Clear framebuffer to the given value/color.
*/
@@ -229,7 +275,6 @@ struct cell_command_render
float xmin, ymin, xmax, ymax; /* XXX another dummy field */
uint min_index;
boolean inline_verts;
uint front_winding; /* the rasterizer needs to be able to determine facing to apply front/back-facing stencil */
};
@@ -260,19 +305,6 @@ struct cell_command_texture
};
/** XXX unions don't seem to work */
/* XXX this should go away; all commands should be placed in batch buffers */
struct cell_command
{
#if 0
struct cell_command_framebuffer fb;
struct cell_command_clear_surface clear;
struct cell_command_render render;
#endif
struct cell_command_vs vs;
} ALIGN16_ATTRIB;
#define MAX_SPU_FUNCTIONS 12
/**
* Used to tell the PPU about the address of particular functions in the
@@ -293,7 +325,7 @@ struct cell_init_info
unsigned id;
unsigned num_spus;
unsigned debug_flags; /**< mask of CELL_DEBUG_x flags */
struct cell_command *cmd;
float inv_timebase; /**< 1.0/timebase, for perf measurement */
/** Buffers for command batches, vertex/index data */
ubyte *buffers[CELL_NUM_BUFFERS];
+1
View File
@@ -24,6 +24,7 @@ SOURCES = \
cell_clear.c \
cell_context.c \
cell_draw_arrays.c \
cell_fence.c \
cell_flush.c \
cell_gen_fragment.c \
cell_gen_fp.c \
+39 -4
View File
@@ -28,6 +28,7 @@
#include "cell_context.h"
#include "cell_batch.h"
#include "cell_fence.h"
#include "cell_spu.h"
@@ -42,7 +43,9 @@
uint
cell_get_empty_buffer(struct cell_context *cell)
{
uint buf = 0, tries = 0;
static uint prev_buffer = 0;
uint buf = (prev_buffer + 1) % CELL_NUM_BUFFERS;
uint tries = 0;
/* Find a buffer that's marked as free by all SPUs */
while (1) {
@@ -58,8 +61,13 @@ cell_get_empty_buffer(struct cell_context *cell)
cell->buffer_status[spu][buf][0] = CELL_BUFFER_STATUS_USED;
}
/*
printf("PPU: ALLOC BUFFER %u\n", buf);
printf("PPU: ALLOC BUFFER %u, %u tries\n", buf, tries);
*/
prev_buffer = buf;
/* release tex buffer associated w/ prev use of this batch buf */
cell_free_fenced_buffers(cell, &cell->fenced_buffers[buf]);
return buf;
}
}
@@ -81,6 +89,26 @@ cell_get_empty_buffer(struct cell_context *cell)
}
/**
* Append a fence command to the current batch buffer.
* Note that we're sure there's always room for this because of the
* adjusted size check in cell_batch_free_space().
*/
static void
emit_fence(struct cell_context *cell)
{
const uint batch = cell->cur_batch;
const uint size = cell->buffer_size[batch];
struct cell_command_fence *fence_cmd;
ASSERT(size + sizeof(struct cell_command_fence) <= CELL_BUFFER_SIZE);
fence_cmd = (struct cell_command_fence *) (cell->buffer[batch] + size);
fence_cmd->opcode = CELL_CMD_FENCE;
fence_cmd->fence = &cell->fenced_buffers[batch].fence;
}
/**
* Flush the current batch buffer to the SPUs.
* An empty buffer will be found and set as the new current batch buffer
@@ -99,6 +127,12 @@ cell_batch_flush(struct cell_context *cell)
if (size == 0)
return;
/* Before we use this batch buffer, make sure any fenced texture buffers
* are released.
*/
if (cell->fenced_buffers[batch].head)
emit_fence(cell);
flushing = TRUE;
assert(batch < CELL_NUM_BUFFERS);
@@ -139,6 +173,7 @@ uint
cell_batch_free_space(const struct cell_context *cell)
{
uint free = CELL_BUFFER_SIZE - cell->buffer_size[cell->cur_batch];
free -= sizeof(struct cell_command_fence);
return free;
}
@@ -169,7 +204,7 @@ cell_batch_append(struct cell_context *cell, const void *data, uint bytes)
size = cell->buffer_size[cell->cur_batch];
if (size + bytes > CELL_BUFFER_SIZE) {
if (bytes > cell_batch_free_space(cell)) {
cell_batch_flush(cell);
size = 0;
}
@@ -223,7 +258,7 @@ cell_batch_alloc_aligned(struct cell_context *cell, uint bytes,
padbytes = (alignment - (size % alignment)) % alignment;
if (padbytes + size + bytes > CELL_BUFFER_SIZE) {
if (padbytes + bytes > cell_batch_free_space(cell)) {
cell_batch_flush(cell);
size = 0;
}
+19 -4
View File
@@ -47,6 +47,7 @@
#include "cell_clear.h"
#include "cell_context.h"
#include "cell_draw_arrays.h"
#include "cell_fence.h"
#include "cell_flush.h"
#include "cell_state.h"
#include "cell_surface.h"
@@ -93,6 +94,8 @@ static const struct debug_named_value cell_debug_flags[] = {
{"sync", CELL_DEBUG_SYNC}, /**< SPUs do synchronous DMA */
{"fragops", CELL_DEBUG_FRAGMENT_OPS}, /**< SPUs emit fragment ops debug messages*/
{"fragopfallback", CELL_DEBUG_FRAGMENT_OP_FALLBACK}, /**< SPUs use reference implementation for fragment ops*/
{"cmd", CELL_DEBUG_CMD}, /**< SPUs dump command buffer info */
{"cache", CELL_DEBUG_CACHE}, /**< report texture cache stats on exit */
{NULL, 0}
};
@@ -102,6 +105,7 @@ cell_create_context(struct pipe_screen *screen,
struct cell_winsys *cws)
{
struct cell_context *cell;
uint i;
/* some fields need to be 16-byte aligned, so align the whole object */
cell = (struct cell_context*) align_malloc(sizeof(struct cell_context), 16);
@@ -149,13 +153,24 @@ cell_create_context(struct pipe_screen *screen,
cell_debug_flags,
0 );
for (i = 0; i < CELL_NUM_BUFFERS; i++)
cell_fence_init(&cell->fenced_buffers[i].fence);
/*
* SPU stuff
*/
cell->num_spus = 6;
/* XXX is this in SDK 3.0 only?
cell->num_spus = spe_cpu_info_get(SPE_COUNT_PHYSICAL_SPES, -1);
*/
/* This call only works with SDK 3.0. Anyone still using 2.1??? */
cell->num_cells = spe_cpu_info_get(SPE_COUNT_PHYSICAL_CPU_NODES, -1);
cell->num_spus = spe_cpu_info_get(SPE_COUNT_USABLE_SPES, 0);
if (cell->debug_flags) {
printf("Cell: found %d Cell(s) with %u SPUs\n",
cell->num_cells, cell->num_spus);
}
if (getenv("CELL_NUM_SPUS")) {
cell->num_spus = atoi(getenv("CELL_NUM_SPUS"));
assert(cell->num_spus > 0);
}
cell_start_spus(cell);
+25 -1
View File
@@ -74,12 +74,26 @@ struct cell_fragment_shader_state
struct cell_fragment_ops_key
{
struct pipe_blend_state blend;
struct pipe_blend_color blend_color;
struct pipe_depth_stencil_alpha_state dsa;
enum pipe_format color_format;
enum pipe_format zs_format;
};
struct cell_buffer_node;
/**
* Fenced buffer list. List of buffers which can be unreferenced after
* the fence has been executed/signalled.
*/
struct cell_buffer_list
{
struct cell_fence fence;
struct cell_buffer_node *head;
};
/**
* Per-context state, subclass of pipe_context.
*/
@@ -120,6 +134,8 @@ struct cell_context
uint *tex_map;
uint dirty;
uint dirty_textures; /* bitmask of texture units */
uint dirty_samplers; /* bitmask of sampler units */
/** Cache of code generated for per-fragment ops */
struct keymap *fragment_ops_cache;
@@ -139,7 +155,7 @@ struct cell_context
struct cell_spu_function_info spu_functions ALIGN16_ATTRIB;
uint num_spus;
uint num_cells, num_spus;
/** Buffers for command batches, vertex/index data */
uint buffer_size[CELL_NUM_BUFFERS];
@@ -151,6 +167,14 @@ struct cell_context
uint buffer_status[CELL_MAX_SPUS][CELL_NUM_BUFFERS][4] ALIGN16_ATTRIB;
/** Associated with each command/batch buffer is a list of pipe_buffers
* that are fenced. When the last command in a buffer is executed, the
* fence will be signalled, indicating that any pipe_buffers preceeding
* that fence can be unreferenced (and probably freed).
*/
struct cell_buffer_list fenced_buffers[CELL_NUM_BUFFERS];
struct spe_function attrib_fetch;
unsigned attrib_fetch_offsets[PIPE_MAX_ATTRIBS];
+158
View File
@@ -0,0 +1,158 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#include <unistd.h>
#include "util/u_memory.h"
#include "pipe/p_inlines.h"
#include "cell_context.h"
#include "cell_batch.h"
#include "cell_fence.h"
#include "cell_texture.h"
void
cell_fence_init(struct cell_fence *fence)
{
uint i;
for (i = 0; i < CELL_MAX_SPUS; i++) {
fence->status[i][0] = CELL_FENCE_IDLE;
}
}
boolean
cell_fence_signalled(const struct cell_context *cell,
const struct cell_fence *fence)
{
uint i;
for (i = 0; i < cell->num_spus; i++) {
//ASSERT(fence->status[i][0] != CELL_FENCE_IDLE);
if (fence->status[i][0] == CELL_FENCE_EMITTED)
return FALSE;
}
return TRUE;
}
void
cell_fence_finish(const struct cell_context *cell,
const struct cell_fence *fence)
{
while (!cell_fence_signalled(cell, fence)) {
usleep(10);
}
}
struct cell_buffer_node
{
struct pipe_buffer *buffer;
struct cell_buffer_node *next;
};
static void
cell_add_buffer_to_list(struct cell_context *cell,
struct cell_buffer_list *list,
struct pipe_buffer *buffer)
{
struct pipe_screen *ps = cell->pipe.screen;
struct cell_buffer_node *node = CALLOC_STRUCT(cell_buffer_node);
/* create new list node which references the buffer, insert at head */
if (node) {
pipe_buffer_reference(ps, &node->buffer, buffer);
node->next = list->head;
list->head = node;
}
}
/**
* Wait for completion of the given fence, then unreference any buffers
* on the list.
* This typically unrefs/frees texture buffers after any rendering which uses
* them has completed.
*/
void
cell_free_fenced_buffers(struct cell_context *cell,
struct cell_buffer_list *list)
{
if (list->head) {
struct pipe_screen *ps = cell->pipe.screen;
struct cell_buffer_node *node;
cell_fence_finish(cell, &list->fence);
/* traverse the list, unreferencing buffers, freeing nodes */
node = list->head;
while (node) {
struct cell_buffer_node *next = node->next;
assert(node->buffer);
pipe_buffer_unmap(ps, node->buffer);
#if 0
printf("Unref buffer %p\n", node->buffer);
if (node->buffer->refcount == 1)
printf(" Delete!\n");
#endif
pipe_buffer_reference(ps, &node->buffer, NULL);
FREE(node);
node = next;
}
list->head = NULL;
}
}
/**
* This should be called for each render command.
* Any texture buffers that are current bound will be added to a fenced
* list to be freed later when the fence is executed/signalled.
*/
void
cell_add_fenced_textures(struct cell_context *cell)
{
struct cell_buffer_list *list = &cell->fenced_buffers[cell->cur_batch];
uint i;
for (i = 0; i < cell->num_textures; i++) {
struct cell_texture *ct = cell->texture[i];
if (ct) {
uint level;
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
if (ct->tiled_buffer[level]) {
#if 0
printf("Adding texture %p buffer %p to list\n",
ct, ct->tiled_buffer[level]);
#endif
cell_add_buffer_to_list(cell, list, ct->tiled_buffer[level]);
}
}
}
}
}
+57
View File
@@ -0,0 +1,57 @@
/**************************************************************************
*
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
#ifndef CELL_FENCE_H
#define CELL_FENCE_H
extern void
cell_fence_init(struct cell_fence *fence);
extern boolean
cell_fence_signalled(const struct cell_context *cell,
const struct cell_fence *fence);
extern void
cell_fence_finish(const struct cell_context *cell,
const struct cell_fence *fence);
extern void
cell_free_fenced_buffers(struct cell_context *cell,
struct cell_buffer_list *list);
extern void
cell_add_fenced_textures(struct cell_context *cell);
#endif /* CELL_FENCE_H */
+120 -5
View File
@@ -84,6 +84,9 @@ struct codegen
/** Index of execution mask register */
int exec_mask_reg;
/** KIL mask: indicates which fragments have been killed */
int kill_mask_reg;
int frame_size; /**< Stack frame size, in words */
struct spe_function *f;
@@ -346,6 +349,22 @@ store_dest_reg(struct codegen *gen,
int value_reg, int channel,
const struct tgsi_full_dst_register *dest)
{
/*
* XXX need to implement dst reg clamping/saturation
*/
#if 0
switch (inst->Instruction.Saturate) {
case TGSI_SAT_NONE:
break;
case TGSI_SAT_ZERO_ONE:
break;
case TGSI_SAT_MINUS_PLUS_ONE:
break;
default:
assert( 0 );
}
#endif
switch (dest->DstRegister.File) {
case TGSI_FILE_TEMPORARY:
if (gen->if_nesting > 0) {
@@ -431,8 +450,21 @@ emit_prologue(struct codegen *gen)
static void
emit_epilogue(struct codegen *gen)
{
const int return_reg = 3;
spe_comment(gen->f, -4, "Function epilogue:");
spe_comment(gen->f, 0, "return the killed mask");
if (gen->kill_mask_reg > 0) {
/* shader called KIL, return the "alive" mask */
spe_move(gen->f, return_reg, gen->kill_mask_reg);
}
else {
/* return {0,0,0,0} */
spe_load_uint(gen->f, return_reg, 0);
}
spe_comment(gen->f, 0, "restore stack and return");
if (gen->frame_size >= 512) {
/* offset is too large for ai instruction */
int offset_reg = spe_allocate_available_register(gen->f);
@@ -1337,16 +1369,33 @@ emit_function_call(struct codegen *gen,
static boolean
emit_TXP(struct codegen *gen, const struct tgsi_full_instruction *inst)
emit_TEX(struct codegen *gen, const struct tgsi_full_instruction *inst)
{
const uint addr = lookup_function(gen->cell, "spu_txp");
const uint target = inst->InstructionExtTexture.Texture;
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
uint addr;
int ch;
int coord_regs[4], d_regs[4];
switch (target) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_2D:
addr = lookup_function(gen->cell, "spu_tex_2d");
break;
case TGSI_TEXTURE_3D:
addr = lookup_function(gen->cell, "spu_tex_3d");
break;
case TGSI_TEXTURE_CUBE:
addr = lookup_function(gen->cell, "spu_tex_cube");
break;
default:
ASSERT(0 && "unsupported texture target");
return FALSE;
}
assert(inst->FullSrcRegisters[1].SrcRegister.File == TGSI_FILE_SAMPLER);
spe_comment(gen->f, -4, "CALL txp:");
spe_comment(gen->f, -4, "CALL tex:");
/* get src/dst reg info */
for (ch = 0; ch < 4; ch++) {
@@ -1368,7 +1417,7 @@ emit_TXP(struct codegen *gen, const struct tgsi_full_instruction *inst)
spe_stqd(gen->f, reg, SPE_REG_SP, 16 * offset);
}
/* setup function arguments */
/* setup function arguments (XXX depends on target) */
for (i = 0; i < 4; i++) {
spe_move(gen->f, 3 + i, coord_regs[i]);
}
@@ -1406,6 +1455,68 @@ emit_TXP(struct codegen *gen, const struct tgsi_full_instruction *inst)
}
/**
* KILL if any of src reg values are less than zero.
*/
static boolean
emit_KIL(struct codegen *gen, const struct tgsi_full_instruction *inst)
{
int ch;
int s_regs[4], kil_reg = -1, cmp_reg, zero_reg;
spe_comment(gen->f, -4, "CALL kil:");
/* zero = {0,0,0,0} */
zero_reg = get_itemp(gen);
spe_load_uint(gen->f, zero_reg, 0);
cmp_reg = get_itemp(gen);
/* get src regs */
for (ch = 0; ch < 4; ch++) {
if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << ch)) {
s_regs[ch] = get_src_reg(gen, ch, &inst->FullSrcRegisters[0]);
}
}
/* test if any src regs are < 0 */
for (ch = 0; ch < 4; ch++) {
if (inst->FullDstRegisters[0].DstRegister.WriteMask & (1 << ch)) {
if (kil_reg >= 0) {
/* cmp = 0 > src ? : ~0 : 0 */
spe_fcgt(gen->f, cmp_reg, zero_reg, s_regs[ch]);
/* kil = kil | cmp */
spe_or(gen->f, kil_reg, kil_reg, cmp_reg);
}
else {
kil_reg = get_itemp(gen);
/* kil = 0 > src ? : ~0 : 0 */
spe_fcgt(gen->f, kil_reg, zero_reg, s_regs[ch]);
}
}
}
if (gen->if_nesting) {
/* may have been a conditional kil */
spe_and(gen->f, kil_reg, kil_reg, gen->exec_mask_reg);
}
/* allocate the kill mask reg if needed */
if (gen->kill_mask_reg <= 0) {
gen->kill_mask_reg = spe_allocate_available_register(gen->f);
spe_move(gen->f, gen->kill_mask_reg, kil_reg);
}
else {
spe_or(gen->f, gen->kill_mask_reg, gen->kill_mask_reg, kil_reg);
}
free_itemps(gen);
return TRUE;
}
/**
* Emit max. See emit_SGT for comments.
*/
@@ -1674,8 +1785,12 @@ emit_instruction(struct codegen *gen,
/* fall-through for now */
case TGSI_OPCODE_TXB:
/* fall-through for now */
case TGSI_OPCODE_TXL:
/* fall-through for now */
case TGSI_OPCODE_TXP:
return emit_TXP(gen, inst);
return emit_TEX(gen, inst);
case TGSI_OPCODE_KIL:
return emit_KIL(gen, inst);
case TGSI_OPCODE_IF:
return emit_IF(gen, inst);
+24 -17
View File
@@ -212,17 +212,24 @@ cell_bind_sampler_states(struct pipe_context *pipe,
unsigned num, void **samplers)
{
struct cell_context *cell = cell_context(pipe);
uint i, changed = 0x0;
assert(num <= CELL_MAX_SAMPLERS);
draw_flush(cell->draw);
memcpy(cell->sampler, samplers, num * sizeof(void *));
memset(&cell->sampler[num], 0, (CELL_MAX_SAMPLERS - num) *
sizeof(void *));
cell->num_samplers = num;
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
struct pipe_sampler_state *new_samp = i < num ? samplers[i] : NULL;
if (cell->sampler[i] != new_samp) {
cell->sampler[i] = new_samp;
changed |= (1 << i);
}
}
cell->dirty |= CELL_NEW_SAMPLER;
if (changed) {
cell->dirty |= CELL_NEW_SAMPLER;
cell->dirty_samplers |= changed;
}
}
@@ -240,25 +247,25 @@ cell_set_sampler_textures(struct pipe_context *pipe,
unsigned num, struct pipe_texture **texture)
{
struct cell_context *cell = cell_context(pipe);
uint i;
uint i, changed = 0x0;
assert(num <= CELL_MAX_SAMPLERS);
/* Check for no-op */
if (num == cell->num_textures &&
!memcmp(cell->texture, texture, num * sizeof(struct pipe_texture *)))
return;
draw_flush(cell->draw);
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
struct pipe_texture *tex = i < num ? texture[i] : NULL;
pipe_texture_reference((struct pipe_texture **) &cell->texture[i], tex);
struct pipe_texture *new_tex = i < num ? texture[i] : NULL;
if ((struct pipe_texture *) cell->texture[i] != new_tex) {
pipe_texture_reference((struct pipe_texture **) &cell->texture[i],
new_tex);
changed |= (1 << i);
}
}
cell->num_textures = num;
cell->dirty |= CELL_NEW_TEXTURE;
if (changed) {
cell->dirty |= CELL_NEW_TEXTURE;
cell->dirty_textures |= changed;
}
}
+33 -5
View File
@@ -52,6 +52,35 @@ helpful headers:
struct cell_global_info cell_global;
/**
* Scan /proc/cpuinfo to determine the timebase for the system.
* This is used by the SPUs to convert 'decrementer' ticks to seconds.
* There may be a better way to get this value...
*/
static unsigned
get_timebase(void)
{
FILE *f = fopen("/proc/cpuinfo", "r");
unsigned timebase;
assert(f);
while (!feof(f)) {
char line[80];
fgets(line, sizeof(line), f);
if (strncmp(line, "timebase", 8) == 0) {
char *colon = strchr(line, ':');
if (colon) {
timebase = atoi(colon + 2);
break;
}
}
}
fclose(f);
return timebase;
}
/**
* Write a 1-word message to the given SPE mailbox.
*/
@@ -115,6 +144,7 @@ cell_start_spus(struct cell_context *cell)
{
static boolean one_time_init = FALSE;
uint i, j;
uint timebase = get_timebase();
if (one_time_init) {
fprintf(stderr, "PPU: Multiple rendering contexts not yet supported "
@@ -124,10 +154,7 @@ cell_start_spus(struct cell_context *cell)
one_time_init = TRUE;
assert(cell->num_spus <= MAX_SPUS);
ASSERT_ALIGN16(&cell_global.command[0]);
ASSERT_ALIGN16(&cell_global.command[1]);
assert(cell->num_spus <= CELL_MAX_SPUS);
ASSERT_ALIGN16(&cell_global.inits[0]);
ASSERT_ALIGN16(&cell_global.inits[1]);
@@ -141,7 +168,8 @@ cell_start_spus(struct cell_context *cell)
cell_global.inits[i].id = i;
cell_global.inits[i].num_spus = cell->num_spus;
cell_global.inits[i].debug_flags = cell->debug_flags;
cell_global.inits[i].cmd = &cell_global.command[i];
cell_global.inits[i].inv_timebase = 1000.0f / timebase;
for (j = 0; j < CELL_NUM_BUFFERS; j++) {
cell_global.inits[i].buffers[j] = cell->buffer[j];
}
+5 -7
View File
@@ -31,13 +31,12 @@
#include <libspe2.h>
#include <libmisc.h>
#include <pthread.h>
#include "cell/common.h"
#include "cell_context.h"
#define MAX_SPUS 8
/**
* Global vars, for now anyway.
*/
@@ -46,14 +45,13 @@ struct cell_global_info
/**
* SPU/SPE handles, etc
*/
spe_context_ptr_t spe_contexts[MAX_SPUS];
pthread_t spe_threads[MAX_SPUS];
spe_context_ptr_t spe_contexts[CELL_MAX_SPUS];
pthread_t spe_threads[CELL_MAX_SPUS];
/**
* Data sent to SPUs
* Data sent to SPUs at start-up
*/
struct cell_init_info inits[MAX_SPUS];
struct cell_command command[MAX_SPUS];
struct cell_init_info inits[CELL_MAX_SPUS];
};
+41 -27
View File
@@ -52,6 +52,7 @@ lookup_fragment_ops(struct cell_context *cell)
*/
memset(&key, 0, sizeof(key));
key.blend = *cell->blend;
key.blend_color = cell->blend_color;
key.dsa = *cell->depth_stencil;
if (cell->framebuffer.cbufs[0])
@@ -146,6 +147,13 @@ cell_emit_state(struct cell_context *cell)
#endif
}
if (cell->dirty & (CELL_NEW_RASTERIZER)) {
struct cell_command_rasterizer *rast =
cell_batch_alloc(cell, sizeof(*rast));
rast->opcode = CELL_CMD_STATE_RASTERIZER;
rast->rasterizer = *cell->rasterizer;
}
if (cell->dirty & (CELL_NEW_FS)) {
/* Send new fragment program to SPUs */
struct cell_command_fragment_program *fp
@@ -193,44 +201,50 @@ cell_emit_state(struct cell_context *cell)
if (cell->dirty & CELL_NEW_SAMPLER) {
uint i;
for (i = 0; i < CELL_MAX_SAMPLERS; i++) {
if (cell->sampler[i]) {
struct cell_command_sampler *sampler
= cell_batch_alloc(cell, sizeof(*sampler));
sampler->opcode = CELL_CMD_STATE_SAMPLER;
sampler->unit = i;
sampler->state = *cell->sampler[i];
if (cell->dirty_samplers & (1 << i)) {
if (cell->sampler[i]) {
struct cell_command_sampler *sampler
= cell_batch_alloc(cell, sizeof(*sampler));
sampler->opcode = CELL_CMD_STATE_SAMPLER;
sampler->unit = i;
sampler->state = *cell->sampler[i];
}
}
}
cell->dirty_samplers = 0x0;
}
if (cell->dirty & CELL_NEW_TEXTURE) {
uint i;
for (i = 0;i < CELL_MAX_SAMPLERS; i++) {
struct cell_command_texture *texture
= cell_batch_alloc(cell, sizeof(*texture));
texture->opcode = CELL_CMD_STATE_TEXTURE;
texture->unit = i;
if (cell->texture[i]) {
uint level;
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
texture->start[level] = cell->texture[i]->tiled_data[level];
texture->width[level] = cell->texture[i]->base.width[level];
texture->height[level] = cell->texture[i]->base.height[level];
texture->depth[level] = cell->texture[i]->base.depth[level];
if (cell->dirty_textures & (1 << i)) {
struct cell_command_texture *texture
= cell_batch_alloc(cell, sizeof(*texture));
texture->opcode = CELL_CMD_STATE_TEXTURE;
texture->unit = i;
if (cell->texture[i]) {
uint level;
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
texture->start[level] = cell->texture[i]->tiled_mapped[level];
texture->width[level] = cell->texture[i]->base.width[level];
texture->height[level] = cell->texture[i]->base.height[level];
texture->depth[level] = cell->texture[i]->base.depth[level];
}
texture->target = cell->texture[i]->base.target;
}
texture->target = cell->texture[i]->base.target;
}
else {
uint level;
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
texture->start[level] = NULL;
texture->width[level] = 0;
texture->height[level] = 0;
texture->depth[level] = 0;
else {
uint level;
for (level = 0; level < CELL_MAX_TEXTURE_LEVELS; level++) {
texture->start[level] = NULL;
texture->width[level] = 0;
texture->height[level] = 0;
texture->depth[level] = 0;
}
texture->target = 0;
}
texture->target = 0;
}
}
cell->dirty_textures = 0x0;
}
if (cell->dirty & CELL_NEW_VERTEX_INFO) {
@@ -191,6 +191,8 @@ cell_set_constant_buffer(struct pipe_context *pipe,
assert(shader < PIPE_SHADER_TYPES);
assert(index == 0);
draw_flush(cell->draw);
/* note: reference counting */
winsys_buffer_reference(ws,
&cell->constants[shader].buffer,
+20 -7
View File
@@ -136,6 +136,9 @@ cell_texture_release(struct pipe_screen *screen,
__FUNCTION__, (void *) *pt, (*pt)->refcount - 1);
*/
if (--(*pt)->refcount <= 0) {
/* Delete this texture now.
* But note that the underlying pipe_buffer may linger...
*/
struct cell_texture *ct = cell_texture(*pt);
uint i;
@@ -146,8 +149,12 @@ cell_texture_release(struct pipe_screen *screen,
pipe_buffer_reference(screen, &ct->buffer, NULL);
for (i = 0; i < CELL_MAX_TEXTURE_LEVELS; i++) {
if (ct->tiled_data[i]) {
align_free(ct->tiled_data[i]);
/* Unreference the tiled image buffer.
* It may not actually be deleted until a fence is hit.
*/
if (ct->tiled_buffer[i]) {
ct->tiled_mapped[i] = NULL;
winsys_buffer_reference(screen->winsys, &ct->tiled_buffer[i], NULL);
}
}
@@ -228,12 +235,18 @@ cell_twiddle_texture(struct pipe_screen *screen,
int offset = bufWidth * bufHeight * 4 * surface->face;
uint *dst;
if (!ct->tiled_data[level]) {
ct->tiled_data[level] =
align_malloc(bufWidth * bufHeight * 4 * numFaces, 16);
if (!ct->tiled_buffer[level]) {
/* allocate buffer for tiled data now */
struct pipe_winsys *ws = screen->winsys;
uint bytes = bufWidth * bufHeight * 4 * numFaces;
ct->tiled_buffer[level] = ws->buffer_create(ws, 16,
PIPE_BUFFER_USAGE_PIXEL,
bytes);
/* and map it */
ct->tiled_mapped[level] = ws->buffer_map(ws, ct->tiled_buffer[level],
PIPE_BUFFER_USAGE_GPU_READ);
}
dst = (uint *) ((ubyte *) ct->tiled_data[level] + offset);
dst = (uint *) ((ubyte *) ct->tiled_mapped[level] + offset);
twiddle_image_uint(texWidth, texHeight, TILE_SIZE, dst,
surface->stride, src);
+4 -1
View File
@@ -48,7 +48,10 @@ struct cell_texture
struct pipe_buffer *buffer;
unsigned long buffer_size;
void *tiled_data[CELL_MAX_TEXTURE_LEVELS]; /* XXX this may be temporary */ /*ALIGN16*/
/** Texture data in tiled layout is held here */
struct pipe_buffer *tiled_buffer[CELL_MAX_TEXTURE_LEVELS];
/** Mapped, tiled texture data */
void *tiled_mapped[CELL_MAX_TEXTURE_LEVELS];
};
+6 -1
View File
@@ -38,6 +38,7 @@
#include "cell_batch.h"
#include "cell_context.h"
#include "cell_fence.h"
#include "cell_flush.h"
#include "cell_spu.h"
#include "cell_vbuf.h"
@@ -108,6 +109,11 @@ cell_vbuf_release_vertices(struct vbuf_render *vbr, void *vertices,
__FUNCTION__, cvbr->vertex_buf, vertices_used);
*/
/* Make sure texture buffers aren't released until we're done rendering
* with them.
*/
cell_add_fenced_textures(cell);
/* Tell SPUs they can release the vert buf */
if (cvbr->vertex_buf != ~0U) {
struct cell_command_release_verts *release
@@ -214,7 +220,6 @@ cell_vbuf_draw(struct vbuf_render *vbr,
render->opcode = CELL_CMD_RENDER;
render->prim_type = cvbr->prim;
render->front_winding = cell->rasterizer->front_winding;
render->num_indexes = nr_indices;
render->min_index = min_index;
+90 -62
View File
@@ -44,7 +44,6 @@
#include "spu_tile.h"
#include "spu_vertex_shader.h"
#include "spu_dcache.h"
#include "spu_debug.h"
#include "cell/common.h"
@@ -77,9 +76,10 @@ static void
release_buffer(uint buffer)
{
/* Evidently, using less than a 16-byte status doesn't work reliably */
static const uint status[4] ALIGN16_ATTRIB
= {CELL_BUFFER_STATUS_FREE, 0, 0, 0};
static const vector unsigned int status = {CELL_BUFFER_STATUS_FREE,
CELL_BUFFER_STATUS_FREE,
CELL_BUFFER_STATUS_FREE,
CELL_BUFFER_STATUS_FREE};
const uint index = 4 * (spu.init.id * CELL_NUM_BUFFERS + buffer);
uint *dst = spu.init.buffer_status + index;
@@ -94,10 +94,33 @@ release_buffer(uint buffer)
}
/**
* Write CELL_FENCE_SIGNALLED back to the fence status qword in main memory.
* There's a qword of status per SPU.
*/
static void
cmd_fence(struct cell_command_fence *fence_cmd)
{
static const vector unsigned int status = {CELL_FENCE_SIGNALLED,
CELL_FENCE_SIGNALLED,
CELL_FENCE_SIGNALLED,
CELL_FENCE_SIGNALLED};
uint *dst = (uint *) fence_cmd->fence;
dst += 4 * spu.init.id; /* main store/memory address, not local store */
mfc_put((void *) &status, /* src in local memory */
(unsigned int) dst, /* dst in main memory */
sizeof(status), /* size */
TAG_FENCE, /* tag */
0, /* tid */
0 /* rid */);
}
static void
cmd_clear_surface(const struct cell_command_clear_surface *clear)
{
DEBUG_PRINTF("CLEAR SURF %u to 0x%08x\n", clear->surface, clear->value);
D_PRINTF(CELL_DEBUG_CMD, "CLEAR SURF %u to 0x%08x\n", clear->surface, clear->value);
if (clear->surface == 0) {
spu.fb.color_clear_value = clear->value;
@@ -165,14 +188,14 @@ cmd_clear_surface(const struct cell_command_clear_surface *clear)
#endif /* CLEAR_OPT */
DEBUG_PRINTF("CLEAR SURF done\n");
D_PRINTF(CELL_DEBUG_CMD, "CLEAR SURF done\n");
}
static void
cmd_release_verts(const struct cell_command_release_verts *release)
{
DEBUG_PRINTF("RELEASE VERTS %u\n", release->vertex_buf);
D_PRINTF(CELL_DEBUG_CMD, "RELEASE VERTS %u\n", release->vertex_buf);
ASSERT(release->vertex_buf != ~0U);
release_buffer(release->vertex_buf);
}
@@ -189,12 +212,13 @@ cmd_state_fragment_ops(const struct cell_command_fragment_ops *fops)
{
static int warned = 0;
DEBUG_PRINTF("CMD_STATE_FRAGMENT_OPS\n");
D_PRINTF(CELL_DEBUG_CMD, "CMD_STATE_FRAGMENT_OPS\n");
/* Copy SPU code from batch buffer to spu buffer */
memcpy(spu.fragment_ops_code, fops->code, SPU_MAX_FRAGMENT_OPS_INSTS * 4);
/* Copy state info (for fallback case only) */
memcpy(&spu.depth_stencil_alpha, &fops->dsa, sizeof(fops->dsa));
memcpy(&spu.blend, &fops->blend, sizeof(fops->blend));
memcpy(&spu.blend_color, &fops->blend_color, sizeof(fops->blend_color));
/* Parity twist! For now, always use the fallback code by default,
* only switching to codegen when specifically requested. This
@@ -228,7 +252,7 @@ cmd_state_fragment_ops(const struct cell_command_fragment_ops *fops)
static void
cmd_state_fragment_program(const struct cell_command_fragment_program *fp)
{
DEBUG_PRINTF("CMD_STATE_FRAGMENT_PROGRAM\n");
D_PRINTF(CELL_DEBUG_CMD, "CMD_STATE_FRAGMENT_PROGRAM\n");
/* Copy SPU code from batch buffer to spu buffer */
memcpy(spu.fragment_program_code, fp->code,
SPU_MAX_FRAGMENT_PROGRAM_INSTS * 4);
@@ -246,10 +270,11 @@ cmd_state_fs_constants(const uint64_t *buffer, uint pos)
const float *constants = (const float *) &buffer[pos + 2];
uint i;
DEBUG_PRINTF("CMD_STATE_FS_CONSTANTS (%u)\n", num_const);
D_PRINTF(CELL_DEBUG_CMD, "CMD_STATE_FS_CONSTANTS (%u)\n", num_const);
/* Expand each float to float[4] for SOA execution */
for (i = 0; i < num_const; i++) {
D_PRINTF(CELL_DEBUG_CMD, " const[%u] = %f\n", i, constants[i]);
spu.constants[i] = spu_splats(constants[i]);
}
@@ -261,7 +286,7 @@ cmd_state_fs_constants(const uint64_t *buffer, uint pos)
static void
cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
{
DEBUG_PRINTF("FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
D_PRINTF(CELL_DEBUG_CMD, "FRAMEBUFFER: %d x %d at %p, cformat 0x%x zformat 0x%x\n",
cmd->width,
cmd->height,
cmd->color_start,
@@ -309,8 +334,7 @@ cmd_state_framebuffer(const struct cell_command_framebuffer *cmd)
*/
static void
update_tex_masks(struct spu_texture *texture,
const struct pipe_sampler_state *sampler,
uint unit)
const struct pipe_sampler_state *sampler)
{
uint i;
@@ -337,11 +361,6 @@ update_tex_masks(struct spu_texture *texture,
texture->level[i].scale_t = spu_splats(1.0f);
}
}
/* XXX temporary hack */
if (texture->target == PIPE_TEXTURE_CUBE) {
spu.sample_texture4[unit] = sample_texture4_cube;
}
}
@@ -350,18 +369,18 @@ cmd_state_sampler(const struct cell_command_sampler *sampler)
{
uint unit = sampler->unit;
DEBUG_PRINTF("SAMPLER [%u]\n", unit);
D_PRINTF(CELL_DEBUG_CMD, "SAMPLER [%u]\n", unit);
spu.sampler[unit] = sampler->state;
switch (spu.sampler[unit].min_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
spu.min_sample_texture4[unit] = sample_texture4_bilinear;
spu.min_sample_texture_2d[unit] = sample_texture_2d_bilinear;
break;
case PIPE_TEX_FILTER_ANISO:
/* fall-through, for now */
case PIPE_TEX_FILTER_NEAREST:
spu.min_sample_texture4[unit] = sample_texture4_nearest;
spu.min_sample_texture_2d[unit] = sample_texture_2d_nearest;
break;
default:
ASSERT(0);
@@ -369,12 +388,12 @@ cmd_state_sampler(const struct cell_command_sampler *sampler)
switch (spu.sampler[sampler->unit].mag_img_filter) {
case PIPE_TEX_FILTER_LINEAR:
spu.mag_sample_texture4[unit] = sample_texture4_bilinear;
spu.mag_sample_texture_2d[unit] = sample_texture_2d_bilinear;
break;
case PIPE_TEX_FILTER_ANISO:
/* fall-through, for now */
case PIPE_TEX_FILTER_NEAREST:
spu.mag_sample_texture4[unit] = sample_texture4_nearest;
spu.mag_sample_texture_2d[unit] = sample_texture_2d_nearest;
break;
default:
ASSERT(0);
@@ -383,16 +402,16 @@ cmd_state_sampler(const struct cell_command_sampler *sampler)
switch (spu.sampler[sampler->unit].min_mip_filter) {
case PIPE_TEX_MIPFILTER_NEAREST:
case PIPE_TEX_MIPFILTER_LINEAR:
spu.sample_texture4[unit] = sample_texture4_lod;
spu.sample_texture_2d[unit] = sample_texture_2d_lod;
break;
case PIPE_TEX_MIPFILTER_NONE:
spu.sample_texture4[unit] = spu.mag_sample_texture4[unit];
spu.sample_texture_2d[unit] = spu.mag_sample_texture_2d[unit];
break;
default:
ASSERT(0);
}
update_tex_masks(&spu.texture[unit], &spu.sampler[unit], unit);
update_tex_masks(&spu.texture[unit], &spu.sampler[unit]);
}
@@ -402,9 +421,7 @@ cmd_state_texture(const struct cell_command_texture *texture)
const uint unit = texture->unit;
uint i;
//if (spu.init.id==0) Debug=1;
DEBUG_PRINTF("TEXTURE [%u]\n", texture->unit);
D_PRINTF(CELL_DEBUG_CMD, "TEXTURE [%u]\n", texture->unit);
spu.texture[unit].max_level = 0;
spu.texture[unit].target = texture->target;
@@ -414,7 +431,7 @@ cmd_state_texture(const struct cell_command_texture *texture)
uint height = texture->height[i];
uint depth = texture->depth[i];
DEBUG_PRINTF(" LEVEL %u: at %p size[0] %u x %u\n", i,
D_PRINTF(CELL_DEBUG_CMD, " LEVEL %u: at %p size[0] %u x %u\n", i,
texture->start[i], texture->width[i], texture->height[i]);
spu.texture[unit].level[i].start = texture->start[i];
@@ -435,16 +452,14 @@ cmd_state_texture(const struct cell_command_texture *texture)
spu.texture[unit].max_level = i;
}
update_tex_masks(&spu.texture[unit], &spu.sampler[unit], unit);
//Debug=0;
update_tex_masks(&spu.texture[unit], &spu.sampler[unit]);
}
static void
cmd_state_vertex_info(const struct vertex_info *vinfo)
{
DEBUG_PRINTF("VERTEX_INFO num_attribs=%u\n", vinfo->num_attribs);
D_PRINTF(CELL_DEBUG_CMD, "VERTEX_INFO num_attribs=%u\n", vinfo->num_attribs);
ASSERT(vinfo->num_attribs >= 1);
ASSERT(vinfo->num_attribs <= 8);
memcpy(&spu.vertex_info, vinfo, sizeof(*vinfo));
@@ -483,7 +498,7 @@ cmd_state_attrib_fetch(const struct cell_attribute_fetch_code *code)
static void
cmd_finish(void)
{
DEBUG_PRINTF("FINISH\n");
D_PRINTF(CELL_DEBUG_CMD, "FINISH\n");
really_clear_tiles(0);
/* wait for all outstanding DMAs to finish */
mfc_write_tag_mask(~0);
@@ -508,7 +523,7 @@ cmd_batch(uint opcode)
const unsigned usize = size / sizeof(buffer[0]);
uint pos;
DEBUG_PRINTF("BATCH buffer %u, len %u, from %p\n",
D_PRINTF(CELL_DEBUG_CMD, "BATCH buffer %u, len %u, from %p\n",
buf, size, spu.init.buffers[buf]);
ASSERT((opcode & CELL_CMD_OPCODE_MASK) == CELL_CMD_BATCH);
@@ -528,7 +543,7 @@ cmd_batch(uint opcode)
wait_on_mask(1 << TAG_BATCH_BUFFER);
/* Tell PPU we're done copying the buffer to local store */
DEBUG_PRINTF("release batch buf %u\n", buf);
D_PRINTF(CELL_DEBUG_CMD, "release batch buf %u\n", buf);
release_buffer(buf);
/*
@@ -586,6 +601,14 @@ cmd_batch(uint opcode)
case CELL_CMD_STATE_FS_CONSTANTS:
pos = cmd_state_fs_constants(buffer, pos);
break;
case CELL_CMD_STATE_RASTERIZER:
{
struct cell_command_rasterizer *rast =
(struct cell_command_rasterizer *) &buffer[pos];
spu.rasterizer = rast->rasterizer;
pos += sizeof(*rast) / 8;
}
break;
case CELL_CMD_STATE_SAMPLER:
{
struct cell_command_sampler *sampler
@@ -638,6 +661,14 @@ cmd_batch(uint opcode)
cmd_finish();
pos += 1;
break;
case CELL_CMD_FENCE:
{
struct cell_command_fence *fence_cmd =
(struct cell_command_fence *) &buffer[pos];
cmd_fence(fence_cmd);
pos += sizeof(*fence_cmd) / 8;
}
break;
case CELL_CMD_RELEASE_VERTS:
{
struct cell_command_release_verts *release
@@ -661,10 +692,12 @@ cmd_batch(uint opcode)
}
}
DEBUG_PRINTF("BATCH complete\n");
D_PRINTF(CELL_DEBUG_CMD, "BATCH complete\n");
}
#define PERF 0
/**
* Main loop for SPEs: Get a command, execute it, repeat.
@@ -672,41 +705,29 @@ cmd_batch(uint opcode)
void
command_loop(void)
{
struct cell_command cmd;
int exitFlag = 0;
uint t0, t1;
DEBUG_PRINTF("Enter command loop\n");
ASSERT((sizeof(struct cell_command) & 0xf) == 0);
ASSERT_ALIGN16(&cmd);
D_PRINTF(CELL_DEBUG_CMD, "Enter command loop\n");
while (!exitFlag) {
unsigned opcode;
int tag = 0;
DEBUG_PRINTF("Wait for cmd...\n");
D_PRINTF(CELL_DEBUG_CMD, "Wait for cmd...\n");
if (PERF)
spu_write_decrementer(~0);
/* read/wait from mailbox */
opcode = (unsigned int) spu_read_in_mbox();
D_PRINTF(CELL_DEBUG_CMD, "got cmd 0x%x\n", opcode);
DEBUG_PRINTF("got cmd 0x%x\n", opcode);
/* command payload */
mfc_get(&cmd, /* dest */
(unsigned int) spu.init.cmd, /* src */
sizeof(struct cell_command), /* bytes */
tag,
0, /* tid */
0 /* rid */);
wait_on_mask( 1 << tag );
/*
* NOTE: most commands should be contained in a batch buffer
*/
if (PERF)
t0 = spu_read_decrementer();
switch (opcode & CELL_CMD_OPCODE_MASK) {
case CELL_CMD_EXIT:
DEBUG_PRINTF("EXIT\n");
D_PRINTF(CELL_DEBUG_CMD, "EXIT\n");
exitFlag = 1;
break;
case CELL_CMD_VS_EXECUTE:
@@ -721,9 +742,16 @@ command_loop(void)
printf("Bad opcode 0x%x!\n", opcode & CELL_CMD_OPCODE_MASK);
}
if (PERF) {
t1 = spu_read_decrementer();
printf("wait mbox time: %gms batch time: %gms\n",
(~0u - t0) * spu.init.inv_timebase,
(t0 - t1) * spu.init.inv_timebase);
}
}
DEBUG_PRINTF("Exit command loop\n");
D_PRINTF(CELL_DEBUG_CMD, "Exit command loop\n");
spu_dcache_report();
if (spu.init.debug_flags & CELL_DEBUG_CACHE)
spu_dcache_report();
}
+3 -1
View File
@@ -36,7 +36,9 @@
#define CACHE_SET_TAGID(set) (((set) & 0x03) + TAG_DCACHE0)
#define CACHE_LOG2NNWAY 2
#define CACHE_LOG2NSETS 6
/*#define CACHE_STATS 1*/
#ifdef DEBUG
#define CACHE_STATS 1
#endif
#include <cache-api.h>
/* Yes folks, this is ugly.
+30 -4
View File
@@ -43,6 +43,7 @@
#include "cell/common.h"
#include "spu_main.h"
#include "spu_funcs.h"
#include "spu_texture.h"
/** For "return"-ing four vectors */
@@ -102,11 +103,34 @@ spu_log2(vector float x)
static struct vec_4x4
spu_txp(vector float s, vector float t, vector float r, vector float q,
unsigned unit)
spu_tex_2d(vector float s, vector float t, vector float r, vector float q,
unsigned unit)
{
struct vec_4x4 colors;
spu.sample_texture4[unit](s, t, r, q, unit, 0, 0, colors.v);
(void) r;
(void) q;
spu.sample_texture_2d[unit](s, t, unit, 0, 0, colors.v);
return colors;
}
static struct vec_4x4
spu_tex_3d(vector float s, vector float t, vector float r, vector float q,
unsigned unit)
{
struct vec_4x4 colors;
(void) r;
(void) q;
spu.sample_texture_2d[unit](s, t, unit, 0, 0, colors.v);
return colors;
}
static struct vec_4x4
spu_tex_cube(vector float s, vector float t, vector float r, vector float q,
unsigned unit)
{
struct vec_4x4 colors;
(void) q;
sample_texture_cube(s, t, r, unit, colors.v);
return colors;
}
@@ -147,7 +171,9 @@ return_function_info(void)
export_func(&funcs, "spu_pow", &spu_pow);
export_func(&funcs, "spu_exp2", &spu_exp2);
export_func(&funcs, "spu_log2", &spu_log2);
export_func(&funcs, "spu_txp", &spu_txp);
export_func(&funcs, "spu_tex_2d", &spu_tex_2d);
export_func(&funcs, "spu_tex_3d", &spu_tex_3d);
export_func(&funcs, "spu_tex_cube", &spu_tex_cube);
/* Send the function info back to the PPU / main memory */
mfc_put((void *) &funcs, /* src in local store */
+1 -8
View File
@@ -40,7 +40,6 @@
#include "spu_per_fragment_op.h"
#include "spu_texture.h"
//#include "spu_test.h"
#include "spu_debug.h"
#include "cell/common.h"
@@ -53,12 +52,6 @@ helpful headers:
struct spu_global spu;
#if DEBUG
boolean Debug = FALSE;
boolean force_fragment_ops_fallback = TRUE;
#endif
static void
one_time_init(void)
{
@@ -102,7 +95,7 @@ main(main_param_t speid, main_param_t argp)
one_time_init();
DEBUG_PRINTF("main() speid=%lu\n", (unsigned long) speid);
D_PRINTF(CELL_DEBUG_CMD, "main() speid=%lu\n", (unsigned long) speid);
D_PRINTF(CELL_DEBUG_FRAGMENT_OP_FALLBACK, "using fragment op fallback\n");
/* get initialization data */
+27 -23
View File
@@ -36,12 +36,18 @@
#include "pipe/p_state.h"
#define MAX_WIDTH 1024
#define MAX_HEIGHT 1024
#define CELL_MAX_CONSTANTS 32 /**< number of float[4] constants */
#if DEBUG
/* These debug macros use the unusual construction ", ##__VA_ARGS__"
* which expands to the expected comma + args if variadic arguments
* are supplied, but swallows the comma if there are no variadic
* arguments (which avoids syntax errors that would otherwise occur).
*/
#define D_PRINTF(flag, format,...) \
if (spu.init.debug_flags & (flag)) \
printf("SPU %u: " format, spu.init.id, ##__VA_ARGS__)
#else
#define D_PRINTF(...)
#endif
/**
@@ -64,12 +70,10 @@ typedef union {
/** Function for sampling textures */
typedef void (*spu_sample_texture4_func)(vector float s,
vector float t,
vector float r,
vector float q,
uint unit, uint level, uint face,
vector float colors[4]);
typedef void (*spu_sample_texture_2d_func)(vector float s,
vector float t,
uint unit, uint level, uint face,
vector float colors[4]);
/** Function for performing per-fragment ops */
@@ -85,9 +89,9 @@ typedef void (*spu_fragment_ops_func)(uint x, uint y,
uint facing);
/** Function for running fragment program */
typedef void (*spu_fragment_program_func)(vector float *inputs,
vector float *outputs,
vector float *constants);
typedef vector unsigned int (*spu_fragment_program_func)(vector float *inputs,
vector float *outputs,
vector float *constants);
struct spu_framebuffer
@@ -145,7 +149,9 @@ struct spu_global
struct spu_framebuffer fb;
struct pipe_depth_stencil_alpha_state depth_stencil_alpha;
struct pipe_blend_state blend;
struct pipe_blend_color blend_color;
struct pipe_sampler_state sampler[PIPE_MAX_SAMPLERS];
struct pipe_rasterizer_state rasterizer;
struct spu_texture texture[PIPE_MAX_SAMPLERS];
struct vertex_info vertex_info;
@@ -161,8 +167,8 @@ struct spu_global
ubyte cur_ctile_status, cur_ztile_status;
/** Status of all tiles in framebuffer */
ubyte ctile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB;
ubyte ztile_status[MAX_HEIGHT/TILE_SIZE][MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB;
ubyte ctile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB;
ubyte ztile_status[CELL_MAX_HEIGHT/TILE_SIZE][CELL_MAX_WIDTH/TILE_SIZE] ALIGN16_ATTRIB;
/** Current fragment ops machine code, at 8-byte boundary */
uint fragment_ops_code[SPU_MAX_FRAGMENT_OPS_INSTS] ALIGN8_ATTRIB;
@@ -175,9 +181,9 @@ struct spu_global
spu_fragment_program_func fragment_program;
/** Current texture sampler function */
spu_sample_texture4_func sample_texture4[CELL_MAX_SAMPLERS];
spu_sample_texture4_func min_sample_texture4[CELL_MAX_SAMPLERS];
spu_sample_texture4_func mag_sample_texture4[CELL_MAX_SAMPLERS];
spu_sample_texture_2d_func sample_texture_2d[CELL_MAX_SAMPLERS];
spu_sample_texture_2d_func min_sample_texture_2d[CELL_MAX_SAMPLERS];
spu_sample_texture_2d_func mag_sample_texture_2d[CELL_MAX_SAMPLERS];
/** Fragment program constants */
vector float constants[4 * CELL_MAX_CONSTANTS];
@@ -186,8 +192,6 @@ struct spu_global
extern struct spu_global spu;
extern boolean Debug;
@@ -206,7 +210,7 @@ extern boolean Debug;
#define TAG_DCACHE1 21
#define TAG_DCACHE2 22
#define TAG_DCACHE3 23
#define TAG_FENCE 24
static INLINE void
@@ -40,6 +40,24 @@
#define LINEAR_QUAD_LAYOUT 1
static INLINE vector float
spu_min(vector float a, vector float b)
{
vector unsigned int m;
m = spu_cmpgt(a, b); /* m = a > b ? ~0 : 0 */
return spu_sel(a, b, m);
}
static INLINE vector float
spu_max(vector float a, vector float b)
{
vector unsigned int m;
m = spu_cmpgt(a, b); /* m = a > b ? ~0 : 0 */
return spu_sel(b, a, m);
}
/**
* Called by rasterizer for each quad after the shader has run. Do
* all the per-fragment operations including alpha test, z test,
@@ -242,7 +260,7 @@ spu_fallback_fragment_ops(uint x, uint y,
}
/*
* Compute Src RGB terms
* Compute Src RGB terms (fragment color * factor)
*/
switch (spu.blend.rgb_src_factor) {
case PIPE_BLENDFACTOR_ONE:
@@ -265,13 +283,33 @@ spu_fallback_fragment_ops(uint x, uint y,
term1g = spu_mul(fragG, fragA);
term1b = spu_mul(fragB, fragA);
break;
case PIPE_BLENDFACTOR_DST_COLOR:
term1r = spu_mul(fragR, fbRGBA[0]);
term1g = spu_mul(fragG, fbRGBA[1]);
term1b = spu_mul(fragB, fbRGBA[1]);
break;
case PIPE_BLENDFACTOR_DST_ALPHA:
term1r = spu_mul(fragR, fbRGBA[3]);
term1g = spu_mul(fragG, fbRGBA[3]);
term1b = spu_mul(fragB, fbRGBA[3]);
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
term1r = spu_mul(fragR, spu_splats(spu.blend_color.color[0]));
term1g = spu_mul(fragG, spu_splats(spu.blend_color.color[1]));
term1b = spu_mul(fragB, spu_splats(spu.blend_color.color[2]));
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
term1r = spu_mul(fragR, spu_splats(spu.blend_color.color[3]));
term1g = spu_mul(fragG, spu_splats(spu.blend_color.color[3]));
term1b = spu_mul(fragB, spu_splats(spu.blend_color.color[3]));
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Src Alpha term
* Compute Src Alpha term (fragment alpha * factor)
*/
switch (spu.blend.alpha_src_factor) {
case PIPE_BLENDFACTOR_ONE:
@@ -283,19 +321,29 @@ spu_fallback_fragment_ops(uint x, uint y,
case PIPE_BLENDFACTOR_SRC_ALPHA:
term1a = spu_mul(fragA, fragA);
break;
case PIPE_BLENDFACTOR_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_DST_ALPHA:
term1a = spu_mul(fragA, fbRGBA[3]);
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_CONST_ALPHA:
term1a = spu_mul(fragR, spu_splats(spu.blend_color.color[3]));
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest RGB terms
* Compute Dest RGB terms (framebuffer color * factor)
*/
switch (spu.blend.rgb_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
term2r = fragR;
term2g = fragG;
term2b = fragB;
term2r = fbRGBA[0];
term2g = fbRGBA[1];
term2b = fbRGBA[2];
break;
case PIPE_BLENDFACTOR_ZERO:
term2r =
@@ -319,17 +367,37 @@ spu_fallback_fragment_ops(uint x, uint y,
term2g = spu_mul(fbRGBA[1], tmp);
term2b = spu_mul(fbRGBA[2], tmp);
break;
/* XXX more cases */
case PIPE_BLENDFACTOR_DST_COLOR:
term2r = spu_mul(fbRGBA[0], fbRGBA[0]);
term2g = spu_mul(fbRGBA[1], fbRGBA[1]);
term2b = spu_mul(fbRGBA[2], fbRGBA[2]);
break;
case PIPE_BLENDFACTOR_DST_ALPHA:
term2r = spu_mul(fbRGBA[0], fbRGBA[3]);
term2g = spu_mul(fbRGBA[1], fbRGBA[3]);
term2b = spu_mul(fbRGBA[2], fbRGBA[3]);
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
term2r = spu_mul(fbRGBA[0], spu_splats(spu.blend_color.color[0]));
term2g = spu_mul(fbRGBA[1], spu_splats(spu.blend_color.color[1]));
term2b = spu_mul(fbRGBA[2], spu_splats(spu.blend_color.color[2]));
break;
case PIPE_BLENDFACTOR_CONST_ALPHA:
term2r = spu_mul(fbRGBA[0], spu_splats(spu.blend_color.color[3]));
term2g = spu_mul(fbRGBA[1], spu_splats(spu.blend_color.color[3]));
term2b = spu_mul(fbRGBA[2], spu_splats(spu.blend_color.color[3]));
break;
/* XXX more cases */
default:
ASSERT(0);
}
/*
* Compute Dest Alpha term
* Compute Dest Alpha term (framebuffer alpha * factor)
*/
switch (spu.blend.alpha_dst_factor) {
case PIPE_BLENDFACTOR_ONE:
term2a = fragA;
term2a = fbRGBA[3];
break;
case PIPE_BLENDFACTOR_SRC_COLOR:
term2a = spu_splats(0.0f);
@@ -342,6 +410,16 @@ spu_fallback_fragment_ops(uint x, uint y,
tmp = spu_sub(one, fragA);
term2a = spu_mul(fbRGBA[3], tmp);
break;
case PIPE_BLENDFACTOR_DST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_DST_ALPHA:
term2a = spu_mul(fbRGBA[3], fbRGBA[3]);
break;
case PIPE_BLENDFACTOR_CONST_COLOR:
/* fall-through */
case PIPE_BLENDFACTOR_CONST_ALPHA:
term2a = spu_mul(fbRGBA[3], spu_splats(spu.blend_color.color[3]));
break;
/* XXX more cases */
default:
ASSERT(0);
@@ -361,7 +439,21 @@ spu_fallback_fragment_ops(uint x, uint y,
fragG = spu_sub(term1g, term2g);
fragB = spu_sub(term1b, term2b);
break;
/* XXX more cases */
case PIPE_BLEND_REVERSE_SUBTRACT:
fragR = spu_sub(term2r, term1r);
fragG = spu_sub(term2g, term1g);
fragB = spu_sub(term2b, term1b);
break;
case PIPE_BLEND_MIN:
fragR = spu_min(term1r, term2r);
fragG = spu_min(term1g, term2g);
fragB = spu_min(term1b, term2b);
break;
case PIPE_BLEND_MAX:
fragR = spu_max(term1r, term2r);
fragG = spu_max(term1g, term2g);
fragB = spu_max(term1b, term2b);
break;
default:
ASSERT(0);
}
@@ -376,7 +468,15 @@ spu_fallback_fragment_ops(uint x, uint y,
case PIPE_BLEND_SUBTRACT:
fragA = spu_sub(term1a, term2a);
break;
/* XXX more cases */
case PIPE_BLEND_REVERSE_SUBTRACT:
fragA = spu_sub(term2a, term1a);
break;
case PIPE_BLEND_MIN:
fragA = spu_min(term1a, term2a);
break;
case PIPE_BLEND_MAX:
fragA = spu_max(term1a, term2a);
break;
default:
ASSERT(0);
}
+15 -19
View File
@@ -175,22 +175,14 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
const ubyte *vertices;
const ushort *indexes;
uint i, j;
uint num_tiles;
if (Debug) {
printf("SPU %u: RENDER prim %u, num_vert=%u num_ind=%u "
"inline_vert=%u\n",
spu.init.id,
render->prim_type,
render->num_verts,
render->num_indexes,
render->inline_verts);
/*
printf(" bound: %g, %g .. %g, %g\n",
render->xmin, render->ymin, render->xmax, render->ymax);
*/
}
D_PRINTF(CELL_DEBUG_CMD,
"RENDER prim=%u num_vert=%u num_ind=%u inline_vert=%u\n",
render->prim_type,
render->num_verts,
render->num_indexes,
render->inline_verts);
ASSERT(sizeof(*render) % 4 == 0);
ASSERT(total_vertex_bytes % 16 == 0);
@@ -251,6 +243,8 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
wait_on_mask(1 << TAG_SURFACE_CLEAR); /* XXX temporary */
num_tiles = 0;
/**
** loop over tiles, rendering tris
**/
@@ -264,6 +258,8 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
if (!my_tile(tx, ty))
continue;
num_tiles++;
spu.cur_ctile_status = spu.ctile_status[ty][tx];
spu.cur_ztile_status = spu.ztile_status[ty][tx];
@@ -279,7 +275,7 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
v1 = (const float *) (vertices + indexes[j+1] * vertex_size);
v2 = (const float *) (vertices + indexes[j+2] * vertex_size);
drawn += tri_draw(v0, v1, v2, tx, ty, render->front_winding);
drawn += tri_draw(v0, v1, v2, tx, ty);
}
//printf("SPU %u: drew %u of %u\n", spu.init.id, drawn, render->num_indexes/3);
@@ -293,7 +289,7 @@ cmd_render(const struct cell_command_render *render, uint *pos_incr)
spu.ztile_status[ty][tx] = spu.cur_ztile_status;
}
if (Debug)
printf("SPU %u: RENDER done\n",
spu.init.id);
D_PRINTF(CELL_DEBUG_CMD,
"RENDER done (%u tiles hit)\n",
num_tiles);
}
+124 -84
View File
@@ -72,10 +72,10 @@ invalidate_tex_cache(void)
* a time.
*/
static void
get_four_texels(uint unit, uint level, uint face, vec_int4 x, vec_int4 y,
get_four_texels(const struct spu_texture_level *tlevel, uint face,
vec_int4 x, vec_int4 y,
vec_uint4 *texels)
{
const struct spu_texture_level *tlevel = &spu.texture[unit].level[level];
unsigned texture_ea = (uintptr_t) tlevel->start;
const vec_int4 tile_x = spu_rlmask(x, -5); /* tile_x = x / 32 */
const vec_int4 tile_y = spu_rlmask(y, -5); /* tile_y = y / 32 */
@@ -126,10 +126,9 @@ spu_clamp(vector signed int vec, vector signed int max)
* \param colors returned colors in SOA format (rrrr, gggg, bbbb, aaaa).
*/
void
sample_texture4_nearest(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4])
sample_texture_2d_nearest(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4])
{
const struct spu_texture_level *tlevel = &spu.texture[unit].level[level];
vector float ss = spu_mul(s, tlevel->scale_s);
@@ -146,7 +145,7 @@ sample_texture4_nearest(vector float s, vector float t,
is = spu_clamp(is, tlevel->max_s);
it = spu_clamp(it, tlevel->max_t);
get_four_texels(unit, level, face, is, it, texels);
get_four_texels(tlevel, face, is, it, texels);
/* convert four packed ARGBA pixels to float RRRR,GGGG,BBBB,AAAA */
spu_unpack_A8R8G8B8_transpose4(texels, colors);
@@ -158,10 +157,9 @@ sample_texture4_nearest(vector float s, vector float t,
* \param colors returned colors in SOA format (rrrr, gggg, bbbb, aaaa).
*/
void
sample_texture4_bilinear(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4])
sample_texture_2d_bilinear(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4])
{
const struct spu_texture_level *tlevel = &spu.texture[unit].level[level];
static const vector float half = {-0.5f, -0.5f, -0.5f, -0.5f};
@@ -190,14 +188,10 @@ sample_texture4_bilinear(vector float s, vector float t,
/* get packed int texels */
vector unsigned int texels[16];
get_four_texels(unit, level, face, is0, it0, texels + 0); /* upper-left */
get_four_texels(unit, level, face, is1, it0, texels + 4); /* upper-right */
get_four_texels(unit, level, face, is0, it1, texels + 8); /* lower-left */
get_four_texels(unit, level, face, is1, it1, texels + 12); /* lower-right */
/* XXX possibly rework following code to compute the weighted sample
* colors with integer arithmetic for fewer int->float conversions.
*/
get_four_texels(tlevel, face, is0, it0, texels + 0); /* upper-left */
get_four_texels(tlevel, face, is1, it0, texels + 4); /* upper-right */
get_four_texels(tlevel, face, is0, it1, texels + 8); /* lower-left */
get_four_texels(tlevel, face, is1, it1, texels + 12); /* lower-right */
/* convert packed int texels to float colors */
vector float ftexels[16];
@@ -305,13 +299,13 @@ transpose(vector unsigned int *mOut0,
/**
* Bilinear filtering, using int intead of float arithmetic
* Bilinear filtering, using int instead of float arithmetic for computing
* sample weights.
*/
void
sample_texture4_bilinear_2(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4])
sample_texture_2d_bilinear_int(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4])
{
const struct spu_texture_level *tlevel = &spu.texture[unit].level[level];
static const vector float half = {-0.5f, -0.5f, -0.5f, -0.5f};
@@ -320,19 +314,19 @@ sample_texture4_bilinear_2(vector float s, vector float t,
vector float ss = spu_madd(s, tlevel->scale_s, half);
vector float tt = spu_madd(t, tlevel->scale_t, half);
/* convert float coords to fixed-pt coords with 8 fraction bits */
vector signed int is = spu_convts(ss, 8);
vector signed int it = spu_convts(tt, 8);
/* convert float coords to fixed-pt coords with 7 fraction bits */
vector signed int is = spu_convts(ss, 7); /* XXX really need floor() here */
vector signed int it = spu_convts(tt, 7); /* XXX really need floor() here */
/* compute integer texel weights in [0, 255] */
vector signed int sWeights0 = spu_and(is, 255);
vector signed int tWeights0 = spu_and(it, 255);
vector signed int sWeights1 = spu_sub(255, sWeights0);
vector signed int tWeights1 = spu_sub(255, tWeights0);
/* compute integer texel weights in [0, 127] */
vector signed int sWeights0 = spu_and(is, 127);
vector signed int tWeights0 = spu_and(it, 127);
vector signed int sWeights1 = spu_sub(127, sWeights0);
vector signed int tWeights1 = spu_sub(127, tWeights0);
/* texel coords: is0 = is / 256, it0 = is / 256 */
vector signed int is0 = spu_rlmask(is, -8);
vector signed int it0 = spu_rlmask(it, -8);
/* texel coords: is0 = is / 128, it0 = is / 128 */
vector signed int is0 = spu_rlmask(is, -7);
vector signed int it0 = spu_rlmask(it, -7);
/* texel coords: i1 = is0 + 1, it1 = it0 + 1 */
vector signed int is1 = spu_add(is0, 1);
@@ -352,10 +346,10 @@ sample_texture4_bilinear_2(vector float s, vector float t,
/* get packed int texels */
vector unsigned int texels[16];
get_four_texels(unit, level, face, is0, it0, texels + 0); /* upper-left */
get_four_texels(unit, level, face, is1, it0, texels + 4); /* upper-right */
get_four_texels(unit, level, face, is0, it1, texels + 8); /* lower-left */
get_four_texels(unit, level, face, is1, it1, texels + 12); /* lower-right */
get_four_texels(tlevel, face, is0, it0, texels + 0); /* upper-left */
get_four_texels(tlevel, face, is1, it0, texels + 4); /* upper-right */
get_four_texels(tlevel, face, is0, it1, texels + 8); /* lower-left */
get_four_texels(tlevel, face, is1, it1, texels + 12); /* lower-right */
/* twiddle packed 32-bit BGRA pixels into RGBA as four unsigned ints */
{
@@ -383,36 +377,36 @@ sample_texture4_bilinear_2(vector float s, vector float t,
vector unsigned int c0, c1, c2, c3, cSum;
/* red */
c0 = (vector unsigned int) si_mpyu((qword) texel0, si_mpyu((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpyu((qword) texel4, si_mpyu((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpyu((qword) texel8, si_mpyu((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpyu((qword) texel12, si_mpyu((qword) sWeights0, (qword) tWeights0)); /*lr*/
c0 = (vector unsigned int) si_mpy((qword) texel0, si_mpy((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpy((qword) texel4, si_mpy((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpy((qword) texel8, si_mpy((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpy((qword) texel12, si_mpy((qword) sWeights0, (qword) tWeights0)); /*lr*/
cSum = spu_add(spu_add(c0, c1), spu_add(c2, c3));
colors[0] = spu_convtf(cSum, 24);
colors[0] = spu_convtf(cSum, 22);
/* green */
c0 = (vector unsigned int) si_mpyu((qword) texel1, si_mpyu((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpyu((qword) texel5, si_mpyu((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpyu((qword) texel9, si_mpyu((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpyu((qword) texel13, si_mpyu((qword) sWeights0, (qword) tWeights0)); /*lr*/
c0 = (vector unsigned int) si_mpy((qword) texel1, si_mpy((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpy((qword) texel5, si_mpy((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpy((qword) texel9, si_mpy((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpy((qword) texel13, si_mpy((qword) sWeights0, (qword) tWeights0)); /*lr*/
cSum = spu_add(spu_add(c0, c1), spu_add(c2, c3));
colors[1] = spu_convtf(cSum, 24);
colors[1] = spu_convtf(cSum, 22);
/* blue */
c0 = (vector unsigned int) si_mpyu((qword) texel2, si_mpyu((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpyu((qword) texel6, si_mpyu((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpyu((qword) texel10, si_mpyu((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpyu((qword) texel14, si_mpyu((qword) sWeights0, (qword) tWeights0)); /*lr*/
c0 = (vector unsigned int) si_mpy((qword) texel2, si_mpy((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpy((qword) texel6, si_mpy((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpy((qword) texel10, si_mpy((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpy((qword) texel14, si_mpy((qword) sWeights0, (qword) tWeights0)); /*lr*/
cSum = spu_add(spu_add(c0, c1), spu_add(c2, c3));
colors[2] = spu_convtf(cSum, 24);
colors[2] = spu_convtf(cSum, 22);
/* alpha */
c0 = (vector unsigned int) si_mpyu((qword) texel3, si_mpyu((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpyu((qword) texel7, si_mpyu((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpyu((qword) texel11, si_mpyu((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpyu((qword) texel15, si_mpyu((qword) sWeights0, (qword) tWeights0)); /*lr*/
c0 = (vector unsigned int) si_mpy((qword) texel3, si_mpy((qword) sWeights1, (qword) tWeights1)); /*ul*/
c1 = (vector unsigned int) si_mpy((qword) texel7, si_mpy((qword) sWeights0, (qword) tWeights1)); /*ur*/
c2 = (vector unsigned int) si_mpy((qword) texel11, si_mpy((qword) sWeights1, (qword) tWeights0)); /*ll*/
c3 = (vector unsigned int) si_mpy((qword) texel15, si_mpy((qword) sWeights0, (qword) tWeights0)); /*lr*/
cSum = spu_add(spu_add(c0, c1), spu_add(c2, c3));
colors[3] = spu_convtf(cSum, 24);
colors[3] = spu_convtf(cSum, 22);
}
@@ -420,8 +414,8 @@ sample_texture4_bilinear_2(vector float s, vector float t,
/**
* Compute level of detail factor from texcoords.
*/
static float
compute_lambda(uint unit, vector float s, vector float t)
static INLINE float
compute_lambda_2d(uint unit, vector float s, vector float t)
{
uint baseLevel = 0;
float width = spu.texture[unit].level[baseLevel].width;
@@ -430,30 +424,60 @@ compute_lambda(uint unit, vector float s, vector float t)
float dsdy = width * (spu_extract(s, 2) - spu_extract(s, 0));
float dtdx = height * (spu_extract(t, 1) - spu_extract(t, 0));
float dtdy = height * (spu_extract(t, 2) - spu_extract(t, 0));
#if 0
/* ideal value */
float x = dsdx * dsdx + dtdx * dtdx;
float y = dsdy * dsdy + dtdy * dtdy;
float rho = x > y ? x : y;
rho = sqrtf(rho);
float lambda = logf(rho) * 1.442695f;
#else
/* approximation */
dsdx = fabsf(dsdx);
dsdy = fabsf(dsdy);
dtdx = fabsf(dtdx);
dtdy = fabsf(dtdy);
float rho = (dsdx + dsdy + dtdx + dtdy) * 0.5;
#endif
float lambda = logf(rho) * 1.442695f; /* compute logbase2(rho) */
return lambda;
}
/**
* Blend two sets of colors according to weight.
*/
static void
blend_colors(vector float c0[4], const vector float c1[4], float weight)
{
vector float t = spu_splats(weight);
vector float dc0 = spu_sub(c1[0], c0[0]);
vector float dc1 = spu_sub(c1[1], c0[1]);
vector float dc2 = spu_sub(c1[2], c0[2]);
vector float dc3 = spu_sub(c1[3], c0[3]);
c0[0] = spu_madd(dc0, t, c0[0]);
c0[1] = spu_madd(dc1, t, c0[1]);
c0[2] = spu_madd(dc2, t, c0[2]);
c0[3] = spu_madd(dc3, t, c0[3]);
}
/**
* Texture sampling with level of detail selection.
* Texture sampling with level of detail selection and possibly mipmap
* interpolation.
*/
void
sample_texture4_lod(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level_ignored, uint face,
vector float colors[4])
sample_texture_2d_lod(vector float s, vector float t,
uint unit, uint level_ignored, uint face,
vector float colors[4])
{
/*
* Note that we're computing a lambda/lod here that's used for all
* four pixels in the quad.
*/
float lambda = compute_lambda(unit, s, t);
float lambda = compute_lambda_2d(unit, s, t);
(void) face;
(void) level_ignored;
/* apply lod bias */
lambda += spu.sampler[unit].lod_bias;
@@ -466,15 +490,34 @@ sample_texture4_lod(vector float s, vector float t,
if (lambda <= 0.0f) {
/* magnify */
spu.mag_sample_texture4[unit](s, t, r, q, unit, 0, 0, colors);
spu.mag_sample_texture_2d[unit](s, t, unit, 0, face, colors);
}
else {
/* minify */
int level = (int) (lambda + 0.5f);
if (level > (int) spu.texture[unit].max_level)
level = spu.texture[unit].max_level;
spu.min_sample_texture4[unit](s, t, r, q, unit, level, 0, colors);
/* XXX to do: mipmap level interpolation */
if (spu.sampler[unit].min_img_filter == PIPE_TEX_FILTER_LINEAR) {
/* sample two mipmap levels and interpolate */
int level = (int) lambda;
if (level > (int) spu.texture[unit].max_level)
level = spu.texture[unit].max_level;
spu.min_sample_texture_2d[unit](s, t, unit, level, face, colors);
if (spu.sampler[unit].min_img_filter == PIPE_TEX_FILTER_LINEAR) {
/* sample second mipmap level */
float weight = lambda - (float) level;
level++;
if (level <= (int) spu.texture[unit].max_level) {
vector float colors2[4];
spu.min_sample_texture_2d[unit](s, t, unit, level, face, colors2);
blend_colors(colors, colors2, weight);
}
}
}
else {
/* sample one mipmap level */
int level = (int) (lambda + 0.5f);
if (level > (int) spu.texture[unit].max_level)
level = spu.texture[unit].max_level;
spu.min_sample_texture_2d[unit](s, t, unit, level, face, colors);
}
}
}
@@ -552,16 +595,13 @@ choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
void
sample_texture4_cube(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face_ignored,
vector float colors[4])
sample_texture_cube(vector float s, vector float t, vector float r,
uint unit, vector float colors[4])
{
static const vector float zero = {0.0f, 0.0f, 0.0f, 0.0f};
uint p, faces[4];
uint p, faces[4], level = 0;
float newS[4], newT[4];
/* Compute cube face referenced by the four sets of texcoords.
/* Compute cube faces referenced by the four sets of texcoords.
* XXX we should SIMD-ize this.
*/
for (p = 0; p < 4; p++) {
@@ -577,15 +617,15 @@ sample_texture4_cube(vector float s, vector float t,
/* GOOD! All four texcoords refer to the same cube face */
s = (vector float) {newS[0], newS[1], newS[2], newS[3]};
t = (vector float) {newT[0], newT[1], newT[2], newT[3]};
sample_texture4_nearest(s, t, zero, zero, unit, level, faces[0], colors);
spu.sample_texture_2d[unit](s, t, unit, level, faces[0], colors);
}
else {
/* BAD! The four texcoords refer to different faces */
for (p = 0; p < 4; p++) {
vector float c[4];
sample_texture4_nearest(spu_splats(newS[p]), spu_splats(newT[p]),
zero, zero, unit, level, faces[p], c);
spu.sample_texture_2d[unit](spu_splats(newS[p]), spu_splats(newT[p]),
unit, level, faces[p], c);
float red = spu_extract(c[0], p);
float green = spu_extract(c[1], p);
+15 -21
View File
@@ -37,37 +37,31 @@ invalidate_tex_cache(void);
extern void
sample_texture4_nearest(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4]);
sample_texture_2d_nearest(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4]);
extern void
sample_texture4_bilinear(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4]);
extern void
sample_texture4_bilinear_2(vector float s, vector float t,
vector float r, vector float q,
sample_texture_2d_bilinear(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4]);
extern void
sample_texture4_lod(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level, uint face,
vector float colors[4]);
sample_texture_2d_bilinear_int(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4]);
extern void
sample_texture4_cube(vector float s, vector float t,
vector float r, vector float q,
uint unit, uint level_ignored, uint face_ignored,
vector float colors[4]);
sample_texture_2d_lod(vector float s, vector float t,
uint unit, uint level, uint face,
vector float colors[4]);
extern void
sample_texture_cube(vector float s, vector float t, vector float r,
uint unit, vector float colors[4]);
#endif /* SPU_TEXTURE_H */
+71 -91
View File
@@ -43,11 +43,6 @@
/** Masks are uint[4] vectors with each element being 0 or 0xffffffff */
typedef vector unsigned int mask_t;
typedef union
{
vector float v;
float f[4];
} float4;
/**
@@ -91,9 +86,9 @@ struct edge {
struct interp_coef
{
float4 a0;
float4 dadx;
float4 dady;
vector float a0;
vector float dadx;
vector float dady;
};
@@ -116,7 +111,7 @@ struct setup_stage {
struct edge etop;
struct edge emaj;
float oneOverArea;
float oneOverArea; /* XXX maybe make into vector? */
uint facing;
@@ -152,14 +147,14 @@ eval_coeff(uint slot, float x, float y, vector float w, vector float result[4])
result[QUAD_TOP_LEFT] =
result[QUAD_TOP_RIGHT] =
result[QUAD_BOTTOM_LEFT] =
result[QUAD_BOTTOM_RIGHT] = setup.coef[slot].a0.v;
result[QUAD_BOTTOM_RIGHT] = setup.coef[slot].a0;
break;
case INTERP_LINEAR:
{
vector float dadx = setup.coef[slot].dadx.v;
vector float dady = setup.coef[slot].dady.v;
vector float dadx = setup.coef[slot].dadx;
vector float dady = setup.coef[slot].dady;
vector float topLeft =
spu_add(setup.coef[slot].a0.v,
spu_add(setup.coef[slot].a0,
spu_add(spu_mul(spu_splats(x), dadx),
spu_mul(spu_splats(y), dady)));
@@ -171,10 +166,10 @@ eval_coeff(uint slot, float x, float y, vector float w, vector float result[4])
break;
case INTERP_PERSPECTIVE:
{
vector float dadx = setup.coef[slot].dadx.v;
vector float dady = setup.coef[slot].dady.v;
vector float dadx = setup.coef[slot].dadx;
vector float dady = setup.coef[slot].dady;
vector float topLeft =
spu_add(setup.coef[slot].a0.v,
spu_add(setup.coef[slot].a0,
spu_add(spu_mul(spu_splats(x), dadx),
spu_mul(spu_splats(y), dady)));
@@ -212,9 +207,9 @@ static INLINE vector float
eval_z(float x, float y)
{
const uint slot = 0;
const float dzdx = setup.coef[slot].dadx.f[2];
const float dzdy = setup.coef[slot].dady.f[2];
const float topLeft = setup.coef[slot].a0.f[2] + x * dzdx + y * dzdy;
const float dzdx = spu_extract(setup.coef[slot].dadx, 2);
const float dzdy = spu_extract(setup.coef[slot].dady, 2);
const float topLeft = spu_extract(setup.coef[slot].a0, 2) + x * dzdx + y * dzdy;
const vector float topLeftv = spu_splats(topLeft);
const vector float derivs = (vector float) { 0.0, dzdx, dzdy, dzdx + dzdy };
return spu_add(topLeftv, derivs);
@@ -226,9 +221,9 @@ static INLINE vector float
eval_w(float x, float y)
{
const uint slot = 0;
const float dwdx = setup.coef[slot].dadx.f[3];
const float dwdy = setup.coef[slot].dady.f[3];
const float topLeft = setup.coef[slot].a0.f[3] + x * dwdx + y * dwdy;
const float dwdx = spu_extract(setup.coef[slot].dadx, 3);
const float dwdy = spu_extract(setup.coef[slot].dady, 3);
const float topLeft = spu_extract(setup.coef[slot].a0, 3) + x * dwdx + y * dwdy;
const vector float topLeftv = spu_splats(topLeft);
const vector float derivs = (vector float) { 0.0, dwdx, dwdy, dwdx + dwdy };
return spu_add(topLeftv, derivs);
@@ -259,6 +254,7 @@ emit_quad( int x, int y, mask_t mask)
vector float inputs[4*4], outputs[2*4];
vector float fragZ = eval_z((float) x, (float) y);
vector float fragW = eval_w((float) x, (float) y);
vector unsigned int kill_mask;
/* setup inputs */
#if 0
@@ -273,7 +269,9 @@ emit_quad( int x, int y, mask_t mask)
ASSERT(spu.fragment_ops);
/* Execute the current fragment program */
spu.fragment_program(inputs, outputs, spu.constants);
kill_mask = spu.fragment_program(inputs, outputs, spu.constants);
mask = spu_andc(mask, kill_mask);
/* Execute per-fragment/quad operations, including:
* alpha test, z test, stencil test, blend and framebuffer writing.
@@ -404,29 +402,40 @@ flush_spans(void)
static void
print_vertex(const struct vertex_header *v)
{
int i;
fprintf(stderr, "Vertex: (%p)\n", v);
for (i = 0; i < setup.quad.nr_attrs; i++) {
fprintf(stderr, " %d: %f %f %f %f\n", i,
v->data[i][0], v->data[i][1], v->data[i][2], v->data[i][3]);
uint i;
fprintf(stderr, " Vertex: (%p)\n", v);
for (i = 0; i < spu.vertex_info.num_attribs; i++) {
fprintf(stderr, " %d: %f %f %f %f\n", i,
spu_extract(v->data[i], 0),
spu_extract(v->data[i], 1),
spu_extract(v->data[i], 2),
spu_extract(v->data[i], 3));
}
}
#endif
/**
* Sort vertices from top to bottom.
* Compute area and determine front vs. back facing.
* Do coarse clip test against tile bounds
* \return FALSE if tri is totally outside tile, TRUE otherwise
*/
static boolean
setup_sort_vertices(const struct vertex_header *v0,
const struct vertex_header *v1,
const struct vertex_header *v2)
{
#if DEBUG_VERTS
fprintf(stderr, "Triangle:\n");
print_vertex(v0);
print_vertex(v1);
print_vertex(v2);
#endif
float area, sign;
setup.vprovoke = v2;
#if DEBUG_VERTS
if (spu.init.id==0) {
fprintf(stderr, "SPU %u: Triangle:\n", spu.init.id);
print_vertex(v0);
print_vertex(v1);
print_vertex(v2);
}
#endif
/* determine bottom to top order of vertices */
{
@@ -439,18 +448,21 @@ setup_sort_vertices(const struct vertex_header *v0,
setup.vmin = v0;
setup.vmid = v1;
setup.vmax = v2;
sign = -1.0f;
}
else if (y2 <= y0) {
/* y2<=y0<=y1 */
setup.vmin = v2;
setup.vmid = v0;
setup.vmax = v1;
sign = -1.0f;
}
else {
/* y0<=y2<=y1 */
setup.vmin = v0;
setup.vmid = v2;
setup.vmax = v1;
sign = 1.0f;
}
}
else {
@@ -459,18 +471,21 @@ setup_sort_vertices(const struct vertex_header *v0,
setup.vmin = v1;
setup.vmid = v0;
setup.vmax = v2;
sign = 1.0f;
}
else if (y2 <= y1) {
/* y2<=y1<=y0 */
setup.vmin = v2;
setup.vmid = v1;
setup.vmax = v0;
sign = 1.0f;
}
else {
/* y1<=y2<=y0 */
setup.vmin = v1;
setup.vmid = v2;
setup.vmax = v0;
sign = -1.0f;
}
}
}
@@ -499,31 +514,16 @@ setup_sort_vertices(const struct vertex_header *v0,
/*
* Compute triangle's area. Use 1/area to compute partial
* derivatives of attributes later.
*
* The area will be the same as prim->det, but the sign may be
* different depending on how the vertices get sorted above.
*
* To determine whether the primitive is front or back facing we
* use the prim->det value because its sign is correct.
*/
{
const float area = (setup.emaj.dx * setup.ebot.dy -
setup.ebot.dx * setup.emaj.dy);
area = setup.emaj.dx * setup.ebot.dy - setup.ebot.dx * setup.emaj.dy;
setup.oneOverArea = 1.0f / area;
/*
_mesa_printf("%s one-over-area %f area %f det %f\n",
__FUNCTION__, setup.oneOverArea, area, prim->det );
*/
}
setup.oneOverArea = 1.0f / area;
#if 0
/* We need to know if this is a front or back-facing triangle for:
* - the GLSL gl_FrontFacing fragment attribute (bool)
* - two-sided stencil test
*/
setup.quad.facing = (prim->det > 0.0) ^ (setup.softpipe->rasterizer->front_winding == PIPE_WINDING_CW);
#endif
/* The product of area * sign indicates front/back orientation (0/1) */
setup.facing = (area * sign > 0.0f)
^ (spu.rasterizer.front_winding == PIPE_WINDING_CW);
setup.vprovoke = v2;
return TRUE;
}
@@ -538,9 +538,9 @@ setup_sort_vertices(const struct vertex_header *v0,
static INLINE void
const_coeff4(uint slot)
{
setup.coef[slot].dadx.v = (vector float) {0.0, 0.0, 0.0, 0.0};
setup.coef[slot].dady.v = (vector float) {0.0, 0.0, 0.0, 0.0};
setup.coef[slot].a0.v = setup.vprovoke->data[slot];
setup.coef[slot].dadx = (vector float) {0.0, 0.0, 0.0, 0.0};
setup.coef[slot].dady = (vector float) {0.0, 0.0, 0.0, 0.0};
setup.coef[slot].a0 = setup.vprovoke->data[slot];
}
@@ -564,13 +564,13 @@ tri_linear_coeff4(uint slot)
vector float b = spu_sub(spu_mul(spu_splats(setup.emaj.dx), botda),
spu_mul(majda, spu_splats(setup.ebot.dx)));
setup.coef[slot].dadx.v = spu_mul(a, spu_splats(setup.oneOverArea));
setup.coef[slot].dady.v = spu_mul(b, spu_splats(setup.oneOverArea));
setup.coef[slot].dadx = spu_mul(a, spu_splats(setup.oneOverArea));
setup.coef[slot].dady = spu_mul(b, spu_splats(setup.oneOverArea));
vector float tempx = spu_mul(setup.coef[slot].dadx.v, xxxx);
vector float tempy = spu_mul(setup.coef[slot].dady.v, yyyy);
vector float tempx = spu_mul(setup.coef[slot].dadx, xxxx);
vector float tempy = spu_mul(setup.coef[slot].dady, yyyy);
setup.coef[slot].a0.v = spu_sub(vmin_d, spu_add(tempx, tempy));
setup.coef[slot].a0 = spu_sub(vmin_d, spu_add(tempx, tempy));
}
@@ -608,13 +608,13 @@ tri_persp_coeff4(uint slot)
vector float b = spu_sub(spu_mul(spu_splats(setup.emaj.dx), botda),
spu_mul(majda, spu_splats(setup.ebot.dx)));
setup.coef[slot].dadx.v = spu_mul(a, spu_splats(setup.oneOverArea));
setup.coef[slot].dady.v = spu_mul(b, spu_splats(setup.oneOverArea));
setup.coef[slot].dadx = spu_mul(a, spu_splats(setup.oneOverArea));
setup.coef[slot].dady = spu_mul(b, spu_splats(setup.oneOverArea));
vector float tempx = spu_mul(setup.coef[slot].dadx.v, xxxx);
vector float tempy = spu_mul(setup.coef[slot].dady.v, yyyy);
vector float tempx = spu_mul(setup.coef[slot].dadx, xxxx);
vector float tempy = spu_mul(setup.coef[slot].dady, yyyy);
setup.coef[slot].a0.v = spu_sub(vmin_d, spu_add(tempx, tempy));
setup.coef[slot].a0 = spu_sub(vmin_d, spu_add(tempx, tempy));
}
@@ -750,27 +750,13 @@ subtriangle(struct edge *eleft, struct edge *eright, unsigned lines)
}
static float
determinant(const float *v0, const float *v1, const float *v2)
{
/* edge vectors e = v0 - v2, f = v1 - v2 */
const float ex = v0[0] - v2[0];
const float ey = v0[1] - v2[1];
const float fx = v1[0] - v2[0];
const float fy = v1[1] - v2[1];
/* det = cross(e,f).z */
return ex * fy - ey * fx;
}
/**
* Draw triangle into tile at (tx, ty) (tile coords)
* The tile data should have already been fetched.
*/
boolean
tri_draw(const float *v0, const float *v1, const float *v2,
uint tx, uint ty, uint front_winding)
uint tx, uint ty)
{
setup.tx = tx;
setup.ty = ty;
@@ -781,12 +767,6 @@ tri_draw(const float *v0, const float *v1, const float *v2,
setup.cliprect_maxx = (tx + 1) * TILE_SIZE;
setup.cliprect_maxy = (ty + 1) * TILE_SIZE;
/* Before we sort vertices, determine the facing of the triangle,
* which will be needed for front/back-face stencil application
*/
float det = determinant(v0, v1, v2);
setup.facing = (det > 0.0) ^ (front_winding == PIPE_WINDING_CW);
if (!setup_sort_vertices((struct vertex_header *) v0,
(struct vertex_header *) v1,
(struct vertex_header *) v2)) {
+1 -1
View File
@@ -31,7 +31,7 @@
extern boolean
tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty, uint front_winding);
tri_draw(const float *v0, const float *v1, const float *v2, uint tx, uint ty);
#endif /* SPU_TRI_H */
+1 -6
View File
@@ -42,7 +42,6 @@
struct sp_exec_fragment_shader
{
struct sp_fragment_shader base;
const struct tgsi_token *machine_tokens;
};
@@ -95,19 +94,15 @@ exec_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
struct tgsi_sampler *samplers )
{
struct sp_exec_fragment_shader *spefs =
sp_exec_fragment_shader(base);
/*
* Bind tokens/shader to the interpreter's machine state.
* Avoid redundant binding.
*/
if (spefs->machine_tokens != base->shader.tokens) {
if (machine->Tokens != base->shader.tokens) {
tgsi_exec_machine_bind_shader( machine,
base->shader.tokens,
PIPE_MAX_SAMPLERS,
samplers );
spefs->machine_tokens = base->shader.tokens;
}
}
+4 -1
View File
@@ -93,8 +93,11 @@
#endif
#endif
#if 0 /* FIXME */
#if defined(__PPC__)
#define PIPE_ARCH_PPC
#if defined(__PPC64__)
#define PIPE_ARCH_PPC_64
#endif
#endif
+13 -9
View File
@@ -5,8 +5,7 @@ Import('*')
if env['platform'] == 'linux' \
and 'mesa' in env['statetrackers'] \
and 'softpipe' in env['drivers'] \
and 'i965simple' in env['drivers'] \
and ('softpipe' or 'i915simple' or 'trace') in env['drivers'] \
and not env['dri']:
env = env.Clone()
@@ -22,15 +21,20 @@ if env['platform'] == 'linux' \
'xfonts.c',
'xm_api.c',
'xm_winsys.c',
'xm_winsys_aub.c',
'brw_aub.c',
]
drivers = [];
if 'softpipe' in env['drivers']:
drivers += [softpipe]
if 'i965simple' in env['drivers']:
drivers += [i965simple]
sources += [
'brw_aub.c',
'xm_winsys_aub.c',
]
drivers = [
softpipe,
i965simple,
]
if 'trace' in env['drivers']:
env.Append(CPPDEFINES = 'GALLIUM_TRACE')
drivers += [trace]
+450 -465
View File
File diff suppressed because it is too large Load Diff
+79 -71
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -36,100 +37,107 @@
/*****************************************************************************/
static void
do_enable_disable(GLenum array, GLboolean val )
do_enable_disable(GLenum array, GLboolean val)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
unsigned index = 0;
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
unsigned index = 0;
if ( array == GL_TEXTURE_COORD_ARRAY ) {
index = __glXGetActiveTextureUnit( state );
}
if (array == GL_TEXTURE_COORD_ARRAY) {
index = __glXGetActiveTextureUnit(state);
}
if ( ! __glXSetArrayEnable( state, array, index, val ) ) {
__glXSetError(gc, GL_INVALID_ENUM);
}
if (!__glXSetArrayEnable(state, array, index, val)) {
__glXSetError(gc, GL_INVALID_ENUM);
}
}
void __indirect_glEnableClientState(GLenum array)
void
__indirect_glEnableClientState(GLenum array)
{
do_enable_disable( array, GL_TRUE );
do_enable_disable(array, GL_TRUE);
}
void __indirect_glDisableClientState(GLenum array)
void
__indirect_glDisableClientState(GLenum array)
{
do_enable_disable( array, GL_FALSE );
do_enable_disable(array, GL_FALSE);
}
/************************************************************************/
void __indirect_glPushClientAttrib(GLuint mask)
void
__indirect_glPushClientAttrib(GLuint mask)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
__GLXattribute **spp = gc->attributes.stackPointer, *sp;
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
__GLXattribute **spp = gc->attributes.stackPointer, *sp;
if (spp < &gc->attributes.stack[__GL_CLIENT_ATTRIB_STACK_DEPTH]) {
if (!(sp = *spp)) {
sp = (__GLXattribute *)Xmalloc(sizeof(__GLXattribute));
*spp = sp;
}
sp->mask = mask;
gc->attributes.stackPointer = spp + 1;
if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
sp->storePack = state->storePack;
sp->storeUnpack = state->storeUnpack;
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
__glXPushArrayState( state );
}
} else {
__glXSetError(gc, GL_STACK_OVERFLOW);
return;
}
if (spp < &gc->attributes.stack[__GL_CLIENT_ATTRIB_STACK_DEPTH]) {
if (!(sp = *spp)) {
sp = (__GLXattribute *) Xmalloc(sizeof(__GLXattribute));
*spp = sp;
}
sp->mask = mask;
gc->attributes.stackPointer = spp + 1;
if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
sp->storePack = state->storePack;
sp->storeUnpack = state->storeUnpack;
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
__glXPushArrayState(state);
}
}
else {
__glXSetError(gc, GL_STACK_OVERFLOW);
return;
}
}
void __indirect_glPopClientAttrib(void)
void
__indirect_glPopClientAttrib(void)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
__GLXattribute **spp = gc->attributes.stackPointer, *sp;
GLuint mask;
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
__GLXattribute **spp = gc->attributes.stackPointer, *sp;
GLuint mask;
if (spp > &gc->attributes.stack[0]) {
--spp;
sp = *spp;
assert(sp != 0);
mask = sp->mask;
gc->attributes.stackPointer = spp;
if (spp > &gc->attributes.stack[0]) {
--spp;
sp = *spp;
assert(sp != 0);
mask = sp->mask;
gc->attributes.stackPointer = spp;
if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
state->storePack = sp->storePack;
state->storeUnpack = sp->storeUnpack;
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
__glXPopArrayState( state );
}
if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
state->storePack = sp->storePack;
state->storeUnpack = sp->storeUnpack;
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
__glXPopArrayState(state);
}
sp->mask = 0;
} else {
__glXSetError(gc, GL_STACK_UNDERFLOW);
return;
}
sp->mask = 0;
}
else {
__glXSetError(gc, GL_STACK_UNDERFLOW);
return;
}
}
void __glFreeAttributeState(__GLXcontext *gc)
void
__glFreeAttributeState(__GLXcontext * gc)
{
__GLXattribute *sp, **spp;
__GLXattribute *sp, **spp;
for (spp = &gc->attributes.stack[0];
spp < &gc->attributes.stack[__GL_CLIENT_ATTRIB_STACK_DEPTH];
spp++) {
sp = *spp;
if (sp) {
XFree((char *)sp);
} else {
break;
}
}
for (spp = &gc->attributes.stack[0];
spp < &gc->attributes.stack[__GL_CLIENT_ATTRIB_STACK_DEPTH]; spp++) {
sp = *spp;
if (sp) {
XFree((char *) sp);
}
else {
break;
}
}
}
+126 -120
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -35,151 +36,156 @@
/*
** Return the number of elements per group of a specified format
*/
GLint __glElementsPerGroup(GLenum format, GLenum type)
GLint
__glElementsPerGroup(GLenum format, GLenum type)
{
/*
/*
** To make row length computation valid for image extraction,
** packed pixel types assume elements per group equals one.
*/
switch(type) {
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_SHORT_8_8_APPLE:
case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
case GL_UNSIGNED_SHORT_15_1_MESA:
case GL_UNSIGNED_SHORT_1_15_REV_MESA:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_24_8_NV:
case GL_UNSIGNED_INT_24_8_MESA:
case GL_UNSIGNED_INT_8_24_REV_MESA:
switch (type) {
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_SHORT_8_8_APPLE:
case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
case GL_UNSIGNED_SHORT_15_1_MESA:
case GL_UNSIGNED_SHORT_1_15_REV_MESA:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_24_8_NV:
case GL_UNSIGNED_INT_24_8_MESA:
case GL_UNSIGNED_INT_8_24_REV_MESA:
return 1;
default:
default:
break;
}
}
switch(format) {
case GL_RGB:
case GL_BGR:
return 3;
case GL_422_EXT:
case GL_422_REV_EXT:
case GL_422_AVERAGE_EXT:
case GL_422_REV_AVERAGE_EXT:
case GL_YCBCR_422_APPLE:
case GL_LUMINANCE_ALPHA:
return 2;
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
return 4;
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_INTENSITY:
return 1;
default:
return 0;
}
switch (format) {
case GL_RGB:
case GL_BGR:
return 3;
case GL_422_EXT:
case GL_422_REV_EXT:
case GL_422_AVERAGE_EXT:
case GL_422_REV_AVERAGE_EXT:
case GL_YCBCR_422_APPLE:
case GL_LUMINANCE_ALPHA:
return 2;
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
return 4;
case GL_COLOR_INDEX:
case GL_STENCIL_INDEX:
case GL_DEPTH_COMPONENT:
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_INTENSITY:
return 1;
default:
return 0;
}
}
/*
** Return the number of bytes per element, based on the element type (other
** than GL_BITMAP).
*/
GLint __glBytesPerElement(GLenum type)
GLint
__glBytesPerElement(GLenum type)
{
switch(type) {
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_SHORT_8_8_APPLE:
case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
case GL_UNSIGNED_SHORT_15_1_MESA:
case GL_UNSIGNED_SHORT_1_15_REV_MESA:
return 2;
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
return 1;
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_24_8_NV:
case GL_UNSIGNED_INT_24_8_MESA:
case GL_UNSIGNED_INT_8_24_REV_MESA:
return 4;
default:
return 0;
}
switch (type) {
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_SHORT_8_8_APPLE:
case GL_UNSIGNED_SHORT_8_8_REV_APPLE:
case GL_UNSIGNED_SHORT_15_1_MESA:
case GL_UNSIGNED_SHORT_1_15_REV_MESA:
return 2;
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
return 1;
case GL_INT:
case GL_UNSIGNED_INT:
case GL_FLOAT:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
case GL_UNSIGNED_INT_24_8_NV:
case GL_UNSIGNED_INT_24_8_MESA:
case GL_UNSIGNED_INT_8_24_REV_MESA:
return 4;
default:
return 0;
}
}
/*
** Compute memory required for internal packed array of data of given type
** and format.
*/
GLint __glImageSize(GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, GLenum target)
GLint
__glImageSize(GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, GLenum target)
{
int bytes_per_row;
int components;
int bytes_per_row;
int components;
switch( target ) {
case GL_PROXY_TEXTURE_1D:
case GL_PROXY_TEXTURE_2D:
case GL_PROXY_TEXTURE_3D:
case GL_PROXY_TEXTURE_4D_SGIS:
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_PROXY_TEXTURE_RECTANGLE_ARB:
case GL_PROXY_HISTOGRAM:
case GL_PROXY_COLOR_TABLE:
case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
return 0;
}
switch (target) {
case GL_PROXY_TEXTURE_1D:
case GL_PROXY_TEXTURE_2D:
case GL_PROXY_TEXTURE_3D:
case GL_PROXY_TEXTURE_4D_SGIS:
case GL_PROXY_TEXTURE_CUBE_MAP:
case GL_PROXY_TEXTURE_RECTANGLE_ARB:
case GL_PROXY_HISTOGRAM:
case GL_PROXY_COLOR_TABLE:
case GL_PROXY_TEXTURE_COLOR_TABLE_SGI:
case GL_PROXY_POST_CONVOLUTION_COLOR_TABLE:
case GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE:
case GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP:
return 0;
}
if (width < 0 || height < 0 || depth < 0) {
return 0;
}
if (width < 0 || height < 0 || depth < 0) {
return 0;
}
/*
/*
** Zero is returned if either format or type are invalid.
*/
components = __glElementsPerGroup(format,type);
if (type == GL_BITMAP) {
if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
bytes_per_row = (width + 7) >> 3;
} else {
return 0;
}
} else {
bytes_per_row = __glBytesPerElement(type) * width;
}
components = __glElementsPerGroup(format, type);
if (type == GL_BITMAP) {
if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
bytes_per_row = (width + 7) >> 3;
}
else {
return 0;
}
}
else {
bytes_per_row = __glBytesPerElement(type) * width;
}
return bytes_per_row * height * depth * components;
return bytes_per_row * height * depth * components;
}
+48 -45
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright © 2008 Red Hat, Inc.
*
@@ -101,8 +102,8 @@ Bool DRI2QueryVersion(Display *dpy, int *major, int *minor)
return True;
}
Bool DRI2Connect(Display *dpy, int screen,
char **driverName, char **busId, unsigned int *sareaHandle)
Bool DRI2Connect(Display *dpy, XID window,
char **driverName, char **deviceName)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2ConnectReply rep;
@@ -114,14 +115,15 @@ Bool DRI2Connect(Display *dpy, int screen,
GetReq(DRI2Connect, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2Connect;
req->screen = screen;
req->window = window;
req->driverType = DRI2DriverDRI;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
if (rep.driverNameLength == 0 && rep.busIdLength == 0) {
if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
UnlockDisplay(dpy);
SyncHandle();
return False;
@@ -131,7 +133,7 @@ Bool DRI2Connect(Display *dpy, int screen,
if (*driverName == NULL) {
_XEatData(dpy,
((rep.driverNameLength + 3) & ~3) +
((rep.busIdLength + 3) & ~3));
((rep.deviceNameLength + 3) & ~3));
UnlockDisplay(dpy);
SyncHandle();
return False;
@@ -139,16 +141,16 @@ Bool DRI2Connect(Display *dpy, int screen,
_XReadPad(dpy, *driverName, rep.driverNameLength);
(*driverName)[rep.driverNameLength] = '\0';
*busId = Xmalloc(rep.busIdLength + 1);
if (*busId == NULL) {
*deviceName = Xmalloc(rep.deviceNameLength + 1);
if (*deviceName == NULL) {
Xfree(*driverName);
_XEatData(dpy, ((rep.busIdLength + 3) & ~3));
_XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
UnlockDisplay(dpy);
SyncHandle();
return False;
}
_XReadPad(dpy, *busId, rep.busIdLength);
(*busId)[rep.busIdLength] = '\0';
_XReadPad(dpy, *deviceName, rep.deviceNameLength);
(*deviceName)[rep.deviceNameLength] = '\0';
UnlockDisplay(dpy);
SyncHandle();
@@ -156,26 +158,27 @@ Bool DRI2Connect(Display *dpy, int screen,
return True;
}
Bool DRI2AuthConnection(Display *dpy, int screen, drm_magic_t magic)
Bool DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2AuthConnectionReq *req;
xDRI2AuthConnectionReply rep;
xDRI2AuthenticateReq *req;
xDRI2AuthenticateReply rep;
XextCheckExtension (dpy, info, dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2AuthConnection, req);
GetReq(DRI2Authenticate, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2AuthConnection;
req->screen = screen;
req->dri2ReqType = X_DRI2Authenticate;
req->window = window;
req->magic = magic;
rep.authenticated = 0;
if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
UnlockDisplay(dpy);
SyncHandle();
return False;
}
UnlockDisplay(dpy);
SyncHandle();
@@ -198,6 +201,24 @@ void DRI2CreateDrawable(Display *dpy, XID drawable)
SyncHandle();
}
void DRI2DestroyDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2DestroyDrawableReq *req;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
XSync(dpy, False);
LockDisplay(dpy);
GetReq(DRI2DestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2DestroyDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
}
DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
@@ -256,45 +277,27 @@ DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
return buffers;
}
void DRI2SwapBuffers(Display *dpy, XID drawable,
int x, int y, int width, int height)
void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2SwapBuffersReq *req;
xDRI2SwapBuffersReply rep;
xDRI2CopyRegionReq *req;
xDRI2CopyRegionReply rep;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
LockDisplay(dpy);
GetReq(DRI2SwapBuffers, req);
GetReq(DRI2CopyRegion, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2SwapBuffers;
req->dri2ReqType = X_DRI2CopyRegion;
req->drawable = drawable;
req->x = x;
req->y = y;
req->width = width;
req->height = height;
req->region = region;
req->dest = dest;
req->src = src;
req->bitmask = 0;
_XReply(dpy, (xReply *)&rep, 0, xFalse);
UnlockDisplay(dpy);
SyncHandle();
}
void DRI2DestroyDrawable(Display *dpy, XID drawable)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2DestroyDrawableReq *req;
XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
XSync(dpy, False);
LockDisplay(dpy);
GetReq(DRI2DestroyDrawable, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2DestroyDrawable;
req->drawable = drawable;
UnlockDisplay(dpy);
SyncHandle();
}
+10 -5
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright © 2007,2008 Red Hat, Inc.
*
@@ -33,6 +34,9 @@
#ifndef _DRI2_H_
#define _DRI2_H_
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/dri2tokens.h>
typedef struct {
unsigned int attachment;
unsigned int name;
@@ -46,10 +50,10 @@ DRI2QueryExtension(Display *display, int *eventBase, int *errorBase);
extern Bool
DRI2QueryVersion(Display *display, int *major, int *minor);
extern Bool
DRI2Connect(Display *display, int screen,
char **driverName, char **busId, unsigned int *sareaHandle);
DRI2Connect(Display *display, XID window,
char **driverName, char **deviceName);
extern Bool
DRI2AuthConnection(Display *display, int screen, drm_magic_t magic);
DRI2Authenticate(Display *display, XID window, drm_magic_t magic);
extern void
DRI2CreateDrawable(Display *display, XID drawable);
extern void
@@ -59,8 +63,9 @@ DRI2GetBuffers(Display *dpy, XID drawable,
int *width, int *height,
unsigned int *attachments, int count,
int *outCount);
extern void
DRI2SwapBuffers(Display *dpy, XID drawable,
int x, int y, int width, int height);
DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
CARD32 dest, CARD32 src);
#endif
+30 -13
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright © 2008 Red Hat, Inc.
*
@@ -38,8 +39,9 @@
#include "glxclient.h"
#include "glcontextmodes.h"
#include "xf86dri.h"
#include "sarea.h"
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "xf86drm.h"
@@ -182,19 +184,35 @@ static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
return &pdraw->base;
}
static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
int x, int y, int width, int height)
{
XRectangle xrect;
XserverRegion region;
xrect.x = x;
xrect.y = y;
xrect.width = width;
xrect.height = height;
region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
DRI2BufferFrontLeft, DRI2BufferBackLeft);
XFixesDestroyRegion(pdraw->psc->dpy, region);
}
static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
{
__GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
DRI2SwapBuffers(pdraw->psc->dpy, pdraw->drawable,
0, 0, priv->width, priv->height);
dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
}
static void dri2DestroyScreen(__GLXscreenConfigs *psc)
{
/* Free the direct rendering per screen data */
(*psc->core->destroyScreen)(psc->__driScreen);
drmClose(psc->fd);
close(psc->fd);
psc->__driScreen = NULL;
}
@@ -248,8 +266,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
__GLXDRIscreen *psp;
unsigned int sareaHandle;
char *driverName, *busID;
char *driverName, *deviceName;
drm_magic_t magic;
int i;
@@ -260,7 +277,8 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
if (!DRI2Connect(psc->dpy, screen, &driverName, &busID, &sareaHandle))
if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
&driverName, &deviceName))
return NULL;
psc->driver = driOpenDriver(driverName);
@@ -285,7 +303,7 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
goto handle_error;
}
psc->fd = drmOpen(NULL, busID);
psc->fd = open(deviceName, O_RDWR);
if (psc->fd < 0) {
ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
return NULL;
@@ -294,10 +312,8 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
if (drmGetMagic(psc->fd, &magic))
return NULL;
if (!DRI2AuthConnection(psc->dpy, screen, magic)) {
ErrorMessageF("failed to authenticate drm access\n");
if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic))
return NULL;
}
psc->__driScreen =
psc->dri2->createNewScreen(screen, psc->fd,
@@ -316,15 +332,16 @@ static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
psp->createContext = dri2CreateContext;
psp->createDrawable = dri2CreateDrawable;
psp->swapBuffers = dri2SwapBuffers;
psp->copySubBuffer = dri2CopySubBuffer;
Xfree(driverName);
Xfree(busID);
Xfree(deviceName);
return psp;
handle_error:
Xfree(driverName);
Xfree(busID);
Xfree(deviceName);
/* FIXME: clean up here */
+2 -1
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright © 2008 Red Hat, Inc.
@@ -339,7 +340,7 @@ driBindExtensions(__GLXscreenConfigs *psc, int dri2)
for (i = 0; extensions[i]; i++) {
#ifdef __DRI_COPY_SUB_BUFFER
if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
psc->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
__glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer_bit");
}
#endif
+10 -8
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright © 2008 Red Hat, Inc.
@@ -36,16 +37,17 @@
#ifndef _DRI_COMMON_H
#define _DRI_COMMON_H
typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
typedef struct __GLXDRIconfigPrivateRec __GLXDRIconfigPrivate;
struct __GLXDRIconfigPrivateRec {
__GLcontextModes modes;
const __DRIconfig *driConfig;
struct __GLXDRIconfigPrivateRec
{
__GLcontextModes modes;
const __DRIconfig *driConfig;
};
extern __GLcontextModes *
driConvertConfigs(const __DRIcoreExtension *core,
__GLcontextModes *modes, const __DRIconfig **configs);
extern __GLcontextModes *driConvertConfigs(const __DRIcoreExtension * core,
__GLcontextModes * modes,
const __DRIconfig ** configs);
extern const __DRIsystemTimeExtension systemTimeExtension;
@@ -55,6 +57,6 @@ extern void ErrorMessageF(const char *f, ...);
extern void *driOpenDriver(const char *driverName);
extern void driBindExtensions(__GLXscreenConfigs *psc, int dri2);
extern void driBindExtensions(__GLXscreenConfigs * psc, int dri2);
#endif /* _DRI_COMMON_H */
+10
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
@@ -574,6 +575,13 @@ static void driSwapBuffers(__GLXDRIdrawable *pdraw)
(*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
}
static void driCopySubBuffer(__GLXDRIdrawable *pdraw,
int x, int y, int width, int height)
{
(*pdraw->psc->driCopySubBuffer->copySubBuffer)(pdraw->driDrawable,
x, y, width, height);
}
static void driDestroyScreen(__GLXscreenConfigs *psc)
{
/* Free the direct rendering per screen data */
@@ -641,6 +649,8 @@ static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
}
driBindExtensions(psc, 0);
if (psc->driCopySubBuffer)
psp->copySubBuffer = driCopySubBuffer;
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
+275 -270
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright 2008 George Sapountzis
*
@@ -33,395 +34,398 @@ typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
struct __GLXDRIdisplayPrivateRec {
__GLXDRIdisplay base;
struct __GLXDRIdisplayPrivateRec
{
__GLXDRIdisplay base;
};
struct __GLXDRIcontextPrivateRec {
__GLXDRIcontext base;
__DRIcontext *driContext;
__GLXscreenConfigs *psc;
struct __GLXDRIcontextPrivateRec
{
__GLXDRIcontext base;
__DRIcontext *driContext;
__GLXscreenConfigs *psc;
};
struct __GLXDRIdrawablePrivateRec {
__GLXDRIdrawable base;
struct __GLXDRIdrawablePrivateRec
{
__GLXDRIdrawable base;
GC gc;
GC swapgc;
GC gc;
GC swapgc;
XVisualInfo *visinfo;
XImage *ximage;
int bpp;
XVisualInfo *visinfo;
XImage *ximage;
int bpp;
};
/**
* swrast loader functions
*/
static Bool XCreateDrawable(__GLXDRIdrawablePrivate *pdp,
Display *dpy, XID drawable, int visualid)
static Bool
XCreateDrawable(__GLXDRIdrawablePrivate * pdp,
Display * dpy, XID drawable, int visualid)
{
XGCValues gcvalues;
long visMask;
XVisualInfo visTemp;
int num_visuals;
XGCValues gcvalues;
long visMask;
XVisualInfo visTemp;
int num_visuals;
/* create GC's */
pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
pdp->swapgc = XCreateGC(dpy, drawable, 0, NULL);
/* create GC's */
pdp->gc = XCreateGC(dpy, drawable, 0, NULL);
pdp->swapgc = XCreateGC(dpy, drawable, 0, NULL);
gcvalues.function = GXcopy;
gcvalues.graphics_exposures = False;
XChangeGC(dpy, pdp->gc, GCFunction, &gcvalues);
XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues);
XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues);
gcvalues.function = GXcopy;
gcvalues.graphics_exposures = False;
XChangeGC(dpy, pdp->gc, GCFunction, &gcvalues);
XChangeGC(dpy, pdp->swapgc, GCFunction, &gcvalues);
XChangeGC(dpy, pdp->swapgc, GCGraphicsExposures, &gcvalues);
/* create XImage */
visTemp.screen = DefaultScreen(dpy);
visTemp.visualid = visualid;
visMask = (VisualScreenMask | VisualIDMask);
pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
/* create XImage */
visTemp.screen = DefaultScreen(dpy);
visTemp.visualid = visualid;
visMask = (VisualScreenMask | VisualIDMask);
pdp->visinfo = XGetVisualInfo(dpy, visMask, &visTemp, &num_visuals);
pdp->ximage = XCreateImage(dpy,
pdp->visinfo->visual,
pdp->visinfo->depth,
ZPixmap, 0, /* format, offset */
NULL, /* data */
0, 0, /* size */
32, /* bitmap_pad */
0); /* bytes_per_line */
pdp->ximage = XCreateImage(dpy, pdp->visinfo->visual, pdp->visinfo->depth, ZPixmap, 0, /* format, offset */
NULL, /* data */
0, 0, /* size */
32, /* bitmap_pad */
0); /* bytes_per_line */
/* get the true number of bits per pixel */
pdp->bpp = pdp->ximage->bits_per_pixel;
/* get the true number of bits per pixel */
pdp->bpp = pdp->ximage->bits_per_pixel;
return True;
}
static void XDestroyDrawable(__GLXDRIdrawablePrivate *pdp,
Display *dpy, XID drawable)
{
XDestroyImage(pdp->ximage);
XFree(pdp->visinfo);
XFreeGC(dpy, pdp->gc);
XFreeGC(dpy, pdp->swapgc);
return True;
}
static void
swrastGetDrawableInfo(__DRIdrawable *draw,
int *x, int *y, int *w, int *h,
void *loaderPrivate)
XDestroyDrawable(__GLXDRIdrawablePrivate * pdp, Display * dpy, XID drawable)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XDestroyImage(pdp->ximage);
XFree(pdp->visinfo);
Window root;
Status stat;
unsigned int bw, depth;
XFreeGC(dpy, pdp->gc);
XFreeGC(dpy, pdp->swapgc);
}
drawable = pdraw->xDrawable;
static void
swrastGetDrawableInfo(__DRIdrawable * draw,
int *x, int *y, int *w, int *h, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
stat = XGetGeometry(dpy, drawable, &root,
x, y, (unsigned int *)w, (unsigned int *)h,
&bw, &depth);
Window root;
Status stat;
unsigned int bw, depth;
drawable = pdraw->xDrawable;
stat = XGetGeometry(dpy, drawable, &root,
x, y, (unsigned int *) w, (unsigned int *) h,
&bw, &depth);
}
static inline int
bytes_per_line(int w, int bpp, unsigned mul)
{
unsigned mask = mul - 1;
unsigned mask = mul - 1;
return ((w * bpp + mask) & ~mask) / 8;
return ((w * bpp + mask) & ~mask) / 8;
}
static void
swrastPutImage(__DRIdrawable *draw, int op,
int x, int y, int w, int h, char *data,
void *loaderPrivate)
swrastPutImage(__DRIdrawable * draw, int op,
int x, int y, int w, int h, char *data, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
GC gc;
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
GC gc;
switch (op) {
case __DRI_SWRAST_IMAGE_OP_DRAW:
gc = pdp->gc;
break;
case __DRI_SWRAST_IMAGE_OP_SWAP:
gc = pdp->swapgc;
break;
default:
return;
}
switch (op) {
case __DRI_SWRAST_IMAGE_OP_DRAW:
gc = pdp->gc;
break;
case __DRI_SWRAST_IMAGE_OP_SWAP:
gc = pdp->swapgc;
break;
default:
return;
}
drawable = pdraw->xDrawable;
drawable = pdraw->xDrawable;
ximage = pdp->ximage;
ximage->data = data;
ximage->width = w;
ximage->height = h;
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
ximage = pdp->ximage;
ximage->data = data;
ximage->width = w;
ximage->height = h;
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
XPutImage(dpy, drawable, gc, ximage, 0, 0, x, y, w, h);
ximage->data = NULL;
ximage->data = NULL;
}
static void
swrastGetImage(__DRIdrawable *draw,
int x, int y, int w, int h, char *data,
void *loaderPrivate)
swrastGetImage(__DRIdrawable * draw,
int x, int y, int w, int h, char *data, void *loaderPrivate)
{
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
__GLXDRIdrawablePrivate *pdp = loaderPrivate;
__GLXDRIdrawable *pdraw = &(pdp->base);;
Display *dpy = pdraw->psc->dpy;
Drawable drawable;
XImage *ximage;
drawable = pdraw->xDrawable;
drawable = pdraw->xDrawable;
ximage = pdp->ximage;
ximage->data = data;
ximage->width = w;
ximage->height = h;
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
ximage = pdp->ximage;
ximage->data = data;
ximage->width = w;
ximage->height = h;
ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);
XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);
ximage->data = NULL;
ximage->data = NULL;
}
static const __DRIswrastLoaderExtension swrastLoaderExtension = {
{ __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
swrastGetDrawableInfo,
swrastPutImage,
swrastGetImage
{__DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION},
swrastGetDrawableInfo,
swrastPutImage,
swrastGetImage
};
static const __DRIextension *loader_extensions[] = {
&systemTimeExtension.base,
&swrastLoaderExtension.base,
NULL
&systemTimeExtension.base,
&swrastLoaderExtension.base,
NULL
};
/**
* GLXDRI functions
*/
static void driDestroyContext(__GLXDRIcontext *context,
__GLXscreenConfigs *psc, Display *dpy)
static void
driDestroyContext(__GLXDRIcontext * context,
__GLXscreenConfigs * psc, Display * dpy)
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
(*core->destroyContext)(pcp->driContext);
(*core->destroyContext) (pcp->driContext);
Xfree(pcp);
Xfree(pcp);
}
static Bool driBindContext(__GLXDRIcontext *context,
__GLXDRIdrawable *draw, __GLXDRIdrawable *read)
static Bool
driBindContext(__GLXDRIcontext * context,
__GLXDRIdrawable * draw, __GLXDRIdrawable * read)
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
return (*core->bindContext)(pcp->driContext,
draw->driDrawable,
read->driDrawable);
return (*core->bindContext) (pcp->driContext,
draw->driDrawable, read->driDrawable);
}
static void driUnbindContext(__GLXDRIcontext *context)
static void
driUnbindContext(__GLXDRIcontext * context)
{
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
__GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
const __DRIcoreExtension *core = pcp->psc->core;
(*core->unbindContext)(pcp->driContext);
(*core->unbindContext) (pcp->driContext);
}
static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
const __GLcontextModes *mode,
GLXContext gc,
GLXContext shareList, int renderType)
static __GLXDRIcontext *
driCreateContext(__GLXscreenConfigs * psc,
const __GLcontextModes * mode,
GLXContext gc, GLXContext shareList, int renderType)
{
__GLXDRIcontextPrivate *pcp, *pcp_shared;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
const __DRIcoreExtension *core = psc->core;
__DRIcontext *shared = NULL;
__GLXDRIcontextPrivate *pcp, *pcp_shared;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
const __DRIcoreExtension *core = psc->core;
__DRIcontext *shared = NULL;
if (!psc || !psc->driScreen)
return NULL;
if (!psc || !psc->driScreen)
return NULL;
if (shareList) {
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
shared = pcp_shared->driContext;
}
if (shareList) {
pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
shared = pcp_shared->driContext;
}
pcp = Xmalloc(sizeof *pcp);
if (pcp == NULL)
return NULL;
pcp = Xmalloc(sizeof *pcp);
if (pcp == NULL)
return NULL;
pcp->psc = psc;
pcp->driContext =
(*core->createNewContext)(psc->__driScreen,
config->driConfig, shared, pcp);
if (pcp->driContext == NULL) {
Xfree(pcp);
return NULL;
}
pcp->psc = psc;
pcp->driContext =
(*core->createNewContext) (psc->__driScreen,
config->driConfig, shared, pcp);
if (pcp->driContext == NULL) {
Xfree(pcp);
return NULL;
}
pcp->base.destroyContext = driDestroyContext;
pcp->base.bindContext = driBindContext;
pcp->base.unbindContext = driUnbindContext;
pcp->base.destroyContext = driDestroyContext;
pcp->base.bindContext = driBindContext;
pcp->base.unbindContext = driUnbindContext;
return &pcp->base;
return &pcp->base;
}
static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
static void
driDestroyDrawable(__GLXDRIdrawable * pdraw)
{
__GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
const __DRIcoreExtension *core = pdraw->psc->core;
__GLXDRIdrawablePrivate *pdp = (__GLXDRIdrawablePrivate *) pdraw;
const __DRIcoreExtension *core = pdraw->psc->core;
(*core->destroyDrawable)(pdraw->driDrawable);
(*core->destroyDrawable) (pdraw->driDrawable);
XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
Xfree(pdp);
XDestroyDrawable(pdp, pdraw->psc->dpy, pdraw->drawable);
Xfree(pdp);
}
static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
XID xDrawable,
GLXDrawable drawable,
const __GLcontextModes *modes)
static __GLXDRIdrawable *
driCreateDrawable(__GLXscreenConfigs * psc,
XID xDrawable,
GLXDrawable drawable, const __GLcontextModes * modes)
{
__GLXDRIdrawable *pdraw;
__GLXDRIdrawablePrivate *pdp;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
const __DRIswrastExtension *swrast = psc->swrast;
__GLXDRIdrawable *pdraw;
__GLXDRIdrawablePrivate *pdp;
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
const __DRIswrastExtension *swrast = psc->swrast;
/* Old dri can't handle GLX 1.3+ drawable constructors. */
if (xDrawable != drawable)
return NULL;
/* Old dri can't handle GLX 1.3+ drawable constructors. */
if (xDrawable != drawable)
return NULL;
pdp = Xmalloc(sizeof(*pdp));
if (!pdp)
return NULL;
pdp = Xmalloc(sizeof(*pdp));
if (!pdp)
return NULL;
pdraw = &(pdp->base);
pdraw->xDrawable = xDrawable;
pdraw->drawable = drawable;
pdraw->psc = psc;
pdraw = &(pdp->base);
pdraw->xDrawable = xDrawable;
pdraw->drawable = drawable;
pdraw->psc = psc;
XCreateDrawable(pdp, psc->dpy, xDrawable, modes->visualID);
XCreateDrawable(pdp, psc->dpy, xDrawable, modes->visualID);
/* Create a new drawable */
pdraw->driDrawable =
(*swrast->createNewDrawable)(psc->__driScreen,
config->driConfig,
pdp);
/* Create a new drawable */
pdraw->driDrawable =
(*swrast->createNewDrawable) (psc->__driScreen, config->driConfig, pdp);
if (!pdraw->driDrawable) {
XDestroyDrawable(pdp, psc->dpy, xDrawable);
Xfree(pdp);
return NULL;
}
if (!pdraw->driDrawable) {
XDestroyDrawable(pdp, psc->dpy, xDrawable);
Xfree(pdp);
return NULL;
}
pdraw->destroyDrawable = driDestroyDrawable;
pdraw->destroyDrawable = driDestroyDrawable;
return pdraw;
return pdraw;
}
static void driSwapBuffers(__GLXDRIdrawable *pdraw)
static void
driSwapBuffers(__GLXDRIdrawable * pdraw)
{
(*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
(*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
}
static void driDestroyScreen(__GLXscreenConfigs *psc)
static void
driDestroyScreen(__GLXscreenConfigs * psc)
{
/* Free the direct rendering per screen data */
(*psc->core->destroyScreen)(psc->__driScreen);
psc->__driScreen = NULL;
if (psc->driver)
dlclose(psc->driver);
/* Free the direct rendering per screen data */
(*psc->core->destroyScreen) (psc->__driScreen);
psc->__driScreen = NULL;
if (psc->driver)
dlclose(psc->driver);
}
static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
__GLXdisplayPrivate *priv)
static __GLXDRIscreen *
driCreateScreen(__GLXscreenConfigs * psc, int screen,
__GLXdisplayPrivate * priv)
{
__GLXDRIscreen *psp;
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
const char *driverName = "swrast";
int i;
__GLXDRIscreen *psp;
const __DRIconfig **driver_configs;
const __DRIextension **extensions;
const char *driverName = "swrast";
int i;
psp = Xmalloc(sizeof *psp);
if (psp == NULL)
return NULL;
psp = Xmalloc(sizeof *psp);
if (psp == NULL)
return NULL;
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
/* Initialize per screen dynamic client GLX extensions */
psc->ext_list_first_time = GL_TRUE;
psc->driver = driOpenDriver(driverName);
if (psc->driver == NULL)
goto handle_error;
psc->driver = driOpenDriver(driverName);
if (psc->driver == NULL)
goto handle_error;
extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
goto handle_error;
}
extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
if (extensions == NULL) {
ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
goto handle_error;
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
psc->core = (__DRIcoreExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
psc->swrast = (__DRIswrastExtension *) extensions[i];
}
for (i = 0; extensions[i]; i++) {
if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
psc->core = (__DRIcoreExtension *) extensions[i];
if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0)
psc->swrast = (__DRIswrastExtension *) extensions[i];
}
if (psc->core == NULL || psc->swrast == NULL) {
ErrorMessageF("core dri extension not found\n");
goto handle_error;
}
if (psc->core == NULL || psc->swrast == NULL) {
ErrorMessageF("core dri extension not found\n");
goto handle_error;
}
psc->__driScreen =
psc->swrast->createNewScreen(screen,
loader_extensions, &driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
goto handle_error;
}
psc->__driScreen =
psc->swrast->createNewScreen(screen,
loader_extensions, &driver_configs, psc);
if (psc->__driScreen == NULL) {
ErrorMessageF("failed to create dri screen\n");
goto handle_error;
}
driBindExtensions(psc, 0);
driBindExtensions(psc, 0);
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
psp->swapBuffers = driSwapBuffers;
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
psp->createDrawable = driCreateDrawable;
psp->swapBuffers = driSwapBuffers;
return psp;
return psp;
handle_error:
Xfree(psp);
Xfree(psp);
if (psc->driver)
dlclose(psc->driver);
if (psc->driver)
dlclose(psc->driver);
ErrorMessageF("reverting to indirect rendering\n");
ErrorMessageF("reverting to indirect rendering\n");
return NULL;
return NULL;
}
/* Called from __glXFreeDisplayPrivate.
*/
static void driDestroyDisplay(__GLXDRIdisplay *dpy)
static void
driDestroyDisplay(__GLXDRIdisplay * dpy)
{
Xfree(dpy);
Xfree(dpy);
}
/*
@@ -429,18 +433,19 @@ static void driDestroyDisplay(__GLXDRIdisplay *dpy)
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
_X_HIDDEN __GLXDRIdisplay *driswCreateDisplay(Display *dpy)
_X_HIDDEN __GLXDRIdisplay *
driswCreateDisplay(Display * dpy)
{
__GLXDRIdisplayPrivate *pdpyp;
__GLXDRIdisplayPrivate *pdpyp;
pdpyp = Xmalloc(sizeof *pdpyp);
if (pdpyp == NULL)
return NULL;
pdpyp = Xmalloc(sizeof *pdpyp);
if (pdpyp == NULL)
return NULL;
pdpyp->base.destroyDisplay = driDestroyDisplay;
pdpyp->base.createScreen = driCreateScreen;
pdpyp->base.destroyDisplay = driDestroyDisplay;
pdpyp->base.createScreen = driCreateScreen;
return &pdpyp->base;
return &pdpyp->base;
}
#endif /* GLX_DIRECT_RENDERING */
+75 -68
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -36,91 +37,97 @@
** the information that the GL needs.
*/
void __glFillMap1f(GLint k, GLint order, GLint stride,
const GLfloat *points, GLubyte *pc)
void
__glFillMap1f(GLint k, GLint order, GLint stride,
const GLfloat * points, GLubyte * pc)
{
if (stride == k) {
/* Just copy the data */
__GLX_PUT_FLOAT_ARRAY(0, points, order * k);
} else {
GLint i;
if (stride == k) {
/* Just copy the data */
__GLX_PUT_FLOAT_ARRAY(0, points, order * k);
}
else {
GLint i;
for (i = 0; i < order; i++) {
__GLX_PUT_FLOAT_ARRAY(0, points, k);
points += stride;
pc += k * __GLX_SIZE_FLOAT32;
}
}
for (i = 0; i < order; i++) {
__GLX_PUT_FLOAT_ARRAY(0, points, k);
points += stride;
pc += k * __GLX_SIZE_FLOAT32;
}
}
}
void __glFillMap1d(GLint k, GLint order, GLint stride,
const GLdouble *points, GLubyte *pc)
void
__glFillMap1d(GLint k, GLint order, GLint stride,
const GLdouble * points, GLubyte * pc)
{
if (stride == k) {
/* Just copy the data */
__GLX_PUT_DOUBLE_ARRAY(0, points, order * k);
} else {
GLint i;
for (i = 0; i < order; i++) {
__GLX_PUT_DOUBLE_ARRAY(0, points, k);
points += stride;
pc += k * __GLX_SIZE_FLOAT64;
}
}
if (stride == k) {
/* Just copy the data */
__GLX_PUT_DOUBLE_ARRAY(0, points, order * k);
}
else {
GLint i;
for (i = 0; i < order; i++) {
__GLX_PUT_DOUBLE_ARRAY(0, points, k);
points += stride;
pc += k * __GLX_SIZE_FLOAT64;
}
}
}
void __glFillMap2f(GLint k, GLint majorOrder, GLint minorOrder,
GLint majorStride, GLint minorStride,
const GLfloat *points, GLfloat *data)
void
__glFillMap2f(GLint k, GLint majorOrder, GLint minorOrder,
GLint majorStride, GLint minorStride,
const GLfloat * points, GLfloat * data)
{
GLint i, j, x;
GLint i, j, x;
if ((minorStride == k) && (majorStride == minorOrder*k)) {
/* Just copy the data */
__GLX_MEM_COPY(data, points, majorOrder * majorStride *
__GLX_SIZE_FLOAT32);
return;
}
for (i = 0; i < majorOrder; i++) {
for (j = 0; j < minorOrder; j++) {
for (x = 0; x < k; x++) {
data[x] = points[x];
}
points += minorStride;
data += k;
}
points += majorStride - minorStride * minorOrder;
}
if ((minorStride == k) && (majorStride == minorOrder * k)) {
/* Just copy the data */
__GLX_MEM_COPY(data, points, majorOrder * majorStride *
__GLX_SIZE_FLOAT32);
return;
}
for (i = 0; i < majorOrder; i++) {
for (j = 0; j < minorOrder; j++) {
for (x = 0; x < k; x++) {
data[x] = points[x];
}
points += minorStride;
data += k;
}
points += majorStride - minorStride * minorOrder;
}
}
void __glFillMap2d(GLint k, GLint majorOrder, GLint minorOrder,
GLint majorStride, GLint minorStride,
const GLdouble *points, GLdouble *data)
void
__glFillMap2d(GLint k, GLint majorOrder, GLint minorOrder,
GLint majorStride, GLint minorStride,
const GLdouble * points, GLdouble * data)
{
int i,j,x;
int i, j, x;
if ((minorStride == k) && (majorStride == minorOrder*k)) {
/* Just copy the data */
__GLX_MEM_COPY(data, points, majorOrder * majorStride *
__GLX_SIZE_FLOAT64);
return;
}
if ((minorStride == k) && (majorStride == minorOrder * k)) {
/* Just copy the data */
__GLX_MEM_COPY(data, points, majorOrder * majorStride *
__GLX_SIZE_FLOAT64);
return;
}
#ifdef __GLX_ALIGN64
x = k * __GLX_SIZE_FLOAT64;
x = k * __GLX_SIZE_FLOAT64;
#endif
for (i = 0; i<majorOrder; i++) {
for (j = 0; j<minorOrder; j++) {
for (i = 0; i < majorOrder; i++) {
for (j = 0; j < minorOrder; j++) {
#ifdef __GLX_ALIGN64
__GLX_MEM_COPY(data, points, x);
__GLX_MEM_COPY(data, points, x);
#else
for (x = 0; x<k; x++) {
data[x] = points[x];
}
for (x = 0; x < k; x++) {
data[x] = points[x];
}
#endif
points += minorStride;
data += k;
}
points += majorStride - minorStride * minorOrder;
}
points += minorStride;
data += k;
}
points += majorStride - minorStride * minorOrder;
}
}
+293 -298
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2003
* All Rights Reserved.
@@ -78,16 +79,16 @@
* be returned. Otherwise \c GLX_NONE will be returned.
*/
GLint
_gl_convert_from_x_visual_type( int visualType )
_gl_convert_from_x_visual_type(int visualType)
{
static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
GLX_STATIC_GRAY, GLX_GRAY_SCALE,
GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
GLX_TRUE_COLOR, GLX_DIRECT_COLOR
};
static const int glx_visual_types[NUM_VISUAL_TYPES] = {
GLX_STATIC_GRAY, GLX_GRAY_SCALE,
GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
GLX_TRUE_COLOR, GLX_DIRECT_COLOR
};
return ( (unsigned) visualType < NUM_VISUAL_TYPES )
? glx_visual_types[ visualType ] : GLX_NONE;
return ((unsigned) visualType < NUM_VISUAL_TYPES)
? glx_visual_types[visualType] : GLX_NONE;
}
@@ -100,16 +101,16 @@ _gl_convert_from_x_visual_type( int visualType )
* be returned. Otherwise -1 will be returned.
*/
GLint
_gl_convert_to_x_visual_type( int visualType )
_gl_convert_to_x_visual_type(int visualType)
{
static const int x_visual_types[ NUM_VISUAL_TYPES ] = {
TrueColor, DirectColor,
PseudoColor, StaticColor,
GrayScale, StaticGray
};
static const int x_visual_types[NUM_VISUAL_TYPES] = {
TrueColor, DirectColor,
PseudoColor, StaticColor,
GrayScale, StaticGray
};
return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES )
? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
return ((unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES)
? x_visual_types[visualType - GLX_TRUE_COLOR] : -1;
}
@@ -128,76 +129,76 @@ _gl_convert_to_x_visual_type( int visualType )
* structure will be set to the \c vid of the \c __GLXvisualConfig structure.
*/
void
_gl_copy_visual_to_context_mode( __GLcontextModes * mode,
const __GLXvisualConfig * config )
_gl_copy_visual_to_context_mode(__GLcontextModes * mode,
const __GLXvisualConfig * config)
{
__GLcontextModes * const next = mode->next;
__GLcontextModes *const next = mode->next;
(void) _mesa_memset( mode, 0, sizeof( __GLcontextModes ) );
mode->next = next;
(void) _mesa_memset(mode, 0, sizeof(__GLcontextModes));
mode->next = next;
mode->visualID = config->vid;
mode->visualType = _gl_convert_from_x_visual_type( config->class );
mode->xRenderable = GL_TRUE;
mode->fbconfigID = config->vid;
mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
mode->visualID = config->vid;
mode->visualType = _gl_convert_from_x_visual_type(config->class);
mode->xRenderable = GL_TRUE;
mode->fbconfigID = config->vid;
mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
mode->rgbMode = (config->rgba != 0);
mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
mode->rgbMode = (config->rgba != 0);
mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
mode->colorIndexMode = !(mode->rgbMode);
mode->doubleBufferMode = (config->doubleBuffer != 0);
mode->stereoMode = (config->stereo != 0);
mode->colorIndexMode = !(mode->rgbMode);
mode->doubleBufferMode = (config->doubleBuffer != 0);
mode->stereoMode = (config->stereo != 0);
mode->haveAccumBuffer = ((config->accumRedSize +
config->accumGreenSize +
config->accumBlueSize +
config->accumAlphaSize) > 0);
mode->haveDepthBuffer = (config->depthSize > 0);
mode->haveStencilBuffer = (config->stencilSize > 0);
mode->haveAccumBuffer = ((config->accumRedSize +
config->accumGreenSize +
config->accumBlueSize +
config->accumAlphaSize) > 0);
mode->haveDepthBuffer = (config->depthSize > 0);
mode->haveStencilBuffer = (config->stencilSize > 0);
mode->redBits = config->redSize;
mode->greenBits = config->greenSize;
mode->blueBits = config->blueSize;
mode->alphaBits = config->alphaSize;
mode->redMask = config->redMask;
mode->greenMask = config->greenMask;
mode->blueMask = config->blueMask;
mode->alphaMask = config->alphaMask;
mode->rgbBits = mode->rgbMode ? config->bufferSize : 0;
mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0;
mode->redBits = config->redSize;
mode->greenBits = config->greenSize;
mode->blueBits = config->blueSize;
mode->alphaBits = config->alphaSize;
mode->redMask = config->redMask;
mode->greenMask = config->greenMask;
mode->blueMask = config->blueMask;
mode->alphaMask = config->alphaMask;
mode->rgbBits = mode->rgbMode ? config->bufferSize : 0;
mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0;
mode->accumRedBits = config->accumRedSize;
mode->accumGreenBits = config->accumGreenSize;
mode->accumBlueBits = config->accumBlueSize;
mode->accumAlphaBits = config->accumAlphaSize;
mode->depthBits = config->depthSize;
mode->stencilBits = config->stencilSize;
mode->accumRedBits = config->accumRedSize;
mode->accumGreenBits = config->accumGreenSize;
mode->accumBlueBits = config->accumBlueSize;
mode->accumAlphaBits = config->accumAlphaSize;
mode->depthBits = config->depthSize;
mode->stencilBits = config->stencilSize;
mode->numAuxBuffers = config->auxBuffers;
mode->level = config->level;
mode->numAuxBuffers = config->auxBuffers;
mode->level = config->level;
mode->visualRating = config->visualRating;
mode->transparentPixel = config->transparentPixel;
mode->transparentRed = config->transparentRed;
mode->transparentGreen = config->transparentGreen;
mode->transparentBlue = config->transparentBlue;
mode->transparentAlpha = config->transparentAlpha;
mode->transparentIndex = config->transparentIndex;
mode->samples = config->multiSampleSize;
mode->sampleBuffers = config->nMultiSampleBuffers;
/* mode->visualSelectGroup = config->visualSelectGroup; ? */
mode->visualRating = config->visualRating;
mode->transparentPixel = config->transparentPixel;
mode->transparentRed = config->transparentRed;
mode->transparentGreen = config->transparentGreen;
mode->transparentBlue = config->transparentBlue;
mode->transparentAlpha = config->transparentAlpha;
mode->transparentIndex = config->transparentIndex;
mode->samples = config->multiSampleSize;
mode->sampleBuffers = config->nMultiSampleBuffers;
/* mode->visualSelectGroup = config->visualSelectGroup; ? */
mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE;
mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ?
GL_TRUE : GL_FALSE;
mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE;
mode->bindToTextureTargets = mode->rgbMode ?
GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
GLX_TEXTURE_RECTANGLE_BIT_EXT : 0;
mode->yInverted = GL_FALSE;
mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE;
mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ?
GL_TRUE : GL_FALSE;
mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE;
mode->bindToTextureTargets = mode->rgbMode ?
GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
GLX_TEXTURE_RECTANGLE_BIT_EXT : 0;
mode->yInverted = GL_FALSE;
}
@@ -211,149 +212,149 @@ _gl_copy_visual_to_context_mode( __GLcontextModes * mode,
* returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned.
*/
int
_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
int *value_return)
_gl_get_context_mode_data(const __GLcontextModes * mode, int attribute,
int *value_return)
{
switch (attribute) {
case GLX_USE_GL:
*value_return = GL_TRUE;
return 0;
case GLX_BUFFER_SIZE:
*value_return = mode->rgbBits;
return 0;
case GLX_RGBA:
*value_return = mode->rgbMode;
return 0;
case GLX_RED_SIZE:
*value_return = mode->redBits;
return 0;
case GLX_GREEN_SIZE:
*value_return = mode->greenBits;
return 0;
case GLX_BLUE_SIZE:
*value_return = mode->blueBits;
return 0;
case GLX_ALPHA_SIZE:
*value_return = mode->alphaBits;
return 0;
case GLX_DOUBLEBUFFER:
*value_return = mode->doubleBufferMode;
return 0;
case GLX_STEREO:
*value_return = mode->stereoMode;
return 0;
case GLX_AUX_BUFFERS:
*value_return = mode->numAuxBuffers;
return 0;
case GLX_DEPTH_SIZE:
*value_return = mode->depthBits;
return 0;
case GLX_STENCIL_SIZE:
*value_return = mode->stencilBits;
return 0;
case GLX_ACCUM_RED_SIZE:
*value_return = mode->accumRedBits;
return 0;
case GLX_ACCUM_GREEN_SIZE:
*value_return = mode->accumGreenBits;
return 0;
case GLX_ACCUM_BLUE_SIZE:
*value_return = mode->accumBlueBits;
return 0;
case GLX_ACCUM_ALPHA_SIZE:
*value_return = mode->accumAlphaBits;
return 0;
case GLX_LEVEL:
*value_return = mode->level;
return 0;
case GLX_TRANSPARENT_TYPE_EXT:
*value_return = mode->transparentPixel;
return 0;
case GLX_TRANSPARENT_RED_VALUE:
*value_return = mode->transparentRed;
return 0;
case GLX_TRANSPARENT_GREEN_VALUE:
*value_return = mode->transparentGreen;
return 0;
case GLX_TRANSPARENT_BLUE_VALUE:
*value_return = mode->transparentBlue;
return 0;
case GLX_TRANSPARENT_ALPHA_VALUE:
*value_return = mode->transparentAlpha;
return 0;
case GLX_TRANSPARENT_INDEX_VALUE:
*value_return = mode->transparentIndex;
return 0;
case GLX_X_VISUAL_TYPE:
*value_return = mode->visualType;
return 0;
case GLX_CONFIG_CAVEAT:
*value_return = mode->visualRating;
return 0;
case GLX_VISUAL_ID:
*value_return = mode->visualID;
return 0;
case GLX_DRAWABLE_TYPE:
*value_return = mode->drawableType;
return 0;
case GLX_RENDER_TYPE:
*value_return = mode->renderType;
return 0;
case GLX_X_RENDERABLE:
*value_return = mode->xRenderable;
return 0;
case GLX_FBCONFIG_ID:
*value_return = mode->fbconfigID;
return 0;
case GLX_MAX_PBUFFER_WIDTH:
*value_return = mode->maxPbufferWidth;
return 0;
case GLX_MAX_PBUFFER_HEIGHT:
*value_return = mode->maxPbufferHeight;
return 0;
case GLX_MAX_PBUFFER_PIXELS:
*value_return = mode->maxPbufferPixels;
return 0;
case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
*value_return = mode->optimalPbufferWidth;
return 0;
case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
*value_return = mode->optimalPbufferHeight;
return 0;
case GLX_SWAP_METHOD_OML:
*value_return = mode->swapMethod;
return 0;
case GLX_SAMPLE_BUFFERS_SGIS:
*value_return = mode->sampleBuffers;
return 0;
case GLX_SAMPLES_SGIS:
*value_return = mode->samples;
return 0;
case GLX_BIND_TO_TEXTURE_RGB_EXT:
*value_return = mode->bindToTextureRgb;
return 0;
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
*value_return = mode->bindToTextureRgba;
return 0;
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
*value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
GL_FALSE;
return 0;
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
*value_return = mode->bindToTextureTargets;
return 0;
case GLX_Y_INVERTED_EXT:
*value_return = mode->yInverted;
return 0;
switch (attribute) {
case GLX_USE_GL:
*value_return = GL_TRUE;
return 0;
case GLX_BUFFER_SIZE:
*value_return = mode->rgbBits;
return 0;
case GLX_RGBA:
*value_return = mode->rgbMode;
return 0;
case GLX_RED_SIZE:
*value_return = mode->redBits;
return 0;
case GLX_GREEN_SIZE:
*value_return = mode->greenBits;
return 0;
case GLX_BLUE_SIZE:
*value_return = mode->blueBits;
return 0;
case GLX_ALPHA_SIZE:
*value_return = mode->alphaBits;
return 0;
case GLX_DOUBLEBUFFER:
*value_return = mode->doubleBufferMode;
return 0;
case GLX_STEREO:
*value_return = mode->stereoMode;
return 0;
case GLX_AUX_BUFFERS:
*value_return = mode->numAuxBuffers;
return 0;
case GLX_DEPTH_SIZE:
*value_return = mode->depthBits;
return 0;
case GLX_STENCIL_SIZE:
*value_return = mode->stencilBits;
return 0;
case GLX_ACCUM_RED_SIZE:
*value_return = mode->accumRedBits;
return 0;
case GLX_ACCUM_GREEN_SIZE:
*value_return = mode->accumGreenBits;
return 0;
case GLX_ACCUM_BLUE_SIZE:
*value_return = mode->accumBlueBits;
return 0;
case GLX_ACCUM_ALPHA_SIZE:
*value_return = mode->accumAlphaBits;
return 0;
case GLX_LEVEL:
*value_return = mode->level;
return 0;
case GLX_TRANSPARENT_TYPE_EXT:
*value_return = mode->transparentPixel;
return 0;
case GLX_TRANSPARENT_RED_VALUE:
*value_return = mode->transparentRed;
return 0;
case GLX_TRANSPARENT_GREEN_VALUE:
*value_return = mode->transparentGreen;
return 0;
case GLX_TRANSPARENT_BLUE_VALUE:
*value_return = mode->transparentBlue;
return 0;
case GLX_TRANSPARENT_ALPHA_VALUE:
*value_return = mode->transparentAlpha;
return 0;
case GLX_TRANSPARENT_INDEX_VALUE:
*value_return = mode->transparentIndex;
return 0;
case GLX_X_VISUAL_TYPE:
*value_return = mode->visualType;
return 0;
case GLX_CONFIG_CAVEAT:
*value_return = mode->visualRating;
return 0;
case GLX_VISUAL_ID:
*value_return = mode->visualID;
return 0;
case GLX_DRAWABLE_TYPE:
*value_return = mode->drawableType;
return 0;
case GLX_RENDER_TYPE:
*value_return = mode->renderType;
return 0;
case GLX_X_RENDERABLE:
*value_return = mode->xRenderable;
return 0;
case GLX_FBCONFIG_ID:
*value_return = mode->fbconfigID;
return 0;
case GLX_MAX_PBUFFER_WIDTH:
*value_return = mode->maxPbufferWidth;
return 0;
case GLX_MAX_PBUFFER_HEIGHT:
*value_return = mode->maxPbufferHeight;
return 0;
case GLX_MAX_PBUFFER_PIXELS:
*value_return = mode->maxPbufferPixels;
return 0;
case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
*value_return = mode->optimalPbufferWidth;
return 0;
case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
*value_return = mode->optimalPbufferHeight;
return 0;
case GLX_SWAP_METHOD_OML:
*value_return = mode->swapMethod;
return 0;
case GLX_SAMPLE_BUFFERS_SGIS:
*value_return = mode->sampleBuffers;
return 0;
case GLX_SAMPLES_SGIS:
*value_return = mode->samples;
return 0;
case GLX_BIND_TO_TEXTURE_RGB_EXT:
*value_return = mode->bindToTextureRgb;
return 0;
case GLX_BIND_TO_TEXTURE_RGBA_EXT:
*value_return = mode->bindToTextureRgba;
return 0;
case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
*value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
GL_FALSE;
return 0;
case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
*value_return = mode->bindToTextureTargets;
return 0;
case GLX_Y_INVERTED_EXT:
*value_return = mode->yInverted;
return 0;
/* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
* It is ONLY for communication between the GLX client and the GLX
* server.
*/
case GLX_VISUAL_SELECT_GROUP_SGIX:
default:
return GLX_BAD_ATTRIBUTE;
}
case GLX_VISUAL_SELECT_GROUP_SGIX:
default:
return GLX_BAD_ATTRIBUTE;
}
}
#endif /* !defined(IN_MINI_GLX) */
@@ -385,24 +386,24 @@ _gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
* extend the \c __GLcontextModes data-structure.
*/
__GLcontextModes *
_gl_context_modes_create( unsigned count, size_t minimum_size )
_gl_context_modes_create(unsigned count, size_t minimum_size)
{
const size_t size = (minimum_size > sizeof( __GLcontextModes ))
? minimum_size : sizeof( __GLcontextModes );
__GLcontextModes * base = NULL;
__GLcontextModes ** next;
unsigned i;
const size_t size = (minimum_size > sizeof(__GLcontextModes))
? minimum_size : sizeof(__GLcontextModes);
__GLcontextModes *base = NULL;
__GLcontextModes **next;
unsigned i;
next = & base;
for ( i = 0 ; i < count ; i++ ) {
*next = (__GLcontextModes *) _mesa_malloc( size );
if ( *next == NULL ) {
_gl_context_modes_destroy( base );
base = NULL;
break;
next = &base;
for (i = 0; i < count; i++) {
*next = (__GLcontextModes *) _mesa_malloc(size);
if (*next == NULL) {
_gl_context_modes_destroy(base);
base = NULL;
break;
}
(void) _mesa_memset( *next, 0, size );
(void) _mesa_memset(*next, 0, size);
(*next)->visualID = GLX_DONT_CARE;
(*next)->visualType = GLX_DONT_CARE;
(*next)->visualRating = GLX_NONE;
@@ -421,7 +422,7 @@ _gl_context_modes_create( unsigned count, size_t minimum_size )
(*next)->bindToTextureTargets = GLX_DONT_CARE;
(*next)->yInverted = GLX_DONT_CARE;
next = & ((*next)->next);
next = &((*next)->next);
}
return base;
@@ -436,12 +437,12 @@ _gl_context_modes_create( unsigned count, size_t minimum_size )
* in the list will be freed.
*/
void
_gl_context_modes_destroy( __GLcontextModes * modes )
_gl_context_modes_destroy(__GLcontextModes * modes)
{
while ( modes != NULL ) {
__GLcontextModes * const next = modes->next;
while (modes != NULL) {
__GLcontextModes *const next = modes->next;
_mesa_free( modes );
_mesa_free(modes);
modes = next;
}
}
@@ -457,27 +458,27 @@ _gl_context_modes_destroy( __GLcontextModes * modes )
*/
__GLcontextModes *
_gl_context_modes_find_visual(__GLcontextModes *modes, int vid)
_gl_context_modes_find_visual(__GLcontextModes * modes, int vid)
{
__GLcontextModes *m;
__GLcontextModes *m;
for (m = modes; m != NULL; m = m->next)
if (m->visualID == vid)
return m;
for (m = modes; m != NULL; m = m->next)
if (m->visualID == vid)
return m;
return NULL;
return NULL;
}
__GLcontextModes *
_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
_gl_context_modes_find_fbconfig(__GLcontextModes * modes, int fbid)
{
__GLcontextModes *m;
__GLcontextModes *m;
for (m = modes; m != NULL; m = m->next)
if (m->fbconfigID == fbid)
return m;
for (m = modes; m != NULL; m = m->next)
if (m->fbconfigID == fbid)
return m;
return NULL;
return NULL;
}
/**
@@ -490,61 +491,55 @@ _gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
* returned otherwise.
*/
GLboolean
_gl_context_modes_are_same( const __GLcontextModes * a,
const __GLcontextModes * b )
_gl_context_modes_are_same(const __GLcontextModes * a,
const __GLcontextModes * b)
{
return( (a->rgbMode == b->rgbMode) &&
(a->floatMode == b->floatMode) &&
(a->colorIndexMode == b->colorIndexMode) &&
(a->doubleBufferMode == b->doubleBufferMode) &&
(a->stereoMode == b->stereoMode) &&
(a->redBits == b->redBits) &&
(a->greenBits == b->greenBits) &&
(a->blueBits == b->blueBits) &&
(a->alphaBits == b->alphaBits) &&
#if 0 /* For some reason these don't get set on the client-side in libGL. */
(a->redMask == b->redMask) &&
(a->greenMask == b->greenMask) &&
(a->blueMask == b->blueMask) &&
(a->alphaMask == b->alphaMask) &&
return ((a->rgbMode == b->rgbMode) &&
(a->floatMode == b->floatMode) &&
(a->colorIndexMode == b->colorIndexMode) &&
(a->doubleBufferMode == b->doubleBufferMode) &&
(a->stereoMode == b->stereoMode) &&
(a->redBits == b->redBits) &&
(a->greenBits == b->greenBits) &&
(a->blueBits == b->blueBits) && (a->alphaBits == b->alphaBits) &&
#if 0 /* For some reason these don't get set on the client-side in libGL. */
(a->redMask == b->redMask) &&
(a->greenMask == b->greenMask) &&
(a->blueMask == b->blueMask) && (a->alphaMask == b->alphaMask) &&
#endif
(a->rgbBits == b->rgbBits) &&
(a->indexBits == b->indexBits) &&
(a->accumRedBits == b->accumRedBits) &&
(a->accumGreenBits == b->accumGreenBits) &&
(a->accumBlueBits == b->accumBlueBits) &&
(a->accumAlphaBits == b->accumAlphaBits) &&
(a->depthBits == b->depthBits) &&
(a->stencilBits == b->stencilBits) &&
(a->numAuxBuffers == b->numAuxBuffers) &&
(a->level == b->level) &&
(a->pixmapMode == b->pixmapMode) &&
(a->visualRating == b->visualRating) &&
(a->transparentPixel == b->transparentPixel) &&
((a->transparentPixel != GLX_TRANSPARENT_RGB) ||
((a->transparentRed == b->transparentRed) &&
(a->transparentGreen == b->transparentGreen) &&
(a->transparentBlue == b->transparentBlue) &&
(a->transparentAlpha == b->transparentAlpha))) &&
((a->transparentPixel != GLX_TRANSPARENT_INDEX) ||
(a->transparentIndex == b->transparentIndex)) &&
(a->sampleBuffers == b->sampleBuffers) &&
(a->samples == b->samples) &&
((a->drawableType & b->drawableType) != 0) &&
(a->renderType == b->renderType) &&
(a->maxPbufferWidth == b->maxPbufferWidth) &&
(a->maxPbufferHeight == b->maxPbufferHeight) &&
(a->maxPbufferPixels == b->maxPbufferPixels) &&
(a->optimalPbufferWidth == b->optimalPbufferWidth) &&
(a->optimalPbufferHeight == b->optimalPbufferHeight) &&
(a->swapMethod == b->swapMethod) &&
(a->bindToTextureRgb == b->bindToTextureRgb) &&
(a->bindToTextureRgba == b->bindToTextureRgba) &&
(a->bindToMipmapTexture == b->bindToMipmapTexture) &&
(a->bindToTextureTargets == b->bindToTextureTargets) &&
(a->yInverted == b->yInverted) );
(a->rgbBits == b->rgbBits) &&
(a->indexBits == b->indexBits) &&
(a->accumRedBits == b->accumRedBits) &&
(a->accumGreenBits == b->accumGreenBits) &&
(a->accumBlueBits == b->accumBlueBits) &&
(a->accumAlphaBits == b->accumAlphaBits) &&
(a->depthBits == b->depthBits) &&
(a->stencilBits == b->stencilBits) &&
(a->numAuxBuffers == b->numAuxBuffers) &&
(a->level == b->level) &&
(a->pixmapMode == b->pixmapMode) &&
(a->visualRating == b->visualRating) &&
(a->transparentPixel == b->transparentPixel) &&
((a->transparentPixel != GLX_TRANSPARENT_RGB) ||
((a->transparentRed == b->transparentRed) &&
(a->transparentGreen == b->transparentGreen) &&
(a->transparentBlue == b->transparentBlue) &&
(a->transparentAlpha == b->transparentAlpha))) &&
((a->transparentPixel != GLX_TRANSPARENT_INDEX) ||
(a->transparentIndex == b->transparentIndex)) &&
(a->sampleBuffers == b->sampleBuffers) &&
(a->samples == b->samples) &&
((a->drawableType & b->drawableType) != 0) &&
(a->renderType == b->renderType) &&
(a->maxPbufferWidth == b->maxPbufferWidth) &&
(a->maxPbufferHeight == b->maxPbufferHeight) &&
(a->maxPbufferPixels == b->maxPbufferPixels) &&
(a->optimalPbufferWidth == b->optimalPbufferWidth) &&
(a->optimalPbufferHeight == b->optimalPbufferHeight) &&
(a->swapMethod == b->swapMethod) &&
(a->bindToTextureRgb == b->bindToTextureRgb) &&
(a->bindToTextureRgba == b->bindToTextureRgba) &&
(a->bindToMipmapTexture == b->bindToMipmapTexture) &&
(a->bindToTextureTargets == b->bindToTextureTargets) &&
(a->yInverted == b->yInverted));
}
+16 -15
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2003
* All Rights Reserved.
@@ -33,22 +34,22 @@
#include "GL/internal/glcore.h"
#if !defined(IN_MINI_GLX)
extern GLint _gl_convert_from_x_visual_type( int visualType );
extern GLint _gl_convert_to_x_visual_type( int visualType );
extern void _gl_copy_visual_to_context_mode( __GLcontextModes * mode,
const __GLXvisualConfig * config );
extern int _gl_get_context_mode_data( const __GLcontextModes *mode,
int attribute, int *value_return );
extern GLint _gl_convert_from_x_visual_type(int visualType);
extern GLint _gl_convert_to_x_visual_type(int visualType);
extern void _gl_copy_visual_to_context_mode(__GLcontextModes * mode,
const __GLXvisualConfig * config);
extern int _gl_get_context_mode_data(const __GLcontextModes * mode,
int attribute, int *value_return);
#endif /* !defined(IN_MINI_GLX) */
extern __GLcontextModes * _gl_context_modes_create( unsigned count,
size_t minimum_size );
extern void _gl_context_modes_destroy( __GLcontextModes * modes );
extern __GLcontextModes *
_gl_context_modes_find_visual(__GLcontextModes *modes, int vid);
extern __GLcontextModes *
_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid);
extern GLboolean _gl_context_modes_are_same( const __GLcontextModes * a,
const __GLcontextModes * b );
extern __GLcontextModes *_gl_context_modes_create(unsigned count,
size_t minimum_size);
extern void _gl_context_modes_destroy(__GLcontextModes * modes);
extern __GLcontextModes *_gl_context_modes_find_visual(__GLcontextModes *
modes, int vid);
extern __GLcontextModes *_gl_context_modes_find_fbconfig(__GLcontextModes *
modes, int fbid);
extern GLboolean _gl_context_modes_are_same(const __GLcontextModes * a,
const __GLcontextModes * b);
#endif /* GLCONTEXTMODES_H */
+186 -187
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004
* All Rights Reserved.
@@ -54,14 +55,14 @@
* This function needs to be modified to work with direct-rendering drivers.
*/
static void
ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable,
const CARD32 * attribs, size_t num_attribs )
ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
const CARD32 * attribs, size_t num_attribs)
{
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
CARD32 * output;
CARD32 *output;
CARD8 opcode;
if ( (dpy == NULL) || (drawable == 0) ) {
if ((dpy == NULL) || (drawable == 0)) {
return;
}
@@ -71,10 +72,10 @@ ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable,
LockDisplay(dpy);
if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXChangeDrawableAttributesReq *req;
GetReqExtra( GLXChangeDrawableAttributes, 8 + (8 * num_attribs), req );
GetReqExtra(GLXChangeDrawableAttributes, 8 + (8 * num_attribs), req);
output = (CARD32 *) (req + 1);
req->reqType = opcode;
@@ -85,7 +86,7 @@ ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable,
else {
xGLXVendorPrivateWithReplyReq *vpreq;
GetReqExtra( GLXVendorPrivateWithReply, 4 + (8 * num_attribs), vpreq );
GetReqExtra(GLXVendorPrivateWithReply, 4 + (8 * num_attribs), vpreq);
output = (CARD32 *) (vpreq + 1);
vpreq->reqType = opcode;
@@ -96,7 +97,7 @@ ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable,
output++;
}
(void) memcpy( output, attribs, sizeof( CARD32 ) * 2 * num_attribs );
(void) memcpy(output, attribs, sizeof(CARD32) * 2 * num_attribs);
UnlockDisplay(dpy);
SyncHandle();
@@ -119,12 +120,12 @@ ChangeDrawableAttribute( Display * dpy, GLXDrawable drawable,
* This function needs to be modified to work with direct-rendering drivers.
*/
static void
DestroyPbuffer( Display * dpy, GLXDrawable drawable )
DestroyPbuffer(Display * dpy, GLXDrawable drawable)
{
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
CARD8 opcode;
if ( (dpy == NULL) || (drawable == 0) ) {
if ((dpy == NULL) || (drawable == 0)) {
return;
}
@@ -134,19 +135,19 @@ DestroyPbuffer( Display * dpy, GLXDrawable drawable )
LockDisplay(dpy);
if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
xGLXDestroyPbufferReq * req;
if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXDestroyPbufferReq *req;
GetReq( GLXDestroyPbuffer, req );
GetReq(GLXDestroyPbuffer, req);
req->reqType = opcode;
req->glxCode = X_GLXDestroyPbuffer;
req->pbuffer = (GLXPbuffer) drawable;
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
CARD32 * data;
CARD32 *data;
GetReqExtra( GLXVendorPrivateWithReply, 4, vpreq );
GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
data = (CARD32 *) (vpreq + 1);
data[0] = (CARD32) drawable;
@@ -164,29 +165,30 @@ DestroyPbuffer( Display * dpy, GLXDrawable drawable )
#ifdef GLX_DIRECT_RENDERING
extern __GLXDRIdrawable *
GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy,
GLXDrawable drawable,
int *const scrn_num);
static GLenum
determineTextureTarget(const int *attribs, int numAttribs)
{
GLenum target = 0;
int i;
GLenum target = 0;
int i;
for (i = 0; i < numAttribs; i++) {
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
switch (attribs[2 * i + 1]) {
case GLX_TEXTURE_2D_EXT:
target = GL_TEXTURE_2D;
break;
case GLX_TEXTURE_RECTANGLE_EXT:
target = GL_TEXTURE_RECTANGLE_ARB;
break;
}
}
}
return target;
for (i = 0; i < numAttribs; i++) {
if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
switch (attribs[2 * i + 1]) {
case GLX_TEXTURE_2D_EXT:
target = GL_TEXTURE_2D;
break;
case GLX_TEXTURE_RECTANGLE_EXT:
target = GL_TEXTURE_RECTANGLE_ARB;
break;
}
}
}
return target;
}
#endif
@@ -209,24 +211,24 @@ determineTextureTarget(const int *attribs, int numAttribs)
* This function needs to be modified to work with direct-rendering drivers.
*/
static int
GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
int attribute, unsigned int *value )
GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
{
__GLXdisplayPrivate *priv;
xGLXGetDrawableAttributesReply reply;
CARD32 * data;
CARD32 *data;
CARD8 opcode;
unsigned int length;
unsigned int i;
unsigned int num_attributes;
if ( (dpy == NULL) || (drawable == 0) ) {
if ((dpy == NULL) || (drawable == 0)) {
return 0;
}
priv = __glXInitialize(dpy);
GLboolean use_glx_1_3 = ((priv->majorVersion > 1)
|| (priv->minorVersion >= 3));
|| (priv->minorVersion >= 3));
*value = 0;
@@ -237,10 +239,10 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
LockDisplay(dpy);
if ( use_glx_1_3 ) {
if (use_glx_1_3) {
xGLXGetDrawableAttributesReq *req;
GetReqExtra( GLXGetDrawableAttributes, 4, req );
GetReqExtra(GLXGetDrawableAttributes, 4, req);
req->reqType = opcode;
req->glxCode = X_GLXGetDrawableAttributes;
req->drawable = drawable;
@@ -248,7 +250,7 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
else {
xGLXVendorPrivateWithReplyReq *vpreq;
GetReqExtra( GLXVendorPrivateWithReply, 4, vpreq );
GetReqExtra(GLXVendorPrivateWithReply, 4, vpreq);
data = (CARD32 *) (vpreq + 1);
data[0] = (CARD32) drawable;
@@ -257,48 +259,47 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
vpreq->vendorCode = X_GLXvop_GetDrawableAttributesSGIX;
}
_XReply(dpy, (xReply*) &reply, 0, False);
_XReply(dpy, (xReply *) & reply, 0, False);
if (reply.type == X_Error)
{
UnlockDisplay(dpy);
SyncHandle();
return 0;
if (reply.type == X_Error) {
UnlockDisplay(dpy);
SyncHandle();
return 0;
}
length = reply.length;
if (length)
{
num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
data = (CARD32 *) Xmalloc( length * sizeof(CARD32) );
if ( data == NULL ) {
/* Throw data on the floor */
_XEatData(dpy, length);
} else {
_XRead(dpy, (char *)data, length * sizeof(CARD32) );
if (length) {
num_attributes = (use_glx_1_3) ? reply.numAttribs : length / 2;
data = (CARD32 *) Xmalloc(length * sizeof(CARD32));
if (data == NULL) {
/* Throw data on the floor */
_XEatData(dpy, length);
}
else {
_XRead(dpy, (char *) data, length * sizeof(CARD32));
/* Search the set of returned attributes for the attribute requested by
* the caller.
*/
for ( i = 0 ; i < num_attributes ; i++ ) {
if ( data[i*2] == attribute ) {
*value = data[ (i*2) + 1 ];
break;
}
}
/* Search the set of returned attributes for the attribute requested by
* the caller.
*/
for (i = 0; i < num_attributes; i++) {
if (data[i * 2] == attribute) {
*value = data[(i * 2) + 1];
break;
}
}
#ifdef GLX_DIRECT_RENDERING
{
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
{
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
if (pdraw != NULL && !pdraw->textureTarget)
pdraw->textureTarget = determineTextureTarget((const int *)data,
num_attributes);
}
if (pdraw != NULL && !pdraw->textureTarget)
pdraw->textureTarget =
determineTextureTarget((const int *) data, num_attributes);
}
#endif
Xfree( data );
}
Xfree(data);
}
}
UnlockDisplay(dpy);
@@ -314,19 +315,18 @@ GetDrawableAttribute( Display *dpy, GLXDrawable drawable,
* This function needs to be modified to work with direct-rendering drivers.
*/
static GLXDrawable
CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
Drawable drawable, const int *attrib_list,
CARD8 glxCode )
CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
Drawable drawable, const int *attrib_list, CARD8 glxCode)
{
xGLXCreateWindowReq * req;
CARD32 * data;
xGLXCreateWindowReq *req;
CARD32 *data;
unsigned int i;
CARD8 opcode;
i = 0;
if (attrib_list) {
while (attrib_list[i * 2] != None)
i++;
while (attrib_list[i * 2] != None)
i++;
}
opcode = __glXSetupForCommand(dpy);
@@ -334,7 +334,7 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
return None;
LockDisplay(dpy);
GetReqExtra( GLXCreateWindow, 8 * i, req );
GetReqExtra(GLXCreateWindow, 8 * i, req);
data = (CARD32 *) (req + 1);
req->reqType = opcode;
@@ -345,40 +345,40 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
req->glxwindow = (GLXWindow) XAllocID(dpy);
req->numAttribs = (CARD32) i;
memcpy( data, attrib_list, 8 * i );
memcpy(data, attrib_list, 8 * i);
UnlockDisplay(dpy);
SyncHandle();
#ifdef GLX_DIRECT_RENDERING
do {
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
* is actually bound to a context... */
/* FIXME: Maybe delay __DRIdrawable creation until the drawable
* is actually bound to a context... */
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw;
__GLXscreenConfigs *psc;
__GLXdisplayPrivate *const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw;
__GLXscreenConfigs *psc;
psc = &priv->screenConfigs[fbconfig->screen];
if (psc->driScreen == NULL)
break;
pdraw = psc->driScreen->createDrawable(psc, drawable,
req->glxwindow, fbconfig);
if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n");
break;
}
if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) {
(*pdraw->destroyDrawable)(pdraw);
return None; /* FIXME: Check what we're supposed to do here... */
}
psc = &priv->screenConfigs[fbconfig->screen];
if (psc->driScreen == NULL)
break;
pdraw = psc->driScreen->createDrawable(psc, drawable,
req->glxwindow, fbconfig);
if (pdraw == NULL) {
fprintf(stderr, "failed to create drawable\n");
break;
}
pdraw->textureTarget = determineTextureTarget(attrib_list, i);
if (__glxHashInsert(psc->drawHash, req->glxwindow, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
return None; /* FIXME: Check what we're supposed to do here... */
}
pdraw->textureTarget = determineTextureTarget(attrib_list, i);
} while (0);
#endif
return (GLXDrawable)req->glxwindow;
return (GLXDrawable) req->glxwindow;
}
@@ -389,12 +389,12 @@ CreateDrawable( Display *dpy, const __GLcontextModes * fbconfig,
* This function needs to be modified to work with direct-rendering drivers.
*/
static void
DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
{
xGLXDestroyPbufferReq * req;
xGLXDestroyPbufferReq *req;
CARD8 opcode;
if ( (dpy == NULL) || (drawable == 0) ) {
if ((dpy == NULL) || (drawable == 0)) {
return;
}
@@ -405,7 +405,7 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
LockDisplay(dpy);
GetReqExtra( GLXDestroyPbuffer, 4, req );
GetReqExtra(GLXDestroyPbuffer, 4, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->pbuffer = (GLXPbuffer) drawable;
@@ -415,15 +415,15 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
#ifdef GLX_DIRECT_RENDERING
{
int screen;
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *psc = &priv->screenConfigs[screen];
int screen;
__GLXdisplayPrivate *const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *psc = &priv->screenConfigs[screen];
if (pdraw != NULL) {
(*pdraw->destroyDrawable)(pdraw);
__glxHashDelete(psc->drawHash, drawable);
}
if (pdraw != NULL) {
(*pdraw->destroyDrawable) (pdraw);
__glxHashDelete(psc->drawHash, drawable);
}
}
#endif
@@ -445,20 +445,20 @@ DestroyDrawable( Display * dpy, GLXDrawable drawable, CARD32 glxCode )
* This function needs to be modified to work with direct-rendering drivers.
*/
static GLXDrawable
CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
unsigned int width, unsigned int height,
const int *attrib_list, GLboolean size_in_attribs )
CreatePbuffer(Display * dpy, const __GLcontextModes * fbconfig,
unsigned int width, unsigned int height,
const int *attrib_list, GLboolean size_in_attribs)
{
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
GLXDrawable id = 0;
CARD32 * data;
CARD32 *data;
CARD8 opcode;
unsigned int i;
unsigned int i;
i = 0;
if (attrib_list) {
while (attrib_list[i * 2])
i++;
while (attrib_list[i * 2])
i++;
}
opcode = __glXSetupForCommand(dpy);
@@ -468,11 +468,11 @@ CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
LockDisplay(dpy);
id = XAllocID(dpy);
if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
xGLXCreatePbufferReq * req;
if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXCreatePbufferReq *req;
unsigned int extra = (size_in_attribs) ? 0 : 2;
GetReqExtra( GLXCreatePbuffer, (8 * (i + extra)), req );
GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
data = (CARD32 *) (req + 1);
req->reqType = opcode;
@@ -482,18 +482,18 @@ CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
req->pbuffer = (GLXPbuffer) id;
req->numAttribs = (CARD32) (i + extra);
if ( ! size_in_attribs ) {
data[(2 * i) + 0] = GLX_PBUFFER_WIDTH;
data[(2 * i) + 1] = width;
data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT;
data[(2 * i) + 3] = height;
data += 4;
if (!size_in_attribs) {
data[(2 * i) + 0] = GLX_PBUFFER_WIDTH;
data[(2 * i) + 1] = width;
data[(2 * i) + 2] = GLX_PBUFFER_HEIGHT;
data[(2 * i) + 3] = height;
data += 4;
}
}
else {
xGLXVendorPrivateReq *vpreq;
GetReqExtra( GLXVendorPrivate, 20 + (8 * i), vpreq );
GetReqExtra(GLXVendorPrivate, 20 + (8 * i), vpreq);
data = (CARD32 *) (vpreq + 1);
vpreq->reqType = opcode;
@@ -508,7 +508,7 @@ CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
data += 5;
}
(void) memcpy( data, attrib_list, sizeof(CARD32) * 2 * i );
(void) memcpy(data, attrib_list, sizeof(CARD32) * 2 * i);
UnlockDisplay(dpy);
SyncHandle();
@@ -521,13 +521,13 @@ CreatePbuffer( Display *dpy, const __GLcontextModes * fbconfig,
* Create a new pbuffer.
*/
PUBLIC GLXPbufferSGIX
glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
unsigned int width, unsigned int height,
int *attrib_list)
glXCreateGLXPbufferSGIX(Display * dpy, GLXFBConfigSGIX config,
unsigned int width, unsigned int height,
int *attrib_list)
{
return (GLXPbufferSGIX) CreatePbuffer( dpy, (__GLcontextModes *) config,
width, height,
attrib_list, GL_FALSE );
return (GLXPbufferSGIX) CreatePbuffer(dpy, (__GLcontextModes *) config,
width, height,
attrib_list, GL_FALSE);
}
@@ -535,7 +535,7 @@ glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
* Create a new pbuffer.
*/
PUBLIC GLXPbuffer
glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
{
int i, width, height;
@@ -545,17 +545,16 @@ glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
for (i = 0; attrib_list[i * 2]; i++) {
switch (attrib_list[i * 2]) {
case GLX_PBUFFER_WIDTH:
width = attrib_list[i * 2 + 1];
break;
width = attrib_list[i * 2 + 1];
break;
case GLX_PBUFFER_HEIGHT:
height = attrib_list[i * 2 + 1];
break;
height = attrib_list[i * 2 + 1];
break;
}
}
return (GLXPbuffer) CreatePbuffer( dpy, (__GLcontextModes *) config,
width, height,
attrib_list, GL_TRUE );
return (GLXPbuffer) CreatePbuffer(dpy, (__GLcontextModes *) config,
width, height, attrib_list, GL_TRUE);
}
@@ -563,9 +562,9 @@ glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attrib_list)
* Destroy an existing pbuffer.
*/
PUBLIC void
glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf)
{
DestroyPbuffer( dpy, pbuf );
DestroyPbuffer(dpy, pbuf);
}
@@ -573,10 +572,10 @@ glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
* Query an attribute of a drawable.
*/
PUBLIC void
glXQueryDrawable(Display *dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
glXQueryDrawable(Display * dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
{
GetDrawableAttribute( dpy, drawable, attribute, value );
GetDrawableAttribute(dpy, drawable, attribute, value);
}
@@ -584,10 +583,10 @@ glXQueryDrawable(Display *dpy, GLXDrawable drawable,
* Query an attribute of a pbuffer.
*/
PUBLIC int
glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX drawable,
int attribute, unsigned int *value)
glXQueryGLXPbufferSGIX(Display * dpy, GLXPbufferSGIX drawable,
int attribute, unsigned int *value)
{
return GetDrawableAttribute( dpy, drawable, attribute, value );
return GetDrawableAttribute(dpy, drawable, attribute, value);
}
@@ -595,14 +594,14 @@ glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX drawable,
* Select the event mask for a drawable.
*/
PUBLIC void
glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
glXSelectEvent(Display * dpy, GLXDrawable drawable, unsigned long mask)
{
CARD32 attribs[2];
attribs[0] = (CARD32) GLX_EVENT_MASK;
attribs[1] = (CARD32) mask;
ChangeDrawableAttribute( dpy, drawable, attribs, 1 );
ChangeDrawableAttribute(dpy, drawable, attribs, 1);
}
@@ -610,7 +609,7 @@ glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
* Get the selected event mask for a drawable.
*/
PUBLIC void
glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
glXGetSelectedEvent(Display * dpy, GLXDrawable drawable, unsigned long *mask)
{
unsigned int value;
@@ -620,56 +619,56 @@ glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
* we could just type-cast the pointer, but why?
*/
GetDrawableAttribute( dpy, drawable, GLX_EVENT_MASK_SGIX, & value );
GetDrawableAttribute(dpy, drawable, GLX_EVENT_MASK_SGIX, &value);
*mask = value;
}
PUBLIC GLXPixmap
glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
const int *attrib_list )
glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
const int *attrib_list)
{
return CreateDrawable( dpy, (__GLcontextModes *) config,
(Drawable) pixmap, attrib_list,
X_GLXCreatePixmap );
return CreateDrawable(dpy, (__GLcontextModes *) config,
(Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
}
PUBLIC GLXWindow
glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
const int *attrib_list )
glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
const int *attrib_list)
{
return CreateDrawable( dpy, (__GLcontextModes *) config,
(Drawable) win, attrib_list,
X_GLXCreateWindow );
return CreateDrawable(dpy, (__GLcontextModes *) config,
(Drawable) win, attrib_list, X_GLXCreateWindow);
}
PUBLIC void
glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
{
DestroyDrawable( dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap );
DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
}
PUBLIC void
glXDestroyWindow(Display *dpy, GLXWindow win)
glXDestroyWindow(Display * dpy, GLXWindow win)
{
DestroyDrawable( dpy, (GLXDrawable) win, X_GLXDestroyWindow );
DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
}
PUBLIC GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
(Display *dpy, GLXPbufferSGIX pbuf),
(dpy, pbuf),
glXDestroyPbuffer)
PUBLIC
GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
(Display * dpy, GLXPbufferSGIX pbuf),
(dpy, pbuf), glXDestroyPbuffer)
PUBLIC GLX_ALIAS_VOID(glXSelectEventSGIX,
(Display *dpy, GLXDrawable drawable, unsigned long mask),
(dpy, drawable, mask),
glXSelectEvent)
PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long mask), (dpy, drawable, mask),
glXSelectEvent)
PUBLIC GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
(Display *dpy, GLXDrawable drawable, unsigned long *mask),
(dpy, drawable, mask),
glXGetSelectedEvent)
PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long *mask), (dpy, drawable, mask),
glXGetSelectedEvent)
+38 -36
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004
* All Rights Reserved.
@@ -39,12 +40,13 @@
* an identical binary layout. The only difference between them is the
* meaning of the \c for_whom field and the value of the \c glxCode.
*/
typedef struct GLXGenericGetString {
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
typedef struct GLXGenericGetString
{
CARD8 reqType;
CARD8 glxCode;
CARD16 length B16;
CARD32 for_whom B32;
CARD32 name B32;
} xGLXGenericGetStringReq;
/* These defines are only needed to make the GetReq macro happy.
@@ -57,46 +59,46 @@ typedef struct GLXGenericGetString {
* This routine will allocate the necessay space for the string.
*/
char *
__glXGetStringFromServer( Display * dpy, int opcode, CARD32 glxCode,
CARD32 for_whom, CARD32 name )
__glXGetStringFromServer(Display * dpy, int opcode, CARD32 glxCode,
CARD32 for_whom, CARD32 name)
{
xGLXGenericGetStringReq *req;
xGLXSingleReply reply;
int length;
int numbytes;
char * buf;
xGLXGenericGetStringReq *req;
xGLXSingleReply reply;
int length;
int numbytes;
char *buf;
LockDisplay( dpy );
LockDisplay(dpy);
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
/* All of the GLX protocol requests for getting a string from the server
* look the same. The exact meaning of the for_whom field is usually
* either the screen number (for glXQueryServerString) or the context tag
* (for GLXSingle).
*/
GetReq( GLXGenericGetString, req );
req->reqType = opcode;
req->glxCode = glxCode;
req->for_whom = for_whom;
req->name = name;
GetReq(GLXGenericGetString, req);
req->reqType = opcode;
req->glxCode = glxCode;
req->for_whom = for_whom;
req->name = name;
_XReply( dpy, (xReply *) & reply, 0, False );
_XReply(dpy, (xReply *) & reply, 0, False);
length = reply.length * 4;
numbytes = reply.size;
length = reply.length * 4;
numbytes = reply.size;
buf = (char *) Xmalloc( numbytes );
if ( buf != NULL ) {
_XRead( dpy, buf, numbytes );
length -= numbytes;
}
buf = (char *) Xmalloc(numbytes);
if (buf != NULL) {
_XRead(dpy, buf, numbytes);
length -= numbytes;
}
_XEatData( dpy, length );
_XEatData(dpy, length);
UnlockDisplay( dpy );
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
return buf;
return buf;
}
+4 -1
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -137,6 +138,8 @@ struct __GLXDRIscreenRec {
const __GLcontextModes *modes);
void (*swapBuffers)(__GLXDRIdrawable *pdraw);
void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
int x, int y, int width, int height);
};
struct __GLXDRIcontextRec {
@@ -492,7 +495,7 @@ struct __GLXscreenConfigsRec {
__GLXDRIscreen *driScreen;
#ifdef __DRI_COPY_SUB_BUFFER
const __DRIcopySubBufferExtension *copySubBuffer;
const __DRIcopySubBufferExtension *driCopySubBuffer;
#endif
#ifdef __DRI_SWAP_CONTROL
+4 -4
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -2498,10 +2499,9 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
if ( pdraw != NULL ) {
__GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
if (psc->copySubBuffer != NULL) {
(*psc->copySubBuffer->copySubBuffer)(pdraw->driDrawable,
x, y, width, height);
__GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
if (psc->driScreen->copySubBuffer != NULL) {
(*psc->driScreen->copySubBuffer)(pdraw, x, y, width, height);
}
return;
+263 -243
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -55,11 +56,11 @@ static GLubyte dummyBuffer[__GLX_BUFFER_LIMIT_SIZE];
** the dummy context structure.
*/
static __GLXcontext dummyContext = {
&dummyBuffer[0],
&dummyBuffer[0],
&dummyBuffer[0],
&dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
sizeof(dummyBuffer),
&dummyBuffer[0],
&dummyBuffer[0],
&dummyBuffer[0],
&dummyBuffer[__GLX_BUFFER_LIMIT_SIZE],
sizeof(dummyBuffer),
};
@@ -79,7 +80,8 @@ static __GLapi *IndirectAPI = NULL;
static GLboolean TSDinitialized = GL_FALSE;
static xthread_key_t ContextTSD;
_X_HIDDEN __GLXcontext *__glXGetCurrentContext(void)
_X_HIDDEN __GLXcontext *
__glXGetCurrentContext(void)
{
if (!TSDinitialized) {
xthread_key_create(&ContextTSD, NULL);
@@ -96,7 +98,8 @@ _X_HIDDEN __GLXcontext *__glXGetCurrentContext(void)
}
}
_X_HIDDEN void __glXSetCurrentContext(__GLXcontext *c)
_X_HIDDEN void
__glXSetCurrentContext(__GLXcontext * c)
{
if (!TSDinitialized) {
xthread_key_create(&ContextTSD, NULL);
@@ -122,12 +125,13 @@ _X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
* \b never be \c NULL. This is important! Because of this
* \c __glXGetCurrentContext can be implemented as trivial macro.
*/
__thread void * __glX_tls_Context __attribute__((tls_model("initial-exec")))
= &dummyContext;
__thread void *__glX_tls_Context __attribute__ ((tls_model("initial-exec")))
= &dummyContext;
_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )
_X_HIDDEN void
__glXSetCurrentContext(__GLXcontext * c)
{
__glX_tls_Context = (c != NULL) ? c : &dummyContext;
__glX_tls_Context = (c != NULL) ? c : &dummyContext;
}
# else
@@ -150,28 +154,31 @@ static pthread_key_t ContextTSD;
* initialize the per-thread data key. This is ideally done using the
* \c pthread_once mechanism.
*/
static void init_thread_data( void )
static void
init_thread_data(void)
{
if ( pthread_key_create( & ContextTSD, NULL ) != 0 ) {
perror( "pthread_key_create" );
exit( -1 );
}
if (pthread_key_create(&ContextTSD, NULL) != 0) {
perror("pthread_key_create");
exit(-1);
}
}
_X_HIDDEN void __glXSetCurrentContext( __GLXcontext * c )
_X_HIDDEN void
__glXSetCurrentContext(__GLXcontext * c)
{
pthread_once( & once_control, init_thread_data );
pthread_setspecific( ContextTSD, c );
pthread_once(&once_control, init_thread_data);
pthread_setspecific(ContextTSD, c);
}
_X_HIDDEN __GLXcontext * __glXGetCurrentContext( void )
_X_HIDDEN __GLXcontext *
__glXGetCurrentContext(void)
{
void * v;
void *v;
pthread_once( & once_control, init_thread_data );
pthread_once(&once_control, init_thread_data);
v = pthread_getspecific( ContextTSD );
return (v == NULL) ? & dummyContext : (__GLXcontext *) v;
v = pthread_getspecific(ContextTSD);
return (v == NULL) ? &dummyContext : (__GLXcontext *) v;
}
# endif /* defined( GLX_USE_TLS ) */
@@ -188,32 +195,36 @@ _X_HIDDEN __GLXcontext *__glXcurrentContext = &dummyContext;
#endif
_X_HIDDEN void __glXSetCurrentContextNull(void)
_X_HIDDEN void
__glXSetCurrentContextNull(void)
{
__glXSetCurrentContext(&dummyContext);
__glXSetCurrentContext(&dummyContext);
#ifdef GLX_DIRECT_RENDERING
_glapi_set_dispatch(NULL); /* no-op functions */
_glapi_set_dispatch(NULL); /* no-op functions */
#endif
}
/************************************************************************/
PUBLIC GLXContext glXGetCurrentContext(void)
PUBLIC GLXContext
glXGetCurrentContext(void)
{
GLXContext cx = __glXGetCurrentContext();
if (cx == &dummyContext) {
return NULL;
} else {
return cx;
}
GLXContext cx = __glXGetCurrentContext();
if (cx == &dummyContext) {
return NULL;
}
else {
return cx;
}
}
PUBLIC GLXDrawable glXGetCurrentDrawable(void)
PUBLIC GLXDrawable
glXGetCurrentDrawable(void)
{
GLXContext gc = __glXGetCurrentContext();
return gc->currentDrawable;
GLXContext gc = __glXGetCurrentContext();
return gc->currentDrawable;
}
@@ -233,107 +244,109 @@ PUBLIC GLXDrawable glXGetCurrentDrawable(void)
* \warning
* This function assumes that \c dpy is locked with \c LockDisplay on entry.
*/
static Bool SendMakeCurrentRequest(Display *dpy, CARD8 opcode,
GLXContextID gc_id, GLXContextTag gc_tag,
GLXDrawable draw, GLXDrawable read,
xGLXMakeCurrentReply *reply)
static Bool
SendMakeCurrentRequest(Display * dpy, CARD8 opcode,
GLXContextID gc_id, GLXContextTag gc_tag,
GLXDrawable draw, GLXDrawable read,
xGLXMakeCurrentReply * reply)
{
Bool ret;
Bool ret;
LockDisplay(dpy);
LockDisplay(dpy);
if (draw == read) {
xGLXMakeCurrentReq *req;
if (draw == read) {
xGLXMakeCurrentReq *req;
GetReq(GLXMakeCurrent,req);
req->reqType = opcode;
req->glxCode = X_GLXMakeCurrent;
req->drawable = draw;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
else {
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
GetReq(GLXMakeCurrent, req);
req->reqType = opcode;
req->glxCode = X_GLXMakeCurrent;
req->drawable = draw;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
else {
__GLXdisplayPrivate *priv = __glXInitialize(dpy);
/* If the server can support the GLX 1.3 version, we should
* perfer that. Not only that, some servers support GLX 1.3 but
* not the SGI extension.
*/
/* If the server can support the GLX 1.3 version, we should
* perfer that. Not only that, some servers support GLX 1.3 but
* not the SGI extension.
*/
if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXMakeContextCurrentReq *req;
if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
xGLXMakeContextCurrentReq *req;
GetReq(GLXMakeContextCurrent,req);
req->reqType = opcode;
req->glxCode = X_GLXMakeContextCurrent;
req->drawable = draw;
req->readdrawable = read;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXMakeCurrentReadSGIReq *req;
GetReq(GLXMakeContextCurrent, req);
req->reqType = opcode;
req->glxCode = X_GLXMakeContextCurrent;
req->drawable = draw;
req->readdrawable = read;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
else {
xGLXVendorPrivateWithReplyReq *vpreq;
xGLXMakeCurrentReadSGIReq *req;
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXMakeCurrentReadSGIReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
req = (xGLXMakeCurrentReadSGIReq *)vpreq;
req->reqType = opcode;
req->glxCode = X_GLXVendorPrivateWithReply;
req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
req->drawable = draw;
req->readable = read;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
}
GetReqExtra(GLXVendorPrivateWithReply,
sz_xGLXMakeCurrentReadSGIReq -
sz_xGLXVendorPrivateWithReplyReq, vpreq);
req = (xGLXMakeCurrentReadSGIReq *) vpreq;
req->reqType = opcode;
req->glxCode = X_GLXVendorPrivateWithReply;
req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
req->drawable = draw;
req->readable = read;
req->context = gc_id;
req->oldContextTag = gc_tag;
}
}
ret = _XReply(dpy, (xReply*) reply, 0, False);
ret = _XReply(dpy, (xReply *) reply, 0, False);
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
return ret;
return ret;
}
#ifdef GLX_DIRECT_RENDERING
static __GLXDRIdrawable *
FetchDRIDrawable(Display *dpy,
GLXDrawable glxDrawable, GLXContext gc, Bool pre13)
FetchDRIDrawable(Display * dpy,
GLXDrawable glxDrawable, GLXContext gc, Bool pre13)
{
__GLXdisplayPrivate * const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw;
__GLXscreenConfigs *psc;
XID drawable;
__GLXdisplayPrivate *const priv = __glXInitialize(dpy);
__GLXDRIdrawable *pdraw;
__GLXscreenConfigs *psc;
XID drawable;
if (priv == NULL)
return NULL;
psc = &priv->screenConfigs[gc->screen];
if (psc->drawHash == NULL)
return NULL;
if (priv == NULL)
return NULL;
if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0)
return pdraw;
psc = &priv->screenConfigs[gc->screen];
if (psc->drawHash == NULL)
return NULL;
/* If this is glXMakeCurrent (pre GLX 1.3) we allow creating the
* GLX drawable on the fly. Otherwise we pass None as the X
* drawable */
if (pre13)
drawable = glxDrawable;
else
drawable = None;
if (__glxHashLookup(psc->drawHash, glxDrawable, (void *) &pdraw) == 0)
return pdraw;
pdraw = psc->driScreen->createDrawable(psc, drawable,
glxDrawable, gc->mode);
if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) {
(*pdraw->destroyDrawable)(pdraw);
return NULL;
}
/* If this is glXMakeCurrent (pre GLX 1.3) we allow creating the
* GLX drawable on the fly. Otherwise we pass None as the X
* drawable */
if (pre13)
drawable = glxDrawable;
else
drawable = None;
return pdraw;
pdraw = psc->driScreen->createDrawable(psc, drawable,
glxDrawable, gc->mode);
if (__glxHashInsert(psc->drawHash, glxDrawable, pdraw)) {
(*pdraw->destroyDrawable) (pdraw);
return NULL;
}
return pdraw;
}
#endif /* GLX_DIRECT_RENDERING */
@@ -343,170 +356,177 @@ FetchDRIDrawable(Display *dpy,
*
* \note This is in this file so that it can access dummyContext.
*/
static Bool MakeContextCurrent(Display *dpy, GLXDrawable draw,
GLXDrawable read, GLXContext gc,
Bool pre13)
static Bool
MakeContextCurrent(Display * dpy, GLXDrawable draw,
GLXDrawable read, GLXContext gc, Bool pre13)
{
xGLXMakeCurrentReply reply;
const GLXContext oldGC = __glXGetCurrentContext();
const CARD8 opcode = __glXSetupForCommand(dpy);
const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
xGLXMakeCurrentReply reply;
const GLXContext oldGC = __glXGetCurrentContext();
const CARD8 opcode = __glXSetupForCommand(dpy);
const CARD8 oldOpcode = ((gc == oldGC) || (oldGC == &dummyContext))
? opcode : __glXSetupForCommand(oldGC->currentDpy);
Bool bindReturnValue;
Bool bindReturnValue;
if (!opcode || !oldOpcode) {
return GL_FALSE;
}
if (!opcode || !oldOpcode) {
return GL_FALSE;
}
/* Make sure that the new context has a nonzero ID. In the request,
* a zero context ID is used only to mean that we bind to no current
* context.
*/
if ((gc != NULL) && (gc->xid == None)) {
return GL_FALSE;
}
/* Make sure that the new context has a nonzero ID. In the request,
* a zero context ID is used only to mean that we bind to no current
* context.
*/
if ((gc != NULL) && (gc->xid == None)) {
return GL_FALSE;
}
_glapi_check_multithread();
_glapi_check_multithread();
#ifdef GLX_DIRECT_RENDERING
/* Bind the direct rendering context to the drawable */
if (gc && gc->driContext) {
__GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc, pre13);
__GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc, pre13);
/* Bind the direct rendering context to the drawable */
if (gc && gc->driContext) {
__GLXDRIdrawable *pdraw = FetchDRIDrawable(dpy, draw, gc, pre13);
__GLXDRIdrawable *pread = FetchDRIDrawable(dpy, read, gc, pre13);
bindReturnValue =
(gc->driContext->bindContext) (gc->driContext, pdraw, pread);
} else
bindReturnValue =
(gc->driContext->bindContext) (gc->driContext, pdraw, pread);
}
else
#endif
{
/* Send a glXMakeCurrent request to bind the new context. */
bindReturnValue =
SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
((dpy != oldGC->currentDpy) || oldGC->isDirect)
? None : oldGC->currentContextTag,
draw, read, &reply);
}
{
/* Send a glXMakeCurrent request to bind the new context. */
bindReturnValue =
SendMakeCurrentRequest(dpy, opcode, gc ? gc->xid : None,
((dpy != oldGC->currentDpy)
|| oldGC->isDirect)
? None : oldGC->currentContextTag, draw, read,
&reply);
}
if (!bindReturnValue) {
return False;
}
if (!bindReturnValue) {
return False;
}
#ifdef GLX_DIRECT_RENDERING
if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) &&
!oldGC->isDirect && oldGC != &dummyContext) {
if ((dpy != oldGC->currentDpy || (gc && gc->driContext)) &&
!oldGC->isDirect && oldGC != &dummyContext) {
#else
if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) {
if ((dpy != oldGC->currentDpy) && oldGC != &dummyContext) {
#endif
xGLXMakeCurrentReply dummy_reply;
xGLXMakeCurrentReply dummy_reply;
/* We are either switching from one dpy to another and have to
* send a request to the previous dpy to unbind the previous
* context, or we are switching away from a indirect context to
* a direct context and have to send a request to the dpy to
* unbind the previous context.
*/
(void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
oldGC->currentContextTag, None, None,
& dummy_reply);
}
/* We are either switching from one dpy to another and have to
* send a request to the previous dpy to unbind the previous
* context, or we are switching away from a indirect context to
* a direct context and have to send a request to the dpy to
* unbind the previous context.
*/
(void) SendMakeCurrentRequest(oldGC->currentDpy, oldOpcode, None,
oldGC->currentContextTag, None, None,
&dummy_reply);
}
#ifdef GLX_DIRECT_RENDERING
else if (oldGC->driContext) {
oldGC->driContext->unbindContext(oldGC->driContext);
}
else if (oldGC->driContext) {
oldGC->driContext->unbindContext(oldGC->driContext);
}
#endif
/* Update our notion of what is current */
__glXLock();
if (gc == oldGC) {
/* Even though the contexts are the same the drawable might have
* changed. Note that gc cannot be the dummy, and that oldGC
* cannot be NULL, therefore if they are the same, gc is not
* NULL and not the dummy.
*/
gc->currentDrawable = draw;
gc->currentReadable = read;
} else {
if (oldGC != &dummyContext) {
/* Old current context is no longer current to anybody */
oldGC->currentDpy = 0;
oldGC->currentDrawable = None;
oldGC->currentReadable = None;
oldGC->currentContextTag = 0;
/* Update our notion of what is current */
__glXLock();
if (gc == oldGC) {
/* Even though the contexts are the same the drawable might have
* changed. Note that gc cannot be the dummy, and that oldGC
* cannot be NULL, therefore if they are the same, gc is not
* NULL and not the dummy.
*/
gc->currentDrawable = draw;
gc->currentReadable = read;
}
else {
if (oldGC != &dummyContext) {
/* Old current context is no longer current to anybody */
oldGC->currentDpy = 0;
oldGC->currentDrawable = None;
oldGC->currentReadable = None;
oldGC->currentContextTag = 0;
if (oldGC->xid == None) {
/* We are switching away from a context that was
* previously destroyed, so we need to free the memory
* for the old handle.
*/
if (oldGC->xid == None) {
/* We are switching away from a context that was
* previously destroyed, so we need to free the memory
* for the old handle.
*/
#ifdef GLX_DIRECT_RENDERING
/* Destroy the old direct rendering context */
if (oldGC->driContext) {
oldGC->driContext->destroyContext(oldGC->driContext,
oldGC->psc,
oldGC->createDpy);
oldGC->driContext = NULL;
}
/* Destroy the old direct rendering context */
if (oldGC->driContext) {
oldGC->driContext->destroyContext(oldGC->driContext,
oldGC->psc,
oldGC->createDpy);
oldGC->driContext = NULL;
}
#endif
__glXFreeContext(oldGC);
}
}
if (gc) {
__glXSetCurrentContext(gc);
__glXFreeContext(oldGC);
}
}
if (gc) {
__glXSetCurrentContext(gc);
gc->currentDpy = dpy;
gc->currentDrawable = draw;
gc->currentReadable = read;
gc->currentDpy = dpy;
gc->currentDrawable = draw;
gc->currentReadable = read;
#ifdef GLX_DIRECT_RENDERING
if (!gc->driContext) {
#ifdef GLX_DIRECT_RENDERING
if (!gc->driContext) {
#endif
if (!IndirectAPI)
IndirectAPI = __glXNewIndirectAPI();
_glapi_set_dispatch(IndirectAPI);
if (!IndirectAPI)
IndirectAPI = __glXNewIndirectAPI();
_glapi_set_dispatch(IndirectAPI);
#ifdef GLX_USE_APPLEGL
do {
extern void XAppleDRIUseIndirectDispatch(void);
XAppleDRIUseIndirectDispatch();
} while (0);
do {
extern void XAppleDRIUseIndirectDispatch(void);
XAppleDRIUseIndirectDispatch();
} while (0);
#endif
__GLXattribute *state =
(__GLXattribute *)(gc->client_state_private);
__GLXattribute *state =
(__GLXattribute *) (gc->client_state_private);
gc->currentContextTag = reply.contextTag;
if (state->array_state == NULL) {
(void) glGetString(GL_EXTENSIONS);
(void) glGetString(GL_VERSION);
__glXInitVertexArrayState(gc);
}
#ifdef GLX_DIRECT_RENDERING
}
else {
gc->currentContextTag = -1;
}
gc->currentContextTag = reply.contextTag;
if (state->array_state == NULL) {
(void) glGetString(GL_EXTENSIONS);
(void) glGetString(GL_VERSION);
__glXInitVertexArrayState(gc);
}
#ifdef GLX_DIRECT_RENDERING
}
else {
gc->currentContextTag = -1;
}
#endif
} else {
__glXSetCurrentContextNull();
}
}
__glXUnlock();
return GL_TRUE;
}
else {
__glXSetCurrentContextNull();
}
}
__glXUnlock();
return GL_TRUE;
}
PUBLIC Bool glXMakeCurrent(Display *dpy, GLXDrawable draw, GLXContext gc)
PUBLIC Bool
glXMakeCurrent(Display * dpy, GLXDrawable draw, GLXContext gc)
{
return MakeContextCurrent(dpy, draw, draw, gc, True);
return MakeContextCurrent(dpy, draw, draw, gc, True);
}
PUBLIC GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
(Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
(dpy, d, r, ctx, False), MakeContextCurrent)
PUBLIC
GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
(Display * dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
(dpy, d, r, ctx, False), MakeContextCurrent)
PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
(Display *dpy, GLXDrawable d, GLXDrawable r, GLXContext ctx),
(dpy, d, r, ctx, False), MakeContextCurrent)
PUBLIC GLX_ALIAS(Bool, glXMakeContextCurrent,
(Display * dpy, GLXDrawable d, GLXDrawable r,
GLXContext ctx), (dpy, d, r, ctx, False),
MakeContextCurrent)
+669 -653
View File
File diff suppressed because it is too large Load Diff
+184 -178
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2002, 2004
* All Rights Reserved.
@@ -48,27 +49,29 @@
#define EXT_ENABLED(bit,supported) (IS_SET( supported, bit ))
struct extension_info {
const char * const name;
unsigned name_len;
struct extension_info
{
const char *const name;
unsigned name_len;
unsigned char bit;
unsigned char bit;
/* This is the lowest version of GLX that "requires" this extension.
* For example, GLX 1.3 requires SGIX_fbconfig, SGIX_pbuffer, and
* SGI_make_current_read. If the extension is not required by any known
* version of GLX, use 0, 0.
*/
unsigned char version_major;
unsigned char version_minor;
unsigned char client_support;
unsigned char direct_support;
unsigned char client_only; /** Is the extension client-side only? */
unsigned char direct_only; /** Is the extension for direct
unsigned char version_major;
unsigned char version_minor;
unsigned char client_support;
unsigned char direct_support;
unsigned char client_only; /** Is the extension client-side only? */
unsigned char direct_only; /** Is the extension for direct
* contexts only?
*/
};
/* *INDENT-OFF* */
static const struct extension_info known_glx_extensions[] = {
{ GLX(ARB_get_proc_address), VER(1,4), Y, N, Y, N },
{ GLX(ARB_multisample), VER(1,4), Y, Y, N, N },
@@ -245,14 +248,15 @@ static const struct extension_info known_gl_extensions[] = {
{ GL(SUN_slice_accum), VER(0,0), Y, N, N, N },
{ NULL }
};
/* *INDENT-ON* */
/* global bit-fields of available extensions and their characteristics */
static unsigned char client_glx_support[8];
static unsigned char client_glx_only[8];
static unsigned char direct_glx_only[8];
static unsigned char client_gl_support[ __GL_EXT_BYTES ];
static unsigned char client_gl_only[ __GL_EXT_BYTES ];
static unsigned char client_gl_support[__GL_EXT_BYTES];
static unsigned char client_gl_only[__GL_EXT_BYTES];
/**
* Bits representing the set of extensions that are enabled by default in all
@@ -267,12 +271,13 @@ static const unsigned gl_major = 1;
static const unsigned gl_minor = 4;
/* client extensions string */
static const char * __glXGLXClientExtensions = NULL;
static const char *__glXGLXClientExtensions = NULL;
static void __glXExtensionsCtr( void );
static void __glXExtensionsCtrScreen( __GLXscreenConfigs *psc );
static void __glXProcessServerString( const struct extension_info * ext,
const char * server_string, unsigned char * server_support );
static void __glXExtensionsCtr(void);
static void __glXExtensionsCtrScreen(__GLXscreenConfigs * psc);
static void __glXProcessServerString(const struct extension_info *ext,
const char *server_string,
unsigned char *server_support);
/**
* Set the state of a GLX extension.
@@ -283,24 +288,24 @@ static void __glXProcessServerString( const struct extension_info * ext,
* \param supported Table in which the state of the extension is to be set.
*/
static void
set_glx_extension( const struct extension_info * ext,
const char * name, unsigned name_len, GLboolean state,
unsigned char * supported )
set_glx_extension(const struct extension_info *ext,
const char *name, unsigned name_len, GLboolean state,
unsigned char *supported)
{
unsigned i;
unsigned i;
for ( i = 0 ; ext[i].name != NULL ; i++ ) {
if ( (name_len == ext[i].name_len)
&& (strncmp( ext[i].name, name, name_len ) == 0) ) {
if ( state ) {
SET_BIT( supported, ext[i].bit );
}
else {
CLR_BIT( supported, ext[i].bit );
}
for (i = 0; ext[i].name != NULL; i++) {
if ((name_len == ext[i].name_len)
&& (strncmp(ext[i].name, name, name_len) == 0)) {
if (state) {
SET_BIT(supported, ext[i].bit);
}
else {
CLR_BIT(supported, ext[i].bit);
}
return;
return;
}
}
}
@@ -321,49 +326,47 @@ set_glx_extension( const struct extension_info * ext,
* the data pointed by \c server_support must be preinitialized to zero.
*/
static void
__glXProcessServerString( const struct extension_info * ext,
const char * server_string,
unsigned char * server_support )
__glXProcessServerString(const struct extension_info *ext,
const char *server_string,
unsigned char *server_support)
{
unsigned base;
unsigned len;
unsigned base;
unsigned len;
for ( base = 0 ; server_string[ base ] != NUL ; /* empty */ ) {
for (base = 0; server_string[base] != NUL; /* empty */ ) {
/* Determine the length of the next extension name.
*/
for ( len = 0
; (server_string[ base + len ] != SEPARATOR)
&& (server_string[ base + len ] != NUL)
; len++ ) {
/* empty */
for (len = 0; (server_string[base + len] != SEPARATOR)
&& (server_string[base + len] != NUL);
len++) {
/* empty */
}
/* Set the bit for the extension in the server_support table.
*/
set_glx_extension( ext, & server_string[ base ], len, GL_TRUE,
server_support );
set_glx_extension(ext, &server_string[base], len, GL_TRUE,
server_support);
/* Advance to the next extension string. This means that we skip
* over the previous string and any trialing white-space.
*/
for ( base += len ;
(server_string[ base ] == SEPARATOR)
&& (server_string[ base ] != NUL)
; base++ ) {
/* empty */
for (base += len; (server_string[base] == SEPARATOR)
&& (server_string[base] != NUL);
base++) {
/* empty */
}
}
}
void
__glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name)
__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name)
{
__glXExtensionsCtr();
__glXExtensionsCtrScreen(psc);
__glXExtensionsCtr();
__glXExtensionsCtrScreen(psc);
set_glx_extension(known_glx_extensions,
name, strlen(name), GL_TRUE, psc->direct_support);
set_glx_extension(known_glx_extensions,
name, strlen(name), GL_TRUE, psc->direct_support);
}
/**
@@ -371,58 +374,58 @@ __glXEnableDirectExtension(__GLXscreenConfigs *psc, const char *name)
*/
static void
__glXExtensionsCtr( void )
__glXExtensionsCtr(void)
{
unsigned i;
unsigned i;
static GLboolean ext_list_first_time = GL_TRUE;
if ( ext_list_first_time ) {
if (ext_list_first_time) {
ext_list_first_time = GL_FALSE;
(void) memset( client_glx_support, 0, sizeof( client_glx_support ) );
(void) memset( direct_glx_support, 0, sizeof( direct_glx_support ) );
(void) memset( client_glx_only, 0, sizeof( client_glx_only ) );
(void) memset( direct_glx_only, 0, sizeof( direct_glx_only ) );
(void) memset(client_glx_support, 0, sizeof(client_glx_support));
(void) memset(direct_glx_support, 0, sizeof(direct_glx_support));
(void) memset(client_glx_only, 0, sizeof(client_glx_only));
(void) memset(direct_glx_only, 0, sizeof(direct_glx_only));
(void) memset( client_gl_support, 0, sizeof( client_gl_support ) );
(void) memset( client_gl_only, 0, sizeof( client_gl_only ) );
(void) memset(client_gl_support, 0, sizeof(client_gl_support));
(void) memset(client_gl_only, 0, sizeof(client_gl_only));
for ( i = 0 ; known_glx_extensions[i].name != NULL ; i++ ) {
const unsigned bit = known_glx_extensions[i].bit;
for (i = 0; known_glx_extensions[i].name != NULL; i++) {
const unsigned bit = known_glx_extensions[i].bit;
if ( known_glx_extensions[i].client_support ) {
SET_BIT( client_glx_support, bit );
}
if (known_glx_extensions[i].client_support) {
SET_BIT(client_glx_support, bit);
}
if ( known_glx_extensions[i].direct_support ) {
SET_BIT( direct_glx_support, bit );
}
if (known_glx_extensions[i].direct_support) {
SET_BIT(direct_glx_support, bit);
}
if ( known_glx_extensions[i].client_only ) {
SET_BIT( client_glx_only, bit );
}
if (known_glx_extensions[i].client_only) {
SET_BIT(client_glx_only, bit);
}
if ( known_glx_extensions[i].direct_only ) {
SET_BIT( direct_glx_only, bit );
}
if (known_glx_extensions[i].direct_only) {
SET_BIT(direct_glx_only, bit);
}
}
for ( i = 0 ; known_gl_extensions[i].name != NULL ; i++ ) {
const unsigned bit = known_gl_extensions[i].bit;
for (i = 0; known_gl_extensions[i].name != NULL; i++) {
const unsigned bit = known_gl_extensions[i].bit;
if ( known_gl_extensions[i].client_support ) {
SET_BIT( client_gl_support, bit );
}
if (known_gl_extensions[i].client_support) {
SET_BIT(client_gl_support, bit);
}
if ( known_gl_extensions[i].client_only ) {
SET_BIT( client_gl_only, bit );
}
if (known_gl_extensions[i].client_only) {
SET_BIT(client_gl_only, bit);
}
}
#if 0
fprintf( stderr, "[%s:%u] Maximum client library version: %u.%u\n",
__func__, __LINE__, gl_major, gl_minor );
fprintf(stderr, "[%s:%u] Maximum client library version: %u.%u\n",
__func__, __LINE__, gl_major, gl_minor);
#endif
}
}
@@ -435,13 +438,13 @@ __glXExtensionsCtr( void )
*/
static void
__glXExtensionsCtrScreen( __GLXscreenConfigs *psc )
__glXExtensionsCtrScreen(__GLXscreenConfigs * psc)
{
if (psc->ext_list_first_time) {
psc->ext_list_first_time = GL_FALSE;
(void) memcpy( psc->direct_support, direct_glx_support,
sizeof( direct_glx_support ) );
}
if (psc->ext_list_first_time) {
psc->ext_list_first_time = GL_FALSE;
(void) memcpy(psc->direct_support, direct_glx_support,
sizeof(direct_glx_support));
}
}
@@ -455,14 +458,14 @@ __glXExtensionsCtrScreen( __GLXscreenConfigs *psc )
* \c NULL, then \c GL_FALSE is returned.
*/
GLboolean
__glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit )
__glXExtensionBitIsEnabled(__GLXscreenConfigs * psc, unsigned bit)
{
GLboolean enabled = GL_FALSE;
if ( psc != NULL ) {
if (psc != NULL) {
__glXExtensionsCtr();
__glXExtensionsCtrScreen( psc );
enabled = EXT_ENABLED( bit, psc->direct_support );
__glXExtensionsCtrScreen(psc);
enabled = EXT_ENABLED(bit, psc->direct_support);
}
return enabled;
@@ -474,12 +477,12 @@ __glXExtensionBitIsEnabled( __GLXscreenConfigs *psc, unsigned bit )
*
*/
GLboolean
__glExtensionBitIsEnabled( const __GLXcontext * gc, unsigned bit )
__glExtensionBitIsEnabled(const __GLXcontext * gc, unsigned bit)
{
GLboolean enabled = GL_FALSE;
if ( gc != NULL ) {
enabled = EXT_ENABLED( bit, gc->gl_extension_bits );
if (gc != NULL) {
enabled = EXT_ENABLED(bit, gc->gl_extension_bits);
}
return enabled;
@@ -491,34 +494,34 @@ __glExtensionBitIsEnabled( const __GLXcontext * gc, unsigned bit )
* Convert a bit-field to a string of supported extensions.
*/
static char *
__glXGetStringFromTable( const struct extension_info * ext,
const unsigned char * supported )
__glXGetStringFromTable(const struct extension_info *ext,
const unsigned char *supported)
{
unsigned i;
unsigned ext_str_len;
char * ext_str;
char * point;
unsigned i;
unsigned ext_str_len;
char *ext_str;
char *point;
ext_str_len = 0;
for ( i = 0 ; ext[i].name != NULL ; i++ ) {
if ( EXT_ENABLED( ext[i].bit, supported ) ) {
ext_str_len += ext[i].name_len + 1;
for (i = 0; ext[i].name != NULL; i++) {
if (EXT_ENABLED(ext[i].bit, supported)) {
ext_str_len += ext[i].name_len + 1;
}
}
ext_str = Xmalloc( ext_str_len + 1 );
if ( ext_str != NULL ) {
ext_str = Xmalloc(ext_str_len + 1);
if (ext_str != NULL) {
point = ext_str;
for ( i = 0 ; ext[i].name != NULL ; i++ ) {
if ( EXT_ENABLED( ext[i].bit, supported ) ) {
(void) memcpy( point, ext[i].name, ext[i].name_len );
point += ext[i].name_len;
for (i = 0; ext[i].name != NULL; i++) {
if (EXT_ENABLED(ext[i].bit, supported)) {
(void) memcpy(point, ext[i].name, ext[i].name_len);
point += ext[i].name_len;
*point = ' ';
point++;
}
*point = ' ';
point++;
}
}
*point = '\0';
@@ -532,12 +535,12 @@ __glXGetStringFromTable( const struct extension_info * ext,
* Get the string of client library supported extensions.
*/
const char *
__glXGetClientExtensions( void )
__glXGetClientExtensions(void)
{
if ( __glXGLXClientExtensions == NULL ) {
if (__glXGLXClientExtensions == NULL) {
__glXExtensionsCtr();
__glXGLXClientExtensions = __glXGetStringFromTable( known_glx_extensions,
client_glx_support );
__glXGLXClientExtensions = __glXGetStringFromTable(known_glx_extensions,
client_glx_support);
}
return __glXGLXClientExtensions;
@@ -555,20 +558,20 @@ __glXGetClientExtensions( void )
*/
void
__glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
GLboolean display_is_direct_capable,
int minor_version )
__glXCalculateUsableExtensions(__GLXscreenConfigs * psc,
GLboolean display_is_direct_capable,
int minor_version)
{
unsigned char server_support[8];
unsigned char usable[8];
unsigned i;
unsigned i;
__glXExtensionsCtr();
__glXExtensionsCtrScreen( psc );
__glXExtensionsCtrScreen(psc);
(void) memset( server_support, 0, sizeof( server_support ) );
__glXProcessServerString( known_glx_extensions,
psc->serverGLXexts, server_support );
(void) memset(server_support, 0, sizeof(server_support));
__glXProcessServerString(known_glx_extensions,
psc->serverGLXexts, server_support);
/* This is a hack. Some servers support GLX 1.3 but don't export
@@ -577,20 +580,20 @@ __glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
* "emulated" as well.
*/
if ( minor_version >= 3 ) {
SET_BIT( server_support, EXT_visual_info_bit );
SET_BIT( server_support, EXT_visual_rating_bit );
SET_BIT( server_support, SGI_make_current_read_bit );
SET_BIT( server_support, SGIX_fbconfig_bit );
SET_BIT( server_support, SGIX_pbuffer_bit );
if (minor_version >= 3) {
SET_BIT(server_support, EXT_visual_info_bit);
SET_BIT(server_support, EXT_visual_rating_bit);
SET_BIT(server_support, SGI_make_current_read_bit);
SET_BIT(server_support, SGIX_fbconfig_bit);
SET_BIT(server_support, SGIX_pbuffer_bit);
/* This one is a little iffy. GLX 1.3 doesn't incorporate all of this
* extension. However, the only part that is not strictly client-side
* is shared. That's the glXQueryContext / glXQueryContextInfoEXT
* function.
*/
SET_BIT( server_support, EXT_import_context_bit );
SET_BIT(server_support, EXT_import_context_bit);
}
@@ -604,22 +607,24 @@ __glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
* support it.
*/
if ( display_is_direct_capable ) {
for ( i = 0 ; i < 8 ; i++ ) {
usable[i] = (client_glx_support[i] & client_glx_only[i])
| (client_glx_support[i] & psc->direct_support[i] & server_support[i])
| (client_glx_support[i] & psc->direct_support[i] & direct_glx_only[i]);
if (display_is_direct_capable) {
for (i = 0; i < 8; i++) {
usable[i] = (client_glx_support[i] & client_glx_only[i])
| (client_glx_support[i] & psc->
direct_support[i] & server_support[i])
| (client_glx_support[i] & psc->
direct_support[i] & direct_glx_only[i]);
}
}
else {
for ( i = 0 ; i < 8 ; i++ ) {
usable[i] = (client_glx_support[i] & client_glx_only[i])
| (client_glx_support[i] & server_support[i]);
for (i = 0; i < 8; i++) {
usable[i] = (client_glx_support[i] & client_glx_only[i])
| (client_glx_support[i] & server_support[i]);
}
}
psc->effectiveGLXexts = __glXGetStringFromTable( known_glx_extensions,
usable );
psc->effectiveGLXexts = __glXGetStringFromTable(known_glx_extensions,
usable);
}
@@ -634,32 +639,33 @@ __glXCalculateUsableExtensions( __GLXscreenConfigs *psc,
*/
void
__glXCalculateUsableGLExtensions( __GLXcontext * gc,
const char * server_string,
int major_version, int minor_version )
__glXCalculateUsableGLExtensions(__GLXcontext * gc,
const char *server_string,
int major_version, int minor_version)
{
unsigned char server_support[ __GL_EXT_BYTES ];
unsigned char usable[ __GL_EXT_BYTES ];
unsigned i;
unsigned char server_support[__GL_EXT_BYTES];
unsigned char usable[__GL_EXT_BYTES];
unsigned i;
__glXExtensionsCtr();
(void) memset( server_support, 0, sizeof( server_support ) );
__glXProcessServerString( known_gl_extensions, server_string,
server_support );
(void) memset(server_support, 0, sizeof(server_support));
__glXProcessServerString(known_gl_extensions, server_string,
server_support);
/* Handle lazy servers that don't export all the extensions strings that
* are part of the GL core version that they support.
*/
for ( i = 0 ; i < __GL_EXT_BYTES ; i++ ) {
if ( (known_gl_extensions[i].version_major != 0)
&& ((major_version > known_gl_extensions[i].version_major)
|| ((major_version == known_gl_extensions[i].version_major)
&& (minor_version >= known_gl_extensions[i].version_minor))) ) {
SET_BIT( server_support, known_gl_extensions[i].bit );
for (i = 0; i < __GL_EXT_BYTES; i++) {
if ((known_gl_extensions[i].version_major != 0)
&& ((major_version > known_gl_extensions[i].version_major)
|| ((major_version == known_gl_extensions[i].version_major)
&& (minor_version >=
known_gl_extensions[i].version_minor)))) {
SET_BIT(server_support, known_gl_extensions[i].bit);
}
}
@@ -669,14 +675,14 @@ __glXCalculateUsableGLExtensions( __GLXcontext * gc,
* and it only needs client-side support.
*/
for ( i = 0 ; i < __GL_EXT_BYTES ; i++ ) {
for (i = 0; i < __GL_EXT_BYTES; i++) {
usable[i] = (client_gl_support[i] & client_gl_only[i])
| (client_gl_support[i] & server_support[i]);
| (client_gl_support[i] & server_support[i]);
}
gc->extensions = (unsigned char *)
__glXGetStringFromTable( known_gl_extensions, usable );
(void) memcpy( gc->gl_extension_bits, usable, sizeof( usable ) );
gc->extensions = (unsigned char *)
__glXGetStringFromTable(known_gl_extensions, usable);
(void) memcpy(gc->gl_extension_bits, usable, sizeof(usable));
}
@@ -685,11 +691,11 @@ __glXCalculateUsableGLExtensions( __GLXcontext * gc,
* rendering.
*/
void
__glXGetGLVersion( int * major_version, int * minor_version )
{
__glXExtensionsCtr();
*major_version = gl_major;
*minor_version = gl_minor;
__glXGetGLVersion(int *major_version, int *minor_version)
{
__glXExtensionsCtr();
*major_version = gl_major;
*minor_version = gl_minor;
}
@@ -699,8 +705,8 @@ __glXGetGLVersion( int * major_version, int * minor_version )
* supported by the client to the server.
*/
char *
__glXGetClientGLExtensionString( void )
__glXGetClientGLExtensionString(void)
{
__glXExtensionsCtr();
return __glXGetStringFromTable( known_gl_extensions, client_gl_support );
__glXExtensionsCtr();
return __glXGetStringFromTable(known_gl_extensions, client_gl_support);
}
+33 -24
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2002, 2004
* All Rights Reserved.
@@ -31,7 +32,8 @@
#ifndef GLX_GLXEXTENSIONS_H
#define GLX_GLXEXTENSIONS_H
enum {
enum
{
ARB_get_proc_address_bit = 0,
ARB_multisample_bit,
ARB_render_texture_bit,
@@ -40,7 +42,7 @@ enum {
EXT_visual_rating_bit,
EXT_import_context_bit,
MESA_agp_offset_bit,
MESA_allocate_memory_bit, /* Replaces MESA_agp_offset & NV_vertex_array_range */
MESA_allocate_memory_bit, /* Replaces MESA_agp_offset & NV_vertex_array_range */
MESA_copy_sub_buffer_bit,
MESA_depth_float_bit,
MESA_pixmap_colormap_bit,
@@ -67,7 +69,8 @@ enum {
EXT_texture_from_pixmap_bit
};
enum {
enum
{
GL_ARB_depth_texture_bit = 0,
GL_ARB_draw_buffers_bit,
GL_ARB_fragment_program_bit,
@@ -230,28 +233,34 @@ enum {
struct __GLXscreenConfigsRec;
struct __GLXcontextRec;
extern GLboolean __glXExtensionBitIsEnabled( struct __GLXscreenConfigsRec *psc, unsigned bit );
extern const char * __glXGetClientExtensions( void );
extern void __glXCalculateUsableExtensions( struct __GLXscreenConfigsRec *psc,
GLboolean display_is_direct_capable, int server_minor_version );
extern GLboolean __glXExtensionBitIsEnabled(struct __GLXscreenConfigsRec *psc,
unsigned bit);
extern const char *__glXGetClientExtensions(void);
extern void __glXCalculateUsableExtensions(struct __GLXscreenConfigsRec *psc,
GLboolean
display_is_direct_capable,
int server_minor_version);
extern void __glXCalculateUsableGLExtensions( struct __GLXcontextRec * gc,
const char * server_string, int major_version, int minor_version );
extern void __glXGetGLVersion( int * major_version, int * minor_version );
extern char * __glXGetClientGLExtensionString( void );
extern void __glXCalculateUsableGLExtensions(struct __GLXcontextRec *gc,
const char *server_string,
int major_version,
int minor_version);
extern void __glXGetGLVersion(int *major_version, int *minor_version);
extern char *__glXGetClientGLExtensionString(void);
extern GLboolean __glExtensionBitIsEnabled( const struct __GLXcontextRec * gc,
unsigned bit );
extern GLboolean __glExtensionBitIsEnabled(const struct __GLXcontextRec *gc,
unsigned bit);
extern void
__glXEnableDirectExtension(struct __GLXscreenConfigsRec *psc, const char *name);
__glXEnableDirectExtension(struct __GLXscreenConfigsRec *psc,
const char *name);
/* Source-level backwards compatibility with old drivers. They won't
* find the respective functions, though.
*/
typedef void (* PFNGLXENABLEEXTENSIONPROC) ( const char * name,
GLboolean force_client );
typedef void (* PFNGLXDISABLEEXTENSIONPROC) ( const char * name );
typedef void (*PFNGLXENABLEEXTENSIONPROC) (const char *name,
GLboolean force_client);
typedef void (*PFNGLXDISABLEEXTENSIONPROC) (const char *name);
/* GLX_ALIAS should be used for functions with a non-void return type.
GLX_ALIAS_VOID is for functions with a void return type. */
@@ -261,17 +270,17 @@ typedef void (* PFNGLXDISABLEEXTENSIONPROC) ( const char * name );
#else
# if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
# define GLX_ALIAS(return_type, real_func, proto_args, args, aliased_func) \
return_type real_func proto_args \
__attribute__ ((alias( # aliased_func ) ));
return_type real_func proto_args \
__attribute__ ((alias( # aliased_func ) ));
# define GLX_ALIAS_VOID(real_func, proto_args, args, aliased_func) \
GLX_ALIAS(void, real_func, proto_args, args, aliased_func)
GLX_ALIAS(void, real_func, proto_args, args, aliased_func)
# else
# define GLX_ALIAS(return_type, real_func, proto_args, args, aliased_func) \
return_type real_func proto_args \
{ return aliased_func args ; }
return_type real_func proto_args \
{ return aliased_func args ; }
# define GLX_ALIAS_VOID(real_func, proto_args, args, aliased_func) \
void real_func proto_args \
{ aliased_func args ; }
void real_func proto_args \
{ aliased_func args ; }
# endif /* __GNUC__ */
#endif /* GLX_NO_STATIC_EXTENSION_FUNCTIONS */
+279 -231
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/* glxhash.c -- Small hash table support for integer -> integer mapping
* Taken from libdrm.
*
@@ -80,8 +81,8 @@
#define HASH_MAGIC 0xdeadbeef
#define HASH_DEBUG 0
#define HASH_SIZE 512 /* Good for about 100 entries */
/* If you change this value, you probably
#define HASH_SIZE 512 /* Good for about 100 entries */
/* If you change this value, you probably
have to change the HashHash hashing
function! */
@@ -92,323 +93,370 @@
#define HASH_RANDOM random()
#define HASH_RANDOM_DESTROY
typedef struct __glxHashBucket {
unsigned long key;
void *value;
struct __glxHashBucket *next;
typedef struct __glxHashBucket
{
unsigned long key;
void *value;
struct __glxHashBucket *next;
} __glxHashBucket, *__glxHashBucketPtr;
typedef struct __glxHashTable *__glxHashTablePtr;
struct __glxHashTable {
unsigned long magic;
unsigned long hits; /* At top of linked list */
unsigned long partials; /* Not at top of linked list */
unsigned long misses; /* Not in table */
__glxHashBucketPtr buckets[HASH_SIZE];
int p0;
__glxHashBucketPtr p1;
struct __glxHashTable
{
unsigned long magic;
unsigned long hits; /* At top of linked list */
unsigned long partials; /* Not at top of linked list */
unsigned long misses; /* Not in table */
__glxHashBucketPtr buckets[HASH_SIZE];
int p0;
__glxHashBucketPtr p1;
};
static unsigned long HashHash(unsigned long key)
static unsigned long
HashHash(unsigned long key)
{
unsigned long hash = 0;
unsigned long tmp = key;
static int init = 0;
static unsigned long scatter[256];
int i;
unsigned long hash = 0;
unsigned long tmp = key;
static int init = 0;
static unsigned long scatter[256];
int i;
if (!init) {
HASH_RANDOM_DECL;
HASH_RANDOM_INIT(37);
for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
HASH_RANDOM_DESTROY;
++init;
}
if (!init) {
HASH_RANDOM_DECL;
HASH_RANDOM_INIT(37);
for (i = 0; i < 256; i++)
scatter[i] = HASH_RANDOM;
HASH_RANDOM_DESTROY;
++init;
}
while (tmp) {
hash = (hash << 1) + scatter[tmp & 0xff];
tmp >>= 8;
}
while (tmp) {
hash = (hash << 1) + scatter[tmp & 0xff];
tmp >>= 8;
}
hash %= HASH_SIZE;
hash %= HASH_SIZE;
#if HASH_DEBUG
printf( "Hash(%d) = %d\n", key, hash);
printf("Hash(%d) = %d\n", key, hash);
#endif
return hash;
return hash;
}
_X_HIDDEN __glxHashTable *__glxHashCreate(void)
_X_HIDDEN __glxHashTable *
__glxHashCreate(void)
{
__glxHashTablePtr table;
int i;
__glxHashTablePtr table;
int i;
table = HASH_ALLOC(sizeof(*table));
if (!table) return NULL;
table->magic = HASH_MAGIC;
table->hits = 0;
table->partials = 0;
table->misses = 0;
table = HASH_ALLOC(sizeof(*table));
if (!table)
return NULL;
table->magic = HASH_MAGIC;
table->hits = 0;
table->partials = 0;
table->misses = 0;
for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
return table;
for (i = 0; i < HASH_SIZE; i++)
table->buckets[i] = NULL;
return table;
}
_X_HIDDEN int __glxHashDestroy(__glxHashTable *t)
_X_HIDDEN int
__glxHashDestroy(__glxHashTable * t)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
__glxHashBucketPtr bucket;
__glxHashBucketPtr next;
int i;
__glxHashTablePtr table = (__glxHashTablePtr) t;
__glxHashBucketPtr bucket;
__glxHashBucketPtr next;
int i;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (table->magic != HASH_MAGIC)
return -1; /* Bad magic */
for (i = 0; i < HASH_SIZE; i++) {
for (bucket = table->buckets[i]; bucket;) {
next = bucket->next;
HASH_FREE(bucket);
bucket = next;
}
}
HASH_FREE(table);
return 0;
for (i = 0; i < HASH_SIZE; i++) {
for (bucket = table->buckets[i]; bucket;) {
next = bucket->next;
HASH_FREE(bucket);
bucket = next;
}
}
HASH_FREE(table);
return 0;
}
/* Find the bucket and organize the list so that this bucket is at the
top. */
static __glxHashBucketPtr HashFind(__glxHashTablePtr table,
unsigned long key, unsigned long *h)
static __glxHashBucketPtr
HashFind(__glxHashTablePtr table, unsigned long key, unsigned long *h)
{
unsigned long hash = HashHash(key);
__glxHashBucketPtr prev = NULL;
__glxHashBucketPtr bucket;
unsigned long hash = HashHash(key);
__glxHashBucketPtr prev = NULL;
__glxHashBucketPtr bucket;
if (h) *h = hash;
if (h)
*h = hash;
for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
if (bucket->key == key) {
if (prev) {
/* Organize */
prev->next = bucket->next;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
++table->partials;
} else {
++table->hits;
}
return bucket;
}
prev = bucket;
}
++table->misses;
return NULL;
for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
if (bucket->key == key) {
if (prev) {
/* Organize */
prev->next = bucket->next;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
++table->partials;
}
else {
++table->hits;
}
return bucket;
}
prev = bucket;
}
++table->misses;
return NULL;
}
_X_HIDDEN int __glxHashLookup(__glxHashTable *t,
unsigned long key, void **value)
_X_HIDDEN int
__glxHashLookup(__glxHashTable * t, unsigned long key, void **value)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
__glxHashBucketPtr bucket;
__glxHashTablePtr table = (__glxHashTablePtr) t;
__glxHashBucketPtr bucket;
if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (!table || table->magic != HASH_MAGIC)
return -1; /* Bad magic */
bucket = HashFind(table, key, NULL);
if (!bucket) return 1; /* Not found */
*value = bucket->value;
return 0; /* Found */
bucket = HashFind(table, key, NULL);
if (!bucket)
return 1; /* Not found */
*value = bucket->value;
return 0; /* Found */
}
_X_HIDDEN int __glxHashInsert(__glxHashTable *t,
unsigned long key, void *value)
_X_HIDDEN int
__glxHashInsert(__glxHashTable * t, unsigned long key, void *value)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
__glxHashBucketPtr bucket;
unsigned long hash;
__glxHashTablePtr table = (__glxHashTablePtr) t;
__glxHashBucketPtr bucket;
unsigned long hash;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (table->magic != HASH_MAGIC)
return -1; /* Bad magic */
if (HashFind(table, key, &hash)) return 1; /* Already in table */
if (HashFind(table, key, &hash))
return 1; /* Already in table */
bucket = HASH_ALLOC(sizeof(*bucket));
if (!bucket) return -1; /* Error */
bucket->key = key;
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
bucket = HASH_ALLOC(sizeof(*bucket));
if (!bucket)
return -1; /* Error */
bucket->key = key;
bucket->value = value;
bucket->next = table->buckets[hash];
table->buckets[hash] = bucket;
#if HASH_DEBUG
printf("Inserted %d at %d/%p\n", key, hash, bucket);
printf("Inserted %d at %d/%p\n", key, hash, bucket);
#endif
return 0; /* Added to table */
return 0; /* Added to table */
}
_X_HIDDEN int __glxHashDelete(__glxHashTable *t, unsigned long key)
_X_HIDDEN int
__glxHashDelete(__glxHashTable * t, unsigned long key)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
unsigned long hash;
__glxHashBucketPtr bucket;
__glxHashTablePtr table = (__glxHashTablePtr) t;
unsigned long hash;
__glxHashBucketPtr bucket;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (table->magic != HASH_MAGIC)
return -1; /* Bad magic */
bucket = HashFind(table, key, &hash);
bucket = HashFind(table, key, &hash);
if (!bucket) return 1; /* Not found */
if (!bucket)
return 1; /* Not found */
table->buckets[hash] = bucket->next;
HASH_FREE(bucket);
return 0;
table->buckets[hash] = bucket->next;
HASH_FREE(bucket);
return 0;
}
_X_HIDDEN int __glxHashNext(__glxHashTable *t,
unsigned long *key, void **value)
_X_HIDDEN int
__glxHashNext(__glxHashTable * t, unsigned long *key, void **value)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
__glxHashTablePtr table = (__glxHashTablePtr) t;
while (table->p0 < HASH_SIZE) {
if (table->p1) {
*key = table->p1->key;
*value = table->p1->value;
table->p1 = table->p1->next;
return 1;
}
table->p1 = table->buckets[table->p0];
++table->p0;
}
return 0;
while (table->p0 < HASH_SIZE) {
if (table->p1) {
*key = table->p1->key;
*value = table->p1->value;
table->p1 = table->p1->next;
return 1;
}
table->p1 = table->buckets[table->p0];
++table->p0;
}
return 0;
}
_X_HIDDEN int __glxHashFirst(__glxHashTable *t,
unsigned long *key, void **value)
_X_HIDDEN int
__glxHashFirst(__glxHashTable * t, unsigned long *key, void **value)
{
__glxHashTablePtr table = (__glxHashTablePtr)t;
__glxHashTablePtr table = (__glxHashTablePtr) t;
if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
if (table->magic != HASH_MAGIC)
return -1; /* Bad magic */
table->p0 = 0;
table->p1 = table->buckets[0];
return __glxHashNext(table, key, value);
table->p0 = 0;
table->p1 = table->buckets[0];
return __glxHashNext(table, key, value);
}
#if HASH_MAIN
#define DIST_LIMIT 10
static int dist[DIST_LIMIT];
static void clear_dist(void) {
int i;
static void
clear_dist(void)
{
int i;
for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
for (i = 0; i < DIST_LIMIT; i++)
dist[i] = 0;
}
static int count_entries(__glxHashBucketPtr bucket)
static int
count_entries(__glxHashBucketPtr bucket)
{
int count = 0;
int count = 0;
for (; bucket; bucket = bucket->next) ++count;
return count;
for (; bucket; bucket = bucket->next)
++count;
return count;
}
static void update_dist(int count)
static void
update_dist(int count)
{
if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
else ++dist[count];
if (count >= DIST_LIMIT)
++dist[DIST_LIMIT - 1];
else
++dist[count];
}
static void compute_dist(__glxHashTablePtr table)
static void
compute_dist(__glxHashTablePtr table)
{
int i;
__glxHashBucketPtr bucket;
int i;
__glxHashBucketPtr bucket;
printf("Hits = %ld, partials = %ld, misses = %ld\n",
table->hits, table->partials, table->misses);
clear_dist();
for (i = 0; i < HASH_SIZE; i++) {
bucket = table->buckets[i];
update_dist(count_entries(bucket));
}
for (i = 0; i < DIST_LIMIT; i++) {
if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
else printf("other %10d\n", dist[i]);
}
printf("Hits = %ld, partials = %ld, misses = %ld\n",
table->hits, table->partials, table->misses);
clear_dist();
for (i = 0; i < HASH_SIZE; i++) {
bucket = table->buckets[i];
update_dist(count_entries(bucket));
}
for (i = 0; i < DIST_LIMIT; i++) {
if (i != DIST_LIMIT - 1)
printf("%5d %10d\n", i, dist[i]);
else
printf("other %10d\n", dist[i]);
}
}
static void check_table(__glxHashTablePtr table,
unsigned long key, unsigned long value)
static void
check_table(__glxHashTablePtr table, unsigned long key, unsigned long value)
{
unsigned long retval = 0;
int retcode = __glxHashLookup(table, key, &retval);
unsigned long retval = 0;
int retcode = __glxHashLookup(table, key, &retval);
switch (retcode) {
case -1:
printf("Bad magic = 0x%08lx:"
" key = %lu, expected = %lu, returned = %lu\n",
table->magic, key, value, retval);
break;
case 1:
printf("Not found: key = %lu, expected = %lu returned = %lu\n",
key, value, retval);
break;
case 0:
if (value != retval)
printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
key, value, retval);
break;
default:
printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
retcode, key, value, retval);
break;
}
switch (retcode) {
case -1:
printf("Bad magic = 0x%08lx:"
" key = %lu, expected = %lu, returned = %lu\n",
table->magic, key, value, retval);
break;
case 1:
printf("Not found: key = %lu, expected = %lu returned = %lu\n",
key, value, retval);
break;
case 0:
if (value != retval)
printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
key, value, retval);
break;
default:
printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
retcode, key, value, retval);
break;
}
}
int main(void)
int
main(void)
{
__glxHashTablePtr table;
int i;
__glxHashTablePtr table;
int i;
printf("\n***** 256 consecutive integers ****\n");
table = __glxHashCreate();
for (i = 0; i < 256; i++) __glxHashInsert(table, i, i);
for (i = 0; i < 256; i++) check_table(table, i, i);
for (i = 256; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 256 consecutive integers ****\n");
table = __glxHashCreate();
for (i = 0; i < 256; i++)
__glxHashInsert(table, i, i);
for (i = 0; i < 256; i++)
check_table(table, i, i);
for (i = 256; i >= 0; i--)
check_table(table, i, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 consecutive integers ****\n");
table = __glxHashCreate();
for (i = 0; i < 1024; i++) __glxHashInsert(table, i, i);
for (i = 0; i < 1024; i++) check_table(table, i, i);
for (i = 1024; i >= 0; i--) check_table(table, i, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 consecutive integers ****\n");
table = __glxHashCreate();
for (i = 0; i < 1024; i++)
__glxHashInsert(table, i, i);
for (i = 0; i < 1024; i++)
check_table(table, i, i);
for (i = 1024; i >= 0; i--)
check_table(table, i, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
table = __glxHashCreate();
for (i = 0; i < 1024; i++) __glxHashInsert(table, i*4096, i);
for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
table = __glxHashCreate();
for (i = 0; i < 1024; i++)
__glxHashInsert(table, i * 4096, i);
for (i = 0; i < 1024; i++)
check_table(table, i * 4096, i);
for (i = 1024; i >= 0; i--)
check_table(table, i * 4096, i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 random integers ****\n");
table = __glxHashCreate();
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) __glxHashInsert(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++) check_table(table, random(), i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 1024 random integers ****\n");
table = __glxHashCreate();
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++)
__glxHashInsert(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++)
check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 1024; i++)
check_table(table, random(), i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 5000 random integers ****\n");
table = __glxHashCreate();
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) __glxHashInsert(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++) check_table(table, random(), i);
compute_dist(table);
__glxHashDestroy(table);
printf("\n***** 5000 random integers ****\n");
table = __glxHashCreate();
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++)
__glxHashInsert(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++)
check_table(table, random(), i);
srandom(0xbeefbeef);
for (i = 0; i < 5000; i++)
check_table(table, random(), i);
compute_dist(table);
__glxHashDestroy(table);
return 0;
return 0;
}
#endif
+11 -6
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
#ifndef _GLX_HASH_H_
#define _GLX_HASH_H_
@@ -6,11 +7,15 @@ typedef struct __glxHashTable __glxHashTable;
/* Hash table routines */
extern __glxHashTable *__glxHashCreate(void);
extern int __glxHashDestroy(__glxHashTable *t);
extern int __glxHashLookup(__glxHashTable *t, unsigned long key, void **value);
extern int __glxHashInsert(__glxHashTable *t, unsigned long key, void *value);
extern int __glxHashDelete(__glxHashTable *t, unsigned long key);
extern int __glxHashFirst(__glxHashTable *t, unsigned long *key, void **value);
extern int __glxHashNext(__glxHashTable *t, unsigned long *key, void **value);
extern int __glxHashDestroy(__glxHashTable * t);
extern int __glxHashLookup(__glxHashTable * t, unsigned long key,
void **value);
extern int __glxHashInsert(__glxHashTable * t, unsigned long key,
void *value);
extern int __glxHashDelete(__glxHashTable * t, unsigned long key);
extern int __glxHashFirst(__glxHashTable * t, unsigned long *key,
void **value);
extern int __glxHashNext(__glxHashTable * t, unsigned long *key,
void **value);
#endif /* _GLX_HASH_H_ */
+1
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/**************************************************************************
Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+239 -242
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004
* All Rights Reserved.
@@ -40,31 +41,31 @@
void
__indirect_glGetCompressedTexImageARB( GLenum target, GLint level,
GLvoid * img )
__indirect_glGetCompressedTexImageARB(GLenum target, GLint level,
GLvoid * img)
{
__GLX_SINGLE_DECLARE_VARIABLES();
xGLXGetTexImageReply reply;
size_t image_bytes;
__GLX_SINGLE_DECLARE_VARIABLES();
xGLXGetTexImageReply reply;
size_t image_bytes;
__GLX_SINGLE_LOAD_VARIABLES();
__GLX_SINGLE_BEGIN( X_GLsop_GetCompressedTexImage, 8 );
__GLX_SINGLE_PUT_LONG( 0, target );
__GLX_SINGLE_PUT_LONG( 4, level );
__GLX_SINGLE_READ_XREPLY();
__GLX_SINGLE_LOAD_VARIABLES();
__GLX_SINGLE_BEGIN(X_GLsop_GetCompressedTexImage, 8);
__GLX_SINGLE_PUT_LONG(0, target);
__GLX_SINGLE_PUT_LONG(4, level);
__GLX_SINGLE_READ_XREPLY();
image_bytes = reply.width;
assert( image_bytes <= ((4 * reply.length) - 0) );
assert( image_bytes >= ((4 * reply.length) - 3) );
if ( image_bytes != 0 ) {
_XRead( dpy, (char *) img, image_bytes );
if ( image_bytes < (4 * reply.length) ) {
_XEatData( dpy, (4 * reply.length) - image_bytes );
}
}
image_bytes = reply.width;
assert(image_bytes <= ((4 * reply.length) - 0));
assert(image_bytes >= ((4 * reply.length) - 3));
__GLX_SINGLE_END();
if (image_bytes != 0) {
_XRead(dpy, (char *) img, image_bytes);
if (image_bytes < (4 * reply.length)) {
_XEatData(dpy, (4 * reply.length) - image_bytes);
}
}
__GLX_SINGLE_END();
}
@@ -73,60 +74,59 @@ __indirect_glGetCompressedTexImageARB( GLenum target, GLint level,
* \c glCompressedTexImage2D.
*/
static void
CompressedTexImage1D2D( GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height,
GLint border, GLsizei image_size,
const GLvoid *data, CARD32 rop )
CompressedTexImage1D2D(GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height,
GLint border, GLsizei image_size,
const GLvoid * data, CARD32 rop)
{
__GLX_DECLARE_VARIABLES();
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if ( gc->currentDpy == NULL ) {
return;
}
__GLX_LOAD_VARIABLES();
if (gc->currentDpy == NULL) {
return;
}
if ( (target == GL_PROXY_TEXTURE_1D)
|| (target == GL_PROXY_TEXTURE_2D)
|| (target == GL_PROXY_TEXTURE_CUBE_MAP) ) {
compsize = 0;
}
else {
compsize = image_size;
}
if ((target == GL_PROXY_TEXTURE_1D)
|| (target == GL_PROXY_TEXTURE_2D)
|| (target == GL_PROXY_TEXTURE_CUBE_MAP)) {
compsize = 0;
}
else {
compsize = image_size;
}
cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE
+ compsize );
if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
__GLX_BEGIN_VARIABLE( rop, cmdlen );
__GLX_PUT_LONG( 4, target );
__GLX_PUT_LONG( 8, level );
__GLX_PUT_LONG( 12, internal_format );
__GLX_PUT_LONG( 16, width );
__GLX_PUT_LONG( 20, height );
__GLX_PUT_LONG( 24, border );
__GLX_PUT_LONG( 28, image_size );
if ( compsize != 0 ) {
__GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE,
data, image_size );
}
__GLX_END( cmdlen );
}
else {
assert( compsize != 0 );
cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + compsize);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
__GLX_BEGIN_VARIABLE(rop, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_LONG(8, level);
__GLX_PUT_LONG(12, internal_format);
__GLX_PUT_LONG(16, width);
__GLX_PUT_LONG(20, height);
__GLX_PUT_LONG(24, border);
__GLX_PUT_LONG(28, image_size);
if (compsize != 0) {
__GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE,
data, image_size);
}
__GLX_END(cmdlen);
}
else {
assert(compsize != 0);
__GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 );
__GLX_PUT_LONG( 8, target );
__GLX_PUT_LONG( 12, level );
__GLX_PUT_LONG( 16, internal_format );
__GLX_PUT_LONG( 20, width );
__GLX_PUT_LONG( 24, height );
__GLX_PUT_LONG( 28, border );
__GLX_PUT_LONG( 32, image_size );
__glXSendLargeCommand( gc, gc->pc,
__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4,
data, image_size );
}
__GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_LONG(12, level);
__GLX_PUT_LONG(16, internal_format);
__GLX_PUT_LONG(20, width);
__GLX_PUT_LONG(24, height);
__GLX_PUT_LONG(28, border);
__GLX_PUT_LONG(32, image_size);
__glXSendLargeCommand(gc, gc->pc,
__GLX_COMPRESSED_TEXIMAGE_CMD_HDR_SIZE + 4,
data, image_size);
}
}
@@ -135,213 +135,210 @@ CompressedTexImage1D2D( GLenum target, GLint level,
* \c glCompressedTexSubImage2D.
*/
static void
CompressedTexSubImage1D2D( GLenum target, GLint level,
GLsizei xoffset, GLsizei yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei image_size,
const GLvoid *data, CARD32 rop )
CompressedTexSubImage1D2D(GLenum target, GLint level,
GLsizei xoffset, GLsizei yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei image_size,
const GLvoid * data, CARD32 rop)
{
__GLX_DECLARE_VARIABLES();
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if ( gc->currentDpy == NULL ) {
return;
}
__GLX_LOAD_VARIABLES();
if (gc->currentDpy == NULL) {
return;
}
if ( target == GL_PROXY_TEXTURE_3D ) {
compsize = 0;
}
else {
compsize = image_size;
}
if (target == GL_PROXY_TEXTURE_3D) {
compsize = 0;
}
else {
compsize = image_size;
}
cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE
+ compsize );
if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
__GLX_BEGIN_VARIABLE( rop, cmdlen );
__GLX_PUT_LONG( 4, target );
__GLX_PUT_LONG( 8, level );
__GLX_PUT_LONG( 12, xoffset );
__GLX_PUT_LONG( 16, yoffset );
__GLX_PUT_LONG( 20, width );
__GLX_PUT_LONG( 24, height );
__GLX_PUT_LONG( 28, format );
__GLX_PUT_LONG( 32, image_size );
if ( compsize != 0 ) {
__GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE,
data, image_size );
}
__GLX_END( cmdlen );
}
else {
assert( compsize != 0 );
cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + compsize);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
__GLX_BEGIN_VARIABLE(rop, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_LONG(8, level);
__GLX_PUT_LONG(12, xoffset);
__GLX_PUT_LONG(16, yoffset);
__GLX_PUT_LONG(20, width);
__GLX_PUT_LONG(24, height);
__GLX_PUT_LONG(28, format);
__GLX_PUT_LONG(32, image_size);
if (compsize != 0) {
__GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE,
data, image_size);
}
__GLX_END(cmdlen);
}
else {
assert(compsize != 0);
__GLX_BEGIN_VARIABLE_LARGE( rop, cmdlen + 4 );
__GLX_PUT_LONG( 8, target );
__GLX_PUT_LONG( 12, level );
__GLX_PUT_LONG( 16, xoffset );
__GLX_PUT_LONG( 20, yoffset );
__GLX_PUT_LONG( 24, width );
__GLX_PUT_LONG( 28, height );
__GLX_PUT_LONG( 32, format );
__GLX_PUT_LONG( 36, image_size );
__glXSendLargeCommand( gc, gc->pc,
__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4,
data, image_size );
}
__GLX_BEGIN_VARIABLE_LARGE(rop, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_LONG(12, level);
__GLX_PUT_LONG(16, xoffset);
__GLX_PUT_LONG(20, yoffset);
__GLX_PUT_LONG(24, width);
__GLX_PUT_LONG(28, height);
__GLX_PUT_LONG(32, format);
__GLX_PUT_LONG(36, image_size);
__glXSendLargeCommand(gc, gc->pc,
__GLX_COMPRESSED_TEXSUBIMAGE_CMD_HDR_SIZE + 4,
data, image_size);
}
}
void
__indirect_glCompressedTexImage1DARB( GLenum target, GLint level,
GLenum internal_format, GLsizei width,
GLint border, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexImage1DARB(GLenum target, GLint level,
GLenum internal_format, GLsizei width,
GLint border, GLsizei image_size,
const GLvoid * data)
{
CompressedTexImage1D2D( target, level, internal_format, width, 0,
border, image_size, data,
X_GLrop_CompressedTexImage1D );
CompressedTexImage1D2D(target, level, internal_format, width, 0,
border, image_size, data,
X_GLrop_CompressedTexImage1D);
}
void
__indirect_glCompressedTexImage2DARB( GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height,
GLint border, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexImage2DARB(GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height,
GLint border, GLsizei image_size,
const GLvoid * data)
{
CompressedTexImage1D2D( target, level, internal_format, width, height,
border, image_size, data,
X_GLrop_CompressedTexImage2D );
CompressedTexImage1D2D(target, level, internal_format, width, height,
border, image_size, data,
X_GLrop_CompressedTexImage2D);
}
void
__indirect_glCompressedTexImage3DARB( GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexImage3DARB(GLenum target, GLint level,
GLenum internal_format,
GLsizei width, GLsizei height,
GLsizei depth, GLint border,
GLsizei image_size, const GLvoid * data)
{
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if ( gc->currentDpy == NULL ) {
return;
}
__GLX_DECLARE_VARIABLES();
cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE
+ image_size );
if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
__GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexImage3D, cmdlen );
__GLX_PUT_LONG( 4, target );
__GLX_PUT_LONG( 8, level );
__GLX_PUT_LONG( 12, internal_format );
__GLX_PUT_LONG( 16, width );
__GLX_PUT_LONG( 20, height );
__GLX_PUT_LONG( 24, depth );
__GLX_PUT_LONG( 28, border );
__GLX_PUT_LONG( 32, image_size );
if ( image_size != 0 ) {
__GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE,
data, image_size );
}
__GLX_END( cmdlen );
}
else {
__GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexImage3D,
cmdlen + 4 );
__GLX_PUT_LONG( 8, target );
__GLX_PUT_LONG( 12, level );
__GLX_PUT_LONG( 16, internal_format );
__GLX_PUT_LONG( 20, width );
__GLX_PUT_LONG( 24, height );
__GLX_PUT_LONG( 28, depth );
__GLX_PUT_LONG( 32, border );
__GLX_PUT_LONG( 36, image_size );
__glXSendLargeCommand( gc, gc->pc,
__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4,
data, image_size );
}
__GLX_LOAD_VARIABLES();
if (gc->currentDpy == NULL) {
return;
}
cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + image_size);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
__GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexImage3D, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_LONG(8, level);
__GLX_PUT_LONG(12, internal_format);
__GLX_PUT_LONG(16, width);
__GLX_PUT_LONG(20, height);
__GLX_PUT_LONG(24, depth);
__GLX_PUT_LONG(28, border);
__GLX_PUT_LONG(32, image_size);
if (image_size != 0) {
__GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE,
data, image_size);
}
__GLX_END(cmdlen);
}
else {
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexImage3D, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_LONG(12, level);
__GLX_PUT_LONG(16, internal_format);
__GLX_PUT_LONG(20, width);
__GLX_PUT_LONG(24, height);
__GLX_PUT_LONG(28, depth);
__GLX_PUT_LONG(32, border);
__GLX_PUT_LONG(36, image_size);
__glXSendLargeCommand(gc, gc->pc,
__GLX_COMPRESSED_TEXIMAGE_3D_CMD_HDR_SIZE + 4,
data, image_size);
}
}
void
__indirect_glCompressedTexSubImage1DARB( GLenum target, GLint level,
GLint xoffset,
GLsizei width,
GLenum format, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexSubImage1DARB(GLenum target, GLint level,
GLint xoffset,
GLsizei width,
GLenum format, GLsizei image_size,
const GLvoid * data)
{
CompressedTexSubImage1D2D( target, level, xoffset, 0, width, 0,
format, image_size, data,
X_GLrop_CompressedTexSubImage1D );
CompressedTexSubImage1D2D(target, level, xoffset, 0, width, 0,
format, image_size, data,
X_GLrop_CompressedTexSubImage1D);
}
void
__indirect_glCompressedTexSubImage2DARB( GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexSubImage2DARB(GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLsizei width, GLsizei height,
GLenum format, GLsizei image_size,
const GLvoid * data)
{
CompressedTexSubImage1D2D( target, level, xoffset, yoffset, width, height,
format, image_size, data,
X_GLrop_CompressedTexSubImage2D );
CompressedTexSubImage1D2D(target, level, xoffset, yoffset, width, height,
format, image_size, data,
X_GLrop_CompressedTexSubImage2D);
}
void
__indirect_glCompressedTexSubImage3DARB( GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLsizei image_size,
const GLvoid *data )
__indirect_glCompressedTexSubImage3DARB(GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint zoffset, GLsizei width,
GLsizei height, GLsizei depth,
GLenum format, GLsizei image_size,
const GLvoid * data)
{
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if ( gc->currentDpy == NULL ) {
return;
}
__GLX_DECLARE_VARIABLES();
cmdlen = __GLX_PAD( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE
+ image_size );
if ( cmdlen <= gc->maxSmallRenderCommandSize ) {
__GLX_BEGIN_VARIABLE( X_GLrop_CompressedTexSubImage3D, cmdlen );
__GLX_PUT_LONG( 4, target );
__GLX_PUT_LONG( 8, level );
__GLX_PUT_LONG( 12, xoffset );
__GLX_PUT_LONG( 16, yoffset );
__GLX_PUT_LONG( 20, zoffset );
__GLX_PUT_LONG( 24, width );
__GLX_PUT_LONG( 28, height );
__GLX_PUT_LONG( 32, depth );
__GLX_PUT_LONG( 36, format );
__GLX_PUT_LONG( 40, image_size );
if ( image_size != 0 ) {
__GLX_PUT_CHAR_ARRAY( __GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE,
data, image_size );
}
__GLX_END( cmdlen );
}
else {
__GLX_BEGIN_VARIABLE_LARGE( X_GLrop_CompressedTexSubImage3D,
cmdlen + 4 );
__GLX_PUT_LONG( 8, target );
__GLX_PUT_LONG( 12, level );
__GLX_PUT_LONG( 16, xoffset );
__GLX_PUT_LONG( 20, yoffset );
__GLX_PUT_LONG( 24, zoffset );
__GLX_PUT_LONG( 28, width );
__GLX_PUT_LONG( 32, height );
__GLX_PUT_LONG( 36, depth );
__GLX_PUT_LONG( 40, format );
__GLX_PUT_LONG( 44, image_size );
__glXSendLargeCommand( gc, gc->pc,
__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4,
data, image_size );
}
__GLX_LOAD_VARIABLES();
if (gc->currentDpy == NULL) {
return;
}
cmdlen = __GLX_PAD(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE
+ image_size);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
__GLX_BEGIN_VARIABLE(X_GLrop_CompressedTexSubImage3D, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_LONG(8, level);
__GLX_PUT_LONG(12, xoffset);
__GLX_PUT_LONG(16, yoffset);
__GLX_PUT_LONG(20, zoffset);
__GLX_PUT_LONG(24, width);
__GLX_PUT_LONG(28, height);
__GLX_PUT_LONG(32, depth);
__GLX_PUT_LONG(36, format);
__GLX_PUT_LONG(40, image_size);
if (image_size != 0) {
__GLX_PUT_CHAR_ARRAY(__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE,
data, image_size);
}
__GLX_END(cmdlen);
}
else {
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_CompressedTexSubImage3D, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_LONG(12, level);
__GLX_PUT_LONG(16, xoffset);
__GLX_PUT_LONG(20, yoffset);
__GLX_PUT_LONG(24, zoffset);
__GLX_PUT_LONG(28, width);
__GLX_PUT_LONG(32, height);
__GLX_PUT_LONG(36, depth);
__GLX_PUT_LONG(40, format);
__GLX_PUT_LONG(44, image_size);
__glXSendLargeCommand(gc, gc->pc,
__GLX_COMPRESSED_TEXSUBIMAGE_3D_CMD_HDR_SIZE + 4,
data, image_size);
}
}
+31 -28
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004
* All Rights Reserved.
@@ -25,59 +26,61 @@
#include <GL/gl.h>
#include "indirect.h"
static void TransposeMatrixf(const GLfloat s[16], GLfloat d[16])
static void
TransposeMatrixf(const GLfloat s[16], GLfloat d[16])
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
d[i*4+j] = s[j*4+i];
}
}
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
d[i * 4 + j] = s[j * 4 + i];
}
}
}
static void TransposeMatrixd(const GLdouble s[16], GLdouble d[16])
static void
TransposeMatrixd(const GLdouble s[16], GLdouble d[16])
{
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
d[i*4+j] = s[j*4+i];
}
}
int i, j;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
d[i * 4 + j] = s[j * 4 + i];
}
}
}
void
__indirect_glLoadTransposeMatrixdARB( const GLdouble * m )
__indirect_glLoadTransposeMatrixdARB(const GLdouble * m)
{
GLdouble mt[16];
TransposeMatrixd( m, mt );
__indirect_glLoadMatrixd( mt );
TransposeMatrixd(m, mt);
__indirect_glLoadMatrixd(mt);
}
void
__indirect_glLoadTransposeMatrixfARB( const GLfloat * m )
__indirect_glLoadTransposeMatrixfARB(const GLfloat * m)
{
GLfloat mt[16];
TransposeMatrixf( m, mt );
__indirect_glLoadMatrixf( mt );
TransposeMatrixf(m, mt);
__indirect_glLoadMatrixf(mt);
}
void
__indirect_glMultTransposeMatrixdARB( const GLdouble * m )
__indirect_glMultTransposeMatrixdARB(const GLdouble * m)
{
GLdouble mt[16];
TransposeMatrixd( m, mt );
__indirect_glMultMatrixd( mt );
TransposeMatrixd(m, mt);
__indirect_glMultMatrixd(mt);
}
void
__indirect_glMultTransposeMatrixfARB( const GLfloat * m )
__indirect_glMultTransposeMatrixfARB(const GLfloat * m)
{
GLfloat mt[16];
TransposeMatrixf( m, mt );
__indirect_glMultMatrixf( mt );
TransposeMatrixf(m, mt);
__indirect_glMultMatrixf(mt);
}
File diff suppressed because it is too large Load Diff
+26 -18
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004, 2005
* All Rights Reserved.
@@ -31,27 +32,34 @@ extern const GLuint __glXTypeSize_table[16];
#define __glXTypeSize(e) ((((e) & ~0x0f) != 0x1400) \
? 0 : __glXTypeSize_table[ (e) & 0x0f ])
extern void __glXArrayDisableAll( __GLXattribute * state );
extern void __glXArrayDisableAll(__GLXattribute * state);
extern GLboolean __glXSetArrayEnable( __GLXattribute * state,
GLenum key, unsigned index, GLboolean enable );
extern GLboolean __glXSetArrayEnable(__GLXattribute * state,
GLenum key, unsigned index,
GLboolean enable);
extern GLboolean __glXGetArrayEnable( const __GLXattribute * const state,
GLenum key, unsigned index, GLintptr * dest );
extern GLboolean __glXGetArraySize( const __GLXattribute * const state,
GLenum key, unsigned index, GLintptr * dest );
extern GLboolean __glXGetArrayType( const __GLXattribute * const state,
GLenum key, unsigned index, GLintptr * dest );
extern GLboolean __glXGetArrayStride( const __GLXattribute * const state,
GLenum key, unsigned index, GLintptr * dest );
extern GLboolean __glXGetArrayPointer( const __GLXattribute * const state,
GLenum key, unsigned index, void ** dest );
extern GLboolean __glXGetArrayNormalized( const __GLXattribute * const state,
GLenum key, unsigned index, GLintptr * dest );
extern GLboolean __glXGetArrayEnable(const __GLXattribute * const state,
GLenum key, unsigned index,
GLintptr * dest);
extern GLboolean __glXGetArraySize(const __GLXattribute * const state,
GLenum key, unsigned index,
GLintptr * dest);
extern GLboolean __glXGetArrayType(const __GLXattribute * const state,
GLenum key, unsigned index,
GLintptr * dest);
extern GLboolean __glXGetArrayStride(const __GLXattribute * const state,
GLenum key, unsigned index,
GLintptr * dest);
extern GLboolean __glXGetArrayPointer(const __GLXattribute * const state,
GLenum key, unsigned index,
void **dest);
extern GLboolean __glXGetArrayNormalized(const __GLXattribute * const state,
GLenum key, unsigned index,
GLintptr * dest);
extern void __glXPushArrayState( __GLXattribute * state );
extern void __glXPopArrayState( __GLXattribute * state );
extern void __glXPushArrayState(__GLXattribute * state);
extern void __glXPopArrayState(__GLXattribute * state);
extern GLuint __glXGetActiveTextureUnit( const __GLXattribute * const state );
extern GLuint __glXGetActiveTextureUnit(const __GLXattribute * const state);
#endif /* INDIRECT_VERTEX_ARRAY_H */
+56 -52
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2004, 2005
* All Rights Reserved.
@@ -42,86 +43,87 @@
/**
* State descriptor for a single array of vertex data.
*/
struct array_state {
struct array_state
{
/**
* Pointer to the application supplied data.
*/
const void * data;
const void *data;
/**
* Enum representing the type of the application supplied data.
*/
GLenum data_type;
GLenum data_type;
/**
* Stride value supplied by the application. This value is not used
* internally. It is only kept so that it can be queried by the
* application using glGet*v.
*/
GLsizei user_stride;
GLsizei user_stride;
/**
* Calculated size, in bytes, of a single element in the array. This
* is calculated based on \c count and the size of the data type
* represented by \c data_type.
*/
GLsizei element_size;
GLsizei element_size;
/**
* Actual byte-stride from one element to the next. This value will
* be equal to either \c user_stride or \c element_stride.
*/
GLsizei true_stride;
GLsizei true_stride;
/**
* Number of data values in each element.
*/
GLint count;
GLint count;
/**
* "Normalized" data is on the range [0,1] (unsigned) or [-1,1] (signed).
* This is used for mapping integral types to floating point types.
*/
GLboolean normalized;
GLboolean normalized;
/**
* Pre-calculated GLX protocol command header.
*/
uint32_t header[2];
uint32_t header[2];
/**
* Size of the header data. For simple data, like glColorPointerfv,
* this is 4. For complex data that requires either a count (e.g.,
* glWeightfvARB), an index (e.g., glVertexAttrib1fvARB), or a
* selector enum (e.g., glMultiTexCoord2fv) this is 8.
*/
unsigned header_size;
unsigned header_size;
/**
* Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
* to \c GL_FALSE.
*/
GLboolean enabled;
GLboolean enabled;
/**
* For multi-arrayed data (e.g., texture coordinates, generic vertex
* program attributes, etc.), this specifies which array this is.
*/
unsigned index;
unsigned index;
/**
* Per-array-type key. For most arrays, this will be the GL enum for
* that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY
* for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
* etc.).
*/
GLenum key;
GLenum key;
/**
* If this array can be used with the "classic" \c glDrawArrays protocol,
* this is set to \c GL_TRUE. Otherwise, it is set to \c GL_FALSE.
*/
GLboolean old_DrawArrays_possible;
GLboolean old_DrawArrays_possible;
};
@@ -129,28 +131,29 @@ struct array_state {
* Array state that is pushed / poped by \c glPushClientAttrib and
* \c glPopClientAttrib.
*/
struct array_stack_state {
struct array_stack_state
{
/**
* Pointer to the application supplied data.
*/
const void * data;
const void *data;
/**
* Enum representing the type of the application supplied data.
*/
GLenum data_type;
GLenum data_type;
/**
* Stride value supplied by the application. This value is not used
* internally. It is only kept so that it can be queried by the
* application using glGet*v.
*/
GLsizei user_stride;
GLsizei user_stride;
/**
* Number of data values in each element.
*/
GLint count;
GLint count;
/**
* Per-array-type key. For most arrays, this will be the GL enum for
@@ -158,30 +161,31 @@ struct array_stack_state {
* for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
* etc.).
*/
GLenum key;
GLenum key;
/**
* For multi-arrayed data (e.g., texture coordinates, generic vertex
* program attributes, etc.), this specifies which array this is.
*/
unsigned index;
unsigned index;
/**
* Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
* to \c GL_FALSE.
*/
GLboolean enabled;
GLboolean enabled;
};
/**
* Collection of all the vertex array state.
*/
struct array_state_vector {
struct array_state_vector
{
/**
* Number of arrays tracked by \c ::arrays.
*/
size_t num_arrays;
size_t num_arrays;
/**
* Array of vertex array state. This array contains all of the valid
@@ -190,13 +194,13 @@ struct array_state_vector {
* EXT_fog_coord, there won't be a GL_FOG_COORD_ARRAY entry in this
* array.
*/
struct array_state * arrays;
struct array_state *arrays;
/**
* Number of currently enabled client-side arrays. The value of this
* field is only valid if \c array_info_cache_valid is true.
*/
size_t enabled_client_array_count;
size_t enabled_client_array_count;
/**
* \name ARRAY_INFO cache.
@@ -214,12 +218,12 @@ struct array_state_vector {
* \c array_info_cache_buffer_size. \c array_info_cache_base stores a
* pointer to the true start of the buffer (i.e., what malloc returned).
*/
/*@{*/
size_t array_info_cache_size;
size_t array_info_cache_buffer_size;
void * array_info_cache;
void * array_info_cache_base;
/*@}*/
/*@{ */
size_t array_info_cache_size;
size_t array_info_cache_buffer_size;
void *array_info_cache;
void *array_info_cache_base;
/*@} */
/**
@@ -228,7 +232,7 @@ struct array_state_vector {
* modifying the array settings for an enabled array and enabling /
* disabling an array.
*/
GLboolean array_info_cache_valid;
GLboolean array_info_cache_valid;
/**
* Is it possible to use the GL 1.1 / EXT_vertex_arrays protocol? Use
@@ -241,7 +245,7 @@ struct array_state_vector {
* opcodes for \c glDrawArrays. For servers that advertise one or the
* other, there should be a way to select which opcode to use.
*/
GLboolean old_DrawArrays_possible;
GLboolean old_DrawArrays_possible;
/**
* Is it possible to use the new GL X.X / ARB_vertex_buffer_object
@@ -251,15 +255,15 @@ struct array_state_vector {
* This protocol has not yet been defined by the ARB, but is currently a
* work in progress. This field is a place-holder.
*/
GLboolean new_DrawArrays_possible;
GLboolean new_DrawArrays_possible;
/**
* Active texture unit set by \c glClientActiveTexture.
*
* \sa __glXGetActiveTextureUnit
*/
unsigned active_texture_unit;
unsigned active_texture_unit;
/**
* Number of supported texture units. Even if ARB_multitexture /
* GL 1.3 are not supported, this will be at least 1. When multitexture
@@ -271,7 +275,7 @@ struct array_state_vector {
* instead (if GL 2.0 / ARB_fragment_shader / ARB_fragment_program /
* NV_fragment_program are supported).
*/
unsigned num_texture_units;
unsigned num_texture_units;
/**
* Number of generic vertex program attribs. If GL_ARB_vertex_program
@@ -279,7 +283,7 @@ struct array_state_vector {
* queries by calling \c glGetProgramiv with \c GL_VERTEX_PROGRAM_ARB
* and \c GL_MAX_PROGRAM_ATTRIBS_ARB.
*/
unsigned num_vertex_program_attribs;
unsigned num_vertex_program_attribs;
/**
* \n Methods for implementing various GL functions.
@@ -294,15 +298,15 @@ struct array_state_vector {
* \todo
* Write code to plug these functions directly into the dispatch table.
*/
/*@{*/
void (*DrawArrays)( GLenum, GLint, GLsizei );
void (*DrawElements)( GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices );
/*@}*/
/*@{ */
void (*DrawArrays) (GLenum, GLint, GLsizei);
void (*DrawElements) (GLenum mode, GLsizei count, GLenum type,
const GLvoid * indices);
/*@} */
struct array_stack_state * stack;
unsigned active_texture_unit_stack[ __GL_CLIENT_ATTRIB_STACK_DEPTH ];
unsigned stack_index;
struct array_stack_state *stack;
unsigned active_texture_unit_stack[__GL_CLIENT_ATTRIB_STACK_DEPTH];
unsigned stack_index;
};
#endif /* _INDIRECT_VA_PRIVATE_ */
+166 -155
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* (C) Copyright IBM Corporation 2005
* All Rights Reserved.
@@ -31,96 +32,104 @@
#include <GL/glxproto.h>
static void
do_vertex_attrib_enable( GLuint index, GLboolean val )
do_vertex_attrib_enable(GLuint index, GLboolean val)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
if ( ! __glXSetArrayEnable( state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
index, val ) ) {
__glXSetError(gc, GL_INVALID_ENUM);
}
if (!__glXSetArrayEnable(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
index, val)) {
__glXSetError(gc, GL_INVALID_ENUM);
}
}
void __indirect_glEnableVertexAttribArrayARB( GLuint index )
void
__indirect_glEnableVertexAttribArrayARB(GLuint index)
{
do_vertex_attrib_enable( index, GL_TRUE );
do_vertex_attrib_enable(index, GL_TRUE);
}
void __indirect_glDisableVertexAttribArrayARB( GLuint index )
void
__indirect_glDisableVertexAttribArrayARB(GLuint index)
{
do_vertex_attrib_enable( index, GL_FALSE );
do_vertex_attrib_enable(index, GL_FALSE);
}
static void
get_parameter( unsigned opcode, unsigned size, GLenum target, GLuint index,
void * params )
get_parameter(unsigned opcode, unsigned size, GLenum target, GLuint index,
void *params)
{
__GLXcontext * const gc = __glXGetCurrentContext();
Display * const dpy = gc->currentDpy;
const GLuint cmdlen = 12;
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 12;
if (__builtin_expect(dpy != NULL, 1)) {
GLubyte const * pc = __glXSetupVendorRequest(gc,
X_GLXVendorPrivateWithReply,
opcode, cmdlen);
if (__builtin_expect(dpy != NULL, 1)) {
GLubyte const *pc = __glXSetupVendorRequest(gc,
X_GLXVendorPrivateWithReply,
opcode, cmdlen);
*((GLenum *)(pc + 0)) = target;
*((GLuint *)(pc + 4)) = index;
*((GLuint *)(pc + 8)) = 0;
*((GLenum *) (pc + 0)) = target;
*((GLuint *) (pc + 4)) = index;
*((GLuint *) (pc + 8)) = 0;
(void) __glXReadReply(dpy, size, params, GL_FALSE);
UnlockDisplay(dpy); SyncHandle();
}
return;
(void) __glXReadReply(dpy, size, params, GL_FALSE);
UnlockDisplay(dpy);
SyncHandle();
}
return;
}
void __indirect_glGetProgramEnvParameterfvARB( GLenum target, GLuint index,
GLfloat * params )
void
__indirect_glGetProgramEnvParameterfvARB(GLenum target, GLuint index,
GLfloat * params)
{
get_parameter( 1296, 4, target, index, params );
get_parameter(1296, 4, target, index, params);
}
void __indirect_glGetProgramEnvParameterdvARB( GLenum target, GLuint index,
GLdouble * params )
void
__indirect_glGetProgramEnvParameterdvARB(GLenum target, GLuint index,
GLdouble * params)
{
get_parameter( 1297, 8, target, index, params );
get_parameter(1297, 8, target, index, params);
}
void __indirect_glGetProgramLocalParameterfvARB( GLenum target, GLuint index,
GLfloat * params )
void
__indirect_glGetProgramLocalParameterfvARB(GLenum target, GLuint index,
GLfloat * params)
{
get_parameter( 1305, 4, target, index, params );
get_parameter(1305, 4, target, index, params);
}
void __indirect_glGetProgramLocalParameterdvARB( GLenum target, GLuint index,
GLdouble * params )
void
__indirect_glGetProgramLocalParameterdvARB(GLenum target, GLuint index,
GLdouble * params)
{
get_parameter( 1306, 8, target, index, params );
get_parameter(1306, 8, target, index, params);
}
void __indirect_glGetVertexAttribPointervNV( GLuint index, GLenum pname,
GLvoid ** pointer )
void
__indirect_glGetVertexAttribPointervNV(GLuint index, GLenum pname,
GLvoid ** pointer)
{
__GLXcontext * const gc = __glXGetCurrentContext();
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
if ( pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB ) {
__glXSetError( gc, GL_INVALID_ENUM );
}
if ( ! __glXGetArrayPointer( state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
index, pointer ) ) {
__glXSetError( gc, GL_INVALID_VALUE );
}
__GLXcontext *const gc = __glXGetCurrentContext();
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
__glXSetError(gc, GL_INVALID_ENUM);
}
if (!__glXGetArrayPointer(state, GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB,
index, pointer)) {
__glXSetError(gc, GL_INVALID_VALUE);
}
}
@@ -131,149 +140,151 @@ void __indirect_glGetVertexAttribPointervNV( GLuint index, GLenum pname,
* On success \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
*/
static GLboolean
get_attrib_array_data( __GLXattribute * state, GLuint index, GLenum cap,
GLintptr * data )
get_attrib_array_data(__GLXattribute * state, GLuint index, GLenum cap,
GLintptr * data)
{
GLboolean retval = GL_FALSE;
const GLenum attrib = GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB;
GLboolean retval = GL_FALSE;
const GLenum attrib = GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB;
switch( cap ) {
case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
retval = __glXGetArrayEnable( state, attrib, index, data );
break;
switch (cap) {
case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
retval = __glXGetArrayEnable(state, attrib, index, data);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
retval = __glXGetArraySize( state, attrib, index, data );
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
retval = __glXGetArraySize(state, attrib, index, data);
break;
case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
retval = __glXGetArrayStride( state, attrib, index, data );
break;
case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
retval = __glXGetArrayStride(state, attrib, index, data);
break;
case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
retval = __glXGetArrayType( state, attrib, index, data );
break;
case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
retval = __glXGetArrayType(state, attrib, index, data);
break;
case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
retval = __glXGetArrayNormalized( state, attrib, index, data );
break;
}
case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
retval = __glXGetArrayNormalized(state, attrib, index, data);
break;
}
return retval;
return retval;
}
static void get_vertex_attrib( __GLXcontext * gc, unsigned vop,
GLuint index, GLenum pname,
xReply * reply )
static void
get_vertex_attrib(__GLXcontext * gc, unsigned vop,
GLuint index, GLenum pname, xReply * reply)
{
Display * const dpy = gc->currentDpy;
GLubyte * const pc = __glXSetupVendorRequest(gc,
X_GLXVendorPrivateWithReply,
vop, 8);
*((uint32_t *)(pc + 0)) = index;
*((uint32_t *)(pc + 4)) = pname;
Display *const dpy = gc->currentDpy;
GLubyte *const pc = __glXSetupVendorRequest(gc,
X_GLXVendorPrivateWithReply,
vop, 8);
(void) _XReply( dpy, reply, 0, False );
*((uint32_t *) (pc + 0)) = index;
*((uint32_t *) (pc + 4)) = pname;
(void) _XReply(dpy, reply, 0, False);
}
void __indirect_glGetVertexAttribivARB( GLuint index, GLenum pname,
GLint * params )
void
__indirect_glGetVertexAttribivARB(GLuint index, GLenum pname, GLint * params)
{
__GLXcontext * const gc = __glXGetCurrentContext();
Display * const dpy = gc->currentDpy;
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
xGLXSingleReply reply;
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
xGLXSingleReply reply;
get_vertex_attrib( gc, 1303, index, pname, (xReply *) & reply );
get_vertex_attrib(gc, 1303, index, pname, (xReply *) & reply);
if ( reply.size != 0 ) {
GLintptr data;
if (reply.size != 0) {
GLintptr data;
if ( get_attrib_array_data( state, index, pname, & data ) ) {
*params = (GLint) data;
}
else {
if (reply.size == 1) {
*params = (GLint) reply.pad3;
}
else {
_XRead(dpy, (void *) params, 4 * reply.size);
}
}
}
if (get_attrib_array_data(state, index, pname, &data)) {
*params = (GLint) data;
}
else {
if (reply.size == 1) {
*params = (GLint) reply.pad3;
}
else {
_XRead(dpy, (void *) params, 4 * reply.size);
}
}
}
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
}
void __indirect_glGetVertexAttribfvARB( GLuint index, GLenum pname,
GLfloat * params )
void
__indirect_glGetVertexAttribfvARB(GLuint index, GLenum pname,
GLfloat * params)
{
__GLXcontext * const gc = __glXGetCurrentContext();
Display * const dpy = gc->currentDpy;
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
xGLXSingleReply reply;
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
xGLXSingleReply reply;
get_vertex_attrib( gc, 1302, index, pname, (xReply *) & reply );
get_vertex_attrib(gc, 1302, index, pname, (xReply *) & reply);
if ( reply.size != 0 ) {
GLintptr data;
if (reply.size != 0) {
GLintptr data;
if ( get_attrib_array_data( state, index, pname, & data ) ) {
*params = (GLfloat) data;
}
else {
if (reply.size == 1) {
(void) memcpy( params, & reply.pad3, sizeof( GLfloat ) );
}
else {
_XRead(dpy, (void *) params, 4 * reply.size);
}
}
}
if (get_attrib_array_data(state, index, pname, &data)) {
*params = (GLfloat) data;
}
else {
if (reply.size == 1) {
(void) memcpy(params, &reply.pad3, sizeof(GLfloat));
}
else {
_XRead(dpy, (void *) params, 4 * reply.size);
}
}
}
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
}
void __indirect_glGetVertexAttribdvARB( GLuint index, GLenum pname,
GLdouble * params )
void
__indirect_glGetVertexAttribdvARB(GLuint index, GLenum pname,
GLdouble * params)
{
__GLXcontext * const gc = __glXGetCurrentContext();
Display * const dpy = gc->currentDpy;
__GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
xGLXSingleReply reply;
__GLXcontext *const gc = __glXGetCurrentContext();
Display *const dpy = gc->currentDpy;
__GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
xGLXSingleReply reply;
get_vertex_attrib( gc, 1301, index, pname, (xReply *) & reply );
get_vertex_attrib(gc, 1301, index, pname, (xReply *) & reply);
if ( reply.size != 0 ) {
GLintptr data;
if (reply.size != 0) {
GLintptr data;
if ( get_attrib_array_data( state, index, pname, & data ) ) {
*params = (GLdouble) data;
}
else {
if (reply.size == 1) {
(void) memcpy( params, & reply.pad3, sizeof( GLdouble ) );
}
else {
_XRead(dpy, (void *) params, 8 * reply.size);
}
}
}
if (get_attrib_array_data(state, index, pname, &data)) {
*params = (GLdouble) data;
}
else {
if (reply.size == 1) {
(void) memcpy(params, &reply.pad3, sizeof(GLdouble));
}
else {
_XRead(dpy, (void *) params, 8 * reply.size);
}
}
}
UnlockDisplay(dpy);
SyncHandle();
UnlockDisplay(dpy);
SyncHandle();
}
+43 -28
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
* (C) Copyright IBM Corporation 2004
@@ -27,72 +28,86 @@
#include <GL/gl.h>
#include "indirect.h"
void __indirect_glWindowPos2dMESA(GLdouble x, GLdouble y)
void
__indirect_glWindowPos2dMESA(GLdouble x, GLdouble y)
{
__indirect_glWindowPos3fMESA(x, y, 0.0);
__indirect_glWindowPos3fMESA(x, y, 0.0);
}
void __indirect_glWindowPos2iMESA(GLint x, GLint y)
void
__indirect_glWindowPos2iMESA(GLint x, GLint y)
{
__indirect_glWindowPos3fMESA(x, y, 0.0);
__indirect_glWindowPos3fMESA(x, y, 0.0);
}
void __indirect_glWindowPos2fMESA(GLfloat x, GLfloat y)
void
__indirect_glWindowPos2fMESA(GLfloat x, GLfloat y)
{
__indirect_glWindowPos3fMESA(x, y, 0.0);
__indirect_glWindowPos3fMESA(x, y, 0.0);
}
void __indirect_glWindowPos2sMESA(GLshort x, GLshort y)
void
__indirect_glWindowPos2sMESA(GLshort x, GLshort y)
{
__indirect_glWindowPos3fMESA(x, y, 0.0);
__indirect_glWindowPos3fMESA(x, y, 0.0);
}
void __indirect_glWindowPos2dvMESA(const GLdouble * p)
void
__indirect_glWindowPos2dvMESA(const GLdouble * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
}
void __indirect_glWindowPos2fvMESA(const GLfloat * p)
void
__indirect_glWindowPos2fvMESA(const GLfloat * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
}
void __indirect_glWindowPos2ivMESA(const GLint * p)
void
__indirect_glWindowPos2ivMESA(const GLint * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
}
void __indirect_glWindowPos2svMESA(const GLshort * p)
void
__indirect_glWindowPos2svMESA(const GLshort * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
__indirect_glWindowPos3fMESA(p[0], p[1], 0.0);
}
void __indirect_glWindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
void
__indirect_glWindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z)
{
__indirect_glWindowPos3fMESA(x, y, z);
__indirect_glWindowPos3fMESA(x, y, z);
}
void __indirect_glWindowPos3iMESA(GLint x, GLint y, GLint z)
void
__indirect_glWindowPos3iMESA(GLint x, GLint y, GLint z)
{
__indirect_glWindowPos3fMESA(x, y, z);
__indirect_glWindowPos3fMESA(x, y, z);
}
void __indirect_glWindowPos3sMESA(GLshort x, GLshort y, GLshort z)
void
__indirect_glWindowPos3sMESA(GLshort x, GLshort y, GLshort z)
{
__indirect_glWindowPos3fMESA(x, y, z);
__indirect_glWindowPos3fMESA(x, y, z);
}
void __indirect_glWindowPos3dvMESA(const GLdouble * p)
void
__indirect_glWindowPos3dvMESA(const GLdouble * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
}
void __indirect_glWindowPos3ivMESA(const GLint * p)
void
__indirect_glWindowPos3ivMESA(const GLint * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
}
void __indirect_glWindowPos3svMESA(const GLshort * p)
void
__indirect_glWindowPos3svMESA(const GLshort * p)
{
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
__indirect_glWindowPos3fMESA(p[0], p[1], p[2]);
}
+116 -115
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
#ifndef __GLX_packrender_h__
#define __GLX_packrender_h__
@@ -48,23 +49,23 @@
#define __GLX_PAD(a) (((a)+3) & ~3)
/*
** Network size parameters
*/
** Network size parameters
*/
#define sz_double 8
/* Setup for all commands */
#define __GLX_DECLARE_VARIABLES() \
__GLXcontext *gc; \
GLubyte *pc, *pixelHeaderPC; \
GLuint compsize, cmdlen
#define __GLX_DECLARE_VARIABLES() \
__GLXcontext *gc; \
GLubyte *pc, *pixelHeaderPC; \
GLuint compsize, cmdlen
#define __GLX_LOAD_VARIABLES() \
gc = __glXGetCurrentContext(); \
pc = gc->pc; \
/* Muffle compilers */ \
cmdlen = 0; (void)cmdlen; \
compsize = 0; (void)compsize; \
pixelHeaderPC = 0; (void)pixelHeaderPC
#define __GLX_LOAD_VARIABLES() \
gc = __glXGetCurrentContext(); \
pc = gc->pc; \
/* Muffle compilers */ \
cmdlen = 0; (void)cmdlen; \
compsize = 0; (void)compsize; \
pixelHeaderPC = 0; (void)pixelHeaderPC
/*
** Variable sized command support macro. This macro is used by calls
@@ -73,53 +74,53 @@
** If the buffer can't hold the command then it is flushed so that
** the command will fit in the next buffer.
*/
#define __GLX_BEGIN_VARIABLE(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode)
#define __GLX_BEGIN_VARIABLE(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode)
#define __GLX_BEGIN_VARIABLE_LARGE(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode)
#define __GLX_BEGIN_VARIABLE_LARGE(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode)
#define __GLX_BEGIN_VARIABLE_WITH_PIXEL(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode); \
pc += __GLX_RENDER_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_WITH_PIXEL(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode); \
pc += __GLX_RENDER_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode); \
pc += __GLX_RENDER_LARGE_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode); \
pc += __GLX_RENDER_LARGE_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_WITH_PIXEL_3D(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode); \
pc += __GLX_RENDER_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_3D_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_WITH_PIXEL_3D(opcode,size) \
if (pc + (size) > gc->bufEnd) { \
pc = __glXFlushRenderBuffer(gc, pc); \
} \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode); \
pc += __GLX_RENDER_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_3D_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL_3D(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode); \
pc += __GLX_RENDER_LARGE_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_3D_HDR_SIZE
#define __GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL_3D(opcode,size) \
pc = __glXFlushRenderBuffer(gc, pc); \
__GLX_PUT_LONG(0,size); \
__GLX_PUT_LONG(4,opcode); \
pc += __GLX_RENDER_LARGE_HDR_SIZE; \
pixelHeaderPC = pc; \
pc += __GLX_PIXEL_3D_HDR_SIZE
/*
** Fixed size command support macro. This macro is used by calls that
@@ -129,8 +130,8 @@
** before doing the storage work.
*/
#define __GLX_BEGIN(opcode,size) \
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode)
__GLX_PUT_SHORT(0,size); \
__GLX_PUT_SHORT(2,opcode)
/*
** Finish a rendering command by advancing the pc. If the pc is now past
@@ -140,52 +141,52 @@
** rendering buffer is flushed out into the X protocol stream (which may
** or may not do I/O).
*/
#define __GLX_END(size) \
pc += size; \
if (pc > gc->limit) { \
(void) __glXFlushRenderBuffer(gc, pc); \
} else { \
gc->pc = pc; \
}
#define __GLX_END(size) \
pc += size; \
if (pc > gc->limit) { \
(void) __glXFlushRenderBuffer(gc, pc); \
} else { \
gc->pc = pc; \
}
/* Array copy macros */
#define __GLX_MEM_COPY(dest,src,bytes) \
if (src && dest) \
memcpy(dest, src, bytes)
#define __GLX_MEM_COPY(dest,src,bytes) \
if (src && dest) \
memcpy(dest, src, bytes)
/* Single item copy macros */
#define __GLX_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#define __GLX_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#ifndef _CRAY
#define __GLX_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define __GLX_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define __GLX_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define __GLX_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define __GLX_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#define __GLX_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#else
#define __GLX_PUT_SHORT(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-16) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffff << shift)) | ((a & 0xffff) << shift); }
#define __GLX_PUT_SHORT(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-16) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffff << shift)) | ((a & 0xffff) << shift); }
#define __GLX_PUT_LONG(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-32) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffffffff << shift)) | ((a & 0xffffffff) << shift); }
#define __GLX_PUT_LONG(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-32) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffffffff << shift)) | ((a & 0xffffffff) << shift); }
#define __GLX_PUT_FLOAT(offset,a) \
gl_put_float((pc + offset),a)
#define __GLX_PUT_FLOAT(offset,a) \
gl_put_float((pc + offset),a)
#define __GLX_PUT_DOUBLE(offset,a) \
gl_put_double(pc + offset, a)
#define __GLX_PUT_DOUBLE(offset,a) \
gl_put_double(pc + offset, a)
extern void gl_put_float(/*GLubyte *, struct cray_single*/);
extern void gl_put_double(/*GLubyte *, struct cray_double*/);
extern void gl_put_float( /*GLubyte *, struct cray_single */ );
extern void gl_put_double( /*GLubyte *, struct cray_double */ );
#endif
#ifndef _CRAY
@@ -195,48 +196,48 @@ extern void gl_put_double(/*GLubyte *, struct cray_double*/);
** This can certainly be done better for a particular machine
** architecture!
*/
#define __GLX_PUT_DOUBLE(offset,a) \
__GLX_MEM_COPY(pc + offset, &a, 8)
#define __GLX_PUT_DOUBLE(offset,a) \
__GLX_MEM_COPY(pc + offset, &a, 8)
#else
#define __GLX_PUT_DOUBLE(offset,a) \
*((FLOAT64 *) (pc + offset)) = a
#define __GLX_PUT_DOUBLE(offset,a) \
*((FLOAT64 *) (pc + offset)) = a
#endif
#endif
#define __GLX_PUT_CHAR_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT8)
#define __GLX_PUT_CHAR_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT8)
#ifndef _CRAY
#define __GLX_PUT_SHORT_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT16)
#define __GLX_PUT_SHORT_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT16)
#define __GLX_PUT_LONG_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT32)
#define __GLX_PUT_LONG_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_INT32)
#define __GLX_PUT_FLOAT_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT32)
#define __GLX_PUT_FLOAT_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT32)
#define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT64)
#define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen) \
__GLX_MEM_COPY(pc + offset, a, alen * __GLX_SIZE_FLOAT64)
#else
#define __GLX_PUT_SHORT_ARRAY(offset,a,alen) \
gl_put_short_array((GLubyte *)(pc + offset), a, alen * __GLX_SIZE_INT16)
#define __GLX_PUT_SHORT_ARRAY(offset,a,alen) \
gl_put_short_array((GLubyte *)(pc + offset), a, alen * __GLX_SIZE_INT16)
#define __GLX_PUT_LONG_ARRAY(offset,a,alen) \
gl_put_long_array((GLubyte *)(pc + offset), (long *)a, alen * __GLX_SIZE_INT32)
#define __GLX_PUT_LONG_ARRAY(offset,a,alen) \
gl_put_long_array((GLubyte *)(pc + offset), (long *)a, alen * __GLX_SIZE_INT32)
#define __GLX_PUT_FLOAT_ARRAY(offset,a,alen) \
gl_put_float_array((GLubyte *)(pc + offset), (float *)a, alen * __GLX_SIZE_FLOAT32)
#define __GLX_PUT_FLOAT_ARRAY(offset,a,alen) \
gl_put_float_array((GLubyte *)(pc + offset), (float *)a, alen * __GLX_SIZE_FLOAT32)
#define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen) \
gl_put_double_array((GLubyte *)(pc + offset), (double *)a, alen * __GLX_SIZE_FLOAT64)
#define __GLX_PUT_DOUBLE_ARRAY(offset,a,alen) \
gl_put_double_array((GLubyte *)(pc + offset), (double *)a, alen * __GLX_SIZE_FLOAT64)
extern gl_put_short_array (GLubyte *, short *, int);
extern gl_put_long_array (GLubyte *, long *, int);
extern gl_put_float_array (GLubyte *, float *, int);
extern gl_put_double_array (GLubyte *, double *, int);
extern gl_put_short_array(GLubyte *, short *, int);
extern gl_put_long_array(GLubyte *, long *, int);
extern gl_put_float_array(GLubyte *, float *, int);
extern gl_put_double_array(GLubyte *, double *, int);
#endif /* _CRAY */
+104 -103
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
#ifndef __GLX_packsingle_h__
#define __GLX_packsingle_h__
@@ -48,107 +49,107 @@
#define X_GLXSingle 0
/* Declare common variables used during a single command */
#define __GLX_SINGLE_DECLARE_VARIABLES() \
__GLXcontext *gc = __glXGetCurrentContext(); \
GLubyte *pc, *pixelHeaderPC; \
GLuint compsize, cmdlen; \
Display *dpy = gc->currentDpy; \
xGLXSingleReq *req
#define __GLX_SINGLE_DECLARE_VARIABLES() \
__GLXcontext *gc = __glXGetCurrentContext(); \
GLubyte *pc, *pixelHeaderPC; \
GLuint compsize, cmdlen; \
Display *dpy = gc->currentDpy; \
xGLXSingleReq *req
#define __GLX_SINGLE_LOAD_VARIABLES() \
pc = gc->pc; \
/* Muffle compilers */ \
pixelHeaderPC = 0; (void)pixelHeaderPC; \
compsize = 0; (void)compsize; \
cmdlen = 0; (void)cmdlen
#define __GLX_SINGLE_LOAD_VARIABLES() \
pc = gc->pc; \
/* Muffle compilers */ \
pixelHeaderPC = 0; (void)pixelHeaderPC; \
compsize = 0; (void)compsize; \
cmdlen = 0; (void)cmdlen
/* Start a single command */
#define __GLX_SINGLE_BEGIN(opcode,bytes) \
if (dpy) { \
(void) __glXFlushRenderBuffer(gc, pc); \
LockDisplay(dpy); \
GetReqExtra(GLXSingle,bytes,req); \
req->reqType = gc->majorOpcode; \
req->glxCode = opcode; \
req->contextTag = gc->currentContextTag; \
pc = ((GLubyte *)(req) + sz_xGLXSingleReq)
#define __GLX_SINGLE_BEGIN(opcode,bytes) \
if (dpy) { \
(void) __glXFlushRenderBuffer(gc, pc); \
LockDisplay(dpy); \
GetReqExtra(GLXSingle,bytes,req); \
req->reqType = gc->majorOpcode; \
req->glxCode = opcode; \
req->contextTag = gc->currentContextTag; \
pc = ((GLubyte *)(req) + sz_xGLXSingleReq)
/* End a single command */
#define __GLX_SINGLE_END() \
UnlockDisplay(dpy); \
SyncHandle(); \
}
#define __GLX_SINGLE_END() \
UnlockDisplay(dpy); \
SyncHandle(); \
}
/* Store data to sending for a single command */
#define __GLX_SINGLE_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_CHAR(offset,a) \
*((INT8 *) (pc + offset)) = a
#ifndef CRAY
#define __GLX_SINGLE_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_SHORT(offset,a) \
*((INT16 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_LONG(offset,a) \
*((INT32 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#define __GLX_SINGLE_PUT_FLOAT(offset,a) \
*((FLOAT32 *) (pc + offset)) = a
#else
#define __GLX_SINGLE_PUT_SHORT(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-16) - ((int)(cp) >> (64-6)); \
#define __GLX_SINGLE_PUT_SHORT(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-16) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffff << shift)) | ((a & 0xffff) << shift); }
#define __GLX_SINGLE_PUT_LONG(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-32) - ((int)(cp) >> (64-6)); \
#define __GLX_SINGLE_PUT_LONG(offset,a) \
{ GLubyte *cp = (pc+offset); \
int shift = (64-32) - ((int)(cp) >> (64-6)); \
*(int *)cp = (*(int *)cp & ~(0xffffffff << shift)) | ((a & 0xffffffff) << shift); }
#define __GLX_SINGLE_PUT_FLOAT(offset,a) \
gl_put_float(pc + offset, a)
#define __GLX_SINGLE_PUT_FLOAT(offset,a) \
gl_put_float(pc + offset, a)
#endif
/* Read support macros */
#define __GLX_SINGLE_READ_XREPLY() \
(void) _XReply(dpy, (xReply*) &reply, 0, False)
#define __GLX_SINGLE_READ_XREPLY() \
(void) _XReply(dpy, (xReply*) &reply, 0, False)
#define __GLX_SINGLE_GET_RETVAL(a,cast) \
a = (cast) reply.retval
#define __GLX_SINGLE_GET_RETVAL(a,cast) \
a = (cast) reply.retval
#define __GLX_SINGLE_GET_SIZE(a) \
a = (GLint) reply.size
#define __GLX_SINGLE_GET_SIZE(a) \
a = (GLint) reply.size
#ifndef _CRAY
#define __GLX_SINGLE_GET_CHAR(p) \
*p = *(GLbyte *)&reply.pad3;
#define __GLX_SINGLE_GET_CHAR(p) \
*p = *(GLbyte *)&reply.pad3;
#define __GLX_SINGLE_GET_SHORT(p) \
*p = *(GLshort *)&reply.pad3;
#define __GLX_SINGLE_GET_SHORT(p) \
*p = *(GLshort *)&reply.pad3;
#define __GLX_SINGLE_GET_LONG(p) \
*p = *(GLint *)&reply.pad3;
#define __GLX_SINGLE_GET_LONG(p) \
*p = *(GLint *)&reply.pad3;
#define __GLX_SINGLE_GET_FLOAT(p) \
*p = *(GLfloat *)&reply.pad3;
#define __GLX_SINGLE_GET_FLOAT(p) \
*p = *(GLfloat *)&reply.pad3;
#else
#define __GLX_SINGLE_GET_CHAR(p) \
*p = reply.pad3 >> 24;
#define __GLX_SINGLE_GET_CHAR(p) \
*p = reply.pad3 >> 24;
#define __GLX_SINGLE_GET_SHORT(p) \
{int t = reply.pad3 >> 16; \
*p = (t & 0x8000) ? (t | ~0xffff) : (t & 0xffff);}
#define __GLX_SINGLE_GET_SHORT(p) \
{int t = reply.pad3 >> 16; \
*p = (t & 0x8000) ? (t | ~0xffff) : (t & 0xffff);}
#define __GLX_SINGLE_GET_LONG(p) \
{int t = reply.pad3; \
*p = (t & 0x80000000) ? (t | ~0xffffffff) : (t & 0xffffffff);}
#define __GLX_SINGLE_GET_LONG(p) \
{int t = reply.pad3; \
*p = (t & 0x80000000) ? (t | ~0xffffffff) : (t & 0xffffffff);}
#define PAD3OFFSET 16
#define __GLX_SINGLE_GET_FLOAT(p) \
*p = gl_ntoh_float((GLubyte *)&reply + PAD3OFFSET);
#define __GLX_SINGLE_GET_FLOAT(p) \
*p = gl_ntoh_float((GLubyte *)&reply + PAD3OFFSET);
#define __GLX_SINGLE_GET_DOUBLE(p) \
*p = gl_ntoh_double((GLubyte *)&reply + PAD3OFFSET);
#define __GLX_SINGLE_GET_DOUBLE(p) \
*p = gl_ntoh_double((GLubyte *)&reply + PAD3OFFSET);
extern float gl_ntoh_float(GLubyte *);
extern float gl_ntoh_double(GLubyte *);
@@ -157,57 +158,57 @@ extern float gl_ntoh_double(GLubyte *);
#ifndef _CRAY
#ifdef __GLX_ALIGN64
#define __GLX_SINGLE_GET_DOUBLE(p) \
__GLX_MEM_COPY(p, &reply.pad3, 8)
#define __GLX_SINGLE_GET_DOUBLE(p) \
__GLX_MEM_COPY(p, &reply.pad3, 8)
#else
#define __GLX_SINGLE_GET_DOUBLE(p) \
*p = *(GLdouble *)&reply.pad3
#define __GLX_SINGLE_GET_DOUBLE(p) \
*p = *(GLdouble *)&reply.pad3
#endif
#endif
/* Get an array of typed data */
#define __GLX_SINGLE_GET_VOID_ARRAY(a,alen) \
{ \
GLint slop = alen*__GLX_SIZE_INT8 & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT8); \
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_VOID_ARRAY(a,alen) \
{ \
GLint slop = alen*__GLX_SIZE_INT8 & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT8); \
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_CHAR_ARRAY(a,alen) \
{ \
GLint slop = alen*__GLX_SIZE_INT8 & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT8); \
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_CHAR_ARRAY(a,alen) \
{ \
GLint slop = alen*__GLX_SIZE_INT8 & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT8); \
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_SHORT_ARRAY(a,alen) \
{ \
GLint slop = (alen*__GLX_SIZE_INT16) & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT16);\
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_LONG_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT32);
#define __GLX_SINGLE_GET_SHORT_ARRAY(a,alen) \
{ \
GLint slop = (alen*__GLX_SIZE_INT16) & 3; \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT16); \
if (slop) _XEatData(dpy,4-slop); \
}
#define __GLX_SINGLE_GET_LONG_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_INT32);
#ifndef _CRAY
#define __GLX_SINGLE_GET_FLOAT_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_FLOAT32);
#define __GLX_SINGLE_GET_FLOAT_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_FLOAT32);
#define __GLX_SINGLE_GET_DOUBLE_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_FLOAT64);
#define __GLX_SINGLE_GET_DOUBLE_ARRAY(a,alen) \
_XRead(dpy,(char *)a,alen*__GLX_SIZE_FLOAT64);
#else
#define __GLX_SINGLE_GET_FLOAT_ARRAY(a,alen) \
gl_get_float_array(dpy,a,alen);
#define __GLX_SINGLE_GET_FLOAT_ARRAY(a,alen) \
gl_get_float_array(dpy,a,alen);
#define __GLX_SINGLE_GET_DOUBLE_ARRAY(a,alen) \
gl_get_double_array(dpy, a, alen);
#define __GLX_SINGLE_GET_DOUBLE_ARRAY(a,alen) \
gl_get_double_array(dpy, a, alen);
extern void gl_get_float_array(Display *dpy, float *a, int alen);
extern void gl_get_double_array(Display *dpy, double *a, int alen);
extern void gl_get_float_array(Display * dpy, float *a, int alen);
extern void gl_get_double_array(Display * dpy, double *a, int alen);
#endif
#endif /* !__GLX_packsingle_h__ */
+374 -349
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -31,46 +32,46 @@
#include "packrender.h"
static const GLubyte MsbToLsbTable[256] = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
static const GLubyte LowBitsMask[9] = {
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
};
static const GLubyte HighBitsMask[9] = {
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff,
};
@@ -79,76 +80,80 @@ static const GLubyte HighBitsMask[9] = {
** data is transfered into the destImage buffer. Return in modes the
** set of pixel modes that are to be done by the server.
*/
static void FillBitmap(__GLXcontext *gc, GLint width, GLint height,
GLenum format, const GLvoid *userdata,
GLubyte *destImage)
static void
FillBitmap(__GLXcontext * gc, GLint width, GLint height,
GLenum format, const GLvoid * userdata, GLubyte * destImage)
{
const __GLXattribute * state = gc->client_state_private;
GLint rowLength = state->storeUnpack.rowLength;
GLint alignment = state->storeUnpack.alignment;
GLint skipPixels = state->storeUnpack.skipPixels;
GLint skipRows = state->storeUnpack.skipRows;
GLint lsbFirst = state->storeUnpack.lsbFirst;
GLint elementsLeft, bitOffset, currentByte, nextByte, highBitMask;
GLint lowBitMask, i;
GLint components, groupsPerRow, rowSize, padding, elementsPerRow;
const GLubyte *start, *iter;
const __GLXattribute *state = gc->client_state_private;
GLint rowLength = state->storeUnpack.rowLength;
GLint alignment = state->storeUnpack.alignment;
GLint skipPixels = state->storeUnpack.skipPixels;
GLint skipRows = state->storeUnpack.skipRows;
GLint lsbFirst = state->storeUnpack.lsbFirst;
GLint elementsLeft, bitOffset, currentByte, nextByte, highBitMask;
GLint lowBitMask, i;
GLint components, groupsPerRow, rowSize, padding, elementsPerRow;
const GLubyte *start, *iter;
if (rowLength > 0) {
groupsPerRow = rowLength;
} else {
groupsPerRow = width;
}
components = __glElementsPerGroup(format,GL_BITMAP);
rowSize = (groupsPerRow * components + 7) >> 3;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
start = ((const GLubyte*) userdata) + skipRows * rowSize +
((skipPixels * components) >> 3);
bitOffset = (skipPixels * components) & 7;
highBitMask = LowBitsMask[8-bitOffset];
lowBitMask = HighBitsMask[bitOffset];
elementsPerRow = width * components;
for (i = 0; i < height; i++) {
elementsLeft = elementsPerRow;
iter = start;
while (elementsLeft) {
/* First retrieve low bits from current byte */
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
} else {
currentByte = iter[0];
}
if (bitOffset) {
/* Need to read next byte to finish current byte */
if (elementsLeft > (8 - bitOffset)) {
if (lsbFirst) {
nextByte = MsbToLsbTable[iter[1]];
} else {
nextByte = iter[1];
}
currentByte =
((currentByte & highBitMask) << bitOffset) |
((nextByte & lowBitMask) >> (8 - bitOffset));
} else {
currentByte =
((currentByte & highBitMask) << bitOffset);
}
}
if (elementsLeft >= 8) {
*destImage = currentByte;
elementsLeft -= 8;
} else {
*destImage = currentByte & HighBitsMask[elementsLeft];
elementsLeft = 0;
}
destImage++;
iter++;
}
start += rowSize;
}
if (rowLength > 0) {
groupsPerRow = rowLength;
}
else {
groupsPerRow = width;
}
components = __glElementsPerGroup(format, GL_BITMAP);
rowSize = (groupsPerRow * components + 7) >> 3;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
start = ((const GLubyte *) userdata) + skipRows * rowSize +
((skipPixels * components) >> 3);
bitOffset = (skipPixels * components) & 7;
highBitMask = LowBitsMask[8 - bitOffset];
lowBitMask = HighBitsMask[bitOffset];
elementsPerRow = width * components;
for (i = 0; i < height; i++) {
elementsLeft = elementsPerRow;
iter = start;
while (elementsLeft) {
/* First retrieve low bits from current byte */
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
}
else {
currentByte = iter[0];
}
if (bitOffset) {
/* Need to read next byte to finish current byte */
if (elementsLeft > (8 - bitOffset)) {
if (lsbFirst) {
nextByte = MsbToLsbTable[iter[1]];
}
else {
nextByte = iter[1];
}
currentByte =
((currentByte & highBitMask) << bitOffset) |
((nextByte & lowBitMask) >> (8 - bitOffset));
}
else {
currentByte = ((currentByte & highBitMask) << bitOffset);
}
}
if (elementsLeft >= 8) {
*destImage = currentByte;
elementsLeft -= 8;
}
else {
*destImage = currentByte & HighBitsMask[elementsLeft];
elementsLeft = 0;
}
destImage++;
iter++;
}
start += rowSize;
}
}
/*
@@ -156,209 +161,224 @@ static void FillBitmap(__GLXcontext *gc, GLint width, GLint height,
** The internal packed array format used has LSB_FIRST = FALSE and
** ALIGNMENT = 1.
*/
void __glFillImage(__GLXcontext *gc, GLint dim, GLint width, GLint height,
GLint depth, GLenum format, GLenum type,
const GLvoid *userdata, GLubyte *newimage, GLubyte *modes)
void
__glFillImage(__GLXcontext * gc, GLint dim, GLint width, GLint height,
GLint depth, GLenum format, GLenum type,
const GLvoid * userdata, GLubyte * newimage, GLubyte * modes)
{
const __GLXattribute * state = gc->client_state_private;
GLint rowLength = state->storeUnpack.rowLength;
GLint imageHeight = state->storeUnpack.imageHeight;
GLint alignment = state->storeUnpack.alignment;
GLint skipPixels = state->storeUnpack.skipPixels;
GLint skipRows = state->storeUnpack.skipRows;
GLint skipImages = state->storeUnpack.skipImages;
GLint swapBytes = state->storeUnpack.swapEndian;
GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize;
GLint elementsPerRow, imageSize, rowsPerImage, h, i, j, k;
const GLubyte *start, *iter, *itera, *iterb, *iterc;
GLubyte *iter2;
const __GLXattribute *state = gc->client_state_private;
GLint rowLength = state->storeUnpack.rowLength;
GLint imageHeight = state->storeUnpack.imageHeight;
GLint alignment = state->storeUnpack.alignment;
GLint skipPixels = state->storeUnpack.skipPixels;
GLint skipRows = state->storeUnpack.skipRows;
GLint skipImages = state->storeUnpack.skipImages;
GLint swapBytes = state->storeUnpack.swapEndian;
GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize;
GLint elementsPerRow, imageSize, rowsPerImage, h, i, j, k;
const GLubyte *start, *iter, *itera, *iterb, *iterc;
GLubyte *iter2;
if (type == GL_BITMAP) {
FillBitmap(gc, width, height, format, userdata, newimage);
} else {
components = __glElementsPerGroup(format,type);
if (rowLength > 0) {
groupsPerRow = rowLength;
} else {
groupsPerRow = width;
}
if (imageHeight > 0) {
rowsPerImage = imageHeight;
} else {
rowsPerImage = height;
}
if (type == GL_BITMAP) {
FillBitmap(gc, width, height, format, userdata, newimage);
}
else {
components = __glElementsPerGroup(format, type);
if (rowLength > 0) {
groupsPerRow = rowLength;
}
else {
groupsPerRow = width;
}
if (imageHeight > 0) {
rowsPerImage = imageHeight;
}
else {
rowsPerImage = height;
}
elementSize = __glBytesPerElement(type);
groupSize = elementSize * components;
if (elementSize == 1) swapBytes = 0;
elementSize = __glBytesPerElement(type);
groupSize = elementSize * components;
if (elementSize == 1)
swapBytes = 0;
rowSize = groupsPerRow * groupSize;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
imageSize = rowSize * rowsPerImage;
start = ((const GLubyte*) userdata) + skipImages * imageSize +
skipRows * rowSize + skipPixels * groupSize;
iter2 = newimage;
elementsPerRow = width * components;
rowSize = groupsPerRow * groupSize;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
imageSize = rowSize * rowsPerImage;
start = ((const GLubyte *) userdata) + skipImages * imageSize +
skipRows * rowSize + skipPixels * groupSize;
iter2 = newimage;
elementsPerRow = width * components;
if (swapBytes) {
itera = start;
for (h = 0; h < depth; h++) {
iterb = itera;
for (i = 0; i < height; i++) {
iterc = iterb;
for (j = 0; j < elementsPerRow; j++) {
for (k = 1; k <= elementSize; k++) {
iter2[k-1] = iterc[elementSize - k];
}
iter2 += elementSize;
iterc += elementSize;
}
iterb += rowSize;
}
itera += imageSize;
}
} else {
itera = start;
for (h = 0; h < depth; h++) {
if (rowSize == elementsPerRow * elementSize) {
/* Ha! This is mondo easy! */
__GLX_MEM_COPY(iter2, itera,
elementsPerRow * elementSize * height);
iter2 += elementsPerRow * elementSize * height;
} else {
iter = itera;
for (i = 0; i < height; i++) {
__GLX_MEM_COPY(iter2, iter, elementsPerRow*elementSize);
iter2 += elementsPerRow * elementSize;
iter += rowSize;
}
}
itera += imageSize;
}
}
}
if (swapBytes) {
itera = start;
for (h = 0; h < depth; h++) {
iterb = itera;
for (i = 0; i < height; i++) {
iterc = iterb;
for (j = 0; j < elementsPerRow; j++) {
for (k = 1; k <= elementSize; k++) {
iter2[k - 1] = iterc[elementSize - k];
}
iter2 += elementSize;
iterc += elementSize;
}
iterb += rowSize;
}
itera += imageSize;
}
}
else {
itera = start;
for (h = 0; h < depth; h++) {
if (rowSize == elementsPerRow * elementSize) {
/* Ha! This is mondo easy! */
__GLX_MEM_COPY(iter2, itera,
elementsPerRow * elementSize * height);
iter2 += elementsPerRow * elementSize * height;
}
else {
iter = itera;
for (i = 0; i < height; i++) {
__GLX_MEM_COPY(iter2, iter, elementsPerRow * elementSize);
iter2 += elementsPerRow * elementSize;
iter += rowSize;
}
}
itera += imageSize;
}
}
}
/* Setup store modes that describe what we just did */
if (modes) {
if ( dim < 3 ) {
(void) memcpy( modes, __glXDefaultPixelStore + 4, 20 );
}
else {
(void) memcpy( modes, __glXDefaultPixelStore + 0, 36 );
}
}
/* Setup store modes that describe what we just did */
if (modes) {
if (dim < 3) {
(void) memcpy(modes, __glXDefaultPixelStore + 4, 20);
}
else {
(void) memcpy(modes, __glXDefaultPixelStore + 0, 36);
}
}
}
/*
** Empty a bitmap in LSB_FIRST=GL_FALSE and ALIGNMENT=4 format packing it
** into the clients memory using the pixel store PACK modes.
*/
static void EmptyBitmap(__GLXcontext *gc, GLint width, GLint height,
GLenum format, const GLubyte *sourceImage,
GLvoid *userdata)
static void
EmptyBitmap(__GLXcontext * gc, GLint width, GLint height,
GLenum format, const GLubyte * sourceImage, GLvoid * userdata)
{
const __GLXattribute * state = gc->client_state_private;
GLint rowLength = state->storePack.rowLength;
GLint alignment = state->storePack.alignment;
GLint skipPixels = state->storePack.skipPixels;
GLint skipRows = state->storePack.skipRows;
GLint lsbFirst = state->storePack.lsbFirst;
GLint components, groupsPerRow, rowSize, padding, elementsPerRow;
GLint sourceRowSize, sourcePadding, sourceSkip;
GLubyte *start, *iter;
GLint elementsLeft, bitOffset, currentByte, highBitMask, lowBitMask;
GLint writeMask, i;
GLubyte writeByte;
const __GLXattribute *state = gc->client_state_private;
GLint rowLength = state->storePack.rowLength;
GLint alignment = state->storePack.alignment;
GLint skipPixels = state->storePack.skipPixels;
GLint skipRows = state->storePack.skipRows;
GLint lsbFirst = state->storePack.lsbFirst;
GLint components, groupsPerRow, rowSize, padding, elementsPerRow;
GLint sourceRowSize, sourcePadding, sourceSkip;
GLubyte *start, *iter;
GLint elementsLeft, bitOffset, currentByte, highBitMask, lowBitMask;
GLint writeMask, i;
GLubyte writeByte;
components = __glElementsPerGroup(format,GL_BITMAP);
if (rowLength > 0) {
groupsPerRow = rowLength;
} else {
groupsPerRow = width;
}
components = __glElementsPerGroup(format, GL_BITMAP);
if (rowLength > 0) {
groupsPerRow = rowLength;
}
else {
groupsPerRow = width;
}
rowSize = (groupsPerRow * components + 7) >> 3;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
sourceRowSize = (width * components + 7) >> 3;
sourcePadding = (sourceRowSize % 4);
if (sourcePadding) {
sourceSkip = 4 - sourcePadding;
} else {
sourceSkip = 0;
}
start = ((GLubyte*) userdata) + skipRows * rowSize +
((skipPixels * components) >> 3);
bitOffset = (skipPixels * components) & 7;
highBitMask = LowBitsMask[8-bitOffset];
lowBitMask = HighBitsMask[bitOffset];
elementsPerRow = width * components;
for (i = 0; i < height; i++) {
elementsLeft = elementsPerRow;
iter = start;
writeMask = highBitMask;
writeByte = 0;
while (elementsLeft) {
/* Set up writeMask (to write to current byte) */
if (elementsLeft + bitOffset < 8) {
/* Need to trim writeMask */
writeMask &= HighBitsMask[bitOffset+elementsLeft];
}
rowSize = (groupsPerRow * components + 7) >> 3;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
sourceRowSize = (width * components + 7) >> 3;
sourcePadding = (sourceRowSize % 4);
if (sourcePadding) {
sourceSkip = 4 - sourcePadding;
}
else {
sourceSkip = 0;
}
start = ((GLubyte *) userdata) + skipRows * rowSize +
((skipPixels * components) >> 3);
bitOffset = (skipPixels * components) & 7;
highBitMask = LowBitsMask[8 - bitOffset];
lowBitMask = HighBitsMask[bitOffset];
elementsPerRow = width * components;
for (i = 0; i < height; i++) {
elementsLeft = elementsPerRow;
iter = start;
writeMask = highBitMask;
writeByte = 0;
while (elementsLeft) {
/* Set up writeMask (to write to current byte) */
if (elementsLeft + bitOffset < 8) {
/* Need to trim writeMask */
writeMask &= HighBitsMask[bitOffset + elementsLeft];
}
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
} else {
currentByte = iter[0];
}
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
}
else {
currentByte = iter[0];
}
if (bitOffset) {
writeByte |= (sourceImage[0] >> bitOffset);
currentByte = (currentByte & ~writeMask) |
(writeByte & writeMask);
writeByte = (sourceImage[0] << (8 - bitOffset));
} else {
currentByte = (currentByte & ~writeMask) |
(sourceImage[0] & writeMask);
}
if (bitOffset) {
writeByte |= (sourceImage[0] >> bitOffset);
currentByte = (currentByte & ~writeMask) |
(writeByte & writeMask);
writeByte = (sourceImage[0] << (8 - bitOffset));
}
else {
currentByte = (currentByte & ~writeMask) |
(sourceImage[0] & writeMask);
}
if (lsbFirst) {
iter[0] = MsbToLsbTable[currentByte];
} else {
iter[0] = currentByte;
}
if (lsbFirst) {
iter[0] = MsbToLsbTable[currentByte];
}
else {
iter[0] = currentByte;
}
if (elementsLeft >= 8) {
elementsLeft -= 8;
} else {
elementsLeft = 0;
}
sourceImage++;
iter++;
writeMask = 0xff;
}
if (writeByte) {
/* Some data left over that still needs writing */
writeMask &= lowBitMask;
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
} else {
currentByte = iter[0];
}
currentByte = (currentByte & ~writeMask) | (writeByte & writeMask);
if (lsbFirst) {
iter[0] = MsbToLsbTable[currentByte];
} else {
iter[0] = currentByte;
}
}
start += rowSize;
sourceImage += sourceSkip;
}
if (elementsLeft >= 8) {
elementsLeft -= 8;
}
else {
elementsLeft = 0;
}
sourceImage++;
iter++;
writeMask = 0xff;
}
if (writeByte) {
/* Some data left over that still needs writing */
writeMask &= lowBitMask;
if (lsbFirst) {
currentByte = MsbToLsbTable[iter[0]];
}
else {
currentByte = iter[0];
}
currentByte = (currentByte & ~writeMask) | (writeByte & writeMask);
if (lsbFirst) {
iter[0] = MsbToLsbTable[currentByte];
}
else {
iter[0] = currentByte;
}
}
start += rowSize;
sourceImage += sourceSkip;
}
}
/*
@@ -368,70 +388,75 @@ static void EmptyBitmap(__GLXcontext *gc, GLint width, GLint height,
** Named __glEmptyImage() because it is the opposite of __glFillImage().
*/
/* ARGSUSED */
void __glEmptyImage(__GLXcontext *gc, GLint dim, GLint width, GLint height,
GLint depth, GLenum format, GLenum type,
const GLubyte *sourceImage, GLvoid *userdata)
void
__glEmptyImage(__GLXcontext * gc, GLint dim, GLint width, GLint height,
GLint depth, GLenum format, GLenum type,
const GLubyte * sourceImage, GLvoid * userdata)
{
const __GLXattribute * state = gc->client_state_private;
GLint rowLength = state->storePack.rowLength;
GLint imageHeight = state->storePack.imageHeight;
GLint alignment = state->storePack.alignment;
GLint skipPixels = state->storePack.skipPixels;
GLint skipRows = state->storePack.skipRows;
GLint skipImages = state->storePack.skipImages;
GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize;
GLint elementsPerRow, sourceRowSize, sourcePadding, h, i;
GLint imageSize, rowsPerImage;
GLubyte *start, *iter, *itera;
const __GLXattribute *state = gc->client_state_private;
GLint rowLength = state->storePack.rowLength;
GLint imageHeight = state->storePack.imageHeight;
GLint alignment = state->storePack.alignment;
GLint skipPixels = state->storePack.skipPixels;
GLint skipRows = state->storePack.skipRows;
GLint skipImages = state->storePack.skipImages;
GLint components, elementSize, rowSize, padding, groupsPerRow, groupSize;
GLint elementsPerRow, sourceRowSize, sourcePadding, h, i;
GLint imageSize, rowsPerImage;
GLubyte *start, *iter, *itera;
if (type == GL_BITMAP) {
EmptyBitmap(gc, width, height, format, sourceImage, userdata);
} else {
components = __glElementsPerGroup(format,type);
if (rowLength > 0) {
groupsPerRow = rowLength;
} else {
groupsPerRow = width;
}
if (imageHeight > 0) {
rowsPerImage = imageHeight;
} else {
rowsPerImage = height;
}
elementSize = __glBytesPerElement(type);
groupSize = elementSize * components;
rowSize = groupsPerRow * groupSize;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
sourceRowSize = width * groupSize;
sourcePadding = (sourceRowSize % 4);
if (sourcePadding) {
sourceRowSize += 4 - sourcePadding;
}
imageSize = sourceRowSize * rowsPerImage;
start = ((GLubyte*) userdata) + skipImages * imageSize +
skipRows * rowSize + skipPixels * groupSize;
elementsPerRow = width * components;
if (type == GL_BITMAP) {
EmptyBitmap(gc, width, height, format, sourceImage, userdata);
}
else {
components = __glElementsPerGroup(format, type);
if (rowLength > 0) {
groupsPerRow = rowLength;
}
else {
groupsPerRow = width;
}
if (imageHeight > 0) {
rowsPerImage = imageHeight;
}
else {
rowsPerImage = height;
}
elementSize = __glBytesPerElement(type);
groupSize = elementSize * components;
rowSize = groupsPerRow * groupSize;
padding = (rowSize % alignment);
if (padding) {
rowSize += alignment - padding;
}
sourceRowSize = width * groupSize;
sourcePadding = (sourceRowSize % 4);
if (sourcePadding) {
sourceRowSize += 4 - sourcePadding;
}
imageSize = sourceRowSize * rowsPerImage;
start = ((GLubyte *) userdata) + skipImages * imageSize +
skipRows * rowSize + skipPixels * groupSize;
elementsPerRow = width * components;
itera = start;
for (h = 0; h < depth; h++) {
if ((rowSize == sourceRowSize) && (sourcePadding == 0)) {
/* Ha! This is mondo easy! */
__GLX_MEM_COPY(itera, sourceImage,
elementsPerRow * elementSize * height);
sourceImage += elementsPerRow * elementSize * height;
} else {
iter = itera;
for (i = 0; i < height; i++) {
__GLX_MEM_COPY(iter, sourceImage,
elementsPerRow * elementSize);
sourceImage += sourceRowSize;
iter += rowSize;
}
}
itera += imageSize;
}
}
itera = start;
for (h = 0; h < depth; h++) {
if ((rowSize == sourceRowSize) && (sourcePadding == 0)) {
/* Ha! This is mondo easy! */
__GLX_MEM_COPY(itera, sourceImage,
elementsPerRow * elementSize * height);
sourceImage += elementsPerRow * elementSize * height;
}
else {
iter = itera;
for (i = 0; i < height; i++) {
__GLX_MEM_COPY(iter, sourceImage,
elementsPerRow * elementSize);
sourceImage += sourceRowSize;
iter += rowSize;
}
}
itera += imageSize;
}
}
}
+272 -254
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -42,148 +43,157 @@
* \sa __indirect_glPixelStorei, __indirect_glPixelStoref
*/
static void
send_PixelStore( __GLXcontext * gc, unsigned sop, GLenum pname,
const void * param )
send_PixelStore(__GLXcontext * gc, unsigned sop, GLenum pname,
const void *param)
{
Display * const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
if (__builtin_expect(dpy != NULL, 1)) {
GLubyte const * pc = __glXSetupSingleRequest(gc, sop, cmdlen);
(void) memcpy((void *)(pc + 0), (void *)(&pname), 4);
(void) memcpy((void *)(pc + 4), param, 4);
UnlockDisplay(dpy); SyncHandle();
}
return;
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = 8;
if (__builtin_expect(dpy != NULL, 1)) {
GLubyte const *pc = __glXSetupSingleRequest(gc, sop, cmdlen);
(void) memcpy((void *) (pc + 0), (void *) (&pname), 4);
(void) memcpy((void *) (pc + 4), param, 4);
UnlockDisplay(dpy);
SyncHandle();
}
return;
}
/*
** Specify parameters that control the storage format of pixel arrays.
*/
void __indirect_glPixelStoref(GLenum pname, GLfloat param)
void
__indirect_glPixelStoref(GLenum pname, GLfloat param)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = gc->client_state_private;
Display *dpy = gc->currentDpy;
GLuint a;
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = gc->client_state_private;
Display *dpy = gc->currentDpy;
GLuint a;
if (!dpy) return;
if (!dpy)
return;
switch (pname) {
case GL_PACK_ROW_LENGTH:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.rowLength = a;
break;
case GL_PACK_IMAGE_HEIGHT:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.imageHeight = a;
break;
case GL_PACK_SKIP_ROWS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipRows = a;
break;
case GL_PACK_SKIP_PIXELS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipPixels = a;
break;
case GL_PACK_SKIP_IMAGES:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipImages = a;
break;
case GL_PACK_ALIGNMENT:
a = (GLint) (param + 0.5);
switch (a) {
case 1: case 2: case 4: case 8:
state->storePack.alignment = a;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_PACK_SWAP_BYTES:
state->storePack.swapEndian = (param != 0);
break;
case GL_PACK_LSB_FIRST:
state->storePack.lsbFirst = (param != 0);
break;
switch (pname) {
case GL_PACK_ROW_LENGTH:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.rowLength = a;
break;
case GL_PACK_IMAGE_HEIGHT:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.imageHeight = a;
break;
case GL_PACK_SKIP_ROWS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipRows = a;
break;
case GL_PACK_SKIP_PIXELS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipPixels = a;
break;
case GL_PACK_SKIP_IMAGES:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipImages = a;
break;
case GL_PACK_ALIGNMENT:
a = (GLint) (param + 0.5);
switch (a) {
case 1:
case 2:
case 4:
case 8:
state->storePack.alignment = a;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_PACK_SWAP_BYTES:
state->storePack.swapEndian = (param != 0);
break;
case GL_PACK_LSB_FIRST:
state->storePack.lsbFirst = (param != 0);
break;
case GL_UNPACK_ROW_LENGTH:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.rowLength = a;
break;
case GL_UNPACK_IMAGE_HEIGHT:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.imageHeight = a;
break;
case GL_UNPACK_SKIP_ROWS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipRows = a;
break;
case GL_UNPACK_SKIP_PIXELS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipPixels = a;
break;
case GL_UNPACK_SKIP_IMAGES:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipImages = a;
break;
case GL_UNPACK_ALIGNMENT:
a = (GLint) (param + 0.5);
switch (a) {
case 1: case 2: case 4: case 8:
state->storeUnpack.alignment = a;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_UNPACK_SWAP_BYTES:
state->storeUnpack.swapEndian = (param != 0);
break;
case GL_UNPACK_LSB_FIRST:
state->storeUnpack.lsbFirst = (param != 0);
break;
case GL_UNPACK_ROW_LENGTH:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.rowLength = a;
break;
case GL_UNPACK_IMAGE_HEIGHT:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.imageHeight = a;
break;
case GL_UNPACK_SKIP_ROWS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipRows = a;
break;
case GL_UNPACK_SKIP_PIXELS:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipPixels = a;
break;
case GL_UNPACK_SKIP_IMAGES:
a = (GLuint) (param + 0.5);
if (((GLint) a) < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipImages = a;
break;
case GL_UNPACK_ALIGNMENT:
a = (GLint) (param + 0.5);
switch (a) {
case 1:
case 2:
case 4:
case 8:
state->storeUnpack.alignment = a;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_UNPACK_SWAP_BYTES:
state->storeUnpack.swapEndian = (param != 0);
break;
case GL_UNPACK_LSB_FIRST:
state->storeUnpack.lsbFirst = (param != 0);
break;
/* Group all of the pixel store modes that need to be sent to the
* server here. Care must be used to only send modes to the server that
@@ -191,128 +201,136 @@ void __indirect_glPixelStoref(GLenum pname, GLfloat param)
* server. GL_PACK_INVERT_MESA is safe in this respect, but other,
* future modes may not be.
*/
case GL_PACK_INVERT_MESA:
send_PixelStore( gc, X_GLsop_PixelStoref, pname, & param );
break;
case GL_PACK_INVERT_MESA:
send_PixelStore(gc, X_GLsop_PixelStoref, pname, &param);
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
break;
}
default:
__glXSetError(gc, GL_INVALID_ENUM);
break;
}
}
void __indirect_glPixelStorei(GLenum pname, GLint param)
void
__indirect_glPixelStorei(GLenum pname, GLint param)
{
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute * state = gc->client_state_private;
Display *dpy = gc->currentDpy;
__GLXcontext *gc = __glXGetCurrentContext();
__GLXattribute *state = gc->client_state_private;
Display *dpy = gc->currentDpy;
if (!dpy) return;
if (!dpy)
return;
switch (pname) {
case GL_PACK_ROW_LENGTH:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.rowLength = param;
break;
case GL_PACK_IMAGE_HEIGHT:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.imageHeight = param;
break;
case GL_PACK_SKIP_ROWS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipRows = param;
break;
case GL_PACK_SKIP_PIXELS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipPixels = param;
break;
case GL_PACK_SKIP_IMAGES:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipImages = param;
break;
case GL_PACK_ALIGNMENT:
switch (param) {
case 1: case 2: case 4: case 8:
state->storePack.alignment = param;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_PACK_SWAP_BYTES:
state->storePack.swapEndian = (param != 0);
break;
case GL_PACK_LSB_FIRST:
state->storePack.lsbFirst = (param != 0);
break;
switch (pname) {
case GL_PACK_ROW_LENGTH:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.rowLength = param;
break;
case GL_PACK_IMAGE_HEIGHT:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.imageHeight = param;
break;
case GL_PACK_SKIP_ROWS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipRows = param;
break;
case GL_PACK_SKIP_PIXELS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipPixels = param;
break;
case GL_PACK_SKIP_IMAGES:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storePack.skipImages = param;
break;
case GL_PACK_ALIGNMENT:
switch (param) {
case 1:
case 2:
case 4:
case 8:
state->storePack.alignment = param;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_PACK_SWAP_BYTES:
state->storePack.swapEndian = (param != 0);
break;
case GL_PACK_LSB_FIRST:
state->storePack.lsbFirst = (param != 0);
break;
case GL_UNPACK_ROW_LENGTH:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.rowLength = param;
break;
case GL_UNPACK_IMAGE_HEIGHT:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.imageHeight = param;
break;
case GL_UNPACK_SKIP_ROWS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipRows = param;
break;
case GL_UNPACK_SKIP_PIXELS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipPixels = param;
break;
case GL_UNPACK_SKIP_IMAGES:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipImages = param;
break;
case GL_UNPACK_ALIGNMENT:
switch (param) {
case 1: case 2: case 4: case 8:
state->storeUnpack.alignment = param;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_UNPACK_SWAP_BYTES:
state->storeUnpack.swapEndian = (param != 0);
break;
case GL_UNPACK_LSB_FIRST:
state->storeUnpack.lsbFirst = (param != 0);
break;
case GL_UNPACK_ROW_LENGTH:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.rowLength = param;
break;
case GL_UNPACK_IMAGE_HEIGHT:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.imageHeight = param;
break;
case GL_UNPACK_SKIP_ROWS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipRows = param;
break;
case GL_UNPACK_SKIP_PIXELS:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipPixels = param;
break;
case GL_UNPACK_SKIP_IMAGES:
if (param < 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
state->storeUnpack.skipImages = param;
break;
case GL_UNPACK_ALIGNMENT:
switch (param) {
case 1:
case 2:
case 4:
case 8:
state->storeUnpack.alignment = param;
break;
default:
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
break;
case GL_UNPACK_SWAP_BYTES:
state->storeUnpack.swapEndian = (param != 0);
break;
case GL_UNPACK_LSB_FIRST:
state->storeUnpack.lsbFirst = (param != 0);
break;
/* Group all of the pixel store modes that need to be sent to the
* server here. Care must be used to only send modes to the server that
@@ -320,12 +338,12 @@ void __indirect_glPixelStorei(GLenum pname, GLint param)
* server. GL_PACK_INVERT_MESA is safe in this respect, but other,
* future modes may not be.
*/
case GL_PACK_INVERT_MESA:
send_PixelStore( gc, X_GLsop_PixelStorei, pname, & param );
break;
case GL_PACK_INVERT_MESA:
send_PixelStore(gc, X_GLsop_PixelStorei, pname, &param);
break;
default:
__glXSetError(gc, GL_INVALID_ENUM);
break;
}
default:
__glXSetError(gc, GL_INVALID_ENUM);
break;
}
}
+297 -272
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -38,320 +39,344 @@
** use the pixel header. See renderpix.c for those routines.
*/
void __indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
GLint order, const GLdouble *pnts)
void
__indirect_glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride,
GLint order, const GLdouble * pnts)
{
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_LOAD_VARIABLES();
k = __glMap1d_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
} else if (stride < k || order <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * order * __GLX_SIZE_FLOAT64;
cmdlen = 28+compsize;
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
k = __glMap1d_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
else if (stride < k || order <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * order * __GLX_SIZE_FLOAT64;
cmdlen = 28 + compsize;
if (!gc->currentDpy)
return;
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map1d,cmdlen);
__GLX_PUT_DOUBLE(4,u1);
__GLX_PUT_DOUBLE(12,u2);
__GLX_PUT_LONG(20,target);
__GLX_PUT_LONG(24,order);
/*
** NOTE: the doubles that follow are not aligned because of 3
** longs preceeding
*/
__glFillMap1d(k, order, stride, pnts, (pc+28));
__GLX_END(cmdlen);
} else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d,cmdlen+4);
__GLX_PUT_DOUBLE(8,u1);
__GLX_PUT_DOUBLE(16,u2);
__GLX_PUT_LONG(24,target);
__GLX_PUT_LONG(28,order);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map1d, cmdlen);
__GLX_PUT_DOUBLE(4, u1);
__GLX_PUT_DOUBLE(12, u2);
__GLX_PUT_LONG(20, target);
__GLX_PUT_LONG(24, order);
/*
** NOTE: the doubles that follow are not aligned because of 3
** longs preceeding
*/
__glFillMap1d(k, order, stride, pnts, (pc + 28));
__GLX_END(cmdlen);
}
else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1d, cmdlen + 4);
__GLX_PUT_DOUBLE(8, u1);
__GLX_PUT_DOUBLE(16, u2);
__GLX_PUT_LONG(24, target);
__GLX_PUT_LONG(28, order);
/*
** NOTE: the doubles that follow are not aligned because of 3
** longs preceeding
*/
if (stride != k) {
GLubyte *buf;
/*
** NOTE: the doubles that follow are not aligned because of 3
** longs preceeding
*/
if (stride != k) {
GLubyte *buf;
buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
__glFillMap1d(k, order, stride, pnts, buf);
__glXSendLargeCommand(gc, pc, 32, buf, compsize);
Xfree((char*) buf);
} else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 32, pnts, compsize);
}
}
buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
__glFillMap1d(k, order, stride, pnts, buf);
__glXSendLargeCommand(gc, pc, 32, buf, compsize);
Xfree((char *) buf);
}
else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 32, pnts, compsize);
}
}
}
void __indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
GLint order, const GLfloat *pnts)
void
__indirect_glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride,
GLint order, const GLfloat * pnts)
{
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_LOAD_VARIABLES();
k = __glMap1f_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
} else if (stride < k || order <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * order * __GLX_SIZE_FLOAT32;
cmdlen = 20+compsize;
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
k = __glMap1f_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
else if (stride < k || order <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * order * __GLX_SIZE_FLOAT32;
cmdlen = 20 + compsize;
if (!gc->currentDpy)
return;
/*
/*
** The order that arguments are packed is different from the order
** for glMap1d.
*/
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map1f,cmdlen);
__GLX_PUT_LONG(4,target);
__GLX_PUT_FLOAT(8,u1);
__GLX_PUT_FLOAT(12,u2);
__GLX_PUT_LONG(16,order);
__glFillMap1f(k, order, stride, pnts, (GLubyte*) (pc+20));
__GLX_END(cmdlen);
} else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f,cmdlen+4);
__GLX_PUT_LONG(8,target);
__GLX_PUT_FLOAT(12,u1);
__GLX_PUT_FLOAT(16,u2);
__GLX_PUT_LONG(20,order);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map1f, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_FLOAT(8, u1);
__GLX_PUT_FLOAT(12, u2);
__GLX_PUT_LONG(16, order);
__glFillMap1f(k, order, stride, pnts, (GLubyte *) (pc + 20));
__GLX_END(cmdlen);
}
else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map1f, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_FLOAT(12, u1);
__GLX_PUT_FLOAT(16, u2);
__GLX_PUT_LONG(20, order);
if (stride != k) {
GLubyte *buf;
if (stride != k) {
GLubyte *buf;
buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
__glFillMap1f(k, order, stride, pnts, buf);
__glXSendLargeCommand(gc, pc, 24, buf, compsize);
Xfree((char*) buf);
} else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 24, pnts, compsize);
}
}
buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
__glFillMap1f(k, order, stride, pnts, buf);
__glXSendLargeCommand(gc, pc, 24, buf, compsize);
Xfree((char *) buf);
}
else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 24, pnts, compsize);
}
}
}
void __indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr, GLint uord,
GLdouble v1, GLdouble v2, GLint vstr, GLint vord,
const GLdouble *pnts)
void
__indirect_glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustr,
GLint uord, GLdouble v1, GLdouble v2, GLint vstr,
GLint vord, const GLdouble * pnts)
{
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_LOAD_VARIABLES();
k = __glMap2d_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
} else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
cmdlen = 48+compsize;
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
k = __glMap2d_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * uord * vord * __GLX_SIZE_FLOAT64;
cmdlen = 48 + compsize;
if (!gc->currentDpy)
return;
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map2d,cmdlen);
__GLX_PUT_DOUBLE(4,u1);
__GLX_PUT_DOUBLE(12,u2);
__GLX_PUT_DOUBLE(20,v1);
__GLX_PUT_DOUBLE(28,v2);
__GLX_PUT_LONG(36,target);
__GLX_PUT_LONG(40,uord);
__GLX_PUT_LONG(44,vord);
/*
** Pack into a u-major ordering.
** NOTE: the doubles that follow are not aligned because of 5
** longs preceeding
*/
__glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble*) (pc+48));
__GLX_END(cmdlen);
} else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d,cmdlen+4);
__GLX_PUT_DOUBLE(8,u1);
__GLX_PUT_DOUBLE(16,u2);
__GLX_PUT_DOUBLE(24,v1);
__GLX_PUT_DOUBLE(32,v2);
__GLX_PUT_LONG(40,target);
__GLX_PUT_LONG(44,uord);
__GLX_PUT_LONG(48,vord);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map2d, cmdlen);
__GLX_PUT_DOUBLE(4, u1);
__GLX_PUT_DOUBLE(12, u2);
__GLX_PUT_DOUBLE(20, v1);
__GLX_PUT_DOUBLE(28, v2);
__GLX_PUT_LONG(36, target);
__GLX_PUT_LONG(40, uord);
__GLX_PUT_LONG(44, vord);
/*
** Pack into a u-major ordering.
** NOTE: the doubles that follow are not aligned because of 5
** longs preceeding
*/
__glFillMap2d(k, uord, vord, ustr, vstr, pnts, (GLdouble *) (pc + 48));
__GLX_END(cmdlen);
}
else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2d, cmdlen + 4);
__GLX_PUT_DOUBLE(8, u1);
__GLX_PUT_DOUBLE(16, u2);
__GLX_PUT_DOUBLE(24, v1);
__GLX_PUT_DOUBLE(32, v2);
__GLX_PUT_LONG(40, target);
__GLX_PUT_LONG(44, uord);
__GLX_PUT_LONG(48, vord);
/*
** NOTE: the doubles that follow are not aligned because of 5
** longs preceeding
*/
if ((vstr != k) || (ustr != k*vord)) {
GLdouble *buf;
/*
** NOTE: the doubles that follow are not aligned because of 5
** longs preceeding
*/
if ((vstr != k) || (ustr != k * vord)) {
GLdouble *buf;
buf = (GLdouble *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
/*
** Pack into a u-major ordering.
*/
__glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
__glXSendLargeCommand(gc, pc, 52, buf, compsize);
Xfree((char*) buf);
} else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 52, pnts, compsize);
}
}
buf = (GLdouble *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
/*
** Pack into a u-major ordering.
*/
__glFillMap2d(k, uord, vord, ustr, vstr, pnts, buf);
__glXSendLargeCommand(gc, pc, 52, buf, compsize);
Xfree((char *) buf);
}
else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 52, pnts, compsize);
}
}
}
void __indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr, GLint uord,
GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
const GLfloat *pnts)
void
__indirect_glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustr,
GLint uord, GLfloat v1, GLfloat v2, GLint vstr, GLint vord,
const GLfloat * pnts)
{
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_DECLARE_VARIABLES();
GLint k;
__GLX_LOAD_VARIABLES();
k = __glMap2f_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
} else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
cmdlen = 32+compsize;
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
k = __glMap2f_size(target);
if (k == 0) {
__glXSetError(gc, GL_INVALID_ENUM);
return;
}
else if (vstr < k || ustr < k || vord <= 0 || uord <= 0) {
__glXSetError(gc, GL_INVALID_VALUE);
return;
}
compsize = k * uord * vord * __GLX_SIZE_FLOAT32;
cmdlen = 32 + compsize;
if (!gc->currentDpy)
return;
/*
/*
** The order that arguments are packed is different from the order
** for glMap2d.
*/
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map2f,cmdlen);
__GLX_PUT_LONG(4,target);
__GLX_PUT_FLOAT(8,u1);
__GLX_PUT_FLOAT(12,u2);
__GLX_PUT_LONG(16,uord);
__GLX_PUT_FLOAT(20,v1);
__GLX_PUT_FLOAT(24,v2);
__GLX_PUT_LONG(28,vord);
/*
** Pack into a u-major ordering.
*/
__glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat*) (pc+32));
__GLX_END(cmdlen);
} else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f,cmdlen+4);
__GLX_PUT_LONG(8,target);
__GLX_PUT_FLOAT(12,u1);
__GLX_PUT_FLOAT(16,u2);
__GLX_PUT_LONG(20,uord);
__GLX_PUT_FLOAT(24,v1);
__GLX_PUT_FLOAT(28,v2);
__GLX_PUT_LONG(32,vord);
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE(X_GLrop_Map2f, cmdlen);
__GLX_PUT_LONG(4, target);
__GLX_PUT_FLOAT(8, u1);
__GLX_PUT_FLOAT(12, u2);
__GLX_PUT_LONG(16, uord);
__GLX_PUT_FLOAT(20, v1);
__GLX_PUT_FLOAT(24, v2);
__GLX_PUT_LONG(28, vord);
/*
** Pack into a u-major ordering.
*/
__glFillMap2f(k, uord, vord, ustr, vstr, pnts, (GLfloat *) (pc + 32));
__GLX_END(cmdlen);
}
else {
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE(X_GLrop_Map2f, cmdlen + 4);
__GLX_PUT_LONG(8, target);
__GLX_PUT_FLOAT(12, u1);
__GLX_PUT_FLOAT(16, u2);
__GLX_PUT_LONG(20, uord);
__GLX_PUT_FLOAT(24, v1);
__GLX_PUT_FLOAT(28, v2);
__GLX_PUT_LONG(32, vord);
if ((vstr != k) || (ustr != k*vord)) {
GLfloat *buf;
if ((vstr != k) || (ustr != k * vord)) {
GLfloat *buf;
buf = (GLfloat *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
/*
** Pack into a u-major ordering.
*/
__glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
__glXSendLargeCommand(gc, pc, 36, buf, compsize);
Xfree((char*) buf);
} else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 36, pnts, compsize);
}
}
buf = (GLfloat *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
/*
** Pack into a u-major ordering.
*/
__glFillMap2f(k, uord, vord, ustr, vstr, pnts, buf);
__glXSendLargeCommand(gc, pc, 36, buf, compsize);
Xfree((char *) buf);
}
else {
/* Data is already packed. Just send it out */
__glXSendLargeCommand(gc, pc, 36, pnts, compsize);
}
}
}
void __indirect_glEnable(GLenum cap)
void
__indirect_glEnable(GLenum cap)
{
__GLX_DECLARE_VARIABLES();
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
if (!gc->currentDpy)
return;
switch(cap) {
case GL_COLOR_ARRAY:
case GL_EDGE_FLAG_ARRAY:
case GL_INDEX_ARRAY:
case GL_NORMAL_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_VERTEX_ARRAY:
case GL_SECONDARY_COLOR_ARRAY:
case GL_FOG_COORD_ARRAY:
__indirect_glEnableClientState(cap);
return;
default:
break;
}
switch (cap) {
case GL_COLOR_ARRAY:
case GL_EDGE_FLAG_ARRAY:
case GL_INDEX_ARRAY:
case GL_NORMAL_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_VERTEX_ARRAY:
case GL_SECONDARY_COLOR_ARRAY:
case GL_FOG_COORD_ARRAY:
__indirect_glEnableClientState(cap);
return;
default:
break;
}
__GLX_BEGIN(X_GLrop_Enable,8);
__GLX_PUT_LONG(4,cap);
__GLX_END(8);
__GLX_BEGIN(X_GLrop_Enable, 8);
__GLX_PUT_LONG(4, cap);
__GLX_END(8);
}
void __indirect_glDisable(GLenum cap)
void
__indirect_glDisable(GLenum cap)
{
__GLX_DECLARE_VARIABLES();
__GLX_DECLARE_VARIABLES();
__GLX_LOAD_VARIABLES();
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
if (!gc->currentDpy)
return;
switch(cap) {
case GL_COLOR_ARRAY:
case GL_EDGE_FLAG_ARRAY:
case GL_INDEX_ARRAY:
case GL_NORMAL_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_VERTEX_ARRAY:
case GL_SECONDARY_COLOR_ARRAY:
case GL_FOG_COORD_ARRAY:
__indirect_glDisableClientState(cap);
return;
default:
break;
}
switch (cap) {
case GL_COLOR_ARRAY:
case GL_EDGE_FLAG_ARRAY:
case GL_INDEX_ARRAY:
case GL_NORMAL_ARRAY:
case GL_TEXTURE_COORD_ARRAY:
case GL_VERTEX_ARRAY:
case GL_SECONDARY_COLOR_ARRAY:
case GL_FOG_COORD_ARRAY:
__indirect_glDisableClientState(cap);
return;
default:
break;
}
__GLX_BEGIN(X_GLrop_Disable,8);
__GLX_PUT_LONG(4,cap);
__GLX_END(8);
__GLX_BEGIN(X_GLrop_Disable, 8);
__GLX_PUT_LONG(4, cap);
__GLX_END(8);
}
+112 -102
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -82,42 +83,43 @@
* broken.
*/
void
__glXSendLargeImage(__GLXcontext *gc, GLint compsize, GLint dim,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type, const GLvoid *src,
GLubyte *pc, GLubyte *modes)
__glXSendLargeImage(__GLXcontext * gc, GLint compsize, GLint dim,
GLint width, GLint height, GLint depth,
GLenum format, GLenum type, const GLvoid * src,
GLubyte * pc, GLubyte * modes)
{
if ( !gc->fastImageUnpack || (src == NULL) ) {
/* Allocate a temporary holding buffer */
GLubyte *buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
if (!gc->fastImageUnpack || (src == NULL)) {
/* Allocate a temporary holding buffer */
GLubyte *buf = (GLubyte *) Xmalloc(compsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
/* Apply pixel store unpack modes to copy data into buf */
if ( src != NULL ) {
(*gc->fillImage)(gc, dim, width, height, depth, format, type,
src, buf, modes);
}
else {
if ( dim < 3 ) {
(void) memcpy( modes, __glXDefaultPixelStore + 4, 20 );
}
else {
(void) memcpy( modes, __glXDefaultPixelStore + 0, 36 );
}
}
/* Apply pixel store unpack modes to copy data into buf */
if (src != NULL) {
(*gc->fillImage) (gc, dim, width, height, depth, format, type,
src, buf, modes);
}
else {
if (dim < 3) {
(void) memcpy(modes, __glXDefaultPixelStore + 4, 20);
}
else {
(void) memcpy(modes, __glXDefaultPixelStore + 0, 36);
}
}
/* Send large command */
__glXSendLargeCommand(gc, gc->pc, pc - gc->pc, buf, compsize);
/* Send large command */
__glXSendLargeCommand(gc, gc->pc, pc - gc->pc, buf, compsize);
/* Free buffer */
Xfree((char*) buf);
} else {
/* Just send the data straight as is */
__glXSendLargeCommand(gc, gc->pc, pc - gc->pc, pc, compsize);
}
/* Free buffer */
Xfree((char *) buf);
}
else {
/* Just send the data straight as is */
__glXSendLargeCommand(gc, gc->pc, pc - gc->pc, pc, compsize);
}
}
/************************************************************************/
@@ -129,81 +131,89 @@ __glXSendLargeImage(__GLXcontext *gc, GLint compsize, GLint dim,
* The \c fastImageUnpack path, which is thankfully never used, is completely
* broken.
*/
void __indirect_glSeparableFilter2D(GLenum target, GLenum internalformat,
GLsizei width, GLsizei height, GLenum format,
GLenum type, const GLvoid *row,
const GLvoid *column)
void
__indirect_glSeparableFilter2D(GLenum target, GLenum internalformat,
GLsizei width, GLsizei height, GLenum format,
GLenum type, const GLvoid * row,
const GLvoid * column)
{
__GLX_DECLARE_VARIABLES();
GLuint compsize2, hdrlen, totalhdrlen, image1len, image2len;
__GLX_DECLARE_VARIABLES();
GLuint compsize2, hdrlen, totalhdrlen, image1len, image2len;
__GLX_LOAD_VARIABLES();
compsize = __glImageSize(width, 1, 1, format, type, 0);
compsize2 = __glImageSize(height, 1, 1, format, type, 0);
totalhdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
hdrlen = __GLX_PAD(__GLX_CONV_FILT_HDR_SIZE);
image1len = __GLX_PAD(compsize);
image2len = __GLX_PAD(compsize2);
cmdlen = totalhdrlen + image1len + image2len;
if (!gc->currentDpy) return;
__GLX_LOAD_VARIABLES();
compsize = __glImageSize(width, 1, 1, format, type, 0);
compsize2 = __glImageSize(height, 1, 1, format, type, 0);
totalhdrlen = __GLX_PAD(__GLX_CONV_FILT_CMD_HDR_SIZE);
hdrlen = __GLX_PAD(__GLX_CONV_FILT_HDR_SIZE);
image1len = __GLX_PAD(compsize);
image2len = __GLX_PAD(compsize2);
cmdlen = totalhdrlen + image1len + image2len;
if (!gc->currentDpy)
return;
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE_WITH_PIXEL(X_GLrop_SeparableFilter2D, cmdlen);
__GLX_PUT_LONG(0,target);
__GLX_PUT_LONG(4,internalformat);
__GLX_PUT_LONG(8,width);
__GLX_PUT_LONG(12,height);
__GLX_PUT_LONG(16,format);
__GLX_PUT_LONG(20,type);
pc += hdrlen;
if (compsize > 0) {
(*gc->fillImage)(gc, 1, width, 1, 1, format, type,
row, pc, pixelHeaderPC);
pc += image1len;
}
if (compsize2 > 0) {
(*gc->fillImage)(gc, 1, height, 1, 1, format, type,
column, pc, NULL);
pc += image2len;
}
if ((compsize == 0) && (compsize2 == 0)) {
/* Setup default store modes */
(void) memcpy( pixelHeaderPC, __glXDefaultPixelStore + 4, 20 );
}
__GLX_END(0);
} else {
const GLint bufsize = image1len + image2len;
if (cmdlen <= gc->maxSmallRenderCommandSize) {
/* Use GLXRender protocol to send small command */
__GLX_BEGIN_VARIABLE_WITH_PIXEL(X_GLrop_SeparableFilter2D, cmdlen);
__GLX_PUT_LONG(0, target);
__GLX_PUT_LONG(4, internalformat);
__GLX_PUT_LONG(8, width);
__GLX_PUT_LONG(12, height);
__GLX_PUT_LONG(16, format);
__GLX_PUT_LONG(20, type);
pc += hdrlen;
if (compsize > 0) {
(*gc->fillImage) (gc, 1, width, 1, 1, format, type,
row, pc, pixelHeaderPC);
pc += image1len;
}
if (compsize2 > 0) {
(*gc->fillImage) (gc, 1, height, 1, 1, format, type,
column, pc, NULL);
pc += image2len;
}
if ((compsize == 0) && (compsize2 == 0)) {
/* Setup default store modes */
(void) memcpy(pixelHeaderPC, __glXDefaultPixelStore + 4, 20);
}
__GLX_END(0);
}
else {
const GLint bufsize = image1len + image2len;
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(X_GLrop_SeparableFilter2D,cmdlen+4);
__GLX_PUT_LONG(0,target);
__GLX_PUT_LONG(4,internalformat);
__GLX_PUT_LONG(8,width);
__GLX_PUT_LONG(12,height);
__GLX_PUT_LONG(16,format);
__GLX_PUT_LONG(20,type);
pc += hdrlen;
/* Use GLXRenderLarge protocol to send command */
__GLX_BEGIN_VARIABLE_LARGE_WITH_PIXEL(X_GLrop_SeparableFilter2D,
cmdlen + 4);
__GLX_PUT_LONG(0, target);
__GLX_PUT_LONG(4, internalformat);
__GLX_PUT_LONG(8, width);
__GLX_PUT_LONG(12, height);
__GLX_PUT_LONG(16, format);
__GLX_PUT_LONG(20, type);
pc += hdrlen;
if (!gc->fastImageUnpack) {
/* Allocate a temporary holding buffer */
GLubyte *buf = (GLubyte *) Xmalloc(bufsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
(*gc->fillImage)(gc, 1, width, 1, 1, format, type, row, buf, pixelHeaderPC);
if (!gc->fastImageUnpack) {
/* Allocate a temporary holding buffer */
GLubyte *buf = (GLubyte *) Xmalloc(bufsize);
if (!buf) {
__glXSetError(gc, GL_OUT_OF_MEMORY);
return;
}
(*gc->fillImage) (gc, 1, width, 1, 1, format, type, row, buf,
pixelHeaderPC);
(*gc->fillImage)(gc, 1, height, 1, 1, format, type, column,
buf + image1len, pixelHeaderPC);
(*gc->fillImage) (gc, 1, height, 1, 1, format, type, column,
buf + image1len, pixelHeaderPC);
/* Send large command */
__glXSendLargeCommand(gc, gc->pc, (GLint)(pc - gc->pc), buf, bufsize);
/* Free buffer */
Xfree((char*) buf);
} else {
/* Just send the data straight as is */
__glXSendLargeCommand(gc, gc->pc, (GLint)(pc - gc->pc), pc, bufsize);
}
}
/* Send large command */
__glXSendLargeCommand(gc, gc->pc, (GLint) (pc - gc->pc), buf,
bufsize);
/* Free buffer */
Xfree((char *) buf);
}
else {
/* Just send the data straight as is */
__glXSendLargeCommand(gc, gc->pc, (GLint) (pc - gc->pc), pc,
bufsize);
}
}
}
+669 -631
View File
File diff suppressed because it is too large Load Diff
+128 -120
View File
@@ -1,3 +1,4 @@
/* -*- mode: c; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 3; coding: utf-8-unix -*- */
/*
* SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
* Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
@@ -36,153 +37,160 @@
#include "glapioffsets.h"
#include <GL/glxproto.h>
void __indirect_glGetSeparableFilter(GLenum target, GLenum format, GLenum type,
GLvoid *row, GLvoid *column, GLvoid *span)
void
__indirect_glGetSeparableFilter(GLenum target, GLenum format, GLenum type,
GLvoid * row, GLvoid * column, GLvoid * span)
{
__GLX_SINGLE_DECLARE_VARIABLES();
const __GLXattribute * state;
xGLXGetSeparableFilterReply reply;
GLubyte *rowBuf, *colBuf;
__GLX_SINGLE_DECLARE_VARIABLES();
const __GLXattribute *state;
xGLXGetSeparableFilterReply reply;
GLubyte *rowBuf, *colBuf;
if (!dpy) return;
__GLX_SINGLE_LOAD_VARIABLES();
state = gc->client_state_private;
if (!dpy)
return;
__GLX_SINGLE_LOAD_VARIABLES();
state = gc->client_state_private;
/* Send request */
__GLX_SINGLE_BEGIN(X_GLsop_GetSeparableFilter, __GLX_PAD(13));
__GLX_SINGLE_PUT_LONG(0,target);
__GLX_SINGLE_PUT_LONG(4,format);
__GLX_SINGLE_PUT_LONG(8,type);
__GLX_SINGLE_PUT_CHAR(12,state->storePack.swapEndian);
__GLX_SINGLE_READ_XREPLY();
compsize = reply.length << 2;
/* Send request */
__GLX_SINGLE_BEGIN(X_GLsop_GetSeparableFilter, __GLX_PAD(13));
__GLX_SINGLE_PUT_LONG(0, target);
__GLX_SINGLE_PUT_LONG(4, format);
__GLX_SINGLE_PUT_LONG(8, type);
__GLX_SINGLE_PUT_CHAR(12, state->storePack.swapEndian);
__GLX_SINGLE_READ_XREPLY();
compsize = reply.length << 2;
if (compsize != 0) {
GLint width, height;
GLint widthsize, heightsize;
if (compsize != 0) {
GLint width, height;
GLint widthsize, heightsize;
width = reply.width;
height = reply.height;
width = reply.width;
height = reply.height;
widthsize = __glImageSize(width,1,1,format, type, 0);
heightsize = __glImageSize(height,1,1,format, type, 0);
widthsize = __glImageSize(width, 1, 1, format, type, 0);
heightsize = __glImageSize(height, 1, 1, format, type, 0);
/* Allocate a holding buffer to transform the data from */
rowBuf = (GLubyte *) Xmalloc(widthsize);
if (!rowBuf) {
/* Throw data away */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
return;
}
else {
__GLX_SINGLE_GET_CHAR_ARRAY(((char *) rowBuf), widthsize);
__glEmptyImage(gc, 1, width, 1, 1, format, type, rowBuf, row);
Xfree((char *) rowBuf);
}
colBuf = (GLubyte *) Xmalloc(heightsize);
if (!colBuf) {
/* Throw data away */
_XEatData(dpy, compsize - __GLX_PAD(widthsize));
__glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
return;
}
else {
__GLX_SINGLE_GET_CHAR_ARRAY(((char *) colBuf), heightsize);
__glEmptyImage(gc, 1, height, 1, 1, format, type, colBuf, column);
Xfree((char *) colBuf);
}
}
else {
/*
** don't modify user's buffer.
*/
}
__GLX_SINGLE_END();
/* Allocate a holding buffer to transform the data from */
rowBuf = (GLubyte*) Xmalloc(widthsize);
if (!rowBuf) {
/* Throw data away */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
return;
} else {
__GLX_SINGLE_GET_CHAR_ARRAY(((char*)rowBuf),widthsize);
__glEmptyImage(gc, 1, width, 1, 1, format, type, rowBuf, row);
Xfree((char*) rowBuf);
}
colBuf = (GLubyte*) Xmalloc(heightsize);
if (!colBuf) {
/* Throw data away */
_XEatData(dpy, compsize - __GLX_PAD(widthsize));
__glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
return;
} else {
__GLX_SINGLE_GET_CHAR_ARRAY(((char*)colBuf),heightsize);
__glEmptyImage(gc, 1, height, 1, 1, format, type, colBuf, column);
Xfree((char*) colBuf);
}
} else {
/*
** don't modify user's buffer.
*/
}
__GLX_SINGLE_END();
}
#define CONCAT(a,b) a ## b
#define NAME(o) CONCAT(gl_dispatch_stub_, o)
void NAME(_gloffset_GetSeparableFilter)(GLenum target, GLenum format, GLenum type,
GLvoid *row, GLvoid *column, GLvoid *span)
void NAME(_gloffset_GetSeparableFilter) (GLenum target, GLenum format,
GLenum type, GLvoid * row,
GLvoid * column, GLvoid * span)
{
__GLXcontext * const gc = __glXGetCurrentContext();
__GLXcontext *const gc = __glXGetCurrentContext();
#ifdef GLX_DIRECT_RENDERING
if (gc->driContext) {
CALL_GetSeparableFilter(GET_DISPATCH(),
(target, format, type, row, column, span));
return;
} else
if (gc->driContext) {
CALL_GetSeparableFilter(GET_DISPATCH(),
(target, format, type, row, column, span));
return;
}
else
#endif
{
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = __GLX_PAD(13);
{
Display *const dpy = gc->currentDpy;
const GLuint cmdlen = __GLX_PAD(13);
if (dpy != NULL) {
const __GLXattribute * const state = gc->client_state_private;
xGLXGetSeparableFilterReply reply;
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
X_GLvop_GetSeparableFilterEXT, cmdlen);
unsigned compsize;
if (dpy != NULL) {
const __GLXattribute *const state = gc->client_state_private;
xGLXGetSeparableFilterReply reply;
GLubyte const *pc =
__glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
X_GLvop_GetSeparableFilterEXT, cmdlen);
unsigned compsize;
(void) memcpy((void *) (pc + 0), (void *) (&target), 4);
(void) memcpy((void *) (pc + 4), (void *) (&format), 4);
(void) memcpy((void *) (pc + 8), (void *) (&type), 4);
*(int8_t *) (pc + 12) = state->storePack.swapEndian;
(void) memcpy((void *) (pc + 0), (void *) (&target), 4);
(void) memcpy((void *) (pc + 4), (void *) (&format), 4);
(void) memcpy((void *) (pc + 8), (void *) (&type), 4);
*(int8_t *) (pc + 12) = state->storePack.swapEndian;
(void) _XReply(dpy, (xReply *) & reply, 0, False);
(void) _XReply(dpy, (xReply *) & reply, 0, False);
compsize = reply.length << 2;
compsize = reply.length << 2;
if (compsize != 0) {
const GLint width = reply.width;
const GLint height = reply.height;
const GLint widthsize =
__glImageSize(width, 1, 1, format, type, 0);
const GLint heightsize =
__glImageSize(height, 1, 1, format, type, 0);
GLubyte * const buf =
(GLubyte*) Xmalloc((widthsize > heightsize) ? widthsize : heightsize);
if (compsize != 0) {
const GLint width = reply.width;
const GLint height = reply.height;
const GLint widthsize =
__glImageSize(width, 1, 1, format, type, 0);
const GLint heightsize =
__glImageSize(height, 1, 1, format, type, 0);
GLubyte *const buf =
(GLubyte *) Xmalloc((widthsize > heightsize) ? widthsize :
heightsize);
if (buf == NULL) {
/* Throw data away */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY);
if (buf == NULL) {
/* Throw data away */
_XEatData(dpy, compsize);
__glXSetError(gc, GL_OUT_OF_MEMORY);
UnlockDisplay(dpy);
SyncHandle();
return;
} else {
int extra;
extra = 4 - (widthsize & 3);
_XRead(dpy, (char *)buf, widthsize);
if (extra < 4) {
_XEatData(dpy, extra);
}
UnlockDisplay(dpy);
SyncHandle();
return;
}
else {
int extra;
__glEmptyImage(gc, 1, width, 1, 1, format, type, buf,
row);
extra = 4 - (widthsize & 3);
_XRead(dpy, (char *) buf, widthsize);
if (extra < 4) {
_XEatData(dpy, extra);
}
extra = 4 - (heightsize & 3);
_XRead(dpy, (char *)buf, heightsize);
if (extra < 4) {
_XEatData(dpy, extra);
}
__glEmptyImage(gc, 1, width, 1, 1, format, type, buf, row);
__glEmptyImage(gc, 1, height, 1, 1, format, type, buf,
column);
extra = 4 - (heightsize & 3);
_XRead(dpy, (char *) buf, heightsize);
if (extra < 4) {
_XEatData(dpy, extra);
}
Xfree((char*) buf);
}
}
}
}
__glEmptyImage(gc, 1, height, 1, 1, format, type, buf, column);
Xfree((char *) buf);
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More