amd: Fix build errors from rebase.
[mesa.git] / src / gallium / winsys / drm / amd / amd_context.c
1 /*
2 * Copyright © 2008 Jérôme Glisse
3 * All Rights Reserved.
4 *
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:
12 *
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.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26 /*
27 * Authors:
28 * Jérôme Glisse <glisse@freedesktop.org>
29 */
30 #include <stdio.h>
31 #include "dri_util.h"
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"
40
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"
62
63 /**
64 * Extension strings exported by the amd driver.
65 */
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},
92 {NULL, NULL}
93 };
94
95 static void amd_update_renderbuffers(__DRIcontext *dri_context,
96 __DRIdrawable *dri_drawable)
97 {
98 struct amd_framebuffer *amd_fb;
99 struct amd_context *amd_context;
100 unsigned attachments[10];
101 __DRIbuffer *buffers;
102 __DRIscreen *screen;
103 int i, count;
104
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;
111 }
112 }
113
114 buffers = (*screen->dri2.loader->getBuffers)(dri_drawable,
115 &dri_drawable->w,
116 &dri_drawable->h,
117 attachments,
118 i,
119 &count,
120 dri_drawable->loaderPrivate);
121 if (buffers == NULL) {
122 return;
123 }
124
125 /* set one cliprect to cover the whole dri_drawable */
126 dri_drawable->x = 0;
127 dri_drawable->y = 0;
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;
140
141 for (i = 0; i < count; i++) {
142 struct pipe_surface *ps;
143 enum pipe_format format = 0;
144 int index = 0;
145
146 switch (buffers[i].attachment) {
147 case __DRI_BUFFER_FRONT_LEFT:
148 index = ST_SURFACE_FRONT_LEFT;
149 switch (buffers[i].cpp) {
150 case 4:
151 format = PIPE_FORMAT_A8R8G8B8_UNORM;
152 break;
153 case 2:
154 format = PIPE_FORMAT_R5G6B5_UNORM;
155 break;
156 default:
157 /* FIXME: error */
158 return;
159 }
160 break;
161 case __DRI_BUFFER_BACK_LEFT:
162 index = ST_SURFACE_BACK_LEFT;
163 switch (buffers[i].cpp) {
164 case 4:
165 format = PIPE_FORMAT_A8R8G8B8_UNORM;
166 break;
167 case 2:
168 format = PIPE_FORMAT_R5G6B5_UNORM;
169 break;
170 default:
171 /* FIXME: error */
172 return;
173 }
174 break;
175 case __DRI_BUFFER_STENCIL:
176 case __DRI_BUFFER_DEPTH:
177 index = ST_SURFACE_DEPTH;
178 switch (buffers[i].cpp) {
179 case 4:
180 format = PIPE_FORMAT_Z24S8_UNORM;
181 break;
182 case 2:
183 format = PIPE_FORMAT_Z16_UNORM;
184 break;
185 default:
186 /* FIXME: error */
187 return;
188 }
189 break;
190 case __DRI_BUFFER_ACCUM:
191 default:
192 fprintf(stderr,
193 "unhandled buffer attach event, attacment type %d\n",
194 buffers[i].attachment);
195 return;
196 }
197
198 ps = amd_surface_from_handle(amd_context,
199 buffers[i].name,
200 format,
201 dri_drawable->w,
202 dri_drawable->h,
203 buffers[i].pitch);
204 assert(ps);
205 st_set_framebuffer_surface(amd_fb->st_framebuffer, index, ps);
206 }
207 st_resize_framebuffer(amd_fb->st_framebuffer,
208 dri_drawable->w,
209 dri_drawable->h);
210 }
211
212 GLboolean amd_context_create(const __GLcontextModes *visual,
213 __DRIcontextPrivate *dri_context,
214 void *shared_context)
215 {
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;
221
222 dri_context->driverPrivate = NULL;
223 amd_context = calloc(1, sizeof(struct amd_context));
224 if (amd_context == NULL) {
225 return GL_FALSE;
226 }
227
228 if (shared_context) {
229 shared_st_context = ((struct amd_context*)shared_context)->st_context;
230 }
231
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;
237
238 amd_context->pipe_winsys = amd_pipe_winsys(amd_screen);
239 if (amd_context->pipe_winsys == NULL) {
240 free(amd_context);
241 return GL_FALSE;
242 }
243
244 if (!getenv("AMD_SOFTPIPE")) {
245 fprintf(stderr, "Creating r300 context...\n");
246 pipe =
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;
251 } else {
252 pipe = amd_create_softpipe(amd_context);
253 }
254 amd_context->st_context = st_create_context(pipe, visual,
255 shared_st_context);
256 driInitExtensions(amd_context->st_context->ctx,
257 amd_card_extensions, GL_TRUE);
258 dri_context->driverPrivate = amd_context;
259 return GL_TRUE;
260 }
261
262 void amd_context_destroy(__DRIcontextPrivate *dri_context)
263 {
264 struct amd_context *amd_context;
265
266 amd_context = dri_context->driverPrivate;
267 st_finish(amd_context->st_context);
268 st_destroy_context(amd_context->st_context);
269 free(amd_context);
270 }
271
272 GLboolean amd_context_bind(__DRIcontextPrivate *dri_context,
273 __DRIdrawablePrivate *dri_drawable,
274 __DRIdrawablePrivate *dri_readable)
275 {
276 struct amd_framebuffer *drawable;
277 struct amd_framebuffer *readable;
278 struct amd_context *amd_context;
279
280 if (dri_context == NULL) {
281 st_make_current(NULL, NULL, NULL);
282 return GL_TRUE;
283 }
284
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);
291
292 amd_update_renderbuffers(dri_context, dri_drawable);
293 if (dri_drawable != dri_readable) {
294 amd_update_renderbuffers(dri_context, dri_readable);
295 }
296 return GL_TRUE;
297 }
298
299 GLboolean amd_context_unbind(__DRIcontextPrivate *dri_context)
300 {
301 struct amd_context *amd_context;
302
303 amd_context = dri_context->driverPrivate;
304 st_flush(amd_context->st_context, PIPE_FLUSH_RENDER_CACHE, NULL);
305 return GL_TRUE;
306 }