draw_pt_fetch.c revision e1180c2d694851ed12e86027aa406ee20546e6d3
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 36#include "cso_cache/cso_cache.h" 37#include "cso_cache/cso_hash.h" 38 39struct pt_fetch { 40 struct draw_context *draw; 41 42 struct translate *translate; 43 44 unsigned vertex_size; 45 46 struct cso_hash *hash; 47}; 48 49static INLINE unsigned translate_hash_key_size(struct translate_key *key) 50{ 51 unsigned size = sizeof(struct translate_key) - 52 sizeof(struct translate_element) * (PIPE_MAX_ATTRIBS - key->nr_elements); 53 return size; 54} 55 56static INLINE unsigned create_key(struct translate_key *key) 57{ 58 unsigned hash_key; 59 unsigned size = translate_hash_key_size(key); 60 /*debug_printf("key size = %d, (els = %d)\n", 61 size, key->nr_elements);*/ 62 hash_key = cso_construct_key(key, size); 63 return hash_key; 64} 65 66static struct translate *cached_translate(struct pt_fetch *fetch, 67 struct translate_key *key) 68{ 69 unsigned hash_key = create_key(key); 70 struct translate *translate = (struct translate*) 71 cso_hash_find_data_from_template(fetch->hash, 72 hash_key, 73 key, sizeof(*key)); 74 75 if (!translate) { 76 /* create/insert */ 77 translate = translate_create(key); 78 cso_hash_insert(fetch->hash, hash_key, translate); 79 } 80 81 return translate; 82} 83 84static INLINE void delete_translates(struct pt_fetch *fetch) 85{ 86 struct cso_hash *hash = fetch->hash; 87 struct cso_hash_iter iter = cso_hash_first_node(hash); 88 while (!cso_hash_iter_is_null(iter)) { 89 struct translate *state = (struct translate*)cso_hash_iter_data(iter); 90 iter = cso_hash_iter_next(iter); 91 if (state) { 92 state->release(state); 93 } 94 } 95} 96 97/* Perform the fetch from API vertex elements & vertex buffers, to a 98 * contiguous set of float[4] attributes as required for the 99 * vertex_shader->run_linear() method. 100 * 101 * This is used in all cases except pure passthrough 102 * (draw_pt_fetch_emit.c) which has its own version to translate 103 * directly to hw vertices. 104 * 105 */ 106void draw_pt_fetch_prepare( struct pt_fetch *fetch, 107 unsigned vertex_size ) 108{ 109 struct draw_context *draw = fetch->draw; 110 unsigned i, nr = 0; 111 unsigned dst_offset = 0; 112 struct translate_key key; 113 114 fetch->vertex_size = vertex_size; 115 116 memset(&key, 0, sizeof(key)); 117 118 /* Always emit/leave space for a vertex header. 119 * 120 * It's worth considering whether the vertex headers should contain 121 * a pointer to the 'data', rather than having it inline. 122 * Something to look at after we've fully switched over to the pt 123 * paths. 124 */ 125 { 126 /* Need to set header->vertex_id = 0xffff somehow. 127 */ 128 key.element[nr].input_format = PIPE_FORMAT_R32_FLOAT; 129 key.element[nr].input_buffer = draw->pt.nr_vertex_buffers; 130 key.element[nr].input_offset = 0; 131 key.element[nr].output_format = PIPE_FORMAT_R32_FLOAT; 132 key.element[nr].output_offset = dst_offset; 133 dst_offset += 1 * sizeof(float); 134 nr++; 135 136 137 /* Just leave the clip[] array untouched. 138 */ 139 dst_offset += 4 * sizeof(float); 140 } 141 142 143 for (i = 0; i < draw->pt.nr_vertex_elements; i++) { 144 key.element[nr].input_format = draw->pt.vertex_element[i].src_format; 145 key.element[nr].input_buffer = draw->pt.vertex_element[i].vertex_buffer_index; 146 key.element[nr].input_offset = draw->pt.vertex_element[i].src_offset; 147 key.element[nr].output_format = PIPE_FORMAT_R32G32B32A32_FLOAT; 148 key.element[nr].output_offset = dst_offset; 149 150 dst_offset += 4 * sizeof(float); 151 nr++; 152 } 153 154 assert(dst_offset <= vertex_size); 155 156 key.nr_elements = nr; 157 key.output_stride = vertex_size; 158 159 160 /* Don't bother with caching at this stage: 161 */ 162 if (!fetch->translate || 163 memcmp(&fetch->translate->key, &key, sizeof(key)) != 0) 164 { 165 fetch->translate = cached_translate(fetch, &key); 166 167 { 168 static struct vertex_header vh = { 0, 0, 0, 0xffff }; 169 fetch->translate->set_buffer(fetch->translate, 170 draw->pt.nr_vertex_buffers, 171 &vh, 172 0); 173 } 174 } 175} 176 177 178 179 180void draw_pt_fetch_run( struct pt_fetch *fetch, 181 const unsigned *elts, 182 unsigned count, 183 char *verts ) 184{ 185 struct draw_context *draw = fetch->draw; 186 struct translate *translate = fetch->translate; 187 unsigned i; 188 189 for (i = 0; i < draw->pt.nr_vertex_buffers; i++) { 190 translate->set_buffer(translate, 191 i, 192 ((char *)draw->pt.user.vbuffer[i] + 193 draw->pt.vertex_buffer[i].buffer_offset), 194 draw->pt.vertex_buffer[i].pitch ); 195 } 196 197 translate->run_elts( translate, 198 elts, 199 count, 200 verts ); 201} 202 203 204struct pt_fetch *draw_pt_fetch_create( struct draw_context *draw ) 205{ 206 struct pt_fetch *fetch = CALLOC_STRUCT(pt_fetch); 207 if (!fetch) 208 return NULL; 209 210 fetch->draw = draw; 211 fetch->hash = cso_hash_create(); 212 return fetch; 213} 214 215void draw_pt_fetch_destroy( struct pt_fetch *fetch ) 216{ 217 delete_translates(fetch); 218 cso_hash_delete(fetch->hash); 219 220 FREE(fetch); 221} 222 223