Merge branch 'asm-shader-rework-1'
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 21 Aug 2009 18:34:30 +0000 (11:34 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Fri, 21 Aug 2009 18:34:30 +0000 (11:34 -0700)
137 files changed:
configs/default
progs/demos/fbotexture.c
progs/egl/demo3.c
progs/glsl/multitex.shtest
progs/glsl/shtest.c
progs/util/shaderutil.c
progs/util/shaderutil.h
progs/xdemos/.gitignore
src/egl/drivers/demo/demo.c
src/egl/drivers/glx/egl_glx.c
src/egl/main/Makefile
src/egl/main/eglapi.c
src/egl/main/eglapi.h
src/egl/main/eglconfig.c
src/egl/main/eglconfig.h
src/egl/main/eglcontext.c
src/egl/main/eglcontext.h
src/egl/main/egldisplay.c
src/egl/main/egldisplay.h
src/egl/main/egldriver.c
src/egl/main/egldriver.h
src/egl/main/eglglobals.c
src/egl/main/eglglobals.h
src/egl/main/eglhash.c [deleted file]
src/egl/main/eglhash.h [deleted file]
src/egl/main/eglmisc.c
src/egl/main/eglmisc.h
src/egl/main/eglmode.c
src/egl/main/eglmode.h
src/egl/main/eglscreen.c
src/egl/main/eglscreen.h
src/egl/main/eglsurface.c
src/egl/main/eglsurface.h
src/egl/main/egltypedefs.h
src/egl/main/eglx.c [deleted file]
src/egl/main/eglx.h [deleted file]
src/gallium/Makefile.template
src/gallium/auxiliary/tgsi/tgsi_build.c
src/gallium/auxiliary/tgsi/tgsi_dump.c
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_exec.h
src/gallium/auxiliary/tgsi/tgsi_parse.h
src/gallium/auxiliary/tgsi/tgsi_ppc.c
src/gallium/auxiliary/tgsi/tgsi_sse2.c
src/gallium/auxiliary/tgsi/tgsi_ureg.c
src/gallium/auxiliary/tgsi/tgsi_ureg.h
src/gallium/auxiliary/util/u_rect.c
src/gallium/auxiliary/util/u_rect.h
src/gallium/auxiliary/util/u_tile.c
src/gallium/drivers/i965simple/brw_surface.c
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_state_validate.c
src/gallium/drivers/nv50/nv50_vbo.c
src/gallium/drivers/r300/r300_chipset.c
src/gallium/drivers/r300/r300_chipset.h
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_query.h
src/gallium/drivers/r300/r300_reg.h
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_inlines.h
src/gallium/drivers/r300/r300_winsys.h
src/gallium/drivers/trace/tr_dump.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_inlines.h
src/gallium/state_trackers/egl/egl_context.c
src/gallium/state_trackers/egl/egl_surface.c
src/gallium/state_trackers/egl/egl_tracker.c
src/gallium/state_trackers/egl/egl_tracker.h
src/gallium/state_trackers/glx/xlib/glx_api.c
src/gallium/state_trackers/python/retrace/parse.py
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/winsys/drm/radeon/core/radeon_buffer.c
src/gallium/winsys/drm/radeon/core/radeon_r300.c
src/gallium/winsys/egl_xlib/egl_xlib.c
src/glx/x11/glxcmds.c
src/mesa/drivers/dri/i965/brw_tex_layout.c
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/r200/Makefile
src/mesa/drivers/dri/r200/r200_cmdbuf.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/r200/r200_tcl.c
src/mesa/drivers/dri/r200/radeon_queryobj.c [new symlink]
src/mesa/drivers/dri/r200/radeon_queryobj.h [new symlink]
src/mesa/drivers/dri/r300/Makefile
src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_draw.c
src/mesa/drivers/dri/r300/r300_ioctl.c
src/mesa/drivers/dri/r300/r300_queryobj.c [deleted file]
src/mesa/drivers/dri/r300/r300_queryobj.h [deleted file]
src/mesa/drivers/dri/r300/r300_render.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_swtcl.c
src/mesa/drivers/dri/r300/r300_texstate.c
src/mesa/drivers/dri/r300/radeon_queryobj.c [new symlink]
src/mesa/drivers/dri/r300/radeon_queryobj.h [new symlink]
src/mesa/drivers/dri/r600/Makefile
src/mesa/drivers/dri/r600/r600_cmdbuf.c
src/mesa/drivers/dri/r600/r600_cmdbuf.h
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/r600/r600_context.h
src/mesa/drivers/dri/r600/r600_emit.c
src/mesa/drivers/dri/r600/r600_texstate.c
src/mesa/drivers/dri/r600/r700_chip.c
src/mesa/drivers/dri/r600/r700_chip.h
src/mesa/drivers/dri/r600/r700_clear.c
src/mesa/drivers/dri/r600/r700_ioctl.c
src/mesa/drivers/dri/r600/r700_render.c
src/mesa/drivers/dri/r600/r700_state.c
src/mesa/drivers/dri/r600/radeon_queryobj.c [new symlink]
src/mesa/drivers/dri/r600/radeon_queryobj.h [new symlink]
src/mesa/drivers/dri/radeon/Makefile
src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
src/mesa/drivers/dri/radeon/radeon_common.c
src/mesa/drivers/dri/radeon/radeon_common_context.c
src/mesa/drivers/dri/radeon/radeon_common_context.h
src/mesa/drivers/dri/radeon/radeon_dma.c
src/mesa/drivers/dri/radeon/radeon_dma.h
src/mesa/drivers/dri/radeon/radeon_queryobj.c [new file with mode: 0644]
src/mesa/drivers/dri/radeon/radeon_queryobj.h [new file with mode: 0644]
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/radeon/radeon_state_init.c
src/mesa/drivers/dri/radeon/radeon_swtcl.c
src/mesa/main/drawpix.c
src/mesa/main/ffvertex_prog.c
src/mesa/main/get.c
src/mesa/main/get_gen.py
src/mesa/state_tracker/st_texture.c

index 60638d739ddd3925428ae0195e7bb8e20ebfded5..127b98e76ce3fd3fd6e1481c48467f3b659a5803 100644 (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 -lpthread
+EGL_LIB_DEPS    = $(EXTRA_LIB_PATH) -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
index 3b36f755a042b42043c2a81fa9a92add913ba67d..56482663dc4c1329f11730e951ad1d44fc6e8bf5 100644 (file)
@@ -498,7 +498,7 @@ SetupFunctionPointers(void)
  * Make FBO to render into given texture.
  */
 static GLuint
-MakeFBO_RenderTexture(GLuint TexObj)
+MakeFBO_RenderTexture(GLuint texObj)
 {
    GLuint fb;
    GLint sizeFudge = 0;
@@ -507,7 +507,7 @@ MakeFBO_RenderTexture(GLuint TexObj)
    glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, fb);
    /* Render color to texture */
    glFramebufferTexture2D_func(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
-                             TexTarget, TexObj, TextureLevel);
+                             TexTarget, texObj, TextureLevel);
 
    if (Use_ARB_fbo) {
       /* use a smaller depth buffer to see what happens */
@@ -541,7 +541,7 @@ MakeFBO_RenderTexture(GLuint TexObj)
 
    /* queries */
    {
-      GLint bits, w, h;
+      GLint bits, w, h, name;
 
       glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, DepthRB);
       glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
@@ -559,8 +559,28 @@ MakeFBO_RenderTexture(GLuint TexObj)
       glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
                                       GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits);
       printf("Stencil renderbuffer size = %d bits\n", bits);
-   }
 
+      glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+                                      GL_COLOR_ATTACHMENT0,
+                                      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+                                      &name);
+      printf("Render to texture name: %d\n", texObj);
+      printf("Color attachment[0] name: %d\n", name);
+      assert(texObj == name);
+
+      glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+                                      GL_STENCIL_ATTACHMENT,
+                                      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+                                      &name);
+      printf("Stencil attachment name: %d\n", name);
+
+      glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+                                      GL_DEPTH_ATTACHMENT,
+                                      GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+                                      &name);
+      printf("Depth attachment name: %d\n", name);
+
+   }
    /* bind the regular framebuffer */
    glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, 0);
 
index a6096a257ec0435598c24a4deae6155dfb3ee939..daab62d1738cce7f27bca8ed6a88ea12cd3b57a9 100644 (file)
@@ -551,7 +551,7 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
    }
 }
 
-#include "../src/egl/main/egldisplay.h"
+#include "../../src/egl/main/egldisplay.h"
 
 typedef struct fb_display
 {
index 5be45f6c7cb9f4ed1d658ce4a99b2309d2ec061b..4b7c3fd4a5f83a6ea3565cc4f21462898799679b 100644 (file)
@@ -1,6 +1,6 @@
 vs multitex.vert
 fs multitex.frag
-texture 0 ../images/tile.rgb
-texture 1 ../images/tree2.rgba
+texture 0 2D ../images/tile.rgb
+texture 1 2D ../images/tree2.rgba
 uniform tex1  GL_SAMPLER_2D  0
 uniform tex2  GL_SAMPLER_2D  1
index 2622af13138442e797422b3438ab8314f7413ada..fa477d9eeb785ef27229cc8e94be2226477ea3e4 100644 (file)
@@ -21,6 +21,9 @@
  * fs shader.frag
  * uniform pi 3.14159
  * uniform v1 1.0 0.5 0.2 0.3
+ * texture 0 2D texture0.rgb
+ * texture 1 CUBE texture1.rgb
+ * texture 2 RECT texture2.rgb
  *
  */
 
@@ -255,7 +258,7 @@ Redisplay(void)
    glMatrixMode(GL_MODELVIEW);
 
    if (Object == SPHERE) {
-      Sphere(2.0, 20, 10);
+      Sphere(2.5, 20, 10);
    }
    else if (Object == CUBE) {
       Cube(2.0);
@@ -376,13 +379,14 @@ InitUniforms(const struct config_file *conf,
 
 
 static void
-LoadTexture(GLint unit, const char *texFileName)
+LoadTexture(GLint unit, GLenum target, const char *texFileName)
 {
    GLint imgWidth, imgHeight;
    GLenum imgFormat;
    GLubyte *image = NULL;
    GLuint tex;
    GLenum filter = GL_LINEAR;
+   GLenum objTarget;
 
    image = LoadRGBImage(texFileName, &imgWidth, &imgHeight, &imgFormat);
    if (!image) {
@@ -390,21 +394,41 @@ LoadTexture(GLint unit, const char *texFileName)
       exit(1);
    }
 
-   printf("Load Texture: unit %d: %s %d x %d\n",
-          unit, texFileName, imgWidth, imgHeight);
+   printf("Load Texture: unit %d, target 0x%x: %s %d x %d\n",
+          unit, target, texFileName, imgWidth, imgHeight);
+
+   if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+       target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
+      objTarget = GL_TEXTURE_CUBE_MAP;
+   }
+   else {
+      objTarget = target;
+   }
 
    glActiveTexture(GL_TEXTURE0 + unit);
    glGenTextures(1, &tex);
-   glBindTexture(GL_TEXTURE_2D, tex);
+   glBindTexture(objTarget, tex);
+
+   if (target == GL_TEXTURE_3D) {
+      /* depth=1 */
+      gluBuild3DMipmaps(target, 4, imgWidth, imgHeight, 1,
+                        imgFormat, GL_UNSIGNED_BYTE, image);
+   }
+   else if (target == GL_TEXTURE_1D) {
+      gluBuild1DMipmaps(target, 4, imgWidth,
+                        imgFormat, GL_UNSIGNED_BYTE, image);
+   }
+   else {
+      gluBuild2DMipmaps(target, 4, imgWidth, imgHeight,
+                        imgFormat, GL_UNSIGNED_BYTE, image);
+   }
 
-   gluBuild2DMipmaps(GL_TEXTURE_2D, 4, imgWidth, imgHeight,
-                     imgFormat, GL_UNSIGNED_BYTE, image);
    free(image);
       
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+   glTexParameteri(objTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
+   glTexParameteri(objTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
+   glTexParameteri(objTarget, GL_TEXTURE_MIN_FILTER, filter);
+   glTexParameteri(objTarget, GL_TEXTURE_MAG_FILTER, filter);
 }
 
 
@@ -423,7 +447,11 @@ TypeFromName(const char *n)
       { "GL_INT_VEC2", GL_INT_VEC2 },
       { "GL_INT_VEC3", GL_INT_VEC3 },
       { "GL_INT_VEC4", GL_INT_VEC4 },
+      { "GL_SAMPLER_1D", GL_SAMPLER_1D },
       { "GL_SAMPLER_2D", GL_SAMPLER_2D },
+      { "GL_SAMPLER_3D", GL_SAMPLER_3D },
+      { "GL_SAMPLER_CUBE", GL_SAMPLER_CUBE },
+      { "GL_SAMPLER_2D_RECT", GL_SAMPLER_2D_RECT_ARB },
       { NULL, 0 }
    };
    GLuint i;
@@ -468,11 +496,40 @@ ReadConfigFile(const char *filename, struct config_file *conf)
             FragShaderFile[strlen(FragShaderFile) - 1] = 0;
          }
          else if (strncmp(line, "texture ", 8) == 0) {
-            char texFileName[100];
+            char target[100], texFileName[100];
             int unit, k;
-            k = sscanf(line + 8, "%d %s", &unit, texFileName);
-            assert(k == 2);
-            LoadTexture(unit, texFileName);
+            k = sscanf(line + 8, "%d %s %s", &unit, target, texFileName);
+            assert(k == 3 || k == 8);
+            if (strcmp(target, "CUBE") == 0) {
+               char texFileNames[6][100];
+               k = sscanf(line + 8, "%d %s  %s %s %s %s %s %s",
+                          &unit, target,
+                          texFileNames[0],
+                          texFileNames[1],
+                          texFileNames[2],
+                          texFileNames[3],
+                          texFileNames[4],
+                          texFileNames[5]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texFileNames[0]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, texFileNames[1]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, texFileNames[2]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, texFileNames[3]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texFileNames[4]);
+               LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texFileNames[5]);
+            }
+            else if (!strcmp(target, "2D")) {
+               LoadTexture(unit, GL_TEXTURE_2D, texFileName);
+            }
+            else if (!strcmp(target, "3D")) {
+               LoadTexture(unit, GL_TEXTURE_3D, texFileName);
+            }
+            else if (!strcmp(target, "RECT")) {
+               LoadTexture(unit, GL_TEXTURE_RECTANGLE_ARB, texFileName);
+            }
+            else {
+               printf("Bad texture target: %s\n", target);
+               exit(1);
+            }
          }
          else if (strncmp(line, "uniform ", 8) == 0) {
             char name[1000], typeName[100];
@@ -509,7 +566,9 @@ ReadConfigFile(const char *filename, struct config_file *conf)
 static void
 Init(void)
 {
+   GLdouble vertTime, fragTime, linkTime;
    struct config_file config;
+
    memset(&config, 0, sizeof(config));
 
    if (ConfigFile)
@@ -529,8 +588,16 @@ Init(void)
       exit(1);
 
    vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertShaderFile);
+   vertTime = GetShaderCompileTime();
    fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragShaderFile);
+   fragTime = GetShaderCompileTime();
+
    Program = LinkShaders(vertShader, fragShader);
+   linkTime = GetShaderLinkTime();
+
+   printf("Time to compile vertex shader: %fs\n", vertTime);
+   printf("Time to compile fragment shader: %fs\n", fragTime);
+   printf("Time to link shaders: %fs\n", linkTime);
 
    glUseProgram(Program);
 
@@ -611,8 +678,8 @@ ParseOptions(int argc, char *argv[])
 int
 main(int argc, char *argv[])
 {
-   glutInit(&argc, argv);
    glutInitWindowSize(400, 400);
+   glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    win = glutCreateWindow(argv[0]);
    glewInit();
index 489e71cc30cb4ee9eddee4b4baa5b297f56ba69d..c58c249831e68e8bc92670a2a71430a90a87f6d0 100644 (file)
 #include <GL/glut.h>
 #include "shaderutil.h"
 
+/** time to compile previous shader */
+static GLdouble CompileTime = 0.0;
+
+/** time to linke previous program */
+static GLdouble LinkTime = 0.0;
+
 
 GLboolean
 ShadersSupported(void)
@@ -37,10 +43,17 @@ CompileShaderText(GLenum shaderType, const char *text)
 {
    GLuint shader;
    GLint stat;
+   GLdouble t0, t1;
 
    shader = glCreateShader(shaderType);
    glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
    glCompileShader(shader);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   CompileTime = t1 - t0;
+
    glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
    if (!stat) {
       GLchar log[1000];
@@ -95,6 +108,7 @@ GLuint
 LinkShaders(GLuint vertShader, GLuint fragShader)
 {
    GLuint program = glCreateProgram();
+   GLdouble t0, t1;
 
    assert(vertShader || fragShader);
 
@@ -102,7 +116,12 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
       glAttachShader(program, fragShader);
    if (vertShader)
       glAttachShader(program, vertShader);
+
+   t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
    glLinkProgram(program);
+   t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+   LinkTime = t1 - t0;
 
    /* check link */
    {
@@ -121,6 +140,20 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
 }
 
 
+GLdouble
+GetShaderCompileTime(void)
+{
+   return CompileTime;
+}
+
+
+GLdouble
+GetShaderLinkTime(void)
+{
+   return LinkTime;
+}
+
+
 void
 SetUniformValues(GLuint program, struct uniform_info uniforms[])
 {
index 0a6be026759b8e958b4bb87fac0fb722c85c1a9f..91c0d4094f8d83b524046b9c14145fa9ceb39218 100644 (file)
@@ -36,6 +36,12 @@ CompileShaderFile(GLenum shaderType, const char *filename);
 extern GLuint
 LinkShaders(GLuint vertShader, GLuint fragShader);
 
+extern GLdouble
+GetShaderCompileTime(void);
+
+extern GLdouble
+GetShaderLinkTime(void);
+
 extern void
 SetUniformValues(GLuint program, struct uniform_info uniforms[]);
 
index 92446dd9fc3e4b81d867c967db2b7839f1112a3e..1b9b3a87c015a9822b3112a9ab31ec53dbd51461 100644 (file)
@@ -13,6 +13,7 @@ glxpixmap
 glxsnoop
 glxswapcontrol
 manywin
+multictx
 offset
 overlay
 pbdemo
index e8c0c1df5ee4301b58be7c381ac26baf1617a757..aea4894448b7625f6f603b25f95b9e22d8299d61 100644 (file)
@@ -49,9 +49,8 @@ typedef struct demo_context
 
 
 static EGLBoolean
-demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    _EGLScreen *scrn;
    EGLint i;
 
@@ -85,7 +84,9 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
       _eglAddConfig(disp, config);
    }
 
-   drv->Initialized = EGL_TRUE;
+   /* enable supported extensions */
+   disp->Extensions.MESA_screen_surface = EGL_TRUE;
+   disp->Extensions.MESA_copy_context = EGL_TRUE;
 
    *major = 1;
    *minor = 0;
@@ -95,71 +96,56 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
 
 
 static EGLBoolean
-demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
+demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
-   free(drv);
    return EGL_TRUE;
 }
 
 
 static DemoContext *
-LookupDemoContext(EGLContext ctx)
+LookupDemoContext(_EGLContext *c)
 {
-   _EGLContext *c = _eglLookupContext(ctx);
    return (DemoContext *) c;
 }
 
 
 static DemoSurface *
-LookupDemoSurface(EGLSurface surf)
+LookupDemoSurface(_EGLSurface *s)
 {
-   _EGLSurface *s = _eglLookupSurface(surf);
    return (DemoSurface *) s;
 }
 
 
-
-static EGLContext
-demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
 {
-   _EGLConfig *conf;
    DemoContext *c;
    int i;
 
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreateContext");
-      return EGL_NO_CONTEXT;
-   }
-
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
          /* no attribs defined for now */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
-         return EGL_NO_CONTEXT;
+         return NULL;
       }
    }
 
    c = (DemoContext *) calloc(1, sizeof(DemoContext));
    if (!c)
-      return EGL_NO_CONTEXT;
+      return NULL;
 
    _eglInitContext(drv, &c->Base, conf, attrib_list);
    c->DemoStuff = 1;
    printf("demoCreateContext\n");
 
-   /* link to display */
-   _eglLinkContext(&c->Base, _eglLookupDisplay(dpy));
-   assert(_eglGetContextHandle(&c->Base));
-
-   return _eglGetContextHandle(&c->Base);
+   return &c->Base;
 }
 
 
-static EGLSurface
-demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
 {
    int i;
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
@@ -167,75 +153,65 @@ demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nativ
          /* no attribs at this time */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
-         return EGL_NO_SURFACE;
+         return NULL;
       }
    }
    printf("eglCreateWindowSurface()\n");
    /* XXX unfinished */
 
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
-static EGLSurface
-demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
 {
-   _EGLConfig *conf;
    EGLint i;
 
-   conf = _eglLookupConfig(drv, dpy, config);
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
-      return EGL_NO_SURFACE;
-   }
-
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
          /* no attribs at this time */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
-         return EGL_NO_SURFACE;
+         return NULL;
       }
    }
 
    if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
       _eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    printf("eglCreatePixmapSurface()\n");
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
-static EGLSurface
-demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                          const EGLint *attrib_list)
 {
    DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
-   _EGLConfig *conf;
 
    if (!surf)
-      return EGL_NO_SURFACE;
+      return NULL;
 
-   conf = _eglLookupConfig(drv, dpy, config);
    if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
                         conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    /* a real driver would allocate the pbuffer memory here */
 
-   return surf->Base.Handle;
+   return &surf->Base;
 }
 
 
 static EGLBoolean
-demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
    DemoSurface *fs = LookupDemoSurface(surface);
-   _eglUnlinkSurface(&fs->Base);
    if (!_eglIsSurfaceBound(&fs->Base))
       free(fs);
    return EGL_TRUE;
@@ -243,10 +219,9 @@ demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
 
 
 static EGLBoolean
-demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
 {
    DemoContext *fc = LookupDemoContext(context);
-   _eglUnlinkContext(&fc->Base);
    if (!_eglIsContextBound(&fc->Base))
       free(fc);
    return EGL_TRUE;
@@ -254,15 +229,12 @@ demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
 
 
 static EGLBoolean
-demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx)
 {
    /*DemoDriver *demo = DEMO_DRIVER(dpy);*/
-   DemoSurface *readSurf = LookupDemoSurface(read);
-   DemoSurface *drawSurf = LookupDemoSurface(draw);
-   DemoContext *ctx = LookupDemoContext(context);
    EGLBoolean b;
 
-   b = _eglMakeCurrent(drv, dpy, draw, read, context);
+   b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx);
    if (!b)
       return EGL_FALSE;
 
@@ -276,12 +248,19 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
 }
 
 
+static void
+demoUnload(_EGLDriver *drv)
+{
+   free(drv);
+}
+
+
 /**
  * The bootstrap function.  Return a new DemoDriver object and
  * plug in API functions.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
 {
    DemoDriver *demo;
 
@@ -303,9 +282,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
    demo->Base.API.DestroySurface = demoDestroySurface;
    demo->Base.API.DestroyContext = demoDestroyContext;
 
-   /* enable supported extensions */
-   demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
-   demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
+   demo->Base.Name = "egl/demo";
+   demo->Base.Unload = demoUnload;
 
    return &demo->Base;
 }
index 5ed4b6883f885983bf7d03d0c51ea444d25b5dd3..3c8f8b6a6845f9b42d227c1c047ade64bf175a33 100644 (file)
@@ -57,7 +57,6 @@
 #include "egldisplay.h"
 #include "egldriver.h"
 #include "eglglobals.h"
-#include "eglhash.h"
 #include "egllog.h"
 #include "eglsurface.h"
 
@@ -157,6 +156,13 @@ GLX_egl_surface(_EGLSurface *surf)
    return (struct GLX_egl_surface *) surf;
 }
 
+static int
+GLX_egl_config_id(_EGLConfig *conf)
+{
+   /* see create_configs */
+   return (int) _eglPointerToUInt(_eglGetConfigHandle(conf)) - 1;
+}
+
 static GLboolean
 get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
                    struct visual_attribs *attribs)
@@ -351,7 +357,6 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
    int numVisuals;
    long mask;
    int i;
-   int egl_configs = 1;
    struct visual_attribs attribs;
 
    GLX_drv->fbconfigs = NULL;
@@ -441,11 +446,10 @@ end:
  * Called via eglInitialize(), GLX_drv->API.Initialize().
  */
 static EGLBoolean
-GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
+GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
                    EGLint *minor, EGLint *major)
 {
    struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
 
    _eglLog(_EGL_DEBUG, "GLX: eglInitialize");
 
@@ -457,10 +461,10 @@ GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
       }
    } 
 
+   disp->ClientAPIsMask = all_apis;
+
    glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min);
    
-   GLX_drv->Base.Initialized = EGL_TRUE;
-
    GLX_drv->Base.Name = "GLX";
 
    /* we're supporting EGL 1.4 */
@@ -504,13 +508,13 @@ FreeDisplayExt(Display *dpy)
  * Called via eglTerminate(), drv->API.Terminate().
  */
 static EGLBoolean
-GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
    _eglLog(_EGL_DEBUG, "GLX: eglTerminate");
 
+   _eglReleaseDisplayResources(drv, disp);
    FreeDisplayExt(disp->Xdpy);
+   _eglCleanupDisplay(disp);
 
    return EGL_TRUE;
 }
@@ -519,42 +523,37 @@ GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
 /**
  * Called via eglCreateContext(), drv->API.CreateContext().
  */
-static EGLContext
-GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                      EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
+                      _EGLContext *share_list, const EGLint *attrib_list)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    struct GLX_egl_context *GLX_ctx = CALLOC_STRUCT(GLX_egl_context);
    struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
-   struct GLX_egl_context *GLX_ctx_shared = NULL;
-   _EGLConfig *conf;
+   struct GLX_egl_context *GLX_ctx_shared = GLX_egl_context(share_list);
 
    if (!GLX_ctx)
-      return EGL_NO_CONTEXT;
-
-   conf = _eglLookupConfig(drv, dpy, config);
-   assert(conf);
+      return NULL;
 
    if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
       free(GLX_ctx);
-      return EGL_NO_CONTEXT;
-   }
-
-   if (share_list != EGL_NO_CONTEXT) {
-      _EGLContext *shareCtx = _eglLookupContext(share_list);
-      if (!shareCtx) {
-         _eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)");
-         return EGL_FALSE;
-      }
-      GLX_ctx_shared = GLX_egl_context(shareCtx);
+      return NULL;
    }
 
 #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);
+      GLX_ctx->context =
+         glXCreateNewContext(disp->Xdpy,
+                             GLX_drv->fbconfigs[GLX_egl_config_id(conf)],
+                             GLX_RGBA_TYPE,
+                             GLX_ctx_shared ? GLX_ctx_shared->context : NULL,
+                             GL_TRUE);
    else
 #endif
-      GLX_ctx->context = glXCreateContext(disp->Xdpy, &GLX_drv->visuals[(int)config-1], GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE);
+      GLX_ctx->context =
+         glXCreateContext(disp->Xdpy,
+                          &GLX_drv->visuals[GLX_egl_config_id(conf)],
+                          GLX_ctx_shared ? GLX_ctx_shared->context : NULL,
+                          GL_TRUE);
    if (!GLX_ctx->context)
       return EGL_FALSE;
 
@@ -564,7 +563,7 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
       return EGL_FALSE;
 #endif
 
-   return _eglLinkContext(&GLX_ctx->Base, disp);
+   return &GLX_ctx->Base;
 }
 
 
@@ -572,18 +571,14 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * Called via eglMakeCurrent(), drv->API.MakeCurrent().
  */
 static EGLBoolean
-GLX_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
-                    EGLSurface r, EGLContext context)
+GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
+                   _EGLSurface *rsurf, _EGLContext *ctx)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLContext *ctx = _eglLookupContext(context);
-   _EGLSurface *dsurf = _eglLookupSurface(d);
-   _EGLSurface *rsurf = _eglLookupSurface(r);
    struct GLX_egl_surface *GLX_dsurf = GLX_egl_surface(dsurf);
    struct GLX_egl_surface *GLX_rsurf = GLX_egl_surface(rsurf);
    struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx);
 
-   if (!_eglMakeCurrent(drv, dpy, d, r, context))
+   if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx))
       return EGL_FALSE;
 
 #ifdef GLX_VERSION_1_3
@@ -612,104 +607,86 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
-static EGLSurface
-GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
                             NativeWindowType window, const EGLint *attrib_list)
 {
-   _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;
+      return NULL;
 
    if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
                         conf, attrib_list)) {
       free(GLX_surf);
-      return EGL_FALSE;
+      return NULL;
    }
 
-   _eglLinkSurface(&GLX_surf->Base, disp);
-
    GLX_surf->drawable = window;
    get_drawable_size(disp->Xdpy, window, &width, &height);
    GLX_surf->Base.Width = width;
    GLX_surf->Base.Height = height;
 
-   return _eglGetSurfaceHandle(&GLX_surf->Base);
+   return &GLX_surf->Base;
 }
 
 #ifdef GLX_VERSION_1_3
-static EGLSurface
-GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, 
+static _EGLSurface *
+GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
                           NativePixmapType pixmap, const EGLint *attrib_list)
 {
    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;
+      return NULL;
 
    if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
                         conf, attrib_list)) {
       free(GLX_surf);
-      return EGL_FALSE;
+      return NULL;
    }
 
-   _eglLinkSurface(&GLX_surf->Base, disp);
-
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
       switch (attrib_list[i]) {
          /* no attribs at this time */
       default:
          _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
-         return EGL_NO_SURFACE;
+         return NULL;
       }
    }
 
-   GLX_surf->drawable = glXCreatePixmap(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], pixmap, NULL);
+   GLX_surf->drawable =
+      glXCreatePixmap(disp->Xdpy,
+                      GLX_drv->fbconfigs[GLX_egl_config_id(conf)],
+                      pixmap, NULL);
 
-   return _eglGetSurfaceHandle(&GLX_surf->Base);
+   return &GLX_surf->Base;
 }
 
-static EGLSurface
-GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
                             const EGLint *attrib_list)
 {
    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;
+      return NULL;
 
    if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
                         conf, attrib_list)) {
       free(GLX_surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   _eglLinkSurface(&GLX_surf->Base, disp);
-
    while(attrib_list[i] != EGL_NONE) {
       switch (attrib_list[i]) {
          case EGL_WIDTH:
@@ -725,38 +702,40 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    }
    attribs[j++] = 0;
 
-   GLX_surf->drawable = glXCreatePbuffer(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], attribs);
+   GLX_surf->drawable =
+      glXCreatePbuffer(disp->Xdpy,
+                       GLX_drv->fbconfigs[GLX_egl_config_id(conf)], attribs);
 
-   return _eglGetSurfaceHandle(&GLX_surf->Base);
+   return &GLX_surf->Base;
 }
 #endif
 
 static EGLBoolean
-GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLSurface *surf = _eglLookupSurface(surface);
-   return EGL_TRUE;
-   if (surf) {
-      _eglUnlinkSurface(surf);
-      if (!_eglIsSurfaceBound(surf))
-         free(surf);
-
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
-      return EGL_FALSE;
+   if (!_eglIsSurfaceBound(surf)) {
+      struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
+      switch (surf->Type) {
+      case EGL_PBUFFER_BIT:
+         glXDestroyPbuffer(disp->Xdpy, GLX_surf->drawable);
+         break;
+      case EGL_PIXMAP_BIT:
+         glXDestroyPixmap(disp->Xdpy, GLX_surf->drawable);
+         break;
+      default:
+         break;
+      }
+      free(surf);
    }
+
+   return EGL_TRUE;
 }
 
 
 static EGLBoolean
-GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+GLX_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
                      EGLint buffer)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLSurface *surf = _eglLookupSurface(surface);
    struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
 
    /* buffer ?? */
@@ -767,11 +746,9 @@ GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
 
 
 static EGLBoolean
-GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+GLX_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
                         EGLint buffer)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLSurface *surf = _eglLookupSurface(surface);
    struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
 
    /* buffer ?? */
@@ -782,16 +759,14 @@ GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
 
 
 static EGLBoolean
-GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLSurface *surf = _eglLookupSurface(draw);
-   struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
+   struct GLX_egl_surface *GLX_surf = GLX_egl_surface(draw);
 
    _eglLog(_EGL_DEBUG, "GLX: EGL SwapBuffers 0x%x",draw);
 
    /* error checking step: */
-   if (!_eglSwapBuffers(drv, dpy, draw))
+   if (!_eglSwapBuffers(drv, disp, draw))
       return EGL_FALSE;
 
    glXSwapBuffers(disp->Xdpy, GLX_surf->drawable);
@@ -810,28 +785,36 @@ GLX_eglGetProcAddress(const char *procname)
     * some point.
     */
    _EGLProc (*get_proc_addr)(const char *procname);
+   _EGLProc proc_addr;
    get_proc_addr = dlsym(NULL, "st_get_proc_address");
    if (get_proc_addr)
       return get_proc_addr(procname);
 
-   get_proc_addr = glXGetProcAddress((const GLubyte *)procname);
-   if (get_proc_addr)
-      return get_proc_addr(procname);
+   proc_addr = glXGetProcAddress((const GLubyte *)procname);
+   if (proc_addr)
+      return proc_addr;
 
    return (_EGLProc)dlsym(NULL, procname);
 }
 
 
+static void
+GLX_Unload(_EGLDriver *drv)
+{
+   struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
+   free(GLX_drv);
+}
+
+
 /**
  * This is the main entrypoint into the driver, called by libEGL.
  * Create a new _EGLDriver object and init its dispatch table.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *disp, const char *args)
+_eglMain(const char *args)
 {
    struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver);
    char *env;
-   int maj = 0, min = 0;
 
    if (!GLX_drv)
       return NULL;
@@ -857,8 +840,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
    GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers;
    GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress;
 
-   GLX_drv->Base.ClientAPIsMask = all_apis;
    GLX_drv->Base.Name = "GLX";
+   GLX_drv->Base.Unload = GLX_Unload;
 
    _eglLog(_EGL_DEBUG, "GLX: main(%s)", args);
 
index ab61d68f2b60fe4542d274ce3d1f50501daabec3..c951b070f1f4a8aa9d9c01d21a7a6a9146ffdcde 100644 (file)
@@ -17,14 +17,12 @@ HEADERS = \
        egldriver.h \
        eglglobals.h \
        egllog.h \
-       eglhash.h \
        eglmisc.h \
        eglmode.h \
        eglmutex.h \
        eglscreen.h \
        eglstring.h \
-       eglsurface.h \
-       eglx.h
+       eglsurface.h
 
 SOURCES = \
        eglapi.c \
@@ -36,13 +34,11 @@ SOURCES = \
        egldriver.c \
        eglglobals.c \
        egllog.c \
-       eglhash.c \
        eglmisc.c \
        eglmode.c \
        eglscreen.c \
        eglstring.c \
-       eglsurface.c \
-       eglx.c
+       eglsurface.c
 
 OBJECTS = $(SOURCES:.c=.o)
 
index fde6b7316c8f31a50fac9eae29e5da0a284dcb7d..29617b7afff0b164eb1210a0438c6d1aa9590566 100644 (file)
@@ -29,7 +29,6 @@
  */
 
 
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -39,7 +38,9 @@
 #include "eglglobals.h"
 #include "egldriver.h"
 #include "eglsurface.h"
-
+#include "eglconfig.h"
+#include "eglscreen.h"
+#include "eglmode.h"
 
 
 /**
@@ -67,232 +68,484 @@ eglGetDisplay(NativeDisplayType nativeDisplay)
 EGLBoolean EGLAPIENTRY
 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDriver *drv;
    EGLint major_int, minor_int;
 
-   if (dpy) {
-      EGLBoolean retVal;
-      _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
-      if (!dpyPriv) {
-         return EGL_FALSE;
-      }
-      dpyPriv->Driver = _eglOpenDriver(dpyPriv,
-                                       dpyPriv->DriverName,
-                                       dpyPriv->DriverArgs);
-      if (!dpyPriv->Driver) {
-         return EGL_FALSE;
-      }
-      /* Initialize the particular driver now */
-      retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
-                                               &major_int, &minor_int);
-
-      dpyPriv->Driver->APImajor = major_int;
-      dpyPriv->Driver->APIminor = minor_int;
-      snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
-               "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name);
-
-      /* Update applications version of major and minor if not NULL */
-      if((major != NULL) && (minor != NULL))
-      {
-         *major = major_int;
-         *minor = minor_int;
+   if (!disp)
+      return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+   drv = disp->Driver;
+   if (!drv) {
+      drv = _eglOpenDriver(disp);
+      if (!drv)
+         return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
+
+      /* Initialize the particular display now */
+      if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) {
+         _eglCloseDriver(drv, disp);
+         return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
       }
 
-      return retVal;
+      disp->APImajor = major_int;
+      disp->APIminor = minor_int;
+      snprintf(disp->Version, sizeof(disp->Version),
+               "%d.%d (%s)", major_int, minor_int, drv->Name);
+
+      /* update the global notion of supported APIs */
+      _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
+
+      disp->Driver = drv;
+   } else {
+      major_int = disp->APImajor;
+      minor_int = disp->APIminor;
+   }
+
+   /* Update applications version of major and minor if not NULL */
+   if ((major != NULL) && (minor != NULL)) {
+      *major = major_int;
+      *minor = minor_int;
    }
-   return EGL_FALSE;
+
+   return EGL_TRUE;
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglTerminate(EGLDisplay dpy)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return _eglCloseDriver(drv, dpy);
-   else
-      return EGL_FALSE;
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLDriver *drv;
+
+   if (!disp)
+      return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+   drv = disp->Driver;
+   if (drv) {
+      drv->API.Terminate(drv, disp);
+      _eglCloseDriver(drv, disp);
+      disp->Driver = NULL;
+   }
+
+   return EGL_TRUE;
+}
+
+
+/**
+ * A bunch of check functions and declare macros to simply error checking.
+ */
+static INLINE _EGLDriver *
+_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
+{
+   if (!disp) {
+      _eglError(EGL_BAD_DISPLAY, msg);
+      return NULL;
+   }
+   if (!disp->Driver) {
+      _eglError(EGL_NOT_INITIALIZED, msg);
+      return NULL;
+   }
+   return disp->Driver;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!surf) {
+      _eglError(EGL_BAD_SURFACE, msg);
+      return NULL;
+   }
+   return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!context) {
+      _eglError(EGL_BAD_CONTEXT, msg);
+      return NULL;
+   }
+   return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!conf) {
+      _eglError(EGL_BAD_CONFIG, msg);
+      return NULL;
+   }
+   return drv;
+}
+
+
+#define _EGL_DECLARE_DD(dpy)                                   \
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
+   _EGLDriver *drv;                                            \
+   do {                                                        \
+      drv = _eglCheckDisplay(disp, __FUNCTION__);              \
+      if (!drv)                                                \
+         return EGL_FALSE;                                     \
+   } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface)              \
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
+   _EGLSurface *surf = _eglLookupSurface((surface), disp);     \
+   _EGLDriver *drv;                                            \
+   do {                                                        \
+      drv = _eglCheckSurface(disp, surf, __FUNCTION__);        \
+      if (!drv)                                                \
+         return EGL_FALSE;                                     \
+   } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx)                  \
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
+   _EGLContext *context = _eglLookupContext((ctx), disp);      \
+   _EGLDriver *drv;                                            \
+   do {                                                        \
+      drv = _eglCheckContext(disp, context, __FUNCTION__);     \
+      if (!drv)                                                \
+         return EGL_FALSE;                                     \
+   } while (0)
+
+
+#ifdef EGL_MESA_screen_surface
+
+
+static INLINE _EGLDriver *
+_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!scrn) {
+      _eglError(EGL_BAD_SCREEN_MESA, msg);
+      return NULL;
+   }
+   return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
+{
+   _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+   if (!drv)
+      return NULL;
+   if (!m) {
+      _eglError(EGL_BAD_MODE_MESA, msg);
+      return NULL;
+   }
+   return drv;
 }
 
 
+#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen)                \
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
+   _EGLScreen *scrn = _eglLookupScreen((screen), disp);        \
+   _EGLDriver *drv;                                            \
+   do {                                                        \
+      drv = _eglCheckScreen(disp, scrn, __FUNCTION__);         \
+      if (!drv)                                                \
+         return EGL_FALSE;                                     \
+   } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_MODE(dpy, mode)                    \
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);                 \
+   _EGLMode *m = _eglLookupMode((mode), disp);                 \
+   _EGLDriver *drv;                                            \
+   do {                                                        \
+      drv = _eglCheckMode(disp, m, __FUNCTION__);              \
+      if (!drv)                                                \
+         return EGL_FALSE;                                     \
+   } while (0)
+
+
+#endif /* EGL_MESA_screen_surface */
+
+
 const char * EGLAPIENTRY
 eglQueryString(EGLDisplay dpy, EGLint name)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.QueryString(drv, dpy, name);
-   else
-      return NULL;
+   _EGL_DECLARE_DD(dpy);
+   return drv->API.QueryString(drv, disp, name);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+              EGLint config_size, EGLint *num_config)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   /* XXX check drv for null in remaining functions */
-   return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
+   _EGL_DECLARE_DD(dpy);
+   return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
+                EGLint config_size, EGLint *num_config)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
+   _EGL_DECLARE_DD(dpy);
+   return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
+                                config_size, num_config);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+                   EGLint attribute, EGLint *value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_FALSE;
+
+   return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
 }
 
 
 EGLContext EGLAPIENTRY
-eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
-{
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
+eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
+                 const EGLint *attrib_list)
+{
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLContext *share = _eglLookupContext(share_list, disp);
+   _EGLDriver *drv;
+   _EGLContext *context;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_CONTEXT;
+   if (!share && share_list != EGL_NO_CONTEXT) {
+      _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+      return EGL_NO_CONTEXT;
+   }
+
+   context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
+   if (context)
+      return _eglLinkContext(context, disp);
+   else
+      return EGL_NO_CONTEXT;
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.DestroyContext(drv, dpy, ctx);
+   _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+   _eglUnlinkContext(context);
+   return drv->API.DestroyContext(drv, disp, context);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
+               EGLContext ctx)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLContext *context = _eglLookupContext(ctx, disp);
+   _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
+   _EGLSurface *read_surf = _eglLookupSurface(read, disp);
+   _EGLDriver *drv;
+
+   drv = _eglCheckDisplay(disp, __FUNCTION__);
+   if (!drv)
+      return EGL_FALSE;
+   if (!context && ctx != EGL_NO_CONTEXT)
+      return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+   if ((!draw_surf && draw != EGL_NO_SURFACE) ||
+       (!read_surf && read != EGL_NO_SURFACE))
+      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+
+   return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+                EGLint attribute, EGLint *value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
+   _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+   return drv->API.QueryContext(drv, disp, context, attribute, value);
 }
 
 
 EGLSurface EGLAPIENTRY
-eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+                       NativeWindowType window, const EGLint *attrib_list)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_SURFACE;
+
+   surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
+   if (surf)
+      return _eglLinkSurface(surf, disp);
+   else
+      return EGL_NO_SURFACE;
 }
 
 
 EGLSurface EGLAPIENTRY
-eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+                       NativePixmapType pixmap, const EGLint *attrib_list)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_SURFACE;
+
+   surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
+   if (surf)
+      return _eglLinkSurface(surf, disp);
+   else
+      return EGL_NO_SURFACE;
 }
 
 
 EGLSurface EGLAPIENTRY
-eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+                        const EGLint *attrib_list)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_SURFACE;
+
+   surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
+   if (surf)
+      return _eglLinkSurface(surf, disp);
+   else
+      return EGL_NO_SURFACE;
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.DestroySurface(drv, dpy, surface);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   _eglUnlinkSurface(surf);
+   return drv->API.DestroySurface(drv, disp, surf);
 }
 
-
 EGLBoolean EGLAPIENTRY
-eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+                EGLint attribute, EGLint *value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.QuerySurface(drv, disp, surf, attribute, value);
 }
 
-
 EGLBoolean EGLAPIENTRY
-eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+                 EGLint attribute, EGLint value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.BindTexImage(drv, dpy, surface, buffer);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.BindTexImage(drv, disp, surf, buffer);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglSwapInterval(EGLDisplay dpy, EGLint interval)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.SwapInterval(drv, dpy, interval);
+   _EGL_DECLARE_DD(dpy);
+   return drv->API.SwapInterval(drv, disp, interval);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.SwapBuffers(drv, dpy, draw);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.SwapBuffers(drv, disp, surf);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CopyBuffers(drv, dpy, surface, target);
+   _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+   return drv->API.CopyBuffers(drv, disp, surf, target);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglWaitGL(void)
 {
-   EGLDisplay dpy = eglGetCurrentDisplay();
-   if (dpy != EGL_NO_DISPLAY) {
-      _EGLDriver *drv = _eglLookupDriver(dpy);
-      return drv->API.WaitGL(drv, dpy);
-   }
-   else
-      return EGL_FALSE;
+   _EGLDisplay *disp = _eglGetCurrentDisplay();
+   _EGLDriver *drv;
+
+   if (!disp)
+      return EGL_TRUE;
+
+   /* a current display is always initialized */
+   drv = disp->Driver;
+
+   return drv->API.WaitGL(drv, disp);
 }
 
 
 EGLBoolean EGLAPIENTRY
 eglWaitNative(EGLint engine)
 {
-   EGLDisplay dpy = eglGetCurrentDisplay();
-   if (dpy != EGL_NO_DISPLAY) {
-      _EGLDriver *drv = _eglLookupDriver(dpy);
-      return drv->API.WaitNative(drv, dpy, engine);
-   }
-   else
-      return EGL_FALSE;
+   _EGLDisplay *disp = _eglGetCurrentDisplay();
+   _EGLDriver *drv;
+
+   if (!disp)
+      return EGL_TRUE;
+
+   /* a current display is always initialized */
+   drv = disp->Driver;
+
+   return drv->API.WaitNative(drv, disp, engine);
 }
 
 
@@ -420,111 +673,168 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
                   const EGLint *attrib_list, EGLModeMESA *modes,
                   EGLint modes_size, EGLint *num_modes)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
-   else
-      return EGL_FALSE;
+   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+   return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
+                                  modes, modes_size, num_modes);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
+eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
+                EGLint mode_size, EGLint *num_mode)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
-   else
-      return EGL_FALSE;
+   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+   return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
+eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
+                     EGLint attribute, EGLint *value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
-   else
-      return EGL_FALSE;
+   _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+   return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
 }
 
 
 EGLBoolean EGLAPIENTRY
-eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
-{
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
-   else
+eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
+                   EGLint mask)
+{
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLContext *source_context = _eglLookupContext(source, disp);
+   _EGLContext *dest_context = _eglLookupContext(dest, disp);
+   _EGLDriver *drv;
+
+   drv = _eglCheckContext(disp, source_context, __FUNCTION__);
+   if (!drv || !dest_context) {
+      if (drv)
+         _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
       return EGL_FALSE;
+   }
+
+   return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
+                                   mask);
 }
 
 
 EGLBoolean
-eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
+eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
+                  EGLint max_screens, EGLint *num_screens)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   if (drv)
-      return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
-   else
-      return EGL_FALSE;
+   _EGL_DECLARE_DD(dpy);
+   return drv->API.GetScreensMESA(drv, disp, screens,
+                                  max_screens, num_screens);
 }
 
 
 EGLSurface
-eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
+                           const EGLint *attrib_list)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_SURFACE;
+
+   surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
+   if (surf)
+      return _eglLinkSurface(surf, disp);
+   else
+      return EGL_NO_SURFACE;
 }
 
 
 EGLBoolean
-eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
+eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
+                         EGLSurface surface, EGLModeMESA mode)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+   _EGLSurface *surf = _eglLookupSurface(surface, disp);
+   _EGLMode *m = _eglLookupMode(mode, disp);
+   _EGLDriver *drv;
+
+   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+   if (!drv)
+      return EGL_FALSE;
+   if (!surf && surface != EGL_NO_SURFACE)
+      return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+   if (!m && mode != EGL_NO_MODE_MESA)
+      return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
+
+   return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
 }
 
 
 EGLBoolean
 eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
+   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+   return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
 }
 
 
 EGLBoolean
-eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
+eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
+                   EGLint attribute, EGLint *value)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
+   _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+   return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
 }
 
 
 EGLBoolean
-eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
+eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
+                          EGLSurface *surface)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+   if (!drv)
+      return EGL_FALSE;
+
+   if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
+      surf = NULL;
+   if (surface)
+      *surface = _eglGetSurfaceHandle(surf);
+   return (surf != NULL);
 }
 
 
 EGLBoolean
 eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+   _EGLDriver *drv;
+   _EGLMode *m;
+
+   drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+   if (!drv)
+      return EGL_FALSE;
+
+   if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
+      m = NULL;
+   if (mode)
+      *mode = m->Handle;
+
+   return (m != NULL);
 }
 
 
 const char *
 eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.QueryModeStringMESA(drv, dpy, mode);
+   _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+   return drv->API.QueryModeStringMESA(drv, disp, m);
 }
 
 
@@ -605,27 +915,37 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
                                  EGLClientBuffer buffer, EGLConfig config,
                                  const EGLint *attrib_list)
 {
-   _EGLDriver *drv = _eglLookupDriver(dpy);
-   return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
-                                                 config, attrib_list);
+   _EGLDisplay *disp = _eglLookupDisplay(dpy);
+   _EGLConfig *conf = _eglLookupConfig(config, disp);
+   _EGLDriver *drv;
+   _EGLSurface *surf;
+
+   drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+   if (!drv)
+      return EGL_NO_SURFACE;
+
+   surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
+                                                 conf, attrib_list);
+   if (surf)
+      return _eglLinkSurface(surf, disp);
+   else
+      return EGL_NO_SURFACE;
 }
 
 
 EGLBoolean
 eglReleaseThread(void)
 {
-   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);
+   /* unbind current context */
+   if (!_eglIsCurrentThreadDummy()) {
+      _EGLDisplay *disp = _eglGetCurrentDisplay();
+      _EGLDriver *drv;
+      if (disp) {
+         drv = disp->Driver;
+         (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+      }
    }
+
    _eglDestroyCurrentThread();
    return EGL_TRUE;
 }
@@ -634,13 +954,17 @@ eglReleaseThread(void)
 EGLBoolean
 eglWaitClient(void)
 {
-   EGLDisplay dpy = eglGetCurrentDisplay();
-   if (dpy != EGL_NO_DISPLAY) {
-      _EGLDriver *drv = _eglLookupDriver(dpy);
-      return drv->API.WaitClient(drv, dpy);
-   }
-   else
-      return EGL_FALSE;
+   _EGLDisplay *disp = _eglGetCurrentDisplay();
+   _EGLDriver *drv;
+
+   if (!disp)
+      return EGL_TRUE;
+
+   /* a current display is always initialized */
+   drv = disp->Driver;
+
+   return drv->API.WaitClient(drv, disp);
 }
 
+
 #endif /* EGL_VERSION_1_2 */
index f6163a0c7a8955125961293695df2c55c1bbf19b..6081e588928959ecca0f5d5a9973433763aa3b20 100644 (file)
@@ -12,61 +12,61 @@ typedef void (*_EGLProc)();
  */
 
 /* driver funcs */
-typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
-typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
+typedef EGLBoolean (*Initialize_t)(_EGLDriver *, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (*Terminate_t)(_EGLDriver *, _EGLDisplay *dpy);
 
 /* config funcs */
-typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLint attribute, EGLint *value);
 
 /* context funcs */
-typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
-typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
+typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
+typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
 
 /* surface funcs */
-typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
-typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
-typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
-typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
+typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value);
+typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
+typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
+typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target);
 
 /* misc funcs */
-typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
-typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
+typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
 
 typedef _EGLProc (*GetProcAddress_t)(const char *procname);
 
 
 
 #ifdef EGL_MESA_screen_surface
-typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
-typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef EGLSurface (*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
-typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
+typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask);
+typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
+typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y);
+typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface);
+typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode);
+typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode);
 #endif /* EGL_MESA_screen_surface */
 
 
 #ifdef EGL_VERSION_1_2
-typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLSurface (*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list);
 #endif /* EGL_VERSION_1_2 */
 
 
index bbc585b55e9ceba8701e6a582aab10be34d1196f..d47b99eed4b4b6a3947a8354c7536370564f1c06 100644 (file)
@@ -71,10 +71,9 @@ _eglGetConfigHandle(_EGLConfig *config)
  * This is the inverse of _eglGetConfigHandle().
  */
 _EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+_eglLookupConfig(EGLConfig config, _EGLDisplay *disp)
 {
    EGLint i;
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    for (i = 0; i < disp->NumConfigs; i++) {
       if (disp->Configs[i]->Handle == config) {
           return disp->Configs[i];
@@ -319,10 +318,9 @@ _eglCompareConfigs(const void *a, const void *b)
  * Typical fallback routine for eglChooseConfig
  */
 EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
                  EGLConfig *configs, EGLint config_size, EGLint *num_configs)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    _EGLConfig **configList, criteria;
    EGLint i, count;
 
@@ -367,10 +365,9 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
  * Fallback for eglGetConfigAttrib.
  */
 EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                     EGLint attribute, EGLint *value)
 {
-   const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
    const EGLint k = attribute - FIRST_ATTRIB;
    if (k >= 0 && k < MAX_ATTRIBS) {
       *value = conf->Attrib[k];
@@ -387,16 +384,9 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * Fallback for eglGetConfigs.
  */
 EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
                EGLint config_size, EGLint *num_config)
 {
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
-   if (!drv->Initialized) {
-      _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
-      return EGL_FALSE;
-   }
-
    if (configs) {
       EGLint i;
       *num_config = MIN2(disp->NumConfigs, config_size);
index db1c4c10e088210e9f9c13200625a16b7e89257c..36ed96ae9562fed6a5e268f9ba83fd141de91629 100644 (file)
@@ -34,7 +34,7 @@ _eglGetConfigHandle(_EGLConfig *config);
 
 
 extern _EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
+_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy);
 
 
 extern _EGLConfig *
@@ -46,15 +46,15 @@ _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
 
 
 extern EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
 
 
 extern EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value);
 
 
 extern EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
 
 
 extern void
index 88de60d69bb7b1fd11403b1306fe8c2686a5a70a..b094f49bfc16fcfd332db77cb99cf27dd0ee3675 100644 (file)
@@ -25,11 +25,6 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
       return EGL_FALSE;
    }
 
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "_eglInitContext");
-      return EGL_FALSE;
-   }
-
    memset(ctx, 0, sizeof(_EGLContext));
 
    ctx->ClientVersion = 1; /* the default, per EGL spec */
@@ -58,32 +53,25 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
 /**
  * Just a placeholder/demo function.  Real driver will never use this!
  */
-EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                  EGLContext share_list, const EGLint *attrib_list)
+_EGLContext *
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                  _EGLContext *share_list, const EGLint *attrib_list)
 {
 #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;
+      return NULL;
 
    if (!_eglInitContext(drv, context, conf, attrib_list)) {
       free(context);
-      return EGL_NO_CONTEXT;
+      return NULL;
    }
 
-   return _eglLinkContext(context, _eglLookupDisplay(dpy));
+   return context;
 #endif
-   return EGL_NO_CONTEXT;
+   return NULL;
 }
 
 
@@ -91,36 +79,21 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * Default fallback routine - drivers should usually override this.
  */
 EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
 {
-   _EGLContext *context = _eglLookupContext(ctx);
-   if (context) {
-      _eglUnlinkContext(context);
-      if (!_eglIsContextBound(context))
-         free(context);
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
-      return EGL_TRUE;
-   }
+   if (!_eglIsContextBound(ctx))
+      free(ctx);
+   return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
                  EGLint attribute, EGLint *value)
 {
-   _EGLContext *c = _eglLookupContext(ctx);
-
    (void) drv;
    (void) dpy;
 
-   if (!c) {
-      _eglError(EGL_BAD_CONTEXT, "eglQueryContext");
-      return EGL_FALSE;
-   }
-
    switch (attribute) {
    case EGL_CONFIG_ID:
       *value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
@@ -146,14 +119,10 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
  * Then, the driver will do its device-dependent Make-Current stuff.
  */
 EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay display, EGLSurface d,
-                EGLSurface r, EGLContext context)
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw,
+                _EGLSurface *read, _EGLContext *ctx)
 {
    _EGLThreadInfo *t = _eglGetCurrentThread();
-   _EGLDisplay *dpy = _eglLookupDisplay(display);
-   _EGLContext *ctx = _eglLookupContext(context);
-   _EGLSurface *draw = _eglLookupSurface(d);
-   _EGLSurface *read = _eglLookupSurface(r);
    _EGLContext *oldContext = NULL;
    _EGLSurface *oldDrawSurface = NULL;
    _EGLSurface *oldReadSurface = NULL;
@@ -161,18 +130,13 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay display, EGLSurface d,
 
    if (_eglIsCurrentThreadDummy())
       return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
-   if (dpy == NULL)
-      return _eglError(EGL_BAD_DISPLAY, "eglMakeCurrent");
 
    if (ctx) {
       /* error checking */
       if (ctx->Binding && ctx->Binding != t)
          return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
-      if (draw == NULL || read == NULL) {
-         EGLint err = (d == EGL_NO_SURFACE || r == EGL_NO_SURFACE)
-                      ? EGL_BAD_MATCH : EGL_BAD_SURFACE;
-         return _eglError(err, "eglMakeCurrent");
-      }
+      if (draw == NULL || read == NULL)
+         return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
       if (draw->Config != ctx->Config || read->Config != ctx->Config)
          return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
       if ((draw->Binding && draw->Binding->Binding != t) ||
@@ -197,8 +161,6 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay display, EGLSurface d,
       apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
    }
    else {
-      if (context != EGL_NO_CONTEXT)
-         return _eglError(EGL_BAD_CONTEXT, "eglMakeCurrent");
       if (draw != NULL || read != NULL)
          return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
       apiIndex = t->CurrentAPIIndex;
@@ -221,23 +183,19 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay display, EGLSurface d,
 
       /*
        * check if the old context or surfaces need to be deleted
-       * FIXME They are linked so that they can be unlinked.  This is ugly.
        */
       if (!_eglIsSurfaceLinked(oldDrawSurface)) {
          assert(draw != oldDrawSurface && read != oldDrawSurface);
-         drv->API.DestroySurface(drv, display,
-                                 _eglLinkSurface(oldDrawSurface, dpy));
+         drv->API.DestroySurface(drv, dpy, oldDrawSurface);
       }
       if (oldReadSurface != oldDrawSurface &&
           !_eglIsSurfaceLinked(oldReadSurface)) {
          assert(draw != oldReadSurface && read != oldReadSurface);
-         drv->API.DestroySurface(drv, display,
-                                 _eglLinkSurface(oldReadSurface, dpy));
+         drv->API.DestroySurface(drv, dpy, oldReadSurface);
       }
       if (!_eglIsContextLinked(oldContext)) {
          assert(ctx != oldContext);
-         drv->API.DestroyContext(drv, display,
-                                 _eglLinkContext(oldContext, dpy));
+         drv->API.DestroyContext(drv, dpy, oldContext);
       }
    }
 
index 4276c0980e297f8f7e47ca9330c8b684ebdac926..647f24488ff8d47d3767ed6c451e3074253b3a82 100644 (file)
@@ -32,20 +32,20 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
                 _EGLConfig *config, const EGLint *attrib_list);
 
 
-extern EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
+extern _EGLContext *
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
 
 
 extern EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
 
 
 extern EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
 
 
 extern EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
 
 
 extern EGLBoolean
index feae1d6040942472970af6b00993d0dae6870d61..2c271efd670674a6fc771b20cfbb9d3cf36d46c8 100644 (file)
 #include "egldisplay.h"
 #include "egldriver.h"
 #include "eglglobals.h"
-#include "eglhash.h"
 #include "eglstring.h"
 #include "eglmutex.h"
 #include "egllog.h"
 
 
-static _EGL_DECLARE_MUTEX(_eglDisplayInitMutex);
-static _EGLHashtable *_eglDisplayHash;
-/* TODO surface hash table should be per-display */
-static _EGLHashtable *_eglSurfaceHash;
-
-
 /**
  * Finish display management.
  */
-static void
+void
 _eglFiniDisplay(void)
 {
-   _eglLockMutex(&_eglDisplayInitMutex);
-   if (_eglDisplayHash) {
-      EGLuint key = _eglHashFirstEntry(_eglDisplayHash);
-
-      while (key) {
-         _EGLDisplay *dpy = (_EGLDisplay *)
-            _eglHashLookup(_eglDisplayHash, key);
-         assert(dpy);
-
-         if (dpy->ContextList || dpy->SurfaceList)
-            _eglLog(_EGL_DEBUG, "Display %u is destroyed with resources", key);
+   _EGLDisplay *dpyList, *dpy;
 
-         _eglCleanupDisplay(dpy);
-         free(dpy);
+   /* atexit function is called with global mutex locked */
+   dpyList = _eglGlobal.DisplayList;
+   while (dpyList) {
+      /* pop list head */
+      dpy = dpyList;
+      dpyList = dpyList->Next;
 
-         key = _eglHashNextEntry(_eglDisplayHash, key);
-      }
+      if (dpy->ContextList || dpy->SurfaceList)
+         _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy);
 
-      _eglDeleteHashTable(_eglDisplayHash);
-      _eglDisplayHash = NULL;
-      _eglDeleteHashTable(_eglSurfaceHash);
-      _eglSurfaceHash = NULL;
+      free(dpy);
    }
-   _eglUnlockMutex(&_eglDisplayInitMutex);
+   _eglGlobal.DisplayList = NULL;
 }
 
 
-/* This can be avoided if hash table can be statically initialized */
-static INLINE void
-_eglInitDisplay(void)
+/**
+ * If the first character is '!' we interpret it as specific driver name
+ * (i.e. "!r200" or "!i830").  Whatever follows ':' is interpreted as
+ * arguments.
+ *
+ * The caller may free() the returned driver name.
+ */
+char *
+_eglSplitDisplayString(const char *dpyString, const char **args)
 {
-   if (!_eglDisplayHash) {
-      _eglLockMutex(&_eglDisplayInitMutex);
-
-      /* check again after acquiring lock */
-      if (!_eglDisplayHash) {
-         _eglDisplayHash = _eglNewHashTable();
-         _eglSurfaceHash = _eglNewHashTable();
-
-         _eglAddAtExitCall(_eglFiniDisplay);
-      }
-
-      _eglUnlockMutex(&_eglDisplayInitMutex);
+   char *drv, *p;
+
+   if (!dpyString || dpyString[0] != '!')
+      return NULL;
+   drv = _eglstrdup(dpyString + 1);
+   if (!drv)
+      return NULL;
+
+   p = strchr(dpyString, ':');
+   if (p) {
+      drv[p - dpyString] = '\0';
+      p++;
    }
+   if (args)
+      *args = p;
+
+   return drv;
 }
 
 
@@ -91,10 +85,7 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
       dpy->Xdpy = (Display *) nativeDisplay;
 #endif
 
-      _eglInitDisplay();
-      dpy->SurfaceHash = _eglSurfaceHash;
-
-      dpy->DriverName = _eglChooseDriver(dpy);
+      dpy->DriverName = _eglPreloadDriver(dpy);
       if (!dpy->DriverName) {
          free(dpy);
          return NULL;
@@ -111,17 +102,14 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
 EGLDisplay
 _eglLinkDisplay(_EGLDisplay *dpy)
 {
-   EGLuint key;
+   _eglLockMutex(_eglGlobal.Mutex);
 
-   _eglInitDisplay();
+   dpy->Next = _eglGlobal.DisplayList;
+   _eglGlobal.DisplayList = dpy;
 
-   key = _eglHashGenKey(_eglDisplayHash);
-   assert(key);
-   /* "link" the display to the hash table */
-   _eglHashInsert(_eglDisplayHash, key, dpy);
-   dpy->Handle = (EGLDisplay) _eglUIntToPointer(key);
+   _eglUnlockMutex(_eglGlobal.Mutex);
 
-   return dpy->Handle;
+   return (EGLDisplay) dpy;
 }
 
 
@@ -132,40 +120,25 @@ _eglLinkDisplay(_EGLDisplay *dpy)
 void
 _eglUnlinkDisplay(_EGLDisplay *dpy)
 {
-   EGLuint key = _eglPointerToUInt((void *) dpy->Handle);
-
-   _eglInitDisplay();
-
-   _eglHashRemove(_eglDisplayHash, key);
-   dpy->Handle = EGL_NO_DISPLAY;
-}
-
-
-/**
- * Return the handle of a linked display, or EGL_NO_DISPLAY.
- */
-EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display)
-{
-   if (display)
-      return display->Handle;
-   else
-      return EGL_NO_DISPLAY;
-}
-
+   _EGLDisplay *prev;
 
-/**
- * Lookup a handle to find the linked display.
- * Return NULL if the handle has no corresponding linked display.
- */
-_EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy)
-{
-   EGLuint key = _eglPointerToUInt((void *) dpy);
+   _eglLockMutex(_eglGlobal.Mutex);
 
-   _eglInitDisplay();
+   prev = _eglGlobal.DisplayList;
+   if (prev != dpy) {
+      while (prev) {
+         if (prev->Next == dpy)
+            break;
+         prev = prev->Next;
+      }
+      assert(prev);
+      prev->Next = dpy->Next;
+   }
+   else {
+      _eglGlobal.DisplayList = dpy->Next;
+   }
 
-   return (_EGLDisplay *) _eglHashLookup(_eglDisplayHash, key);
+   _eglUnlockMutex(_eglGlobal.Mutex);
 }
 
 
@@ -176,22 +149,21 @@ _eglLookupDisplay(EGLDisplay dpy)
 _EGLDisplay *
 _eglFindDisplay(NativeDisplayType nativeDisplay)
 {
-   EGLuint key;
-
-   _eglInitDisplay();
+   _EGLDisplay *dpy;
 
-   /* Walk the hash table.  Should switch to list if it is a problem. */
-   key = _eglHashFirstEntry(_eglDisplayHash);
-   while (key) {
-      _EGLDisplay *dpy = (_EGLDisplay *)
-            _eglHashLookup(_eglDisplayHash, key);
-      assert(dpy);
+   _eglLockMutex(_eglGlobal.Mutex);
 
-      if (dpy->NativeDisplay == nativeDisplay)
+   dpy = _eglGlobal.DisplayList;
+   while (dpy) {
+      if (dpy->NativeDisplay == nativeDisplay) {
+         _eglUnlockMutex(_eglGlobal.Mutex);
          return dpy;
-      key = _eglHashNextEntry(_eglDisplayHash, key);
+      }
+      dpy = dpy->Next;
    }
 
+   _eglUnlockMutex(_eglGlobal.Mutex);
+
    return NULL;
 }
 
@@ -200,29 +172,29 @@ _eglFindDisplay(NativeDisplayType nativeDisplay)
  * Destroy the contexts and surfaces that are linked to the display.
  */
 void
-_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy)
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
 {
-   _EGLDisplay *display;
    _EGLContext *contexts;
    _EGLSurface *surfaces;
 
-   display = _eglLookupDisplay(dpy);
-   if (!display)
-      return;
    contexts = display->ContextList;
    surfaces = display->SurfaceList;
 
    while (contexts) {
-      EGLContext handle = _eglGetContextHandle(contexts);
+      _EGLContext *ctx = contexts;
       contexts = contexts->Next;
-      drv->API.DestroyContext(drv, dpy, handle);
+
+      _eglUnlinkContext(ctx);
+      drv->API.DestroyContext(drv, display, ctx);
    }
    assert(!display->ContextList);
 
    while (surfaces) {
-      EGLSurface handle = _eglGetSurfaceHandle(surfaces);
+      _EGLSurface *surf = surfaces;
       surfaces = surfaces->Next;
-      drv->API.DestroySurface(drv, dpy, handle);
+
+      _eglUnlinkSurface(surf);
+      drv->API.DestroySurface(drv, display, surf);
    }
    assert(!display->SurfaceList);
 }
@@ -237,18 +209,15 @@ _eglCleanupDisplay(_EGLDisplay *disp)
 {
    EGLint i;
 
-   for (i = 0; i < disp->NumConfigs; i++) {
-      free(disp->Configs[i]);
+   if (disp->Configs) {
+      for (i = 0; i < disp->NumConfigs; i++)
+         free(disp->Configs[i]);
+      free(disp->Configs);
+      disp->Configs = NULL;
+      disp->NumConfigs = 0;
    }
-   free(disp->Configs);
-   disp->Configs = NULL;
 
    /* XXX incomplete */
-
-   free((void *) disp->DriverName);
-   disp->DriverName = NULL;
-
-   /* driver deletes the _EGLDisplay object */
 }
 
 
@@ -294,28 +263,6 @@ _eglUnlinkContext(_EGLContext *ctx)
 }
 
 
-/**
- * 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.
@@ -323,18 +270,10 @@ _eglLookupContext(EGLContext ctx)
 EGLSurface
 _eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
 {
-   EGLuint key;
-
    surf->Display = dpy;
    surf->Next = dpy->SurfaceList;
    dpy->SurfaceList = surf;
-
-   key = _eglHashGenKey(dpy->SurfaceHash);
-   assert(key);
-   _eglHashInsert(dpy->SurfaceHash, key, surf);
-
-   surf->Handle = (EGLSurface) _eglUIntToPointer(key);
-   return surf->Handle;
+   return (EGLSurface) surf;
 }
 
 
@@ -346,10 +285,6 @@ void
 _eglUnlinkSurface(_EGLSurface *surf)
 {
    _EGLSurface *prev;
-   EGLuint key = _eglPointerToUInt((void *) surf->Handle);
-
-   _eglHashRemove(surf->Display->SurfaceHash, key);
-   surf->Handle = EGL_NO_SURFACE;
 
    prev = surf->Display->SurfaceList;
    if (prev != surf) {
@@ -371,26 +306,69 @@ _eglUnlinkSurface(_EGLSurface *surf)
 }
 
 
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
 /**
- * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ * Return EGL_TRUE if the given handle is a valid handle to a display.
  */
-EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *surface)
+EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
 {
-   if (surface)
-      return surface->Handle;
-   else
-      return EGL_NO_SURFACE;
+   _EGLDisplay *cur;
+
+   _eglLockMutex(_eglGlobal.Mutex);
+   cur = _eglGlobal.DisplayList;
+   while (cur) {
+      if (cur == (_EGLDisplay *) dpy)
+         break;
+      cur = cur->Next;
+   }
+   _eglUnlockMutex(_eglGlobal.Mutex);
+   return (cur != NULL);
 }
 
 
 /**
- * Lookup a handle to find the linked surface.
- * Return NULL if the handle has no corresponding linked surface.
+ * Return EGL_TRUE if the given handle is a valid handle to a context.
  */
-_EGLSurface *
-_eglLookupSurface(EGLSurface surf)
+EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
 {
-   EGLuint key = _eglPointerToUInt((void *) surf);
-   return (_EGLSurface *) _eglHashLookup(_eglSurfaceHash, key);
+   _EGLContext *cur = NULL;
+
+   if (dpy)
+      cur = dpy->ContextList;
+   while (cur) {
+      if (cur == (_EGLContext *) ctx) {
+         assert(cur->Display == dpy);
+         break;
+      }
+      cur = cur->Next;
+   }
+   return (cur != NULL);
 }
+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a surface.
+ */
+EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
+{
+   _EGLSurface *cur = NULL;
+
+   if (dpy)
+      cur = dpy->SurfaceList;
+   while (cur) {
+      if (cur == (_EGLSurface *) surf) {
+         assert(cur->Display == dpy);
+         break;
+      }
+      cur = cur->Next;
+   }
+   return (cur != NULL);
+}
+
+
+#endif /* !_EGL_SKIP_HANDLE_CHECK */
index 70c59ef5e46807bfe762d0c01f8d013d85c8df37..c7a41cd588358c266f42ee332639dc50e25ef1bb 100644 (file)
@@ -6,17 +6,44 @@
 #endif
 
 #include "egltypedefs.h"
-#include "eglhash.h"
+#include "egldefines.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+
+
+/**
+ * Optional EGL extensions info.
+ */
+struct _egl_extensions
+{
+   EGLBoolean MESA_screen_surface;
+   EGLBoolean MESA_copy_context;
+
+   char String[_EGL_MAX_EXTENSIONS_LEN];
+};
 
 
 struct _egl_display 
 {
+   /* used to link displays */
+   _EGLDisplay *Next;
+
    EGLNativeDisplayType NativeDisplay;
-   EGLDisplay Handle;
 
    const char *DriverName;
-   const char *DriverArgs;
    _EGLDriver *Driver;
+   void *DriverData; /* private to driver */
+
+   int APImajor, APIminor; /**< as returned by eglInitialize() */
+   char Version[1000];     /**< initialized from APImajor/minor, DriverName */
+
+   /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
+   EGLint ClientAPIsMask;
+   char ClientAPIs[1000];   /**< updated by eglQueryString */
+
+   _EGLExtensions Extensions;
+
+   int LargestPbuffer;
 
    EGLint NumScreens;
    _EGLScreen **Screens;  /* array [NumScreens] */
@@ -28,15 +55,20 @@ struct _egl_display
    _EGLContext *ContextList;
    _EGLSurface *SurfaceList;
 
-   /* hash table to map surfaces to handles */
-   _EGLHashtable *SurfaceHash;
-
 #ifdef _EGL_PLATFORM_X
    Display *Xdpy;
 #endif
 };
 
 
+extern void
+_eglFiniDisplay(void);
+
+
+extern char *
+_eglSplitDisplayString(const char *dpyString, const char **args);
+
+
 extern _EGLDisplay *
 _eglNewDisplay(NativeDisplayType displayName);
 
@@ -49,30 +81,12 @@ extern void
 _eglUnlinkDisplay(_EGLDisplay *dpy);
 
 
-extern EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display);
-
-
-extern _EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy);
-
-
-/**
- * Return true if the display is linked.
- */
-static INLINE EGLBoolean
-_eglIsDisplayLinked(_EGLDisplay *dpy)
-{
-   return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
-}
-
-
 extern _EGLDisplay *
 _eglFindDisplay(NativeDisplayType nativeDisplay);
 
 
 extern void
-_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy);
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy);
 
 
 extern void
@@ -87,37 +101,149 @@ extern void
 _eglUnlinkContext(_EGLContext *ctx);
 
 
-extern EGLContext
-_eglGetContextHandle(_EGLContext *ctx);
+extern EGLSurface
+_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkSurface(_EGLSurface *surf);
+
+
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
+extern EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy);
+
+
+extern EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy);
+
+
+extern EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy);
+
+
+#else /* !_EGL_SKIP_HANDLE_CHECK */
+
+/* Only do a quick check.  This is NOT standard compliant. */
+
+static INLINE EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+   return ((_EGLDisplay *) dpy != NULL);
+}
+
+
+static INLINE EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
+{
+   _EGLContext *c = (_EGLContext *) ctx;
+   return (dpy && c && c->Display == dpy);
+}
+
+
+static INLINE EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
+{
+   _EGLSurface *s = (_EGLSurface *) surf;
+   return (dpy && s && s->Display == dpy);
+}
 
 
-extern _EGLContext *
-_eglLookupContext(EGLContext ctx);
+#endif /* _EGL_SKIP_HANDLE_CHECK */
 
 
 /**
- * Return true if the context is linked to a display.
+ * Lookup a handle to find the linked display.
+ * Return NULL if the handle has no corresponding linked display.
+ */
+static INLINE _EGLDisplay *
+_eglLookupDisplay(EGLDisplay display)
+{
+   _EGLDisplay *dpy = (_EGLDisplay *) display;
+   if (!_eglCheckDisplayHandle(display))
+      dpy = NULL;
+   return dpy;
+}
+
+
+/**
+ * Return the handle of a linked display, or EGL_NO_DISPLAY.
+ */
+static INLINE EGLDisplay
+_eglGetDisplayHandle(_EGLDisplay *dpy)
+{
+   return (EGLDisplay) ((dpy) ? dpy : EGL_NO_DISPLAY);
+}
+
+
+/**
+ * Return true if the display is linked.
  */
 static INLINE EGLBoolean
-_eglIsContextLinked(_EGLContext *ctx)
+_eglIsDisplayLinked(_EGLDisplay *dpy)
 {
-   return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+   return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
 }
 
-extern EGLSurface
-_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+/**
+ * Lookup a handle to find the linked context.
+ * Return NULL if the handle has no corresponding linked context.
+ */
+static INLINE _EGLContext *
+_eglLookupContext(EGLContext context, _EGLDisplay *dpy)
+{
+   _EGLContext *ctx = (_EGLContext *) context;
+   if (!_eglCheckContextHandle(context, dpy))
+      ctx = NULL;
+   return ctx;
+}
 
 
-extern void
-_eglUnlinkSurface(_EGLSurface *surf);
+/**
+ * Return the handle of a linked context, or EGL_NO_CONTEXT.
+ */
+static INLINE EGLContext
+_eglGetContextHandle(_EGLContext *ctx)
+{
+   return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT);
+}
 
 
-extern EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *);
+/**
+ * Return true if the context is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsContextLinked(_EGLContext *ctx)
+{
+   return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+}
+
+
+/**
+ * Lookup a handle to find the linked surface.
+ * Return NULL if the handle has no corresponding linked surface.
+ */
+static INLINE _EGLSurface *
+_eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy)
+{
+   _EGLSurface *surf = (_EGLSurface *) surface;
+   if (!_eglCheckSurfaceHandle(surf, dpy))
+      surf = NULL;
+   return surf;
+}
 
 
-extern _EGLSurface *
-_eglLookupSurface(EGLSurface surf);
+/**
+ * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ */
+static INLINE EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surf)
+{
+   return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE);
+}
 
 
 /**
index f2a864cd8a705f50ce45178a99636495c771a310..87786e36bbf06ea82156607fe3fd73ea619c1645 100644 (file)
@@ -22,7 +22,6 @@
 
 #if defined(_EGL_PLATFORM_X)
 #include <dlfcn.h>
-#include "eglx.h"
 #elif defined(_EGL_PLATFORM_WINDOWS)
 /* Use static linking on Windows for now */
 #define WINDOWS_STATIC_LINK
@@ -38,7 +37,6 @@
    /* XXX Need to decide how to do dynamic name lookup on Windows */
    static const char *DefaultDriverName = "TBD";
 #endif
-   static const char *SysFS = NULL;
    typedef HMODULE lib_handle;
 
    static HMODULE
@@ -61,8 +59,7 @@
    }
 
 #elif defined(_EGL_PLATFORM_X)
-   static const char *DefaultDriverName = ":0";
-   static const char *SysFS = "/sys/class";
+   static const char *DefaultDriverName = "egl_softpipe";
 
    typedef void * lib_handle;
 
    
 #endif
 
-/**
- * Given a card number, use sysfs to determine the DRI driver name.
- */
-const char *
-_eglChooseDRMDriver(int card)
-{
-#if 0
-   return _eglstrdup("libEGLdri");
-#else
-   char path[2000], driverName[2000];
-   FILE *f;
-   int length;
-
-   snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
-
-   f = fopen(path, "r");
-   if (!f)
-      return NULL;
-
-   fgets(driverName, sizeof(driverName), f);
-   fclose(f);
-
-   if ((length = strlen(driverName)) > 1) {
-      /* remove the trailing newline from sysfs */
-      driverName[length - 1] = '\0';
-      strncat(driverName, "_dri", sizeof(driverName));
-      return _eglstrdup(driverName);
-   }
-   else {
-      return NULL;
-   }   
-#endif
-}
 
 /**
- * XXX this function is totally subject change!!!
- *
- *
- * Determine/return the name of the driver to use for the given _EGLDisplay.
- *
- * Try to be clever and determine if nativeDisplay is an Xlib Display
- * ptr or a string (naming a driver or screen number, etc).
- *
- * If the first character is ':' we interpret it as a screen or card index
- * number (i.e. ":0" or ":1", etc)
- * Else if the first character is '!' we interpret it as specific driver name
- * (i.e. "!r200" or "!i830".
- *
- * Whatever follows ':' is copied and put into dpy->DriverArgs.
- *
- * The caller may free() the returned string.
+ * Choose a driver for a given display.
+ * The caller may free() the returned strings.
  */
-const char *
-_eglChooseDriver(_EGLDisplay *dpy)
+static char *
+_eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
 {
-   /* Under Windows, the NativeDisplay is an HDC handle, therefore */
-   /* it can't be interpreted as a string or a pointer. */
-#if defined(_EGL_PLATFORM_WINDOWS)
-   const char *displayString = NULL;
-#else
-   const char *displayString = (const char *) dpy->NativeDisplay;
-#endif
-   const char *driverName = NULL;
+   char *path = NULL;
+   const char *args = NULL;
+   const char *suffix = NULL;
+   const char *p;
 
-   (void) DefaultDriverName;
+   path = getenv("EGL_DRIVER");
+   if (path)
+      path = _eglstrdup(path);
 
 #if defined(_EGL_PLATFORM_X)
-   /* First, if the EGL_DRIVER env var is set, use that */
-   driverName = getenv("EGL_DRIVER");
-   if (driverName)
-      return _eglstrdup(driverName);
-#endif
-
-#if 0
-   if (!displayString) {
-      /* choose a default */
-      displayString = DefaultDriverName;
-   }
-#endif
-   /* extract default DriverArgs = whatever follows ':' */
-   if (displayString &&
-       (displayString[0] == '!' ||
-        displayString[0] == ':')) {
-      const char *args = strchr(displayString, ':');
-      if (args)
-         dpy->DriverArgs = _eglstrdup(args + 1);
+   if (!path && dpy->NativeDisplay) {
+      /* assume (wrongly!) that the native display is a display string */
+      path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
    }
-
-   /* determine driver name now */
-   if (displayString && displayString[0] == ':' &&
-       (displayString[1] >= '0' && displayString[1] <= '9') &&
-       !displayString[2]) {
-      int card = atoi(displayString + 1);
-      driverName = _eglChooseDRMDriver(card);
-   }
-   else if (displayString && displayString[0] == '!') {
-      /* use user-specified driver name */
-      driverName = _eglstrdup(displayString + 1);
-      /* truncate driverName at ':' if present */
-      {
-         char *args = strchr(driverName, ':');
-         if (args) {
-            *args = 0;
-         }
+   suffix = "so";
+#elif defined(_EGL_PLATFORM_WINDOWS)
+   suffix = "dll";
+#endif /* _EGL_PLATFORM_X */
+
+   if (!path)
+      path = _eglstrdup(DefaultDriverName);
+
+   /* append suffix if there isn't */
+   p = strrchr(path, '.');
+   if (!p && suffix) {
+      size_t len = strlen(path);
+      char *tmp = malloc(len + strlen(suffix) + 2);
+      if (tmp) {
+         memcpy(tmp, path, len);
+         tmp[len++] = '.';
+         tmp[len] = '\0';
+         strcat(tmp + len, suffix);
+
+         free(path);
+         path = tmp;
       }
    }
-   else 
-   {
-      /* NativeDisplay is not a string! */
-#if defined(_EGL_PLATFORM_X)
-      driverName = _xeglChooseDriver(dpy);
-#else
-      driverName = DefaultDriverName;
-#endif
-   }
 
-   return driverName;
+   if (argsRet)
+      *argsRet = (args) ? _eglstrdup(args) : NULL;
+
+   return path;
 }
 
 
 /**
- * Open/load the named driver and call its bootstrap function: _eglMain().
- * By the time this function is called, the dpy->DriverName should have
- * been determined.
- *
- * \return  new _EGLDriver object.
+ * Open the named driver and find its bootstrap function: _eglMain().
  */
-_EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
+static _EGLMain_t
+_eglOpenLibrary(const char *driverPath, lib_handle *handle)
 {
-   _EGLDriver *drv;
    _EGLMain_t mainFunc;
    lib_handle lib;
-   char driverFilename[1000];
 
-   assert(driverName);
+   assert(driverPath);
 
 #if defined(_EGL_PLATFORM_WINDOWS)
 /* Use static linking on Windows for now */
@@ -224,83 +148,190 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
    mainFunc = (_EGLMain_t)_eglMain;
 #else
    /* XXX untested */
-   sprintf(driverFilename, "%s.dll", driverName);
-   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
-   lib = open_library(driverFilename);
+   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+   lib = open_library(driverPath);
    if (!lib) {
       _eglLog(_EGL_WARNING, "Could not open %s",
-              driverFilename);
+              driverPath);
       return NULL;
    }
    mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
 #endif
 #elif defined(_EGL_PLATFORM_X)
-   /* XXX also prepend a directory path??? */
-   sprintf(driverFilename, "%s.so", driverName);
-   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
-   lib = open_library(driverFilename);
+   _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+   lib = open_library(driverPath);
    if (!lib) {
       _eglLog(_EGL_WARNING, "Could not open %s (%s)",
-              driverFilename, dlerror());
+              driverPath, dlerror());
+      if (!getenv("EGL_DRIVER"))
+         _eglLog(_EGL_WARNING,
+                 "The driver can be overridden by setting EGL_DRIVER");
       return NULL;
    }
    mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
 #endif
 
    if (!mainFunc) {
-      _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
-      close_library(lib);
+      _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
+      if (lib)
+         close_library(lib);
       return NULL;
    }
 
-   drv = mainFunc(dpy, args);
+   *handle = lib;
+   return mainFunc;
+}
+
+
+/**
+ * Load the named driver.  The path and args passed will be
+ * owned by the driver and freed.
+ */
+static _EGLDriver *
+_eglLoadDriver(char *path, char *args)
+{
+   _EGLMain_t mainFunc;
+   lib_handle lib;
+   _EGLDriver *drv = NULL;
+
+   mainFunc = _eglOpenLibrary(path, &lib);
+   if (!mainFunc)
+      return NULL;
+
+   drv = mainFunc(args);
    if (!drv) {
-      close_library(lib);
+      if (lib)
+         close_library(lib);
       return NULL;
    }
 
-   /* with a recurvise open you want the inner most handle */
-   if (!drv->LibHandle) {
-      drv->LibHandle = lib;
-   }
-   else {
-      close_library(lib);
+   if (!drv->Name) {
+      _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
+      drv->Name = "UNNAMED";
    }
 
-   /* update the global notion of supported APIs */
-   _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
-
-   _eglSaveDriver(drv);
+   drv->Path = path;
+   drv->Args = args;
+   drv->LibHandle = lib;
 
    return drv;
 }
 
 
-EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
+/**
+ * Match a display to a preloaded driver.
+ */
+static _EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy)
+{
+   _EGLDriver *defaultDriver = NULL;
+   EGLint i;
+
+   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+      _EGLDriver *drv = _eglGlobal.Drivers[i];
+
+      /* display specifies a driver */
+      if (dpy->DriverName) {
+         if (strcmp(dpy->DriverName, drv->Name) == 0)
+            return drv;
+      }
+      else if (drv->Probe) {
+         if (drv->Probe(drv, dpy))
+            return drv;
+      }
+      else {
+         if (!defaultDriver)
+            defaultDriver = drv;
+      }
+   }
+
+   return defaultDriver;
+}
+
+
+/**
+ * Load a driver and save it.
+ */
+const char *
+_eglPreloadDriver(_EGLDisplay *dpy)
 {
-   void *handle = drv->LibHandle;
-   EGLBoolean b;
+   char *path, *args;
+   _EGLDriver *drv;
+   EGLint i;
+
+   path = _eglChooseDriver(dpy, &args);
+   if (!path)
+      return NULL;
 
-   _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
+   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+      drv = _eglGlobal.Drivers[i];
+      if (strcmp(drv->Path, path) == 0) {
+         _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
+                 drv->Name);
+         free(path);
+         if (args)
+            free(args);
+         return drv->Name;
+      }
+   }
 
-   _eglReleaseDisplayResources(drv, dpy);
+   drv = _eglLoadDriver(path, args);
+   if (!drv)
+      return NULL;
 
-   b = drv->API.Terminate(drv, dpy);
+   _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+
+   return drv->Name;
+}
+
+
+/**
+ * Open a preloaded driver.
+ */
+_EGLDriver *
+_eglOpenDriver(_EGLDisplay *dpy)
+{
+   _EGLDriver *drv = _eglMatchDriver(dpy);
+   return drv;
+}
 
-   close_library(handle);
 
-   return b;
+/**
+ * Close a preloaded driver.
+ */
+EGLBoolean
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+   return EGL_TRUE;
 }
 
 
 /**
- * Save the given driver pointer in the list of all known drivers.
+ * Unload preloaded drivers.
  */
 void
-_eglSaveDriver(_EGLDriver *drv)
+_eglUnloadDrivers(void)
 {
-   _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
+   EGLint i;
+   for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+      _EGLDriver *drv = _eglGlobal.Drivers[i];
+      lib_handle handle = drv->LibHandle;
+
+      if (drv->Path)
+         free((char *) drv->Path);
+      if (drv->Args)
+         free((char *) drv->Args);
+
+      /* destroy driver */
+      if (drv->Unload)
+         drv->Unload(drv);
+
+      if (handle)
+         close_library(handle);
+      _eglGlobal.Drivers[i] = NULL;
+   }
+
+   _eglGlobal.NumDrivers = 0;
 }
 
 
index 4066c6ec1df9b9c3ab134a7ce78763b7423b7d88..6c848eb35eab5f2fe72d7bd08c936ff5c68c8861 100644 (file)
@@ -4,19 +4,6 @@
 
 #include "egltypedefs.h"
 #include "eglapi.h"
-#include "egldefines.h"
-
-
-/**
- * Optional EGL extensions info.
- */
-struct _egl_extensions
-{
-   EGLBoolean MESA_screen_surface;
-   EGLBoolean MESA_copy_context;
-
-   char String[_EGL_MAX_EXTENSIONS_LEN];
-};
 
 
 /**
@@ -24,46 +11,37 @@ struct _egl_extensions
  */
 struct _egl_driver
 {
-   EGLBoolean Initialized; /**< set by driver after initialized */
-
    void *LibHandle; /**< dlopen handle */
+   const char *Path;  /**< path to this driver */
+   const char *Args;  /**< args to load this driver */
 
    const char *Name;  /**< name of this driver */
-
-   int APImajor, APIminor; /**< as returned by eglInitialize() */
-   char Version[1000];       /**< initialized from APImajor/minor, Name */
-
-   /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
-   EGLint ClientAPIsMask;
+   /**< probe a display to see if it is supported */
+   EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
+   /**< called before dlclose to release this driver */
+   void (*Unload)(_EGLDriver *drv);
 
    _EGLAPI API;  /**< EGL API dispatch table */
-
-   _EGLExtensions Extensions;
-
-   int LargestPbuffer;
 };
 
 
-extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
+extern _EGLDriver *_eglMain(const char *args);
 
 
 extern const char *
-_eglChooseDRMDriver(int card);
-
-extern const char *
-_eglChooseDriver(_EGLDisplay *dpy);
+_eglPreloadDriver(_EGLDisplay *dpy);
 
 
 extern _EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args);
+_eglOpenDriver(_EGLDisplay *dpy);
 
 
 extern EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy);
 
 
-extern void
-_eglSaveDriver(_EGLDriver *drv);
+void
+_eglUnloadDrivers(void);
 
 
 extern _EGLDriver *
index e93b48e03b80bb58e8c368babc040594bbf4af2d..3ae4c1ad3a3223a5814ab2f2a77159359319166e 100644 (file)
@@ -1,7 +1,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include "eglglobals.h"
-#include "egldisplay.h"
+#include "egldriver.h"
 #include "egllog.h"
 #include "eglmutex.h"
 
@@ -13,13 +13,16 @@ static _EGL_DECLARE_MUTEX(_eglGlobalMutex);
 struct _egl_global _eglGlobal =
 {
    &_eglGlobalMutex,       /* Mutex */
+   NULL,                   /* DisplayList */
    1,                      /* FreeScreenHandle */
    0x0,                    /* ClientAPIsMask */
-   { 0x0 },                /* ClientAPIs */
    0,                      /* NumDrivers */
    { NULL },               /* Drivers */
-   0,                      /* NumAtExitCalls */
-   { NULL },               /* AtExitCalls */
+   2,                      /* NumAtExitCalls */
+   {                       /* AtExitCalls */
+      _eglFiniDisplay,
+      _eglUnloadDrivers
+   },
 };
 
 
index 1e2c67426306dc8eee2960c9f275e5d3e549d107..58511076d452b1315eaa3dde873536d492523af6 100644 (file)
@@ -2,7 +2,7 @@
 #define EGLGLOBALS_INCLUDED
 
 #include "egltypedefs.h"
-#include "eglhash.h"
+#include "egldisplay.h"
 #include "eglcurrent.h"
 #include "eglmutex.h"
 
 struct _egl_global
 {
    _EGLMutex *Mutex;
+
+   /* the list of all displays */
+   _EGLDisplay *DisplayList;
+
    EGLScreenMESA FreeScreenHandle;
 
    /* bitmaks of supported APIs (supported by _some_ driver) */
    EGLint ClientAPIsMask;
 
-   char ClientAPIs[1000];   /**< updated by eglQueryString */
-
    EGLint NumDrivers;
    _EGLDriver *Drivers[10];
 
diff --git a/src/egl/main/eglhash.c b/src/egl/main/eglhash.c
deleted file mode 100644 (file)
index 8e3da2e..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/**
- * \file hash.c
- * Generic hash table. 
- *
- * This code taken from Mesa and adapted.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "eglhash.h"
-
-
-#define TABLE_SIZE 1023  /**< Size of lookup table/array */
-
-#define HASH_FUNC(K)  ((K) % TABLE_SIZE)
-
-
-/*
- * Unfinished mutex stuff
- */
-
-typedef int _EGLMutex;
-
-static void
-_eglInitMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglDestroyMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglLockMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglUnlockMutex(_EGLMutex m)
-{
-}
-
-
-
-typedef struct _egl_hashentry _EGLHashentry;
-
-struct _egl_hashentry
-{
-   EGLuint Key;            /**< the entry's key */
-   void *Data;             /**< the entry's data */
-   _EGLHashentry *Next;    /**< pointer to next entry */
-};
-
-
-struct _egl_hashtable
-{
-   _EGLHashentry *Table[TABLE_SIZE];  /**< the lookup table */
-   EGLuint MaxKey;                    /**< highest key inserted so far */
-   _EGLMutex Mutex;                   /**< mutual exclusion lock */
-};
-
-
-/**
- * Create a new hash table.
- * 
- * \return pointer to a new, empty hash table.
- */
-_EGLHashtable *
-_eglNewHashTable(void)
-{
-   _EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable));
-   if (table) {
-      _eglInitMutex(table->Mutex);
-      table->MaxKey = 1;
-   }
-   return table;
-}
-
-
-
-/**
- * Delete a hash table.
- * Frees each entry on the hash table and then the hash table structure itself.
- * Note that the caller should have already traversed the table and deleted
- * the objects in the table (i.e. We don't free the entries' data pointer).
- *
- * \param table the hash table to delete.
- */
-void
-_eglDeleteHashTable(_EGLHashtable *table)
-{
-   EGLuint i;
-   assert(table);
-   for (i = 0; i < TABLE_SIZE; i++) {
-      _EGLHashentry *entry = table->Table[i];
-      while (entry) {
-        _EGLHashentry *next = entry->Next;
-        free(entry);
-        entry = next;
-      }
-   }
-   _eglDestroyMutex(table->Mutex);
-   free(table);
-}
-
-
-
-/**
- * Lookup an entry in the hash table.
- * 
- * \param table the hash table.
- * \param key the key.
- * 
- * \return pointer to user's data or NULL if key not in table
- */
-void *
-_eglHashLookup(const _EGLHashtable *table, EGLuint key)
-{
-   EGLuint pos;
-   const _EGLHashentry *entry;
-
-   assert(table);
-
-   if (!key)
-      return NULL;
-
-   pos = HASH_FUNC(key);
-   entry = table->Table[pos];
-   while (entry) {
-      if (entry->Key == key) {
-        return entry->Data;
-      }
-      entry = entry->Next;
-   }
-   return NULL;
-}
-
-
-
-/**
- * Insert a key/pointer pair into the hash table.  
- * If an entry with this key already exists we'll replace the existing entry.
- * 
- * \param table the hash table.
- * \param key the key (not zero).
- * \param data pointer to user data.
- */
-void
-_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data)
-{
-   /* search for existing entry with this key */
-   EGLuint pos;
-   _EGLHashentry *entry;
-
-   assert(table);
-   assert(key);
-
-   _eglLockMutex(table->Mutex);
-
-   if (key > table->MaxKey)
-      table->MaxKey = key;
-
-   pos = HASH_FUNC(key);
-   entry = table->Table[pos];
-   while (entry) {
-      if (entry->Key == key) {
-         /* replace entry's data */
-        entry->Data = data;
-         _eglUnlockMutex(table->Mutex);
-        return;
-      }
-      entry = entry->Next;
-   }
-
-   /* alloc and insert new table entry */
-   entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry));
-   entry->Key = key;
-   entry->Data = data;
-   entry->Next = table->Table[pos];
-   table->Table[pos] = entry;
-
-   _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Remove an entry from the hash table.
- * 
- * \param table the hash table.
- * \param key key of entry to remove.
- *
- * While holding the hash table's lock, searches the entry with the matching
- * key and unlinks it.
- */
-void
-_eglHashRemove(_EGLHashtable *table, EGLuint key)
-{
-   EGLuint pos;
-   _EGLHashentry *entry, *prev;
-
-   assert(table);
-   assert(key);
-
-   _eglLockMutex(table->Mutex);
-
-   pos = HASH_FUNC(key);
-   prev = NULL;
-   entry = table->Table[pos];
-   while (entry) {
-      if (entry->Key == key) {
-         /* found it! */
-         if (prev) {
-            prev->Next = entry->Next;
-         }
-         else {
-            table->Table[pos] = entry->Next;
-         }
-         free(entry);
-         _eglUnlockMutex(table->Mutex);
-        return;
-      }
-      prev = entry;
-      entry = entry->Next;
-   }
-
-   _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Get the key of the "first" entry in the hash table.
- * 
- * This is used in the course of deleting all display lists when
- * a context is destroyed.
- * 
- * \param table the hash table
- * 
- * \return key for the "first" entry in the hash table.
- *
- * While holding the lock, walks through all table positions until finding
- * the first entry of the first non-empty one.
- */
-EGLuint
-_eglHashFirstEntry(_EGLHashtable *table)
-{
-   EGLuint pos;
-   assert(table);
-   _eglLockMutex(table->Mutex);
-   for (pos = 0; pos < TABLE_SIZE; pos++) {
-      if (table->Table[pos]) {
-         _eglUnlockMutex(table->Mutex);
-         return table->Table[pos]->Key;
-      }
-   }
-   _eglUnlockMutex(table->Mutex);
-   return 0;
-}
-
-
-/**
- * Given a hash table key, return the next key.  This is used to walk
- * over all entries in the table.  Note that the keys returned during
- * walking won't be in any particular order.
- * \return next hash key or 0 if end of table.
- */
-EGLuint
-_eglHashNextEntry(const _EGLHashtable *table, EGLuint key)
-{
-   const _EGLHashentry *entry;
-   EGLuint pos;
-
-   assert(table);
-   assert(key);
-
-   /* Find the entry with given key */
-   pos = HASH_FUNC(key);
-   entry = table->Table[pos];
-   while (entry) {
-      if (entry->Key == key) {
-         break;
-      }
-      entry = entry->Next;
-   }
-
-   if (!entry) {
-      /* the key was not found, we can't find next entry */
-      return 0;
-   }
-
-   if (entry->Next) {
-      /* return next in linked list */
-      return entry->Next->Key;
-   }
-   else {
-      /* look for next non-empty table slot */
-      pos++;
-      while (pos < TABLE_SIZE) {
-         if (table->Table[pos]) {
-            return table->Table[pos]->Key;
-         }
-         pos++;
-      }
-      return 0;
-   }
-}
-
-
-/**
- * Dump contents of hash table for debugging.
- * 
- * \param table the hash table.
- */
-void
-_eglHashPrint(const _EGLHashtable *table)
-{
-   EGLuint i;
-   assert(table);
-   for (i = 0; i < TABLE_SIZE; i++) {
-      const _EGLHashentry *entry = table->Table[i];
-      while (entry) {
-        printf("%u %p\n", entry->Key, entry->Data);
-        entry = entry->Next;
-      }
-   }
-}
-
-
-
-/**
- * Return a new, unused hash key.
- */
-EGLuint
-_eglHashGenKey(_EGLHashtable *table)
-{
-   EGLuint k;
-
-   _eglLockMutex(table->Mutex);
-   k = table->MaxKey;
-   table->MaxKey++;
-   _eglUnlockMutex(table->Mutex);
-   return k;
-}
-
diff --git a/src/egl/main/eglhash.h b/src/egl/main/eglhash.h
deleted file mode 100644 (file)
index 1d6db95..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * \file eglhash.h
- * Generic hash table. 
- */
-
-
-#ifndef EGLHASH_INCLUDED
-#define EGLHASH_INCLUDED
-
-
-/* XXX move this? */
-typedef unsigned int EGLuint;
-
-
-typedef struct _egl_hashtable _EGLHashtable;
-
-
-extern _EGLHashtable *_eglNewHashTable(void);
-
-extern void _eglDeleteHashTable(_EGLHashtable *table);
-
-extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data);
-
-extern void _eglHashRemove(_EGLHashtable *table, EGLuint key);
-
-extern EGLuint _eglHashFirstEntry(_EGLHashtable *table);
-
-extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashPrint(const _EGLHashtable *table);
-
-extern EGLuint _eglHashGenKey(_EGLHashtable *table);
-
-extern void _egltest_hash_functions(void);
-
-
-#endif /* EGLHASH_INCLUDED */
index b5bdc3ea4bfe48fc181ab68110dae12967930471..b37213faf1019d3e28f7ea5887069916de9c0e70 100644 (file)
@@ -35,6 +35,7 @@
 #include <string.h>
 #include "eglglobals.h"
 #include "eglmisc.h"
+#include "egldisplay.h"
 
 
 /**
  * the driver's Extensions string.
  */
 static void
-_eglUpdateExtensionsString(_EGLDriver *drv)
+_eglUpdateExtensionsString(_EGLDisplay *dpy)
 {
-   drv->Extensions.String[0] = 0;
+   char *exts = dpy->Extensions.String;
 
-   if (drv->Extensions.MESA_screen_surface)
-      strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
-   if (drv->Extensions.MESA_copy_context)
-      strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
-   assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN);
+   if (exts[0])
+      return;
+
+   if (dpy->Extensions.MESA_screen_surface)
+      strcat(exts, "EGL_MESA_screen_surface ");
+   if (dpy->Extensions.MESA_copy_context)
+      strcat(exts, "EGL_MESA_copy_context ");
+   assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
 }
 
 
 static void
-_eglUpdateAPIsString(_EGLDriver *drv)
+_eglUpdateAPIsString(_EGLDisplay *dpy)
 {
-   _eglGlobal.ClientAPIs[0] = 0;
+   char *apis = dpy->ClientAPIs;
 
-   if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT)
-      strcat(_eglGlobal.ClientAPIs, "OpenGL ");
+   if (apis[0] || !dpy->ClientAPIsMask)
+      return;
 
-   if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT)
-      strcat(_eglGlobal.ClientAPIs, "OpenGL_ES ");
+   if (dpy->ClientAPIsMask & EGL_OPENGL_BIT)
+      strcat(apis, "OpenGL ");
 
-   if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT)
-      strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 ");
+   if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT)
+      strcat(apis, "OpenGL_ES ");
 
-   if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT)
-      strcat(_eglGlobal.ClientAPIs, "OpenVG ");
+   if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT)
+      strcat(apis, "OpenGL_ES2 ");
 
-   assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs));
-}
+   if (dpy->ClientAPIsMask & EGL_OPENVG_BIT)
+      strcat(apis, "OpenVG ");
 
+   assert(strlen(apis) < sizeof(dpy->ClientAPIs));
+}
 
 
 const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
 {
    (void) drv;
    (void) dpy;
@@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
    case EGL_VENDOR:
       return _EGL_VENDOR_STRING;
    case EGL_VERSION:
-      return drv->Version;
+      return dpy->Version;
    case EGL_EXTENSIONS:
-      _eglUpdateExtensionsString(drv);
-      return drv->Extensions.String;
+      _eglUpdateExtensionsString(dpy);
+      return dpy->Extensions.String;
 #ifdef EGL_VERSION_1_2
    case EGL_CLIENT_APIS:
-      _eglUpdateAPIsString(drv);
-      return _eglGlobal.ClientAPIs;
+      _eglUpdateAPIsString(dpy);
+      return dpy->ClientAPIs;
 #endif
    default:
       _eglError(EGL_BAD_PARAMETER, "eglQueryString");
@@ -102,7 +108,7 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
 
 
 EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy)
 {
    /* just a placeholder */
    (void) drv;
@@ -112,7 +118,7 @@ _eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
 
 
 EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
 {
    /* just a placeholder */
    (void) drv;
index 4e2a40ea991a85aadddb0bb91f0849566b856010..a15c839be2b2d51b5473d2062f0aeb5ad807a25d 100644 (file)
 
 
 extern const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
 
 
 extern EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy);
 
 
 extern EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
 
 
 #endif /* EGLMISC_INCLUDED */
index 786432234bbd72d18718c0fbad563ae39579f3ff..0f3ba6e5c08021ca7d652aeed36d5ce5bef53ecb 100644 (file)
@@ -34,9 +34,8 @@ my_strdup(const char *s)
  * or null if non-existant.
  */
 _EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode)
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
 {
-   const _EGLDisplay *disp = _eglLookupDisplay(dpy);
    EGLint scrnum;
 
    /* loop over all screens on the display */
@@ -272,19 +271,13 @@ _eglCompareModes(const void *a, const void *b)
  * Called via eglChooseModeMESA API function.
  */
 EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                    const EGLint *attrib_list, EGLModeMESA *modes,
                    EGLint modes_size, EGLint *num_modes)
 {
-   const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
    _EGLMode **modeList, min;
    EGLint i, count;
 
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglChooseModeMESA");
-      return EGL_FALSE;
-   }
-
    if (!_eglParseModeAttribs(&min, attrib_list)) {
       /* error code will have been recorded */
       return EGL_FALSE;
@@ -326,16 +319,9 @@ _eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
  * Called via eglGetModesMESA() API function.
  */
 EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                  EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
 {
-   _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglGetModesMESA");
-      return EGL_FALSE;
-   }
-
    if (modes) {
       EGLint i;
       *num_modes = MIN2(scrn->NumModes, modes_size);
@@ -356,17 +342,11 @@ _eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
  * Query an attribute of a mode.
  */
 EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
-                      EGLModeMESA mode, EGLint attribute, EGLint *value)
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+                      _EGLMode *m, EGLint attribute, EGLint *value)
 {
-   _EGLMode *m = _eglLookupMode(dpy, mode);
    EGLint v;
 
-   if (!m) {
-      _eglError(EGL_BAD_MODE_MESA, "eglGetModeAttribMESA");
-      return EGL_FALSE;
-   }
-
    v = getModeAttrib(m, attribute);
    if (v < 0) {
       _eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
@@ -382,13 +362,8 @@ _eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
  * This is the default function called by eglQueryModeStringMESA().
  */
 const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode)
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
 {
-   _EGLMode *m = _eglLookupMode(dpy, mode);
-   if (!m) {
-      _eglError(EGL_BAD_MODE_MESA, "eglQueryModeStringMESA");
-      return NULL;
-   }
    return m->Name;
 }
 
index 52d4875676dffffb57bd289700b500c214fb4e60..af7c2c56d33c407f3a7a6f97d5b3a3c5ad1ee34d 100644 (file)
@@ -26,7 +26,7 @@ struct _egl_mode
 
 
 extern _EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode);
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
 
 
 extern _EGLMode *
@@ -35,23 +35,23 @@ _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
 
 
 extern EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                    const EGLint *attrib_list, EGLModeMESA *modes,
                    EGLint modes_size, EGLint *num_modes);
 
 
 extern EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                  EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
 
 
 extern EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode,
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m,
                       EGLint attribute, EGLint *value);
 
 
 extern const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m);
 
 
 #endif /* EGLMODE_INCLUDED */
index b6bde65e8b52a80c8611c8478a54b55775bb90a2..14a1e9f8fe3a10672c531241f3267ca421ab4ceb 100644 (file)
@@ -52,13 +52,9 @@ _eglInitScreen(_EGLScreen *screen)
  * Given a public screen handle, return the internal _EGLScreen object.
  */
 _EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen)
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
 {
    EGLint i;
-   _EGLDisplay *display = _eglLookupDisplay(dpy);
-
-   if (!display)
-      return NULL;
 
    for (i = 0; i < display->NumScreens; i++) {
       if (display->Screens[i]->Handle == screen)
@@ -89,17 +85,11 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
 
 
 EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
                    EGLint max_screens, EGLint *num_screens)
 {
-   _EGLDisplay *display = _eglLookupDisplay(dpy);
    EGLint n;
 
-   if (!display) {
-      _eglError(EGL_BAD_DISPLAY, "eglGetScreensMESA");
-      return EGL_FALSE;
-   }
-
    if (display->NumScreens > max_screens) {
       n = max_screens;
    }
@@ -122,33 +112,26 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
 /**
  * Example function - drivers should do a proper implementation.
  */
-EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                             const EGLint *attrib_list)
 {
 #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;
+      return NULL;
 
    if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA,
                         conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+   return surf;
 #endif
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
@@ -160,28 +143,15 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * this with code that _really_ shows the surface.
  */
 EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
-                          EGLScreenMESA screen, EGLSurface surface,
-                          EGLModeMESA m)
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+                          _EGLScreen *scrn, _EGLSurface *surf,
+                          _EGLMode *mode)
 {
-   _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-   _EGLMode *mode = _eglLookupMode(dpy, m);
-
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
-      return EGL_FALSE;
-   }
-   if (!mode && (m != EGL_NO_MODE_MESA )) {
-      _eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA");
-      return EGL_FALSE;
-   }
-
-   if (surface == EGL_NO_SURFACE) {
+   if (!surf) {
       scrn->CurrentSurface = NULL;
    }
    else {
-      _EGLSurface *surf = _eglLookupSurface(surface);
-      if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
+      if (surf->Type != EGL_SCREEN_BIT_MESA) {
          _eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
          return EGL_FALSE;
       }
@@ -206,18 +176,10 @@ _eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
  * this with code that _really_ sets the mode.
  */
 EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
-                   EGLModeMESA mode)
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+                   _EGLMode *m)
 {
-   _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
-      return EGL_FALSE;
-   }
-
-   scrn->CurrentMode = _eglLookupMode(dpy, mode);
-
+   scrn->CurrentMode = m;
    return EGL_TRUE;
 }
 
@@ -226,15 +188,9 @@ _eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
  * Set a screen's surface origin.
  */
 EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
-                       EGLScreenMESA screen, EGLint x, EGLint y)
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+                       _EGLScreen *scrn, EGLint x, EGLint y)
 {
-   _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
-      return EGL_FALSE;
-   }
-
    scrn->OriginX = x;
    scrn->OriginY = y;
 
@@ -246,14 +202,10 @@ _eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
  * Query a screen's current surface.
  */
 EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
-                           EGLScreenMESA screen, EGLSurface *surface)
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+                           _EGLScreen *scrn, _EGLSurface **surf)
 {
-   const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-   if (scrn->CurrentSurface)
-      *surface = scrn->CurrentSurface->Handle;
-   else
-      *surface = EGL_NO_SURFACE;
+   *surf = scrn->CurrentSurface;
    return EGL_TRUE;
 }
 
@@ -262,29 +214,18 @@ _eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
  * Query a screen's current mode.
  */
 EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
-                        EGLModeMESA *mode)
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+                        _EGLMode **m)
 {
-   const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-   if (scrn->CurrentMode)
-      *mode = scrn->CurrentMode->Handle;
-   else
-      *mode = EGL_NO_MODE_MESA;
+   *m = scrn->CurrentMode;
    return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
                     EGLint attribute, EGLint *value)
 {
-   const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
-   if (!scrn) {
-      _eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
-      return EGL_FALSE;
-   }
-
    switch (attribute) {
    case EGL_SCREEN_POSITION_MESA:
       value[0] = scrn->OriginX;
index 833439b41073f7b8340634a680a47366797036ed..8860a2aa7f699104d27df12782498502577e2a81 100644 (file)
@@ -35,7 +35,7 @@ _eglInitScreen(_EGLScreen *screen);
 
 
 extern _EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen);
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
 
 
 extern void
@@ -43,40 +43,40 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
 
 
 extern EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
 
 
-extern EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
 
 
 extern EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLSurface *surf, _EGLMode *m);
 
 
 extern EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA mode);
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode *m);
 
 
 extern EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y);
 
 
 extern EGLBoolean
-_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value);
+_eglQueryDisplayMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLint attribute, EGLint *value);
 
 
 extern EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
-                           EGLScreenMESA screen, EGLSurface *surface);
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+                           _EGLScreen *scrn, _EGLSurface **surface);
 
 
 extern EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m);
 
 
 extern EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value);
 
 
 extern void
index 394705112762a4cbdbc1f32e7da55b2ba3a6aa52..e7a1a8329e1807a24b15241e3807055a3ba01fb9 100644 (file)
@@ -11,7 +11,6 @@
 #include "eglconfig.h"
 #include "egldriver.h"
 #include "eglglobals.h"
-#include "eglhash.h"
 #include "egllog.h"
 #include "eglsurface.h"
 
@@ -211,22 +210,15 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
 
 
 EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
 {
-   /* Basically just do error checking here.  Drivers have to do the
-    * actual buffer swap.
-    */
-   _EGLSurface *surface = _eglLookupSurface(draw);
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
-      return EGL_FALSE;
-   }
+   /* Drivers have to do the actual buffer swap.  */
    return EGL_TRUE;
 }
 
 
 EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
                 NativePixmapType target)
 {
    /* copy surface to native pixmap */
@@ -236,14 +228,9 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
 
 
 EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint attribute, EGLint *value)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
-      return EGL_FALSE;
-   }
    switch (attribute) {
    case EGL_WIDTH:
       *value = surface->Width;
@@ -255,7 +242,7 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
       *value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
       return EGL_TRUE;
    case EGL_LARGEST_PBUFFER:
-      *value = drv->LargestPbuffer;
+      *value = dpy->LargestPbuffer;
       return EGL_TRUE;
    case EGL_SURFACE_TYPE:
       *value = surface->Type;
@@ -312,96 +299,75 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
 /**
  * Example function - drivers should do a proper implementation.
  */
-EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                         NativeWindowType window, const EGLint *attrib_list)
 {
 #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;
+      return NULL;
 
    if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+   return surf;
 #endif
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
 /**
  * Example function - drivers should do a proper implementation.
  */
-EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                         NativePixmapType pixmap, const EGLint *attrib_list)
 {
 #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;
+      return NULL;
 
    if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+   return surf;
 #endif
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
 /**
  * Example function - drivers should do a proper implementation.
  */
-EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                          const EGLint *attrib_list)
 {
 #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;
+      return NULL;
 
    if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+   return NULL;
 #endif
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 
@@ -409,19 +375,11 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
  * Default fallback routine - drivers should usually override this.
  */
 EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
 {
-   _EGLSurface *surf = _eglLookupSurface(surface);
-   if (surf) {
-      _eglUnlinkSurface(surf);
-      if (!_eglIsSurfaceBound(surf))
-         free(surf);
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
-      return EGL_FALSE;
-   }
+   if (!_eglIsSurfaceBound(surf))
+      free(surf);
+   return EGL_TRUE;
 }
 
 
@@ -429,16 +387,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
  * Default fallback routine - drivers might override this.
  */
 EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                   EGLint attribute, EGLint value)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
-
-   if (surface == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
-      return EGL_FALSE;
-   }
-
    switch (attribute) {
    case EGL_MIPMAP_LEVEL:
       surface->MipmapLevel = value;
@@ -452,15 +403,14 @@ _eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
 
 
 EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint buffer)
 {
    /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
-   _EGLSurface *surface = _eglLookupSurface(surf);
 
-   if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+   if (surface->Type != EGL_PBUFFER_BIT) {
       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
       return EGL_FALSE;
    }
@@ -482,15 +432,14 @@ _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
 
 
 EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                     EGLint buffer)
 {
    /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
-   _EGLSurface *surface = _eglLookupSurface(surf);
 
-   if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+   if (surface->Type != EGL_PBUFFER_BIT) {
       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
       return EGL_FALSE;
    }
@@ -517,14 +466,11 @@ _eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
 
 
 EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval)
 {
    _EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
-   if (surf == NULL) {
-      _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
-      return EGL_FALSE;
-   }
-   surf->SwapInterval = interval;
+   if (surf)
+      surf->SwapInterval = interval;
    return EGL_TRUE;
 }
 
@@ -534,17 +480,17 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
 /**
  * Example function - drivers should do a proper implementation.
  */
-EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+_EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
                                   EGLenum buftype, EGLClientBuffer buffer,
-                                  EGLConfig config, const EGLint *attrib_list)
+                                  _EGLConfig *conf, const EGLint *attrib_list)
 {
    if (buftype != EGL_OPENVG_IMAGE) {
       _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   return EGL_NO_SURFACE;
+   return NULL;
 }
 
 #endif /* EGL_VERSION_1_2 */
index 886417684494a65f62251b490164321132d70c94..f6d44b5922e0c826548bf4fc9cc6c2d178b9a317 100644 (file)
@@ -13,7 +13,6 @@ struct _egl_surface
    /* Managed by EGLDisplay for linking */
    _EGLDisplay *Display;
    _EGLSurface *Next;
-   EGLSurface Handle;
 
    /* The bound status of the surface */
    _EGLContext *Binding;
@@ -47,55 +46,55 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
 
 
 extern EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
 
 
 extern EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target);
 
 
 extern EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value);
 
 
-extern EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
 
 
-extern EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
 
 
-extern EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
 
 
 extern EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
 
 
 extern EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
 
 
 extern EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
 
 
 extern EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
 
 
 extern EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
 
 
 #ifdef EGL_VERSION_1_2
 
-extern EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+extern _EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
                                   EGLenum buftype, EGLClientBuffer buffer,
-                                  EGLConfig config, const EGLint *attrib_list);
+                                  _EGLConfig *conf, const EGLint *attrib_list);
 
 #endif /* EGL_VERSION_1_2 */
 
index 0a770dec0cbf335323f3d53c7aa9248aa7c948f4..4461440b9b72da14e44056403a1149bd5632961a 100644 (file)
@@ -29,7 +29,7 @@ typedef struct _egl_surface _EGLSurface;
 typedef struct _egl_thread_info _EGLThreadInfo;
 
 
-typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args);
+typedef _EGLDriver *(*_EGLMain_t)(const char *args);
 
 
 #endif /* EGLTYPEDEFS_INCLUDED */
diff --git a/src/egl/main/eglx.c b/src/egl/main/eglx.c
deleted file mode 100644 (file)
index 50acc3a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- * 
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-
-/**
- * X-specific EGL code.
- *
- * Any glue code needed to make EGL work with X is placed in this file.
- */
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-
-#include "egldriver.h"
-#include "egllog.h"
-#include "eglstring.h"
-#include "eglx.h"
-
-
-static const char *DefaultGLXDriver = "egl_glx";
-static const char *DefaultSoftDriver = "egl_softpipe";
-
-
-/**
- * Given an X Display ptr (at dpy->Xdpy) try to determine the appropriate
- * device driver.  Return its name.
- *
- * This boils down to whether to use the egl_glx.so driver which will
- * load a DRI driver or the egl_softpipe.so driver that'll do software
- * rendering on Xlib.
- */
-const char *
-_xeglChooseDriver(_EGLDisplay *dpy)
-{
-#ifdef _EGL_PLATFORM_X
-   _XPrivDisplay xdpy;
-   int screen;
-   const char *driverName;
-
-   assert(dpy);
-
-   if (!dpy->Xdpy) {
-      dpy->Xdpy = XOpenDisplay(NULL);
-      if (!dpy->Xdpy) {
-         /* can't open X display -> can't use X-based driver */
-         return NULL;
-      }
-   }
-   xdpy = (_XPrivDisplay) dpy->Xdpy;
-
-   assert(dpy->Xdpy);
-
-   screen = DefaultScreen(dpy->Xdpy);
-
-   /* See if we can choose a DRI/DRM driver */
-   driverName = _eglChooseDRMDriver(screen);
-   if (driverName) {
-      free((void *) driverName);
-      driverName = _eglstrdup(DefaultGLXDriver);
-   }
-   else {
-      driverName = _eglstrdup(DefaultSoftDriver);
-   }
-
-   _eglLog(_EGL_DEBUG, "_xeglChooseDriver: %s", driverName);
-
-   return driverName;
-#else
-   return NULL;
-#endif
-}
-
-
diff --git a/src/egl/main/eglx.h b/src/egl/main/eglx.h
deleted file mode 100644 (file)
index 4323d55..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef EGLX_INCLUDED
-#define EGLX_INCLUDED
-
-
-#include "egldisplay.h"
-
-
-extern const char *
-_xeglChooseDriver(_EGLDisplay *dpy);
-
-
-#endif /* EGLX_INCLUDED */
index 2e3da436cd7a82bf9453c7ecd2f2a996dd5a60c9..63983c52201ffcbd397a5fc50ec57749916d80d8 100644 (file)
@@ -41,7 +41,7 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
 
 # Emacs tags
 tags:
-       etags `find . -name \*.[ch]` `find ../include`
+       etags `find . -name \*.[ch]` `find $(TOP)/src/gallium/include -name \*.h`
 
 # Remove .o and backup files
 clean:
index 010d501c601a901a7ecffc2a0d8c9c5dae54b1fb..e0cfc54420e61d5716899684503ff65073189f41 100644 (file)
@@ -482,6 +482,8 @@ tgsi_default_full_instruction( void )
       full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register();
    }
 
+   full_instruction.Flags = 0x0;
+
    return full_instruction;
 }
 
index f36b1114a9559229bf4e9da8bbaaa7b213586ddf..05b07a3a73eca8c66cc2601225d382e2a964ec94 100644 (file)
 #include "tgsi_info.h"
 #include "tgsi_iterate.h"
 
+
+/** Number of spaces to indent for IF/LOOP/etc */
+static const int indent_spaces = 3;
+
+
 struct dump_ctx
 {
    struct tgsi_iterate_context iter;
 
    uint instno;
    
+   uint indentation;
+
    void (*printf)(struct dump_ctx *ctx, const char *format, ...);
 };
 
@@ -328,6 +335,14 @@ tgsi_dump_immediate(
    iter_immediate( &ctx.iter, (struct tgsi_full_immediate *)imm );
 }
 
+static void
+indent(struct dump_ctx *ctx)
+{
+   uint i;
+   for (i = 0; i < ctx->indentation; i++)
+      TXT(" ");
+}
+
 static boolean
 iter_instruction(
    struct tgsi_iterate_context *iter,
@@ -341,6 +356,15 @@ iter_instruction(
 
    INSTID( instno );
    TXT( ": " );
+
+   /* update indentation */
+   if (inst->Instruction.Opcode == TGSI_OPCODE_ENDIF ||
+       inst->Instruction.Opcode == TGSI_OPCODE_ENDFOR ||
+       inst->Instruction.Opcode == TGSI_OPCODE_ENDLOOP) {
+      ctx->indentation -= indent_spaces;
+   }
+   indent(ctx);
+
    TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic );
 
    switch (inst->Instruction.Saturate) {
@@ -481,6 +505,14 @@ iter_instruction(
       break;
    }
 
+   /* update indentation */
+   if (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
+       inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
+       inst->Instruction.Opcode == TGSI_OPCODE_BGNFOR ||
+       inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) {
+      ctx->indentation += indent_spaces;
+   }
+
    EOL();
 
    return TRUE;
@@ -495,6 +527,7 @@ tgsi_dump_instruction(
 
    ctx.instno = instno;
    ctx.printf = dump_ctx_printf;
+   ctx.indentation = 0;
 
    iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst );
 }
@@ -527,6 +560,7 @@ tgsi_dump(
 
    ctx.instno = 0;
    ctx.printf = dump_ctx_printf;
+   ctx.indentation = 0;
 
    tgsi_iterate_shader( tokens, &ctx.iter );
 }
@@ -579,6 +613,7 @@ tgsi_dump_str(
 
    ctx.base.instno = 0;
    ctx.base.printf = &str_dump_ctx_printf;
+   ctx.base.indentation = 0;
 
    ctx.str = str;
    ctx.str[0] = 0;
index 951ecfd5528307713f0e4a8dbc19258356ae8373..711e86d6edfdf4df2f53f632e376d30fef28a867 100644 (file)
@@ -62,6 +62,9 @@
 
 #define FAST_MATH 1
 
+/** for tgsi_full_instruction::Flags */
+#define SOA_DEPENDENCY_FLAG 0x1
+
 #define TILE_TOP_LEFT     0
 #define TILE_TOP_RIGHT    1
 #define TILE_BOTTOM_LEFT  2
@@ -182,7 +185,7 @@ print_temp(const struct tgsi_exec_machine *mach, uint index)
  *   MOV t3, t2;
  * The second instruction will have the wrong value for t0 if executed as-is.
  */
-static boolean
+boolean
 tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
 {
    uint i, chan;
@@ -328,19 +331,24 @@ tgsi_exec_machine_bind_shader(
                                    * sizeof(struct tgsi_full_instruction));
             maxInstructions += 10;
          }
-         memcpy(instructions + numInstructions,
-                &parse.FullToken.FullInstruction,
-                sizeof(instructions[0]));
 
-#if 0
          if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
-            debug_printf("SOA dependency in instruction:\n");
-            tgsi_dump_instruction(&parse.FullToken.FullInstruction,
-                                  numInstructions);
+            uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+            parse.FullToken.FullInstruction.Flags = SOA_DEPENDENCY_FLAG;
+            /* XXX we only handle SOA dependencies properly for MOV/SWZ
+             * at this time!
+             */
+            if (opcode != TGSI_OPCODE_MOV && opcode != TGSI_OPCODE_SWZ) {
+               debug_printf("Warning: SOA dependency in instruction"
+                            " is not handled:\n");
+               tgsi_dump_instruction(&parse.FullToken.FullInstruction,
+                                     numInstructions);
+            }
          }
-#else
-         (void) tgsi_check_soa_dependencies;
-#endif
+
+         memcpy(instructions + numInstructions,
+                &parse.FullToken.FullInstruction,
+                sizeof(instructions[0]));
 
          numInstructions++;
          break;
@@ -2024,9 +2032,23 @@ exec_instruction(
 
    case TGSI_OPCODE_MOV:
    case TGSI_OPCODE_SWZ:
-      FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
-         FETCH( &r[0], 0, chan_index );
-         STORE( &r[0], 0, chan_index );
+      if (inst->Flags & SOA_DEPENDENCY_FLAG) {
+         /* Do all fetches into temp regs, then do all stores to avoid
+          * intermediate/accidental clobbering.  This could be done all the
+          * time for MOV but for other instructions we'll need more temps...
+          */
+         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+            FETCH( &r[chan_index], 0, chan_index );
+         }
+         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+            STORE( &r[chan_index], 0, chan_index );
+         }
+      }
+      else {
+         FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+            FETCH( &r[0], 0, chan_index );
+            STORE( &r[0], 0, chan_index );
+         }
       }
       break;
 
index 8a9100f4c3e8c3f94685d69273c8745abe0ff74a..fd9ef6f35df6334ecab4e07f5f399f6f19a00e71 100644 (file)
@@ -272,6 +272,14 @@ tgsi_exec_machine_run(
    struct tgsi_exec_machine *mach );
 
 
+void
+tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach);
+
+
+boolean
+tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst);
+
+
 static INLINE void
 tgsi_set_kill_mask(struct tgsi_exec_machine *mach, unsigned mask)
 {
index 1035bda1a87391b9ce674dee326cefe5929cf616..a26ee5ba8627e80fc11359e79e255a1b4f6ab048 100644 (file)
@@ -87,6 +87,7 @@ struct tgsi_full_instruction
    struct tgsi_instruction_ext_texture InstructionExtTexture;
    struct tgsi_full_dst_register       FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS];
    struct tgsi_full_src_register       FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS];
+   uint Flags;  /**< user-defined usage */
 };
 
 union tgsi_full_token
index 2d6ad12ffbdde138e7b3c0a24835e504ae2bf1ae..4b1c7d4e01bca0e271b25ab8b5c909f97cc3315c 100644 (file)
@@ -1108,6 +1108,15 @@ static int
 emit_instruction(struct gen_context *gen,
                  struct tgsi_full_instruction *inst)
 {
+
+   /* we don't handle saturation/clamping yet */
+   if (inst->Instruction.Saturate != TGSI_SAT_NONE)
+      return 0;
+
+   /* need to use extra temps to fix SOA dependencies : */
+   if (tgsi_check_soa_dependencies(inst))
+      return FALSE;
+
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_MOV:
    case TGSI_OPCODE_SWZ:
index cfec5cfc0193a482643e4a2002add6966c50420d..46f2387c1582948b0fa463754d3ca4e04e728a5d 100644 (file)
@@ -1747,6 +1747,14 @@ emit_instruction(
    if (indirect_temp_reference(inst))
       return FALSE;
 
+   /* we don't handle saturation/clamping yet */
+   if (inst->Instruction.Saturate != TGSI_SAT_NONE)
+      return FALSE;
+
+   /* need to use extra temps to fix SOA dependencies : */
+   if (tgsi_check_soa_dependencies(inst))
+      return FALSE;
+
    switch (inst->Instruction.Opcode) {
    case TGSI_OPCODE_ARL:
       FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
index ba84a82b2b0edc7d0730bac0551c23f73188be6f..792293136168e1264e028c41c74c55e4b6c38aa4 100644 (file)
@@ -31,6 +31,7 @@
 #include "tgsi/tgsi_ureg.h"
 #include "tgsi/tgsi_dump.h"
 #include "util/u_memory.h"
+#include "util/u_math.h"
 
 union tgsi_any_token {
    struct tgsi_version version;
@@ -103,6 +104,7 @@ struct ureg_program
 
    unsigned nr_constants;
    unsigned nr_samplers;
+   unsigned nr_instructions;
 
    struct ureg_tokens domain[2];
 };
@@ -301,7 +303,7 @@ out:
  */
 struct ureg_src ureg_DECL_constant(struct ureg_program *ureg )
 {
-   return ureg_src_register( TGSI_FILE_TEMPORARY, ureg->nr_constants++ );
+   return ureg_src_register( TGSI_FILE_CONSTANT, ureg->nr_constants++ );
 }
 
 
@@ -392,7 +394,7 @@ struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
                                      unsigned nr )
 {
    unsigned i;
-   unsigned swizzle;
+   unsigned swizzle = 0;
 
    /* Could do a first pass where we examine all existing immediates
     * without expanding.
@@ -525,7 +527,9 @@ ureg_emit_insn(struct ureg_program *ureg,
    out[0].insn.NumSrcRegs = num_src;
    out[0].insn.Padding = 0;
    out[0].insn.Extended = 0;
-
+   
+   ureg->nr_instructions++;
+   
    return ureg->domain[DOMAIN_INSN].count - 1;
 }
 
@@ -544,6 +548,31 @@ ureg_emit_label(struct ureg_program *ureg,
 
    out[0].value = 0;
    out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
+   
+   *label_token = ureg->domain[DOMAIN_INSN].count - 1;
+}
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg )
+{
+   return ureg->nr_instructions;
+}
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+                 unsigned label_token,
+                 unsigned instruction_number )
+{
+   union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
+
+   assert(out->insn_ext_label.Type == TGSI_INSTRUCTION_EXT_TYPE_LABEL);
+   out->insn_ext_label.Label = instruction_number;
 }
 
 
@@ -571,6 +600,7 @@ ureg_fixup_insn_size(struct ureg_program *ureg,
 {
    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
 
+   assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
    out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
 }
 
@@ -710,8 +740,7 @@ static void copy_instructions( struct ureg_program *ureg )
 
 
 static void
-fixup_header_size(struct ureg_program *ureg,
-                     unsigned insn )
+fixup_header_size(struct ureg_program *ureg )
 {
    union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );
 
@@ -739,12 +768,11 @@ emit_header( struct ureg_program *ureg )
 void *ureg_create_shader( struct ureg_program *ureg )
 {
    struct pipe_shader_state state;
-   unsigned insn;
 
    emit_header( ureg );
    emit_decls( ureg );
    copy_instructions( ureg );
-   fixup_header_size( ureg, insn );
+   fixup_header_size( ureg );
    
    if (ureg->domain[0].tokens == error_tokens ||
        ureg->domain[1].tokens == error_tokens) {
index 0a976fd63b7f70166d1e9c66a7bb45f5e3ec0a75..5a48bb7a35cf678b5216feb716d234e5405ac2ca 100644 (file)
@@ -174,6 +174,33 @@ ureg_DECL_immediate1f( struct ureg_program *ureg,
    return ureg_DECL_immediate( ureg, v, 1 );
 }
 
+/***********************************************************************
+ * Functions for patching up labels
+ */
+
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg );
+
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ *
+ * Labels are obtained from instruction emitters, eg ureg_CAL().
+ * Instruction numbers are obtained from ureg_get_instruction_number(),
+ * above.
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+                 unsigned label_token,
+                 unsigned instruction_number );
+
+
+
+
 /***********************************************************************
  * Internal instruction helpers, don't call these directly:
  */
index 74259d453b119c22ca8b2adae8594e23a60dae93..9866b6fc8a0e626eb3ff1cfc17777ea94b2962f0 100644 (file)
@@ -43,7 +43,7 @@
  * src_pitch may be negative to do vertical flip of pixels from source.
  */
 void
-pipe_copy_rect(ubyte * dst,
+util_copy_rect(ubyte * dst,
                const struct pipe_format_block *block,
                unsigned dst_stride,
                unsigned dst_x,
@@ -91,7 +91,7 @@ pipe_copy_rect(ubyte * dst,
 }
 
 void
-pipe_fill_rect(ubyte * dst,
+util_fill_rect(ubyte * dst,
                const struct pipe_format_block *block,
                unsigned dst_stride,
                unsigned dst_x,
@@ -204,7 +204,7 @@ util_surface_copy(struct pipe_context *pipe,
 
    if (src_map && dst_map) {
       /* If do_flip, invert src_y position and pass negative src stride */
-      pipe_copy_rect(dst_map,
+      util_copy_rect(dst_map,
                      &dst_trans->block,
                      dst_trans->stride,
                      0, 0,
@@ -263,7 +263,7 @@ util_surface_fill(struct pipe_context *pipe,
       case 1:
       case 2:
       case 4:
-         pipe_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
+         util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
                         0, 0, width, height, value);
          break;
       case 8:
index 59e842e16d147e9df5f99958e78c2faf9252eb77..daa50834d367bc39d57a0db346e8b0ecb82ffb8c 100644 (file)
@@ -42,13 +42,13 @@ struct pipe_surface;
 
 
 extern void
-pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block,
+util_copy_rect(ubyte * dst, const struct pipe_format_block *block,
                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
                unsigned width, unsigned height, const ubyte * src,
                int src_stride, unsigned src_x, int src_y);
 
 extern void
-pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block,
+util_fill_rect(ubyte * dst, const struct pipe_format_block *block,
                unsigned dst_stride, unsigned dst_x, unsigned dst_y,
                unsigned width, unsigned height, uint32_t value);
 
index 422bc76003ac2915c69a23ee8cb2c68ff81b7a37..9e76cfbb053d7c3b3b231a5b8c268ef73a7d710c 100644 (file)
@@ -62,7 +62,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
    if(!src)
       return;
 
-   pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
+   util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
 
    screen->transfer_unmap(screen, pt);
 }
@@ -90,7 +90,7 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
    if(!dst)
       return;
 
-   pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
+   util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
 
    screen->transfer_unmap(screen, pt);
 }
index 511779dbfa04a9c00aa9080087958ace904064dd..724a69b2eee9eeaff98ffc4195cd3bce8c87f773 100644 (file)
@@ -60,7 +60,7 @@ brw_surface_copy(struct pipe_context *pipe,
                                                        src,
                                                        PIPE_BUFFER_USAGE_CPU_READ );
       
-      pipe_copy_rect(dst_map,
+      util_copy_rect(dst_map,
                      &dst->block,
                      dst->stride,
                      dstx, dsty,
@@ -99,7 +99,7 @@ brw_surface_fill(struct pipe_context *pipe,
                                                  dst,
                                                  PIPE_BUFFER_USAGE_CPU_WRITE );
 
-      pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
+      util_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
 
       pipe->screen->surface_unmap(pipe->screen, dst);
    }
index 5cbc2c8f823415d90032ed26f68cb441d269ac53..4de6e8cfa2968eea2265fdc0daf76df34c767d33 100644 (file)
@@ -120,6 +120,7 @@ struct nv50_state {
        struct nouveau_stateobj *fragprog;
        struct nouveau_stateobj *vtxfmt;
        struct nouveau_stateobj *vtxbuf;
+       struct nouveau_stateobj *vtxattr;
 };
 
 struct nv50_context {
index a879df2e6e29af1665c51b7fc9fcaf4033eef4ff..99d5b96e4563117c39b45a27e3ff0bdda7272853 100644 (file)
@@ -204,6 +204,8 @@ nv50_state_emit(struct nv50_context *nv50)
        if (nv50->state.dirty & NV50_NEW_ARRAYS) {
                so_emit(chan, nv50->state.vtxfmt);
                so_emit(chan, nv50->state.vtxbuf);
+               if (nv50->state.vtxattr)
+                       so_emit(chan, nv50->state.vtxattr);
        }
        nv50->state.dirty = 0;
 
index 17283f3f4184f7239b80f9a905fad3caeef7b440..36f1b24b2f0b98415c77735c22f002f3ce912c76 100644 (file)
@@ -49,55 +49,80 @@ nv50_prim(unsigned mode)
        return NV50TCL_VERTEX_BEGIN_POINTS;
 }
 
-static INLINE unsigned
-nv50_vtxeltfmt(unsigned pf)
+static INLINE uint32_t
+nv50_vbo_type_to_hw(unsigned type)
 {
-       static const uint8_t vtxelt_32[4] = { 0x90, 0x20, 0x10, 0x08 };
-       static const uint8_t vtxelt_16[4] = { 0xd8, 0x78, 0x28, 0x18 };
-       static const uint8_t vtxelt_08[4] = { 0xe8, 0xc0, 0x98, 0x50 };
-
-       unsigned nf, c = 0;
-
-       switch (pf_type(pf)) {
+       switch (type) {
        case PIPE_FORMAT_TYPE_FLOAT:
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT; break;
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT;
        case PIPE_FORMAT_TYPE_UNORM:
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM; break;
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM;
        case PIPE_FORMAT_TYPE_SNORM:
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM; break;
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM;
        case PIPE_FORMAT_TYPE_USCALED:
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED; break;
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED;
        case PIPE_FORMAT_TYPE_SSCALED:
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED; break;
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED;
+       /*
+       case PIPE_FORMAT_TYPE_UINT:
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT;
+       case PIPE_FORMAT_TYPE_SINT:
+               return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT; */
        default:
-               NOUVEAU_ERR("invalid vbo type %d\n",pf_type(pf));
-               assert(0);
-               nf = NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT;
-               break;
+               return 0;
        }
+}
 
-       if (pf_size_y(pf)) c++;
-       if (pf_size_z(pf)) c++;
-       if (pf_size_w(pf)) c++;
-
-       if (pf_exp2(pf) == 3) {
-               switch (pf_size_x(pf)) {
-               case 1: return (nf | (vtxelt_08[c] << 16));
-               case 2: return (nf | (vtxelt_16[c] << 16));
-               case 4: return (nf | (vtxelt_32[c] << 16));
-               default:
-                       break;
-               }
-       } else
-       if (pf_exp2(pf) == 6 && pf_size_x(pf) == 1) {
-               NOUVEAU_ERR("unsupported vbo component size 64\n");
-               assert(0);
-               return (nf | 0x08000000);
+static INLINE uint32_t
+nv50_vbo_size_to_hw(unsigned size, unsigned nr_c)
+{
+       static const uint32_t hw_values[] = {
+               0, 0, 0, 0,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8_8,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16_16,
+               0, 0, 0, 0,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32,
+               NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32_32 };
+
+       /* we'd also have R11G11B10 and R10G10B10A2 */
+
+       assert(nr_c > 0 && nr_c <= 4);
+
+       if (size > 32)
+               return 0;
+       size >>= (3 - 2);
+
+       return hw_values[size + (nr_c - 1)];
+}
+
+static INLINE uint32_t
+nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
+{
+       uint32_t hw_type, hw_size;
+       enum pipe_format pf = ve->src_format;
+       unsigned size = pf_size_x(pf) << pf_exp2(pf);
+
+       hw_type = nv50_vbo_type_to_hw(pf_type(pf));
+       hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
+
+       if (!hw_type || !hw_size) {
+               NOUVEAU_ERR("unsupported vbo format: %s\n", pf_name(pf));
+               abort();
+               return 0x24e80000;
        }
 
-       NOUVEAU_ERR("invalid vbo format %s\n",pf_name(pf));
-       assert(0);
-       return (nf | 0x08000000);
+       if (pf_swizzle_x(pf) == 2) /* BGRA */
+               hw_size |= (1 << 31); /* no real swizzle bits :-( */
+
+       return (hw_type | hw_size);
 }
 
 boolean
@@ -252,18 +277,78 @@ nv50_draw_elements(struct pipe_context *pipe,
        return TRUE;
 }
 
+static INLINE boolean
+nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
+                      struct nouveau_stateobj **pso,
+                      struct pipe_vertex_element *ve,
+                      struct pipe_vertex_buffer *vb)
+
+{
+       struct nouveau_stateobj *so;
+       struct nouveau_grobj *tesla = nv50->screen->tesla;
+       struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+       float *v;
+       int ret;
+       enum pipe_format pf = ve->src_format;
+
+       if ((pf_type(pf) != PIPE_FORMAT_TYPE_FLOAT) ||
+           (pf_size_x(pf) << pf_exp2(pf)) != 32)
+               return FALSE;
+
+       ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
+       if (ret)
+               return FALSE;
+       v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset));
+
+       so = *pso;
+       if (!so)
+               *pso = so = so_new(nv50->vtxelt_nr * 5, 0);
+
+       switch (ve->nr_components) {
+       case 4:
+               so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
+               so_data  (so, fui(v[0]));
+               so_data  (so, fui(v[1]));
+               so_data  (so, fui(v[2]));
+               so_data  (so, fui(v[3]));
+               break;
+       case 3:
+               so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 4);
+               so_data  (so, fui(v[0]));
+               so_data  (so, fui(v[1]));
+               so_data  (so, fui(v[2]));
+               break;
+       case 2:
+               so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 4);
+               so_data  (so, fui(v[0]));
+               so_data  (so, fui(v[1]));
+               break;
+       case 1:
+               so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 4);
+               so_data  (so, fui(v[0]));
+               break;
+       default:
+               nouveau_bo_unmap(bo);
+               return FALSE;
+       }
+
+       nouveau_bo_unmap(bo);
+       return TRUE;
+}
+
 void
 nv50_vbo_validate(struct nv50_context *nv50)
 {
        struct nouveau_grobj *tesla = nv50->screen->tesla;
-       struct nouveau_stateobj *vtxbuf, *vtxfmt;
-       int i;
+       struct nouveau_stateobj *vtxbuf, *vtxfmt, *vtxattr;
+       unsigned i;
 
        /* don't validate if Gallium took away our buffers */
        if (nv50->vtxbuf_nr == 0)
                return;
 
-       vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2);
+       vtxattr = NULL;
+       vtxbuf = so_new(nv50->vtxelt_nr * 7, nv50->vtxelt_nr * 4);
        vtxfmt = so_new(nv50->vtxelt_nr + 1, 0);
        so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0),
                nv50->vtxelt_nr);
@@ -273,8 +358,18 @@ nv50_vbo_validate(struct nv50_context *nv50)
                struct pipe_vertex_buffer *vb =
                        &nv50->vtxbuf[ve->vertex_buffer_index];
                struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+               uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
+
+               if (!vb->stride &&
+                   nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
+                       so_data(vtxfmt, hw | (1 << 4));
 
-               so_data(vtxfmt, nv50_vtxeltfmt(ve->src_format) | i);
+                       so_method(vtxbuf, tesla,
+                                 NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
+                       so_data  (vtxbuf, 0);
+                       continue;
+               }
+               so_data(vtxfmt, hw | i);
 
                so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
                so_data  (vtxbuf, 0x20000000 | vb->stride);
@@ -284,11 +379,22 @@ nv50_vbo_validate(struct nv50_context *nv50)
                so_reloc (vtxbuf, bo, vb->buffer_offset +
                          ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
                          NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+
+               /* vertex array limits */
+               so_method(vtxbuf, tesla, 0x1080 + (i * 8), 2);
+               so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+                         NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
+                         NOUVEAU_BO_HIGH, 0, 0);
+               so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+                         NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
+                         NOUVEAU_BO_LOW, 0, 0);
        }
 
        so_ref (vtxfmt, &nv50->state.vtxfmt);
        so_ref (vtxbuf, &nv50->state.vtxbuf);
+       so_ref (vtxattr, &nv50->state.vtxattr);
        so_ref (NULL, &vtxbuf);
        so_ref (NULL, &vtxfmt);
+       so_ref (NULL, &vtxattr);
 }
 
index 00fae8d26f3df80d1efede5f938a2baf314be5a8..d138866d33cac217ab015b0729f88fe2a9879105 100644 (file)
 void r300_parse_chipset(struct r300_capabilities* caps)
 {
     /* Reasonable defaults */
+    caps->num_vert_fpus = 4;
     caps->has_tcl = getenv("RADEON_NO_TCL") ? FALSE : TRUE;
     caps->is_r500 = FALSE;
-    caps->num_vert_fpus = 4;
+    caps->high_second_pipe = FALSE;
+
 
     /* Note: These are not ordered by PCI ID. I leave that task to GCC,
      * which will perform the ordering while collating jump tables. Instead,
@@ -40,6 +42,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
     switch (caps->pci_id) {
         case 0x4144:
             caps->family = CHIP_FAMILY_R300;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x4145:
@@ -50,6 +53,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x4E46:
         case 0x4E47:
             caps->family = CHIP_FAMILY_R300;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x4150:
@@ -66,6 +70,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x4E54:
         case 0x4E56:
             caps->family = CHIP_FAMILY_RV350;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x4148:
@@ -76,10 +81,12 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x4E49:
         case 0x4E4B:
             caps->family = CHIP_FAMILY_R350;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x4E4A:
             caps->family = CHIP_FAMILY_R360;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x5460:
@@ -91,6 +98,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x5B64:
         case 0x5B65:
             caps->family = CHIP_FAMILY_RV370;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x3150:
@@ -99,6 +107,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
         case 0x3E50:
         case 0x3E54:
             caps->family = CHIP_FAMILY_RV380;
+            caps->high_second_pipe = TRUE;
             break;
 
         case 0x4A48:
index 5b2e1f0568817e6bb54c7731ffc098d5da41accf..322d4a57e414f9e04284e505d0eb83a875f9323b 100644 (file)
@@ -34,6 +34,8 @@ struct r300_capabilities {
     int family;
     /* The number of vertex floating-point units */
     int num_vert_fpus;
+    /* The number of fragment pipes */
+    int num_frag_pipes;
     /* Whether or not TCL is physically present */
     boolean has_tcl;
     /* Whether or not this is an RV515 or newer; R500s have many differences
@@ -42,6 +44,8 @@ struct r300_capabilities {
      * - Blend color is split across two registers
      * - Universal Shader (US) block used for fragment shaders */
     boolean is_r500;
+    /* Whether or not the second pixel pipe is accessed with the high bit */
+    boolean high_second_pipe;
 };
 
 /* Enumerations for legibility and telling which card we're running on. */
index c8510bc63e4391793d6243e9eefe1c14526e4acb..da67bc29b89888504a9af244961b48581ec10f6c 100644 (file)
@@ -88,9 +88,21 @@ static boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
 
 static void r300_destroy_context(struct pipe_context* context) {
     struct r300_context* r300 = r300_context(context);
+    struct r300_query* query, * temp;
 
     draw_destroy(r300->draw);
 
+    /* Free the OQ BO. */
+    context->screen->buffer_destroy(r300->oqbo);
+
+    /* If there are any queries pending or not destroyed, remove them now. */
+    if (r300->query_list) {
+        foreach_s(query, temp, r300->query_list) {
+            remove_from_list(query);
+            FREE(query);
+        }
+    }
+
     FREE(r300->blend_color_state);
     FREE(r300->rs_block);
     FREE(r300->scissor_state);
@@ -145,6 +157,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
     r300->context.is_texture_referenced = r300_is_texture_referenced;
     r300->context.is_buffer_referenced = r300_is_buffer_referenced;
 
+    r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
+    r300->rs_block = CALLOC_STRUCT(r300_rs_block);
+    r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
+    r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
+
     /* Create a Draw. This is used for vert collation and SW TCL. */
     r300->draw = draw_create();
     /* Enable our renderer. */
@@ -155,10 +172,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
      * transform in hardware, always. */
     draw_set_viewport_state(r300->draw, &r300_viewport_identity);
 
-    r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
-    r300->rs_block = CALLOC_STRUCT(r300_rs_block);
-    r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
-    r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
+    /* Open up the OQ BO. */
+    r300->oqbo = screen->buffer_create(screen, 4096,
+            PIPE_BUFFER_USAGE_VERTEX, 4096);
 
     r300_init_flush_functions(r300);
 
index fc8a4498933a4a6af7330f7fa576a3f25a97fd34..f78492d4aa997e0c974f6b3be2621abb837b84da 100644 (file)
 
 #include "draw/draw_context.h"
 #include "draw/draw_vertex.h"
+
 #include "pipe/p_context.h"
+
 #include "tgsi/tgsi_scan.h"
+
 #include "util/u_memory.h"
+#include "util/u_simple_list.h"
 
 #include "r300_clear.h"
 #include "r300_query.h"
@@ -150,6 +154,29 @@ struct r300_constant_buffer {
     unsigned count;
 };
 
+/* Query object.
+ *
+ * This is not a subclass of pipe_query because pipe_query is never
+ * actually fully defined. So, rather than have it as a member, and do
+ * subclass-style casting, we treat pipe_query as an opaque, and just
+ * trust that our state tracker does not ever mess up query objects.
+ */
+struct r300_query {
+    /* The kind of query. Currently only OQ is supported. */
+    unsigned type;
+    /* Whether this query is currently active. Only active queries will
+     * get emitted into the command stream, and only active queries get
+     * tallied. */
+    boolean active;
+    /* The current count of this query. Required to be at least 32 bits. */
+    unsigned int count;
+    /* The offset of this query into the query buffer, in bytes. */
+    unsigned offset;
+    /* Linked list members. */
+    struct r300_query* prev;
+    struct r300_query* next;
+};
+
 struct r300_texture {
     /* Parent class */
     struct pipe_texture tex;
@@ -203,6 +230,11 @@ struct r300_context {
     /* Offset into the VBO. */
     size_t vbo_offset;
 
+    /* Occlusion query buffer. */
+    struct pipe_buffer* oqbo;
+    /* Query list. */
+    struct r300_query* query_list;
+
     /* Various CSO state objects. */
     /* Blend state. */
     struct r300_blend_state* blend_state;
index 53256fc6dd36844ddf9b36877811894da311e5b5..bd4d59e6f1ad6097e0863ac2b97d35e16f43a3cf 100644 (file)
@@ -319,6 +319,79 @@ void r300_emit_fb_state(struct r300_context* r300,
     END_CS;
 }
 
+void r300_emit_query_begin(struct r300_context* r300,
+                           struct r300_query* query)
+{
+    CS_LOCALS(r300);
+
+    /* XXX This will almost certainly not return good results
+     * for overlapping queries. */
+    BEGIN_CS(2);
+    OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
+    END_CS;
+}
+
+void r300_emit_query_end(struct r300_context* r300,
+                         struct r300_query* query)
+{
+    struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
+    CS_LOCALS(r300);
+
+    if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
+                0, RADEON_GEM_DOMAIN_GTT)) {
+        debug_printf("r300: There wasn't room for the OQ buffer!?"
+                " Oh noes!\n");
+    }
+
+    assert(caps->num_frag_pipes);
+    BEGIN_CS(6 * caps->num_frag_pipes + 2);
+    /* I'm not so sure I like this switch, but it's hard to be elegant
+     * when there's so many special cases...
+     *
+     * So here's the basic idea. For each pipe, enable writes to it only,
+     * then put out the relocation for ZPASS_ADDR, taking into account a
+     * 4-byte offset for each pipe. RV380 and older are special; they have
+     * only two pipes, and the second pipe's enable is on bit 3, not bit 1,
+     * so there's a chipset cap for that. */
+    switch (caps->num_frag_pipes) {
+        case 4:
+            /* pipe 3 only */
+            OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
+            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
+                    0, RADEON_GEM_DOMAIN_GTT, 0);
+        case 3:
+            /* pipe 2 only */
+            OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
+            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
+                    0, RADEON_GEM_DOMAIN_GTT, 0);
+        case 2:
+            /* pipe 1 only */
+            /* As mentioned above, accomodate RV380 and older. */
+            OUT_CS_REG(R300_SU_REG_DEST,
+                    1 << (caps->high_second_pipe ? 3 : 1));
+            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
+                    0, RADEON_GEM_DOMAIN_GTT, 0);
+        case 1:
+            /* pipe 0 only */
+            OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
+            OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+            OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
+                    0, RADEON_GEM_DOMAIN_GTT, 0);
+        default:
+            debug_printf("r300: Implementation error: Chipset reports %d"
+                    " pixel pipes!\n", caps->num_frag_pipes);
+            assert(0);
+    }
+
+    /* And, finally, reset it to normal... */
+    OUT_CS_REG(R300_SU_REG_DEST, 0xF);
+    END_CS;
+
+}
+
 void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
 {
     CS_LOCALS(r300);
@@ -615,6 +688,12 @@ validate:
             goto validate;
         }
     }
+    /* ...occlusion query buffer... */
+    if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
+                0, RADEON_GEM_DOMAIN_GTT)) {
+        r300->context.flush(&r300->context, 0, NULL);
+        goto validate;
+    }
     /* ...and vertex buffer. */
     if (r300->vbo) {
         if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
index 8fc61c2dec71fdca056b2d2d7c085f4973c91cf6..1d5185b417eccfd07e870c4097ae3798653cb07d 100644 (file)
 static struct pipe_query* r300_create_query(struct pipe_context* pipe,
                                             unsigned query_type)
 {
-    struct r300_query* q = CALLOC_STRUCT(r300_query);
+    struct r300_context* r300 = r300_context(pipe);
+    struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    unsigned query_size = r300screen->caps->num_frag_pipes * 4;
+    struct r300_query* q, * qptr;
+
+    q = CALLOC_STRUCT(r300_query);
 
     q->type = query_type;
     assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
-    /* XXX this is to force winsys to give us a GTT buffer */
-    q->buf = pipe->screen->buffer_create(pipe->screen, 64,
-            PIPE_BUFFER_USAGE_VERTEX, 64);
+    q->active = FALSE;
+
+    if (!r300->query_list) {
+        r300->query_list = q;
+    } else if (!is_empty_list(r300->query_list)) {
+        qptr = last_elem(r300->query_list);
+        q->offset = qptr->offset + query_size;
+        insert_at_tail(r300->query_list, q);
+    }
+
+    /* XXX */
+    if (q->offset >= 4096) {
+        q->offset = 0;
+    }
 
     return (struct pipe_query*)q;
 }
@@ -40,6 +56,9 @@ static struct pipe_query* r300_create_query(struct pipe_context* pipe,
 static void r300_destroy_query(struct pipe_context* pipe,
                                struct pipe_query* query)
 {
+    struct r300_query* q = (struct r300_query*)query;
+
+    remove_from_list(q);
     FREE(query);
 }
 
@@ -49,15 +68,15 @@ static void r300_begin_query(struct pipe_context* pipe,
     uint32_t* map;
     struct r300_context* r300 = r300_context(pipe);
     struct r300_query* q = (struct r300_query*)query;
-    CS_LOCALS(r300);
 
-    map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo,
+            PIPE_BUFFER_USAGE_CPU_WRITE);
+    map += q->offset / 4;
     *map = ~0;
-    pipe_buffer_unmap(pipe->screen, q->buf);
+    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
 
-    BEGIN_CS(2);
-    OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
-    END_CS;
+    r300_emit_dirty_state(r300);
+    r300_emit_query_begin(r300, q);
 }
 
 static void r300_end_query(struct pipe_context* pipe,
@@ -65,12 +84,9 @@ static void r300_end_query(struct pipe_context* pipe,
 {
     struct r300_context* r300 = r300_context(pipe);
     struct r300_query* q = (struct r300_query*)query;
-    CS_LOCALS(r300);
 
-    BEGIN_CS(4);
-    OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
-    OUT_CS_RELOC(q->buf, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
-    END_CS;
+    r300_emit_dirty_state(r300);
+    r300_emit_query_end(r300, q);
 }
 
 static boolean r300_get_query_result(struct pipe_context* pipe,
@@ -78,22 +94,38 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
                                      boolean wait,
                                      uint64_t* result)
 {
+    struct r300_context* r300 = r300_context(pipe);
+    struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct r300_query* q = (struct r300_query*)query;
+    unsigned flags = PIPE_BUFFER_USAGE_CPU_READ;
     uint32_t* map;
     uint32_t temp;
+    unsigned i;
 
     if (wait) {
-        /* Well, we're expected to just sit here and spin, so let's go ahead
-         * and flush so we can be sure that the card's spinning... */
-        /* XXX double-check these params */
         pipe->flush(pipe, 0, NULL);
+    } else {
+        flags |= PIPE_BUFFER_USAGE_DONTBLOCK;
     }
 
-    map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_READ);
-    temp = *map;
-    pipe_buffer_unmap(pipe->screen, q->buf);
+    map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, flags);
+    map += q->offset / 4;
+    for (i = 0; i < r300screen->caps->num_frag_pipes; i++) {
+        if (*map == ~0) {
+            /* Looks like our results aren't ready yet. */
+            if (wait) {
+                debug_printf("r300: Despite waiting, OQ results haven't"
+                        " come in yet.\n");
+            }
+            temp = ~0;
+            break;
+        }
+        temp += *map;
+        map++;
+    }
+    pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
 
-    if (temp 0) {
+    if (temp == ~0) {
         /* Our results haven't been written yet... */
         return FALSE;
     }
index 6a7646087a74bb5fbc821116591d570068673016..4f50e8f84401599ddd5ae9b89ffe92219089287d 100644 (file)
 
 struct r300_context;
 
-struct r300_query {
-    /* The kind of query. Currently only OQ is supported. */
-    unsigned type;
-    /* Buffer object where we want our results to reside. */
-    struct pipe_buffer* buf;
-};
-
 static INLINE struct r300_query* r300_query(struct pipe_query* q)
 {
     return (struct r300_query*)q;
index 6825d9987001b49f5da23774bc8bb5b1671d000d..03cd219cde91ace20ac4eeb8e16a223511bc892b 100644 (file)
@@ -3312,6 +3312,10 @@ enum {
 
 #define R200_3D_DRAW_IMMD_2      0xC0003500
 
+/* XXX Oh look, stuff not brought over from docs yet */
+
+#define R300_SU_REG_DEST                    0x42C8
+
 #endif /* _R300_REG_H */
 
 /* *INDENT-ON* */
index 96a730462177cd58a3b99eb4c3c44ee13ed553f3..15740f61252adb863844fd786f45b20eca8778d1 100644 (file)
@@ -392,6 +392,7 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
         return NULL;
 
     caps->pci_id = r300_winsys->pci_id;
+    caps->num_frag_pipes = r300_winsys->gb_pipes;
 
     r300_parse_chipset(caps);
 
index a02fb34b2a7e2e8089be415709b72f3094abc0be..27680a38631bcfd8c2fffe4d25a09d07145ae9e1 100644 (file)
@@ -224,7 +224,8 @@ static void*
         dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,
                                      0, 1023);
     } else {
-        dsa->z_buffer_top = R300_ZTOP_ENABLE;
+        /* XXX need to fix this to be dynamically set
+        dsa->z_buffer_top = R300_ZTOP_ENABLE; */
     }
 
     return (void*)dsa;
index 22c8e199ae32399810cb098da4125a408373f75d..91b93fc367eda2089431a89a9b964fe3e552b75b 100644 (file)
@@ -353,6 +353,25 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
 
 /* Non-CSO state. (For now.) */
 
+static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
+{
+    switch (pipe_count) {
+        case 1:
+            return R300_GB_TILE_PIPE_COUNT_RV300;
+            break;
+        case 2:
+            return R300_GB_TILE_PIPE_COUNT_R300;
+            break;
+        case 3:
+            return R300_GB_TILE_PIPE_COUNT_R420_3P;
+            break;
+        case 4:
+            return R300_GB_TILE_PIPE_COUNT_R420;
+            break;
+    }
+    return 0;
+}
+
 static INLINE uint32_t translate_vertex_data_type(int type) {
     switch (type) {
         case EMIT_1F:
index d2893c3b9d76b3f41a8a8d670ebe443dba0bf986..f18ad75a47d8c6ef6ad1f60a08216407b29229d4 100644 (file)
@@ -45,6 +45,9 @@ struct r300_winsys {
     /* PCI ID */
     uint32_t pci_id;
 
+    /* GB pipe count */
+    uint32_t gb_pipes;
+
     /* GART size. */
     uint32_t gart_size;
 
index 643587ab4275407895d8fb9f998f76ae461c0156..7e2ccbcfdc575b5e3e3c4599ec20b285fcb80c0a 100644 (file)
@@ -351,7 +351,7 @@ void trace_dump_call_begin_locked(const char *klass, const char *method)
    trace_dump_indent(1);
    trace_dump_writes("<call no=\'");
    trace_dump_writef("%lu", call_no);
-   trace_dump_writes("\' class =\'");
+   trace_dump_writes("\' class=\'");
    trace_dump_escape(klass);
    trace_dump_writes("\' method=\'");
    trace_dump_escape(method);
index 57e966ac3b04b42043da066b9125c3be2922edab..39620a7198027dfefe846401b5b761fda5cc97be 100644 (file)
@@ -98,7 +98,7 @@ struct pipe_context {
     */
    /*@{*/
    struct pipe_query *(*create_query)( struct pipe_context *pipe,
-                                              unsigned query_type );
+                                       unsigned query_type );
 
    void (*destroy_query)(struct pipe_context *pipe,
                          struct pipe_query *q);
@@ -215,10 +215,12 @@ struct pipe_context {
 
    /**
     * Clear the specified set of currently bound buffers to specified values.
+    * The entire buffers are cleared (no scissor, no colormask, etc).
     *
-    * buffers is a bitfield of PIPE_CLEAR_* values.
-    *
-    * rgba is a pointer to an array of one float for each of r, g, b, a.
+    * \param buffers  bitfield of PIPE_CLEAR_* values.
+    * \param rgba  pointer to an array of one float for each of r, g, b, a.
+    * \param depth  depth clear value in [0,1].
+    * \param stencil  stencil clear value
     */
    void (*clear)(struct pipe_context *pipe,
                  unsigned buffers,
@@ -226,7 +228,9 @@ struct pipe_context {
                  double depth,
                 unsigned stencil);
 
-   /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
+   /** Flush rendering
+    * \param flags  bitmask of PIPE_FLUSH_x tokens)
+    */
    void (*flush)( struct pipe_context *pipe,
                   unsigned flags,
                   struct pipe_fence_handle **fence );
@@ -242,10 +246,10 @@ struct pipe_context {
     * \param texture  texture to check.
     * \param face  cubemap face. Use 0 for non-cubemap texture.
     */
-
    unsigned int (*is_texture_referenced) (struct pipe_context *pipe,
                                          struct pipe_texture *texture,
                                          unsigned face, unsigned level);
+
    /**
     * Check whether a buffer is referenced by an unflushed hw command.
     * The state-tracker uses this function to optimize away unnecessary
@@ -255,7 +259,6 @@ struct pipe_context {
     *              checked.
     * \param buf  Buffer to check.
     */
-
    unsigned int (*is_buffer_referenced) (struct pipe_context *pipe,
                                         struct pipe_buffer *buf);
 };
index cf176c9209961efd93a7d5174ce402da41a6b134..a5c1e8270a3aeb1177a56b4eff4e09ab5b1cd875 100644 (file)
@@ -63,6 +63,13 @@ pipe_buffer_map(struct pipe_screen *screen,
    if(screen->buffer_map_range) {
       unsigned offset = 0;
       unsigned length = buf->size;
+
+      /* XXX: Actually we should be using/detecting DISCARD
+       * instead of assuming that WRITE implies discard */
+      if((usage & PIPE_BUFFER_USAGE_CPU_WRITE) &&
+         !(usage & PIPE_BUFFER_USAGE_DISCARD))
+         usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
       return screen->buffer_map_range(screen, buf, offset, length, usage);
    }
    else
index 2c8f51cf3887ab660f32a06bff354d63c8fcab93..52b6453d2914bb7d51a379cd79964cffffdd5305 100644 (file)
@@ -83,23 +83,16 @@ const struct dri_extension card_extensions[] = {
        {NULL, NULL}
 };
 
-EGLContext
-drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+_EGLContext *
+drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
 {
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_context *ctx;
        struct drm_context *share = NULL;
        struct st_context *st_share = NULL;
-       _EGLConfig *conf;
        int i;
        __GLcontextModes *visual;
 
-       conf = _eglLookupConfig(drv, dpy, config);
-       if (!conf) {
-               _eglError(EGL_BAD_CONFIG, "eglCreateContext");
-               return EGL_NO_CONTEXT;
-       }
-
        for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
                switch (attrib_list[i]) {
                        /* no attribs defined for now */
@@ -129,25 +122,20 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
        if (!ctx->st)
                goto err_gl;
 
-        /* link to display */
-        _eglLinkContext(&ctx->base, _eglLookupDisplay(dpy));
-       assert(_eglGetContextHandle(&ctx->base));
-
-       return _eglGetContextHandle(&ctx->base);
+       return &ctx->base;
 
 err_gl:
        ctx->pipe->destroy(ctx->pipe);
 err_pipe:
        free(ctx);
 err_c:
-       return EGL_NO_CONTEXT;
+       return NULL;
 }
 
 EGLBoolean
-drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
 {
        struct drm_context *c = lookup_drm_context(context);
-        _eglUnlinkContext(&c->base);
        if (!_eglIsContextBound(&c->base)) {
                st_destroy_context(c->st);
                c->pipe->destroy(c->pipe);
@@ -157,7 +145,7 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
 }
 
 EGLBoolean
-drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context)
 {
        struct drm_surface *readSurf = lookup_drm_surface(read);
        struct drm_surface *drawSurf = lookup_drm_surface(draw);
index d4cd2d3c743e442432494deb92bf1b89e462d3b9..0cca68dc36f3f91f0dfa0b2785a8084faea63a11 100644 (file)
@@ -76,26 +76,8 @@ drm_create_texture(_EGLDriver *drv,
        struct pipe_surface *surface;
        struct pipe_texture *texture;
        struct pipe_texture templat;
-       struct pipe_buffer *buf;
-       unsigned stride = 1024;
+       struct pipe_buffer *buf = NULL;
        unsigned pitch = 0;
-       unsigned size = 0;
-
-       /* ugly */
-       if (stride < w)
-               stride = 2048;
-
-       pitch = stride * 4;
-       size = h * 2 * pitch;
-
-       buf = pipe_buffer_create(screen,
-                                0, /* alignment */
-                                PIPE_BUFFER_USAGE_GPU_READ_WRITE |
-                                PIPE_BUFFER_USAGE_CPU_READ_WRITE,
-                                size);
-
-       if (!buf)
-               goto err_buf;
 
        memset(&templat, 0, sizeof(templat));
        templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -108,13 +90,16 @@ drm_create_texture(_EGLDriver *drv,
        templat.height[0] = h;
        pf_get_block(templat.format, &templat.block);
 
-       texture = screen->texture_blanket(dev->screen,
-                                         &templat,
-                                         &pitch,
-                                         buf);
+       texture = screen->texture_create(dev->screen,
+                                        &templat);
+
        if (!texture)
                goto err_tex;
 
+       dev->api->buffer_from_texture(dev->api, texture, &buf, &pitch);
+       if (!buf)
+               goto err_buf;
+
        surface = screen->get_tex_surface(screen,
                                          texture,
                                          0,
@@ -125,7 +110,6 @@ drm_create_texture(_EGLDriver *drv,
        if (!surface)
                goto err_surf;
 
-
        scrn->tex = texture;
        scrn->surface = surface;
        scrn->buffer = buf;
@@ -142,9 +126,9 @@ err_handle:
        pipe_surface_reference(&surface, NULL);
 err_surf:
        pipe_texture_reference(&texture, NULL);
+err_buf:
 err_tex:
        pipe_buffer_reference(&buf, NULL);
-err_buf:
        return;
 }
 
@@ -178,22 +162,22 @@ drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
        screen->shown = 0;
 }
 
-EGLSurface
-drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+_EGLSurface *
+drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
 {
-       return EGL_NO_SURFACE;
+       return NULL;
 }
 
 
-EGLSurface
-drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+_EGLSurface *
+drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
 {
-       return EGL_NO_SURFACE;
+       return NULL;
 }
 
 
-EGLSurface
-drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
                            const EGLint *attrib_list)
 {
        int i;
@@ -201,13 +185,6 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
        int height = -1;
        struct drm_surface *surf = NULL;
        __GLcontextModes *visual;
-       _EGLConfig *conf;
-
-       conf = _eglLookupConfig(drv, dpy, config);
-       if (!conf) {
-               _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
-               return EGL_NO_CONTEXT;
-       }
 
        for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
                switch (attrib_list[i]) {
@@ -225,7 +202,7 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
 
        if (width < 1 || height < 1) {
                _eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
-               return EGL_NO_SURFACE;
+               return NULL;
        }
 
        surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
@@ -245,17 +222,16 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
                                            (void*)surf);
        drm_visual_modes_destroy(visual);
 
-        _eglLinkSurface(&surf->base, _eglLookupDisplay(dpy));
-       return surf->base.Handle;
+       return &surf->base;
 
 err_surf:
        free(surf);
 err:
-       return EGL_NO_SURFACE;
+       return NULL;
 }
 
-EGLSurface
-drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
+_EGLSurface *
+drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg,
                                const EGLint *attrib_list)
 {
        EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
@@ -264,14 +240,13 @@ drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
 }
 
 EGLBoolean
-drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
-                             EGLScreenMESA screen,
-                             EGLSurface surface, EGLModeMESA m)
+drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
+                             _EGLScreen *screen,
+                             _EGLSurface *surface, _EGLMode *mode)
 {
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_surface *surf = lookup_drm_surface(surface);
-       struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
-       _EGLMode *mode = _eglLookupMode(dpy, m);
+       struct drm_screen *scrn = lookup_drm_screen(screen);
        int ret;
        unsigned int i, k;
 
@@ -361,11 +336,9 @@ err_bo:
 }
 
 EGLBoolean
-drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
        struct drm_surface *surf = lookup_drm_surface(surface);
-       _eglUnlinkSurface(&surf->base);
-
        if (!_eglIsSurfaceBound(&surf->base)) {
                if (surf->screen)
                        drm_takedown_shown_screen(drv, surf->screen);
@@ -376,8 +349,9 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
 }
 
 EGLBoolean
-drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
 {
+       struct drm_device *dev = (struct drm_device *)drv;
        struct drm_surface *surf = lookup_drm_surface(draw);
        struct pipe_surface *back_surf;
 
@@ -395,7 +369,6 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
                st_notify_swapbuffers(surf->stfb);
 
                if (surf->screen) {
-                       surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
                        surf->user->pipe->surface_copy(surf->user->pipe,
                                surf->screen->surface,
                                0, 0,
@@ -403,7 +376,15 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
                                0, 0,
                                surf->w, surf->h);
                        surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
-                       /* TODO stuff here */
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+                       /* TODO query connector property to see if this is needed */
+                       drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0);
+#else
+                       (void)dev;
+#endif
+
+                       /* TODO more stuff here */
                }
        }
 
index 521c91d8958484d2bbcefcfbf38d620d421d7bd4..57c81da767ab0753bd7a92c51d695d791592ffe6 100644 (file)
@@ -6,6 +6,8 @@
 #include <string.h>
 #include "egl_tracker.h"
 
+#include <fcntl.h>
+
 #include "egllog.h"
 #include "state_tracker/drm_api.h"
 
@@ -21,12 +23,20 @@ extern const struct dri_extension card_extensions[];
  * Exported functions
  */
 
+static void
+drm_unload(_EGLDriver *drv)
+{
+       struct drm_device *dev = (struct drm_device *)drv;
+       dev->api->destroy(dev->api);
+       free(dev);
+}
+
 /**
  * The bootstrap function.  Return a new drm_driver object and
  * plug in API functions.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
 {
        struct drm_device *drm;
 
@@ -53,12 +63,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
        drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
        drm->base.API.SwapBuffers = drm_swap_buffers;
 
-       drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
        drm->base.Name = "DRM/Gallium/Win";
-
-       /* enable supported extensions */
-       drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
-       drm->base.Extensions.MESA_copy_context = EGL_TRUE;
+       drm->base.Unload = drm_unload;
 
        return &drm->base;
 }
@@ -128,10 +134,17 @@ drm_find_dpms(struct drm_device *dev, struct drm_screen *screen)
        screen->dpms = p;
 }
 
+static int drm_open_minor(int minor)
+{
+       char buf[64];
+
+       sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+       return open(buf, O_RDWR, 0);
+}
+
 EGLBoolean
-drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
 {
-       _EGLDisplay *disp = _eglLookupDisplay(dpy);
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_screen *screen = NULL;
        drmModeConnectorPtr connector = NULL;
@@ -141,7 +154,8 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
        EGLint i;
        int fd;
 
-       fd = drmOpen("i915", NULL);
+       /* try the first node */
+       fd = drm_open_minor(0);
        if (fd < 0)
                goto err_fd;
 
@@ -200,7 +214,10 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
        _eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
        _eglAddConfig(disp, config);
 
-       drv->Initialized = EGL_TRUE;
+       disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+       /* enable supported extensions */
+       disp->Extensions.MESA_screen_surface = EGL_TRUE;
+       disp->Extensions.MESA_copy_context = EGL_TRUE;
 
        *major = 1;
        *minor = 4;
@@ -214,12 +231,14 @@ err_fd:
 }
 
 EGLBoolean
-drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
        struct drm_device *dev = (struct drm_device *)drv;
        struct drm_screen *screen;
        int i = 0;
 
+       _eglReleaseDisplayResources(drv, dpy);
+
        drmFreeVersion(dev->version);
 
        for (i = 0; i < dev->count_screens; i++) {
@@ -236,12 +255,10 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
 
        dev->screen->destroy(dev->screen);
        dev->winsys = NULL;
-       dev->api->destroy(dev->api);
 
        drmClose(dev->drmFD);
 
-       _eglCleanupDisplay(_eglLookupDisplay(dpy));
-       free(dev);
+       _eglCleanupDisplay(dpy);
 
        return EGL_TRUE;
 }
index 3b8836720d62834bd92d9eee9a5312e9451205c9..25f70d885e09139a0585f37a1f856d3e580b5f59 100644 (file)
@@ -137,24 +137,21 @@ struct drm_screen
 
 
 static INLINE struct drm_context *
-lookup_drm_context(EGLContext context)
+lookup_drm_context(_EGLContext *c)
 {
-       _EGLContext *c = _eglLookupContext(context);
        return (struct drm_context *) c;
 }
 
 
 static INLINE struct drm_surface *
-lookup_drm_surface(EGLSurface surface)
+lookup_drm_surface(_EGLSurface *s)
 {
-       _EGLSurface *s = _eglLookupSurface(surface);
        return (struct drm_surface *) s;
 }
 
 static INLINE struct drm_screen *
-lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
+lookup_drm_screen(_EGLScreen *s)
 {
-       _EGLScreen *s = _eglLookupScreen(dpy, screen);
        return (struct drm_screen *) s;
 }
 
@@ -178,18 +175,18 @@ void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen);
  * All function exported to the egl side.
  */
 /*@{*/
-EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor);
-EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy);
-EGLContext drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-EGLBoolean drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context);
-EGLSurface drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-EGLSurface drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-EGLSurface drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list);
-EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m);
-EGLBoolean drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
-EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context);
-EGLBoolean drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
+EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy);
+_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
+EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context);
+_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
+_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
+_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
+_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
+EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
+EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
+EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context);
+EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
 /*@}*/
 
 #endif
index 96490dbedaabd682d973119d617e93074fb6f6ec..d1a98f899176cd3b8b6eca204dc6e1e37a0c2350 100644 (file)
@@ -109,19 +109,6 @@ GetCurrentContext(void)
 
 
 
-/**********************************************************************/
-/***                     Debug helper code                          ***/
-/**********************************************************************/
-
-extern void _kw_ungrab_all( Display *dpy );
-void _kw_ungrab_all( Display *dpy )
-{
-   XUngrabPointer( dpy, CurrentTime );
-   XUngrabKeyboard( dpy, CurrentTime );
-}
-
-
-
 /**********************************************************************/
 /***                       GLX Visual Code                          ***/
 /**********************************************************************/
@@ -1311,10 +1298,8 @@ void
 glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
                 unsigned long mask )
 {
-   GLXContext fakeSrc = src;
-   GLXContext fakeDst = dst;
-   XMesaContext xm_src = fakeSrc->xmesaContext;
-   XMesaContext xm_dst = fakeDst->xmesaContext;
+   XMesaContext xm_src = src->xmesaContext;
+   XMesaContext xm_dst = dst->xmesaContext;
    (void) dpy;
    if (MakeCurrent_PrevContext == src) {
       _mesa_Flush();
index b0f3e8a432f2939c5648c6ba7a296c56f2fec384..b08d36867154025693e0728401d1c42a8d5e1ddb 100755 (executable)
@@ -371,7 +371,7 @@ class Main:
                     stream = GzipFile(arg, 'rt')
                 elif arg.endswith('.bz2'):
                     from bz2 import BZ2File
-                    stream = BZ2File(arg, 'rt')
+                    stream = BZ2File(arg, 'rU')
                 else:
                     stream = open(arg, 'rt')
                 self.process_arg(stream, options)
index f2dac73e908c75ad544c0e6e8204e3884a33f389..8da113ec61852426ed310ab2f21d864db8213d7e 100644 (file)
@@ -491,7 +491,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
            exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
                                        PIPE_TRANSFER_WRITE,
                                        0, 0, width, height);
-        pipe_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+        util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
                        &priv->tex->block, transfer->stride, 0, 0,
                        width, height, pPixData, pPixmap->devKind, 0, 0);
         exa->scrn->transfer_unmap(exa->scrn, transfer);
index 775bda8308f6595d9af1e210783423939b88347a..07551e7cd16ccea087fa73216c64bcb6e4872b4d 100644 (file)
@@ -134,18 +134,17 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
         (struct radeon_pipe_buffer*)buffer;
     int write = 0;
 
-    if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
-       /* XXX Remove this when radeon_bo_map supports DONTBLOCK */
-       return NULL;
+    if (!(flags & PIPE_BUFFER_USAGE_DONTBLOCK)) {
+        radeon_bo_wait(radeon_buffer->bo);
     }
     if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
         write = 1;
     }
 
-    radeon_bo_wait(radeon_buffer->bo);
-
-    if (radeon_bo_map(radeon_buffer->bo, write))
+    if (radeon_bo_map(radeon_buffer->bo, write)) {
         return NULL;
+    }
+
     return radeon_buffer->bo->ptr;
 }
 
index 4e9a2ddd161444bf1e1b595d55660f50734ad77c..d723876221906a7cfc36250e0dbe67d43cbceabe 100644 (file)
@@ -139,7 +139,17 @@ static void do_ioctls(struct r300_winsys* winsys, int fd)
 
     info.value = &target;
 
-    /* First, get PCI ID */
+    /* First, get the number of pixel pipes */
+    info.request = RADEON_INFO_NUM_GB_PIPES;
+    retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+    if (retval) {
+        fprintf(stderr, "%s: Failed to get GB pipe count, "
+                "error number %d\n", __FUNCTION__, retval);
+        exit(1);
+    }
+    winsys->gb_pipes = target;
+
+    /* Then, get PCI ID */
     info.request = RADEON_INFO_DEVICE_ID;
     retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
     if (retval) {
@@ -149,7 +159,7 @@ static void do_ioctls(struct r300_winsys* winsys, int fd)
     }
     winsys->pci_id = target;
 
-    /* Then, retrieve MM info */
+    /* Finally, retrieve MM info */
     retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
             &gem_info, sizeof(gem_info));
     if (retval) {
index f409a3fd6bae5ba9c2a4de45048182accef2bc4d..96f460f88a96171520584cd4b3a8144d00573bc5 100644 (file)
@@ -62,6 +62,7 @@ struct xlib_egl_driver
 {
    _EGLDriver Base;   /**< base class */
 
+   EGLint apis;
    struct pipe_winsys *winsys;
    struct pipe_screen *screen;
 };
@@ -103,18 +104,16 @@ xlib_egl_driver(_EGLDriver *drv)
 
 
 static INLINE struct xlib_egl_surface *
-lookup_surface(EGLSurface surf)
+lookup_surface(_EGLSurface *surf)
 {
-   _EGLSurface *surface = _eglLookupSurface(surf);
-   return (struct xlib_egl_surface *) surface;
+   return (struct xlib_egl_surface *) surf;
 }
 
 
 static INLINE struct xlib_egl_context *
-lookup_context(EGLContext ctx)
+lookup_context(_EGLContext *ctx)
 {
-   _EGLContext *context = _eglLookupContext(ctx);
-   return (struct xlib_egl_context *) context;
+   return (struct xlib_egl_context *) ctx;
 }
 
 
@@ -133,13 +132,12 @@ bitcount(unsigned int n)
  * Create the EGLConfigs.  (one per X visual)
  */
 static void
-create_configs(_EGLDriver *drv, EGLDisplay dpy)
+create_configs(_EGLDriver *drv, _EGLDisplay *disp)
 {
    static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
                                    EGL_OPENGL_ES2_BIT |
                                    EGL_OPENVG_BIT |
                                    EGL_OPENGL_BIT);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
    XVisualInfo *visInfo, visTemplate;
    int num_visuals, i;
 
@@ -194,12 +192,18 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
  * Called via eglInitialize(), drv->API.Initialize().
  */
 static EGLBoolean
-xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
+xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
                    EGLint *minor, EGLint *major)
 {
+   struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+
+   if (!dpy->Xdpy) {
+      dpy->Xdpy = XOpenDisplay(NULL);
+   }
+
    create_configs(drv, dpy);
 
-   drv->Initialized = EGL_TRUE;
+   dpy->ClientAPIsMask = xdrv->apis;
 
    /* we're supporting EGL 1.4 */
    *minor = 1;
@@ -213,8 +217,10 @@ xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
  * Called via eglTerminate(), drv->API.Terminate().
  */
 static EGLBoolean
-xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
 {
+   _eglReleaseDisplayResources(drv, dpy);
+   _eglCleanupDisplay(dpy);
    return EGL_TRUE;
 }
 
@@ -342,24 +348,23 @@ flush_frontbuffer(struct pipe_winsys *pws,
 /**
  * Called via eglCreateContext(), drv->API.CreateContext().
  */
-static EGLContext
-xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
-                      EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+                      _EGLContext *share_list, const EGLint *attrib_list)
 {
    struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
-   _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
    struct xlib_egl_context *ctx;
    struct st_context *share_ctx = NULL; /* XXX fix */
    __GLcontextModes visual;
 
    ctx = CALLOC_STRUCT(xlib_egl_context);
    if (!ctx)
-      return EGL_NO_CONTEXT;
+      return NULL;
 
    /* let EGL lib init the common stuff */
    if (!_eglInitContext(drv, &ctx->Base, conf, attrib_list)) {
       free(ctx);
-      return EGL_NO_CONTEXT;
+      return NULL;
    }
 
    /* API-dependent context creation */
@@ -379,41 +384,33 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
    default:
       _eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)");
       free(ctx);
-      return EGL_NO_CONTEXT;
+      return NULL;
    }
 
-   _eglLinkContext(&ctx->Base, _eglLookupDisplay(dpy));
-
-   return _eglGetContextHandle(&ctx->Base);
+   return &ctx->Base;
 }
 
 
 static EGLBoolean
-xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+xlib_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
 {
    struct xlib_egl_context *context = lookup_context(ctx);
-   if (context) {
-      _eglUnlinkContext(&context->Base);
-      if (!_eglIsContextBound(&context->Base)) {
-         /* API-dependent clean-up */
-         switch (context->Base.ClientAPI) {
-         case EGL_OPENGL_ES_API:
-         case EGL_OPENVG_API:
-            /* fall-through */
-         case EGL_OPENGL_API:
-            st_destroy_context(context->Context);
-            break;
-         default:
-            assert(0);
-         }
-         free(context);
+
+   if (!_eglIsContextBound(&context->Base)) {
+      /* API-dependent clean-up */
+      switch (context->Base.ClientAPI) {
+      case EGL_OPENGL_ES_API:
+      case EGL_OPENVG_API:
+         /* fall-through */
+      case EGL_OPENGL_API:
+         st_destroy_context(context->Context);
+         break;
+      default:
+         assert(0);
       }
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
-      return EGL_TRUE;
+      free(context);
    }
+   return EGL_TRUE;
 }
 
 
@@ -421,20 +418,25 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
  * Called via eglMakeCurrent(), drv->API.MakeCurrent().
  */
 static EGLBoolean
-xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy,
-                    EGLSurface draw, EGLSurface read, EGLContext ctx)
+xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy,
+                    _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
 {
    struct xlib_egl_context *context = lookup_context(ctx);
    struct xlib_egl_surface *draw_surf = lookup_surface(draw);
    struct xlib_egl_surface *read_surf = lookup_surface(read);
-   struct st_context *oldctx = st_get_current();
+   struct st_context *oldcontext = NULL;
+   _EGLContext *oldctx;
+
+   oldctx = _eglGetCurrentContext();
+   if (oldctx && _eglIsContextLinked(oldctx))
+      oldcontext = st_get_current();
 
-   if (!_eglMakeCurrent(drv, dpy, draw, read, context))
+   if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
       return EGL_FALSE;
 
    /* Flush before switching context.  Check client API? */
-   if (oldctx)
-      st_flush(oldctx, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
+   if (oldcontext)
+      st_flush(oldcontext, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
    st_make_current((context ? context->Context : NULL),
                    (draw_surf ? draw_surf->Framebuffer : NULL),
                    (read_surf ? read_surf->Framebuffer : NULL));
@@ -488,31 +490,26 @@ choose_stencil_format(const __GLcontextModes *visual)
 /**
  * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
  */
-static EGLSurface
-xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
                             NativeWindowType window, const EGLint *attrib_list)
 {
    struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
-
    struct xlib_egl_surface *surf;
    __GLcontextModes visual;
    uint width, height;
 
    surf = CALLOC_STRUCT(xlib_egl_surface);
    if (!surf)
-      return EGL_NO_SURFACE;
+      return NULL;
 
    /* Let EGL lib init the common stuff */
    if (!_eglInitSurface(drv, &surf->Base, EGL_WINDOW_BIT,
                         conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
-   _eglLinkSurface(&surf->Base, disp);
-
    /*
     * Now init the Xlib and gallium stuff
     */
@@ -539,46 +536,35 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
 
    st_resize_framebuffer(surf->Framebuffer, width, height);
 
-   return _eglGetSurfaceHandle(&surf->Base);
+   return &surf->Base;
 }
 
 
-static EGLSurface
-xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
                              const EGLint *attrib_list)
 {
    struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
-   _EGLDisplay *disp = _eglLookupDisplay(dpy);
-   _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
    struct xlib_egl_surface *surf;
    __GLcontextModes visual;
    uint width, height;
    EGLBoolean bind_texture;
 
-   if (!disp) {
-      _eglError(EGL_BAD_DISPLAY, "eglCreatePbufferSurface");
-      return EGL_NO_SURFACE;
-   }
-   if (!conf) {
-      _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
-      return EGL_NO_SURFACE;
-   }
-
    surf = CALLOC_STRUCT(xlib_egl_surface);
    if (!surf) {
       _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
                         conf, attrib_list)) {
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
    if (surf->Base.Width < 0 || surf->Base.Height < 0) {
       _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface");
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE);
@@ -588,19 +574,19 @@ xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
        (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) {
       _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
    /* a framebuffer of zero width or height confuses st */
    if (width == 0 || height == 0) {
       _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
    /* no mipmap generation */
    if (surf->Base.MipmapTexture) {
       _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
       free(surf);
-      return EGL_NO_SURFACE;
+      return NULL;
    }
 
    surf->winsys = xdrv->winsys;
@@ -616,34 +602,27 @@ xlib_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
                                              (void *) surf);
    st_resize_framebuffer(surf->Framebuffer, width, height);
 
-   return _eglLinkSurface(&surf->Base, disp);
+   return &surf->Base;
 }
 
 
 static EGLBoolean
-xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+xlib_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
 {
    struct xlib_egl_surface *surf = lookup_surface(surface);
-   if (surf) {
-      _eglUnlinkSurface(&surf->Base);
-      if (!_eglIsSurfaceBound(&surf->Base)) {
-         if (surf->Base.Type != EGL_PBUFFER_BIT)
-            XFreeGC(surf->Dpy, surf->Gc);
-         st_unreference_framebuffer(surf->Framebuffer);
-         free(surf);
-      }
-      return EGL_TRUE;
-   }
-   else {
-      _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
-      return EGL_FALSE;
+   if (!_eglIsSurfaceBound(&surf->Base)) {
+      if (surf->Base.Type != EGL_PBUFFER_BIT)
+         XFreeGC(surf->Dpy, surf->Gc);
+      st_unreference_framebuffer(surf->Framebuffer);
+      free(surf);
    }
+   return EGL_TRUE;
 }
 
 
 static EGLBoolean
-xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy,
-                     EGLSurface surface, EGLint buffer)
+xlib_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy,
+                     _EGLSurface *surface, EGLint buffer)
 {
    struct xlib_egl_surface *xsurf = lookup_surface(surface);
    struct xlib_egl_context *xctx;
@@ -680,12 +659,12 @@ xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy,
 
    /* flush properly */
    if (eglGetCurrentSurface(EGL_DRAW) == surface) {
-      xctx = lookup_context(eglGetCurrentContext());
+      xctx = lookup_context(_eglGetCurrentContext());
       st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
                NULL);
    }
    else if (_eglIsSurfaceBound(&xsurf->Base)) {
-      xctx = lookup_context(_eglGetContextHandle(xsurf->Base.Binding));
+      xctx = lookup_context(xsurf->Base.Binding);
       if (xctx)
          st_finish(xctx->Context);
    }
@@ -700,7 +679,7 @@ xlib_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy,
 
 
 static EGLBoolean
-xlib_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+xlib_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                         EGLint buffer)
 {
    struct xlib_egl_surface *xsurf = lookup_surface(surface);
@@ -722,7 +701,7 @@ xlib_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
 
 
 static EGLBoolean
-xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
 {
    /* error checking step: */
    if (!_eglSwapBuffers(drv, dpy, draw))
@@ -779,12 +758,22 @@ find_supported_apis(void)
 }
 
 
+static void
+xlib_Unload(_EGLDriver *drv)
+{
+   struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+   xdrv->screen->destroy(xdrv->screen);
+   free(xdrv->winsys);
+   free(xdrv);
+}
+
+
 /**
  * This is the main entrypoint into the driver.
  * Called by libEGL to instantiate an _EGLDriver object.
  */
 _EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
 {
    struct xlib_egl_driver *xdrv;
 
@@ -794,10 +783,6 @@ _eglMain(_EGLDisplay *dpy, const char *args)
    if (!xdrv)
       return NULL;
 
-   if (!dpy->Xdpy) {
-      dpy->Xdpy = XOpenDisplay(NULL);
-   }
-
    _eglInitDriverFallbacks(&xdrv->Base);
    xdrv->Base.API.Initialize = xlib_eglInitialize;
    xdrv->Base.API.Terminate = xlib_eglTerminate;
@@ -812,16 +797,17 @@ _eglMain(_EGLDisplay *dpy, const char *args)
    xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
    xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
 
-   xdrv->Base.ClientAPIsMask = find_supported_apis();
-   if (xdrv->Base.ClientAPIsMask == 0x0) {
+   xdrv->apis = find_supported_apis();
+   if (xdrv->apis == 0x0) {
       /* the app isn't directly linked with any EGL-supprted APIs
        * (such as libGLESv2.so) so use an EGL utility to see what
        * APIs might be loaded dynamically on this system.
        */
-      xdrv->Base.ClientAPIsMask = _eglFindAPIs();
-   }      
+      xdrv->apis = _eglFindAPIs();
+   }
 
    xdrv->Base.Name = "Xlib/softpipe";
+   xdrv->Base.Unload = xlib_Unload;
 
    /* create one winsys and use it for all contexts/surfaces */
    xdrv->winsys = create_sw_winsys();
@@ -831,4 +817,3 @@ _eglMain(_EGLDisplay *dpy, const char *args)
 
    return &xdrv->Base;
 }
-
index 7eb23dbacabf284c5f1e678755d3ce00c029f591..2efe191982098c5d385e022f9b27b8fee8914865 100644 (file)
@@ -1960,7 +1960,7 @@ __glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
 {
    int status = GLX_BAD_CONTEXT;
 #ifdef __DRI_FRAME_TRACKING
-   int screen;
+   int screen = 0;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 
@@ -1979,7 +1979,7 @@ __glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
 {
    int status = GLX_BAD_CONTEXT;
 #ifdef __DRI_FRAME_TRACKING
-   int screen;
+   int screen = 0;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
 
@@ -1999,7 +1999,7 @@ __glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
 {
    int status = GLX_BAD_CONTEXT;
 #ifdef __DRI_FRAME_TRACKING
-   int screen;
+   int screen = 0;
    __GLXDRIdrawable *const pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 
@@ -2029,7 +2029,7 @@ __glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
 {
    int status = GLX_BAD_CONTEXT;
 #ifdef __DRI_FRAME_TRACKING
-   int screen;
+   int screen = 0;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
 
@@ -2213,7 +2213,7 @@ PUBLIC GLXFBConfigSGIX
 glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
 {
    __GLXdisplayPrivate *priv;
-   __GLXscreenConfigs *psc;
+   __GLXscreenConfigs *psc = NULL;
 
    if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success)
        && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
@@ -2432,7 +2432,7 @@ __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
                    int64_t * msc, int64_t * sbc)
 {
 #ifdef __DRI_MEDIA_STREAM_COUNTER
-   int screen;
+   int screen = 0;
    __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
    __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
    int ret;
index 1d2e953eb1ef173e84055a247ba90a6340c2fbfe..5986cbffade3ee81180863ec6388dd7d95228dc1 100644 (file)
@@ -194,6 +194,16 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
         }
 
       }
+      /* The 965's sampler lays cachelines out according to how accesses
+       * in the texture surfaces run, so they may be "vertical" through
+       * memory.  As a result, the docs say in Surface Padding Requirements:
+       * Sampling Engine Surfaces that two extra rows of padding are required.
+       * We don't know of similar requirements for pre-965, but given that
+       * those docs are silent on padding requirements in general, let's play
+       * it safe.
+       */
+      if (mt->target == GL_TEXTURE_CUBE_MAP)
+        mt->total_height += 2;
       break;
    }
 
index 497f7967649eaafe9d47d63d3f9d48ef9b79b5e3..068a3f33797b4c4cedc85551ff8858c11a97d5f5 100644 (file)
@@ -181,10 +181,20 @@ intel_region_alloc(struct intel_context *intel,
    dri_bo *buffer;
    struct intel_region *region;
 
+   /* If we're tiled, our allocations are in 8 or 32-row blocks, so
+    * failure to align our height means that we won't allocate enough pages.
+    *
+    * If we're untiled, we still have to align to 2 rows high because the
+    * data port accesses 2x2 blocks even if the bottom row isn't to be
+    * rendered, so failure to align means we could walk off the end of the
+    * GTT and fault.
+    */
    if (tiling == I915_TILING_X)
       height = ALIGN(height, 8);
    else if (tiling == I915_TILING_Y)
       height = ALIGN(height, 32);
+   else
+      height = ALIGN(height, 2);
 
    if (expect_accelerated_upload) {
       buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
index e81a1b38ac369dd6b14f012f9105d52fe43b1fef..2114ce55c14d6dd10f46c907b93c7f1692f4cd81 100644 (file)
@@ -27,7 +27,8 @@ RADEON_COMMON_SOURCES = \
        radeon_cs_legacy.c \
        radeon_mipmap_tree.c \
        radeon_span.c \
-       radeon_fbo.c
+       radeon_fbo.c \
+       radeon_queryobj.c
 
 
 DRIVER_SOURCES = r200_context.c \
index 14d6bc19c988345a5db14b51bc2f2275386bfd78..e63935378e0bb6d0277f383617905918ba25ab86 100644 (file)
@@ -219,6 +219,9 @@ void r200FlushElts(GLcontext *ctx)
    radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
    rmesa->radeon.tcl.elt_dma_bo = NULL;
 
+   if (R200_ELT_BUF_SZ > elt_used)
+     radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
+
    if (R200_DEBUG & DEBUG_SYNC) {
       fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
       radeonFinish( rmesa->radeon.glCtx );
@@ -240,22 +243,13 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
    
    radeonEmitState(&rmesa->radeon);
 
-   rmesa->radeon.tcl.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
-                                         0, R200_ELT_BUF_SZ, 4,
-                                         RADEON_GEM_DOMAIN_GTT, 0);
-   rmesa->radeon.tcl.elt_dma_offset = 0;
+   radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
+                       &rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4);
    rmesa->tcl.elt_used = min_nr * 2;
 
-   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo,
-                                RADEON_GEM_DOMAIN_GTT, 0);
-   if (ret) {
-      fprintf(stderr,"failure to revalidate BOs - badness\n");
-   }
-
    radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
    retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
    
-
    if (R200_DEBUG & DEBUG_PRIMS)
       fprintf(stderr, "%s: header prim %x \n",
              __FUNCTION__, primitive);
index 5a6fd20d8c2db1bede3e5a1877fe31964a99deec..ffc1a95745489bef96783dfc69364af9a1c684f5 100644 (file)
@@ -2289,8 +2289,11 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    struct radeon_renderbuffer *rrb;
+   struct radeon_dma_bo *dma_bo;
    int i, ret;
 
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s\n", __FUNCTION__);
    radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
 
    rrb = radeon_get_colorbuffer(&rmesa->radeon);
@@ -2323,9 +2326,12 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
                           RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
    }
 
-   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
-   if (ret)
-       return GL_FALSE;
+   dma_bo = first_elem(&rmesa->radeon.dma.reserved);
+   {
+       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
+       if (ret)
+          return GL_FALSE;
+   }
    return GL_TRUE;
 }
 
index 83e70b586d7f7b00c4c9544e67f00e46c347a619..1b2389114088fea77f8d9b2a651d0cedcfe9cb3d 100644 (file)
@@ -39,6 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/image.h"
 #include "main/imports.h"
 #include "main/macros.h"
+#include "main/simple_list.h"
 
 #include "swrast/s_context.h"
 #include "swrast/s_fog.h"
@@ -275,7 +276,7 @@ void r200_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
    radeonEmitState(&rmesa->radeon);
    r200EmitVertexAOS( rmesa,
                      rmesa->radeon.swtcl.vertex_size,
-                     rmesa->radeon.dma.current,
+                     first_elem(&rmesa->radeon.dma.reserved)->bo,
                      current_offset);
 
 
index 580370933ee4612230ac332ca4b364ff16649388..ca9a8dbf8c27505e97a0bee708670f7ab345249c 100644 (file)
@@ -146,7 +146,7 @@ static GLushort *r200AllocElts( r200ContextPtr rmesa, GLuint nr )
        rmesa->tcl.elt_used + nr*2 < R200_ELT_BUF_SZ) {
 
       GLushort *dest = (GLushort *)(rmesa->radeon.tcl.elt_dma_bo->ptr +
-                                   rmesa->tcl.elt_used);
+                                   rmesa->radeon.tcl.elt_dma_offset + rmesa->tcl.elt_used);
 
       rmesa->tcl.elt_used += nr*2;
 
diff --git a/src/mesa/drivers/dri/r200/radeon_queryobj.c b/src/mesa/drivers/dri/r200/radeon_queryobj.c
new file mode 120000 (symlink)
index 0000000..1d6ebc1
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_queryobj.h b/src/mesa/drivers/dri/r200/radeon_queryobj.h
new file mode 120000 (symlink)
index 0000000..8f6f842
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h
\ No newline at end of file
index 77b3d168f342854b3721dcb8918b984faf54b8c5..188efcb7a0754a99e8af70af2d04a709a61d5c25 100644 (file)
@@ -37,7 +37,8 @@ RADEON_COMMON_SOURCES = \
        radeon_mipmap_tree.c \
        radeon_span.c \
        radeon_fbo.c \
-       radeon_buffer_objects.c
+       radeon_buffer_objects.c \
+       radeon_queryobj.c
 
 DRIVER_SOURCES = \
                 radeon_screen.c \
@@ -54,7 +55,6 @@ DRIVER_SOURCES = \
                 r300_shader.c \
                 r300_emit.c \
                 r300_swtcl.c \
-                r300_queryobj.c \
                 $(RADEON_COMMON_SOURCES) \
                 $(EGL_SOURCES) \
                 $(CS_SOURCES)
index 39cc6953ba50f8aabb03773228774f26f916f61c..980ef3eaea11c4f277bb6e63975fe31a40167c54 100644 (file)
@@ -128,24 +128,24 @@ static char* r300_vs_swiz_debug[] = {
 
 static void r300_vs_op_dump(uint32_t op)
 {
-       printf(" dst: %d%s op: ",
+       fprintf(stderr, " dst: %d%s op: ",
                        (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
        if (op & 0x80) {
                if (op & 0x1) {
-                       printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
+                       fprintf(stderr, "PVS_MACRO_OP_2CLK_M2X_ADD\n");
                } else {
-                       printf("   PVS_MACRO_OP_2CLK_MADD\n");
+                       fprintf(stderr, "   PVS_MACRO_OP_2CLK_MADD\n");
                }
        } else if (op & 0x40) {
-               printf("%s\n", r300_vs_me_ops[op & 0x1f]);
+               fprintf(stderr, "%s\n", r300_vs_me_ops[op & 0x1f]);
        } else {
-               printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
+               fprintf(stderr, "%s\n", r300_vs_ve_ops[op & 0x1f]);
        }
 }
 
 static void r300_vs_src_dump(uint32_t src)
 {
-       printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
+       fprintf(stderr, " reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
                        (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
                        src & (1 << 25) ? "-" : " ",
                        r300_vs_swiz_debug[(src >> 13) & 0x7],
@@ -166,11 +166,11 @@ void r300_vertex_program_dump(struct r300_vertex_program_code * vs)
                unsigned offset = i*4;
                unsigned src;
 
-               printf("%d: op: 0x%08x", i, vs->body.d[offset]);
+               fprintf(stderr, "%d: op: 0x%08x", i, vs->body.d[offset]);
                r300_vs_op_dump(vs->body.d[offset]);
 
                for(src = 0; src < 3; ++src) {
-                       printf(" src%i: 0x%08x", src, vs->body.d[offset+1+src]);
+                       fprintf(stderr, " src%i: 0x%08x", src, vs->body.d[offset+1+src]);
                        r300_vs_src_dump(vs->body.d[offset+1+src]);
                }
        }
index bd46f9acf2e64dd69cd5c9485695cd9243eaac74..1ca9eacda100eb43d18134e1be326e07f0ad6da5 100644 (file)
@@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_mipmap_tree.h"
 #include "r300_state.h"
 #include "radeon_reg.h"
+#include "radeon_queryobj.h"
 
 /** # of dwords reserved for additional instructions that may need to be written
  * during flushing.
@@ -430,6 +431,7 @@ static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom
            format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
        }
 
+       BEGIN_BATCH_NO_AUTOSTATE(5);
        OUT_BATCH(atom->cmd[0]);
        atom->cmd[1] &= ~0xf;
        atom->cmd[1] |= format;
@@ -437,6 +439,7 @@ static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom
        OUT_BATCH(atom->cmd[2]);
        OUT_BATCH(atom->cmd[3]);
        OUT_BATCH(atom->cmd[4]);
+       END_BATCH();
 }
 
 static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -791,6 +794,17 @@ void r300InitCmdBuf(r300ContextPtr r300)
        r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
            cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0);
 
+       radeon_init_query_stateobj(&r300->radeon, R300_QUERYOBJ_CMDSIZE);
+       if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
+               r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RV530_FG_ZBREG_DEST, 1);
+               r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL;
+       } else {
+               r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_REG_DEST, 1);
+               r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = R300_RASTER_PIPE_SELECT_ALL;
+       }
+       r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_ZPASS_DATA, 1);
+       r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_1] = 0;
+
        r300->radeon.hw.is_dirty = GL_TRUE;
        r300->radeon.hw.all_dirty = GL_TRUE;
 
index 91fa77a169058deea8d7b6a9cf4ad6831ac382a2..ca8021df16a0243e317dd6d5ecdc367c48c2b08b 100644 (file)
@@ -64,11 +64,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_ioctl.h"
 #include "r300_tex.h"
 #include "r300_emit.h"
-#include "r300_queryobj.h"
 #include "r300_swtcl.h"
 #include "radeon_bocs_wrapper.h"
 #include "radeon_buffer_objects.h"
-
+#include "radeon_queryobj.h"
 
 #include "vblank.h"
 #include "utils.h"
@@ -234,6 +233,84 @@ static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
                r300->radeon.Fallback &= ~bit;
 }
 
+static void r300_emit_query_finish(radeonContextPtr radeon)
+{
+       r300ContextPtr r300 = (r300ContextPtr)radeon;
+       struct radeon_query_object *query = radeon->query.current;
+       BATCH_LOCALS(radeon);
+
+       BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->num_z_pipes + 2);
+       switch (r300->num_z_pipes) {
+       case 4:
+               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+       case 3:
+               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
+               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+       case 2:
+               if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
+                       OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+               } else {
+                       OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
+               }
+               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+       case 1:
+       default:
+               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
+               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+               OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+               break;
+       }
+       OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
+       END_BATCH();
+       query->curr_offset += r300->num_z_pipes * sizeof(uint32_t);
+       assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+       query->emitted_begin = GL_FALSE;
+}
+
+static void rv530_emit_query_finish_single_z(radeonContextPtr radeon)
+{
+       BATCH_LOCALS(radeon);
+       struct radeon_query_object *query = radeon->query.current;
+
+       BEGIN_BATCH_NO_AUTOSTATE(8);
+       OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+       OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+       OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+       OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+       END_BATCH();
+
+       query->curr_offset += sizeof(uint32_t);
+       assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+       query->emitted_begin = GL_FALSE;
+}
+
+#if 0
+static void rv530_emit_query_finish_double_z(radeonContextPtr radeon)
+{
+       r300ContextPtr r300 = (r300ContextPtr)radeon;
+       BATCH_LOCALS(radeon);
+       struct radeon_query_object *query = radeon->query.current;
+
+       BEGIN_BATCH_NO_AUTOSTATE(6);
+       OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+       OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+       OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+       OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
+       OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+       OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+       OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+       END_BATCH();
+
+       query->curr_offset += 2 * sizeof(uint32_t);
+       assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+       query->emitted_begin = GL_FALSE;
+}
+#endif
+
 static void r300_init_vtbl(radeonContextPtr radeon)
 {
        radeon->vtbl.get_lock = r300_get_lock;
@@ -242,6 +319,12 @@ static void r300_init_vtbl(radeonContextPtr radeon)
        radeon->vtbl.swtcl_flush = r300_swtcl_flush;
        radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
        radeon->vtbl.fallback = r300_fallback;
+       if (radeon->radeonScreen->chip_family == CHIP_FAMILY_RV530)
+               /* single Z gives me correct results on my hw need to check if we ever need
+                * double z */
+               radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z;
+       else
+               radeon->vtbl.emit_query_finish = r300_emit_query_finish;
 }
 
 static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
@@ -361,8 +444,7 @@ static void r300InitGLExtensions(GLcontext *ctx)
                _mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
        }
 
-       if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries ||
-               !r300->options.hw_tcl_enabled) {
+       if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) {
                _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
        }
 }
@@ -389,6 +471,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 
        r300ParseOptions(r300, screen);
 
+       r300->radeon.radeonScreen = screen;
        r300_init_vtbl(&r300->radeon);
 
        _mesa_init_driver_functions(&functions);
@@ -396,7 +479,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
        r300InitStateFuncs(&functions);
        r300InitTextureFuncs(&functions);
        r300InitShaderFuncs(&functions);
-       r300InitQueryObjFunctions(&functions);
+       radeonInitQueryObjFunctions(&functions);
        radeonInitBufferObjectFuncs(&functions);
 
        if (!radeonInitContext(&r300->radeon, &functions,
@@ -453,8 +536,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
 
        r300InitGLExtensions(ctx);
 
-       make_empty_list(&r300->query.not_flushed_head);
-
        return GL_TRUE;
 }
 
index 3ba34266084e852b922283b26edcb8e1cb6a5fd4..339b3045586878a76012107dbb9703fc81835a29 100644 (file)
@@ -51,22 +51,6 @@ typedef struct r300_context r300ContextRec;
 typedef struct r300_context *r300ContextPtr;
 
 
-/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
-   I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
-   with other compilers ... GLUE!
-*/
-#define WARN_ONCE(a, ...)      { \
-       static int warn##__LINE__=1; \
-       if(warn##__LINE__){ \
-               fprintf(stderr, "*********************************WARN_ONCE*********************************\n"); \
-               fprintf(stderr, "File %s function %s line %d\n", \
-                       __FILE__, __FUNCTION__, __LINE__); \
-               fprintf(stderr,  a, ## __VA_ARGS__);\
-               fprintf(stderr, "***************************************************************************\n"); \
-               warn##__LINE__=0;\
-               } \
-       }
-
 #include "r300_vertprog.h"
 
 
@@ -290,6 +274,12 @@ typedef struct r300_context *r300ContextPtr;
 #define R300_TEX_CMDSIZE       (MAX_TEXTURE_UNITS+1)
 */
 
+#define R300_QUERYOBJ_CMD_0  0
+#define R300_QUERYOBJ_DATA_0 1
+#define R300_QUERYOBJ_CMD_1  2
+#define R300_QUERYOBJ_DATA_1  3
+#define R300_QUERYOBJ_CMDSIZE  4
+
 /**
  * Cache for hardware register state.
  */
@@ -380,7 +370,6 @@ struct r300_hw_state {
                struct radeon_state_atom border_color;
        } tex;
        struct radeon_state_atom txe;   /* tex enable (4104) */
-
        radeonTexObj *textures[R300_MAX_TEXTURE_UNITS];
 };
 
@@ -505,15 +494,6 @@ struct r300_index_buffer {
        GLuint count;
 };
 
-struct r300_query_object {
-       struct gl_query_object Base;
-       struct radeon_bo *bo;
-       int curr_offset;
-       GLboolean emitted_begin;
-
-       /* Double linked list of not flushed query objects */
-       struct r300_query_object *prev, *next;
-};
 
 /**
  * \brief R300 context structure.
@@ -549,12 +529,6 @@ struct r300_context {
        uint32_t fallback;
 
        DECLARE_RENDERINPUTS(render_inputs_bitset);
-
-       struct {
-               struct r300_query_object *current;
-               struct r300_query_object not_flushed_head;
-       } query;
-
        int num_z_pipes;
 };
 
index d524d60299847b9e7746a40dd98f988114806974..dbf5384d558eb5ecc3f5e583462cfff61cc728b8 100644 (file)
 #include "main/state.h"
 #include "main/api_validate.h"
 #include "main/enums.h"
+#include "main/simple_list.h"
 
 #include "r300_reg.h"
 #include "r300_context.h"
 #include "r300_emit.h"
 #include "r300_render.h"
-#include "r300_queryobj.h"
 #include "r300_state.h"
 #include "r300_tex.h"
 
@@ -114,7 +114,7 @@ static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
 
                radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offet, size, 4);
 
-               assert(r300->ind_buf.bo->ptr != NULL)
+               assert(r300->ind_buf.bo->ptr != NULL);
                out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
 
                for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) {
@@ -511,7 +511,7 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar
                }
 
                r300->radeon.tcl.aos_count = vbuf->num_attribs;
-               ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, r300->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+               ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, first_elem(&r300->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
                if (ret)
                        r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, GL_TRUE);
        }
@@ -583,16 +583,12 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
        r300EmitCacheFlush(r300);
        radeonEmitState(&r300->radeon);
 
-       r300EmitQueryBegin(ctx);
-
        for (i = 0; i < nr_prims; ++i) {
                r300RunRenderPrimitive(ctx, prim[i].start, prim[i].start + prim[i].count, prim[i].mode);
        }
 
        r300EmitCacheFlush(r300);
 
-       r300EmitQueryEnd(ctx);
-
        r300FreeData(ctx);
 
        return GL_TRUE;
index da801f42e4c80f21a3907097e75fb1818237d8e2..7ab6928247a769727e4d600d0b88666122fd63fc 100644 (file)
@@ -57,7 +57,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_reg.h"
 #include "r300_emit.h"
 #include "r300_context.h"
-#include "r300_queryobj.h"
 
 #include "vblank.h"
 
@@ -755,19 +754,9 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
        }
 }
 
-static void r300Flush(GLcontext *ctx)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-       radeonFlush(ctx);
-
-       make_empty_list(&r300->query.not_flushed_head);
-}
-
-
 void r300InitIoctlFuncs(struct dd_function_table *functions)
 {
        functions->Clear = r300Clear;
        functions->Finish = radeonFinish;
-       functions->Flush = r300Flush;
+       functions->Flush = radeonFlush;
 }
diff --git a/src/mesa/drivers/dri/r300/r300_queryobj.c b/src/mesa/drivers/dri/r300/r300_queryobj.c
deleted file mode 100644 (file)
index df1fb32..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright © 2008-2009 Maciej Cencora <m.cencora@gmail.com>
- *
- * 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Maciej Cencora <m.cencora@gmail.com>
- *
- */
-
-#include "r300_queryobj.h"
-#include "r300_emit.h"
-
-#include "main/imports.h"
-#include "main/simple_list.h"
-
-#define DDEBUG 0
-
-#define PAGE_SIZE 4096
-
-static void r300QueryGetResult(GLcontext *ctx, struct gl_query_object *q)
-{
-       struct r300_query_object *query = (struct r300_query_object *)q;
-       uint32_t *result;
-       int i;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, result %d\n", __FUNCTION__, query->Base.Id, (int) query->Base.Result);
-
-       radeon_bo_map(query->bo, GL_FALSE);
-
-       result = query->bo->ptr;
-
-       query->Base.Result = 0;
-       for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
-               query->Base.Result += result[i];
-               if (DDEBUG) fprintf(stderr, "result[%d] = %d\n", i, result[i]);
-       }
-
-       radeon_bo_unmap(query->bo);
-}
-
-static struct gl_query_object * r300NewQueryObject(GLcontext *ctx, GLuint id)
-{
-       struct r300_query_object *query;
-
-       query = _mesa_calloc(sizeof(struct r300_query_object));
-
-       query->Base.Id = id;
-       query->Base.Result = 0;
-       query->Base.Active = GL_FALSE;
-       query->Base.Ready = GL_TRUE;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
-
-       return &query->Base;
-}
-
-static void r300DeleteQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-       struct r300_query_object *query = (struct r300_query_object *)q;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-       if (query->bo) {
-               radeon_bo_unref(query->bo);
-       }
-
-       _mesa_free(query);
-}
-
-static void r300BeginQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-       struct r300_query_object *query = (struct r300_query_object *)q;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-       assert(r300->query.current == NULL);
-
-       if (!query->bo) {
-               query->bo = radeon_bo_open(r300->radeon.radeonScreen->bom, 0, PAGE_SIZE, PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
-       }
-       query->curr_offset = 0;
-
-       r300->query.current = query;
-       insert_at_tail(&r300->query.not_flushed_head, query);
-}
-
-static void r300EndQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-       r300EmitQueryEnd(ctx);
-
-       r300->query.current = NULL;
-}
-
-static void r300WaitQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-       struct r300_query_object *tmp, *query = (struct r300_query_object *)q;
-
-       /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
-       {
-               GLboolean found = GL_FALSE;
-               foreach(tmp, &r300->query.not_flushed_head) {
-                       if (tmp == query) {
-                               found = GL_TRUE;
-                               break;
-                       }
-               }
-
-               if (found)
-                       ctx->Driver.Flush(ctx);
-       }
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
-
-       r300QueryGetResult(ctx, q);
-
-       query->Base.Ready = GL_TRUE;
-}
-
-
-/**
- * TODO:
- * should check if bo is idle, bo there's no interface to do it
- * just wait for result now
- */
-static void r300CheckQuery(GLcontext *ctx, struct gl_query_object *q)
-{
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
-
-       r300WaitQuery(ctx, q);
-}
-
-void r300EmitQueryBegin(GLcontext *ctx)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-       struct r300_query_object *query = r300->query.current;
-       BATCH_LOCALS(&r300->radeon);
-
-       if (!query || query->emitted_begin)
-               return;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
-
-       if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
-               BEGIN_BATCH_NO_AUTOSTATE(4);
-               OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
-               OUT_BATCH_REGVAL(R300_ZB_ZPASS_DATA, 0);
-               END_BATCH();
-       } else {
-               BEGIN_BATCH_NO_AUTOSTATE(4);
-               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
-               OUT_BATCH_REGVAL(R300_ZB_ZPASS_DATA, 0);
-               END_BATCH();
-       }
-
-       query->emitted_begin = GL_TRUE;
-}
-
-void r300EmitQueryEnd(GLcontext *ctx)
-{
-       r300ContextPtr r300 = R300_CONTEXT(ctx);
-       struct r300_query_object *query = r300->query.current;
-       BATCH_LOCALS(&r300->radeon);
-
-       if (!query || !query->emitted_begin)
-               return;
-
-       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
-
-       radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs,
-                                                                 query->bo,
-                                                                 0, RADEON_GEM_DOMAIN_GTT);
-
-       if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
-               BEGIN_BATCH_NO_AUTOSTATE(14);
-               OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
-               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-               OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
-               OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
-               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-               OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-               OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
-               END_BATCH();
-       } else {
-               BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->num_z_pipes + 2);
-               switch (r300->num_z_pipes) {
-                       case 4:
-                               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
-                               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-                               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-                       case 3:
-                               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
-                               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-                               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-                       case 2:
-                               if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
-                                       OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
-                               } else {
-                                       OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
-                               }
-                               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-                               OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
-                       case 1:
-                       default:
-                               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
-                               OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
-                               OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
-                               break;
-               }
-               OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
-               END_BATCH();
-       }
-
-       query->curr_offset += r300->num_z_pipes * sizeof(uint32_t);
-       assert(query->curr_offset < PAGE_SIZE);
-       query->emitted_begin = GL_FALSE;
-}
-
-void r300InitQueryObjFunctions(struct dd_function_table *functions)
-{
-       functions->NewQueryObject = r300NewQueryObject;
-       functions->DeleteQuery = r300DeleteQuery;
-       functions->BeginQuery = r300BeginQuery;
-       functions->EndQuery = r300EndQuery;
-       functions->CheckQuery = r300CheckQuery;
-       functions->WaitQuery = r300WaitQuery;
-}
diff --git a/src/mesa/drivers/dri/r300/r300_queryobj.h b/src/mesa/drivers/dri/r300/r300_queryobj.h
deleted file mode 100644 (file)
index f301f0b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright © 2008 Maciej Cencora <m.cencora@gmail.com>
- *
- * 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- *
- * Authors:
- *    Maciej Cencora <m.cencora@gmail.com>
- *
- */
-
-#include "main/imports.h"
-#include "r300_context.h"
-
-extern void r300EmitQueryBegin(GLcontext *ctx);
-extern void r300EmitQueryEnd(GLcontext *ctx);
-
-extern void r300InitQueryObjFunctions(struct dd_function_table *functions);
index 45330cda3c11ad36effcff43e498ac747c403b9e..e1a6fae57f380c326fc73e5119689a5ff01518b5 100644 (file)
@@ -76,7 +76,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_tex.h"
 #include "r300_emit.h"
 #include "r300_fragprog_common.h"
-#include "r300_queryobj.h"
 #include "r300_swtcl.h"
 
 /**
index 6081c337864244e523c6f3e481cbbe82ceef69ed..ce0666b90193efad559a5a16e8d8665202aad277 100644 (file)
@@ -471,7 +471,7 @@ static void r300SetEarlyZState(GLcontext * ctx)
                topZ = R300_ZTOP_DISABLE;
        else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill)
                topZ = R300_ZTOP_DISABLE;
-       else if (r300->query.current)
+       else if (r300->radeon.query.current)
                topZ = R300_ZTOP_DISABLE;
 
        if (topZ != r300->hw.zstencil_format.cmd[2]) {
index a634cb5192da8f2e5a8dd4d978dff09d8e7f4fd7..9d6f7568799b474cf2b95fe1e6db474aca3e4a52 100644 (file)
@@ -39,6 +39,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_emit.h"
 #include "r300_tex.h"
 #include "r300_render.h"
+#include "main/simple_list.h"
 
 #define EMIT_ATTR( ATTR, STYLE )                                       \
 do {                                                                   \
@@ -617,7 +618,7 @@ void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
     r300_emit_scissor(ctx);
        r300EmitVertexAOS(rmesa,
                        rmesa->radeon.swtcl.vertex_size,
-                       rmesa->radeon.dma.current,
+                       first_elem(&rmesa->radeon.dma.reserved)->bo,
                        current_offset);
 
        r300EmitVbufPrim(rmesa,
index 6f489ace7bf537efa24cbd95dc46214a98bc862b..f030451b282209fe152a7d85a72b90d8e414209f 100644 (file)
@@ -43,6 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/enums.h"
+#include "main/simple_list.h"
 
 #include "r300_context.h"
 #include "r300_state.h"
@@ -323,7 +324,7 @@ GLboolean r300ValidateBuffers(GLcontext * ctx)
                                                          RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
        }
 
-       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
        if (ret)
                return GL_FALSE;
        return GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.c b/src/mesa/drivers/dri/r300/radeon_queryobj.c
new file mode 120000 (symlink)
index 0000000..1d6ebc1
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.h b/src/mesa/drivers/dri/r300/radeon_queryobj.h
new file mode 120000 (symlink)
index 0000000..8f6f842
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h
\ No newline at end of file
index 5bdc1afbf07edee8736522759f8e4f7e41074f89..3c3100ab914d38e2ee0fd8837f9a04202bb8c838 100644 (file)
@@ -36,7 +36,8 @@ RADEON_COMMON_SOURCES = \
        radeon_cs_legacy.c \
        radeon_mipmap_tree.c \
        radeon_span.c \
-       radeon_fbo.c
+       radeon_fbo.c \
+       radeon_queryobj.c
 
 DRIVER_SOURCES = \
                 radeon_screen.c \
index dc2fb0144a28a23676b76f7908610d60d18c260e..38814b6d71e5d9b5ccfd038a1fe276713789e851 100644 (file)
@@ -129,10 +129,10 @@ int r600_cs_write_reloc(struct radeon_cs *cs,
             }
             relocs[i].indices = indices;
             relocs[i].reloc_indices = reloc_indices;
-            relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1;
-            relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->section_cdw;
-            cs->section_ndw += 2;
+            relocs[i].indices[relocs[i].cindices - 1] = cs->cdw;
+            relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->cdw;
             cs->section_cdw += 2;
+           cs->cdw += 2;
 
             return 0;
         }
@@ -156,10 +156,10 @@ int r600_cs_write_reloc(struct radeon_cs *cs,
         return -ENOMEM;
     }
 
-    relocs[cs->crelocs].indices[0] = cs->cdw - 1;
-    relocs[cs->crelocs].reloc_indices[0] = cs->section_cdw;
-    cs->section_ndw += 2;
+    relocs[cs->crelocs].indices[0] = cs->cdw;
+    relocs[cs->crelocs].reloc_indices[0] = cs->cdw;
     cs->section_cdw += 2;
+    cs->cdw += 2;
     relocs[cs->crelocs].cindices = 1;
     cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
     cs->crelocs++;
@@ -183,7 +183,14 @@ static int r600_cs_begin(struct radeon_cs *cs,
         return -EPIPE;
     }
 
-    if (cs->cdw + ndw + 32 > cs->ndw) { /* Left 32 DWORD (8 offset+pitch) spare room for reloc indices */
+    cs->section = 1;
+    cs->section_ndw = ndw;
+    cs->section_cdw = 0;
+    cs->section_file = file;
+    cs->section_func = func;
+    cs->section_line = line;
+
+    if (cs->cdw + ndw > cs->ndw) {
         uint32_t tmp, *ptr;
        int num = (ndw > 0x3FF) ? ndw : 0x3FF;
 
@@ -196,13 +203,6 @@ static int r600_cs_begin(struct radeon_cs *cs,
         cs->ndw = tmp;
     }
 
-    cs->section = 1;
-    cs->section_ndw = 0; 
-    cs->section_cdw = cs->cdw + ndw; /* start of reloc indices. */
-    cs->section_file = file;
-    cs->section_func = func;
-    cs->section_line = line;
-
     return 0;
 }
 
@@ -219,8 +219,7 @@ static int r600_cs_end(struct radeon_cs *cs,
     }
     cs->section = 0;
 
-    if ( (cs->section_ndw + cs->cdw) != cs->section_cdw ) 
-    {
+    if ( cs->section_ndw != cs->section_cdw ) {
         fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
                 cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
         fprintf(stderr, "cs->section_ndw = %d, cs->cdw = %d, cs->section_cdw = %d \n",
@@ -230,7 +229,6 @@ static int r600_cs_end(struct radeon_cs *cs,
         return -EPIPE;
     }
 
-    cs->cdw = cs->section_cdw;
     return 0;
 }
 
@@ -453,12 +451,10 @@ struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_cont
 
 void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
 {
-    radeonContextPtr rmesa = &r600->radeon;
-    GLuint size;
-    rmesa->hw.max_state_size = 4000; /* rough estimate */
+       radeonContextPtr rmesa = &r600->radeon;
+       GLuint size;
 
-    rmesa->hw.all_dirty = GL_TRUE;
-    rmesa->hw.is_dirty = GL_TRUE;
+       r600InitAtoms(r600);
 
        /* Initialize command buffer */
        size = 256 * driQueryOptioni(&rmesa->optionCache,
@@ -482,7 +478,7 @@ void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
        rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
        assert(rmesa->cmdbuf.cs != NULL);
        rmesa->cmdbuf.size = size;
-       
+
        if (!rmesa->radeonScreen->kernel_mm) {
                radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
                radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
index 5df0cf1ab61e5cecea2be612750d4b9d4ae3e8f2..06eddf2eeef780a5bdb483fffbd51632206c0392 100644 (file)
@@ -143,6 +143,9 @@ extern int r600_cs_write_reloc(struct radeon_cs *cs,
 static inline void r600_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
 {
     cs->packets[cs->cdw++] = dword;
+    if (cs->section) {
+           cs->section_cdw++;
+    }
 }
 
 struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_context *ctx);
@@ -175,7 +178,6 @@ struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_cont
             fprintf(stderr, "(%s:%s:%d) offset : %d\n",                \
             __FILE__, __FUNCTION__, __LINE__, offset);         \
         }                                                      \
-        r600_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset);     \
         r600_cs_write_reloc(b_l_rmesa->cmdbuf.cs,              \
                               bo, rd, wd, flags);              \
        } while(0)
index 7009374b0ca71fec157f50c949666309f35b2008..4489064c0d09fd852fd01bf75db72c7ea15c697f 100644 (file)
@@ -247,8 +247,6 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
         */
        _mesa_init_driver_functions(&functions);
 
-       r700InitChipObject(r600);  /* let the eag... */
-
        r700InitStateFuncs(&functions);
        r600InitTextureFuncs(&functions);
        r700InitShaderFuncs(&functions);
@@ -386,18 +384,4 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
        return GL_TRUE;
 }
 
-/* Clean our own things only, radeonDestroyContext will do every thing else. */
-void
-r600DestroyContext (__DRIcontextPrivate * driContextPriv)
-{
-    GET_CURRENT_CONTEXT (ctx);
-    context_t *context = ctx ? R700_CONTEXT(ctx) : NULL;
-
-    if (context)
-           FREE(context->hw.pStateList);
-
-    radeonDestroyContext(driContextPriv);
-}
-
-
 
index 30ddce682c191f3b1283a3fad0057635cab5dbfa..a9b080baa312ec8cec81a22d3561b67b5cd94a6f 100644 (file)
@@ -55,28 +55,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 struct r600_context;
 typedef struct r600_context context_t;
 
-GLboolean r700SendPSState(context_t *context);
-GLboolean r700SendVSState(context_t *context);
-GLboolean r700SendSQConfig(context_t *context);
+extern GLboolean r700SendPSState(context_t *context);
+extern GLboolean r700SendVSState(context_t *context);
+extern GLboolean r700SendFSState(context_t *context);
 
 #include "main/mm.h"
 
-/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
-   I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
-   with other compilers ... GLUE!
-*/
-#define WARN_ONCE(a, ...)      { \
-       static int warn##__LINE__=1; \
-       if(warn##__LINE__){ \
-               fprintf(stderr, "*********************************WARN_ONCE*********************************\n"); \
-               fprintf(stderr, "File %s function %s line %d\n", \
-                       __FILE__, __FUNCTION__, __LINE__); \
-               fprintf(stderr,  a, ## __VA_ARGS__);\
-               fprintf(stderr, "***************************************************************************\n"); \
-               warn##__LINE__=0;\
-               } \
-       }
-
 /************ DMA BUFFERS **************/
 
 /* The blit width for texture uploads
@@ -128,6 +112,22 @@ enum
     RIGHT_SHIFT = 2,
 };
 
+struct r600_hw_state {
+       struct radeon_state_atom sq;
+       struct radeon_state_atom db;
+       struct radeon_state_atom db_target;
+       struct radeon_state_atom sc;
+       struct radeon_state_atom cl;
+       struct radeon_state_atom ucp;
+       struct radeon_state_atom su;
+       struct radeon_state_atom cb;
+       struct radeon_state_atom cb_target;
+       struct radeon_state_atom sx;
+       struct radeon_state_atom vgt;
+       struct radeon_state_atom spi;
+       struct radeon_state_atom vpt;
+};
+
 /**
  * \brief R600 context structure.
  */
@@ -137,6 +137,8 @@ struct r600_context {
        /* ------ */
        R700_CHIP_CONTEXT hw;
 
+       struct r600_hw_state atoms;
+
        /* Vertex buffers
         */
        GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
@@ -147,22 +149,26 @@ struct r600_context {
 #define R700_CONTEXT(ctx)              ((context_t *)(ctx->DriverCtx))
 #define GL_CONTEXT(context)     ((GLcontext *)(context->radeon.glCtx))
 
-extern void r600DestroyContext(__DRIcontextPrivate * driContextPriv);
 extern GLboolean r600CreateContext(const __GLcontextModes * glVisual,
                                   __DRIcontextPrivate * driContextPriv,
                                   void *sharedContextPrivate);
 
 #define R700_CONTEXT_STATES(context) ((R700_CHIP_CONTEXT *)(&context->hw))
 
-extern GLboolean r700InitChipObject(context_t *context);
-extern GLboolean r700SendContextStates(context_t *context);
-extern GLboolean r700SendViewportState(context_t *context, int id);
-extern GLboolean r700SendRenderTargetState(context_t *context, int id);
+#define R600_NEWPRIM( rmesa )                  \
+do {                                           \
+       if ( rmesa->radeon.dma.flush )                  \
+               rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \
+} while (0)
+
+#define R600_STATECHANGE(r600, ATOM)                   \
+do {                                                   \
+       R600_NEWPRIM(r600);                                     \
+       r600->atoms.ATOM.dirty = GL_TRUE;                                       \
+       r600->radeon.hw.is_dirty = GL_TRUE;                     \
+} while(0)
+
 extern GLboolean r700SendTextureState(context_t *context);
-extern GLboolean r700SendDepthTargetState(context_t *context);
-extern GLboolean r700SendUCPState(context_t *context);
-extern GLboolean r700SendFSState(context_t *context);
-extern void r700EmitState(GLcontext * ctx);
 
 extern GLboolean r700SyncSurf(context_t *context,
                              struct radeon_bo *pbo,
@@ -178,6 +184,8 @@ extern void      r700SetupVTXConstants(GLcontext  * ctx,
                                       unsigned int stride,
                                       unsigned int Count);    /* number of vectors in stream */
 
+extern void r600InitAtoms(context_t *context);
+
 #define RADEON_D_CAPTURE 0
 #define RADEON_D_PLAYBACK 1
 #define RADEON_D_PLAYBACK_RAW 2
index b695ed958389d22faa2365e94b80cc4cac03dfb3..b0c7294682a198fa278b06eca5a3193ba8c01ada 100644 (file)
@@ -49,7 +49,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 void r600EmitCacheFlush(context_t *rmesa)
 {
-       BATCH_LOCALS(&rmesa->radeon);
 }
 
 GLboolean r600EmitShader(GLcontext * ctx, 
index ee9b64ee43af089637427abdb8ba9b22b21890b1..1057d7d8bbff2ebc61d6518db651607d88396e61 100644 (file)
@@ -43,6 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/teximage.h"
 #include "main/texobj.h"
 #include "main/enums.h"
+#include "main/simple_list.h"
 
 #include "r600_context.h"
 #include "r700_state.h"
@@ -685,7 +686,7 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
                                                          RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
        }
 
-       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+       ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
        if (ret)
                return GL_FALSE;
        return GL_TRUE;
index 0fb355a0b6a4a8e9894f5d1024a54b5b1c72d793..2d68f021dfc2b7d82c4081a47338002555dd6475 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "main/imports.h"
 #include "main/glheader.h"
+#include "main/simple_list.h"
 
 #include "r600_context.h"
 #include "r600_cmdbuf.h"
 
 #include "radeon_mipmap_tree.h"
 
-#define LINK_STATES(reg)                                            \
-do                                                                  \
-{                                                                   \
-    pStateListWork->puiValue = (unsigned int*)&(r700->reg);         \
-    pStateListWork->unOffset = mm##reg - ASIC_CONTEXT_BASE_INDEX; \
-    pStateListWork->pNext    = pStateListWork + 1;                  \
-    pStateListWork++;                                               \
-}while(0)
-
-GLboolean r700InitChipObject(context_t *context)
-{
-    ContextState * pStateListWork;
-
-    R700_CHIP_CONTEXT *r700 = &context->hw;
-
-    /* init state list */
-    r700->pStateList = (ContextState*) MALLOC (sizeof(ContextState)*sizeof(R700_CHIP_CONTEXT)/sizeof(unsigned int));
-    pStateListWork = r700->pStateList;
-
-    // misc
-    LINK_STATES(TA_CNTL_AUX);
-    LINK_STATES(VC_ENHANCE);
-    LINK_STATES(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ);
-    LINK_STATES(DB_DEBUG);
-    LINK_STATES(DB_WATERMARKS);
-
-    // SC
-    LINK_STATES(PA_SC_SCREEN_SCISSOR_TL);
-    LINK_STATES(PA_SC_SCREEN_SCISSOR_BR);
-    LINK_STATES(PA_SC_WINDOW_OFFSET);
-    LINK_STATES(PA_SC_WINDOW_SCISSOR_TL);
-    LINK_STATES(PA_SC_WINDOW_SCISSOR_BR);
-    LINK_STATES(PA_SC_CLIPRECT_RULE);
-    LINK_STATES(PA_SC_CLIPRECT_0_TL);
-    LINK_STATES(PA_SC_CLIPRECT_0_BR);
-    LINK_STATES(PA_SC_CLIPRECT_1_TL);
-    LINK_STATES(PA_SC_CLIPRECT_1_BR);
-    LINK_STATES(PA_SC_CLIPRECT_2_TL);
-    LINK_STATES(PA_SC_CLIPRECT_2_BR);
-    LINK_STATES(PA_SC_CLIPRECT_3_TL);
-    LINK_STATES(PA_SC_CLIPRECT_3_BR);
-    LINK_STATES(PA_SC_EDGERULE);
-    LINK_STATES(PA_SC_GENERIC_SCISSOR_TL);
-    LINK_STATES(PA_SC_GENERIC_SCISSOR_BR);
-    LINK_STATES(PA_SC_LINE_STIPPLE);
-    LINK_STATES(PA_SC_MPASS_PS_CNTL);
-    LINK_STATES(PA_SC_MODE_CNTL);
-    LINK_STATES(PA_SC_LINE_CNTL);
-    LINK_STATES(PA_SC_AA_CONFIG);
-    LINK_STATES(PA_SC_AA_SAMPLE_LOCS_MCTX);
-    LINK_STATES(PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX);
-    LINK_STATES(PA_SC_AA_MASK);
-
-    // SU
-    LINK_STATES(PA_SU_POINT_SIZE);
-    LINK_STATES(PA_SU_POINT_MINMAX);
-    LINK_STATES(PA_SU_LINE_CNTL);
-    LINK_STATES(PA_SU_SC_MODE_CNTL);
-    LINK_STATES(PA_SU_VTX_CNTL);
-    LINK_STATES(PA_SU_POLY_OFFSET_DB_FMT_CNTL);
-    LINK_STATES(PA_SU_POLY_OFFSET_CLAMP);
-    LINK_STATES(PA_SU_POLY_OFFSET_FRONT_SCALE);
-    LINK_STATES(PA_SU_POLY_OFFSET_FRONT_OFFSET);
-    LINK_STATES(PA_SU_POLY_OFFSET_BACK_SCALE);
-    LINK_STATES(PA_SU_POLY_OFFSET_BACK_OFFSET);
-
-    // CL
-    LINK_STATES(PA_CL_CLIP_CNTL);
-    LINK_STATES(PA_CL_VTE_CNTL);
-    LINK_STATES(PA_CL_VS_OUT_CNTL);
-    LINK_STATES(PA_CL_NANINF_CNTL);
-    LINK_STATES(PA_CL_GB_VERT_CLIP_ADJ);
-    LINK_STATES(PA_CL_GB_VERT_DISC_ADJ);
-    LINK_STATES(PA_CL_GB_HORZ_CLIP_ADJ);
-    LINK_STATES(PA_CL_GB_HORZ_DISC_ADJ);
-
-    // CB
-    LINK_STATES(CB_CLEAR_RED_R6XX);
-    LINK_STATES(CB_CLEAR_GREEN_R6XX);
-    LINK_STATES(CB_CLEAR_BLUE_R6XX);
-    LINK_STATES(CB_CLEAR_ALPHA_R6XX);
-    LINK_STATES(CB_TARGET_MASK);
-    LINK_STATES(CB_SHADER_MASK);
-    LINK_STATES(CB_BLEND_RED);
-    LINK_STATES(CB_BLEND_GREEN);
-    LINK_STATES(CB_BLEND_BLUE);
-    LINK_STATES(CB_BLEND_ALPHA);
-    LINK_STATES(CB_FOG_RED_R6XX);
-    LINK_STATES(CB_FOG_GREEN_R6XX);
-    LINK_STATES(CB_FOG_BLUE_R6XX);
-    LINK_STATES(CB_SHADER_CONTROL);
-    LINK_STATES(CB_COLOR_CONTROL);
-    LINK_STATES(CB_CLRCMP_CONTROL);
-    LINK_STATES(CB_CLRCMP_SRC);
-    LINK_STATES(CB_CLRCMP_DST);
-    LINK_STATES(CB_CLRCMP_MSK);
-    LINK_STATES(CB_BLEND_CONTROL);
-
-    //DB
-    LINK_STATES(DB_HTILE_DATA_BASE);
-    LINK_STATES(DB_STENCIL_CLEAR);
-    LINK_STATES(DB_DEPTH_CLEAR);
-    LINK_STATES(DB_STENCILREFMASK);
-    LINK_STATES(DB_STENCILREFMASK_BF);
-    LINK_STATES(DB_DEPTH_CONTROL);
-    LINK_STATES(DB_SHADER_CONTROL);
-    LINK_STATES(DB_RENDER_CONTROL);
-    LINK_STATES(DB_RENDER_OVERRIDE);
-    LINK_STATES(DB_HTILE_SURFACE);
-    LINK_STATES(DB_ALPHA_TO_MASK);
-
-    // SX
-    LINK_STATES(SX_MISC);
-    LINK_STATES(SX_ALPHA_TEST_CONTROL);
-    LINK_STATES(SX_ALPHA_REF);
-
-    // VGT
-    LINK_STATES(VGT_MAX_VTX_INDX);
-    LINK_STATES(VGT_MIN_VTX_INDX);
-    LINK_STATES(VGT_INDX_OFFSET);
-    LINK_STATES(VGT_MULTI_PRIM_IB_RESET_INDX);
-    LINK_STATES(VGT_OUTPUT_PATH_CNTL);
-    LINK_STATES(VGT_HOS_CNTL);
-    LINK_STATES(VGT_HOS_MAX_TESS_LEVEL);
-    LINK_STATES(VGT_HOS_MIN_TESS_LEVEL);
-    LINK_STATES(VGT_HOS_REUSE_DEPTH);
-    LINK_STATES(VGT_GROUP_PRIM_TYPE);
-    LINK_STATES(VGT_GROUP_FIRST_DECR);
-    LINK_STATES(VGT_GROUP_DECR);
-    LINK_STATES(VGT_GROUP_VECT_0_CNTL);
-    LINK_STATES(VGT_GROUP_VECT_1_CNTL);
-    LINK_STATES(VGT_GROUP_VECT_0_FMT_CNTL);
-    LINK_STATES(VGT_GROUP_VECT_1_FMT_CNTL);
-    LINK_STATES(VGT_GS_MODE);
-    LINK_STATES(VGT_PRIMITIVEID_EN);
-    LINK_STATES(VGT_MULTI_PRIM_IB_RESET_EN);
-    LINK_STATES(VGT_INSTANCE_STEP_RATE_0);
-    LINK_STATES(VGT_INSTANCE_STEP_RATE_1);
-    LINK_STATES(VGT_STRMOUT_EN);
-    LINK_STATES(VGT_REUSE_OFF);
-    LINK_STATES(VGT_VTX_CNT_EN);
-    LINK_STATES(VGT_STRMOUT_BUFFER_EN);
-
-    LINK_STATES(SQ_VTX_SEMANTIC_0);
-    LINK_STATES(SQ_VTX_SEMANTIC_1);
-    LINK_STATES(SQ_VTX_SEMANTIC_2);
-    LINK_STATES(SQ_VTX_SEMANTIC_3);
-    LINK_STATES(SQ_VTX_SEMANTIC_4);
-    LINK_STATES(SQ_VTX_SEMANTIC_5);
-    LINK_STATES(SQ_VTX_SEMANTIC_6);
-    LINK_STATES(SQ_VTX_SEMANTIC_7);
-    LINK_STATES(SQ_VTX_SEMANTIC_8);
-    LINK_STATES(SQ_VTX_SEMANTIC_9);
-    LINK_STATES(SQ_VTX_SEMANTIC_10);
-    LINK_STATES(SQ_VTX_SEMANTIC_11);
-    LINK_STATES(SQ_VTX_SEMANTIC_12);
-    LINK_STATES(SQ_VTX_SEMANTIC_13);
-    LINK_STATES(SQ_VTX_SEMANTIC_14);
-    LINK_STATES(SQ_VTX_SEMANTIC_15);
-    LINK_STATES(SQ_VTX_SEMANTIC_16);
-    LINK_STATES(SQ_VTX_SEMANTIC_17);
-    LINK_STATES(SQ_VTX_SEMANTIC_18);
-    LINK_STATES(SQ_VTX_SEMANTIC_19);
-    LINK_STATES(SQ_VTX_SEMANTIC_20);
-    LINK_STATES(SQ_VTX_SEMANTIC_21);
-    LINK_STATES(SQ_VTX_SEMANTIC_22);
-    LINK_STATES(SQ_VTX_SEMANTIC_23);
-    LINK_STATES(SQ_VTX_SEMANTIC_24);
-    LINK_STATES(SQ_VTX_SEMANTIC_25);
-    LINK_STATES(SQ_VTX_SEMANTIC_26);
-    LINK_STATES(SQ_VTX_SEMANTIC_27);
-    LINK_STATES(SQ_VTX_SEMANTIC_28);
-    LINK_STATES(SQ_VTX_SEMANTIC_29);
-    LINK_STATES(SQ_VTX_SEMANTIC_30);
-    LINK_STATES(SQ_VTX_SEMANTIC_31);
-
-    // SPI
-    LINK_STATES(SPI_VS_OUT_ID_0);
-    LINK_STATES(SPI_VS_OUT_ID_1);
-    LINK_STATES(SPI_VS_OUT_ID_2);
-    LINK_STATES(SPI_VS_OUT_ID_3);
-    LINK_STATES(SPI_VS_OUT_ID_4);
-    LINK_STATES(SPI_VS_OUT_ID_5);
-    LINK_STATES(SPI_VS_OUT_ID_6);
-    LINK_STATES(SPI_VS_OUT_ID_7);
-    LINK_STATES(SPI_VS_OUT_ID_8);
-    LINK_STATES(SPI_VS_OUT_ID_9);
-
-    LINK_STATES(SPI_VS_OUT_CONFIG);
-    LINK_STATES(SPI_THREAD_GROUPING);
-    LINK_STATES(SPI_PS_IN_CONTROL_0);
-    LINK_STATES(SPI_PS_IN_CONTROL_1);
-    LINK_STATES(SPI_INTERP_CONTROL_0);
-    LINK_STATES(SPI_INPUT_Z);
-    LINK_STATES(SPI_FOG_CNTL);
-    LINK_STATES(SPI_FOG_FUNC_SCALE);
-    LINK_STATES(SPI_FOG_FUNC_BIAS);
-
-    // SQ
-    LINK_STATES(SQ_ESGS_RING_ITEMSIZE);
-    LINK_STATES(SQ_GSVS_RING_ITEMSIZE);
-    LINK_STATES(SQ_ESTMP_RING_ITEMSIZE);
-    LINK_STATES(SQ_GSTMP_RING_ITEMSIZE);
-    LINK_STATES(SQ_VSTMP_RING_ITEMSIZE);
-    LINK_STATES(SQ_PSTMP_RING_ITEMSIZE);
-    LINK_STATES(SQ_FBUF_RING_ITEMSIZE);
-    LINK_STATES(SQ_REDUC_RING_ITEMSIZE);
-    //LINK_STATES(SQ_GS_VERT_ITEMSIZE);
-
-    pStateListWork->puiValue = (unsigned int*)&(r700->SQ_GS_VERT_ITEMSIZE);
-    pStateListWork->unOffset = mmSQ_GS_VERT_ITEMSIZE - ASIC_CONTEXT_BASE_INDEX;
-    pStateListWork->pNext    = NULL;  /* END OF STATE LIST */
-
-    return GL_TRUE;
-}
-
 GLboolean r700SendTextureState(context_t *context)
 {
     unsigned int i;
@@ -276,11 +61,16 @@ GLboolean r700SendTextureState(context_t *context)
                                         RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
                                         0, TC_ACTION_ENA_bit);
 
-                           BEGIN_BATCH_NO_AUTOSTATE(9);
+                           BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
                            R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
                            R600_OUT_BATCH(i * 7);
                            R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
                            R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
+                           R600_OUT_BATCH(0); /* r700->textures[i]->SQ_TEX_RESOURCE2 */
+                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE3);
+                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
+                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
+                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
                            R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
                                                 bo,
                                                 0,
@@ -289,9 +79,6 @@ GLboolean r700SendTextureState(context_t *context)
                                                 bo,
                                                 r700->textures[i]->SQ_TEX_RESOURCE3,
                                                 RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
-                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
-                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
-                           R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
                            END_BATCH();
 
                            BEGIN_BATCH_NO_AUTOSTATE(5);
@@ -362,22 +149,21 @@ void r700SetupVTXConstants(GLcontext  * ctx,
     SETfield(uSQ_VTX_CONSTANT_WORD6_0, SQ_TEX_VTX_VALID_BUFFER,
             SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
 
-    BEGIN_BATCH_NO_AUTOSTATE(9);
+    BEGIN_BATCH_NO_AUTOSTATE(9 + 2);
 
     R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
     R600_OUT_BATCH((nStreamID + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE);
-
-    R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0,
-                         paos->bo,
-                         uSQ_VTX_CONSTANT_WORD0_0,
-                         RADEON_GEM_DOMAIN_GTT, 0, 0);
+    R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD0_0);
     R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD1_0);
     R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD2_0);
     R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD3_0);
     R600_OUT_BATCH(0);
     R600_OUT_BATCH(0);
     R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD6_0);
-
+    R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0,
+                         paos->bo,
+                         uSQ_VTX_CONSTANT_WORD0_0,
+                         RADEON_GEM_DOMAIN_GTT, 0, 0);
     END_BATCH();
     COMMIT_BATCH();
 
@@ -408,7 +194,6 @@ int r700SetupStreams(GLcontext * ctx)
     END_BATCH();
     COMMIT_BATCH();
 
-    context->radeon.tcl.aos_count = 0;
        for(i=0; i<VERT_ATTRIB_MAX; i++)
        {
                unBit = 1 << i;
@@ -429,83 +214,16 @@ int r700SetupStreams(GLcontext * ctx)
                                              (unsigned int)context->radeon.tcl.aos[j].stride * 4,
                                              (unsigned int)context->radeon.tcl.aos[j].count);
                        j++;
-                       context->radeon.tcl.aos_count++;
                }
        }
+       context->radeon.tcl.aos_count = j;
 
     return R600_FALLBACK_NONE;
 }
 
-GLboolean r700SendContextStates(context_t *context)
-{
-    BATCH_LOCALS(&context->radeon);
-
-    R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
-
-    ContextState * pState = r700->pStateList;
-    ContextState * pInit;
-    unsigned int   toSend;
-    unsigned int   ui;
-
-    while(NULL != pState)
-    {
-        toSend = 1;
-
-        pInit = pState;
-
-       while(NULL != pState->pNext)
-       {
-                if ((pState->pNext->unOffset - pState->unOffset) > 1)
-                {
-                       break;
-                }
-                else
-                {
-                       pState = pState->pNext;
-                       toSend++;
-                }
-       }
-
-        pState = pState->pNext;
-
-        BEGIN_BATCH_NO_AUTOSTATE(toSend + 2);
-        R600_OUT_BATCH_REGSEQ(((pInit->unOffset + ASIC_CONTEXT_BASE_INDEX)<<2), toSend);
-        for(ui=0; ui<toSend; ui++)
-        {
-                R600_OUT_BATCH(*(pInit->puiValue));
-               pInit = pInit->pNext;
-        };
-        END_BATCH();
-    };
-
-    /* todo:
-     * - split this into a separate function?
-     * - only emit the ones we use
-     */
-    BEGIN_BATCH_NO_AUTOSTATE(2 + R700_MAX_SHADER_EXPORTS);
-    R600_OUT_BATCH_REGSEQ(SPI_PS_INPUT_CNTL_0, R700_MAX_SHADER_EXPORTS);
-    for(ui = 0; ui < R700_MAX_SHADER_EXPORTS; ui++)
-           R600_OUT_BATCH(r700->SPI_PS_INPUT_CNTL[ui].u32All);
-    END_BATCH();
-
-    if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
-           for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
-                   if (r700->render_target[ui].enabled) {
-                           BEGIN_BATCH_NO_AUTOSTATE(3);
-                           R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * ui),
-                                                 r700->render_target[ui].CB_BLEND0_CONTROL.u32All);
-                           END_BATCH();
-                   }
-           }
-    }
-
-    COMMIT_BATCH();
-
-    return GL_TRUE;
-}
-
-GLboolean r700SendDepthTargetState(context_t *context)
+static void r700SendDepthTargetState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
        struct radeon_renderbuffer *rrb;
        BATCH_LOCALS(&context->radeon);
@@ -513,19 +231,20 @@ GLboolean r700SendDepthTargetState(context_t *context)
        rrb = radeon_get_depthbuffer(&context->radeon);
        if (!rrb || !rrb->bo) {
                fprintf(stderr, "no rrb\n");
-               return GL_FALSE;
+               return;
        }
 
-        BEGIN_BATCH_NO_AUTOSTATE(8);
+        BEGIN_BATCH_NO_AUTOSTATE(8 + 2);
        R600_OUT_BATCH_REGSEQ(DB_DEPTH_SIZE, 2);
        R600_OUT_BATCH(r700->DB_DEPTH_SIZE.u32All);
        R600_OUT_BATCH(r700->DB_DEPTH_VIEW.u32All);
        R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 2);
+       R600_OUT_BATCH(r700->DB_DEPTH_BASE.u32All);
+       R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All);
        R600_OUT_BATCH_RELOC(r700->DB_DEPTH_BASE.u32All,
                             rrb->bo,
                             r700->DB_DEPTH_BASE.u32All,
                             0, RADEON_GEM_DOMAIN_VRAM, 0);
-       R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All);
         END_BATCH();
 
        if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) &&
@@ -538,32 +257,31 @@ GLboolean r700SendDepthTargetState(context_t *context)
 
        COMMIT_BATCH();
 
-       r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
-                    DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
-
-       return GL_TRUE;
 }
 
-GLboolean r700SendRenderTargetState(context_t *context, int id)
+static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
        struct radeon_renderbuffer *rrb;
        BATCH_LOCALS(&context->radeon);
+       int id = 0;
 
        rrb = radeon_get_colorbuffer(&context->radeon);
        if (!rrb || !rrb->bo) {
                fprintf(stderr, "no rrb\n");
-               return GL_FALSE;
+               return;
        }
 
        if (id > R700_MAX_RENDER_TARGETS)
-               return GL_FALSE;
+               return;
 
        if (!r700->render_target[id].enabled)
-               return GL_FALSE;
+               return;
 
-        BEGIN_BATCH_NO_AUTOSTATE(3);
+        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
        R600_OUT_BATCH_REGSEQ(CB_COLOR0_BASE + (4 * id), 1);
+       R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_BASE.u32All);
        R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All,
                             rrb->bo,
                             r700->render_target[id].CB_COLOR0_BASE.u32All,
@@ -589,10 +307,6 @@ GLboolean r700SendRenderTargetState(context_t *context, int id)
 
        COMMIT_BATCH();
 
-       r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
-                    CB_ACTION_ENA_bit | (1 << (id + 6)));
-
-       return GL_TRUE;
 }
 
 GLboolean r700SendPSState(context_t *context)
@@ -608,8 +322,9 @@ GLboolean r700SendPSState(context_t *context)
 
        r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
 
-        BEGIN_BATCH_NO_AUTOSTATE(3);
+        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
        R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1);
+       R600_OUT_BATCH(r700->ps.SQ_PGM_START_PS.u32All);
        R600_OUT_BATCH_RELOC(r700->ps.SQ_PGM_START_PS.u32All,
                             pbo,
                             r700->ps.SQ_PGM_START_PS.u32All,
@@ -624,6 +339,8 @@ GLboolean r700SendPSState(context_t *context)
 
        COMMIT_BATCH();
 
+       r700->ps.dirty = GL_FALSE;
+
        return GL_TRUE;
 }
 
@@ -640,8 +357,9 @@ GLboolean r700SendVSState(context_t *context)
 
        r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
 
-        BEGIN_BATCH_NO_AUTOSTATE(3);
+        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
        R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1);
+       R600_OUT_BATCH(r700->vs.SQ_PGM_START_VS.u32All);
        R600_OUT_BATCH_RELOC(r700->vs.SQ_PGM_START_VS.u32All,
                             pbo,
                             r700->vs.SQ_PGM_START_VS.u32All,
@@ -655,6 +373,8 @@ GLboolean r700SendVSState(context_t *context)
 
        COMMIT_BATCH();
 
+       r700->vs.dirty = GL_FALSE;
+
        return GL_TRUE;
 }
 
@@ -680,8 +400,9 @@ GLboolean r700SendFSState(context_t *context)
 
        r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
 
-        BEGIN_BATCH_NO_AUTOSTATE(3);
+        BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
        R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1);
+       R600_OUT_BATCH(r700->fs.SQ_PGM_START_FS.u32All);
        R600_OUT_BATCH_RELOC(r700->fs.SQ_PGM_START_FS.u32All,
                             pbo,
                             r700->fs.SQ_PGM_START_FS.u32All,
@@ -695,19 +416,23 @@ GLboolean r700SendFSState(context_t *context)
 
        COMMIT_BATCH();
 
+       r700->fs.dirty = GL_FALSE;
+
        return GL_TRUE;
 }
 
-GLboolean r700SendViewportState(context_t *context, int id)
+static void r700SendViewportState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
        BATCH_LOCALS(&context->radeon);
+       int id = 0;
 
        if (id > R700_MAX_VIEWPORTS)
-               return GL_FALSE;
+               return;
 
        if (!r700->viewport[id].enabled)
-               return GL_FALSE;
+               return;
 
         BEGIN_BATCH_NO_AUTOSTATE(16);
        R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_SCISSOR_0_TL + (8 * id), 2);
@@ -727,15 +452,15 @@ GLboolean r700SendViewportState(context_t *context, int id)
 
        COMMIT_BATCH();
 
-       return GL_TRUE;
 }
 
-GLboolean r700SendSQConfig(context_t *context)
+static void r700SendSQConfig(GLcontext *ctx, struct radeon_state_atom *atom)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
        BATCH_LOCALS(&context->radeon);
 
-        BEGIN_BATCH_NO_AUTOSTATE(8);
+        BEGIN_BATCH_NO_AUTOSTATE(34);
        R600_OUT_BATCH_REGSEQ(SQ_CONFIG, 6);
        R600_OUT_BATCH(r700->sq_config.SQ_CONFIG.u32All);
        R600_OUT_BATCH(r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All);
@@ -743,14 +468,31 @@ GLboolean r700SendSQConfig(context_t *context)
        R600_OUT_BATCH(r700->sq_config.SQ_THREAD_RESOURCE_MGMT.u32All);
        R600_OUT_BATCH(r700->sq_config.SQ_STACK_RESOURCE_MGMT_1.u32All);
        R600_OUT_BATCH(r700->sq_config.SQ_STACK_RESOURCE_MGMT_2.u32All);
+
+       R600_OUT_BATCH_REGVAL(TA_CNTL_AUX, r700->TA_CNTL_AUX.u32All);
+       R600_OUT_BATCH_REGVAL(VC_ENHANCE, r700->VC_ENHANCE.u32All);
+       R600_OUT_BATCH_REGVAL(R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, r700->SQ_DYN_GPR_CNTL_PS_FLUSH_REQ.u32All);
+       R600_OUT_BATCH_REGVAL(DB_DEBUG, r700->DB_DEBUG.u32All);
+       R600_OUT_BATCH_REGVAL(DB_WATERMARKS, r700->DB_WATERMARKS.u32All);
+
+       R600_OUT_BATCH_REGSEQ(SQ_ESGS_RING_ITEMSIZE, 9);
+       R600_OUT_BATCH(r700->SQ_ESGS_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_GSVS_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_ESTMP_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_GSTMP_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_VSTMP_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_PSTMP_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_FBUF_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_REDUC_RING_ITEMSIZE.u32All);
+       R600_OUT_BATCH(r700->SQ_GS_VERT_ITEMSIZE.u32All);
         END_BATCH();
-       COMMIT_BATCH();
 
-       return GL_TRUE;
+       COMMIT_BATCH();
 }
 
-GLboolean r700SendUCPState(context_t *context)
+static void r700SendUCPState(GLcontext *ctx, struct radeon_state_atom *atom)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
        BATCH_LOCALS(&context->radeon);
        int i;
@@ -767,7 +509,366 @@ GLboolean r700SendUCPState(context_t *context)
                        COMMIT_BATCH();
                }
        }
+}
 
-       return GL_TRUE;
+static void r700SendSPIState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+       unsigned int ui;
+
+       BEGIN_BATCH_NO_AUTOSTATE(59 + R700_MAX_SHADER_EXPORTS);
+
+       R600_OUT_BATCH_REGSEQ(SQ_VTX_SEMANTIC_0, 32);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_0.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_1.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_2.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_3.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_4.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_5.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_6.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_7.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_8.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_9.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_10.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_11.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_12.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_13.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_14.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_15.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_16.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_17.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_18.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_19.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_20.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_21.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_22.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_23.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_24.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_25.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_26.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_27.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_28.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_29.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_30.u32All);
+       R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_31.u32All);
+
+       R600_OUT_BATCH_REGSEQ(SPI_VS_OUT_ID_0, 10);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_0.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_1.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_2.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_3.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_4.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_5.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_6.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_7.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_8.u32All);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_ID_9.u32All);
+
+       R600_OUT_BATCH_REGSEQ(SPI_VS_OUT_CONFIG, 9);
+       R600_OUT_BATCH(r700->SPI_VS_OUT_CONFIG.u32All);
+       R600_OUT_BATCH(r700->SPI_THREAD_GROUPING.u32All);
+       R600_OUT_BATCH(r700->SPI_PS_IN_CONTROL_0.u32All);
+       R600_OUT_BATCH(r700->SPI_PS_IN_CONTROL_1.u32All);
+       R600_OUT_BATCH(r700->SPI_INTERP_CONTROL_0.u32All);
+       R600_OUT_BATCH(r700->SPI_INPUT_Z.u32All);
+       R600_OUT_BATCH(r700->SPI_FOG_CNTL.u32All);
+       R600_OUT_BATCH(r700->SPI_FOG_FUNC_SCALE.u32All);
+       R600_OUT_BATCH(r700->SPI_FOG_FUNC_BIAS.u32All);
+
+       R600_OUT_BATCH_REGSEQ(SPI_PS_INPUT_CNTL_0, R700_MAX_SHADER_EXPORTS);
+       for(ui = 0; ui < R700_MAX_SHADER_EXPORTS; ui++)
+               R600_OUT_BATCH(r700->SPI_PS_INPUT_CNTL[ui].u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
 }
 
+static void r700SendVGTState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+        BEGIN_BATCH_NO_AUTOSTATE(41);
+
+       R600_OUT_BATCH_REGSEQ(VGT_MAX_VTX_INDX, 4);
+       R600_OUT_BATCH(r700->VGT_MAX_VTX_INDX.u32All);
+       R600_OUT_BATCH(r700->VGT_MIN_VTX_INDX.u32All);
+       R600_OUT_BATCH(r700->VGT_INDX_OFFSET.u32All);
+       R600_OUT_BATCH(r700->VGT_MULTI_PRIM_IB_RESET_INDX.u32All);
+
+       R600_OUT_BATCH_REGSEQ(VGT_OUTPUT_PATH_CNTL, 13);
+       R600_OUT_BATCH(r700->VGT_OUTPUT_PATH_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_HOS_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_HOS_MAX_TESS_LEVEL.u32All);
+       R600_OUT_BATCH(r700->VGT_HOS_MIN_TESS_LEVEL.u32All);
+       R600_OUT_BATCH(r700->VGT_HOS_REUSE_DEPTH.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_PRIM_TYPE.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_FIRST_DECR.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_DECR.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_VECT_0_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_VECT_1_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_VECT_0_FMT_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_GROUP_VECT_1_FMT_CNTL.u32All);
+       R600_OUT_BATCH(r700->VGT_GS_MODE.u32All);
+
+       R600_OUT_BATCH_REGVAL(VGT_PRIMITIVEID_EN, r700->VGT_PRIMITIVEID_EN.u32All);
+       R600_OUT_BATCH_REGVAL(VGT_MULTI_PRIM_IB_RESET_EN, r700->VGT_MULTI_PRIM_IB_RESET_EN.u32All);
+       R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_0, r700->VGT_INSTANCE_STEP_RATE_0.u32All);
+       R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_1, r700->VGT_INSTANCE_STEP_RATE_1.u32All);
+
+       R600_OUT_BATCH_REGSEQ(VGT_STRMOUT_EN, 3);
+       R600_OUT_BATCH(r700->VGT_STRMOUT_EN.u32All);
+       R600_OUT_BATCH(r700->VGT_REUSE_OFF.u32All);
+       R600_OUT_BATCH(r700->VGT_VTX_CNT_EN.u32All);
+
+       R600_OUT_BATCH_REGVAL(VGT_STRMOUT_BUFFER_EN, r700->VGT_STRMOUT_BUFFER_EN.u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
+}
+
+static void r700SendSXState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+        BEGIN_BATCH_NO_AUTOSTATE(9);
+       R600_OUT_BATCH_REGVAL(SX_MISC, r700->SX_MISC.u32All);
+       R600_OUT_BATCH_REGVAL(SX_ALPHA_TEST_CONTROL, r700->SX_ALPHA_TEST_CONTROL.u32All);
+       R600_OUT_BATCH_REGVAL(SX_ALPHA_REF, r700->SX_ALPHA_REF.u32All);
+       END_BATCH();
+       COMMIT_BATCH();
+}
+
+static void r700SendDBState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+        BEGIN_BATCH_NO_AUTOSTATE(27);
+       R600_OUT_BATCH_REGVAL(DB_HTILE_DATA_BASE, r700->DB_HTILE_DATA_BASE.u32All);
+
+       R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
+       R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
+       R600_OUT_BATCH(r700->DB_DEPTH_CLEAR.u32All);
+
+       R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
+       R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
+       R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
+
+       R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, r700->DB_DEPTH_CONTROL.u32All);
+       R600_OUT_BATCH_REGVAL(DB_SHADER_CONTROL, r700->DB_SHADER_CONTROL.u32All);
+
+       R600_OUT_BATCH_REGSEQ(DB_RENDER_CONTROL, 2);
+       R600_OUT_BATCH(r700->DB_RENDER_CONTROL.u32All);
+       R600_OUT_BATCH(r700->DB_RENDER_OVERRIDE.u32All);
+
+       R600_OUT_BATCH_REGVAL(DB_HTILE_SURFACE, r700->DB_HTILE_SURFACE.u32All);
+       R600_OUT_BATCH_REGVAL(DB_ALPHA_TO_MASK, r700->DB_ALPHA_TO_MASK.u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
+}
+
+static void r700SendCBState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+       unsigned int ui;
+
+       if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) {
+               BEGIN_BATCH_NO_AUTOSTATE(14);
+               R600_OUT_BATCH_REGSEQ(CB_CLEAR_RED, 4);
+               R600_OUT_BATCH(r700->CB_CLEAR_RED_R6XX.u32All);
+               R600_OUT_BATCH(r700->CB_CLEAR_GREEN_R6XX.u32All);
+               R600_OUT_BATCH(r700->CB_CLEAR_BLUE_R6XX.u32All);
+               R600_OUT_BATCH(r700->CB_CLEAR_ALPHA_R6XX.u32All);
+               R600_OUT_BATCH_REGSEQ(CB_FOG_RED, 3);
+               R600_OUT_BATCH(r700->CB_FOG_RED_R6XX.u32All);
+               R600_OUT_BATCH(r700->CB_FOG_GREEN_R6XX.u32All);
+               R600_OUT_BATCH(r700->CB_FOG_BLUE_R6XX.u32All);
+               /* R600 does not have per-MRT blend */
+               R600_OUT_BATCH_REGVAL(CB_BLEND_CONTROL, r700->CB_BLEND_CONTROL.u32All);
+               END_BATCH();
+       }
+
+       BEGIN_BATCH_NO_AUTOSTATE(22);
+       R600_OUT_BATCH_REGSEQ(CB_TARGET_MASK, 2);
+       R600_OUT_BATCH(r700->CB_TARGET_MASK.u32All);
+       R600_OUT_BATCH(r700->CB_SHADER_MASK.u32All);
+
+       R600_OUT_BATCH_REGSEQ(CB_BLEND_RED, 4);
+       R600_OUT_BATCH(r700->CB_BLEND_RED.u32All);
+       R600_OUT_BATCH(r700->CB_BLEND_GREEN.u32All);
+       R600_OUT_BATCH(r700->CB_BLEND_BLUE.u32All);
+       R600_OUT_BATCH(r700->CB_BLEND_ALPHA.u32All);
+
+       R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, r700->CB_SHADER_CONTROL.u32All);
+       R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, r700->CB_COLOR_CONTROL.u32All);
+
+       R600_OUT_BATCH_REGSEQ(CB_CLRCMP_CONTROL, 4);
+       R600_OUT_BATCH(r700->CB_CLRCMP_CONTROL.u32All);
+       R600_OUT_BATCH(r700->CB_CLRCMP_SRC.u32All);
+       R600_OUT_BATCH(r700->CB_CLRCMP_DST.u32All);
+       R600_OUT_BATCH(r700->CB_CLRCMP_MSK.u32All);
+       END_BATCH();
+
+       if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
+               for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
+                       if (r700->render_target[ui].enabled) {
+                               BEGIN_BATCH_NO_AUTOSTATE(3);
+                               R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * ui),
+                                                     r700->render_target[ui].CB_BLEND0_CONTROL.u32All);
+                               END_BATCH();
+                       }
+               }
+       }
+
+       COMMIT_BATCH();
+
+}
+
+static void r700SendSUState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+       BEGIN_BATCH_NO_AUTOSTATE(19);
+       R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, r700->PA_SU_SC_MODE_CNTL.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_SU_POINT_SIZE, 4);
+       R600_OUT_BATCH(r700->PA_SU_POINT_SIZE.u32All);
+       R600_OUT_BATCH(r700->PA_SU_POINT_MINMAX.u32All);
+       R600_OUT_BATCH(r700->PA_SU_LINE_CNTL.u32All);
+       R600_OUT_BATCH(r700->PA_SU_VTX_CNTL.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_DB_FMT_CNTL, 2);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_CLAMP.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_FRONT_SCALE, 4);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_SCALE.u32All);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.u32All);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_SCALE.u32All);
+       R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_OFFSET.u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
+
+}
+
+static void r700SendCLState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+       BEGIN_BATCH_NO_AUTOSTATE(18);
+       R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, r700->PA_CL_CLIP_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, r700->PA_CL_VTE_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, r700->PA_CL_VS_OUT_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_CL_NANINF_CNTL, r700->PA_CL_NANINF_CNTL.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_CL_GB_VERT_CLIP_ADJ, 4);
+       R600_OUT_BATCH(r700->PA_CL_GB_VERT_CLIP_ADJ.u32All);
+       R600_OUT_BATCH(r700->PA_CL_GB_VERT_DISC_ADJ.u32All);
+       R600_OUT_BATCH(r700->PA_CL_GB_HORZ_CLIP_ADJ.u32All);
+       R600_OUT_BATCH(r700->PA_CL_GB_HORZ_DISC_ADJ.u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
+}
+
+// XXX need to split this up
+static void r700SendSCState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+       BATCH_LOCALS(&context->radeon);
+
+       BEGIN_BATCH_NO_AUTOSTATE(47);
+       R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2);
+       R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_BR.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 13);
+       R600_OUT_BATCH(r700->PA_SC_WINDOW_OFFSET.u32All);
+       R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_BR.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_RULE.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_0_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_0_BR.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_1_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_1_BR.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_2_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_2_BR.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_BR.u32All);
+       R600_OUT_BATCH(r700->PA_SC_EDGERULE.u32All);
+
+       R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2);
+       R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_TL.u32All);
+       R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_BR.u32All);
+
+       R600_OUT_BATCH_REGVAL(PA_SC_LINE_STIPPLE, r700->PA_SC_LINE_STIPPLE.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_MPASS_PS_CNTL, r700->PA_SC_MPASS_PS_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_MODE_CNTL, r700->PA_SC_MODE_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_LINE_CNTL, r700->PA_SC_LINE_CNTL.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_AA_CONFIG, r700->PA_SC_AA_CONFIG.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_MCTX.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX.u32All);
+       R600_OUT_BATCH_REGVAL(PA_SC_AA_MASK, r700->PA_SC_AA_MASK.u32All);
+
+       END_BATCH();
+       COMMIT_BATCH();
+}
+
+static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       return atom->cmd_size;
+}
+
+#define ALLOC_STATE( ATOM, SZ, EMIT )                                  \
+do {                                                                   \
+      context->atoms.ATOM.cmd_size = (SZ);                                     \
+      context->atoms.ATOM.cmd = NULL;                                  \
+      context->atoms.ATOM.name = #ATOM;                                        \
+      context->atoms.ATOM.idx = 0;                                             \
+      context->atoms.ATOM.check = check_always;                                \
+      context->atoms.ATOM.dirty = GL_FALSE;                            \
+      context->atoms.ATOM.emit = (EMIT);                                       \
+      context->radeon.hw.max_state_size += (SZ);                       \
+      insert_at_tail(&context->radeon.hw.atomlist, &context->atoms.ATOM); \
+} while (0)
+
+void r600InitAtoms(context_t *context)
+{
+
+       /* Setup the atom linked list */
+       make_empty_list(&context->radeon.hw.atomlist);
+       context->radeon.hw.atomlist.name = "atom-list";
+
+       ALLOC_STATE(sq, 34, r700SendSQConfig);
+       ALLOC_STATE(db, 27, r700SendDBState);
+       ALLOC_STATE(db_target, 19, r700SendDepthTargetState);
+       ALLOC_STATE(sc, 47, r700SendSCState);
+       ALLOC_STATE(cl, 18, r700SendCLState);
+       ALLOC_STATE(ucp, 36, r700SendUCPState);
+       ALLOC_STATE(su, 19, r700SendSUState);
+       ALLOC_STATE(cb, 39, r700SendCBState);
+       ALLOC_STATE(cb_target, 32, r700SendRenderTargetState);
+       ALLOC_STATE(sx, 9, r700SendSXState);
+       ALLOC_STATE(vgt, 41, r700SendVGTState);
+       ALLOC_STATE(spi, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
+       ALLOC_STATE(vpt, 16, r700SendViewportState);
+
+       context->radeon.hw.is_dirty = GL_TRUE;
+       context->radeon.hw.all_dirty = GL_TRUE;
+}
index 4e89c75f2f9dcac6733ec9d71e285cd2dc708410..c0ec4b0dd593a346a8923f3aae74ac2c798cd8a9 100644 (file)
@@ -188,6 +188,7 @@ typedef struct _RENDER_TARGET_STATE_STRUCT
        union UINT_FLOAT                CB_COLOR0_MASK;  /* 0xA040 */
        union UINT_FLOAT                CB_BLEND0_CONTROL;  /* 0xA1E0 */
        GLboolean                         enabled;
+       GLboolean                         dirty;
 } RENDER_TARGET_STATE_STRUCT;
 
 typedef struct _VIEWPORT_STATE_STRUCT
@@ -203,6 +204,7 @@ typedef struct _VIEWPORT_STATE_STRUCT
        union UINT_FLOAT        PA_CL_VPORT_ZSCALE;        /* 0xA113 */
        union UINT_FLOAT        PA_CL_VPORT_ZOFFSET;       /* 0xA114 */
        GLboolean                         enabled;
+       GLboolean                         dirty;
 } VIEWPORT_STATE_STRUCT;
 
 typedef struct _UCP_STATE_STRUCT
@@ -212,6 +214,7 @@ typedef struct _UCP_STATE_STRUCT
        union UINT_FLOAT        PA_CL_UCP_0_Z;
        union UINT_FLOAT        PA_CL_UCP_0_W;
        GLboolean                         enabled;
+       GLboolean                         dirty;
 } UCP_STATE_STRUCT;
 
 typedef struct _PS_STATE_STRUCT
@@ -220,6 +223,7 @@ typedef struct _PS_STATE_STRUCT
        union UINT_FLOAT                SQ_PGM_RESOURCES_PS       ;  /* 0xA214 */
        union UINT_FLOAT                SQ_PGM_EXPORTS_PS         ;  /* 0xA215 */
        union UINT_FLOAT                SQ_PGM_CF_OFFSET_PS       ;  /* 0xA233 */
+       GLboolean                         dirty;
 } PS_STATE_STRUCT;
 
 typedef struct _VS_STATE_STRUCT
@@ -227,6 +231,7 @@ typedef struct _VS_STATE_STRUCT
        union UINT_FLOAT                SQ_PGM_START_VS           ;  /* 0xA216 */
        union UINT_FLOAT                SQ_PGM_RESOURCES_VS       ;  /* 0xA21A */
        union UINT_FLOAT                SQ_PGM_CF_OFFSET_VS       ;  /* 0xA234 */
+       GLboolean                         dirty;
 } VS_STATE_STRUCT;
 
 typedef struct _GS_STATE_STRUCT
@@ -234,6 +239,7 @@ typedef struct _GS_STATE_STRUCT
        union UINT_FLOAT                SQ_PGM_START_GS           ;  /* 0xA21B */
        union UINT_FLOAT                SQ_PGM_RESOURCES_GS       ;  /* 0xA21F */
        union UINT_FLOAT                SQ_PGM_CF_OFFSET_GS       ;  /* 0xA235 */
+       GLboolean                         dirty;
 } GS_STATE_STRUCT;
 
 typedef struct _ES_STATE_STRUCT
@@ -241,6 +247,7 @@ typedef struct _ES_STATE_STRUCT
        union UINT_FLOAT                SQ_PGM_START_ES           ;  /* 0xA220 */
        union UINT_FLOAT                SQ_PGM_RESOURCES_ES       ;  /* 0xA224 */
        union UINT_FLOAT                SQ_PGM_CF_OFFSET_ES       ;  /* 0xA236 */
+       GLboolean                         dirty;
 } ES_STATE_STRUCT;
 
 typedef struct _FS_STATE_STRUCT
@@ -248,6 +255,7 @@ typedef struct _FS_STATE_STRUCT
        union UINT_FLOAT                SQ_PGM_START_FS           ;  /* 0xA225 */
        union UINT_FLOAT                SQ_PGM_RESOURCES_FS       ;  /* 0xA229 */
        union UINT_FLOAT                SQ_PGM_CF_OFFSET_FS       ;  /* 0xA237 */
+       GLboolean                         dirty;
 } FS_STATE_STRUCT;
 
 typedef struct _SQ_CONFIG_STRUCT
@@ -260,27 +268,14 @@ typedef struct _SQ_CONFIG_STRUCT
        union UINT_FLOAT                SQ_STACK_RESOURCE_MGMT_2  ;  /* 0x2305 */
 } SQ_CONFIG_STRUCT;
 
-typedef struct ContextState
-{
-    unsigned int * puiValue;
-    unsigned int   unOffset;
-    struct ContextState * pNext;
-} ContextState;
-
 typedef struct _R700_CHIP_CONTEXT
 {
-       // misc
-       union UINT_FLOAT                TA_CNTL_AUX               ;  /* 0x2542 */
-       union UINT_FLOAT                VC_ENHANCE                ;  /* 0x25C5 */
-       union UINT_FLOAT                SQ_DYN_GPR_CNTL_PS_FLUSH_REQ;  /* 0x2363 */
-       union UINT_FLOAT                DB_DEBUG                  ;  /* 0x260C */
-       union UINT_FLOAT                DB_WATERMARKS             ;  /* 0x260E */
-
        // DB
        union UINT_FLOAT                DB_DEPTH_SIZE             ;  /* 0xA000 */
        union UINT_FLOAT                DB_DEPTH_VIEW             ;  /* 0xA001 */
        union UINT_FLOAT                DB_DEPTH_BASE             ;  /* 0xA003 */
        union UINT_FLOAT                DB_DEPTH_INFO             ;  /* 0xA004 */
+       GLboolean                       db_target_dirty;
        union UINT_FLOAT                DB_HTILE_DATA_BASE        ;  /* 0xA005 */
        union UINT_FLOAT                DB_STENCIL_CLEAR          ;  /* 0xA00A */
        union UINT_FLOAT                DB_DEPTH_CLEAR            ;  /* 0xA00B */
@@ -292,6 +287,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                DB_ALPHA_TO_MASK          ;  /* 0xA351 */
        union UINT_FLOAT                DB_DEPTH_CONTROL          ;  /* 0xA200 */
        union UINT_FLOAT                DB_SHADER_CONTROL         ;  /* 0xA203 */
+       GLboolean                       db_dirty;
 
        // SC
        union UINT_FLOAT                PA_SC_SCREEN_SCISSOR_TL   ;  /* 0xA00C */
@@ -311,6 +307,8 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                PA_SC_EDGERULE            ;  /* 0xA08C */
        union UINT_FLOAT                PA_SC_GENERIC_SCISSOR_TL  ;  /* 0xA090 */
        union UINT_FLOAT                PA_SC_GENERIC_SCISSOR_BR  ;  /* 0xA091 */
+       GLboolean                       scissor_dirty;
+
        union UINT_FLOAT                PA_SC_LINE_STIPPLE        ;  /* 0xA283 */
        union UINT_FLOAT                PA_SC_LINE_CNTL           ;  /* 0xA300 */
        union UINT_FLOAT                PA_SC_AA_CONFIG           ;  /* 0xA301 */
@@ -319,6 +317,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                PA_SC_AA_SAMPLE_LOCS_MCTX ;  /* 0xA307 */
        union UINT_FLOAT                PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX; /* 0xA308 */
        union UINT_FLOAT                PA_SC_AA_MASK             ;  /* 0xA312 */
+       GLboolean                       sc_dirty;
 
        // CL
        union UINT_FLOAT                PA_CL_CLIP_CNTL           ;  /* 0xA204 */
@@ -329,6 +328,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                PA_CL_GB_VERT_DISC_ADJ    ;  /* 0xA304 */
        union UINT_FLOAT                PA_CL_GB_HORZ_CLIP_ADJ    ;  /* 0xA305 */
        union UINT_FLOAT                PA_CL_GB_HORZ_DISC_ADJ    ;  /* 0xA306 */
+       GLboolean                       cl_dirty;
 
        // SU
        union UINT_FLOAT                PA_SU_SC_MODE_CNTL        ;  /* 0xA205 */
@@ -342,6 +342,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                PA_SU_POLY_OFFSET_FRONT_OFFSET; /* 0xA381 */
        union UINT_FLOAT                PA_SU_POLY_OFFSET_BACK_SCALE;    /* 0xA382 */
        union UINT_FLOAT                PA_SU_POLY_OFFSET_BACK_OFFSET;   /* 0xA383 */
+       GLboolean                       su_dirty;
 
        VIEWPORT_STATE_STRUCT           viewport[R700_MAX_VIEWPORTS];
        UCP_STATE_STRUCT                ucp[R700_MAX_UCP];
@@ -367,12 +368,14 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                CB_CLRCMP_DST             ;  /* 0xA30E */
        union UINT_FLOAT                CB_CLRCMP_MSK             ;  /* 0xA30F */
        union UINT_FLOAT                CB_BLEND_CONTROL          ;  /* 0xABD0 */
+       GLboolean                       cb_dirty;
        RENDER_TARGET_STATE_STRUCT      render_target[R700_MAX_RENDER_TARGETS];
 
        // SX
        union UINT_FLOAT                SX_MISC                   ;  /* 0xA0D4 */
        union UINT_FLOAT                SX_ALPHA_TEST_CONTROL     ;  /* 0xA104 */
        union UINT_FLOAT                SX_ALPHA_REF              ;  /* 0xA10E */
+       GLboolean                       sx_dirty;
 
        // VGT
        union UINT_FLOAT                VGT_MAX_VTX_INDX          ;  /* 0xA100 */
@@ -400,6 +403,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                VGT_REUSE_OFF             ;  /* 0xA2AD */
        union UINT_FLOAT                VGT_VTX_CNT_EN            ;  /* 0xA2AE */
        union UINT_FLOAT                VGT_STRMOUT_BUFFER_EN     ;  /* 0xA2C8 */
+       GLboolean                       vgt_dirty;
 
        // SPI
        union UINT_FLOAT                SPI_VS_OUT_ID_0           ;  /* 0xA185 */
@@ -454,8 +458,8 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                SQ_VTX_SEMANTIC_29        ;  /* 0xA0FD */
        union UINT_FLOAT                SQ_VTX_SEMANTIC_30        ;  /* 0xA0FE */
        union UINT_FLOAT                SQ_VTX_SEMANTIC_31        ;  /* 0xA0FF */
-
-       union UINT_FLOAT        SPI_PS_INPUT_CNTL[R700_MAX_SHADER_EXPORTS];
+       union UINT_FLOAT                SPI_PS_INPUT_CNTL[R700_MAX_SHADER_EXPORTS];
+       GLboolean                       spi_dirty;
 
        // shaders
        PS_STATE_STRUCT                 ps;
@@ -466,7 +470,12 @@ typedef struct _R700_CHIP_CONTEXT
 
        // SQ CONFIG
        SQ_CONFIG_STRUCT                sq_config;
-
+       // misc
+       union UINT_FLOAT                TA_CNTL_AUX               ;  /* 0x2542 */
+       union UINT_FLOAT                VC_ENHANCE                ;  /* 0x25C5 */
+       union UINT_FLOAT                SQ_DYN_GPR_CNTL_PS_FLUSH_REQ;  /* 0x2363 */
+       union UINT_FLOAT                DB_DEBUG                  ;  /* 0x260C */
+       union UINT_FLOAT                DB_WATERMARKS             ;  /* 0x260E */
        // SQ
        union UINT_FLOAT                SQ_ESGS_RING_ITEMSIZE     ;  /* 0xA22A */
        union UINT_FLOAT                SQ_GSVS_RING_ITEMSIZE     ;  /* 0xA22B */
@@ -477,8 +486,7 @@ typedef struct _R700_CHIP_CONTEXT
        union UINT_FLOAT                SQ_FBUF_RING_ITEMSIZE     ;  /* 0xA230 */
        union UINT_FLOAT                SQ_REDUC_RING_ITEMSIZE    ;  /* 0xA231 */
        union UINT_FLOAT                SQ_GS_VERT_ITEMSIZE       ;  /* 0xA232 */
-
-       ContextState*                   pStateList;
+       GLboolean                       sq_dirty;
 
        radeonTexObj*                   textures[R700_TEXTURE_NUMBERUNITS];
 
index 05d4af331e04f1f6d62150e7f5137c407bfcdd88..6d4ea90ccc631b5a9edf64a77c842310461ae30b 100644 (file)
@@ -46,12 +46,6 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask)
     return GL_FALSE;
 }
 
-#define R600_NEWPRIM( rmesa )                  \
-  do {                                         \
-  if ( rmesa->radeon.dma.flush )                       \
-    rmesa->radeon.dma.flush( rmesa->radeon.glCtx );    \
-  } while (0)
-
 void r700Clear(GLcontext * ctx, GLbitfield mask)
 {
     context_t *context = R700_CONTEXT(ctx);
index 23cc128d6dbc391f8b67fd351f12dfd8956764b0..72a8978976718ada78274b0d4a01bc5e8f7d1b00 100644 (file)
@@ -31,6 +31,7 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/context.h"
+#include "main/simple_list.h"
 #include "swrast/swrast.h"
 
 #include "radeon_common.h"
 #include "r700_ioctl.h"
 #include "r700_clear.h"
 
-static void r700Flush(GLcontext *ctx)
-{
-       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
-
-       if (RADEON_DEBUG & DEBUG_IOCTL)
-               fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw);
-
-       /* okay if we have no cmds in the buffer &&
-          we have no DMA flush &&
-          we have no DMA buffer allocated.
-          then no point flushing anything at all.
-       */
-       if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current)
-               return;
-
-       if (radeon->dma.flush)
-               radeon->dma.flush( ctx );
-
-       r700EmitState(ctx);
-
-       if (radeon->cmdbuf.cs->cdw)
-               rcommonFlushCmdBuf(radeon, __FUNCTION__);
-}
 
 void r700InitIoctlFuncs(struct dd_function_table *functions)
 {
        functions->Clear = r700Clear;
        functions->Finish = radeonFinish;
-       functions->Flush = r700Flush;
+       functions->Flush = radeonFlush;
 }
index 6985bd4ffabcfe72460d179f87730ca325e5cd01..f0cd357c76506091f531ae8d570b50d581e7f3d9 100644 (file)
@@ -166,15 +166,16 @@ GLboolean r700SyncSurf(context_t *context,
     else
            cp_coher_size = ((pbo->size + 255) >> 8);
 
-    BEGIN_BATCH_NO_AUTOSTATE(5);
+    BEGIN_BATCH_NO_AUTOSTATE(5 + 2);
     R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
     R600_OUT_BATCH(sync_type);
     R600_OUT_BATCH(cp_coher_size);
+    R600_OUT_BATCH(0);
+    R600_OUT_BATCH(10);
     R600_OUT_BATCH_RELOC(0,
                         pbo,
                         0,
                         read_domain, write_domain, 0); // ???
-    R600_OUT_BATCH(10);
 
     END_BATCH();
     COMMIT_BATCH();
@@ -331,42 +332,28 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
 
 }
 
-void r700EmitState(GLcontext * ctx)
-{
-       context_t *context = R700_CONTEXT(ctx);
-       radeonContextPtr radeon = &context->radeon;
-
-       if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty)
-               return;
-
-       rcommonEnsureCmdBufSpace(&context->radeon,
-                                context->radeon.hw.max_state_size, __FUNCTION__);
-
-       r700SendSQConfig(context);
-
-       r700SendUCPState(context);
-       r700SendContextStates(context);
-       r700SendViewportState(context, 0);
-       r700SendRenderTargetState(context, 0);
-       r700SendDepthTargetState(context);
-
-}
-
 static GLboolean r700RunRender(GLcontext * ctx,
                                           struct tnl_pipeline_stage *stage)
 {
     context_t *context = R700_CONTEXT(ctx);
-    unsigned int i;
+    radeonContextPtr radeon = &context->radeon;
+    unsigned int i, ind_count = 0, id = 0;
     TNLcontext *tnl = TNL_CONTEXT(ctx);
     struct vertex_buffer *vb = &tnl->vb;
+    struct radeon_renderbuffer *rrb;
 
-    r700Start3D(context);
+    for (i = 0; i < vb->PrimitiveCount; i++)
+           ind_count += vb->Primitive[i].count + 10;
+
+    /* just an estimate, need to properly calculate this */
+    rcommonEnsureCmdBufSpace(&context->radeon,
+                            radeon->hw.max_state_size + ind_count + 1000, __FUNCTION__);
 
+    r700Start3D(context);
     r700UpdateShaders(ctx);
     r700SetScissor(context);
     r700SetupShaders(ctx);
-
-    r700EmitState(ctx);
+    radeonEmitState(radeon);
 
     /* richard test code */
     for (i = 0; i < vb->PrimitiveCount; i++) {
@@ -379,6 +366,16 @@ static GLboolean r700RunRender(GLcontext * ctx,
     /* Flush render op cached for last several quads. */
     r700WaitForIdleClean(context);
 
+    rrb = radeon_get_colorbuffer(&context->radeon);
+    if (!rrb || !rrb->bo)
+           r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+                        CB_ACTION_ENA_bit | (1 << (id + 6)));
+
+    rrb = radeon_get_depthbuffer(&context->radeon);
+    if (!rrb || !rrb->bo)
+           r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+                        DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
+
     radeonReleaseArrays(ctx, ~0);
 
     return GL_FALSE;
index 835b5e18c2cb5bb2a1e7b1210830433aa6b710d3..6b44cc0ceb669657f386309b445c2cdb8798a7db 100644 (file)
@@ -148,8 +148,15 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
        GLfloat tx = v[MAT_TX] + xoffset;
        GLfloat ty = (-v[MAT_TY]) + yoffset;
 
-       r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
-       r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
+       if (r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All != tx ||
+           r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All != ty) {
+               /* Note: this should also modify whatever data the context reset
+                * code uses...
+                */
+               R600_STATECHANGE(context, vpt);
+               r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
+               r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
+       }
 
        radeonUpdateScissor(ctx);
 }
@@ -161,6 +168,10 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
 void r700UpdateDrawBuffer(GLcontext * ctx) /* TODO */ //---------------------
 {
        context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
+       R600_STATECHANGE(context, cb_target);
+       R600_STATECHANGE(context, db_target);
 
        r700SetRenderTarget(context, 0);
        r700SetDepthTarget(context);
@@ -233,6 +244,9 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
 
        r700UpdateStateParameters(ctx, new_state);
 
+    R600_STATECHANGE(context, cl);
+    R600_STATECHANGE(context, spi);
+
     if(GL_TRUE == r700->bEnablePerspective)
     {
         /* Do scale XY and Z by 1/W0 for perspective correction on pos. For orthogonal case, set both to one. */
@@ -256,14 +270,15 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
         SETbit(r700->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
     }
 
-       context->radeon.NewGLState |= new_state;
+    context->radeon.NewGLState |= new_state;
 }
 
 static void r700SetDepthState(GLcontext * ctx)
 {
        context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
-    R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+       R600_STATECHANGE(context, db);
 
     if (ctx->Depth.Test)
     {
@@ -331,6 +346,8 @@ static void r700SetAlphaState(GLcontext * ctx)
        uint32_t alpha_func = REF_ALWAYS;
        GLboolean really_enabled = ctx->Color.AlphaEnabled;
 
+       R600_STATECHANGE(context, sx);
+
        switch (ctx->Color.AlphaFunc) {
        case GL_NEVER:
                alpha_func = REF_NEVER;
@@ -383,6 +400,8 @@ static void r700BlendColor(GLcontext * ctx, const GLfloat cf[4]) //-------------
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, cb);
+
        r700->CB_BLEND_RED.f32All = cf[0];
        r700->CB_BLEND_GREEN.f32All = cf[1];
        r700->CB_BLEND_BLUE.f32All = cf[2];
@@ -451,6 +470,8 @@ static void r700SetBlendState(GLcontext * ctx)
        int id = 0;
        uint32_t blend_reg = 0, eqn, eqnA;
 
+       R600_STATECHANGE(context, cb);
+
        if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
                SETfield(blend_reg,
                         BLEND_ONE, COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
@@ -637,8 +658,11 @@ static GLuint translate_logicop(GLenum logicop)
  */
 static void r700SetLogicOpState(GLcontext *ctx)
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
 
+       R600_STATECHANGE(context, cb);
+
        if (RGBA_LOGICOP_ENABLED(ctx))
                SETfield(r700->CB_COLOR_CONTROL.u32All,
                         translate_logicop(ctx->Color.LogicOp), ROP3_shift, ROP3_mask);
@@ -658,7 +682,10 @@ static void r700LogicOpcode(GLcontext *ctx, GLenum logicop)
 
 static void r700UpdateCulling(GLcontext * ctx)
 {
-    R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+
+    R600_STATECHANGE(context, su);
 
     CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, FACE_bit);
     CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
@@ -703,7 +730,11 @@ static void r700UpdateCulling(GLcontext * ctx)
 
 static void r700UpdateLineStipple(GLcontext * ctx)
 {
-    R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+       context_t *context = R700_CONTEXT(ctx);
+       R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+
+    R600_STATECHANGE(context, sc);
+
     if (ctx->Line.StippleFlag)
     {
        SETbit(r700->PA_SC_MODE_CNTL.u32All, LINE_STIPPLE_ENABLE_bit);
@@ -778,14 +809,17 @@ static void r700Enable(GLcontext * ctx, GLenum cap, GLboolean state) //---------
 static void r700ColorMask(GLcontext * ctx,
                          GLboolean r, GLboolean g, GLboolean b, GLboolean a) //------------------
 {
+       context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
        unsigned int mask = ((r ? 1 : 0) |
                             (g ? 2 : 0) |
                             (b ? 4 : 0) |
                             (a ? 8 : 0));
 
-       if (mask != r700->CB_SHADER_MASK.u32All)
+       if (mask != r700->CB_SHADER_MASK.u32All) {
+               R600_STATECHANGE(context, cb);
                SETfield(r700->CB_SHADER_MASK.u32All, mask, OUTPUT0_ENABLE_shift, OUTPUT0_ENABLE_mask);
+       }
 }
 
 /**
@@ -841,6 +875,8 @@ static void r700ShadeModel(GLcontext * ctx, GLenum mode) //--------------------
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, spi);
+
        /* also need to set/clear FLAT_SHADE bit per param in SPI_PS_INPUT_CNTL_[0-31] */
        switch (mode) {
        case GL_FLAT:
@@ -862,6 +898,8 @@ static void r700PointSize(GLcontext * ctx, GLfloat size)
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, su);
+
        /* We need to clamp to user defined range here, because
         * the HW clamping happens only for per vertex point size. */
        size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize);
@@ -882,6 +920,8 @@ static void r700PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, su);
+
        /* format is 12.4 fixed point */
        switch (pname) {
        case GL_POINT_SIZE_MIN:
@@ -966,6 +1006,7 @@ static void r700SetStencilState(GLcontext * ctx, GLboolean state)
        }
 
        if (hw_stencil) {
+               R600_STATECHANGE(context, db);
                if (state)
                        SETbit(r700->DB_DEPTH_CONTROL.u32All, STENCIL_ENABLE_bit);
                else
@@ -983,6 +1024,8 @@ static void r700StencilFuncSeparate(GLcontext * ctx, GLenum face,
        //fixme
        //r300CatchStencilFallback(ctx);
 
+       R600_STATECHANGE(context, db);
+
        //front
        SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.Ref[0],
                 STENCILREF_shift, STENCILREF_mask);
@@ -1012,6 +1055,8 @@ static void r700StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) /
        //fixme
        //r300CatchStencilFallback(ctx);
 
+       R600_STATECHANGE(context, db);
+
        // front
        SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.WriteMask[0],
                 STENCILWRITEMASK_shift, STENCILWRITEMASK_mask);
@@ -1032,6 +1077,8 @@ static void r700StencilOpSeparate(GLcontext * ctx, GLenum face,
        //fixme
        //r300CatchStencilFallback(ctx);
 
+       R600_STATECHANGE(context, db);
+
        SETfield(r700->DB_DEPTH_CONTROL.u32All, translate_stencil_op(ctx->Stencil.FailFunc[0]),
                 STENCILFAIL_shift, STENCILFAIL_mask);
        SETfield(r700->DB_DEPTH_CONTROL.u32All, translate_stencil_op(ctx->Stencil.ZFailFunc[0]),
@@ -1074,7 +1121,7 @@ static void r700UpdateWindow(GLcontext * ctx, int id) //--------------------
        GLfloat sz = v[MAT_SZ] * depthScale;
        GLfloat tz = v[MAT_TZ] * depthScale;
 
-       /* TODO : Need DMA flush as well. */
+       R600_STATECHANGE(context, vpt);
 
        r700->viewport[id].PA_CL_VPORT_XSCALE.f32All  = sx;
        r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
@@ -1112,10 +1159,13 @@ static void r700LineWidth(GLcontext * ctx, GLfloat widthf) //---------------
     context_t *context = R700_CONTEXT(ctx);
     R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
     uint32_t lineWidth = (uint32_t)((widthf * 0.5) * (1 << 4));
+
+    R600_STATECHANGE(context, su);
+
     if (lineWidth > 0xFFFF)
-       lineWidth = 0xFFFF;
+           lineWidth = 0xFFFF;
     SETfield(r700->PA_SU_LINE_CNTL.u32All,(uint16_t)lineWidth,
-       PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
+            PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
 }
 
 static void r700LineStipple(GLcontext *ctx, GLint factor, GLushort pattern)
@@ -1123,6 +1173,8 @@ static void r700LineStipple(GLcontext *ctx, GLint factor, GLushort pattern)
     context_t *context = R700_CONTEXT(ctx);
     R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+    R600_STATECHANGE(context, sc);
+
     SETfield(r700->PA_SC_LINE_STIPPLE.u32All, pattern, LINE_PATTERN_shift, LINE_PATTERN_mask);
     SETfield(r700->PA_SC_LINE_STIPPLE.u32All, (factor-1), REPEAT_COUNT_shift, REPEAT_COUNT_mask);
     SETfield(r700->PA_SC_LINE_STIPPLE.u32All, 1, AUTO_RESET_CNTL_shift, AUTO_RESET_CNTL_mask);
@@ -1133,6 +1185,8 @@ static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, su);
+
        if (state) {
                SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_FRONT_ENABLE_bit);
                SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_BACK_ENABLE_bit);
@@ -1161,6 +1215,8 @@ static void r700PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) //
 
        factor *= 12.0;
 
+       R600_STATECHANGE(context, su);
+
        r700->PA_SU_POLY_OFFSET_FRONT_SCALE.f32All = factor;
        r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.f32All = constant;
        r700->PA_SU_POLY_OFFSET_BACK_SCALE.f32All = factor;
@@ -1172,6 +1228,8 @@ static void r700UpdatePolygonMode(GLcontext * ctx)
        context_t *context = R700_CONTEXT(ctx);
        R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
 
+       R600_STATECHANGE(context, su);
+
        SETfield(r700->PA_SU_SC_MODE_CNTL.u32All, X_DISABLE_POLY_MODE, POLY_MODE_shift, POLY_MODE_mask);
 
        /* Only do something if a polygon mode is wanted, default is GL_FILL */
@@ -1247,6 +1305,8 @@ static void r700ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
        p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
        ip = (GLint *)ctx->Transform._ClipUserPlane[p];
 
+       R600_STATECHANGE(context, ucp);
+
        r700->ucp[p].PA_CL_UCP_0_X.u32All = ip[0];
        r700->ucp[p].PA_CL_UCP_0_Y.u32All = ip[1];
        r700->ucp[p].PA_CL_UCP_0_Z.u32All = ip[2];
@@ -1260,6 +1320,9 @@ static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state)
        GLuint p;
 
        p = cap - GL_CLIP_PLANE0;
+
+       R600_STATECHANGE(context, cl);
+
        if (state) {
                r700->PA_CL_CLIP_CNTL.u32All |= (UCP_ENA_0_bit << p);
                r700->ucp[p].enabled = GL_TRUE;
@@ -1293,6 +1356,8 @@ void r700SetScissor(context_t *context) //---------------
                y2 = rrb->dPriv->y + rrb->dPriv->h;
        }
 
+       R600_STATECHANGE(context, sc);
+
        /* window */
        SETbit(r700->PA_SC_WINDOW_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
        SETfield(r700->PA_SC_WINDOW_SCISSOR_TL.u32All, x1,
@@ -1361,6 +1426,9 @@ static void r700SetRenderTarget(context_t *context, int id)
            return;
     }
 
+    R600_STATECHANGE(context, cb_target);
+    R600_STATECHANGE(context, cb);
+
     /* screen/window/view */
     SETfield(r700->CB_TARGET_MASK.u32All, 0xF, (4 * id), TARGET0_ENABLE_mask);
 
@@ -1407,6 +1475,8 @@ static void r700SetDepthTarget(context_t *context)
     if (!rrb)
            return;
 
+    R600_STATECHANGE(context, db_target);
+
     /* depth buf */
     r700->DB_DEPTH_SIZE.u32All = 0;
     r700->DB_DEPTH_BASE.u32All = 0;
@@ -1467,6 +1537,8 @@ static void r700InitSQConfig(GLcontext * ctx)
     int num_gs_stack_entries;
     int num_es_stack_entries;
 
+    R600_STATECHANGE(context, sq);
+
     // SQ
     ps_prio = 0;
     vs_prio = 1;
diff --git a/src/mesa/drivers/dri/r600/radeon_queryobj.c b/src/mesa/drivers/dri/r600/radeon_queryobj.c
new file mode 120000 (symlink)
index 0000000..1d6ebc1
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c
\ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_queryobj.h b/src/mesa/drivers/dri/r600/radeon_queryobj.h
new file mode 120000 (symlink)
index 0000000..8f6f842
--- /dev/null
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h
\ No newline at end of file
index b59ad68f445d3ecb4c26d734e5359f3e32aaab17..6bf67d2ea590033d468b94b9a7aa70cb9c469f1b 100644 (file)
@@ -24,7 +24,8 @@ RADEON_COMMON_SOURCES = \
        radeon_cs_legacy.c \
        radeon_mipmap_tree.c \
        radeon_span.c \
-       radeon_fbo.c
+       radeon_fbo.c \
+       radeon_queryobj.c
 
 DRIVER_SOURCES = \
        radeon_context.c \
index 5575da69712402a602b75a4b91a7f1af9c6dfa36..b1cc155f71a34bc5e1336de885db43e827b9f283 100644 (file)
@@ -235,8 +235,9 @@ static int legacy_wait_pending(struct radeon_bo *bo)
     return 0;
 }
 
-static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
+void legacy_track_pending(struct radeon_bo_manager *bom, int debug)
 {
+    struct bo_manager_legacy *boml = (struct bo_manager_legacy*) bom;
     struct bo_legacy *bo_legacy;
     struct bo_legacy *next;
 
@@ -244,8 +245,8 @@ static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
     bo_legacy = boml->pending_bos.pnext;
     while (bo_legacy) {
         if (debug)
-         fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
-                 boml->current_age, bo_legacy->pending);
+            fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
+                    boml->current_age, bo_legacy->pending);
         next = bo_legacy->pnext;
         if (legacy_is_pending(&(bo_legacy->base))) {
         }
@@ -444,7 +445,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
     if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT) 
     {
 retry:
-        legacy_track_pending(boml, 0);
+        legacy_track_pending(&boml->base, 0);
         /* dma buffers */
 
         r = bo_dma_alloc(&(bo_legacy->base));
@@ -580,7 +581,7 @@ static int bo_vram_validate(struct radeon_bo *bo,
         if (r) {
                pending_retry = 0;
                while(boml->cpendings && pending_retry++ < 10000) {
-                       legacy_track_pending(boml, 0);
+                       legacy_track_pending(&boml->base, 0);
                        retry_count++;
                        if (retry_count > 2) {
                                free(bo_legacy->tobj);
@@ -706,7 +707,7 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
 
         r = bo_vram_validate(bo, soffset, eoffset);
         if (r) {
-           legacy_track_pending(boml, 0);
+           legacy_track_pending(&boml->base, 0);
            legacy_kick_all_buffers(boml);
            retries++;
            if (retries == 2) {
index 455adebc099ac1acf8e435944e1b23a04ec398ed..2cf15dfaff30579fcab84baee452de6baf836fd2 100644 (file)
@@ -45,5 +45,6 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo);
 struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
                                              int size,
                                              uint32_t offset);
+void legacy_track_pending(struct radeon_bo_manager *bom, int debug);
 
 #endif
index 0614c894595b2d2f8acc61f9e965a58c1d5a6839..b5b4fed8fa8d74c7939bb80bff28dbf12587e091 100644 (file)
@@ -83,6 +83,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_lock.h"
 #include "radeon_drm.h"
 #include "radeon_mipmap_tree.h"
+#include "radeon_queryobj.h"
 
 #define DEBUG_CMDBUF         0
 
@@ -1042,7 +1043,7 @@ void radeonFlush(GLcontext *ctx)
           we have no DMA buffer allocated.
           then no point flushing anything at all.
        */
-       if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current)
+       if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
                return;
 
        if (radeon->dma.flush)
@@ -1072,6 +1073,9 @@ void radeonFlush(GLcontext *ctx)
                        }
                }
        }
+
+       make_empty_list(&radeon->query.not_flushed_head);
+
 }
 
 /* Make sure all commands have been sent to the hardware and have
@@ -1128,6 +1132,8 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
                        __FUNCTION__, caller, rmesa->numClipRects);
        }
 
+       radeonEmitQueryEnd(rmesa->glCtx);
+
        if (rmesa->cmdbuf.cs->cdw) {
                ret = radeon_cs_emit(rmesa->cmdbuf.cs);
                rmesa->hw.all_dirty = GL_TRUE;
@@ -1146,7 +1152,7 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
 {
        int ret;
 
-       radeonReleaseDmaRegion(rmesa);
+       radeonReleaseDmaRegions(rmesa);
 
        LOCK_HARDWARE(rmesa);
        ret = rcommonFlushCmdBufLocked(rmesa, caller);
index c0abcbfa21e3a321565c40c61536a0611e9ae74a..ad4584a2bde60e10efb3a6b01ada7b646c02ef31 100644 (file)
@@ -263,6 +263,9 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
                radeon->texture_compressed_row_align = 64;
        }
 
+       make_empty_list(&radeon->query.not_flushed_head);
+       radeon_init_dma(radeon);
+
        return GL_TRUE;
 }
 
@@ -295,10 +298,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
        GET_CURRENT_CONTEXT(ctx);
        radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
        radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
-       __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
-       radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
-#endif
 
        if (radeon == current) {
                radeon_firevertices(radeon);
@@ -307,10 +306,11 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
 
        assert(radeon);
        if (radeon) {
-               if (radeon->dma.current) {
+               if (!is_empty_list(&radeon->dma.reserved)) {
                        rcommonFlushCmdBuf( radeon, __FUNCTION__ );
                }
 
+               radeonFreeDmaRegions(radeon);
                radeonReleaseArrays(radeon->glCtx, ~0);
                meta_destroy_metaops(&radeon->meta);
                if (radeon->vtbl.free_context)
@@ -334,9 +334,6 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
 
                rcommonDestroyCmdBuf(radeon);
 
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
-           if (!IS_R600_CLASS(screen))
-#endif
                radeon_destroy_atom_list(radeon);
 
                if (radeon->state.scissor.pClipRects) {
index ee46c1f81a668c17fc452ef43fc9a94a87df981e..9e9c35650d416e044f2c333b701bf322cac6b420 100644 (file)
@@ -18,6 +18,22 @@ struct radeon_context;
 
 #include "radeon_bocs_wrapper.h"
 
+/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
+   I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
+   with other compilers ... GLUE!
+*/
+#define WARN_ONCE(a, ...)      { \
+       static int warn##__LINE__=1; \
+       if(warn##__LINE__){ \
+               fprintf(stderr, "*********************************WARN_ONCE*********************************\n"); \
+               fprintf(stderr, "File %s function %s line %d\n", \
+                       __FILE__, __FUNCTION__, __LINE__); \
+               fprintf(stderr,  a, ## __VA_ARGS__);\
+               fprintf(stderr, "***************************************************************************\n"); \
+               warn##__LINE__=0;\
+               } \
+       }
+
 /* This union is used to avoid warnings/miscompilation
    with float to uint32_t casts due to strict-aliasing */
 typedef union { GLfloat f; uint32_t ui32; } float_ui32_type;
@@ -163,6 +179,7 @@ struct radeon_hw_state {
        /* Head of the linked list of state atoms. */
        struct radeon_state_atom atomlist;
        int max_state_size;     /* Number of bytes necessary for a full state emit. */
+       int max_post_flush_size; /* Number of bytes necessary for post flushing emits */
        GLboolean is_dirty, all_dirty;
 };
 
@@ -254,6 +271,17 @@ static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj)
        return (radeonTexObj*)texObj;
 }
 
+/* occlusion query */
+struct radeon_query_object {
+       struct gl_query_object Base;
+       struct radeon_bo *bo;
+       int curr_offset;
+       GLboolean emitted_begin;
+
+       /* Double linked list of not flushed query objects */
+       struct radeon_query_object *prev, *next;
+};
+
 /* Need refcounting on dma buffers:
  */
 struct radeon_dma_buffer {
@@ -269,14 +297,25 @@ struct radeon_aos {
        int count; /** Number of vertices */
 };
 
+#define DMA_BO_FREE_TIME 100
+
+struct radeon_dma_bo {
+  struct radeon_dma_bo *next, *prev;
+  struct radeon_bo *bo;
+  int expire_counter;
+};
+
 struct radeon_dma {
         /* Active dma region.  Allocations for vertices and retained
          * regions come from here.  Also used for emitting random vertices,
          * these may be flushed by calling flush_current();
          */
-        struct radeon_bo *current; /** Buffer that DMA memory is allocated from */
-        int current_used; /** Number of bytes allocated and forgotten about */
-        int current_vertexptr; /** End of active vertex region */
+       struct radeon_dma_bo free;
+       struct radeon_dma_bo wait;
+       struct radeon_dma_bo reserved;
+        size_t current_used; /** Number of bytes allocated and forgotten about */
+        size_t current_vertexptr; /** End of active vertex region */
+        size_t minimum_size;
 
         /**
          * If current_vertexptr != current_used then flush must be non-zero.
@@ -284,12 +323,6 @@ struct radeon_dma {
          * performed.
          */
         void (*flush) (GLcontext *);
-
-        /* Number of "in-flight" DMA buffers, i.e. the number of buffers
-         * for which a DISCARD command is currently queued in the command buffer
-.
-         */
-        GLuint nr_released_bufs;
 };
 
 /* radeon_swtcl.c
@@ -499,6 +532,12 @@ struct radeon_context {
 
    struct dri_metaops meta;
 
+   struct {
+       struct radeon_query_object *current;
+       struct radeon_query_object not_flushed_head;
+       struct radeon_state_atom queryobj;
+   } query;
+
    struct {
           void (*get_lock)(radeonContextPtr radeon);
           void (*update_viewport_offset)(GLcontext *ctx);
@@ -508,6 +547,7 @@ struct radeon_context {
           void (*pre_emit_state)(radeonContextPtr rmesa);
           void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode);
           void (*free_context)(GLcontext *ctx);
+          void (*emit_query_finish)(radeonContextPtr radeon);
    } vtbl;
 };
 
@@ -523,7 +563,6 @@ static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon)
        return radeon->dri.context->driReadablePriv;
 }
 
-
 /**
  * This function takes a float and packs it into a uint32_t
  */
index 5e755c51edb7865c75c82ebc0670c1a7f26d6100..7e6b74add862c69660744b73634638e6ab2e202b 100644 (file)
@@ -31,6 +31,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 **************************************************************************/
 
 #include "radeon_common.h"
+#include "main/simple_list.h"
 
 #if defined(USE_X86_ASM)
 #define COPY_DWORDS( dst, src, nr )                                    \
@@ -161,10 +162,20 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
        }
 }
 
-void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
+void radeon_init_dma(radeonContextPtr rmesa)
 {
+       make_empty_list(&rmesa->dma.free);
+       make_empty_list(&rmesa->dma.wait);
+       make_empty_list(&rmesa->dma.reserved);
+       rmesa->dma.minimum_size = MAX_DMA_BUF_SZ;
+}
 
-       size = MAX2(size, MAX_DMA_BUF_SZ);
+void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
+{
+       /* we set minimum sizes to at least requested size
+          aligned to next 16 bytes. */
+       if (size > rmesa->dma.minimum_size)
+               rmesa->dma.minimum_size = (size + 15) & (~15);
 
        if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
                fprintf(stderr, "%s\n", __FUNCTION__);
@@ -173,43 +184,49 @@ void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
                rmesa->dma.flush(rmesa->glCtx);
        }
 
-       if (rmesa->dma.nr_released_bufs > 4) {
-               rcommonFlushCmdBuf(rmesa, __FUNCTION__);
-               rmesa->dma.nr_released_bufs = 0;
-       }
+       /* unmap old reserved bo */
+       if (!is_empty_list(&rmesa->dma.reserved))
+               radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
 
-       if (rmesa->dma.current) {
-               radeon_bo_unmap(rmesa->dma.current);
-               radeon_bo_unref(rmesa->dma.current);
-               rmesa->dma.current = 0;
-       }
+       if (is_empty_list(&rmesa->dma.free)
+             || last_elem(&rmesa->dma.free)->bo->size < size) {
+               struct radeon_dma_bo *dma_bo = CALLOC(sizeof(struct radeon_dma_bo));
+               assert(dma_bo);
 
 again_alloc:
-       rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
-                                           0, size, 4, RADEON_GEM_DOMAIN_GTT,
-                                           0);
+               dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom,
+                                           0, rmesa->dma.minimum_size, 4,
+                                           RADEON_GEM_DOMAIN_GTT, 0);
 
-       if (!rmesa->dma.current) {
-               rcommonFlushCmdBuf(rmesa, __FUNCTION__);
-               rmesa->dma.nr_released_bufs = 0;
-               goto again_alloc;
+               if (!dma_bo->bo) {
+                       rcommonFlushCmdBuf(rmesa, __FUNCTION__);
+                       goto again_alloc;
+               }
+               insert_at_head(&rmesa->dma.reserved, dma_bo);
+       } else {
+               /* We push and pop buffers from end of list so we can keep
+                  counter on unused buffers for later freeing them from
+                  begin of list */
+               struct radeon_dma_bo *dma_bo = last_elem(&rmesa->dma.free);
+               assert(dma_bo->bo->cref == 1);
+               remove_from_list(dma_bo);
+               insert_at_head(&rmesa->dma.reserved, dma_bo);
        }
 
        rmesa->dma.current_used = 0;
        rmesa->dma.current_vertexptr = 0;
        
        if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs,
-                                         rmesa->dma.current,
+                                         first_elem(&rmesa->dma.reserved)->bo,
                                          RADEON_GEM_DOMAIN_GTT, 0))
                fprintf(stderr,"failure to revalidate BOs - badness\n");
 
-       if (!rmesa->dma.current) {
+       if (is_empty_list(&rmesa->dma.reserved)) {
         /* Cmd buff have been flushed in radeon_revalidate_bos */
-               rmesa->dma.nr_released_bufs = 0;
                goto again_alloc;
        }
 
-       radeon_bo_map(rmesa->dma.current, 1);
+       radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1);
 }
 
 /* Allocates a region from rmesa->dma.current.  If there isn't enough
@@ -230,30 +247,142 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa,
        alignment--;
        rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
 
-       if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size)
-               radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
+       if (is_empty_list(&rmesa->dma.reserved)
+               || rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size)
+               radeonRefillCurrentDmaRegion(rmesa, bytes);
 
        *poffset = rmesa->dma.current_used;
-       *pbo = rmesa->dma.current;
+       *pbo = first_elem(&rmesa->dma.reserved)->bo;
        radeon_bo_ref(*pbo);
 
        /* Always align to at least 16 bytes */
        rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
        rmesa->dma.current_vertexptr = rmesa->dma.current_used;
 
-       assert(rmesa->dma.current_used <= rmesa->dma.current->size);
+       assert(rmesa->dma.current_used <= first_elem(&rmesa->dma.reserved)->bo->size);
 }
 
-void radeonReleaseDmaRegion(radeonContextPtr rmesa)
+void radeonFreeDmaRegions(radeonContextPtr rmesa)
 {
+       struct radeon_dma_bo *dma_bo;
+       struct radeon_dma_bo *temp;
+       if (RADEON_DEBUG & DEBUG_DMA)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       foreach_s(dma_bo, temp, &rmesa->dma.free) {
+               remove_from_list(dma_bo);
+               radeon_bo_unref(dma_bo->bo);
+               FREE(dma_bo);
+       }
+
+       foreach_s(dma_bo, temp, &rmesa->dma.wait) {
+               remove_from_list(dma_bo);
+               radeon_bo_unref(dma_bo->bo);
+               FREE(dma_bo);
+       }
+
+       foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
+               remove_from_list(dma_bo);
+               radeon_bo_unmap(dma_bo->bo);
+               radeon_bo_unref(dma_bo->bo);
+               FREE(dma_bo);
+       }
+}
+
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes)
+{
+       if (is_empty_list(&rmesa->dma.reserved))
+               return;
+
        if (RADEON_DEBUG & DEBUG_IOCTL)
-               fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current);
-       if (rmesa->dma.current) {
-               rmesa->dma.nr_released_bufs++;
-               radeon_bo_unmap(rmesa->dma.current);
-               radeon_bo_unref(rmesa->dma.current);
+               fprintf(stderr, "%s %d\n", __FUNCTION__, return_bytes);
+       rmesa->dma.current_used -= return_bytes;
+       rmesa->dma.current_vertexptr = rmesa->dma.current_used;
+}
+
+static int radeon_bo_is_idle(struct radeon_bo* bo)
+{
+       return bo->cref == 1;
+}
+
+void radeonReleaseDmaRegions(radeonContextPtr rmesa)
+{
+       struct radeon_dma_bo *dma_bo;
+       struct radeon_dma_bo *temp;
+       const int expire_at = ++rmesa->dma.free.expire_counter + DMA_BO_FREE_TIME;
+       const int time = rmesa->dma.free.expire_counter;
+
+       if (RADEON_DEBUG & DEBUG_DMA) {
+               size_t free = 0,
+                      wait = 0,
+                      reserved = 0;
+               foreach(dma_bo, &rmesa->dma.free)
+                       ++free;
+
+               foreach(dma_bo, &rmesa->dma.wait)
+                       ++wait;
+
+               foreach(dma_bo, &rmesa->dma.reserved)
+                       ++reserved;
+
+               fprintf(stderr, "%s: free %u, wait %u, reserved %u, minimum_size: %u\n", 
+                     __FUNCTION__, free, wait, reserved, rmesa->dma.minimum_size);
+       }
+
+       if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
+               /* request updated cs processing information from kernel */
+               legacy_track_pending(rmesa->radeonScreen->bom, 0);
+       }
+       /* move waiting bos to free list.
+          wait list provides gpu time to handle data before reuse */
+       foreach_s(dma_bo, temp, &rmesa->dma.wait) {
+               if (dma_bo->expire_counter == time) {
+                       WARN_ONCE("Leaking dma buffer object!\n");
+                       radeon_bo_unref(dma_bo->bo);
+                       remove_from_list(dma_bo);
+                       FREE(dma_bo);
+                       continue;
+               }
+               /* free objects that are too small to be used because of large request */
+               if (dma_bo->bo->size < rmesa->dma.minimum_size) {
+                  radeon_bo_unref(dma_bo->bo);
+                  remove_from_list(dma_bo);
+                  FREE(dma_bo);
+                  continue;
+               }
+               if (!radeon_bo_is_idle(dma_bo->bo))
+                       continue;
+               remove_from_list(dma_bo);
+               dma_bo->expire_counter = expire_at;
+               insert_at_tail(&rmesa->dma.free, dma_bo);
+       }
+
+       /* unmap the last dma region */
+       if (!is_empty_list(&rmesa->dma.reserved))
+               radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
+       /* move reserved to wait list */
+       foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
+               /* free objects that are too small to be used because of large request */
+               if (dma_bo->bo->size < rmesa->dma.minimum_size) {
+                  radeon_bo_unref(dma_bo->bo);
+                  remove_from_list(dma_bo);
+                  FREE(dma_bo);
+                  continue;
+               }
+               remove_from_list(dma_bo);
+               dma_bo->expire_counter = expire_at;
+               insert_at_tail(&rmesa->dma.wait, dma_bo);
+       }
+
+       /* free bos that have been unused for some time */
+       foreach_s(dma_bo, temp, &rmesa->dma.free) {
+               if (dma_bo->expire_counter != time)
+                       break;
+               remove_from_list(dma_bo);
+               radeon_bo_unref(dma_bo->bo);
+               FREE(dma_bo);
        }
-       rmesa->dma.current = NULL;
+
 }
 
 
@@ -266,10 +395,10 @@ void rcommon_flush_last_swtcl_prim( GLcontext *ctx  )
                
 
        if (RADEON_DEBUG & DEBUG_IOCTL)
-               fprintf(stderr, "%s %p\n", __FUNCTION__, dma->current);
+               fprintf(stderr, "%s\n", __FUNCTION__);
        dma->flush = NULL;
 
-       if (dma->current) {
+       if (!is_empty_list(&dma->reserved)) {
            GLuint current_offset = dma->current_used;
 
            assert (dma->current_used +
@@ -292,7 +421,10 @@ rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize )
        GLuint bytes = vsize * nverts;
        void *head;
 restart:
-       if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) {
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+       if (is_empty_list(&rmesa->dma.reserved)
+               || rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) {
                 radeonRefillCurrentDmaRegion(rmesa, bytes);
        }
 
@@ -302,7 +434,7 @@ restart:
                              rmesa->hw.max_state_size + (20*sizeof(int)),
                              __FUNCTION__);
                /* if cmdbuf flushed DMA restart */
-               if (!rmesa->dma.current)
+               if (is_empty_list(&rmesa->dma.reserved))
                        goto restart;
                 rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
                 rmesa->dma.flush = rcommon_flush_last_swtcl_prim;
@@ -314,7 +446,7 @@ restart:
                 rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
                 rmesa->dma.current_vertexptr );
 
-       head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr);
+       head = (first_elem(&rmesa->dma.reserved)->bo->ptr + rmesa->dma.current_vertexptr);
        rmesa->dma.current_vertexptr += bytes;
        rmesa->swtcl.numverts += nverts;
        return head;
@@ -324,18 +456,17 @@ void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
 {
    radeonContextPtr radeon = RADEON_CONTEXT( ctx );
    int i;
+       if (RADEON_DEBUG & DEBUG_IOCTL)
+               fprintf(stderr, "%s\n", __FUNCTION__);
 
    if (radeon->dma.flush) {
        radeon->dma.flush(radeon->glCtx);
    }
-   if (radeon->tcl.elt_dma_bo) {
-          radeon_bo_unref(radeon->tcl.elt_dma_bo);
-          radeon->tcl.elt_dma_bo = NULL;
-   }
    for (i = 0; i < radeon->tcl.aos_count; i++) {
       if (radeon->tcl.aos[i].bo) {
          radeon_bo_unref(radeon->tcl.aos[i].bo);
          radeon->tcl.aos[i].bo = NULL;
+
       }
    }
 }
index 55509ed00c1868aeeac64cbdd7254b4ec37fde33..74e653fd189524939590d0dd985ad11fbbf4925d 100644 (file)
@@ -41,14 +41,18 @@ void radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count);
 void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
                         const GLvoid * data, int size, int stride, int count);
 
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes);
 void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size);
+void radeon_init_dma(radeonContextPtr rmesa);
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes);
 void radeonAllocDmaRegion(radeonContextPtr rmesa,
                          struct radeon_bo **pbo, int *poffset,
                          int bytes, int alignment);
-void radeonReleaseDmaRegion(radeonContextPtr rmesa);
+void radeonReleaseDmaRegions(radeonContextPtr rmesa);
 
 void rcommon_flush_last_swtcl_prim(GLcontext *ctx);
 
 void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize);
+void radeonFreeDmaRegions(radeonContextPtr rmesa);
 void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs );
 #endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
new file mode 100644 (file)
index 0000000..7025194
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright © 2008-2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Maciej Cencora <m.cencora@gmail.com>
+ *
+ */
+#include "radeon_common.h"
+#include "radeon_queryobj.h"
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+
+#define DDEBUG 0
+
+#define PAGE_SIZE 4096
+
+static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
+{
+       struct radeon_query_object *query = (struct radeon_query_object *)q;
+       uint32_t *result;
+       int i;
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d, result %d\n", __FUNCTION__, query->Base.Id, (int) query->Base.Result);
+
+       radeon_bo_map(query->bo, GL_FALSE);
+
+       result = query->bo->ptr;
+
+       query->Base.Result = 0;
+       for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
+               query->Base.Result += result[i];
+               if (DDEBUG) fprintf(stderr, "result[%d] = %d\n", i, result[i]);
+       }
+
+       radeon_bo_unmap(query->bo);
+}
+
+static struct gl_query_object * radeonNewQueryObject(GLcontext *ctx, GLuint id)
+{
+       struct radeon_query_object *query;
+
+       query = _mesa_calloc(sizeof(struct radeon_query_object));
+
+       query->Base.Id = id;
+       query->Base.Result = 0;
+       query->Base.Active = GL_FALSE;
+       query->Base.Ready = GL_TRUE;
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, query->Base.Id);
+
+       return &query->Base;
+}
+
+static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+       struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+       if (query->bo) {
+               radeon_bo_unref(query->bo);
+       }
+
+       _mesa_free(query);
+}
+
+static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
+
+       /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
+       {
+               GLboolean found = GL_FALSE;
+               foreach(tmp, &radeon->query.not_flushed_head) {
+                       if (tmp == query) {
+                               found = GL_TRUE;
+                               break;
+                       }
+               }
+
+               if (found)
+                       ctx->Driver.Flush(ctx);
+       }
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
+
+       radeonQueryGetResult(ctx, q);
+
+       query->Base.Ready = GL_TRUE;
+}
+
+
+static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+       assert(radeon->query.current == NULL);
+
+       if (radeon->dma.flush)
+               radeon->dma.flush(radeon->glCtx);
+
+       if (!query->bo) {
+               query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, PAGE_SIZE, PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
+       }
+       query->curr_offset = 0;
+
+       radeon->query.current = query;
+
+       radeon->query.queryobj.dirty = GL_TRUE;
+       insert_at_tail(&radeon->query.not_flushed_head, query);
+
+}
+
+void radeonEmitQueryEnd(GLcontext *ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct radeon_query_object *query = radeon->query.current;
+
+       if (!query)
+               return;
+
+       if (query->emitted_begin == GL_FALSE)
+               return;
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
+
+       radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
+                                     query->bo,
+                                     0, RADEON_GEM_DOMAIN_GTT);
+
+       radeon->vtbl.emit_query_finish(radeon);
+}
+
+static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+       if (radeon->dma.flush)
+               radeon->dma.flush(radeon->glCtx);
+       radeonEmitQueryEnd(ctx);
+
+       radeon->query.current = NULL;
+}
+
+/**
+ * TODO:
+ * should check if bo is idle, bo there's no interface to do it
+ * just wait for result now
+ */
+static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+       if (DDEBUG) fprintf(stderr, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+       radeonWaitQuery(ctx, q);
+}
+
+void radeonInitQueryObjFunctions(struct dd_function_table *functions)
+{
+       functions->NewQueryObject = radeonNewQueryObject;
+       functions->DeleteQuery = radeonDeleteQuery;
+       functions->BeginQuery = radeonBeginQuery;
+       functions->EndQuery = radeonEndQuery;
+       functions->CheckQuery = radeonCheckQuery;
+       functions->WaitQuery = radeonWaitQuery;
+}
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       struct radeon_query_object *query = radeon->query.current;
+
+       if (!query || query->emitted_begin)
+               return 0;
+       return atom->cmd_size;
+}
+
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       BATCH_LOCALS(radeon);
+       int dwords;
+
+       dwords = (*atom->check) (ctx, atom);
+
+       BEGIN_BATCH_NO_AUTOSTATE(dwords);
+       OUT_BATCH_TABLE(atom->cmd, dwords);
+       END_BATCH();
+
+       radeon->query.current->emitted_begin = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.h b/src/mesa/drivers/dri/radeon/radeon_queryobj.h
new file mode 100644 (file)
index 0000000..19374dc
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2008 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Maciej Cencora <m.cencora@gmail.com>
+ *
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "radeon_common_context.h"
+
+extern void radeonEmitQueryBegin(GLcontext *ctx);
+extern void radeonEmitQueryEnd(GLcontext *ctx);
+
+extern void radeonInitQueryObjFunctions(struct dd_function_table *functions);
+
+#define RADEON_QUERY_PAGE_SIZE 4096
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom);
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom);
+
+static inline void radeon_init_query_stateobj(radeonContextPtr radeon, int SZ)
+{
+       radeon->query.queryobj.cmd_size = (SZ);
+       radeon->query.queryobj.cmd = (uint32_t*)CALLOC((SZ) * sizeof(uint32_t));
+       radeon->query.queryobj.name = "queryobj";
+       radeon->query.queryobj.idx = 0;
+       radeon->query.queryobj.check = radeon_check_query_active;
+       radeon->query.queryobj.dirty = GL_FALSE;
+       radeon->query.queryobj.emit = radeon_emit_queryobj;
+
+       radeon->hw.max_state_size += (SZ);
+       insert_at_tail(&radeon->hw.atomlist, &radeon->query.queryobj);
+}
+
index c8d491621a850a7b00f255b8f21990baf8bf901b..e28543d855abe9734c42ecdccae416b6506dc98b 100644 (file)
@@ -1797,7 +1797,7 @@ const struct __DriverAPIRec driDriverAPI = {
    .DestroyContext  = r200DestroyContext,
 #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
    .CreateContext   = r600CreateContext,
-   .DestroyContext  = r600DestroyContext,
+   .DestroyContext  = radeonDestroyContext,
 #else
    .CreateContext   = radeonCreateContext,
    .DestroyContext  = radeonDestroyContext,
index 0d1728b747a38a50aeb022aea725e057d8bbe9ab..56f82bdb0b62191466a4626e8bc49494a5ca4d5f 100644 (file)
@@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/state.h"
 #include "main/context.h"
 #include "main/framebuffer.h"
+#include "main/simple_list.h"
 
 #include "vbo/vbo.h"
 #include "tnl/tnl.h"
@@ -2099,7 +2100,7 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx)
                           RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
    }
 
-   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
    if (ret)
        return GL_FALSE;
    return GL_TRUE;
index 57aa7f1ca46c8a42bb55ec26e04106224260d9e6..501ea0b66b1740e13932c686ad61de253b2dd566 100644 (file)
@@ -798,7 +798,7 @@ void radeonInitState( r100ContextPtr rmesa )
       rmesa->hw.glt.emit = vec_emit;
       rmesa->hw.eye.emit = vec_emit;
       
-      for (i = 0; i <= 6; i++)
+      for (i = 0; i < 6; i++)
         rmesa->hw.mat[i].emit = vec_emit;
 
       for (i = 0; i < 8; i++)
index e31f045991ca994a008b7a48d6c79007c0a12268..58b3be9391bd6c5b3be8f36aa1c5e410adb58b5c 100644 (file)
@@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/enums.h"
 #include "main/imports.h"
 #include "main/macros.h"
+#include "main/simple_list.h"
 
 #include "swrast_setup/swrast_setup.h"
 #include "math/m_translate.h"
@@ -291,7 +292,7 @@ void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
    radeonEmitState(&rmesa->radeon);
    radeonEmitVertexAOS( rmesa,
                        rmesa->radeon.swtcl.vertex_size,
-                       rmesa->radeon.dma.current,
+                       first_elem(&rmesa->radeon.dma.reserved)->bo,
                        current_offset);
 
                      
index 6d31f32443a316668dbc4500ac844e77484e1abc..67311f71a2671abda40bd67aea5021aaa4c21c91 100644 (file)
@@ -152,7 +152,14 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
       return;
    }
 
-   if (type != GL_COLOR && type != GL_DEPTH && type != GL_STENCIL) {
+   /* Note: more detailed 'type' checking is done by the
+    * _mesa_source/dest_buffer_exists() calls below.  That's where we
+    * check if the stencil buffer exists, etc.
+    */
+   if (type != GL_COLOR &&
+       type != GL_DEPTH &&
+       type != GL_STENCIL &&
+       type != GL_DEPTH_STENCIL) {
       _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
                   _mesa_lookup_enum_by_nr(type));
       return;
index 80dde4b5aa2338a93a79d3db5ddd4625f3266d7e..8e21a27f897c08ff1c4ee5f0ea3b7e748149d40b 100644 (file)
@@ -1306,7 +1306,9 @@ static void build_fog( struct tnl_program *p )
       input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
    }
 
+   /* result.fog = {abs(f),0,0,1}; */
    emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input);
+   emit_op1(p, OPCODE_MOV, fog, WRITEMASK_YZW, get_identity_param(p));
 }
 
 
index 79f06a3c40431185573e03054296f6a97fa23c9a..d0c9cea00c78a28c200a4eed862c35663c1f9d1c 100644 (file)
@@ -276,6 +276,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
       case GL_CURRENT_TEXTURE_COORDS:
          {
          const GLuint texUnit = ctx->Texture.CurrentUnit;
+         FLUSH_CURRENT(ctx, 0);
          params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
          params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
          params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
@@ -2102,6 +2103,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
       case GL_CURRENT_TEXTURE_COORDS:
          {
          const GLuint texUnit = ctx->Texture.CurrentUnit;
+         FLUSH_CURRENT(ctx, 0);
          params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0];
          params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1];
          params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2];
@@ -3928,6 +3930,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
       case GL_CURRENT_TEXTURE_COORDS:
          {
          const GLuint texUnit = ctx->Texture.CurrentUnit;
+         FLUSH_CURRENT(ctx, 0);
          params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
          params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
          params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
index e9c8226d08d572c352834dfa8bc6a75992af64d9..97dc78502016e011145ac141eda69f424f5e1c00 100644 (file)
@@ -176,7 +176,8 @@ StateVars = [
           "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]",
           "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]",
           "ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"],
-         "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ),
+         """const GLuint texUnit = ctx->Texture.CurrentUnit;
+         FLUSH_CURRENT(ctx, 0);""", None ),
        ( "GL_DEPTH_BIAS", GLfloat, ["ctx->Pixel.DepthBias"], "", None ),
        ( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"],
          "", None ),
index d58803991a545690a7539ea36d13d659d1aace85..bbc2830e69413069b19244f11c0d3b20afc96fd0 100644 (file)
@@ -240,7 +240,7 @@ st_surface_data(struct pipe_context *pipe,
    struct pipe_screen *screen = pipe->screen;
    void *map = screen->transfer_map(screen, dst);
 
-   pipe_copy_rect(map,
+   util_copy_rect(map,
                   &dst->block,
                   dst->stride,
                   dstx, dsty,