2
* Copyright 2008, 2010 George Sapountzis <gsapountzis@gmail.com>
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
11
* The above copyright notice and this permission notice shall be included
12
* in all copies or substantial portions of the Software.
14
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
* DRI software rasterizer
25
* This is the mesa swrast module packaged into a DRI driver structure.
27
* The front-buffer is allocated by the loader. The loader provides read/write
28
* callbacks for access to the front-buffer. The driver uses a scratch row for
29
* front-buffer rendering to avoid repeated calls to the loader.
31
* The back-buffer is allocated by the driver and is private.
34
#include "main/context.h"
35
#include "main/extensions.h"
36
#include "main/formats.h"
37
#include "main/framebuffer.h"
38
#include "main/imports.h"
39
#include "main/renderbuffer.h"
40
#include "swrast/swrast.h"
41
#include "swrast/s_renderbuffer.h"
42
#include "swrast_setup/swrast_setup.h"
44
#include "tnl/t_context.h"
45
#include "tnl/t_pipeline.h"
47
#include "drivers/common/driverfuncs.h"
48
#include "drivers/common/meta.h"
51
#include "main/teximage.h"
52
#include "main/texformat.h"
53
#include "main/texstate.h"
55
#include "swrast_priv.h"
56
#include "swrast/s_context.h"
60
* Screen and config-related functions
63
static void swrastSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
64
GLint texture_format, __DRIdrawable *dPriv)
66
struct dri_context *dri_ctx;
68
__DRIscreen *sPriv = dPriv->driScreenPriv;
69
struct gl_texture_unit *texUnit;
70
struct gl_texture_object *texObj;
71
struct gl_texture_image *texImage;
72
struct swrast_texture_image *swImage;
73
uint32_t internalFormat;
76
dri_ctx = pDRICtx->driverPrivate;
78
internalFormat = (texture_format == __DRI_TEXTURE_FORMAT_RGB ? 3 : 4);
80
texUnit = _mesa_get_current_tex_unit(&dri_ctx->Base);
81
texObj = _mesa_select_tex_object(&dri_ctx->Base, texUnit, target);
82
texImage = _mesa_get_tex_image(&dri_ctx->Base, texObj, target, 0);
83
swImage = swrast_texture_image(texImage);
85
_mesa_lock_texture(&dri_ctx->Base, texObj);
87
sPriv->swrast_loader->getDrawableInfo(dPriv, &x, &y, &w, &h, dPriv->loaderPrivate);
89
if (texture_format == __DRI_TEXTURE_FORMAT_RGB)
90
texFormat = MESA_FORMAT_XRGB8888;
92
texFormat = MESA_FORMAT_ARGB8888;
94
_mesa_init_teximage_fields(&dri_ctx->Base, texImage,
95
w, h, 1, 0, internalFormat, texFormat);
97
sPriv->swrast_loader->getImage(dPriv, x, y, w, h, (char *)swImage->Buffer,
98
dPriv->loaderPrivate);
100
_mesa_unlock_texture(&dri_ctx->Base, texObj);
103
static void swrastSetTexBuffer(__DRIcontext *pDRICtx, GLint target,
104
__DRIdrawable *dPriv)
106
swrastSetTexBuffer2(pDRICtx, target, __DRI_TEXTURE_FORMAT_RGBA, dPriv);
109
static const __DRItexBufferExtension swrastTexBufferExtension = {
110
{ __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
115
static const __DRIextension *dri_screen_extensions[] = {
116
&swrastTexBufferExtension.base,
120
static __DRIconfig **
121
swrastFillInModes(__DRIscreen *psp,
122
unsigned pixel_bits, unsigned depth_bits,
123
unsigned stencil_bits, GLboolean have_back_buffer)
125
__DRIconfig **configs;
126
unsigned depth_buffer_factor;
127
unsigned back_buffer_factor;
131
/* GLX_SWAP_COPY_OML is only supported because the Intel driver doesn't
132
* support pageflipping at all.
134
static const GLenum back_buffer_modes[] = {
135
GLX_NONE, GLX_SWAP_UNDEFINED_OML
138
uint8_t depth_bits_array[4];
139
uint8_t stencil_bits_array[4];
140
uint8_t msaa_samples_array[1];
143
(void) have_back_buffer;
145
depth_bits_array[0] = 0;
146
depth_bits_array[1] = 0;
147
depth_bits_array[2] = depth_bits;
148
depth_bits_array[3] = depth_bits;
150
/* Just like with the accumulation buffer, always provide some modes
151
* with a stencil buffer.
153
stencil_bits_array[0] = 0;
154
stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
155
stencil_bits_array[2] = 0;
156
stencil_bits_array[3] = (stencil_bits == 0) ? 8 : stencil_bits;
158
msaa_samples_array[0] = 0;
160
depth_buffer_factor = 4;
161
back_buffer_factor = 2;
163
switch (pixel_bits) {
166
fb_type = GL_UNSIGNED_BYTE_2_3_3_REV;
170
fb_type = GL_UNSIGNED_SHORT_5_6_5;
174
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
178
fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
181
fprintf(stderr, "[%s:%u] bad depth %d\n", __func__, __LINE__,
186
configs = driCreateConfigs(fb_format, fb_type,
187
depth_bits_array, stencil_bits_array,
188
depth_buffer_factor, back_buffer_modes,
189
back_buffer_factor, msaa_samples_array, 1,
191
if (configs == NULL) {
192
fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__,
200
static const __DRIconfig **
201
dri_init_screen(__DRIscreen * psp)
203
__DRIconfig **configs8, **configs16, **configs24, **configs32;
207
psp->extensions = dri_screen_extensions;
209
configs8 = swrastFillInModes(psp, 8, 8, 0, 1);
210
configs16 = swrastFillInModes(psp, 16, 16, 0, 1);
211
configs24 = swrastFillInModes(psp, 24, 24, 8, 1);
212
configs32 = swrastFillInModes(psp, 32, 24, 8, 1);
214
configs16 = driConcatConfigs(configs8, configs16);
215
configs24 = driConcatConfigs(configs16, configs24);
216
configs32 = driConcatConfigs(configs24, configs32);
218
return (const __DRIconfig **)configs32;
222
dri_destroy_screen(__DRIscreen * sPriv)
230
* Framebuffer and renderbuffer-related functions.
234
choose_pixel_format(const struct gl_config *v)
236
int depth = v->rgbBits;
239
&& v->redMask == 0xff0000
240
&& v->greenMask == 0x00ff00
241
&& v->blueMask == 0x0000ff)
244
&& v->redMask == 0xff0000
245
&& v->greenMask == 0x00ff00
246
&& v->blueMask == 0x0000ff)
249
&& v->redMask == 0xf800
250
&& v->greenMask == 0x07e0
251
&& v->blueMask == 0x001f)
254
&& v->redMask == 0x07
255
&& v->greenMask == 0x38
256
&& v->blueMask == 0xc0)
259
_mesa_problem( NULL, "unexpected format in %s", __FUNCTION__ );
264
swrast_delete_renderbuffer(struct gl_renderbuffer *rb)
266
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
270
free(xrb->Base.Buffer);
274
/* see bytes_per_line in libGL */
276
bytes_per_line(unsigned pitch_bits, unsigned mul)
278
unsigned mask = mul - 1;
280
return ((pitch_bits + mask) & ~mask) / 8;
284
swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
285
GLenum internalFormat, GLuint width, GLuint height)
287
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
292
(void) internalFormat;
294
xrb->Base.Buffer = NULL;
297
xrb->pitch = bytes_per_line(width * xrb->bpp, 32);
303
swrast_alloc_back_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
304
GLenum internalFormat, GLuint width, GLuint height)
306
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
310
free(xrb->Base.Buffer);
312
swrast_alloc_front_storage(ctx, rb, internalFormat, width, height);
314
xrb->Base.Buffer = malloc(height * xrb->pitch);
319
static struct dri_swrast_renderbuffer *
320
swrast_new_renderbuffer(const struct gl_config *visual, __DRIdrawable *dPriv,
323
struct dri_swrast_renderbuffer *xrb = calloc(1, sizeof *xrb);
324
struct gl_renderbuffer *rb;
332
rb = &xrb->Base.Base;
334
_mesa_init_renderbuffer(rb, 0);
336
pixel_format = choose_pixel_format(visual);
339
xrb->Base.Base.Delete = swrast_delete_renderbuffer;
341
rb->AllocStorage = swrast_alloc_front_storage;
344
rb->AllocStorage = swrast_alloc_back_storage;
347
switch (pixel_format) {
349
rb->Format = MESA_FORMAT_ARGB8888;
350
rb->InternalFormat = GL_RGBA;
351
rb->_BaseFormat = GL_RGBA;
355
rb->Format = MESA_FORMAT_ARGB8888; /* XXX */
356
rb->InternalFormat = GL_RGB;
357
rb->_BaseFormat = GL_RGB;
361
rb->Format = MESA_FORMAT_RGB565;
362
rb->InternalFormat = GL_RGB;
363
rb->_BaseFormat = GL_RGB;
367
rb->Format = MESA_FORMAT_RGB332;
368
rb->InternalFormat = GL_RGB;
369
rb->_BaseFormat = GL_RGB;
380
swrast_map_renderbuffer(struct gl_context *ctx,
381
struct gl_renderbuffer *rb,
382
GLuint x, GLuint y, GLuint w, GLuint h,
387
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
388
GLubyte *map = xrb->Base.Buffer;
389
int cpp = _mesa_get_format_bytes(rb->Format);
390
int stride = rb->Width * cpp;
392
if (rb->AllocStorage == swrast_alloc_front_storage) {
393
__DRIdrawable *dPriv = xrb->dPriv;
394
__DRIscreen *sPriv = dPriv->driScreenPriv;
396
xrb->map_mode = mode;
403
xrb->Base.Buffer = malloc(h * stride);
405
sPriv->swrast_loader->getImage(dPriv, x, y, w, h,
406
(char *) xrb->Base.Buffer,
407
dPriv->loaderPrivate);
409
*out_map = xrb->Base.Buffer;
410
*out_stride = stride;
414
ASSERT(xrb->Base.Buffer);
416
if (rb->AllocStorage == swrast_alloc_back_storage) {
417
map += (rb->Height - 1) * stride;
421
map += (GLsizei)y * stride;
422
map += (GLsizei)x * cpp;
425
*out_stride = stride;
429
swrast_unmap_renderbuffer(struct gl_context *ctx,
430
struct gl_renderbuffer *rb)
432
struct dri_swrast_renderbuffer *xrb = dri_swrast_renderbuffer(rb);
434
if (rb->AllocStorage == swrast_alloc_front_storage) {
435
__DRIdrawable *dPriv = xrb->dPriv;
436
__DRIscreen *sPriv = dPriv->driScreenPriv;
438
if (xrb->map_mode & GL_MAP_WRITE_BIT) {
439
sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_DRAW,
440
xrb->map_x, xrb->map_y,
441
xrb->map_w, xrb->map_h,
442
(char *) xrb->Base.Buffer,
443
dPriv->loaderPrivate);
446
free(xrb->Base.Buffer);
447
xrb->Base.Buffer = NULL;
452
dri_create_buffer(__DRIscreen * sPriv,
453
__DRIdrawable * dPriv,
454
const struct gl_config * visual, GLboolean isPixmap)
456
struct dri_drawable *drawable = NULL;
457
struct gl_framebuffer *fb;
458
struct dri_swrast_renderbuffer *frontrb, *backrb;
465
drawable = CALLOC_STRUCT(dri_drawable);
466
if (drawable == NULL)
469
dPriv->driverPrivate = drawable;
470
drawable->dPriv = dPriv;
472
drawable->row = malloc(SWRAST_MAX_WIDTH * 4);
473
if (drawable->row == NULL)
476
fb = &drawable->Base;
478
/* basic framebuffer setup */
479
_mesa_initialize_window_framebuffer(fb, visual);
481
/* add front renderbuffer */
482
frontrb = swrast_new_renderbuffer(visual, dPriv, GL_TRUE);
483
_mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base.Base);
485
/* add back renderbuffer */
486
if (visual->doubleBufferMode) {
487
backrb = swrast_new_renderbuffer(visual, dPriv, GL_FALSE);
488
_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base.Base);
491
/* add software renderbuffers */
492
_swrast_add_soft_renderbuffers(fb,
493
GL_FALSE, /* color */
494
visual->haveDepthBuffer,
495
visual->haveStencilBuffer,
496
visual->haveAccumBuffer,
497
GL_FALSE, /* alpha */
498
GL_FALSE /* aux bufs */);
513
dri_destroy_buffer(__DRIdrawable * dPriv)
518
struct dri_drawable *drawable = dri_drawable(dPriv);
519
struct gl_framebuffer *fb;
523
fb = &drawable->Base;
525
fb->DeletePending = GL_TRUE;
526
_mesa_reference_framebuffer(&fb, NULL);
531
dri_swap_buffers(__DRIdrawable * dPriv)
533
__DRIscreen *sPriv = dPriv->driScreenPriv;
535
GET_CURRENT_CONTEXT(ctx);
537
struct dri_drawable *drawable = dri_drawable(dPriv);
538
struct gl_framebuffer *fb;
539
struct dri_swrast_renderbuffer *frontrb, *backrb;
543
fb = &drawable->Base;
546
dri_swrast_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
548
dri_swrast_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
550
/* check for signle-buffered */
554
/* check if swapping currently bound buffer */
555
if (ctx && ctx->DrawBuffer == fb) {
556
/* flush pending rendering */
557
_mesa_notifySwapBuffers(ctx);
560
sPriv->swrast_loader->putImage(dPriv, __DRI_SWRAST_IMAGE_OP_SWAP,
562
frontrb->Base.Base.Width,
563
frontrb->Base.Base.Height,
564
(char *) backrb->Base.Buffer,
565
dPriv->loaderPrivate);
570
* General device driver functions.
574
get_window_size( struct gl_framebuffer *fb, GLsizei *w, GLsizei *h )
576
__DRIdrawable *dPriv = swrast_drawable(fb)->dPriv;
577
__DRIscreen *sPriv = dPriv->driScreenPriv;
580
sPriv->swrast_loader->getDrawableInfo(dPriv,
582
dPriv->loaderPrivate);
586
swrast_check_and_update_window_size( struct gl_context *ctx, struct gl_framebuffer *fb )
588
GLsizei width, height;
590
get_window_size(fb, &width, &height);
591
if (fb->Width != width || fb->Height != height) {
592
_mesa_resize_framebuffer(ctx, fb, width, height);
596
static const GLubyte *
597
get_string(struct gl_context *ctx, GLenum pname)
602
return (const GLubyte *) "Mesa Project";
604
return (const GLubyte *) "Software Rasterizer";
611
update_state( struct gl_context *ctx, GLuint new_state )
613
/* not much to do here - pass it on */
614
_swrast_InvalidateState( ctx, new_state );
615
_swsetup_InvalidateState( ctx, new_state );
616
_vbo_InvalidateState( ctx, new_state );
617
_tnl_InvalidateState( ctx, new_state );
621
viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
623
struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
624
struct gl_framebuffer *read = ctx->WinSysReadBuffer;
630
swrast_check_and_update_window_size(ctx, draw);
631
swrast_check_and_update_window_size(ctx, read);
634
static gl_format swrastChooseTextureFormat(struct gl_context * ctx,
636
GLint internalFormat,
640
if (internalFormat == GL_RGB)
641
return MESA_FORMAT_XRGB8888;
642
return _mesa_choose_tex_format(ctx, target, internalFormat, format, type);
646
swrast_init_driver_functions(struct dd_function_table *driver)
648
driver->GetString = get_string;
649
driver->UpdateState = update_state;
650
driver->GetBufferSize = NULL;
651
driver->Viewport = viewport;
652
driver->ChooseTextureFormat = swrastChooseTextureFormat;
653
driver->MapRenderbuffer = swrast_map_renderbuffer;
654
driver->UnmapRenderbuffer = swrast_unmap_renderbuffer;
657
static const char *es2_extensions[] = {
658
/* Used by mesa internally (cf all_mesa_extensions in ../common/utils.c) */
659
"GL_ARB_transpose_matrix",
661
"GL_EXT_blend_func_separate",
662
"GL_EXT_compiled_vertex_array",
663
"GL_EXT_framebuffer_blit",
664
"GL_IBM_multimode_draw_arrays",
665
"GL_MESA_window_pos",
666
"GL_NV_vertex_program",
668
/* Required by GLES2 */
669
"GL_ARB_fragment_program",
670
"GL_ARB_fragment_shader",
671
"GL_ARB_shader_objects",
672
"GL_ARB_texture_cube_map",
673
"GL_ARB_texture_non_power_of_two",
674
"GL_ARB_vertex_shader",
675
"GL_EXT_blend_color",
676
"GL_EXT_blend_equation_separate",
677
"GL_EXT_blend_minmax",
680
"GL_ARB_framebuffer_object",
681
"GL_EXT_texture_filter_anisotropic",
682
"GL_ARB_depth_texture",
683
"GL_EXT_packed_depth_stencil",
684
"GL_EXT_framebuffer_object",
689
InitExtensionsES2(struct gl_context *ctx)
693
for (i = 0; es2_extensions[i]; i++)
694
_mesa_enable_extension(ctx, es2_extensions[i]);
698
* Context-related functions.
702
dri_create_context(gl_api api,
703
const struct gl_config * visual,
704
__DRIcontext * cPriv,
705
unsigned major_version,
706
unsigned minor_version,
709
void *sharedContextPrivate)
711
struct dri_context *ctx = NULL;
712
struct dri_context *share = (struct dri_context *)sharedContextPrivate;
713
struct gl_context *mesaCtx = NULL;
714
struct gl_context *sharedCtx = NULL;
715
struct dd_function_table functions;
719
/* Flag filtering is handled in dri2CreateContextAttribs.
725
if (major_version > 2
726
|| (major_version == 2 && minor_version > 1)) {
727
*error = __DRI_CTX_ERROR_BAD_VERSION;
734
case API_OPENGL_CORE:
735
*error = __DRI_CTX_ERROR_BAD_API;
739
ctx = CALLOC_STRUCT(dri_context);
741
*error = __DRI_CTX_ERROR_NO_MEMORY;
745
cPriv->driverPrivate = ctx;
748
/* build table of device driver functions */
749
_mesa_init_driver_functions(&functions);
750
swrast_init_driver_functions(&functions);
753
sharedCtx = &share->Base;
756
mesaCtx = &ctx->Base;
758
/* basic context setup */
759
if (!_mesa_initialize_context(mesaCtx, api, visual, sharedCtx, &functions, (void *) cPriv)) {
760
*error = __DRI_CTX_ERROR_NO_MEMORY;
764
/* do bounds checking to prevent segfaults and server crashes! */
765
mesaCtx->Const.CheckArrayBounds = GL_TRUE;
767
/* create module contexts */
768
_swrast_CreateContext( mesaCtx );
769
_vbo_CreateContext( mesaCtx );
770
_tnl_CreateContext( mesaCtx );
771
_swsetup_CreateContext( mesaCtx );
772
_swsetup_Wakeup( mesaCtx );
774
/* use default TCL pipeline */
776
TNLcontext *tnl = TNL_CONTEXT(mesaCtx);
777
tnl->Driver.RunPipeline = _tnl_run_pipeline;
780
_mesa_meta_init(mesaCtx);
781
_mesa_enable_sw_extensions(mesaCtx);
784
case API_OPENGL_CORE:
785
/* XXX fix me, fall-through for now */
787
_mesa_enable_1_3_extensions(mesaCtx);
788
_mesa_enable_1_4_extensions(mesaCtx);
789
_mesa_enable_1_5_extensions(mesaCtx);
790
_mesa_enable_2_0_extensions(mesaCtx);
791
_mesa_enable_2_1_extensions(mesaCtx);
794
_mesa_enable_1_3_extensions(mesaCtx);
795
_mesa_enable_1_4_extensions(mesaCtx);
796
_mesa_enable_1_5_extensions(mesaCtx);
800
InitExtensionsES2( mesaCtx);
804
*error = __DRI_CTX_ERROR_SUCCESS;
815
dri_destroy_context(__DRIcontext * cPriv)
820
struct dri_context *ctx = dri_context(cPriv);
821
struct gl_context *mesaCtx;
823
mesaCtx = &ctx->Base;
825
_mesa_meta_free(mesaCtx);
826
_swsetup_DestroyContext( mesaCtx );
827
_swrast_DestroyContext( mesaCtx );
828
_tnl_DestroyContext( mesaCtx );
829
_vbo_DestroyContext( mesaCtx );
830
_mesa_destroy_context( mesaCtx );
835
dri_make_current(__DRIcontext * cPriv,
836
__DRIdrawable * driDrawPriv,
837
__DRIdrawable * driReadPriv)
839
struct gl_context *mesaCtx;
840
struct gl_framebuffer *mesaDraw;
841
struct gl_framebuffer *mesaRead;
845
struct dri_context *ctx = dri_context(cPriv);
846
struct dri_drawable *draw;
847
struct dri_drawable *read;
849
if (!driDrawPriv || !driReadPriv)
852
draw = dri_drawable(driDrawPriv);
853
read = dri_drawable(driReadPriv);
854
mesaCtx = &ctx->Base;
855
mesaDraw = &draw->Base;
856
mesaRead = &read->Base;
858
/* check for same context and buffer */
859
if (mesaCtx == _mesa_get_current_context()
860
&& mesaCtx->DrawBuffer == mesaDraw
861
&& mesaCtx->ReadBuffer == mesaRead) {
865
_glapi_check_multithread();
867
swrast_check_and_update_window_size(mesaCtx, mesaDraw);
868
if (mesaRead != mesaDraw)
869
swrast_check_and_update_window_size(mesaCtx, mesaRead);
871
_mesa_make_current( mesaCtx,
877
_mesa_make_current( NULL, NULL, NULL );
884
dri_unbind_context(__DRIcontext * cPriv)
889
/* Unset current context and dispath table */
890
_mesa_make_current(NULL, NULL, NULL);
896
const struct __DriverAPIRec driDriverAPI = {
897
.InitScreen = dri_init_screen,
898
.DestroyScreen = dri_destroy_screen,
899
.CreateContext = dri_create_context,
900
.DestroyContext = dri_destroy_context,
901
.CreateBuffer = dri_create_buffer,
902
.DestroyBuffer = dri_destroy_buffer,
903
.SwapBuffers = dri_swap_buffers,
904
.MakeCurrent = dri_make_current,
905
.UnbindContext = dri_unbind_context,
908
/* This is the table of extensions that the loader will dlsym() for. */
909
PUBLIC const __DRIextension *__driDriverExtensions[] = {
910
&driCoreExtension.base,
911
&driSWRastExtension.base,