From ca69249f25e0cb89dbfc3d98b92e7386a3029efa Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 16 Mar 2010 09:47:18 +0800 Subject: st/dri: Move DRI1 bits in dri_screen.c to dri1.c. --- src/gallium/state_trackers/dri/Makefile | 3 +- src/gallium/state_trackers/dri/SConscript | 1 + src/gallium/state_trackers/dri/dri1.c | 117 ++++++++++++++++++++++++++ src/gallium/state_trackers/dri/dri1.h | 43 ++++++++++ src/gallium/state_trackers/dri/dri_context.c | 1 + src/gallium/state_trackers/dri/dri_drawable.c | 1 + src/gallium/state_trackers/dri/dri_drawable.h | 1 + src/gallium/state_trackers/dri/dri_screen.c | 79 +---------------- src/gallium/state_trackers/dri/dri_screen.h | 9 +- 9 files changed, 173 insertions(+), 82 deletions(-) create mode 100644 src/gallium/state_trackers/dri/dri1.c create mode 100644 src/gallium/state_trackers/dri/dri1.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/Makefile b/src/gallium/state_trackers/dri/Makefile index ef8f19709a..24244417b9 100644 --- a/src/gallium/state_trackers/dri/Makefile +++ b/src/gallium/state_trackers/dri/Makefile @@ -15,7 +15,8 @@ C_SOURCES = \ dri_context.c \ dri_screen.c \ dri_drawable.c \ - dri_extensions.c + dri_extensions.c \ + dri1.c # $(TOP)/src/mesa/drivers/dri/common/utils.c \ $(TOP)/src/mesa/drivers/dri/common/vblank.c \ diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript index ce2c273597..6310fe06e4 100644 --- a/src/gallium/state_trackers/dri/SConscript +++ b/src/gallium/state_trackers/dri/SConscript @@ -18,6 +18,7 @@ if env['dri']: 'dri_drawable.c', 'dri_extensions.c', 'dri_screen.c', + 'dri1.c', ] ) Export('st_dri') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c new file mode 100644 index 0000000000..1222f42e23 --- /dev/null +++ b/src/gallium/state_trackers/dri/dri1.c @@ -0,0 +1,117 @@ +/************************************************************************** + * + * 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 + * Author: Jakob Bornecrantz + */ + +#include "util/u_memory.h" + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" +#include "dri1.h" + +static const __DRIextension *dri1_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + +struct dri1_api *__dri1_api_hooks = NULL; + +static INLINE void +dri1_copy_version(struct dri1_api_version *dst, + const struct __DRIversionRec *src) +{ + dst->major = src->major; + dst->minor = src->minor; + dst->patch_level = src->patch; +} + +const __DRIconfig ** +dri1_init_screen(__DRIscreen * sPriv) +{ + struct dri_screen *screen; + const __DRIconfig **configs; + struct dri1_create_screen_arg arg; + + screen = CALLOC_STRUCT(dri_screen); + if (!screen) + return NULL; + + screen->api = drm_api_create(); + screen->sPriv = sPriv; + screen->fd = sPriv->fd; + screen->drmLock = (drmLock *) & sPriv->pSAREA->lock; + + sPriv->private = (void *)screen; + sPriv->extensions = dri1_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; + dri1_copy_version(&arg.ddx_version, &sPriv->ddx_version); + dri1_copy_version(&arg.dri_version, &sPriv->dri_version); + dri1_copy_version(&arg.drm_version, &sPriv->drm_version); + arg.api = NULL; + + screen->pipe_screen = screen->api->create_screen(screen->api, 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); + + /** + * FIXME: If the driver supports format conversion swapbuffer blits, we might + * want to support other color bit depths than the server is currently + * using. + */ + + configs = dri_fill_in_modes(screen, sPriv->fbBPP); + 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; +} diff --git a/src/gallium/state_trackers/dri/dri1.h b/src/gallium/state_trackers/dri/dri1.h new file mode 100644 index 0000000000..731b13cb06 --- /dev/null +++ b/src/gallium/state_trackers/dri/dri1.h @@ -0,0 +1,43 @@ +/************************************************************************** + * + * 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 + * Author: Jakob Bornecrantz + */ + +#ifndef DRI1_H +#define DRI1_H + +#include "state_tracker/dri1_api.h" +#include "dri_util.h" + +extern struct dri1_api *__dri1_api_hooks; + +const __DRIconfig ** +dri1_init_screen(__DRIscreen * sPriv); + +#endif /* DRI1_H */ diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index f772ba5d16..a5ed0006dc 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -38,6 +38,7 @@ #include "pipe/p_context.h" #include "dri_context.h" +#include "dri1.h" #include "util/u_memory.h" diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index c400725c7f..83b1a29681 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -32,6 +32,7 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" +#include "dri1.h" #include "pipe/p_context.h" #include "pipe/p_screen.h" diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 8bc59cb4c3..80bd2f5bdf 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -29,6 +29,7 @@ #define DRI_DRAWABLE_H #include "pipe/p_compiler.h" +#include "pipe/p_format.h" struct pipe_surface; struct pipe_fence_handle; diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 7ccad8f5dd..8a586d637f 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -36,6 +36,7 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" +#include "dri1.h" #include "pipe/p_screen.h" #include "pipe/p_format.h" @@ -53,7 +54,7 @@ PUBLIC const char __driConfigOptions[] = DRI_CONF_ALLOW_LARGE_TEXTURES(1) DRI_CONF_SECTION_END DRI_CONF_END; - const uint __driNConfigOptions = 3; +const uint __driNConfigOptions = 3; static const __DRItexBufferExtension dri2TexBufferExtension = { { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION }, @@ -83,9 +84,7 @@ static const __DRI2flushExtension dri2FlushExtension = { NULL }; -struct dri1_api *__dri1_api_hooks = NULL; - -static const __DRIconfig ** +const __DRIconfig ** dri_fill_in_modes(struct dri_screen *screen, unsigned pixel_bits) { @@ -240,75 +239,6 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo) 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; -} - -static const __DRIconfig ** -dri_init_screen(__DRIscreen * sPriv) -{ - struct dri_screen *screen; - const __DRIconfig **configs; - struct dri1_create_screen_arg arg; - - screen = CALLOC_STRUCT(dri_screen); - if (!screen) - return NULL; - - screen->api = drm_api_create(); - 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 = screen->api->create_screen(screen->api, 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); - - /** - * FIXME: If the driver supports format conversion swapbuffer blits, we might - * want to support other color bit depths than the server is currently - * using. - */ - - configs = dri_fill_in_modes(screen, sPriv->fbBPP); - 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. * @@ -375,7 +305,6 @@ dri_destroy_screen(__DRIscreen * sPriv) } PUBLIC const struct __DriverAPIRec driDriverAPI = { - .InitScreen = dri_init_screen, .DestroyScreen = dri_destroy_screen, .CreateContext = dri_create_context, .DestroyContext = dri_destroy_context, @@ -388,7 +317,7 @@ PUBLIC const struct __DriverAPIRec driDriverAPI = { .GetDrawableMSC = driDrawableGetMSC32, .WaitForMSC = driWaitForMSC32, .CopySubBuffer = dri_copy_sub_buffer, - .InitScreen = dri_init_screen, + .InitScreen = dri1_init_screen, .InitScreen2 = dri_init_screen2, }; diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index 75a0ee4250..3130135692 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -37,8 +37,6 @@ #include "pipe/p_compiler.h" -#include "state_tracker/dri1_api.h" - struct dri_screen { /* dri */ @@ -69,11 +67,10 @@ dri_screen(__DRIscreen * sPriv) return (struct dri_screen *)sPriv->private; } -/*********************************************************************** - * dri_screen.c - */ +extern const uint __driNConfigOptions; -extern struct dri1_api *__dri1_api_hooks; +const __DRIconfig ** +dri_fill_in_modes(struct dri_screen *screen, unsigned pixel_bits); #endif -- cgit v1.2.3 From a437bc50f2f8ff6e91fdf4dc9758b35cff35645a Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 16 Mar 2010 10:25:50 +0800 Subject: st/dri: Move DRI1 bits in dri_drawable.c to dri1.c. --- src/gallium/state_trackers/dri/dri1.c | 314 ++++++++++++++++++++++++++ src/gallium/state_trackers/dri/dri1.h | 16 ++ src/gallium/state_trackers/dri/dri_drawable.c | 306 +------------------------ src/gallium/state_trackers/dri/dri_drawable.h | 12 - src/gallium/state_trackers/dri/dri_screen.c | 7 +- 5 files changed, 336 insertions(+), 319 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c index 1222f42e23..2d809459ca 100644 --- a/src/gallium/state_trackers/dri/dri1.c +++ b/src/gallium/state_trackers/dri/dri1.c @@ -30,12 +30,326 @@ */ #include "util/u_memory.h" +#include "util/u_rect.h" +#include "pipe/p_context.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_public.h" #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" #include "dri1.h" +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 +dri1_swap_fences_clear(struct dri_drawable *drawable) +{ + struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; + struct pipe_fence_handle *fence; + + while (drawable->cur_fences) { + fence = dri_swap_fences_pop_front(drawable); + screen->fence_reference(screen, &fence, NULL); + } +} + +static void +dri1_update_drawables_locked(struct dri_context *ctx, + __DRIdrawable * driDrawPriv, + __DRIdrawable * 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) +{ + __DRIdrawable *dPriv = ctx->dPriv; + __DRIdrawable *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, + __DRIdrawable * 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)) { + if (pipe->surface_copy) { + 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); + } else { + util_surface_copy(pipe, FALSE, 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, + __DRIdrawable * 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 +dri1_swap_buffers(__DRIdrawable * 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 +dri1_copy_sub_buffer(__DRIdrawable * 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); + } +} + static const __DRIextension *dri1_screen_extensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, diff --git a/src/gallium/state_trackers/dri/dri1.h b/src/gallium/state_trackers/dri/dri1.h index 731b13cb06..b2304af7e1 100644 --- a/src/gallium/state_trackers/dri/dri1.h +++ b/src/gallium/state_trackers/dri/dri1.h @@ -40,4 +40,20 @@ extern struct dri1_api *__dri1_api_hooks; const __DRIconfig ** dri1_init_screen(__DRIscreen * sPriv); +void +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); + +void dri1_swap_buffers(__DRIdrawable * dPriv); + +void +dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h); + +void +dri1_swap_fences_clear(struct dri_drawable *drawable); + #endif /* DRI1_H */ diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 83b1a29681..6c4de71c89 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -448,319 +448,17 @@ fail: 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(__DRIdrawable * 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, - __DRIdrawable * driDrawPriv, - __DRIdrawable * 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) -{ - __DRIdrawable *dPriv = ctx->dPriv; - __DRIdrawable *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, - __DRIdrawable * 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; + dri1_swap_fences_clear(drawable); - for (i = 0; i < dPriv->numClipRects; ++i) { - if (dri1_intersect_src_bbox(&clip, dPriv->x, dPriv->y, cur++, bbox)) { - if (pipe->surface_copy) { - 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); - } else { - util_surface_copy(pipe, FALSE, 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, - __DRIdrawable * 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(__DRIdrawable * 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(__DRIdrawable * 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); - } + FREE(drawable); } /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 80bd2f5bdf..48d24e959c 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -88,11 +88,6 @@ void dri_flush_frontbuffer(struct pipe_screen *screen, struct pipe_surface *surf, void *context_private); -void dri_swap_buffers(__DRIdrawable * dPriv); - -void -dri_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h); - void dri_get_buffers(__DRIdrawable * dPriv); void dri_destroy_buffer(__DRIdrawable * dPriv); @@ -103,13 +98,6 @@ void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv); -void -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/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 8a586d637f..b6cd92d0f8 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -310,15 +310,16 @@ PUBLIC const struct __DriverAPIRec driDriverAPI = { .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 = dri1_init_screen, .InitScreen2 = dri_init_screen2, + + .InitScreen = dri1_init_screen, + .SwapBuffers = dri1_swap_buffers, + .CopySubBuffer = dri1_copy_sub_buffer, }; /* This is the table of extensions that the loader will dlsym() for. */ -- cgit v1.2.3 From 61631a89a3268925c89934c77ed7c2482eaa1fd1 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 16 Mar 2010 10:31:40 +0800 Subject: st/dri: Move DRI1 bits in dri_context.c to dri1.c. --- src/gallium/state_trackers/dri/dri1.c | 68 ++++++++++++++++++++++++++-- src/gallium/state_trackers/dri/dri_context.c | 38 ---------------- src/gallium/state_trackers/dri/dri_context.h | 24 ---------- 3 files changed, 64 insertions(+), 66 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c index 2d809459ca..a4284f6fe7 100644 --- a/src/gallium/state_trackers/dri/dri1.c +++ b/src/gallium/state_trackers/dri/dri1.c @@ -40,6 +40,28 @@ #include "dri_drawable.h" #include "dri1.h" +static INLINE void +dri1_lock(struct dri_context *ctx) +{ + 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 +dri1_unlock(struct dri_context *ctx) +{ + ctx->isLocked = FALSE; + DRM_UNLOCK(ctx->sPriv->fd, ctx->lock, ctx->cPriv->hHWContext); +} + static struct pipe_fence_handle * dri_swap_fences_pop_front(struct dri_drawable *draw) { @@ -141,9 +163,9 @@ void dri1_update_drawables(struct dri_context *ctx, struct dri_drawable *draw, struct dri_drawable *read) { - dri_lock(ctx); + dri1_lock(ctx); dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv); - dri_unlock(ctx); + dri1_unlock(ctx); dri1_propagate_drawable_change(ctx); } @@ -228,7 +250,7 @@ dri1_copy_to_front(struct dri_context *ctx, *fence = NULL; - dri_lock(ctx); + dri1_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); @@ -268,7 +290,7 @@ dri1_copy_to_front(struct dri_context *ctx, if (!sub_box) dri1_update_drawables_locked(ctx, ctx->dPriv, ctx->rPriv); - dri_unlock(ctx); + dri1_unlock(ctx); dri1_propagate_drawable_change(ctx); } @@ -350,6 +372,44 @@ dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h) } } +static void +st_dri_lock(struct pipe_context *pipe) +{ + dri1_lock((struct dri_context *)pipe->priv); +} + +static void +st_dri_unlock(struct pipe_context *pipe) +{ + dri1_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; +} + +static 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 +}; + static const __DRIextension *dri1_screen_extensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index a5ed0006dc..58f2b17585 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -182,42 +182,4 @@ dri_make_current(__DRIcontext * 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/dri/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h index 13f497462f..f0700b9aaf 100644 --- a/src/gallium/state_trackers/dri/dri_context.h +++ b/src/gallium/state_trackers/dri/dri_context.h @@ -72,33 +72,9 @@ dri_context(__DRIcontext * driContextPriv) return (struct dri_context *)driContextPriv->driverPrivate; } -static INLINE void -dri_lock(struct dri_context *ctx) -{ - 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 */ -extern struct dri1_api_lock_funcs dri1_lf; - void dri_destroy_context(__DRIcontext * driContextPriv); boolean dri_unbind_context(__DRIcontext * driContextPriv); -- cgit v1.2.3 From 903b90926c7aebb7f48f3c0fdbe90cd22dd5b662 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Tue, 16 Mar 2010 10:55:40 +0800 Subject: st/dri: Headers and public symbols clean up. Remove unused headers and stop marking driDriverAPI as PUBLIC. --- src/gallium/state_trackers/dri/dri1.c | 1 + src/gallium/state_trackers/dri/dri1.h | 3 ++- src/gallium/state_trackers/dri/dri_context.c | 8 ++------ src/gallium/state_trackers/dri/dri_drawable.c | 7 ++----- src/gallium/state_trackers/dri/dri_screen.c | 3 +-- 5 files changed, 8 insertions(+), 14 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c index a4284f6fe7..543891f813 100644 --- a/src/gallium/state_trackers/dri/dri1.c +++ b/src/gallium/state_trackers/dri/dri1.c @@ -34,6 +34,7 @@ #include "pipe/p_context.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" +#include "state_tracker/dri1_api.h" #include "dri_screen.h" #include "dri_context.h" diff --git a/src/gallium/state_trackers/dri/dri1.h b/src/gallium/state_trackers/dri/dri1.h index b2304af7e1..e525ce64c3 100644 --- a/src/gallium/state_trackers/dri/dri1.h +++ b/src/gallium/state_trackers/dri/dri1.h @@ -32,7 +32,8 @@ #ifndef DRI1_H #define DRI1_H -#include "state_tracker/dri1_api.h" +#include "dri_context.h" +#include "dri_drawable.h" #include "dri_util.h" extern struct dri1_api *__dri1_api_hooks; diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 58f2b17585..8e74d3b9bf 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -30,16 +30,12 @@ */ #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 "pipe/p_context.h" - #include "dri_context.h" #include "dri1.h" +#include "state_tracker/st_public.h" +#include "pipe/p_context.h" #include "util/u_memory.h" GLboolean diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 6c4de71c89..9238f94299 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -34,19 +34,16 @@ #include "dri_drawable.h" #include "dri1.h" -#include "pipe/p_context.h" -#include "pipe/p_screen.h" #include "main/mtypes.h" #include "main/renderbuffer.h" -#include "state_tracker/drm_api.h" -#include "state_tracker/dri1_api.h" #include "state_tracker/st_context.h" #include "state_tracker/st_public.h" #include "state_tracker/st_cb_fbo.h" +#include "state_tracker/drm_api.h" +#include "pipe/p_screen.h" #include "util/u_format.h" #include "util/u_memory.h" -#include "util/u_rect.h" #include "util/u_inlines.h" static struct pipe_surface * diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index b6cd92d0f8..cffe3b33b2 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -41,7 +41,6 @@ #include "pipe/p_screen.h" #include "pipe/p_format.h" #include "state_tracker/drm_api.h" -#include "state_tracker/dri1_api.h" #include "util/u_debug.h" @@ -304,7 +303,7 @@ dri_destroy_screen(__DRIscreen * sPriv) sPriv->private = NULL; } -PUBLIC const struct __DriverAPIRec driDriverAPI = { +const struct __DriverAPIRec driDriverAPI = { .DestroyScreen = dri_destroy_screen, .CreateContext = dri_create_context, .DestroyContext = dri_destroy_context, -- cgit v1.2.3 From 5ff21634f3074122ed8b8e4019c8092e31be0335 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 8 Mar 2010 19:25:32 +0800 Subject: st/dri: Implement st_api.h callbacks. This commit adds dri_st_api.c that implements st_api.h callbacks. A following commit will switch st/dri from st_public.h to st_api.h. --- src/gallium/state_trackers/dri/Makefile | 1 + src/gallium/state_trackers/dri/SConscript | 1 + src/gallium/state_trackers/dri/dri_drawable.h | 6 + src/gallium/state_trackers/dri/dri_st_api.c | 442 ++++++++++++++++++++++++++ src/gallium/state_trackers/dri/dri_st_api.h | 55 ++++ 5 files changed, 505 insertions(+) create mode 100644 src/gallium/state_trackers/dri/dri_st_api.c create mode 100644 src/gallium/state_trackers/dri/dri_st_api.h (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/Makefile b/src/gallium/state_trackers/dri/Makefile index 24244417b9..f5af8aa3a6 100644 --- a/src/gallium/state_trackers/dri/Makefile +++ b/src/gallium/state_trackers/dri/Makefile @@ -16,6 +16,7 @@ C_SOURCES = \ dri_screen.c \ dri_drawable.c \ dri_extensions.c \ + dri_st_api.c \ dri1.c # $(TOP)/src/mesa/drivers/dri/common/utils.c \ diff --git a/src/gallium/state_trackers/dri/SConscript b/src/gallium/state_trackers/dri/SConscript index 6310fe06e4..7c67ceecd8 100644 --- a/src/gallium/state_trackers/dri/SConscript +++ b/src/gallium/state_trackers/dri/SConscript @@ -18,6 +18,7 @@ if env['dri']: 'dri_drawable.c', 'dri_extensions.c', 'dri_screen.c', + 'dri_st_api.c', 'dri1.c', ] ) diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index 48d24e959c..ea66c483a1 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -30,6 +30,7 @@ #include "pipe/p_compiler.h" #include "pipe/p_format.h" +#include "state_tracker/st_api.h" struct pipe_surface; struct pipe_fence_handle; @@ -57,6 +58,11 @@ struct dri_drawable /* gallium */ struct st_framebuffer *stfb; + struct st_visual stvis; + + struct pipe_texture *textures[ST_ATTACHMENT_COUNT]; + unsigned int texture_mask, texture_stamp; + struct pipe_fence_handle *swap_fences[DRI_SWAP_FENCES_MAX]; unsigned int head; unsigned int tail; diff --git a/src/gallium/state_trackers/dri/dri_st_api.c b/src/gallium/state_trackers/dri/dri_st_api.c new file mode 100644 index 0000000000..379515152e --- /dev/null +++ b/src/gallium/state_trackers/dri/dri_st_api.c @@ -0,0 +1,442 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu + */ + +#include "util/u_memory.h" +#include "util/u_inlines.h" +#include "util/u_format.h" +#include "util/u_debug.h" +#include "state_tracker/drm_api.h" +#include "state_tracker/st_manager.h" /* for st_manager_create_api */ + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" +#include "dri_st_api.h" +#include "dri1.h" + +static struct { + int32_t refcnt; + struct st_api *stapi; +} dri_st_api; + +/** + * Get the format of an attachment. + */ +static INLINE enum pipe_format +dri_drawable_get_format(struct dri_drawable *drawable, + enum st_attachment_type statt) +{ + enum pipe_format format; + + switch (statt) { + case ST_ATTACHMENT_FRONT_LEFT: + case ST_ATTACHMENT_BACK_LEFT: + case ST_ATTACHMENT_FRONT_RIGHT: + case ST_ATTACHMENT_BACK_RIGHT: + format = drawable->stvis.color_format; + break; + case ST_ATTACHMENT_DEPTH_STENCIL: + format = drawable->stvis.depth_stencil_format; + break; + default: + format = PIPE_FORMAT_NONE; + break; + } + + return format; +} + +/** + * Process __DRIbuffer and convert them into pipe_textures. + */ +static void +dri_drawable_process_buffers(struct dri_drawable *drawable, + __DRIbuffer *buffers, unsigned count) +{ + struct dri_screen *screen = dri_screen(drawable->sPriv); + __DRIdrawable *dri_drawable = drawable->dPriv; + struct pipe_texture templ; + struct winsys_handle whandle; + boolean have_depth = FALSE; + unsigned i; + + 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; + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_texture_reference(&drawable->textures[i], NULL); + + memset(&templ, 0, sizeof(templ)); + templ.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET; + templ.target = PIPE_TEXTURE_2D; + templ.last_level = 0; + templ.width0 = dri_drawable->w; + templ.height0 = dri_drawable->h; + templ.depth0 = 1; + + memset(&whandle, 0, sizeof(whandle)); + + for (i = 0; i < count; i++) { + __DRIbuffer *buf = &buffers[i]; + enum st_attachment_type statt; + enum pipe_format format; + + switch (buf->attachment) { + case __DRI_BUFFER_FRONT_LEFT: + if (!screen->auto_fake_front) { + statt = ST_ATTACHMENT_INVALID; + break; + } + /* fallthrough */ + case __DRI_BUFFER_FAKE_FRONT_LEFT: + statt = ST_ATTACHMENT_FRONT_LEFT; + break; + case __DRI_BUFFER_BACK_LEFT: + statt = ST_ATTACHMENT_BACK_LEFT; + break; + case __DRI_BUFFER_DEPTH: + case __DRI_BUFFER_DEPTH_STENCIL: + case __DRI_BUFFER_STENCIL: + statt = ST_ATTACHMENT_DEPTH_STENCIL; + /* use only the first depth/stencil buffer */ + if (have_depth) + statt = ST_ATTACHMENT_INVALID; + else + have_depth = TRUE; + break; + default: + statt = ST_ATTACHMENT_INVALID; + break; + } + + format = dri_drawable_get_format(drawable, statt); + if (statt == ST_ATTACHMENT_INVALID || format == PIPE_FORMAT_NONE) + continue; + + templ.format = format; + whandle.handle = buf->name; + whandle.stride = buf->pitch; + + drawable->textures[statt] = + screen->pipe_screen->texture_from_handle(screen->pipe_screen, + &templ, &whandle); + } + + drawable->old_num = count; + drawable->old_w = dri_drawable->w; + drawable->old_h = dri_drawable->h; + memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count); +} + +/** + * Retrieve __DRIbuffer from the DRI loader. + */ +static __DRIbuffer * +dri_drawable_get_buffers(struct dri_drawable *drawable, + const enum st_attachment_type *statts, + unsigned *count) +{ + __DRIdrawable *dri_drawable = drawable->dPriv; + struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader; + boolean with_format; + __DRIbuffer *buffers; + int num_buffers; + unsigned attachments[8]; + unsigned num_attachments, i; + + assert(loader); + with_format = (loader->base.version > 2 && loader->getBuffersWithFormat); + + num_attachments = 0; + for (i = 0; i < *count; i++) { + enum pipe_format format; + int att; + + format = dri_drawable_get_format(drawable, statts[i]); + if (format == PIPE_FORMAT_NONE) + continue; + + switch (statts[i]) { + case ST_ATTACHMENT_FRONT_LEFT: + att = __DRI_BUFFER_FRONT_LEFT; + break; + case ST_ATTACHMENT_BACK_LEFT: + att = __DRI_BUFFER_BACK_LEFT; + break; + case ST_ATTACHMENT_FRONT_RIGHT: + att = __DRI_BUFFER_FRONT_RIGHT; + break; + case ST_ATTACHMENT_BACK_RIGHT: + att = __DRI_BUFFER_BACK_RIGHT; + break; + case ST_ATTACHMENT_DEPTH_STENCIL: + att = __DRI_BUFFER_DEPTH_STENCIL; + break; + default: + att = -1; + break; + } + + if (att >= 0) { + attachments[num_attachments++] = att; + if (with_format) { + attachments[num_attachments++] = + util_format_get_blocksizebits(format); + } + } + } + + if (with_format) { + num_attachments /= 2; + buffers = loader->getBuffersWithFormat(dri_drawable, + &dri_drawable->w, &dri_drawable->h, + attachments, num_attachments, + &num_buffers, dri_drawable->loaderPrivate); + } + else { + buffers = loader->getBuffers(dri_drawable, + &dri_drawable->w, &dri_drawable->h, + attachments, num_attachments, + &num_buffers, dri_drawable->loaderPrivate); + } + + if (buffers) { + /* 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; + + *count = num_buffers; + } + + return buffers; +} + +static boolean +dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, + const enum st_attachment_type *statts, + unsigned count, + struct pipe_texture **out) +{ + struct dri_drawable *drawable = + (struct dri_drawable *) stfbi->st_manager_private; + unsigned statt_mask, i; + + statt_mask = 0x0; + for (i = 0; i < count; i++) + statt_mask |= (1 << statts[i]); + + /* + * dPriv->pStamp is the server stamp. It should be accessed with a lock, at + * least for DRI1. dPriv->lastStamp is the client stamp. It has the value + * of the server stamp when last checked. + * + * This function updates the textures and records the stamp of the textures. + */ + if (drawable->texture_stamp != drawable->dPriv->lastStamp || + (statt_mask & ~drawable->texture_mask)) { + if (__dri1_api_hooks) { + /* TODO */ + return FALSE; + } + else { + __DRIbuffer *buffers; + unsigned num_buffers = count; + + buffers = dri_drawable_get_buffers(drawable, statts, &num_buffers); + dri_drawable_process_buffers(drawable, buffers, num_buffers); + } + + drawable->texture_stamp = drawable->dPriv->lastStamp; + drawable->texture_mask = statt_mask; + } + + if (!out) + return TRUE; + + for (i = 0; i < count; i++) { + out[i] = NULL; + pipe_texture_reference(&out[i], drawable->textures[statts[i]]); + } + + return TRUE; +} + +static boolean +dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, + enum st_attachment_type statt) +{ + struct dri_drawable *drawable = + (struct dri_drawable *) stfbi->st_manager_private; + struct __DRIdri2LoaderExtensionRec *loader = + drawable->sPriv->dri2.loader; + + /* TODO */ + if (__dri1_api_hooks) + return FALSE; + + if (statt == ST_ATTACHMENT_FRONT_LEFT && loader->flushFrontBuffer) { + loader->flushFrontBuffer(drawable->dPriv, + drawable->dPriv->loaderPrivate); + } + + return TRUE; +} + +/** + * Create a framebuffer from the given drawable. + */ +struct st_framebuffer_iface * +dri_create_st_framebuffer(struct dri_drawable *drawable) +{ + struct st_framebuffer_iface *stfbi; + + stfbi = CALLOC_STRUCT(st_framebuffer_iface); + if (stfbi) { + stfbi->visual = &drawable->stvis; + stfbi->flush_front = dri_st_framebuffer_flush_front; + stfbi->validate = dri_st_framebuffer_validate; + stfbi->st_manager_private = (void *) drawable; + } + + return stfbi; +} + +/** + * Destroy a framebuffer. + */ +void +dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi) +{ + FREE(stfbi); +} + +/** + * Return the texture at an attachment. Allocate the texture if it does not + * exist. + */ +struct pipe_texture * +dri_get_st_framebuffer_texture(struct st_framebuffer_iface *stfbi, + enum st_attachment_type statt) +{ + struct dri_drawable *drawable = + (struct dri_drawable *) stfbi->st_manager_private; + + if (!(drawable->texture_mask & (1 << statt))) { + enum st_attachment_type statts[ST_ATTACHMENT_COUNT]; + unsigned i, count = 0; + + /* make sure DRI2 does not destroy existing buffers */ + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { + if (drawable->texture_mask & (1 << i)) { + statts[count++] = i; + } + } + statts[count++] = statt; + + drawable->texture_stamp = drawable->dPriv->lastStamp - 1; + dri_st_framebuffer_validate(stfbi, statts, count, NULL); + } + + return drawable->textures[statt]; +} + +/** + * Add a reference to the st_api of the state tracker. + */ +static void +_dri_get_st_api(void) +{ + p_atomic_inc(&dri_st_api.refcnt); + if (p_atomic_read(&dri_st_api.refcnt) == 1) + dri_st_api.stapi = st_manager_create_api(); +} + +/** + * Remove a reference to the st_api of the state tracker. + */ +static void +_dri_put_st_api(void) +{ + struct st_api *stapi = dri_st_api.stapi; + + if (p_atomic_dec_zero(&dri_st_api.refcnt)) { + stapi->destroy(dri_st_api.stapi); + dri_st_api.stapi = NULL; + } +} + +/** + * Create a state tracker manager from the given screen. + */ +struct st_manager * +dri_create_st_manager(struct dri_screen *screen) +{ + struct st_manager *smapi; + + smapi = CALLOC_STRUCT(st_manager); + if (smapi) { + smapi->screen = screen->pipe_screen; + _dri_get_st_api(); + } + + return smapi; +} + +/** + * Destroy a state tracker manager. + */ +void +dri_destroy_st_manager(struct st_manager *smapi) +{ + _dri_put_st_api(); + FREE(smapi); +} + +/** + * Return the st_api of OpenGL state tracker. + */ +struct st_api * +dri_get_st_api(void) +{ + assert(dri_st_api.stapi); + return dri_st_api.stapi; +} diff --git a/src/gallium/state_trackers/dri/dri_st_api.h b/src/gallium/state_trackers/dri/dri_st_api.h new file mode 100644 index 0000000000..7cf522e469 --- /dev/null +++ b/src/gallium/state_trackers/dri/dri_st_api.h @@ -0,0 +1,55 @@ +/* + * Mesa 3-D graphics library + * Version: 7.9 + * + * Copyright (C) 2010 LunarG Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Chia-I Wu + */ + +#ifndef _DRI_ST_API_H_ +#define _DRI_ST_API_H_ + +#include "state_tracker/st_api.h" + +struct dri_screen; +struct dri_drawable; + +struct st_api * +dri_get_st_api(void); + +struct st_manager * +dri_create_st_manager(struct dri_screen *screen); + +void +dri_destroy_st_manager(struct st_manager *smapi); + +struct st_framebuffer_iface * +dri_create_st_framebuffer(struct dri_drawable *drawable); + +void +dri_destroy_st_framebuffer(struct st_framebuffer_iface *stfbi); + +struct pipe_texture * +dri_get_st_framebuffer_texture(struct st_framebuffer_iface *stfbi, + enum st_attachment_type statt); + +#endif /* _DRI_ST_API_H_ */ -- cgit v1.2.3 From bd1ce874728c06d08a1f9881f51edbdd2f1c9db0 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 8 Mar 2010 22:19:48 +0800 Subject: st/dri: Switch from st_public.h to st_api.h. This is tested with demos found in progs/demos. However, only the DRI2 path is tested. --- src/gallium/state_trackers/dri/dri1.c | 281 ++++++++++++------ src/gallium/state_trackers/dri/dri1.h | 11 +- src/gallium/state_trackers/dri/dri_context.c | 82 +++-- src/gallium/state_trackers/dri/dri_context.h | 9 +- src/gallium/state_trackers/dri/dri_drawable.c | 378 ++---------------------- src/gallium/state_trackers/dri/dri_drawable.h | 24 +- src/gallium/state_trackers/dri/dri_extensions.c | 4 +- src/gallium/state_trackers/dri/dri_screen.c | 137 +++++++-- src/gallium/state_trackers/dri/dri_screen.h | 12 + src/gallium/state_trackers/dri/dri_st_api.c | 13 +- 10 files changed, 393 insertions(+), 558 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c index 543891f813..41dba82d52 100644 --- a/src/gallium/state_trackers/dri/dri1.c +++ b/src/gallium/state_trackers/dri/dri1.c @@ -29,16 +29,18 @@ * Author: Jakob Bornecrantz */ +/* XXX DRI1 is untested after the switch to st_api.h */ + #include "util/u_memory.h" #include "util/u_rect.h" +#include "util/u_inlines.h" #include "pipe/p_context.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" #include "state_tracker/dri1_api.h" #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" +#include "dri_st_api.h" #include "dri1.h" static INLINE void @@ -125,52 +127,29 @@ dri1_update_drawables_locked(struct dri_context *ctx, /** * 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) { __DRIdrawable *dPriv = ctx->dPriv; __DRIdrawable *rPriv = ctx->rPriv; + struct dri_drawable *draw = dri_drawable(dPriv); + struct dri_drawable *read = dri_drawable(rPriv); boolean flushed = FALSE; - if (dPriv && ctx->d_stamp != dPriv->lastStamp) { - - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + if (dPriv && draw->texture_stamp != dPriv->lastStamp) { + ctx->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); - + ctx->st->notify_invalid_framebuffer(ctx->st, draw->stfb); } - if (rPriv && dPriv != rPriv && ctx->r_stamp != rPriv->lastStamp) { - + if (rPriv && dPriv != rPriv && read->texture_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; - + ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->st->notify_invalid_framebuffer(ctx->st, read->stfb); } } -void -dri1_update_drawables(struct dri_context *ctx, - struct dri_drawable *draw, struct dri_drawable *read) -{ - dri1_lock(ctx); - dri1_update_drawables_locked(ctx, draw->dPriv, read->dPriv); - dri1_unlock(ctx); - - dri1_propagate_drawable_change(ctx); -} - static INLINE boolean dri1_intersect_src_bbox(struct drm_clip_rect *dst, int dst_x, @@ -204,12 +183,11 @@ dri1_intersect_src_bbox(struct drm_clip_rect *dst, } static void -dri1_swap_copy(struct dri_context *ctx, +dri1_swap_copy(struct pipe_context *pipe, struct pipe_surface *dst, struct pipe_surface *src, __DRIdrawable * 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; @@ -235,52 +213,96 @@ dri1_swap_copy(struct dri_context *ctx, } } +static struct pipe_surface * +dri1_get_pipe_surface(struct dri_drawable *drawable, struct pipe_texture *ptex) +{ + struct pipe_screen *pipe_screen = dri_screen(drawable->sPriv)->pipe_screen; + struct pipe_surface *psurf = drawable->dri1_surface; + + if (!psurf || psurf->texture != ptex) { + pipe_surface_reference(&drawable->dri1_surface, NULL); + + drawable->dri1_surface = pipe_screen->get_tex_surface(pipe_screen, + ptex, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ); + + psurf = drawable->dri1_surface; + } + + return psurf; +} + +static struct pipe_context * +dri1_get_pipe_context(struct dri_drawable *drawable) +{ + struct dri_screen *screen = dri_screen(drawable->sPriv); + struct pipe_context *pipe = screen->dri1_pipe; + + if (!pipe) { + screen->dri1_pipe = + screen->pipe_screen->context_create(screen->pipe_screen, NULL); + pipe = screen->dri1_pipe; + } + + return pipe; +} + static void -dri1_copy_to_front(struct dri_context *ctx, - struct pipe_surface *surf, - __DRIdrawable * dPriv, - const struct drm_clip_rect *sub_box, - struct pipe_fence_handle **fence) +dri1_present_texture_locked(__DRIdrawable * dPriv, + struct pipe_texture *ptex, + 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 dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_context *pipe; + struct pipe_surface *psurf; struct drm_clip_rect bbox; boolean visible = TRUE; *fence = NULL; - dri1_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.x2 = ptex->width0; bbox.y1 = 0; - bbox.y2 = cur_h; + bbox.y2 = ptex->height0; if (sub_box) visible = dri1_intersect_src_bbox(&bbox, 0, 0, &bbox, sub_box); + if (!visible) + return; - 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) { + pipe = dri1_get_pipe_context(drawable); + psurf = dri1_get_pipe_surface(drawable, ptex); + if (!pipe || !psurf) + return; + if (__dri1_api_hooks->present_locked) { + __dri1_api_hooks->present_locked(pipe, psurf, + dPriv->pClipRects, dPriv->numClipRects, + dPriv->x, dPriv->y, &bbox, fence); + } else if (__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); + dri1_swap_copy(pipe, front, psurf, dPriv, &bbox); - st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, fence); + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, fence); } +} + +static void +dri1_copy_to_front(struct dri_context *ctx, + struct pipe_texture *ptex, + __DRIdrawable * dPriv, + const struct drm_clip_rect *sub_box, + struct pipe_fence_handle **fence) +{ + boolean save_lost_lock; + + dri1_lock(ctx); + save_lost_lock = ctx->stLostLock; + dri1_update_drawables_locked(ctx, dPriv, dPriv); + + dri1_present_texture_locked(dPriv, ptex, sub_box, fence); ctx->stLostLock = save_lost_lock; @@ -296,14 +318,23 @@ dri1_copy_to_front(struct dri_context *ctx, } void -dri1_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, void *context_private) +dri1_flush_frontbuffer(struct dri_drawable *drawable, + struct pipe_texture *ptex) { - struct dri_context *ctx = (struct dri_context *)context_private; + struct st_api *stapi = dri_get_st_api(); + struct dri_screen *screen = dri_screen(drawable->sPriv); + struct pipe_screen *pipe_screen = screen->pipe_screen; + struct dri_context *ctx; struct pipe_fence_handle *dummy_fence; + struct st_context_iface *st = stapi->get_current(stapi); - dri1_copy_to_front(ctx, surf, ctx->dPriv, NULL, &dummy_fence); - screen->fence_reference(screen, &dummy_fence, NULL); + if (!st) + return; + + ctx = (struct dri_context *) st->st_manager_private; + + dri1_copy_to_front(ctx, ptex, ctx->dPriv, NULL, &dummy_fence); + pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL); /** * FIXME: Do we need swap throttling here? @@ -313,66 +344,127 @@ dri1_flush_frontbuffer(struct pipe_screen *screen, void dri1_swap_buffers(__DRIdrawable * dPriv) { - struct dri_context *ctx; - struct pipe_surface *back_surf; + struct dri_context *ctx = dri_get_current(); struct dri_drawable *draw = dri_drawable(dPriv); - struct pipe_screen *screen = dri_screen(draw->sPriv)->pipe_screen; + struct dri_screen *screen = dri_screen(draw->sPriv); + struct pipe_screen *pipe_screen = screen->pipe_screen; struct pipe_fence_handle *fence; - struct st_context *st = st_get_current(); + struct pipe_texture *ptex; assert(__dri1_api_hooks != NULL); - if (!st) + if (!ctx) 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); + ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT]; + if (ptex) { + ctx->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); + (void)pipe_screen->fence_finish(pipe_screen, fence, 0); + pipe_screen->fence_reference(pipe_screen, &fence, NULL); } - dri1_copy_to_front(ctx, back_surf, dPriv, NULL, &fence); + dri1_copy_to_front(ctx, ptex, dPriv, NULL, &fence); dri_swap_fences_push_back(draw, fence); - screen->fence_reference(screen, &fence, NULL); + pipe_screen->fence_reference(pipe_screen, &fence, NULL); } } void dri1_copy_sub_buffer(__DRIdrawable * dPriv, int x, int y, int w, int h) { - struct pipe_screen *screen = dri_screen(dPriv->driScreenPriv)->pipe_screen; + struct dri_context *ctx = dri_get_current(); + struct dri_screen *screen = dri_screen(dPriv->driScreenPriv); + struct pipe_screen *pipe_screen = screen->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(); + struct pipe_texture *ptex; assert(__dri1_api_hooks != NULL); - if (!st) + if (!ctx) 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); + ptex = draw->textures[ST_ATTACHMENT_BACK_LEFT]; + if (ptex) { + ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + dri1_copy_to_front(ctx, ptex, dPriv, &sub_bbox, &dummy_fence); + pipe_screen->fence_reference(pipe_screen, &dummy_fence, NULL); } } +void +dri1_allocate_textures(struct dri_drawable *drawable, + unsigned width, unsigned height, + unsigned mask) +{ + struct dri_screen *screen = dri_screen(drawable->sPriv); + struct pipe_texture templ; + int i; + + /* remove outdated textures */ + if (drawable->old_w != width || drawable->old_h != height) { + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_texture_reference(&drawable->textures[i], NULL); + } + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.last_level = 0; + + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) { + enum pipe_format format; + unsigned tex_usage; + + /* the texture already exists or not requested */ + if (drawable->textures[i] || !(mask & (1 << i))) { + /* remember the texture */ + if (drawable->textures[i]) + mask |= (1 << i); + continue; + } + + switch (i) { + case ST_ATTACHMENT_FRONT_LEFT: + case ST_ATTACHMENT_BACK_LEFT: + case ST_ATTACHMENT_FRONT_RIGHT: + case ST_ATTACHMENT_BACK_RIGHT: + format = drawable->stvis.color_format; + tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET | + PIPE_TEXTURE_USAGE_RENDER_TARGET; + break; + case ST_ATTACHMENT_DEPTH_STENCIL: + format = drawable->stvis.depth_stencil_format; + tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL; + break; + default: + format = PIPE_FORMAT_NONE; + break; + } + + if (templ.format != PIPE_FORMAT_NONE) { + templ.format = format; + templ.tex_usage = tex_usage; + + drawable->textures[i] = + screen->pipe_screen->texture_create(screen->pipe_screen, &templ); + } + } + + drawable->old_w = width; + drawable->old_h = height; + drawable->texture_mask = mask; +} + static void st_dri_lock(struct pipe_context *pipe) { @@ -469,7 +561,6 @@ dri1_init_screen(__DRIscreen * sPriv) __dri1_api_hooks = arg.api; - screen->pipe_screen->flush_frontbuffer = dri1_flush_frontbuffer; driParseOptionInfo(&screen->optionCache, __driConfigOptions, __driNConfigOptions); diff --git a/src/gallium/state_trackers/dri/dri1.h b/src/gallium/state_trackers/dri/dri1.h index e525ce64c3..e83571e57b 100644 --- a/src/gallium/state_trackers/dri/dri1.h +++ b/src/gallium/state_trackers/dri/dri1.h @@ -34,6 +34,8 @@ #include "dri_context.h" #include "dri_drawable.h" + +#include "state_tracker/st_api.h" #include "dri_util.h" extern struct dri1_api *__dri1_api_hooks; @@ -42,12 +44,13 @@ const __DRIconfig ** dri1_init_screen(__DRIscreen * sPriv); void -dri1_update_drawables(struct dri_context *ctx, - struct dri_drawable *draw, struct dri_drawable *read); +dri1_flush_frontbuffer(struct dri_drawable *drawable, + struct pipe_texture *ptex); void -dri1_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, void *context_private); +dri1_allocate_textures(struct dri_drawable *drawable, + unsigned width, unsigned height, + unsigned mask); void dri1_swap_buffers(__DRIdrawable * dPriv); diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 8e74d3b9bf..c1848b026c 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -32,9 +32,9 @@ #include "dri_screen.h" #include "dri_drawable.h" #include "dri_context.h" +#include "dri_st_api.h" #include "dri1.h" -#include "state_tracker/st_public.h" #include "pipe/p_context.h" #include "util/u_memory.h" @@ -42,10 +42,12 @@ GLboolean dri_create_context(const __GLcontextModes * visual, __DRIcontext * cPriv, void *sharedContextPrivate) { + struct st_api *stapi = dri_get_st_api(); __DRIscreen *sPriv = cPriv->driScreenPriv; struct dri_screen *screen = dri_screen(sPriv); struct dri_context *ctx = NULL; - struct st_context *st_share = NULL; + struct st_context_iface *st_share = NULL; + struct st_visual stvis; if (sharedContextPrivate) { st_share = ((struct dri_context *)sharedContextPrivate)->st; @@ -59,21 +61,15 @@ dri_create_context(const __GLcontextModes * visual, 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"); - ctx->pipe = screen->pipe_screen->context_create( screen->pipe_screen, - ctx ); - - if (ctx->pipe == NULL) - goto fail; - - ctx->st = st_create_context(ctx->pipe, visual, st_share); + dri_fill_st_visual(&stvis, screen, visual); + ctx->st = stapi->create_context(stapi, screen->smapi, &stvis, st_share); if (ctx->st == NULL) goto fail; + ctx->st->st_manager_private = (void *) ctx; dri_init_extensions(ctx); @@ -81,10 +77,7 @@ dri_create_context(const __GLcontextModes * visual, fail: if (ctx && ctx->st) - st_destroy_context(ctx->st); - - if (ctx && ctx->pipe) - ctx->pipe->destroy(ctx->pipe); + ctx->st->destroy(ctx->st); FREE(ctx); return FALSE; @@ -106,11 +99,8 @@ dri_destroy_context(__DRIcontext * cPriv) * to avoid having to add code elsewhere to cope with flushing a * partially destroyed context. */ - st_flush(ctx->st, 0, NULL); - - /* Also frees ctx->pipe? - */ - st_destroy_context(ctx->st); + ctx->st->flush(ctx->st, 0, NULL); + ctx->st->destroy(ctx->st); FREE(ctx); } @@ -118,14 +108,16 @@ dri_destroy_context(__DRIcontext * cPriv) GLboolean dri_unbind_context(__DRIcontext * cPriv) { + struct st_api *stapi = dri_get_st_api(); + 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, NULL); - } + if (ctx->st == stapi->get_current(stapi)) { + ctx->st->flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + stapi->make_current(stapi, NULL, NULL, NULL); + } } } @@ -137,45 +129,47 @@ dri_make_current(__DRIcontext * cPriv, __DRIdrawable * driDrawPriv, __DRIdrawable * driReadPriv) { + struct st_api *stapi = dri_get_st_api(); + if (cPriv) { struct dri_context *ctx = dri_context(cPriv); struct dri_drawable *draw = dri_drawable(driDrawPriv); struct dri_drawable *read = dri_drawable(driReadPriv); - struct st_context *old_st = st_get_current(); + struct st_context_iface *old_st; + old_st = stapi->get_current(stapi); if (old_st && old_st != ctx->st) - st_flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL); + ctx->st->flush(old_st, PIPE_FLUSH_RENDER_CACHE, NULL); ++ctx->bind_count; if (ctx->dPriv != driDrawPriv) { ctx->dPriv = driDrawPriv; - ctx->d_stamp = driDrawPriv->lastStamp - 1; + draw->texture_stamp = driDrawPriv->lastStamp - 1; } if (ctx->rPriv != driReadPriv) { ctx->rPriv = driReadPriv; - ctx->r_stamp = driReadPriv->lastStamp - 1; + draw->texture_stamp = driReadPriv->lastStamp - 1; } - /* DRI co-state tracker currently overrides flush_frontbuffer. - * When this is fixed, will need to pass the drawable in the - * fourth parameter here so that when Mesa calls - * flush_frontbuffer directly (in front-buffer rendering), it - * will have access to the drawable argument: - */ - st_make_current(ctx->st, draw->stfb, read->stfb, ctx); - - if (__dri1_api_hooks) { - dri1_update_drawables(ctx, draw, read); - } else { - dri_update_buffer(ctx->pipe->screen, - ctx->pipe->priv); - } - } else { - st_make_current(NULL, NULL, NULL, NULL); + stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb); + } + else { + stapi->make_current(stapi, NULL, NULL, NULL); } return GL_TRUE; } +struct dri_context * +dri_get_current(void) +{ + struct st_api *stapi = dri_get_st_api(); + struct st_context_iface *st; + + st = stapi->get_current(stapi); + + return (struct dri_context *) (st) ? st->st_manager_private : NULL; +} + /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/dri_context.h b/src/gallium/state_trackers/dri/dri_context.h index f0700b9aaf..845b420cf8 100644 --- a/src/gallium/state_trackers/dri/dri_context.h +++ b/src/gallium/state_trackers/dri/dri_context.h @@ -51,9 +51,6 @@ struct dri_context driOptionCache optionCache; - unsigned int d_stamp; - unsigned int r_stamp; - drmLock *lock; boolean isLocked; boolean stLostLock; @@ -62,8 +59,7 @@ struct dri_context unsigned int bind_count; /* gallium */ - struct st_context *st; - struct pipe_context *pipe; + struct st_context_iface *st; }; static INLINE struct dri_context * @@ -84,6 +80,9 @@ dri_make_current(__DRIcontext * driContextPriv, __DRIdrawable * driDrawPriv, __DRIdrawable * driReadPriv); +struct dri_context * +dri_get_current(void); + boolean dri_create_context(const __GLcontextModes * visual, __DRIcontext * driContextPriv, diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index 9238f94299..930387f8a6 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -32,249 +32,30 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" +#include "dri_st_api.h" #include "dri1.h" -#include "main/mtypes.h" -#include "main/renderbuffer.h" -#include "state_tracker/st_context.h" -#include "state_tracker/st_public.h" -#include "state_tracker/st_cb_fbo.h" -#include "state_tracker/drm_api.h" - #include "pipe/p_screen.h" #include "util/u_format.h" #include "util/u_memory.h" #include "util/u_inlines.h" -static struct pipe_surface * -dri_surface_from_handle(struct drm_api *api, - 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 winsys_handle whandle; - - memset(&templat, 0, sizeof(templat)); - templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; - templat.target = PIPE_TEXTURE_2D; - templat.last_level = 0; - templat.depth0 = 1; - templat.format = format; - templat.width0 = width; - templat.height0 = height; - - memset(&whandle, 0, sizeof(whandle)); - whandle.handle = handle; - whandle.stride = pitch; - - texture = screen->texture_from_handle(screen, &templat, &whandle); - - if (!texture) { - debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__); - 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; -} - -/** - * Pixmaps have will have the same name of fake front and front. - */ -static boolean -dri2_check_if_pixmap(__DRIbuffer *buffers, int count) -{ - boolean found = FALSE; - boolean is_pixmap = FALSE; - unsigned name; - int i; - - for (i = 0; i < count; i++) { - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - case __DRI_BUFFER_FAKE_FRONT_LEFT: - if (found) { - is_pixmap = buffers[i].name == name; - } else { - name = buffers[i].name; - found = TRUE; - } - default: - continue; - } - } - - return is_pixmap; -} - -/** - * This will be called a drawable is known to have been resized. - */ -void -dri_get_buffers(__DRIdrawable * dPriv) -{ - - struct dri_drawable *drawable = dri_drawable(dPriv); - struct pipe_surface *surface = NULL; - struct dri_screen *st_screen = dri_screen(drawable->sPriv); - struct pipe_screen *screen = st_screen->pipe_screen; - __DRIbuffer *buffers = NULL; - __DRIscreen *dri_screen = drawable->sPriv; - __DRIdrawable *dri_drawable = drawable->dPriv; - struct drm_api *api = st_screen->api; - boolean have_depth = FALSE; - int i, count; - - if ((dri_screen->dri2.loader - && (dri_screen->dri2.loader->base.version > 2) - && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) { - buffers = (*dri_screen->dri2.loader->getBuffersWithFormat) - (dri_drawable, &dri_drawable->w, &dri_drawable->h, - drawable->attachments, drawable->num_attachments, - &count, dri_drawable->loaderPrivate); - } else { - assert(dri_screen->dri2.loader); - 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); - } - - drawable->is_pixmap = dri2_check_if_pixmap(buffers, count); - - for (i = 0; i < count; i++) { - enum pipe_format format = 0; - int index = 0; - - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - if (!st_screen->auto_fake_front) - continue; - /* fallthrough */ - case __DRI_BUFFER_FAKE_FRONT_LEFT: - index = ST_SURFACE_FRONT_LEFT; - format = drawable->color_format; - break; - case __DRI_BUFFER_BACK_LEFT: - index = ST_SURFACE_BACK_LEFT; - format = drawable->color_format; - break; - case __DRI_BUFFER_DEPTH: - case __DRI_BUFFER_DEPTH_STENCIL: - case __DRI_BUFFER_STENCIL: - index = ST_SURFACE_DEPTH; - format = drawable->depth_stencil_format; - break; - case __DRI_BUFFER_ACCUM: - default: - assert(0); - } - - if (index == ST_SURFACE_DEPTH) { - if (have_depth) - continue; - else - have_depth = TRUE; - } - - surface = dri_surface_from_handle(api, - screen, - buffers[i].name, - format, - dri_drawable->w, - dri_drawable->h, buffers[i].pitch); - - switch (buffers[i].attachment) { - case __DRI_BUFFER_FRONT_LEFT: - case __DRI_BUFFER_FAKE_FRONT_LEFT: - case __DRI_BUFFER_BACK_LEFT: - drawable->color_format = surface->format; - break; - case __DRI_BUFFER_DEPTH: - case __DRI_BUFFER_DEPTH_STENCIL: - case __DRI_BUFFER_STENCIL: - drawable->depth_stencil_format = surface->format; - break; - case __DRI_BUFFER_ACCUM: - default: - assert(0); - } - - 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); -} - /** * These are used for GLX_EXT_texture_from_pixmap */ void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, GLint format, __DRIdrawable *dPriv) { + struct dri_context *ctx = dri_context(pDRICtx); struct dri_drawable *drawable = dri_drawable(dPriv); - struct pipe_surface *ps; + struct pipe_texture *pt = + dri_get_st_framebuffer_texture(drawable->stfb, ST_ATTACHMENT_FRONT_LEFT); - if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) { - struct gl_renderbuffer *rb = - st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE); - _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb); + if (pt) { + ctx->st->teximage(ctx->st, + (target == GL_TEXTURE_2D) ? ST_TEXTURE_2D : ST_TEXTURE_RECT, + 0, drawable->stvis.color_format, pt, FALSE); } - - dri_get_buffers(drawable->dPriv); - st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps); - - if (!ps) - return; - - st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D : - ST_TEXTURE_RECT, 0, drawable->color_format); } void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, @@ -283,53 +64,6 @@ void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target, dri2_set_tex_buffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv); } -void -dri_update_buffer(struct pipe_screen *screen, void *context_private) -{ - struct dri_context *ctx = (struct dri_context *)context_private; - - if (ctx->d_stamp == *ctx->dPriv->pStamp && - ctx->r_stamp == *ctx->rPriv->pStamp) - return; - - ctx->d_stamp = *ctx->dPriv->pStamp; - ctx->r_stamp = *ctx->rPriv->pStamp; - - /* Ask the X server for new renderbuffers. */ - dri_get_buffers(ctx->dPriv); - if (ctx->dPriv != ctx->rPriv) - dri_get_buffers(ctx->rPriv); - -} - -void -dri_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, void *context_private) -{ - struct dri_context *ctx = (struct dri_context *)context_private; - struct dri_drawable *drawable = dri_drawable(ctx->dPriv); - __DRIdrawable *dri_drawable = ctx->dPriv; - __DRIscreen *dri_screen = ctx->sPriv; - - /* XXX Does this function get called with DRI1? */ - - if (ctx->dPriv == NULL) { - debug_printf("%s: no drawable bound to context\n", __func__); - return; - } - -#if 0 - /* TODO if rendering to pixmaps is slow enable this code. */ - if (drawable->is_pixmap) - return; -#else - (void)drawable; -#endif - - (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable, - dri_drawable->loaderPrivate); -} - /** * This is called when we need to set up GL rendering to a new X window. */ @@ -340,7 +74,6 @@ dri_create_buffer(__DRIscreen * sPriv, { struct dri_screen *screen = sPriv->private; struct dri_drawable *drawable = NULL; - int i; if (isPixmap) goto fail; /* not implemented */ @@ -349,45 +82,8 @@ dri_create_buffer(__DRIscreen * sPriv, if (drawable == NULL) goto fail; - if (visual->redBits == 8) { - if (visual->alphaBits == 8) - drawable->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; - else - drawable->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; - } else { - drawable->color_format = PIPE_FORMAT_B5G6R5_UNORM; - } - - switch(visual->depthBits) { - default: - case 0: - drawable->depth_stencil_format = PIPE_FORMAT_NONE; - break; - case 16: - drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; - break; - case 24: - if (visual->stencilBits == 0) { - drawable->depth_stencil_format = (screen->d_depth_bits_last) ? - PIPE_FORMAT_Z24X8_UNORM: - PIPE_FORMAT_X8Z24_UNORM; - } else { - drawable->depth_stencil_format = (screen->sd_depth_bits_last) ? - PIPE_FORMAT_Z24S8_UNORM: - PIPE_FORMAT_S8Z24_UNORM; - } - break; - case 32: - drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; - break; - } - - drawable->stfb = st_create_framebuffer(visual, - drawable->color_format, - drawable->depth_stencil_format, - drawable->depth_stencil_format, - dPriv->w, - dPriv->h, (void *)drawable); + dri_fill_st_visual(&drawable->stvis, screen, visual); + drawable->stfb = dri_create_st_framebuffer(drawable); if (drawable->stfb == NULL) goto fail; @@ -395,48 +91,6 @@ dri_create_buffer(__DRIscreen * sPriv, drawable->dPriv = dPriv; dPriv->driverPrivate = (void *)drawable; - /* setup dri2 buffers information */ - /* TODO incase of double buffer visual, delay fake creation */ - i = 0; - if (sPriv->dri2.loader - && (sPriv->dri2.loader->base.version > 2) - && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) { - drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - drawable->attachments[i++] = visual->rgbBits; - if (!screen->auto_fake_front) { - drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; - drawable->attachments[i++] = visual->rgbBits; - } - if (visual->doubleBufferMode) { - drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; - drawable->attachments[i++] = visual->rgbBits; - } - if (visual->depthBits && visual->stencilBits) { - drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; - drawable->attachments[i++] = visual->depthBits + visual->stencilBits; - } else if (visual->depthBits) { - drawable->attachments[i++] = __DRI_BUFFER_DEPTH; - drawable->attachments[i++] = visual->depthBits; - } else if (visual->stencilBits) { - drawable->attachments[i++] = __DRI_BUFFER_STENCIL; - drawable->attachments[i++] = visual->stencilBits; - } - drawable->num_attachments = i / 2; - } else { - drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (!screen->auto_fake_front) - drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; - if (visual->doubleBufferMode) - drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (visual->depthBits && visual->stencilBits) - drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; - else if (visual->depthBits) - drawable->attachments[i++] = __DRI_BUFFER_DEPTH; - else if (visual->stencilBits) - drawable->attachments[i++] = __DRI_BUFFER_STENCIL; - drawable->num_attachments = i; - } - drawable->desired_fences = 2; return GL_TRUE; @@ -449,12 +103,18 @@ void dri_destroy_buffer(__DRIdrawable * dPriv) { struct dri_drawable *drawable = dri_drawable(dPriv); - - st_unreference_framebuffer(drawable->stfb); - drawable->desired_fences = 0; + int i; dri1_swap_fences_clear(drawable); + pipe_surface_reference(&drawable->dri1_surface, NULL); + for (i = 0; i < ST_ATTACHMENT_COUNT; i++) + pipe_texture_reference(&drawable->textures[i], NULL); + + dri_destroy_st_framebuffer(drawable->stfb); + + drawable->desired_fences = 0; + FREE(drawable); } diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h index ea66c483a1..7f687b65f2 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.h +++ b/src/gallium/state_trackers/dri/dri_drawable.h @@ -46,20 +46,15 @@ struct dri_drawable __DRIdrawable *dPriv; __DRIscreen *sPriv; - unsigned attachments[8]; - unsigned num_attachments; - - boolean is_pixmap; + /* gallium */ + struct st_framebuffer_iface *stfb; + struct st_visual stvis; __DRIbuffer old[8]; unsigned old_num; unsigned old_w; unsigned old_h; - /* gallium */ - struct st_framebuffer *stfb; - struct st_visual stvis; - struct pipe_texture *textures[ST_ATTACHMENT_COUNT]; unsigned int texture_mask, texture_stamp; @@ -69,8 +64,8 @@ struct dri_drawable unsigned int desired_fences; unsigned int cur_fences; - enum pipe_format color_format; - enum pipe_format depth_stencil_format; + /* used only by DRI1 */ + struct pipe_surface *dri1_surface; }; static INLINE struct dri_drawable * @@ -87,15 +82,6 @@ dri_create_buffer(__DRIscreen * sPriv, __DRIdrawable * dPriv, const __GLcontextModes * visual, boolean isPixmap); -void -dri_update_buffer(struct pipe_screen *screen, void *context_private); - -void -dri_flush_frontbuffer(struct pipe_screen *screen, - struct pipe_surface *surf, void *context_private); - -void dri_get_buffers(__DRIdrawable * dPriv); - void dri_destroy_buffer(__DRIdrawable * dPriv); void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target, diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c index 800677a2d1..df458e1eb0 100644 --- a/src/gallium/state_trackers/dri/dri_extensions.c +++ b/src/gallium/state_trackers/dri/dri_extensions.c @@ -38,9 +38,11 @@ void dri_init_extensions(struct dri_context *ctx) { + struct st_context *st = (struct st_context *) ctx->st; + /* New extensions should be added in mesa/state_tracker/st_extensions.c * and not in this file. */ - driInitExtensions(ctx->st->ctx, NULL, GL_FALSE); + driInitExtensions(st->ctx, NULL, GL_FALSE); } /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index cffe3b33b2..17b9f1c5fa 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -36,8 +36,10 @@ #include "dri_screen.h" #include "dri_context.h" #include "dri_drawable.h" +#include "dri_st_api.h" #include "dri1.h" +#include "util/u_inlines.h" #include "pipe/p_screen.h" #include "pipe/p_format.h" #include "state_tracker/drm_api.h" @@ -66,10 +68,23 @@ dri2_flush_drawable(__DRIdrawable *draw) { } +static void +dri2_invalidate_drawable(__DRIdrawable *dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct dri_context *ctx = dri_context(dPriv->driContextPriv); + + dri2InvalidateDrawable(dPriv); + drawable->dPriv->lastStamp = *drawable->dPriv->pStamp; + + if (ctx) + ctx->st->notify_invalid_framebuffer(ctx->st, drawable->stfb); +} + static const __DRI2flushExtension dri2FlushExtension = { { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, dri2_flush_drawable, - dri2InvalidateDrawable, + dri2_invalidate_drawable, }; static const __DRIextension *dri_screen_extensions[] = { @@ -226,6 +241,68 @@ dri_fill_in_modes(struct dri_screen *screen, return (const __DRIconfig **)configs; } +/** + * Roughly the converse of dri_fill_in_modes. + */ +void +dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, + const __GLcontextModes *mode) +{ + memset(stvis, 0, sizeof(*stvis)); + + stvis->samples = mode->samples; + stvis->render_buffer = ST_ATTACHMENT_INVALID; + + if (mode->redBits == 8) { + if (mode->alphaBits == 8) + stvis->color_format = PIPE_FORMAT_B8G8R8A8_UNORM; + else + stvis->color_format = PIPE_FORMAT_B8G8R8X8_UNORM; + } else { + stvis->color_format = PIPE_FORMAT_B5G6R5_UNORM; + } + + switch (mode->depthBits) { + default: + case 0: + stvis->depth_stencil_format = PIPE_FORMAT_NONE; + break; + case 16: + stvis->depth_stencil_format = PIPE_FORMAT_Z16_UNORM; + break; + case 24: + if (mode->stencilBits == 0) { + stvis->depth_stencil_format = (screen->d_depth_bits_last) ? + PIPE_FORMAT_Z24X8_UNORM: + PIPE_FORMAT_X8Z24_UNORM; + } else { + stvis->depth_stencil_format = (screen->sd_depth_bits_last) ? + PIPE_FORMAT_Z24S8_UNORM: + PIPE_FORMAT_S8Z24_UNORM; + } + break; + case 32: + stvis->depth_stencil_format = PIPE_FORMAT_Z32_UNORM; + break; + } + + stvis->accum_format = (mode->haveAccumBuffer) ? + PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE; + + stvis->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK; + if (mode->doubleBufferMode) + stvis->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; + if (mode->stereoMode) { + stvis->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; + if (mode->doubleBufferMode) + stvis->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; + } + + if (mode->haveDepthBuffer || mode->haveStencilBuffer) + stvis->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK; + /* let the state tracker allocate the accum buffer */ +} + /** * Get information about previous buffer swaps. */ @@ -238,6 +315,33 @@ dri_get_swap_info(__DRIdrawable * dPriv, __DRIswapInfo * sInfo) return 0; } +static void +dri_destroy_screen(__DRIscreen * sPriv) +{ + struct dri_screen *screen = dri_screen(sPriv); + int i; + + if (screen->dri1_pipe) + screen->dri1_pipe->destroy(screen->dri1_pipe); + + if (screen->smapi) + dri_destroy_st_manager(screen->smapi); + if (screen->pipe_screen) + screen->pipe_screen->destroy(screen->pipe_screen); + + for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { + FREE(screen->optionCache.info[i].name); + FREE(screen->optionCache.info[i].ranges); + } + + FREE(screen->optionCache.info); + FREE(screen->optionCache.values); + + FREE(screen); + sPriv->private = NULL; + sPriv->extensions = NULL; +} + /** * This is the driver specific part of the createNewScreen entry point. * @@ -253,7 +357,7 @@ dri_init_screen2(__DRIscreen * sPriv) screen = CALLOC_STRUCT(dri_screen); if (!screen) - goto fail; + return NULL; screen->api = drm_api_create(); screen->sPriv = sPriv; @@ -268,9 +372,9 @@ dri_init_screen2(__DRIscreen * sPriv) goto fail; } - /* We need to hook in here */ - screen->pipe_screen->update_buffer = dri_update_buffer; - screen->pipe_screen->flush_frontbuffer = dri_flush_frontbuffer; + screen->smapi = dri_create_st_manager(screen); + if (!screen->smapi) + goto fail; driParseOptionInfo(&screen->optionCache, __driConfigOptions, __driNConfigOptions); @@ -279,30 +383,11 @@ dri_init_screen2(__DRIscreen * sPriv) dri2_ext->getBuffersWithFormat != NULL; return dri_fill_in_modes(screen, 32); - fail: +fail: + dri_destroy_screen(sPriv); return NULL; } -static void -dri_destroy_screen(__DRIscreen * sPriv) -{ - struct dri_screen *screen = dri_screen(sPriv); - int i; - - screen->pipe_screen->destroy(screen->pipe_screen); - - for (i = 0; i < (1 << screen->optionCache.tableSize); ++i) { - FREE(screen->optionCache.info[i].name); - FREE(screen->optionCache.info[i].ranges); - } - - FREE(screen->optionCache.info); - FREE(screen->optionCache.values); - - FREE(screen); - sPriv->private = NULL; -} - const struct __DriverAPIRec driDriverAPI = { .DestroyScreen = dri_destroy_screen, .CreateContext = dri_create_context, diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h index 3130135692..e9944e0f63 100644 --- a/src/gallium/state_trackers/dri/dri_screen.h +++ b/src/gallium/state_trackers/dri/dri_screen.h @@ -36,6 +36,9 @@ #include "xmlconfig.h" #include "pipe/p_compiler.h" +#include "pipe/p_context.h" +#include "pipe/p_state.h" +#include "state_tracker/st_api.h" struct dri_screen { @@ -58,6 +61,11 @@ struct dri_screen boolean d_depth_bits_last; boolean sd_depth_bits_last; boolean auto_fake_front; + + struct st_manager *smapi; + + /* used only by DRI1 */ + struct pipe_context *dri1_pipe; }; /** cast wrapper */ @@ -72,6 +80,10 @@ extern const uint __driNConfigOptions; const __DRIconfig ** dri_fill_in_modes(struct dri_screen *screen, unsigned pixel_bits); +void +dri_fill_st_visual(struct st_visual *stvis, struct dri_screen *screen, + const __GLcontextModes *mode); + #endif /* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri/dri_st_api.c b/src/gallium/state_trackers/dri/dri_st_api.c index 379515152e..2cde01967d 100644 --- a/src/gallium/state_trackers/dri/dri_st_api.c +++ b/src/gallium/state_trackers/dri/dri_st_api.c @@ -274,8 +274,8 @@ dri_st_framebuffer_validate(struct st_framebuffer_iface *stfbi, if (drawable->texture_stamp != drawable->dPriv->lastStamp || (statt_mask & ~drawable->texture_mask)) { if (__dri1_api_hooks) { - /* TODO */ - return FALSE; + dri1_allocate_textures(drawable, + drawable->dPriv->w, drawable->dPriv->h, statt_mask); } else { __DRIbuffer *buffers; @@ -309,9 +309,12 @@ dri_st_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, struct __DRIdri2LoaderExtensionRec *loader = drawable->sPriv->dri2.loader; - /* TODO */ - if (__dri1_api_hooks) - return FALSE; + if (__dri1_api_hooks) { + struct pipe_texture *ptex = drawable->textures[statt]; + if (ptex) + dri1_flush_frontbuffer(drawable, ptex); + return TRUE; + } if (statt == ST_ATTACHMENT_FRONT_LEFT && loader->flushFrontBuffer) { loader->flushFrontBuffer(drawable->dPriv, -- cgit v1.2.3 From 92827cd4511fabcaeb8abfdd11122e04502d5944 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Fri, 19 Mar 2010 02:38:10 +0200 Subject: st/dri: fix bug in allocate_textures --- src/gallium/state_trackers/dri/dri1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri1.c b/src/gallium/state_trackers/dri/dri1.c index 41dba82d52..240bc69efd 100644 --- a/src/gallium/state_trackers/dri/dri1.c +++ b/src/gallium/state_trackers/dri/dri1.c @@ -451,7 +451,7 @@ dri1_allocate_textures(struct dri_drawable *drawable, break; } - if (templ.format != PIPE_FORMAT_NONE) { + if (format != PIPE_FORMAT_NONE) { templ.format = format; templ.tex_usage = tex_usage; -- cgit v1.2.3 From fe5f070ef94219f12196bff6cb3274756ea03660 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Fri, 19 Mar 2010 19:16:21 +0000 Subject: st/dri: fix bug in make_current --- src/gallium/state_trackers/dri/dri_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/gallium') diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index c1848b026c..54568a8b22 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -149,7 +149,7 @@ dri_make_current(__DRIcontext * cPriv, } if (ctx->rPriv != driReadPriv) { ctx->rPriv = driReadPriv; - draw->texture_stamp = driReadPriv->lastStamp - 1; + read->texture_stamp = driReadPriv->lastStamp - 1; } stapi->make_current(stapi, ctx->st, draw->stfb, read->stfb); -- cgit v1.2.3