62687071dc0964b0c05290f519a95904a3c5ed2f
[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 * Authors:
30 * Nicolai Haehnle <prefect_@gmx.net>
31 */
32
33 #include "glheader.h"
34 #include "state.h"
35 #include "imports.h"
36 #include "enums.h"
37 #include "macros.h"
38 #include "context.h"
39 #include "dd.h"
40 #include "simple_list.h"
41
42 #include "api_arrayelt.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
45 #include "vbo/vbo.h"
46 #include "tnl/tnl.h"
47 #include "tnl/t_vp_build.h"
48
49 #include "radeon_reg.h"
50 #include "radeon_macros.h"
51 #include "radeon_ioctl.h"
52 #include "radeon_state.h"
53 #include "r300_context.h"
54 #include "r300_ioctl.h"
55 #include "r300_state.h"
56 #include "r300_reg.h"
57 #include "r300_program.h"
58 #include "r300_tex.h"
59 #include "r300_maos.h"
60 #include "r300_emit.h"
61
62 extern int future_hw_tcl_on;
63
64 /**********************************************************************
65 * Hardware rasterization
66 *
67 * When we fell back to software TCL, we still try to use the
68 * rasterization hardware for rendering.
69 **********************************************************************/
70
71 static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int prim)
72 {
73 int type=-1;
74
75 switch (prim & PRIM_MODE_MASK) {
76 case GL_POINTS:
77 type=R300_VAP_VF_CNTL__PRIM_POINTS;
78 break;
79 case GL_LINES:
80 type=R300_VAP_VF_CNTL__PRIM_LINES;
81 break;
82 case GL_LINE_STRIP:
83 type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
84 break;
85 case GL_LINE_LOOP:
86 type=R300_VAP_VF_CNTL__PRIM_LINE_LOOP;
87 break;
88 case GL_TRIANGLES:
89 type=R300_VAP_VF_CNTL__PRIM_TRIANGLES;
90 break;
91 case GL_TRIANGLE_STRIP:
92 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP;
93 break;
94 case GL_TRIANGLE_FAN:
95 type=R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN;
96 break;
97 case GL_QUADS:
98 type=R300_VAP_VF_CNTL__PRIM_QUADS;
99 break;
100 case GL_QUAD_STRIP:
101 type=R300_VAP_VF_CNTL__PRIM_QUAD_STRIP;
102 break;
103 case GL_POLYGON:
104 type=R300_VAP_VF_CNTL__PRIM_POLYGON;
105 break;
106 default:
107 fprintf(stderr, "%s:%s Do not know how to handle primitive 0x%04x - help me !\n",
108 __FILE__, __FUNCTION__,
109 prim & PRIM_MODE_MASK);
110 return -1;
111 break;
112 }
113 return type;
114 }
115
116 int r300_get_num_verts(r300ContextPtr rmesa, int num_verts, int prim)
117 {
118 int verts_off=0;
119
120 switch (prim & PRIM_MODE_MASK) {
121 case GL_POINTS:
122 verts_off = 0;
123 break;
124 case GL_LINES:
125 verts_off = num_verts % 2;
126 break;
127 case GL_LINE_STRIP:
128 if(num_verts < 2)
129 verts_off = num_verts;
130 break;
131 case GL_LINE_LOOP:
132 if(num_verts < 2)
133 verts_off = num_verts;
134 break;
135 case GL_TRIANGLES:
136 verts_off = num_verts % 3;
137 break;
138 case GL_TRIANGLE_STRIP:
139 if(num_verts < 3)
140 verts_off = num_verts;
141 break;
142 case GL_TRIANGLE_FAN:
143 if(num_verts < 3)
144 verts_off = num_verts;
145 break;
146 case GL_QUADS:
147 verts_off = num_verts % 4;
148 break;
149 case GL_QUAD_STRIP:
150 if(num_verts < 4)
151 verts_off = num_verts;
152 else
153 verts_off = num_verts % 2;
154 break;
155 case GL_POLYGON:
156 if(num_verts < 3)
157 verts_off = num_verts;
158 break;
159 default:
160 fprintf(stderr, "%s:%s Do not know how to handle primitive 0x%04x - help me !\n",
161 __FILE__, __FUNCTION__,
162 prim & PRIM_MODE_MASK);
163 return -1;
164 break;
165 }
166
167 if (RADEON_DEBUG & DEBUG_VERTS) {
168 if (num_verts - verts_off == 0) {
169 WARN_ONCE("user error: Need more than %d vertices to draw primitive 0x%04x !\n",
170 num_verts, prim & PRIM_MODE_MASK);
171 return 0;
172 }
173
174 if (verts_off > 0) {
175 WARN_ONCE("user error: %d is not a valid number of vertices for primitive 0x%04x !\n",
176 num_verts, prim & PRIM_MODE_MASK);
177 }
178 }
179
180 return num_verts - verts_off;
181 }
182
183 /* Immediate implementation has been removed from CVS. */
184
185 /* vertex buffer implementation */
186
187 static void inline fire_EB(r300ContextPtr rmesa, unsigned long addr, int vertex_count, int type, int elt_size)
188 {
189 int cmd_reserved = 0;
190 int cmd_written = 0;
191 drm_radeon_cmd_header_t *cmd = NULL;
192 unsigned long t_addr;
193 unsigned long magic_1, magic_2;
194 GLcontext *ctx;
195 ctx = rmesa->radeon.glCtx;
196
197 assert(elt_size == 2 || elt_size == 4);
198
199 if(addr & (elt_size-1)){
200 WARN_ONCE("Badly aligned buffer\n");
201 return ;
202 }
203
204 magic_1 = (addr % 32) / 4;
205 t_addr = addr & (~0x1d);
206 magic_2 = (vertex_count + 1 + (t_addr & 0x2)) / 2 + magic_1;
207
208 check_space(6);
209
210 start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
211 if(elt_size == 4){
212 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type | R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
213 } else {
214 e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
215 }
216
217 start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
218 #ifdef OPTIMIZE_ELTS
219 if(elt_size == 4){
220 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
221 e32(addr);
222 } else {
223 e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
224 e32(t_addr);
225 }
226 #else
227 e32(R300_EB_UNK1 | (0 << 16) | R300_EB_UNK2);
228 e32(addr);
229 #endif
230
231 if(elt_size == 4){
232 e32(vertex_count);
233 } else {
234 #ifdef OPTIMIZE_ELTS
235 e32(magic_2);
236 #else
237 e32((vertex_count+1)/2);
238 #endif
239 }
240 }
241
242 static void r300_render_vb_primitive(r300ContextPtr rmesa,
243 GLcontext *ctx,
244 int start,
245 int end,
246 int prim)
247 {
248 int type, num_verts;
249
250 type=r300_get_primitive_type(rmesa, ctx, prim);
251 num_verts=r300_get_num_verts(rmesa, end-start, prim);
252
253 if(type<0 || num_verts <= 0)return;
254
255 if(rmesa->state.VB.Elts){
256 r300EmitAOS(rmesa, rmesa->state.aos_count, /*0*/start);
257 if(num_verts > 65535){ /* not implemented yet */
258 WARN_ONCE("Too many elts\n");
259 return;
260 }
261 r300EmitElts(ctx, rmesa->state.VB.Elts, num_verts, rmesa->state.VB.elt_size);
262 fire_EB(rmesa, rmesa->state.elt_dma.aos_offset, num_verts, type, rmesa->state.VB.elt_size);
263 }else{
264 r300EmitAOS(rmesa, rmesa->state.aos_count, start);
265 fire_AOS(rmesa, num_verts, type);
266 }
267 }
268
269 GLboolean r300_run_vb_render(GLcontext *ctx,
270 struct tnl_pipeline_stage *stage)
271 {
272 r300ContextPtr rmesa = R300_CONTEXT(ctx);
273 struct radeon_vertex_buffer *VB = &rmesa->state.VB;
274 int i;
275 int cmd_reserved = 0;
276 int cmd_written = 0;
277 drm_radeon_cmd_header_t *cmd = NULL;
278
279
280 if (RADEON_DEBUG & DEBUG_PRIMS)
281 fprintf(stderr, "%s\n", __FUNCTION__);
282
283 if (stage) {
284 TNLcontext *tnl = TNL_CONTEXT(ctx);
285 radeon_vb_to_rvb(rmesa, VB, &tnl->vb);
286 }
287
288 r300UpdateShaders(rmesa);
289 if (r300EmitArrays(ctx))
290 return GL_TRUE;
291
292 r300UpdateShaderStates(rmesa);
293
294 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
295 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A);
296
297 reg_start(R300_RB3D_ZCACHE_CTLSTAT,0);
298 e32(R300_RB3D_ZCACHE_UNKNOWN_03);
299
300 r300EmitState(rmesa);
301
302 for(i=0; i < VB->PrimitiveCount; i++){
303 GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
304 GLuint start = VB->Primitive[i].start;
305 GLuint length = VB->Primitive[i].count;
306
307 r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
308 }
309
310 reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
311 e32(R300_RB3D_DSTCACHE_UNKNOWN_0A /*R300_RB3D_DSTCACHE_UNKNOWN_02*/);
312
313 reg_start(R300_RB3D_ZCACHE_CTLSTAT,0);
314 e32(R300_RB3D_ZCACHE_UNKNOWN_03 /*R300_RB3D_ZCACHE_UNKNOWN_01*/);
315
316 #ifdef USER_BUFFERS
317 r300UseArrays(ctx);
318 #endif
319 r300ReleaseArrays(ctx);
320 return GL_FALSE;
321 }
322
323 #define FALLBACK_IF(expr) \
324 do { \
325 if (expr) { \
326 if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \
327 WARN_ONCE("Software fallback:%s\n", \
328 #expr); \
329 return R300_FALLBACK_RAST; \
330 } \
331 } while(0)
332
333 int r300Fallback(GLcontext *ctx)
334 {
335 r300ContextPtr r300 = R300_CONTEXT(ctx);
336 struct r300_fragment_program *rp =
337 (struct r300_fragment_program *)
338 (char *)ctx->FragmentProgram._Current;
339
340 if (rp) {
341 if (!rp->translated)
342 r300_translate_fragment_shader(r300, rp);
343
344 FALLBACK_IF(!rp->translated);
345 }
346
347 /* We do not do SELECT or FEEDBACK (yet ?)
348 * Is it worth doing them ?
349 */
350 FALLBACK_IF(ctx->RenderMode != GL_RENDER);
351
352 FALLBACK_IF(ctx->Stencil._TestTwoSide &&
353 (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] ||
354 ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] ||
355 ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]));
356
357 if(!r300->disable_lowimpact_fallback){
358 /* GL_POLYGON_OFFSET_POINT */
359 FALLBACK_IF(ctx->Polygon.OffsetPoint);
360 /* GL_POLYGON_OFFSET_LINE */
361 FALLBACK_IF(ctx->Polygon.OffsetLine);
362 /* GL_POLYGON_STIPPLE */
363 FALLBACK_IF(ctx->Polygon.StippleFlag);
364 /* GL_MULTISAMPLE_ARB */
365 FALLBACK_IF(ctx->Multisample.Enabled);
366 /* blender ? */
367 FALLBACK_IF(ctx->Line.StippleFlag);
368 /* GL_LINE_SMOOTH */
369 FALLBACK_IF(ctx->Line.SmoothFlag);
370 /* GL_POINT_SMOOTH */
371 FALLBACK_IF(ctx->Point.SmoothFlag);
372 }
373
374 /* Fallback for LOGICOP */
375 FALLBACK_IF(ctx->Color.ColorLogicOpEnabled);
376
377 /* Rest could be done with vertex fragments */
378 if (ctx->Extensions.NV_point_sprite ||
379 ctx->Extensions.ARB_point_sprite)
380 /* GL_POINT_SPRITE_NV */
381 FALLBACK_IF(ctx->Point.PointSprite);
382
383 return R300_FALLBACK_NONE;
384 }
385
386 /**
387 * Called by the pipeline manager to render a batch of primitives.
388 * We can return true to pass on to the next stage (i.e. software
389 * rasterization) or false to indicate that the pipeline has finished
390 * after we render something.
391 */
392 static GLboolean r300_run_render(GLcontext *ctx,
393 struct tnl_pipeline_stage *stage)
394 {
395 if (RADEON_DEBUG & DEBUG_PRIMS)
396 fprintf(stderr, "%s\n", __FUNCTION__);
397
398 if (r300Fallback(ctx) >= R300_FALLBACK_RAST)
399 return GL_TRUE;
400
401 return r300_run_vb_render(ctx, stage);
402 }
403
404 const struct tnl_pipeline_stage _r300_render_stage = {
405 "r300 hw rasterize",
406 NULL,
407 NULL,
408 NULL,
409 NULL,
410 r300_run_render /* run */
411 };
412
413 static GLboolean r300_run_tcl_render(GLcontext *ctx,
414 struct tnl_pipeline_stage *stage)
415 {
416 r300ContextPtr rmesa = R300_CONTEXT(ctx);
417 struct r300_vertex_program *vp;
418
419 hw_tcl_on=future_hw_tcl_on;
420
421 if (RADEON_DEBUG & DEBUG_PRIMS)
422 fprintf(stderr, "%s\n", __FUNCTION__);
423 if(hw_tcl_on == GL_FALSE)
424 return GL_TRUE;
425
426 if (r300Fallback(ctx) >= R300_FALLBACK_TCL) {
427 hw_tcl_on = GL_FALSE;
428 return GL_TRUE;
429 }
430
431 r300UpdateShaders(rmesa);
432
433 vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
434 if (vp->native == GL_FALSE) {
435 hw_tcl_on = GL_FALSE;
436 return GL_TRUE;
437 }
438
439 //r300UpdateShaderStates(rmesa);
440
441 return r300_run_vb_render(ctx, stage);
442 }
443
444 const struct tnl_pipeline_stage _r300_tcl_stage = {
445 "r300 tcl",
446 NULL,
447 NULL,
448 NULL,
449 NULL,
450 r300_run_tcl_render /* run */
451 };
452