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/api_validate.h"
33 #include "main/enums.h"
36 #include "r300_context.h"
37 #include "r300_emit.h"
38 #include "r300_render.h"
39 #include "r300_state.h"
43 #include "tnl/t_vp_build.h"
44 #include "vbo/vbo_context.h"
45 #include "swrast/swrast.h"
46 #include "swrast_setup/swrast_setup.h"
48 static void r300FixupIndexBuffer(GLcontext
*ctx
, const struct _mesa_index_buffer
*mesa_ind_buf
, struct gl_buffer_object
**bo
, GLuint
*nr_bo
)
50 r300ContextPtr r300
= R300_CONTEXT(ctx
);
51 struct r300_index_buffer
*ind_buf
= &r300
->ind_buf
;
59 ind_buf
->count
= mesa_ind_buf
->count
;
60 if (mesa_ind_buf
->obj
->Name
&& !mesa_ind_buf
->obj
->Pointer
) {
61 bo
[*nr_bo
] = mesa_ind_buf
->obj
;
63 ctx
->Driver
.MapBuffer(ctx
, GL_ELEMENT_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, mesa_ind_buf
->obj
);
64 assert(mesa_ind_buf
->obj
->Pointer
!= NULL
);
66 src_ptr
= ADD_POINTERS(mesa_ind_buf
->obj
->Pointer
, mesa_ind_buf
->ptr
);
68 if (mesa_ind_buf
->type
== GL_UNSIGNED_BYTE
) {
69 GLubyte
*in
= (GLubyte
*)src_ptr
;
70 GLuint
*out
= _mesa_malloc(sizeof(GLushort
) * ((mesa_ind_buf
->count
+ 1) & ~1));
75 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
76 *out
++ = in
[i
] | in
[i
+ 1] << 16;
79 if (i
< mesa_ind_buf
->count
) {
83 ind_buf
->free_needed
= GL_TRUE
;
84 ind_buf
->is_32bit
= GL_FALSE
;
85 } else if (mesa_ind_buf
->type
== GL_UNSIGNED_SHORT
) {
87 GLushort
*in
= (GLushort
*)src_ptr
;
88 GLuint
*out
= _mesa_malloc(sizeof(GLushort
) *
89 ((mesa_ind_buf
->count
+ 1) & ~1));
94 for (i
= 0; i
+ 1 < mesa_ind_buf
->count
; i
+= 2) {
95 *out
++ = in
[i
] | in
[i
+ 1] << 16;
98 if (i
< mesa_ind_buf
->count
) {
102 ind_buf
->free_needed
= GL_TRUE
;
104 ind_buf
->ptr
= src_ptr
;
105 ind_buf
->free_needed
= GL_FALSE
;
107 ind_buf
->is_32bit
= GL_FALSE
;
109 ind_buf
->ptr
= src_ptr
;
110 ind_buf
->free_needed
= GL_FALSE
;
111 ind_buf
->is_32bit
= GL_TRUE
;
115 static int getTypeSize(GLenum type
)
119 return sizeof(GLdouble
);
121 return sizeof(GLfloat
);
123 return sizeof(GLint
);
124 case GL_UNSIGNED_INT
:
125 return sizeof(GLuint
);
127 return sizeof(GLshort
);
128 case GL_UNSIGNED_SHORT
:
129 return sizeof(GLushort
);
131 return sizeof(GLbyte
);
132 case GL_UNSIGNED_BYTE
:
133 return sizeof(GLubyte
);
140 #define CONVERT( TYPE, MACRO ) do { \
143 if (input->Normalized) { \
144 for (i = 0; i < count; i++) { \
145 const TYPE *in = (TYPE *)src_ptr; \
146 for (j = 0; j < sz; j++) { \
147 *dst_ptr++ = MACRO(*in); \
153 for (i = 0; i < count; i++) { \
154 const TYPE *in = (TYPE *)src_ptr; \
155 for (j = 0; j < sz; j++) { \
156 *dst_ptr++ = (GLfloat)(*in); \
164 static void r300TranslateAttrib(GLcontext
*ctx
, GLuint attr
, int count
, const struct gl_client_array
*input
, struct gl_buffer_object
**bo
, GLuint
*nr_bo
)
166 r300ContextPtr r300
= R300_CONTEXT(ctx
);
167 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
168 struct vertex_attribute r300_attr
;
173 if (input
->BufferObj
->Name
) {
174 if (!input
->BufferObj
->Pointer
) {
175 bo
[*nr_bo
] = input
->BufferObj
;
177 ctx
->Driver
.MapBuffer(ctx
, GL_ARRAY_BUFFER
, GL_READ_ONLY_ARB
, input
->BufferObj
);
178 assert(input
->BufferObj
->Pointer
!= NULL
);
181 src_ptr
= ADD_POINTERS(input
->BufferObj
->Pointer
, input
->Ptr
);
183 src_ptr
= input
->Ptr
;
185 stride
= (input
->StrideB
== 0) ? getTypeSize(input
->Type
) * input
->Size
: input
->StrideB
;
187 if (input
->Type
== GL_DOUBLE
|| input
->Type
== GL_UNSIGNED_INT
|| input
->Type
== GL_INT
||
189 getTypeSize(input
->Type
) != 4 ||
192 if (RADEON_DEBUG
& DEBUG_FALLBACKS
) {
193 fprintf(stderr
, "%s: Converting vertex attributes, attribute data format %x,", __FUNCTION__
, input
->Type
);
194 fprintf(stderr
, "stride %d, components %d\n", stride
, input
->Size
);
197 GLfloat
*dst_ptr
, *tmp
;
199 /* Convert value for first element only */
200 if (input
->StrideB
== 0)
203 tmp
= dst_ptr
= _mesa_malloc(sizeof(GLfloat
) * input
->Size
* count
);
205 switch (input
->Type
) {
207 CONVERT(GLdouble
, (GLfloat
));
209 case GL_UNSIGNED_INT
:
210 CONVERT(GLuint
, UINT_TO_FLOAT
);
213 CONVERT(GLint
, INT_TO_FLOAT
);
215 case GL_UNSIGNED_SHORT
:
216 CONVERT(GLushort
, USHORT_TO_FLOAT
);
219 CONVERT(GLshort
, SHORT_TO_FLOAT
);
221 case GL_UNSIGNED_BYTE
:
222 assert(input
->Format
!= GL_BGRA
);
223 CONVERT(GLubyte
, UBYTE_TO_FLOAT
);
226 CONVERT(GLbyte
, BYTE_TO_FLOAT
);
234 r300_attr
.free_needed
= GL_TRUE
;
235 r300_attr
.data
= tmp
;
236 if (input
->StrideB
== 0) {
237 r300_attr
.stride
= 0;
239 r300_attr
.stride
= sizeof(GLfloat
) * input
->Size
;
241 r300_attr
.dwords
= input
->Size
;
244 r300_attr
.free_needed
= GL_FALSE
;
245 r300_attr
.data
= (GLvoid
*)src_ptr
;
246 r300_attr
.stride
= input
->StrideB
;
247 r300_attr
.dwords
= (getTypeSize(type
) * input
->Size
+ 3)/ 4;
250 r300_attr
.size
= input
->Size
;
251 r300_attr
.element
= attr
;
252 r300_attr
.dst_loc
= vbuf
->num_attribs
;
256 switch (input
->Size
) {
257 case 1: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_1
; break;
258 case 2: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_2
; break;
259 case 3: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_3
; break;
260 case 4: r300_attr
.data_type
= R300_DATA_TYPE_FLOAT_4
; break;
262 r300_attr
._signed
= 0;
263 r300_attr
.normalize
= 0;
266 r300_attr
._signed
= 1;
267 r300_attr
.normalize
= input
->Normalized
;
268 switch (input
->Size
) {
271 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
275 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
280 r300_attr
._signed
= 1;
281 r300_attr
.normalize
= input
->Normalized
;
282 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
284 case GL_UNSIGNED_SHORT
:
285 r300_attr
._signed
= 0;
286 r300_attr
.normalize
= input
->Normalized
;
287 switch (input
->Size
) {
290 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_2
;
294 r300_attr
.data_type
= R300_DATA_TYPE_SHORT_4
;
298 case GL_UNSIGNED_BYTE
:
299 r300_attr
._signed
= 0;
300 r300_attr
.normalize
= input
->Normalized
;
301 if (input
->Format
== GL_BGRA
)
302 r300_attr
.data_type
= R300_DATA_TYPE_D3DCOLOR
;
304 r300_attr
.data_type
= R300_DATA_TYPE_BYTE
;
310 case GL_UNSIGNED_INT
:
315 switch (input
->Size
) {
317 r300_attr
.swizzle
= SWIZZLE_XYZW
;
320 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_Z
, SWIZZLE_ONE
);
323 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_Y
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
326 r300_attr
.swizzle
= MAKE_SWIZZLE4(SWIZZLE_X
, SWIZZLE_ZERO
, SWIZZLE_ZERO
, SWIZZLE_ONE
);
330 r300_attr
.write_mask
= MASK_XYZW
;
332 vbuf
->attribs
[vbuf
->num_attribs
] = r300_attr
;
336 static void r300SetVertexFormat(GLcontext
*ctx
, const struct gl_client_array
*arrays
[], int count
, struct gl_buffer_object
**bo
, GLuint
*nr_bo
)
338 r300ContextPtr r300
= R300_CONTEXT(ctx
);
339 struct r300_vertex_buffer
*vbuf
= &r300
->vbuf
;
344 tmp
= r300
->selected_vp
->code
.InputsRead
;
346 vbuf
->num_attribs
= 0;
348 /* find first enabled bit */
354 r300TranslateAttrib(ctx
, i
, count
, arrays
[i
], bo
, nr_bo
);
361 r300SwitchFallback(ctx
, R300_FALLBACK_AOS_LIMIT
, vbuf
->num_attribs
> R300_MAX_AOS_ARRAYS
);
368 for (i
= 0; i
< vbuf
->num_attribs
; i
++) {
369 rcommon_emit_vector(ctx
, &r300
->radeon
.tcl
.aos
[i
],
370 vbuf
->attribs
[i
].data
, vbuf
->attribs
[i
].dwords
,
371 vbuf
->attribs
[i
].stride
, count
);
374 r300
->radeon
.tcl
.aos_count
= vbuf
->num_attribs
;
378 static void r300FreeData(GLcontext
*ctx
, struct gl_buffer_object
**bo
, GLuint nr_bo
)
381 struct r300_vertex_buffer
*vbuf
= &R300_CONTEXT(ctx
)->vbuf
;
384 for (i
= 0; i
< vbuf
->num_attribs
; i
++) {
385 if (vbuf
->attribs
[i
].free_needed
)
386 _mesa_free(vbuf
->attribs
[i
].data
);
391 struct r300_index_buffer
*ind_buf
= &R300_CONTEXT(ctx
)->ind_buf
;
392 if (ind_buf
->free_needed
)
393 _mesa_free(ind_buf
->ptr
);
399 for (i
= 0; i
< nr_bo
; ++i
) {
400 ctx
->Driver
.UnmapBuffer(ctx
, 0, bo
[i
]);
405 static GLboolean
r300TryDrawPrims(GLcontext
*ctx
,
406 const struct gl_client_array
*arrays
[],
407 const struct _mesa_prim
*prim
,
409 const struct _mesa_index_buffer
*ib
,
413 struct r300_context
*r300
= R300_CONTEXT(ctx
);
414 struct gl_buffer_object
*bo
[VERT_ATTRIB_MAX
+1];
418 _mesa_update_state( ctx
);
420 if (r300
->options
.hw_tcl_enabled
)
421 _tnl_UpdateFixedFunctionProgram(ctx
);
423 r300UpdateShaders(r300
);
425 r300SwitchFallback(ctx
, R300_FALLBACK_INVALID_BUFFERS
, !r300ValidateBuffers(ctx
));
427 r300FixupIndexBuffer(ctx
, ib
, bo
, &nr_bo
);
429 /* ensure we have the cmd buf space in advance to cover
430 * the state + DMA AOS pointers */
431 rcommonEnsureCmdBufSpace(&r300
->radeon
,
432 r300
->radeon
.hw
.max_state_size
+ (50*sizeof(int)),
435 r300SetVertexFormat(ctx
, arrays
, max_index
+ 1, bo
, &nr_bo
);
440 r300SetupVAP(ctx
, r300
->selected_vp
->code
.InputsRead
, r300
->selected_vp
->code
.OutputsWritten
);
442 r300UpdateShaderStates(r300
);
444 r300EmitCacheFlush(r300
);
445 radeonEmitState(&r300
->radeon
);
447 for (i
= 0; i
< nr_prims
; ++i
) {
448 r300RunRenderPrimitive(ctx
, prim
[i
].start
, prim
[i
].start
+ prim
[i
].count
, prim
[i
].mode
);
451 r300EmitCacheFlush(r300
);
453 radeonReleaseArrays(ctx
, ~0);
455 r300FreeData(ctx
, bo
, nr_bo
);
460 static void r300DrawPrims(GLcontext
*ctx
,
461 const struct gl_client_array
*arrays
[],
462 const struct _mesa_prim
*prim
,
464 const struct _mesa_index_buffer
*ib
,
465 GLboolean index_bounds_valid
,
469 struct split_limits limits
;
473 limits
.max_verts
= 0xffffffff;
475 limits
.max_verts
= 65535;
477 limits
.max_indices
= 65535;
478 limits
.max_vb_size
= 1024*1024;
480 /* This check should get folded into just the places that
481 * min/max index are really needed.
483 if (!index_bounds_valid
)
484 vbo_get_minmax_index(ctx
, prim
, ib
, &min_index
, &max_index
);
487 vbo_rebase_prims( ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
, r300DrawPrims
);
490 if ((ib
&& ib
->count
> 65535)) {
491 vbo_split_prims (ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
, r300DrawPrims
, &limits
);
495 /* Make an attempt at drawing */
496 retval
= r300TryDrawPrims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
498 /* If failed run tnl pipeline - it should take care of fallbacks */
500 _tnl_draw_prims(ctx
, arrays
, prim
, nr_prims
, ib
, min_index
, max_index
);
503 void r300InitDraw(GLcontext
*ctx
)
505 struct vbo_context
*vbo
= vbo_context(ctx
);
507 vbo
->draw_prims
= r300DrawPrims
;