dri2: Add plumbing to get context version requirements and flags to drivers
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_context.c
1 /**************************************************************************
2
3 Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and
4 VA Linux Systems Inc., Fremont, California.
5
6 All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 "Software"), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
15
16 The above copyright notice and this permission notice (including the
17 next paragraph) shall be included in all copies or substantial
18 portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
24 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 **************************************************************************/
29
30 /*
31 * Authors:
32 * Kevin E. Martin <martin@valinux.com>
33 * Gareth Hughes <gareth@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
35 */
36
37 #include <stdbool.h>
38 #include "main/glheader.h"
39 #include "main/api_arrayelt.h"
40 #include "main/context.h"
41 #include "main/simple_list.h"
42 #include "main/imports.h"
43 #include "main/extensions.h"
44 #include "main/mfeatures.h"
45 #include "main/version.h"
46
47 #include "swrast/swrast.h"
48 #include "swrast_setup/swrast_setup.h"
49 #include "vbo/vbo.h"
50
51 #include "tnl/tnl.h"
52 #include "tnl/t_pipeline.h"
53
54 #include "drivers/common/driverfuncs.h"
55
56 #include "radeon_common.h"
57 #include "radeon_context.h"
58 #include "radeon_ioctl.h"
59 #include "radeon_state.h"
60 #include "radeon_span.h"
61 #include "radeon_tex.h"
62 #include "radeon_swtcl.h"
63 #include "radeon_tcl.h"
64 #include "radeon_queryobj.h"
65 #include "radeon_blit.h"
66
67 #include "utils.h"
68 #include "xmlpool.h" /* for symbolic values of enum-type options */
69
70 extern const struct tnl_pipeline_stage _radeon_render_stage;
71 extern const struct tnl_pipeline_stage _radeon_tcl_stage;
72
73 static const struct tnl_pipeline_stage *radeon_pipeline[] = {
74
75 /* Try and go straight to t&l
76 */
77 &_radeon_tcl_stage,
78
79 /* Catch any t&l fallbacks
80 */
81 &_tnl_vertex_transform_stage,
82 &_tnl_normal_transform_stage,
83 &_tnl_lighting_stage,
84 &_tnl_fog_coordinate_stage,
85 &_tnl_texgen_stage,
86 &_tnl_texture_transform_stage,
87
88 &_radeon_render_stage,
89 &_tnl_render_stage, /* FALLBACK: */
90 NULL,
91 };
92
93 static void r100_get_lock(radeonContextPtr radeon)
94 {
95 r100ContextPtr rmesa = (r100ContextPtr)radeon;
96 drm_radeon_sarea_t *sarea = radeon->sarea;
97
98 RADEON_STATECHANGE(rmesa, ctx);
99 if (rmesa->radeon.sarea->tiling_enabled) {
100 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |=
101 RADEON_COLOR_TILE_ENABLE;
102 } else {
103 rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &=
104 ~RADEON_COLOR_TILE_ENABLE;
105 }
106
107 if (sarea->ctx_owner != rmesa->radeon.dri.hwContext) {
108 sarea->ctx_owner = rmesa->radeon.dri.hwContext;
109 }
110 }
111
112 static void r100_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
113 {
114 }
115
116 static void r100_vtbl_pre_emit_state(radeonContextPtr radeon)
117 {
118 r100ContextPtr rmesa = (r100ContextPtr)radeon;
119
120 /* r100 always needs to emit ZBS to avoid TCL lockups */
121 rmesa->hw.zbs.dirty = 1;
122 radeon->hw.is_dirty = 1;
123 }
124
125 static void r100_vtbl_free_context(struct gl_context *ctx)
126 {
127 r100ContextPtr rmesa = R100_CONTEXT(ctx);
128 _mesa_vector4f_free( &rmesa->tcl.ObjClean );
129 }
130
131 static void r100_emit_query_finish(radeonContextPtr radeon)
132 {
133 BATCH_LOCALS(radeon);
134 struct radeon_query_object *query = radeon->query.current;
135
136 BEGIN_BATCH_NO_AUTOSTATE(4);
137 OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
138 OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
139 END_BATCH();
140 query->curr_offset += sizeof(uint32_t);
141 assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
142 query->emitted_begin = GL_FALSE;
143 }
144
145 static void r100_init_vtbl(radeonContextPtr radeon)
146 {
147 radeon->vtbl.get_lock = r100_get_lock;
148 radeon->vtbl.update_viewport_offset = radeonUpdateViewportOffset;
149 radeon->vtbl.emit_cs_header = r100_vtbl_emit_cs_header;
150 radeon->vtbl.swtcl_flush = r100_swtcl_flush;
151 radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state;
152 radeon->vtbl.fallback = radeonFallback;
153 radeon->vtbl.free_context = r100_vtbl_free_context;
154 radeon->vtbl.emit_query_finish = r100_emit_query_finish;
155 radeon->vtbl.check_blit = r100_check_blit;
156 radeon->vtbl.blit = r100_blit;
157 radeon->vtbl.is_format_renderable = radeonIsFormatRenderable;
158 }
159
160 /* Create the device specific context.
161 */
162 GLboolean
163 r100CreateContext( gl_api api,
164 const struct gl_config *glVisual,
165 __DRIcontext *driContextPriv,
166 unsigned major_version,
167 unsigned minor_version,
168 uint32_t flags,
169 unsigned *error,
170 void *sharedContextPrivate)
171 {
172 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
173 radeonScreenPtr screen = (radeonScreenPtr)(sPriv->driverPrivate);
174 struct dd_function_table functions;
175 r100ContextPtr rmesa;
176 struct gl_context *ctx;
177 int i;
178 int tcl_mode, fthrottle_mode;
179
180 /* API and flag filtering is handled in dri2CreateContextAttribs.
181 */
182 (void) api;
183 (void) flags;
184
185 assert(glVisual);
186 assert(driContextPriv);
187 assert(screen);
188
189 /* Allocate the Radeon context */
190 rmesa = (r100ContextPtr) CALLOC( sizeof(*rmesa) );
191 if ( !rmesa ) {
192 *error = __DRI_CTX_ERROR_NO_MEMORY;
193 return GL_FALSE;
194 }
195
196 rmesa->radeon.radeonScreen = screen;
197 r100_init_vtbl(&rmesa->radeon);
198
199 /* init exp fog table data */
200 radeonInitStaticFogData();
201
202 /* Parse configuration files.
203 * Do this here so that initialMaxAnisotropy is set before we create
204 * the default textures.
205 */
206 driParseConfigFiles (&rmesa->radeon.optionCache, &screen->optionCache,
207 screen->driScreen->myNum, "radeon");
208 rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
209 "def_max_anisotropy");
210
211 if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
212 if ( sPriv->drm_version.minor < 13 )
213 fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
214 "disabling.\n", sPriv->drm_version.minor );
215 else
216 rmesa->using_hyperz = GL_TRUE;
217 }
218
219 if ( sPriv->drm_version.minor >= 15 )
220 rmesa->texmicrotile = GL_TRUE;
221
222 /* Init default driver functions then plug in our Radeon-specific functions
223 * (the texture functions are especially important)
224 */
225 _mesa_init_driver_functions( &functions );
226 radeonInitTextureFuncs( &rmesa->radeon, &functions );
227 radeonInitQueryObjFunctions(&functions);
228
229 if (!radeonInitContext(&rmesa->radeon, &functions,
230 glVisual, driContextPriv,
231 sharedContextPrivate)) {
232 FREE(rmesa);
233 *error = __DRI_CTX_ERROR_NO_MEMORY;
234 return GL_FALSE;
235 }
236
237 rmesa->radeon.swtcl.RenderIndex = ~0;
238 rmesa->radeon.hw.all_dirty = GL_TRUE;
239
240 /* Set the maximum texture size small enough that we can guarentee that
241 * all texture units can bind a maximal texture and have all of them in
242 * texturable memory at once. Depending on the allow_large_textures driconf
243 * setting allow larger textures.
244 */
245
246 ctx = rmesa->radeon.glCtx;
247 ctx->Const.MaxTextureUnits = driQueryOptioni (&rmesa->radeon.optionCache,
248 "texture_units");
249 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
250 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
251 ctx->Const.MaxCombinedTextureImageUnits = ctx->Const.MaxTextureUnits;
252
253 ctx->Const.StripTextureBorder = GL_TRUE;
254
255 i = driQueryOptioni( &rmesa->radeon.optionCache, "allow_large_textures");
256
257 /* FIXME: When no memory manager is available we should set this
258 * to some reasonable value based on texture memory pool size */
259 ctx->Const.MaxTextureLevels = 12;
260 ctx->Const.Max3DTextureLevels = 9;
261 ctx->Const.MaxCubeTextureLevels = 12;
262 ctx->Const.MaxTextureRectSize = 2048;
263
264 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
265
266 /* No wide points.
267 */
268 ctx->Const.MinPointSize = 1.0;
269 ctx->Const.MinPointSizeAA = 1.0;
270 ctx->Const.MaxPointSize = 1.0;
271 ctx->Const.MaxPointSizeAA = 1.0;
272
273 ctx->Const.MinLineWidth = 1.0;
274 ctx->Const.MinLineWidthAA = 1.0;
275 ctx->Const.MaxLineWidth = 10.0;
276 ctx->Const.MaxLineWidthAA = 10.0;
277 ctx->Const.LineWidthGranularity = 0.0625;
278
279 /* Set maxlocksize (and hence vb size) small enough to avoid
280 * fallbacks in radeon_tcl.c. ie. guarentee that all vertices can
281 * fit in a single dma buffer for indexed rendering of quad strips,
282 * etc.
283 */
284 ctx->Const.MaxArrayLockSize =
285 MIN2( ctx->Const.MaxArrayLockSize,
286 RADEON_BUFFER_SIZE / RADEON_MAX_TCL_VERTSIZE );
287
288 rmesa->boxes = 0;
289
290 ctx->Const.MaxDrawBuffers = 1;
291 ctx->Const.MaxColorAttachments = 1;
292 ctx->Const.MaxRenderbufferSize = 2048;
293
294 _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
295
296 /* Initialize the software rasterizer and helper modules.
297 */
298 _swrast_CreateContext( ctx );
299 _vbo_CreateContext( ctx );
300 _tnl_CreateContext( ctx );
301 _swsetup_CreateContext( ctx );
302 _ae_create_context( ctx );
303
304 /* Install the customized pipeline:
305 */
306 _tnl_destroy_pipeline( ctx );
307 _tnl_install_pipeline( ctx, radeon_pipeline );
308
309 /* Try and keep materials and vertices separate:
310 */
311 /* _tnl_isolate_materials( ctx, GL_TRUE ); */
312
313 /* Configure swrast and T&L to match hardware characteristics:
314 */
315 _swrast_allow_pixel_fog( ctx, GL_FALSE );
316 _swrast_allow_vertex_fog( ctx, GL_TRUE );
317 _tnl_allow_pixel_fog( ctx, GL_FALSE );
318 _tnl_allow_vertex_fog( ctx, GL_TRUE );
319
320
321 for ( i = 0 ; i < RADEON_MAX_TEXTURE_UNITS ; i++ ) {
322 _math_matrix_ctr( &rmesa->TexGenMatrix[i] );
323 _math_matrix_ctr( &rmesa->tmpmat[i] );
324 _math_matrix_set_identity( &rmesa->TexGenMatrix[i] );
325 _math_matrix_set_identity( &rmesa->tmpmat[i] );
326 }
327
328 ctx->Extensions.ARB_texture_border_clamp = true;
329 ctx->Extensions.ARB_texture_env_combine = true;
330 ctx->Extensions.ARB_texture_env_crossbar = true;
331 ctx->Extensions.ARB_texture_env_dot3 = true;
332 ctx->Extensions.EXT_fog_coord = true;
333 ctx->Extensions.EXT_packed_depth_stencil = true;
334 ctx->Extensions.EXT_secondary_color = true;
335 ctx->Extensions.EXT_texture_env_dot3 = true;
336 ctx->Extensions.EXT_texture_filter_anisotropic = true;
337 ctx->Extensions.EXT_texture_mirror_clamp = true;
338 ctx->Extensions.ATI_texture_env_combine3 = true;
339 ctx->Extensions.ATI_texture_mirror_once = true;
340 ctx->Extensions.MESA_ycbcr_texture = true;
341 ctx->Extensions.NV_blend_square = true;
342 #if FEATURE_OES_EGL_image
343 ctx->Extensions.OES_EGL_image = true;
344 #endif
345
346 ctx->Extensions.EXT_framebuffer_object = true;
347
348 ctx->Extensions.ARB_texture_cube_map = true;
349
350 if (rmesa->radeon.glCtx->Mesa_DXTn) {
351 ctx->Extensions.EXT_texture_compression_s3tc = true;
352 ctx->Extensions.S3_s3tc = true;
353 }
354 else if (driQueryOptionb (&rmesa->radeon.optionCache, "force_s3tc_enable")) {
355 ctx->Extensions.EXT_texture_compression_s3tc = true;
356 }
357
358 ctx->Extensions.NV_texture_rectangle = true;
359 ctx->Extensions.ARB_occlusion_query = true;
360
361 /* XXX these should really go right after _mesa_init_driver_functions() */
362 radeon_fbo_init(&rmesa->radeon);
363 radeonInitSpanFuncs( ctx );
364 radeonInitIoctlFuncs( ctx );
365 radeonInitStateFuncs( ctx );
366 radeonInitState( rmesa );
367 radeonInitSwtcl( ctx );
368
369 _mesa_vector4f_alloc( &rmesa->tcl.ObjClean, 0,
370 ctx->Const.MaxArrayLockSize, 32 );
371
372 fthrottle_mode = driQueryOptioni(&rmesa->radeon.optionCache, "fthrottle_mode");
373 rmesa->radeon.iw.irq_seq = -1;
374 rmesa->radeon.irqsEmitted = 0;
375 rmesa->radeon.do_irqs = (rmesa->radeon.radeonScreen->irq != 0 &&
376 fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS);
377
378 rmesa->radeon.do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
379
380
381 #if DO_DEBUG
382 RADEON_DEBUG = driParseDebugString( getenv( "RADEON_DEBUG" ),
383 debug_control );
384 #endif
385
386 tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
387 if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
388 fprintf(stderr, "disabling 3D acceleration\n");
389 FALLBACK(rmesa, RADEON_FALLBACK_DISABLE, 1);
390 } else if (tcl_mode == DRI_CONF_TCL_SW ||
391 !(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) {
392 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
393 rmesa->radeon.radeonScreen->chip_flags &= ~RADEON_CHIPSET_TCL;
394 fprintf(stderr, "Disabling HW TCL support\n");
395 }
396 TCL_FALLBACK(rmesa->radeon.glCtx, RADEON_TCL_FALLBACK_TCL_DISABLE, 1);
397 }
398
399 if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) {
400 /* _tnl_need_dlist_norm_lengths( ctx, GL_FALSE ); */
401 }
402
403 _mesa_compute_version(ctx);
404 if (ctx->VersionMajor < major_version
405 || (ctx->VersionMajor == major_version
406 && ctx->VersionMinor < minor_version)) {
407 radeonDestroyContext(driContextPriv);
408 *error = __DRI_CTX_ERROR_BAD_VERSION;
409 return GL_FALSE;
410 }
411
412 *error = __DRI_CTX_ERROR_SUCCESS;
413 return GL_TRUE;
414 }