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 **************************************************************************/
29 #include "util/u_memory.h"
30 #include "util/u_inlines.h"
31 #include "pipe/p_context.h"
32 #include "state_tracker/drm_api.h"
34 #include "dri_screen.h"
35 #include "dri_context.h"
36 #include "dri_drawable.h"
37 #include "dri_st_api.h"
38 #include "dri1_helper.h"
43 get_drawable_info(__DRIdrawable
*dPriv
, int *w
, int *h
)
45 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
46 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
49 loader
->getDrawableInfo(dPriv
,
51 dPriv
->loaderPrivate
);
55 put_image(__DRIdrawable
*dPriv
, void *data
)
57 __DRIscreen
*sPriv
= dPriv
->driScreenPriv
;
58 const __DRIswrastLoaderExtension
*loader
= sPriv
->swrast_loader
;
60 loader
->putImage(dPriv
, __DRI_SWRAST_IMAGE_OP_SWAP
,
61 0, 0, dPriv
->w
, dPriv
->h
,
62 data
, dPriv
->loaderPrivate
);
66 drisw_update_drawable_info(__DRIdrawable
*dPriv
)
68 get_drawable_info(dPriv
, &dPriv
->w
, &dPriv
->h
);
72 drisw_present_texture(__DRIdrawable
*dPriv
,
73 struct pipe_texture
*ptex
)
75 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
76 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
77 struct pipe_context
*pipe
;
78 struct pipe_surface
*psurf
;
79 struct pipe_transfer
*ptrans
;
82 pipe
= dri1_get_pipe_context(screen
);
83 psurf
= dri1_get_pipe_surface(drawable
, ptex
);
87 ptrans
= pipe
->get_tex_transfer(pipe
, ptex
, 0, 0, 0,
89 0, 0, dPriv
->w
, dPriv
->h
);
91 pmap
= pipe
->transfer_map(pipe
, ptrans
);
95 put_image(dPriv
, pmap
);
97 pipe
->transfer_unmap(pipe
, ptrans
);
99 pipe
->tex_transfer_destroy(pipe
, ptrans
);
103 drisw_invalidate_drawable(__DRIdrawable
*dPriv
)
105 struct dri_context
*ctx
= dri_get_current();
106 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
108 drawable
->texture_stamp
= dPriv
->lastStamp
- 1;
110 /* check if swapping currently bound buffer */
111 if (ctx
&& ctx
->dPriv
== dPriv
)
112 ctx
->st
->notify_invalid_framebuffer(ctx
->st
, drawable
->stfb
);
116 drisw_copy_to_front(__DRIdrawable
* dPriv
,
117 struct pipe_texture
*ptex
)
119 drisw_present_texture(dPriv
, ptex
);
121 drisw_invalidate_drawable(dPriv
);
125 * Backend functions for st_framebuffer interface and swap_buffers.
129 drisw_flush_frontbuffer(struct dri_drawable
*drawable
,
130 enum st_attachment_type statt
)
132 struct dri_context
*ctx
= dri_get_current();
133 struct pipe_texture
*ptex
;
138 ptex
= drawable
->textures
[statt
];
141 drisw_copy_to_front(ctx
->dPriv
, ptex
);
146 drisw_swap_buffers(__DRIdrawable
*dPriv
)
148 struct dri_context
*ctx
= dri_get_current();
149 struct dri_drawable
*drawable
= dri_drawable(dPriv
);
150 struct pipe_texture
*ptex
;
155 ptex
= drawable
->textures
[ST_ATTACHMENT_BACK_LEFT
];
158 ctx
->st
->flush(ctx
->st
, PIPE_FLUSH_RENDER_CACHE
, NULL
);
160 drisw_copy_to_front(dPriv
, ptex
);
165 * Allocate framebuffer attachments.
167 * During fixed-size operation, the function keeps allocating new attachments
168 * as they are requested. Unused attachments are not removed, not until the
169 * framebuffer is resized or destroyed.
171 * It should be possible for DRI1 and DRISW to share this function, but it
172 * seems a better seperation and safer for each DRI version to provide its own
176 drisw_allocate_textures(struct dri_drawable
*drawable
,
179 struct dri_screen
*screen
= dri_screen(drawable
->sPriv
);
180 struct pipe_texture templ
;
181 unsigned width
, height
;
185 width
= drawable
->dPriv
->w
;
186 height
= drawable
->dPriv
->h
;
188 resized
= (drawable
->old_w
!= width
||
189 drawable
->old_h
!= height
);
191 /* remove outdated textures */
193 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
194 pipe_texture_reference(&drawable
->textures
[i
], NULL
);
197 memset(&templ
, 0, sizeof(templ
));
198 templ
.target
= PIPE_TEXTURE_2D
;
199 templ
.width0
= width
;
200 templ
.height0
= height
;
202 templ
.last_level
= 0;
204 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
205 enum pipe_format format
;
208 /* the texture already exists or not requested */
209 if (drawable
->textures
[i
] || !(mask
& (1 << i
))) {
214 case ST_ATTACHMENT_FRONT_LEFT
:
215 case ST_ATTACHMENT_BACK_LEFT
:
216 case ST_ATTACHMENT_FRONT_RIGHT
:
217 case ST_ATTACHMENT_BACK_RIGHT
:
218 format
= drawable
->stvis
.color_format
;
219 tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
220 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
222 case ST_ATTACHMENT_DEPTH_STENCIL
:
223 format
= drawable
->stvis
.depth_stencil_format
;
224 tex_usage
= PIPE_TEXTURE_USAGE_DEPTH_STENCIL
;
227 format
= PIPE_FORMAT_NONE
;
231 if (format
!= PIPE_FORMAT_NONE
) {
232 templ
.format
= format
;
233 templ
.tex_usage
= tex_usage
;
235 drawable
->textures
[i
] =
236 screen
->pipe_screen
->texture_create(screen
->pipe_screen
, &templ
);
240 drawable
->old_w
= width
;
241 drawable
->old_h
= height
;
245 * Backend function for init_screen.
248 static const __DRIextension
*drisw_screen_extensions
[] = {
253 drisw_init_screen(__DRIscreen
* sPriv
)
255 struct dri_screen
*screen
;
256 struct drm_create_screen_arg arg
;
258 screen
= CALLOC_STRUCT(dri_screen
);
262 screen
->api
= drm_api_create();
263 screen
->sPriv
= sPriv
;
265 sPriv
->private = (void *)screen
;
266 sPriv
->extensions
= drisw_screen_extensions
;
267 arg
.mode
= DRM_CREATE_DRISW
;
269 screen
->pipe_screen
= screen
->api
->create_screen(screen
->api
, -1, &arg
);
270 if (!screen
->pipe_screen
) {
271 debug_printf("%s: failed to create pipe_screen\n", __FUNCTION__
);
275 screen
->smapi
= dri_create_st_manager(screen
);
279 driParseOptionInfo(&screen
->optionCache
,
280 __driConfigOptions
, __driNConfigOptions
);
282 return dri_fill_in_modes(screen
, 32);
284 dri_destroy_screen(sPriv
);
288 /* vim: set sw=3 ts=8 sts=3 expandtab: */