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>
32 #include "pipe/p_defines.h"
33 #include "pipe/p_inlines.h"
34 #include "state_tracker/st_public.h"
35 #include "state_tracker/st_context.h"
36 #include "amd_screen.h"
37 #include "amd_context.h"
38 #include "amd_buffer.h"
39 #include "amd_winsys_softpipe.h"
41 #define need_GL_ARB_fragment_program
42 #define need_GL_ARB_multisample
43 #define need_GL_ARB_point_parameters
44 #define need_GL_ARB_shader_objects
45 #define need_GL_ARB_texture_compression
46 #define need_GL_ARB_vertex_buffer_object
47 #define need_GL_ARB_vertex_program
48 #define need_GL_ARB_vertex_shader
49 #define need_GL_EXT_blend_color
50 #define need_GL_EXT_blend_equation_separate
51 #define need_GL_EXT_blend_func_separate
52 #define need_GL_EXT_blend_minmax
53 #define need_GL_EXT_cull_vertex
54 #define need_GL_EXT_compiled_vertex_array
55 #define need_GL_EXT_fog_coord
56 #define need_GL_EXT_framebuffer_object
57 #define need_GL_EXT_multi_draw_arrays
58 #define need_GL_EXT_secondary_color
59 #define need_GL_VERSION_2_0
60 #define need_GL_VERSION_2_1
61 #include "extension_helper.h"
64 * Extension strings exported by the amd driver.
66 const struct dri_extension amd_card_extensions
[] = {
67 {"GL_ARB_multitexture", NULL
},
68 {"GL_ARB_texture_border_clamp", NULL
},
69 {"GL_ARB_texture_rectangle", NULL
},
70 {"GL_ARB_pixel_buffer_object", NULL
},
71 {"GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
72 {"GL_ARB_shader_objects", GL_ARB_shader_objects_functions
},
73 {"GL_ARB_shading_language_100", GL_VERSION_2_0_functions
},
74 {"GL_ARB_shading_language_120", GL_VERSION_2_1_functions
},
75 {"GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions
},
76 {"GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
77 {"GL_ARB_vertex_shader", GL_ARB_vertex_shader_functions
},
78 {"GL_EXT_blend_color", GL_EXT_blend_color_functions
},
79 {"GL_EXT_blend_equation_separate", GL_EXT_blend_equation_separate_functions
},
80 {"GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions
},
81 {"GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions
},
82 {"GL_EXT_blend_subtract", NULL
},
83 {"GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions
},
84 {"GL_EXT_cull_vertex", GL_EXT_cull_vertex_functions
},
85 {"GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
86 {"GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions
},
87 {"GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions
},
88 {"GL_EXT_packed_depth_stencil", NULL
},
89 {"GL_EXT_pixel_buffer_object", NULL
},
90 {"GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
91 {"GL_EXT_stencil_wrap", NULL
},
95 static void amd_update_renderbuffers(__DRIcontext
*dri_context
,
96 __DRIdrawable
*dri_drawable
)
98 struct amd_framebuffer
*amd_fb
;
99 struct amd_context
*amd_context
;
100 unsigned attachments
[10];
101 __DRIbuffer
*buffers
;
105 amd_context
= dri_context
->driverPrivate
;
106 screen
= dri_drawable
->driScreenPriv
;
107 amd_fb
= dri_drawable
->driverPrivate
;
108 for (count
= 0, i
= 0; count
< 6; count
++) {
109 if (amd_fb
->attachments
& (1 << count
)) {
110 attachments
[i
++] = count
;
114 buffers
= (*screen
->dri2
.loader
->getBuffers
)(dri_drawable
,
120 dri_drawable
->loaderPrivate
);
121 if (buffers
== NULL
) {
125 /* set one cliprect to cover the whole dri_drawable */
128 dri_drawable
->backX
= 0;
129 dri_drawable
->backY
= 0;
130 dri_drawable
->numClipRects
= 1;
131 dri_drawable
->pClipRects
[0].x1
= 0;
132 dri_drawable
->pClipRects
[0].y1
= 0;
133 dri_drawable
->pClipRects
[0].x2
= dri_drawable
->w
;
134 dri_drawable
->pClipRects
[0].y2
= dri_drawable
->h
;
135 dri_drawable
->numBackClipRects
= 1;
136 dri_drawable
->pBackClipRects
[0].x1
= 0;
137 dri_drawable
->pBackClipRects
[0].y1
= 0;
138 dri_drawable
->pBackClipRects
[0].x2
= dri_drawable
->w
;
139 dri_drawable
->pBackClipRects
[0].y2
= dri_drawable
->h
;
141 for (i
= 0; i
< count
; i
++) {
142 struct pipe_surface
*ps
;
143 enum pipe_format format
= 0;
146 switch (buffers
[i
].attachment
) {
147 case __DRI_BUFFER_FRONT_LEFT
:
148 index
= ST_SURFACE_FRONT_LEFT
;
149 switch (buffers
[i
].cpp
) {
151 format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
154 format
= PIPE_FORMAT_R5G6B5_UNORM
;
161 case __DRI_BUFFER_BACK_LEFT
:
162 index
= ST_SURFACE_BACK_LEFT
;
163 switch (buffers
[i
].cpp
) {
165 format
= PIPE_FORMAT_A8R8G8B8_UNORM
;
168 format
= PIPE_FORMAT_R5G6B5_UNORM
;
175 case __DRI_BUFFER_STENCIL
:
176 case __DRI_BUFFER_DEPTH
:
177 index
= ST_SURFACE_DEPTH
;
178 switch (buffers
[i
].cpp
) {
180 format
= PIPE_FORMAT_Z24S8_UNORM
;
183 format
= PIPE_FORMAT_Z16_UNORM
;
190 case __DRI_BUFFER_ACCUM
:
193 "unhandled buffer attach event, attacment type %d\n",
194 buffers
[i
].attachment
);
198 ps
= amd_surface_from_handle(amd_context
,
205 st_set_framebuffer_surface(amd_fb
->st_framebuffer
, index
, ps
);
207 st_resize_framebuffer(amd_fb
->st_framebuffer
,
212 GLboolean
amd_context_create(const __GLcontextModes
*visual
,
213 __DRIcontextPrivate
*dri_context
,
214 void *shared_context
)
216 __DRIscreenPrivate
*dri_screen
;
217 struct amd_context
*amd_context
;
218 struct amd_screen
*amd_screen
;
219 struct pipe_context
*pipe
;
220 struct st_context
*shared_st_context
= NULL
;
222 dri_context
->driverPrivate
= NULL
;
223 amd_context
= calloc(1, sizeof(struct amd_context
));
224 if (amd_context
== NULL
) {
228 if (shared_context
) {
229 shared_st_context
= ((struct amd_context
*)shared_context
)->st_context
;
232 dri_screen
= dri_context
->driScreenPriv
;
233 amd_screen
= dri_screen
->private;
234 amd_context
->dri_screen
= dri_screen
;
235 amd_context
->amd_screen
= amd_screen
;
236 amd_context
->drm_fd
= dri_screen
->fd
;
238 amd_context
->pipe_winsys
= amd_pipe_winsys(amd_screen
);
239 if (amd_context
->pipe_winsys
== NULL
) {
244 if (!getenv("AMD_SOFTPIPE")) {
245 fprintf(stderr
, "Creating r300 context...\n");
247 r300_create_context(NULL
,
248 amd_context
->pipe_winsys
,
249 amd_create_r300_winsys(amd_context
->drm_fd
));
250 amd_context
->pipe_screen
= pipe
->screen
;
252 pipe
= amd_create_softpipe(amd_context
);
254 amd_context
->st_context
= st_create_context(pipe
, visual
,
256 driInitExtensions(amd_context
->st_context
->ctx
,
257 amd_card_extensions
, GL_TRUE
);
258 dri_context
->driverPrivate
= amd_context
;
262 void amd_context_destroy(__DRIcontextPrivate
*dri_context
)
264 struct amd_context
*amd_context
;
266 amd_context
= dri_context
->driverPrivate
;
267 st_finish(amd_context
->st_context
);
268 st_destroy_context(amd_context
->st_context
);
272 GLboolean
amd_context_bind(__DRIcontextPrivate
*dri_context
,
273 __DRIdrawablePrivate
*dri_drawable
,
274 __DRIdrawablePrivate
*dri_readable
)
276 struct amd_framebuffer
*drawable
;
277 struct amd_framebuffer
*readable
;
278 struct amd_context
*amd_context
;
280 if (dri_context
== NULL
) {
281 st_make_current(NULL
, NULL
, NULL
);
285 amd_context
= dri_context
->driverPrivate
;
286 drawable
= dri_drawable
->driverPrivate
;
287 readable
= dri_readable
->driverPrivate
;
288 st_make_current(amd_context
->st_context
,
289 drawable
->st_framebuffer
,
290 readable
->st_framebuffer
);
292 amd_update_renderbuffers(dri_context
, dri_drawable
);
293 if (dri_drawable
!= dri_readable
) {
294 amd_update_renderbuffers(dri_context
, dri_readable
);
299 GLboolean
amd_context_unbind(__DRIcontextPrivate
*dri_context
)
301 struct amd_context
*amd_context
;
303 amd_context
= dri_context
->driverPrivate
;
304 st_flush(amd_context
->st_context
, PIPE_FLUSH_RENDER_CACHE
, NULL
);