Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/mesa/mesa into r6xx-rewrite

This commit is contained in:
Alex Deucher 2009-07-17 14:46:40 -04:00
commit e910f6831b
43 changed files with 1904 additions and 847 deletions

View file

@ -105,7 +105,7 @@ GALLIUM_STATE_TRACKERS_DIRS = glx
# Library dependencies
#EXTRA_LIB_PATH ?=
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -ldl
EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -ldl -lpthread
OSMESA_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
GLU_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm
GLUT_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -lX11 -lXmu -lXi -lm

View file

@ -7,4 +7,5 @@ eglscreen
egltri
peglgears
xeglgears
xeglthreads
xegl_tri

View file

@ -18,6 +18,7 @@ PROGRAMS = \
eglscreen \
peglgears \
xeglgears \
xeglthreads \
xegl_tri
@ -90,6 +91,13 @@ xeglgears.o: xeglgears.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include xeglgears.c
xeglthreads: xeglthreads.o $(TOP)/$(LIB_DIR)/libEGL.so
$(CC) $(CFLAGS) xeglthreads.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
xeglthreads.o: xeglthreads.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include xeglthreads.c
xegl_tri: xegl_tri.o $(TOP)/$(LIB_DIR)/libEGL.so
$(CC) $(CFLAGS) xegl_tri.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@

773
progs/egl/xeglthreads.c Normal file
View file

