draw_pt_emit.c revision cec016271ccf38d2f32e426f96e7d5d1fdf962f7
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}; 44 45void draw_pt_emit_prepare( struct pt_emit *emit, 46 unsigned prim ) 47{ 48 struct draw_context *draw = emit->draw; 49 const struct vertex_info *vinfo; 50 unsigned dst_offset; 51 struct translate_key hw_key; 52 unsigned keysize; 53 unsigned i; 54 boolean ok; 55 56 ok = draw->render->set_primitive(draw->render, prim); 57 if (!ok) { 58 assert(0); 59 return; 60 } 61 62 /* Must do this after set_primitive() above: 63 */ 64 vinfo = draw->render->get_vertex_info(draw->render); 65 keysize = 2*4 + vinfo->num_attribs * sizeof(hw_key.element[0]); 66 67 /* Translate from pipeline vertices to hw vertices. 68 */ 69 dst_offset = 0; 70 for (i = 0; i < vinfo->num_attribs; i++) { 71 unsigned emit_sz = 0; 72 unsigned src_buffer = 0; 73 unsigned output_format; 74 unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) ); 75 76 77 78 switch (vinfo->emit[i]) { 79 case EMIT_4F: 80 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 81 emit_sz = 4 * sizeof(float); 82 break; 83 case EMIT_3F: 84 output_format = PIPE_FORMAT_R32G32B32_FLOAT; 85 emit_sz = 3 * sizeof(float); 86 break; 87 case EMIT_2F: 88 output_format = PIPE_FORMAT_R32G32_FLOAT; 89 emit_sz = 2 * sizeof(float); 90 break; 91 case EMIT_1F: 92 output_format = PIPE_FORMAT_R32_FLOAT; 93 emit_sz = 1 * sizeof(float); 94 break; 95 case EMIT_1F_PSIZE: 96 output_format = PIPE_FORMAT_R32_FLOAT; 97 emit_sz = 1 * sizeof(float); 98 src_buffer = 1; 99 src_offset = 0; 100 break; 101 case EMIT_4UB: 102 output_format = PIPE_FORMAT_B8G8R8A8_UNORM; 103 emit_sz = 4 * sizeof(ubyte); 104 default: 105 assert(0); 106 output_format = PIPE_FORMAT_NONE; 107 emit_sz = 0; 108 break; 109 } 110 111 hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 112 hw_key.element[i].input_buffer = src_buffer; 113 hw_key.element[i].input_offset = src_offset; 114 hw_key.element[i].output_format = output_format; 115 hw_key.element[i].output_offset = dst_offset; 116 117 dst_offset += emit_sz; 118 } 119 120 hw_key.nr_elements = vinfo->num_attribs; 121 hw_key.output_stride = vinfo->size * 4; 122 123 if (!emit->translate || 124 memcmp(&emit->translate->key, &hw_key, keysize) != 0) 125 { 126 memset((char *)&hw_key + keysize, 0, sizeof(hw_key) - keysize); 127 emit->translate = translate_cache_find(emit->cache, &hw_key); 128 } 129} 130 131 132void draw_pt_emit( struct pt_emit *emit, 133 const float (*vertex_data)[4], 134 unsigned vertex_count, 135 unsigned stride, 136 const ushort *elts, 137 unsigned count ) 138{ 139 struct draw_context *draw = emit->draw; 140 struct translate *translate = emit->translate; 141 struct vbuf_render *render = draw->render; 142 void *hw_verts; 143 144 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 145 */ 146 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 147 148 hw_verts = render->allocate_vertices(render, 149 (ushort)translate->key.output_stride, 150 (ushort)count); 151 if (!hw_verts) { 152 assert(0); 153 return; 154 } 155 156 translate->set_buffer(translate, 157 0, 158 vertex_data, 159 stride ); 160 161 translate->set_buffer(translate, 162 1, 163 &draw->rasterizer->point_size, 164 0); 165 166 translate->run( translate, 167 0, 168 vertex_count, 169 hw_verts ); 170 171 render->draw(render, 172 elts, 173 count); 174 175 render->release_vertices(render, 176 hw_verts, 177 translate->key.output_stride, 178 vertex_count); 179} 180 181 182void draw_pt_emit_linear(struct pt_emit *emit, 183 const float (*vertex_data)[4], 184 unsigned vertex_count, 185 unsigned stride, 186 unsigned start, 187 unsigned count) 188{ 189 struct draw_context *draw = emit->draw; 190 struct translate *translate = emit->translate; 191 struct vbuf_render *render = draw->render; 192 void *hw_verts; 193 194#if 0 195 debug_printf("Linear emit\n"); 196#endif 197 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 198 */ 199 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 200 201 hw_verts = render->allocate_vertices(render, 202 (ushort)translate->key.output_stride, 203 (ushort)count); 204 if (!hw_verts) { 205 assert(0); 206 return; 207 } 208 209 translate->set_buffer(translate, 0, 210 vertex_data, stride); 211 212 translate->set_buffer(translate, 1, 213 &draw->rasterizer->point_size, 214 0); 215 216 translate->run(translate, 217 0, 218 vertex_count, 219 hw_verts); 220 221 render->draw_arrays(render, start, count); 222 223 render->release_vertices(render, 224 hw_verts, 225 translate->key.output_stride, 226 vertex_count); 227} 228 229struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) 230{ 231 struct pt_emit *emit = CALLOC_STRUCT(pt_emit); 232 if (!emit) 233 return NULL; 234 235 emit->draw = draw; 236 emit->cache = translate_cache_create(); 237 if (!emit->cache) { 238 FREE(emit); 239 return NULL; 240 } 241 242 return emit; 243} 244 245void draw_pt_emit_destroy( struct pt_emit *emit ) 246{ 247 translate_cache_destroy(emit->cache); 248 249 FREE(emit); 250} 251