Fix r6 code bugs.
[mesa.git] / src / mesa / drivers / dri / r600 / r600_swtcl.c
1 /**************************************************************************
2
3 Copyright (C) 2007 Dave Airlie
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 THE COPYRIGHT OWNER(S) AND/OR ITS 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 * Dave Airlie <airlied@linux.ie>
31 * Maciej Cencora <m.cencora@gmail.com>
32 */
33
34 #include "tnl/tnl.h"
35 #include "tnl/t_pipeline.h"
36
37 #include "r600_swtcl.h"
38 #include "r600_emit.h"
39
40 #define EMIT_ATTR( ATTR, STYLE ) \
41 do { \
42 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
43 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
44 rmesa->radeon.swtcl.vertex_attr_count++; \
45 } while (0)
46
47 #define EMIT_PAD( N ) \
48 do { \
49 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = 0; \
50 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = EMIT_PAD; \
51 rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].offset = (N); \
52 rmesa->radeon.swtcl.vertex_attr_count++; \
53 } while (0)
54
55 #define ADD_ATTR(_attr, _format, _dst_loc, _swizzle, _write_mask) \
56 do { \
57 attrs[num_attrs].attr = (_attr); \
58 attrs[num_attrs].format = (_format); \
59 attrs[num_attrs].dst_loc = (_dst_loc); \
60 attrs[num_attrs].swizzle = (_swizzle); \
61 attrs[num_attrs].write_mask = (_write_mask); \
62 ++num_attrs; \
63 } while (0)
64
65 static void r600SwtclVAPSetup(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
66 {
67 }
68
69
70 static void r600SetVertexFormat( GLcontext *ctx )
71 {
72 #if 0 /* to be enabled */
73 r600ContextPtr rmesa = R600_CONTEXT( ctx );
74 TNLcontext *tnl = TNL_CONTEXT(ctx);
75 struct vertex_buffer *VB = &tnl->vb;
76 int fog_id = -1;
77 GLuint InputsRead = 0;
78 GLuint OutputsWritten = 0;
79 int num_attrs = 0;
80 struct vertex_attribute *attrs = rmesa->swtcl.vert_attrs;
81
82 rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
83 rmesa->radeon.swtcl.vertex_attr_count = 0;
84
85 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS)) {
86 InputsRead |= 1 << VERT_ATTRIB_POS;
87 OutputsWritten |= 1 << VERT_RESULT_HPOS;
88 EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F );
89 ADD_ATTR(VERT_ATTRIB_POS, EMIT_4F, SWTCL_OVM_POS, SWIZZLE_XYZW, MASK_XYZW);
90 rmesa->swtcl.coloroffset = 4;
91 }
92
93 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR0)) {
94 InputsRead |= 1 << VERT_ATTRIB_COLOR0;
95 OutputsWritten |= 1 << VERT_RESULT_COL0;
96 #if MESA_LITTLE_ENDIAN
97 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA );
98 ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW);
99 #else
100 EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR );
101 ADD_ATTR(VERT_ATTRIB_COLOR0, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR0, SWIZZLE_XYZW, MASK_XYZW);
102 #endif
103 }
104
105 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_COLOR1 )) {
106 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
107 InputsRead |= 1 << VERT_ATTRIB_COLOR1;
108 OutputsWritten |= 1 << VERT_RESULT_COL1;
109 #if MESA_LITTLE_ENDIAN
110 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA );
111 ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_RGBA, SWTCL_OVM_COLOR1, swiz, MASK_XYZW);
112 #else
113 EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR );
114 ADD_ATTR(VERT_ATTRIB_COLOR1, EMIT_4UB_4F_ABGR, SWTCL_OVM_COLOR1, swiz, MASK_XYZW);
115 #endif
116 rmesa->swtcl.specoffset = rmesa->swtcl.coloroffset + 1;
117 }
118
119 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POINTSIZE )) {
120 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
121 InputsRead |= 1 << VERT_ATTRIB_POINT_SIZE;
122 OutputsWritten |= 1 << VERT_RESULT_PSIZ;
123 EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F );
124 ADD_ATTR(VERT_ATTRIB_POINT_SIZE, EMIT_1F, SWTCL_OVM_POINT_SIZE, swiz, MASK_X);
125 }
126
127 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_FOG)) {
128 /* find first free tex coord slot */
129 if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
130 int i;
131 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
132 if (!RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
133 fog_id = i;
134 break;
135 }
136 }
137 } else {
138 fog_id = 0;
139 }
140
141 if (fog_id == -1) {
142 fprintf(stderr, "\tout of free texcoords to do fog\n");
143 _mesa_exit(-1);
144 }
145
146 InputsRead |= 1 << VERT_ATTRIB_FOG;
147 OutputsWritten |= 1 << VERT_RESULT_FOGC;
148 GLuint swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
149 EMIT_ATTR( _TNL_ATTRIB_FOG, EMIT_1F );
150 ADD_ATTR(VERT_ATTRIB_FOG, EMIT_1F, SWTCL_OVM_TEX(fog_id), swiz, MASK_X);
151 }
152
153 if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
154 int i;
155 GLuint swiz, mask, format;
156 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
157 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
158 switch (VB->TexCoordPtr[i]->size) {
159 case 1:
160 case 2:
161 format = EMIT_2F;
162 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
163 mask = MASK_X | MASK_Y;
164 break;
165 case 3:
166 format = EMIT_3F;
167 swiz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
168 mask = MASK_X | MASK_Y | MASK_Z;
169 break;
170 case 4:
171 format = EMIT_4F;
172 swiz = SWIZZLE_XYZW;
173 mask = MASK_XYZW;
174 break;
175 default:
176 continue;
177 }
178 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + i);
179 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i);
180 EMIT_ATTR(_TNL_ATTRIB_TEX(i), format);
181 ADD_ATTR(VERT_ATTRIB_TEX0 + i, format, SWTCL_OVM_TEX(i), swiz, mask);
182 }
183 }
184 }
185
186 /* RS can't put fragment position on the pixel stack, so stuff it in texcoord if needed */
187 if (RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_POS) && (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) {
188 int first_free_tex = -1;
189 if (fog_id >= 0) {
190 first_free_tex = fog_id+1;
191 } else {
192 if (RENDERINPUTS_TEST_RANGE(tnl->render_inputs_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) {
193 int i;
194 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
195 if (!RENDERINPUTS_TEST(tnl->render_inputs_bitset, _TNL_ATTRIB_TEX(i) )) {
196 first_free_tex = i;
197 break;
198 }
199 }
200 } else {
201 first_free_tex = 0;
202 }
203 }
204
205 if (first_free_tex == -1) {
206 fprintf(stderr, "\tout of free texcoords to write w pos\n");
207 _mesa_exit(-1);
208 }
209
210 InputsRead |= 1 << (VERT_ATTRIB_TEX0 + first_free_tex);
211 OutputsWritten |= 1 << (VERT_RESULT_TEX0 + first_free_tex);
212 EMIT_ATTR( _TNL_ATTRIB_TEX(first_free_tex), EMIT_4F );
213 ADD_ATTR(VERT_ATTRIB_TEX0 + first_free_tex, EMIT_4F, SWTCL_OVM_TEX(first_free_tex), SWIZZLE_XYZW, MASK_XYZW);
214 }
215
216 R600_NEWPRIM(rmesa);
217 r600SwtclVAPSetup(ctx, InputsRead, OutputsWritten);
218
219 rmesa->radeon.swtcl.vertex_size =
220 _tnl_install_attrs( ctx,
221 rmesa->radeon.swtcl.vertex_attrs,
222 rmesa->radeon.swtcl.vertex_attr_count,
223 NULL, 0 );
224
225 rmesa->radeon.swtcl.vertex_size /= 4;
226
227 RENDERINPUTS_COPY(rmesa->state.render_inputs_bitset, tnl->render_inputs_bitset);
228 #endif /* to be enabled */
229 }
230
231
232 static GLuint reduced_prim[] = {
233 GL_POINTS,
234 GL_LINES,
235 GL_LINES,
236 GL_LINES,
237 GL_TRIANGLES,
238 GL_TRIANGLES,
239 GL_TRIANGLES,
240 GL_TRIANGLES,
241 GL_TRIANGLES,
242 GL_TRIANGLES,
243 };
244
245 static void r600RasterPrimitive( GLcontext *ctx, GLuint prim );
246 static void r600RenderPrimitive( GLcontext *ctx, GLenum prim );
247
248 /***********************************************************************
249 * Emit primitives as inline vertices *
250 ***********************************************************************/
251
252
253 #define HAVE_POINTS 1
254 #define HAVE_LINES 1
255 #define HAVE_LINE_STRIPS 1
256 #define HAVE_TRIANGLES 1
257 #define HAVE_TRI_STRIPS 1
258 #define HAVE_TRI_STRIP_1 0
259 #define HAVE_TRI_FANS 1
260 #define HAVE_QUADS 0
261 #define HAVE_QUAD_STRIPS 0
262 #define HAVE_POLYGONS 1
263 #define HAVE_ELTS 1
264
265 #undef LOCAL_VARS
266 #undef ALLOC_VERTS
267 #define CTX_ARG r600ContextPtr rmesa
268 #define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
269 #define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
270 #define LOCAL_VARS \
271 r600ContextPtr rmesa = R600_CONTEXT(ctx); \
272 const char *r600verts = (char *)rmesa->radeon.swtcl.verts;
273 #define VERT(x) (r600Vertex *)(r600verts + ((x) * vertsize * sizeof(int)))
274 #define VERTEX r600Vertex
275 #undef TAG
276 #define TAG(x) r600_##x
277 #include "tnl_dd/t_dd_triemit.h"
278
279
280
281 /***********************************************************************
282 * Macros for t_dd_tritmp.h to draw basic primitives *
283 ***********************************************************************/
284
285 #define QUAD( a, b, c, d ) r600_quad( rmesa, a, b, c, d )
286 #define TRI( a, b, c ) r600_triangle( rmesa, a, b, c )
287 #define LINE( a, b ) r600_line( rmesa, a, b )
288 #define POINT( a ) r600_point( rmesa, a )
289
290 /***********************************************************************
291 * Build render functions from dd templates *
292 ***********************************************************************/
293
294 #define R600_TWOSIDE_BIT 0x01
295 #define R600_UNFILLED_BIT 0x02
296 #define R600_MAX_TRIFUNC 0x04
297
298 static struct {
299 tnl_points_func points;
300 tnl_line_func line;
301 tnl_triangle_func triangle;
302 tnl_quad_func quad;
303 } rast_tab[R600_MAX_TRIFUNC];
304
305 #define DO_FALLBACK 0
306 #define DO_UNFILLED (IND & R600_UNFILLED_BIT)
307 #define DO_TWOSIDE (IND & R600_TWOSIDE_BIT)
308 #define DO_FLAT 0
309 #define DO_OFFSET 0
310 #define DO_TRI 1
311 #define DO_QUAD 1
312 #define DO_LINE 1
313 #define DO_POINTS 1
314 #define DO_FULL_QUAD 1
315
316 #define HAVE_RGBA 1
317 #define HAVE_SPEC 1
318 #define HAVE_BACK_COLORS 0
319 #define HAVE_HW_FLATSHADE 1
320 #define TAB rast_tab
321
322 #define DEPTH_SCALE 1.0
323 #define UNFILLED_TRI unfilled_tri
324 #define UNFILLED_QUAD unfilled_quad
325 #define VERT_X(_v) _v->v.x
326 #define VERT_Y(_v) _v->v.y
327 #define VERT_Z(_v) _v->v.z
328 #define AREA_IS_CCW( a ) (a < 0)
329 #define GET_VERTEX(e) (rmesa->radeon.swtcl.verts + (e*rmesa->radeon.swtcl.vertex_size*sizeof(int)))
330
331 #define VERT_SET_RGBA( v, c ) \
332 do { \
333 r600_color_t *color = (r600_color_t *)&((v)->ui[coloroffset]); \
334 UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \
335 UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \
336 UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \
337 UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \
338 } while (0)
339
340 #define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset]
341
342 #define VERT_SET_SPEC( v0, c ) \
343 do { \
344 if (specoffset) { \
345 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.red, (c)[0]); \
346 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.green, (c)[1]); \
347 UNCLAMPED_FLOAT_TO_UBYTE(v0->v.specular.blue, (c)[2]); \
348 } \
349 } while (0)
350
351 #define VERT_COPY_SPEC( v0, v1 ) \
352 do { \
353 if (specoffset) { \
354 v0->v.specular.red = v1->v.specular.red; \
355 v0->v.specular.green = v1->v.specular.green; \
356 v0->v.specular.blue = v1->v.specular.blue; \
357 } \
358 } while (0)
359
360 #define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset]
361 #define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx]
362 #define VERT_SAVE_SPEC( idx ) if (specoffset) spec[idx] = v[idx]->ui[specoffset]
363 #define VERT_RESTORE_SPEC( idx ) if (specoffset) v[idx]->ui[specoffset] = spec[idx]
364
365 #undef LOCAL_VARS
366 #undef TAG
367 #undef INIT
368
369 #define LOCAL_VARS(n) \
370 r600ContextPtr rmesa = R600_CONTEXT(ctx); \
371 GLuint color[n] = { 0, }, spec[n] = { 0, }; \
372 GLuint coloroffset = rmesa->swtcl.coloroffset; \
373 GLuint specoffset = rmesa->swtcl.specoffset; \
374 (void) color; (void) spec; (void) coloroffset; (void) specoffset;
375
376 /***********************************************************************
377 * Helpers for rendering unfilled primitives *
378 ***********************************************************************/
379
380 #define RASTERIZE(x) r600RasterPrimitive( ctx, reduced_prim[x] )
381 #define RENDER_PRIMITIVE rmesa->radeon.swtcl.render_primitive
382 #undef TAG
383 #define TAG(x) x
384 #include "tnl_dd/t_dd_unfilled.h"
385 #undef IND
386
387
388 /***********************************************************************
389 * Generate GL render functions *
390 ***********************************************************************/
391
392
393 #define IND (0)
394 #define TAG(x) x
395 #include "tnl_dd/t_dd_tritmp.h"
396
397 #define IND (R600_TWOSIDE_BIT)
398 #define TAG(x) x##_twoside
399 #include "tnl_dd/t_dd_tritmp.h"
400
401 #define IND (R600_UNFILLED_BIT)
402 #define TAG(x) x##_unfilled
403 #include "tnl_dd/t_dd_tritmp.h"
404
405 #define IND (R600_TWOSIDE_BIT|R600_UNFILLED_BIT)
406 #define TAG(x) x##_twoside_unfilled
407 #include "tnl_dd/t_dd_tritmp.h"
408
409
410
411 static void init_rast_tab( void )
412 {
413 init();
414 init_twoside();
415 init_unfilled();
416 init_twoside_unfilled();
417 }
418
419 /**********************************************************************/
420 /* Render unclipped begin/end objects */
421 /**********************************************************************/
422
423 #define RENDER_POINTS( start, count ) \
424 for ( ; start < count ; start++) \
425 r600_point( rmesa, VERT(start) )
426 #define RENDER_LINE( v0, v1 ) \
427 r600_line( rmesa, VERT(v0), VERT(v1) )
428 #define RENDER_TRI( v0, v1, v2 ) \
429 r600_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) )
430 #define RENDER_QUAD( v0, v1, v2, v3 ) \
431 r600_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) )
432 #define INIT(x) do { \
433 r600RenderPrimitive( ctx, x ); \
434 } while (0)
435 #undef LOCAL_VARS
436 #define LOCAL_VARS \
437 r600ContextPtr rmesa = R600_CONTEXT(ctx); \
438 const GLuint vertsize = rmesa->radeon.swtcl.vertex_size; \
439 const char *r600verts = (char *)rmesa->radeon.swtcl.verts; \
440 const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \
441 const GLboolean stipple = ctx->Line.StippleFlag; \
442 (void) elt; (void) stipple;
443 #define RESET_STIPPLE //if ( stipple ) r200ResetLineStipple( ctx );
444 #define RESET_OCCLUSION
445 #define PRESERVE_VB_DEFS
446 #define ELT(x) (x)
447 #define TAG(x) r600_##x##_verts
448 #include "tnl/t_vb_rendertmp.h"
449 #undef ELT
450 #undef TAG
451 #define TAG(x) r600_##x##_elts
452 #define ELT(x) elt[x]
453 #include "tnl/t_vb_rendertmp.h"
454
455
456
457
458 /**********************************************************************/
459 /* Choose render functions */
460 /**********************************************************************/
461 static void r600ChooseRenderState( GLcontext *ctx )
462 {
463 TNLcontext *tnl = TNL_CONTEXT(ctx);
464 r600ContextPtr rmesa = R600_CONTEXT(ctx);
465 GLuint index = 0;
466 GLuint flags = ctx->_TriangleCaps;
467
468 if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R600_TWOSIDE_BIT;
469 if (flags & DD_TRI_UNFILLED) index |= R600_UNFILLED_BIT;
470
471 if (index != rmesa->radeon.swtcl.RenderIndex) {
472 tnl->Driver.Render.Points = rast_tab[index].points;
473 tnl->Driver.Render.Line = rast_tab[index].line;
474 tnl->Driver.Render.ClippedLine = rast_tab[index].line;
475 tnl->Driver.Render.Triangle = rast_tab[index].triangle;
476 tnl->Driver.Render.Quad = rast_tab[index].quad;
477
478 if (index == 0) {
479 tnl->Driver.Render.PrimTabVerts = r600_render_tab_verts;
480 tnl->Driver.Render.PrimTabElts = r600_render_tab_elts;
481 tnl->Driver.Render.ClippedPolygon = r600_fast_clipped_poly;
482 } else {
483 tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
484 tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
485 tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon;
486 }
487
488 rmesa->radeon.swtcl.RenderIndex = index;
489 }
490 }
491
492
493 static void r600RenderStart(GLcontext *ctx)
494 {
495 #if 0 /* to be enabled */
496 r600ContextPtr rmesa = R600_CONTEXT( ctx );
497
498 r600ChooseRenderState(ctx);
499 r600SetVertexFormat(ctx);
500
501 r600ValidateBuffers(ctx);
502
503 r600UpdateShaders(rmesa);
504 r600UpdateShaderStates(rmesa);
505
506 r600EmitCacheFlush(rmesa);
507
508 /* investigate if we can put back flush optimisation if needed */
509 if (rmesa->radeon.dma.flush != NULL) {
510 rmesa->radeon.dma.flush(ctx);
511 }
512 #endif /* to be enabled */
513 }
514
515 static void r600RenderFinish(GLcontext *ctx)
516 {
517 }
518
519 static void r600RasterPrimitive( GLcontext *ctx, GLuint hwprim )
520 {
521 #if 0 /* to be enabled */
522 r600ContextPtr rmesa = R600_CONTEXT(ctx);
523
524 if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
525 R600_NEWPRIM( rmesa );
526 rmesa->radeon.swtcl.hw_primitive = hwprim;
527 }
528 #endif /* to be enabled */
529 }
530
531 static void r600RenderPrimitive(GLcontext *ctx, GLenum prim)
532 {
533
534 r600ContextPtr rmesa = R600_CONTEXT(ctx);
535 rmesa->radeon.swtcl.render_primitive = prim;
536
537 if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
538 return;
539
540 r600RasterPrimitive( ctx, reduced_prim[prim] );
541 }
542
543 static void r600ResetLineStipple(GLcontext *ctx)
544 {
545 }
546
547 void r600InitSwtcl(GLcontext *ctx)
548 {
549 TNLcontext *tnl = TNL_CONTEXT(ctx);
550 r600ContextPtr rmesa = R600_CONTEXT(ctx);
551 static int firsttime = 1;
552
553 if (firsttime) {
554 init_rast_tab();
555 firsttime = 0;
556 }
557
558 tnl->Driver.Render.Start = r600RenderStart;
559 tnl->Driver.Render.Finish = r600RenderFinish;
560 tnl->Driver.Render.PrimitiveNotify = r600RenderPrimitive;
561 tnl->Driver.Render.ResetLineStipple = r600ResetLineStipple;
562 tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
563 tnl->Driver.Render.CopyPV = _tnl_copy_pv;
564 tnl->Driver.Render.Interp = _tnl_interp;
565
566 /* FIXME: what are these numbers? */
567 _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12,
568 48 * sizeof(GLfloat) );
569
570 rmesa->radeon.swtcl.verts = (GLubyte *)tnl->clipspace.vertex_buf;
571 rmesa->radeon.swtcl.RenderIndex = ~0;
572 rmesa->radeon.swtcl.render_primitive = GL_TRIANGLES;
573 rmesa->radeon.swtcl.hw_primitive = 0;
574
575 _tnl_invalidate_vertex_state( ctx, ~0 );
576 _tnl_invalidate_vertices( ctx, ~0 );
577
578 _tnl_need_projected_coords( ctx, GL_FALSE );
579 r600ChooseRenderState(ctx);
580 }
581
582 void r600DestroySwtcl(GLcontext *ctx)
583 {
584 }
585
586 static void r600EmitVertexAOS(r600ContextPtr rmesa, GLuint vertex_size, struct radeon_bo *bo, GLuint offset)
587 {
588 #if 0 /* to be enabled */
589 BATCH_LOCALS(&rmesa->radeon);
590
591 if (RADEON_DEBUG & DEBUG_VERTS)
592 fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
593 __FUNCTION__, vertex_size, offset);
594
595 BEGIN_BATCH(7);
596 OUT_BATCH_PACKET3(R600_PACKET3_3D_LOAD_VBPNTR, 2);
597 R600_OUT_BATCH(1);
598 R600_OUT_BATCH(vertex_size | (vertex_size << 8));
599 OUT_BATCH_RELOC(offset, bo, offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
600 END_BATCH();
601 #endif /* to be enabled */
602 }
603
604 static void r600EmitVbufPrim(r600ContextPtr rmesa, GLuint primitive, GLuint vertex_nr)
605 {
606 #if 0 /* to be enabled */
607 BATCH_LOCALS(&rmesa->radeon);
608 int type, num_verts;
609
610 type = r600PrimitiveType(rmesa, primitive);
611 num_verts = r600NumVerts(rmesa, vertex_nr, primitive);
612
613 BEGIN_BATCH(3);
614 OUT_BATCH_PACKET3(R600_PACKET3_3D_DRAW_VBUF_2, 0);
615 R600_OUT_BATCH(R600_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (num_verts << 16) | type);
616 END_BATCH();
617 #endif /* to be enabled */
618 }
619
620 void r600_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
621 {
622 #if 0 /* to be enabled */
623 r600ContextPtr rmesa = R600_CONTEXT(ctx);
624
625 rcommonEnsureCmdBufSpace(&rmesa->radeon,
626 rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
627 __FUNCTION__);
628 radeonEmitState(&rmesa->radeon);
629 r600EmitVertexAOS(rmesa,
630 rmesa->radeon.swtcl.vertex_size,
631 rmesa->radeon.dma.current,
632 current_offset);
633
634 r600EmitVbufPrim(rmesa,
635 rmesa->radeon.swtcl.hw_primitive,
636 rmesa->radeon.swtcl.numverts);
637 r600EmitCacheFlush(rmesa);
638 COMMIT_BATCH();
639 #endif /* to be enabled */
640 }