diff options
80 files changed, 3535 insertions, 863 deletions
| diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 533c0a15f3..17ff61b675 100644 --- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c +++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c @@ -284,16 +284,26 @@ fenced_buffer_map(struct pb_buffer *buf,                    unsigned flags)  {     struct fenced_buffer *fenced_buf = fenced_buffer(buf); +   struct fenced_buffer_list *fenced_list = fenced_buf->list; +   struct pb_fence_ops *ops = fenced_list->ops;     void *map; -   assert(flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE); -   assert(!(flags & ~PIPE_BUFFER_USAGE_CPU_READ_WRITE)); -   flags &= PIPE_BUFFER_USAGE_CPU_READ_WRITE; +   assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); -   /* Check for GPU read/write access */ -   if(fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) { -      /* Wait for the GPU to finish writing */ -      _fenced_buffer_finish(fenced_buf); +   /* Serialize writes */ +   if((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_WRITE) || +      ((fenced_buf->flags & PIPE_BUFFER_USAGE_GPU_READ) && (flags & PIPE_BUFFER_USAGE_CPU_WRITE))) { +      if(flags & PIPE_BUFFER_USAGE_DONTBLOCK) { +         /* Don't wait for the GPU to finish writing */ +         if(ops->fence_signalled(ops, fenced_buf->fence, 0) == 0) +            _fenced_buffer_remove(fenced_list, fenced_buf); +         else +            return NULL; +      } +      else { +         /* Wait for the GPU to finish writing */ +         _fenced_buffer_finish(fenced_buf); +      }     }  #if 0 @@ -307,7 +317,7 @@ fenced_buffer_map(struct pb_buffer *buf,     map = pb_map(fenced_buf->buffer, flags);     if(map) {        ++fenced_buf->mapcount; -      fenced_buf->flags |= flags; +      fenced_buf->flags |= flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE;     }     return map; diff --git a/src/gallium/drivers/nv04/nv04_transfer.c b/src/gallium/drivers/nv04/nv04_transfer.c index 314d2045f7..573b043f5b 100644 --- a/src/gallium/drivers/nv04/nv04_transfer.c +++ b/src/gallium/drivers/nv04/nv04_transfer.c @@ -87,7 +87,7 @@ nv04_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  	{  		tx->direct = true;  		tx->surface = pscreen->get_tex_surface(pscreen, pt, -	                                               face, level, zslice, +	                                               0, 0, 0,  	                                               nv04_usage_tx_to_buf(usage));  		return &tx->base;  	} diff --git a/src/gallium/drivers/nv10/nv10_transfer.c b/src/gallium/drivers/nv10/nv10_transfer.c index 967e2cc20c..daec37ab28 100644 --- a/src/gallium/drivers/nv10/nv10_transfer.c +++ b/src/gallium/drivers/nv10/nv10_transfer.c @@ -87,7 +87,7 @@ nv10_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  	{  		tx->direct = true;  		tx->surface = pscreen->get_tex_surface(pscreen, pt, -	                                               face, level, zslice, +	                                               0, 0, 0,  	                                               nv10_usage_tx_to_buf(usage));  		return &tx->base;  	} diff --git a/src/gallium/drivers/nv20/nv20_transfer.c b/src/gallium/drivers/nv20/nv20_transfer.c index 19de09486d..1631637067 100644 --- a/src/gallium/drivers/nv20/nv20_transfer.c +++ b/src/gallium/drivers/nv20/nv20_transfer.c @@ -87,7 +87,7 @@ nv20_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  	{  		tx->direct = true;  		tx->surface = pscreen->get_tex_surface(pscreen, pt, -	                                               face, level, zslice, +	                                               0, 0, 0,  	                                               nv20_usage_tx_to_buf(usage));  		return &tx->base;  	} diff --git a/src/gallium/drivers/nv30/nv30_transfer.c b/src/gallium/drivers/nv30/nv30_transfer.c index df4dc4b1f6..6367374a61 100644 --- a/src/gallium/drivers/nv30/nv30_transfer.c +++ b/src/gallium/drivers/nv30/nv30_transfer.c @@ -104,7 +104,7 @@ nv30_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  	}  	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, -	                                       face, level, zslice, +	                                       0, 0, 0,  	                                       nv30_usage_tx_to_buf(usage));  	pipe_texture_reference(&tx_tex, NULL); diff --git a/src/gallium/drivers/nv40/nv40_transfer.c b/src/gallium/drivers/nv40/nv40_transfer.c index b090f2238e..f762f32f0c 100644 --- a/src/gallium/drivers/nv40/nv40_transfer.c +++ b/src/gallium/drivers/nv40/nv40_transfer.c @@ -104,7 +104,7 @@ nv40_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,  	}  	tx->surface = pscreen->get_tex_surface(pscreen, tx_tex, -	                                       face, level, zslice, +	                                       0, 0, 0,  	                                       nv40_usage_tx_to_buf(usage));  	pipe_texture_reference(&tx_tex, NULL); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 3cbc93d12b..52d443970b 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -215,6 +215,7 @@ enum pipe_transfer_usage {  #define PIPE_BUFFER_USAGE_INDEX     (1 << 6)  #define PIPE_BUFFER_USAGE_CONSTANT  (1 << 7)  #define PIPE_BUFFER_USAGE_DISCARD   (1 << 8) +#define PIPE_BUFFER_USAGE_DONTBLOCK (1 << 9)  /** Pipe driver custom usage flags should be greater or equal to this value */  #define PIPE_BUFFER_USAGE_CUSTOM    (1 << 16) diff --git a/src/gallium/state_trackers/dri2/Makefile b/src/gallium/state_trackers/dri2/Makefile new file mode 100644 index 0000000000..47750e997e --- /dev/null +++ b/src/gallium/state_trackers/dri2/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = dri2drm + +LIBRARY_INCLUDES = \ +	-I$(TOP)/include \ +	-I$(TOP)/src/mesa \ +	-I$(TOP)/src/mesa/drivers/dri/common \ +	-I$(TOP)/src/mesa/main \ +         $(shell pkg-config --cflags-only-I libdrm) + + +C_SOURCES = \ +	dri_context.c \ +	dri_screen.c \ +	dri_drawable.c \ +	dri_extensions.c + +#	$(TOP)/src/mesa/drivers/dri/common/utils.c \ +	$(TOP)/src/mesa/drivers/dri/common/vblank.c \ +	$(TOP)/src/mesa/drivers/dri/common/dri_util.c \ +	$(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \ +	$(TOP)/src/mesa/drivers/common/driverfuncs.c \ +	$(TOP)/src/mesa/drivers/dri/common/texmem.c \ +	$(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +include ../../Makefile.template diff --git a/src/gallium/state_trackers/glx/dri/dri_context.c b/src/gallium/state_trackers/dri2/dri_context.c index 9424e18bee..a8a94be176 100644 --- a/src/gallium/state_trackers/glx/dri/dri_context.c +++ b/src/gallium/state_trackers/dri2/dri_context.c @@ -18,22 +18,29 @@   * 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 + * IN NO EVENT SHALL VMWARE 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.   *   **************************************************************************/ - +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */  #include "dri_screen.h" -#include "dri_context.h" -#include "dri_winsys.h" +#include "dri_drawable.h" + + +#include "state_tracker/drm_api.h"  #include "state_tracker/st_public.h"  #include "state_tracker/st_context.h"  #include "pipe/p_context.h" +#include "dri_context.h" +  #include "util/u_memory.h" @@ -59,14 +66,13 @@ dri_create_context(const __GLcontextModes *visual,     ctx->cPriv = cPriv;     ctx->sPriv = sPriv; -   driParseConfigFiles(&ctx->optionCache,  +   driParseConfigFiles(&ctx->optionCache,                         &screen->optionCache, -                       sPriv->myNum,  +                       sPriv->myNum,                         "dri"); -    -   ctx->pipe = screen->pipe_screen->create_context(screen->pipe_screen, -                                                   screen->pipe_winsys, -                                                   hw_winsys ); + +   ctx->pipe = drm_api_hocks.create_context(screen->pipe_screen); +     if (ctx->pipe == NULL)        goto fail; @@ -76,16 +82,16 @@ dri_create_context(const __GLcontextModes *visual,     if (ctx->st == NULL)        goto fail; -   dri_init_extensions( ctx ); +   dri_init_extensions(ctx);     return GL_TRUE;  fail:     if (ctx && ctx->st) -      st_destroy_context( ctx->st ); +      st_destroy_context(ctx->st);     if (ctx && ctx->pipe) -      ctx->pipe->destroy( ctx->pipe ); +      ctx->pipe->destroy(ctx->pipe);     FREE(ctx);     return FALSE; @@ -97,14 +103,13 @@ dri_destroy_context(__DRIcontextPrivate *cPriv)  {     struct dri_context *ctx = dri_context(cPriv);     struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); -   struct pipe_winsys *winsys = screen->winsys;     /* No particular reason to wait for command completion before      * destroying a context, but it is probably worthwhile flushing it      * to avoid having to add code elsewhere to cope with flushing a      * partially destroyed context.      */ -   st_flush(ctx->st); +   st_flush(ctx->st, 0, NULL);     if (screen->dummyContext == ctx)        screen->dummyContext = NULL; @@ -143,26 +148,21 @@ dri_make_current(__DRIcontextPrivate *cPriv,         */        screen->dummyContext = ctx; -      st_make_current( ctx->st,  -                       draw->stfb,  -                       read->stfb ); +      st_make_current(ctx->st, +                      draw->stfb, +                      read->stfb);        ctx->dPriv = driDrawPriv; -      /* Update window sizes if necessary: -       */ -      if (draw->stamp != driDrawPriv->lastStamp) { -         dri_update_window_size( draw ); -      } - -      if (read->stamp != driReadPriv->lastStamp) { -         dri_update_window_size( read ); -      } - -   } -   else { +      if (driDrawPriv) +         dri_get_buffers(driDrawPriv); +      if (driDrawPriv != driReadPriv && driReadPriv) +         dri_get_buffers(driReadPriv); +   } else {        st_make_current(NULL, NULL, NULL);     }     return GL_TRUE;  } + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_context.h b/src/gallium/state_trackers/dri2/dri_context.h index 4e6a305abb..e910472700 100644 --- a/src/gallium/state_trackers/glx/dri/dri_context.h +++ b/src/gallium/state_trackers/dri2/dri_context.h @@ -1,6 +1,7 @@  /**************************************************************************   * - * Copyright (C) 2009 VMware, Inc.  All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. + * All Rights Reserved.   *   * Permission is hereby granted, free of charge, to any person obtaining a   * copy of this software and associated documentation files (the @@ -17,12 +18,16 @@   * 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 + * IN NO EVENT SHALL VMWARE 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.   *   **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */  #ifndef DRI_CONTEXT_H  #define DRI_CONTEXT_H @@ -35,22 +40,21 @@  struct pipe_context;  struct pipe_fence;  struct st_context; +struct dri_drawable;  struct dri_context  { +   /* dri */ +   __DRIscreenPrivate *sPriv;     __DRIcontextPrivate *cPriv;     __DRIdrawablePrivate *dPriv; +   driOptionCache optionCache; + +   /* gallium */     struct st_context *st;     struct pipe_context *pipe; - -   boolean locked; - -   /** -    * Configuration cache -    */ -   driOptionCache optionCache;  }; @@ -60,13 +64,14 @@ dri_context(__DRIcontextPrivate *driContextPriv)     return (struct dri_context *) driContextPriv->driverPrivate;  } +  /***********************************************************************   * dri_context.c   */ -void  +void  dri_destroy_context(__DRIcontextPrivate * driContextPriv); -boolean  +boolean  dri_unbind_context(__DRIcontextPrivate * driContextPriv);  boolean @@ -80,16 +85,12 @@ dri_create_context(const __GLcontextModes * visual,                     void *sharedContextPrivate); -  /*********************************************************************** - * dri_lock.c + * dri_extensions.c   */ -void dri_lock_hardware( struct dri_context *context,  -                        struct dri_drawable *drawable ); - -void dri_unlock_hardware( struct dri_context *dri ); -boolean dri_is_locked( struct dri_context *dri ); - - +void +dri_init_extensions(struct dri_context *ctx);  #endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_drawable.c b/src/gallium/state_trackers/dri2/dri_drawable.c new file mode 100644 index 0000000000..120d45bc03 --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_drawable.c @@ -0,0 +1,315 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * 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 VMWARE 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. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */ + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/drm_api.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" + +#include "util/u_memory.h" + + +static struct pipe_surface * +dri_surface_from_handle(struct pipe_screen *screen, +                        unsigned handle, +                        enum pipe_format format, +                        unsigned width, +                        unsigned height, +                        unsigned pitch) +{ +   struct pipe_surface *surface = NULL; +   struct pipe_texture *texture = NULL; +   struct pipe_texture templat; +   struct pipe_buffer *buf = NULL; + +   buf = drm_api_hocks.buffer_from_handle(screen, "dri2 buffer", handle); +   if (!buf) +      return NULL; + +   memset(&templat, 0, sizeof(templat)); +   templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; +   templat.target = PIPE_TEXTURE_2D; +   templat.last_level = 0; +   templat.depth[0] = 1; +   templat.format = format; +   templat.width[0] = width; +   templat.height[0] = height; +   pf_get_block(templat.format, &templat.block); + +   texture = screen->texture_blanket(screen, +                                     &templat, +                                     &pitch, +                                     buf); + +   /* we don't need the buffer from this point on */ +   pipe_buffer_reference(screen, &buf, NULL); + +   if (!texture) +      return NULL; + +   surface = screen->get_tex_surface(screen, texture, 0, 0, 0, +                                     PIPE_BUFFER_USAGE_GPU_READ | +                                     PIPE_BUFFER_USAGE_GPU_WRITE); + +   /* we don't need the texture from this point on */ +   pipe_texture_reference(&texture, NULL); +   return surface; +} + + +/** + * This will be called a drawable is known to have been resized. + */ +void +dri_get_buffers(__DRIdrawablePrivate *dPriv) +{ +   struct dri_drawable *drawable = dri_drawable(dPriv); +   struct pipe_surface *surface = NULL; +   struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; +   __DRIbuffer *buffers = NULL; +   __DRIscreen *dri_screen = drawable->sPriv; +   __DRIdrawable *dri_drawable = drawable->dPriv; +   boolean have_depth = FALSE; +   int i, count; + +   buffers = (*dri_screen->dri2.loader->getBuffers)(dri_drawable, +                                                    &dri_drawable->w, +                                                    &dri_drawable->h, +                                                    drawable->attachments, +                                                    drawable->num_attachments, +                                                    &count, +                                                    dri_drawable->loaderPrivate); + +   if (buffers == NULL) { +      return; +   } + +   /* set one cliprect to cover the whole dri_drawable */ +   dri_drawable->x = 0; +   dri_drawable->y = 0; +   dri_drawable->backX = 0; +   dri_drawable->backY = 0; +   dri_drawable->numClipRects = 1; +   dri_drawable->pClipRects[0].x1 = 0; +   dri_drawable->pClipRects[0].y1 = 0; +   dri_drawable->pClipRects[0].x2 = dri_drawable->w; +   dri_drawable->pClipRects[0].y2 = dri_drawable->h; +   dri_drawable->numBackClipRects = 1; +   dri_drawable->pBackClipRects[0].x1 = 0; +   dri_drawable->pBackClipRects[0].y1 = 0; +   dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; +   dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; + +   for (i = 0; i < count; i++) { +      enum pipe_format format = 0; +      int index = 0; + +      switch (buffers[i].attachment) { +         case __DRI_BUFFER_FRONT_LEFT: +            index = ST_SURFACE_FRONT_LEFT; +            format = PIPE_FORMAT_A8R8G8B8_UNORM; +            break; +         case __DRI_BUFFER_BACK_LEFT: +            index = ST_SURFACE_BACK_LEFT; +            format = PIPE_FORMAT_A8R8G8B8_UNORM; +            break; +         case __DRI_BUFFER_DEPTH: +            index = ST_SURFACE_DEPTH; +            format = PIPE_FORMAT_Z24S8_UNORM; +            break; +         case __DRI_BUFFER_STENCIL: +            index = ST_SURFACE_DEPTH; +            format = PIPE_FORMAT_Z24S8_UNORM; +            break; +         case __DRI_BUFFER_ACCUM: +         default: +            assert(0); +      } +      assert(buffers[i].cpp == 4); + +      if (index == ST_SURFACE_DEPTH) { +         if (have_depth) +            continue; +         else +            have_depth = TRUE; +      } + +      surface = dri_surface_from_handle(screen, +                                        buffers[i].name, +                                        format, +                                        dri_drawable->w, +                                        dri_drawable->h, +                                        buffers[i].pitch); + +      st_set_framebuffer_surface(drawable->stfb, index, surface); +      pipe_surface_reference(&surface, NULL); +   } +   /* this needed, or else the state tracker fails to pick the new buffers */ +   st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h); +} + + +void +dri_swap_buffers(__DRIdrawablePrivate * dPriv) +{ +   struct dri_drawable *drawable = dri_drawable(dPriv); +   struct pipe_surface *back_surf; + +   assert(drawable); +   assert(drawable->stfb); + +   st_get_framebuffer_surface(drawable->stfb, +                              ST_SURFACE_BACK_LEFT, +                              &back_surf); +   if (back_surf) { +      st_notify_swapbuffers(drawable->stfb); +      /* TODO do stuff here */ +      st_notify_swapbuffers_complete(drawable->stfb); +   } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ +   struct dri_drawable *drawable = dri_drawable(dPriv); +   struct pipe_surface *back_surf; + +   assert(drawable); +   assert(drawable->stfb); + +   st_get_framebuffer_surface(drawable->stfb, +                              ST_SURFACE_BACK_LEFT, +                              &back_surf); +   if (back_surf) { +      drm_clip_rect_t rect; +      rect.x1 = x; +      rect.y1 = y; +      rect.x2 = w; +      rect.y2 = h; + +      /* do stuff here */ +   } +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +boolean +dri_create_buffer(__DRIscreenPrivate *sPriv, +                  __DRIdrawablePrivate *dPriv, +                  const __GLcontextModes *visual, +                  boolean isPixmap) +{ +   enum pipe_format colorFormat, depthFormat, stencilFormat; +   struct dri_drawable *drawable = NULL; +   int i; + +   if (isPixmap) +      goto fail; /* not implemented */ + +   drawable = CALLOC_STRUCT(dri_drawable); +   if (drawable == NULL) +      goto fail; + +   /* XXX: todo: use the pipe_screen queries to figure out which +    * render targets are supportable. +    */ +   assert(visual->redBits == 8); +   assert(visual->depthBits == 24 || visual->depthBits == 0); +   assert(visual->stencilBits == 8 || visual->stencilBits == 0); + +   colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + +   if (visual->depthBits) +      depthFormat = PIPE_FORMAT_S8Z24_UNORM; +   else +      depthFormat = PIPE_FORMAT_NONE; + +   if (visual->stencilBits) +      stencilFormat = PIPE_FORMAT_S8Z24_UNORM; +   else +      stencilFormat = PIPE_FORMAT_NONE; + +   drawable->stfb = st_create_framebuffer(visual, +                                          colorFormat, +                                          depthFormat, +                                          stencilFormat, +                                          dPriv->w, +                                          dPriv->h, +                                          (void*) drawable); +   if (drawable->stfb == NULL) +      goto fail; + +   drawable->sPriv = sPriv; +   drawable->dPriv = dPriv; +   dPriv->driverPrivate = (void *) drawable; + +   /* setup dri2 buffers information */ +   i = 0; +   drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; +   drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; +   if (visual->depthBits) +      drawable->attachments[i++] = __DRI_BUFFER_DEPTH; +   if (visual->stencilBits) +      drawable->attachments[i++] = __DRI_BUFFER_STENCIL; +   drawable->num_attachments = i; + +   return GL_TRUE; +fail: +   FREE(drawable); +   return GL_FALSE; +} + + +void +dri_destroy_buffer(__DRIdrawablePrivate *dPriv) +{ +   struct dri_drawable *drawable = dri_drawable(dPriv); + +   st_unreference_framebuffer(drawable->stfb); + +   FREE(drawable); +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_drawable.h b/src/gallium/state_trackers/dri2/dri_drawable.h index 1001bb8c57..d40d09c9b5 100644 --- a/src/gallium/state_trackers/glx/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri2/dri_drawable.h @@ -18,7 +18,7 @@   * 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 + * IN NO EVENT SHALL VMWARE 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. @@ -37,12 +37,14 @@ struct st_framebuffer;  struct dri_drawable  { +   /* dri */     __DRIdrawablePrivate *dPriv; -   unsigned stamp; +   __DRIscreenPrivate *sPriv; -   struct pipe_fence *last_swap_fence; -   struct pipe_fence *first_swap_fence; +   unsigned attachments[8]; +   unsigned num_attachments; +   /* gallium */     struct st_framebuffer *stfb;  }; @@ -57,17 +59,26 @@ dri_drawable(__DRIdrawablePrivate * driDrawPriv)  /***********************************************************************   * dri_drawable.c   */ +boolean +dri_create_buffer(__DRIscreenPrivate *sPriv, +                  __DRIdrawablePrivate *dPriv, +                  const __GLcontextModes *visual, +                  boolean isPixmap); -void  +void  dri_swap_buffers(__DRIdrawablePrivate * dPriv); -void  +void  dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, -                    int x, int y,  +                    int x, int y,                      int w, int h); -void  -dri_update_window_size(__DRIdrawablePrivate *dPriv); +void +dri_get_buffers(__DRIdrawablePrivate * dPriv); +void +dri_destroy_buffer(__DRIdrawablePrivate *dPriv);  #endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_extensions.c b/src/gallium/state_trackers/dri2/dri_extensions.c index 126faf7601..9c7a27282b 100644 --- a/src/gallium/state_trackers/glx/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri2/dri_extensions.c @@ -18,15 +18,20 @@   * 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 + * IN NO EVENT SHALL VMWARE 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.   *   **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */ - - +#include "dri_screen.h" +#include "dri_context.h" +#include "state_tracker/st_context.h"  #define need_GL_ARB_multisample  #define need_GL_ARB_point_parameters @@ -96,13 +101,17 @@ const struct dri_extension card_extensions[] = {  }; - -void  -dri_init_extensions( void ) +void +dri_init_extensions(struct dri_context *ctx)  {     /* The card_extensions list should be pruned according to the -    * capabilities of the pipe_screen.  This is actually something +    * capabilities of the pipe_screen. This is actually something      * that can/should be done inside st_create_context().      */ -   driInitExtensions( ctx->st->ctx, card_extensions, GL_TRUE ); +   if (ctx) +      driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE); +   else +      driInitExtensions(NULL, card_extensions, GL_FALSE);  } + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_screen.c b/src/gallium/state_trackers/dri2/dri_screen.c index f7119b949a..1fef538294 100644 --- a/src/gallium/state_trackers/glx/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri2/dri_screen.c @@ -18,23 +18,29 @@   * 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 + * IN NO EVENT SHALL VMWARE 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.   *   **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */  #include "utils.h"  #include "vblank.h"  #include "xmlpool.h" -#include "dri_context.h"  #include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h"  #include "pipe/p_context.h"  #include "pipe/p_screen.h"  #include "pipe/p_inlines.h" +#include "state_tracker/drm_api.h"  #include "state_tracker/st_public.h"  #include "state_tracker/st_cb_fbo.h" @@ -44,19 +50,15 @@ PUBLIC const char __driConfigOptions[] =      DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)      DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)     DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY -//   DRI_CONF_FORCE_S3TC_ENABLE(false) +    /*DRI_CONF_FORCE_S3TC_ENABLE(false)*/      DRI_CONF_ALLOW_LARGE_TEXTURES(1)     DRI_CONF_SECTION_END DRI_CONF_END; -const uint __driNConfigOptions = 3; - -static PFNGLXCREATECONTEXTMODES create_context_modes = NULL; - -extern const struct dri_extension card_extensions[]; +const uint __driNConfigOptions = 3; -static const __DRIextension *driScreenExtensions[] = { +static const __DRIextension *dri_screen_extensions[] = {      &driReadDrawableExtension,      &driCopySubBufferExtension.base,      &driSwapControlExtension.base, @@ -66,46 +68,40 @@ static const __DRIextension *driScreenExtensions[] = {  }; - - -static const char * -dri_get_name( struct pipe_winsys *winsys ) +static void +dri_get_drm_minor(struct dri_screen *screen)  { -   return "dri"; +   /* TODO get the real minor */ +   screen->minor = 0;  } -  static void -dri_destroy_screen(__DRIscreenPrivate * sPriv) +dri_get_device_id(struct dri_screen *screen)  { -   struct dri_screen *screen = dri_screen(sPriv); - -   screen->pipe_screen->destroy( screen->pipe_screen ); -   screen->pipe_winsys->destroy( screen->pipe_winsys ); -   FREE(screen); -   sPriv->private = NULL; -} +   char path[512]; +   FILE *file; +   /* +    * There must be a better way to get the deviceID. +    * XXX this only works on Linux. +    */ +   snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", screen->minor); +   file = fopen(path, "r"); +   if (!file) { +      return; +   } -/** - * Get information about previous buffer swaps. - */ -static int -dri_get_swap_info(__DRIdrawablePrivate * dPriv,  -                  __DRIswapInfo * sInfo) -{ -   if (dPriv == NULL ||  -       dPriv->driverPrivate == NULL || -       sInfo == NULL)  -      return -1; -   else -      return 0; +   fgets(path, sizeof(path), file); +   sscanf(path, "%x", &screen->deviceID); +   fclose(file);  } +  static const __DRIconfig **  dri_fill_in_modes(__DRIscreenPrivate *psp, -                  unsigned pixel_bits ) +                  unsigned pixel_bits, unsigned depth_bits, +                  unsigned stencil_bits, GLboolean have_back_buffer)  {     __DRIconfig **configs;     __GLcontextModes *m; @@ -115,17 +111,19 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,     uint8_t msaa_samples_array[1];     unsigned depth_buffer_factor;     unsigned back_buffer_factor; +   unsigned msaa_samples_factor;     GLenum fb_format;     GLenum fb_type;     int i;     static const GLenum back_buffer_modes[] = { -      GLX_NONE, GLX_SWAP_UNDEFINED_OML +      GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML     }; +   /* TODO probe the hardware of what is supports */     depth_bits_array[0] = 0; -   depth_bits_array[1] = depth_bits; -   depth_bits_array[2] = depth_bits; +   depth_bits_array[1] = 24; +   depth_bits_array[2] = 24;     stencil_bits_array[0] = 0;   /* no depth or stencil */     stencil_bits_array[1] = 0;   /* z24x8 */ @@ -134,9 +132,10 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,     msaa_samples_array[0] = 0;     depth_buffer_factor = 3; -   back_buffer_factor = 1; +   back_buffer_factor = 3; +   msaa_samples_factor = 1; -   num_modes = depth_buffer_factor * back_buffer_factor * 4; +   num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;     if (pixel_bits == 16) {        fb_format = GL_RGB; @@ -148,85 +147,79 @@ dri_fill_in_modes(__DRIscreenPrivate *psp,     }     configs = driCreateConfigs(fb_format, fb_type, -			      depth_bits_array,  -                              stencil_bits_array, depth_buffer_factor,  +			      depth_bits_array, +                              stencil_bits_array, depth_buffer_factor,                                back_buffer_modes, back_buffer_factor, -                              msaa_samples_array, 1); +                              msaa_samples_array, msaa_samples_factor);     if (configs == NULL) {        debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);        return NULL;     } -   return configs; +   for (i = 0; configs[i]; i++) { +      m = &configs[i]->modes; +      if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { +         m->visualRating = GLX_SLOW_CONFIG; +      } +   } + +   return (const const __DRIconfig **) configs;  } +/** + * Get information about previous buffer swaps. + */ +int +dri_get_swap_info(__DRIdrawablePrivate * dPriv, +                  __DRIswapInfo * sInfo) +{ +   if (dPriv == NULL || +       dPriv->driverPrivate == NULL || +       sInfo == NULL) +      return -1; +   else +      return 0; +} + -/* This is the driver specific part of the createNewScreen entry point. - *  +/** + * This is the driver specific part of the createNewScreen entry point. + *   * Returns the __GLcontextModes supported by this driver.   */ -static const __DRIconfig **dri_init_screen(__DRIscreenPrivate *sPriv) +const __DRIconfig ** +dri_init_screen2(__DRIscreenPrivate *sPriv)  { -   static const __DRIversion ddx_expected = { 1, 6, 0 }; /* hw query */ -   static const __DRIversion dri_expected = { 4, 0, 0 }; -   static const __DRIversion drm_expected = { 1, 5, 0 }; /* hw query */     struct dri_screen *screen; -   if (!driCheckDriDdxDrmVersions2("dri", -                                   &sPriv->dri_version, &dri_expected, -                                   &sPriv->ddx_version, &ddx_expected, -                                   &sPriv->drm_version, &drm_expected)) { -      return NULL; -   } - -   /* Set up dispatch table to cope with all known extensions: -    */ -   driInitExtensions( NULL, card_extensions, GL_FALSE ); - +   /* Set up dispatch table to cope with all known extensions */ +   dri_init_extensions(NULL);     screen = CALLOC_STRUCT(dri_screen);     if (!screen)        goto fail;     screen->sPriv = sPriv; +   screen->fd = sPriv->fd; +   dri_get_drm_minor(screen); +   dri_get_device_id(screen);     sPriv->private = (void *) screen; +   sPriv->extensions = dri_screen_extensions; -   /* Search the registered winsys' for one that likes this sPriv. -    * This is required in situations where multiple devices speak to -    * the same DDX and are built into the same binary.   -    * -    * Note that cases like Intel i915 vs i965 doesn't fall into this -    * category because they are built into separate binaries. -    * -    * Nonetheless, it's healthy to keep that level of detail out of -    * this state_tracker. -    */ -   for (i = 0;  -        i < dri1_winsys_count &&  -           screen->st_winsys == NULL;  -        i++)  -   { -      screen->dri_winsys =  -         dri_winsys[i]->check_dri_privates( sPriv->pDevPriv, -                                            sPriv->pSAREA -                                            /* versions, etc?? */)); +   screen->pipe_screen = drm_api_hocks.create_screen(screen->fd, screen->deviceID); +   if (!screen->pipe_screen) { +      debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); +      goto fail;     } -                                                  driParseOptionInfo(&screen->optionCache, -                      __driConfigOptions,  +                      __driConfigOptions,                        __driNConfigOptions); - -   /* Plug our info back into the __DRIscreenPrivate: -    */ -   sPriv->private = (void *) screen; -   sPriv->extensions = driScreenExtensions; - -   return dri_fill_in_modes(sPriv,  -                            dri_priv->cpp * 8, +   return dri_fill_in_modes(sPriv, +                            4 * 8,                              24,                              8,                              1); @@ -235,21 +228,32 @@ fail:  } +void +dri_destroy_screen(__DRIscreenPrivate * sPriv) +{ +   struct dri_screen *screen = dri_screen(sPriv); + +   screen->pipe_screen->destroy(screen->pipe_screen); +   FREE(screen); +   sPriv->private = NULL; +} -const struct __DriverAPIRec driDriverAPI = { -   .InitScreen		 = dri_init_screen, -   .DestroyScreen	 = dri_destroy_screen, -   .CreateContext	 = dri_create_context, -   .DestroyContext	 = dri_destroy_context, -   .CreateBuffer	 = dri_create_buffer, -   .DestroyBuffer	 = dri_destroy_buffer, -   .SwapBuffers		 = dri_swap_buffers, -   .MakeCurrent		 = dri_make_current, -   .UnbindContext	 = dri_unbind_context, -   .GetSwapInfo		 = dri_get_swap_info, -   .GetDrawableMSC	 = driDrawableGetMSC32, -   .WaitForMSC		 = driWaitForMSC32, -   .CopySubBuffer	 = dri_copy_sub_buffer, -   //.InitScreen2		 = dri_init_screen2, +PUBLIC const struct __DriverAPIRec driDriverAPI = { +   .InitScreen          = NULL, +   .DestroyScreen       = dri_destroy_screen, +   .CreateContext       = dri_create_context, +   .DestroyContext      = dri_destroy_context, +   .CreateBuffer        = dri_create_buffer, +   .DestroyBuffer       = dri_destroy_buffer, +   .SwapBuffers         = dri_swap_buffers, +   .MakeCurrent         = dri_make_current, +   .UnbindContext       = dri_unbind_context, +   .GetSwapInfo         = dri_get_swap_info, +   .GetDrawableMSC      = driDrawableGetMSC32, +   .WaitForMSC          = driWaitForMSC32, +   .CopySubBuffer       = dri_copy_sub_buffer, +   .InitScreen2         = dri_init_screen2,  }; + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_screen.h b/src/gallium/state_trackers/dri2/dri_screen.h index 12ed86d22a..fe2676d0be 100644 --- a/src/gallium/state_trackers/glx/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri2/dri_screen.h @@ -18,12 +18,16 @@   * 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 + * IN NO EVENT SHALL VMWARE 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.   *   **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */  #ifndef DRI_SCREEN_H  #define DRI_SCREEN_H @@ -35,27 +39,8 @@  struct dri_screen  { -   __DRIScreenPrivate *sPriv; -   struct pipe_winsys *pipe_winsys; -   struct pipe_screen *pipe_screen; - -   struct { -      /* Need a pipe_surface pointer to do client-side swapbuffers: -       */ -      unsigned long buffer_handle; -      struct pipe_surface *surface; -      struct pipe_texture *texture; - -      int pitch;                   /* row stride, in bytes */ -      int width; -      int height; -      int size; -      int cpp;                     /* for front and back buffers */ -   } front; - -   int deviceID; -   int drmMinor; - +   /* dri */ +   __DRIscreenPrivate *sPriv;     /**      * Configuration cache with default values for all contexts @@ -67,8 +52,16 @@ struct dri_screen      * which we need a rendering context, but none is currently bound.      */     struct dri_context *dummyContext; -}; +   /* drm */ +   int deviceID; +   int fd; +   int minor; + +   /* gallium */ +   struct pipe_winsys *pipe_winsys; +   struct pipe_screen *pipe_screen; +};  /** cast wrapper */ @@ -79,5 +72,19 @@ dri_screen(__DRIscreenPrivate *sPriv)  } +/*********************************************************************** + * dri_screen.c + */ +const __DRIconfig ** +dri_init_screen2(__DRIscreenPrivate *sPriv); + +void +dri_destroy_screen(__DRIscreenPrivate * sPriv); + +int +dri_get_swap_info(__DRIdrawablePrivate * dPriv, +                  __DRIswapInfo * sInfo);  #endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/glx/dri/dri_drawable.c b/src/gallium/state_trackers/glx/dri/dri_drawable.c deleted file mode 100644 index b712acda88..0000000000 --- a/src/gallium/state_trackers/glx/dri/dri_drawable.c +++ /dev/null @@ -1,363 +0,0 @@ -/************************************************************************** - * - * Copyright 2009, VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_swapbuffers.h" - -#include "pipe/p_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_cb_fbo.h" - - -static void -blit_swapbuffers(__DRIdrawablePrivate *dPriv, -                 __DRIcontextPrivate *cPriv, -		 struct pipe_surface *src, -		 const drm_clip_rect_t *rect) -{ -   struct dri_screen *screen = dri_screen(dPriv->driScreenPriv); -   struct dri_drawable *fb = dri_drawable(dPriv); -   struct dri_context *context = dri_context(cPriv); - -   const int nbox = dPriv->numClipRects; -   const drm_clip_rect_t *pbox = dPriv->pClipRects; - -   struct pipe_surface *dest = fb->front_surface; -   const int backWidth = fb->stfb->Base.Width; -   const int backHeight = fb->stfb->Base.Height; -   int i; - -   for (i = 0; i < nbox; i++, pbox++) { -      drm_clip_rect_t box; -      drm_clip_rect_t sbox; -	  -      if (pbox->x1 > pbox->x2 || -	  pbox->y1 > pbox->y2 || -	  (pbox->x2 - pbox->x1) > dest->width ||  -	  (pbox->y2 - pbox->y1) > dest->height)  -	 continue; - -      box = *pbox; - -      if (rect) { -	 drm_clip_rect_t rrect; - -	 rrect.x1 = dPriv->x + rect->x1; -	 rrect.y1 = (dPriv->h - rect->y1 - rect->y2) + dPriv->y; -	 rrect.x2 = rect->x2 + rrect.x1; -	 rrect.y2 = rect->y2 + rrect.y1; -	 if (rrect.x1 > box.x1) -	    box.x1 = rrect.x1; -	 if (rrect.y1 > box.y1) -	    box.y1 = rrect.y1; -	 if (rrect.x2 < box.x2) -	    box.x2 = rrect.x2; -	 if (rrect.y2 < box.y2) -	    box.y2 = rrect.y2; - -	 if (box.x1 > box.x2 || box.y1 > box.y2) -	    continue; -      } - -      /* restrict blit to size of actually rendered area */ -      if (box.x2 - box.x1 > backWidth) -	 box.x2 = backWidth + box.x1; -      if (box.y2 - box.y1 > backHeight) -	 box.y2 = backHeight + box.y1; - -      debug_printf("%s: box %d,%d-%d,%d\n", __FUNCTION__, -                   box.x1, box.y1, box.x2, box.y2); - -      sbox.x1 = box.x1 - dPriv->x; -      sbox.y1 = box.y1 - dPriv->y; - -      ctx->st->pipe->surface_copy( ctx->st->pipe, -                                   FALSE, -                                   dest, -                                   box.x1, box.y1, -                                   src, -                                   sbox.x1, sbox.y1, -                                   box.x2 - box.x1,  -                                   box.y2 - box.y1 ); -   } -} - -/** - * Display a colorbuffer surface in an X window. - * Used for SwapBuffers and flushing front buffer rendering. - * - * \param dPriv  the window/drawable to display into - * \param surf  the surface to display - * \param rect  optional subrect of surface to display (may be NULL). - */ -static void -dri_display_surface(__DRIdrawablePrivate *dPriv, -                    struct pipe_surface *source, -                    const drm_clip_rect_t *rect) -{ -   struct dri_drawable *drawable = dri_drawable(dPriv); -   struct dri_screen *screen = dri_screen(dPriv->driScreenPriv); -   struct dri_context *context = screen->dummy_context; -   struct pipe_winsys *winsys = screen->winsys; -       -   if (!context)  -      return; - -   if (drawable->last_swap_fence) { -      winsys->fence_finish( winsys, -                            drawable->last_swap_fence, -                            0 ); - -      winsys->fence_reference( winsys, -                               &drawable->last_swap_fence, -                               NULL ); -   } - -   drawable->last_swap_fence = drawable->first_swap_fence; -   drawable->first_swap_fence = NULL; - -   /* Call lock_hardware to update dPriv cliprects.  -    */ -   dri_lock_hardware(context, drawable); -   { -      if (dPriv->numClipRects) { -         blit_swapbuffers( context, dPriv, source, rect ); -      } -   } -   dri_unlock_hardware(context); - -   if (drawble->stamp != drawable->dPriv->lastStamp) { -      dri_update_window_size( dpriv ); -   } -} - - - -/** - * This will be called a drawable is known to have moved/resized. - */ -void -dri_update_window_size(__DRIdrawablePrivate *dPriv) -{ -   struct dri_drawable *drawable = dri_drawable(dPriv); -   st_resize_framebuffer(drawable->stfb, dPriv->w, dPriv->h); -   drawable->stamp = dPriv->lastStamp; -} - - - -void -dri_swap_buffers(__DRIdrawablePrivate * dPriv) -{ -   struct dri_drawable *drawable = dri_drawable(dPriv); -   struct pipe_surface *back_surf; - -   assert(drawable); -   assert(drawable->stfb); - -   back_surf = st_get_framebuffer_surface(drawable->stfb, -                                          ST_SURFACE_BACK_LEFT); -   if (back_surf) { -      st_notify_swapbuffers(drawable->stfb); -      dri_display_surface(dPriv, back_surf, NULL); -      st_notify_swapbuffers_complete(drawable->stfb); -   } -} - - -/** - * Called via glXCopySubBufferMESA() to copy a subrect of the back - * buffer to the front buffer/screen. - */ -void -dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ -   struct dri_drawable *drawable = dri_drawable(dPriv); -   struct pipe_surface *back_surf; - -   assert(drawable); -   assert(drawable->stfb); - -   back_surf = st_get_framebuffer_surface(drawable->stfb, -                                          ST_SURFACE_BACK_LEFT); -   if (back_surf) { -      drm_clip_rect_t rect; -      rect.x1 = x; -      rect.y1 = y; -      rect.x2 = w; -      rect.y2 = h; - -      st_notify_swapbuffers(drawable->stfb); -      dri_display_surface(dPriv, back_surf, &rect); -   } -} - - - -/* - * The state tracker keeps track of whether the fake frontbuffer has - * been touched by any rendering since the last time we copied its - * contents to the real frontbuffer.  Our task is easy: - */ -static void -dri_flush_frontbuffer( struct pipe_winsys *winsys, -                       struct pipe_surface *surf, -                       void *context_private) -{ -   struct dri_context *dri = (struct dri_context *) context_private; -   __DRIdrawablePrivate *dPriv = dri->driDrawable; - -   dri_display_surface(dPriv, surf, NULL); -} - - - -/* Need to create a surface which wraps the front surface to support - * client-side swapbuffers. - */ -static void -dri_create_front_surface(struct dri_screen *screen,  -                         struct pipe_winsys *winsys,  -                         unsigned handle) -{ -   struct pipe_screen *pipe_screen = screen->pipe_screen; -   struct pipe_texture *texture; -   struct pipe_texture templat; -   struct pipe_surface *surface; -   struct pipe_buffer *buffer; -   unsigned pitch; - -   assert(screen->front.cpp == 4); - -//   buffer = dri_buffer_from_handle(screen->winsys, -//                                        "front", handle); - -   if (!buffer) -      return; - -   screen->front.buffer = dri_bo(buffer); - -   memset(&templat, 0, sizeof(templat)); -   templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET; -   templat.target = PIPE_TEXTURE_2D; -   templat.last_level = 0; -   templat.depth[0] = 1; -   templat.format = PIPE_FORMAT_A8R8G8B8_UNORM; -   templat.width[0] = screen->front.width; -   templat.height[0] = screen->front.height; -   pf_get_block(templat.format, &templat.block); -   pitch = screen->front.pitch; - -   texture = pipe_screen->texture_blanket(pipe_screen, -                                          &templat, -                                          &pitch, -                                          buffer); - -   /* Unref the buffer we don't need it anyways */ -   pipe_buffer_reference(screen, &buffer, NULL); - -   surface = pipe_screen->get_tex_surface(pipe_screen, -                                          texture, -                                          0, -                                          0, -                                          0, -                                          PIPE_BUFFER_USAGE_GPU_WRITE); - -   screen->front.texture = texture; -   screen->front.surface = surface; -} - -/** - * This is called when we need to set up GL rendering to a new X window. - */ -static boolean -dri_create_buffer(__DRIscreenPrivate *sPriv, -                  __DRIdrawablePrivate *dPriv, -                  const __GLcontextModes *visual, -                  boolean isPixmap) -{ -   enum pipe_format colorFormat, depthFormat, stencilFormat; -   struct dri_drawable *drawable; - -   if (isPixmap)  -      goto fail;          /* not implemented */ - -   drawable = CALLOC_STRUCT(dri_drawable); -   if (drawable == NULL) -      goto fail; - -   /* XXX: todo: use the pipe_screen queries to figure out which -    * render targets are supportable. -    */ -   if (visual->redBits == 5) -      colorFormat = PIPE_FORMAT_R5G6B5_UNORM; -   else -      colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - -   if (visual->depthBits == 16) -      depthFormat = PIPE_FORMAT_Z16_UNORM; -   else if (visual->depthBits == 24) { -      if (visual->stencilBits == 8) -         depthFormat = PIPE_FORMAT_S8Z24_UNORM; -      else -         depthFormat = PIPE_FORMAT_X8Z24_UNORM; -   } - -   drawable->stfb = st_create_framebuffer(visual, -                                    colorFormat, -                                    depthFormat, -                                    dPriv->w, -                                    dPriv->h, -                                    (void*) drawable); -   if (drawable->stfb == NULL) -      goto fail; - -   dPriv->driverPrivate = (void *) drawable; -   return GL_TRUE; - -fail: -   FREE(drawable); -   return GL_FALSE; -} - -static void -dri_destroy_buffer(__DRIdrawablePrivate *dPriv) -{ -   struct dri_drawable *drawable = dri_drawable(dPriv); - -   /* No particular need to wait on fences before dereferencing them: -    */ -   winsys->fence_reference( winsys, &ctx->last_swap_fence, NULL ); -   winsys->fence_reference( winsys, &ctx->first_swap_fence, NULL ); - -   st_unreference_framebuffer(drawable->stfb); - -   FREE(drawable); -} - diff --git a/src/gallium/state_trackers/glx/dri/dri_lock.c b/src/gallium/state_trackers/glx/dri/dri_lock.c deleted file mode 100644 index b272ab55f3..0000000000 --- a/src/gallium/state_trackers/glx/dri/dri_lock.c +++ /dev/null @@ -1,90 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - - -#include "pipe/p_thread.h" -#include "dri_context.h" -#include "xf86drm.h" - -pipe_static_mutex( lockMutex ); - -static void -dri_contended_lock(struct dri_context *ctx) -{ -   __DRIdrawablePrivate *dPriv = ctx->dPriv; -   __DRIcontextPrivate *cPriv = ctx->cPriv; -   __DRIscreenPrivate *sPriv = cPriv->driScreenPriv; - -   drmGetLock(sPriv->fd, cPriv->hHWContext, 0); - -   /* Perform round trip communication with server (including dropping -    * and retaking the above lock) to update window dimensions: -    */ -   if (dPriv) -      DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv); -} - - -/* Lock the hardware and validate our state. - */ -void dri_lock_hardware( struct dri_context *ctx ) -{ -   __DRIcontextPrivate *cPriv = ctx->cPriv; -   __DRIscreenPrivate *sPriv = cPriv->driScreenPriv; -   char __ret = 0; - -   pipe_mutex_lock(lockMutex); -   assert(!ctx->locked); - -   DRM_CAS((drmLock *) &sPriv->pSAREA->lock, -           cPriv->hHWContext, -           (DRM_LOCK_HELD | cPriv->hHWContext), -           __ret); - -   if (__ret) -      dri_contended_lock( ctx ); - -   ctx->locked = TRUE; -} - - -/* Unlock the hardware using the global current context - */ -void dri_unlock_hardware( struct dri_context *ctx ) -{ -   __DRIcontextPrivate *cPriv = ctx->cPriv; -   __DRIscreenPrivate *sPriv = cPriv->driScreenPriv; - -   assert(ctx->locked); -   ctx->locked = FALSE; - -   DRM_UNLOCK(sPriv->fd,  -              (drmLock *) &sPriv->pSAREA->lock, -              cPriv->hHWContext); - -   pipe_mutex_unlock(lockMutex); -} diff --git a/src/gallium/state_trackers/xorg/Makefile b/src/gallium/state_trackers/xorg/Makefile new file mode 100644 index 0000000000..a00ea3e2a4 --- /dev/null +++ b/src/gallium/state_trackers/xorg/Makefile @@ -0,0 +1,29 @@ +TARGET     = libxorgtracker.a +CFILES     = $(wildcard ./*.c) +OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES)) +GALLIUMDIR = ../.. +TOP        = ../../../.. + +include $(TOP)/configs/current + +CFLAGS = -DHAVE_CONFIG_H \ +         -g -Wall -Wimplicit-function-declaration -fPIC \ +         $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ +         -I$(GALLIUMDIR)/include \ +         -I$(GALLIUMDIR)/auxiliary \ +         -I$(TOP)/src/mesa/drivers/dri/common \ +         -I$(TOP)/src/mesa \ +         -I$(TOP)/include \ +         -I$(TOP)/src/egl/main + +############################################# + +.PHONY	= all clean + +all: $(TARGET) + +$(TARGET): $(OBJECTS) +	ar rcs $(TARGET) $(OBJECTS) + +clean: +	rm -rf $(OBJECTS) $(TARGET) diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c new file mode 100644 index 0000000000..0765f56ee1 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_crtc.c @@ -0,0 +1,314 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include <unistd.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <math.h> +#include <stdint.h> + +#include "xorg-server.h" +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include "xorg_tracker.h" +#include "xf86Modes.h" + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "pipe/p_inlines.h" + +struct crtc_private +{ +    drmModeCrtcPtr drm_crtc; + +    /* hwcursor */ +    struct pipe_buffer *cursor_buf; +    unsigned cursor_handle; +}; + +static void +crtc_dpms(xf86CrtcPtr crtc, int mode) +{ +    //ScrnInfoPtr pScrn = crtc->scrn; + +    switch (mode) { +    case DPMSModeOn: +    case DPMSModeStandby: +    case DPMSModeSuspend: +	break; +    case DPMSModeOff: +	break; +    } +} + +static Bool +crtc_lock(xf86CrtcPtr crtc) +{ +    return FALSE; +} + +static void +crtc_unlock(xf86CrtcPtr crtc) +{ +} + +static void +crtc_prepare(xf86CrtcPtr crtc) +{ +} + +static void +crtc_commit(xf86CrtcPtr crtc) +{ +} + +static Bool +crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, +		DisplayModePtr adjusted_mode) +{ +    return TRUE; +} + +static void +crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, +	      DisplayModePtr adjusted_mode, int x, int y) +{ +    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn); +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    xf86OutputPtr output = config->output[config->compat_output]; +    drmModeConnectorPtr drm_connector = output->driver_private; +    struct crtc_private *crtcp = crtc->driver_private; +    drmModeCrtcPtr drm_crtc = crtcp->drm_crtc; +    drmModeModeInfo drm_mode; + +    drm_mode.clock = mode->Clock; +    drm_mode.hdisplay = mode->HDisplay; +    drm_mode.hsync_start = mode->HSyncStart; +    drm_mode.hsync_end = mode->HSyncEnd; +    drm_mode.htotal = mode->HTotal; +    drm_mode.vdisplay = mode->VDisplay; +    drm_mode.vsync_start = mode->VSyncStart; +    drm_mode.vsync_end = mode->VSyncEnd; +    drm_mode.vtotal = mode->VTotal; +    drm_mode.flags = mode->Flags; +    drm_mode.hskew = mode->HSkew; +    drm_mode.vscan = mode->VScan; +    drm_mode.vrefresh = mode->VRefresh; +    if (!mode->name) +	xf86SetModeDefaultName(mode); +    strncpy(drm_mode.name, mode->name, DRM_DISPLAY_MODE_LEN); + +    drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y, +		   &drm_connector->connector_id, 1, &drm_mode); +} + +#if 0 +static void +crtc_load_lut(xf86CrtcPtr crtc) +{ +    //ScrnInfoPtr pScrn = crtc->scrn; +} +#endif + +static void +crtc_gamma_set(xf86CrtcPtr crtc, CARD16 * red, CARD16 * green, CARD16 * blue, +	       int size) +{ +} + +static void * +crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) +{ +    //ScrnInfoPtr pScrn = crtc->scrn; + +    return NULL; +} + +static PixmapPtr +crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) +{ +    //ScrnInfoPtr pScrn = crtc->scrn; + +    return NULL; +} + +static void +crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) +{ +    //ScrnInfoPtr pScrn = crtc->scrn; +} + +static void +crtc_destroy(xf86CrtcPtr crtc) +{ +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    if (crtcp->cursor_buf) +	pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL); + +    drmModeFreeCrtc(crtcp->drm_crtc); +    xfree(crtcp); +} + +static void +crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image) +{ +    unsigned char *ptr; +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    if (!crtcp->cursor_buf) { +	crtcp->cursor_buf = pipe_buffer_create(ms->screen, +					       0, +					       PIPE_BUFFER_USAGE_CPU_WRITE | +					       PIPE_BUFFER_USAGE_GPU_READ, +					       64*64*4); +	drm_api_hocks.handle_from_buffer(ms->screen, +					 crtcp->cursor_buf, +					 &crtcp->cursor_handle); +    } + +    ptr = pipe_buffer_map(ms->screen, crtcp->cursor_buf, PIPE_BUFFER_USAGE_CPU_WRITE); + +    if (ptr) +	memcpy(ptr, image, 64 * 64 * 4); + +    pipe_buffer_unmap(ms->screen, crtcp->cursor_buf); +} + +static void +crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y) +{ +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    drmModeMoveCursor(ms->fd, crtcp->drm_crtc->crtc_id, x, y); +} + +static void +crtc_show_cursor(xf86CrtcPtr crtc) +{ +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    if (crtcp->cursor_buf) +	drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, +			 crtcp->cursor_handle, 64, 64); +} + +static void +crtc_hide_cursor(xf86CrtcPtr crtc) +{ +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id, 0, 0, 0); +} + +static const xf86CrtcFuncsRec crtc_funcs = { +    .dpms = crtc_dpms, +    .save = NULL, +    .restore = NULL, +    .lock = crtc_lock, +    .unlock = crtc_unlock, +    .mode_fixup = crtc_mode_fixup, +    .prepare = crtc_prepare, +    .mode_set = crtc_mode_set, +    .commit = crtc_commit, +    .gamma_set = crtc_gamma_set, +    .shadow_create = crtc_shadow_create, +    .shadow_allocate = crtc_shadow_allocate, +    .shadow_destroy = crtc_shadow_destroy, +    .set_cursor_position = crtc_set_cursor_position, +    .show_cursor = crtc_show_cursor, +    .hide_cursor = crtc_hide_cursor, +    .load_cursor_image = NULL,	       /* lets convert to argb only */ +    .set_cursor_colors = NULL,	       /* using argb only */ +    .load_cursor_argb = crtc_load_cursor_argb, +    .destroy = crtc_destroy, +}; + +void +cursor_destroy(xf86CrtcPtr crtc) +{ +    modesettingPtr ms = modesettingPTR(crtc->scrn); +    struct crtc_private *crtcp = crtc->driver_private; + +    if (crtcp->cursor_buf) { +	pipe_buffer_reference(ms->screen, &crtcp->cursor_buf, NULL); +    } +} + +void +crtc_init(ScrnInfoPtr pScrn) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    xf86CrtcPtr crtc; +    drmModeResPtr res; +    drmModeCrtcPtr drm_crtc = NULL; +    struct crtc_private *crtcp; +    int c; + +    res = drmModeGetResources(ms->fd); +    if (res == 0) { +	ErrorF("Failed drmModeGetResources %d\n", errno); +	return; +    } + +    for (c = 0; c < res->count_crtcs; c++) { +	drm_crtc = drmModeGetCrtc(ms->fd, res->crtcs[c]); +	if (!drm_crtc) +	    continue; + +	crtc = xf86CrtcCreate(pScrn, &crtc_funcs); +	if (crtc == NULL) +	    goto out; + +	crtcp = xcalloc(1, sizeof(struct crtc_private)); +	if (!crtcp) { +	    xf86CrtcDestroy(crtc); +	    goto out; +	} + +	crtcp->drm_crtc = drm_crtc; + +	crtc->driver_private = crtcp; + +    } + +  out: +    drmModeFreeResources(res); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c new file mode 100644 index 0000000000..72b333eaf1 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -0,0 +1,212 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "xf86.h" +#include "xf86_OSproc.h" + +#include "xorg_tracker.h" + +#include "dri2.h" + +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +typedef struct { +    PixmapPtr pPixmap; +    struct pipe_texture *tex; +    struct pipe_buffer *buf; +} *BufferPrivatePtr; + +static DRI2BufferPtr +driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) +{ +    struct pipe_texture *depth, *tex; +    struct pipe_buffer *buf; +    ScreenPtr pScreen = pDraw->pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    BufferPrivatePtr privates; +    DRI2BufferPtr buffers; +    PixmapPtr pPixmap; +    unsigned stride, handle; +    int i; + +    buffers = xcalloc(count, sizeof *buffers); +    if (!buffers) +	goto fail_buffers; + +    privates = xcalloc(count, sizeof *privates); +    if (!privates) +	goto fail_privates; + +    depth = NULL; +    for (i = 0; i < count; i++) { +	pPixmap = NULL; +	tex = NULL; +	buf = NULL; +	if (attachments[i] == DRI2BufferFrontLeft) { +	    if (pDraw->type == DRAWABLE_PIXMAP) +		pPixmap = (PixmapPtr) pDraw; +	    else +		pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw); +	    pPixmap->refcnt++; +	    tex = xorg_exa_get_texture(pPixmap); +	} else if (attachments[i] == DRI2BufferStencil) { +	    pipe_texture_reference(&tex, depth); +	} else if (attachments[i] == DRI2BufferDepth) { +	    struct pipe_texture template; + +	    memset(&template, 0, sizeof(template)); +	    template.target = PIPE_TEXTURE_2D; +	    template.compressed = 0; +	    template.format = PIPE_FORMAT_S8Z24_UNORM; +	    pf_get_block(template.format, &template.block); +	    template.width[0] = pDraw->width; +	    template.height[0] = pDraw->height; +	    template.depth[0] = 1; +	    template.last_level = 0; +	    template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; +	    tex = ms->screen->texture_create(ms->screen, &template); +	} else { +	    struct pipe_texture template; +	    memset(&template, 0, sizeof(template)); +	    template.target = PIPE_TEXTURE_2D; +	    template.compressed = 0; +	    template.format = PIPE_FORMAT_A8R8G8B8_UNORM; +	    pf_get_block(template.format, &template.block); +	    template.width[0] = pDraw->width; +	    template.height[0] = pDraw->height; +	    template.depth[0] = 1; +	    template.last_level = 0; +	    template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; +	    tex = ms->screen->texture_create(ms->screen, &template); +	} + +	drm_api_hocks.buffer_from_texture(tex, &buf, &stride); +	drm_api_hocks.global_handle_from_buffer(ms->screen, buf, &handle); + +	buffers[i].name = handle; +	buffers[i].attachment = attachments[i]; +	buffers[i].pitch = stride; +	buffers[i].cpp = 4; +	buffers[i].driverPrivate = &privates[i]; +	buffers[i].flags = 0; /* not tiled */ +	privates[i].pPixmap = pPixmap; +	privates[i].buf = buf; +	privates[i].tex = tex; +    } + +    return buffers; + +fail_privates: +    xfree(buffers); +fail_buffers: +    return NULL; +} + +static void +driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count) +{ +    ScreenPtr pScreen = pDraw->pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    BufferPrivatePtr private; +    int i; + +    for (i = 0; i < count; i++) { +	private = buffers[i].driverPrivate; + +	if (private->pPixmap) +	    (*pScreen->DestroyPixmap)(private->pPixmap); + +	pipe_texture_reference(&private->tex, NULL); +	pipe_buffer_reference(ms->screen, &private->buf, NULL); +    } + +    if (buffers) { +	xfree(buffers[0].driverPrivate); +	xfree(buffers); +    } +} + +static void +driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion, +              DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer) +{ +    ScreenPtr pScreen = pDraw->pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate; +    BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate; + +    struct pipe_surface *dst_surf = +	ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0, +				    PIPE_BUFFER_USAGE_GPU_WRITE); +    struct pipe_surface *src_surf = +	ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0, +				    PIPE_BUFFER_USAGE_GPU_READ); + +    ms->ctx->surface_copy(ms->ctx, 0, dst_surf, 0, 0, src_surf, +			  0, 0, pDraw->width, pDraw->height); + +    pipe_surface_reference(&dst_surf, NULL); +    pipe_surface_reference(&src_surf, NULL); +} + +Bool +driScreenInit(ScreenPtr pScreen) +{ +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    DRI2InfoRec dri2info; + +    dri2info.version = 1; +    dri2info.fd = ms->fd; +#if 0 +    dri2info.driverName = pScrn->name; +#else +    dri2info.driverName = "i915"; /* FIXME */ +#endif +    dri2info.deviceName = "/dev/dri/card0"; /* FIXME */ + +    dri2info.CreateBuffers = driCreateBuffers; +    dri2info.DestroyBuffers = driDestroyBuffers; +    dri2info.CopyRegion = driCopyRegion; + +    return DRI2ScreenInit(pScreen, &dri2info); +} + +void +driCloseScreen(ScreenPtr pScreen) +{ +    DRI2CloseScreen(pScreen); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c new file mode 100644 index 0000000000..d166a365ac --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -0,0 +1,695 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include "compiler.h" +#include "xf86RAC.h" +#include "xf86PciInfo.h" +#include "xf86Pci.h" +#include "xf86Resources.h" +#include "mipointer.h" +#include "micmap.h" +#include <X11/extensions/randr.h> +#include "fb.h" +#include "edid.h" +#include "xf86i2c.h" +#include "xf86Crtc.h" +#include "miscstruct.h" +#include "dixstruct.h" +#include "xf86xv.h" +#include <X11/extensions/Xv.h> +#ifndef XSERVER_LIBPCIACCESS +#error "libpciaccess needed" +#endif + +#include <pciaccess.h> + +#include "xorg_tracker.h" +#include "xorg_winsys.h" + +static void AdjustFrame(int scrnIndex, int x, int y, int flags); +static Bool CloseScreen(int scrnIndex, ScreenPtr pScreen); +static Bool EnterVT(int scrnIndex, int flags); +static Bool SaveHWState(ScrnInfoPtr pScrn); +static Bool RestoreHWState(ScrnInfoPtr pScrn); + + +static ModeStatus ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, +			    int flags); +static void FreeScreen(int scrnIndex, int flags); +static void LeaveVT(int scrnIndex, int flags); +static Bool SwitchMode(int scrnIndex, DisplayModePtr mode, int flags); +static Bool ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, +		       char **argv); +static Bool PreInit(ScrnInfoPtr pScrn, int flags); + +typedef enum +{ +    OPTION_SW_CURSOR, +} modesettingOpts; + +static const OptionInfoRec Options[] = { +    {OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE}, +    {-1, NULL, OPTV_NONE, {0}, FALSE} +}; + +/* + * Functions that might be needed + */ + +static const char *exaSymbols[] = { +    "exaGetVersion", +    "exaDriverInit", +    "exaDriverFini", +    "exaOffscreenAlloc", +    "exaOffscreenFree", +    "exaWaitSync", +    NULL +}; + +static const char *fbSymbols[] = { +    "fbPictureInit", +    "fbScreenInit", +    NULL +}; + +static const char *ddcSymbols[] = { +    "xf86PrintEDID", +    "xf86SetDDCproperties", +    NULL +}; + +/* + * Exported Xorg driver functions to winsys + */ + +void +xorg_tracker_loader_ref_sym_lists() +{ +    LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL); +} + +const OptionInfoRec * +xorg_tracker_available_options(int chipid, int busid) +{ +    return Options; +} + +void +xorg_tracker_set_functions(ScrnInfoPtr scrn) +{ +    scrn->PreInit = PreInit; +    scrn->ScreenInit = ScreenInit; +    scrn->SwitchMode = SwitchMode; +    scrn->AdjustFrame = AdjustFrame; +    scrn->EnterVT = EnterVT; +    scrn->LeaveVT = LeaveVT; +    scrn->FreeScreen = FreeScreen; +    scrn->ValidMode = ValidMode; +} + +/* + * Static Xorg funtctions + */ + +static Bool +GetRec(ScrnInfoPtr pScrn) +{ +    if (pScrn->driverPrivate) +	return TRUE; + +    pScrn->driverPrivate = xnfcalloc(sizeof(modesettingRec), 1); + +    return TRUE; +} + +static void +FreeRec(ScrnInfoPtr pScrn) +{ +    if (!pScrn) +	return; + +    if (!pScrn->driverPrivate) +	return; + +    xfree(pScrn->driverPrivate); + +    pScrn->driverPrivate = NULL; +} + +static void +ProbeDDC(ScrnInfoPtr pScrn, int index) +{ +    ConfiguredMonitor = NULL; +} + +static Bool +CreateFrontBuffer(ScrnInfoPtr pScrn) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    ScreenPtr pScreen = pScrn->pScreen; +    PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); + +    ms->noEvict = TRUE; +    pScreen->ModifyPixmapHeader(rootPixmap, +				pScrn->virtualX, pScrn->virtualY, +				pScrn->depth, pScrn->bitsPerPixel, +				pScrn->displayWidth * pScrn->bitsPerPixel / 8, +				NULL); +    ms->noEvict = FALSE; + +    drmModeAddFB(ms->fd, +		 pScrn->virtualX, +		 pScrn->virtualY, +		 pScrn->depth, +		 pScrn->bitsPerPixel, +		 pScrn->displayWidth * pScrn->bitsPerPixel / 8, +		 xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id); + +    pScrn->frameX0 = 0; +    pScrn->frameY0 = 0; +    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + +    return TRUE; +} + +static Bool +crtc_resize(ScrnInfoPtr pScrn, int width, int height) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    //ScreenPtr pScreen = pScrn->pScreen; +    //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); +    //Bool fbAccessDisabled; +    //CARD8 *fbstart; + +    if (width == pScrn->virtualX && height == pScrn->virtualY) +	return TRUE; + +    ErrorF("RESIZING TO %dx%d\n", width, height); + +    pScrn->virtualX = width; +    pScrn->virtualY = height; + +    /* HW dependent - FIXME */ +    pScrn->displayWidth = pScrn->virtualX; + +    drmModeRmFB(ms->fd, ms->fb_id); + +    /* now create new frontbuffer */ +    return CreateFrontBuffer(pScrn); +} + +static const xf86CrtcConfigFuncsRec crtc_config_funcs = { +    crtc_resize +}; + +static Bool +PreInit(ScrnInfoPtr pScrn, int flags) +{ +    xf86CrtcConfigPtr xf86_config; +    modesettingPtr ms; +    rgb defaultWeight = { 0, 0, 0 }; +    EntityInfoPtr pEnt; +    EntPtr msEnt = NULL; +    char *BusID; +    int max_width, max_height; + +    if (pScrn->numEntities != 1) +	return FALSE; + +    pEnt = xf86GetEntityInfo(pScrn->entityList[0]); + +    if (flags & PROBE_DETECT) { +	ProbeDDC(pScrn, pEnt->index); +	return TRUE; +    } + +    /* Allocate driverPrivate */ +    if (!GetRec(pScrn)) +	return FALSE; + +    ms = modesettingPTR(pScrn); +    ms->SaveGeneration = -1; +    ms->pEnt = pEnt; + +    pScrn->displayWidth = 640;	       /* default it */ + +    if (ms->pEnt->location.type != BUS_PCI) +	return FALSE; + +    ms->PciInfo = xf86GetPciInfoForEntity(ms->pEnt->index); + +    /* Allocate an entity private if necessary */ +    if (xf86IsEntityShared(pScrn->entityList[0])) { +	FatalError("Entity"); +#if 0 +	msEnt = xf86GetEntityPrivate(pScrn->entityList[0], +				     modesettingEntityIndex)->ptr; +	ms->entityPrivate = msEnt; +#else +	(void)msEnt; +#endif +    } else +	ms->entityPrivate = NULL; + +    if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) { +	return FALSE; +    } + +    if (xf86IsEntityShared(pScrn->entityList[0])) { +	if (xf86IsPrimInitDone(pScrn->entityList[0])) { +	    /* do something */ +	} else { +	    xf86SetPrimInitDone(pScrn->entityList[0]); +	} +    } + +    BusID = xalloc(64); +    sprintf(BusID, "PCI:%d:%d:%d", +	    ((ms->PciInfo->domain << 8) | ms->PciInfo->bus), +	    ms->PciInfo->dev, ms->PciInfo->func +	); + +    ms->fd = drmOpen(NULL, BusID); + +    if (ms->fd < 0) +	return FALSE; + +    pScrn->racMemFlags = RAC_FB | RAC_COLORMAP; +    pScrn->monitor = pScrn->confScreen->monitor; +    pScrn->progClock = TRUE; +    pScrn->rgbBits = 8; + +    if (!xf86SetDepthBpp +	(pScrn, 0, 0, 0, +	 PreferConvert24to32 | SupportConvert24to32 | Support32bppFb)) +	return FALSE; + +    switch (pScrn->depth) { +    case 15: +    case 16: +    case 24: +	break; +    default: +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, +		   "Given depth (%d) is not supported by the driver\n", +		   pScrn->depth); +	return FALSE; +    } +    xf86PrintDepthBpp(pScrn); + +    if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) +	return FALSE; +    if (!xf86SetDefaultVisual(pScrn, -1)) +	return FALSE; + +    /* Process the options */ +    xf86CollectOptions(pScrn, NULL); +    if (!(ms->Options = xalloc(sizeof(Options)))) +	return FALSE; +    memcpy(ms->Options, Options, sizeof(Options)); +    xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, ms->Options); + +    /* Allocate an xf86CrtcConfig */ +    xf86CrtcConfigInit(pScrn, &crtc_config_funcs); +    xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + +    max_width = 8192; +    max_height = 8192; +    xf86CrtcSetSizeRange(pScrn, 320, 200, max_width, max_height); + +    if (xf86ReturnOptValBool(ms->Options, OPTION_SW_CURSOR, FALSE)) { +	ms->SWCursor = TRUE; +    } + +    SaveHWState(pScrn); + +    crtc_init(pScrn); +    output_init(pScrn); + +    if (!xf86InitialConfiguration(pScrn, TRUE)) { +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); +	RestoreHWState(pScrn); +	return FALSE; +    } + +    RestoreHWState(pScrn); + +    /* +     * If the driver can do gamma correction, it should call xf86SetGamma() here. +     */ +    { +	Gamma zeros = { 0.0, 0.0, 0.0 }; + +	if (!xf86SetGamma(pScrn, zeros)) { +	    return FALSE; +	} +    } + +    if (pScrn->modes == NULL) { +	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n"); +	return FALSE; +    } + +    pScrn->currentMode = pScrn->modes; + +    /* Set display resolution */ +    xf86SetDpi(pScrn, 0, 0); + +    /* Load the required sub modules */ +    if (!xf86LoadSubModule(pScrn, "fb")) { +	return FALSE; +    } + +    xf86LoaderReqSymLists(fbSymbols, NULL); + +    xf86LoadSubModule(pScrn, "exa"); + +#ifdef DRI2 +    xf86LoadSubModule(pScrn, "dri2"); +#endif + +    return TRUE; +} + +static Bool +SaveHWState(ScrnInfoPtr pScrn) +{ +    /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/ + +    return TRUE; +} + +static Bool +RestoreHWState(ScrnInfoPtr pScrn) +{ +    /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/ + +    return TRUE; +} + +static Bool +CreateScreenResources(ScreenPtr pScreen) +{ +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    PixmapPtr rootPixmap; +    Bool ret; + +    ms->noEvict = TRUE; + +    pScreen->CreateScreenResources = ms->createScreenResources; +    ret = pScreen->CreateScreenResources(pScreen); +    pScreen->CreateScreenResources = CreateScreenResources; + +    rootPixmap = pScreen->GetScreenPixmap(pScreen); + +    if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL)) +	FatalError("Couldn't adjust screen pixmap\n"); + +    ms->noEvict = FALSE; + +    drmModeAddFB(ms->fd, +		 pScrn->virtualX, +		 pScrn->virtualY, +		 pScrn->depth, +		 pScrn->bitsPerPixel, +		 pScrn->displayWidth * pScrn->bitsPerPixel / 8, +		 xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id); + +    AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); + +    return ret; +} + +static Bool +ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) +{ +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    VisualPtr visual; + +    /* deal with server regeneration */ +    if (ms->fd < 0) { +	char *BusID; + +	BusID = xalloc(64); +	sprintf(BusID, "PCI:%d:%d:%d", +		((ms->PciInfo->domain << 8) | ms->PciInfo->bus), +		ms->PciInfo->dev, ms->PciInfo->func +	    ); + +	ms->fd = drmOpen(NULL, BusID); + +	if (ms->fd < 0) +	    return FALSE; +    } + +    if (!ms->screen) { +	ms->screen = drm_api_hocks.create_screen(ms->fd, ms->PciInfo->device_id); + +	if (!ms->screen) { +	    FatalError("Could not init pipe_screen\n"); +	    return FALSE; +	} +    } + +    pScrn->pScreen = pScreen; + +    /* HW dependent - FIXME */ +    pScrn->displayWidth = pScrn->virtualX; + +    miClearVisualTypes(); + +    if (!miSetVisualTypes(pScrn->depth, +			  miGetDefaultVisualMask(pScrn->depth), +			  pScrn->rgbBits, pScrn->defaultVisual)) +	return FALSE; + +    if (!miSetPixmapDepths()) +	return FALSE; + +    pScrn->memPhysBase = 0; +    pScrn->fbOffset = 0; + +    if (!fbScreenInit(pScreen, NULL, +		      pScrn->virtualX, pScrn->virtualY, +		      pScrn->xDpi, pScrn->yDpi, +		      pScrn->displayWidth, pScrn->bitsPerPixel)) +	return FALSE; + +    if (pScrn->bitsPerPixel > 8) { +	/* Fixup RGB ordering */ +	visual = pScreen->visuals + pScreen->numVisuals; +	while (--visual >= pScreen->visuals) { +	    if ((visual->class | DynamicClass) == DirectColor) { +		visual->offsetRed = pScrn->offset.red; +		visual->offsetGreen = pScrn->offset.green; +		visual->offsetBlue = pScrn->offset.blue; +		visual->redMask = pScrn->mask.red; +		visual->greenMask = pScrn->mask.green; +		visual->blueMask = pScrn->mask.blue; +	    } +	} +    } + +    fbPictureInit(pScreen, NULL, 0); + +    ms->createScreenResources = pScreen->CreateScreenResources; +    pScreen->CreateScreenResources = CreateScreenResources; + +    xf86SetBlackWhitePixels(pScreen); + +    ms->exa = xorg_exa_init(pScrn); + +    miInitializeBackingStore(pScreen); +    xf86SetBackingStore(pScreen); +    xf86SetSilkenMouse(pScreen); +    miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); + +    /* Need to extend HWcursor support to handle mask interleave */ +    if (!ms->SWCursor) +	xf86_cursors_init(pScreen, 64, 64, +			  HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | +			  HARDWARE_CURSOR_ARGB); + +    /* Must force it before EnterVT, so we are in control of VT and +     * later memory should be bound when allocating, e.g rotate_mem */ +    pScrn->vtSema = TRUE; + +    pScreen->SaveScreen = xf86SaveScreen; +    ms->CloseScreen = pScreen->CloseScreen; +    pScreen->CloseScreen = CloseScreen; + +    if (!xf86CrtcScreenInit(pScreen)) +	return FALSE; + +    if (!miCreateDefColormap(pScreen)) +	return FALSE; + +    xf86DPMSInit(pScreen, xf86DPMSSet, 0); + +    if (serverGeneration == 1) +	xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); + +#if 1 +#ifdef DRI2 +    driScreenInit(pScreen); +#endif +#endif + +    return EnterVT(scrnIndex, 1); +} + +static void +AdjustFrame(int scrnIndex, int x, int y, int flags) +{ +    ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +    xf86OutputPtr output = config->output[config->compat_output]; +    xf86CrtcPtr crtc = output->crtc; + +    if (crtc && crtc->enabled) { +	crtc->funcs->mode_set(crtc, pScrn->currentMode, pScrn->currentMode, x, +			      y); +	crtc->x = output->initial_x + x; +	crtc->y = output->initial_y + y; +    } +} + +static void +FreeScreen(int scrnIndex, int flags) +{ +    FreeRec(xf86Screens[scrnIndex]); +} + +/* HACK */ +void +cursor_destroy(xf86CrtcPtr crtc); + +static void +LeaveVT(int scrnIndex, int flags) +{ +    ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +    modesettingPtr ms = modesettingPTR(pScrn); +    xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +    int o; + +    for (o = 0; o < config->num_crtc; o++) { +	xf86CrtcPtr crtc = config->crtc[o]; + +	cursor_destroy(crtc); + +	if (crtc->rotatedPixmap || crtc->rotatedData) { +	    crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap, +					crtc->rotatedData); +	    crtc->rotatedPixmap = NULL; +	    crtc->rotatedData = NULL; +	} +    } + +    drmModeRmFB(ms->fd, ms->fb_id); + +    RestoreHWState(pScrn); + +    pScrn->vtSema = FALSE; +} + +/* + * This gets called when gaining control of the VT, and from ScreenInit(). + */ +static Bool +EnterVT(int scrnIndex, int flags) +{ +    ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +    modesettingPtr ms = modesettingPTR(pScrn); + +    /* +     * Only save state once per server generation since that's what most +     * drivers do.  Could change this to save state at each VT enter. +     */ +    if (ms->SaveGeneration != serverGeneration) { +	ms->SaveGeneration = serverGeneration; +	SaveHWState(pScrn); +    } + +    if (!flags)			       /* signals startup as we'll do this in CreateScreenResources */ +	CreateFrontBuffer(pScrn); + +    if (!xf86SetDesiredModes(pScrn)) +	return FALSE; + +    return TRUE; +} + +static Bool +SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) +{ +    ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + +    return xf86SetSingleMode(pScrn, mode, RR_Rotate_0); +} + +static Bool +CloseScreen(int scrnIndex, ScreenPtr pScreen) +{ +    ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; +    modesettingPtr ms = modesettingPTR(pScrn); + +    if (pScrn->vtSema) { +	LeaveVT(scrnIndex, 0); +    } +#ifdef DRI2 +    driCloseScreen(pScreen); +#endif + +    pScreen->CreateScreenResources = ms->createScreenResources; + +    if (ms->exa) +	xorg_exa_close(pScrn); + +    drmClose(ms->fd); +    ms->fd = -1; + +    pScrn->vtSema = FALSE; +    pScreen->CloseScreen = ms->CloseScreen; +    return (*pScreen->CloseScreen) (scrnIndex, pScreen); +} + +static ModeStatus +ValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) +{ +    return MODE_OK; +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c new file mode 100644 index 0000000000..ac0bfc88a4 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -0,0 +1,534 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +/* FIXME ! */ +#define DRI_DRIVER_PATH "/ISO/X.Org/modular/i386/lib/dri" + +#include "xf86.h" +//#include "xf86_OSproc.h" +#include "xorg_tracker.h" + +//#include "pipe/p_winsys.h" +#include "pipe/p_format.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "pipe/p_inlines.h" + +struct exa_entity +{ +    ExaDriverPtr pExa; +    struct pipe_context *ctx; +    struct pipe_screen *scrn; +}; + +struct PixmapPriv +{ +    int flags; +    struct pipe_texture *tex; +    unsigned int color; +    struct pipe_surface *src_surf; /* for copies */ +    struct pipe_transfer *map_transfer; +}; + +/* + * Helper functions + */ + +static enum pipe_format +exa_get_pipe_format(int depth) +{ +    switch (depth) { +    case 32: +	return PIPE_FORMAT_A8R8G8B8_UNORM; +    case 24: +	return PIPE_FORMAT_X8R8G8B8_UNORM; +    case 16: +	return PIPE_FORMAT_R5G6B5_UNORM; +    case 15: +	return PIPE_FORMAT_A1R5G5B5_UNORM; +    case 8: +    case 4: +    case 1: +	return PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */ +    default: +	assert(0); +	return 0; +    } +} + +/* + * Static exported EXA functions + */ + +static void +ExaWaitMarker(ScreenPtr pScreen, int marker) +{ +} + +static int +ExaMarkSync(ScreenPtr pScreen) +{ +    return 1; +} + +static Bool +ExaPrepareAccess(PixmapPtr pPix, int index) +{ +    ScreenPtr pScreen = pPix->drawable.pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); +    struct exa_entity *exa = ms->exa; +    struct PixmapPriv *priv; +    //int ret; + +    priv = exaGetPixmapDriverPrivate(pPix); + +    if (!priv) +	return FALSE; + +    if (!priv->tex) +	return FALSE; +    { +	priv->map_transfer = +	    exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, +					PIPE_TRANSFER_READ_WRITE, +					0, 0, priv->tex->width[0], priv->tex->height[0]); + +	pPix->devPrivate.ptr = +	    exa->scrn->transfer_map(exa->scrn, priv->map_transfer); +	pPix->devKind = priv->map_transfer->stride; +    } + +    return TRUE; +} + +static void +ExaFinishAccess(PixmapPtr pPix, int index) +{ +    ScreenPtr pScreen = pPix->drawable.pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; +    struct PixmapPriv *priv; +    priv = exaGetPixmapDriverPrivate(pPix); + +    if (!priv) +	return; + +    if (!priv->map_transfer) +	return; + +    exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer); +    pipe_transfer_reference(&priv->map_transfer, NULL); + +} + +static void +ExaDone(PixmapPtr pPixmap) +{ +    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); +    struct exa_entity *exa = ms->exa; + +    if (!priv) +	return; + +    if (priv->src_surf) +	exa->scrn->tex_surface_release(exa->scrn, &priv->src_surf); +    priv->src_surf = NULL; +} + +static void +ExaDoneComposite(PixmapPtr pPixmap) +{ + +} + +static Bool +ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) +{ +    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); +    struct exa_entity *exa = ms->exa; + +    if (1) +        return FALSE; + +    if (pPixmap->drawable.depth < 15) +	return FALSE; + +    if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask)) +	return FALSE; + +    if (!priv || !priv->tex) +	return FALSE; + +    if (alu != GXcopy) +	return FALSE; + +    if (!exa->ctx || !exa->ctx->surface_fill) +	return FALSE; + +    priv->color = fg; + +    return TRUE; +} + +static void +ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1) +{ +    ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); +    struct pipe_surface *surf = +	exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, +				   PIPE_BUFFER_USAGE_GPU_READ | +				   PIPE_BUFFER_USAGE_GPU_WRITE); + +    exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0, +			   priv->color); + +    exa->scrn->tex_surface_release(exa->scrn, &surf); +} + +static Bool +ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, +	       int ydir, int alu, Pixel planeMask) +{ +    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); +    struct PixmapPriv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap); + +    if (1) +        return FALSE; + +    if (alu != GXcopy) +	return FALSE; + +    if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15) +	return FALSE; + +    if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask)) +	return FALSE; + +    if (!priv || !src_priv) +	return FALSE; + +    if (!priv->tex || !src_priv->tex) +	return FALSE; + +    if (!exa->ctx || !exa->ctx->surface_copy) +	return FALSE; + +    priv->src_surf = +	exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0, +				   PIPE_BUFFER_USAGE_GPU_READ | +				   PIPE_BUFFER_USAGE_GPU_WRITE); + +    return FALSE; +} + +static void +ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, +	int width, int height) +{ +    ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pDstPixmap); +    struct pipe_surface *surf = +	exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0, +				   PIPE_BUFFER_USAGE_GPU_READ | +				   PIPE_BUFFER_USAGE_GPU_WRITE); + +    exa->ctx->surface_copy(exa->ctx, 0, surf, dstX, dstY, priv->src_surf, +			   srcX, srcY, width, height); +    exa->scrn->tex_surface_release(exa->scrn, &surf); +} + +static Bool +ExaPrepareComposite(int op, PicturePtr pSrcPicture, +		    PicturePtr pMaskPicture, PicturePtr pDstPicture, +		    PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) +{ +    return FALSE; +} + +#if 0 +static Bool +ExaUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src, +		  int src_pitch) +{ +    ErrorF("UPLOAD\n"); + +    return FALSE; +} +#endif + +static void +ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, +	     int dstX, int dstY, int width, int height) +{ +} + +static Bool +ExaCheckComposite(int op, +		  PicturePtr pSrcPicture, PicturePtr pMaskPicture, +		  PicturePtr pDstPicture) +{ +    return FALSE; +} + +static void * +ExaCreatePixmap(ScreenPtr pScreen, int size, int align) +{ +    struct PixmapPriv *priv; + +    priv = xcalloc(1, sizeof(struct PixmapPriv)); +    if (!priv) +	return NULL; + +    return priv; +} + +static void +ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv) +{ +    struct PixmapPriv *priv = (struct PixmapPriv *)dPriv; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; + +    if (!priv) +	return; + +    if (priv->tex) +	ms->screen->texture_release(exa->scrn, &priv->tex); + +    xfree(priv); +} + +static Bool +ExaPixmapIsOffscreen(PixmapPtr pPixmap) +{ +    struct PixmapPriv *priv; + +    priv = exaGetPixmapDriverPrivate(pPixmap); + +    if (!priv) +	return FALSE; + +    if (priv->tex) +	return TRUE; + +    return FALSE; +} + +unsigned +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap) +{ +    ScreenPtr pScreen = pPixmap->drawable.pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    modesettingPtr ms = modesettingPTR(pScrn); +    struct PixmapPriv *priv; +    struct pipe_buffer *buffer = NULL; +    unsigned handle; +    unsigned stride; + +    if (!ms->exa) { +	FatalError("NO MS->EXA\n"); +	return 0; +    } + +    priv = exaGetPixmapDriverPrivate(pPixmap); + +    if (!priv) { +	FatalError("NO PIXMAP PRIVATE\n"); +	return 0; +    } + +    drm_api_hocks.buffer_from_texture(priv->tex, &buffer, &stride); +    drm_api_hocks.handle_from_buffer(ms->screen, buffer, &handle); +    pipe_buffer_reference(ms->screen, &buffer, NULL); +    return handle; +} + +static Bool +ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, +		      int depth, int bitsPerPixel, int devKind, +		      pointer pPixData) +{ +    ScreenPtr pScreen = pPixmap->drawable.pScreen; +    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); +    modesettingPtr ms = modesettingPTR(pScrn); +    //PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen); +    struct exa_entity *exa = ms->exa; + +    if (!priv) +	return FALSE; + +    if (depth <= 0) +	depth = pPixmap->drawable.depth; + +    if (bitsPerPixel <= 0) +	bitsPerPixel = pPixmap->drawable.bitsPerPixel; + +    if (width <= 0) +	width = pPixmap->drawable.width; + +    if (height <= 0) +	height = pPixmap->drawable.height; + +    if (width <= 0 || height <= 0 || depth <= 0) +	return FALSE; + +    miModifyPixmapHeader(pPixmap, width, height, depth, +			     bitsPerPixel, devKind, NULL); + +    /* Deal with screen resize */ +    if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) { +	pipe_texture_reference(&priv->tex, NULL); +    } + +    if (!priv->tex) { +	struct pipe_texture template; + +	memset(&template, 0, sizeof(template)); +	template.target = PIPE_TEXTURE_2D; +	template.compressed = 0; +	template.format = exa_get_pipe_format(depth); +	pf_get_block(template.format, &template.block); +	template.width[0] = width; +	template.height[0] = height; +	template.depth[0] = 1; +	template.last_level = 0; +	template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; +	priv->tex = exa->scrn->texture_create(exa->scrn, &template); +    } + +    return TRUE; +} + +struct pipe_texture * +xorg_exa_get_texture(PixmapPtr pPixmap) +{ +    struct PixmapPriv *priv = exaGetPixmapDriverPrivate(pPixmap); +    struct pipe_texture *tex = NULL; +    pipe_texture_reference(&tex, priv->tex); +    return tex; +} + +void +xorg_exa_close(ScrnInfoPtr pScrn) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa = ms->exa; + +    if (exa->ctx) +	exa->ctx->destroy(exa->ctx); + +    exaDriverFini(pScrn->pScreen); +    xfree(exa); +    ms->exa = NULL; +} + +void * +xorg_exa_init(ScrnInfoPtr pScrn) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    struct exa_entity *exa; +    ExaDriverPtr pExa; + +    exa = xcalloc(1, sizeof(struct exa_entity)); +    if (!exa) +	return NULL; + +    pExa = exaDriverAlloc(); +    if (!pExa) { +	goto out_err; +    } + +    memset(pExa, 0, sizeof(*pExa)); +    pExa->exa_major = 2; +    pExa->exa_minor = 2; +    pExa->memoryBase = 0; +    pExa->memorySize = 0; +    pExa->offScreenBase = 0; +    pExa->pixmapOffsetAlign = 0; +    pExa->pixmapPitchAlign = 1; +    pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS; +    pExa->maxX = 8191;		       /* FIXME */ +    pExa->maxY = 8191;		       /* FIXME */ +    pExa->WaitMarker = ExaWaitMarker; +    pExa->MarkSync = ExaMarkSync; +    pExa->PrepareSolid = ExaPrepareSolid; +    pExa->Solid = ExaSolid; +    pExa->DoneSolid = ExaDone; +    pExa->PrepareCopy = ExaPrepareCopy; +    pExa->Copy = ExaCopy; +    pExa->DoneCopy = ExaDone; +    pExa->CheckComposite = ExaCheckComposite; +    pExa->PrepareComposite = ExaPrepareComposite; +    pExa->Composite = ExaComposite; +    pExa->DoneComposite = ExaDoneComposite; +    pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen; +    pExa->PrepareAccess = ExaPrepareAccess; +    pExa->FinishAccess = ExaFinishAccess; +    //pExa->UploadToScreen = ExaUploadToScreen; +    pExa->UploadToScreen = NULL; +    pExa->CreatePixmap = ExaCreatePixmap; +    pExa->DestroyPixmap = ExaDestroyPixmap; +    pExa->ModifyPixmapHeader = ExaModifyPixmapHeader; + +    if (!exaDriverInit(pScrn->pScreen, pExa)) { +	goto out_err; +    } + +    exa->scrn = ms->screen; +    exa->ctx = drm_api_hocks.create_context(exa->scrn); +    /* Share context with DRI */ +    ms->ctx = exa->ctx; + +    return (void *)exa; + +  out_err: +    xorg_exa_close(pScrn); + +    return NULL; +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c new file mode 100644 index 0000000000..950af942f5 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_output.c @@ -0,0 +1,296 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "xorg-server.h" +#include <xf86.h> +#include <xf86i2c.h> +#include <xf86Crtc.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> + +#define DPMS_SERVER +#include <X11/extensions/dpms.h> + +#include "X11/Xatom.h" + +#include "xorg_tracker.h" + +static char *connector_enum_list[] = { +    "Unknown", +    "VGA", +    "DVI-I", +    "DVI-D", +    "DVI-A", +    "Composite", +    "SVIDEO", +    "LVDS", +    "Component", +    "9-pin DIN", +    "DisplayPort", +    "HDMI Type A", +    "HDMI Type B", +}; + +static void +dpms(xf86OutputPtr output, int mode) +{ +} + +static void +save(xf86OutputPtr output) +{ +} + +static void +restore(xf86OutputPtr output) +{ +} + +static int +mode_valid(xf86OutputPtr output, DisplayModePtr pMode) +{ +    return MODE_OK; +} + +static Bool +mode_fixup(xf86OutputPtr output, DisplayModePtr mode, +	   DisplayModePtr adjusted_mode) +{ +    return TRUE; +} + +static void +prepare(xf86OutputPtr output) +{ +    dpms(output, DPMSModeOff); +} + +static void +mode_set(xf86OutputPtr output, DisplayModePtr mode, +	 DisplayModePtr adjusted_mode) +{ +} + +static void +commit(xf86OutputPtr output) +{ +    dpms(output, DPMSModeOn); + +    if (output->scrn->pScreen != NULL) +	xf86_reload_cursors(output->scrn->pScreen); +} + +static xf86OutputStatus +detect(xf86OutputPtr output) +{ +    drmModeConnectorPtr drm_connector = output->driver_private; + +    switch (drm_connector->connection) { +    case DRM_MODE_CONNECTED: +	return XF86OutputStatusConnected; +    case DRM_MODE_DISCONNECTED: +	return XF86OutputStatusDisconnected; +    default: +	return XF86OutputStatusUnknown; +    } +} + +static DisplayModePtr +get_modes(xf86OutputPtr output) +{ +    drmModeConnectorPtr drm_connector = output->driver_private; +    drmModeModeInfoPtr drm_mode = NULL; +    DisplayModePtr modes = NULL, mode = NULL; +    int i; + +    for (i = 0; i < drm_connector->count_modes; i++) { +	drm_mode = &drm_connector->modes[i]; +	if (drm_mode) { +	    mode = xcalloc(1, sizeof(DisplayModeRec)); +	    if (!mode) +		continue; +	    mode->type = 0; +	    mode->Clock = drm_mode->clock; +	    mode->HDisplay = drm_mode->hdisplay; +	    mode->HSyncStart = drm_mode->hsync_start; +	    mode->HSyncEnd = drm_mode->hsync_end; +	    mode->HTotal = drm_mode->htotal; +	    mode->VDisplay = drm_mode->vdisplay; +	    mode->VSyncStart = drm_mode->vsync_start; +	    mode->VSyncEnd = drm_mode->vsync_end; +	    mode->VTotal = drm_mode->vtotal; +	    mode->Flags = drm_mode->flags; +	    mode->HSkew = drm_mode->hskew; +	    mode->VScan = drm_mode->vscan; +	    mode->VRefresh = xf86ModeVRefresh(mode); +	    mode->Private = (void *)drm_mode; +	    xf86SetModeDefaultName(mode); +	    modes = xf86ModesAdd(modes, mode); +	    xf86PrintModeline(0, mode); +	} +    } + +    return modes; +} + +static void +destroy(xf86OutputPtr output) +{ +    drmModeFreeConnector(output->driver_private); +} + +static void +create_resources(xf86OutputPtr output) +{ +#ifdef RANDR_12_INTERFACE +#endif /* RANDR_12_INTERFACE */ +} + +#ifdef RANDR_12_INTERFACE +static Bool +set_property(xf86OutputPtr output, Atom property, RRPropertyValuePtr value) +{ +    return TRUE; +} +#endif /* RANDR_12_INTERFACE */ + +#ifdef RANDR_13_INTERFACE +static Bool +get_property(xf86OutputPtr output, Atom property) +{ +    return TRUE; +} +#endif /* RANDR_13_INTERFACE */ + +#ifdef RANDR_GET_CRTC_INTERFACE +static xf86CrtcPtr +get_crtc(xf86OutputPtr output) +{ +    return NULL; +} +#endif + +static const xf86OutputFuncsRec output_funcs = { +    .create_resources = create_resources, +    .dpms = dpms, +    .save = save, +    .restore = restore, +    .mode_valid = mode_valid, +    .mode_fixup = mode_fixup, +    .prepare = prepare, +    .mode_set = mode_set, +    .commit = commit, +    .detect = detect, +    .get_modes = get_modes, +#ifdef RANDR_12_INTERFACE +    .set_property = set_property, +#endif +#ifdef RANDR_13_INTERFACE +    .get_property = get_property, +#endif +    .destroy = destroy, +#ifdef RANDR_GET_CRTC_INTERFACE +    .get_crtc = get_crtc, +#endif +}; + +void +output_init(ScrnInfoPtr pScrn) +{ +    modesettingPtr ms = modesettingPTR(pScrn); +    xf86OutputPtr output; +    drmModeResPtr res; +    drmModeConnectorPtr drm_connector = NULL; +    drmModeEncoderPtr drm_encoder = NULL; +    char *name; +    int c, v, p; + +    res = drmModeGetResources(ms->fd); +    if (res == 0) { +	DRV_ERROR("Failed drmModeGetResources\n"); +	return; +    } + +    for (c = 0; c < res->count_connectors; c++) { +	drm_connector = drmModeGetConnector(ms->fd, res->connectors[c]); +	if (!drm_connector) +	    goto out; + +#if 0 +	for (p = 0; p < drm_connector->count_props; p++) { +	    drmModePropertyPtr prop; + +	    prop = drmModeGetProperty(ms->fd, drm_connector->props[p]); + +	    name = NULL; +	    if (prop) { +		ErrorF("VALUES %d\n", prop->count_values); + +		for (v = 0; v < prop->count_values; v++) +		    ErrorF("%s %lld\n", prop->name, prop->values[v]); +	    } +	} +#else +	(void)p; +	(void)v; +#endif + +	name = connector_enum_list[drm_connector->connector_type]; + +	output = xf86OutputCreate(pScrn, &output_funcs, name); +	if (!output) +	    continue; + +	drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]); +	if (drm_encoder) { +	    output->possible_crtcs = drm_encoder->possible_crtcs; +	    output->possible_clones = drm_encoder->possible_clones; +	} else { +	    output->possible_crtcs = 0; +	    output->possible_clones = 0; +	} +	output->driver_private = drm_connector; +	output->subpixel_order = SubPixelHorizontalRGB; +	output->interlaceAllowed = FALSE; +	output->doubleScanAllowed = FALSE; +    } + +  out: +    drmModeFreeResources(res); +} + +/* vim: set sw=4 ts=8 sts=4: */ diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h new file mode 100644 index 0000000000..82c3890dfb --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_tracker.h @@ -0,0 +1,130 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#ifndef _XORG_TRACKER_H_ +#define _XORG_TRACKER_H_ + +#include <errno.h> +#include <drm.h> +#include <xf86drm.h> +#include <xf86drmMode.h> +#include "exa.h" + +#include "pipe/p_screen.h" +#include "state_tracker/drm_api.h" + +#define DRV_ERROR(msg)	xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg); + +typedef struct +{ +    int lastInstance; +    int refCount; +    ScrnInfoPtr pScrn_1; +    ScrnInfoPtr pScrn_2; +} EntRec, *EntPtr; + +typedef struct _modesettingRec +{ +    /* drm */ +    int fd; +    unsigned fb_id; + +    /* X */ +    EntPtr entityPrivate; + +    int Chipset; +    EntityInfoPtr pEnt; +    struct pci_device *PciInfo; + +    Bool noAccel; +    Bool SWCursor; +    CloseScreenProcPtr CloseScreen; + +    /* Broken-out options. */ +    OptionInfoPtr Options; + +    unsigned int SaveGeneration; + +    CreateScreenResourcesProcPtr createScreenResources; + +    /* gallium */ +    struct pipe_screen *screen; +    struct pipe_context *ctx; + +    /* exa */ +    void *exa; +    Bool noEvict; + +} modesettingRec, *modesettingPtr; + +#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate)) + + +/*********************************************************************** + * xorg_exa.c + */ +struct pipe_texture * +xorg_exa_get_texture(PixmapPtr pPixmap); + +unsigned +xorg_exa_get_pixmap_handle(PixmapPtr pPixmap); + +void * +xorg_exa_init(ScrnInfoPtr pScrn); + +void +xorg_exa_close(ScrnInfoPtr pScrn); + + +/*********************************************************************** + * xorg_dri2.c + */ +Bool +driScreenInit(ScreenPtr pScreen); + +void +driCloseScreen(ScreenPtr pScreen); + + +/*********************************************************************** + * xorg_crtc.c + */ +void +crtc_init(ScrnInfoPtr pScrn); + + +/*********************************************************************** + * xorg_output.c + */ +void +output_init(ScrnInfoPtr pScrn); + + +#endif /* _XORG_TRACKER_H_ */ diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h new file mode 100644 index 0000000000..d523080e90 --- /dev/null +++ b/src/gallium/state_trackers/xorg/xorg_winsys.h @@ -0,0 +1,51 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +/* + * File with all the junk needed to personalize the a xorg driver. + */ + +#ifndef _XORG_WINSYS_H_ +#define _XORG_WINSYS_H_ + +#include "xorg-server.h" +#include "xf86.h" +#include "xf86Resources.h" +#include "pciaccess.h" + +#ifndef XSERVER_LIBPCIACCESS +#error "libpciaccess needed" +#endif + +void xorg_tracker_set_functions(ScrnInfoPtr scrn); +const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid); +void xorg_tracker_loader_ref_sym_lists(void); + +#endif diff --git a/src/gallium/winsys/drm/intel/dri2/Makefile b/src/gallium/winsys/drm/intel/dri2/Makefile new file mode 100644 index 0000000000..1a02109274 --- /dev/null +++ b/src/gallium/winsys/drm/intel/dri2/Makefile @@ -0,0 +1,22 @@ +TOP = ../../../../../.. +include $(TOP)/configs/current + +LIBNAME = i915_dri.so + +PIPE_DRIVERS = \ +	$(TOP)/src/gallium/state_trackers/dri2/libdri2drm.a \ +	$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \ +	$(TOP)/src/gallium/drivers/i915simple/libi915simple.a + + +DRIVER_SOURCES = + +C_SOURCES = \ +	$(COMMON_GALLIUM_SOURCES) \ +	$(DRIVER_SOURCES) + +include ../../Makefile.template + +DRI_LIB_DEPS += -ldrm_intel + +symlinks: diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c index d9556e1f38..0137433785 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c @@ -21,7 +21,7 @@ intel_be_batchbuffer_alloc(struct intel_be_context *intel)  	batch->base.size = 0;  	batch->base.actual_size = intel->device->max_batch_size;  	batch->base.relocs = 0; -	batch->base.max_relocs = INTEL_DEFAULT_RELOCS; +	batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/  	batch->base.map = malloc(batch->base.actual_size);  	memset(batch->base.map, 0, batch->base.actual_size); @@ -47,7 +47,6 @@ intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)  	batch->base.size = batch->base.actual_size - BATCH_RESERVED;  	batch->base.relocs = 0; -	batch->base.max_relocs = INTEL_DEFAULT_RELOCS;  	batch->bo = drm_intel_bo_alloc(dev->pools.gem,  	                               "gallium3d_batch_buffer", diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c index 595de44726..2e191a6d12 100644 --- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c +++ b/src/gallium/winsys/drm/intel/gem/intel_be_device.c @@ -26,6 +26,12 @@ intel_be_buffer_map(struct pipe_winsys *winsys,  	int write = 0;  	int ret; +        if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { +           /* Remove this when drm_intel_bo_map supports DONTBLOCK  +            */ +           return NULL; +        } +  	if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)  		write = 1; diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile new file mode 100644 index 0000000000..8130fdb226 --- /dev/null +++ b/src/gallium/winsys/drm/intel/xorg/Makefile @@ -0,0 +1,42 @@ +TARGET     = modesetting_drv.so +CFILES     = $(wildcard ./*.c) +OBJECTS    = $(patsubst ./%.c,./%.o,$(CFILES)) +GALLIUMDIR = ../../../.. +TOP        = ../../../../../.. + +include ${TOP}/configs/current + +CFLAGS = -DHAVE_CONFIG_H \ +         -g -Wall -Wimplicit-function-declaration -fPIC \ +         $(shell pkg-config --cflags pixman-1 xorg-server libdrm xproto) \ +	 -I../gem \ +         -I${GALLIUMDIR}/include \ +         -I${GALLIUMDIR}/drivers \ +         -I${GALLIUMDIR}/auxiliary \ +         -I${TOP}/src/mesa \ +         -I$(TOP)/include \ +         -I$(TOP)/src/egl/main + +LIBS = \ +	$(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a \ +	$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \ +	$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \ +	$(GALLIUM_AUXILIARIES) + +############################################# + + + +all default: $(TARGET) + +$(TARGET): $(OBJECTS) Makefile $(GALLIUMDIR)/state_trackers/xorg/libxorgtracker.a +	$(TOP)/bin/mklib -noprefix -o $@ \ +	$(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_intel + +clean: +	rm -rf $(OBJECTS) $(TARGET) + +install: +	cp $(TARGET) /opt/kms/lib/xorg/modules/drivers + +.PHONY	= all clean install diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c new file mode 100644 index 0000000000..aea39247e5 --- /dev/null +++ b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c @@ -0,0 +1,156 @@ +/* + * 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. + * + * + * Author: Alan Hourihane <alanh@tungstengraphics.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + * + */ + +#include "../../../../state_trackers/xorg/xorg_winsys.h" + +static void intel_xorg_identify(int flags); +static Bool intel_xorg_pci_probe(DriverPtr driver, +				 int entity_num, +				 struct pci_device *device, +				 intptr_t match_data); + +static const struct pci_id_match intel_xorg_device_match[] = { +    {0x8086, 0x2592, 0xffff, 0xffff, 0, 0, 0}, +    {0x8086, 0x27A2, 0xffff, 0xffff, 0, 0, 0}, +    {0, 0, 0}, +}; + +static SymTabRec intel_xorg_chipsets[] = { +    {0x2592, "Intel Graphics Device"}, +    {0x27A2, "Intel Graphics Device"}, +    {-1, NULL} +}; + +static PciChipsets intel_xorg_pci_devices[] = { +    {0x2592, 0x2592, RES_SHARED_VGA}, +    {0x27A2, 0x27A2, RES_SHARED_VGA}, +    {-1, -1, RES_UNDEFINED} +}; + +static XF86ModuleVersionInfo intel_xorg_version = { +    "modesetting", +    MODULEVENDORSTRING, +    MODINFOSTRING1, +    MODINFOSTRING2, +    XORG_VERSION_CURRENT, +    0, 1, 0, /* major, minor, patch */ +    ABI_CLASS_VIDEODRV, +    ABI_VIDEODRV_VERSION, +    MOD_CLASS_VIDEODRV, +    {0, 0, 0, 0} +}; + +/* + * Xorg driver exported structures + */ + +_X_EXPORT DriverRec modesetting = { +    1, +    "modesetting", +    intel_xorg_identify, +    NULL, +    xorg_tracker_available_options, +    NULL, +    0, +    NULL, +    intel_xorg_device_match, +    intel_xorg_pci_probe +}; + +static MODULESETUPPROTO(intel_xorg_setup); + +_X_EXPORT XF86ModuleData modesettingModuleData = { +    &intel_xorg_version, +    intel_xorg_setup, +    NULL +}; + +/* + * Xorg driver functions + */ + +static pointer +intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin) +{ +    static Bool setupDone = 0; + +    /* This module should be loaded only once, but check to be sure. +     */ +    if (!setupDone) { +	setupDone = 1; +	xf86AddDriver(&modesetting, module, HaveDriverFuncs); + +	/* +	 * Tell the loader about symbols from other modules that this module +	 * might refer to. +	 */ +	xorg_tracker_loader_ref_sym_lists(); + +	/* +	 * The return value must be non-NULL on success even though there +	 * is no TearDownProc. +	 */ +	return (pointer) 1; +    } else { +	if (errmaj) +	    *errmaj = LDR_ONCEONLY; +	return NULL; +    } +} + +static void +intel_xorg_identify(int flags) +{ +    xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers", +		      intel_xorg_chipsets); +} + +static Bool +intel_xorg_pci_probe(DriverPtr driver, +	  int entity_num, struct pci_device *device, intptr_t match_data) +{ +    ScrnInfoPtr scrn = NULL; +    EntityInfoPtr entity; + +    scrn = xf86ConfigPciEntity(scrn, 0, entity_num, intel_xorg_pci_devices, +			       NULL, NULL, NULL, NULL, NULL); +    if (scrn != NULL) { +	scrn->driverVersion = 1; +	scrn->driverName = "modesetting"; +	scrn->name = "modesetting"; +	scrn->Probe = NULL; + +	entity = xf86GetEntityInfo(entity_num); + +	/* Use all the functions from the xorg tracker */ +	xorg_tracker_set_functions(scrn); +    } +    return scrn != NULL; +} diff --git a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c index e3ee985afc..54c7dd46b1 100644 --- a/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c +++ b/src/gallium/winsys/drm/nouveau/common/nouveau_winsys_pipe.c @@ -119,6 +119,12 @@ nouveau_pipe_bo_map(struct pipe_winsys *pws, struct pipe_buffer *buf,  	struct nouveau_pipe_buffer *nvbuf = nouveau_pipe_buffer(buf);  	uint32_t map_flags = 0; +        if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { +           /* Remove this when this code is modified to support DONTBLOCK  +            */ +           return NULL; +        } +  	if (flags & PIPE_BUFFER_USAGE_CPU_READ)  		map_flags |= NOUVEAU_BO_RD;  	if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) diff --git a/src/gallium/winsys/drm/radeon/radeon_buffer.c b/src/gallium/winsys/drm/radeon/radeon_buffer.c index 259a505c0a..918d2f98e2 100644 --- a/src/gallium/winsys/drm/radeon/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/radeon_buffer.c @@ -112,6 +112,12 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,      struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer;      int write = 0; +    if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) { +       /* Remove this when radeon_bo_map supports DONTBLOCK  +        */ +       return NULL; +    } +      if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {          write = 1;      } diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c index acfb8ec4ea..c4623e82f9 100644 --- a/src/gallium/winsys/g3dvl/xsp_winsys.c +++ b/src/gallium/winsys/g3dvl/xsp_winsys.c @@ -6,6 +6,7 @@  #include <util/u_memory.h>  #include <util/u_math.h>  #include <softpipe/sp_winsys.h> +#include <softpipe/sp_texture.h>  /* pipe_winsys implementation */ @@ -162,7 +163,7 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *  	xsp_winsys->fbimage.width = surface->width;  	xsp_winsys->fbimage.height = surface->height;  	xsp_winsys->fbimage.bytes_per_line = surface->width * (xsp_winsys->fbimage.bits_per_pixel >> 3); -	xsp_winsys->fbimage.data = pipe_surface_map(surface, 0); +	xsp_winsys->fbimage.data = ((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset;  	XPutImage  	( @@ -178,7 +179,6 @@ static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *  		surface->height  	);  	XFlush(xsp_context->display); -	pipe_surface_unmap(surface);  }  static const char* xsp_get_name(struct pipe_winsys *pws) diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 986f751bdc..9bee212c6a 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -308,7 +308,7 @@ _mesa_init_driver_state(GLcontext *ctx)     ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag);     ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag);     ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); -   ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); +   ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);     ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE);     ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE);     ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); diff --git a/src/mesa/drivers/dri/ffb/ffb_state.c b/src/mesa/drivers/dri/ffb/ffb_state.c index ee0fe4e0db..5eb8f417ff 100644 --- a/src/mesa/drivers/dri/ffb/ffb_state.c +++ b/src/mesa/drivers/dri/ffb/ffb_state.c @@ -275,7 +275,7 @@ ffbDDStencilFuncSeparate(GLcontext *ctx, GLenum face, GLenum func,  	/* We will properly update sw/hw state when stenciling is  	 * enabled.  	 */ -	if (! ctx->Stencil.Enabled) +	if (! ctx->Stencil._Enabled)  		return;  	stencilctl = fmesa->stencilctl; @@ -333,7 +333,7 @@ ffbDDStencilOpSeparate(GLcontext *ctx, GLenum face, GLenum fail,  	/* We will properly update sw/hw state when stenciling is  	 * enabled.  	 */ -	if (! ctx->Stencil.Enabled) +	if (! ctx->Stencil._Enabled)  		return;  	stencilctl = fmesa->stencilctl; diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c index 82370162f5..c724218cf5 100644 --- a/src/mesa/drivers/dri/i965/brw_cc.c +++ b/src/mesa/drivers/dri/i965/brw_cc.c @@ -88,7 +88,7 @@ cc_unit_populate_key(struct brw_context *brw, struct brw_cc_unit_key *key)     memset(key, 0, sizeof(*key)); -   key->stencil = ctx->Stencil.Enabled; +   key->stencil = ctx->Stencil._Enabled;     key->stencil_two_side = ctx->Stencil._TestTwoSide;     if (key->stencil) { diff --git a/src/mesa/drivers/dri/i965/brw_fallback.c b/src/mesa/drivers/dri/i965/brw_fallback.c index 5f4f2d515d..299357409c 100644 --- a/src/mesa/drivers/dri/i965/brw_fallback.c +++ b/src/mesa/drivers/dri/i965/brw_fallback.c @@ -75,7 +75,7 @@ static GLboolean do_check_fallback(struct brw_context *brw)     /* _NEW_STENCIL       */ -   if (ctx->Stencil.Enabled && +   if (ctx->Stencil._Enabled &&         (ctx->DrawBuffer->Name == 0 && !brw->intel.hw_stencil)) {        DBG("FALLBACK: stencil\n");        return GL_TRUE; diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c index 06a6f3f0f4..879000644b 100644 --- a/src/mesa/drivers/dri/i965/brw_wm.c +++ b/src/mesa/drivers/dri/i965/brw_wm.c @@ -210,7 +210,7 @@ static void brw_wm_populate_key( struct brw_context *brw,        lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;     /* _NEW_STENCIL */ -   if (ctx->Stencil.Enabled) { +   if (ctx->Stencil._Enabled) {        lookup |= IZ_STENCIL_TEST_ENABLE_BIT;        if (ctx->Stencil.WriteMask[0] || diff --git a/src/mesa/drivers/dri/intel/intel_buffers.c b/src/mesa/drivers/dri/intel/intel_buffers.c index 7f2144abd4..732bae5b5a 100644 --- a/src/mesa/drivers/dri/intel/intel_buffers.c +++ b/src/mesa/drivers/dri/intel/intel_buffers.c @@ -263,7 +263,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)        }     }     else { -      /* XXX FBO: instead of FALSE, pass ctx->Stencil.Enabled ??? */ +      /* XXX FBO: instead of FALSE, pass ctx->Stencil._Enabled ??? */        FALLBACK(intel, INTEL_FALLBACK_STENCIL_BUFFER, GL_FALSE);     } @@ -274,7 +274,7 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)        ctx->Driver.Enable(ctx, GL_DEPTH_TEST,                           (ctx->Depth.Test && fb->Visual.depthBits > 0));        ctx->Driver.Enable(ctx, GL_STENCIL_TEST, -                         (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0)); +                         (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));     }     else {        ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL); diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c index c3ba50f355..28281b3861 100644 --- a/src/mesa/drivers/dri/intel/intel_clear.c +++ b/src/mesa/drivers/dri/intel/intel_clear.c @@ -247,13 +247,10 @@ static const char *buffer_names[] = {     [BUFFER_BACK_LEFT] = "back",     [BUFFER_FRONT_RIGHT] = "front right",     [BUFFER_BACK_RIGHT] = "back right", -   [BUFFER_AUX0] = "aux0", -   [BUFFER_AUX1] = "aux1", -   [BUFFER_AUX2] = "aux2", -   [BUFFER_AUX3] = "aux3",     [BUFFER_DEPTH] = "depth",     [BUFFER_STENCIL] = "stencil",     [BUFFER_ACCUM] = "accum", +   [BUFFER_AUX0] = "aux0",     [BUFFER_COLOR0] = "color0",     [BUFFER_COLOR1] = "color1",     [BUFFER_COLOR2] = "color2", diff --git a/src/mesa/drivers/dri/intel/intel_pixel.c b/src/mesa/drivers/dri/intel/intel_pixel.c index 5e32288844..9f4b4ff0ba 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel.c +++ b/src/mesa/drivers/dri/intel/intel_pixel.c @@ -112,7 +112,7 @@ intel_check_blit_fragment_ops(GLcontext * ctx, GLboolean src_alpha_is_one)        return GL_FALSE;     } -   if (ctx->Stencil.Enabled) { +   if (ctx->Stencil._Enabled) {        DBG("fallback due to image stencil\n");        return GL_FALSE;     } diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c index 7c7aa6097c..d50dd68092 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c @@ -87,7 +87,7 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)              ctx->Color.AlphaEnabled ||              ctx->Depth.Test ||              ctx->Fog.Enabled || -            ctx->Stencil.Enabled || +            ctx->Stencil._Enabled ||              !ctx->Color.ColorMask[0] ||              !ctx->Color.ColorMask[1] ||              !ctx->Color.ColorMask[2] || diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c index 7be7ea82b3..e8d5ac8569 100644 --- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c +++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c @@ -233,7 +233,7 @@ intel_stencil_drawpixels(GLcontext * ctx,     }     /* We don't support stencil testing/ops here */ -   if (ctx->Stencil.Enabled) +   if (ctx->Stencil._Enabled)        return GL_FALSE;     /* We use FBOs for our wrapping of the depthbuffer into a color diff --git a/src/mesa/drivers/dri/mga/mgapixel.c b/src/mesa/drivers/dri/mga/mgapixel.c index 9f90047ba5..977dfa0b76 100644 --- a/src/mesa/drivers/dri/mga/mgapixel.c +++ b/src/mesa/drivers/dri/mga/mgapixel.c @@ -133,7 +133,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )  		    ctx->Depth.Test ||  		    ctx->Fog.Enabled ||  		    ctx->Scissor.Enabled || -		    ctx->Stencil.Enabled || +		    ctx->Stencil._Enabled ||  		    !ctx->Color.ColorMask[0] ||  		    !ctx->Color.ColorMask[1] ||  		    !ctx->Color.ColorMask[2] || diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c index be68821dc1..2797cbb3dc 100644 --- a/src/mesa/drivers/dri/r200/r200_pixel.c +++ b/src/mesa/drivers/dri/r200/r200_pixel.c @@ -87,7 +87,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )  		    ctx->Depth.Test ||  		    ctx->Fog.Enabled ||  		    ctx->Scissor.Enabled || -		    ctx->Stencil.Enabled || +		    ctx->Stencil._Enabled ||  		    !ctx->Color.ColorMask[0] ||  		    !ctx->Color.ColorMask[1] ||  		    !ctx->Color.ColorMask[2] || diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index ade45f581c..37dae6c886 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -2205,7 +2205,7 @@ static void r300ResetHwState(r300ContextPtr r300)  	r300DepthFunc(ctx, ctx->Depth.Func);  	/* stencil */ -	r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); +	r300Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);  	r300StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);  	r300StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0],  				ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]); diff --git a/src/mesa/drivers/dri/savage/savagestate.c b/src/mesa/drivers/dri/savage/savagestate.c index 73d85ed57b..84e1b52585 100644 --- a/src/mesa/drivers/dri/savage/savagestate.c +++ b/src/mesa/drivers/dri/savage/savagestate.c @@ -514,7 +514,7 @@ static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)  	imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;  	imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;      } -    else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil) +    else if (imesa->glCtx->Stencil._Enabled && imesa->hw_stencil)      {          /* Need to keep Z on for Stencil. */  	imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always; @@ -1092,7 +1092,7 @@ static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)  		FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);  	    else {  		imesa->regs.s4.stencilCtrl.ni.stencilEn = state; -		if (ctx->Stencil.Enabled && +		if (ctx->Stencil._Enabled &&  		    imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)  		{  		    /* Stencil buffer requires Z enabled. */ diff --git a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c index 9ab9c05f2b..18729d5ae0 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_pixels.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_pixels.c @@ -610,7 +610,7 @@ tdfx_drawpixels_R8G8B8A8(GLcontext * ctx, GLint x, GLint y,         ctx->Depth.Test ||         ctx->Fog.Enabled ||         ctx->Scissor.Enabled || -       ctx->Stencil.Enabled || +       ctx->Stencil._Enabled ||         !ctx->Color.ColorMask[0] ||         !ctx->Color.ColorMask[1] ||         !ctx->Color.ColorMask[2] || diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c index cf840c57a7..2cd8e12d95 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_render.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c @@ -740,7 +740,7 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa )     }     if ( fxMesa->dirty & TDFX_UPLOAD_STENCIL ) { -      if (fxMesa->glCtx->Stencil.Enabled) { +      if (fxMesa->glCtx->Stencil._Enabled) {           fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT);           fxMesa->Glide.grStencilOp(fxMesa->Stencil.FailFunc,                                     fxMesa->Stencil.ZFailFunc, diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index a2d7bcd97d..591df8a905 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -459,7 +459,7 @@ static void tdfxUpdateStencil( GLcontext *ctx )     }     if (fxMesa->haveHwStencil) { -      if (ctx->Stencil.Enabled) { +      if (ctx->Stencil._Enabled) {           fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER;           fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff;           fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff; diff --git a/src/mesa/drivers/dri/unichrome/via_state.c b/src/mesa/drivers/dri/unichrome/via_state.c index 1cef01ab03..840e4e42da 100644 --- a/src/mesa/drivers/dri/unichrome/via_state.c +++ b/src/mesa/drivers/dri/unichrome/via_state.c @@ -1342,7 +1342,7 @@ static void viaChooseStencilState(GLcontext *ctx)  {      struct via_context *vmesa = VIA_CONTEXT(ctx); -    if (ctx->Stencil.Enabled) { +    if (ctx->Stencil._Enabled) {          GLuint temp;          vmesa->regEnable |= HC_HenST_MASK; diff --git a/src/mesa/drivers/ggi/default/stubs.c b/src/mesa/drivers/ggi/default/stubs.c index 7b442b6d20..62722972b2 100644 --- a/src/mesa/drivers/ggi/default/stubs.c +++ b/src/mesa/drivers/ggi/default/stubs.c @@ -472,7 +472,7 @@ static void GGItriangle_flat_depth(GLcontext *ctx, const SWvertex *v0, const SWv  static swrast_tri_func ggimesa_stubs_get_triangle_func(GLcontext *ctx)  { -	if (ctx->Stencil.Enabled) return NULL; +	if (ctx->Stencil._Enabled) return NULL;  	if (ctx->Polygon.SmoothFlag) return NULL;  	if (ctx->Polygon.StippleFlag) return NULL;  	if (ctx->Texture._ReallyEnabled) return NULL;   diff --git a/src/mesa/drivers/glide/fxdd.c b/src/mesa/drivers/glide/fxdd.c index 338cd37382..1bcf2512a6 100644 --- a/src/mesa/drivers/glide/fxdd.c +++ b/src/mesa/drivers/glide/fxdd.c @@ -1948,7 +1948,7 @@ fx_check_IsInHardware(GLcontext * ctx)        return FX_FALLBACK_RENDER_MODE;     } -   if (ctx->Stencil.Enabled && !fxMesa->haveHwStencil) { +   if (ctx->Stencil._Enabled && !fxMesa->haveHwStencil) {        return FX_FALLBACK_STENCIL;     } diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index 62d30a6987..908fecc85a 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -2410,11 +2410,8 @@ xbuffer_to_renderbuffer(int buffer)     case GLX_AUX0_EXT:        return BUFFER_AUX0;     case GLX_AUX1_EXT: -      return BUFFER_AUX1;     case GLX_AUX2_EXT: -      return BUFFER_AUX2;     case GLX_AUX3_EXT: -      return BUFFER_AUX3;     case GLX_AUX4_EXT:     case GLX_AUX5_EXT:     case GLX_AUX6_EXT: diff --git a/src/mesa/drivers/x11/xm_span.c b/src/mesa/drivers/x11/xm_span.c index 57b5749448..309cefcb8e 100644 --- a/src/mesa/drivers/x11/xm_span.c +++ b/src/mesa/drivers/x11/xm_span.c @@ -471,8 +471,26 @@ static void put_row_8R8G8B_pixmap( PUT_ROW_ARGS )     if (mask) {        for (i=0;i<n;i++,x++) {           if (mask[i]) { +#if 1 +            /* +             * XXX Something funny is going on here. +             * If we're drawing into a window that uses a depth 32 TrueColor +             * visual, we see the right pixels on screen, but when we read +             * them back with XGetImage() we get random colors. +             * The alternative code below which uses XPutImage() instead +             * seems to mostly fix the problem, but not always. +             * We don't normally create windows with this visual, but glean +             * does and we're seeing some failures there. +             */              XMesaSetForeground( dpy, gc, PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ));              XMesaDrawPoint( dpy, buffer, gc, (int) x, (int) y ); +#else +            /* This code works more often, but not always */ +            XMesaImage *rowimg = XMESA_BUFFER(ctx->DrawBuffer)->rowimage; +            GLuint *ptr4 = (GLuint *) rowimg->data; +            *ptr4 = PACK_8R8G8B( rgba[i][RCOMP], rgba[i][GCOMP], rgba[i][BCOMP] ); +            XMesaPutImage( dpy, buffer, gc, rowimg, 0, 0, x, y, 1, 1 ); +#endif           }        }     } diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 5c8955d7c8..42d1e579e0 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -87,11 +87,20 @@ check_valid_to_render(GLcontext *ctx, char *function)        return GL_FALSE;     } -   /* Always need vertex positions, unless a vertex program is in use */ -   if (!ctx->VertexProgram._Current && -       !ctx->Array.ArrayObj->Vertex.Enabled && +#if FEATURE_es2_glsl +   /* For ES2, we can draw if any vertex array is enabled (and we should +    * always have a vertex program/shader). +    */ +   if (ctx->Array.ArrayObj->_Enabled == 0x0 || !ctx->VertexProgram._Current) +      return GL_FALSE; +#else +   /* For regular OpenGL, only draw if we have vertex positions (regardless +    * of whether or not we have a vertex program/shader). +    */ +   if (!ctx->Array.ArrayObj->Vertex.Enabled &&         !ctx->Array.ArrayObj->VertexAttrib[0].Enabled)        return GL_FALSE; +#endif     return GL_TRUE;  } diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 85db3868c4..1580487ffd 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -119,12 +119,6 @@ draw_buffer_enum_to_bitmask(GLenum buffer)           return BUFFER_BIT_FRONT_LEFT;        case GL_AUX0:           return BUFFER_BIT_AUX0; -      case GL_AUX1: -         return BUFFER_BIT_AUX1; -      case GL_AUX2: -         return BUFFER_BIT_AUX2; -      case GL_AUX3: -         return BUFFER_BIT_AUX3;        case GL_COLOR_ATTACHMENT0_EXT:           return BUFFER_BIT_COLOR0;        case GL_COLOR_ATTACHMENT1_EXT: @@ -176,12 +170,6 @@ read_buffer_enum_to_index(GLenum buffer)           return BUFFER_FRONT_LEFT;        case GL_AUX0:           return BUFFER_AUX0; -      case GL_AUX1: -         return BUFFER_AUX1; -      case GL_AUX2: -         return BUFFER_AUX2; -      case GL_AUX3: -         return BUFFER_AUX3;        case GL_COLOR_ATTACHMENT0_EXT:           return BUFFER_COLOR0;        case GL_COLOR_ATTACHMENT1_EXT: diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index bb3e980bfa..282ad9514c 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -68,7 +68,7 @@  #define MAX_PIXEL_MAP_TABLE 256  /** Maximum number of auxillary color buffers */ -#define MAX_AUX_BUFFERS 4 +#define MAX_AUX_BUFFERS 1  /** Maximum order (degree) of curves */  #ifdef AMIGA diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 411b6a7b21..a335f77479 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -36,6 +36,22 @@  struct gl_pixelstore_attrib;  struct gl_display_list; +#if FEATURE_ARB_vertex_buffer_object +/* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return + * NULL) if buffer is unavailable for immediate mapping. + * + * Does GL_MAP_INVALIDATE_RANGE_BIT do this?  It seems so, but it + * would require more book-keeping in the driver than seems necessary + * at this point. + * + * Does GL_MAP_INVALDIATE_BUFFER_BIT do this?  Not really -- we don't + * want to provoke the driver to throw away the old storage, we will + * respect the contents of already referenced data. + */ +#define MESA_MAP_NOWAIT_BIT       0x0040 +#endif + +  /**   * Device driver function table.   * Core Mesa uses these function pointers to call into device drivers. @@ -785,6 +801,16 @@ struct dd_function_table {     void * (*MapBuffer)( GLcontext *ctx, GLenum target, GLenum access,  			struct gl_buffer_object *obj ); +   /* May return NULL if MESA_MAP_NOWAIT_BIT is set in access: +    */ +   void * (*MapBufferRange)( GLcontext *ctx, GLenum target, +                             GLintptr offset, GLsizeiptr length, GLbitfield access, +                             struct gl_buffer_object *obj); + +   void (*FlushMappedBufferRange) (GLcontext *ctx, GLenum target,  +                                   GLintptr offset, GLsizeiptr length, +                                   struct gl_buffer_object *obj); +     GLboolean (*UnmapBuffer)( GLcontext *ctx, GLenum target,  			     struct gl_buffer_object *obj );     /*@}*/ @@ -954,6 +980,12 @@ struct dd_function_table {     GLuint NeedFlush;     GLuint SaveNeedFlush; + +   /* Called prior to any of the GLvertexformat functions being +    * called.  Paired with Driver.FlushVertices(). +    */ +   void (*BeginVertices)( GLcontext *ctx ); +     /**      * If inside glBegin()/glEnd(), it should ASSERT(0).  Otherwise, if      * FLUSH_STORED_VERTICES bit in \p flags is set flushes any buffered diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index fcef093ac3..fdd10dd307 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -23,6 +23,7 @@   */  #include "mtypes.h" +#include "colormac.h"  #include "context.h"  #include "hash.h"  #include "imports.h" @@ -274,6 +275,27 @@ write_texture_image(struct gl_texture_object *texObj)        case MESA_FORMAT_ARGB8888:           write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);           break; +      case MESA_FORMAT_RGB888: +         write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0); +         break; +      case MESA_FORMAT_RGB565: +         { +            GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3); +            GLint i; +            for (i = 0; i < img->Width * img->Height; i++) { +               GLint r, g, b; +               GLushort s = ((GLushort *) img->Data)[i]; +               r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) ); +               g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >>  9) & 0x3) ); +               b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >>  2) & 0x7) ); +               buf2[i*3+1] = r; +               buf2[i*3+2] = g; +               buf2[i*3+3] = b; +            } +            write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0); +            _mesa_free(buf2); +         } +         break;        default:           printf("XXXX unsupported mesa tex format %d in %s\n",                  img->TexFormat->MesaFormat, __FUNCTION__); diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 7ff3b15c84..a824705bdc 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -602,11 +602,6 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)           ctx->Texture.SharedPalette = state;           break;        case GL_STENCIL_TEST: -         if (state && ctx->DrawBuffer->Visual.stencilBits == 0) { -            _mesa_warning(ctx, -                          "glEnable(GL_STENCIL_TEST) but no stencil buffer"); -            return; -         }           if (ctx->Stencil.Enabled == state)              return;           FLUSH_VERTICES(ctx, _NEW_STENCIL); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f17b9e1e71..f906de8357 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -285,14 +285,11 @@ typedef enum     BUFFER_BACK_LEFT,     BUFFER_FRONT_RIGHT,     BUFFER_BACK_RIGHT, -   /* optional aux buffers */ -   BUFFER_AUX0, -   BUFFER_AUX1, -   BUFFER_AUX2, -   BUFFER_AUX3,     BUFFER_DEPTH,     BUFFER_STENCIL,     BUFFER_ACCUM, +   /* optional aux buffer */ +   BUFFER_AUX0,     /* generic renderbuffers */     BUFFER_COLOR0,     BUFFER_COLOR1, @@ -336,9 +333,6 @@ typedef enum                              BUFFER_BIT_FRONT_RIGHT | \                              BUFFER_BIT_BACK_RIGHT | \                              BUFFER_BIT_AUX0 | \ -                            BUFFER_BIT_AUX1 | \ -                            BUFFER_BIT_AUX2 | \ -                            BUFFER_BIT_AUX3 | \                              BUFFER_BIT_COLOR0 | \                              BUFFER_BIT_COLOR1 | \                              BUFFER_BIT_COLOR2 | \ @@ -1018,6 +1012,7 @@ struct gl_stencil_attrib     GLboolean Enabled;		/**< Enabled flag */     GLboolean TestTwoSide;	/**< GL_EXT_stencil_two_side */     GLubyte ActiveFace;		/**< GL_EXT_stencil_two_side (0 or 2) */ +   GLboolean _Enabled;          /**< Enabled and stencil buffer present */     GLboolean _TestTwoSide;     GLubyte _BackFace;           /**< Current back stencil state (1 or 2) */     GLenum Function[3];		/**< Stencil function */ @@ -1446,14 +1441,20 @@ struct gl_texture_attrib     GLboolean SharedPalette;     struct gl_color_table Palette; -   /** Per-unit flags */ -   /*@{*/ -   GLbitfield _EnabledUnits;  /**< one bit set for each really-enabled unit */ -   GLbitfield _EnabledCoordUnits;   /**< one bit per enabled coordinate unit */ -   GLbitfield _GenFlags;            /**< for texgen */ -   GLbitfield _TexGenEnabled;  /**< Mask of ENABLE_TEXGEN flags */ -   GLbitfield _TexMatEnabled;  /**< Mask of ENABLE_TEXMAT flags */ -   /*@}*/ +   /** Texture units/samplers used by vertex or fragment texturing */ +   GLbitfield _EnabledUnits; + +   /** Texture coord units/sets used for fragment texturing */ +   GLbitfield _EnabledCoordUnits; + +   /** Texture coord units that have texgen enabled */ +   GLbitfield _TexGenEnabled; + +   /** Texture coord units that have non-identity matrices */ +   GLbitfield _TexMatEnabled; + +   /** Bitwise-OR of all Texture.Unit[i]._GenFlags */ +   GLbitfield _GenFlags;  }; diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 0a39279bff..9ea932ea96 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -490,7 +490,7 @@ _mesa_update_state_locked( GLcontext *ctx )     if (new_state & _NEW_LIGHT)        _mesa_update_lighting( ctx ); -   if (new_state & _NEW_STENCIL) +   if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))        _mesa_update_stencil( ctx );  #if FEATURE_pixel_transfer diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index e4a255d0a7..15c98e2015 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -536,7 +536,11 @@ _mesa_update_stencil(GLcontext *ctx)  {     const GLint face = ctx->Stencil._BackFace; -   ctx->Stencil._TestTwoSide = +   ctx->Stencil._Enabled = (ctx->Stencil.Enabled && +                            ctx->DrawBuffer->Visual.stencilBits > 0); + +    ctx->Stencil._TestTwoSide = +       ctx->Stencil._Enabled &&         (ctx->Stencil.Function[0] != ctx->Stencil.Function[face] ||  	ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] ||  	ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] || diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index e25c9e732c..2b07da805c 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -385,28 +385,6 @@ update_texture_compare_function(GLcontext *ctx,  /** - * Helper function for determining which texture object (1D, 2D, cube, etc) - * should actually be used. - */ -static void -texture_override(GLcontext *ctx, -                 struct gl_texture_unit *texUnit, GLbitfield enableBits, -                 struct gl_texture_object *texObj, GLuint textureBit) -{ -   if (!texUnit->_ReallyEnabled && (enableBits & textureBit)) { -      if (!texObj->_Complete) { -         _mesa_test_texobj_completeness(ctx, texObj); -      } -      if (texObj->_Complete) { -         texUnit->_ReallyEnabled = textureBit; -         texUnit->_Current = texObj; -         update_texture_compare_function(ctx, texObj); -      } -   } -} - - -/**   * Examine texture unit's combine/env state to update derived state.   */  static void @@ -514,6 +492,7 @@ update_texture_state( GLcontext *ctx )     GLuint unit;     struct gl_fragment_program *fprog = NULL;     struct gl_vertex_program *vprog = NULL; +   GLbitfield enabledFragUnits = 0x0;     if (ctx->Shader.CurrentProgram &&         ctx->Shader.CurrentProgram->LinkStatus) { @@ -545,44 +524,60 @@ update_texture_state( GLcontext *ctx )      */     for (unit = 0; unit < ctx->Const.MaxTextureImageUnits; unit++) {        struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; -      GLbitfield enableBits; +      GLbitfield enabledVertTargets = 0x0; +      GLbitfield enabledFragTargets = 0x0; +      GLbitfield enabledTargets = 0x0;        GLuint texIndex; -      texUnit->_Current = NULL; -      texUnit->_ReallyEnabled = 0x0; -        /* Get the bitmask of texture target enables.         * enableBits will be a mask of the TEXTURE_*_BIT flags indicating         * which texture targets are enabled (fixed function) or referenced         * by a fragment shader/program.  When multiple flags are set, we'll -       * settle on the one with highest priority (see texture_override below). +       * settle on the one with highest priority (see below).         */ -      enableBits = 0x0;        if (vprog) { -         enableBits |= vprog->Base.TexturesUsed[unit]; +         enabledVertTargets |= vprog->Base.TexturesUsed[unit];        } +        if (fprog) { -         enableBits |= fprog->Base.TexturesUsed[unit]; +         enabledFragTargets |= fprog->Base.TexturesUsed[unit];        }        else {           /* fixed-function fragment program */ -         enableBits |= texUnit->Enabled; +         enabledFragTargets |= texUnit->Enabled;        } -      if (enableBits == 0x0) +      enabledTargets = enabledVertTargets | enabledFragTargets; + +      texUnit->_ReallyEnabled = 0x0; + +      if (enabledTargets == 0x0) { +         /* neither vertex nor fragment processing uses this unit */           continue; +      } -      /* Look for the highest-priority texture target that's enabled and -       * complete.  That's the one we'll use for texturing.  If we're using -       * a fragment program we're guaranteed that bitcount(enabledBits) <= 1. +      /* Look for the highest priority texture target that's enabled (or used +       * by the vert/frag shaders) and "complete".  That's the one we'll use +       * for texturing.  If we're using vert/frag program we're guaranteed +       * that bitcount(enabledBits) <= 1.         * Note that the TEXTURE_x_INDEX values are in high to low priority.         */        for (texIndex = 0; texIndex < NUM_TEXTURE_TARGETS; texIndex++) { -         texture_override(ctx, texUnit, enableBits, -                          texUnit->CurrentTex[texIndex], 1 << texIndex); +         if (enabledTargets & (1 << texIndex)) { +            struct gl_texture_object *texObj = texUnit->CurrentTex[texIndex]; +            if (!texObj->_Complete) { +               _mesa_test_texobj_completeness(ctx, texObj); +            } +            if (texObj->_Complete) { +               texUnit->_ReallyEnabled = 1 << texIndex; +               _mesa_reference_texobj(&texUnit->_Current, texObj); +               break; +            } +         }        }        if (!texUnit->_ReallyEnabled) { +         _mesa_reference_texobj(&texUnit->_Current, NULL);           continue;        } @@ -590,7 +585,11 @@ update_texture_state( GLcontext *ctx )        ctx->Texture._EnabledUnits |= (1 << unit); +      if (enabledFragTargets) +         enabledFragUnits |= (1 << unit); +        update_tex_combine(ctx, texUnit); +      update_texture_compare_function(ctx, texUnit->_Current);     } @@ -601,7 +600,7 @@ update_texture_state( GLcontext *ctx )           = (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;     }     else { -      ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits; +      ctx->Texture._EnabledCoordUnits = enabledFragUnits;     }     /* Setup texgen for those texture coordinate sets that are in use */ diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c index 0204979003..1f807dc3dc 100644 --- a/src/mesa/main/vtxfmt.c +++ b/src/mesa/main/vtxfmt.c @@ -54,9 +54,12 @@     ASSERT( tnl->Current );						\     ASSERT( tnl->SwapCount < NUM_VERTEX_FORMAT_ENTRIES );		\     ASSERT( tmp_offset >= 0 );						\ -									\ -   /* Save the swapped function's dispatch entry so it can be */	\ -   /* restored later. */						\ +                                                                        \ +   if (tnl->SwapCount == 0)                                             \ +      ctx->Driver.BeginVertices( ctx );                                 \ +                                                                        \ +   /* Save the swapped function's dispatch entry so it can be */        \ +   /* restored later. */                                                \     tnl->Swapped[tnl->SwapCount].location = & (((_glapi_proc *)ctx->Exec)[tmp_offset]); \     tnl->Swapped[tnl->SwapCount].function = (_glapi_proc)TAG(FUNC);	\     tnl->SwapCount++;							\ diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index 357661456a..92c2183a94 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -91,7 +91,6 @@ MATH_SOURCES = \  	math/m_vector.c  MATH_XFORM_SOURCES = \ -	$(MATH_SOURCES) \  	math/m_xform.c  SWRAST_SOURCES = \ @@ -165,11 +164,6 @@ VBO_SOURCES = \  	vbo/vbo_save_draw.c \  	vbo/vbo_save_loopback.c  -VF_SOURCES = \ -	vf/vf.c \ -	vf/vf_generic.c \ -	vf/vf_sse.c -  STATETRACKER_SOURCES = \  	state_tracker/st_atom.c \  	state_tracker/st_atom_blend.c \ @@ -311,6 +305,7 @@ COMMON_DRIVER_SOURCES =			\  # Sources for building non-Gallium drivers  MESA_SOURCES = \  	$(MAIN_SOURCES)		\ +	$(MATH_SOURCES)		\  	$(MATH_XFORM_SOURCES)	\  	$(VBO_SOURCES)		\  	$(TNL_SOURCES)		\ diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c index 4ea62dda18..0aa128f947 100644 --- a/src/mesa/state_tracker/st_atom_depth.c +++ b/src/mesa/state_tracker/st_atom_depth.c @@ -98,9 +98,11 @@ update_depth_stencil_alpha(struct st_context *st)     memset(dsa, 0, sizeof(*dsa)); -   dsa->depth.enabled = ctx->Depth.Test; -   dsa->depth.writemask = ctx->Depth.Mask; -   dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func); +   if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) { +      dsa->depth.enabled = 1; +      dsa->depth.writemask = ctx->Depth.Mask; +      dsa->depth.func = st_compare_func_to_pipe(ctx->Depth.Func); +   }     if (ctx->Query.CurrentOcclusionObject &&         ctx->Query.CurrentOcclusionObject->Active) diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c index 562ac6c65c..28e387c399 100644 --- a/src/mesa/state_tracker/st_cb_bufferobjects.c +++ b/src/mesa/state_tracker/st_cb_bufferobjects.c @@ -206,8 +206,40 @@ st_bufferobj_map(GLcontext *ctx, GLenum target, GLenum access,  } +  /** - * Called via glMapBufferARB(). + * Called via glMapBufferRange(). + */ +static void * +st_bufferobj_map_range(GLcontext *ctx, GLenum target,  +                       GLintptr offset, GLsizeiptr length, GLbitfield access, +                       struct gl_buffer_object *obj) +{ +   struct pipe_context *pipe = st_context(ctx)->pipe; +   struct st_buffer_object *st_obj = st_buffer_object(obj); +   GLuint flags = 0; + +   if (access & GL_MAP_WRITE_BIT) +      flags |= PIPE_BUFFER_USAGE_CPU_WRITE; + +   if (access & GL_MAP_READ_BIT) +      flags |= PIPE_BUFFER_USAGE_CPU_READ; + +   /* ... other flags ... +    */ + +   if (access & MESA_MAP_NOWAIT_BIT) +      flags |= PIPE_BUFFER_USAGE_DONTBLOCK; + +   obj->Pointer = pipe_buffer_map(pipe->screen, st_obj->buffer, flags); +   return obj->Pointer; +} + + + + +/** + * Called via glUnmapBufferARB().   */  static GLboolean  st_bufferobj_unmap(GLcontext *ctx, GLenum target, struct gl_buffer_object *obj) @@ -230,5 +262,6 @@ st_init_bufferobject_functions(struct dd_function_table *functions)     functions->BufferSubData = st_bufferobj_subdata;     functions->GetBufferSubData = st_bufferobj_get_subdata;     functions->MapBuffer = st_bufferobj_map; +   functions->MapBufferRange = st_bufferobj_map_range;     functions->UnmapBuffer = st_bufferobj_unmap;  } diff --git a/src/mesa/swrast/s_buffers.c b/src/mesa/swrast/s_buffers.c index af475ad8cb..34ae1b4fcc 100644 --- a/src/mesa/swrast/s_buffers.c +++ b/src/mesa/swrast/s_buffers.c @@ -317,10 +317,7 @@ _swrast_Clear(GLcontext *ctx, GLbitfield buffers)  	 BUFFER_BIT_DEPTH |  	 BUFFER_BIT_STENCIL |  	 BUFFER_BIT_ACCUM | -         BUFFER_BIT_AUX0 | -         BUFFER_BIT_AUX1 | -         BUFFER_BIT_AUX2 | -         BUFFER_BIT_AUX3; +         BUFFER_BIT_AUX0;        assert((buffers & (~legalBits)) == 0);     }  #endif diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 719e6b8296..4dbccbb2d5 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -61,7 +61,7 @@ _swrast_update_rasterflags( GLcontext *ctx )     if (ctx->Depth.Test)                   rasterMask |= DEPTH_BIT;     if (swrast->_FogEnabled)               rasterMask |= FOG_BIT;     if (ctx->Scissor.Enabled)              rasterMask |= CLIP_BIT; -   if (ctx->Stencil.Enabled)              rasterMask |= STENCIL_BIT; +   if (ctx->Stencil._Enabled)             rasterMask |= STENCIL_BIT;     if (ctx->Visual.rgbMode) {        const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);        if (colorMask != 0xffffffff)        rasterMask |= MASKING_BIT; diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index ab7b82b19d..5e1f412d6b 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -846,11 +846,11 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)     }     /* Stencil and Z testing */ -   if (ctx->Depth.Test || ctx->Stencil.Enabled) { +   if (ctx->Stencil._Enabled || ctx->Depth.Test) {        if (!(span->arrayMask & SPAN_Z))           _swrast_span_interpolate_z(ctx, span); -      if (ctx->Stencil.Enabled) { +      if (ctx->Stencil._Enabled) {           if (!_swrast_stencil_and_ztest_span(ctx, span)) {              span->arrayMask = origArrayMask;              return; @@ -1211,7 +1211,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span)           _swrast_exec_fragment_shader(ctx, span);        }     } -   else if (ctx->Texture._EnabledUnits) { +   else if (ctx->Texture._EnabledCoordUnits) {        /* conventional texturing */  #if CHAN_BITS == 32 @@ -1250,7 +1250,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)     void * const origRgba = span->array->rgba;     const GLboolean shader = (ctx->FragmentProgram._Current                               || ctx->ATIFragmentShader._Enabled); -   const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; +   const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits;     struct gl_framebuffer *fb = ctx->DrawBuffer;     /* @@ -1317,11 +1317,11 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span)     }     /* Stencil and Z testing */ -   if (ctx->Stencil.Enabled || ctx->Depth.Test) { +   if (ctx->Stencil._Enabled || ctx->Depth.Test) {        if (!(span->arrayMask & SPAN_Z))           _swrast_span_interpolate_z(ctx, span); -      if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { +      if (ctx->Stencil._Enabled) {           /* Combined Z/stencil tests */           if (!_swrast_stencil_and_ztest_span(ctx, span)) {              /* all fragments failed test */ diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index ab08b7325a..9260e35066 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -266,7 +266,7 @@ affine_span(GLcontext *ctx, SWspan *span,              struct affine_info *info)  {     GLchan sample[4];  /* the filtered texture sample */ -   const GLuint texEnableSave = ctx->Texture._EnabledUnits; +   const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits;     /* Instead of defining a function for each mode, a test is done      * between the outer and inner loops. This is to reduce code size @@ -397,7 +397,7 @@ affine_span(GLcontext *ctx, SWspan *span,     GLchan *dest = span->array->rgba[0];     /* Disable tex units so they're not re-applied in swrast_write_rgba_span */ -   ctx->Texture._EnabledUnits = 0x0; +   ctx->Texture._EnabledCoordUnits = 0x0;     span->intTex[0] -= FIXED_HALF;     span->intTex[1] -= FIXED_HALF; @@ -504,7 +504,7 @@ affine_span(GLcontext *ctx, SWspan *span,     _swrast_write_rgba_span(ctx, span);     /* re-enable texture units */ -   ctx->Texture._EnabledUnits = texEnableSave; +   ctx->Texture._EnabledCoordUnits = texEnableSave;  #undef SPAN_NEAREST  #undef SPAN_LINEAR @@ -664,8 +664,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span,     GLfloat tex_coord[3], tex_step[3];     GLchan *dest = span->array->rgba[0]; -   const GLuint savedTexEnable = ctx->Texture._EnabledUnits; -   ctx->Texture._EnabledUnits = 0; +   const GLuint texEnableSave = ctx->Texture._EnabledCoordUnits; +   ctx->Texture._EnabledCoordUnits = 0;     tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0]  * (info->smask + 1);     tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); @@ -778,7 +778,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span,  #undef SPAN_LINEAR     /* restore state */ -   ctx->Texture._EnabledUnits = savedTexEnable; +   ctx->Texture._EnabledCoordUnits = texEnableSave;  } @@ -1022,7 +1022,7 @@ _swrast_choose_triangle( GLcontext *ctx )            ctx->Depth.Test &&            ctx->Depth.Mask == GL_FALSE &&            ctx->Depth.Func == GL_LESS && -          !ctx->Stencil.Enabled) { +          !ctx->Stencil._Enabled) {           if ((rgbmode &&                ctx->Color.ColorMask[0] == 0 &&                ctx->Color.ColorMask[1] == 0 && diff --git a/src/mesa/vbo/vbo_exec.c b/src/mesa/vbo/vbo_exec.c index 635f239acc..e168a89ea5 100644 --- a/src/mesa/vbo/vbo_exec.c +++ b/src/mesa/vbo/vbo_exec.c @@ -57,6 +57,7 @@ void vbo_exec_init( GLcontext *ctx )     ctx->Driver.NeedFlush = 0;     ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END; +   ctx->Driver.BeginVertices = vbo_exec_BeginVertices;     ctx->Driver.FlushVertices = vbo_exec_FlushVertices;     vbo_exec_invalidate_state( ctx, ~0 ); diff --git a/src/mesa/vbo/vbo_exec.h b/src/mesa/vbo/vbo_exec.h index ddbcbe1181..100bb8a5de 100644 --- a/src/mesa/vbo/vbo_exec.h +++ b/src/mesa/vbo/vbo_exec.h @@ -43,7 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.  /* Wierd implementation stuff:   */ -#define VBO_VERT_BUFFER_SIZE (1024*16)	/* dwords == 64k */ +#define VBO_VERT_BUFFER_SIZE (1024*64)	/* bytes */  #define VBO_MAX_ATTR_CODEGEN 16   #define ERROR_ATTRIB 16 @@ -78,14 +78,15 @@ struct vbo_exec_context     struct {        struct gl_buffer_object *bufferobj; -      GLubyte *buffer_map; -      GLuint vertex_size; +      GLuint vertex_size;       /* in dwords */        struct _mesa_prim prim[VBO_MAX_PRIM];        GLuint prim_count; -      GLfloat *vbptr;		     /* cursor, points into buffer */ +      GLfloat *buffer_map; +      GLfloat *buffer_ptr;              /* cursor, points into buffer */ +      GLuint   buffer_used;             /* in bytes */        GLfloat vertex[VBO_ATTRIB_MAX*4]; /* current vertex */        GLuint vert_count; @@ -140,6 +141,9 @@ struct vbo_exec_context  void vbo_exec_init( GLcontext *ctx );  void vbo_exec_destroy( GLcontext *ctx );  void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state ); +void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap ); + +void vbo_exec_BeginVertices( GLcontext *ctx );  void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ); @@ -151,7 +155,8 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec );  void vbo_exec_vtx_init( struct vbo_exec_context *exec );  void vbo_exec_vtx_destroy( struct vbo_exec_context *exec ); -void vbo_exec_vtx_flush( struct vbo_exec_context *exec ); +void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap ); +void vbo_exec_vtx_map( struct vbo_exec_context *exec );  void vbo_exec_vtx_wrap( struct vbo_exec_context *exec );  void vbo_exec_eval_update( struct vbo_exec_context *exec ); diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c index 2743bf6b55..c0ffdb55e4 100644 --- a/src/mesa/vbo/vbo_exec_api.c +++ b/src/mesa/vbo/vbo_exec_api.c @@ -62,7 +62,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )     if (exec->vtx.prim_count == 0) {        exec->vtx.copied.nr = 0;        exec->vtx.vert_count = 0; -      exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; +      exec->vtx.buffer_ptr = exec->vtx.buffer_map;     }     else {        GLuint last_begin = exec->vtx.prim[exec->vtx.prim_count-1].begin; @@ -80,7 +80,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )        /* Execute the buffer and save copied vertices.         */        if (exec->vtx.vert_count) -	 vbo_exec_vtx_flush( exec ); +	 vbo_exec_vtx_flush( exec, GL_FALSE );        else {  	 exec->vtx.prim_count = 0;  	 exec->vtx.copied.nr = 0; @@ -121,9 +121,9 @@ void vbo_exec_vtx_wrap( struct vbo_exec_context *exec )     assert(exec->vtx.max_vert - exec->vtx.vert_count > exec->vtx.copied.nr);     for (i = 0 ; i < exec->vtx.copied.nr ; i++) { -      _mesa_memcpy( exec->vtx.vbptr, data,  +      _mesa_memcpy( exec->vtx.buffer_ptr, data,   		    exec->vtx.vertex_size * sizeof(GLfloat)); -      exec->vtx.vbptr += exec->vtx.vertex_size; +      exec->vtx.buffer_ptr += exec->vtx.vertex_size;        data += exec->vtx.vertex_size;        exec->vtx.vert_count++;     } @@ -251,9 +251,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,     exec->vtx.attrsz[attr] = newsz;     exec->vtx.vertex_size += newsz - oldsz; -   exec->vtx.max_vert = VBO_VERT_BUFFER_SIZE / exec->vtx.vertex_size; +   exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /  +                         (exec->vtx.vertex_size * sizeof(GLfloat)));     exec->vtx.vert_count = 0; -   exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map; +   exec->vtx.buffer_ptr = exec->vtx.buffer_map;     /* Recalculate all the attrptr[] values @@ -279,10 +280,10 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,     if (exec->vtx.copied.nr)     {        GLfloat *data = exec->vtx.copied.buffer; -      GLfloat *dest = exec->vtx.vbptr; +      GLfloat *dest = exec->vtx.buffer_ptr;        GLuint j; -      assert(exec->vtx.vbptr == (GLfloat *)exec->vtx.buffer_map); +      assert(exec->vtx.buffer_ptr == exec->vtx.buffer_map);        for (i = 0 ; i < exec->vtx.copied.nr ; i++) {  	 for (j = 0 ; j < VBO_ATTRIB_MAX ; j++) { @@ -308,7 +309,7 @@ static void vbo_exec_wrap_upgrade_vertex( struct vbo_exec_context *exec,  	 }        } -      exec->vtx.vbptr = dest; +      exec->vtx.buffer_ptr = dest;        exec->vtx.vert_count += exec->vtx.copied.nr;        exec->vtx.copied.nr = 0;     } @@ -373,9 +374,9 @@ do {								\        GLuint i;							\  								\        for (i = 0; i < exec->vtx.vertex_size; i++)		\ -	 exec->vtx.vbptr[i] = exec->vtx.vertex[i];		\ +	 exec->vtx.buffer_ptr[i] = exec->vtx.vertex[i];		\  								\ -      exec->vtx.vbptr += exec->vtx.vertex_size;			\ +      exec->vtx.buffer_ptr += exec->vtx.vertex_size;			\        exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;	\  								\        if (++exec->vtx.vert_count >= exec->vtx.max_vert)		\ @@ -532,7 +533,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )         * begin/end pairs.         */        if (exec->vtx.vertex_size && !exec->vtx.attrsz[0])  -	 vbo_exec_FlushVertices( ctx, ~0 ); +	 vbo_exec_FlushVertices_internal( ctx, GL_FALSE );        i = exec->vtx.prim_count++;        exec->vtx.prim[i].mode = mode; @@ -566,7 +567,7 @@ static void GLAPIENTRY vbo_exec_End( void )        ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;        if (exec->vtx.prim_count == VBO_MAX_PRIM) -	 vbo_exec_vtx_flush( exec );	 +	 vbo_exec_vtx_flush( exec, GL_FALSE );     }     else         _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); @@ -672,23 +673,19 @@ void vbo_use_buffer_objects(GLcontext *ctx)      */     GLuint bufName = 0xaabbccdd;     GLenum target = GL_ARRAY_BUFFER_ARB; -   GLenum access = GL_READ_WRITE_ARB;     GLenum usage = GL_STREAM_DRAW_ARB; -   GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat); +   GLsizei size = VBO_VERT_BUFFER_SIZE;     /* Make sure this func is only used once */     assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);     if (exec->vtx.buffer_map) {        _mesa_align_free(exec->vtx.buffer_map); +      exec->vtx.buffer_map = NULL;     }     /* Allocate a real buffer object now */     exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);     ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); - -   /* and map it */ -   exec->vtx.buffer_map -      = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);  } @@ -708,7 +705,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )                                   ctx->Array.NullBufferObj);     ASSERT(!exec->vtx.buffer_map); -   exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64); +   exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64); +     vbo_exec_vtxfmt_init( exec );     /* Hook our functions into the dispatch table. @@ -747,22 +745,45 @@ void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )     }  } - -void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) +void vbo_exec_BeginVertices( GLcontext *ctx )  {     struct vbo_exec_context *exec = &vbo_context(ctx)->exec; +   if (0) _mesa_printf("%s\n", __FUNCTION__); +   vbo_exec_vtx_map( exec ); +} -   if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) -      return; +void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap ) +{ +   struct vbo_exec_context *exec = &vbo_context(ctx)->exec; -   if (exec->vtx.vert_count) { -      vbo_exec_vtx_flush( exec ); +   if (exec->vtx.vert_count || unmap) { +      vbo_exec_vtx_flush( exec, unmap );     }     if (exec->vtx.vertex_size) {        vbo_exec_copy_to_current( exec );        reset_attrfv( exec );     } +} + + + +void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags ) +{ +   struct vbo_exec_context *exec = &vbo_context(ctx)->exec; + +   if (0) _mesa_printf("%s\n", __FUNCTION__); + +   if (exec->ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) { +      if (0) _mesa_printf("%s - inside begin/end\n", __FUNCTION__); +      return; +   } + +   vbo_exec_FlushVertices_internal( ctx, GL_TRUE ); + +   /* Need to do this to ensure BeginVertices gets called again: +    */ +   _mesa_restore_exec_vtxfmt( ctx );     exec->ctx->Driver.NeedFlush = 0;  } diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 8871e10cf6..cf7c7056c5 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -31,6 +31,7 @@  #include "main/api_validate.h"  #include "main/api_noop.h"  #include "main/varray.h" +#include "main/bufferobj.h"  #include "glapi/dispatch.h"  #include "vbo_context.h" @@ -291,6 +292,47 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)     prim[0].indexed = 0;     vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL, start, start + count - 1 ); + +#if 0 +   { +      int i; + +      _mesa_printf("vbo_exec_DrawArrays(mode 0x%x, start %d, count %d):\n", +                   mode, start, count); + +      for (i = 0; i < 32; i++) { +         GLuint bufName = exec->array.inputs[i]->BufferObj->Name; +         GLint stride = exec->array.inputs[i]->Stride; +         _mesa_printf("attr %2d: size %d stride %d  enabled %d  " +                      "ptr %p  Bufobj %u\n", +                      i, +                      exec->array.inputs[i]->Size, +                      stride, +                      /*exec->array.inputs[i]->Enabled,*/ +                      exec->array.legacy_array[i]->Enabled, +                      exec->array.inputs[i]->Ptr, +                      bufName); +          +         if (bufName) { +            struct gl_buffer_object *buf = _mesa_lookup_bufferobj(ctx, bufName); +            GLubyte *p = ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER_ARB, +                                            GL_READ_ONLY_ARB, buf); +            int offset = (int) exec->array.inputs[i]->Ptr; +            float *f = (float *) (p + offset); +            int *k = (int *) f; +            int i; +            int n = (count * stride) / 4; +            if (n > 32) +               n = 32; +            _mesa_printf("  Data at offset %d:\n", offset); +            for (i = 0; i < n; i++) { +               _mesa_printf("    float[%d] = 0x%08x %f\n", i, k[i], f[i]); +            } +            ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, buf); +         } +      } +   } +#endif  } diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index 45133fa4f3..38b6c56f47 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -70,7 +70,7 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec )     GLuint ovf, i;     GLuint sz = exec->vtx.vertex_size;     GLfloat *dst = exec->vtx.copied.buffer; -   GLfloat *src = ((GLfloat *)exec->vtx.buffer_map +  +   GLfloat *src = (exec->vtx.buffer_map +   		   exec->vtx.prim[exec->vtx.prim_count-1].start *   		   exec->vtx.vertex_size); @@ -147,7 +147,7 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )     struct vbo_exec_context *exec = &vbo->exec;     struct gl_client_array *arrays = exec->vtx.arrays;     GLuint count = exec->vtx.vert_count; -   GLubyte *data = exec->vtx.buffer_map; +   GLubyte *data = (GLubyte *)exec->vtx.buffer_map;     const GLuint *map;     GLuint attr;     GLbitfield varying_inputs = 0x0; @@ -234,10 +234,78 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )  } +static void vbo_exec_vtx_unmap( struct vbo_exec_context *exec ) +{ +   GLenum target = GL_ARRAY_BUFFER_ARB; + +   if (exec->vtx.bufferobj->Name) { +      GLcontext *ctx = exec->ctx; + +      exec->vtx.buffer_used += (exec->vtx.buffer_ptr - +                                exec->vtx.buffer_map) * sizeof(float); +             +      ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj); +      exec->vtx.buffer_map = NULL; +      exec->vtx.buffer_ptr = NULL; +      exec->vtx.max_vert = 0; +   } +} + +void vbo_exec_vtx_map( struct vbo_exec_context *exec ) +{ +   GLcontext *ctx = exec->ctx; +   GLenum target = GL_ARRAY_BUFFER_ARB; +   GLenum access = GL_READ_WRITE_ARB; +   GLenum usage = GL_STREAM_DRAW_ARB; +    +   if (exec->vtx.bufferobj->Name == 0) +      return; + +   if (exec->vtx.buffer_map != NULL) { +      assert(0); +      exec->vtx.buffer_map = NULL; +   } + +   if (VBO_VERT_BUFFER_SIZE > exec->vtx.buffer_used + 1024 && +       ctx->Driver.MapBufferRange) +   { +      exec->vtx.buffer_map =  +         (GLfloat *)ctx->Driver.MapBufferRange(ctx,  +                                               target,  +                                               exec->vtx.buffer_used, +                                               (VBO_VERT_BUFFER_SIZE -  +                                                exec->vtx.buffer_used), +                                               (GL_MAP_WRITE_BIT | +                                                GL_MAP_INVALIDATE_RANGE_BIT |  +                                                GL_MAP_UNSYNCHRONIZED_BIT |  +                                                MESA_MAP_NOWAIT_BIT), +                                               exec->vtx.bufferobj); +   } + +   if (exec->vtx.buffer_map) { +      exec->vtx.buffer_map += exec->vtx.buffer_used / sizeof(float); +   } +   else { +      exec->vtx.buffer_used = 0; + +      ctx->Driver.BufferData(ctx, target,  +                             VBO_VERT_BUFFER_SIZE,  +                             NULL, usage, exec->vtx.bufferobj); + +      exec->vtx.buffer_map =  +         (GLfloat *)ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj); +   } + +   if (0) _mesa_printf("map %d..\n", exec->vtx.buffer_used); +} + + +  /**   * Execute the buffer and save copied verts.   */ -void vbo_exec_vtx_flush( struct vbo_exec_context *exec ) +void vbo_exec_vtx_flush( struct vbo_exec_context *exec, +                         GLboolean unmap )  {     if (0)        vbo_exec_debug_verts( exec ); @@ -250,25 +318,22 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )        if (exec->vtx.copied.nr != exec->vtx.vert_count) {  	 GLcontext *ctx = exec->ctx; - -	 GLenum target = GL_ARRAY_BUFFER_ARB; -	 GLenum access = GL_READ_WRITE_ARB; -	 GLenum usage = GL_STREAM_DRAW_ARB; -	 GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat); -	 /* Before the unmap (why?) +	 /* Before the update_state() as this may raise _NEW_ARRAY +          * from _mesa_set_varying_vp_inputs().  	  */  	 vbo_exec_bind_arrays( ctx );           if (ctx->NewState)              _mesa_update_state( ctx ); -         /* if using a real VBO, unmap it before drawing */           if (exec->vtx.bufferobj->Name) { -            ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj); -            exec->vtx.buffer_map = NULL; +            vbo_exec_vtx_unmap( exec );           } +         if (0) _mesa_printf("%s %d %d\n", __FUNCTION__, exec->vtx.prim_count, +                      exec->vtx.vert_count); +  	 vbo_context(ctx)->draw_prims( ctx,   				       exec->vtx.inputs,   				       exec->vtx.prim,  @@ -277,16 +342,31 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )  				       0,  				       exec->vtx.vert_count - 1); -	 /* If using a real VBO, get new storage */ -         if (exec->vtx.bufferobj->Name) { -            ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj); -            exec->vtx.buffer_map =  -               ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj); -         } +	 /* If using a real VBO, get new storage -- unless asked not to. +          */ +         if (exec->vtx.bufferobj->Name && !unmap) { +            vbo_exec_vtx_map( exec ); +          }        }     } +   /* May have to unmap explicitly if we didn't draw: +    */ +   if (unmap &&  +       exec->vtx.bufferobj->Name && +       exec->vtx.buffer_map) { +      vbo_exec_vtx_unmap( exec ); +   } + + +   if (unmap)  +      exec->vtx.max_vert = 0; +   else +      exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /  +                            (exec->vtx.vertex_size * sizeof(GLfloat))); + + +   exec->vtx.buffer_ptr = exec->vtx.buffer_map;     exec->vtx.prim_count = 0;     exec->vtx.vert_count = 0; -   exec->vtx.vbptr = (GLfloat *)exec->vtx.buffer_map;  } diff --git a/src/mesa/vbo/vbo_save.h b/src/mesa/vbo/vbo_save.h index 7dda54af48..9558f83883 100644 --- a/src/mesa/vbo/vbo_save.h +++ b/src/mesa/vbo/vbo_save.h @@ -130,7 +130,7 @@ struct vbo_save_context {     struct vbo_save_vertex_store *vertex_store;     struct vbo_save_primitive_store *prim_store; -   GLfloat *vbptr;		   /* cursor, points into buffer */ +   GLfloat *buffer_ptr;		   /* cursor, points into buffer */     GLfloat vertex[VBO_ATTRIB_MAX*4];	   /* current values */     GLfloat *attrptr[VBO_ATTRIB_MAX];     GLuint vert_count; diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index ddfd276577..52b6f1884e 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -241,7 +241,7 @@ static void _save_reset_counters( GLcontext *ctx )     save->buffer = (save->vertex_store->buffer +   		   save->vertex_store->used); -   assert(save->buffer == save->vbptr); +   assert(save->buffer == save->buffer_ptr);     if (save->vertex_size)        save->max_vert = ((VBO_SAVE_BUFFER_SIZE - save->vertex_store->used) /  @@ -343,7 +343,7 @@ static void _save_compile_vertex_list( GLcontext *ctx )        /* Allocate and map new store:         */        save->vertex_store = alloc_vertex_store( ctx ); -      save->vbptr = map_vertex_store( ctx, save->vertex_store ); +      save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );     }      if (save->prim_store->used > VBO_SAVE_PRIM_SIZE - 6) { @@ -414,9 +414,9 @@ static void _save_wrap_filled_vertex( GLcontext *ctx )     assert(save->max_vert - save->vert_count > save->copied.nr);     for (i = 0 ; i < save->copied.nr ; i++) { -      _mesa_memcpy( save->vbptr, data, save->vertex_size * sizeof(GLfloat)); +      _mesa_memcpy( save->buffer_ptr, data, save->vertex_size * sizeof(GLfloat));        data += save->vertex_size; -      save->vbptr += save->vertex_size; +      save->buffer_ptr += save->vertex_size;        save->vert_count++;     }  } @@ -550,7 +550,7 @@ static void _save_upgrade_vertex( GLcontext *ctx,  	 }        } -      save->vbptr = dest; +      save->buffer_ptr = dest;        save->vert_count += save->copied.nr;     }  } @@ -622,9 +622,9 @@ do {								\        GLuint i;							\  								\        for (i = 0; i < save->vertex_size; i++)			\ -	 save->vbptr[i] = save->vertex[i];			\ +	 save->buffer_ptr[i] = save->vertex[i];			\  								\ -      save->vbptr += save->vertex_size;				\ +      save->buffer_ptr += save->vertex_size;				\  								\        if (++save->vert_count >= save->max_vert)			\  	 _save_wrap_filled_vertex( ctx );			\ @@ -1035,7 +1035,7 @@ void vbo_save_NewList( GLcontext *ctx, GLuint list, GLenum mode )     if (!save->vertex_store)         save->vertex_store = alloc_vertex_store( ctx ); -   save->vbptr = map_vertex_store( ctx, save->vertex_store ); +   save->buffer_ptr = map_vertex_store( ctx, save->vertex_store );     _save_reset_vertex( ctx );     _save_reset_counters( ctx );   | 
