slang: initialize the context
[mesa.git] / src / mesa / drivers / dri / r300 / r300_render.c
1 /**************************************************************************
2
3 Copyright (C) 2004 Nicolai Haehnle.
4
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /**
29 * \file
30 *
31 * \brief R300 Render (Vertex Buffer Implementation)
32 *
33 * The immediate implementation has been removed from CVS in favor of the vertex
34 * buffer implementation.
35 *
36 * The render functions are called by the pipeline manager to render a batch of
37 * primitives. They return TRUE to pass on to the next stage (i.e. software
38 * rasterization) or FALSE to indicate that the pipeline has finished after
39 * rendering something.
40 *
41 * When falling back to software TCL still attempt to use hardware
42 * rasterization.
43 *
44 * I am not sure that the cache related registers are setup correctly, but
45 * obviously this does work... Further investigation is needed.
46 *
47 * \author Nicolai Haehnle <prefect_@gmx.net>
48 *
49 * \todo Add immediate implementation back? Perhaps this is useful if there are
50 * no bugs...
51 */
52
53 #include "main/glheader.h"
54 #include "main/state.h"
55 #include "main/imports.h"
56 #include "main/enums.h"
57 #include "main/macros.h"
58 #include "main/context.h"
59 #include "main/dd.h"
60 #include "main/simple_list.h"
61 #include "main/api_arrayelt.h"
62 #include "swrast/swrast.h"
63 #include "swrast_setup/swrast_setup.h"
64 #include "vbo/vbo.h"
65 #include "tnl/tnl.h"
66 #include "tnl/t_vp_build.h"
67 #include "radeon_reg.h"
68 #include "radeon_macros.h"
69 #include "radeon_ioctl.h"
70 #include "radeon_state.h"
71 #include "r300_context.h"
72 #include "r300_ioctl.h"
73 #include "r300_state.h"
74 #include "r300_reg.h"
75 #include "r300_tex.h"
76 #include "r300_emit.h"
77 #include "r300_fragprog.h"
78 extern int future_hw_tcl_on;
79
80 /**
81 * \brief Convert a OpenGL primitive type into a R300 primitive type.
82 */
83 int r300PrimitiveType(r300ContextPtr rmesa, int prim)
84 {
85 switch (prim & PRIM_MODE_MASK) {
86 case GL_POINTS:
87 return R300_VAP_VF_CNTL__PRIM_POINTS;
88 break;
89 case GL_LINES:
90 return R300_VAP_VF_CNTL__PRIM_LINES;
91 break;
92 case GL_LINE_STRIP:
93 return R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
94 break;
95 case GL_LINE_LOOP:
96 return R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
97 break;
98 case GL_TRIANGLES:
99 return R300_VAP_VF_CNTL__PRIM_TRIANGLES;
100 break;
101 case GL_TRIANGLE_STRIP:
102 return R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
103 break;
104 case GL_TRIANGLE_FAN:
105 return R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
106 break;
107 case GL_QUADS:
108 return R300_VAP_VF_CNTL__PRIM_QUADS;
109 break;
110 case GL_QUAD_STRIP:
111 return R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
112 break;
113 case GL_POLYGON:
114 return R300_VAP_VF_CNTL__PRIM_POLYGON;
115 break;
116 default:
117 assert(0);
118 return -1;
119 break;
120 }
121 }
122
123 int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
124 {
125 int verts_off = 0;
126
127 switch (prim & PRIM_MODE_MASK) {
128 case GL_POINTS:
129 verts_off = 0;
130 break;
131 case GL_LINES:
132 verts_off = num_verts % 2;
133 break;
134 case GL_LINE_STRIP:
135 if (num_verts < 2)
136 verts_off = num_verts;
137 break;
138 case GL_LINE_LOOP:
139 if (num_verts < 2)
140 verts_off = num_verts;
141 break;
142 case GL_TRIANGLES:
143 verts_off = num_verts % 3;
144 break;
145 case GL_TRIANGLE_STRIP:
146 if (num_verts < 3)
147 verts_off = num_verts;
148 break;
149 case GL_TRIANGLE_FAN:
150 if (num_verts < 3)
151 verts_off = num_verts;
152 break;
153 case GL_QUADS:
154 verts_off = num_verts % 4;
155 break;
156 case GL_QUAD_STRIP:
157 if (num_verts < 4)
158 verts_off = num_verts;
159 else
160 verts_off = num_verts % 2;
161 break;
162 case GL_POLYGON:
163 if (num_verts < 3)
164 verts_off = num_verts;
165 break;
166 default:
167 assert(0);
168 return -1;
169 break;
170 }
171
172 return num_verts - verts_off;
173 }
174
175 static void r300EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts)
176 {
177 r300ContextPtr rmesa = R300_CONTEXT(ctx);
178 struct r300_dma_region *rvb = &rmesa->state.elt_dma;
179 void *out;
180
181 if (r300IsGartMemory(rmesa, elts, n_elts * 4)) {
182 rvb->address = rmesa->radeon.radeonScreen->gartTextures.map;
183 rvb->start = ((char *)elts) - rvb->address;
184 rvb->aos_offset =
185 rmesa->radeon.radeonScreen->gart_texture_offset +
186 rvb->start;
187 return;
188 } else if (r300IsGartMemory(rmesa, elts, 1)) {
189 WARN_ONCE("Pointer not within GART memory!\n");
190 _mesa_exit(-1);
191 }
192
193 r300AllocDmaRegion(rmesa, rvb, n_elts * 4, 4);
194 rvb->aos_offset = GET_START(rvb);
195
196 out = rvb->address + rvb->start;
197 memcpy(out, elts, n_elts * 4);
198 }
199
200 static void r300FireEB(r300ContextPtr rmesa, unsigned long addr,
201 int vertex_count, int type)
202 {
203 int cmd_reserved = 0;
204 int cmd_written = 0;
205 drm_radeon_cmd_header_t *cmd = NULL;
206
207 start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0), 0);
208 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count << 16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
209
210 start_packet3(CP_PACKET3(R300_PACKET3_INDX_BUFFER, 2), 2);
211 e32(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
212 (R300_VAP_PORT_IDX0 >> 2));
213 e32(addr);
214 e32(vertex_count);
215 }
216
217 static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
218 {
219 int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
220 int i;
221 int cmd_reserved = 0;
222 int cmd_written = 0;
223 drm_radeon_cmd_header_t *cmd = NULL;
224
225 if (RADEON_DEBUG & DEBUG_VERTS)
226 fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
227 offset);
228
229 start_packet3(CP_PACKET3(R300_PACKET3_3D_LOAD_VBPNTR, sz - 1), sz - 1);
230 e32(nr);
231
232 for (i = 0; i + 1 < nr; i += 2) {
233 e32((rmesa->state.aos[i].aos_size << 0) |
234 (rmesa->state.aos[i].aos_stride << 8) |
235 (rmesa->state.aos[i + 1].aos_size << 16) |
236 (rmesa->state.aos[i + 1].aos_stride << 24));
237
238 e32(rmesa->state.aos[i].aos_offset + offset * 4 * rmesa->state.aos[i].aos_stride);
239 e32(rmesa->state.aos[i + 1].aos_offset + offset * 4 * rmesa->state.aos[i + 1].aos_stride);
240 }
241
242 if (nr & 1) {
243 e32((rmesa->state.aos[nr - 1].aos_size << 0) |
244 (rmesa->state.aos[nr - 1].aos_stride << 8));
245 e32(rmesa->state.aos[nr - 1].aos_offset + offset * 4 * rmesa->state.aos[nr - 1].aos_stride);
246 }
247 }
248
249 static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type)
250 {
251 int cmd_reserved = 0;
252 int cmd_written = 0;
253 drm_radeon_cmd_header_t *cmd = NULL;
254
255 start_packet3(CP_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0), 0);
256 e32(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
257 }
258
259 static void r300RunRenderPrimitive(r300ContextPtr rmesa, GLcontext * ctx,
260 int start, int end, int prim)
261 {
262 int type, num_verts;
263 TNLcontext *tnl = TNL_CONTEXT(ctx);
264 struct vertex_buffer *vb = &tnl->vb;
265
266 type = r300PrimitiveType(rmesa, prim);
267 num_verts = r300NumVerts(rmesa, end - start, prim);
268
269 if (type < 0 || num_verts <= 0)
270 return;
271
272 if (vb->Elts) {
273 if (num_verts > 65535) {
274 /* not implemented yet */
275 WARN_ONCE("Too many elts\n");
276 return;
277 }
278 /* Note: The following is incorrect, but it's the best I can do
279 * without a major refactoring of how DMA memory is handled.
280 * The problem: Ensuring that both vertex arrays *and* index
281 * arrays are at the right position, and then ensuring that
282 * the LOAD_VBPNTR, DRAW_INDX and INDX_BUFFER packets are emitted
283 * at once.
284 *
285 * So why is the following incorrect? Well, it seems like
286 * allocating the index array might actually evict the vertex
287 * arrays. *sigh*
288 */
289 r300EmitElts(ctx, vb->Elts, num_verts);
290 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
291 r300FireEB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type);
292 } else {
293 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
294 r300FireAOS(rmesa, num_verts, type);
295 }
296 }
297
298 static GLboolean r300RunRender(GLcontext * ctx,
299 struct tnl_pipeline_stage *stage)
300 {
301 r300ContextPtr rmesa = R300_CONTEXT(ctx);
302 int i;
303 TNLcontext *tnl = TNL_CONTEXT(ctx);
304 struct vertex_buffer *vb = &tnl->vb;
305
306
307 if (RADEON_DEBUG & DEBUG_PRIMS)
308 fprintf(stderr, "%s\n", __FUNCTION__);
309
310 r300UpdateShaders(rmesa);
311 if (r300EmitArrays(ctx))
312 return GL_TRUE;
313
314 r300UpdateShaderStates(rmesa);
315
316 r300EmitCacheFlush(rmesa);
317 r300EmitState(rmesa);
318
319 for (i = 0; i < vb->PrimitiveCount; i++) {
320 GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
321 GLuint start = vb->Primitive[i].start;
322 GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
323 r300RunRenderPrimitive(rmesa, ctx, start, end, prim);
324 }
325
326 r300EmitCacheFlush(rmesa);
327
328 #ifdef USER_BUFFERS
329 r300UseArrays(ctx);
330 #endif
331
332 r300ReleaseArrays(ctx);
333
334 return GL_FALSE;
335 }
336
337 #define FALLBACK_IF(expr) \
338 do { \
339 if (expr) { \
340 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
341 WARN_ONCE("Software fallback:%s\n", \
342 #expr); \
343 return R300_FALLBACK_RAST; \
344 } \
345 } while(0)
346
347 static int r300Fallback(GLcontext * ctx)
348 {
349 r300ContextPtr r300 = R300_CONTEXT(ctx);
350 const unsigned back = ctx->Stencil._BackFace;
351
352 /* Do we need to use new-style shaders?
353 * Also is there a better way to do this? */
354 if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
355 struct r500_fragment_program *fp = (struct r500_fragment_program *)
356 (char *)ctx->FragmentProgram._Current;
357 if (fp) {
358 if (!fp->translated) {
359 r500TranslateFragmentShader(r300, fp);
360 FALLBACK_IF(!fp->translated);
361 }
362 }
363 } else {
364 struct r300_fragment_program *fp = (struct r300_fragment_program *)
365 (char *)ctx->FragmentProgram._Current;
366 if (fp) {
367 if (!fp->translated) {
368 r300TranslateFragmentShader(r300, fp);
369 FALLBACK_IF(!fp->translated);
370 }
371 }
372 }
373
374 FALLBACK_IF(ctx->RenderMode != GL_RENDER);
375
376 /* If GL_EXT_stencil_two_side is disabled, this fallback check can
377 * be removed.
378 */
379 FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
380 || ctx->Stencil.ValueMask[0] !=
381 ctx->Stencil.ValueMask[back]
382 || ctx->Stencil.WriteMask[0] !=
383 ctx->Stencil.WriteMask[back]);
384
385 if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
386 FALLBACK_IF(ctx->Point.PointSprite);
387
388 if (!r300->disable_lowimpact_fallback) {
389 FALLBACK_IF(ctx->Polygon.StippleFlag);
390 FALLBACK_IF(ctx->Multisample._Enabled);
391 FALLBACK_IF(ctx->Line.StippleFlag);
392 FALLBACK_IF(ctx->Line.SmoothFlag);
393 FALLBACK_IF(ctx->Point.SmoothFlag);
394 }
395
396 return R300_FALLBACK_NONE;
397 }
398
399 static GLboolean r300RunNonTCLRender(GLcontext * ctx,
400 struct tnl_pipeline_stage *stage)
401 {
402 r300ContextPtr rmesa = R300_CONTEXT(ctx);
403
404 if (RADEON_DEBUG & DEBUG_PRIMS)
405 fprintf(stderr, "%s\n", __FUNCTION__);
406
407 if (r300Fallback(ctx) >= R300_FALLBACK_RAST)
408 return GL_TRUE;
409
410 if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
411 return GL_TRUE;
412
413 return r300RunRender(ctx, stage);
414 }
415
416 static GLboolean r300RunTCLRender(GLcontext * ctx,
417 struct tnl_pipeline_stage *stage)
418 {
419 r300ContextPtr rmesa = R300_CONTEXT(ctx);
420 struct r300_vertex_program *vp;
421
422 hw_tcl_on = future_hw_tcl_on;
423
424 if (RADEON_DEBUG & DEBUG_PRIMS)
425 fprintf(stderr, "%s\n", __FUNCTION__);
426
427 if (hw_tcl_on == GL_FALSE)
428 return GL_TRUE;
429
430 if (r300Fallback(ctx) >= R300_FALLBACK_TCL) {
431 hw_tcl_on = GL_FALSE;
432 return GL_TRUE;
433 }
434
435 r300UpdateShaders(rmesa);
436
437 vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
438 if (vp->native == GL_FALSE) {
439 hw_tcl_on = GL_FALSE;
440 return GL_TRUE;
441 }
442
443 return r300RunRender(ctx, stage);
444 }
445
446 const struct tnl_pipeline_stage _r300_render_stage = {
447 "r300 Hardware Rasterization",
448 NULL,
449 NULL,
450 NULL,
451 NULL,
452 r300RunNonTCLRender
453 };
454
455 const struct tnl_pipeline_stage _r300_tcl_stage = {
456 "r300 Hardware Transform, Clipping and Lighting",
457 NULL,
458 NULL,
459 NULL,
460 NULL,
461 r300RunTCLRender
462 };