@ -0,0 +1,773 @@
/*
* Copyright (C) 2000 Brian Paul 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, sublicense,
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL 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.
*
* Ported to EGL by Chia-I Wu <olvaffe@gmail.com>
*/
/*
* This program tests EGL thread safety.
* Command line options:
* -p Open a display connection for each thread
* -l Enable application-side locking
* -n <num threads> Number of threads to create (default is 2)
* -display <display name> Specify X display (default is $DISPLAY)
* -t Use texture mapping
*
* Brian Paul 20 July 2000
*/
/*
* Notes:
* - Each thread gets its own EGL context.
*
* - The EGL contexts share texture objects.
*
* - When 't' is pressed to update the texture image, the window/thread which
* has input focus is signalled to change the texture. The other threads
* should see the updated texture the next time they call glBindTexture.
*/
#if defined(PTHREADS) /* defined by Mesa on Linux and other platforms */
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <EGL/egl.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
/*
* Each window/thread/context:
*/
struct winthread {
Display *Dpy;
int Index;
pthread_t Thread;
Window Win;
EGLDisplay Display;
EGLContext Context;
EGLSurface Surface;
float Angle;
int WinWidth, WinHeight;
GLboolean NewSize;
GLboolean Initialized;
GLboolean MakeNewTexture;
};
#define MAX_WINTHREADS 100
static struct winthread WinThreads[MAX_WINTHREADS];
static int NumWinThreads = 0;
static volatile GLboolean ExitFlag = GL_FALSE;
static GLboolean MultiDisplays = 0;
static GLboolean Locking = 0;
static GLboolean Texture = GL_FALSE;
static GLuint TexObj = 12;
static GLboolean Animate = GL_TRUE;
static pthread_mutex_t Mutex;
static pthread_cond_t CondVar;
static pthread_mutex_t CondMutex;
static void
Error(const char *msg)
{
fprintf(stderr, "Error: %s\n", msg);
exit(1);
}
static void
signal_redraw(void)
{
pthread_mutex_lock(&CondMutex);
pthread_cond_broadcast(&CondVar);
pthread_mutex_unlock(&CondMutex);
}
static void
MakeNewTexture(struct winthread *wt)
{
#define TEX_SIZE 128
static float step = 0.0;
GLfloat image[TEX_SIZE][TEX_SIZE][4];
GLint width;
int i, j;
for (j = 0; j < TEX_SIZE; j++) {
for (i = 0; i < TEX_SIZE; i++) {
float dt = 5.0 * (j - 0.5 * TEX_SIZE) / TEX_SIZE;
float ds = 5.0 * (i - 0.5 * TEX_SIZE) / TEX_SIZE;
float r = dt * dt + ds * ds + step;
image[j][i][0] =
image[j][i][1] =
image[j][i][2] = 0.75 + 0.25 * cos(r);
image[j][i][3] = 1.0;
}
}
step += 0.5;
glBindTexture(GL_TEXTURE_2D, TexObj);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
if (width) {
assert(width == TEX_SIZE);
/* sub-tex replace */
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, TEX_SIZE, TEX_SIZE,
GL_RGBA, GL_FLOAT, image);
}
else {
/* create new */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
GL_RGBA, GL_FLOAT, image);
}
}
/* draw a colored cube */
static void
draw_object(void)
{
glPushMatrix();
glScalef(0.75, 0.75, 0.75);
glColor3f(1, 0, 0);
if (Texture) {
glBindTexture(GL_TEXTURE_2D, TexObj);
glEnable(GL_TEXTURE_2D);
}
else {
glDisable(GL_TEXTURE_2D);
}
glBegin(GL_QUADS);
/* -X */
glColor3f(0, 1, 1);
glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2f(1, 0); glVertex3f(-1, 1, -1);
glTexCoord2f(1, 1); glVertex3f(-1, 1, 1);
glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
/* +X */
glColor3f(1, 0, 0);
glTexCoord2f(0, 0); glVertex3f(1, -1, -1);
glTexCoord2f(1, 0); glVertex3f(1, 1, -1);
glTexCoord2f(1, 1); glVertex3f(1, 1, 1);
glTexCoord2f(0, 1); glVertex3f(1, -1, 1);
/* -Y */
glColor3f(1, 0, 1);
glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2f(1, 1); glVertex3f( 1, -1, 1);
glTexCoord2f(0, 1); glVertex3f(-1, -1, 1);
/* +Y */
glColor3f(0, 1, 0);
glTexCoord2f(0, 0); glVertex3f(-1, 1, -1);
glTexCoord2f(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
/* -Z */
glColor3f(1, 1, 0);
glTexCoord2f(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2f(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2f(1, 1); glVertex3f( 1, 1, -1);
glTexCoord2f(0, 1); glVertex3f(-1, 1, -1);
/* +Y */
glColor3f(0, 0, 1);
glTexCoord2f(0, 0); glVertex3f(-1, -1, 1);
glTexCoord2f(1, 0); glVertex3f( 1, -1, 1);
glTexCoord2f(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2f(0, 1); glVertex3f(-1, 1, 1);
glEnd();
glPopMatrix();
}
/* signal resize of given window */
static void
resize(struct winthread *wt, int w, int h)
{
wt->NewSize = GL_TRUE;
wt->WinWidth = w;
wt->WinHeight = h;
if (!Animate)
signal_redraw();
}
/*
* We have an instance of this for each thread.
*/
static void
draw_loop(struct winthread *wt)
{
while (!ExitFlag) {
if (Locking)
pthread_mutex_lock(&Mutex);
if (!wt->Initialized) {
eglMakeCurrent(wt->Display, wt->Surface, wt->Surface, wt->Context);
printf("xeglthreads: %d: GL_RENDERER = %s\n", wt->Index,
(char *) glGetString(GL_RENDERER));
if (Texture /*&& wt->Index == 0*/) {
MakeNewTexture(wt);
}
wt->Initialized = GL_TRUE;
}
if (Locking)
pthread_mutex_unlock(&Mutex);
eglBindAPI(EGL_OPENGL_API);
if (eglGetCurrentContext() != wt->Context) {
printf("xeglthreads: current context %p != %p\n",
eglGetCurrentContext(), wt->Context);
}
glEnable(GL_DEPTH_TEST);
if (wt->NewSize) {
GLfloat w = (float) wt->WinWidth / (float) wt->WinHeight;
glViewport(0, 0, wt->WinWidth, wt->WinHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-w, w, -1.0, 1.0, 1.5, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -2.5);
wt->NewSize = GL_FALSE;
}
if (wt->MakeNewTexture) {
MakeNewTexture(wt);
wt->MakeNewTexture = GL_FALSE;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(wt->Angle, 0, 1, 0);
glRotatef(wt->Angle, 1, 0, 0);
glScalef(0.7, 0.7, 0.7);
draw_object();
glPopMatrix();
if (Locking)
pthread_mutex_lock(&Mutex);
eglSwapBuffers(wt->Display, wt->Surface);
if (Locking)
pthread_mutex_unlock(&Mutex);
if (Animate) {
usleep(5000);
}
else {
/* wait for signal to draw */
pthread_mutex_lock(&CondMutex);
pthread_cond_wait(&CondVar, &CondMutex);
pthread_mutex_unlock(&CondMutex);
}
wt->Angle += 1.0;
}
eglMakeCurrent(wt->Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
static void
keypress(XEvent *event, struct winthread *wt)
{
char buf[100];
KeySym keySym;
XComposeStatus stat;
XLookupString(&event->xkey, buf, sizeof(buf), &keySym, &stat);
switch (keySym) {
case XK_Escape:
/* tell all threads to exit */
if (!Animate) {
signal_redraw();
}
ExitFlag = GL_TRUE;
/*printf("exit draw_loop %d\n", wt->Index);*/
return;
case XK_t:
case XK_T:
if (Texture) {
wt->MakeNewTexture = GL_TRUE;
if (!Animate)
signal_redraw();
}
break;
case XK_a:
case XK_A:
Animate = !Animate;
if (Animate) /* yes, prev Animate state! */
signal_redraw();
break;
case XK_s:
case XK_S:
if (!Animate)
signal_redraw();
break;
default:
; /* nop */
}
}
/*
* The main process thread runs this loop.
* Single display connection for all threads.
*/
static void
event_loop(Display *dpy)
{
XEvent event;
int i;
assert(!MultiDisplays);
while (!ExitFlag) {
if (Locking) {
while (1) {
int k;
pthread_mutex_lock(&Mutex);
k = XPending(dpy);
if (k) {
XNextEvent(dpy, &event);
pthread_mutex_unlock(&Mutex);
break;
}
pthread_mutex_unlock(&Mutex);
usleep(5000);
}
}
else {
XNextEvent(dpy, &event);
}
switch (event.type) {
case ConfigureNotify:
/* Find winthread for this event's window */
for (i = 0; i < NumWinThreads; i++) {
struct winthread *wt = &WinThreads[i];
if (event.xconfigure.window == wt->Win) {
resize(wt, event.xconfigure.width,
event.xconfigure.height);
break;
}
}
break;
case KeyPress:
for (i = 0; i < NumWinThreads; i++) {
struct winthread *wt = &WinThreads[i];
if (event.xkey.window == wt->Win) {
keypress(&event, wt);
break;
}
}
break;
default:
/*no-op*/ ;
}
}
}
/*
* Separate display connection for each thread.
*/
static void
event_loop_multi(void)
{
XEvent event;
int w = 0;
assert(MultiDisplays);
while (!ExitFlag) {
struct winthread *wt = &WinThreads[w];
if (XPending(wt->Dpy)) {
XNextEvent(wt->Dpy, &event);
switch (event.type) {
case ConfigureNotify:
resize(wt, event.xconfigure.width, event.xconfigure.height);
break;
case KeyPress:
keypress(&event, wt);
break;
default:
; /* nop */
}
}
w = (w + 1) % NumWinThreads;
usleep(5000);
}
}
/*
* we'll call this once for each thread, before the threads are created.
*/
static void
create_window(struct winthread *wt, EGLContext shareCtx)
{
Window win;
EGLContext ctx;
EGLSurface surf;
EGLint attribs[] = { EGL_RED_SIZE, 1,
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_NONE };
EGLConfig config;
EGLint num_configs;
EGLint vid;
int scrnum;
XSetWindowAttributes attr;
unsigned long mask;
Window root;
XVisualInfo *visinfo, visTemplate;
int num_visuals;
int width = 160, height = 160;
int xpos = (wt->Index % 8) * (width + 10);
int ypos = (wt->Index / 8) * (width + 20);
scrnum = DefaultScreen(wt->Dpy);
root = RootWindow(wt->Dpy, scrnum);
if (!eglChooseConfig(wt->Display, attribs, &config, 1, &num_configs)) {
Error("Unable to choose an EGL config");
}
assert(config);
assert(num_configs > 0);
if (!eglGetConfigAttrib(wt->Display, config, EGL_NATIVE_VISUAL_ID, &vid)) {
Error("Unable to get visual id of EGL config\n");
}
visTemplate.visualid = vid;
visinfo = XGetVisualInfo(wt->Dpy, VisualIDMask,
&visTemplate, &num_visuals);
if (!visinfo) {
Error("Unable to find RGB, Z, double-buffered visual");
}
/* window attributes */
attr.background_pixel = 0;
attr.border_pixel = 0;
attr.colormap = XCreateColormap(wt->Dpy, root, visinfo->visual, AllocNone);
attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
win = XCreateWindow(wt->Dpy, root, xpos, ypos, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr);
if (!win) {
Error("Couldn't create window");
}
XFree(visinfo);
{
XSizeHints sizehints;
sizehints.x = xpos;
sizehints.y = ypos;
sizehints.width = width;
sizehints.height = height;
sizehints.flags = USSize | USPosition;
XSetNormalHints(wt->Dpy, win, &sizehints);
XSetStandardProperties(wt->Dpy, win, "xeglthreads", "xeglthreads",
None, (char **)NULL, 0, &sizehints);
}
eglBindAPI(EGL_OPENGL_API);
ctx = eglCreateContext(wt->Display, config, shareCtx, NULL);
if (!ctx) {
Error("Couldn't create EGL context");
}
surf = eglCreateWindowSurface(wt->Display, config, win, NULL);
if (!surf) {
Error("Couldn't create EGL surface");
}
XMapWindow(wt->Dpy, win);
XSync(wt->Dpy, 0);
/* save the info for this window/context */
wt->Win = win;
wt->Context = ctx;
wt->Surface = surf;
wt->Angle = 0.0;
wt->WinWidth = width;
wt->WinHeight = height;
wt->NewSize = GL_TRUE;
}
/*
* Called by pthread_create()
*/
static void *
thread_function(void *p)
{
struct winthread *wt = (struct winthread *) p;
draw_loop(wt);
return NULL;
}
/*
* called before exit to wait for all threads to finish
*/
static void
clean_up(void)
{
int i;
/* wait for threads to finish */
for (i = 0; i < NumWinThreads; i++) {
pthread_join(WinThreads[i].Thread, NULL);
}
for (i = 0; i < NumWinThreads; i++) {
eglDestroyContext(WinThreads[i].Display, WinThreads[i].Context);
XDestroyWindow(WinThreads[i].Dpy, WinThreads[i].Win);
}
}
static void
usage(void)
{
printf("xeglthreads: test of EGL/GL thread safety (any key = exit)\n");
printf("Usage:\n");
printf(" xeglthreads [options]\n");
printf("Options:\n");
printf(" -display DISPLAYNAME Specify display string\n");
printf(" -n NUMTHREADS Number of threads to create\n");
printf(" -p Use a separate display connection for each thread\n");
printf(" -l Use application-side locking\n");
printf(" -t Enable texturing\n");
printf("Keyboard:\n");
printf(" Esc Exit\n");
printf(" t Change texture image (requires -t option)\n");
printf(" a Toggle animation\n");
printf(" s Step rotation (when not animating)\n");
}
int
main(int argc, char *argv[])
{
char *displayName = NULL;
int numThreads = 2;
Display *dpy = NULL;
EGLDisplay *egl_dpy = NULL;
int i;
Status threadStat;
if (argc == 1) {
usage();
}
else {
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-display") == 0 && i + 1 < argc) {
displayName = argv[i + 1];
i++;
}
else if (strcmp(argv[i], "-p") == 0) {
MultiDisplays = 1;
}
else if (strcmp(argv[i], "-l") == 0) {
Locking = 1;
}
else if (strcmp(argv[i], "-t") == 0) {
Texture = 1;
}
else if (strcmp(argv[i], "-n") == 0 && i + 1 < argc) {
numThreads = atoi(argv[i + 1]);
if (numThreads < 1)
numThreads = 1;
else if (numThreads > MAX_WINTHREADS)
numThreads = MAX_WINTHREADS;
i++;
}
else {
usage();
exit(1);
}
}
}
if (Locking)
printf("xeglthreads: Using explicit locks around Xlib calls.\n");
else
printf("xeglthreads: No explict locking.\n");
if (MultiDisplays)
printf("xeglthreads: Per-thread display connections.\n");
else
printf("xeglthreads: Single display connection.\n");
/*
* VERY IMPORTANT: call XInitThreads() before any other Xlib functions.
*/
if (!MultiDisplays) {
if (!Locking) {
threadStat = XInitThreads();
if (threadStat) {
printf("XInitThreads() returned %d (success)\n",
(int) threadStat);
}
else {
printf("XInitThreads() returned 0 "
"(failure- this program may fail)\n");
}
}
dpy = XOpenDisplay(displayName);
if (!dpy) {
fprintf(stderr, "Unable to open display %s\n",
XDisplayName(displayName));
return -1;
}
egl_dpy = eglGetDisplay(dpy);
if (!egl_dpy) {
fprintf(stderr, "Unable to get EGL display\n");
XCloseDisplay(dpy);
return -1;
}
if (!eglInitialize(egl_dpy, NULL, NULL)) {
fprintf(stderr, "Unable to initialize EGL display\n");
return -1;
}
}
pthread_mutex_init(&Mutex, NULL);
pthread_mutex_init(&CondMutex, NULL);
pthread_cond_init(&CondVar, NULL);
printf("xeglthreads: creating windows\n");
NumWinThreads = numThreads;
/* Create the EGL windows and contexts */
for (i = 0; i < numThreads; i++) {
EGLContext share;
if (MultiDisplays) {
WinThreads[i].Dpy = XOpenDisplay(displayName);
assert(WinThreads[i].Dpy);
WinThreads[i].Display = eglGetDisplay(WinThreads[i].Dpy);
assert(eglInitialize(WinThreads[i].Display, NULL, NULL));
}
else {
WinThreads[i].Dpy = dpy;
WinThreads[i].Display = egl_dpy;
}
WinThreads[i].Index = i;
WinThreads[i].Initialized = GL_FALSE;
share = (Texture && i > 0) ? WinThreads[0].Context : 0;
create_window(&WinThreads[i], share);
}
printf("xeglthreads: creating threads\n");
/* Create the threads */
for (i = 0; i < numThreads; i++) {
pthread_create(&WinThreads[i].Thread, NULL, thread_function,
(void*) &WinThreads[i]);
printf("xeglthreads: Created thread %p\n",
(void *) WinThreads[i].Thread);
}
if (MultiDisplays)
event_loop_multi();
else
event_loop(dpy);
clean_up();
if (MultiDisplays) {
for (i = 0; i < numThreads; i++) {
eglTerminate(WinThreads[i].Display);
XCloseDisplay(WinThreads[i].Dpy);
}
}
else {
eglTerminate(egl_dpy);
XCloseDisplay(dpy);
}
return 0;
}
#else /* PTHREADS */
#include <stdio.h>
int
main(int argc, char *argv[])
{
printf("Sorry, this program wasn't compiled with PTHREADS defined.\n");
return 0;
}
#endif /* PTHREADS */

View file

@ -146,12 +146,12 @@ demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
if (!c)
return EGL_NO_CONTEXT;
_eglInitContext(drv, dpy, &c->Base, config, attrib_list);
_eglInitContext(drv, &c->Base, conf, attrib_list);
c->DemoStuff = 1;
printf("demoCreateContext\n");
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
/* link to display */
_eglLinkContext(&c->Base, _eglLookupDisplay(dpy));
assert(_eglGetContextHandle(&c->Base));
return _eglGetContextHandle(&c->Base);
@ -213,11 +213,14 @@ demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
_EGLConfig *conf;
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT,
config, attrib_list)) {
conf = _eglLookupConfig(drv, dpy, config);
if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
@ -232,13 +235,9 @@ static EGLBoolean
demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
DemoSurface *fs = LookupDemoSurface(surface);
_eglRemoveSurface(&fs->Base);
if (fs->Base.IsBound) {
fs->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(&fs->Base);
if (!fs->Base.IsBound)
free(fs);
}
return EGL_TRUE;
}
@ -247,13 +246,9 @@ static EGLBoolean
demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
DemoContext *fc = LookupDemoContext(context);
_eglRemoveContext(&fc->Base);
if (fc->Base.IsBound) {
fc->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkContext(&fc->Base);
if (!fc->Base.IsBound)
free(fc);
}
return EGL_TRUE;
}

View file

@ -171,7 +171,10 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!c)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, &c->Base, config, attrib_list)) {
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
if (!_eglInitContext(drv, &c->Base, conf, attrib_list)) {
free(c);
return EGL_NO_CONTEXT;
}
@ -189,8 +192,6 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
else
sharePriv = NULL;
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
_eglConfigToContextModesRec(conf, &visMode);
c->driContext.private = disp->driScreen.createNewContext(disp, &visMode,
@ -200,8 +201,8 @@ _eglDRICreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_FALSE;
}
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
/* link to display */
_eglLinkContext(&c->Base, &disp->Base);
return _eglGetContextHandle(&c->Base);
}
@ -237,14 +238,18 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
driSurface *surf;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
surf = (driSurface *) calloc(1, sizeof(*surf));
if (!surf) {
return EGL_NO_SURFACE;
}
if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_PBUFFER_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
@ -275,7 +280,7 @@ _eglDRICreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
#endif
}
_eglSaveSurface(&surf->Base);
_eglLinkSurface(&surf->Base, _eglLookupDisplay(dpy));
return surf->Base.Handle;
}
@ -287,16 +292,12 @@ _eglDRIDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
driDisplay *disp = Lookup_driDisplay(dpy);
driSurface *fs = Lookup_driSurface(surface);
_eglRemoveSurface(&fs->Base);
_eglUnlinkSurface(&fs->Base);
fs->drawable.destroyDrawable(disp, fs->drawable.private);
if (fs->Base.IsBound) {
fs->Base.DeletePending = EGL_TRUE;
}
else {
if (!fs->Base.IsBound)
free(fs);
}
return EGL_TRUE;
}
@ -307,16 +308,12 @@ _eglDRIDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
driDisplay *disp = Lookup_driDisplay(dpy);
driContext *fc = Lookup_driContext(context);
_eglRemoveContext(&fc->Base);
_eglUnlinkContext(&fc->Base);
fc->driContext.destroyContext(disp, 0, fc->driContext.private);
if (fc->Base.IsBound) {
fc->Base.DeletePending = EGL_TRUE;
}
else {
if (!fc->Base.IsBound)
free(fc);
}
return EGL_TRUE;
}
@ -340,13 +337,13 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
}
/* init base class, do error checking, etc. */
if (!_eglInitSurface(drv, dpy, &surface->Base, EGL_SCREEN_BIT_MESA,
cfg, attrib_list)) {
if (!_eglInitSurface(drv, &surface->Base, EGL_SCREEN_BIT_MESA,
config, attrib_list)) {
free(surface);
return EGL_NO_SURFACE;
}
_eglSaveSurface(&surface->Base);
_eglLinkSurface(&surface->Base &disp->Base);
/*
@ -363,7 +360,7 @@ _eglDRICreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
if (!disp->driScreen.createNewDrawable(disp, &visMode, drawBuf,
&surface->drawable, GLX_WINDOW_BIT,
empty_attribute_list)) {
_eglRemoveSurface(&surface->Base);
_eglUnlinkSurface(&surface->Base);
free(surface);
return EGL_NO_SURFACE;
}

View file

@ -532,7 +532,10 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!GLX_ctx)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, &GLX_ctx->Base, config, attrib_list)) {
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
free(GLX_ctx);
return EGL_NO_CONTEXT;
}
@ -546,9 +549,6 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
GLX_ctx_shared = GLX_egl_context(shareCtx);
}
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
#ifdef GLX_VERSION_1_3
if (GLX_drv->fbconfigs)
GLX_ctx->context = glXCreateNewContext(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], GLX_RGBA_TYPE, GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE);
@ -564,7 +564,7 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_FALSE;
#endif
return _eglGetContextHandle(&GLX_ctx->Base);
return _eglLinkContext(&GLX_ctx->Base, disp);
}
@ -619,18 +619,22 @@ GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct GLX_egl_surface *GLX_surf;
uint width, height;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
if (!GLX_surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_WINDOW_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(GLX_surf);
return EGL_FALSE;
}
_eglSaveSurface(&GLX_surf->Base);
_eglLinkSurface(&GLX_surf->Base, disp);
GLX_surf->drawable = window;
get_drawable_size(disp->Xdpy, window, &width, &height);
@ -648,19 +652,23 @@ GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct GLX_egl_surface *GLX_surf;
_EGLConfig *conf;
int i;
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
if (!GLX_surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PIXMAP_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
conf, attrib_list)) {
free(GLX_surf);
return EGL_FALSE;
}
_eglSaveSurface(&GLX_surf->Base);
_eglLinkSurface(&GLX_surf->Base, disp);
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
@ -683,20 +691,24 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct GLX_egl_surface *GLX_surf;
_EGLConfig *conf;
int attribs[5];
int i = 0, j = 0;
conf = _eglLookupConfig(drv, dpy, config);
assert(conf);
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
if (!GLX_surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &GLX_surf->Base, EGL_PBUFFER_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(GLX_surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(&GLX_surf->Base);
_eglLinkSurface(&GLX_surf->Base, disp);
while(attrib_list[i] != EGL_NONE) {
switch (attrib_list[i]) {
@ -726,13 +738,9 @@ GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
_EGLSurface *surf = _eglLookupSurface(surface);
return EGL_TRUE;
if (surf) {
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
if (surf->IsBound) {
surf->DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(surf);
if (!surf->IsBound)
free(surf);
}
return EGL_TRUE;
}

View file

@ -770,7 +770,7 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!xdri_ctx)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, &xdri_ctx->Base, config, attrib_list)) {
if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
free(xdri_ctx);
return EGL_NO_CONTEXT;
}
@ -794,7 +794,7 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
xdri_ctx->driContext.mode = xdri_config->mode;
return _eglGetContextHandle(&xdri_ctx->Base);
return _eglLinkContext(&xdri_ctx->Base, &disp);
}
@ -835,6 +835,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
NativeWindowType window, const EGLint *attrib_list)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
struct xdri_egl_surface *xdri_surf;
int scrn = DefaultScreen(disp->Xdpy);
uint width, height;
@ -843,8 +844,8 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!xdri_surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_WINDOW_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT,
&xdri_config->Base, attrib_list)) {
free(xdri_surf);
return EGL_FALSE;
}
@ -856,7 +857,7 @@ xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
xdri_surf->driDrawable = window;
_eglSaveSurface(&xdri_surf->Base);
_eglLinkSurface(&xdri_surf->Base, disp);
get_drawable_size(disp->Xdpy, window, &width, &height);
xdri_surf->Base.Width = width;
@ -888,8 +889,8 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!xdri_surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, &xdri_surf->Base, EGL_PBUFFER_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_PBUFFER_BIT,
&xdri_config->Base, attrib_list)) {
free(xdri_surf);
return EGL_FALSE;
}
@ -939,7 +940,7 @@ xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
xdri_surf->driDrawable = window;
_eglSaveSurface(&xdri_surf->Base);
_eglLinkSurface(&xdri_surf->Base, disp);
_eglLog(_EGL_DEBUG,
"XDRI: CreatePbufferSurface handle %d hDrawable %d",
@ -956,11 +957,8 @@ xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
if (xdri_surf) {
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
if (xdri_surf->Base.IsBound) {
xdri_surf->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(&xdri_surf->Base);
if (!xdri_surf->Base.IsBound) {
/*
st_unreference_framebuffer(surf->Framebuffer);
*/

View file

@ -7,9 +7,11 @@ include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
HEADERS = \
eglcompiler.h \
eglconfig.h \
eglconfigutil.h \
eglcontext.h \
eglcurrent.h \
egldefines.h \
egldisplay.h \
egldriver.h \
@ -28,6 +30,7 @@ SOURCES = \
eglconfig.c \
eglconfigutil.c \
eglcontext.c \
eglcurrent.c \
egldisplay.c \
egldriver.c \
eglglobals.c \

View file

@ -51,7 +51,12 @@ eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
_eglInitGlobals();
dpy = _eglNewDisplay(nativeDisplay);
dpy = _eglFindDisplay(nativeDisplay);
if (!dpy) {
dpy = _eglNewDisplay(nativeDisplay);
if (dpy)
_eglLinkDisplay(dpy);
}
return _eglGetDisplayHandle(dpy);
}
@ -321,7 +326,8 @@ eglGetError(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLint e = t->LastError;
t->LastError = EGL_SUCCESS;
if (!_eglIsCurrentThreadDummy())
t->LastError = EGL_SUCCESS;
return e;
}
@ -546,11 +552,17 @@ eglBindAPI(EGLenum api)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglBindAPI");
if (!_eglIsApiValid(api))
return _eglError(EGL_BAD_PARAMETER, "eglBindAPI");
switch (api) {
#ifdef EGL_VERSION_1_4
case EGL_OPENGL_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT) {
t->CurrentAPI = api;
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
@ -558,14 +570,14 @@ eglBindAPI(EGLenum api)
#endif
case EGL_OPENGL_ES_API:
if (_eglGlobal.ClientAPIsMask & (EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT)) {
t->CurrentAPI = api;
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
return EGL_FALSE;
case EGL_OPENVG_API:
if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT) {
t->CurrentAPI = api;
t->CurrentAPIIndex = _eglConvertApiToIndex(api);
return EGL_TRUE;
}
_eglError(EGL_BAD_PARAMETER, "eglBindAPI");
@ -585,7 +597,7 @@ eglQueryAPI(void)
{
/* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */
_EGLThreadInfo *t = _eglGetCurrentThread();
return t->CurrentAPI;
return _eglConvertApiFromIndex(t->CurrentAPIIndex);
}
@ -603,15 +615,19 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLBoolean
eglReleaseThread(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
EGLDisplay dpy = eglGetCurrentDisplay();
EGLDisplay dpy;
if (_eglIsCurrentThreadDummy())
return EGL_TRUE;
dpy = eglGetCurrentDisplay();
if (dpy) {
_EGLDriver *drv = _eglLookupDriver(dpy);
/* unbind context */
(void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
_eglDeleteThreadData(t);
_eglDestroyCurrentThread();
return EGL_TRUE;
}

View file

@ -0,0 +1,31 @@
#ifndef EGLCOMPILER_INCLUDED
#define EGLCOMPILER_INCLUDED
/**
* Function inlining
*/
#if defined(__GNUC__)
# define INLINE __inline__
#elif defined(__MSC__)
# define INLINE __inline
#elif defined(_MSC_VER)
# define INLINE __inline
#elif defined(__ICL)
# define INLINE __inline
#elif defined(__INTEL_COMPILER)
# define INLINE inline
#elif defined(__WATCOMC__) && (__WATCOMC__ >= 1100)
# define INLINE __inline
#elif defined(__SUNPRO_C) && defined(__C99FEATURES__)
# define INLINE inline
# define __inline inline
# define __inline__ inline
#elif (__STDC_VERSION__ >= 199901L) /* C99 */
# define INLINE inline
#else
# define INLINE
#endif
#endif /* EGLCOMPILER_INCLUDED */

View file

@ -14,11 +14,9 @@
* in the attrib_list.
*/
EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list)
_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
_EGLConfig *conf, const EGLint *attrib_list)
{
_EGLConfig *conf;
_EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint i;
const EGLenum api = eglQueryAPI();
@ -27,7 +25,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
return EGL_FALSE;
}
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "_eglInitContext");
return EGL_FALSE;
@ -49,7 +46,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
}
}
ctx->Display = display;
ctx->Config = conf;
ctx->DrawSurface = EGL_NO_SURFACE;
ctx->ReadSurface = EGL_NO_SURFACE;
@ -59,66 +55,6 @@ _eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
}
/**
* Save a new _EGLContext into the hash table.
*/
void
_eglSaveContext(_EGLContext *ctx)
{
/* no-op.
* Public EGLContext handle and private _EGLContext are the same.
*/
}
/**
* Remove the given _EGLContext object from the hash table.
*/
void
_eglRemoveContext(_EGLContext *ctx)
{
/* no-op.
* Public EGLContext handle and private _EGLContext are the same.
*/
}
/**
* Return the public handle for the given private context ptr.
* This is the inverse of _eglLookupContext().
*/
EGLContext
_eglGetContextHandle(_EGLContext *ctx)
{
/* just a cast! */
return (EGLContext) ctx;
}
/**
* Return the _EGLContext object that corresponds to the given
* EGLContext handle.
* This is the inverse of _eglGetContextHandle().
*/
_EGLContext *
_eglLookupContext(EGLContext ctx)
{
/* just a cast since EGLContext is just a void ptr */
return (_EGLContext *) ctx;
}
/**
* Return the currently bound _EGLContext object, or NULL.
*/
_EGLContext *
_eglGetCurrentContext(void)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
return t->CurrentContext;
}
/**
* Just a placeholder/demo function. Real driver will never use this!
*/
@ -128,18 +64,24 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* example code */
_EGLContext *context;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_NO_CONTEXT;
}
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, context, config, attrib_list)) {
if (!_eglInitContext(drv, context, conf, attrib_list)) {
free(context);
return EGL_NO_CONTEXT;
}
_eglSaveContext(context);
return (EGLContext) context;
return _eglLinkContext(context, _eglLookupDisplay(dpy));
#endif
return EGL_NO_CONTEXT;
}
@ -153,12 +95,9 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
if (context->IsBound) {
context->DeletePending = EGL_TRUE;
}
else {
_eglUnlinkContext(context);
if (!context->IsBound)
free(context);
}
return EGL_TRUE;
}
else {
@ -203,7 +142,7 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
/**
* Drivers will typically call this to do the error checking and
* update the various IsBound and DeletePending flags.
* update the various flags.
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
@ -214,10 +153,13 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_EGLContext *ctx = _eglLookupContext(context);
_EGLSurface *draw = _eglLookupSurface(d);
_EGLSurface *read = _eglLookupSurface(r);
_EGLContext *oldContext = NULL;
_EGLSurface *oldDrawSurface = NULL;
_EGLSurface *oldReadSurface = NULL;
EGLint apiIndex;
_EGLContext *oldContext = _eglGetCurrentContext();
_EGLSurface *oldDrawSurface = _eglGetCurrentSurface(EGL_DRAW);
_EGLSurface *oldReadSurface = _eglGetCurrentSurface(EGL_READ);
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
/* error checking */
if (ctx) {
@ -233,6 +175,32 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
_eglError(EGL_BAD_MATCH, "eglMakeCurrent");
return EGL_FALSE;
}
#ifdef EGL_VERSION_1_4
/* OpenGL and OpenGL ES are conflicting */
switch (ctx->ClientAPI) {
case EGL_OPENGL_ES_API:
if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_API)])
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
break;
case EGL_OPENGL_API:
if (t->CurrentContexts[_eglConvertApiToIndex(EGL_OPENGL_ES_API)])
return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
break;
default:
break;
}
#endif
apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
}
else {
apiIndex = t->CurrentAPIIndex;
}
oldContext = t->CurrentContexts[apiIndex];
if (oldContext) {
oldDrawSurface = oldContext->DrawSurface;
oldReadSurface = oldContext->ReadSurface;
}
/*
@ -240,7 +208,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
*/
if (oldDrawSurface != NULL) {
oldDrawSurface->IsBound = EGL_FALSE;
if (oldDrawSurface->DeletePending) {
if (!_eglIsSurfaceLinked(oldDrawSurface)) {
/* make sure we don't try to rebind a deleted surface */
if (draw == oldDrawSurface || draw == oldReadSurface) {
draw = NULL;
@ -251,7 +219,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
}
if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
oldReadSurface->IsBound = EGL_FALSE;
if (oldReadSurface->DeletePending) {
if (!_eglIsSurfaceLinked(oldReadSurface)) {
/* make sure we don't try to rebind a deleted surface */
if (read == oldDrawSurface || read == oldReadSurface) {
read = NULL;
@ -262,7 +230,7 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
}
if (oldContext != NULL) {
oldContext->IsBound = EGL_FALSE;
if (oldContext->DeletePending) {
if (!_eglIsContextLinked(oldContext)) {
/* make sure we don't try to rebind a deleted context */
if (ctx == oldContext) {
ctx = NULL;
@ -283,9 +251,11 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
ctx->IsBound = EGL_TRUE;
draw->IsBound = EGL_TRUE;
read->IsBound = EGL_TRUE;
t->CurrentContexts[apiIndex] = ctx;
}
else {
t->CurrentContexts[apiIndex] = NULL;
}
t->CurrentContext = ctx;
return EGL_TRUE;
}

View file

@ -11,7 +11,9 @@
*/
struct _egl_context
{
_EGLDisplay *Display; /* who do I belong to? */
/* Managed by EGLDisplay for linking */
_EGLDisplay *Display;
_EGLContext *Next;
_EGLConfig *Config;
@ -19,7 +21,6 @@ struct _egl_context
_EGLSurface *ReadSurface;
EGLBoolean IsBound;
EGLBoolean DeletePending;
EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
@ -27,28 +28,8 @@ struct _egl_context
extern EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list);
extern void
_eglSaveContext(_EGLContext *ctx);
extern void
_eglRemoveContext(_EGLContext *ctx);
extern EGLContext
_eglGetContextHandle(_EGLContext *ctx);
extern _EGLContext *
_eglLookupContext(EGLContext ctx);
extern _EGLContext *
_eglGetCurrentContext(void);
_eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
_EGLConfig *config, const EGLint *attrib_list);
extern EGLContext

View file

@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include "eglcontext.h"
#include "eglsurface.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
@ -25,11 +26,6 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
if (dpy) {
EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
dpy->Handle = (EGLDisplay) key;
_eglHashInsert(_eglGlobal.Displays, key, dpy);
dpy->NativeDisplay = nativeDisplay;
#if defined(_EGL_PLATFORM_X)
dpy->Xdpy = (Display *) nativeDisplay;
@ -46,8 +42,37 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
/**
* Return the public handle for an internal _EGLDisplay.
* This is the inverse of _eglLookupDisplay().
* Link a display to itself and return the handle of the link.
* The handle can be passed to client directly.
*/
EGLDisplay
_eglLinkDisplay(_EGLDisplay *dpy)
{
EGLuint key;
key = _eglHashGenKey(_eglGlobal.Displays);
assert(key);
/* "link" the display to the hash table */
_eglHashInsert(_eglGlobal.Displays, key, dpy);
dpy->Handle = (EGLDisplay) key;
return dpy->Handle;
}
/**
* Unlink a linked display from itself.
* Accessing an unlinked display should generate EGL_BAD_DISPLAY error.
*/
void
_eglUnlinkDisplay(_EGLDisplay *dpy)
{
_eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle);
dpy->Handle = EGL_NO_DISPLAY;
}
/**
* Return the handle of a linked display, or EGL_NO_DISPLAY.
*/
EGLDisplay
_eglGetDisplayHandle(_EGLDisplay *display)
@ -60,40 +85,70 @@ _eglGetDisplayHandle(_EGLDisplay *display)
/**
* Return the _EGLDisplay object that corresponds to the given public/
* opaque display handle.
* This is the inverse of _eglGetDisplayHandle().
* Lookup a handle to find the linked display.
* Return NULL if the handle has no corresponding linked display.
*/
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
EGLuint key = (EGLuint) dpy;
if (!_eglGlobal.Displays)
return NULL;
return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
}
void
_eglSaveDisplay(_EGLDisplay *dpy)
/**
* Find the display corresponding to the specified native display id in all
* linked displays.
*/
_EGLDisplay *
_eglFindDisplay(NativeDisplayType nativeDisplay)
{
EGLuint key = _eglHashGenKey(_eglGlobal.Displays);
assert(dpy);
assert(!dpy->Handle);
dpy->Handle = (EGLDisplay) key;
assert(dpy->Handle);
_eglHashInsert(_eglGlobal.Displays, key, dpy);
EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays);
/* Walk the hash table. Should switch to list if it is a problem. */
while (key) {
_EGLDisplay *dpy = (_EGLDisplay *)
_eglHashLookup(_eglGlobal.Displays, key);
assert(dpy);
if (dpy->NativeDisplay == nativeDisplay)
return dpy;
key = _eglHashNextEntry(_eglGlobal.Displays, key);
}
return NULL;
}
_EGLDisplay *
_eglGetCurrentDisplay(void)
/**
* Destroy the contexts and surfaces that are linked to the display.
*/
void
_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx)
return ctx->Display;
else
return NULL;
_EGLDisplay *display;
_EGLContext *contexts;
_EGLSurface *surfaces;
display = _eglLookupDisplay(dpy);
if (!display)
return;
contexts = display->ContextList;
surfaces = display->SurfaceList;
while (contexts) {
EGLContext handle = _eglGetContextHandle(contexts);
contexts = contexts->Next;
drv->API.DestroyContext(drv, dpy, handle);
}
assert(!display->ContextList);
while (surfaces) {
EGLSurface handle = _eglGetSurfaceHandle(surfaces);
surfaces = surfaces->Next;
drv->API.DestroySurface(drv, dpy, handle);
}
assert(!display->SurfaceList);
}
@ -119,3 +174,147 @@ _eglCleanupDisplay(_EGLDisplay *disp)
/* driver deletes the _EGLDisplay object */
}
/**
* Link a context to a display and return the handle of the link.
* The handle can be passed to client directly.
*/
EGLContext
_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy)
{
ctx->Display = dpy;
ctx->Next = dpy->ContextList;
dpy->ContextList = ctx;
return (EGLContext) ctx;
}
/**
* Unlink a linked context from its display.
* Accessing an unlinked context should generate EGL_BAD_CONTEXT error.
*/
void
_eglUnlinkContext(_EGLContext *ctx)
{
_EGLContext *prev;
prev = ctx->Display->ContextList;
if (prev != ctx) {
while (prev) {
if (prev->Next == ctx)
break;
prev = prev->Next;
}
assert(prev);
prev->Next = ctx->Next;
}
else {
ctx->Display->ContextList = ctx->Next;
}
ctx->Next = NULL;
ctx->Display = NULL;
}
/**
* Return the handle of a linked context, or EGL_NO_CONTEXT.
*/
EGLContext
_eglGetContextHandle(_EGLContext *ctx)
{
return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT;
}
/**
* Lookup a handle to find the linked context.
* Return NULL if the handle has no corresponding linked context.
*/
_EGLContext *
_eglLookupContext(EGLContext ctx)
{
_EGLContext *context = (_EGLContext *) ctx;
return (context && context->Display) ? context : NULL;
}
/**
* Link a surface to a display and return the handle of the link.
* The handle can be passed to client directly.
*/
EGLSurface
_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
{
EGLuint key;
surf->Display = dpy;
surf->Next = dpy->SurfaceList;
dpy->SurfaceList = surf;
key = _eglHashGenKey(_eglGlobal.Surfaces);
assert(key);
_eglHashInsert(_eglGlobal.Surfaces, key, surf);
surf->Handle = (EGLSurface) key;
return surf->Handle;
}
/**
* Unlink a linked surface from its display.
* Accessing an unlinked surface should generate EGL_BAD_SURFACE error.
*/
void
_eglUnlinkSurface(_EGLSurface *surf)
{
_EGLSurface *prev;
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
surf->Handle = EGL_NO_SURFACE;
prev = surf->Display->SurfaceList;
if (prev != surf) {
while (prev) {
if (prev->Next == surf)
break;
prev = prev->Next;
}
assert(prev);
prev->Next = surf->Next;
}
else {
prev = NULL;
surf->Display->SurfaceList = surf->Next;
}
surf->Next = NULL;
surf->Display = NULL;
}
/**
* Return the handle of a linked surface, or EGL_NO_SURFACE.
*/
EGLSurface
_eglGetSurfaceHandle(_EGLSurface *surface)
{
if (surface)
return surface->Handle;
else
return EGL_NO_SURFACE;
}
/**
* Lookup a handle to find the linked surface.
* Return NULL if the handle has no corresponding linked surface.
*/
_EGLSurface *
_eglLookupSurface(EGLSurface surf)
{
_EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
(EGLuint) surf);
return c;
}

