draw_pt_emit.c revision 93bfc94c351a2eafd43ac7a20b362d969f98d86a
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 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: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 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. 25 * 26 **************************************************************************/ 27 28#include "pipe/p_util.h" 29#include "draw/draw_context.h" 30#include "draw/draw_private.h" 31#include "draw/draw_vbuf.h" 32#include "draw/draw_vertex.h" 33#include "draw/draw_pt.h" 34#include "translate/translate.h" 35#include "translate/translate_cache.h" 36 37struct pt_emit { 38 struct draw_context *draw; 39 40 struct translate *translate; 41 42 struct translate_cache *cache; 43 unsigned prim; 44}; 45 46void draw_pt_emit_prepare( struct pt_emit *emit, 47 unsigned prim ) 48{ 49 struct draw_context *draw = emit->draw; 50 const struct vertex_info *vinfo; 51 unsigned dst_offset; 52 struct translate_key hw_key; 53 unsigned i; 54 boolean ok; 55 56 57 /* XXX: may need to defensively reset this later on as clipping can 58 * clobber this state in the render backend. 59 */ 60 emit->prim = prim; 61 62 ok = draw->render->set_primitive(draw->render, emit->prim); 63 if (!ok) { 64 assert(0); 65 return; 66 } 67 68 /* Must do this after set_primitive() above: 69 */ 70 vinfo = draw->render->get_vertex_info(draw->render); 71 72 73 /* Translate from pipeline vertices to hw vertices. 74 */ 75 dst_offset = 0; 76 for (i = 0; i < vinfo->num_attribs; i++) { 77 unsigned emit_sz = 0; 78 unsigned src_buffer = 0; 79 unsigned output_format; 80 unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) ); 81 82 83 84 switch (vinfo->emit[i]) { 85 case EMIT_4F: 86 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 87 emit_sz = 4 * sizeof(float); 88 break; 89 case EMIT_3F: 90 output_format = PIPE_FORMAT_R32G32B32_FLOAT; 91 emit_sz = 3 * sizeof(float); 92 break; 93 case EMIT_2F: 94 output_format = PIPE_FORMAT_R32G32_FLOAT; 95 emit_sz = 2 * sizeof(float); 96 break; 97 case EMIT_1F: 98 output_format = PIPE_FORMAT_R32_FLOAT; 99 emit_sz = 1 * sizeof(float); 100 break; 101 case EMIT_1F_PSIZE: 102 output_format = PIPE_FORMAT_R32_FLOAT; 103 emit_sz = 1 * sizeof(float); 104 src_buffer = 1; 105 src_offset = 0; 106 break; 107 case EMIT_4UB: 108 output_format = PIPE_FORMAT_B8G8R8A8_UNORM; 109 emit_sz = 4 * sizeof(ubyte); 110 break; 111 default: 112 assert(0); 113 output_format = PIPE_FORMAT_NONE; 114 emit_sz = 0; 115 break; 116 } 117 118 hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 119 hw_key.element[i].input_buffer = src_buffer; 120 hw_key.element[i].input_offset = src_offset; 121 hw_key.element[i].output_format = output_format; 122 hw_key.element[i].output_offset = dst_offset; 123 124 dst_offset += emit_sz; 125 } 126 127 hw_key.nr_elements = vinfo->num_attribs; 128 hw_key.output_stride = vinfo->size * 4; 129 130 if (!emit->translate || 131 translate_key_compare(&emit->translate->key, &hw_key) != 0) 132 { 133 translate_key_sanitize(&hw_key); 134 emit->translate = translate_cache_find(emit->cache, &hw_key); 135 } 136} 137 138 139void draw_pt_emit( struct pt_emit *emit, 140 const float (*vertex_data)[4], 141 unsigned vertex_count, 142 unsigned stride, 143 const ushort *elts, 144 unsigned count ) 145{ 146 struct draw_context *draw = emit->draw; 147 struct translate *translate = emit->translate; 148 struct vbuf_render *render = draw->render; 149 void *hw_verts; 150 151 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 152 */ 153 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 154 155 /* XXX: and work out some way to coordinate the render primitive 156 * between vbuf.c and here... 157 */ 158 if (!draw->render->set_primitive(draw->render, emit->prim)) { 159 assert(0); 160 return; 161 } 162 163 hw_verts = render->allocate_vertices(render, 164 (ushort)translate->key.output_stride, 165 (ushort)vertex_count); 166 if (!hw_verts) { 167 assert(0); 168 return; 169 } 170 171 translate->set_buffer(translate, 172 0, 173 vertex_data, 174 stride ); 175 176 translate->set_buffer(translate, 177 1, 178 &draw->rasterizer->point_size, 179 0); 180 181 translate->run( translate, 182 0, 183 vertex_count, 184 hw_verts ); 185 186 render->draw(render, 187 elts, 188 count); 189 190 render->release_vertices(render, 191 hw_verts, 192 translate->key.output_stride, 193 vertex_count); 194} 195 196 197void draw_pt_emit_linear(struct pt_emit *emit, 198 const float (*vertex_data)[4], 199 unsigned vertex_count, 200 unsigned stride, 201 unsigned start, 202 unsigned count) 203{ 204 struct draw_context *draw = emit->draw; 205 struct translate *translate = emit->translate; 206 struct vbuf_render *render = draw->render; 207 void *hw_verts; 208 209#if 0 210 debug_printf("Linear emit\n"); 211#endif 212 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 213 */ 214 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 215 216 /* XXX: and work out some way to coordinate the render primitive 217 * between vbuf.c and here... 218 */ 219 if (!draw->render->set_primitive(draw->render, emit->prim)) { 220 assert(0); 221 return; 222 } 223 224 hw_verts = render->allocate_vertices(render, 225 (ushort)translate->key.output_stride, 226 (ushort)count); 227 if (!hw_verts) { 228 assert(0); 229 return; 230 } 231 232 translate->set_buffer(translate, 0, 233 vertex_data, stride); 234 235 translate->set_buffer(translate, 1, 236 &draw->rasterizer->point_size, 237 0); 238 239 translate->run(translate, 240 0, 241 vertex_count, 242 hw_verts); 243 244 render->draw_arrays(render, start, count); 245 246 render->release_vertices(render, 247 hw_verts, 248 translate->key.output_stride, 249 vertex_count); 250} 251 252struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) 253{ 254 struct pt_emit *emit = CALLOC_STRUCT(pt_emit); 255 if (!emit) 256 return NULL; 257 258 emit->draw = draw; 259 emit->cache = translate_cache_create(); 260 if (!emit->cache) { 261 FREE(emit); 262 return NULL; 263 } 264 265 return emit; 266} 267 268void draw_pt_emit_destroy( struct pt_emit *emit ) 269{ 270 if (emit->cache) 271 translate_cache_destroy(emit->cache); 272 273 FREE(emit); 274} 275