1 /* 2 * Copyright 2010 Marek Olk <maraeo (at) gmail.com> 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22 23 #include "pipe/p_context.h" 24 #include "util/u_index_modify.h" 25 #include "util/u_inlines.h" 26 27 /* Ubyte indices. */ 28 29 void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, 30 struct pipe_index_buffer *ib, 31 int index_bias, 32 unsigned start, 33 unsigned count, 34 void *out) 35 { 36 struct pipe_transfer *src_transfer = NULL; 37 const unsigned char *in_map; 38 unsigned short *out_map = out; 39 unsigned i; 40 41 if (ib->user_buffer) { 42 in_map = ib->user_buffer; 43 } else { 44 in_map = pipe_buffer_map(context, ib->buffer, 45 PIPE_TRANSFER_READ | 46 PIPE_TRANSFER_UNSYNCHRONIZED, 47 &src_transfer); 48 } 49 in_map += start; 50 51 for (i = 0; i < count; i++) { 52 *out_map = (unsigned short)(*in_map + index_bias); 53 in_map++; 54 out_map++; 55 } 56 57 if (src_transfer) 58 pipe_buffer_unmap(context, src_transfer); 59 } 60 61 void util_shorten_ubyte_elts(struct pipe_context *context, 62 struct pipe_index_buffer *ib, 63 struct pipe_resource **out_buf, 64 int index_bias, 65 unsigned start, 66 unsigned count) 67 { 68 struct pipe_resource* new_elts; 69 unsigned short *out_map; 70 struct pipe_transfer *dst_transfer; 71 72 new_elts = pipe_buffer_create(context->screen, 73 PIPE_BIND_INDEX_BUFFER, 74 PIPE_USAGE_STATIC, 75 2 * count); 76 77 out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE, 78 &dst_transfer); 79 util_shorten_ubyte_elts_to_userptr(context, ib, index_bias, 80 start, count, out_map); 81 pipe_buffer_unmap(context, dst_transfer); 82 83 pipe_resource_reference(out_buf, NULL); 84 *out_buf = new_elts; 85 } 86 87 88 /* Ushort indices. */ 89 90 void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, 91 struct pipe_index_buffer *ib, 92 int index_bias, 93 unsigned start, unsigned count, 94 void *out) 95 { 96 struct pipe_transfer *in_transfer = NULL; 97 const unsigned short *in_map; 98 unsigned short *out_map = out; 99 unsigned i; 100 101 if (ib->user_buffer) { 102 in_map = ib->user_buffer; 103 } else { 104 in_map = pipe_buffer_map(context, ib->buffer, 105 PIPE_TRANSFER_READ | 106 PIPE_TRANSFER_UNSYNCHRONIZED, 107 &in_transfer); 108 } 109 in_map += start; 110 111 for (i = 0; i < count; i++) { 112 *out_map = (unsigned short)(*in_map + index_bias); 113 in_map++; 114 out_map++; 115 } 116 117 if (in_transfer) 118 pipe_buffer_unmap(context, in_transfer); 119 } 120 121 void util_rebuild_ushort_elts(struct pipe_context *context, 122 struct pipe_index_buffer *ib, 123 struct pipe_resource **out_buf, 124 int index_bias, 125 unsigned start, unsigned count) 126 { 127 struct pipe_transfer *out_transfer = NULL; 128 struct pipe_resource *new_elts; 129 unsigned short *out_map; 130 131 new_elts = pipe_buffer_create(context->screen, 132 PIPE_BIND_INDEX_BUFFER, 133 PIPE_USAGE_STATIC, 134 2 * count); 135 136 out_map = pipe_buffer_map(context, new_elts, 137 PIPE_TRANSFER_WRITE, &out_transfer); 138 util_rebuild_ushort_elts_to_userptr(context, ib, index_bias, 139 start, count, out_map); 140 pipe_buffer_unmap(context, out_transfer); 141 142 pipe_resource_reference(out_buf, NULL); 143 *out_buf = new_elts; 144 } 145 146 147 /* Uint indices. */ 148 149 void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, 150 struct pipe_index_buffer *ib, 151 int index_bias, 152 unsigned start, unsigned count, 153 void *out) 154 { 155 struct pipe_transfer *in_transfer = NULL; 156 const unsigned int *in_map; 157 unsigned int *out_map = out; 158 unsigned i; 159 160 if (ib->user_buffer) { 161 in_map = ib->user_buffer; 162 } else { 163 in_map = pipe_buffer_map(context, ib->buffer, 164 PIPE_TRANSFER_READ | 165 PIPE_TRANSFER_UNSYNCHRONIZED, 166 &in_transfer); 167 } 168 in_map += start; 169 170 for (i = 0; i < count; i++) { 171 *out_map = (unsigned int)(*in_map + index_bias); 172 in_map++; 173 out_map++; 174 } 175 176 if (in_transfer) 177 pipe_buffer_unmap(context, in_transfer); 178 } 179 180 void util_rebuild_uint_elts(struct pipe_context *context, 181 struct pipe_index_buffer *ib, 182 struct pipe_resource **out_buf, 183 int index_bias, 184 unsigned start, unsigned count) 185 { 186 struct pipe_transfer *out_transfer = NULL; 187 struct pipe_resource *new_elts; 188 unsigned int *out_map; 189 190 new_elts = pipe_buffer_create(context->screen, 191 PIPE_BIND_INDEX_BUFFER, 192 PIPE_USAGE_STATIC, 193 2 * count); 194 195 out_map = pipe_buffer_map(context, new_elts, 196 PIPE_TRANSFER_WRITE, &out_transfer); 197 util_rebuild_uint_elts_to_userptr(context, ib, index_bias, 198 start, count, out_map); 199 pipe_buffer_unmap(context, out_transfer); 200 201 pipe_resource_reference(out_buf, NULL); 202 *out_buf = new_elts; 203 } 204