diff options
Diffstat (limited to 'src/gallium/state_trackers')
45 files changed, 2978 insertions, 2230 deletions
diff --git a/src/gallium/state_trackers/dri2/Makefile b/src/gallium/state_trackers/dri/Makefile index 47750e997e..ef8f19709a 100644 --- a/src/gallium/state_trackers/dri2/Makefile +++ b/src/gallium/state_trackers/dri/Makefile @@ -1,7 +1,7 @@ TOP = ../../../.. include $(TOP)/configs/current -LIBNAME = dri2drm +LIBNAME = dridrm LIBRARY_INCLUDES = \ -I$(TOP)/include \ diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript new file mode 100644 index 0000000000..ce2c273597 --- /dev/null +++ b/src/gallium/state_trackers/dri/SConscript @@ -0,0 +1,23 @@ +####################################################################### +# SConscript for dri state_tracker + +Import('*') + +if env['dri']: + + env = env.Clone() + + env.Append(CPPPATH = [ + '#/src/mesa', + '#/src/mesa/drivers/dri/common', + ]) + + st_dri = env.ConvenienceLibrary( + target = 'st_dri', + source = [ 'dri_context.c', + 'dri_drawable.c', + 'dri_extensions.c', + 'dri_screen.c', + ] + ) + Export('st_dri') diff --git a/src/gallium/state_trackers/dri2/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 92c26ac70f..45eaec4ed3 100644 --- a/src/gallium/state_trackers/dri2/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -32,9 +32,8 @@ #include "dri_screen.h" #include "dri_drawable.h" - - #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" #include "state_tracker/st_public.h" #include "state_tracker/st_context.h" #include "pipe/p_context.h" @@ -43,11 +42,9 @@ #include "util/u_memory.h" - GLboolean -dri_create_context(const __GLcontextModes *visual, - __DRIcontextPrivate *cPriv, - void *sharedContextPrivate) +dri_create_context(const __GLcontextModes * visual, + __DRIcontextPrivate * cPriv, void *sharedContextPrivate) { __DRIscreenPrivate *sPriv = cPriv->driScreenPriv; struct dri_screen *screen = dri_screen(sPriv); @@ -55,7 +52,7 @@ dri_create_context(const __GLcontextModes *visual, struct st_context *st_share = NULL; if (sharedContextPrivate) { - st_share = ((struct dri_context *) sharedContextPrivate)->st; + st_share = ((struct dri_context *)sharedContextPrivate)->st; } ctx = CALLOC_STRUCT(dri_context); @@ -65,11 +62,12 @@ dri_create_context(const __GLcontextModes *visual, cPriv->driverPrivate = ctx; ctx->cPriv = cPriv; ctx->sPriv = sPriv; + ctx->lock = screen->drmLock; + ctx->d_stamp = -1; + ctx->r_stamp = -1; driParseConfigFiles(&ctx->optionCache, - &screen->optionCache, - sPriv->myNum, - "dri"); + &screen->optionCache, sPriv->myNum, "dri"); ctx->pipe = drm_api_hooks.create_context(screen->pipe_screen); @@ -87,7 +85,7 @@ dri_create_context(const __GLcontextModes *visual, return GL_TRUE; -fail: + fail: if (ctx && ctx->st) st_destroy_context(ctx->st); @@ -98,9 +96,8 @@ fail: return FALSE; } - void -dri_destroy_context(__DRIcontextPrivate *cPriv) +dri_destroy_context(__DRIcontextPrivate * cPriv) { struct dri_context *ctx = dri_context(cPriv); struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); @@ -122,44 +119,64 @@ dri_destroy_context(__DRIcontextPrivate *cPriv) FREE(ctx); } - GLboolean -dri_unbind_context(__DRIcontextPrivate *cPriv) +dri_unbind_context(__DRIcontextPrivate * cPriv) { - struct dri_context *ctx = dri_context(cPriv); - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); - /* XXX make_current(NULL)? */ + if (cPriv) { + struct dri_context *ctx = dri_context(cPriv); + + if (--ctx->bind_count == 0) { + if (ctx->st && ctx->st == st_get_current()) { + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + st_make_current(NULL, NULL, NULL); + } + } + } + return GL_TRUE; } - GLboolean -dri_make_current(__DRIcontextPrivate *cPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) +dri_make_current(__DRIcontextPrivate * cPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) { if (cPriv) { struct dri_context *ctx = dri_context(cPriv); struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); struct dri_drawable *draw = dri_drawable(driDrawPriv); struct dri_drawable *read = dri_drawable(driReadPriv); + struct st_context *old_st = st_get_current(); + + if (old_st && old_st != ctx->st) + st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL); + + ++ctx->bind_count; /* This is for situations in which we need a rendering context but * there may not be any currently bound. */ screen->dummyContext = ctx; - st_make_current(ctx->st, - draw->stfb, - read->stfb); - - /* used in dri_flush_frontbuffer */ - ctx->dPriv = driDrawPriv; - - if (driDrawPriv) - dri_get_buffers(driDrawPriv); - if (driDrawPriv != driReadPriv && driReadPriv) - dri_get_buffers(driReadPriv); + if (ctx->dPriv != driDrawPriv) { + ctx->dPriv = driDrawPriv; + ctx->d_stamp = driDrawPriv->lastStamp - 1; + } + if (ctx->rPriv != driReadPriv) { + ctx->rPriv = driReadPriv; + ctx->r_stamp = driReadPriv->lastStamp - 1; + } + + st_make_current(ctx->st, draw->stfb, read->stfb); + + if (__dri1_api_hooks) { + dri1_update_drawables(ctx, draw, read); + } else { + if (driDrawPriv) + dri_get_buffers(driDrawPriv); + if (driDrawPriv != driReadPriv && driReadPriv) + dri_get_buffers(driReadPriv); + } } else { st_make_current(NULL, NULL, NULL); } @@ -167,4 +184,42 @@ dri_make_current(__DRIcontextPrivate *cPriv, return GL_TRUE; } +static void +st_dri_lock(struct pipe_context *pipe) +{ + dri_lock((struct dri_context *)pipe->priv); +} + +static void +st_dri_unlock(struct pipe_context *pipe) +{ + dri_unlock((struct dri_context *)pipe->priv); +} + +static boolean +st_dri_is_locked(struct pipe_context *pipe) +{ + return ((struct dri_context *)pipe->priv)->isLocked; +} + +static boolean +st_dri_lost_lock(struct pipe_context *pipe) +{ + return ((struct dri_context *)pipe->priv)->wsLostLock; +} + +static void +st_dri_clear_lost_lock(struct pipe_context *pipe) +{ + ((struct dri_context *)pipe->priv)->wsLostLock = FALSE; +} + +struct dri1_api_lock_funcs dri1_lf = { + .lock = st_dri_lock, + .unlock = st_dri_unlock, + .is_locked = st_dri_is_locked, + .is_lock_lost = st_dri_lost_lock, + .clear_lost_lock = st_dri_clear_lost_lock +}; + /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h index e910472700..4650178734 100644 --- a/src/gallium/state_trackers/dri2/dri_context.h +++ b/src/gallium/state_trackers/dri/dri_context.h @@ -36,60 +36,87 @@ #include "drm.h" #include "dri_util.h" - struct pipe_context; struct pipe_fence; struct st_context; struct dri_drawable; - struct dri_context { /* dri */ __DRIscreenPrivate *sPriv; __DRIcontextPrivate *cPriv; __DRIdrawablePrivate *dPriv; + __DRIdrawablePrivate *rPriv; driOptionCache optionCache; + unsigned int d_stamp; + unsigned int r_stamp; + + drmLock *lock; + boolean isLocked; + boolean stLostLock; + boolean wsLostLock; + + unsigned int bind_count; + /* gallium */ struct st_context *st; struct pipe_context *pipe; }; - static INLINE struct dri_context * -dri_context(__DRIcontextPrivate *driContextPriv) +dri_context(__DRIcontextPrivate * driContextPriv) +{ + return (struct dri_context *)driContextPriv->driverPrivate; +} + +static INLINE void +dri_lock(struct dri_context *ctx) { - return (struct dri_context *) driContextPriv->driverPrivate; + drm_context_t hw_context = ctx->cPriv->hHWContext; + char ret = 0; + + DRM_CAS(ctx->lock, hw_context, DRM_LOCK_HELD | hw_context, ret); + if (ret) { + drmGetLock(ctx->sPriv->fd, hw_context, 0); + ctx->stLostLock = TRUE; + ctx->wsLostLock = TRUE; + } + ctx->isLocked = TRUE; } +static INLINE void +dri_unlock(struct dri_context *ctx) +{ + ctx->isLocked = FALSE; + DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext); +} /*********************************************************************** * dri_context.c */ -void -dri_destroy_context(__DRIcontextPrivate * driContextPriv); +extern struct dri1_api_lock_funcs dri1_lf; -boolean -dri_unbind_context(__DRIcontextPrivate * driContextPriv); +void dri_destroy_context(__DRIcontextPrivate * driContextPriv); + +boolean dri_unbind_context(__DRIcontextPrivate * driContextPriv); boolean dri_make_current(__DRIcontextPrivate * driContextPriv, - __DRIdrawablePrivate * driDrawPriv, - __DRIdrawablePrivate * driReadPriv); + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); boolean dri_create_context(const __GLcontextModes * visual, - __DRIcontextPrivate * driContextPriv, - void *sharedContextPrivate); - + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); /*********************************************************************** * dri_extensions.c */ -void -dri_init_extensions(struct dri_context *ctx); +void dri_init_extensions(struct dri_context *ctx); #endif diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c new file mode 100644 index 0000000000..09cd3091d2 --- /dev/null +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -0,0 +1,605 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <keithw@vmware.com> + * Author: Jakob Bornecrantz <wallbraker@gmail.com> + */ + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/drm_api.h" +#include "state_tracker/dri1_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 void +dri_copy_to_front(__DRIdrawablePrivate * dPriv, + struct pipe_surface *from, + int x, int y, unsigned w, unsigned h) +{ + /* TODO send a message to the Xserver to copy to the real front buffer */ +} + +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_hooks.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(&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; + + if (drawable->old_num == count && + drawable->old_w == dri_drawable->w && + drawable->old_h == dri_drawable->h && + memcmp(drawable->old, buffers, sizeof(__DRIbuffer) * count) == 0) { + return; + } else { + drawable->old_num = count; + drawable->old_w = dri_drawable->w; + drawable->old_h = dri_drawable->h; + memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count); + } + + 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_FAKE_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_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private) +{ + struct dri_context *ctx = (struct dri_context *)context_private; + + dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height); +} + +/** + * 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_screen *screen = sPriv->private; + struct dri_drawable *drawable = NULL; + struct pipe_screen *pscreen = screen->pipe_screen; + 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) { + if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) + depthFormat = PIPE_FORMAT_Z24S8_UNORM; + else + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + } else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits) { + if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) + stencilFormat = PIPE_FORMAT_Z24S8_UNORM; + else + 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; +#if 0 + /* TODO incase of double buffer visual, delay fake creation */ + drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; +#endif + if (visual->doubleBufferMode) + 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; + + drawable->desired_fences = 2; + + return GL_TRUE; + fail: + FREE(drawable); + return GL_FALSE; +} + +static struct pipe_fence_handle * +dri_swap_fences_pop_front(struct dri_drawable *draw) +{ + struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen; + struct pipe_fence_handle *fence = NULL; + + if (draw->cur_fences >= draw->desired_fences) { + screen->fence_reference(screen, &fence, draw->swap_fences[draw->tail]); + screen->fence_reference(screen, &draw->swap_fences[draw->tail++], NULL); + --draw->cur_fences; + draw->tail &= DRI_SWAP_FENCES_MASK; + } + return fence; +} + +static void +dri_swap_fences_push_back(struct dri_drawable *draw, + struct pipe_fence_handle *fence) +{ + struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen; + + if (!fence) + return; + + if (draw->cur_fences < DRI_SWAP_FENCES_MAX) { + draw->cur_fences++; + screen->fence_reference(screen, &draw->swap_fences[draw->head++], + fence); + draw->head &= DRI_SWAP_FENCES_MASK; + } +} + +void +dri_destroy_buffer(__DRIdrawablePrivate * dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_fence_handle *fence; + struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; + + st_unreference_framebuffer(drawable->stfb); + drawable->desired_fences = 0; + while (drawable->cur_fences) { + fence = dri_swap_fences_pop_front(drawable); + screen->fence_reference(screen, &fence, NULL); + } + + FREE(drawable); +} + +static void +dri1_update_drawables_locked(struct dri_context *ctx, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv) +{ + if (ctx->stLostLock) { + ctx->stLostLock = FALSE; + if (driDrawPriv == driReadPriv) + DRI_VALIDATE_DRAWABLE_INFO(ctx->sPriv, driDrawPriv); + else + DRI_VALIDATE_TWO_DRAWABLES_INFO(ctx->sPriv, driDrawPriv, + driReadPriv); + } +} + +/** + * This ensures all contexts which bind to a drawable pick up the + * drawable change and signal new buffer state. + * Calling st_resize_framebuffer for each context may seem like overkill, + * but no new buffers will actually be allocated if the dimensions don't + * change. + */ + +static void +dri1_propagate_drawable_change(struct dri_context *ctx) +{ + __DRIdrawablePrivate *dPriv = ctx->dPriv; + __DRIdrawablePrivate *rPriv = ctx->rPriv; + boolean flushed = FALSE; + + if (dPriv && ctx->d_stamp != dPriv->lastStamp) { + + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + flushed = TRUE; + ctx->d_stamp = dPriv->lastStamp; + st_resize_framebuffer(dri_drawable(dPriv)->stfb, dPriv->w, dPriv->h); + + } + + if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) { + + if (!flushed) + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->r_stamp = rPriv->lastStamp; + st_resize_framebuffer(dri_drawable(rPriv)->stfb, rPriv->w, rPriv->h); + + } else if (rPriv && dPriv == rPriv) { + + ctx->r_stamp = ctx->d_stamp; + + } +} + +void +dri1_update_drawables(struct dri_context *ctx, + struct dri_drawable *draw, struct dri_drawable *read) +{ + dri_lock(ctx); + dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv); + dri_unlock(ctx); + + dri1_propagate_drawable_change(ctx); +} + +static INLINE boolean +dri1_intersect_src_bbox(struct drm_clip_rect *dst, + int dst_x, + int dst_y, + const struct drm_clip_rect *src, + const struct drm_clip_rect *bbox) +{ + int xy1; + int xy2; + + xy1 = ((int)src->x1 > (int)bbox->x1 + dst_x) ? src->x1 : + (int)bbox->x1 + dst_x; + xy2 = ((int)src->x2 < (int)bbox->x2 + dst_x) ? src->x2 : + (int)bbox->x2 + dst_x; + if (xy1 >= xy2 || xy1 < 0) + return FALSE; + + dst->x1 = xy1; + dst->x2 = xy2; + + xy1 = ((int)src->y1 > (int)bbox->y1 + dst_y) ? src->y1 : + (int)bbox->y1 + dst_y; + xy2 = ((int)src->y2 < (int)bbox->y2 + dst_y) ? src->y2 : + (int)bbox->y2 + dst_y; + if (xy1 >= xy2 || xy1 < 0) + return FALSE; + + dst->y1 = xy1; + dst->y2 = xy2; + return TRUE; +} + +static void +dri1_swap_copy(struct dri_context *ctx, + struct pipe_surface *dst, + struct pipe_surface *src, + __DRIdrawablePrivate * dPriv, const struct drm_clip_rect *bbox) +{ + struct pipe_context *pipe = ctx->pipe; + struct drm_clip_rect clip; + struct drm_clip_rect *cur; + int i; + + cur = dPriv->pClipRects; + + for (i = 0; i < dPriv->numClipRects; ++i) { + if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) + pipe->surface_copy(pipe, dst, clip.x1, clip.y1, + src, + (int)clip.x1 - dPriv->x, + (int)clip.y1 - dPriv->y, + clip.x2 - clip.x1, clip.y2 - clip.y1); + } +} + +static void +dri1_copy_to_front(struct dri_context *ctx, + struct pipe_surface *surf, + __DRIdrawablePrivate * dPriv, + const struct drm_clip_rect *sub_box, + struct pipe_fence_handle **fence) +{ + struct pipe_context *pipe = ctx->pipe; + boolean save_lost_lock; + uint cur_w; + uint cur_h; + struct drm_clip_rect bbox; + boolean visible = TRUE; + + *fence = NULL; + + dri_lock(ctx); + save_lost_lock = ctx->stLostLock; + dri1_update_drawables_locked(ctx, dPriv, dPriv); + st_get_framebuffer_dimensions(dri_drawable(dPriv)->stfb, &cur_w, &cur_h); + + bbox.x1 = 0; + bbox.x2 = cur_w; + bbox.y1 = 0; + bbox.y2 = cur_h; + + if (sub_box) + visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box); + + if (visible && __dri1_api_hooks->present_locked) { + + __dri1_api_hooks->present_locked(pipe, + surf, + dPriv->pClipRects, + dPriv->numClipRects, + dPriv->x, dPriv->y, &bbox, fence); + + } else if (visible && __dri1_api_hooks->front_srf_locked) { + + struct pipe_surface *front = __dri1_api_hooks->front_srf_locked(pipe); + + if (front) + dri1_swap_copy(ctx, front, surf, dPriv, &bbox); + + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence); + } + + ctx->stLostLock = save_lost_lock; + + /** + * FIXME: Revisit this: Update drawables on copy_sub_buffer ? + */ + + if (!sub_box) + dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv); + + dri_unlock(ctx); + dri1_propagate_drawable_change(ctx); +} + +void +dri1_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private) +{ + struct dri_context *ctx = (struct dri_context *)context_private; + struct pipe_fence_handle *dummy_fence; + + dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence); + screen->fence_reference(screen, &dummy_fence, NULL); + + /** + * FIXME: Do we need swap throttling here? + */ +} + +void +dri_swap_buffers(__DRIdrawablePrivate * dPriv) +{ + struct dri_context *ctx; + struct pipe_surface *back_surf; + struct dri_drawable *draw = dri_drawable(dPriv); + struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen; + struct pipe_fence_handle *fence; + struct st_context *st = st_get_current(); + + assert(__dri1_api_hooks != NULL); + + if (!st) + return; /* For now */ + + ctx = (struct dri_context *)st->pipe->priv; + + st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf); + if (back_surf) { + st_notify_swapbuffers(draw->stfb); + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + fence = dri_swap_fences_pop_front(draw); + if (fence) { + (void)screen->fence_finish(screen, fence, 0); + screen->fence_reference(screen, &fence, NULL); + } + dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence); + dri_swap_fences_push_back(draw, fence); + screen->fence_reference(screen, &fence, NULL); + } +} + +void +dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen; + struct drm_clip_rect sub_bbox; + struct dri_context *ctx; + struct pipe_surface *back_surf; + struct dri_drawable *draw = dri_drawable(dPriv); + struct pipe_fence_handle *dummy_fence; + struct st_context *st = st_get_current(); + + assert(__dri1_api_hooks != NULL); + + if (!st) + return; + + ctx = (struct dri_context *)st->pipe->priv; + + sub_bbox.x1 = x; + sub_bbox.x2 = x + w; + sub_bbox.y1 = y; + sub_bbox.y2 = y + h; + + st_get_framebuffer_surface(draw->stfb, ST_SURFACE_BACK_LEFT, &back_surf); + if (back_surf) { + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + dri1_copy_to_front(ctx, back_surf, dPriv, &sub_bbox, &dummy_fence); + screen->fence_reference(screen, &dummy_fence, NULL); + } +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 185c657b35..0f654d804a 100644 --- a/src/gallium/state_trackers/dri2/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -31,9 +31,11 @@ #include "pipe/p_compiler.h" struct pipe_surface; -struct pipe_fence; +struct pipe_fence_handle; struct st_framebuffer; +#define DRI_SWAP_FENCES_MAX 8 +#define DRI_SWAP_FENCES_MASK 7 struct dri_drawable { @@ -44,46 +46,54 @@ struct dri_drawable unsigned attachments[8]; unsigned num_attachments; + __DRIbuffer old[8]; + unsigned old_num; + unsigned old_w; + unsigned old_h; + /* gallium */ struct st_framebuffer *stfb; + struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; + unsigned int head; + unsigned int tail; + unsigned int desired_fences; + unsigned int cur_fences; }; - static INLINE struct dri_drawable * dri_drawable(__DRIdrawablePrivate * driDrawPriv) { - return (struct dri_drawable *) driDrawPriv->driverPrivate; + return (struct dri_drawable *)driDrawPriv->driverPrivate; } - /*********************************************************************** * dri_drawable.c */ boolean -dri_create_buffer(__DRIscreenPrivate *sPriv, - __DRIdrawablePrivate *dPriv, - const __GLcontextModes *visual, - boolean isPixmap); +dri_create_buffer(__DRIscreenPrivate * sPriv, + __DRIdrawablePrivate * dPriv, + const __GLcontextModes * visual, boolean isPixmap); void dri_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, - void *context_private); + struct pipe_surface *surf, void *context_private); -void -dri_swap_buffers(__DRIdrawablePrivate * dPriv); +void dri_swap_buffers(__DRIdrawablePrivate * dPriv); void -dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, - int x, int y, - int w, int h); +dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h); -void -dri_get_buffers(__DRIdrawablePrivate * dPriv); +void dri_get_buffers(__DRIdrawablePrivate * dPriv); + +void dri_destroy_buffer(__DRIdrawablePrivate * dPriv); void -dri_destroy_buffer(__DRIdrawablePrivate *dPriv); +dri1_update_drawables(struct dri_context *ctx, + struct dri_drawable *draw, struct dri_drawable *read); +void +dri1_flush_frontbuffer(struct pipe_screen *screen, + struct pipe_surface *surf, void *context_private); #endif /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 732d1e89b0..2f48162526 100644 --- a/src/gallium/state_trackers/dri2/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -36,9 +36,11 @@ #define need_GL_ARB_multisample #define need_GL_ARB_occlusion_query #define need_GL_ARB_point_parameters +#define need_GL_ARB_shader_objects #define need_GL_ARB_texture_compression #define need_GL_ARB_vertex_buffer_object #define need_GL_ARB_vertex_program +#define need_GL_ARB_vertex_shader #define need_GL_ARB_window_pos #define need_GL_EXT_blend_color #define need_GL_EXT_blend_equation_separate @@ -50,17 +52,23 @@ #define need_GL_EXT_multi_draw_arrays #define need_GL_EXT_secondary_color #define need_GL_NV_vertex_program +#define need_GL_VERSION_2_0 +#define need_GL_VERSION_2_1 #include "extension_helper.h" - /** * Extension strings exported by the driver. */ const struct dri_extension card_extensions[] = { + {"GL_ARB_fragment_shader", NULL}, {"GL_ARB_multisample", GL_ARB_multisample_functions}, {"GL_ARB_multitexture", NULL}, {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions }, + {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions }, + {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions}, {"GL_ARB_texture_border_clamp", NULL}, {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, {"GL_ARB_texture_cube_map", NULL}, @@ -70,11 +78,12 @@ const struct dri_extension card_extensions[] = { {"GL_ARB_texture_mirrored_repeat", NULL}, {"GL_ARB_texture_rectangle", NULL}, {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, - {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions}, {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, - {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_equation_separate", + GL_EXT_blend_equation_separate_functions}, {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, {"GL_EXT_blend_subtract", NULL}, @@ -98,11 +107,10 @@ const struct dri_extension card_extensions[] = { {"GL_NV_blend_square", NULL}, {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, {"GL_NV_vertex_program1_1", NULL}, - {"GL_SGIS_generate_mipmap", NULL }, + {"GL_SGIS_generate_mipmap", NULL}, {NULL, NULL} }; - void dri_init_extensions(struct dri_context *ctx) { diff --git a/src/gallium/state_trackers/dri2/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index ab5878a4bc..d3392ee690 100644 --- a/src/gallium/state_trackers/dri2/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -40,68 +40,38 @@ #include "pipe/p_context.h" #include "pipe/p_screen.h" #include "pipe/p_inlines.h" +#include "pipe/p_format.h" #include "state_tracker/drm_api.h" +#include "state_tracker/dri1_api.h" #include "state_tracker/st_public.h" #include "state_tracker/st_cb_fbo.h" - PUBLIC const char __driConfigOptions[] = DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE - DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) - DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + 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_ALLOW_LARGE_TEXTURES(1) + /*DRI_CONF_FORCE_S3TC_ENABLE(false) */ + DRI_CONF_ALLOW_LARGE_TEXTURES(1) DRI_CONF_SECTION_END DRI_CONF_END; + const uint __driNConfigOptions = 3; -const uint __driNConfigOptions = 3; - - -static const __DRIextension *dri_screen_extensions[] = { - &driReadDrawableExtension, - &driCopySubBufferExtension.base, - &driSwapControlExtension.base, - &driFrameTrackingExtension.base, - &driMediaStreamCounterExtension.base, - NULL -}; - - -static void -dri_get_drm_minor(struct dri_screen *screen) -{ - /* TODO get the real minor */ - screen->minor = 0; -} - - -static void -dri_get_device_id(struct dri_screen *screen) -{ - 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; - } - - fgets(path, sizeof(path), file); - sscanf(path, "%x", &screen->deviceID); - fclose(file); -} + static const __DRIextension *dri_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL + }; +struct dri1_api *__dri1_api_hooks = NULL; static const __DRIconfig ** -dri_fill_in_modes(__DRIscreenPrivate *psp, - unsigned pixel_bits, unsigned depth_bits, - unsigned stencil_bits, GLboolean have_back_buffer) +dri_fill_in_modes(__DRIscreenPrivate * psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) { __DRIconfig **configs; __GLcontextModes *m; @@ -125,9 +95,9 @@ dri_fill_in_modes(__DRIscreenPrivate *psp, 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 */ - stencil_bits_array[2] = 8; /* z24s8 */ + stencil_bits_array[0] = 0; /* no depth or stencil */ + stencil_bits_array[1] = 0; /* z24x8 */ + stencil_bits_array[2] = 8; /* z24s8 */ msaa_samples_array[0] = 0; @@ -135,22 +105,22 @@ dri_fill_in_modes(__DRIscreenPrivate *psp, back_buffer_factor = 3; msaa_samples_factor = 1; - num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; + num_modes = + depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; if (pixel_bits == 16) { fb_format = GL_RGB; fb_type = GL_UNSIGNED_SHORT_5_6_5; - } - else { + } else { fb_format = GL_BGRA; fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; } configs = driCreateConfigs(fb_format, fb_type, depth_bits_array, - stencil_bits_array, depth_buffer_factor, - back_buffer_modes, back_buffer_factor, - msaa_samples_array, msaa_samples_factor); + stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + msaa_samples_array, msaa_samples_factor); if (configs == NULL) { debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); return NULL; @@ -159,49 +129,99 @@ dri_fill_in_modes(__DRIscreenPrivate *psp, for (i = 0; configs[i]; i++) { m = &configs[i]->modes; if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { - m->visualRating = GLX_SLOW_CONFIG; + m->visualRating = GLX_SLOW_CONFIG; } } - return (const const __DRIconfig **) configs; + return (const const __DRIconfig **)configs; } - /** * Get information about previous buffer swaps. */ -int -dri_get_swap_info(__DRIdrawablePrivate * dPriv, - __DRIswapInfo * sInfo) +static int +dri_get_swap_info(__DRIdrawablePrivate * dPriv, __DRIswapInfo * sInfo) { - if (dPriv == NULL || - dPriv->driverPrivate == NULL || - sInfo == NULL) + if (dPriv == NULL || dPriv->driverPrivate == NULL || sInfo == NULL) return -1; else return 0; } +static INLINE void +dri_copy_version(struct dri1_api_version *dst, + const struct __DRIversionRec *src) +{ + dst->major = src->major; + dst->minor = src->minor; + dst->patch_level = src->patch; +} -/** - * NULL stub for old dri loaders - */ -const __DRIconfig ** -dri_init_screen(__DRIscreenPrivate *sPriv) +static const __DRIconfig ** +dri_init_screen(__DRIscreenPrivate * sPriv) { + struct dri_screen *screen; + const __DRIconfig **configs; + struct dri1_create_screen_arg arg; + + dri_init_extensions(NULL); + + screen = CALLOC_STRUCT(dri_screen); + if (!screen) + return NULL; + + screen->sPriv = sPriv; + screen->fd = sPriv->fd; + screen->drmLock = (drmLock *) & sPriv->pSAREA->lock; + + sPriv->private = (void *)screen; + sPriv->extensions = dri_screen_extensions; + + arg.base.mode = DRM_CREATE_DRI1; + arg.lf = &dri1_lf; + arg.ddx_info = sPriv->pDevPriv; + arg.ddx_info_size = sPriv->devPrivSize; + arg.sarea = sPriv->pSAREA; + dri_copy_version(&arg.ddx_version, &sPriv->ddx_version); + dri_copy_version(&arg.dri_version, &sPriv->dri_version); + dri_copy_version(&arg.drm_version, &sPriv->drm_version); + arg.api = NULL; + + screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg.base); + + if (!screen->pipe_screen || !arg.api) { + debug_printf("%s: failed to create dri1 screen\n", __FUNCTION__); + goto out_no_screen; + } + + __dri1_api_hooks = arg.api; + + screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer; + driParseOptionInfo(&screen->optionCache, + __driConfigOptions, __driNConfigOptions); + + configs = dri_fill_in_modes(sPriv, sPriv->fbBPP, 24, 8, 1); + if (!configs) + goto out_no_configs; + + return configs; + out_no_configs: + screen->pipe_screen->destroy(screen->pipe_screen); + out_no_screen: + FREE(screen); return NULL; } - /** * This is the driver specific part of the createNewScreen entry point. * * Returns the __GLcontextModes supported by this driver. */ -const __DRIconfig ** -dri_init_screen2(__DRIscreenPrivate *sPriv) +static const __DRIconfig ** +dri_init_screen2(__DRIscreenPrivate * sPriv) { struct dri_screen *screen; + struct drm_create_screen_arg arg; /* Set up dispatch table to cope with all known extensions */ dri_init_extensions(NULL); @@ -212,13 +232,11 @@ dri_init_screen2(__DRIscreenPrivate *sPriv) screen->sPriv = sPriv; screen->fd = sPriv->fd; - dri_get_drm_minor(screen); - dri_get_device_id(screen); - sPriv->private = (void *) screen; + sPriv->private = (void *)screen; sPriv->extensions = dri_screen_extensions; + arg.mode = DRM_CREATE_NORMAL; - - screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, screen->deviceID); + screen->pipe_screen = drm_api_hooks.create_screen(screen->fd, &arg); if (!screen->pipe_screen) { debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); goto fail; @@ -228,20 +246,14 @@ dri_init_screen2(__DRIscreenPrivate *sPriv) screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer; driParseOptionInfo(&screen->optionCache, - __driConfigOptions, - __driNConfigOptions); - - return dri_fill_in_modes(sPriv, - 4 * 8, - 24, - 8, - 1); -fail: + __driConfigOptions, __driNConfigOptions); + + return dri_fill_in_modes(sPriv, 4 * 8, 24, 8, 1); + fail: return NULL; } - -void +static void dri_destroy_screen(__DRIscreenPrivate * sPriv) { struct dri_screen *screen = dri_screen(sPriv); @@ -251,22 +263,22 @@ dri_destroy_screen(__DRIscreenPrivate * sPriv) sPriv->private = NULL; } - PUBLIC const struct __DriverAPIRec driDriverAPI = { - .InitScreen = dri_init_screen, /* not supported but exported */ - .DestroyScreen = dri_destroy_screen, - .CreateContext = dri_create_context, - .DestroyContext = dri_destroy_context, - .CreateBuffer = dri_create_buffer, - .DestroyBuffer = dri_destroy_buffer, - .SwapBuffers = dri_swap_buffers, /* not supported but exported */ - .MakeCurrent = dri_make_current, - .UnbindContext = dri_unbind_context, - .GetSwapInfo = dri_get_swap_info, - .GetDrawableMSC = driDrawableGetMSC32, - .WaitForMSC = driWaitForMSC32, - .CopySubBuffer = dri_copy_sub_buffer, /* not supported but exported */ - .InitScreen2 = dri_init_screen2, + .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, + .InitScreen = dri_init_screen, + .InitScreen2 = dri_init_screen2, }; /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index fe2676d0be..100d9e50e0 100644 --- a/src/gallium/state_trackers/dri2/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -37,6 +37,8 @@ #include "pipe/p_compiler.h" +#include "state_tracker/dri1_api.h" + struct dri_screen { /* dri */ @@ -54,36 +56,26 @@ struct dri_screen struct dri_context *dummyContext; /* drm */ - int deviceID; int fd; - int minor; + drmLock *drmLock; /* gallium */ struct pipe_winsys *pipe_winsys; struct pipe_screen *pipe_screen; }; - /** cast wrapper */ static INLINE struct dri_screen * -dri_screen(__DRIscreenPrivate *sPriv) +dri_screen(__DRIscreenPrivate * sPriv) { - return (struct dri_screen *) sPriv->private; + return (struct dri_screen *)sPriv->private; } - /*********************************************************************** * 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); +extern struct dri1_api *__dri1_api_hooks; #endif diff --git a/src/gallium/state_trackers/dri2/dri_drawable.c b/src/gallium/state_trackers/dri2/dri_drawable.c deleted file mode 100644 index 2e3f4099e2..0000000000 --- a/src/gallium/state_trackers/dri2/dri_drawable.c +++ /dev/null @@ -1,325 +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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ -/* - * Author: Keith Whitwell <keithw@vmware.com> - * Author: Jakob Bornecrantz <wallbraker@gmail.com> - */ - -#include "dri_screen.h" -#include "dri_context.h" -#include "dri_drawable.h" - -#include "pipe/p_context.h" -#include "pipe/p_screen.h" -#include "pipe/p_inlines.h" -#include "state_tracker/drm_api.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_cb_fbo.h" - -#include "util/u_memory.h" - - -static void -dri_copy_to_front(__DRIdrawablePrivate *dPriv, - struct pipe_surface *from, - int x, int y, unsigned w, unsigned h) -{ - /* TODO send a message to the Xserver to copy to the real front buffer */ -} - - -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_hooks.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(&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_FAKE_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_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, - void *context_private) -{ - struct dri_context *ctx = (struct dri_context *)context_private; - dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height); -} - - -void -dri_swap_buffers(__DRIdrawablePrivate * dPriv) -{ - /* not needed for dri2 */ - assert(0); -} - - -void -dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) -{ - /* not needed for dri2 */ - assert(0); -} - - -/** - * 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_screen *screen = sPriv->private; - struct dri_drawable *drawable = NULL; - struct pipe_screen *pscreen = screen->pipe_screen; - 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) { - if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) - depthFormat = PIPE_FORMAT_Z24S8_UNORM; - else - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - } else - depthFormat = PIPE_FORMAT_NONE; - - if (visual->stencilBits) { - if (pscreen->is_format_supported(pscreen, PIPE_FORMAT_Z24S8_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET | - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) - stencilFormat = PIPE_FORMAT_Z24S8_UNORM; - else - 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; -#if 0 - /* TODO incase of double buffer visual, delay fake creation */ - drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; -#endif - if (visual->doubleBufferMode) - 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/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 692a3c8b76..e825aa718b 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -1,29 +1,19 @@ -TARGET = libegldrm.a -CFILES = $(wildcard ./*.c) -OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES)) -GALLIUMDIR = ../.. -TOP = ../../../.. +TOP = ../../../.. +include $(TOP)/configs/current -include ${TOP}/configs/current +LIBNAME = egldrm -CFLAGS := \ - -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 \ - ${LIBDRM_CFLAGS} \ - ${CFLAGS} +LIBRARY_INCLUDES = \ + -I$(TOP)/src/gallium/include \ + -I$(TOP)/src/gallium/auxiliary \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -I$(TOP)/src/mesa \ + -I$(TOP)/include \ + -I$(TOP)/src/egl/main \ + $(shell pkg-config --cflags-only-I libdrm) -############################################# -.PHONY = all clean +C_SOURCES = $(wildcard ./*.c) -all: ${TARGET} -${TARGET}: ${OBJECTS} - ar rcs $@ $^ - -clean: - rm -rf ${OBJECTS} ${TARGET} +include ../../Makefile.template diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c index abdf84544f..8e62008461 100644 --- a/src/gallium/state_trackers/egl/egl_tracker.c +++ b/src/gallium/state_trackers/egl/egl_tracker.c @@ -146,7 +146,7 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor) dev->drmFD = fd; drm_get_device_id(dev); - dev->screen = drm_api_hooks.create_screen(dev->drmFD, dev->deviceID); + dev->screen = drm_api_hooks.create_screen(dev->drmFD, NULL); if (!dev->screen) goto err_screen; dev->winsys = dev->screen->winsys; diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/fakeglx.c index 65e7048188..85e7ecfb9e 100644 --- a/src/gallium/state_trackers/glx/xlib/fakeglx.c +++ b/src/gallium/state_trackers/glx/xlib/fakeglx.c @@ -97,6 +97,9 @@ struct fake_glx_context { +#define DEFAULT_DIRECT GL_TRUE + + /**********************************************************************/ /*** GLX Visual Code ***/ /**********************************************************************/ @@ -1059,7 +1062,7 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo, return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ @@ -1296,9 +1299,9 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx ) static Bool Fake_glXIsDirect( Display *dpy, GLXContext ctx ) { - (void) dpy; + struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx; (void) ctx; - return False; + return glxCtx->glxContext.isDirect; } @@ -2055,7 +2058,7 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config, return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ @@ -2277,7 +2280,7 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re return NULL; } - glxCtx->glxContext.isDirect = GL_FALSE; + glxCtx->glxContext.isDirect = DEFAULT_DIRECT; glxCtx->glxContext.currentDpy = dpy; glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */ diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c index a3d1651653..79c2230588 100644 --- a/src/gallium/state_trackers/glx/xlib/xm_api.c +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c @@ -1100,26 +1100,19 @@ XMesaContext XMesaGetCurrentContext( void ) - - - -/* - * Copy the back buffer to the front buffer. If there's no back buffer - * this is a no-op. +/** + * Swap front and back color buffers and have winsys display front buffer. + * If there's no front color buffer no swap actually occurs. */ PUBLIC void XMesaSwapBuffers( XMesaBuffer b ) { - struct pipe_surface *surf; + struct pipe_surface *frontLeftSurf; - /* If we're swapping the buffer associated with the current context - * we have to flush any pending rendering commands first. - */ - st_notify_swapbuffers(b->stfb); + st_swapbuffers(b->stfb, &frontLeftSurf, NULL); - st_get_framebuffer_surface(b->stfb, ST_SURFACE_BACK_LEFT, &surf); - if (surf) { - driver.display_surface(b, surf); + if (frontLeftSurf) { + driver.display_surface(b, frontLeftSurf); } xmesa_check_and_update_buffer_size(NULL, b); diff --git a/src/gallium/state_trackers/python/p_texture.i b/src/gallium/state_trackers/python/p_texture.i index f41a95e6eb..1d513abf3c 100644 --- a/src/gallium/state_trackers/python/p_texture.i +++ b/src/gallium/state_trackers/python/p_texture.i @@ -426,7 +426,7 @@ struct st_surface if(!*STRING) return; - pipe_buffer_read(screen, $self, 0, $self->size, STRING); + pipe_buffer_read(screen, $self, 0, $self->size, *STRING); } %cstring_input_binary(const char *STRING, unsigned LENGTH); diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/src/gallium/state_trackers/python/retrace/interpreter.py index 5ea07724a5..5885e162c2 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/src/gallium/state_trackers/python/retrace/interpreter.py @@ -32,7 +32,7 @@ import struct import gallium import model -import parser +import parse as parser try: @@ -43,19 +43,27 @@ except ImportError: return struct.unpack(fmt, buf[offset:offset + size]) -def make_image(surface): +def make_image(surface, x=None, y=None, w=None, h=None): + if x is None: + x = 0 + if y is None: + y = 0 + if w is None: + w = surface.width - x + if h is None: + h = surface.height - y data = surface.get_tile_rgba8(0, 0, surface.width, surface.height) import Image outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1) return outimage -def save_image(filename, surface): - outimage = make_image(surface) +def save_image(filename, surface, x=None, y=None, w=None, h=None): + outimage = make_image(surface, x, y, w, h) outimage.save(filename, "PNG") -def show_image(surface, title): - outimage = make_image(surface) +def show_image(surface, title, x=None, y=None, w=None, h=None): + outimage = make_image(surface, x, y, w, h) import Tkinter as tk from PIL import Image, ImageTk @@ -305,7 +313,11 @@ class Screen(Object): def get_tex_transfer(self, texture, face, level, zslice, usage, x, y, w, h): if texture is None: return None - return Transfer(texture.get_surface(face, level, zslice), x, y, w, h) + transfer = Transfer(texture.get_surface(face, level, zslice), x, y, w, h) + if transfer and usage != gallium.PIPE_TRANSFER_WRITE: + if self.interpreter.options.all: + self.interpreter.present(transfer.surface, 'transf_read', x, y, w, h) + return transfer def tex_transfer_destroy(self, transfer): self.interpreter.unregister_object(transfer) @@ -314,6 +326,8 @@ class Screen(Object): if transfer is None: return transfer.surface.put_tile_raw(transfer.x, transfer.y, transfer.w, transfer.h, data, stride) + if self.interpreter.options.all: + self.interpreter.present(transfer.surface, 'transf_write', transfer.x, transfer.y, transfer.w, transfer.h) def user_buffer_create(self, data, size): # We don't really care to distinguish between user and regular buffers @@ -577,6 +591,14 @@ class Context(Object): self.real.draw_range_elements(indexBuffer, indexSize, minIndex, maxIndex, mode, start, count) self._set_dirty() + def is_texture_referenced(self, texture, face, level): + #return self.real.is_texture_referenced(format, texture, face, level) + pass + + def is_buffer_referenced(self, buf): + #return self.real.is_buffer_referenced(format, buf) + pass + def _set_dirty(self): if self.interpreter.options.step: self._present() @@ -602,6 +624,9 @@ class Context(Object): if self.cbufs and self.cbufs[0]: self.interpreter.present(self.cbufs[0], "cbuf") + if self.zsbuf: + if self.interpreter.options.all: + self.interpreter.present(self.zsbuf, "zsbuf") class Interpreter(parser.TraceDumper): @@ -671,16 +696,16 @@ class Interpreter(parser.TraceDumper): def verbosity(self, level): return self.options.verbosity >= level - def present(self, surface, description): + def present(self, surface, description, x=None, y=None, w=None, h=None): if self.call_no < self.options.start: return if self.options.images: - filename = '%s_%04u.png' % (description, self.call_no) - save_image(filename, surface) + filename = '%04u_%s.png' % (self.call_no, description) + save_image(filename, surface, x, y, w, h) else: title = '%u. %s' % (self.call_no, description) - show_image(surface, title) + show_image(surface, title, x, y, w, h) class Main(parser.Main): @@ -690,6 +715,7 @@ class Main(parser.Main): optparser.add_option("-q", "--quiet", action="store_const", const=0, dest="verbosity", help="no messages") optparser.add_option("-v", "--verbose", action="count", dest="verbosity", default=1, help="increase verbosity level") optparser.add_option("-i", "--images", action="store_true", dest="images", default=False, help="save images instead of showing them") + optparser.add_option("-a", "--all", action="store_true", dest="all", default=False, help="show depth, stencil, and transfers") optparser.add_option("-s", "--step", action="store_true", dest="step", default=False, help="step trhough every draw") optparser.add_option("-f", "--from", action="store", type="int", dest="start", default=0, help="from call no") optparser.add_option("-t", "--to", action="store", type="int", dest="stop", default=0, help="until call no") diff --git a/src/gallium/state_trackers/python/retrace/parse.py b/src/gallium/state_trackers/python/retrace/parse.py new file mode 100755 index 0000000000..b0f3e8a432 --- /dev/null +++ b/src/gallium/state_trackers/python/retrace/parse.py @@ -0,0 +1,392 @@ +#!/usr/bin/env python +########################################################################## +# +# 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. +# +########################################################################## + + +import sys +import xml.parsers.expat +import binascii +import optparse + +from model import * + + +ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4) + + +class XmlToken: + + def __init__(self, type, name_or_data, attrs = None, line = None, column = None): + assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF) + self.type = type + self.name_or_data = name_or_data + self.attrs = attrs + self.line = line + self.column = column + + def __str__(self): + if self.type == ELEMENT_START: + return '<' + self.name_or_data + ' ...>' + if self.type == ELEMENT_END: + return '</' + self.name_or_data + '>' + if self.type == CHARACTER_DATA: + return self.name_or_data + if self.type == EOF: + return 'end of file' + assert 0 + + +class XmlTokenizer: + """Expat based XML tokenizer.""" + + def __init__(self, fp, skip_ws = True): + self.fp = fp + self.tokens = [] + self.index = 0 + self.final = False + self.skip_ws = skip_ws + + self.character_pos = 0, 0 + self.character_data = '' + + self.parser = xml.parsers.expat.ParserCreate() + self.parser.StartElementHandler = self.handle_element_start + self.parser.EndElementHandler = self.handle_element_end + self.parser.CharacterDataHandler = self.handle_character_data + + def handle_element_start(self, name, attributes): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(ELEMENT_START, name, attributes, line, column) + self.tokens.append(token) + + def handle_element_end(self, name): + self.finish_character_data() + line, column = self.pos() + token = XmlToken(ELEMENT_END, name, None, line, column) + self.tokens.append(token) + + def handle_character_data(self, data): + if not self.character_data: + self.character_pos = self.pos() + self.character_data += data + + def finish_character_data(self): + if self.character_data: + if not self.skip_ws or not self.character_data.isspace(): + line, column = self.character_pos + token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column) + self.tokens.append(token) + self.character_data = '' + + def next(self): + size = 16*1024 + while self.index >= len(self.tokens) and not self.final: + self.tokens = [] + self.index = 0 + data = self.fp.read(size) + self.final = len(data) < size + data = data.rstrip('\0') + try: + self.parser.Parse(data, self.final) + except xml.parsers.expat.ExpatError, e: + #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: + if e.code == 3: + pass + else: + raise e + if self.index >= len(self.tokens): + line, column = self.pos() + token = XmlToken(EOF, None, None, line, column) + else: + token = self.tokens[self.index] + self.index += 1 + return token + + def pos(self): + return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber + + +class TokenMismatch(Exception): + + def __init__(self, expected, found): + self.expected = expected + self.found = found + + def __str__(self): + return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) + + + +class XmlParser: + """Base XML document parser.""" + + def __init__(self, fp): + self.tokenizer = XmlTokenizer(fp) + self.consume() + + def consume(self): + self.token = self.tokenizer.next() + + def match_element_start(self, name): + return self.token.type == ELEMENT_START and self.token.name_or_data == name + + def match_element_end(self, name): + return self.token.type == ELEMENT_END and self.token.name_or_data == name + + def element_start(self, name): + while self.token.type == CHARACTER_DATA: + self.consume() + if self.token.type != ELEMENT_START: + raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) + if self.token.name_or_data != name: + raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) + attrs = self.token.attrs + self.consume() + return attrs + + def element_end(self, name): + while self.token.type == CHARACTER_DATA: + self.consume() + if self.token.type != ELEMENT_END: + raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) + if self.token.name_or_data != name: + raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) + self.consume() + + def character_data(self, strip = True): + data = '' + while self.token.type == CHARACTER_DATA: + data += self.token.name_or_data + self.consume() + if strip: + data = data.strip() + return data + + +class TraceParser(XmlParser): + + def __init__(self, fp): + XmlParser.__init__(self, fp) + self.last_call_no = 0 + + def parse(self): + self.element_start('trace') + while self.token.type not in (ELEMENT_END, EOF): + call = self.parse_call() + self.handle_call(call) + if self.token.type != EOF: + self.element_end('trace') + + def parse_call(self): + attrs = self.element_start('call') + try: + no = int(attrs['no']) + except KeyError: + self.last_call_no += 1 + no = self.last_call_no + else: + self.last_call_no = no + klass = attrs['class'] + method = attrs['method'] + args = [] + ret = None + while self.token.type == ELEMENT_START: + if self.token.name_or_data == 'arg': + arg = self.parse_arg() + args.append(arg) + elif self.token.name_or_data == 'ret': + ret = self.parse_ret() + elif self.token.name_or_data == 'call': + # ignore nested function calls + self.parse_call() + else: + raise TokenMismatch("<arg ...> or <ret ...>", self.token) + self.element_end('call') + + return Call(no, klass, method, args, ret) + + def parse_arg(self): + attrs = self.element_start('arg') + name = attrs['name'] + value = self.parse_value() + self.element_end('arg') + + return name, value + + def parse_ret(self): + attrs = self.element_start('ret') + value = self.parse_value() + self.element_end('ret') + + return value + + def parse_value(self): + expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes') + if self.token.type == ELEMENT_START: + if self.token.name_or_data in expected_tokens: + method = getattr(self, 'parse_' + self.token.name_or_data) + return method() + raise TokenMismatch(" or " .join(expected_tokens), self.token) + + def parse_null(self): + self.element_start('null') + self.element_end('null') + return Literal(None) + + def parse_bool(self): + self.element_start('bool') + value = int(self.character_data()) + self.element_end('bool') + return Literal(value) + + def parse_int(self): + self.element_start('int') + value = int(self.character_data()) + self.element_end('int') + return Literal(value) + + def parse_uint(self): + self.element_start('uint') + value = int(self.character_data()) + self.element_end('uint') + return Literal(value) + + def parse_float(self): + self.element_start('float') + value = float(self.character_data()) + self.element_end('float') + return Literal(value) + + def parse_enum(self): + self.element_start('enum') + name = self.character_data() + self.element_end('enum') + return NamedConstant(name) + + def parse_string(self): + self.element_start('string') + value = self.character_data() + self.element_end('string') + return Literal(value) + + def parse_bytes(self): + self.element_start('bytes') + value = binascii.a2b_hex(self.character_data()) + self.element_end('bytes') + return Literal(value) + + def parse_array(self): + self.element_start('array') + elems = [] + while self.token.type != ELEMENT_END: + elems.append(self.parse_elem()) + self.element_end('array') + return Array(elems) + + def parse_elem(self): + self.element_start('elem') + value = self.parse_value() + self.element_end('elem') + return value + + def parse_struct(self): + attrs = self.element_start('struct') + name = attrs['name'] + members = [] + while self.token.type != ELEMENT_END: + members.append(self.parse_member()) + self.element_end('struct') + return Struct(name, members) + + def parse_member(self): + attrs = self.element_start('member') + name = attrs['name'] + value = self.parse_value() + self.element_end('member') + + return name, value + + def parse_ptr(self): + self.element_start('ptr') + address = self.character_data() + self.element_end('ptr') + + return Pointer(address) + + def handle_call(self, call): + pass + + +class TraceDumper(TraceParser): + + def __init__(self, fp): + TraceParser.__init__(self, fp) + self.formatter = format.DefaultFormatter(sys.stdout) + self.pretty_printer = PrettyPrinter(self.formatter) + + def handle_call(self, call): + call.visit(self.pretty_printer) + self.formatter.newline() + + +class Main: + '''Common main class for all retrace command line utilities.''' + + def __init__(self): + pass + + def main(self): + optparser = self.get_optparser() + (options, args) = optparser.parse_args(sys.argv[1:]) + + if args: + for arg in args: + if arg.endswith('.gz'): + from gzip import GzipFile + stream = GzipFile(arg, 'rt') + elif arg.endswith('.bz2'): + from bz2 import BZ2File + stream = BZ2File(arg, 'rt') + else: + stream = open(arg, 'rt') + self.process_arg(stream, options) + else: + self.process_arg(stream, options) + + def get_optparser(self): + optparser = optparse.OptionParser( + usage="\n\t%prog [options] [traces] ...") + return optparser + + def process_arg(self, stream, options): + parser = TraceDumper(stream) + parser.parse() + + +if __name__ == '__main__': + Main().main() diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/src/gallium/state_trackers/python/retrace/parser.py index b0f3e8a432..bd47c9a6b0 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/src/gallium/state_trackers/python/retrace/parser.py @@ -27,365 +27,7 @@ ########################################################################## -import sys -import xml.parsers.expat -import binascii -import optparse - -from model import * - - -ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4) - - -class XmlToken: - - def __init__(self, type, name_or_data, attrs = None, line = None, column = None): - assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF) - self.type = type - self.name_or_data = name_or_data - self.attrs = attrs - self.line = line - self.column = column - - def __str__(self): - if self.type == ELEMENT_START: - return '<' + self.name_or_data + ' ...>' - if self.type == ELEMENT_END: - return '</' + self.name_or_data + '>' - if self.type == CHARACTER_DATA: - return self.name_or_data - if self.type == EOF: - return 'end of file' - assert 0 - - -class XmlTokenizer: - """Expat based XML tokenizer.""" - - def __init__(self, fp, skip_ws = True): - self.fp = fp - self.tokens = [] - self.index = 0 - self.final = False - self.skip_ws = skip_ws - - self.character_pos = 0, 0 - self.character_data = '' - - self.parser = xml.parsers.expat.ParserCreate() - self.parser.StartElementHandler = self.handle_element_start - self.parser.EndElementHandler = self.handle_element_end - self.parser.CharacterDataHandler = self.handle_character_data - - def handle_element_start(self, name, attributes): - self.finish_character_data() - line, column = self.pos() - token = XmlToken(ELEMENT_START, name, attributes, line, column) - self.tokens.append(token) - - def handle_element_end(self, name): - self.finish_character_data() - line, column = self.pos() - token = XmlToken(ELEMENT_END, name, None, line, column) - self.tokens.append(token) - - def handle_character_data(self, data): - if not self.character_data: - self.character_pos = self.pos() - self.character_data += data - - def finish_character_data(self): - if self.character_data: - if not self.skip_ws or not self.character_data.isspace(): - line, column = self.character_pos - token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column) - self.tokens.append(token) - self.character_data = '' - - def next(self): - size = 16*1024 - while self.index >= len(self.tokens) and not self.final: - self.tokens = [] - self.index = 0 - data = self.fp.read(size) - self.final = len(data) < size - data = data.rstrip('\0') - try: - self.parser.Parse(data, self.final) - except xml.parsers.expat.ExpatError, e: - #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS: - if e.code == 3: - pass - else: - raise e - if self.index >= len(self.tokens): - line, column = self.pos() - token = XmlToken(EOF, None, None, line, column) - else: - token = self.tokens[self.index] - self.index += 1 - return token - - def pos(self): - return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber - - -class TokenMismatch(Exception): - - def __init__(self, expected, found): - self.expected = expected - self.found = found - - def __str__(self): - return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found)) - - - -class XmlParser: - """Base XML document parser.""" - - def __init__(self, fp): - self.tokenizer = XmlTokenizer(fp) - self.consume() - - def consume(self): - self.token = self.tokenizer.next() - - def match_element_start(self, name): - return self.token.type == ELEMENT_START and self.token.name_or_data == name - - def match_element_end(self, name): - return self.token.type == ELEMENT_END and self.token.name_or_data == name - - def element_start(self, name): - while self.token.type == CHARACTER_DATA: - self.consume() - if self.token.type != ELEMENT_START: - raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) - if self.token.name_or_data != name: - raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token) - attrs = self.token.attrs - self.consume() - return attrs - - def element_end(self, name): - while self.token.type == CHARACTER_DATA: - self.consume() - if self.token.type != ELEMENT_END: - raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) - if self.token.name_or_data != name: - raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token) - self.consume() - - def character_data(self, strip = True): - data = '' - while self.token.type == CHARACTER_DATA: - data += self.token.name_or_data - self.consume() - if strip: - data = data.strip() - return data - - -class TraceParser(XmlParser): - - def __init__(self, fp): - XmlParser.__init__(self, fp) - self.last_call_no = 0 - - def parse(self): - self.element_start('trace') - while self.token.type not in (ELEMENT_END, EOF): - call = self.parse_call() - self.handle_call(call) - if self.token.type != EOF: - self.element_end('trace') - - def parse_call(self): - attrs = self.element_start('call') - try: - no = int(attrs['no']) - except KeyError: - self.last_call_no += 1 - no = self.last_call_no - else: - self.last_call_no = no - klass = attrs['class'] - method = attrs['method'] - args = [] - ret = None - while self.token.type == ELEMENT_START: - if self.token.name_or_data == 'arg': - arg = self.parse_arg() - args.append(arg) - elif self.token.name_or_data == 'ret': - ret = self.parse_ret() - elif self.token.name_or_data == 'call': - # ignore nested function calls - self.parse_call() - else: - raise TokenMismatch("<arg ...> or <ret ...>", self.token) - self.element_end('call') - - return Call(no, klass, method, args, ret) - - def parse_arg(self): - attrs = self.element_start('arg') - name = attrs['name'] - value = self.parse_value() - self.element_end('arg') - - return name, value - - def parse_ret(self): - attrs = self.element_start('ret') - value = self.parse_value() - self.element_end('ret') - - return value - - def parse_value(self): - expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes') - if self.token.type == ELEMENT_START: - if self.token.name_or_data in expected_tokens: - method = getattr(self, 'parse_' + self.token.name_or_data) - return method() - raise TokenMismatch(" or " .join(expected_tokens), self.token) - - def parse_null(self): - self.element_start('null') - self.element_end('null') - return Literal(None) - - def parse_bool(self): - self.element_start('bool') - value = int(self.character_data()) - self.element_end('bool') - return Literal(value) - - def parse_int(self): - self.element_start('int') - value = int(self.character_data()) - self.element_end('int') - return Literal(value) - - def parse_uint(self): - self.element_start('uint') - value = int(self.character_data()) - self.element_end('uint') - return Literal(value) - - def parse_float(self): - self.element_start('float') - value = float(self.character_data()) - self.element_end('float') - return Literal(value) - - def parse_enum(self): - self.element_start('enum') - name = self.character_data() - self.element_end('enum') - return NamedConstant(name) - - def parse_string(self): - self.element_start('string') - value = self.character_data() - self.element_end('string') - return Literal(value) - - def parse_bytes(self): - self.element_start('bytes') - value = binascii.a2b_hex(self.character_data()) - self.element_end('bytes') - return Literal(value) - - def parse_array(self): - self.element_start('array') - elems = [] - while self.token.type != ELEMENT_END: - elems.append(self.parse_elem()) - self.element_end('array') - return Array(elems) - - def parse_elem(self): - self.element_start('elem') - value = self.parse_value() - self.element_end('elem') - return value - - def parse_struct(self): - attrs = self.element_start('struct') - name = attrs['name'] - members = [] - while self.token.type != ELEMENT_END: - members.append(self.parse_member()) - self.element_end('struct') - return Struct(name, members) - - def parse_member(self): - attrs = self.element_start('member') - name = attrs['name'] - value = self.parse_value() - self.element_end('member') - - return name, value - - def parse_ptr(self): - self.element_start('ptr') - address = self.character_data() - self.element_end('ptr') - - return Pointer(address) - - def handle_call(self, call): - pass - - -class TraceDumper(TraceParser): - - def __init__(self, fp): - TraceParser.__init__(self, fp) - self.formatter = format.DefaultFormatter(sys.stdout) - self.pretty_printer = PrettyPrinter(self.formatter) - - def handle_call(self, call): - call.visit(self.pretty_printer) - self.formatter.newline() - - -class Main: - '''Common main class for all retrace command line utilities.''' - - def __init__(self): - pass - - def main(self): - optparser = self.get_optparser() - (options, args) = optparser.parse_args(sys.argv[1:]) - - if args: - for arg in args: - if arg.endswith('.gz'): - from gzip import GzipFile - stream = GzipFile(arg, 'rt') - elif arg.endswith('.bz2'): - from bz2 import BZ2File - stream = BZ2File(arg, 'rt') - else: - stream = open(arg, 'rt') - self.process_arg(stream, options) - else: - self.process_arg(stream, options) - - def get_optparser(self): - optparser = optparse.OptionParser( - usage="\n\t%prog [options] [traces] ...") - return optparser - - def process_arg(self, stream, options): - parser = TraceDumper(stream) - parser.parse() +from parse import * if __name__ == '__main__': diff --git a/src/gallium/state_trackers/python/st_softpipe_winsys.c b/src/gallium/state_trackers/python/st_softpipe_winsys.c index 41cdeaa6fd..f0a4826a00 100644 --- a/src/gallium/state_trackers/python/st_softpipe_winsys.c +++ b/src/gallium/state_trackers/python/st_softpipe_winsys.c @@ -260,7 +260,7 @@ st_softpipe_screen_create(void) static struct pipe_context * st_softpipe_context_create(struct pipe_screen *screen) { - return softpipe_create(screen, screen->winsys, NULL); + return softpipe_create(screen); } diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/src/gallium/state_trackers/python/tests/texture_sample.py index a382424667..06130ea1c9 100755 --- a/src/gallium/state_trackers/python/tests/texture_sample.py +++ b/src/gallium/state_trackers/python/tests/texture_sample.py @@ -99,7 +99,7 @@ def is_pot(n): return n & (n - 1) == 0 -class TextureTest(TestCase): +class TextureColorSampleTest(TestCase): tags = ( 'target', @@ -286,6 +286,206 @@ class TextureTest(TestCase): self.assert_rgba(cbuf, x, y, w, h, expected_rgba, 4.0/256, 0.85) +class TextureDepthSampleTest(TestCase): + + tags = ( + 'target', + 'format', + 'width', + 'height', + 'depth', + 'last_level', + 'face', + 'level', + 'zslice', + ) + + def test(self): + dev = self.dev + + target = self.target + format = self.format + width = self.width + height = self.height + depth = self.depth + last_level = self.last_level + face = self.face + level = self.level + zslice = self.zslice + + tex_usage = PIPE_TEXTURE_USAGE_SAMPLER + geom_flags = 0 + if width != height: + geom_flags |= PIPE_TEXTURE_GEOM_NON_SQUARE + if not is_pot(width) or not is_pot(height) or not is_pot(depth): + geom_flags |= PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO + + if not dev.is_format_supported(format, target, tex_usage, geom_flags): + raise TestSkip + + ctx = self.dev.context_create() + + # disabled blending/masking + blend = Blend() + blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE + blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE + blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO + blend.colormask = PIPE_MASK_RGBA + ctx.set_blend(blend) + + # depth/stencil/alpha + depth_stencil_alpha = DepthStencilAlpha() + depth_stencil_alpha.depth.enabled = 1 + depth_stencil_alpha.depth.writemask = 1 + depth_stencil_alpha.depth.func = PIPE_FUNC_LESS + ctx.set_depth_stencil_alpha(depth_stencil_alpha) + + # rasterizer + rasterizer = Rasterizer() + rasterizer.front_winding = PIPE_WINDING_CW + rasterizer.cull_mode = PIPE_WINDING_NONE + rasterizer.bypass_vs_clip_and_viewport = 1 + ctx.set_rasterizer(rasterizer) + + # samplers + sampler = Sampler() + sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE + sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST + sampler.normalized_coords = 1 + sampler.min_lod = 0 + sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1 + ctx.set_sampler(0, sampler) + + # texture + texture = dev.texture_create( + target = target, + format = format, + width = width, + height = height, + depth = depth, + last_level = last_level, + tex_usage = tex_usage, + ) + + expected_rgba = FloatArray(height*width*4) + texture.get_surface( + face = face, + level = level, + zslice = zslice, + ).sample_rgba(expected_rgba) + + ctx.set_sampler_texture(0, texture) + + # framebuffer + cbuf_tex = dev.texture_create( + PIPE_FORMAT_A8R8G8B8_UNORM, + width, + height, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) + + zsbuf_tex = dev.texture_create( + PIPE_FORMAT_Z24X8_UNORM, + width, + height, + tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET, + ) + + cbuf = cbuf_tex.get_surface() + zsbuf = zsbuf_tex.get_surface() + fb = Framebuffer() + fb.width = width + fb.height = height + fb.nr_cbufs = 1 + fb.set_cbuf(0, cbuf) + fb.set_zsbuf(zsbuf) + ctx.set_framebuffer(fb) + rgba = FloatArray(4); + rgba[0] = 0.5 + rgba[1] = 0.5 + rgba[2] = 0.5 + rgba[3] = 0.5 + ctx.clear(PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0) + del fb + + # vertex shader + vs = Shader(''' + VERT1.1 + DCL IN[0], POSITION, CONSTANT + DCL IN[1], GENERIC, CONSTANT + DCL OUT[0], POSITION, CONSTANT + DCL OUT[1], GENERIC, CONSTANT + 0:MOV OUT[0], IN[0] + 1:MOV OUT[1], IN[1] + 2:END + ''') + #vs.dump() + ctx.set_vertex_shader(vs) + + # fragment shader + op = { + PIPE_TEXTURE_1D: "1D", + PIPE_TEXTURE_2D: "2D", + PIPE_TEXTURE_3D: "3D", + PIPE_TEXTURE_CUBE: "CUBE", + }[target] + fs = Shader(''' + FRAG1.1 + DCL IN[0], GENERIC[0], LINEAR + DCL SAMP[0], CONSTANT + DCL OUT[0].z, POSITION + 0:TEX OUT[0].z, IN[0], SAMP[0], %s + 1:END + ''' % op) + #fs.dump() + ctx.set_fragment_shader(fs) + + nverts = 4 + nattrs = 2 + verts = FloatArray(nverts * nattrs * 4) + + x = 0 + y = 0 + w, h = minify((width, height), level) + + pos = [ + [x, y], + [x+w, y], + [x+w, y+h], + [x, y+h], + ] + + tex = tex_coords(texture, face, level, zslice) + + for i in range(0, 4): + j = 8*i + verts[j + 0] = pos[i][0] # x + verts[j + 1] = pos[i][1] # y + verts[j + 2] = 0.0 # z + verts[j + 3] = 1.0 # w + verts[j + 4] = tex[i][0] # s + verts[j + 5] = tex[i][1] # r + verts[j + 6] = tex[i][2] # q + verts[j + 7] = 1.0 + + ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN, + nverts, + nattrs, + verts) + + ctx.flush() + + zsbuf = zsbuf_tex.get_surface() + + self.assert_rgba(zsbuf, x, y, w, h, expected_rgba, 4.0/256, 0.85) + + + def main(): dev = Device() @@ -304,11 +504,10 @@ def main(): PIPE_FORMAT_R5G6B5_UNORM, PIPE_FORMAT_A1R5G5B5_UNORM, PIPE_FORMAT_A4R4G4B4_UNORM, - #PIPE_FORMAT_Z32_UNORM, - #PIPE_FORMAT_Z24S8_UNORM, - #PIPE_FORMAT_Z24X8_UNORM, - #PIPE_FORMAT_Z16_UNORM, - #PIPE_FORMAT_S8_UNORM, + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_Z16_UNORM, PIPE_FORMAT_A8_UNORM, PIPE_FORMAT_L8_UNORM, PIPE_FORMAT_YCBCR, @@ -347,7 +546,17 @@ def main(): for level in range(0, last_level + 1): zslice = 0 while zslice < depth >> level: - test = TextureTest( + if format in ( + PIPE_FORMAT_Z32_UNORM, + PIPE_FORMAT_Z24S8_UNORM, + PIPE_FORMAT_Z24X8_UNORM, + PIPE_FORMAT_Z16_UNORM, + ): + klass = TextureDepthSampleTest + else: + klass = TextureColorSampleTest + + test = klass( dev = dev, target = target, format = format, diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript index 038a7a31b3..5bbcc7175f 100644 --- a/src/gallium/state_trackers/wgl/SConscript +++ b/src/gallium/state_trackers/wgl/SConscript @@ -26,8 +26,7 @@ if env['platform'] in ['windows']: 'shared/stw_device.c', 'shared/stw_framebuffer.c', 'shared/stw_pixelformat.c', - 'shared/stw_quirks.c', - 'shared/stw_arbextensionsstring.c', + 'shared/stw_extensionsstring.c', 'shared/stw_getprocaddress.c', 'shared/stw_arbpixelformat.c', 'shared/stw_tls.c', diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.c b/src/gallium/state_trackers/wgl/icd/stw_icd.c index faf7f2f410..347f40aa06 100644 --- a/src/gallium/state_trackers/wgl/icd/stw_icd.c +++ b/src/gallium/state_trackers/wgl/icd/stw_icd.c @@ -38,9 +38,6 @@ #define DBG 0 -static GLCLTPROCTABLE cpt; -static boolean cpt_initialized = FALSE; - BOOL APIENTRY DrvCopyContext( @@ -57,7 +54,15 @@ DrvCreateLayerContext( HDC hdc, INT iLayerPlane ) { - return stw_create_layer_context( hdc, iLayerPlane ); + DHGLRC r; + + r = stw_create_layer_context( hdc, iLayerPlane ); + + if (DBG) + debug_printf( "%s( %p, %i ) = %u\n", + __FUNCTION__, hdc, iLayerPlane, r ); + + return r; } DHGLRC APIENTRY @@ -71,7 +76,15 @@ BOOL APIENTRY DrvDeleteContext( DHGLRC dhglrc ) { - return stw_delete_context( dhglrc ); + BOOL r; + + r = stw_delete_context( dhglrc ); + + if (DBG) + debug_printf( "%s( %u ) = %u\n", + __FUNCTION__, dhglrc, r ); + + return r; } BOOL APIENTRY @@ -129,7 +142,7 @@ DrvGetProcAddress( r = stw_get_proc_address( lpszProc ); if (DBG) - debug_printf( "%s( \", __FUNCTION__%s\" ) = %p\n", lpszProc, r ); + debug_printf( "%s( \"%s\" ) = %p\n", __FUNCTION__, lpszProc, r ); return r; } @@ -165,351 +178,352 @@ DrvSetCallbackProcs( } -static void init_proc_table( GLCLTPROCTABLE *cpt ) -{ - GLDISPATCHTABLE *disp = &cpt->glDispatchTable; - - memset( cpt, 0, sizeof *cpt ); - cpt->cEntries = OPENGL_VERSION_110_ENTRIES; - -#define GPA_GL( NAME ) disp->NAME = gl##NAME - GPA_GL( NewList ); - GPA_GL( EndList ); - GPA_GL( CallList ); - GPA_GL( CallLists ); - GPA_GL( DeleteLists ); - GPA_GL( GenLists ); - GPA_GL( ListBase ); - GPA_GL( Begin ); - GPA_GL( Bitmap ); - GPA_GL( Color3b ); - GPA_GL( Color3bv ); - GPA_GL( Color3d ); - GPA_GL( Color3dv ); - GPA_GL( Color3f ); - GPA_GL( Color3fv ); - GPA_GL( Color3i ); - GPA_GL( Color3iv ); - GPA_GL( Color3s ); - GPA_GL( Color3sv ); - GPA_GL( Color3ub ); - GPA_GL( Color3ubv ); - GPA_GL( Color3ui ); - GPA_GL( Color3uiv ); - GPA_GL( Color3us ); - GPA_GL( Color3usv ); - GPA_GL( Color4b ); - GPA_GL( Color4bv ); - GPA_GL( Color4d ); - GPA_GL( Color4dv ); - GPA_GL( Color4f ); - GPA_GL( Color4fv ); - GPA_GL( Color4i ); - GPA_GL( Color4iv ); - GPA_GL( Color4s ); - GPA_GL( Color4sv ); - GPA_GL( Color4ub ); - GPA_GL( Color4ubv ); - GPA_GL( Color4ui ); - GPA_GL( Color4uiv ); - GPA_GL( Color4us ); - GPA_GL( Color4usv ); - GPA_GL( EdgeFlag ); - GPA_GL( EdgeFlagv ); - GPA_GL( End ); - GPA_GL( Indexd ); - GPA_GL( Indexdv ); - GPA_GL( Indexf ); - GPA_GL( Indexfv ); - GPA_GL( Indexi ); - GPA_GL( Indexiv ); - GPA_GL( Indexs ); - GPA_GL( Indexsv ); - GPA_GL( Normal3b ); - GPA_GL( Normal3bv ); - GPA_GL( Normal3d ); - GPA_GL( Normal3dv ); - GPA_GL( Normal3f ); - GPA_GL( Normal3fv ); - GPA_GL( Normal3i ); - GPA_GL( Normal3iv ); - GPA_GL( Normal3s ); - GPA_GL( Normal3sv ); - GPA_GL( RasterPos2d ); - GPA_GL( RasterPos2dv ); - GPA_GL( RasterPos2f ); - GPA_GL( RasterPos2fv ); - GPA_GL( RasterPos2i ); - GPA_GL( RasterPos2iv ); - GPA_GL( RasterPos2s ); - GPA_GL( RasterPos2sv ); - GPA_GL( RasterPos3d ); - GPA_GL( RasterPos3dv ); - GPA_GL( RasterPos3f ); - GPA_GL( RasterPos3fv ); - GPA_GL( RasterPos3i ); - GPA_GL( RasterPos3iv ); - GPA_GL( RasterPos3s ); - GPA_GL( RasterPos3sv ); - GPA_GL( RasterPos4d ); - GPA_GL( RasterPos4dv ); - GPA_GL( RasterPos4f ); - GPA_GL( RasterPos4fv ); - GPA_GL( RasterPos4i ); - GPA_GL( RasterPos4iv ); - GPA_GL( RasterPos4s ); - GPA_GL( RasterPos4sv ); - GPA_GL( Rectd ); - GPA_GL( Rectdv ); - GPA_GL( Rectf ); - GPA_GL( Rectfv ); - GPA_GL( Recti ); - GPA_GL( Rectiv ); - GPA_GL( Rects ); - GPA_GL( Rectsv ); - GPA_GL( TexCoord1d ); - GPA_GL( TexCoord1dv ); - GPA_GL( TexCoord1f ); - GPA_GL( TexCoord1fv ); - GPA_GL( TexCoord1i ); - GPA_GL( TexCoord1iv ); - GPA_GL( TexCoord1s ); - GPA_GL( TexCoord1sv ); - GPA_GL( TexCoord2d ); - GPA_GL( TexCoord2dv ); - GPA_GL( TexCoord2f ); - GPA_GL( TexCoord2fv ); - GPA_GL( TexCoord2i ); - GPA_GL( TexCoord2iv ); - GPA_GL( TexCoord2s ); - GPA_GL( TexCoord2sv ); - GPA_GL( TexCoord3d ); - GPA_GL( TexCoord3dv ); - GPA_GL( TexCoord3f ); - GPA_GL( TexCoord3fv ); - GPA_GL( TexCoord3i ); - GPA_GL( TexCoord3iv ); - GPA_GL( TexCoord3s ); - GPA_GL( TexCoord3sv ); - GPA_GL( TexCoord4d ); - GPA_GL( TexCoord4dv ); - GPA_GL( TexCoord4f ); - GPA_GL( TexCoord4fv ); - GPA_GL( TexCoord4i ); - GPA_GL( TexCoord4iv ); - GPA_GL( TexCoord4s ); - GPA_GL( TexCoord4sv ); - GPA_GL( Vertex2d ); - GPA_GL( Vertex2dv ); - GPA_GL( Vertex2f ); - GPA_GL( Vertex2fv ); - GPA_GL( Vertex2i ); - GPA_GL( Vertex2iv ); - GPA_GL( Vertex2s ); - GPA_GL( Vertex2sv ); - GPA_GL( Vertex3d ); - GPA_GL( Vertex3dv ); - GPA_GL( Vertex3f ); - GPA_GL( Vertex3fv ); - GPA_GL( Vertex3i ); - GPA_GL( Vertex3iv ); - GPA_GL( Vertex3s ); - GPA_GL( Vertex3sv ); - GPA_GL( Vertex4d ); - GPA_GL( Vertex4dv ); - GPA_GL( Vertex4f ); - GPA_GL( Vertex4fv ); - GPA_GL( Vertex4i ); - GPA_GL( Vertex4iv ); - GPA_GL( Vertex4s ); - GPA_GL( Vertex4sv ); - GPA_GL( ClipPlane ); - GPA_GL( ColorMaterial ); - GPA_GL( CullFace ); - GPA_GL( Fogf ); - GPA_GL( Fogfv ); - GPA_GL( Fogi ); - GPA_GL( Fogiv ); - GPA_GL( FrontFace ); - GPA_GL( Hint ); - GPA_GL( Lightf ); - GPA_GL( Lightfv ); - GPA_GL( Lighti ); - GPA_GL( Lightiv ); - GPA_GL( LightModelf ); - GPA_GL( LightModelfv ); - GPA_GL( LightModeli ); - GPA_GL( LightModeliv ); - GPA_GL( LineStipple ); - GPA_GL( LineWidth ); - GPA_GL( Materialf ); - GPA_GL( Materialfv ); - GPA_GL( Materiali ); - GPA_GL( Materialiv ); - GPA_GL( PointSize ); - GPA_GL( PolygonMode ); - GPA_GL( PolygonStipple ); - GPA_GL( Scissor ); - GPA_GL( ShadeModel ); - GPA_GL( TexParameterf ); - GPA_GL( TexParameterfv ); - GPA_GL( TexParameteri ); - GPA_GL( TexParameteriv ); - GPA_GL( TexImage1D ); - GPA_GL( TexImage2D ); - GPA_GL( TexEnvf ); - GPA_GL( TexEnvfv ); - GPA_GL( TexEnvi ); - GPA_GL( TexEnviv ); - GPA_GL( TexGend ); - GPA_GL( TexGendv ); - GPA_GL( TexGenf ); - GPA_GL( TexGenfv ); - GPA_GL( TexGeni ); - GPA_GL( TexGeniv ); - GPA_GL( FeedbackBuffer ); - GPA_GL( SelectBuffer ); - GPA_GL( RenderMode ); - GPA_GL( InitNames ); - GPA_GL( LoadName ); - GPA_GL( PassThrough ); - GPA_GL( PopName ); - GPA_GL( PushName ); - GPA_GL( DrawBuffer ); - GPA_GL( Clear ); - GPA_GL( ClearAccum ); - GPA_GL( ClearIndex ); - GPA_GL( ClearColor ); - GPA_GL( ClearStencil ); - GPA_GL( ClearDepth ); - GPA_GL( StencilMask ); - GPA_GL( ColorMask ); - GPA_GL( DepthMask ); - GPA_GL( IndexMask ); - GPA_GL( Accum ); - GPA_GL( Disable ); - GPA_GL( Enable ); - GPA_GL( Finish ); - GPA_GL( Flush ); - GPA_GL( PopAttrib ); - GPA_GL( PushAttrib ); - GPA_GL( Map1d ); - GPA_GL( Map1f ); - GPA_GL( Map2d ); - GPA_GL( Map2f ); - GPA_GL( MapGrid1d ); - GPA_GL( MapGrid1f ); - GPA_GL( MapGrid2d ); - GPA_GL( MapGrid2f ); - GPA_GL( EvalCoord1d ); - GPA_GL( EvalCoord1dv ); - GPA_GL( EvalCoord1f ); - GPA_GL( EvalCoord1fv ); - GPA_GL( EvalCoord2d ); - GPA_GL( EvalCoord2dv ); - GPA_GL( EvalCoord2f ); - GPA_GL( EvalCoord2fv ); - GPA_GL( EvalMesh1 ); - GPA_GL( EvalPoint1 ); - GPA_GL( EvalMesh2 ); - GPA_GL( EvalPoint2 ); - GPA_GL( AlphaFunc ); - GPA_GL( BlendFunc ); - GPA_GL( LogicOp ); - GPA_GL( StencilFunc ); - GPA_GL( StencilOp ); - GPA_GL( DepthFunc ); - GPA_GL( PixelZoom ); - GPA_GL( PixelTransferf ); - GPA_GL( PixelTransferi ); - GPA_GL( PixelStoref ); - GPA_GL( PixelStorei ); - GPA_GL( PixelMapfv ); - GPA_GL( PixelMapuiv ); - GPA_GL( PixelMapusv ); - GPA_GL( ReadBuffer ); - GPA_GL( CopyPixels ); - GPA_GL( ReadPixels ); - GPA_GL( DrawPixels ); - GPA_GL( GetBooleanv ); - GPA_GL( GetClipPlane ); - GPA_GL( GetDoublev ); - GPA_GL( GetError ); - GPA_GL( GetFloatv ); - GPA_GL( GetIntegerv ); - GPA_GL( GetLightfv ); - GPA_GL( GetLightiv ); - GPA_GL( GetMapdv ); - GPA_GL( GetMapfv ); - GPA_GL( GetMapiv ); - GPA_GL( GetMaterialfv ); - GPA_GL( GetMaterialiv ); - GPA_GL( GetPixelMapfv ); - GPA_GL( GetPixelMapuiv ); - GPA_GL( GetPixelMapusv ); - GPA_GL( GetPolygonStipple ); - GPA_GL( GetString ); - GPA_GL( GetTexEnvfv ); - GPA_GL( GetTexEnviv ); - GPA_GL( GetTexGendv ); - GPA_GL( GetTexGenfv ); - GPA_GL( GetTexGeniv ); - GPA_GL( GetTexImage ); - GPA_GL( GetTexParameterfv ); - GPA_GL( GetTexParameteriv ); - GPA_GL( GetTexLevelParameterfv ); - GPA_GL( GetTexLevelParameteriv ); - GPA_GL( IsEnabled ); - GPA_GL( IsList ); - GPA_GL( DepthRange ); - GPA_GL( Frustum ); - GPA_GL( LoadIdentity ); - GPA_GL( LoadMatrixf ); - GPA_GL( LoadMatrixd ); - GPA_GL( MatrixMode ); - GPA_GL( MultMatrixf ); - GPA_GL( MultMatrixd ); - GPA_GL( Ortho ); - GPA_GL( PopMatrix ); - GPA_GL( PushMatrix ); - GPA_GL( Rotated ); - GPA_GL( Rotatef ); - GPA_GL( Scaled ); - GPA_GL( Scalef ); - GPA_GL( Translated ); - GPA_GL( Translatef ); - GPA_GL( Viewport ); - GPA_GL( ArrayElement ); - GPA_GL( BindTexture ); - GPA_GL( ColorPointer ); - GPA_GL( DisableClientState ); - GPA_GL( DrawArrays ); - GPA_GL( DrawElements ); - GPA_GL( EdgeFlagPointer ); - GPA_GL( EnableClientState ); - GPA_GL( IndexPointer ); - GPA_GL( Indexub ); - GPA_GL( Indexubv ); - GPA_GL( InterleavedArrays ); - GPA_GL( NormalPointer ); - GPA_GL( PolygonOffset ); - GPA_GL( TexCoordPointer ); - GPA_GL( VertexPointer ); - GPA_GL( AreTexturesResident ); - GPA_GL( CopyTexImage1D ); - GPA_GL( CopyTexImage2D ); - GPA_GL( CopyTexSubImage1D ); - GPA_GL( CopyTexSubImage2D ); - GPA_GL( DeleteTextures ); - GPA_GL( GenTextures ); - GPA_GL( GetPointerv ); - GPA_GL( IsTexture ); - GPA_GL( PrioritizeTextures ); - GPA_GL( TexSubImage1D ); - GPA_GL( TexSubImage2D ); - GPA_GL( PopClientAttrib ); - GPA_GL( PushClientAttrib ); -} +/** + * Although WGL allows different dispatch entrypoints per context + */ +static const GLCLTPROCTABLE cpt = +{ + OPENGL_VERSION_110_ENTRIES, + { + &glNewList, + &glEndList, + &glCallList, + &glCallLists, + &glDeleteLists, + &glGenLists, + &glListBase, + &glBegin, + &glBitmap, + &glColor3b, + &glColor3bv, + &glColor3d, + &glColor3dv, + &glColor3f, + &glColor3fv, + &glColor3i, + &glColor3iv, + &glColor3s, + &glColor3sv, + &glColor3ub, + &glColor3ubv, + &glColor3ui, + &glColor3uiv, + &glColor3us, + &glColor3usv, + &glColor4b, + &glColor4bv, + &glColor4d, + &glColor4dv, + &glColor4f, + &glColor4fv, + &glColor4i, + &glColor4iv, + &glColor4s, + &glColor4sv, + &glColor4ub, + &glColor4ubv, + &glColor4ui, + &glColor4uiv, + &glColor4us, + &glColor4usv, + &glEdgeFlag, + &glEdgeFlagv, + &glEnd, + &glIndexd, + &glIndexdv, + &glIndexf, + &glIndexfv, + &glIndexi, + &glIndexiv, + &glIndexs, + &glIndexsv, + &glNormal3b, + &glNormal3bv, + &glNormal3d, + &glNormal3dv, + &glNormal3f, + &glNormal3fv, + &glNormal3i, + &glNormal3iv, + &glNormal3s, + &glNormal3sv, + &glRasterPos2d, + &glRasterPos2dv, + &glRasterPos2f, + &glRasterPos2fv, + &glRasterPos2i, + &glRasterPos2iv, + &glRasterPos2s, + &glRasterPos2sv, + &glRasterPos3d, + &glRasterPos3dv, + &glRasterPos3f, + &glRasterPos3fv, + &glRasterPos3i, + &glRasterPos3iv, + &glRasterPos3s, + &glRasterPos3sv, + &glRasterPos4d, + &glRasterPos4dv, + &glRasterPos4f, + &glRasterPos4fv, + &glRasterPos4i, + &glRasterPos4iv, + &glRasterPos4s, + &glRasterPos4sv, + &glRectd, + &glRectdv, + &glRectf, + &glRectfv, + &glRecti, + &glRectiv, + &glRects, + &glRectsv, + &glTexCoord1d, + &glTexCoord1dv, + &glTexCoord1f, + &glTexCoord1fv, + &glTexCoord1i, + &glTexCoord1iv, + &glTexCoord1s, + &glTexCoord1sv, + &glTexCoord2d, + &glTexCoord2dv, + &glTexCoord2f, + &glTexCoord2fv, + &glTexCoord2i, + &glTexCoord2iv, + &glTexCoord2s, + &glTexCoord2sv, + &glTexCoord3d, + &glTexCoord3dv, + &glTexCoord3f, + &glTexCoord3fv, + &glTexCoord3i, + &glTexCoord3iv, + &glTexCoord3s, + &glTexCoord3sv, + &glTexCoord4d, + &glTexCoord4dv, + &glTexCoord4f, + &glTexCoord4fv, + &glTexCoord4i, + &glTexCoord4iv, + &glTexCoord4s, + &glTexCoord4sv, + &glVertex2d, + &glVertex2dv, + &glVertex2f, + &glVertex2fv, + &glVertex2i, + &glVertex2iv, + &glVertex2s, + &glVertex2sv, + &glVertex3d, + &glVertex3dv, + &glVertex3f, + &glVertex3fv, + &glVertex3i, + &glVertex3iv, + &glVertex3s, + &glVertex3sv, + &glVertex4d, + &glVertex4dv, + &glVertex4f, + &glVertex4fv, + &glVertex4i, + &glVertex4iv, + &glVertex4s, + &glVertex4sv, + &glClipPlane, + &glColorMaterial, + &glCullFace, + &glFogf, + &glFogfv, + &glFogi, + &glFogiv, + &glFrontFace, + &glHint, + &glLightf, + &glLightfv, + &glLighti, + &glLightiv, + &glLightModelf, + &glLightModelfv, + &glLightModeli, + &glLightModeliv, + &glLineStipple, + &glLineWidth, + &glMaterialf, + &glMaterialfv, + &glMateriali, + &glMaterialiv, + &glPointSize, + &glPolygonMode, + &glPolygonStipple, + &glScissor, + &glShadeModel, + &glTexParameterf, + &glTexParameterfv, + &glTexParameteri, + &glTexParameteriv, + &glTexImage1D, + &glTexImage2D, + &glTexEnvf, + &glTexEnvfv, + &glTexEnvi, + &glTexEnviv, + &glTexGend, + &glTexGendv, + &glTexGenf, + &glTexGenfv, + &glTexGeni, + &glTexGeniv, + &glFeedbackBuffer, + &glSelectBuffer, + &glRenderMode, + &glInitNames, + &glLoadName, + &glPassThrough, + &glPopName, + &glPushName, + &glDrawBuffer, + &glClear, + &glClearAccum, + &glClearIndex, + &glClearColor, + &glClearStencil, + &glClearDepth, + &glStencilMask, + &glColorMask, + &glDepthMask, + &glIndexMask, + &glAccum, + &glDisable, + &glEnable, + &glFinish, + &glFlush, + &glPopAttrib, + &glPushAttrib, + &glMap1d, + &glMap1f, + &glMap2d, + &glMap2f, + &glMapGrid1d, + &glMapGrid1f, + &glMapGrid2d, + &glMapGrid2f, + &glEvalCoord1d, + &glEvalCoord1dv, + &glEvalCoord1f, + &glEvalCoord1fv, + &glEvalCoord2d, + &glEvalCoord2dv, + &glEvalCoord2f, + &glEvalCoord2fv, + &glEvalMesh1, + &glEvalPoint1, + &glEvalMesh2, + &glEvalPoint2, + &glAlphaFunc, + &glBlendFunc, + &glLogicOp, + &glStencilFunc, + &glStencilOp, + &glDepthFunc, + &glPixelZoom, + &glPixelTransferf, + &glPixelTransferi, + &glPixelStoref, + &glPixelStorei, + &glPixelMapfv, + &glPixelMapuiv, + &glPixelMapusv, + &glReadBuffer, + &glCopyPixels, + &glReadPixels, + &glDrawPixels, + &glGetBooleanv, + &glGetClipPlane, + &glGetDoublev, + &glGetError, + &glGetFloatv, + &glGetIntegerv, + &glGetLightfv, + &glGetLightiv, + &glGetMapdv, + &glGetMapfv, + &glGetMapiv, + &glGetMaterialfv, + &glGetMaterialiv, + &glGetPixelMapfv, + &glGetPixelMapuiv, + &glGetPixelMapusv, + &glGetPolygonStipple, + &glGetString, + &glGetTexEnvfv, + &glGetTexEnviv, + &glGetTexGendv, + &glGetTexGenfv, + &glGetTexGeniv, + &glGetTexImage, + &glGetTexParameterfv, + &glGetTexParameteriv, + &glGetTexLevelParameterfv, + &glGetTexLevelParameteriv, + &glIsEnabled, + &glIsList, + &glDepthRange, + &glFrustum, + &glLoadIdentity, + &glLoadMatrixf, + &glLoadMatrixd, + &glMatrixMode, + &glMultMatrixf, + &glMultMatrixd, + &glOrtho, + &glPopMatrix, + &glPushMatrix, + &glRotated, + &glRotatef, + &glScaled, + &glScalef, + &glTranslated, + &glTranslatef, + &glViewport, + &glArrayElement, + &glBindTexture, + &glColorPointer, + &glDisableClientState, + &glDrawArrays, + &glDrawElements, + &glEdgeFlagPointer, + &glEnableClientState, + &glIndexPointer, + &glIndexub, + &glIndexubv, + &glInterleavedArrays, + &glNormalPointer, + &glPolygonOffset, + &glTexCoordPointer, + &glVertexPointer, + &glAreTexturesResident, + &glCopyTexImage1D, + &glCopyTexImage2D, + &glCopyTexSubImage1D, + &glCopyTexSubImage2D, + &glDeleteTextures, + &glGenTextures, + &glGetPointerv, + &glIsTexture, + &glPrioritizeTextures, + &glTexSubImage1D, + &glTexSubImage2D, + &glPopClientAttrib, + &glPushClientAttrib + } +}; + PGLCLTPROCTABLE APIENTRY DrvSetContext( @@ -517,21 +531,16 @@ DrvSetContext( DHGLRC dhglrc, PFN_SETPROCTABLE pfnSetProcTable ) { - if (DBG) - debug_printf( "%s( 0x%p, %u, 0x%p )\n", - __FUNCTION__, hdc, dhglrc, pfnSetProcTable ); - - /* Although WGL allows different dispatch entrypoints per - */ - if (!cpt_initialized) { - init_proc_table( &cpt ); - cpt_initialized = TRUE; - } - + PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt; + if (!stw_make_current( hdc, dhglrc )) - return NULL; + r = NULL; - return &cpt; + if (DBG) + debug_printf( "%s( 0x%p, %u, 0x%p ) = %p\n", + __FUNCTION__, hdc, dhglrc, pfnSetProcTable, r ); + + return r; } int APIENTRY @@ -571,7 +580,7 @@ DrvShareLists( if (DBG) debug_printf( "%s\n", __FUNCTION__ ); - return FALSE; + return stw_share_lists(dhglrc1, dhglrc2); } BOOL APIENTRY @@ -592,7 +601,7 @@ DrvSwapLayerBuffers( if (DBG) debug_printf( "%s\n", __FUNCTION__ ); - return FALSE; + return stw_swap_layer_buffers( hdc, fuPlanes ); } BOOL APIENTRY diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.h b/src/gallium/state_trackers/wgl/icd/stw_icd.h index 8e676fb5b7..cbc1a66548 100644 --- a/src/gallium/state_trackers/wgl/icd/stw_icd.h +++ b/src/gallium/state_trackers/wgl/icd/stw_icd.h @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef DRV_H -#define DRV_H +#ifndef STW_ICD_H +#define STW_ICD_H #include <windows.h> @@ -486,4 +486,4 @@ BOOL APIENTRY DrvValidateVersion( ULONG ulVersion ); -#endif /* DRV_H */ +#endif /* STW_ICD_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h b/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h deleted file mode 100644 index a0e4c5d98e..0000000000 --- a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.h +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef WGL_ARBEXTENSIONSSTRING_H -#define WGL_ARBEXTENSIONSSTRING_H - -WINGDIAPI const char * APIENTRY -wglGetExtensionsStringARB( - HDC hdc ); - -#endif /* WGL_ARBEXTENSIONSSTRING_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c index f563635420..0e2d407699 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c +++ b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c @@ -25,75 +25,30 @@ * **************************************************************************/ +/** + * @file + * + * WGL_ARB_pixel_format extension implementation. + * + * @sa http://www.opengl.org/registry/specs/ARB/wgl_pixel_format.txt + */ + + #include <windows.h> +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + #include "pipe/p_compiler.h" #include "util/u_memory.h" #include "stw_public.h" #include "stw_pixelformat.h" -#include "stw_arbpixelformat.h" - -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 - -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 - -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A - -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C - -/* From arb_multisample: - */ -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 static boolean -query_attrib( +stw_query_attrib( int iPixelFormat, int iLayerPlane, int attrib, @@ -101,9 +56,9 @@ query_attrib( { uint count; uint index; - const struct pixelformat_info *pf; + const struct stw_pixelformat_info *pfi; - count = pixelformat_get_extended_count(); + count = stw_pixelformat_get_extended_count(); if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) { *pvalue = (int) count; @@ -114,30 +69,27 @@ query_attrib( if (index >= count) return FALSE; - pf = pixelformat_get_info( index ); + pfi = stw_pixelformat_get_info( index ); switch (attrib) { case WGL_DRAW_TO_WINDOW_ARB: - *pvalue = TRUE; + *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_WINDOW ? TRUE : FALSE; return TRUE; case WGL_DRAW_TO_BITMAP_ARB: - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_DRAW_TO_BITMAP ? TRUE : FALSE; return TRUE; case WGL_NEED_PALETTE_ARB: - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_NEED_PALETTE ? TRUE : FALSE; return TRUE; case WGL_NEED_SYSTEM_PALETTE_ARB: - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_NEED_SYSTEM_PALETTE ? TRUE : FALSE; return TRUE; case WGL_SWAP_METHOD_ARB: - if (pf->flags & PF_FLAG_DOUBLEBUFFER) - *pvalue = WGL_SWAP_COPY_ARB; - else - *pvalue = WGL_SWAP_UNDEFINED_ARB; + *pvalue = pfi->pfd.dwFlags & PFD_SWAP_COPY ? WGL_SWAP_COPY_ARB : WGL_SWAP_UNDEFINED_ARB; return TRUE; case WGL_SWAP_LAYER_BUFFERS_ARB: @@ -179,96 +131,108 @@ query_attrib( break; case WGL_SUPPORT_GDI_ARB: - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_GDI ? TRUE : FALSE; break; case WGL_SUPPORT_OPENGL_ARB: - *pvalue = TRUE; + *pvalue = pfi->pfd.dwFlags & PFD_SUPPORT_OPENGL ? TRUE : FALSE; break; case WGL_DOUBLE_BUFFER_ARB: - if (pf->flags & PF_FLAG_DOUBLEBUFFER) - *pvalue = TRUE; - else - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_DOUBLEBUFFER ? TRUE : FALSE; break; case WGL_STEREO_ARB: - *pvalue = FALSE; + *pvalue = pfi->pfd.dwFlags & PFD_STEREO ? TRUE : FALSE; break; case WGL_PIXEL_TYPE_ARB: - *pvalue = WGL_TYPE_RGBA_ARB; + switch (pfi->pfd.iPixelType) { + case PFD_TYPE_RGBA: + *pvalue = WGL_TYPE_RGBA_ARB; + break; + case PFD_TYPE_COLORINDEX: + *pvalue = WGL_TYPE_COLORINDEX_ARB; + break; + default: + return FALSE; + } break; case WGL_COLOR_BITS_ARB: - *pvalue = (int) (pf->color.redbits + pf->color.greenbits + pf->color.bluebits); + *pvalue = pfi->pfd.cColorBits; break; case WGL_RED_BITS_ARB: - *pvalue = (int) pf->color.redbits; + *pvalue = pfi->pfd.cRedBits; break; case WGL_RED_SHIFT_ARB: - *pvalue = (int) pf->color.redshift; + *pvalue = pfi->pfd.cRedShift; break; case WGL_GREEN_BITS_ARB: - *pvalue = (int) pf->color.greenbits; + *pvalue = pfi->pfd.cGreenBits; break; case WGL_GREEN_SHIFT_ARB: - *pvalue = (int) pf->color.greenshift; + *pvalue = pfi->pfd.cGreenShift; break; case WGL_BLUE_BITS_ARB: - *pvalue = (int) pf->color.bluebits; + *pvalue = pfi->pfd.cBlueBits; break; case WGL_BLUE_SHIFT_ARB: - *pvalue = (int) pf->color.blueshift; + *pvalue = pfi->pfd.cBlueShift; break; case WGL_ALPHA_BITS_ARB: - *pvalue = (int) pf->alpha.alphabits; + *pvalue = pfi->pfd.cAlphaBits; break; case WGL_ALPHA_SHIFT_ARB: - *pvalue = (int) pf->alpha.alphashift; + *pvalue = pfi->pfd.cAlphaShift; break; case WGL_ACCUM_BITS_ARB: + *pvalue = pfi->pfd.cAccumBits; + break; + case WGL_ACCUM_RED_BITS_ARB: + *pvalue = pfi->pfd.cAccumRedBits; + break; + case WGL_ACCUM_GREEN_BITS_ARB: + *pvalue = pfi->pfd.cAccumGreenBits; + break; + case WGL_ACCUM_BLUE_BITS_ARB: + *pvalue = pfi->pfd.cAccumBlueBits; + break; + case WGL_ACCUM_ALPHA_BITS_ARB: - *pvalue = 0; + *pvalue = pfi->pfd.cAccumAlphaBits; break; case WGL_DEPTH_BITS_ARB: - *pvalue = (int) pf->depth.depthbits; + *pvalue = pfi->pfd.cDepthBits; break; case WGL_STENCIL_BITS_ARB: - *pvalue = (int) pf->depth.stencilbits; + *pvalue = pfi->pfd.cStencilBits; break; case WGL_AUX_BUFFERS_ARB: - *pvalue = 0; + *pvalue = pfi->pfd.cAuxBuffers; break; case WGL_SAMPLE_BUFFERS_ARB: - if (pf->flags & PF_FLAG_MULTISAMPLED) - *pvalue = stw_query_sample_buffers(); - else - *pvalue = 0; + *pvalue = pfi->numSampleBuffers; break; case WGL_SAMPLES_ARB: - if (pf->flags & PF_FLAG_MULTISAMPLED) - *pvalue = stw_query_samples(); - else - *pvalue = 0; + *pvalue = pfi->numSamples; break; default: @@ -285,7 +249,7 @@ struct attrib_match_info BOOL exact; }; -static struct attrib_match_info attrib_match[] = { +static const struct attrib_match_info attrib_match[] = { /* WGL_ARB_pixel_format */ { WGL_DRAW_TO_WINDOW_ARB, 0, TRUE }, @@ -324,7 +288,7 @@ static struct attrib_match_info attrib_match[] = { { WGL_SAMPLES_ARB, 2, FALSE } }; -struct pixelformat_score +struct stw_pixelformat_score { int points; uint index; @@ -332,13 +296,13 @@ struct pixelformat_score static BOOL score_pixelformats( - struct pixelformat_score *scores, + struct stw_pixelformat_score *scores, uint count, int attribute, int expected_value ) { uint i; - struct attrib_match_info *ami = NULL; + const struct attrib_match_info *ami = NULL; uint index; /* Find out if a given attribute should be considered for score calculation. @@ -358,7 +322,7 @@ score_pixelformats( for (index = 0; index < count; index++) { int actual_value; - if (!query_attrib( index + 1, 0, attribute, &actual_value )) + if (!stw_query_attrib( index + 1, 0, attribute, &actual_value )) return FALSE; if (ami->exact) { @@ -395,7 +359,7 @@ wglChoosePixelFormatARB( UINT *nNumFormats ) { uint count; - struct pixelformat_score *scores; + struct stw_pixelformat_score *scores; uint i; *nNumFormats = 0; @@ -405,8 +369,8 @@ wglChoosePixelFormatARB( * points for a mismatch when the match does not have to be exact. * Set a score to 0 if there is a mismatch for an exact match criteria. */ - count = pixelformat_get_extended_count(); - scores = (struct pixelformat_score *) MALLOC( count * sizeof( struct pixelformat_score ) ); + count = stw_pixelformat_get_extended_count(); + scores = (struct stw_pixelformat_score *) MALLOC( count * sizeof( struct stw_pixelformat_score ) ); if (scores == NULL) return FALSE; for (i = 0; i < count; i++) { @@ -446,7 +410,7 @@ wglChoosePixelFormatARB( swapped = FALSE; for (i = 1; i < n; i++) { if (scores[i - 1].points < scores[i].points) { - struct pixelformat_score score = scores[i - 1]; + struct stw_pixelformat_score score = scores[i - 1]; scores[i - 1] = scores[i]; scores[i] = score; @@ -489,7 +453,7 @@ wglGetPixelFormatAttribfvARB( for (i = 0; i < nAttributes; i++) { int value; - if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value )) + if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value )) return FALSE; pfValues[i] = (FLOAT) value; } @@ -511,7 +475,7 @@ wglGetPixelFormatAttribivARB( (void) hdc; for (i = 0; i < nAttributes; i++) { - if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] )) + if (!stw_query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] )) return FALSE; } diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h b/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h deleted file mode 100644 index a6c4259942..0000000000 --- a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.h +++ /dev/null @@ -1,61 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#ifndef WGL_ARBPIXELFORMAT_H -#define WGL_ARBPIXELFORMAT_H - - -/* Extension functions for get_proc_address: - */ -WINGDIAPI BOOL APIENTRY -wglChoosePixelFormatARB( - HDC hdc, - const int *piAttribIList, - const FLOAT *pfAttribFList, - UINT nMaxFormats, - int *piFormats, - UINT *nNumFormats ); - -WINGDIAPI BOOL APIENTRY -wglGetPixelFormatAttribfvARB( - HDC hdc, - int iPixelFormat, - int iLayerPlane, - UINT nAttributes, - const int *piAttributes, - FLOAT *pfValues ); - -WINGDIAPI BOOL APIENTRY -wglGetPixelFormatAttribivARB( - HDC hdc, - int iPixelFormat, - int iLayerPlane, - UINT nAttributes, - const int *piAttributes, - int *piValues ); - -#endif /* WGL_ARBPIXELFORMAT_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c index f890225242..662b5fbcd2 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_context.c +++ b/src/gallium/state_trackers/wgl/shared/stw_context.c @@ -59,11 +59,12 @@ stw_copy_context( pipe_mutex_lock( stw_dev->mutex ); - src = stw_lookup_context( hglrcSrc ); - dst = stw_lookup_context( hglrcDst ); + src = stw_lookup_context_locked( hglrcSrc ); + dst = stw_lookup_context_locked( hglrcDst ); if (src && dst) { /* FIXME */ + assert(0); (void) src; (void) dst; (void) mask; @@ -74,58 +75,61 @@ stw_copy_context( return ret; } +BOOL +stw_share_lists( + UINT_PTR hglrc1, + UINT_PTR hglrc2 ) +{ + struct stw_context *ctx1; + struct stw_context *ctx2; + BOOL ret = FALSE; + + pipe_mutex_lock( stw_dev->mutex ); + + ctx1 = stw_lookup_context_locked( hglrc1 ); + ctx2 = stw_lookup_context_locked( hglrc2 ); + + if (ctx1 && ctx2 && + ctx1->iPixelFormat == ctx2->iPixelFormat) { + ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx); + } + + pipe_mutex_unlock( stw_dev->mutex ); + + return ret; +} + UINT_PTR stw_create_layer_context( HDC hdc, int iLayerPlane ) { - uint pfi; - const struct pixelformat_info *pf = NULL; + int iPixelFormat; + const struct stw_pixelformat_info *pfi; + GLvisual visual; struct stw_context *ctx = NULL; - GLvisual *visual = NULL; struct pipe_screen *screen = NULL; struct pipe_context *pipe = NULL; - UINT_PTR hglrc = 0; - + if(!stw_dev) return 0; if (iLayerPlane != 0) return 0; - pfi = stw_pixelformat_get( hdc ); - if (pfi == 0) + iPixelFormat = GetPixelFormat(hdc); + if(!iPixelFormat) return 0; - - pf = pixelformat_get_info( pfi - 1 ); - + + pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); + stw_pixelformat_visual(&visual, pfi); + ctx = CALLOC_STRUCT( stw_context ); if (ctx == NULL) - return 0; + goto no_ctx; ctx->hdc = hdc; - ctx->color_bits = GetDeviceCaps( ctx->hdc, BITSPIXEL ); - - /* Create visual based on flags - */ - visual = _mesa_create_visual( - GL_TRUE, - (pf->flags & PF_FLAG_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE, - GL_FALSE, - pf->color.redbits, - pf->color.greenbits, - pf->color.bluebits, - pf->alpha.alphabits, - 0, - pf->depth.depthbits, - pf->depth.stencilbits, - 0, - 0, - 0, - 0, - (pf->flags & PF_FLAG_MULTISAMPLED) ? stw_query_samples() : 0 ); - if (visual == NULL) - goto fail; + ctx->iPixelFormat = iPixelFormat; screen = stw_dev->screen; @@ -137,7 +141,7 @@ stw_create_layer_context( pipe = stw_dev->stw_winsys->create_context( screen ); if (pipe == NULL) - goto fail; + goto no_pipe; #ifdef DEBUG /* Wrap context */ @@ -145,34 +149,32 @@ stw_create_layer_context( pipe = trace_context_create(stw_dev->screen, pipe); #endif + /* pass to stw_flush_frontbuffer as context_private */ assert(!pipe->priv); pipe->priv = hdc; - ctx->st = st_create_context( pipe, visual, NULL ); + ctx->st = st_create_context( pipe, &visual, NULL ); if (ctx->st == NULL) - goto fail; + goto no_st_ctx; ctx->st->ctx->DriverCtx = ctx; pipe_mutex_lock( stw_dev->mutex ); - { - hglrc = handle_table_add(stw_dev->ctx_table, ctx); - } + ctx->hglrc = handle_table_add(stw_dev->ctx_table, ctx); pipe_mutex_unlock( stw_dev->mutex ); - - /* Success? - */ - if (hglrc != 0) - return hglrc; - -fail: - if (visual) - _mesa_destroy_visual( visual ); - - if (pipe) - pipe->destroy( pipe ); - - FREE( ctx ); + if (!ctx->hglrc) + goto no_hglrc; + + return ctx->hglrc; + +no_hglrc: + st_destroy_context(ctx->st); + goto no_pipe; /* st_context_destroy already destroys pipe */ +no_st_ctx: + pipe->destroy( pipe ); +no_pipe: + FREE(ctx); +no_ctx: return 0; } @@ -187,38 +189,24 @@ stw_delete_context( return FALSE; pipe_mutex_lock( stw_dev->mutex ); + ctx = stw_lookup_context_locked(hglrc); + handle_table_remove(stw_dev->ctx_table, hglrc); + pipe_mutex_unlock( stw_dev->mutex ); - ctx = stw_lookup_context(hglrc); if (ctx) { GLcontext *glctx = ctx->st->ctx; GET_CURRENT_CONTEXT( glcurctx ); - struct stw_framebuffer *fb; - /* Unbind current if deleting current context. - */ + /* Unbind current if deleting current context. */ if (glcurctx == glctx) st_make_current( NULL, NULL, NULL ); - fb = framebuffer_from_hdc( ctx->hdc ); - if (fb) - framebuffer_destroy( fb ); - - if (WindowFromDC( ctx->hdc ) != NULL) - ReleaseDC( WindowFromDC( ctx->hdc ), ctx->hdc ); - - pipe_mutex_lock(stw_dev->mutex); - { - st_destroy_context(ctx->st); - FREE(ctx); - handle_table_remove(stw_dev->ctx_table, hglrc); - } - pipe_mutex_unlock(stw_dev->mutex); + st_destroy_context(ctx->st); + FREE(ctx); ret = TRUE; } - pipe_mutex_unlock( stw_dev->mutex ); - return ret; } @@ -226,62 +214,69 @@ BOOL stw_release_context( UINT_PTR hglrc ) { - BOOL ret = FALSE; + struct stw_context *ctx; if (!stw_dev) - return ret; + return FALSE; pipe_mutex_lock( stw_dev->mutex ); - { - struct stw_context *ctx; - - /* XXX: The expectation is that ctx is the same context which is - * current for this thread. We should check that and return False - * if not the case. - */ - ctx = stw_lookup_context( hglrc ); - if (ctx == NULL) - goto done; + ctx = stw_lookup_context_locked( hglrc ); + pipe_mutex_unlock( stw_dev->mutex ); - if (stw_make_current( NULL, 0 ) == FALSE) - goto done; + if (!ctx) + return FALSE; + + /* The expectation is that ctx is the same context which is + * current for this thread. We should check that and return False + * if not the case. + */ + { + GLcontext *glctx = ctx->st->ctx; + GET_CURRENT_CONTEXT( glcurctx ); - ret = TRUE; + if (glcurctx != glctx) + return FALSE; } -done: - pipe_mutex_unlock( stw_dev->mutex ); - - return ret; -} -/* Find the width and height of the window named by hdc. - */ -static void -get_window_size( HDC hdc, GLuint *width, GLuint *height ) -{ - if (WindowFromDC( hdc )) { - RECT rect; + if (stw_make_current( NULL, 0 ) == FALSE) + return FALSE; - GetClientRect( WindowFromDC( hdc ), &rect ); - *width = rect.right - rect.left; - *height = rect.bottom - rect.top; - } - else { - *width = GetDeviceCaps( hdc, HORZRES ); - *height = GetDeviceCaps( hdc, VERTRES ); - } + return TRUE; } + UINT_PTR stw_get_current_context( void ) { - return stw_tls_get_data()->currentGLRC; + GET_CURRENT_CONTEXT( glcurctx ); + struct stw_context *ctx; + + if(!glcurctx) + return 0; + + ctx = (struct stw_context *)glcurctx->DriverCtx; + assert(ctx); + if(!ctx) + return 0; + + return ctx->hglrc; } HDC stw_get_current_dc( void ) { - return stw_tls_get_data()->currentDC; + GET_CURRENT_CONTEXT( glcurctx ); + struct stw_context *ctx; + + if(!glcurctx) + return NULL; + + ctx = (struct stw_context *)glcurctx->DriverCtx; + assert(ctx); + if(!ctx) + return NULL; + + return ctx->hdc; } BOOL @@ -292,64 +287,68 @@ stw_make_current( struct stw_context *ctx; GET_CURRENT_CONTEXT( glcurctx ); struct stw_framebuffer *fb; - GLuint width = 0; - GLuint height = 0; - struct stw_context *curctx; if (!stw_dev) - return FALSE; - - pipe_mutex_lock( stw_dev->mutex ); - ctx = stw_lookup_context( hglrc ); - pipe_mutex_unlock( stw_dev->mutex ); - - stw_tls_get_data()->currentDC = hdc; - stw_tls_get_data()->currentGLRC = hglrc; + goto fail; if (glcurctx != NULL) { + struct stw_context *curctx; curctx = (struct stw_context *) glcurctx->DriverCtx; - if (curctx != ctx) + if (curctx->hglrc != hglrc) st_flush(glcurctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* Return if already current. */ + if (curctx->hglrc == hglrc && curctx->hdc == hdc) + return TRUE; } if (hdc == NULL || hglrc == 0) { - st_make_current( NULL, NULL, NULL ); - return TRUE; + return st_make_current( NULL, NULL, NULL ); } - /* Return if already current. - */ - if (glcurctx != NULL) { - if (curctx != NULL && curctx == ctx && ctx->hdc == hdc) - return TRUE; - } + pipe_mutex_lock( stw_dev->mutex ); - fb = framebuffer_from_hdc( hdc ); + ctx = stw_lookup_context_locked( hglrc ); + if(!ctx) + goto fail; - if (hdc != NULL) - get_window_size( hdc, &width, &height ); + fb = stw_framebuffer_from_hdc_locked( hdc ); + if(!fb) { + /* Applications should call SetPixelFormat before creating a context, + * but not all do, and the opengl32 runtime seems to use a default pixel + * format in some cases, so we must create a framebuffer for those here + */ + int iPixelFormat = GetPixelFormat(hdc); + if(iPixelFormat) + fb = stw_framebuffer_create_locked( hdc, iPixelFormat ); + if(!fb) + goto fail; + } + + pipe_mutex_unlock( stw_dev->mutex ); - /* Lazy creation of framebuffers. - */ - if (fb == NULL && ctx != NULL && hdc != NULL) { - GLvisual *visual = &ctx->st->ctx->Visual; + if(fb->iPixelFormat != ctx->iPixelFormat) + goto fail; - fb = framebuffer_create( hdc, visual, width, height ); - if (fb == NULL) - return FALSE; - } + /* Lazy allocation of the frame buffer */ + if(!stw_framebuffer_allocate(fb)) + goto fail; - if (ctx && fb) { - st_make_current( ctx->st, fb->stfb, fb->stfb ); - framebuffer_resize( fb, width, height ); - ctx->hdc = hdc; - ctx->st->pipe->priv = hdc; - } - else { - /* Detach */ - st_make_current( NULL, NULL, NULL ); - } + /* Bind the new framebuffer */ + ctx->hdc = hdc; + + /* pass to stw_flush_frontbuffer as context_private */ + ctx->st->pipe->priv = hdc; + + if(!st_make_current( ctx->st, fb->stfb, fb->stfb )) + goto fail; + stw_framebuffer_resize(fb); + return TRUE; + +fail: + st_make_current( NULL, NULL, NULL ); + return FALSE; } diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.h b/src/gallium/state_trackers/wgl/shared/stw_context.h index b289615272..166471de5e 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_context.h +++ b/src/gallium/state_trackers/wgl/shared/stw_context.h @@ -35,8 +35,9 @@ struct st_context; struct stw_context { struct st_context *st; + UINT_PTR hglrc; + int iPixelFormat; HDC hdc; - DWORD color_bits; }; #endif /* STW_CONTEXT_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/shared/stw_device.c index 51936c2bdd..1a6b29807d 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_device.c +++ b/src/gallium/state_trackers/wgl/shared/stw_device.c @@ -41,6 +41,7 @@ #include "shared/stw_pixelformat.h" #include "shared/stw_public.h" #include "shared/stw_tls.h" +#include "shared/stw_framebuffer.h" #ifdef WIN32_THREADS extern _glthread_Mutex OneTimeLock; @@ -56,7 +57,7 @@ struct stw_device *stw_dev = NULL; * stw_winsys::flush_front_buffer. */ static void -st_flush_frontbuffer(struct pipe_screen *screen, +stw_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surface, void *context_private ) { @@ -75,7 +76,7 @@ st_flush_frontbuffer(struct pipe_screen *screen, boolean -st_init(const struct stw_winsys *stw_winsys) +stw_init(const struct stw_winsys *stw_winsys) { static struct stw_device stw_dev_storage; struct pipe_screen *screen; @@ -110,7 +111,7 @@ st_init(const struct stw_winsys *stw_winsys) stw_dev->screen = screen; #endif - stw_dev->screen->flush_frontbuffer = st_flush_frontbuffer; + stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer; pipe_mutex_init( stw_dev->mutex ); @@ -119,7 +120,7 @@ st_init(const struct stw_winsys *stw_winsys) goto error1; } - pixelformat_init(); + stw_pixelformat_init(); return TRUE; @@ -130,25 +131,28 @@ error1: boolean -st_init_thread(void) +stw_init_thread(void) { - if (!stw_tls_init_thread()) { + if (!stw_tls_init_thread()) + return FALSE; + + if (!stw_framebuffer_init_thread()) return FALSE; - } return TRUE; } void -st_cleanup_thread(void) +stw_cleanup_thread(void) { + stw_framebuffer_cleanup_thread(); stw_tls_cleanup_thread(); } void -st_cleanup(void) +stw_cleanup(void) { unsigned i; @@ -169,6 +173,8 @@ st_cleanup(void) } pipe_mutex_unlock( stw_dev->mutex ); + stw_framebuffer_cleanup(); + pipe_mutex_destroy( stw_dev->mutex ); stw_dev->screen->destroy(stw_dev->screen); @@ -189,7 +195,7 @@ st_cleanup(void) struct stw_context * -stw_lookup_context( UINT_PTR dhglrc ) +stw_lookup_context_locked( UINT_PTR dhglrc ) { if (dhglrc == 0) return NULL; diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.h b/src/gallium/state_trackers/wgl/shared/stw_device.h index 703cb67081..e097f1f71e 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_device.h +++ b/src/gallium/state_trackers/wgl/shared/stw_device.h @@ -29,12 +29,19 @@ #define STW_DEVICE_H_ +#include <windows.h> + #include "pipe/p_compiler.h" #include "pipe/p_thread.h" #include "util/u_handle_table.h" +#include "stw_pixelformat.h" + + +#define STW_MAX_PIXELFORMATS 256 struct pipe_screen; +struct stw_framebuffer; struct stw_device { @@ -45,18 +52,24 @@ struct stw_device #ifdef DEBUG boolean trace_running; #endif - + + struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS]; + unsigned pixelformat_count; + unsigned pixelformat_extended_count; + pipe_mutex mutex; struct handle_table *ctx_table; + struct stw_framebuffer *fb_head; + #ifdef DEBUG unsigned long memdbg_no; #endif }; struct stw_context * -stw_lookup_context( UINT_PTR hglrc ); +stw_lookup_context_locked( UINT_PTR hglrc ); extern struct stw_device *stw_dev; diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.c b/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c index b3934cb464..2660c591f9 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_arbextensionsstring.c +++ b/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c @@ -1,5 +1,6 @@ /************************************************************************** * + * Copyright 2009 VMware, Inc. * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. * @@ -27,7 +28,18 @@ #include <windows.h> -#include "stw_arbextensionsstring.h" +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + + +static const char *stw_extension_string = + "WGL_ARB_extensions_string " + "WGL_ARB_multisample " + "WGL_ARB_pixel_format " + "WGL_EXT_extensions_string"; + WINGDIAPI const char * APIENTRY wglGetExtensionsStringARB( @@ -35,8 +47,12 @@ wglGetExtensionsStringARB( { (void) hdc; - return - "WGL_ARB_extensions_string " - "WGL_ARB_multisample " - "WGL_ARB_pixel_format"; + return stw_extension_string; +} + + +WINGDIAPI const char * APIENTRY +wglGetExtensionsStringEXT( void ) +{ + return stw_extension_string; } diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c index c96c4b8dfa..58f1830319 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c @@ -42,208 +42,329 @@ #include "stw_device.h" #include "stw_public.h" #include "stw_winsys.h" +#include "stw_tls.h" -void -framebuffer_resize( - struct stw_framebuffer *fb, - GLuint width, - GLuint height ) +static INLINE struct stw_framebuffer * +stw_framebuffer_from_hwnd_locked( + HWND hwnd ) +{ + struct stw_framebuffer *fb; + + for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next) + if (fb->hWnd == hwnd) + break; + + return fb; +} + + +static INLINE void +stw_framebuffer_destroy_locked( + struct stw_framebuffer *fb ) { - st_resize_framebuffer( fb->stfb, width, height ); + struct stw_framebuffer **link; + + link = &stw_dev->fb_head; + while (*link != fb) + link = &(*link)->next; + assert(*link); + *link = fb->next; + fb->next = NULL; + + st_unreference_framebuffer(fb->stfb); + + pipe_mutex_destroy( fb->mutex ); + + FREE( fb ); } -static struct stw_framebuffer *fb_head = NULL; +/** + * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx + * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx + */ static LRESULT CALLBACK -window_proc( - HWND hWnd, - UINT uMsg, +stw_call_window_proc( + int nCode, WPARAM wParam, LPARAM lParam ) { - struct stw_framebuffer *fb; - - for (fb = fb_head; fb != NULL; fb = fb->next) - if (fb->hWnd == hWnd) - break; - assert( fb != NULL ); + struct stw_tls_data *tls_data; + PCWPSTRUCT pParams = (PCWPSTRUCT)lParam; + + tls_data = stw_tls_get_data(); + if(!tls_data) + return 0; + + if (nCode < 0) + return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); + + if (pParams->message == WM_SIZE && pParams->wParam != SIZE_MINIMIZED) { + struct stw_framebuffer *fb; + + pipe_mutex_lock( stw_dev->mutex ); + fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd ); + pipe_mutex_unlock( stw_dev->mutex ); + + if(fb) { + unsigned width = LOWORD( pParams->lParam ); + unsigned height = HIWORD( pParams->lParam ); + + /* FIXME: The mesa statetracker makes the assumptions that only + * one context is using the framebuffer, and that that context is the + * current one. However neither holds true, as WGL allows more than + * one context to be bound to the same drawable, and this function can + * be called from any thread. + */ + pipe_mutex_lock( fb->mutex ); + if (fb->stfb) + st_resize_framebuffer( fb->stfb, width, height ); + pipe_mutex_unlock( fb->mutex ); + } + } - if (uMsg == WM_SIZE && wParam != SIZE_MINIMIZED) - framebuffer_resize( fb, LOWORD( lParam ), HIWORD( lParam ) ); + if (pParams->message == WM_DESTROY) { + struct stw_framebuffer *fb; - return CallWindowProc( fb->WndProc, hWnd, uMsg, wParam, lParam ); -} + pipe_mutex_lock( stw_dev->mutex ); + + fb = stw_framebuffer_from_hwnd_locked( pParams->hwnd ); + if(fb) + stw_framebuffer_destroy_locked(fb); + + pipe_mutex_unlock( stw_dev->mutex ); + } -static INLINE boolean -stw_is_supported_color(enum pipe_format format) -{ - struct pipe_screen *screen = stw_dev->screen; - return screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); + return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); } -static INLINE boolean -stw_is_supported_depth_stencil(enum pipe_format format) -{ - struct pipe_screen *screen = stw_dev->screen; - return screen->is_format_supported(screen, format, PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); -} -/* Create a new framebuffer object which will correspond to the given HDC. +/** + * Create a new framebuffer object which will correspond to the given HDC. */ struct stw_framebuffer * -framebuffer_create( +stw_framebuffer_create_locked( HDC hdc, - GLvisual *visual, - GLuint width, - GLuint height ) + int iPixelFormat ) { + HWND hWnd; struct stw_framebuffer *fb; - enum pipe_format colorFormat, depthFormat, stencilFormat; - - /* Determine PIPE_FORMATs for buffers. - */ + const struct stw_pixelformat_info *pfi; - if(visual->alphaBits <= 0 && visual->redBits <= 5 && visual->blueBits <= 6 && visual->greenBits <= 5 && - stw_is_supported_color(PIPE_FORMAT_R5G6B5_UNORM)) { - colorFormat = PIPE_FORMAT_R5G6B5_UNORM; - } - else if(visual->alphaBits <= 0 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 && - stw_is_supported_color(PIPE_FORMAT_X8R8G8B8_UNORM)) { - colorFormat = PIPE_FORMAT_X8R8G8B8_UNORM; - } - else if(visual->alphaBits <= 1 && visual->redBits <= 5 && visual->blueBits <= 5 && visual->greenBits <= 5 && - stw_is_supported_color(PIPE_FORMAT_A1R5G5B5_UNORM)) { - colorFormat = PIPE_FORMAT_A1R5G5B5_UNORM; - } - else if(visual->alphaBits <= 4 && visual->redBits <= 4 && visual->blueBits <= 4 && visual->greenBits <= 4 && - stw_is_supported_color(PIPE_FORMAT_A4R4G4B4_UNORM)) { - colorFormat = PIPE_FORMAT_A4R4G4B4_UNORM; - } - else if(visual->alphaBits <= 8 && visual->redBits <= 8 && visual->blueBits <= 8 && visual->greenBits <= 8 && - stw_is_supported_color(PIPE_FORMAT_A8R8G8B8_UNORM)) { - colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; - } - else { - assert(0); + /* We only support drawing to a window. */ + hWnd = WindowFromDC( hdc ); + if(!hWnd) + return NULL; + + fb = CALLOC_STRUCT( stw_framebuffer ); + if (fb == NULL) return NULL; - } - if (visual->depthBits == 0) - depthFormat = PIPE_FORMAT_NONE; - else if (visual->depthBits <= 16 && - stw_is_supported_depth_stencil(PIPE_FORMAT_Z16_UNORM)) - depthFormat = PIPE_FORMAT_Z16_UNORM; - else if (visual->depthBits <= 24 && visual->stencilBits != 8 && - stw_is_supported_depth_stencil(PIPE_FORMAT_X8Z24_UNORM)) { - depthFormat = PIPE_FORMAT_X8Z24_UNORM; - } - else if (visual->depthBits <= 24 && visual->stencilBits != 8 && - stw_is_supported_depth_stencil(PIPE_FORMAT_Z24X8_UNORM)) { - depthFormat = PIPE_FORMAT_Z24X8_UNORM; - } - else if (visual->depthBits <= 24 && visual->stencilBits == 8 && - stw_is_supported_depth_stencil(PIPE_FORMAT_S8Z24_UNORM)) { - depthFormat = PIPE_FORMAT_S8Z24_UNORM; - } - else if (visual->depthBits <= 24 && visual->stencilBits == 8 && - stw_is_supported_depth_stencil(PIPE_FORMAT_Z24S8_UNORM)) { - depthFormat = PIPE_FORMAT_Z24S8_UNORM; - } - else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_UNORM)) { - depthFormat = PIPE_FORMAT_Z32_UNORM; - } - else if(stw_is_supported_depth_stencil(PIPE_FORMAT_Z32_FLOAT)) { - depthFormat = PIPE_FORMAT_Z32_FLOAT; - } - else { - assert(0); - depthFormat = PIPE_FORMAT_NONE; - } + fb->hDC = hdc; + fb->hWnd = hWnd; + fb->iPixelFormat = iPixelFormat; - if (depthFormat == PIPE_FORMAT_S8Z24_UNORM || - depthFormat == PIPE_FORMAT_Z24S8_UNORM) { - stencilFormat = depthFormat; - } - else if (visual->stencilBits == 8 && - stw_is_supported_depth_stencil(PIPE_FORMAT_S8_UNORM)) { - stencilFormat = PIPE_FORMAT_S8_UNORM; + fb->pfi = pfi = stw_pixelformat_get_info( iPixelFormat - 1 ); + + stw_pixelformat_visual(&fb->visual, pfi); + + pipe_mutex_init( fb->mutex ); + + fb->next = stw_dev->fb_head; + stw_dev->fb_head = fb; + + return fb; +} + + +static void +stw_framebuffer_get_size( struct stw_framebuffer *fb, GLuint *pwidth, GLuint *pheight ) +{ + GLuint width, height; + + if (fb->hWnd) { + RECT rect; + GetClientRect( fb->hWnd, &rect ); + width = rect.right - rect.left; + height = rect.bottom - rect.top; } else { - stencilFormat = PIPE_FORMAT_NONE; + width = GetDeviceCaps( fb->hDC, HORZRES ); + height = GetDeviceCaps( fb->hDC, VERTRES ); } - fb = CALLOC_STRUCT( stw_framebuffer ); - if (fb == NULL) - return NULL; + if(width < 1) + width = 1; + if(height < 1) + height = 1; - fb->stfb = st_create_framebuffer( - visual, - colorFormat, - depthFormat, - stencilFormat, - width, - height, - (void *) fb ); + *pwidth = width; + *pheight = height; +} - fb->cColorBits = GetDeviceCaps( hdc, BITSPIXEL ); - fb->hDC = hdc; - /* Subclass a window associated with the device context. - */ - fb->hWnd = WindowFromDC( hdc ); - if (fb->hWnd != NULL) { - fb->WndProc = (WNDPROC) SetWindowLongPtr( - fb->hWnd, - GWLP_WNDPROC, - (LONG_PTR) window_proc ); +BOOL +stw_framebuffer_allocate( + struct stw_framebuffer *fb) +{ + pipe_mutex_lock( fb->mutex ); + + if(!fb->stfb) { + const struct stw_pixelformat_info *pfi = fb->pfi; + enum pipe_format colorFormat, depthFormat, stencilFormat; + GLuint width, height; + + colorFormat = pfi->color_format; + + assert(pf_layout( pfi->depth_stencil_format ) == PIPE_FORMAT_LAYOUT_RGBAZS ); + + if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_Z )) + depthFormat = pfi->depth_stencil_format; + else + depthFormat = PIPE_FORMAT_NONE; + + if(pf_get_component_bits( pfi->depth_stencil_format, PIPE_FORMAT_COMP_S )) + stencilFormat = pfi->depth_stencil_format; + else + stencilFormat = PIPE_FORMAT_NONE; + + stw_framebuffer_get_size(fb, &width, &height); + + fb->stfb = st_create_framebuffer( + &fb->visual, + colorFormat, + depthFormat, + stencilFormat, + width, + height, + (void *) fb ); } + + pipe_mutex_unlock( fb->mutex ); - fb->next = fb_head; - fb_head = fb; - return fb; + return fb->stfb ? TRUE : FALSE; } + void -framebuffer_destroy( - struct stw_framebuffer *fb ) +stw_framebuffer_resize( + struct stw_framebuffer *fb) { - struct stw_framebuffer **link = &fb_head; - struct stw_framebuffer *pfb = fb_head; - - while (pfb != NULL) { - if (pfb == fb) { - if (fb->hWnd != NULL) { - SetWindowLongPtr( - fb->hWnd, - GWLP_WNDPROC, - (LONG_PTR) fb->WndProc ); - } - - *link = fb->next; - FREE( fb ); - return; - } + GLuint width, height; + assert(fb->stfb); + stw_framebuffer_get_size(fb, &width, &height); + st_resize_framebuffer(fb->stfb, width, height); +} + + +void +stw_framebuffer_cleanup( void ) +{ + struct stw_framebuffer *fb; + struct stw_framebuffer *next; + + pipe_mutex_lock( stw_dev->mutex ); - link = &pfb->next; - pfb = pfb->next; + fb = stw_dev->fb_head; + while (fb) { + next = fb->next; + stw_framebuffer_destroy_locked(fb); + fb = next; } + stw_dev->fb_head = NULL; + + pipe_mutex_unlock( stw_dev->mutex ); } -/* Given an hdc, return the corresponding stw_framebuffer. + +/** + * Given an hdc, return the corresponding stw_framebuffer. */ struct stw_framebuffer * -framebuffer_from_hdc( +stw_framebuffer_from_hdc_locked( HDC hdc ) { struct stw_framebuffer *fb; - for (fb = fb_head; fb != NULL; fb = fb->next) + for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next) if (fb->hDC == hdc) - return fb; - return NULL; + break; + + return fb; +} + + +/** + * Given an hdc, return the corresponding stw_framebuffer. + */ +struct stw_framebuffer * +stw_framebuffer_from_hdc( + HDC hdc ) +{ + struct stw_framebuffer *fb; + + pipe_mutex_lock( stw_dev->mutex ); + fb = stw_framebuffer_from_hdc_locked(hdc); + pipe_mutex_unlock( stw_dev->mutex ); + + return fb; +} + + +BOOL +stw_pixelformat_set( + HDC hdc, + int iPixelFormat ) +{ + uint count; + uint index; + struct stw_framebuffer *fb; + + index = (uint) iPixelFormat - 1; + count = stw_pixelformat_get_extended_count(); + if (index >= count) + return FALSE; + + pipe_mutex_lock( stw_dev->mutex ); + + fb = stw_framebuffer_from_hdc_locked(hdc); + if(fb) { + /* SetPixelFormat must be called only once */ + pipe_mutex_unlock( stw_dev->mutex ); + return FALSE; + } + + fb = stw_framebuffer_create_locked(hdc, iPixelFormat); + if(!fb) { + pipe_mutex_unlock( stw_dev->mutex ); + return FALSE; + } + + pipe_mutex_unlock( stw_dev->mutex ); + + /* Some applications mistakenly use the undocumented wglSetPixelFormat + * function instead of SetPixelFormat, so we call SetPixelFormat here to + * avoid opengl32.dll's wglCreateContext to fail */ + if (GetPixelFormat(hdc) == 0) { + SetPixelFormat(hdc, iPixelFormat, NULL); + } + + return TRUE; +} + + +int +stw_pixelformat_get( + HDC hdc ) +{ + struct stw_framebuffer *fb; + + fb = stw_framebuffer_from_hdc(hdc); + if(!fb) + return 0; + + return fb->iPixelFormat; } @@ -255,10 +376,15 @@ stw_swap_buffers( struct pipe_screen *screen; struct pipe_surface *surface; - fb = framebuffer_from_hdc( hdc ); + fb = stw_framebuffer_from_hdc( hdc ); if (fb == NULL) return FALSE; + if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) + return TRUE; + + pipe_mutex_lock( fb->mutex ); + /* If we're swapping the buffer associated with the current context * we have to flush any pending rendering commands first. */ @@ -266,9 +392,11 @@ stw_swap_buffers( screen = stw_dev->screen; - if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) + if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) { /* FIXME: this shouldn't happen, but does on glean */ + pipe_mutex_unlock( fb->mutex ); return FALSE; + } #ifdef DEBUG if(stw_dev->trace_running) { @@ -279,5 +407,54 @@ stw_swap_buffers( stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc ); + pipe_mutex_unlock( fb->mutex ); + return TRUE; } + + +BOOL +stw_swap_layer_buffers( + HDC hdc, + UINT fuPlanes ) +{ + if(fuPlanes & WGL_SWAP_MAIN_PLANE) + return stw_swap_buffers(hdc); + + return FALSE; +} + + +boolean +stw_framebuffer_init_thread(void) +{ + struct stw_tls_data *tls_data; + + tls_data = stw_tls_get_data(); + if(!tls_data) + return FALSE; + + tls_data->hCallWndProcHook = SetWindowsHookEx(WH_CALLWNDPROC, + stw_call_window_proc, + NULL, + GetCurrentThreadId()); + if(tls_data->hCallWndProcHook == NULL) + return FALSE; + + return TRUE; +} + +void +stw_framebuffer_cleanup_thread(void) +{ + struct stw_tls_data *tls_data; + + tls_data = stw_tls_get_data(); + if(!tls_data) + return; + + if(tls_data->hCallWndProcHook) { + UnhookWindowsHookEx(tls_data->hCallWndProcHook); + tls_data->hCallWndProcHook = NULL; + } +} diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h index 5abdf18997..e7fa51c3a8 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h +++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h @@ -28,39 +28,61 @@ #ifndef STW_FRAMEBUFFER_H #define STW_FRAMEBUFFER_H +#include <windows.h> + #include "main/mtypes.h" -/* Windows framebuffer, derived from gl_framebuffer. +#include "pipe/p_thread.h" + +struct stw_pixelformat_info; + +/** + * Windows framebuffer, derived from gl_framebuffer. */ struct stw_framebuffer { - struct st_framebuffer *stfb; HDC hDC; - BYTE cColorBits; HWND hWnd; - WNDPROC WndProc; + + int iPixelFormat; + const struct stw_pixelformat_info *pfi; + GLvisual visual; + + pipe_mutex mutex; + struct st_framebuffer *stfb; + + /** This is protected by stw_device::mutex, not the mutex above */ struct stw_framebuffer *next; }; struct stw_framebuffer * -framebuffer_create( +stw_framebuffer_create_locked( HDC hdc, - GLvisual *visual, - GLuint width, - GLuint height ); + int iPixelFormat ); -void -framebuffer_destroy( +BOOL +stw_framebuffer_allocate( struct stw_framebuffer *fb ); void -framebuffer_resize( - struct stw_framebuffer *fb, - GLuint width, - GLuint height ); +stw_framebuffer_resize( + struct stw_framebuffer *fb); + +void +stw_framebuffer_cleanup(void); + +struct stw_framebuffer * +stw_framebuffer_from_hdc_locked( + HDC hdc ); struct stw_framebuffer * -framebuffer_from_hdc( +stw_framebuffer_from_hdc( HDC hdc ); +boolean +stw_framebuffer_init_thread(void); + +void +stw_framebuffer_cleanup_thread(void); + #endif /* STW_FRAMEBUFFER_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c index ac2d6fc260..4070cbd5c0 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c +++ b/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c @@ -27,28 +27,34 @@ #include <windows.h> +#define WGL_WGLEXT_PROTOTYPES + +#include <GL/gl.h> +#include <GL/wglext.h> + #include "glapi/glapi.h" -#include "stw_arbextensionsstring.h" -#include "stw_arbpixelformat.h" #include "stw_public.h" -struct extension_entry +struct stw_extension_entry { const char *name; PROC proc; }; -#define EXTENTRY(P) { #P, (PROC) P } +#define STW_EXTENSION_ENTRY(P) { #P, (PROC) P } -static struct extension_entry extension_entries[] = { +static const struct stw_extension_entry stw_extension_entries[] = { /* WGL_ARB_extensions_string */ - EXTENTRY( wglGetExtensionsStringARB ), + STW_EXTENSION_ENTRY( wglGetExtensionsStringARB ), /* WGL_ARB_pixel_format */ - EXTENTRY( wglChoosePixelFormatARB ), - EXTENTRY( wglGetPixelFormatAttribfvARB ), - EXTENTRY( wglGetPixelFormatAttribivARB ), + STW_EXTENSION_ENTRY( wglChoosePixelFormatARB ), + STW_EXTENSION_ENTRY( wglGetPixelFormatAttribfvARB ), + STW_EXTENSION_ENTRY( wglGetPixelFormatAttribivARB ), + + /* WGL_EXT_extensions_string */ + STW_EXTENSION_ENTRY( wglGetExtensionsStringEXT ), { NULL, NULL } }; @@ -57,13 +63,13 @@ PROC stw_get_proc_address( LPCSTR lpszProc ) { - struct extension_entry *entry; + const struct stw_extension_entry *entry; - PROC p = (PROC) _glapi_get_proc_address( (const char *) lpszProc ); + PROC p = (PROC) _glapi_get_proc_address( lpszProc ); if (p) return p; - for (entry = extension_entries; entry->name; entry++) + for (entry = stw_extension_entries; entry->name; entry++) if (strcmp( lpszProc, entry->name ) == 0) return entry->proc; diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c index b216ca5c82..c296744838 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c @@ -25,113 +25,266 @@ * **************************************************************************/ +#include "main/mtypes.h" +#include "main/context.h" + +#include "pipe/p_format.h" +#include "pipe/p_defines.h" +#include "pipe/p_screen.h" + #include "util/u_debug.h" + +#include "stw_device.h" #include "stw_pixelformat.h" #include "stw_public.h" #include "stw_tls.h" -#define MAX_PIXELFORMATS 16 -static struct pixelformat_info pixelformats[MAX_PIXELFORMATS]; -static uint pixelformat_count = 0; -static uint pixelformat_extended_count = 0; +struct stw_pf_color_info +{ + enum pipe_format format; + struct { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + } bits; + struct { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + } shift; +}; + +struct stw_pf_depth_info +{ + enum pipe_format format; + struct { + unsigned char depth; + unsigned char stencil; + } bits; +}; + + +/* NOTE: order matters, since in otherwise equal circumstances the first + * format listed will get chosen */ + +static const struct stw_pf_color_info +stw_pf_color[] = { + /* no-alpha */ + { PIPE_FORMAT_X8R8G8B8_UNORM, { 8, 8, 8, 0}, {16, 8, 0, 0} }, + { PIPE_FORMAT_B8G8R8X8_UNORM, { 8, 8, 8, 0}, { 8, 16, 24, 0} }, + { PIPE_FORMAT_R5G6B5_UNORM, { 5, 6, 5, 0}, {11, 5, 0, 0} }, + /* alpha */ + { PIPE_FORMAT_A8R8G8B8_UNORM, { 8, 8, 8, 8}, {16, 8, 0, 24} }, + { PIPE_FORMAT_B8G8R8A8_UNORM, { 8, 8, 8, 8}, { 8, 16, 24, 0} }, +#if 0 + { PIPE_FORMAT_A2B10G10R10_UNORM, {10, 10, 10, 2}, { 0, 10, 20, 30} }, +#endif + { PIPE_FORMAT_A1R5G5B5_UNORM, { 5, 5, 5, 1}, {10, 5, 0, 15} }, + { PIPE_FORMAT_A4R4G4B4_UNORM, { 4, 4, 4, 4}, {16, 4, 0, 12} } +}; + + +static const struct stw_pf_depth_info +stw_pf_depth_stencil[] = { + /* pure depth */ + { PIPE_FORMAT_Z32_UNORM, {32, 0} }, + { PIPE_FORMAT_Z24X8_UNORM, {24, 0} }, + { PIPE_FORMAT_X8Z24_UNORM, {24, 0} }, + { PIPE_FORMAT_Z16_UNORM, {16, 0} }, + /* pure stencil */ + { PIPE_FORMAT_S8_UNORM, { 0, 8} }, + /* combined depth-stencil */ + { PIPE_FORMAT_S8Z24_UNORM, {24, 8} }, + { PIPE_FORMAT_Z24S8_UNORM, {24, 8} } +}; + + +static const boolean +stw_pf_doublebuffer[] = { + FALSE, + TRUE, +}; + + +const unsigned +stw_pf_multisample[] = { + 0, + 4 +}; static void -add_standard_pixelformats( - struct pixelformat_info **ppf, - uint flags ) +stw_pixelformat_add( + struct stw_device *stw_dev, + const struct stw_pf_color_info *color, + const struct stw_pf_depth_info *depth, + unsigned accum, + boolean doublebuffer, + unsigned samples ) { - struct pixelformat_info *pf = *ppf; - struct pixelformat_color_info color24 = { 8, 0, 8, 8, 8, 16 }; - struct pixelformat_alpha_info alpha8 = { 8, 24 }; - struct pixelformat_alpha_info noalpha = { 0, 0 }; - struct pixelformat_depth_info depth24s8 = { 24, 8 }; - struct pixelformat_depth_info depth16 = { 16, 0 }; - - pf->flags = PF_FLAG_DOUBLEBUFFER | flags; - pf->color = color24; - pf->alpha = alpha8; - pf->depth = depth16; - pf++; - - pf->flags = PF_FLAG_DOUBLEBUFFER | flags; - pf->color = color24; - pf->alpha = alpha8; - pf->depth = depth24s8; - pf++; - - pf->flags = PF_FLAG_DOUBLEBUFFER | flags; - pf->color = color24; - pf->alpha = noalpha; - pf->depth = depth16; - pf++; - - pf->flags = PF_FLAG_DOUBLEBUFFER | flags; - pf->color = color24; - pf->alpha = noalpha; - pf->depth = depth24s8; - pf++; - - pf->flags = flags; - pf->color = color24; - pf->alpha = alpha8; - pf->depth = depth16; - pf++; - - pf->flags = flags; - pf->color = color24; - pf->alpha = alpha8; - pf->depth = depth24s8; - pf++; - - pf->flags = flags; - pf->color = color24; - pf->alpha = noalpha; - pf->depth = depth16; - pf++; - - pf->flags = flags; - pf->color = color24; - pf->alpha = noalpha; - pf->depth = depth24s8; - pf++; - - *ppf = pf; + boolean extended = FALSE; + struct stw_pixelformat_info *pfi; + + assert(stw_dev->pixelformat_extended_count < STW_MAX_PIXELFORMATS); + if(stw_dev->pixelformat_extended_count >= STW_MAX_PIXELFORMATS) + return; + + assert(pf_layout( color->format ) == PIPE_FORMAT_LAYOUT_RGBAZS ); + assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_R ) == color->bits.red ); + assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_G ) == color->bits.green ); + assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_B ) == color->bits.blue ); + assert(pf_get_component_bits( color->format, PIPE_FORMAT_COMP_A ) == color->bits.alpha ); + assert(pf_layout( depth->format ) == PIPE_FORMAT_LAYOUT_RGBAZS ); + assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_Z ) == depth->bits.depth ); + assert(pf_get_component_bits( depth->format, PIPE_FORMAT_COMP_S ) == depth->bits.stencil ); + + pfi = &stw_dev->pixelformats[stw_dev->pixelformat_extended_count]; + + memset(pfi, 0, sizeof *pfi); + + pfi->color_format = color->format; + pfi->depth_stencil_format = depth->format; + + pfi->pfd.nSize = sizeof pfi->pfd; + pfi->pfd.nVersion = 1; + + pfi->pfd.dwFlags = PFD_SUPPORT_OPENGL; + + /* TODO: also support non-native pixel formats */ + pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW ; + + if (doublebuffer) + pfi->pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY; + + pfi->pfd.iPixelType = PFD_TYPE_RGBA; + + pfi->pfd.cColorBits = color->bits.red + color->bits.green + color->bits.blue + color->bits.alpha; + pfi->pfd.cRedBits = color->bits.red; + pfi->pfd.cRedShift = color->shift.red; + pfi->pfd.cGreenBits = color->bits.green; + pfi->pfd.cGreenShift = color->shift.green; + pfi->pfd.cBlueBits = color->bits.blue; + pfi->pfd.cBlueShift = color->shift.blue; + pfi->pfd.cAlphaBits = color->bits.alpha; + pfi->pfd.cAlphaShift = color->shift.alpha; + pfi->pfd.cAccumBits = 4*accum; + pfi->pfd.cAccumRedBits = accum; + pfi->pfd.cAccumGreenBits = accum; + pfi->pfd.cAccumBlueBits = accum; + pfi->pfd.cAccumAlphaBits = accum; + pfi->pfd.cDepthBits = depth->bits.depth; + pfi->pfd.cStencilBits = depth->bits.stencil; + pfi->pfd.cAuxBuffers = 0; + pfi->pfd.iLayerType = 0; + pfi->pfd.bReserved = 0; + pfi->pfd.dwLayerMask = 0; + pfi->pfd.dwVisibleMask = 0; + pfi->pfd.dwDamageMask = 0; + + if(samples) { + pfi->numSampleBuffers = 1; + pfi->numSamples = samples; + extended = TRUE; + } + + ++stw_dev->pixelformat_extended_count; + + if(!extended) { + ++stw_dev->pixelformat_count; + assert(stw_dev->pixelformat_count == stw_dev->pixelformat_extended_count); + } } void -pixelformat_init( void ) +stw_pixelformat_init( void ) { - struct pixelformat_info *pf = pixelformats; - - add_standard_pixelformats( &pf, 0 ); - pixelformat_count = pf - pixelformats; - - add_standard_pixelformats( &pf, PF_FLAG_MULTISAMPLED ); - pixelformat_extended_count = pf - pixelformats; + struct pipe_screen *screen = stw_dev->screen; + unsigned i, j, k, l; + + assert( !stw_dev->pixelformat_count ); + assert( !stw_dev->pixelformat_extended_count ); + + for(i = 0; i < Elements(stw_pf_multisample); ++i) { + unsigned samples = stw_pf_multisample[i]; + + /* FIXME: re-enabled MSAA when we can query it */ + if(samples) + continue; - assert( pixelformat_extended_count <= MAX_PIXELFORMATS ); + for(j = 0; j < Elements(stw_pf_color); ++j) { + const struct stw_pf_color_info *color = &stw_pf_color[j]; + + if(!screen->is_format_supported(screen, color->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) + continue; + + for(k = 0; k < Elements(stw_pf_doublebuffer); ++k) { + unsigned doublebuffer = stw_pf_doublebuffer[k]; + + for(l = 0; l < Elements(stw_pf_depth_stencil); ++l) { + const struct stw_pf_depth_info *depth = &stw_pf_depth_stencil[l]; + + if(!screen->is_format_supported(screen, depth->format, PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) + continue; + + stw_pixelformat_add( stw_dev, color, depth, 0, doublebuffer, samples ); + stw_pixelformat_add( stw_dev, color, depth, 16, doublebuffer, samples ); + } + } + } + } + + assert( stw_dev->pixelformat_count <= stw_dev->pixelformat_extended_count ); + assert( stw_dev->pixelformat_extended_count <= STW_MAX_PIXELFORMATS ); } uint -pixelformat_get_count( void ) +stw_pixelformat_get_count( void ) { - return pixelformat_count; + return stw_dev->pixelformat_count; } uint -pixelformat_get_extended_count( void ) +stw_pixelformat_get_extended_count( void ) { - return pixelformat_extended_count; + return stw_dev->pixelformat_extended_count; } -const struct pixelformat_info * -pixelformat_get_info( uint index ) +const struct stw_pixelformat_info * +stw_pixelformat_get_info( uint index ) { - assert( index < pixelformat_extended_count ); + assert( index < stw_dev->pixelformat_extended_count ); + + return &stw_dev->pixelformats[index]; +} + - return &pixelformats[index]; +void +stw_pixelformat_visual(GLvisual *visual, + const struct stw_pixelformat_info *pfi ) +{ + memset(visual, 0, sizeof *visual); + _mesa_initialize_visual( + visual, + (pfi->pfd.iPixelType == PFD_TYPE_RGBA) ? GL_TRUE : GL_FALSE, + (pfi->pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE, + (pfi->pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE, + pfi->pfd.cRedBits, + pfi->pfd.cGreenBits, + pfi->pfd.cBlueBits, + pfi->pfd.cAlphaBits, + (pfi->pfd.iPixelType == PFD_TYPE_COLORINDEX) ? pfi->pfd.cColorBits : 0, + pfi->pfd.cDepthBits, + pfi->pfd.cStencilBits, + pfi->pfd.cAccumRedBits, + pfi->pfd.cAccumGreenBits, + pfi->pfd.cAccumBlueBits, + pfi->pfd.cAccumAlphaBits, + pfi->numSamples ); } @@ -144,11 +297,11 @@ stw_pixelformat_describe( { uint count; uint index; - const struct pixelformat_info *pf; + const struct stw_pixelformat_info *pfi; (void) hdc; - count = pixelformat_get_extended_count(); + count = stw_pixelformat_get_extended_count(); index = (uint) iPixelFormat - 1; if (ppfd == NULL) @@ -156,36 +309,9 @@ stw_pixelformat_describe( if (index >= count || nBytes != sizeof( PIXELFORMATDESCRIPTOR )) return 0; - pf = pixelformat_get_info( index ); - - ppfd->nSize = sizeof( PIXELFORMATDESCRIPTOR ); - ppfd->nVersion = 1; - ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - if (pf->flags & PF_FLAG_DOUBLEBUFFER) - ppfd->dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY; - ppfd->iPixelType = PFD_TYPE_RGBA; - ppfd->cColorBits = pf->color.redbits + pf->color.greenbits + pf->color.bluebits; - ppfd->cRedBits = pf->color.redbits; - ppfd->cRedShift = pf->color.redshift; - ppfd->cGreenBits = pf->color.greenbits; - ppfd->cGreenShift = pf->color.greenshift; - ppfd->cBlueBits = pf->color.bluebits; - ppfd->cBlueShift = pf->color.blueshift; - ppfd->cAlphaBits = pf->alpha.alphabits; - ppfd->cAlphaShift = pf->alpha.alphashift; - ppfd->cAccumBits = 0; - ppfd->cAccumRedBits = 0; - ppfd->cAccumGreenBits = 0; - ppfd->cAccumBlueBits = 0; - ppfd->cAccumAlphaBits = 0; - ppfd->cDepthBits = pf->depth.depthbits; - ppfd->cStencilBits = pf->depth.stencilbits; - ppfd->cAuxBuffers = 0; - ppfd->iLayerType = 0; - ppfd->bReserved = 0; - ppfd->dwLayerMask = 0; - ppfd->dwVisibleMask = 0; - ppfd->dwDamageMask = 0; + pfi = stw_pixelformat_get_info( index ); + + memcpy(ppfd, &pfi->pfd, sizeof( PIXELFORMATDESCRIPTOR )); return count; } @@ -203,29 +329,30 @@ int stw_pixelformat_choose( HDC hdc, (void) hdc; - count = pixelformat_get_count(); + count = stw_pixelformat_get_count(); bestindex = count; - bestdelta = 0xffffffff; + bestdelta = ~0U; for (index = 0; index < count; index++) { uint delta = 0; - const struct pixelformat_info *pf = pixelformat_get_info( index ); + const struct stw_pixelformat_info *pfi = stw_pixelformat_get_info( index ); if (!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) && !!(ppfd->dwFlags & PFD_DOUBLEBUFFER) != - !!(pf->flags & PF_FLAG_DOUBLEBUFFER)) + !!(pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) continue; - if (ppfd->cColorBits != pf->color.redbits + pf->color.greenbits + pf->color.bluebits) + /* FIXME: Take in account individual channel bits */ + if (ppfd->cColorBits != pfi->pfd.cColorBits) delta += 8; - if (ppfd->cDepthBits != pf->depth.depthbits) + if (ppfd->cDepthBits != pfi->pfd.cDepthBits) delta += 4; - if (ppfd->cStencilBits != pf->depth.stencilbits) + if (ppfd->cStencilBits != pfi->pfd.cStencilBits) delta += 2; - if (ppfd->cAlphaBits != pf->alpha.alphabits) + if (ppfd->cAlphaBits != pfi->pfd.cAlphaBits) delta++; if (delta < bestdelta) { @@ -241,57 +368,3 @@ int stw_pixelformat_choose( HDC hdc, return bestindex + 1; } - - -int -stw_pixelformat_get( - HDC hdc ) -{ - return stw_tls_get_data()->currentPixelFormat; -} - - -BOOL -stw_pixelformat_set( - HDC hdc, - int iPixelFormat ) -{ - uint count; - uint index; - - (void) hdc; - - index = (uint) iPixelFormat - 1; - count = pixelformat_get_extended_count(); - if (index >= count) - return FALSE; - - stw_tls_get_data()->currentPixelFormat = iPixelFormat; - - /* Some applications mistakenly use the undocumented wglSetPixelFormat - * function instead of SetPixelFormat, so we call SetPixelFormat here to - * avoid opengl32.dll's wglCreateContext to fail */ - if (GetPixelFormat(hdc) == 0) { - SetPixelFormat(hdc, iPixelFormat, NULL); - } - - return TRUE; -} - - - -/* XXX: this needs to be turned into queries on pipe_screen or - * stw_winsys. - */ -int -stw_query_sample_buffers( void ) -{ - return 1; -} - -int -stw_query_samples( void ) -{ - return 4; -} - diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h index 7ca4194a2a..bec429231b 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h +++ b/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h @@ -25,59 +25,41 @@ * **************************************************************************/ -#ifndef PIXELFORMAT_H -#define PIXELFORMAT_H +#ifndef STW_PIXELFORMAT_H +#define STW_PIXELFORMAT_H #include <windows.h> -#include "pipe/p_compiler.h" - -#define PF_FLAG_DOUBLEBUFFER 0x00000001 -#define PF_FLAG_MULTISAMPLED 0x00000002 - -struct pixelformat_color_info -{ - uint redbits; - uint redshift; - uint greenbits; - uint greenshift; - uint bluebits; - uint blueshift; -}; -struct pixelformat_alpha_info -{ - uint alphabits; - uint alphashift; -}; +#include "main/mtypes.h" -struct pixelformat_depth_info -{ - uint depthbits; - uint stencilbits; -}; +#include "pipe/p_compiler.h" +#include "pipe/p_format.h" -struct pixelformat_info +struct stw_pixelformat_info { - uint flags; - struct pixelformat_color_info color; - struct pixelformat_alpha_info alpha; - struct pixelformat_depth_info depth; + enum pipe_format color_format; + enum pipe_format depth_stencil_format; + + PIXELFORMATDESCRIPTOR pfd; + + unsigned numSampleBuffers; + unsigned numSamples; }; void -pixelformat_init( void ); +stw_pixelformat_init( void ); uint -pixelformat_get_count( void ); +stw_pixelformat_get_count( void ); uint -pixelformat_get_extended_count( void ); - -const struct pixelformat_info * -pixelformat_get_info( uint index ); +stw_pixelformat_get_extended_count( void ); -int stw_query_sample_buffers( void ); -int stw_query_samples( void ); +const struct stw_pixelformat_info * +stw_pixelformat_get_info( uint index ); +void +stw_pixelformat_visual(GLvisual *visual, + const struct stw_pixelformat_info *pfi ); -#endif /* PIXELFORMAT_H */ +#endif /* STW_PIXELFORMAT_H */ diff --git a/src/gallium/state_trackers/wgl/shared/stw_public.h b/src/gallium/state_trackers/wgl/shared/stw_public.h index 39d377c16b..7fe9cfb356 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_public.h +++ b/src/gallium/state_trackers/wgl/shared/stw_public.h @@ -37,6 +37,8 @@ BOOL stw_copy_context( UINT_PTR hglrcSrc, UINT_PTR stw_create_layer_context( HDC hdc, int iLayerPlane ); +BOOL stw_share_lists( UINT_PTR hglrc1, UINT_PTR hglrc2 ); + BOOL stw_delete_context( UINT_PTR hglrc ); BOOL @@ -50,6 +52,9 @@ BOOL stw_make_current( HDC hdc, UINT_PTR hglrc ); BOOL stw_swap_buffers( HDC hdc ); +BOOL +stw_swap_layer_buffers( HDC hdc, UINT fuPlanes ); + PROC stw_get_proc_address( LPCSTR lpszProc ); int stw_pixelformat_describe( HDC hdc, diff --git a/src/gallium/state_trackers/wgl/shared/stw_quirks.c b/src/gallium/state_trackers/wgl/shared/stw_quirks.c deleted file mode 100644 index 2f7091a52c..0000000000 --- a/src/gallium/state_trackers/wgl/shared/stw_quirks.c +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/** - * @file - * - * This is hopefully a temporary hack to define some needed dispatch - * table entries. Hopefully, I'll find a better solution. The - * dispatch table generation scripts ought to be making these dummy - * stubs as well. - */ - -void gl_dispatch_stub_543(void){} -void gl_dispatch_stub_544(void){} -void gl_dispatch_stub_545(void){} -void gl_dispatch_stub_546(void){} -void gl_dispatch_stub_547(void){} -void gl_dispatch_stub_548(void){} -void gl_dispatch_stub_549(void){} -void gl_dispatch_stub_550(void){} -void gl_dispatch_stub_551(void){} -void gl_dispatch_stub_552(void){} -void gl_dispatch_stub_553(void){} -void gl_dispatch_stub_554(void){} -void gl_dispatch_stub_555(void){} -void gl_dispatch_stub_556(void){} -void gl_dispatch_stub_557(void){} -void gl_dispatch_stub_558(void){} -void gl_dispatch_stub_559(void){} -void gl_dispatch_stub_560(void){} -void gl_dispatch_stub_561(void){} -void gl_dispatch_stub_565(void){} -void gl_dispatch_stub_566(void){} -void gl_dispatch_stub_570(void){} -void gl_dispatch_stub_577(void){} -void gl_dispatch_stub_578(void){} -void gl_dispatch_stub_582(void){} -void gl_dispatch_stub_603(void){} -void gl_dispatch_stub_607(void){} -void gl_dispatch_stub_645(void){} -void gl_dispatch_stub_646(void){} -void gl_dispatch_stub_647(void){} -void gl_dispatch_stub_648(void){} -void gl_dispatch_stub_649(void){} -void gl_dispatch_stub_650(void){} -void gl_dispatch_stub_651(void){} -void gl_dispatch_stub_652(void){} -void gl_dispatch_stub_653(void){} -void gl_dispatch_stub_657(void){} -void gl_dispatch_stub_733(void){} -void gl_dispatch_stub_734(void){} -void gl_dispatch_stub_735(void){} -void gl_dispatch_stub_736(void){} -void gl_dispatch_stub_737(void){} -void gl_dispatch_stub_738(void){} -void gl_dispatch_stub_744(void){} -void gl_dispatch_stub_745(void){} -void gl_dispatch_stub_746(void){} -void gl_dispatch_stub_760(void){} -void gl_dispatch_stub_761(void){} -void gl_dispatch_stub_763(void){} -void gl_dispatch_stub_764(void){} -void gl_dispatch_stub_765(void){} -void gl_dispatch_stub_766(void){} -void gl_dispatch_stub_767(void){} -void gl_dispatch_stub_768(void){} - -void gl_dispatch_stub_562(void){} -void gl_dispatch_stub_563(void){} -void gl_dispatch_stub_564(void){} -void gl_dispatch_stub_567(void){} -void gl_dispatch_stub_568(void){} -void gl_dispatch_stub_569(void){} -void gl_dispatch_stub_580(void){} -void gl_dispatch_stub_581(void){} -void gl_dispatch_stub_606(void){} -void gl_dispatch_stub_654(void){} -void gl_dispatch_stub_655(void){} -void gl_dispatch_stub_656(void){} -void gl_dispatch_stub_739(void){} -void gl_dispatch_stub_740(void){} -void gl_dispatch_stub_741(void){} -void gl_dispatch_stub_748(void){} -void gl_dispatch_stub_749(void){} -void gl_dispatch_stub_769(void){} -void gl_dispatch_stub_770(void){} -void gl_dispatch_stub_771(void){} -void gl_dispatch_stub_772(void){} -void gl_dispatch_stub_773(void){} -void gl_dispatch_stub_774(void){} -void gl_dispatch_stub_750(void){} -void gl_dispatch_stub_742(void){} diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.c b/src/gallium/state_trackers/wgl/shared/stw_tls.c index e72bafb880..0c18a52352 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_tls.c +++ b/src/gallium/state_trackers/wgl/shared/stw_tls.c @@ -44,6 +44,18 @@ stw_tls_init(void) return TRUE; } +static INLINE struct stw_tls_data * +stw_tls_data_create() +{ + struct stw_tls_data *data; + + data = CALLOC_STRUCT(stw_tls_data); + if (!data) + return NULL; + + return data; +} + boolean stw_tls_init_thread(void) { @@ -53,14 +65,9 @@ stw_tls_init_thread(void) return FALSE; } - data = MALLOC(sizeof(*data)); - if (!data) { + data = stw_tls_data_create(); + if(!data) return FALSE; - } - - data->currentPixelFormat = 0; - data->currentDC = NULL; - data->currentGLRC = 0; TlsSetValue(tlsIndex, data); @@ -93,9 +100,23 @@ stw_tls_cleanup(void) struct stw_tls_data * stw_tls_get_data(void) { + struct stw_tls_data *data; + if (tlsIndex == TLS_OUT_OF_INDEXES) { return NULL; } + + data = (struct stw_tls_data *) TlsGetValue(tlsIndex); + if(!data) { + /* DllMain is called with DLL_THREAD_ATTACH only by threads created after + * the DLL is loaded by the process */ + + data = stw_tls_data_create(); + if(!data) + return NULL; + + TlsSetValue(tlsIndex, data); + } - return (struct stw_tls_data *) TlsGetValue(tlsIndex); + return data; } diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.h b/src/gallium/state_trackers/wgl/shared/stw_tls.h index 23b61e68ff..6af8be70c9 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_tls.h +++ b/src/gallium/state_trackers/wgl/shared/stw_tls.h @@ -28,11 +28,11 @@ #ifndef STW_TLS_H #define STW_TLS_H +#include <windows.h> + struct stw_tls_data { - uint currentPixelFormat; - HDC currentDC; - UINT_PTR currentGLRC; + HHOOK hCallWndProcHook; }; boolean diff --git a/src/gallium/state_trackers/wgl/shared/stw_winsys.h b/src/gallium/state_trackers/wgl/shared/stw_winsys.h index e4a1d4f979..c0bf82c9ed 100644 --- a/src/gallium/state_trackers/wgl/shared/stw_winsys.h +++ b/src/gallium/state_trackers/wgl/shared/stw_winsys.h @@ -51,15 +51,15 @@ struct stw_winsys }; boolean -st_init(const struct stw_winsys *stw_winsys); +stw_init(const struct stw_winsys *stw_winsys); boolean -st_init_thread(void); +stw_init_thread(void); void -st_cleanup_thread(void); +stw_cleanup_thread(void); void -st_cleanup(void); +stw_cleanup(void); #endif /* STW_WINSYS_H */ diff --git a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/wgl/stw_wgl.c index e06d2640b4..a131292f7a 100644 --- a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c +++ b/src/gallium/state_trackers/wgl/wgl/stw_wgl.c @@ -100,10 +100,7 @@ wglSwapLayerBuffers( HDC hdc, UINT fuPlanes ) { - (void) hdc; - (void) fuPlanes; - - return FALSE; + return stw_swap_layer_buffers( hdc, fuPlanes ); } WINGDIAPI PROC APIENTRY @@ -189,12 +186,7 @@ wglShareLists( HGLRC hglrc1, HGLRC hglrc2 ) { - (void) hglrc1; - (void) hglrc2; - - assert( 0 ); - - return FALSE; + return stw_share_lists( (UINT_PTR)hglrc1, (UINT_PTR)hglrc2);; } WINGDIAPI BOOL APIENTRY diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index d04204e1bf..401bd39dac 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -28,6 +28,7 @@ * */ +#include "xorg-server.h" #include "xf86.h" #include "xf86_OSproc.h" @@ -85,7 +86,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) 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; @@ -98,7 +98,6 @@ driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) 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; diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c index 8a2711e70c..45e831f0c2 100644 --- a/src/gallium/state_trackers/xorg/xorg_driver.c +++ b/src/gallium/state_trackers/xorg/xorg_driver.c @@ -476,7 +476,7 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) } if (!ms->screen) { - ms->screen = drm_api_hooks.create_screen(ms->fd, ms->PciInfo->device_id); + ms->screen = drm_api_hooks.create_screen(ms->fd, NULL); if (!ms->screen) { FatalError("Could not init pipe_screen\n"); diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index 56c8fdccb2..7913174354 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -28,6 +28,7 @@ * */ +#include "xorg-server.h" #include "xf86.h" #include "xorg_tracker.h" @@ -36,6 +37,8 @@ #include "pipe/p_state.h" #include "pipe/p_inlines.h" +#include "util/u_rect.h" + struct exa_entity { ExaDriverPtr pExa; @@ -425,7 +428,6 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; - template.compressed = 0; exa_get_pipe_format(depth, &template.format, &bitsPerPixel); pf_get_block(template.format, &template.block); template.width[0] = width; @@ -436,6 +438,18 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, priv->tex = exa->scrn->texture_create(exa->scrn, &template); } + if (pPixData) { + struct pipe_transfer *transfer = + exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0, + PIPE_TRANSFER_WRITE, + 0, 0, width, height); + pipe_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer), + &priv->tex->block, transfer->stride, 0, 0, + width, height, pPixData, pPixmap->devKind, 0, 0); + exa->scrn->transfer_unmap(exa->scrn, transfer); + exa->scrn->tex_transfer_destroy(transfer); + } + return TRUE; } |