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 "util/u_memory.h"
00029 #include "draw/draw_context.h"
00030 #include "draw/draw_private.h"
00031 #include "draw/draw_vbuf.h"
00032 #include "draw/draw_vertex.h"
00033 #include "draw/draw_pt.h"
00034 #include "translate/translate.h"
00035 #include "translate/translate_cache.h"
00036
00037 struct pt_emit {
00038 struct draw_context *draw;
00039
00040 struct translate *translate;
00041
00042 struct translate_cache *cache;
00043 unsigned prim;
00044
00045 const struct vertex_info *vinfo;
00046 };
00047
00048 void draw_pt_emit_prepare( struct pt_emit *emit,
00049 unsigned prim,
00050 unsigned *max_vertices )
00051 {
00052 struct draw_context *draw = emit->draw;
00053 const struct vertex_info *vinfo;
00054 unsigned dst_offset;
00055 struct translate_key hw_key;
00056 unsigned i;
00057 boolean ok;
00058
00059
00060
00061 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00062
00063
00064
00065
00066
00067 emit->prim = prim;
00068
00069 ok = draw->render->set_primitive(draw->render, emit->prim);
00070 if (!ok) {
00071 assert(0);
00072 return;
00073 }
00074
00075
00076
00077 emit->vinfo = vinfo = draw->render->get_vertex_info(draw->render);
00078
00079
00080
00081
00082 dst_offset = 0;
00083 for (i = 0; i < vinfo->num_attribs; i++) {
00084 unsigned emit_sz = 0;
00085 unsigned src_buffer = 0;
00086 unsigned output_format;
00087 unsigned src_offset = (vinfo->attrib[i].src_index * 4 * sizeof(float) );
00088
00089
00090
00091 switch (vinfo->attrib[i].emit) {
00092 case EMIT_4F:
00093 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
00094 emit_sz = 4 * sizeof(float);
00095 break;
00096 case EMIT_3F:
00097 output_format = PIPE_FORMAT_R32G32B32_FLOAT;
00098 emit_sz = 3 * sizeof(float);
00099 break;
00100 case EMIT_2F:
00101 output_format = PIPE_FORMAT_R32G32_FLOAT;
00102 emit_sz = 2 * sizeof(float);
00103 break;
00104 case EMIT_1F:
00105 output_format = PIPE_FORMAT_R32_FLOAT;
00106 emit_sz = 1 * sizeof(float);
00107 break;
00108 case EMIT_1F_PSIZE:
00109 output_format = PIPE_FORMAT_R32_FLOAT;
00110 emit_sz = 1 * sizeof(float);
00111 src_buffer = 1;
00112 src_offset = 0;
00113 break;
00114 case EMIT_4UB:
00115 output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
00116 emit_sz = 4 * sizeof(ubyte);
00117 break;
00118 default:
00119 assert(0);
00120 output_format = PIPE_FORMAT_NONE;
00121 emit_sz = 0;
00122 break;
00123 }
00124
00125 hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
00126 hw_key.element[i].input_buffer = src_buffer;
00127 hw_key.element[i].input_offset = src_offset;
00128 hw_key.element[i].output_format = output_format;
00129 hw_key.element[i].output_offset = dst_offset;
00130
00131 dst_offset += emit_sz;
00132 }
00133
00134 hw_key.nr_elements = vinfo->num_attribs;
00135 hw_key.output_stride = vinfo->size * 4;
00136
00137 if (!emit->translate ||
00138 translate_key_compare(&emit->translate->key, &hw_key) != 0)
00139 {
00140 translate_key_sanitize(&hw_key);
00141 emit->translate = translate_cache_find(emit->cache, &hw_key);
00142 }
00143
00144 *max_vertices = (draw->render->max_vertex_buffer_bytes /
00145 (vinfo->size * 4));
00146
00147
00148 *max_vertices = *max_vertices & ~1;
00149 }
00150
00151
00152 void draw_pt_emit( struct pt_emit *emit,
00153 const float (*vertex_data)[4],
00154 unsigned vertex_count,
00155 unsigned stride,
00156 const ushort *elts,
00157 unsigned count )
00158 {
00159 struct draw_context *draw = emit->draw;
00160 struct translate *translate = emit->translate;
00161 struct vbuf_render *render = draw->render;
00162 void *hw_verts;
00163
00164
00165
00166 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00167
00168
00169
00170
00171 if (!draw->render->set_primitive(draw->render, emit->prim)) {
00172 assert(0);
00173 return;
00174 }
00175
00176 hw_verts = render->allocate_vertices(render,
00177 (ushort)translate->key.output_stride,
00178 (ushort)vertex_count);
00179 if (!hw_verts) {
00180 assert(0);
00181 return;
00182 }
00183
00184 translate->set_buffer(translate,
00185 0,
00186 vertex_data,
00187 stride );
00188
00189 translate->set_buffer(translate,
00190 1,
00191 &draw->rasterizer->point_size,
00192 0);
00193
00194 translate->run( translate,
00195 0,
00196 vertex_count,
00197 hw_verts );
00198
00199 render->draw(render,
00200 elts,
00201 count);
00202
00203 render->release_vertices(render,
00204 hw_verts,
00205 translate->key.output_stride,
00206 vertex_count);
00207 }
00208
00209
00210 void draw_pt_emit_linear(struct pt_emit *emit,
00211 const float (*vertex_data)[4],
00212 unsigned vertex_count,
00213 unsigned stride,
00214 unsigned start,
00215 unsigned count)
00216 {
00217 struct draw_context *draw = emit->draw;
00218 struct translate *translate = emit->translate;
00219 struct vbuf_render *render = draw->render;
00220 void *hw_verts;
00221
00222 #if 0
00223 debug_printf("Linear emit\n");
00224 #endif
00225
00226
00227 draw_do_flush( draw, DRAW_FLUSH_BACKEND );
00228
00229
00230
00231
00232 if (!draw->render->set_primitive(draw->render, emit->prim)) {
00233 assert(0);
00234 return;
00235 }
00236
00237 hw_verts = render->allocate_vertices(render,
00238 (ushort)translate->key.output_stride,
00239 (ushort)count);
00240 if (!hw_verts) {
00241 assert(0);
00242 return;
00243 }
00244
00245 translate->set_buffer(translate, 0,
00246 vertex_data, stride);
00247
00248 translate->set_buffer(translate, 1,
00249 &draw->rasterizer->point_size,
00250 0);
00251
00252 translate->run(translate,
00253 0,
00254 vertex_count,
00255 hw_verts);
00256
00257 if (0) {
00258 unsigned i;
00259 for (i = 0; i < vertex_count; i++) {
00260 debug_printf("\n\n%s vertex %d:\n", __FUNCTION__, i);
00261 draw_dump_emitted_vertex( emit->vinfo,
00262 (const uint8_t *)hw_verts +
00263 translate->key.output_stride * i );
00264 }
00265 }
00266
00267
00268 render->draw_arrays(render, start, count);
00269
00270 render->release_vertices(render,
00271 hw_verts,
00272 translate->key.output_stride,
00273 vertex_count);
00274 }
00275
00276 struct pt_emit *draw_pt_emit_create( struct draw_context *draw )
00277 {
00278 struct pt_emit *emit = CALLOC_STRUCT(pt_emit);
00279 if (!emit)
00280 return NULL;
00281
00282 emit->draw = draw;
00283 emit->cache = translate_cache_create();
00284 if (!emit->cache) {
00285 FREE(emit);
00286 return NULL;
00287 }
00288
00289 return emit;
00290 }
00291
00292 void draw_pt_emit_destroy( struct pt_emit *emit )
00293 {
00294 if (emit->cache)
00295 translate_cache_destroy(emit->cache);
00296
00297 FREE(emit);
00298 }