diff options
80 files changed, 3536 insertions, 864 deletions
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c index 533c0a15f39..17ff61b675c 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; - - /* 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); + assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE)); + + /* 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 314d2045f76..573b043f5b6 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 967e2cc20ce..daec37ab28e 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 19de09486d3..1631637067d 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 df4dc4b1f68..6367374a616 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 b090f2238e4..f762f32f0c3 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 3cbc93d12bc..52d443970b0 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 00000000000..47750e997e9 --- /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 9424e18bee3..a8a94be176c 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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ #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 4e6a305abb0..e910472700c 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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ #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 00000000000..120d45bc036 --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#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 1001bb8c578..d40d09c9b5b 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 126faf76014..9c7a27282b2 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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ - - +#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 f7119b949a3..1fef5382946 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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ #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 12ed86d22a9..fe2676d0be3 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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ #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 b712acda88e..00000000000 --- 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 b272ab55f34..00000000000 --- 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 00000000000..a00ea3e2a4e --- /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 00000000000..0765f56ee15 --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +#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 00000000000..72b333eaf18 --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +#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 00000000000..d166a365ac5 --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + + +#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 00000000000..ac0bfc88a4d --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +/* 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 00000000000..950af942f5b --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +#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 00000000000..82c3890dfbd --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +#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 00000000000..d523080e90f --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +/* + * 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 00000000000..1a021092743 --- /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 d9556e1f384..01374337852 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 595de447267..2e191a6d126 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 00000000000..8130fdb2265 --- /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 00000000000..aea39247e51 --- /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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + * + */ + +#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 e3ee985afcd..54c7dd46b14 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 259a505c0a6..918d2f98e2a 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 acfb8ec4ea2..c4623e82f90 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 986f751bdc1..9bee212c6a3 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 ee0fe4e0dbe..5eb8f417ffb 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 82370162f59..c724218cf56 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 5f4f2d515df..299357409ce 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 06a6f3f0f4e..879000644b2 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 7f2144abd4b..732bae5b5ae 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 c3ba50f3550..28281b38615 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 5e32288844c..9f4b4ff0ba0 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 7c7aa6097c8..d50dd68092d 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 7be7ea82b35..e8d5ac8569d 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 9f90047ba59..977dfa0b760 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 be68821dc1d..2797cbb3dc0 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 ade45f581ca..37dae6c8869 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 73d85ed57b4..84e1b525854 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 9ab9c05f2bd..18729d5ae08 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 cf840c57a7a..2cd8e12d955 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 a2d7bcd97d9..591df8a905a 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 1cef01ab033..840e4e42da9 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 7b442b6d20b..62722972b2a 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 338cd37382a..1bcf2512a63 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 62d30a69878..908fecc85a1 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 57b57494483..309cefcb8e8 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 5c8955d7c8d..42d1e579e08 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 85db3868c49..1580487ffd6 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 bb3e980bfaa..282ad9514c2 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 411b6a7b21f..a335f77479d 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 fcef093ac35..fdd10dd3074 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 7ff3b15c846..a824705bdcc 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 f17b9e1e717..f906de8357e 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 0a39279bff3..9ea932ea962 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 e4a255d0a7e..15c98e20156 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 e25c9e732c3..2b07da805c0 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 0204979003e..1f807dc3dc3 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 357661456ad..92c2183a942 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 4ea62dda184..0aa128f9479 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 562ac6c65c5..28e387c399d 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 af475ad8cb5..34ae1b4fccf 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 719e6b82964..4dbccbb2d59 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 ab7b82b19d9..5e1f412d6bf 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 ab08b7325a5..9260e35066f 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 635f239acc8..e168a89ea5e 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 ddbcbe11814..100bb8a5dec 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 2743bf6b55c..c0ffdb55e47 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 8871e10cf60..cf7c7056c5a 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 45133fa4f32..38b6c56f479 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 7dda54af48b..9558f838837 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 ddfd2765774..52b6f1884ee 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 ); |