2 * Mesa 3-D graphics library
5 * Copyright (C) 2010 LunarG Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "util/u_memory.h"
29 #include "util/u_inlines.h"
34 /* support OpenGL by default */
35 #ifndef XMESA_ST_MODULE
36 #define XMESA_ST_MODULE st_module_OpenGL
39 struct xmesa_st_framebuffer
{
40 struct pipe_screen
*screen
;
43 struct st_visual stvis
;
45 unsigned texture_width
, texture_height
;
46 struct pipe_texture
*textures
[ST_ATTACHMENT_COUNT
];
48 struct pipe_surface
*display_surface
;
51 static INLINE
struct xmesa_st_framebuffer
*
52 xmesa_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
54 return (struct xmesa_st_framebuffer
*) stfbi
->st_manager_private
;
58 * Display an attachment to the xlib_drawable of the framebuffer.
61 xmesa_st_framebuffer_display(struct st_framebuffer_iface
*stfbi
,
62 enum st_attachment_type statt
)
64 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
65 struct pipe_texture
*ptex
= xstfb
->textures
[statt
];
66 struct pipe_surface
*psurf
;
71 psurf
= xstfb
->display_surface
;
72 /* (re)allocate the surface for the texture to be displayed */
73 if (!psurf
|| psurf
->texture
!= ptex
) {
74 pipe_surface_reference(&xstfb
->display_surface
, NULL
);
76 psurf
= xstfb
->screen
->get_tex_surface(xstfb
->screen
,
77 ptex
, 0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ
);
81 xstfb
->display_surface
= psurf
;
84 xstfb
->screen
->flush_frontbuffer(xstfb
->screen
, psurf
, &xstfb
->buffer
->ws
);
90 * Remove outdated textures and create the requested ones.
93 xmesa_st_framebuffer_validate_textures(struct st_framebuffer_iface
*stfbi
,
94 const enum st_attachment_type
*statts
,
97 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
98 struct pipe_texture templ
;
99 unsigned request_mask
, i
;
102 for (i
= 0; i
< count
; i
++)
103 request_mask
|= 1 << statts
[i
];
105 memset(&templ
, 0, sizeof(templ
));
106 templ
.target
= PIPE_TEXTURE_2D
;
107 templ
.width0
= xstfb
->texture_width
;
108 templ
.height0
= xstfb
->texture_height
;
110 templ
.last_level
= 0;
112 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
113 struct pipe_texture
*ptex
= xstfb
->textures
[i
];
114 enum pipe_format format
;
117 /* remove outdated textures */
118 if (ptex
&& (ptex
->width0
!= xstfb
->texture_width
||
119 ptex
->height0
!= xstfb
->texture_height
)) {
120 pipe_texture_reference(&xstfb
->textures
[i
], NULL
);
124 /* the texture already exists or not requested */
125 if (ptex
|| !(request_mask
& (1 << i
)))
129 case ST_ATTACHMENT_FRONT_LEFT
:
130 case ST_ATTACHMENT_BACK_LEFT
:
131 case ST_ATTACHMENT_FRONT_RIGHT
:
132 case ST_ATTACHMENT_BACK_RIGHT
:
133 format
= xstfb
->stvis
.color_format
;
134 tex_usage
= PIPE_TEXTURE_USAGE_DISPLAY_TARGET
|
135 PIPE_TEXTURE_USAGE_RENDER_TARGET
;
137 case ST_ATTACHMENT_DEPTH_STENCIL
:
138 format
= xstfb
->stvis
.depth_stencil_format
;
139 tex_usage
= PIPE_TEXTURE_USAGE_DEPTH_STENCIL
;
142 format
= PIPE_FORMAT_NONE
;
146 if (format
!= PIPE_FORMAT_NONE
) {
147 templ
.format
= format
;
148 templ
.tex_usage
= tex_usage
;
151 xstfb
->screen
->texture_create(xstfb
->screen
, &templ
);
157 xmesa_st_framebuffer_validate(struct st_framebuffer_iface
*stfbi
,
158 const enum st_attachment_type
*statts
,
160 struct pipe_texture
**out
)
162 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
165 /* revalidate textures */
166 if (xstfb
->buffer
->width
!= xstfb
->texture_width
||
167 xstfb
->buffer
->height
!= xstfb
->texture_height
) {
168 xstfb
->texture_width
= xstfb
->buffer
->width
;
169 xstfb
->texture_height
= xstfb
->buffer
->height
;
171 xmesa_st_framebuffer_validate_textures(stfbi
, statts
, count
);
174 for (i
= 0; i
< count
; i
++) {
176 pipe_texture_reference(&out
[i
], xstfb
->textures
[statts
[i
]]);
183 xmesa_st_framebuffer_flush_front(struct st_framebuffer_iface
*stfbi
,
184 enum st_attachment_type statt
)
186 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
189 ret
= xmesa_st_framebuffer_display(stfbi
, statt
);
191 xmesa_check_buffer_size(xstfb
->buffer
);
196 struct st_framebuffer_iface
*
197 xmesa_create_st_framebuffer(struct pipe_screen
*screen
, XMesaBuffer b
)
199 struct st_framebuffer_iface
*stfbi
;
200 struct xmesa_st_framebuffer
*xstfb
;
202 stfbi
= CALLOC_STRUCT(st_framebuffer_iface
);
203 xstfb
= CALLOC_STRUCT(xmesa_st_framebuffer
);
204 if (!stfbi
|| !xstfb
) {
212 xstfb
->screen
= screen
;
214 xstfb
->stvis
= b
->xm_visual
->stvis
;
216 stfbi
->visual
= &xstfb
->stvis
;
217 stfbi
->flush_front
= xmesa_st_framebuffer_flush_front
;
218 stfbi
->validate
= xmesa_st_framebuffer_validate
;
219 stfbi
->st_manager_private
= (void *) xstfb
;
225 xmesa_destroy_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
227 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
234 xmesa_swap_st_framebuffer(struct st_framebuffer_iface
*stfbi
)
236 struct xmesa_st_framebuffer
*xstfb
= xmesa_st_framebuffer(stfbi
);
239 ret
= xmesa_st_framebuffer_display(stfbi
, ST_ATTACHMENT_BACK_LEFT
);
241 struct pipe_texture
**front
, **back
, *tmp
;
243 front
= &xstfb
->textures
[ST_ATTACHMENT_FRONT_LEFT
];
244 back
= &xstfb
->textures
[ST_ATTACHMENT_BACK_LEFT
];
245 /* swap textures only if the front texture has been allocated */
252 xmesa_check_buffer_size(xstfb
->buffer
);
257 xmesa_copy_st_framebuffer(struct st_framebuffer_iface
*stfbi
,
258 enum st_attachment_type src
,
259 enum st_attachment_type dst
,
260 int x
, int y
, int w
, int h
)
266 xmesa_create_st_api(void)
268 return XMESA_ST_MODULE
.create_api();