2 * Mesa 3-D graphics library
4 * Copyright (C) 2010 LunarG Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
28 #include "util/u_memory.h"
29 #include "util/u_inlines.h"
30 #include "util/u_atomic.h"
31 #include "state_tracker/st_gl_api.h" /* for st_gl_api_create */
34 #include "stw_device.h"
35 #include "stw_framebuffer.h"
36 #include "stw_pixelformat.h"
38 struct stw_st_framebuffer
{
39 struct st_framebuffer_iface base
;
41 struct stw_framebuffer
*fb
;
42 struct st_visual stvis
;
44 struct pipe_resource
*textures
[ST_ATTACHMENT_COUNT
];
45 unsigned texture_width
, texture_height
;
46 unsigned texture_mask
;
49 static inline struct stw_st_framebuffer
*
50 stw_st_framebuffer(struct st_framebuffer_iface
*stfb
)
52 return (struct stw_st_framebuffer
*) stfb
;
56 * Remove outdated textures and create the requested ones.
59 stw_st_framebuffer_validate_locked(struct st_framebuffer_iface
*stfb
,
60 unsigned width
, unsigned height
,
63 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
64 struct pipe_resource templ
;
67 /* remove outdated textures */
68 if (stwfb
->texture_width
!= width
|| stwfb
->texture_height
!= height
) {
69 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
70 pipe_resource_reference(&stwfb
->textures
[i
], NULL
);
73 memset(&templ
, 0, sizeof(templ
));
74 templ
.target
= PIPE_TEXTURE_2D
;
76 templ
.height0
= height
;
80 templ
.nr_samples
= stwfb
->stvis
.samples
;
82 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++) {
83 enum pipe_format format
;
86 /* the texture already exists or not requested */
87 if (stwfb
->textures
[i
] || !(mask
& (1 << i
))) {
88 /* remember the texture */
89 if (stwfb
->textures
[i
])
95 case ST_ATTACHMENT_FRONT_LEFT
:
96 case ST_ATTACHMENT_BACK_LEFT
:
97 format
= stwfb
->stvis
.color_format
;
98 bind
= PIPE_BIND_DISPLAY_TARGET
|
99 PIPE_BIND_SAMPLER_VIEW
|
100 PIPE_BIND_RENDER_TARGET
;
102 case ST_ATTACHMENT_DEPTH_STENCIL
:
103 format
= stwfb
->stvis
.depth_stencil_format
;
104 bind
= PIPE_BIND_DEPTH_STENCIL
;
107 format
= PIPE_FORMAT_NONE
;
111 if (format
!= PIPE_FORMAT_NONE
) {
112 templ
.format
= format
;
116 stw_dev
->screen
->resource_create(stw_dev
->screen
, &templ
);
120 stwfb
->texture_width
= width
;
121 stwfb
->texture_height
= height
;
122 stwfb
->texture_mask
= mask
;
126 stw_st_framebuffer_validate(struct st_context_iface
*stctx
,
127 struct st_framebuffer_iface
*stfb
,
128 const enum st_attachment_type
*statts
,
130 struct pipe_resource
**out
)
132 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
133 unsigned statt_mask
, i
;
136 for (i
= 0; i
< count
; i
++)
137 statt_mask
|= 1 << statts
[i
];
139 stw_framebuffer_lock(stwfb
->fb
);
141 if (stwfb
->fb
->must_resize
|| (statt_mask
& ~stwfb
->texture_mask
)) {
142 stw_st_framebuffer_validate_locked(&stwfb
->base
,
143 stwfb
->fb
->width
, stwfb
->fb
->height
, statt_mask
);
144 stwfb
->fb
->must_resize
= FALSE
;
147 for (i
= 0; i
< count
; i
++) {
149 pipe_resource_reference(&out
[i
], stwfb
->textures
[statts
[i
]]);
152 stw_framebuffer_unlock(stwfb
->fb
);
158 * Present an attachment of the framebuffer.
161 stw_st_framebuffer_present_locked(HDC hdc
,
162 struct st_framebuffer_iface
*stfb
,
163 enum st_attachment_type statt
)
165 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
166 struct pipe_resource
*resource
;
168 resource
= stwfb
->textures
[statt
];
170 stw_framebuffer_present_locked(hdc
, stwfb
->fb
, resource
);
173 stw_framebuffer_unlock(stwfb
->fb
);
180 stw_st_framebuffer_flush_front(struct st_context_iface
*stctx
,
181 struct st_framebuffer_iface
*stfb
,
182 enum st_attachment_type statt
)
184 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
188 stw_framebuffer_lock(stwfb
->fb
);
190 /* We must not cache HDCs anywhere, as they can be invalidated by the
191 * application, or screen resolution changes. */
193 hDC
= GetDC(stwfb
->fb
->hWnd
);
195 ret
= stw_st_framebuffer_present_locked(hDC
, &stwfb
->base
, statt
);
197 ReleaseDC(stwfb
->fb
->hWnd
, hDC
);
203 * Create a framebuffer interface.
205 struct st_framebuffer_iface
*
206 stw_st_create_framebuffer(struct stw_framebuffer
*fb
)
208 struct stw_st_framebuffer
*stwfb
;
210 stwfb
= CALLOC_STRUCT(stw_st_framebuffer
);
215 stwfb
->stvis
= fb
->pfi
->stvis
;
217 stwfb
->base
.visual
= &stwfb
->stvis
;
218 p_atomic_set(&stwfb
->base
.stamp
, 1);
219 stwfb
->base
.flush_front
= stw_st_framebuffer_flush_front
;
220 stwfb
->base
.validate
= stw_st_framebuffer_validate
;
226 * Destroy a framebuffer interface.
229 stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface
*stfb
)
231 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
234 for (i
= 0; i
< ST_ATTACHMENT_COUNT
; i
++)
235 pipe_resource_reference(&stwfb
->textures
[i
], NULL
);
241 * Swap the buffers of the given framebuffer.
244 stw_st_swap_framebuffer_locked(HDC hdc
, struct st_framebuffer_iface
*stfb
)
246 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
247 unsigned front
= ST_ATTACHMENT_FRONT_LEFT
, back
= ST_ATTACHMENT_BACK_LEFT
;
248 struct pipe_resource
*ptex
;
251 /* swap the textures */
252 ptex
= stwfb
->textures
[front
];
253 stwfb
->textures
[front
] = stwfb
->textures
[back
];
254 stwfb
->textures
[back
] = ptex
;
256 /* convert to mask */
260 /* swap the bits in mask */
261 mask
= stwfb
->texture_mask
& ~(front
| back
);
262 if (stwfb
->texture_mask
& front
)
264 if (stwfb
->texture_mask
& back
)
266 stwfb
->texture_mask
= mask
;
268 front
= ST_ATTACHMENT_FRONT_LEFT
;
269 return stw_st_framebuffer_present_locked(hdc
, &stwfb
->base
, front
);
274 * Return the pipe_resource that correspond to given buffer.
276 struct pipe_resource
*
277 stw_get_framebuffer_resource(struct st_framebuffer_iface
*stfb
,
278 enum st_attachment_type att
)
280 struct stw_st_framebuffer
*stwfb
= stw_st_framebuffer(stfb
);
281 return stwfb
->textures
[att
];
286 * Create an st_api of the state tracker.
289 stw_st_create_api(void)
291 return st_gl_api_create();