mesa: Eliminate dd_function_table::MapBuffer
[mesa.git] / src / mesa / drivers / dri / r600 / evergreen_render.c
1 /*
2 * Copyright (C) 2008-2010 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 /*
23 * Authors:
24 * Richard Li <RichardZ.Li@amd.com>, <richardradeon@gmail.com>
25 */
26
27 #include "main/glheader.h"
28 #include "main/state.h"
29 #include "main/imports.h"
30 #include "main/enums.h"
31 #include "main/macros.h"
32 #include "main/context.h"
33 #include "main/dd.h"
34 #include "main/simple_list.h"
35 #include "main/api_arrayelt.h"
36 #include "swrast/swrast.h"
37 #include "swrast_setup/swrast_setup.h"
38 #include "vbo/vbo.h"
39
40 #include "tnl/tnl.h"
41 #include "tnl/t_vp_build.h"
42 #include "tnl/t_context.h"
43 #include "tnl/t_vertex.h"
44 #include "vbo/vbo_context.h"
45
46 #include "r600_context.h"
47 #include "r600_cmdbuf.h"
48
49 #include "evergreen_fragprog.h"
50 #include "evergreen_vertprog.h"
51
52 #include "evergreen_state.h"
53 #include "evergreen_tex.h"
54
55 #include "radeon_buffer_objects.h"
56 #include "radeon_common_context.h"
57
58 static unsigned int evergreenPrimitiveType(int prim) //same
59 {
60 switch (prim & PRIM_MODE_MASK)
61 {
62 case GL_POINTS:
63 return DI_PT_POINTLIST;
64 break;
65 case GL_LINES:
66 return DI_PT_LINELIST;
67 break;
68 case GL_LINE_STRIP:
69 return DI_PT_LINESTRIP;
70 break;
71 case GL_LINE_LOOP:
72 return DI_PT_LINELOOP;
73 break;
74 case GL_TRIANGLES:
75 return DI_PT_TRILIST;
76 break;
77 case GL_TRIANGLE_STRIP:
78 return DI_PT_TRISTRIP;
79 break;
80 case GL_TRIANGLE_FAN:
81 return DI_PT_TRIFAN;
82 break;
83 case GL_QUADS:
84 return DI_PT_QUADLIST;
85 break;
86 case GL_QUAD_STRIP:
87 return DI_PT_QUADSTRIP;
88 break;
89 case GL_POLYGON:
90 return DI_PT_POLYGON;
91 break;
92 default:
93 assert(0);
94 return -1;
95 break;
96 }
97 }
98
99 static int evergreenNumVerts(int num_verts, int prim) //same
100 {
101 int verts_off = 0;
102
103 switch (prim & PRIM_MODE_MASK) {
104 case GL_POINTS:
105 verts_off = 0;
106 break;
107 case GL_LINES:
108 verts_off = num_verts % 2;
109 break;
110 case GL_LINE_STRIP:
111 if (num_verts < 2)
112 verts_off = num_verts;
113 break;
114 case GL_LINE_LOOP:
115 if (num_verts < 2)
116 verts_off = num_verts;
117 break;
118 case GL_TRIANGLES:
119 verts_off = num_verts % 3;
120 break;
121 case GL_TRIANGLE_STRIP:
122 if (num_verts < 3)
123 verts_off = num_verts;
124 break;
125 case GL_TRIANGLE_FAN:
126 if (num_verts < 3)
127 verts_off = num_verts;
128 break;
129 case GL_QUADS:
130 verts_off = num_verts % 4;
131 break;
132 case GL_QUAD_STRIP:
133 if (num_verts < 4)
134 verts_off = num_verts;
135 else
136 verts_off = num_verts % 2;
137 break;
138 case GL_POLYGON:
139 if (num_verts < 3)
140 verts_off = num_verts;
141 break;
142 default:
143 assert(0);
144 return -1;
145 break;
146 }
147
148 return num_verts - verts_off;
149 }
150
151 static void evergreenRunRenderPrimitive(struct gl_context * ctx, int start, int end, int prim,
152 GLint basevertex) //same
153 {
154 context_t *context = EVERGREEN_CONTEXT(ctx);
155 BATCH_LOCALS(&context->radeon);
156 int type, total_emit;
157 int num_indices;
158 uint32_t vgt_draw_initiator = 0;
159 uint32_t vgt_index_type = 0;
160 uint32_t vgt_primitive_type = 0;
161 uint32_t vgt_num_indices = 0;
162
163 type = evergreenPrimitiveType(prim);
164 num_indices = evergreenNumVerts(end - start, prim);
165
166 radeon_print(RADEON_RENDER, RADEON_TRACE,
167 "%s type %x num_indices %d\n",
168 __func__, type, num_indices);
169
170 if (type < 0 || num_indices <= 0)
171 return;
172
173 SETfield(vgt_primitive_type, type,
174 VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
175
176 SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
177
178 if(GL_TRUE != context->ind_buf.is_32bit)
179 {
180 SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
181 }
182
183 /* 16-bit indexes are packed in a 32-bit value */
184 SETfield(vgt_index_type,
185 #if MESA_BIG_ENDIAN
186 VGT_DMA_SWAP_32_BIT,
187 #else
188 VGT_DMA_SWAP_NONE,
189 #endif
190 SWAP_MODE_shift, SWAP_MODE_mask);
191
192 vgt_num_indices = num_indices;
193 SETfield(vgt_draw_initiator, DI_SRC_SEL_DMA, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
194 SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
195
196 total_emit = 3 /* VGT_PRIMITIVE_TYPE */
197 + 2 /* VGT_INDEX_TYPE */
198 + 2 /* NUM_INSTANCES */
199 + 4 /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */
200 + 5 + 2; /* DRAW_INDEX */
201
202 BEGIN_BATCH_NO_AUTOSTATE(total_emit);
203 // prim
204 R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1);
205 R600_OUT_BATCH(vgt_primitive_type);
206 // index type
207 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
208 R600_OUT_BATCH(vgt_index_type);
209 // num instances
210 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
211 R600_OUT_BATCH(1);
212 /* offset */
213 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2));
214 R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
215 R600_OUT_BATCH(basevertex); //VTX_BASE_VTX_LOC
216 R600_OUT_BATCH(0); //VTX_START_INST_LOC
217 // draw packet
218 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3));
219 R600_OUT_BATCH(context->ind_buf.bo_offset);
220 R600_OUT_BATCH(0);
221 R600_OUT_BATCH(vgt_num_indices);
222 R600_OUT_BATCH(vgt_draw_initiator);
223 R600_OUT_BATCH_RELOC(context->ind_buf.bo_offset,
224 context->ind_buf.bo,
225 context->ind_buf.bo_offset,
226 RADEON_GEM_DOMAIN_GTT, 0, 0);
227 END_BATCH();
228 COMMIT_BATCH();
229 }
230
231 static void evergreenRunRenderPrimitiveImmediate(struct gl_context * ctx, int start, int end, int prim) //same
232 {
233 context_t *context = EVERGREEN_CONTEXT(ctx);
234 BATCH_LOCALS(&context->radeon);
235 int type, i;
236 uint32_t num_indices, total_emit = 0;
237 uint32_t vgt_draw_initiator = 0;
238 uint32_t vgt_index_type = 0;
239 uint32_t vgt_primitive_type = 0;
240 uint32_t vgt_num_indices = 0;
241
242 type = evergreenPrimitiveType(prim);
243 num_indices = evergreenNumVerts(end - start, prim);
244
245 radeon_print(RADEON_RENDER, RADEON_TRACE,
246 "%s type %x num_indices %d\n",
247 __func__, type, num_indices);
248
249 if (type < 0 || num_indices <= 0)
250 return;
251
252 SETfield(vgt_primitive_type, type,
253 VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
254
255 if (num_indices > 0xffff)
256 {
257 SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
258 }
259 else
260 {
261 SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
262 }
263
264 /* 16-bit indexes are packed in a 32-bit value */
265 SETfield(vgt_index_type,
266 #if MESA_BIG_ENDIAN
267 VGT_DMA_SWAP_32_BIT,
268 #else
269 VGT_DMA_SWAP_NONE,
270 #endif
271 SWAP_MODE_shift, SWAP_MODE_mask);
272
273 vgt_num_indices = num_indices;
274 SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
275
276 if (start == 0)
277 {
278 SETfield(vgt_draw_initiator, DI_SRC_SEL_AUTO_INDEX, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
279 }
280 else
281 {
282 if (num_indices > 0xffff)
283 {
284 total_emit += num_indices;
285 }
286 else
287 {
288 total_emit += (num_indices + 1) / 2;
289 }
290 SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
291 }
292
293 total_emit += 3 /* VGT_PRIMITIVE_TYPE */
294 + 2 /* VGT_INDEX_TYPE */
295 + 2 /* NUM_INSTANCES */
296 + 4 /* VTX_BASE_VTX_LOC + VTX_START_INST_LOC */
297 + 3; /* DRAW */
298
299 BEGIN_BATCH_NO_AUTOSTATE(total_emit);
300 // prim
301 R600_OUT_BATCH_REGSEQ(VGT_PRIMITIVE_TYPE, 1);
302 R600_OUT_BATCH(vgt_primitive_type);
303 // index type
304 R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
305 R600_OUT_BATCH(vgt_index_type);
306 // num instances
307 R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
308 R600_OUT_BATCH(1);
309 /* offset */
310 R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 2));
311 R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
312 R600_OUT_BATCH(0); //VTX_BASE_VTX_LOC
313 R600_OUT_BATCH(0); //VTX_START_INST_LOC
314 // draw packet
315 if(start == 0)
316 {
317 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_AUTO, 1));
318 R600_OUT_BATCH(vgt_num_indices);
319 R600_OUT_BATCH(vgt_draw_initiator);
320 }
321 else
322 {
323 if (num_indices > 0xffff)
324 {
325 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
326 R600_OUT_BATCH(vgt_num_indices);
327 R600_OUT_BATCH(vgt_draw_initiator);
328 for (i = start; i < (start + num_indices); i++)
329 {
330 R600_OUT_BATCH(i);
331 }
332 }
333 else
334 {
335 R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (((num_indices + 1) / 2) + 1)));
336 R600_OUT_BATCH(vgt_num_indices);
337 R600_OUT_BATCH(vgt_draw_initiator);
338 for (i = start; i < (start + num_indices); i += 2)
339 {
340 if ((i + 1) == (start + num_indices))
341 {
342 R600_OUT_BATCH(i);
343 }
344 else
345 {
346 R600_OUT_BATCH(((i + 1) << 16) | (i));
347 }
348 }
349 }
350 }
351
352 END_BATCH();
353 COMMIT_BATCH();
354 }
355
356 #define CONVERT( TYPE, MACRO ) do { \
357 GLuint i, j, sz; \
358 sz = input->Size; \
359 if (input->Normalized) { \
360 for (i = 0; i < count; i++) { \
361 const TYPE *in = (TYPE *)src_ptr; \
362 for (j = 0; j < sz; j++) { \
363 *dst_ptr++ = MACRO(*in); \
364 in++; \
365 } \
366 src_ptr += stride; \
367 } \
368 } else { \
369 for (i = 0; i < count; i++) { \
370 const TYPE *in = (TYPE *)src_ptr; \
371 for (j = 0; j < sz; j++) { \
372 *dst_ptr++ = (GLfloat)(*in); \
373 in++; \
374 } \
375 src_ptr += stride; \
376 } \
377 } \
378 } while (0)
379
380 /**
381 * Convert attribute data type to float
382 * If the attribute uses named buffer object replace the bo with newly allocated bo
383 */
384 static void evergreenConvertAttrib(struct gl_context *ctx, int count,
385 const struct gl_client_array *input,
386 struct StreamDesc *attr)
387 {
388 context_t *context = R700_CONTEXT(ctx);
389 const GLvoid *src_ptr;
390 GLboolean mapped_named_bo = GL_FALSE;
391 GLfloat *dst_ptr;
392 GLuint stride;
393
394 stride = (input->StrideB == 0) ? evergreen_getTypeSize(input->Type) * input->Size : input->StrideB;
395
396 /* Convert value for first element only */
397 if (input->StrideB == 0)
398 {
399 count = 1;
400 }
401
402 if (input->BufferObj->Name)
403 {
404 if (!input->BufferObj->Pointer)
405 {
406 ctx->Driver.MapBufferRange(ctx, 0, input->BufferObj->Size,
407 GL_MAP_READ_BIT, input->BufferObj);
408 mapped_named_bo = GL_TRUE;
409 }
410
411 src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
412 }
413 else
414 {
415 src_ptr = input->Ptr;
416 }
417
418 radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset,
419 sizeof(GLfloat) * input->Size * count, 32);
420
421 radeon_bo_map(attr->bo, 1);
422
423 dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
424
425 assert(src_ptr != NULL);
426
427 switch (input->Type)
428 {
429 case GL_DOUBLE:
430 CONVERT(GLdouble, (GLfloat));
431 break;
432 case GL_UNSIGNED_INT:
433 CONVERT(GLuint, UINT_TO_FLOAT);
434 break;
435 case GL_INT:
436 CONVERT(GLint, INT_TO_FLOAT);
437 break;
438 case GL_UNSIGNED_SHORT:
439 CONVERT(GLushort, USHORT_TO_FLOAT);
440 break;
441 case GL_SHORT:
442 CONVERT(GLshort, SHORT_TO_FLOAT);
443 break;
444 case GL_UNSIGNED_BYTE:
445 assert(input->Format != GL_BGRA);
446 CONVERT(GLubyte, UBYTE_TO_FLOAT);
447 break;
448 case GL_BYTE:
449 CONVERT(GLbyte, BYTE_TO_FLOAT);
450 break;
451 default:
452 assert(0);
453 break;
454 }
455
456 radeon_bo_unmap(attr->bo);
457
458 if (mapped_named_bo)
459 {
460 ctx->Driver.UnmapBuffer(ctx, input->BufferObj);
461 }
462 }
463
464 static void evergreenFixupIndexBuffer(struct gl_context *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
465 {
466 context_t *context = EVERGREEN_CONTEXT(ctx);
467 GLvoid *src_ptr;
468 GLuint *out;
469 int i;
470 GLboolean mapped_named_bo = GL_FALSE;
471
472 if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
473 {
474 ctx->Driver.MapBufferRange(ctx, 0, mesa_ind_buf->obj->Size,
475 GL_MAP_READ_BIT, mesa_ind_buf->obj);
476 mapped_named_bo = GL_TRUE;
477 assert(mesa_ind_buf->obj->Pointer != NULL);
478 }
479 src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
480
481 if (mesa_ind_buf->type == GL_UNSIGNED_BYTE)
482 {
483 GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
484 GLubyte *in = (GLubyte *)src_ptr;
485
486 radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
487 &context->ind_buf.bo_offset, size, 4);
488
489 radeon_bo_map(context->ind_buf.bo, 1);
490 assert(context->ind_buf.bo->ptr != NULL);
491 out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
492
493 for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
494 {
495 *out++ = in[i] | in[i + 1] << 16;
496 }
497
498 if (i < mesa_ind_buf->count)
499 {
500 *out++ = in[i];
501 }
502
503 radeon_bo_unmap(context->ind_buf.bo);
504 #if MESA_BIG_ENDIAN
505 }
506 else
507 { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
508 GLushort *in = (GLushort *)src_ptr;
509 GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
510
511 radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
512 &context->ind_buf.bo_offset, size, 4);
513
514 radeon_bo_map(context->ind_buf.bo, 1);
515 assert(context->ind_buf.bo->ptr != NULL);
516 out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
517
518 for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
519 {
520 *out++ = in[i] | in[i + 1] << 16;
521 }
522
523 if (i < mesa_ind_buf->count)
524 {
525 *out++ = in[i];
526 }
527 radeon_bo_unmap(context->ind_buf.bo);
528 #endif
529 }
530
531 context->ind_buf.is_32bit = GL_FALSE;
532 context->ind_buf.count = mesa_ind_buf->count;
533
534 if (mapped_named_bo)
535 {
536 ctx->Driver.UnmapBuffer(ctx, mesa_ind_buf->obj);
537 }
538 }
539
540 static GLboolean evergreen_check_fallbacks(struct gl_context *ctx) //same
541 {
542 if (ctx->RenderMode != GL_RENDER)
543 return GL_TRUE;
544
545 return GL_FALSE;
546 }
547
548 /* start 3d, idle, cb/db flush */
549 #define PRE_EMIT_STATE_BUFSZ 5 + 5 + 14
550
551 static GLuint evergreenPredictRenderSize(struct gl_context* ctx,
552 const struct _mesa_prim *prim,
553 const struct _mesa_index_buffer *ib,
554 GLuint nr_prims)
555 {
556 context_t *context = EVERGREEN_CONTEXT(ctx);
557 GLboolean flushed;
558 GLuint dwords, i;
559 GLuint state_size;
560
561 dwords = PRE_EMIT_STATE_BUFSZ;
562 if (ib)
563 dwords += nr_prims * 18;
564 else {
565 for (i = 0; i < nr_prims; ++i)
566 {
567 if (prim[i].start == 0)
568 dwords += 14;
569 else if (prim[i].count > 0xffff)
570 dwords += prim[i].count + 14;
571 else
572 dwords += ((prim[i].count + 1) / 2) + 14;
573 }
574 }
575
576 state_size = radeonCountStateEmitSize(&context->radeon);
577 flushed = rcommonEnsureCmdBufSpace(&context->radeon,
578 dwords + state_size,
579 __FUNCTION__);
580 if (flushed)
581 dwords += radeonCountStateEmitSize(&context->radeon);
582 else
583 dwords += state_size;
584
585 radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s: total prediction size is %d.\n", __FUNCTION__, dwords);
586 return dwords;
587
588 }
589
590 static void evergreenSetupIndexBuffer(struct gl_context *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
591 {
592 context_t *context = EVERGREEN_CONTEXT(ctx);
593
594 if (!mesa_ind_buf) {
595 context->ind_buf.bo = NULL;
596 return;
597 }
598
599 #if MESA_BIG_ENDIAN
600 if (mesa_ind_buf->type == GL_UNSIGNED_INT)
601 #else
602 if (mesa_ind_buf->type != GL_UNSIGNED_BYTE)
603 #endif
604 {
605 const GLvoid *src_ptr;
606 GLvoid *dst_ptr;
607 GLboolean mapped_named_bo = GL_FALSE;
608
609 if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
610 {
611 ctx->Driver.MapBufferRange(ctx, 0, mesa_ind_buf->obj->Size,
612 GL_MAP_READ_BIT, mesa_ind_buf->obj);
613 assert(mesa_ind_buf->obj->Pointer != NULL);
614 mapped_named_bo = GL_TRUE;
615 }
616
617 src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
618
619 const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);
620
621 radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
622 &context->ind_buf.bo_offset, size, 4);
623 radeon_bo_map(context->ind_buf.bo, 1);
624 assert(context->ind_buf.bo->ptr != NULL);
625 dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
626
627 memcpy(dst_ptr, src_ptr, size);
628
629 radeon_bo_unmap(context->ind_buf.bo);
630 context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
631 context->ind_buf.count = mesa_ind_buf->count;
632
633 if (mapped_named_bo)
634 {
635 ctx->Driver.UnmapBuffer(ctx, mesa_ind_buf->obj);
636 }
637 }
638 else
639 {
640 evergreenFixupIndexBuffer(ctx, mesa_ind_buf);
641 }
642 }
643
644 #if 0 /* unused */
645 static void evergreenAlignDataToDword(struct gl_context *ctx,
646 const struct gl_client_array *input,
647 int count,
648 struct StreamDesc *attr)
649 {
650 context_t *context = EVERGREEN_CONTEXT(ctx);
651 const int dst_stride = (input->StrideB + 3) & ~3;
652 const int size = getTypeSize(input->Type) * input->Size * count;
653 GLboolean mapped_named_bo = GL_FALSE;
654
655 radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);
656
657 radeon_bo_map(attr->bo, 1);
658
659 if (!input->BufferObj->Pointer)
660 {
661 ctx->Driver.MapBufferRange(ctx, 0, input->BufferObj->Size,
662 GL_MAP_READ_BIT, input->BufferObj->obj);
663 mapped_named_bo = GL_TRUE;
664 }
665
666 {
667 GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
668 GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
669 int i;
670
671 for (i = 0; i < count; ++i)
672 {
673 memcpy(dst_ptr, src_ptr, input->StrideB);
674 src_ptr += input->StrideB;
675 dst_ptr += dst_stride;
676 }
677 }
678
679 radeon_bo_unmap(attr->bo);
680 if (mapped_named_bo)
681 {
682 ctx->Driver.UnmapBuffer(ctx, input->BufferObj);
683 }
684
685 attr->stride = dst_stride;
686 }
687 #endif
688
689 static void evergreenSetupStreams(struct gl_context *ctx, const struct gl_client_array *input[], int count)
690 {
691 context_t *context = EVERGREEN_CONTEXT(ctx);
692 GLuint stride;
693 int ret;
694 int i, index;
695
696 EVERGREEN_STATECHANGE(context, vtx);
697
698 for(index = 0; index < context->nNumActiveAos; index++)
699 {
700 struct radeon_aos *aos = &context->radeon.tcl.aos[index];
701 i = context->stream_desc[index].element;
702
703 stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB;
704
705 if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT
706 #if MESA_BIG_ENDIAN
707 || getTypeSize(input[i]->Type) != 4
708 #endif
709 )
710 {
711 evergreenConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
712 }
713 else
714 {
715 if (input[i]->BufferObj->Name)
716 {
717 context->stream_desc[index].stride = input[i]->StrideB;
718 context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
719 context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
720 context->stream_desc[index].is_named_bo = GL_TRUE;
721 }
722 else
723 {
724 int size;
725 int local_count = count;
726 uint32_t *dst;
727
728 if (input[i]->StrideB == 0)
729 {
730 size = getTypeSize(input[i]->Type) * input[i]->Size;
731 local_count = 1;
732 }
733 else
734 {
735 size = getTypeSize(input[i]->Type) * input[i]->Size * local_count;
736 }
737
738 radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo,
739 &context->stream_desc[index].bo_offset, size, 32);
740
741 radeon_bo_map(context->stream_desc[index].bo, 1);
742 assert(context->stream_desc[index].bo->ptr != NULL);
743
744
745 dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr,
746 context->stream_desc[index].bo_offset);
747
748 switch (context->stream_desc[index].dwords)
749 {
750 case 1:
751 radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);
752 break;
753 case 2:
754 radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count);
755 break;
756 case 3:
757 radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count);
758 break;
759 case 4:
760 radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count);
761 break;
762 default:
763 assert(0);
764 break;
765 }
766
767 radeon_bo_unmap(context->stream_desc[index].bo);
768 }
769 }
770
771 aos->count = context->stream_desc[index].stride == 0 ? 1 : count;
772 aos->stride = context->stream_desc[index].stride / sizeof(float);
773 aos->components = context->stream_desc[index].dwords;
774 aos->bo = context->stream_desc[index].bo;
775 aos->offset = context->stream_desc[index].bo_offset;
776
777 if(context->stream_desc[index].is_named_bo)
778 {
779 radeon_cs_space_add_persistent_bo(context->radeon.cmdbuf.cs,
780 context->stream_desc[index].bo,
781 RADEON_GEM_DOMAIN_GTT, 0);
782 }
783 }
784
785 ret = radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs,
786 first_elem(&context->radeon.dma.reserved)->bo,
787 RADEON_GEM_DOMAIN_GTT, 0);
788 }
789
790 static void evergreenFreeData(struct gl_context *ctx)
791 {
792 /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
793 * to prevent double unref in radeonReleaseArrays
794 * called during context destroy
795 */
796 context_t *context = EVERGREEN_CONTEXT(ctx);
797
798 int i;
799
800 for (i = 0; i < context->nNumActiveAos; i++)
801 {
802 if (!context->stream_desc[i].is_named_bo)
803 {
804 radeon_bo_unref(context->stream_desc[i].bo);
805 }
806 context->radeon.tcl.aos[i].bo = NULL;
807 }
808
809 if(context->vp_Constbo != NULL)
810 {
811 radeon_bo_unref(context->vp_Constbo);
812 context->vp_Constbo = NULL;
813 }
814 if(context->fp_Constbo != NULL)
815 {
816 radeon_bo_unref(context->fp_Constbo);
817 context->fp_Constbo = NULL;
818 }
819
820 if (context->ind_buf.bo != NULL)
821 {
822 radeon_bo_unref(context->ind_buf.bo);
823 }
824 }
825
826 static GLboolean evergreenTryDrawPrims(struct gl_context *ctx,
827 const struct gl_client_array *arrays[],
828 const struct _mesa_prim *prim,
829 GLuint nr_prims,
830 const struct _mesa_index_buffer *ib,
831 GLuint min_index,
832 GLuint max_index )
833 {
834 context_t *context = EVERGREEN_CONTEXT(ctx);
835 radeonContextPtr radeon = &context->radeon;
836 GLuint i, id = 0;
837 struct radeon_renderbuffer *rrb;
838
839 if (ctx->NewState)
840 _mesa_update_state( ctx );
841
842 if (evergreen_check_fallbacks(ctx))
843 return GL_FALSE;
844
845 _tnl_UpdateFixedFunctionProgram(ctx);
846 evergreenSetVertexFormat(ctx, arrays, max_index + 1);
847
848
849 /* shaders need to be updated before buffers are validated */
850 evergreenUpdateShaders(ctx);
851 if (!evergreenValidateBuffers(ctx))
852 return GL_FALSE;
853
854 /* always emit CB base to prevent
855 * lock ups on some chips.
856 */
857 EVERGREEN_STATECHANGE(context, cb);
858 /* mark vtx as dirty since it changes per-draw */
859 EVERGREEN_STATECHANGE(context, vtx);
860
861 evergreenSetScissor(context);
862
863 evergreenSetupVertexProgram(ctx);
864 evergreenSetupFragmentProgram(ctx);
865 evergreenUpdateShaderStates(ctx);
866
867 GLuint emit_end = evergreenPredictRenderSize(ctx, prim, ib, nr_prims)
868 + context->radeon.cmdbuf.cs->cdw;
869
870 /* evergreenPredictRenderSize will call radeonReleaseDmaRegions, so update VP/FP const buf after it. */
871 evergreenSetupVPconstants(ctx);
872 evergreenSetupFPconstants(ctx);
873
874 evergreenSetupIndexBuffer(ctx, ib);
875
876 evergreenSetupStreams(ctx, arrays, max_index + 1);
877
878 radeonEmitState(radeon);
879
880 radeon_debug_add_indent();
881
882 for (i = 0; i < nr_prims; ++i)
883 {
884 if (context->ind_buf.bo)
885 evergreenRunRenderPrimitive(ctx,
886 prim[i].start,
887 prim[i].start + prim[i].count,
888 prim[i].mode,
889 prim[i].basevertex);
890 else
891 evergreenRunRenderPrimitiveImmediate(ctx,
892 prim[i].start,
893 prim[i].start + prim[i].count,
894 prim[i].mode);
895 }
896
897 radeon_debug_remove_indent();
898
899 /* Flush render op cached for last several quads. */
900 /* XXX drm should handle this in fence submit */
901
902 //evergreeWaitForIdleClean(context);
903
904 rrb = radeon_get_colorbuffer(&context->radeon);
905 if (rrb && rrb->bo)
906 r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
907 CB_ACTION_ENA_bit | (1 << (id + 6)));
908
909 rrb = radeon_get_depthbuffer(&context->radeon);
910 if (rrb && rrb->bo)
911 r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
912 DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
913
914 evergreenFreeData(ctx);
915
916 if (emit_end < context->radeon.cmdbuf.cs->cdw)
917 {
918 WARN_ONCE("Rendering was %d commands larger than predicted size."
919 " We might overflow command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end);
920 }
921
922 return GL_TRUE;
923 }
924
925 static void evergreenDrawPrims(struct gl_context *ctx,
926 const struct gl_client_array *arrays[],
927 const struct _mesa_prim *prim,
928 GLuint nr_prims,
929 const struct _mesa_index_buffer *ib,
930 GLboolean index_bounds_valid,
931 GLuint min_index,
932 GLuint max_index)
933 {
934 GLboolean retval = GL_FALSE;
935
936 context_t *context = EVERGREEN_CONTEXT(ctx);
937 radeonContextPtr radeon = &context->radeon;
938 radeon_prepare_render(radeon);
939
940 /* This check should get folded into just the places that
941 * min/max index are really needed.
942 */
943 if (!vbo_all_varyings_in_vbos(arrays)) {
944 if (!index_bounds_valid)
945 vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
946 /* do we want to rebase, minimizes the
947 * amount of data to upload? */
948 if (min_index) {
949 vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, evergreenDrawPrims );
950 return;
951 }
952 }
953 /* Make an attempt at drawing */
954 retval = evergreenTryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
955
956 /* If failed run tnl pipeline - it should take care of fallbacks */
957 if (!retval) {
958 _swsetup_Wakeup(ctx);
959 _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
960 }
961 }
962
963 void evergreenInitDraw(struct gl_context *ctx)
964 {
965 struct vbo_context *vbo = vbo_context(ctx);
966
967 /* to be enabled */
968 vbo->draw_prims = evergreenDrawPrims;
969 }
970
971