draw_pt_emit.c revision 7462f0557f9cce73ff2d32e62ef110b5d8622f87
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 i; 53 boolean ok; 54 55 ok = draw->render->set_primitive(draw->render, prim); 56 if (!ok) { 57 assert(0); 58 return; 59 } 60 61 /* Must do this after set_primitive() above: 62 */ 63 vinfo = draw->render->get_vertex_info(draw->render); 64 65 66 /* Translate from pipeline vertices to hw vertices. 67 */ 68 dst_offset = 0; 69 for (i = 0; i < vinfo->num_attribs; i++) { 70 unsigned emit_sz = 0; 71 unsigned src_buffer = 0; 72 unsigned output_format; 73 unsigned src_offset = (vinfo->src_index[i] * 4 * sizeof(float) ); 74 75 76 77 switch (vinfo->emit[i]) { 78 case EMIT_4F: 79 output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 80 emit_sz = 4 * sizeof(float); 81 break; 82 case EMIT_3F: 83 output_format = PIPE_FORMAT_R32G32B32_FLOAT; 84 emit_sz = 3 * sizeof(float); 85 break; 86 case EMIT_2F: 87 output_format = PIPE_FORMAT_R32G32_FLOAT; 88 emit_sz = 2 * sizeof(float); 89 break; 90 case EMIT_1F: 91 output_format = PIPE_FORMAT_R32_FLOAT; 92 emit_sz = 1 * sizeof(float); 93 break; 94 case EMIT_1F_PSIZE: 95 output_format = PIPE_FORMAT_R32_FLOAT; 96 emit_sz = 1 * sizeof(float); 97 src_buffer = 1; 98 src_offset = 0; 99 break; 100 case EMIT_4UB: 101 output_format = PIPE_FORMAT_B8G8R8A8_UNORM; 102 emit_sz = 4 * sizeof(ubyte); 103 default: 104 assert(0); 105 output_format = PIPE_FORMAT_NONE; 106 emit_sz = 0; 107 break; 108 } 109 110 hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 111 hw_key.element[i].input_buffer = src_buffer; 112 hw_key.element[i].input_offset = src_offset; 113 hw_key.element[i].output_format = output_format; 114 hw_key.element[i].output_offset = dst_offset; 115 116 dst_offset += emit_sz; 117 } 118 119 hw_key.nr_elements = vinfo->num_attribs; 120 hw_key.output_stride = vinfo->size * 4; 121 122 if (!emit->translate || 123 translate_key_compare(&emit->translate->key, &hw_key) != 0) 124 { 125 translate_key_sanitize(&hw_key); 126 emit->translate = translate_cache_find(emit->cache, &hw_key); 127 } 128} 129 130 131void draw_pt_emit( struct pt_emit *emit, 132 const float (*vertex_data)[4], 133 unsigned vertex_count, 134 unsigned stride, 135 const ushort *elts, 136 unsigned count ) 137{ 138 struct draw_context *draw = emit->draw; 139 struct translate *translate = emit->translate; 140 struct vbuf_render *render = draw->render; 141 void *hw_verts; 142 143 /* XXX: need to flush to get prim_vbuf.c to release its allocation?? 144 */ 145 draw_do_flush( draw, DRAW_FLUSH_BACKEND ); 146 147 hw_verts = render->allocate_vertices(render, 148 (ushort)translate->key.output_stride, 149 (ushort)vertex_count); 150 if (!hw_verts) { 151 assert(0); 152 return; 153 } 154 155 translate->set_buffer(translate, 156 0, 157 vertex_data, 158 stride ); 159 160 translate->set_buffer(translate, 161 1, 162 &draw->rasterizer->point_size, 163 0); 164 165 translate->run( translate, 166 0, 167 vertex_count, 168 hw_verts ); 169 170 render->draw(render, 171 elts, 172 count); 173 174 render->release_vertices(render, 175 hw_verts, 176 translate->key.output_stride, 177 vertex_count); 178} 179 180 181struct pt_emit *draw_pt_emit_create( struct draw_context *draw ) 182{ 183 struct pt_emit *emit = CALLOC_STRUCT(pt_emit); 184 if (!emit) 185 return NULL; 186 187 emit->draw = draw; 188 emit->cache = translate_cache_create(); 189 if (!emit->cache) { 190 FREE(emit); 191 return NULL; 192 } 193 194 return emit; 195} 196 197void draw_pt_emit_destroy( struct pt_emit *emit ) 198{ 199 if (emit->cache) 200 translate_cache_destroy(emit->cache); 201 202 FREE(emit); 203} 204