2 * Copyright © 2008 Jérôme Glisse
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 * Jérôme Glisse <glisse@freedesktop.org>
31 #include "pipe/p_screen.h"
32 #include "pipe/p_defines.h"
33 #include "pipe/p_inlines.h"
34 #include "pipe/p_context.h"
35 #include "pipe/p_state.h"
36 #include "state_tracker/st_public.h"
37 #include "state_tracker/st_context.h"
42 #include "radeon_screen.h"
43 #include "radeon_context.h"
44 #include "radeon_buffer.h"
45 #include "radeon_bo.h"
46 #include "radeon_bo_gem.h"
47 #include "radeon_drm.h"
49 extern const struct dri_extension radeon_card_extensions
[];
51 static const __DRIextension
*radeon_screen_extensions
[] = {
52 &driReadDrawableExtension
,
53 &driCopySubBufferExtension
.base
,
54 &driSwapControlExtension
.base
,
55 &driFrameTrackingExtension
.base
,
56 &driMediaStreamCounterExtension
.base
,
60 static __DRIconfig
**radeon_fill_in_modes(unsigned pixel_bits
,
62 GLboolean have_back_buffer
)
64 __DRIconfig
**configs
;
65 unsigned depth_buffer_factor
;
66 unsigned back_buffer_factor
;
70 uint8_t depth_bits_array
[3];
71 uint8_t stencil_bits_array
[3];
72 uint8_t msaa_samples_array
[1];
73 /* TODO: pageflipping ? */
74 static const GLenum back_buffer_modes
[] = {
75 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
78 stencil_bits_array
[0] = 0;
79 stencil_bits_array
[1] = 0;
80 if (depth_bits
== 24) {
81 stencil_bits_array
[2] = 8;
85 depth_bits_array
[0] = 0;
86 depth_bits_array
[1] = depth_bits
;
87 depth_bits_array
[2] = depth_bits
;
88 depth_buffer_factor
= (depth_bits
== 24) ? 3 : 2;
90 back_buffer_factor
= (have_back_buffer
) ? 3 : 1;
92 msaa_samples_array
[0] = 0;
94 if (pixel_bits
== 16) {
96 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
99 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
102 configs
= (__DRIconfig
**)driCreateConfigs(fb_format
,
111 if (configs
== NULL
) {
112 fprintf(stderr
, "[%s:%u] Error creating FBConfig!\n",
119 static void radeon_screen_destroy(__DRIscreenPrivate
*dri_screen
)
121 struct radeon_screen
*radeon_screen
= (struct radeon_screen
*)dri_screen
->private;
123 radeon_bo_manager_gem_dtor(radeon_screen
->bom
);
128 static const __DRIconfig
**radeon_screen_init(__DRIscreenPrivate
*dri_screen
)
130 struct radeon_screen
*radeon_screen
;
132 /* Calling driInitExtensions here, with a NULL context pointer,
133 * does not actually enable the extensions. It just makes sure
134 * that all the dispatch offsets for all the extensions that
135 * *might* be enables are known. This is needed because the
136 * dispatch offsets need to be known when _mesa_context_create is
137 * called, but we can't enable the extensions until we have a
140 * Hello chicken. Hello egg. How are you two today?
142 driInitExtensions(NULL
, radeon_card_extensions
, GL_FALSE
);
144 radeon_screen
= calloc(1, sizeof(struct radeon_screen
));
145 if (radeon_screen
== NULL
) {
146 fprintf(stderr
, "\nERROR! Allocating private area failed\n");
149 dri_screen
->private = (void*)radeon_screen
;
150 dri_screen
->extensions
= radeon_screen_extensions
;
151 radeon_screen
->dri_screen
= dri_screen
;
153 radeon_screen
->bom
= radeon_bo_manager_gem_ctor(dri_screen
->fd
);
154 if (radeon_screen
->bom
== NULL
) {
155 radeon_screen_destroy(dri_screen
);
159 return driConcatConfigs(radeon_fill_in_modes(16, 16, 1),
160 radeon_fill_in_modes(32, 24, 1));
163 static boolean
radeon_buffer_create(__DRIscreenPrivate
*dri_screen
,
164 __DRIdrawablePrivate
*dri_drawable
,
165 const __GLcontextModes
*visual
,
169 /* TODO: implement ? */
172 enum pipe_format color_format
, depth_format
, stencil_format
;
173 struct radeon_framebuffer
*radeon_fb
;
175 radeon_fb
= calloc(1, sizeof(struct radeon_framebuffer
));
176 if (radeon_fb
== NULL
) {
180 switch (visual
->redBits
) {
182 color_format
= PIPE_FORMAT_R5G6B5_UNORM
;
185 color_format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
189 switch (visual
->depthBits
) {
191 depth_format
= PIPE_FORMAT_S8Z24_UNORM
;
194 depth_format
= PIPE_FORMAT_Z16_UNORM
;
197 depth_format
= PIPE_FORMAT_NONE
;
201 switch (visual
->stencilBits
) {
203 /* force depth format */
204 depth_format
= PIPE_FORMAT_S8Z24_UNORM
;
205 stencil_format
= PIPE_FORMAT_S8Z24_UNORM
;
208 stencil_format
= PIPE_FORMAT_NONE
;
212 radeon_fb
->st_framebuffer
= st_create_framebuffer(visual
,
219 if (radeon_fb
->st_framebuffer
== NULL
) {
223 dri_drawable
->driverPrivate
= (void *) radeon_fb
;
225 radeon_fb
->attachments
= (1 << __DRI_BUFFER_FRONT_LEFT
);
226 if (visual
->doubleBufferMode
) {
227 radeon_fb
->attachments
|= (1 << __DRI_BUFFER_BACK_LEFT
);
229 if (visual
->depthBits
|| visual
->stencilBits
) {
230 radeon_fb
->attachments
|= (1 << __DRI_BUFFER_DEPTH
);
237 static void radeon_buffer_destroy(__DRIdrawablePrivate
* dri_drawable
)
239 struct radeon_framebuffer
*radeon_fb
;
241 radeon_fb
= dri_drawable
->driverPrivate
;
242 assert(radeon_fb
->st_framebuffer
);
243 st_unreference_framebuffer(radeon_fb
->st_framebuffer
);
247 static void radeon_swap_buffers(__DRIdrawablePrivate
*dri_drawable
)
249 struct radeon_framebuffer
*radeon_fb
;
250 struct pipe_surface
*back_surf
= NULL
;
252 radeon_fb
= dri_drawable
->driverPrivate
;
254 assert(radeon_fb
->st_framebuffer
);
256 st_get_framebuffer_surface(radeon_fb
->st_framebuffer
,
257 ST_SURFACE_BACK_LEFT
,
260 st_notify_swapbuffers(radeon_fb
->st_framebuffer
);
261 /* TODO: do we want to do anythings ? */
262 st_notify_swapbuffers_complete(radeon_fb
->st_framebuffer
);
267 * Called via glXCopySubBufferMESA() to copy a subrect of the back
268 * buffer to the front buffer/screen.
270 static void radeon_copy_sub_buffer(__DRIdrawablePrivate
*dri_drawable
,
271 int x
, int y
, int w
, int h
)
276 const struct __DriverAPIRec driDriverAPI
= {
278 .DestroyScreen
= radeon_screen_destroy
,
279 .CreateContext
= radeon_context_create
,
280 .DestroyContext
= radeon_context_destroy
,
281 .CreateBuffer
= radeon_buffer_create
,
282 .DestroyBuffer
= radeon_buffer_destroy
,
283 .SwapBuffers
= radeon_swap_buffers
,
284 .MakeCurrent
= radeon_context_bind
,
285 .UnbindContext
= radeon_context_unbind
,
286 .CopySubBuffer
= radeon_copy_sub_buffer
,
287 .InitScreen2
= radeon_screen_init
,