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 dri1_api and use it to call the loader. This
42 * is predicated on support for calling the loader from the winsys, which has
43 * to grow for DRI2 as well.
45 * xshm / texture_from_pixmap / EGLImage:
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 other issues.
54 * No fences are used, are they needed for llvmpipe / cell ?
57 #include "util/u_format.h"
58 #include "util/u_memory.h"
59 #include "util/u_inlines.h"
60 #include "pipe/p_context.h"
61 #include "state_tracker/drm_api.h"
63 #include "dri_screen.h"
64 #include "dri_context.h"
65 #include "dri_drawable.h"
66 #include "dri_st_api.h"
67 #include "dri1_helper.h"
72 get_drawable_info(__DRIdrawable
*dPriv
, int *w
, int *h
)
74 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
75 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
78 loader
->getDrawableInfo(dPriv
,
80 dPriv
->loaderPrivate
);
84 * Set the width to 'stride / cpp'. PutImage seems to correctly clip the width
85 * to the actual width of the dst drawable. Even if this is not specified but
86 * an implementation detail, it is the correct thing to do, so rely on it. XXX
89 put_image(__DRIdrawable
*dPriv
, void *data
, unsigned width
)
91 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
92 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
94 loader
->putImage(dPriv
, __DRI_SWRAST_IMAGE_OP_SWAP
,
95 0, 0, width
, dPriv
->h
,
96 data
, dPriv
->loaderPrivate
);
100 drisw_update_drawable_info(__DRIdrawable
*dPriv
)
102 get_drawable_info(dPriv
, &dPriv
->w
, &dPriv
->h
);
106 drisw_present_texture(__DRIdrawable
*dPriv
,
107 struct pipe_texture
*ptex
)
109 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
110 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
111 struct pipe_context
*pipe
;
112 struct pipe_surface
*psurf
;
113 struct pipe_transfer
*ptrans
;
117 pipe
= dri1_get_pipe_context(screen
);
118 psurf
= dri1_get_pipe_surface(drawable
, ptex
);
122 ptrans
= pipe
->get_tex_transfer(pipe
, ptex
, 0, 0, 0,
124 0, 0, dPriv
->w
, dPriv
->h
);
126 width
= ptrans
->stride
/ util_format_get_blocksize(ptex
->format
);
128 pmap
= pipe
->transfer_map(pipe
, ptrans
);
132 put_image(dPriv
, pmap
, width
);
134 pipe
->transfer_unmap(pipe
, ptrans
);
136 pipe
->tex_transfer_destroy(pipe
, ptrans
);
140 drisw_invalidate_drawable(__DRIdrawable
*dPriv
)
142 struct dri_context
*ctx
= dri_get_current();
143 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
145 drawable
->texture_stamp
= dPriv
->lastStamp
- 1;
147 /* check if swapping currently bound buffer */
148 if (ctx
&& ctx
->dPriv
== dPriv
)
149 ctx
->st
->notify_invalid_framebuffer(ctx
->st
, drawable
->stfb
);
153 drisw_copy_to_front(__DRIdrawable
* dPriv
,
154 struct pipe_texture
*ptex
)
156 drisw_present_texture(dPriv
, ptex
);
158 drisw_invalidate_drawable(dPriv
);
162 * Backend functions for st_framebuffer interface and swap_buffers.
166 drisw_flush_frontbuffer(struct dri_drawable
*drawable
,
167 enum st_attachment_type statt
)
169 struct dri_context
*ctx
= dri_get_current();
170 struct pipe_texture
*ptex
;
175 ptex
= drawable
->textures
[statt
];
178 drisw_copy_to_front(ctx
->dPriv
, ptex
);
183 drisw_swap_buffers(__DRIdrawable
*dPriv
)
185 struct dri_context
*ctx
= dri_get_current();
186 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
187 struct pipe_texture
*ptex
;
192 ptex
= drawable
->textures
[ST_ATTACHMENT_BACK_LEFT
];
195 ctx
->st
->flush(ctx
->st
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
197 drisw_copy_to_front(dPriv
, ptex
);
202 * Allocate framebuffer attachments.
204 * During fixed-size operation, the function keeps allocating new attachments
205 * as they are requested. Unused attachments are not removed, not until the
206 * framebuffer is resized or destroyed.
208 * It should be possible for DRI1 and DRISW to share this function, but it
209 * seems a better seperation and safer for each DRI version to provide its own
213 drisw_allocate_textures(struct dri_drawable
*drawable
,
216 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
217 struct pipe_texture templ
;
218 unsigned width
, height
;
222 width
= drawable
->dPriv
->w
;
223 height
= drawable
->dPriv
->h
;
225 resized
= (drawable
->old_w
!= width
||
226 drawable
->old_h
!= height
);
228 /* remove outdated textures */
230 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
231 pipe_texture_reference(&drawable
->textures
[i
], NULL
);
234 memset(&templ
, 0, sizeof(templ
));
235 templ
.target
= PIPE_TEXTURE_2D
;
236 templ
.width0
= width
;
237 templ
.height0
= height
;
239 templ
.last_level
= 0;
241 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
242 enum pipe_format format
;
245 /* the texture already exists or not requested */
246 if (drawable
->textures
[i
] || !(mask
& (1 << i
))) {
251 case ST_ATTACHMENT_FRONT_LEFT
:
252 case ST_ATTACHMENT_BACK_LEFT
:
253 case ST_ATTACHMENT_FRONT_RIGHT
:
254 case ST_ATTACHMENT_BACK_RIGHT
:
255 format
= drawable
->stvis
.color_format
;
256 tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
257 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
259 case ST_ATTACHMENT_DEPTH_STENCIL
:
260 format
= drawable
->stvis
.depth_stencil_format
;
261 tex_usage
= PIPE_TEXTURE_USAGE_DEPTH_STENCIL
;
264 format
= PIPE_FORMAT_NONE
;
268 if (format
!= PIPE_FORMAT_NONE
) {
269 templ
.format
= format
;
270 templ
.tex_usage
= tex_usage
;
272 drawable
->textures
[i
] =
273 screen
->pipe_screen
->texture_create(screen
->pipe_screen
, &templ
);
277 drawable
->old_w
= width
;
278 drawable
->old_h
= height
;
282 * Backend function for init_screen.
285 static const __DRIextension
*drisw_screen_extensions
[] = {
290 drisw_init_screen(__DRIscreen
* sPriv
)
292 const __DRIconfig
**configs
;
293 struct dri_screen
*screen
;
294 struct drm_create_screen_arg arg
;
296 screen
= CALLOC_STRUCT(dri_screen
);
300 screen
->api
= drm_api_create();
301 screen
->sPriv
= sPriv
;
304 sPriv
->private = (void *)screen
;
305 sPriv
->extensions
= drisw_screen_extensions
;
307 arg
.mode
= DRM_CREATE_DRISW
;
309 configs
= dri_init_screen_helper(screen
, &arg
, 32);
315 dri_destroy_screen_helper(screen
);
320 /* This is the table of extensions that the loader will dlsym() for. */
321 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
322 &driCoreExtension
.base
,
323 &driSWRastExtension
.base
,
327 /* vim: set sw=3 ts=8 sts=3 expandtab: */