2 Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 The Weather Channel (TM) funded Tungsten Graphics to develop the
5 initial release of the Radeon 8500 driver under the XFree86 license.
6 This notice must be preserved.
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:
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.
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.
28 **************************************************************************/
33 * \author Keith Whitwell <keith@tungstengraphics.com>
35 * \author Nicolai Haehnle <prefect_@gmx.net>
39 #include "main/glheader.h"
40 #include "main/api_arrayelt.h"
41 #include "main/context.h"
42 #include "main/simple_list.h"
43 #include "main/imports.h"
44 #include "main/extensions.h"
45 #include "main/bufferobj.h"
46 #include "main/texobj.h"
47 #include "main/points.h"
48 #include "main/mfeatures.h"
49 #include "main/version.h"
51 #include "swrast/swrast.h"
52 #include "swrast_setup/swrast_setup.h"
56 #include "tnl/t_pipeline.h"
58 #include "drivers/common/driverfuncs.h"
60 #include "radeon_debug.h"
61 #include "r600_context.h"
62 #include "radeon_common_context.h"
63 #include "radeon_buffer_objects.h"
64 #include "radeon_span.h"
65 #include "r600_cmdbuf.h"
66 #include "radeon_bocs_wrapper.h"
67 #include "radeon_queryobj.h"
68 #include "r600_blit.h"
70 #include "r700_state.h"
71 #include "r700_ioctl.h"
73 #include "evergreen_context.h"
74 #include "evergreen_state.h"
75 #include "evergreen_tex.h"
76 #include "evergreen_ioctl.h"
77 #include "evergreen_oglprog.h"
81 #define R600_ENABLE_GLSL_TEST 1
83 static const struct tnl_pipeline_stage *r600_pipeline[] = {
84 /* Catch any t&l fallbacks
86 &_tnl_vertex_transform_stage,
87 &_tnl_normal_transform_stage,
89 &_tnl_fog_coordinate_stage,
91 &_tnl_texture_transform_stage,
92 &_tnl_point_attenuation_stage,
93 &_tnl_vertex_program_stage,
98 static void r600_get_lock(radeonContextPtr rmesa)
100 drm_radeon_sarea_t *sarea = rmesa->sarea;
102 if (sarea->ctx_owner != rmesa->dri.hwContext) {
103 sarea->ctx_owner = rmesa->dri.hwContext;
104 if (!rmesa->radeonScreen->kernel_mm)
105 radeon_bo_legacy_texture_age(rmesa->radeonScreen->bom);
109 static void r600_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmesa)
111 /* please flush pipe do all pending work */
115 static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon)
117 r700Start3D((context_t *)radeon);
120 static void r600_fallback(struct gl_context *ctx, GLuint bit, GLboolean mode)
122 context_t *context = R700_CONTEXT(ctx);
124 context->radeon.Fallback |= bit;
126 context->radeon.Fallback &= ~bit;
129 static void r600_emit_query_finish(radeonContextPtr radeon)
131 context_t *context = (context_t*) radeon;
132 BATCH_LOCALS(&context->radeon);
134 struct radeon_query_object *query = radeon->query.current;
136 BEGIN_BATCH_NO_AUTOSTATE(4 + 2);
137 R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 2));
138 R600_OUT_BATCH(R600_EVENT_TYPE(ZPASS_DONE) | R600_EVENT_INDEX(1));
139 R600_OUT_BATCH(query->curr_offset + 8); /* hw writes qwords */
140 R600_OUT_BATCH(0x00000000);
141 R600_OUT_BATCH_RELOC(VGT_EVENT_INITIATOR, query->bo, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
143 assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
144 query->emitted_begin = GL_FALSE;
147 static void r600_init_vtbl(radeonContextPtr radeon)
149 radeon->vtbl.get_lock = r600_get_lock;
150 radeon->vtbl.update_viewport_offset = r700UpdateViewportOffset;
151 radeon->vtbl.emit_cs_header = r600_vtbl_emit_cs_header;
152 radeon->vtbl.swtcl_flush = NULL;
153 radeon->vtbl.pre_emit_atoms = r600_vtbl_pre_emit_atoms;
154 radeon->vtbl.fallback = r600_fallback;
155 radeon->vtbl.emit_query_finish = r600_emit_query_finish;
156 radeon->vtbl.check_blit = r600_check_blit;
157 radeon->vtbl.blit = r600_blit;
158 radeon->vtbl.is_format_renderable = r600IsFormatRenderable;
161 static void r600InitConstValues(struct gl_context *ctx, radeonScreenPtr screen)
163 context_t *context = R700_CONTEXT(ctx);
164 R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
166 if( (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_CEDAR)
167 &&(context->radeon.radeonScreen->chip_family <= CHIP_FAMILY_CAICOS) )
169 r700->bShaderUseMemConstant = GL_TRUE;
173 r700->bShaderUseMemConstant = GL_FALSE;
176 ctx->Const.GLSLVersion = 120;
177 _mesa_override_glsl_version(ctx);
179 ctx->Const.MaxTextureImageUnits = 16;
180 /* 8 per clause on r6xx, 16 on r7xx
181 * but I think mesa only supports 8 at the moment
183 ctx->Const.MaxTextureCoordUnits = 8;
184 ctx->Const.MaxTextureUnits =
185 MIN2(ctx->Const.MaxTextureImageUnits,
186 ctx->Const.MaxTextureCoordUnits);
187 ctx->Const.MaxCombinedTextureImageUnits =
188 ctx->Const.MaxVertexTextureImageUnits +
189 ctx->Const.MaxTextureImageUnits;
191 ctx->Const.MaxTextureMaxAnisotropy = 16.0;
192 ctx->Const.MaxTextureLodBias = 16.0;
194 if (screen->chip_family >= CHIP_FAMILY_CEDAR) {
195 ctx->Const.MaxTextureLevels = 15;
196 ctx->Const.MaxTextureRectSize = 16384;
198 ctx->Const.MaxTextureLevels = 14;
199 ctx->Const.MaxTextureRectSize = 8192;
202 ctx->Const.MinPointSize = 0x0001 / 8.0;
203 ctx->Const.MinPointSizeAA = 0x0001 / 8.0;
204 ctx->Const.MaxPointSize = 0xffff / 8.0;
205 ctx->Const.MaxPointSizeAA = 0xffff / 8.0;
207 ctx->Const.MinLineWidth = 0x0001 / 8.0;
208 ctx->Const.MinLineWidthAA = 0x0001 / 8.0;
209 ctx->Const.MaxLineWidth = 0xffff / 8.0;
210 ctx->Const.MaxLineWidthAA = 0xffff / 8.0;
212 ctx->Const.MaxDrawBuffers = 1; /* hw supports 8 */
213 ctx->Const.MaxColorAttachments = 1;
214 ctx->Const.MaxRenderbufferSize = 4096;
216 /* 256 for reg-based consts, inline consts also supported */
217 ctx->Const.VertexProgram.MaxInstructions = 8192; /* in theory no limit */
218 ctx->Const.VertexProgram.MaxNativeInstructions = 8192;
219 ctx->Const.VertexProgram.MaxNativeAttribs = 160;
220 ctx->Const.VertexProgram.MaxTemps = 128;
221 ctx->Const.VertexProgram.MaxNativeTemps = 128;
222 ctx->Const.VertexProgram.MaxNativeParameters = 256;
223 ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; /* ??? */
225 ctx->Const.FragmentProgram.MaxNativeTemps = 128;
226 ctx->Const.FragmentProgram.MaxNativeAttribs = 32;
227 ctx->Const.FragmentProgram.MaxNativeParameters = 256;
228 ctx->Const.FragmentProgram.MaxNativeAluInstructions = 8192;
229 /* 8 per clause on r6xx, 16 on r7xx */
230 if (screen->chip_family >= CHIP_FAMILY_RV770)
231 ctx->Const.FragmentProgram.MaxNativeTexInstructions = 16;
233 ctx->Const.FragmentProgram.MaxNativeTexInstructions = 8;
234 ctx->Const.FragmentProgram.MaxNativeInstructions = 8192;
235 ctx->Const.FragmentProgram.MaxNativeTexIndirections = 8; /* ??? */
236 ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
239 static void r600ParseOptions(context_t *r600, radeonScreenPtr screen)
241 /* Parse configuration files.
242 * Do this here so that initialMaxAnisotropy is set before we create
243 * the default textures.
245 driParseConfigFiles(&r600->radeon.optionCache, &screen->optionCache,
246 screen->driScreen->myNum, "r600");
248 r600->radeon.initialMaxAnisotropy = driQueryOptionf(&r600->radeon.optionCache,
249 "def_max_anisotropy");
253 static void r600InitGLExtensions(struct gl_context *ctx)
255 context_t *r600 = R700_CONTEXT(ctx);
256 #ifdef R600_ENABLE_GLSL_TEST
260 ctx->Extensions.ARB_depth_clamp = true;
261 ctx->Extensions.ARB_depth_texture = true;
262 ctx->Extensions.ARB_draw_elements_base_vertex = true;
263 ctx->Extensions.ARB_fragment_program = true;
264 ctx->Extensions.ARB_fragment_program_shadow = true;
265 ctx->Extensions.ARB_occlusion_query = true;
266 ctx->Extensions.ARB_shadow = true;
267 ctx->Extensions.ARB_shadow_ambient = true;
268 ctx->Extensions.ARB_texture_border_clamp = true;
269 ctx->Extensions.ARB_texture_cube_map = true;
270 ctx->Extensions.ARB_texture_env_combine = true;
271 ctx->Extensions.ARB_texture_env_crossbar = true;
272 ctx->Extensions.ARB_texture_env_dot3 = true;
273 ctx->Extensions.ARB_texture_non_power_of_two = true;
274 ctx->Extensions.ARB_vertex_program = true;
275 ctx->Extensions.EXT_blend_color = true;
276 ctx->Extensions.EXT_blend_equation_separate = true;
277 ctx->Extensions.EXT_blend_func_separate = true;
278 ctx->Extensions.EXT_blend_minmax = true;
279 ctx->Extensions.EXT_packed_depth_stencil = true;
280 ctx->Extensions.EXT_fog_coord = true;
281 ctx->Extensions.EXT_gpu_program_parameters = true;
282 ctx->Extensions.EXT_pixel_buffer_object = true;
283 ctx->Extensions.EXT_point_parameters = true;
284 ctx->Extensions.EXT_provoking_vertex = true;
285 ctx->Extensions.EXT_secondary_color = true;
286 ctx->Extensions.EXT_shadow_funcs = true;
287 ctx->Extensions.EXT_stencil_two_side = true;
288 ctx->Extensions.EXT_texture_env_dot3 = true;
289 ctx->Extensions.EXT_texture_filter_anisotropic = true;
290 ctx->Extensions.EXT_texture_mirror_clamp = true;
291 ctx->Extensions.EXT_vertex_array_bgra = true;
292 ctx->Extensions.EXT_texture_sRGB = true;
293 ctx->Extensions.ATI_separate_stencil = true;
294 ctx->Extensions.ATI_texture_env_combine3 = true;
295 ctx->Extensions.ATI_texture_mirror_once = true;
296 ctx->Extensions.MESA_pack_invert = true;
297 ctx->Extensions.MESA_ycbcr_texture = true;
298 ctx->Extensions.NV_blend_square = true;
299 ctx->Extensions.NV_texture_rectangle = true;
300 ctx->Extensions.NV_vertex_program = true;
301 #if FEATURE_OES_EGL_image
302 ctx->Extensions.OES_EGL_image = true;
305 if (r600->radeon.radeonScreen->kernel_mm)
306 ctx->Extensions.EXT_framebuffer_object = true;
308 #ifdef R600_ENABLE_GLSL_TEST
309 ctx->Extensions.ARB_shading_language_100 = true;
310 _mesa_enable_2_0_extensions(ctx);
312 /* glsl compiler has problem if this is not GL_TRUE */
313 for (i = 0; i <= MESA_SHADER_FRAGMENT; i++)
314 ctx->ShaderCompilerOptions[i].EmitCondCodes = GL_TRUE;
315 #endif /* R600_ENABLE_GLSL_TEST */
318 (&r600->radeon.optionCache, "disable_stencil_two_side"))
319 ctx->Extensions.EXT_stencil_two_side = false;
321 if (r600->radeon.glCtx->Mesa_DXTn
322 && !driQueryOptionb(&r600->radeon.optionCache, "disable_s3tc")) {
323 ctx->Extensions.EXT_texture_compression_s3tc = true;
324 ctx->Extensions.S3_s3tc = true;
326 if (driQueryOptionb(&r600->radeon.optionCache, "force_s3tc_enable"))
328 ctx->Extensions.EXT_texture_compression_s3tc = true;
331 /* RV740 had a broken pipe config prior to drm 1.32 */
332 if (!r600->radeon.radeonScreen->kernel_mm) {
333 if ((r600->radeon.dri.drmMinor < 32) &&
334 (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV740))
335 ctx->Extensions.ARB_occlusion_query = false;
339 /* Create the device specific rendering context.
341 GLboolean r600CreateContext(gl_api api,
342 const struct gl_config * glVisual,
343 __DRIcontext * driContextPriv,
344 void *sharedContextPrivate)
346 __DRIscreen *sPriv = driContextPriv->driScreenPriv;
347 radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
348 struct dd_function_table functions;
350 struct gl_context *ctx;
353 assert(driContextPriv);
356 /* Allocate the R600 context */
357 r600 = (context_t*) CALLOC(sizeof(*r600));
359 radeon_error("Failed to allocate memory for context.\n");
363 r600ParseOptions(r600, screen);
365 r600->radeon.radeonScreen = screen;
367 if(screen->chip_family >= CHIP_FAMILY_CEDAR)
369 evergreen_init_vtbl(&r600->radeon);
373 r600_init_vtbl(&r600->radeon);
376 /* Init default driver functions then plug in our R600-specific functions
377 * (the texture functions are especially important)
379 _mesa_init_driver_functions(&functions);
381 if(screen->chip_family >= CHIP_FAMILY_CEDAR)
383 evergreenCreateChip(r600);
384 evergreenInitStateFuncs(&r600->radeon, &functions);
385 evergreenInitTextureFuncs(&r600->radeon, &functions);
386 evergreenInitShaderFuncs(&functions);
390 r700InitStateFuncs(&r600->radeon, &functions);
391 r600InitTextureFuncs(&r600->radeon, &functions);
392 r700InitShaderFuncs(&functions);
395 radeonInitQueryObjFunctions(&functions);
397 if(screen->chip_family >= CHIP_FAMILY_CEDAR)
399 evergreenInitIoctlFuncs(&functions);
403 r700InitIoctlFuncs(&functions);
405 radeonInitBufferObjectFuncs(&functions);
407 if (!radeonInitContext(&r600->radeon, &functions,
408 glVisual, driContextPriv,
409 sharedContextPrivate)) {
410 radeon_error("Initializing context failed.\n");
415 ctx = r600->radeon.glCtx;
417 ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
418 ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
420 r600InitConstValues(ctx, screen);
422 /* reinit, it depends on consts above */
423 _mesa_init_point(ctx);
425 _mesa_set_mvp_with_dp4( ctx, GL_TRUE );
427 /* Initialize the software rasterizer and helper modules.
429 _swrast_CreateContext(ctx);
430 _vbo_CreateContext(ctx);
431 _tnl_CreateContext(ctx);
432 _swsetup_CreateContext(ctx);
433 _swsetup_Wakeup(ctx);
435 /* Install the customized pipeline:
437 _tnl_destroy_pipeline(ctx);
438 _tnl_install_pipeline(ctx, r600_pipeline);
439 TNL_CONTEXT(ctx)->Driver.RunPipeline = _tnl_run_pipeline;
441 /* Configure swrast and TNL to match hardware characteristics:
443 _swrast_allow_pixel_fog(ctx, GL_FALSE);
444 _swrast_allow_vertex_fog(ctx, GL_TRUE);
445 _tnl_allow_pixel_fog(ctx, GL_FALSE);
446 _tnl_allow_vertex_fog(ctx, GL_TRUE);
450 if(screen->chip_family >= CHIP_FAMILY_CEDAR)
452 evergreenInitDraw(ctx);
459 radeon_fbo_init(&r600->radeon);
460 radeonInitSpanFuncs( ctx );
461 r600InitCmdBuf(r600);
463 if(screen->chip_family >= CHIP_FAMILY_CEDAR)
465 evergreenInitState(r600->radeon.glCtx);
469 r700InitState(r600->radeon.glCtx);
472 r600InitGLExtensions(ctx);
477 void r600DestroyContext(__DRIcontext *driContextPriv )
480 context_t *context = (context_t *) driContextPriv->driverPrivate;
484 pChip = context->pChip;
486 /* destroy context first, free pChip, in case there are things flush to asic. */
487 radeonDestroyContext(driContextPriv);