View file

@ -23,6 +23,9 @@ struct _egl_display
EGLint NumConfigs;
_EGLConfig **Configs; /* array [NumConfigs] of ptr to _EGLConfig */
/* lists of linked contexts and surface */
_EGLContext *ContextList;
_EGLSurface *SurfaceList;
#ifdef _EGL_PLATFORM_X
Display *Xdpy;
#endif
@ -33,7 +36,15 @@ extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
EGLDisplay
extern EGLDisplay
_eglLinkDisplay(_EGLDisplay *dpy);
extern void
_eglUnlinkDisplay(_EGLDisplay *dpy);
extern EGLDisplay
_eglGetDisplayHandle(_EGLDisplay *display);
@ -41,21 +52,77 @@ extern _EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy);
extern void
_eglSaveDisplay(_EGLDisplay *dpy);
/**
* Return true if the display is linked.
*/
static INLINE EGLBoolean
_eglIsDisplayLinked(_EGLDisplay *dpy)
{
return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
}
extern _EGLDisplay *
_eglGetCurrentDisplay(void);
_eglFindDisplay(NativeDisplayType nativeDisplay);
extern void
_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy);
extern void
_eglCleanupDisplay(_EGLDisplay *disp);
extern EGLBoolean
_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attrib, EGLint *value);
extern EGLContext
_eglLinkContext(_EGLContext *ctx, _EGLDisplay *dpy);
extern void
_eglUnlinkContext(_EGLContext *ctx);
extern EGLContext
_eglGetContextHandle(_EGLContext *ctx);
extern _EGLContext *
_eglLookupContext(EGLContext ctx);
/**
* Return true if the context is linked to a display.
*/
static INLINE EGLBoolean
_eglIsContextLinked(_EGLContext *ctx)
{
return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
}
extern EGLSurface
_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
extern void
_eglUnlinkSurface(_EGLSurface *surf);
extern EGLSurface
_eglGetSurfaceHandle(_EGLSurface *);
extern _EGLSurface *
_eglLookupSurface(EGLSurface surf);
/**
* Return true if the surface is linked to a display.
*/
static INLINE EGLBoolean
_eglIsSurfaceLinked(_EGLSurface *surf)
{
return (EGLBoolean) (_eglGetSurfaceHandle(surf) != EGL_NO_SURFACE);
}
#endif /* EGLDISPLAY_INCLUDED */

