1 /**************************************************************************
3 * Copyright 2009 Maciej Cencora
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHOR(S) AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 **************************************************************************/
29 #include "main/glheader.h"
30 #include "main/context.h"
31 #include "main/state.h"
32 #include "main/enums.h"
33 #include "main/simple_list.h"
36 #include "r300_context.h"
37 #include "r300_emit.h"
38 #include "r300_render.h"
39 #include "r300_state.h"
41 #include "r300_cmdbuf.h"
43 #include "radeon_buffer_objects.h"
44 #include "radeon_common_context.h"
47 #include "tnl/t_vp_build.h"
48 #include "vbo/vbo_context.h"
51 static int getTypeSize(GLenum type
)
55 return sizeof(GLdouble
);
57 return sizeof(GLhalfARB
);
59 return sizeof(GLfloat
);
63 return sizeof(GLuint
);
65 return sizeof(GLshort
);
66 case GL_UNSIGNED_SHORT
:
67 return sizeof(GLushort
);
69 return sizeof(GLbyte
);
70 case GL_UNSIGNED_BYTE
:
71 return sizeof(GLubyte
);
78 static void r300FixupIndexBuffer(struct gl_context
*ctx
, const struct _mesa_index_buffer
*mesa_ind_buf
)
80 r300ContextPtr r300
= R300_CONTEXT(ctx
);
84 GLboolean mapped_named_bo
= GL_FALSE
;
86 if (mesa_ind_buf
->obj
->Name
&& !mesa_ind_buf
->obj
->Pointer
) {
87 ctx
->Driver
.MapBufferRange(ctx
, 0, mesa_ind_buf
->obj
->Size
,
88 GL_MAP_READ_BIT
, mesa_ind_buf
->obj
);
89 mapped_named_bo
= GL_TRUE
;
90 assert(mesa_ind_buf
->obj
->Pointer
!= NULL
);
92 src_ptr
= ADD_POINTERS(mesa_ind_buf
->obj
->Pointer
, mesa_ind_buf
->ptr
);
94 radeon_print(RADEON_FALLBACKS
, RADEON_IMPORTANT
,
95 "%s: Fixing index buffer format. type %d\n",
96 __func__
, mesa_ind_buf
->type
);
98 if (mesa_ind_buf
->type
== GL_UNSIGNED_BYTE
) {
99 GLuint size
= sizeof(GLushort
) * ((mesa_ind_buf
->count
+ 1) & ~1);
100 GLubyte
*in
= (GLubyte
*)src_ptr
;
102 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
, &r300
->ind_buf
.bo_offset
, size
, 4);
103 radeon_bo_map(r300
->ind_buf
.bo
, 1);
104 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
105 out
= (GLuint
*)ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
107 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
108 *out
++ = in
[i
] | in
[i
+ 1] << 16;
111 if (i
< mesa_ind_buf
->count
) {
114 radeon_bo_unmap(r300
->ind_buf
.bo
);
116 } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
117 GLushort
*in
= (GLushort
*)src_ptr
;
118 GLuint size
= sizeof(GLushort
) * ((mesa_ind_buf
->count
+ 1) & ~1);
120 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
,
121 &r300
->ind_buf
.bo_offset
, size
, 4);
123 radeon_bo_map(r300
->ind_buf
.bo
, 1);
124 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
125 out
= (GLuint
*)ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
127 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
128 *out
++ = in
[i
] | in
[i
+ 1] << 16;
131 if (i
< mesa_ind_buf
->count
) {
134 radeon_bo_unmap(r300
->ind_buf
.bo
);
138 r300
->ind_buf
.is_32bit
= GL_FALSE
;
139 r300
->ind_buf
.count
= mesa_ind_buf
->count
;
141 if (mapped_named_bo
) {
142 ctx
->Driver
.UnmapBuffer(ctx
, mesa_ind_buf
->obj
);
147 static void r300SetupIndexBuffer(struct gl_context
*ctx
, const struct _mesa_index_buffer
*mesa_ind_buf
)
149 r300ContextPtr r300
= R300_CONTEXT(ctx
);
152 r300
->ind_buf
.bo
= NULL
;
155 radeon_print(RADEON_RENDER
, RADEON_TRACE
, "%s\n", __func__
);
158 if (mesa_ind_buf
->type
== GL_UNSIGNED_INT
) {
160 if (mesa_ind_buf
->type
!= GL_UNSIGNED_BYTE
) {
162 const GLvoid
*src_ptr
;
164 GLboolean mapped_named_bo
= GL_FALSE
;
166 if (mesa_ind_buf
->obj
->Name
&& !mesa_ind_buf
->obj
->Pointer
) {
167 ctx
->Driver
.MapBufferRange(ctx
, 0,
168 mesa_ind_buf
->obj
->Size
,
171 assert(mesa_ind_buf
->obj
->Pointer
!= NULL
);
172 mapped_named_bo
= GL_TRUE
;
175 src_ptr
= ADD_POINTERS(mesa_ind_buf
->obj
->Pointer
, mesa_ind_buf
->ptr
);
177 const GLuint size
= mesa_ind_buf
->count
* getTypeSize(mesa_ind_buf
->type
);
179 radeonAllocDmaRegion(&r300
->radeon
, &r300
->ind_buf
.bo
, &r300
->ind_buf
.bo_offset
, size
, 4);
181 radeon_bo_map(r300
->ind_buf
.bo
, 1);
182 assert(r300
->ind_buf
.bo
->ptr
!= NULL
);
183 dst_ptr
= ADD_POINTERS(r300
->ind_buf
.bo
->ptr
, r300
->ind_buf
.bo_offset
);
184 memcpy(dst_ptr
, src_ptr
, size
);
186 radeon_bo_unmap(r300
->ind_buf
.bo
);
187 r300
->ind_buf
.is_32bit
= (mesa_ind_buf
->type
== GL_UNSIGNED_INT
);
188 r300
->ind_buf
.count
= mesa_ind_buf
->count
;
190 if (mapped_named_bo
) {
191 ctx
->Driver
.UnmapBuffer(ctx
, mesa_ind_buf
->obj
);
194 r300FixupIndexBuffer(ctx
, mesa_ind_buf
);
198 #define CONVERT( TYPE, MACRO ) do { \
201 if (input->Normalized) { \
202 for (i = 0; i < count; i++) { \
203 const TYPE *in = (TYPE *)src_ptr; \
204 for (j = 0; j < sz; j++) { \
205 *dst_ptr++ = MACRO(*in); \
211 for (i = 0; i < count; i++) { \
212 const TYPE *in = (TYPE *)src_ptr; \
213 for (j = 0; j < sz; j++) { \
214 *dst_ptr++ = (GLfloat)(*in); \
223 * Convert attribute data type to float
224 * If the attribute uses named buffer object replace the bo with newly allocated bo
226 static void r300ConvertAttrib(struct gl_context
*ctx
, int count
, const struct gl_client_array
*input
, struct vertex_attribute
*attr
)
228 r300ContextPtr r300
= R300_CONTEXT(ctx
);
229 const GLvoid
*src_ptr
;
230 GLboolean mapped_named_bo
= GL_FALSE
;
234 stride
= (input
->StrideB
== 0) ? getTypeSize(input
->Type
) * input
->Size
: input
->StrideB
;
236 /* Convert value for first element only */
237 if (input
->StrideB
== 0)
240 if (input
->BufferObj
->Name
) {
241 if (!input
->BufferObj
->Pointer
) {
242 ctx
->Driver
.MapBufferRange(ctx
, 0, input
->BufferObj
->Size
,
243 GL_MAP_READ_BIT
, input
->BufferObj
);
244 mapped_named_bo
= GL_TRUE
;
247 src_ptr
= ADD_POINTERS(input
->BufferObj
->Pointer
, input
->Ptr
);
249 src_ptr
= input
->Ptr
;
252 radeonAllocDmaRegion(&r300
->radeon
, &attr
->bo
, &attr
->bo_offset
, sizeof(GLfloat
) * input
->Size
* count
, 32);
253 radeon_bo_map(attr
->bo
, 1);
254 dst_ptr
= (GLfloat
*)ADD_POINTERS(attr
->bo
->ptr
, attr
->bo_offset
);
256 radeon_print(RADEON_FALLBACKS
, RADEON_IMPORTANT
,
257 "%s: Converting vertex attributes, attribute data format %x,"
258 "stride %d, components %d\n"
259 , __FUNCTION__
, input
->Type
260 , stride
, input
->Size
);
262 assert(src_ptr
!= NULL
);
264 switch (input
->Type
) {
266 CONVERT(GLdouble
, (GLfloat
));
268 case GL_UNSIGNED_INT
:
269 CONVERT(GLuint
, UINT_TO_FLOAT
);
272 CONVERT(GLint
, INT_TO_FLOAT
);
274 case GL_UNSIGNED_SHORT
:
275 CONVERT(GLushort
, USHORT_TO_FLOAT
);
278 CONVERT(GLshort
, SHORT_TO_FLOAT
);
280 case GL_UNSIGNED_BYTE
:
281 assert(input
->Format
!= GL_BGRA
);
282 CONVERT(GLubyte
, UBYTE_TO_FLOAT
);
285 CONVERT(GLbyte
, BYTE_TO_FLOAT
);
292 radeon_bo_unmap(attr
->bo
);
293 if (mapped_named_bo
) {
294 ctx
->Driver
.UnmapBuffer(ctx
, input
->BufferObj
);
298 static void r300AlignDataToDword(struct gl_context
*ctx
, const struct gl_client_array
*input
, int count
, struct vertex_attribute
*attr
)
300 r300ContextPtr r300
= R300_CONTEXT(ctx
);
301 const int dst_stride
= (input
->StrideB
+ 3) & ~3;
302 const int size
= getTypeSize(input
->Type
) * input
->Size
* count
;
303 GLboolean mapped_named_bo
= GL_FALSE
;
305 radeonAllocDmaRegion(&r300
->radeon
, &attr
->bo
, &attr
->bo_offset
, size
, 32);
307 radeon_bo_map(attr
->bo
, 1);
309 if (!input
->BufferObj
->Pointer
) {
310 ctx
->Driver
.MapBufferRange(ctx
, 0, input
->BufferObj
->Size
,
311 GL_MAP_READ_BIT
, input
->BufferObj
);
312 mapped_named_bo
= GL_TRUE
;
315 radeon_print(RADEON_FALLBACKS
, RADEON_IMPORTANT
, "%s. Vertex alignment doesn't match hw requirements.\n", __func__
);
318 GLvoid
*src_ptr
= ADD_POINTERS(input
->BufferObj
->Pointer
, input
->Ptr
);
319 GLvoid
*dst_ptr
= ADD_POINTERS(attr
->bo
->ptr
, attr
->bo_offset
);
322 for (i
= 0; i
< count
; ++i
) {
323 memcpy(dst_ptr
, src_ptr
, input
->StrideB
);
324 src_ptr
+= input
->StrideB
;
325 dst_ptr
+= dst_stride
;
329 if (mapped_named_bo
) {
330 ctx
->Driver
.UnmapBuffer(ctx
, input
->BufferObj
);
333 radeon_bo_unmap(attr
->bo
);
334 attr
->stride
= dst_stride
;
337 static void r300TranslateAttrib(struct gl_context
*ctx
, GLuint attr
, int count
, const struct gl_client_array
*input
)
339 r300ContextPtr r300
= R300_CONTEXT(ctx
);
340 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
341 struct vertex_attribute r300_attr
= { 0 };
345 radeon_print(RADEON_RENDER
, RADEON_TRACE
, "%s\n", __func__
);
346 stride
= (input
->StrideB
== 0) ? getTypeSize(input
->Type
) * input
->Size
: input
->StrideB
;
348 if (input
->Type
== GL_DOUBLE
|| input
->Type
== GL_UNSIGNED_INT
|| input
->Type
== GL_INT
||
350 getTypeSize(input
->Type
) != 4 ||
356 if (input
->StrideB
== 0) {
357 r300_attr
.stride
= 0;
359 r300_attr
.stride
= sizeof(GLfloat
) * input
->Size
;
361 r300_attr
.dwords
= input
->Size
;
362 r300_attr
.is_named_bo
= GL_FALSE
;
365 r300_attr
.dwords
= (getTypeSize(type
) * input
->Size
+ 3)/ 4;
366 if (!input
->BufferObj
->Name
) {
368 if (input
->StrideB
== 0) {
369 r300_attr
.stride
= 0;
371 r300_attr
.stride
= (getTypeSize(type
) * input
->Size
+ 3) & ~3;
374 r300_attr
.is_named_bo
= GL_FALSE
;
378 r300_attr
.size
= input
->Size
;
379 r300_attr
.element
= attr
;
380 r300_attr
.dst_loc
= vbuf
->num_attribs
;
384 switch (input
->Size
) {
385 case 1: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_1
; break;
386 case 2: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_2
; break;
387 case 3: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_3
; break;
388 case 4: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_4
; break;
390 r300_attr
._signed
= 0;
391 r300_attr
.normalize
= 0;
394 switch (input
->Size
) {
397 r300_attr
.data_type
= R300_DATA_TYPE_FLT16_2
;
401 r300_attr
.data_type
= R300_DATA_TYPE_FLT16_4
;
406 r300_attr
._signed
= 1;
407 r300_attr
.normalize
= input
->Normalized
;
408 switch (input
->Size
) {
411 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
415 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
420 r300_attr
._signed
= 1;
421 r300_attr
.normalize
= input
->Normalized
;
422 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
424 case GL_UNSIGNED_SHORT
:
425 r300_attr
._signed
= 0;
426 r300_attr
.normalize
= input
->Normalized
;
427 switch (input
->Size
) {
430 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
434 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
438 case GL_UNSIGNED_BYTE
:
439 r300_attr
._signed
= 0;
440 r300_attr
.normalize
= input
->Normalized
;
441 if (input
->Format
== GL_BGRA
)
442 r300_attr
.data_type
= R300_DATA_TYPE_D3DCOLOR
;
444 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
450 case GL_UNSIGNED_INT
:
455 switch (input
->Size
) {
457 r300_attr
.swizzle
= SWIZZLE_XYZW
;
460 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
463 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
466 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
470 r300_attr
.write_mask
= MASK_XYZW
;
472 vbuf
->attribs
[vbuf
->num_attribs
] = r300_attr
;
476 static void r300SetVertexFormat(struct gl_context
*ctx
, const struct gl_client_array
*arrays
[], int count
)
478 r300ContextPtr r300
= R300_CONTEXT(ctx
);
479 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
480 radeon_print(RADEON_RENDER
, RADEON_VERBOSE
, "%s\n", __func__
);
484 tmp
= r300
->selected_vp
->code
.InputsRead
;
486 vbuf
->num_attribs
= 0;
488 /* find first enabled bit */
494 r300TranslateAttrib(ctx
, i
, count
, arrays
[i
]);
501 r300SwitchFallback(ctx
, R300_FALLBACK_AOS_LIMIT
, vbuf
->num_attribs
> R300_MAX_AOS_ARRAYS
);
506 static void r300AllocDmaRegions(struct gl_context
*ctx
, const struct gl_client_array
*input
[], int count
)
508 r300ContextPtr r300
= R300_CONTEXT(ctx
);
509 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
513 radeon_print(RADEON_RENDER
, RADEON_VERBOSE
,
514 "%s: count %d num_attribs %d\n",
515 __func__
, count
, vbuf
->num_attribs
);
517 for (index
= 0; index
< vbuf
->num_attribs
; index
++) {
518 struct radeon_aos
*aos
= &r300
->radeon
.tcl
.aos
[index
];
519 i
= vbuf
->attribs
[index
].element
;
521 stride
= (input
[i
]->StrideB
== 0) ? getTypeSize(input
[i
]->Type
) * input
[i
]->Size
: input
[i
]->StrideB
;
523 if (input
[i
]->Type
== GL_DOUBLE
|| input
[i
]->Type
== GL_UNSIGNED_INT
|| input
[i
]->Type
== GL_INT
||
525 getTypeSize(input
[i
]->Type
) != 4 ||
529 r300ConvertAttrib(ctx
, count
, input
[i
], &vbuf
->attribs
[index
]);
531 if (input
[i
]->BufferObj
->Name
) {
532 if (stride
% 4 != 0 || (intptr_t)input
[i
]->Ptr
% 4 != 0) {
533 r300AlignDataToDword(ctx
, input
[i
], count
, &vbuf
->attribs
[index
]);
534 vbuf
->attribs
[index
].is_named_bo
= GL_FALSE
;
536 vbuf
->attribs
[index
].stride
= input
[i
]->StrideB
;
537 vbuf
->attribs
[index
].bo_offset
= (intptr_t) input
[i
]->Ptr
;
538 vbuf
->attribs
[index
].bo
= get_radeon_buffer_object(input
[i
]->BufferObj
)->bo
;
539 vbuf
->attribs
[index
].is_named_bo
= GL_TRUE
;
544 int local_count
= count
;
547 if (input
[i
]->StrideB
== 0) {
548 size
= getTypeSize(input
[i
]->Type
) * input
[i
]->Size
;
551 size
= getTypeSize(input
[i
]->Type
) * input
[i
]->Size
* local_count
;
554 radeonAllocDmaRegion(&r300
->radeon
, &vbuf
->attribs
[index
].bo
, &vbuf
->attribs
[index
].bo_offset
, size
, 32);
555 radeon_bo_map(vbuf
->attribs
[index
].bo
, 1);
556 assert(vbuf
->attribs
[index
].bo
->ptr
!= NULL
);
557 dst
= (uint32_t *)ADD_POINTERS(vbuf
->attribs
[index
].bo
->ptr
, vbuf
->attribs
[index
].bo_offset
);
558 switch (vbuf
->attribs
[index
].dwords
) {
559 case 1: radeonEmitVec4(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
560 case 2: radeonEmitVec8(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
561 case 3: radeonEmitVec12(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
562 case 4: radeonEmitVec16(dst
, input
[i
]->Ptr
, input
[i
]->StrideB
, local_count
); break;
563 default: assert(0); break;
565 radeon_bo_unmap(vbuf
->attribs
[index
].bo
);
570 aos
->count
= vbuf
->attribs
[index
].stride
== 0 ? 1 : count
;
571 aos
->stride
= vbuf
->attribs
[index
].stride
/ sizeof(float);
572 aos
->components
= vbuf
->attribs
[index
].dwords
;
573 aos
->bo
= vbuf
->attribs
[index
].bo
;
574 aos
->offset
= vbuf
->attribs
[index
].bo_offset
;
576 if (vbuf
->attribs
[index
].is_named_bo
) {
577 radeon_cs_space_add_persistent_bo(r300
->radeon
.cmdbuf
.cs
, r300
->vbuf
.attribs
[index
].bo
, RADEON_GEM_DOMAIN_GTT
, 0);
581 r300
->radeon
.tcl
.aos_count
= vbuf
->num_attribs
;
582 ret
= radeon_cs_space_check_with_bo(r300
->radeon
.cmdbuf
.cs
, first_elem(&r300
->radeon
.dma
.reserved
)->bo
, RADEON_GEM_DOMAIN_GTT
, 0);
583 r300SwitchFallback(ctx
, R300_FALLBACK_INVALID_BUFFERS
, ret
);
587 static void r300FreeData(struct gl_context
*ctx
)
589 /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
590 * to prevent double unref in radeonReleaseArrays
591 * called during context destroy
593 radeon_print(RADEON_RENDER
, RADEON_VERBOSE
, "%s\n", __func__
);
594 r300ContextPtr r300
= R300_CONTEXT(ctx
);
598 for (i
= 0; i
< r300
->vbuf
.num_attribs
; i
++) {
599 if (!r300
->vbuf
.attribs
[i
].is_named_bo
) {
600 radeon_bo_unref(r300
->vbuf
.attribs
[i
].bo
);
602 r300
->radeon
.tcl
.aos
[i
].bo
= NULL
;
607 if (r300
->ind_buf
.bo
!= NULL
) {
608 radeon_bo_unref(r300
->ind_buf
.bo
);
613 static GLuint
r300PredictTryDrawPrimsSize(struct gl_context
*ctx
,
614 GLuint nr_prims
, const struct _mesa_prim
*prim
)
616 struct r300_context
*r300
= R300_CONTEXT(ctx
);
617 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
622 GLuint extra_prims
= 0;
624 /* Check for primitive splitting. */
625 for (i
= 0; i
< nr_prims
; ++i
) {
626 const GLuint num_verts
= r300NumVerts(r300
, prim
[i
].count
, prim
[i
].mode
);
627 extra_prims
+= num_verts
/(65535 - 32);
629 nr_prims
+= extra_prims
;
631 dwords
= 2*CACHE_FLUSH_BUFSZ
;
632 dwords
+= PRE_EMIT_STATE_BUFSZ
;
633 dwords
+= (AOS_BUFSZ(vbuf
->num_attribs
)
635 + FIREAOS_BUFSZ
)*nr_prims
;
637 state_size
= radeonCountStateEmitSize(&r300
->radeon
);
638 flushed
= rcommonEnsureCmdBufSpace(&r300
->radeon
,
642 dwords
+= radeonCountStateEmitSize(&r300
->radeon
);
644 dwords
+= state_size
;
646 radeon_print(RADEON_RENDER
, RADEON_VERBOSE
, "%s: total prediction size is %d.\n", __FUNCTION__
, dwords
);
650 static GLboolean
r300TryDrawPrims(struct gl_context
*ctx
,
651 const struct gl_client_array
*arrays
[],
652 const struct _mesa_prim
*prim
,
654 const struct _mesa_index_buffer
*ib
,
658 struct r300_context
*r300
= R300_CONTEXT(ctx
);
661 radeon_print(RADEON_RENDER
, RADEON_NORMAL
, "%s: %u (%d-%d) cs begin at %d\n",
662 __FUNCTION__
, nr_prims
, min_index
, max_index
, r300
->radeon
.cmdbuf
.cs
->cdw
);
665 _mesa_update_state( ctx
);
667 if (r300
->options
.hw_tcl_enabled
)
668 _tnl_UpdateFixedFunctionProgram(ctx
);
670 r300UpdateShaders(r300
);
672 r300SwitchFallback(ctx
, R300_FALLBACK_INVALID_BUFFERS
, !r300ValidateBuffers(ctx
));
674 r300SetVertexFormat(ctx
, arrays
, max_index
+ 1);
679 r300SetupVAP(ctx
, r300
->selected_vp
->code
.InputsRead
, r300
->selected_vp
->code
.OutputsWritten
);
681 r300UpdateShaderStates(r300
);
683 /* ensure we have the cmd buf space in advance to cover
684 * the state + DMA AOS pointers */
685 GLuint emit_end
= r300PredictTryDrawPrimsSize(ctx
, nr_prims
, prim
)
686 + r300
->radeon
.cmdbuf
.cs
->cdw
;
688 r300SetupIndexBuffer(ctx
, ib
);
690 r300AllocDmaRegions(ctx
, arrays
, max_index
+ 1);
695 r300EmitCacheFlush(r300
);
696 radeonEmitState(&r300
->radeon
);
698 for (i
= 0; i
< nr_prims
; ++i
) {
699 r300RunRenderPrimitive(ctx
, prim
[i
].start
, prim
[i
].start
+ prim
[i
].count
, prim
[i
].mode
);
702 r300EmitCacheFlush(r300
);
706 radeon_print(RADEON_RENDER
, RADEON_VERBOSE
, "%s: %u (%d-%d) cs ending at %d\n",
707 __FUNCTION__
, nr_prims
, min_index
, max_index
, r300
->radeon
.cmdbuf
.cs
->cdw
);
709 if (emit_end
< r300
->radeon
.cmdbuf
.cs
->cdw
)
710 WARN_ONCE("Rendering was %d commands larger than predicted size."
711 " We might overflow command buffer.\n", r300
->radeon
.cmdbuf
.cs
->cdw
- emit_end
);
716 static void r300DrawPrims(struct gl_context
*ctx
,
717 const struct gl_client_array
*arrays
[],
718 const struct _mesa_prim
*prim
,
720 const struct _mesa_index_buffer
*ib
,
721 GLboolean index_bounds_valid
,
726 struct r300_context
*r300
= R300_CONTEXT(ctx
);
727 radeonContextPtr radeon
= &r300
->radeon
;
729 radeon_prepare_render(radeon
);
731 /* This check should get folded into just the places that
732 * min/max index are really needed.
734 if (!index_bounds_valid
) {
735 vbo_get_minmax_index(ctx
, prim
, ib
, &min_index
, &max_index
);
739 radeon_print(RADEON_FALLBACKS
, RADEON_IMPORTANT
,
740 "%s: Rebasing primitives. %p nr_prims %d min_index %u max_index %u\n",
741 __func__
, prim
, nr_prims
, min_index
, max_index
);
742 vbo_rebase_prims( ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
, r300DrawPrims
);
746 /* Make an attempt at drawing */
747 retval
= r300TryDrawPrims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
749 /* If failed run tnl pipeline - it should take care of fallbacks */
751 _tnl_draw_prims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
754 void r300InitDraw(struct gl_context
*ctx
)
756 struct vbo_context
*vbo
= vbo_context(ctx
);
758 vbo
->draw_prims
= r300DrawPrims
;