Merge remote branch 'origin/gallium-0.2' into gallium-0.2
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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=%)
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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'
|
||||
])
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@ rtasm = env.ConvenienceLibrary(
|
||||
'rtasm_cpu.c',
|
||||
'rtasm_execmem.c',
|
||||
'rtasm_x86sse.c',
|
||||
'rtasm_ppc.c',
|
||||
'rtasm_ppc_spe.c',
|
||||
])
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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 */
|
||||
@@ -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];
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+79
-71
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+184
-178
@@ -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
@@ -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
@@ -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
@@ -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,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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+1334
-1224
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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, ¶m);
|
||||
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, ¶m);
|
||||
break;
|
||||
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
__glXSetError(gc, GL_INVALID_ENUM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+297
-272
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+128
-120
@@ -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
Reference in New Issue
Block a user