View file

@ -284,9 +284,7 @@ _eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
_eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
/*
* XXX check for currently bound context/surfaces and delete them?
*/
_eglReleaseDisplayResources(drv, dpy);
b = drv->API.Terminate(drv, dpy);

View file

@ -1,6 +1,6 @@
#include <stdio.h>
#include <stdlib.h>
#include "eglglobals.h"
#include "egllog.h"
struct _egl_global _eglGlobal =
{
@ -22,8 +22,8 @@ _eglInitGlobals(void)
_eglGlobal.ClientAPIsMask = 0x0;
/* XXX temporary */
_eglGlobal.ThreadInfo = _eglNewThreadInfo();
if (!_eglInitCurrent())
_eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
}
}
@ -34,113 +34,8 @@ _eglInitGlobals(void)
void
_eglDestroyGlobals(void)
{
_eglFiniCurrent();
/* XXX TODO walk over table entries, deleting each */
_eglDeleteHashTable(_eglGlobal.Displays);
_eglDeleteHashTable(_eglGlobal.Surfaces);
}
/**
* Allocate and init a new _EGLThreadInfo object.
*/
_EGLThreadInfo *
_eglNewThreadInfo(void)
{
_EGLThreadInfo *t = (_EGLThreadInfo *) calloc(1, sizeof(_EGLThreadInfo));
if (t) {
t->CurrentContext = EGL_NO_CONTEXT;
t->LastError = EGL_SUCCESS;
t->CurrentAPI = EGL_OPENGL_ES_API; /* default, per EGL spec */
}
return t;
}
/**
* Delete/free a _EGLThreadInfo object.
*/
void
_eglDeleteThreadData(_EGLThreadInfo *t)
{
free(t);
}
/**
* Return pointer to calling thread's _EGLThreadInfo object.
* Create a new one if needed.
* Should never return NULL.
*/
_EGLThreadInfo *
_eglGetCurrentThread(void)
{
_eglInitGlobals();
/* XXX temporary */
return _eglGlobal.ThreadInfo;
}
/**
* Record EGL error code.
*/
void
_eglError(EGLint errCode, const char *msg)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
const char *s;
if (t->LastError == EGL_SUCCESS) {
t->LastError = errCode;
switch (errCode) {
case EGL_BAD_ACCESS:
s = "EGL_BAD_ACCESS";
break;
case EGL_BAD_ALLOC:
s = "EGL_BAD_ALLOC";
break;
case EGL_BAD_ATTRIBUTE:
s = "EGL_BAD_ATTRIBUTE";
break;
case EGL_BAD_CONFIG:
s = "EGL_BAD_CONFIG";
break;
case EGL_BAD_CONTEXT:
s = "EGL_BAD_CONTEXT";
break;
case EGL_BAD_CURRENT_SURFACE:
s = "EGL_BAD_CURRENT_SURFACE";
break;
case EGL_BAD_DISPLAY:
s = "EGL_BAD_DISPLAY";
break;
case EGL_BAD_MATCH:
s = "EGL_BAD_MATCH";
break;
case EGL_BAD_NATIVE_PIXMAP:
s = "EGL_BAD_NATIVE_PIXMAP";
break;
case EGL_BAD_NATIVE_WINDOW:
s = "EGL_BAD_NATIVE_WINDOW";
break;
case EGL_BAD_PARAMETER:
s = "EGL_BAD_PARAMETER";
break;
case EGL_BAD_SURFACE:
s = "EGL_BAD_SURFACE";
break;
case EGL_BAD_SCREEN_MESA:
s = "EGL_BAD_SCREEN_MESA";
break;
case EGL_BAD_MODE_MESA:
s = "EGL_BAD_MODE_MESA";
break;
default:
s = "other";
}
/* XXX temporary */
fprintf(stderr, "EGL user error 0x%x (%s) in %s\n", errCode, s, msg);
}
}

View file

@ -3,17 +3,7 @@
#include "egltypedefs.h"
#include "eglhash.h"
/**
* Per-thread info
*/
struct _egl_thread_info
{
EGLint LastError;
_EGLContext *CurrentContext;
EGLenum CurrentAPI;
};
#include "eglcurrent.h"
/**
@ -23,6 +13,7 @@ struct _egl_global
{
EGLBoolean Initialized;
/* these are private to egldisplay.c */
_EGLHashtable *Displays;
_EGLHashtable *Surfaces;
@ -33,9 +24,6 @@ struct _egl_global
char ClientAPIs[1000]; /**< updated by eglQueryString */
/* XXX temporary - should be thread-specific data (TSD) */
_EGLThreadInfo *ThreadInfo;
EGLint NumDrivers;
_EGLDriver *Drivers[10];
};
@ -52,20 +40,4 @@ extern void
_eglDestroyGlobals(void);
extern _EGLThreadInfo *
_eglNewThreadInfo(void);
extern void
_eglDeleteThreadData(_EGLThreadInfo *t);
extern _EGLThreadInfo *
_eglGetCurrentThread(void);
extern void
_eglError(EGLint errCode, const char *msg);
#endif /* EGLGLOBALS_INCLUDED */

