1 /**************************************************************************
3 * Copyright 2009, VMware, Inc.
5 * Copyright 2010 George Sapountzis <gsapountzis@gmail.com>
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
33 * The driver and the loaders (libGL, xserver/glx) compute the stride from the
34 * width independently. winsys has a workaround that works for softpipe but may
35 * explode for other drivers or platforms, rendering- or performance-wise.
36 * Solving this issue properly requires extending the DRISW loader extension,
37 * in order to make the stride available to the putImage callback.
41 * Define drisw_api similarly to dri_api and use it to call the loader. This is
42 * predicated on support for calling the loader from the winsys, which has to
43 * grow for DRI2 as well.
47 * Allow the loaders to use the XSHM extension. It probably requires callbacks
48 * for createImage/destroyImage similar to DRI2 getBuffers. Probably not worth
49 * it, given the scope of DRISW, unless it falls naturally from properly
50 * solving the above two issues.
52 * swrast_create_screen:
54 * Allow for any software renderer to be used. Factor out the code from
55 * targets/libgl-xlib/xlib.c, put it in targets/common or winsys/sw/common and
56 * use it in all software targets.
59 #include "util/u_memory.h"
60 #include "util/u_inlines.h"
61 #include "pipe/p_context.h"
62 #include "state_tracker/drm_api.h"
64 #include "dri_screen.h"
65 #include "dri_context.h"
66 #include "dri_drawable.h"
67 #include "dri_st_api.h"
68 #include "dri1_helper.h"
73 get_drawable_info(__DRIdrawable
*dPriv
, int *w
, int *h
)
75 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
76 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
79 loader
->getDrawableInfo(dPriv
,
81 dPriv
->loaderPrivate
);
85 put_image(__DRIdrawable
*dPriv
, void *data
)
87 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
88 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
90 loader
->putImage(dPriv
, __DRI_SWRAST_IMAGE_OP_SWAP
,
91 0, 0, dPriv
->w
, dPriv
->h
,
92 data
, dPriv
->loaderPrivate
);
96 drisw_update_drawable_info(__DRIdrawable
*dPriv
)
98 get_drawable_info(dPriv
, &dPriv
->w
, &dPriv
->h
);
102 drisw_present_texture(__DRIdrawable
*dPriv
,
103 struct pipe_texture
*ptex
)
105 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
106 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
107 struct pipe_context
*pipe
;
108 struct pipe_surface
*psurf
;
109 struct pipe_transfer
*ptrans
;
112 pipe
= dri1_get_pipe_context(screen
);
113 psurf
= dri1_get_pipe_surface(drawable
, ptex
);
117 ptrans
= pipe
->get_tex_transfer(pipe
, ptex
, 0, 0, 0,
119 0, 0, dPriv
->w
, dPriv
->h
);
121 pmap
= pipe
->transfer_map(pipe
, ptrans
);
125 put_image(dPriv
, pmap
);
127 pipe
->transfer_unmap(pipe
, ptrans
);
129 pipe
->tex_transfer_destroy(pipe
, ptrans
);
133 drisw_invalidate_drawable(__DRIdrawable
*dPriv
)
135 struct dri_context
*ctx
= dri_get_current();
136 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
138 drawable
->texture_stamp
= dPriv
->lastStamp
- 1;
140 /* check if swapping currently bound buffer */
141 if (ctx
&& ctx
->dPriv
== dPriv
)
142 ctx
->st
->notify_invalid_framebuffer(ctx
->st
, drawable
->stfb
);
146 drisw_copy_to_front(__DRIdrawable
* dPriv
,
147 struct pipe_texture
*ptex
)
149 drisw_present_texture(dPriv
, ptex
);
151 drisw_invalidate_drawable(dPriv
);
155 * Backend functions for st_framebuffer interface and swap_buffers.
159 drisw_flush_frontbuffer(struct dri_drawable
*drawable
,
160 enum st_attachment_type statt
)
162 struct dri_context
*ctx
= dri_get_current();
163 struct pipe_texture
*ptex
;
168 ptex
= drawable
->textures
[statt
];
171 drisw_copy_to_front(ctx
->dPriv
, ptex
);
176 drisw_swap_buffers(__DRIdrawable
*dPriv
)
178 struct dri_context
*ctx
= dri_get_current();
179 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
180 struct pipe_texture
*ptex
;
185 ptex
= drawable
->textures
[ST_ATTACHMENT_BACK_LEFT
];
188 ctx
->st
->flush(ctx
->st
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
190 drisw_copy_to_front(dPriv
, ptex
);
195 * Allocate framebuffer attachments.
197 * During fixed-size operation, the function keeps allocating new attachments
198 * as they are requested. Unused attachments are not removed, not until the
199 * framebuffer is resized or destroyed.
201 * It should be possible for DRI1 and DRISW to share this function, but it
202 * seems a better seperation and safer for each DRI version to provide its own
206 drisw_allocate_textures(struct dri_drawable
*drawable
,
209 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
210 struct pipe_texture templ
;
211 unsigned width
, height
;
215 width
= drawable
->dPriv
->w
;
216 height
= drawable
->dPriv
->h
;
218 resized
= (drawable
->old_w
!= width
||
219 drawable
->old_h
!= height
);
221 /* remove outdated textures */
223 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
224 pipe_texture_reference(&drawable
->textures
[i
], NULL
);
227 memset(&templ
, 0, sizeof(templ
));
228 templ
.target
= PIPE_TEXTURE_2D
;
229 templ
.width0
= width
;
230 templ
.height0
= height
;
232 templ
.last_level
= 0;
234 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
235 enum pipe_format format
;
238 /* the texture already exists or not requested */
239 if (drawable
->textures
[i
] || !(mask
& (1 << i
))) {
244 case ST_ATTACHMENT_FRONT_LEFT
:
245 case ST_ATTACHMENT_BACK_LEFT
:
246 case ST_ATTACHMENT_FRONT_RIGHT
:
247 case ST_ATTACHMENT_BACK_RIGHT
:
248 format
= drawable
->stvis
.color_format
;
249 tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
250 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
252 case ST_ATTACHMENT_DEPTH_STENCIL
:
253 format
= drawable
->stvis
.depth_stencil_format
;
254 tex_usage
= PIPE_TEXTURE_USAGE_DEPTH_STENCIL
;
257 format
= PIPE_FORMAT_NONE
;
261 if (format
!= PIPE_FORMAT_NONE
) {
262 templ
.format
= format
;
263 templ
.tex_usage
= tex_usage
;
265 drawable
->textures
[i
] =
266 screen
->pipe_screen
->texture_create(screen
->pipe_screen
, &templ
);
270 drawable
->old_w
= width
;
271 drawable
->old_h
= height
;
275 * Backend function for init_screen.
278 static const __DRIextension
*drisw_screen_extensions
[] = {
283 drisw_init_screen(__DRIscreen
* sPriv
)
285 struct dri_screen
*screen
;
286 struct drm_create_screen_arg arg
;
288 screen
= CALLOC_STRUCT(dri_screen
);
292 screen
->api
= drm_api_create();
293 screen
->sPriv
= sPriv
;
295 sPriv
->private = (void *)screen
;
296 sPriv
->extensions
= drisw_screen_extensions
;
297 arg
.mode
= DRM_CREATE_DRISW
;
299 screen
->pipe_screen
= screen
->api
->create_screen(screen
->api
, -1, &arg
);
300 if (!screen
->pipe_screen
) {
301 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__
);
305 screen
->smapi
= dri_create_st_manager(screen
);
309 driParseOptionInfo(&screen
->optionCache
,
310 __driConfigOptions
, __driNConfigOptions
);
312 return dri_fill_in_modes(screen
, 32);
314 dri_destroy_screen(sPriv
);
318 /* vim: set sw=3 ts=8 sts=3 expandtab: */