diff options
Diffstat (limited to 'src/gallium/state_trackers/dri2')
-rw-r--r-- | src/gallium/state_trackers/dri2/Makefile | 28 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_context.c | 168 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_context.h | 96 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_drawable.c | 315 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_drawable.h | 84 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_extensions.c | 117 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_screen.c | 259 | ||||
-rw-r--r-- | src/gallium/state_trackers/dri2/dri_screen.h | 90 |
8 files changed, 1157 insertions, 0 deletions
diff --git a/src/gallium/state_trackers/dri2/Makefile b/src/gallium/state_trackers/dri2/Makefile new file mode 100644 index 00000000000..47750e997e9 --- /dev/null +++ b/src/gallium/state_trackers/dri2/Makefile @@ -0,0 +1,28 @@ +TOP = ../../../.. +include $(TOP)/configs/current + +LIBNAME = dri2drm + +LIBRARY_INCLUDES = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/drivers/dri/common \ + -I$(TOP)/src/mesa/main \ + $(shell pkg-config --cflags-only-I libdrm) + + +C_SOURCES = \ + dri_context.c \ + dri_screen.c \ + dri_drawable.c \ + dri_extensions.c + +# $(TOP)/src/mesa/drivers/dri/common/utils.c \ + $(TOP)/src/mesa/drivers/dri/common/vblank.c \ + $(TOP)/src/mesa/drivers/dri/common/dri_util.c \ + $(TOP)/src/mesa/drivers/dri/common/xmlconfig.c \ + $(TOP)/src/mesa/drivers/common/driverfuncs.c \ + $(TOP)/src/mesa/drivers/dri/common/texmem.c \ + $(TOP)/src/mesa/drivers/dri/common/drirenderbuffer.c + +include ../../Makefile.template diff --git a/src/gallium/state_trackers/dri2/dri_context.c b/src/gallium/state_trackers/dri2/dri_context.c new file mode 100644 index 00000000000..a8a94be176c --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_context.c @@ -0,0 +1,168 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#include "dri_screen.h" + +#include "dri_drawable.h" + + +#include "state_tracker/drm_api.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "pipe/p_context.h" + +#include "dri_context.h" + +#include "util/u_memory.h" + + +GLboolean +dri_create_context(const __GLcontextModes *visual, + __DRIcontextPrivate *cPriv, + void *sharedContextPrivate) +{ + __DRIscreenPrivate *sPriv = cPriv->driScreenPriv; + struct dri_screen *screen = dri_screen(sPriv); + struct dri_context *ctx = NULL; + struct st_context *st_share = NULL; + + if (sharedContextPrivate) { + st_share = ((struct dri_context *) sharedContextPrivate)->st; + } + + ctx = CALLOC_STRUCT(dri_context); + if (ctx == NULL) + goto fail; + + cPriv->driverPrivate = ctx; + ctx->cPriv = cPriv; + ctx->sPriv = sPriv; + + driParseConfigFiles(&ctx->optionCache, + &screen->optionCache, + sPriv->myNum, + "dri"); + + ctx->pipe = drm_api_hocks.create_context(screen->pipe_screen); + + if (ctx->pipe == NULL) + goto fail; + + ctx->pipe->priv = ctx; /* I guess */ + + ctx->st = st_create_context(ctx->pipe, visual, st_share); + if (ctx->st == NULL) + goto fail; + + dri_init_extensions(ctx); + + return GL_TRUE; + +fail: + if (ctx && ctx->st) + st_destroy_context(ctx->st); + + if (ctx && ctx->pipe) + ctx->pipe->destroy(ctx->pipe); + + FREE(ctx); + return FALSE; +} + + +void +dri_destroy_context(__DRIcontextPrivate *cPriv) +{ + struct dri_context *ctx = dri_context(cPriv); + struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); + + /* No particular reason to wait for command completion before + * destroying a context, but it is probably worthwhile flushing it + * to avoid having to add code elsewhere to cope with flushing a + * partially destroyed context. + */ + st_flush(ctx->st, 0, NULL); + + if (screen->dummyContext == ctx) + screen->dummyContext = NULL; + + /* Also frees ctx->pipe? + */ + st_destroy_context(ctx->st); + + FREE(ctx); +} + + +GLboolean +dri_unbind_context(__DRIcontextPrivate *cPriv) +{ + struct dri_context *ctx = dri_context(cPriv); + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + /* XXX make_current(NULL)? */ + return GL_TRUE; +} + + +GLboolean +dri_make_current(__DRIcontextPrivate *cPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv) +{ + if (cPriv) { + struct dri_context *ctx = dri_context(cPriv); + struct dri_screen *screen = dri_screen(cPriv->driScreenPriv); + struct dri_drawable *draw = dri_drawable(driDrawPriv); + struct dri_drawable *read = dri_drawable(driReadPriv); + + /* This is for situations in which we need a rendering context but + * there may not be any currently bound. + */ + screen->dummyContext = ctx; + + st_make_current(ctx->st, + draw->stfb, + read->stfb); + + ctx->dPriv = driDrawPriv; + + if (driDrawPriv) + dri_get_buffers(driDrawPriv); + if (driDrawPriv != driReadPriv && driReadPriv) + dri_get_buffers(driReadPriv); + } else { + st_make_current(NULL, NULL, NULL); + } + + return GL_TRUE; +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_context.h b/src/gallium/state_trackers/dri2/dri_context.h new file mode 100644 index 00000000000..e910472700c --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_context.h @@ -0,0 +1,96 @@ +/************************************************************************** + * + * Copyright (C) 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#ifndef DRI_CONTEXT_H +#define DRI_CONTEXT_H + +#include "pipe/p_compiler.h" +#include "drm.h" +#include "dri_util.h" + + +struct pipe_context; +struct pipe_fence; +struct st_context; +struct dri_drawable; + + +struct dri_context +{ + /* dri */ + __DRIscreenPrivate *sPriv; + __DRIcontextPrivate *cPriv; + __DRIdrawablePrivate *dPriv; + + driOptionCache optionCache; + + /* gallium */ + struct st_context *st; + struct pipe_context *pipe; +}; + + +static INLINE struct dri_context * +dri_context(__DRIcontextPrivate *driContextPriv) +{ + return (struct dri_context *) driContextPriv->driverPrivate; +} + + +/*********************************************************************** + * dri_context.c + */ +void +dri_destroy_context(__DRIcontextPrivate * driContextPriv); + +boolean +dri_unbind_context(__DRIcontextPrivate * driContextPriv); + +boolean +dri_make_current(__DRIcontextPrivate * driContextPriv, + __DRIdrawablePrivate * driDrawPriv, + __DRIdrawablePrivate * driReadPriv); + +boolean +dri_create_context(const __GLcontextModes * visual, + __DRIcontextPrivate * driContextPriv, + void *sharedContextPrivate); + + +/*********************************************************************** + * dri_extensions.c + */ +void +dri_init_extensions(struct dri_context *ctx); + +#endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_drawable.c b/src/gallium/state_trackers/dri2/dri_drawable.c new file mode 100644 index 00000000000..120d45bc036 --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_drawable.c @@ -0,0 +1,315 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/drm_api.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_fbo.h" + +#include "util/u_memory.h" + + +static struct pipe_surface * +dri_surface_from_handle(struct pipe_screen *screen, + unsigned handle, + enum pipe_format format, + unsigned width, + unsigned height, + unsigned pitch) +{ + struct pipe_surface *surface = NULL; + struct pipe_texture *texture = NULL; + struct pipe_texture templat; + struct pipe_buffer *buf = NULL; + + buf = drm_api_hocks.buffer_from_handle(screen, "dri2 buffer", handle); + if (!buf) + return NULL; + + memset(&templat, 0, sizeof(templat)); + templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET; + templat.target = PIPE_TEXTURE_2D; + templat.last_level = 0; + templat.depth[0] = 1; + templat.format = format; + templat.width[0] = width; + templat.height[0] = height; + pf_get_block(templat.format, &templat.block); + + texture = screen->texture_blanket(screen, + &templat, + &pitch, + buf); + + /* we don't need the buffer from this point on */ + pipe_buffer_reference(screen, &buf, NULL); + + if (!texture) + return NULL; + + surface = screen->get_tex_surface(screen, texture, 0, 0, 0, + PIPE_BUFFER_USAGE_GPU_READ | + PIPE_BUFFER_USAGE_GPU_WRITE); + + /* we don't need the texture from this point on */ + pipe_texture_reference(&texture, NULL); + return surface; +} + + +/** + * This will be called a drawable is known to have been resized. + */ +void +dri_get_buffers(__DRIdrawablePrivate *dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_surface *surface = NULL; + struct pipe_screen *screen = dri_screen(drawable->sPriv)->pipe_screen; + __DRIbuffer *buffers = NULL; + __DRIscreen *dri_screen = drawable->sPriv; + __DRIdrawable *dri_drawable = drawable->dPriv; + boolean have_depth = FALSE; + int i, count; + + buffers = (*dri_screen->dri2.loader->getBuffers)(dri_drawable, + &dri_drawable->w, + &dri_drawable->h, + drawable->attachments, + drawable->num_attachments, + &count, + dri_drawable->loaderPrivate); + + if (buffers == NULL) { + return; + } + + /* set one cliprect to cover the whole dri_drawable */ + dri_drawable->x = 0; + dri_drawable->y = 0; + dri_drawable->backX = 0; + dri_drawable->backY = 0; + dri_drawable->numClipRects = 1; + dri_drawable->pClipRects[0].x1 = 0; + dri_drawable->pClipRects[0].y1 = 0; + dri_drawable->pClipRects[0].x2 = dri_drawable->w; + dri_drawable->pClipRects[0].y2 = dri_drawable->h; + dri_drawable->numBackClipRects = 1; + dri_drawable->pBackClipRects[0].x1 = 0; + dri_drawable->pBackClipRects[0].y1 = 0; + dri_drawable->pBackClipRects[0].x2 = dri_drawable->w; + dri_drawable->pBackClipRects[0].y2 = dri_drawable->h; + + for (i = 0; i < count; i++) { + enum pipe_format format = 0; + int index = 0; + + switch (buffers[i].attachment) { + case __DRI_BUFFER_FRONT_LEFT: + index = ST_SURFACE_FRONT_LEFT; + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case __DRI_BUFFER_BACK_LEFT: + index = ST_SURFACE_BACK_LEFT; + format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + case __DRI_BUFFER_DEPTH: + index = ST_SURFACE_DEPTH; + format = PIPE_FORMAT_Z24S8_UNORM; + break; + case __DRI_BUFFER_STENCIL: + index = ST_SURFACE_DEPTH; + format = PIPE_FORMAT_Z24S8_UNORM; + break; + case __DRI_BUFFER_ACCUM: + default: + assert(0); + } + assert(buffers[i].cpp == 4); + + if (index == ST_SURFACE_DEPTH) { + if (have_depth) + continue; + else + have_depth = TRUE; + } + + surface = dri_surface_from_handle(screen, + buffers[i].name, + format, + dri_drawable->w, + dri_drawable->h, + buffers[i].pitch); + + st_set_framebuffer_surface(drawable->stfb, index, surface); + pipe_surface_reference(&surface, NULL); + } + /* this needed, or else the state tracker fails to pick the new buffers */ + st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h); +} + + +void +dri_swap_buffers(__DRIdrawablePrivate * dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_surface *back_surf; + + assert(drawable); + assert(drawable->stfb); + + st_get_framebuffer_surface(drawable->stfb, + ST_SURFACE_BACK_LEFT, + &back_surf); + if (back_surf) { + st_notify_swapbuffers(drawable->stfb); + /* TODO do stuff here */ + st_notify_swapbuffers_complete(drawable->stfb); + } +} + + +/** + * Called via glXCopySubBufferMESA() to copy a subrect of the back + * buffer to the front buffer/screen. + */ +void +dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, int x, int y, int w, int h) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + struct pipe_surface *back_surf; + + assert(drawable); + assert(drawable->stfb); + + st_get_framebuffer_surface(drawable->stfb, + ST_SURFACE_BACK_LEFT, + &back_surf); + if (back_surf) { + drm_clip_rect_t rect; + rect.x1 = x; + rect.y1 = y; + rect.x2 = w; + rect.y2 = h; + + /* do stuff here */ + } +} + + +/** + * This is called when we need to set up GL rendering to a new X window. + */ +boolean +dri_create_buffer(__DRIscreenPrivate *sPriv, + __DRIdrawablePrivate *dPriv, + const __GLcontextModes *visual, + boolean isPixmap) +{ + enum pipe_format colorFormat, depthFormat, stencilFormat; + struct dri_drawable *drawable = NULL; + int i; + + if (isPixmap) + goto fail; /* not implemented */ + + drawable = CALLOC_STRUCT(dri_drawable); + if (drawable == NULL) + goto fail; + + /* XXX: todo: use the pipe_screen queries to figure out which + * render targets are supportable. + */ + assert(visual->redBits == 8); + assert(visual->depthBits == 24 || visual->depthBits == 0); + assert(visual->stencilBits == 8 || visual->stencilBits == 0); + + colorFormat = PIPE_FORMAT_A8R8G8B8_UNORM; + + if (visual->depthBits) + depthFormat = PIPE_FORMAT_S8Z24_UNORM; + else + depthFormat = PIPE_FORMAT_NONE; + + if (visual->stencilBits) + stencilFormat = PIPE_FORMAT_S8Z24_UNORM; + else + stencilFormat = PIPE_FORMAT_NONE; + + drawable->stfb = st_create_framebuffer(visual, + colorFormat, + depthFormat, + stencilFormat, + dPriv->w, + dPriv->h, + (void*) drawable); + if (drawable->stfb == NULL) + goto fail; + + drawable->sPriv = sPriv; + drawable->dPriv = dPriv; + dPriv->driverPrivate = (void *) drawable; + + /* setup dri2 buffers information */ + i = 0; + drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (visual->depthBits) + drawable->attachments[i++] = __DRI_BUFFER_DEPTH; + if (visual->stencilBits) + drawable->attachments[i++] = __DRI_BUFFER_STENCIL; + drawable->num_attachments = i; + + return GL_TRUE; +fail: + FREE(drawable); + return GL_FALSE; +} + + +void +dri_destroy_buffer(__DRIdrawablePrivate *dPriv) +{ + struct dri_drawable *drawable = dri_drawable(dPriv); + + st_unreference_framebuffer(drawable->stfb); + + FREE(drawable); +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_drawable.h b/src/gallium/state_trackers/dri2/dri_drawable.h new file mode 100644 index 00000000000..d40d09c9b5b --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_drawable.h @@ -0,0 +1,84 @@ +/************************************************************************** + * + * 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. + * + **************************************************************************/ + +#ifndef DRI_DRAWABLE_H +#define DRI_DRAWABLE_H + +#include "pipe/p_compiler.h" + +struct pipe_surface; +struct pipe_fence; +struct st_framebuffer; + + +struct dri_drawable +{ + /* dri */ + __DRIdrawablePrivate *dPriv; + __DRIscreenPrivate *sPriv; + + unsigned attachments[8]; + unsigned num_attachments; + + /* gallium */ + struct st_framebuffer *stfb; +}; + + +static INLINE struct dri_drawable * +dri_drawable(__DRIdrawablePrivate * driDrawPriv) +{ + return (struct dri_drawable *) driDrawPriv->driverPrivate; +} + + +/*********************************************************************** + * dri_drawable.c + */ +boolean +dri_create_buffer(__DRIscreenPrivate *sPriv, + __DRIdrawablePrivate *dPriv, + const __GLcontextModes *visual, + boolean isPixmap); + +void +dri_swap_buffers(__DRIdrawablePrivate * dPriv); + +void +dri_copy_sub_buffer(__DRIdrawablePrivate * dPriv, + int x, int y, + int w, int h); + +void +dri_get_buffers(__DRIdrawablePrivate * dPriv); + +void +dri_destroy_buffer(__DRIdrawablePrivate *dPriv); + +#endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_extensions.c b/src/gallium/state_trackers/dri2/dri_extensions.c new file mode 100644 index 00000000000..9c7a27282b2 --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_extensions.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 <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#include "dri_screen.h" +#include "dri_context.h" +#include "state_tracker/st_context.h" + +#define need_GL_ARB_multisample +#define need_GL_ARB_point_parameters +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_ARB_vertex_program +#define need_GL_ARB_window_pos +#define need_GL_EXT_blend_color +#define need_GL_EXT_blend_equation_separate +#define need_GL_EXT_blend_func_separate +#define need_GL_EXT_blend_minmax +#define need_GL_EXT_cull_vertex +#define need_GL_EXT_fog_coord +#define need_GL_EXT_framebuffer_object +#define need_GL_EXT_multi_draw_arrays +#define need_GL_EXT_secondary_color +#define need_GL_NV_vertex_program +#include "extension_helper.h" + + +/** + * Extension strings exported by the driver. + */ +const struct dri_extension card_extensions[] = { + {"GL_ARB_multisample", GL_ARB_multisample_functions}, + {"GL_ARB_multitexture", NULL}, + {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions}, + {"GL_ARB_texture_border_clamp", NULL}, + {"GL_ARB_texture_compression", GL_ARB_texture_compression_functions}, + {"GL_ARB_texture_cube_map", NULL}, + {"GL_ARB_texture_env_add", NULL}, + {"GL_ARB_texture_env_combine", NULL}, + {"GL_ARB_texture_env_dot3", NULL}, + {"GL_ARB_texture_mirrored_repeat", NULL}, + {"GL_ARB_texture_rectangle", NULL}, + {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions}, + {"GL_ARB_pixel_buffer_object", NULL}, + {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions}, + {"GL_ARB_window_pos", GL_ARB_window_pos_functions}, + {"GL_EXT_blend_color", GL_EXT_blend_color_functions}, + {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions}, + {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions}, + {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions}, + {"GL_EXT_blend_subtract", NULL}, + {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions}, + {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions}, + {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions}, + {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions}, + {"GL_EXT_packed_depth_stencil", NULL}, + {"GL_EXT_pixel_buffer_object", NULL}, + {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions}, + {"GL_EXT_stencil_wrap", NULL}, + {"GL_EXT_texture_edge_clamp", NULL}, + {"GL_EXT_texture_env_combine", NULL}, + {"GL_EXT_texture_env_dot3", NULL}, + {"GL_EXT_texture_filter_anisotropic", NULL}, + {"GL_EXT_texture_lod_bias", NULL}, + {"GL_3DFX_texture_compression_FXT1", NULL}, + {"GL_APPLE_client_storage", NULL}, + {"GL_MESA_pack_invert", NULL}, + {"GL_MESA_ycbcr_texture", NULL}, + {"GL_NV_blend_square", NULL}, + {"GL_NV_vertex_program", GL_NV_vertex_program_functions}, + {"GL_NV_vertex_program1_1", NULL}, + {"GL_SGIS_generate_mipmap", NULL }, + {NULL, NULL} +}; + + +void +dri_init_extensions(struct dri_context *ctx) +{ + /* The card_extensions list should be pruned according to the + * capabilities of the pipe_screen. This is actually something + * that can/should be done inside st_create_context(). + */ + if (ctx) + driInitExtensions(ctx->st->ctx, card_extensions, GL_TRUE); + else + driInitExtensions(NULL, card_extensions, GL_FALSE); +} + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_screen.c b/src/gallium/state_trackers/dri2/dri_screen.c new file mode 100644 index 00000000000..1fef5382946 --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_screen.c @@ -0,0 +1,259 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#include "utils.h" +#include "vblank.h" +#include "xmlpool.h" + +#include "dri_screen.h" +#include "dri_context.h" +#include "dri_drawable.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "pipe/p_inlines.h" +#include "state_tracker/drm_api.h" +#include "state_tracker/st_public.h" +#include "state_tracker/st_cb_fbo.h" + + +PUBLIC const char __driConfigOptions[] = + DRI_CONF_BEGIN DRI_CONF_SECTION_PERFORMANCE + DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS) + DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0) + DRI_CONF_SECTION_END DRI_CONF_SECTION_QUALITY + /*DRI_CONF_FORCE_S3TC_ENABLE(false)*/ + DRI_CONF_ALLOW_LARGE_TEXTURES(1) + DRI_CONF_SECTION_END DRI_CONF_END; + + +const uint __driNConfigOptions = 3; + + +static const __DRIextension *dri_screen_extensions[] = { + &driReadDrawableExtension, + &driCopySubBufferExtension.base, + &driSwapControlExtension.base, + &driFrameTrackingExtension.base, + &driMediaStreamCounterExtension.base, + NULL +}; + + +static void +dri_get_drm_minor(struct dri_screen *screen) +{ + /* TODO get the real minor */ + screen->minor = 0; +} + + +static void +dri_get_device_id(struct dri_screen *screen) +{ + char path[512]; + FILE *file; + + /* + * There must be a better way to get the deviceID. + * XXX this only works on Linux. + */ + snprintf(path, sizeof(path), "/sys/class/drm/card%d/device/device", screen->minor); + file = fopen(path, "r"); + if (!file) { + return; + } + + fgets(path, sizeof(path), file); + sscanf(path, "%x", &screen->deviceID); + fclose(file); +} + + +static const __DRIconfig ** +dri_fill_in_modes(__DRIscreenPrivate *psp, + unsigned pixel_bits, unsigned depth_bits, + unsigned stencil_bits, GLboolean have_back_buffer) +{ + __DRIconfig **configs; + __GLcontextModes *m; + unsigned num_modes; + uint8_t depth_bits_array[3]; + uint8_t stencil_bits_array[3]; + uint8_t msaa_samples_array[1]; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + unsigned msaa_samples_factor; + GLenum fb_format; + GLenum fb_type; + int i; + + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML + }; + + /* TODO probe the hardware of what is supports */ + depth_bits_array[0] = 0; + depth_bits_array[1] = 24; + depth_bits_array[2] = 24; + + stencil_bits_array[0] = 0; /* no depth or stencil */ + stencil_bits_array[1] = 0; /* z24x8 */ + stencil_bits_array[2] = 8; /* z24s8 */ + + msaa_samples_array[0] = 0; + + depth_buffer_factor = 3; + back_buffer_factor = 3; + msaa_samples_factor = 1; + + num_modes = depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4; + + if (pixel_bits == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } + else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + configs = driCreateConfigs(fb_format, fb_type, + depth_bits_array, + stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + msaa_samples_array, msaa_samples_factor); + if (configs == NULL) { + debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__); + return NULL; + } + + for (i = 0; configs[i]; i++) { + m = &configs[i]->modes; + if ((m->stencilBits != 0) && (m->stencilBits != stencil_bits)) { + m->visualRating = GLX_SLOW_CONFIG; + } + } + + return (const const __DRIconfig **) configs; +} + + +/** + * Get information about previous buffer swaps. + */ +int +dri_get_swap_info(__DRIdrawablePrivate * dPriv, + __DRIswapInfo * sInfo) +{ + if (dPriv == NULL || + dPriv->driverPrivate == NULL || + sInfo == NULL) + return -1; + else + return 0; +} + + +/** + * This is the driver specific part of the createNewScreen entry point. + * + * Returns the __GLcontextModes supported by this driver. + */ +const __DRIconfig ** +dri_init_screen2(__DRIscreenPrivate *sPriv) +{ + struct dri_screen *screen; + + /* Set up dispatch table to cope with all known extensions */ + dri_init_extensions(NULL); + + screen = CALLOC_STRUCT(dri_screen); + if (!screen) + goto fail; + + screen->sPriv = sPriv; + screen->fd = sPriv->fd; + dri_get_drm_minor(screen); + dri_get_device_id(screen); + sPriv->private = (void *) screen; + sPriv->extensions = dri_screen_extensions; + + + screen->pipe_screen = drm_api_hocks.create_screen(screen->fd, screen->deviceID); + if (!screen->pipe_screen) { + debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__); + goto fail; + } + + driParseOptionInfo(&screen->optionCache, + __driConfigOptions, + __driNConfigOptions); + + return dri_fill_in_modes(sPriv, + 4 * 8, + 24, + 8, + 1); +fail: + return NULL; +} + + +void +dri_destroy_screen(__DRIscreenPrivate * sPriv) +{ + struct dri_screen *screen = dri_screen(sPriv); + + screen->pipe_screen->destroy(screen->pipe_screen); + FREE(screen); + sPriv->private = NULL; +} + + +PUBLIC const struct __DriverAPIRec driDriverAPI = { + .InitScreen = NULL, + .DestroyScreen = dri_destroy_screen, + .CreateContext = dri_create_context, + .DestroyContext = dri_destroy_context, + .CreateBuffer = dri_create_buffer, + .DestroyBuffer = dri_destroy_buffer, + .SwapBuffers = dri_swap_buffers, + .MakeCurrent = dri_make_current, + .UnbindContext = dri_unbind_context, + .GetSwapInfo = dri_get_swap_info, + .GetDrawableMSC = driDrawableGetMSC32, + .WaitForMSC = driWaitForMSC32, + .CopySubBuffer = dri_copy_sub_buffer, + .InitScreen2 = dri_init_screen2, +}; + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ diff --git a/src/gallium/state_trackers/dri2/dri_screen.h b/src/gallium/state_trackers/dri2/dri_screen.h new file mode 100644 index 00000000000..fe2676d0be3 --- /dev/null +++ b/src/gallium/state_trackers/dri2/dri_screen.h @@ -0,0 +1,90 @@ +/************************************************************************** + * + * Copyright 2009, VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Author: Keith Whitwell <[email protected]> + * Author: Jakob Bornecrantz <[email protected]> + */ + +#ifndef DRI_SCREEN_H +#define DRI_SCREEN_H + +#include "dri_util.h" +#include "xmlconfig.h" + +#include "pipe/p_compiler.h" + +struct dri_screen +{ + /* dri */ + __DRIscreenPrivate *sPriv; + + /** + * Configuration cache with default values for all contexts + */ + driOptionCache optionCache; + + /** + * Temporary(?) context to use for SwapBuffers or other situations in + * which we need a rendering context, but none is currently bound. + */ + struct dri_context *dummyContext; + + /* drm */ + int deviceID; + int fd; + int minor; + + /* gallium */ + struct pipe_winsys *pipe_winsys; + struct pipe_screen *pipe_screen; +}; + + +/** cast wrapper */ +static INLINE struct dri_screen * +dri_screen(__DRIscreenPrivate *sPriv) +{ + return (struct dri_screen *) sPriv->private; +} + + +/*********************************************************************** + * dri_screen.c + */ +const __DRIconfig ** +dri_init_screen2(__DRIscreenPrivate *sPriv); + +void +dri_destroy_screen(__DRIscreenPrivate * sPriv); + +int +dri_get_swap_info(__DRIdrawablePrivate * dPriv, + __DRIswapInfo * sInfo); + +#endif + +/* vim: set sw=3 ts=8 sts=3 expandtab: */ |