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
00038 struct pt_fetch {
00039 struct draw_context *draw;
00040
00041 struct translate *translate;
00042
00043 unsigned vertex_size;
00044 boolean need_edgeflags;
00045
00046 struct translate_cache *cache;
00047 };
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 void draw_pt_fetch_prepare( struct pt_fetch *fetch,
00059 unsigned vertex_size )
00060 {
00061 struct draw_context *draw = fetch->draw;
00062 unsigned i, nr = 0;
00063 unsigned dst_offset = 0;
00064 struct translate_key key;
00065
00066 fetch->vertex_size = vertex_size;
00067
00068
00069
00070
00071
00072
00073
00074
00075 {
00076
00077
00078 key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT;
00079 key.element[nr].input_buffer = draw->pt.nr_vertex_buffers;
00080 key.element[nr].input_offset = 0;
00081 key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT;
00082 key.element[nr].output_offset = dst_offset;
00083 dst_offset += 1 * sizeof(float);
00084 nr++;
00085
00086
00087
00088
00089 dst_offset += 4 * sizeof(float);
00090 }
00091
00092
00093 for (i = 0; i < draw->pt.nr_vertex_elements; i++) {
00094 key.element[nr].input_format = draw->pt.vertex_element[i].src_format;
00095 key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index;
00096 key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset;
00097 key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
00098 key.element[nr].output_offset = dst_offset;
00099
00100 dst_offset += 4 * sizeof(float);
00101 nr++;
00102 }
00103
00104 assert(dst_offset <= vertex_size);
00105
00106 key.nr_elements = nr;
00107 key.output_stride = vertex_size;
00108
00109
00110 if (!fetch->translate ||
00111 translate_key_compare(&fetch->translate->key, &key) != 0)
00112 {
00113 translate_key_sanitize(&key);
00114 fetch->translate = translate_cache_find(fetch->cache, &key);
00115
00116 {
00117 static struct vertex_header vh = { 0, 1, 0, UNDEFINED_VERTEX_ID, { .0f, .0f, .0f, .0f } };
00118 fetch->translate->set_buffer(fetch->translate,
00119 draw->pt.nr_vertex_buffers,
00120 &vh,
00121 0);
00122 }
00123 }
00124
00125 fetch->need_edgeflags = ((draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
00126 draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) &&
00127 draw->pt.user.edgeflag);
00128 }
00129
00130
00131
00132
00133 void draw_pt_fetch_run( struct pt_fetch *fetch,
00134 const unsigned *elts,
00135 unsigned count,
00136 char *verts )
00137 {
00138 struct draw_context *draw = fetch->draw;
00139 struct translate *translate = fetch->translate;
00140 unsigned i;
00141
00142 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00143 translate->set_buffer(translate,
00144 i,
00145 ((char *)draw->pt.user.vbuffer[i] +
00146 draw->pt.vertex_buffer[i].buffer_offset),
00147 draw->pt.vertex_buffer[i].pitch );
00148 }
00149
00150 translate->run_elts( translate,
00151 elts,
00152 count,
00153 verts );
00154
00155
00156
00157
00158
00159
00160 if (fetch->need_edgeflags) {
00161 for (i = 0; i < count; i++) {
00162 struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
00163 vh->edgeflag = draw_pt_get_edgeflag( draw, elts[i] );
00164 }
00165 }
00166 }
00167
00168
00169 void draw_pt_fetch_run_linear( struct pt_fetch *fetch,
00170 unsigned start,
00171 unsigned count,
00172 char *verts )
00173 {
00174 struct draw_context *draw = fetch->draw;
00175 struct translate *translate = fetch->translate;
00176 unsigned i;
00177
00178 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) {
00179 translate->set_buffer(translate,
00180 i,
00181 ((char *)draw->pt.user.vbuffer[i] +
00182 draw->pt.vertex_buffer[i].buffer_offset),
00183 draw->pt.vertex_buffer[i].pitch );
00184 }
00185
00186 translate->run( translate,
00187 start,
00188 count,
00189 verts );
00190
00191
00192
00193
00194
00195
00196 if (fetch->need_edgeflags) {
00197 for (i = 0; i < count; i++) {
00198 struct vertex_header *vh = (struct vertex_header *)(verts + i * fetch->vertex_size);
00199 vh->edgeflag = draw_pt_get_edgeflag( draw, start + i );
00200 }
00201 }
00202 }
00203
00204
00205 struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw )
00206 {
00207 struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch);
00208 if (!fetch)
00209 return NULL;
00210
00211 fetch->draw = draw;
00212 fetch->cache = translate_cache_create();
00213 if (!fetch->cache) {
00214 FREE(fetch);
00215 return NULL;
00216 }
00217
00218 return fetch;
00219 }
00220
00221 void draw_pt_fetch_destroy( struct pt_fetch *fetch )
00222 {
00223 if (fetch->cache)
00224 translate_cache_destroy(fetch->cache);
00225
00226 FREE(fetch);
00227 }
00228