00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdlib.h>
00029
00030 #include "brw_batch.h"
00031 #include "brw_draw.h"
00032 #include "brw_defines.h"
00033 #include "brw_context.h"
00034 #include "brw_state.h"
00035
00036 #include "pipe/p_context.h"
00037 #include "pipe/p_winsys.h"
00038
00039 static unsigned hw_prim[PIPE_PRIM_POLYGON+1] = {
00040 _3DPRIM_POINTLIST,
00041 _3DPRIM_LINELIST,
00042 _3DPRIM_LINELOOP,
00043 _3DPRIM_LINESTRIP,
00044 _3DPRIM_TRILIST,
00045 _3DPRIM_TRISTRIP,
00046 _3DPRIM_TRIFAN,
00047 _3DPRIM_QUADLIST,
00048 _3DPRIM_QUADSTRIP,
00049 _3DPRIM_POLYGON
00050 };
00051
00052
00053 static const int reduced_prim[PIPE_PRIM_POLYGON+1] = {
00054 PIPE_PRIM_POINTS,
00055 PIPE_PRIM_LINES,
00056 PIPE_PRIM_LINES,
00057 PIPE_PRIM_LINES,
00058 PIPE_PRIM_TRIANGLES,
00059 PIPE_PRIM_TRIANGLES,
00060 PIPE_PRIM_TRIANGLES,
00061 PIPE_PRIM_TRIANGLES,
00062 PIPE_PRIM_TRIANGLES,
00063 PIPE_PRIM_TRIANGLES
00064 };
00065
00066
00067
00068
00069
00070
00071
00072 static void brw_set_prim(struct brw_context *brw, int prim)
00073 {
00074 PRINT("PRIM: %d\n", prim);
00075
00076
00077
00078 if (prim == PIPE_PRIM_QUAD_STRIP &&
00079 brw->attribs.Raster->flatshade &&
00080 brw->attribs.Raster->fill_cw == PIPE_POLYGON_MODE_FILL &&
00081 brw->attribs.Raster->fill_ccw == PIPE_POLYGON_MODE_FILL)
00082 prim = PIPE_PRIM_TRIANGLE_STRIP;
00083
00084 if (prim != brw->primitive) {
00085 brw->primitive = prim;
00086 brw->state.dirty.brw |= BRW_NEW_PRIMITIVE;
00087
00088 if (reduced_prim[prim] != brw->reduced_primitive) {
00089 brw->reduced_primitive = reduced_prim[prim];
00090 brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
00091 }
00092
00093 brw_validate_state(brw);
00094 }
00095
00096 }
00097
00098
00099 static unsigned trim(int prim, unsigned length)
00100 {
00101 if (prim == PIPE_PRIM_QUAD_STRIP)
00102 return length > 3 ? (length - length % 2) : 0;
00103 else if (prim == PIPE_PRIM_QUADS)
00104 return length - length % 4;
00105 else
00106 return length;
00107 }
00108
00109
00110
00111 static boolean brw_emit_prim( struct brw_context *brw,
00112 boolean indexed,
00113 unsigned start,
00114 unsigned count )
00115
00116 {
00117 struct brw_3d_primitive prim_packet;
00118
00119 if (BRW_DEBUG & DEBUG_PRIMS)
00120 PRINT("PRIM: %d %d %d\n", brw->primitive, start, count);
00121
00122 prim_packet.header.opcode = CMD_3D_PRIM;
00123 prim_packet.header.length = sizeof(prim_packet)/4 - 2;
00124 prim_packet.header.pad = 0;
00125 prim_packet.header.topology = hw_prim[brw->primitive];
00126 prim_packet.header.indexed = indexed;
00127
00128 prim_packet.verts_per_instance = trim(brw->primitive, count);
00129 prim_packet.start_vert_location = start;
00130 prim_packet.instance_count = 1;
00131 prim_packet.start_instance_location = 0;
00132 prim_packet.base_vert_location = 0;
00133
00134 if (prim_packet.verts_per_instance == 0)
00135 return TRUE;
00136
00137 return brw_batchbuffer_data( brw->winsys,
00138 &prim_packet,
00139 sizeof(prim_packet) );
00140 }
00141
00142
00143
00144
00145
00146 static boolean brw_try_draw_elements( struct pipe_context *pipe,
00147 struct pipe_buffer *index_buffer,
00148 unsigned index_size,
00149 unsigned mode,
00150 unsigned start,
00151 unsigned count )
00152 {
00153 struct brw_context *brw = brw_context(pipe);
00154
00155
00156
00157 brw_set_prim(brw, mode);
00158
00159
00160
00161 if (index_buffer &&
00162 !brw_upload_indices( brw, index_buffer, index_size, start, count ))
00163 return FALSE;
00164
00165 if (!brw_upload_vertex_buffers(brw))
00166 return FALSE;
00167
00168 if (!brw_upload_vertex_elements( brw ))
00169 return FALSE;
00170
00171
00172
00173 if (brw->state.dirty.brw)
00174 brw_validate_state( brw );
00175
00176 if (!brw_emit_prim(brw, index_buffer != NULL,
00177 start, count))
00178 return FALSE;
00179
00180 return TRUE;
00181 }
00182
00183
00184
00185 static boolean brw_draw_elements( struct pipe_context *pipe,
00186 struct pipe_buffer *indexBuffer,
00187 unsigned indexSize,
00188 unsigned mode,
00189 unsigned start,
00190 unsigned count )
00191 {
00192 if (!brw_try_draw_elements( pipe,
00193 indexBuffer,
00194 indexSize,
00195 mode, start, count ))
00196 {
00197
00198
00199 if (!brw_try_draw_elements( pipe,
00200 indexBuffer,
00201 indexSize,
00202 mode, start,
00203 count )) {
00204 assert(0);
00205 return FALSE;
00206 }
00207 }
00208
00209 return TRUE;
00210 }
00211
00212
00213
00214 static boolean brw_draw_arrays( struct pipe_context *pipe,
00215 unsigned mode,
00216 unsigned start,
00217 unsigned count )
00218 {
00219 if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) {
00220
00221
00222 if (!brw_try_draw_elements( pipe, NULL, 0, mode, start, count )) {
00223 assert(0);
00224 return FALSE;
00225 }
00226 }
00227
00228 return TRUE;
00229 }
00230
00231
00232
00233 void brw_init_draw_functions( struct brw_context *brw )
00234 {
00235 brw->pipe.draw_arrays = brw_draw_arrays;
00236 brw->pipe.draw_elements = brw_draw_elements;
00237 }
00238
00239