1 /*
2  * Copyright 2010 Marek Olšák <maraeo@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 
util_shorten_ubyte_elts_to_userptr(struct pipe_context * context,const struct pipe_draw_info * info,unsigned add_transfer_flags,int index_bias,unsigned start,unsigned count,void * out)29 void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
30 					const struct pipe_draw_info *info,
31                                         unsigned add_transfer_flags,
32 					int index_bias,
33 					unsigned start,
34 					unsigned count,
35 					void *out)
36 {
37     struct pipe_transfer *src_transfer = NULL;
38     const unsigned char *in_map;
39     unsigned short *out_map = out;
40     unsigned i;
41 
42     if (info->has_user_indices) {
43        in_map = info->index.user;
44     } else {
45        in_map = pipe_buffer_map(context, info->index.resource,
46                                 PIPE_MAP_READ |
47                                 add_transfer_flags,
48                                 &src_transfer);
49     }
50     in_map += start;
51 
52     for (i = 0; i < count; i++) {
53         *out_map = (unsigned short)(*in_map + index_bias);
54         in_map++;
55         out_map++;
56     }
57 
58     if (src_transfer)
59        pipe_buffer_unmap(context, src_transfer);
60 }
61 
62 /* Ushort indices. */
63 
util_rebuild_ushort_elts_to_userptr(struct pipe_context * context,const struct pipe_draw_info * info,unsigned add_transfer_flags,int index_bias,unsigned start,unsigned count,void * out)64 void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
65 					 const struct pipe_draw_info *info,
66                                          unsigned add_transfer_flags,
67 					 int index_bias,
68 					 unsigned start, unsigned count,
69 					 void *out)
70 {
71     struct pipe_transfer *in_transfer = NULL;
72     const unsigned short *in_map;
73     unsigned short *out_map = out;
74     unsigned i;
75 
76     if (info->has_user_indices) {
77        in_map = info->index.user;
78     } else {
79        in_map = pipe_buffer_map(context, info->index.resource,
80                                 PIPE_MAP_READ |
81                                 add_transfer_flags,
82                                 &in_transfer);
83     }
84     in_map += start;
85 
86     for (i = 0; i < count; i++) {
87         *out_map = (unsigned short)(*in_map + index_bias);
88         in_map++;
89         out_map++;
90     }
91 
92     if (in_transfer)
93        pipe_buffer_unmap(context, in_transfer);
94 }
95 
96 /* Uint indices. */
97 
util_rebuild_uint_elts_to_userptr(struct pipe_context * context,const struct pipe_draw_info * info,unsigned add_transfer_flags,int index_bias,unsigned start,unsigned count,void * out)98 void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
99 				       const struct pipe_draw_info *info,
100                                        unsigned add_transfer_flags,
101 				       int index_bias,
102 				       unsigned start, unsigned count,
103 				       void *out)
104 {
105     struct pipe_transfer *in_transfer = NULL;
106     const unsigned int *in_map;
107     unsigned int *out_map = out;
108     unsigned i;
109 
110     if (info->has_user_indices) {
111        in_map = info->index.user;
112     } else {
113        in_map = pipe_buffer_map(context, info->index.resource,
114                                 PIPE_MAP_READ |
115                                 add_transfer_flags,
116                                 &in_transfer);
117     }
118     in_map += start;
119 
120     for (i = 0; i < count; i++) {
121         *out_map = (unsigned int)(*in_map + index_bias);
122         in_map++;
123         out_map++;
124     }
125 
126     if (in_transfer)
127        pipe_buffer_unmap(context, in_transfer);
128 }
129