2 * Mesa 3-D graphics library
4 * Copyright 2009, VMware, Inc.
6 * Copyright (C) 2010 LunarG Inc.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keithw@vmware.com> Jakob Bornecrantz
28 * <wallbraker@gmail.com> Chia-I Wu <olv@lunarg.com>
31 #include "util/u_memory.h"
32 #include "util/u_inlines.h"
33 #include "util/u_format.h"
34 #include "util/u_debug.h"
35 #include "state_tracker/drm_driver.h"
37 #include "dri_screen.h"
38 #include "dri_context.h"
39 #include "dri_drawable.h"
40 #include "dri2_buffer.h"
43 * DRI2 flush extension.
46 dri2_flush_drawable(__DRIdrawable
*dPriv
)
48 dri_flush(dPriv
->driContextPriv
, dPriv
, __DRI2_FLUSH_DRAWABLE
, 0);
52 dri2_invalidate_drawable(__DRIdrawable
*dPriv
)
54 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
56 dri2InvalidateDrawable(dPriv
);
57 drawable
->dPriv
->lastStamp
= drawable
->dPriv
->dri2
.stamp
;
59 p_atomic_inc(&drawable
->base
.stamp
);
62 static const __DRI2flushExtension dri2FlushExtension
= {
63 { __DRI2_FLUSH
, __DRI2_FLUSH_VERSION
},
65 dri2_invalidate_drawable
,
70 * Retrieve __DRIbuffer from the DRI loader.
73 dri2_drawable_get_buffers(struct dri_drawable
*drawable
,
74 const enum st_attachment_type
*atts
,
77 __DRIdrawable
*dri_drawable
= drawable
->dPriv
;
78 struct __DRIdri2LoaderExtensionRec
*loader
= drawable
->sPriv
->dri2
.loader
;
82 unsigned attachments
[10];
83 unsigned num_attachments
, i
;
86 with_format
= dri_with_format(drawable
->sPriv
);
90 /* for Xserver 1.6.0 (DRI2 version 1) we always need to ask for the front */
92 attachments
[num_attachments
++] = __DRI_BUFFER_FRONT_LEFT
;
94 for (i
= 0; i
< *count
; i
++) {
95 enum pipe_format format
;
99 dri_drawable_get_format(drawable
, atts
[i
], &format
, &bind
);
100 if (format
== PIPE_FORMAT_NONE
)
104 case ST_ATTACHMENT_FRONT_LEFT
:
108 att
= __DRI_BUFFER_FRONT_LEFT
;
110 case ST_ATTACHMENT_BACK_LEFT
:
111 att
= __DRI_BUFFER_BACK_LEFT
;
113 case ST_ATTACHMENT_FRONT_RIGHT
:
114 att
= __DRI_BUFFER_FRONT_RIGHT
;
116 case ST_ATTACHMENT_BACK_RIGHT
:
117 att
= __DRI_BUFFER_BACK_RIGHT
;
124 * In this switch statement we must support all formats that
125 * may occur as the stvis->color_format.
128 case PIPE_FORMAT_B8G8R8A8_UNORM
:
131 case PIPE_FORMAT_B8G8R8X8_UNORM
:
134 case PIPE_FORMAT_B5G6R5_UNORM
:
138 depth
= util_format_get_blocksizebits(format
);
139 assert(!"Unexpected format in dri2_drawable_get_buffers()");
142 attachments
[num_attachments
++] = att
;
144 attachments
[num_attachments
++] = depth
;
149 num_attachments
/= 2;
150 buffers
= loader
->getBuffersWithFormat(dri_drawable
,
151 &dri_drawable
->w
, &dri_drawable
->h
,
152 attachments
, num_attachments
,
153 &num_buffers
, dri_drawable
->loaderPrivate
);
156 buffers
= loader
->getBuffers(dri_drawable
,
157 &dri_drawable
->w
, &dri_drawable
->h
,
158 attachments
, num_attachments
,
159 &num_buffers
, dri_drawable
->loaderPrivate
);
163 *count
= num_buffers
;
169 * Process __DRIbuffer and convert them into pipe_resources.
172 dri2_drawable_process_buffers(struct dri_drawable
*drawable
,
173 __DRIbuffer
*buffers
, unsigned buffer_count
,
174 const enum st_attachment_type
*atts
,
177 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
178 __DRIdrawable
*dri_drawable
= drawable
->dPriv
;
179 struct pipe_resource templ
;
180 struct winsys_handle whandle
;
181 boolean alloc_depthstencil
= FALSE
;
184 if (drawable
->old_num
== buffer_count
&&
185 drawable
->old_w
== dri_drawable
->w
&&
186 drawable
->old_h
== dri_drawable
->h
&&
187 memcmp(drawable
->old
, buffers
, sizeof(__DRIbuffer
) * buffer_count
) == 0)
190 /* See if we need a depth-stencil buffer. */
191 for (i
= 0; i
< att_count
; i
++) {
192 if (atts
[i
] == ST_ATTACHMENT_DEPTH_STENCIL
) {
193 alloc_depthstencil
= TRUE
;
198 /* Delete the resources we won't need. */
199 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
200 /* Don't delete the depth-stencil buffer, we can reuse it. */
201 if (i
== ST_ATTACHMENT_DEPTH_STENCIL
&& alloc_depthstencil
)
204 pipe_resource_reference(&drawable
->textures
[i
], NULL
);
207 if (drawable
->stvis
.samples
> 1) {
208 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
211 /* Don't delete MSAA resources for the attachments which are enabled,
212 * we can reuse them. */
213 for (j
= 0; j
< att_count
; j
++) {
221 pipe_resource_reference(&drawable
->msaa_textures
[i
], NULL
);
226 memset(&templ
, 0, sizeof(templ
));
227 templ
.target
= screen
->target
;
228 templ
.last_level
= 0;
229 templ
.width0
= dri_drawable
->w
;
230 templ
.height0
= dri_drawable
->h
;
232 templ
.array_size
= 1;
234 memset(&whandle
, 0, sizeof(whandle
));
236 /* Process DRI-provided buffers and get pipe_resources. */
237 for (i
= 0; i
< buffer_count
; i
++) {
238 __DRIbuffer
*buf
= &buffers
[i
];
239 enum st_attachment_type statt
;
240 enum pipe_format format
;
242 switch (buf
->attachment
) {
243 case __DRI_BUFFER_FRONT_LEFT
:
244 if (!screen
->auto_fake_front
) {
245 continue; /* invalid attachment */
248 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
249 statt
= ST_ATTACHMENT_FRONT_LEFT
;
251 case __DRI_BUFFER_BACK_LEFT
:
252 statt
= ST_ATTACHMENT_BACK_LEFT
;
255 continue; /* invalid attachment */
258 dri_drawable_get_format(drawable
, statt
, &format
, &bind
);
259 if (format
== PIPE_FORMAT_NONE
)
262 templ
.format
= format
;
264 whandle
.handle
= buf
->name
;
265 whandle
.stride
= buf
->pitch
;
267 drawable
->textures
[statt
] =
268 screen
->base
.screen
->resource_from_handle(screen
->base
.screen
,
270 assert(drawable
->textures
[statt
]);
273 /* Allocate private MSAA colorbuffers. */
274 if (drawable
->stvis
.samples
> 1) {
275 for (i
= 0; i
< att_count
; i
++) {
276 enum st_attachment_type att
= atts
[i
];
278 if (att
== ST_ATTACHMENT_DEPTH_STENCIL
)
281 if (drawable
->textures
[att
]) {
282 templ
.format
= drawable
->textures
[att
]->format
;
283 templ
.bind
= drawable
->textures
[att
]->bind
;
284 templ
.nr_samples
= drawable
->stvis
.samples
;
286 /* Try to reuse the resource.
287 * (the other resource parameters should be constant)
289 if (!drawable
->msaa_textures
[att
] ||
290 drawable
->msaa_textures
[att
]->width0
!= templ
.width0
||
291 drawable
->msaa_textures
[att
]->height0
!= templ
.height0
) {
292 /* Allocate a new one. */
293 pipe_resource_reference(&drawable
->msaa_textures
[att
], NULL
);
295 drawable
->msaa_textures
[att
] =
296 screen
->base
.screen
->resource_create(screen
->base
.screen
,
298 assert(drawable
->msaa_textures
[att
]);
302 pipe_resource_reference(&drawable
->msaa_textures
[att
], NULL
);
307 /* Allocate a private depth-stencil buffer. */
308 if (alloc_depthstencil
) {
309 enum st_attachment_type att
= ST_ATTACHMENT_DEPTH_STENCIL
;
310 struct pipe_resource
**zsbuf
;
311 enum pipe_format format
;
314 dri_drawable_get_format(drawable
, att
, &format
, &bind
);
317 templ
.format
= format
;
320 if (drawable
->stvis
.samples
> 1) {
321 templ
.nr_samples
= drawable
->stvis
.samples
;
322 zsbuf
= &drawable
->msaa_textures
[att
];
325 templ
.nr_samples
= 0;
326 zsbuf
= &drawable
->textures
[att
];
329 /* Try to reuse the resource.
330 * (the other resource parameters should be constant)
333 (*zsbuf
)->width0
!= templ
.width0
||
334 (*zsbuf
)->height0
!= templ
.height0
) {
335 /* Allocate a new one. */
336 pipe_resource_reference(zsbuf
, NULL
);
337 *zsbuf
= screen
->base
.screen
->resource_create(screen
->base
.screen
,
343 pipe_resource_reference(&drawable
->msaa_textures
[att
], NULL
);
344 pipe_resource_reference(&drawable
->textures
[att
], NULL
);
348 drawable
->old_num
= buffer_count
;
349 drawable
->old_w
= dri_drawable
->w
;
350 drawable
->old_h
= dri_drawable
->h
;
351 memcpy(drawable
->old
, buffers
, sizeof(__DRIbuffer
) * buffer_count
);
355 dri2_allocate_buffer(__DRIscreen
*sPriv
,
356 unsigned attachment
, unsigned format
,
357 int width
, int height
)
359 struct dri_screen
*screen
= dri_screen(sPriv
);
360 struct dri2_buffer
*buffer
;
361 struct pipe_resource templ
;
364 struct winsys_handle whandle
;
366 switch (attachment
) {
367 case __DRI_BUFFER_FRONT_LEFT
:
368 case __DRI_BUFFER_FAKE_FRONT_LEFT
:
369 bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
371 case __DRI_BUFFER_BACK_LEFT
:
372 bind
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
374 case __DRI_BUFFER_DEPTH
:
375 case __DRI_BUFFER_DEPTH_STENCIL
:
376 case __DRI_BUFFER_STENCIL
:
377 bind
= PIPE_BIND_DEPTH_STENCIL
; /* XXX sampler? */
381 /* because we get the handle and stride */
382 bind
|= PIPE_BIND_SHARED
;
386 pf
= PIPE_FORMAT_B8G8R8A8_UNORM
;
389 pf
= PIPE_FORMAT_B8G8R8X8_UNORM
;
392 pf
= PIPE_FORMAT_Z16_UNORM
;
398 buffer
= CALLOC_STRUCT(dri2_buffer
);
402 memset(&templ
, 0, sizeof(templ
));
405 templ
.target
= PIPE_TEXTURE_2D
;
406 templ
.last_level
= 0;
407 templ
.width0
= width
;
408 templ
.height0
= height
;
410 templ
.array_size
= 1;
413 screen
->base
.screen
->resource_create(screen
->base
.screen
, &templ
);
414 if (!buffer
->resource
) {
419 memset(&whandle
, 0, sizeof(whandle
));
420 whandle
.type
= DRM_API_HANDLE_TYPE_SHARED
;
421 screen
->base
.screen
->resource_get_handle(screen
->base
.screen
,
422 buffer
->resource
, &whandle
);
424 buffer
->base
.attachment
= attachment
;
425 buffer
->base
.name
= whandle
.handle
;
426 buffer
->base
.cpp
= util_format_get_blocksize(pf
);
427 buffer
->base
.pitch
= whandle
.stride
;
429 return &buffer
->base
;
433 dri2_release_buffer(__DRIscreen
*sPriv
, __DRIbuffer
*bPriv
)
435 struct dri2_buffer
*buffer
= dri2_buffer(bPriv
);
437 pipe_resource_reference(&buffer
->resource
, NULL
);
442 * Backend functions for st_framebuffer interface.
446 dri2_allocate_textures(struct dri_drawable
*drawable
,
447 const enum st_attachment_type
*statts
,
448 unsigned statts_count
)
450 __DRIbuffer
*buffers
;
451 unsigned num_buffers
= statts_count
;
453 buffers
= dri2_drawable_get_buffers(drawable
, statts
, &num_buffers
);
455 dri2_drawable_process_buffers(drawable
, buffers
, num_buffers
,
456 statts
, statts_count
);
460 dri2_flush_frontbuffer(struct dri_context
*ctx
,
461 struct dri_drawable
*drawable
,
462 enum st_attachment_type statt
)
464 __DRIdrawable
*dri_drawable
= drawable
->dPriv
;
465 struct __DRIdri2LoaderExtensionRec
*loader
= drawable
->sPriv
->dri2
.loader
;
467 if (statt
!= ST_ATTACHMENT_FRONT_LEFT
)
470 if (drawable
->stvis
.samples
> 1) {
471 struct pipe_context
*pipe
= ctx
->st
->pipe
;
473 /* Resolve the front buffer. */
474 dri_pipe_blit(ctx
->st
->pipe
,
475 drawable
->textures
[ST_ATTACHMENT_FRONT_LEFT
],
476 drawable
->msaa_textures
[ST_ATTACHMENT_FRONT_LEFT
]);
477 pipe
->flush(pipe
, NULL
, 0);
480 if (loader
->flushFrontBuffer
) {
481 loader
->flushFrontBuffer(dri_drawable
, dri_drawable
->loaderPrivate
);
486 dri2_update_tex_buffer(struct dri_drawable
*drawable
,
487 struct dri_context
*ctx
,
488 struct pipe_resource
*res
)
494 dri2_lookup_egl_image(struct dri_screen
*screen
, void *handle
)
496 __DRIimageLookupExtension
*loader
= screen
->sPriv
->dri2
.image
;
499 if (!loader
->lookupEGLImage
)
502 img
= loader
->lookupEGLImage(screen
->sPriv
,
503 handle
, screen
->sPriv
->loaderPrivate
);
509 dri2_create_image_from_name(__DRIscreen
*_screen
,
510 int width
, int height
, int format
,
511 int name
, int pitch
, void *loaderPrivate
)
513 struct dri_screen
*screen
= dri_screen(_screen
);
515 struct pipe_resource templ
;
516 struct winsys_handle whandle
;
520 tex_usage
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
523 case __DRI_IMAGE_FORMAT_RGB565
:
524 pf
= PIPE_FORMAT_B5G6R5_UNORM
;
526 case __DRI_IMAGE_FORMAT_XRGB8888
:
527 pf
= PIPE_FORMAT_B8G8R8X8_UNORM
;
529 case __DRI_IMAGE_FORMAT_ARGB8888
:
530 pf
= PIPE_FORMAT_B8G8R8A8_UNORM
;
532 case __DRI_IMAGE_FORMAT_ABGR8888
:
533 pf
= PIPE_FORMAT_R8G8B8A8_UNORM
;
536 pf
= PIPE_FORMAT_NONE
;
539 if (pf
== PIPE_FORMAT_NONE
)
542 img
= CALLOC_STRUCT(__DRIimageRec
);
546 memset(&templ
, 0, sizeof(templ
));
547 templ
.bind
= tex_usage
;
549 templ
.target
= screen
->target
;
550 templ
.last_level
= 0;
551 templ
.width0
= width
;
552 templ
.height0
= height
;
554 templ
.array_size
= 1;
556 memset(&whandle
, 0, sizeof(whandle
));
557 whandle
.handle
= name
;
558 whandle
.stride
= pitch
* util_format_get_blocksize(pf
);
560 img
->texture
= screen
->base
.screen
->resource_from_handle(screen
->base
.screen
,
569 img
->dri_format
= format
;
570 img
->loader_private
= loaderPrivate
;
576 dri2_create_image_from_renderbuffer(__DRIcontext
*context
,
577 int renderbuffer
, void *loaderPrivate
)
579 struct dri_context
*ctx
= dri_context(context
);
581 if (!ctx
->st
->get_resource_for_egl_image
)
589 dri2_create_image(__DRIscreen
*_screen
,
590 int width
, int height
, int format
,
591 unsigned int use
, void *loaderPrivate
)
593 struct dri_screen
*screen
= dri_screen(_screen
);
595 struct pipe_resource templ
;
599 tex_usage
= PIPE_BIND_RENDER_TARGET
| PIPE_BIND_SAMPLER_VIEW
;
600 if (use
& __DRI_IMAGE_USE_SCANOUT
)
601 tex_usage
|= PIPE_BIND_SCANOUT
;
602 if (use
& __DRI_IMAGE_USE_SHARE
)
603 tex_usage
|= PIPE_BIND_SHARED
;
604 if (use
& __DRI_IMAGE_USE_CURSOR
) {
605 if (width
!= 64 || height
!= 64)
607 tex_usage
|= PIPE_BIND_CURSOR
;
611 case __DRI_IMAGE_FORMAT_RGB565
:
612 pf
= PIPE_FORMAT_B5G6R5_UNORM
;
614 case __DRI_IMAGE_FORMAT_XRGB8888
:
615 pf
= PIPE_FORMAT_B8G8R8X8_UNORM
;
617 case __DRI_IMAGE_FORMAT_ARGB8888
:
618 pf
= PIPE_FORMAT_B8G8R8A8_UNORM
;
620 case __DRI_IMAGE_FORMAT_ABGR8888
:
621 pf
= PIPE_FORMAT_R8G8B8A8_UNORM
;
624 pf
= PIPE_FORMAT_NONE
;
627 if (pf
== PIPE_FORMAT_NONE
)
630 img
= CALLOC_STRUCT(__DRIimageRec
);
634 memset(&templ
, 0, sizeof(templ
));
635 templ
.bind
= tex_usage
;
637 templ
.target
= PIPE_TEXTURE_2D
;
638 templ
.last_level
= 0;
639 templ
.width0
= width
;
640 templ
.height0
= height
;
642 templ
.array_size
= 1;
644 img
->texture
= screen
->base
.screen
->resource_create(screen
->base
.screen
, &templ
);
652 img
->dri_format
= format
;
653 img
->dri_components
= 0;
655 img
->loader_private
= loaderPrivate
;
660 dri2_query_image(__DRIimage
*image
, int attrib
, int *value
)
662 struct winsys_handle whandle
;
663 memset(&whandle
, 0, sizeof(whandle
));
666 case __DRI_IMAGE_ATTRIB_STRIDE
:
667 image
->texture
->screen
->resource_get_handle(image
->texture
->screen
,
668 image
->texture
, &whandle
);
669 *value
= whandle
.stride
;
671 case __DRI_IMAGE_ATTRIB_HANDLE
:
672 whandle
.type
= DRM_API_HANDLE_TYPE_KMS
;
673 image
->texture
->screen
->resource_get_handle(image
->texture
->screen
,
674 image
->texture
, &whandle
);
675 *value
= whandle
.handle
;
677 case __DRI_IMAGE_ATTRIB_NAME
:
678 whandle
.type
= DRM_API_HANDLE_TYPE_SHARED
;
679 image
->texture
->screen
->resource_get_handle(image
->texture
->screen
,
680 image
->texture
, &whandle
);
681 *value
= whandle
.handle
;
683 case __DRI_IMAGE_ATTRIB_FORMAT
:
684 *value
= image
->dri_format
;
686 case __DRI_IMAGE_ATTRIB_WIDTH
:
687 *value
= image
->texture
->width0
;
689 case __DRI_IMAGE_ATTRIB_HEIGHT
:
690 *value
= image
->texture
->height0
;
692 case __DRI_IMAGE_ATTRIB_COMPONENTS
:
693 if (image
->dri_components
== 0)
695 *value
= image
->dri_components
;
703 dri2_dup_image(__DRIimage
*image
, void *loaderPrivate
)
707 img
= CALLOC_STRUCT(__DRIimageRec
);
712 pipe_resource_reference(&img
->texture
, image
->texture
);
713 img
->level
= image
->level
;
714 img
->layer
= image
->layer
;
715 /* This should be 0 for sub images, but dup is also used for base images. */
716 img
->dri_components
= image
->dri_components
;
717 img
->loader_private
= loaderPrivate
;
723 dri2_validate_usage(__DRIimage
*image
, unsigned int use
)
726 * Gallium drivers are bad at adding usages to the resources
727 * once opened again in another process, which is the main use
728 * case for this, so we have to lie.
737 dri2_from_names(__DRIscreen
*screen
, int width
, int height
, int format
,
738 int *names
, int num_names
, int *strides
, int *offsets
,
742 int stride
, dri_components
;
750 case __DRI_IMAGE_FOURCC_RGB565
:
751 format
= __DRI_IMAGE_FORMAT_RGB565
;
752 dri_components
= __DRI_IMAGE_COMPONENTS_RGB
;
754 case __DRI_IMAGE_FOURCC_ARGB8888
:
755 format
= __DRI_IMAGE_FORMAT_ARGB8888
;
756 dri_components
= __DRI_IMAGE_COMPONENTS_RGBA
;
758 case __DRI_IMAGE_FOURCC_XRGB8888
:
759 format
= __DRI_IMAGE_FORMAT_XRGB8888
;
760 dri_components
= __DRI_IMAGE_COMPONENTS_RGB
;
762 case __DRI_IMAGE_FOURCC_ABGR8888
:
763 format
= __DRI_IMAGE_FORMAT_ABGR8888
;
764 dri_components
= __DRI_IMAGE_COMPONENTS_RGBA
;
766 case __DRI_IMAGE_FOURCC_XBGR8888
:
767 format
= __DRI_IMAGE_FORMAT_XBGR8888
;
768 dri_components
= __DRI_IMAGE_COMPONENTS_RGB
;
774 /* Strides are in bytes not pixels. */
775 stride
= strides
[0] /4;
777 img
= dri2_create_image_from_name(screen
, width
, height
, format
,
778 names
[0], stride
, loaderPrivate
);
782 img
->dri_components
= dri_components
;
787 dri2_from_planar(__DRIimage
*image
, int plane
, void *loaderPrivate
)
794 if (image
->dri_components
== 0)
797 img
= dri2_dup_image(image
, loaderPrivate
);
801 /* set this to 0 for sub images. */
802 img
->dri_components
= 0;
807 dri2_destroy_image(__DRIimage
*img
)
809 pipe_resource_reference(&img
->texture
, NULL
);
813 static struct __DRIimageExtensionRec dri2ImageExtension
= {
815 dri2_create_image_from_name
,
816 dri2_create_image_from_renderbuffer
,
827 * Backend function init_screen.
830 static const __DRIextension
*dri_screen_extensions
[] = {
831 &driTexBufferExtension
.base
,
832 &dri2FlushExtension
.base
,
833 &dri2ImageExtension
.base
,
834 &dri2ConfigQueryExtension
.base
,
835 &dri2ThrottleExtension
.base
,
840 * This is the driver specific part of the createNewScreen entry point.
842 * Returns the struct gl_config supported by this driver.
844 static const __DRIconfig
**
845 dri2_init_screen(__DRIscreen
* sPriv
)
847 const __DRIconfig
**configs
;
848 struct dri_screen
*screen
;
849 struct pipe_screen
*pscreen
;
850 const struct drm_conf_ret
*throttle_ret
= NULL
;
852 screen
= CALLOC_STRUCT(dri_screen
);
856 screen
->sPriv
= sPriv
;
857 screen
->fd
= sPriv
->fd
;
859 sPriv
->driverPrivate
= (void *)screen
;
861 pscreen
= driver_descriptor
.create_screen(screen
->fd
);
862 if (driver_descriptor
.configuration
)
863 throttle_ret
= driver_descriptor
.configuration(DRM_CONF_THROTTLE
);
865 if (throttle_ret
&& throttle_ret
->val
.val_int
!= -1) {
866 screen
->throttling_enabled
= TRUE
;
867 screen
->default_throttle_frames
= throttle_ret
->val
.val_int
;
870 sPriv
->extensions
= dri_screen_extensions
;
872 /* dri_init_screen_helper checks pscreen for us */
874 configs
= dri_init_screen_helper(screen
, pscreen
);
879 if (screen
->st_api
->profile_mask
& ST_PROFILE_DEFAULT_MASK
)
880 sPriv
->api_mask
|= 1 << __DRI_API_OPENGL
;
881 if (screen
->st_api
->profile_mask
& ST_PROFILE_OPENGL_ES1_MASK
)
882 sPriv
->api_mask
|= 1 << __DRI_API_GLES
;
883 if (screen
->st_api
->profile_mask
& ST_PROFILE_OPENGL_ES2_MASK
)
884 sPriv
->api_mask
|= 1 << __DRI_API_GLES2
;
886 screen
->auto_fake_front
= dri_with_format(sPriv
);
887 screen
->broken_invalidate
= !sPriv
->dri2
.useInvalidate
;
888 screen
->lookup_egl_image
= dri2_lookup_egl_image
;
892 dri_destroy_screen_helper(screen
);
898 dri2_create_buffer(__DRIscreen
* sPriv
,
899 __DRIdrawable
* dPriv
,
900 const struct gl_config
* visual
, boolean isPixmap
)
902 struct dri_drawable
*drawable
= NULL
;
904 if (!dri_create_buffer(sPriv
, dPriv
, visual
, isPixmap
))
907 drawable
= dPriv
->driverPrivate
;
909 drawable
->allocate_textures
= dri2_allocate_textures
;
910 drawable
->flush_frontbuffer
= dri2_flush_frontbuffer
;
911 drawable
->update_tex_buffer
= dri2_update_tex_buffer
;
917 * DRI driver virtual function table.
919 * DRI versions differ in their implementation of init_screen and swap_buffers.
921 const struct __DriverAPIRec driDriverAPI
= {
922 .InitScreen
= dri2_init_screen
,
923 .DestroyScreen
= dri_destroy_screen
,
924 .CreateContext
= dri_create_context
,
925 .DestroyContext
= dri_destroy_context
,
926 .CreateBuffer
= dri2_create_buffer
,
927 .DestroyBuffer
= dri_destroy_buffer
,
928 .MakeCurrent
= dri_make_current
,
929 .UnbindContext
= dri_unbind_context
,
931 .AllocateBuffer
= dri2_allocate_buffer
,
932 .ReleaseBuffer
= dri2_release_buffer
,
935 /* This is the table of extensions that the loader will dlsym() for. */
936 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
937 &driCoreExtension
.base
,
938 &driDRI2Extension
.base
,
942 /* vim: set sw=3 ts=8 sts=3 expandtab: */