View file

@ -128,20 +128,25 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateScreenSurfaceMESA");
return EGL_NO_SURFACE;
}
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA,
config, attrib_list)) {
if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA,
conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}

View file

@ -6,6 +6,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "egldisplay.h"
#include "eglcontext.h"
#include "eglconfig.h"
#include "egldriver.h"
@ -20,12 +21,10 @@
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list)
_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list)
{
const char *func;
_EGLConfig *conf;
EGLint width = 0, height = 0, largest = 0;
EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
EGLint renderBuffer = EGL_BACK_BUFFER;
@ -55,7 +54,6 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
return EGL_FALSE;
}
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
@ -211,72 +209,6 @@ _eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
}
void
_eglSaveSurface(_EGLSurface *surf)
{
EGLuint key = _eglHashGenKey(_eglGlobal.Surfaces);
assert(surf);
assert(!surf->Handle);
surf->Handle = (EGLSurface) key;
assert(surf->Handle);
_eglHashInsert(_eglGlobal.Surfaces, key, surf);
}
void
_eglRemoveSurface(_EGLSurface *surf)
{
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
}
/**
* Return the public handle for an internal _EGLSurface.
* This is the inverse of _eglLookupSurface().
*/
EGLSurface
_eglGetSurfaceHandle(_EGLSurface *surface)
{
if (surface)
return surface->Handle;
else
return EGL_NO_SURFACE;
}
/**
* Return the private _EGLSurface which corresponds to a public EGLSurface
* handle.
* This is the inverse of _eglGetSurfaceHandle().
*/
_EGLSurface *
_eglLookupSurface(EGLSurface surf)
{
_EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
(EGLuint) surf);
return c;
}
_EGLSurface *
_eglGetCurrentSurface(EGLint readdraw)
{
_EGLContext *ctx = _eglGetCurrentContext();
if (ctx) {
switch (readdraw) {
case EGL_DRAW:
return ctx->DrawSurface;
case EGL_READ:
return ctx->ReadSurface;
default:
return NULL;
}
}
return NULL;
}
EGLBoolean
_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
{
@ -385,19 +317,24 @@ _eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateWindowSurface");
return EGL_NO_SURFACE;
}
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) {
if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@ -412,19 +349,24 @@ _eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
return EGL_NO_SURFACE;
}
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) {
if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@ -439,19 +381,24 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
_EGLConfig *conf;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) {
if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
#endif
return EGL_NO_SURFACE;
}
@ -465,13 +412,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
_EGLSurface *surf = _eglLookupSurface(surface);
if (surf) {
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
if (surf->IsBound) {
surf->DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(surf);
if (!surf->IsBound)
free(surf);
}
return EGL_TRUE;
}
else {

View file

@ -10,12 +10,15 @@
*/
struct _egl_surface
{
EGLSurface Handle; /* The public/opaque handle which names this object */
/* Managed by EGLDisplay for linking */
_EGLDisplay *Display;
_EGLSurface *Next;
EGLSurface Handle;
_EGLConfig *Config;
/* May need reference counting here */
EGLBoolean IsBound;
EGLBoolean DeletePending;
EGLBoolean BoundToTexture;
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
@ -39,29 +42,8 @@ struct _egl_surface
extern EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list);
extern void
_eglSaveSurface(_EGLSurface *surf);
extern void
_eglRemoveSurface(_EGLSurface *surf);
extern EGLSurface
_eglGetSurfaceHandle(_EGLSurface *surface);
extern _EGLSurface *
_eglLookupSurface(EGLSurface surf);
extern _EGLSurface *
_eglGetCurrentSurface(EGLint readdraw);
_eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
_EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean

View file

@ -6,6 +6,7 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include "eglcompiler.h"
typedef struct _egl_api _EGLAPI;

View file

@ -44,7 +44,6 @@
#include "pipe/p_state.h"
#include "pipe/p_defines.h"
#include "tgsi/tgsi_exec.h"
#include "tgsi/tgsi_scan.h"
@ -55,6 +54,8 @@ struct draw_vertex_shader;
struct draw_context;
struct draw_stage;
struct vbuf_render;
struct tgsi_exec_machine;
struct tgsi_sampler;
/**
@ -185,7 +186,7 @@ struct draw_context
uint position_output;
/** TGSI program interpreter runtime state */
struct tgsi_exec_machine machine;
struct tgsi_exec_machine *machine;
uint num_samplers;
struct tgsi_sampler **samplers;

View file

@ -43,6 +43,8 @@
#include "translate/translate.h"
#include "translate/translate_cache.h"
#include "tgsi/tgsi_exec.h"
@ -146,16 +148,8 @@ draw_delete_vertex_shader(struct draw_context *draw,
boolean
draw_vs_init( struct draw_context *draw )
{
tgsi_exec_machine_init(&draw->vs.machine);
/* FIXME: give this machine thing a proper constructor:
*/
draw->vs.machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
if (!draw->vs.machine.Inputs)
return FALSE;
draw->vs.machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
if (!draw->vs.machine.Outputs)
draw->vs.machine = tgsi_exec_machine_create();
if (!draw->vs.machine)
return FALSE;
draw->vs.emit_cache = translate_cache_create();
@ -178,12 +172,6 @@ draw_vs_init( struct draw_context *draw )
void
draw_vs_destroy( struct draw_context *draw )
{
if (draw->vs.machine.Inputs)
align_free(draw->vs.machine.Inputs);
if (draw->vs.machine.Outputs)
align_free(draw->vs.machine.Outputs);
if (draw->vs.fetch_cache)
translate_cache_destroy(draw->vs.fetch_cache);
@ -196,8 +184,7 @@ draw_vs_destroy( struct draw_context *draw )
if (draw->vs.aligned_constant_storage)
align_free((void*)draw->vs.aligned_constant_storage);
tgsi_exec_machine_free_data(&draw->vs.machine);
tgsi_exec_machine_destroy(draw->vs.machine);
}

View file

@ -41,6 +41,7 @@
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_exec.h"
struct exec_vertex_shader {
@ -201,7 +202,7 @@ draw_create_vs_exec(struct draw_context *draw,
vs->base.run_linear = vs_exec_run_linear;
vs->base.delete = vs_exec_delete;
vs->base.create_varient = draw_vs_varient_generic;
vs->machine = &draw->vs.machine;
vs->machine = draw->vs.machine;
return &vs->base;
}

View file

@ -48,6 +48,7 @@
#include "rtasm/rtasm_ppc.h"
#include "tgsi/tgsi_ppc.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_exec.h"

View file

@ -48,27 +48,16 @@
#include "rtasm/rtasm_x86sse.h"
#include "tgsi/tgsi_sse2.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_exec.h"
#define SSE_MAX_VERTICES 4
typedef void (PIPE_CDECL *codegen_function) (
const struct tgsi_exec_vector *input, /* 1 */
struct tgsi_exec_vector *output, /* 2 */
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 */
struct draw_sse_vertex_shader {
struct draw_vertex_shader base;
struct x86_function sse2_program;
codegen_function func;
tgsi_sse2_vs_func func;
struct tgsi_exec_machine *machine;
};
@ -118,11 +107,9 @@ vs_sse_run_linear( struct draw_vertex_shader *base,
/* run compiled shader
*/
shader->func(machine->Inputs,
machine->Outputs,
(float (*)[4])constants,
machine->Temps,
(float (*)[4])shader->base.immediates,
shader->func(machine,
constants,
shader->base.immediates,
input,
base->info.num_inputs,
input_stride,
@ -184,7 +171,7 @@ draw_create_vs_sse(struct draw_context *draw,
vs->base.immediates = align_malloc(TGSI_EXEC_NUM_IMMEDIATES * 4 *
sizeof(float), 16);
vs->machine = &draw->vs.machine;
vs->machine = draw->vs.machine;
x86_init_func( &vs->sse2_program );
@ -194,7 +181,7 @@ draw_create_vs_sse(struct draw_context *draw,
TRUE ))
goto fail;
vs->func = (codegen_function) x86_get_func( &vs->sse2_program );
vs->func = (tgsi_sse2_vs_func) x86_get_func( &vs->sse2_program );
if (!vs->func) {
goto fail;
}

View file

@ -993,6 +993,15 @@ void sse_pmovmskb( struct x86_function *p,
emit_modrm(p, dst, src);
}
void sse_movmskps( struct x86_function *p,
struct x86_reg dst,
struct x86_reg src)
{
DUMP_RR( dst, src );
emit_2ub(p, X86_TWOB, 0x50);
emit_modrm(p, dst, src);
}
/***********************************************************************
* SSE2 instructions
*/

View file

@ -223,6 +223,7 @@ void sse_unpckhps( struct x86_function *p, struct x86_reg dst, struct x86_reg sr
void sse_unpcklps( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_pmovmskb( struct x86_function *p, struct x86_reg dest, struct x86_reg src );
void sse2_punpcklbw( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void sse_movmskps( struct x86_function *p, struct x86_reg dst, struct x86_reg src);
void x86_add( struct x86_function *p, struct x86_reg dst, struct x86_reg src );
void x86_and( struct x86_function *p, struct x86_reg dst, struct x86_reg src );

View file

@ -365,15 +365,26 @@ tgsi_exec_machine_bind_shader(
}
void
tgsi_exec_machine_init(
struct tgsi_exec_machine *mach )
struct tgsi_exec_machine *
tgsi_exec_machine_create( void )
{
struct tgsi_exec_machine *mach;
uint i;
mach->Temps = (struct tgsi_exec_vector *) tgsi_align_128bit( mach->_Temps);
mach = align_malloc( sizeof *mach, 16 );
if (!mach)
goto fail;
mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
mach->Samplers = NULL;
mach->Consts = NULL;
mach->Tokens = NULL;
mach->Primitives = NULL;
mach->InterpCoefs = NULL;
mach->Instructions = NULL;
mach->Declarations = NULL;
/* Setup constants. */
for( i = 0; i < 4; i++ ) {
mach->Temps[TEMP_0_I].xyzw[TEMP_0_C].u[i] = 0x00000000;
@ -393,22 +404,24 @@ tgsi_exec_machine_init(
(void) print_chan;
(void) print_temp;
#endif
return mach;
fail:
align_free(mach);
return NULL;
}
void
tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach)
tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach)
{
if (mach->Instructions) {
if (mach) {
FREE(mach->Instructions);
mach->Instructions = NULL;
mach->NumInstructions = 0;
}
if (mach->Declarations) {
FREE(mach->Declarations);
mach->Declarations = NULL;
mach->NumDeclarations = 0;
}
align_free(mach);
}

View file

@ -29,6 +29,7 @@
#define TGSI_EXEC_H
#include "pipe/p_compiler.h"
#include "pipe/p_state.h"
#if defined __cplusplus
extern "C" {
@ -94,7 +95,6 @@ struct tgsi_exec_labels
#define TGSI_EXEC_NUM_TEMPS 128
#define TGSI_EXEC_NUM_TEMP_EXTRAS 6
#define TGSI_EXEC_NUM_IMMEDIATES 256
/*
@ -162,9 +162,14 @@ struct tgsi_exec_labels
#define TGSI_EXEC_MASK_I (TGSI_EXEC_NUM_TEMPS + 3)
#define TGSI_EXEC_MASK_C 2
/* 4 register buffer for various purposes */
#define TGSI_EXEC_TEMP_R0 (TGSI_EXEC_NUM_TEMPS + 4)
#define TGSI_EXEC_NUM_TEMP_R 4
#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 8)
#define TGSI_EXEC_NUM_ADDRS 1
#define TGSI_EXEC_NUM_TEMP_EXTRAS 9
#define TGSI_EXEC_TEMP_ADDR (TGSI_EXEC_NUM_TEMPS + 5)
#define TGSI_EXEC_MAX_COND_NESTING 20
@ -187,24 +192,21 @@ struct tgsi_exec_labels
struct tgsi_exec_machine
{
/* Total = program temporaries + internal temporaries
* + 1 padding to align to 16 bytes
*/
struct tgsi_exec_vector _Temps[TGSI_EXEC_NUM_TEMPS +
TGSI_EXEC_NUM_TEMP_EXTRAS + 1];
struct tgsi_exec_vector Temps[TGSI_EXEC_NUM_TEMPS +
TGSI_EXEC_NUM_TEMP_EXTRAS];
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
struct tgsi_exec_vector Inputs[PIPE_MAX_ATTRIBS];
struct tgsi_exec_vector Outputs[PIPE_MAX_ATTRIBS];
/*
* This will point to _Temps after aligning to 16B boundary.
*/
struct tgsi_exec_vector *Temps;
struct tgsi_exec_vector *Addrs;
struct tgsi_sampler **Samplers;
float Imms[TGSI_EXEC_NUM_IMMEDIATES][4];
unsigned ImmLimit;
const float (*Consts)[4];
struct tgsi_exec_vector *Inputs;
struct tgsi_exec_vector *Outputs;
const struct tgsi_token *Tokens; /**< Declarations, instructions */
unsigned Processor; /**< TGSI_PROCESSOR_x */
@ -251,9 +253,11 @@ struct tgsi_exec_machine
struct tgsi_exec_labels Labels;
};
struct tgsi_exec_machine *
tgsi_exec_machine_create( void );
void
tgsi_exec_machine_init(
struct tgsi_exec_machine *mach );
tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach);
void
@ -268,10 +272,6 @@ tgsi_exec_machine_run(
struct tgsi_exec_machine *mach );
void
tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach);
static INLINE void
tgsi_set_kill_mask(struct tgsi_exec_machine *mach, unsigned mask)
{

View file

@ -32,6 +32,7 @@
#include "util/u_debug.h"
#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#if defined(PIPE_ARCH_SSE)
#include "util/u_sse.h"
#endif
@ -97,6 +98,14 @@ make_xmm(
static struct x86_reg
get_const_base( void )
{
return x86_make_reg(
file_REG32,
reg_AX );
}
static struct x86_reg
get_machine_base( void )
{
return x86_make_reg(
file_REG32,
@ -106,21 +115,29 @@ get_const_base( void )
static struct x86_reg
get_input_base( void )
{
return x86_make_reg(
file_REG32,
reg_AX );
return x86_make_disp(
get_machine_base(),
Offset(struct tgsi_exec_machine, Inputs) );
}
static struct x86_reg
get_output_base( void )
{
return x86_make_reg(
file_REG32,
reg_DX );
return x86_make_disp(
get_machine_base(),
Offset(struct tgsi_exec_machine, Outputs) );
}
static struct x86_reg
get_temp_base( void )
{
return x86_make_disp(
get_machine_base(),
Offset(struct tgsi_exec_machine, Temps) );
}
static struct x86_reg
get_coef_base( void )
{
return x86_make_reg(
file_REG32,
@ -128,9 +145,11 @@ get_temp_base( void )
}
static struct x86_reg
get_coef_base( void )
get_sampler_base( void )
{
return get_output_base();
return x86_make_reg(
file_REG32,
reg_DI );
}
static struct x86_reg
@ -138,7 +157,7 @@ get_immediate_base( void )
{
return x86_make_reg(
file_REG32,
reg_DI );
reg_DX );
}
@ -167,6 +186,15 @@ get_const(
(vec * 4 + chan) * 4 );
}
static struct x86_reg
get_sampler_ptr(
unsigned unit )
{
return x86_make_disp(
get_sampler_base(),
unit * sizeof( struct tgsi_sampler * ) );
}
static struct x86_reg
get_input(
unsigned vec,
@ -520,24 +548,15 @@ emit_coef_dady(
* that the stack pointer is 16 byte aligned, as expected.
*/
static void
emit_func_call_dst(
emit_func_call(
struct x86_function *func,
unsigned xmm_save,
unsigned xmm_dst,
unsigned xmm_save_mask,
const struct x86_reg *arg,
unsigned nr_args,
void (PIPE_CDECL *code)() )
{
struct x86_reg ecx = x86_make_reg( file_REG32, reg_CX );
unsigned i, n;
unsigned xmm_mask;
/* Bitmask of the xmm registers to save */
xmm_mask = (1 << xmm_save) - 1;
xmm_mask &= ~(1 << xmm_dst);
sse_movaps(
func,
get_temp( TEMP_R0, 0 ),
make_xmm( xmm_dst ) );
x86_push(
func,
@ -549,8 +568,10 @@ emit_func_call_dst(
func,
x86_make_reg( file_REG32, reg_DX) );
/* Store XMM regs to the stack
*/
for(i = 0, n = 0; i < 8; ++i)
if(xmm_mask & (1 << i))
if(xmm_save_mask & (1 << i))
++n;
x86_sub_imm(
@ -559,26 +580,42 @@ emit_func_call_dst(
n*16);
for(i = 0, n = 0; i < 8; ++i)
if(xmm_mask & (1 << i)) {
if(xmm_save_mask & (1 << i)) {
sse_movups(
func,
x86_make_disp( x86_make_reg( file_REG32, reg_SP ), n*16 ),
make_xmm( i ) );
++n;
}
for (i = 0; i < nr_args; i++) {
/* Load the address of the buffer we use for passing arguments and
* receiving results:
*/
x86_lea(
func,
ecx,
arg[i] );
x86_lea(
func,
ecx,
get_temp( TEMP_R0, 0 ) );
x86_push( func, ecx );
/* Push actual function arguments (currently just the pointer to
* the buffer above), and call the function:
*/
x86_push( func, ecx );
}
x86_mov_reg_imm( func, ecx, (unsigned long) code );
x86_call( func, ecx );
x86_pop(func, ecx );
/* Pop the arguments (or just add an immediate to esp)
*/
for (i = 0; i < nr_args; i++) {
x86_pop(func, ecx );
}
/* Pop the saved XMM regs:
*/
for(i = 0, n = 0; i < 8; ++i)
if(xmm_mask & (1 << i)) {
if(xmm_save_mask & (1 << i)) {
sse_movups(
func,
make_xmm( i ),
@ -602,34 +639,86 @@ emit_func_call_dst(
x86_pop(
func,
x86_make_reg( file_REG32, reg_AX) );
}
static void
emit_func_call_dst_src1(
struct x86_function *func,
unsigned xmm_save,
unsigned xmm_dst,
unsigned xmm_src0,
void (PIPE_CDECL *code)() )
{
struct x86_reg store = get_temp( TEMP_R0, 0 );
unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst);
/* Store our input parameters (in xmm regs) to the buffer we use
* for passing arguments. We will pass a pointer to this buffer as
* the actual function argument.
*/
sse_movaps(
func,
store,
make_xmm( xmm_src0 ) );
emit_func_call( func,
xmm_mask,
&store,
1,
code );
sse_movaps(
func,
make_xmm( xmm_dst ),
get_temp( TEMP_R0, 0 ) );
store );
}
static void
emit_func_call_dst_src(
emit_func_call_dst_src2(
struct x86_function *func,
unsigned xmm_save,
unsigned xmm_dst,
unsigned xmm_src,
unsigned xmm_src0,
unsigned xmm_src1,
void (PIPE_CDECL *code)() )
{
struct x86_reg store = get_temp( TEMP_R0, 0 );
unsigned xmm_mask = ((1 << xmm_save) - 1) & ~(1 << xmm_dst);
/* Store two inputs to parameter buffer.
*/
sse_movaps(
func,
get_temp( TEMP_R0, 1 ),
make_xmm( xmm_src ) );
store,
make_xmm( xmm_src0 ) );
emit_func_call_dst(
sse_movaps(
func,
xmm_save,
xmm_dst,
code );
x86_make_disp( store, 4 * sizeof(float) ),
make_xmm( xmm_src1 ) );
/* Emit the call
*/
emit_func_call( func,
xmm_mask,
&store,
1,
code );
/* Retrieve the results:
*/
sse_movaps(
func,
make_xmm( xmm_dst ),
store );
}
#if defined(PIPE_ARCH_SSE)
/*
@ -782,10 +871,11 @@ emit_cos(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
cos4f );
}
@ -812,10 +902,11 @@ emit_ex2(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
ex24f );
}
@ -857,10 +948,11 @@ emit_flr(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
flr4f );
}
@ -880,10 +972,11 @@ emit_frc(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
frc4f );
}
@ -910,10 +1003,11 @@ emit_lg2(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
lg24f );
}
@ -975,13 +1069,15 @@ emit_pow(
struct x86_function *func,
unsigned xmm_save,
unsigned xmm_dst,
unsigned xmm_src )
unsigned xmm_src0,
unsigned xmm_src1 )
{
emit_func_call_dst_src(
emit_func_call_dst_src2(
func,
xmm_save,
xmm_dst,
xmm_src,
xmm_src0,
xmm_src1,
pow4f );
}
@ -1017,10 +1113,11 @@ emit_rnd(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
rnd4f );
}
@ -1099,10 +1196,11 @@ emit_sgn(
unsigned xmm_save,
unsigned xmm_dst )
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
sgn4f );
}
@ -1121,10 +1219,11 @@ emit_sin (struct x86_function *func,
unsigned xmm_save,
unsigned xmm_dst)
{
emit_func_call_dst(
emit_func_call_dst_src1(
func,
xmm_save,
xmm_dst,
xmm_dst,
sin4f );
}
@ -1140,6 +1239,12 @@ emit_sub(
make_xmm( xmm_src ) );
}
/**
* Register fetch.
*/
@ -1298,20 +1403,164 @@ emit_store(
#define STORE( FUNC, INST, XMM, INDEX, CHAN )\
emit_store( FUNC, XMM, &(INST).FullDstRegisters[INDEX], &(INST), CHAN )
static void PIPE_CDECL
fetch_texel( struct tgsi_sampler **sampler,
float *store )
{
#if 0
uint j;
debug_printf("%s sampler: %p (%p) store: %p\n",
__FUNCTION__,
sampler, *sampler,
store );
debug_printf("lodbias %f\n", store[12]);
for (j = 0; j < 4; j++)
debug_printf("sample %d texcoord %f %f\n",
j,
store[0+j],
store[4+j]);
#endif
{
float rgba[NUM_CHANNELS][QUAD_SIZE];
(*sampler)->get_samples(*sampler,
&store[0],
&store[4],
&store[8],
0.0f, /*store[12], lodbias */
rgba);
memcpy( store, rgba, 16 * sizeof(float));
}
#if 0
for (j = 0; j < 4; j++)
debug_printf("sample %d result %f %f %f %f\n",
j,
store[0+j],
store[4+j],
store[8+j],
store[12+j]);
#endif
}
/**
* High-level instruction translators.
*/
static void
emit_tex( struct x86_function *func,
const struct tgsi_full_instruction *inst,
boolean lodbias,
boolean projected)
{
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
struct x86_reg args[2];
unsigned count;
unsigned i;
switch (inst->InstructionExtTexture.Texture) {
case TGSI_TEXTURE_1D:
case TGSI_TEXTURE_SHADOW1D:
count = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
case TGSI_TEXTURE_SHADOW2D:
case TGSI_TEXTURE_SHADOWRECT:
count = 2;
break;
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
count = 3;
break;
default:
assert(0);
return;
}
if (lodbias) {
FETCH( func, *inst, 3, 0, 3 );
}
else {
emit_tempf(
func,
3,
TGSI_EXEC_TEMP_00000000_I,
TGSI_EXEC_TEMP_00000000_C );
}
/* store lodbias whether enabled or not -- fetch_texel currently
* respects it always.
*/
sse_movaps( func,
get_temp( TEMP_R0, 3 ),
make_xmm( 3 ) );
if (projected) {
FETCH( func, *inst, 3, 0, 3 );
emit_rcp( func, 3, 3 );
}
for (i = 0; i < count; i++) {
FETCH( func, *inst, i, 0, i );
if (projected) {
sse_mulps(
func,
make_xmm( i ),
make_xmm( 3 ) );
}
/* Store in the argument buffer:
*/
sse_movaps(
func,
get_temp( TEMP_R0, i ),
make_xmm( i ) );
}
args[0] = get_temp( TEMP_R0, 0 );
args[1] = get_sampler_ptr( unit );
emit_func_call( func,
0,
args,
Elements(args),
fetch_texel );
/* If all four channels are enabled, could use a pointer to
* dst[0].x instead of TEMP_R0 for store?
*/
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, i ) {
sse_movaps(
func,
make_xmm( 0 ),
get_temp( TEMP_R0, i ) );
STORE( func, *inst, 0, 0, i );
}
}
static void
emit_kil(
struct x86_function *func,
const struct tgsi_full_src_register *reg )
{
unsigned uniquemask;
unsigned registers[4];
unsigned nextregister = 0;
unsigned firstchan = ~0;
unsigned unique_count = 0;
unsigned chan_index;
unsigned i;
/* This mask stores component bits that were already tested. Note that
* we test if the value is less than zero, so 1.0 and 0.0 need not to be
@ -1331,18 +1580,11 @@ emit_kil(
uniquemask |= 1 << swizzle;
/* allocate register */
registers[chan_index] = nextregister;
emit_fetch(
func,
nextregister,
unique_count++,
reg,
chan_index );
nextregister++;
/* mark the first channel used */
if( firstchan == ~0 ) {
firstchan = chan_index;
}
}
}
@ -1353,32 +1595,32 @@ emit_kil(
func,
x86_make_reg( file_REG32, reg_DX ) );
FOR_EACH_CHANNEL( chan_index ) {
if( uniquemask & (1 << chan_index) ) {
sse_cmpps(
func,
make_xmm( registers[chan_index] ),
get_temp(
TGSI_EXEC_TEMP_00000000_I,
TGSI_EXEC_TEMP_00000000_C ),
cc_LessThan );
for (i = 0 ; i < unique_count; i++ ) {
struct x86_reg dataXMM = make_xmm(i);
if( chan_index == firstchan ) {
sse_pmovmskb(
func,
x86_make_reg( file_REG32, reg_AX ),
make_xmm( registers[chan_index] ) );
}
else {
sse_pmovmskb(
func,
x86_make_reg( file_REG32, reg_DX ),
make_xmm( registers[chan_index] ) );
x86_or(
func,
x86_make_reg( file_REG32, reg_AX ),
x86_make_reg( file_REG32, reg_DX ) );
}
sse_cmpps(
func,
dataXMM,
get_temp(
TGSI_EXEC_TEMP_00000000_I,
TGSI_EXEC_TEMP_00000000_C ),
cc_LessThan );
if( i == 0 ) {
sse_movmskps(
func,
x86_make_reg( file_REG32, reg_AX ),
dataXMM );
}
else {
sse_movmskps(
func,
x86_make_reg( file_REG32, reg_DX ),
dataXMM );
x86_or(
func,
x86_make_reg( file_REG32, reg_AX ),
x86_make_reg( file_REG32, reg_DX ) );
}
}
@ -1573,7 +1815,7 @@ emit_instruction(
get_temp(
TGSI_EXEC_TEMP_MINUS_128_I,
TGSI_EXEC_TEMP_MINUS_128_C ) );
emit_pow( func, 3, 1, 2 );
emit_pow( func, 3, 1, 1, 2 );
FETCH( func, *inst, 0, 0, CHAN_X );
sse_xorps(
func,
@ -1917,7 +2159,7 @@ emit_instruction(
/* TGSI_OPCODE_POW */
FETCH( func, *inst, 0, 0, CHAN_X );
FETCH( func, *inst, 1, 1, CHAN_X );
emit_pow( func, 0, 0, 1 );
emit_pow( func, 0, 0, 0, 1 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
STORE( func, *inst, 0, 0, chan_index );
}
@ -2086,21 +2328,7 @@ emit_instruction(
break;
case TGSI_OPCODE_TEX:
if (0) {
/* Disable dummy texture code:
*/
emit_tempf(
func,
0,
TEMP_ONE_I,
TEMP_ONE_C );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
STORE( func, *inst, 0, 0, chan_index );
}
}
else {
return 0;
}
emit_tex( func, inst, FALSE, FALSE );
break;
case TGSI_OPCODE_TXD:
@ -2198,7 +2426,7 @@ emit_instruction(
break;
case TGSI_OPCODE_TXB:
return 0;
emit_tex( func, inst, TRUE, FALSE );
break;
case TGSI_OPCODE_NRM:
@ -2306,9 +2534,13 @@ emit_instruction(
break;
case TGSI_OPCODE_TXL:
return 0;
emit_tex( func, inst, TRUE, FALSE );
break;
case TGSI_OPCODE_TXP:
emit_tex( func, inst, FALSE, TRUE );
break;
case TGSI_OPCODE_BRK:
return 0;
break;
@ -2488,7 +2720,7 @@ emit_declaration(
static void aos_to_soa( struct x86_function *func,
uint arg_aos,
uint arg_soa,
uint arg_machine,
uint arg_num,
uint arg_stride )
{
@ -2503,7 +2735,10 @@ static void aos_to_soa( struct x86_function *func,
x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
x86_mov( func, aos_input, x86_fn_arg( func, arg_aos ) );
x86_mov( func, soa_input, x86_fn_arg( func, arg_soa ) );
x86_mov( func, soa_input, x86_fn_arg( func, arg_machine ) );
x86_lea( func, soa_input,
x86_make_disp( soa_input,
Offset(struct tgsi_exec_machine, Inputs) ) );
x86_mov( func, num_inputs, x86_fn_arg( func, arg_num ) );
x86_mov( func, stride, x86_fn_arg( func, arg_stride ) );
@ -2545,28 +2780,30 @@ static void aos_to_soa( struct x86_function *func,
x86_jcc( func, cc_NE, inner_loop );
/* Restore EBX */
x86_pop( func, aos_input );
x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
}
static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num, uint stride )
static void soa_to_aos( struct x86_function *func,
uint arg_aos,
uint arg_machine,
uint arg_num,
uint arg_stride )
{
struct x86_reg soa_output;
struct x86_reg aos_output;
struct x86_reg num_outputs;
struct x86_reg temp;
struct x86_reg soa_output = x86_make_reg( file_REG32, reg_AX );
struct x86_reg aos_output = x86_make_reg( file_REG32, reg_BX );
struct x86_reg num_outputs = x86_make_reg( file_REG32, reg_CX );
struct x86_reg temp = x86_make_reg( file_REG32, reg_DX );
int inner_loop;
soa_output = x86_make_reg( file_REG32, reg_AX );
aos_output = x86_make_reg( file_REG32, reg_BX );
num_outputs = x86_make_reg( file_REG32, reg_CX );
temp = x86_make_reg( file_REG32, reg_DX );
/* Save EBX */
x86_push( func, aos_output );
x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
x86_mov( func, soa_output, x86_fn_arg( func, soa ) );
x86_mov( func, aos_output, x86_fn_arg( func, aos ) );
x86_mov( func, num_outputs, x86_fn_arg( func, num ) );
x86_mov( func, aos_output, x86_fn_arg( func, arg_aos ) );
x86_mov( func, soa_output, x86_fn_arg( func, arg_machine ) );
x86_lea( func, soa_output,
x86_make_disp( soa_output,
Offset(struct tgsi_exec_machine, Outputs) ) );
x86_mov( func, num_outputs, x86_fn_arg( func, arg_num ) );
/* do */
inner_loop = x86_get_label( func );
@ -2583,7 +2820,7 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num,
sse_unpcklps( func, make_xmm( 3 ), make_xmm( 4 ) );
sse_unpckhps( func, make_xmm( 5 ), make_xmm( 4 ) );
x86_mov( func, temp, x86_fn_arg( func, stride ) );
x86_mov( func, temp, x86_fn_arg( func, arg_stride ) );
x86_push( func, aos_output );
sse_movlps( func, x86_make_disp( aos_output, 0 ), make_xmm( 0 ) );
sse_movlps( func, x86_make_disp( aos_output, 8 ), make_xmm( 3 ) );
@ -2607,20 +2844,13 @@ static void soa_to_aos( struct x86_function *func, uint aos, uint soa, uint num,
x86_jcc( func, cc_NE, inner_loop );
/* Restore EBX */
x86_pop( func, aos_output );
x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
}
/**
* Translate a TGSI vertex/fragment shader to SSE2 code.
* Slightly different things are done for vertex vs. fragment shaders.
*
* Note that fragment shaders are responsible for interpolating shader
* inputs. Because on x86 we have only 4 GP registers, and here we
* have 5 shader arguments (input, output, const, temp and coef), the
* code is split into two phases -- DECLARATION and INSTRUCTION phase.
* GP register holding the output argument is aliased with the coeff
* argument, as outputs are not needed in the DECLARATION phase.
*
* \param tokens the TGSI input shader
* \param func the output SSE code/function
* \param immediates buffer to place immediates, later passed to SSE func
@ -2634,7 +2864,6 @@ tgsi_emit_sse2(
boolean do_swizzles )
{
struct tgsi_parse_context parse;
boolean instruction_phase = FALSE;
unsigned ok = 1;
uint num_immediates = 0;
@ -2646,74 +2875,48 @@ tgsi_emit_sse2(
/* Can't just use EDI, EBX without save/restoring them:
*/
x86_push(
func,
get_immediate_base() );
x86_push(
func,
get_temp_base() );
x86_push( func, x86_make_reg( file_REG32, reg_BX ) );
x86_push( func, x86_make_reg( file_REG32, reg_DI ) );
/*
* Different function args for vertex/fragment shaders:
*/
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
/* DECLARATION phase, do not load output argument. */
x86_mov(
func,
get_input_base(),
x86_fn_arg( func, 1 ) );
/* skipping outputs argument here */
x86_mov(
func,
get_const_base(),
x86_fn_arg( func, 3 ) );
x86_mov(
func,
get_temp_base(),
x86_fn_arg( func, 4 ) );
x86_mov(
func,
get_coef_base(),
x86_fn_arg( func, 5 ) );
x86_mov(
func,
get_immediate_base(),
x86_fn_arg( func, 6 ) );
}
else {
assert(parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX);
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) {
if (do_swizzles)
aos_to_soa( func,
6, /* aos_input */
1, /* machine->input */
7, /* num_inputs */
8 ); /* input_stride */
4, /* aos_input */
1, /* machine */
5, /* num_inputs */
6 ); /* input_stride */
}
x86_mov(
func,
get_machine_base(),
x86_fn_arg( func, 1 ) );
x86_mov(
func,
get_const_base(),
x86_fn_arg( func, 2 ) );
x86_mov(
func,
get_immediate_base(),
x86_fn_arg( func, 3 ) );
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
x86_mov(
func,
get_coef_base(),
x86_fn_arg( func, 4 ) );
x86_mov(
func,
get_input_base(),
x86_fn_arg( func, 1 ) );
x86_mov(
func,
get_output_base(),
x86_fn_arg( func, 2 ) );
x86_mov(
func,
get_const_base(),
x86_fn_arg( func, 3 ) );
x86_mov(
func,
get_temp_base(),
x86_fn_arg( func, 4 ) );
x86_mov(
func,
get_immediate_base(),
x86_fn_arg( func, 5 ) );
func,
get_sampler_base(),
x86_make_disp( get_machine_base(),
Offset( struct tgsi_exec_machine, Samplers ) ) );
}
while( !tgsi_parse_end_of_tokens( &parse ) && ok ) {
tgsi_parse_token( &parse );
@ -2727,17 +2930,6 @@ tgsi_emit_sse2(
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_FRAGMENT) {
if( !instruction_phase ) {
/* INSTRUCTION phase, overwrite coeff with output. */
instruction_phase = TRUE;
x86_mov(
func,
get_output_base(),
x86_fn_arg( func, 2 ) );
}
}
ok = emit_instruction(
func,
&parse.FullToken.FullInstruction );
@ -2781,18 +2973,17 @@ tgsi_emit_sse2(
if (parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX) {
if (do_swizzles)
soa_to_aos( func, 9, 2, 10, 11 );
soa_to_aos( func,
7, /* aos_output */
1, /* machine */
8, /* num_outputs */
9 ); /* output_stride */
}
/* Can't just use EBX, EDI without save/restoring them:
*/
x86_pop(
func,
get_temp_base() );
x86_pop(
func,
get_immediate_base() );
x86_pop( func, x86_make_reg( file_REG32, reg_DI ) );
x86_pop( func, x86_make_reg( file_REG32, reg_BX ) );
emit_ret( func );

View file

@ -34,6 +34,7 @@ extern "C" {
struct tgsi_token;
struct x86_function;
struct tgsi_interp_coef;
unsigned
tgsi_emit_sse2(
@ -42,6 +43,33 @@ tgsi_emit_sse2(
float (*immediates)[4],
boolean do_swizzles );
/* This is the function prototype generated when do_swizzles is false
* -- effectively for fragment shaders.
*/
typedef void (PIPE_CDECL *tgsi_sse2_fs_function) (
struct tgsi_exec_machine *machine, /* 1 */
const float (*constant)[4], /* 2 */
const float (*immediate)[4], /* 3 */
const struct tgsi_interp_coef *coef /* 4 */
);
/* This is the function prototype generated when do_swizzles is true
* -- effectively for vertex shaders.
*/
typedef void (PIPE_CDECL *tgsi_sse2_vs_func) (
struct tgsi_exec_machine *machine, /* 1 */
const float (*constant)[4], /* 2 */
const float (*immediate)[4], /* 3 */
const float (*aos_input)[4], /* 4 */
uint num_inputs, /* 5 */
uint input_stride, /* 6 */
float (*aos_output)[4], /* 7 */
uint num_outputs, /* 8 */
uint output_stride ); /* 9 */
#if defined __cplusplus
}
#endif

View file

@ -45,17 +45,6 @@
#include "rtasm/rtasm_x86sse.h"
/* Surely this should be defined somewhere in a tgsi header:
*/
typedef void (PIPE_CDECL *codegen_function)(
const struct tgsi_exec_vector *input,
struct tgsi_exec_vector *output,
const float (*constant)[4],
struct tgsi_exec_vector *temporary,
const struct tgsi_interp_coef *coef,
float (*immediates)[4]
//, const struct tgsi_exec_vector *quadPos
);
/**
@ -65,7 +54,7 @@ struct sp_sse_fragment_shader
{
struct sp_fragment_shader base;
struct x86_function sse2_program;
codegen_function func;
tgsi_sse2_fs_function func;
float immediates[TGSI_EXEC_NUM_IMMEDIATES][4];
};
@ -83,6 +72,7 @@ fs_sse_prepare( const struct sp_fragment_shader *base,
struct tgsi_exec_machine *machine,
struct tgsi_sampler **samplers )
{
machine->Samplers = samplers;
}
@ -107,12 +97,10 @@ fs_sse_run( const struct sp_fragment_shader *base,
tgsi_set_kill_mask(machine, 0x0);
tgsi_set_exec_mask(machine, 1, 1, 1, 1);
shader->func( machine->Inputs,
machine->Outputs,
shader->func( machine,
machine->Consts,
machine->Temps,
machine->InterpCoefs,
shader->immediates
(const float (*)[4])shader->immediates,
machine->InterpCoefs
// , &machine->QuadPos
);
@ -151,7 +139,7 @@ softpipe_create_fs_sse(struct softpipe_context *softpipe,
return NULL;
}
shader->func = (codegen_function) x86_get_func( &shader->sse2_program );
shader->func = (tgsi_sse2_fs_function) x86_get_func( &shader->sse2_program );
if (!shader->func) {
x86_release_func( &shader->sse2_program );
FREE(shader);

View file

@ -52,7 +52,7 @@
struct quad_shade_stage
{
struct quad_stage stage; /**< base class */
struct tgsi_exec_machine machine;
struct tgsi_exec_machine *machine;
struct tgsi_exec_vector *inputs, *outputs;
};
@ -73,7 +73,7 @@ shade_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
struct tgsi_exec_machine *machine = &qss->machine;
struct tgsi_exec_machine *machine = qss->machine;
boolean z_written;
/* Consts do not require 16 byte alignment. */
@ -146,7 +146,7 @@ shade_begin(struct quad_stage *qs)
struct softpipe_context *softpipe = qs->softpipe;
softpipe->fs->prepare( softpipe->fs,
&qss->machine,
qss->machine,
(struct tgsi_sampler **)
softpipe->tgsi.frag_samplers_list );
@ -159,9 +159,8 @@ shade_destroy(struct quad_stage *qs)
{
struct quad_shade_stage *qss = (struct quad_shade_stage *) qs;
tgsi_exec_machine_free_data(&qss->machine);
FREE( qss->inputs );
FREE( qss->outputs );
tgsi_exec_machine_destroy(qss->machine);
FREE( qs );
}
@ -170,19 +169,24 @@ struct quad_stage *
sp_quad_shade_stage( struct softpipe_context *softpipe )
{
struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
/* allocate storage for program inputs/outputs, aligned to 16 bytes */
qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16);
qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16);
qss->machine.Inputs = align16(qss->inputs);
qss->machine.Outputs = align16(qss->outputs);
if (!qss)
goto fail;
qss->stage.softpipe = softpipe;
qss->stage.begin = shade_begin;
qss->stage.run = shade_quad;
qss->stage.destroy = shade_destroy;
tgsi_exec_machine_init( &qss->machine );
qss->machine = tgsi_exec_machine_create();
if (!qss->machine)
goto fail;
return &qss->stage;
fail:
if (qss && qss->machine)
tgsi_exec_machine_destroy(qss->machine);
FREE(qss);
return NULL;
}

View file

@ -113,7 +113,7 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
if (!ctx)
goto err_c;
_eglInitContext(drv, dpy, &ctx->base, config, attrib_list);
_eglInitContext(drv, dpy, &ctx->base, conf, attrib_list);
ctx->pipe = dev->api->create_context(dev->api, dev->screen);
if (!ctx->pipe)
@ -129,8 +129,8 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
if (!ctx->st)
goto err_gl;
/* generate handle and insert into hash table */
_eglSaveContext(&ctx->base);
/* link to display */
_eglLinkContext(&ctx->base, _eglLookupDisplay(dpy));
assert(_eglGetContextHandle(&ctx->base));
return _eglGetContextHandle(&ctx->base);
@ -147,10 +147,8 @@ EGLBoolean
drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
struct drm_context *c = lookup_drm_context(context);
_eglRemoveContext(&c->base);
if (c->base.IsBound) {
c->base.DeletePending = EGL_TRUE;
} else {
_eglUnlinkContext(&c->base);
if (!c->base.IsBound) {
st_destroy_context(c->st);
c->pipe->destroy(c->pipe);
free(c);

View file

@ -232,7 +232,7 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (!surf)
goto err;
if (!_eglInitSurface(drv, dpy, &surf->base, EGL_PBUFFER_BIT, config, attrib_list))
if (!_eglInitSurface(drv, &surf->base, EGL_PBUFFER_BIT, conf, attrib_list))
goto err_surf;
surf->w = width;
@ -245,7 +245,7 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
(void*)surf);
drm_visual_modes_destroy(visual);
_eglSaveSurface(&surf->base);
_eglLinkSurface(&surf->base, _eglLookupDisplay(dpy));
return surf->base.Handle;
err_surf:
@ -364,10 +364,9 @@ EGLBoolean
drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct drm_surface *surf = lookup_drm_surface(surface);
_eglRemoveSurface(&surf->base);
if (surf->base.IsBound) {
surf->base.DeletePending = EGL_TRUE;
} else {
_eglUnlinkSurface(&surf->base);
if (!surf->base.IsBound) {
if (surf->screen)
drm_takedown_shown_screen(drv, surf->screen);
st_unreference_framebuffer(surf->stfb);

View file

@ -345,7 +345,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_NO_CONTEXT;
/* let EGL lib init the common stuff */
if (!_eglInitContext(drv, dpy, &ctx->Base, config, attrib_list)) {
if (!_eglInitContext(drv, &ctx->Base, conf, attrib_list)) {
free(ctx);
return EGL_NO_CONTEXT;
}
@ -370,7 +370,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_NO_CONTEXT;
}
_eglSaveContext(&ctx->Base);
_eglLinkContext(&ctx->Base, _eglLookupDisplay(dpy));
return _eglGetContextHandle(&ctx->Base);
}
@ -381,10 +381,8 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
{
struct xlib_egl_context *context = lookup_context(ctx);
if (context) {
if (context->Base.IsBound) {
context->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkContext(&context->Base);
if (!context->Base.IsBound) {
/* API-dependent clean-up */
switch (context->Base.ClientAPI) {
case EGL_OPENGL_ES_API:
@ -491,13 +489,13 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
return EGL_NO_SURFACE;
/* Let EGL lib init the common stuff */
if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT,
config, attrib_list)) {
if (!_eglInitSurface(drv, &surf->Base, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(&surf->Base);
_eglLinkSurface(&surf->Base, disp);
/*
* Now init the Xlib and gallium stuff
@ -534,11 +532,8 @@ xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
struct xlib_egl_surface *surf = lookup_surface(surface);
if (surf) {
_eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surface);
if (surf->Base.IsBound) {
surf->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(&surf->Base);
if (!surf->Base.IsBound) {
XFreeGC(surf->Dpy, surf->Gc);
st_unreference_framebuffer(surf->Framebuffer);
free(surf);

View file

@ -472,8 +472,8 @@ fbCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext sh
c->Base.DrawSurface = EGL_NO_SURFACE;
c->Base.ReadSurface = EGL_NO_SURFACE;
/* generate handle and insert into hash table */
_eglSaveContext(&c->Base);
/* link to display */
_eglLinkContext(&c->Base, disp);
assert(c->Base.Handle);
/* Init default driver functions then plug in our FBdev-specific functions
@ -604,13 +604,9 @@ static EGLBoolean
fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
fbSurface *fs = Lookup_fbSurface(surface);
_eglRemoveSurface(&fs->Base);
if (fs->Base.IsBound) {
fs->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkSurface(&fs->Base);
if (!fs->Base.IsBound)
free(fs);
}
return EGL_TRUE;
}
@ -619,13 +615,9 @@ static EGLBoolean
fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
fbContext *fc = Lookup_fbContext(context);
_eglRemoveContext(&fc->Base);
if (fc->Base.IsBound) {
fc->Base.DeletePending = EGL_TRUE;
}
else {
_eglUnlinkContext(&fc->Base);
if (!fc->Base.IsBound)
free(fc);
}
return EGL_TRUE;
}
@ -688,7 +680,7 @@ fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
surface->mesa_framebuffer = _mesa_create_framebuffer(&vis);
if (!surface->mesa_framebuffer) {
free(surface);
_eglRemoveSurface(&surface->Base);
_eglUnlinkSurface(&surface->Base);
return EGL_NO_SURFACE;
}

View file

@ -246,7 +246,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
else if (sf.sf6.line_width <= 0x2)
sf.sf6.line_width = 0;
/* _NEW_POINT */
/* _NEW_BUFFERS */
key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
if (!key->render_to_fbo) {
/* Rendering to an OpenGL window */
@ -276,6 +276,7 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
}
/* XXX clamp max depends on AA vs. non-AA */
/* _NEW_POINT */
sf.sf7.sprite_point = key->point_sprite;
sf.sf7.point_size = CLAMP(rint(key->point_size), 1, 255) * (1<<3);
sf.sf7.use_point_size_state = !key->point_attenuated;
@ -341,7 +342,8 @@ const struct brw_tracked_state brw_sf_unit = {
.mesa = (_NEW_POLYGON |
_NEW_LINE |
_NEW_POINT |
_NEW_SCISSOR),
_NEW_SCISSOR |
_NEW_BUFFERS),
.brw = BRW_NEW_URB_FENCE,
.cache = (CACHE_NEW_SF_VP |
CACHE_NEW_SF_PROG)

View file

@ -546,7 +546,7 @@ _mesa_update_state_locked( GLcontext *ctx )
/* Determine which state flags effect vertex/fragment program state */
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
prog_flags |= (_NEW_TEXTURE | _NEW_FOG | _DD_NEW_SEPARATE_SPECULAR |
prog_flags |= (_NEW_TEXTURE | _NEW_FOG |
_NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE);
}
if (ctx->VertexProgram._MaintainTnlProgram) {

View file

@ -62,6 +62,18 @@ struct texenvprog_cache_item
struct texenvprog_cache_item *next;
};
static GLboolean
texenv_doing_secondary_color(GLcontext *ctx)
{
if (ctx->Light.Enabled &&
(ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR))
return GL_TRUE;
if (ctx->Fog.ColorSumEnabled)
return GL_TRUE;
return GL_FALSE;
}
/**
* Up to nine instructions per tex unit, plus fog, specular color.
@ -298,7 +310,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (ctx->Light.Enabled) {
fp_inputs |= FRAG_BIT_COL0;
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
if (texenv_doing_secondary_color(ctx))
fp_inputs |= FRAG_BIT_COL1;
}
@ -416,8 +428,8 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
}
}
/* _DD_NEW_SEPARATE_SPECULAR */
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
/* _NEW_LIGHT | _NEW_FOG */
if (texenv_doing_secondary_color(ctx)) {
key->separate_specular = 1;
inputs_referenced |= FRAG_BIT_COL1;
}

View file

@ -151,6 +151,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_ATTRIB_TEX5:
case VERT_ATTRIB_TEX6:
case VERT_ATTRIB_TEX7:
assert(slot < Elements(vs_input_semantic_name));
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
vs_input_semantic_index[slot] = num_generic++;
break;
@ -171,6 +172,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_ATTRIB_GENERIC14:
case VERT_ATTRIB_GENERIC15:
assert(attr < VERT_ATTRIB_MAX);
assert(slot < Elements(vs_input_semantic_name));
vs_input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
vs_input_semantic_index[slot] = num_generic++;
break;
@ -198,6 +200,7 @@ st_translate_vertex_program(struct st_context *st,
/* initialize output semantics to defaults */
for (i = 0; i < PIPE_MAX_SHADER_OUTPUTS; i++) {
assert(i < Elements(vs_output_semantic_name));
vs_output_semantic_name[i] = TGSI_SEMANTIC_GENERIC;
vs_output_semantic_index[i] = 0;
output_flags[i] = 0x0;
@ -273,6 +276,7 @@ st_translate_vertex_program(struct st_context *st,
case VERT_RESULT_VAR0:
/* fall-through */
default:
assert(slot < Elements(vs_output_semantic_name));
if (outputSemanticName) {
/* use provided semantic into */
assert(outputSemanticName[attr] != TGSI_SEMANTIC_COUNT);
@ -286,6 +290,7 @@ st_translate_vertex_program(struct st_context *st,
}
}
assert(slot < Elements(output_flags));
output_flags[slot] = stvp->Base.Base.OutputFlags[attr];
}
}