1 /**************************************************************************
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
30 #include "brw_batch.h"
32 #include "brw_defines.h"
33 #include "brw_context.h"
34 #include "brw_state.h"
36 #include "pipe/p_context.h"
37 #include "pipe/p_winsys.h"
39 static unsigned hw_prim
[PIPE_PRIM_POLYGON
+1] = {
53 static const int reduced_prim
[PIPE_PRIM_POLYGON
+1] = {
67 /* When the primitive changes, set a state bit and re-validate. Not
68 * the nicest and would rather deal with this by having all the
69 * programs be immune to the active primitive (ie. cope with all
70 * possibilities). That may not be realistic however.
72 static void brw_set_prim(struct brw_context
*brw
, int prim
)
74 PRINT("PRIM: %d\n", prim
);
76 /* Slight optimization to avoid the GS program when not needed:
78 if (prim
== PIPE_PRIM_QUAD_STRIP
&&
79 brw
->attribs
.Raster
->flatshade
&&
80 brw
->attribs
.Raster
->fill_cw
== PIPE_POLYGON_MODE_FILL
&&
81 brw
->attribs
.Raster
->fill_ccw
== PIPE_POLYGON_MODE_FILL
)
82 prim
= PIPE_PRIM_TRIANGLE_STRIP
;
84 if (prim
!= brw
->primitive
) {
85 brw
->primitive
= prim
;
86 brw
->state
.dirty
.brw
|= BRW_NEW_PRIMITIVE
;
88 if (reduced_prim
[prim
] != brw
->reduced_primitive
) {
89 brw
->reduced_primitive
= reduced_prim
[prim
];
90 brw
->state
.dirty
.brw
|= BRW_NEW_REDUCED_PRIMITIVE
;
93 brw_validate_state(brw
);
99 static unsigned trim(int prim
, unsigned length
)
101 if (prim
== PIPE_PRIM_QUAD_STRIP
)
102 return length
> 3 ? (length
- length
% 2) : 0;
103 else if (prim
== PIPE_PRIM_QUADS
)
104 return length
- length
% 4;
111 static boolean
brw_emit_prim( struct brw_context
*brw
,
117 struct brw_3d_primitive prim_packet
;
119 if (BRW_DEBUG
& DEBUG_PRIMS
)
120 PRINT("PRIM: %d %d %d\n", brw
->primitive
, start
, count
);
122 prim_packet
.header
.opcode
= CMD_3D_PRIM
;
123 prim_packet
.header
.length
= sizeof(prim_packet
)/4 - 2;
124 prim_packet
.header
.pad
= 0;
125 prim_packet
.header
.topology
= hw_prim
[brw
->primitive
];
126 prim_packet
.header
.indexed
= indexed
;
128 prim_packet
.verts_per_instance
= trim(brw
->primitive
, count
);
129 prim_packet
.start_vert_location
= start
;
130 prim_packet
.instance_count
= 1;
131 prim_packet
.start_instance_location
= 0;
132 prim_packet
.base_vert_location
= 0;
134 if (prim_packet
.verts_per_instance
== 0)
137 return brw_batchbuffer_data( brw
->winsys
,
139 sizeof(prim_packet
) );
143 /* May fail if out of video memory for texture or vbo upload, or on
144 * fallback conditions.
146 static boolean
brw_try_draw_elements( struct pipe_context
*pipe
,
147 struct pipe_buffer
*index_buffer
,
153 struct brw_context
*brw
= brw_context(pipe
);
155 /* Set the first primitive ahead of validate_state:
157 brw_set_prim(brw
, mode
);
159 /* Upload index, vertex data:
162 !brw_upload_indices( brw
, index_buffer
, index_size
, start
, count
))
165 if (!brw_upload_vertex_buffers(brw
))
168 if (!brw_upload_vertex_elements( brw
))
171 /* XXX: Need to separate validate and upload of state.
173 if (brw
->state
.dirty
.brw
)
174 brw_validate_state( brw
);
176 if (!brw_emit_prim(brw
, index_buffer
!= NULL
,
185 static boolean
brw_draw_elements( struct pipe_context
*pipe
,
186 struct pipe_buffer
*indexBuffer
,
192 if (!brw_try_draw_elements( pipe
,
195 mode
, start
, count
))
199 if (!brw_try_draw_elements( pipe
,
214 static boolean
brw_draw_arrays( struct pipe_context
*pipe
,
219 if (!brw_try_draw_elements( pipe
, NULL
, 0, mode
, start
, count
)) {
222 if (!brw_try_draw_elements( pipe
, NULL
, 0, mode
, start
, count
)) {
233 void brw_init_draw_functions( struct brw_context
*brw
)
235 brw
->pipe
.draw_arrays
= brw_draw_arrays
;
236 brw
->pipe
.draw_elements
= brw_draw_elements
;