• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Mesa 3-D graphics library
3  *
4  * Copyright (C) 2012-2013 LunarG, Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included
14  * in all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  *
24  * Authors:
25  *    Chia-I Wu <olv@lunarg.com>
26  */
27 
28 #ifndef TOY_HELPERS_H
29 #define TOY_HELPERS_H
30 
31 #include "toy_compiler.h"
32 
33 /**
34  * Transpose a dst operand.
35  *
36  * Instead of processing a single vertex with each of its attributes in one
37  * register, such as
38  *
39  *   r0 = [x0, y0, z0, w0]
40  *
41  * we want to process four vertices at a time
42  *
43  *   r0 = [x0, y0, z0, w0]
44  *   r1 = [x1, y1, z1, w1]
45  *   r2 = [x2, y2, z2, w2]
46  *   r3 = [x3, y3, z3, w3]
47  *
48  * but with the attribute data "transposed"
49  *
50  *   r0 = [x0, x1, x2, x3]
51  *   r1 = [y0, y1, y2, y3]
52  *   r2 = [z0, z1, z2, z3]
53  *   r3 = [w0, w1, w2, w3]
54  *
55  * This is also known as the SoA form.
56  */
57 static inline void
tdst_transpose(struct toy_dst dst,struct toy_dst * trans)58 tdst_transpose(struct toy_dst dst, struct toy_dst *trans)
59 {
60    int i;
61 
62    switch (dst.file) {
63    case TOY_FILE_VRF:
64       assert(!dst.indirect);
65       for (i = 0; i < 4; i++) {
66          if (dst.writemask & (1 << i)) {
67             trans[i] = tdst_offset(dst, i, 0);
68             trans[i].writemask = TOY_WRITEMASK_XYZW;
69          }
70          else {
71             trans[i] = tdst_null();
72          }
73       }
74       break;
75    case TOY_FILE_ARF:
76       assert(tdst_is_null(dst));
77       for (i = 0; i < 4; i++)
78          trans[i] = dst;
79       break;
80    case TOY_FILE_GRF:
81    case TOY_FILE_MRF:
82    case TOY_FILE_IMM:
83    default:
84       assert(!"unexpected file in dst transposition");
85       for (i = 0; i < 4; i++)
86          trans[i] = tdst_null();
87       break;
88    }
89 }
90 
91 /**
92  * Transpose a src operand.
93  */
94 static inline void
tsrc_transpose(struct toy_src src,struct toy_src * trans)95 tsrc_transpose(struct toy_src src, struct toy_src *trans)
96 {
97    const enum toy_swizzle swizzle[4] = {
98       src.swizzle_x, src.swizzle_y,
99       src.swizzle_z, src.swizzle_w,
100    };
101    int i;
102 
103    switch (src.file) {
104    case TOY_FILE_VRF:
105       assert(!src.indirect);
106       for (i = 0; i < 4; i++) {
107          trans[i] = tsrc_offset(src, swizzle[i], 0);
108          trans[i].swizzle_x = TOY_SWIZZLE_X;
109          trans[i].swizzle_y = TOY_SWIZZLE_Y;
110          trans[i].swizzle_z = TOY_SWIZZLE_Z;
111          trans[i].swizzle_w = TOY_SWIZZLE_W;
112       }
113       break;
114    case TOY_FILE_ARF:
115       assert(tsrc_is_null(src));
116       /* fall through */
117    case TOY_FILE_IMM:
118       for (i = 0; i < 4; i++)
119          trans[i] = src;
120       break;
121    case TOY_FILE_GRF:
122    case TOY_FILE_MRF:
123    default:
124       assert(!"unexpected file in src transposition");
125       for (i = 0; i < 4; i++)
126          trans[i] = tsrc_null();
127       break;
128    }
129 }
130 
131 static inline struct toy_src
tsrc_imm_mdesc(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool header_present,uint32_t function_control)132 tsrc_imm_mdesc(const struct toy_compiler *tc,
133                bool eot,
134                unsigned message_length,
135                unsigned response_length,
136                bool header_present,
137                uint32_t function_control)
138 {
139    uint32_t desc;
140 
141    assert(message_length >= 1 && message_length <= 15);
142    assert(response_length >= 0 && response_length <= 16);
143    assert(function_control < 1 << 19);
144 
145    desc = eot << 31 |
146           message_length << 25 |
147           response_length << 20 |
148           header_present << 19 |
149           function_control;
150 
151    return tsrc_imm_ud(desc);
152 }
153 
154 static inline struct toy_src
tsrc_imm_mdesc_sampler(const struct toy_compiler * tc,unsigned message_length,unsigned response_length,bool header_present,unsigned simd_mode,unsigned message_type,unsigned sampler_index,unsigned binding_table_index)155 tsrc_imm_mdesc_sampler(const struct toy_compiler *tc,
156                        unsigned message_length,
157                        unsigned response_length,
158                        bool header_present,
159                        unsigned simd_mode,
160                        unsigned message_type,
161                        unsigned sampler_index,
162                        unsigned binding_table_index)
163 {
164    const bool eot = false;
165    uint32_t ctrl;
166 
167    assert(simd_mode < 4);
168    assert(sampler_index < 16);
169    assert(binding_table_index < 256);
170 
171    if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
172       ctrl = simd_mode << 17 |
173              message_type << 12 |
174              sampler_index << 8 |
175              binding_table_index;
176    }
177    else {
178       ctrl = simd_mode << 16 |
179              message_type << 12 |
180              sampler_index << 8 |
181              binding_table_index;
182    }
183 
184    return tsrc_imm_mdesc(tc, eot, message_length,
185          response_length, header_present, ctrl);
186 }
187 
188 static inline struct toy_src
tsrc_imm_mdesc_data_port(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool header_present,bool send_write_commit_message,unsigned message_type,unsigned message_specific_control,unsigned binding_table_index)189 tsrc_imm_mdesc_data_port(const struct toy_compiler *tc,
190                          bool eot,
191                          unsigned message_length,
192                          unsigned response_length,
193                          bool header_present,
194                          bool send_write_commit_message,
195                          unsigned message_type,
196                          unsigned message_specific_control,
197                          unsigned binding_table_index)
198 {
199    uint32_t ctrl;
200 
201    if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
202       assert(!send_write_commit_message);
203       assert((message_specific_control & 0x3f00) == message_specific_control);
204 
205       ctrl = message_type << 14 |
206              (message_specific_control & 0x3f00) |
207              binding_table_index;
208    }
209    else {
210       assert(!send_write_commit_message ||
211              message_type == GEN6_MSG_DP_SVB_WRITE);
212       assert((message_specific_control & 0x1f00) == message_specific_control);
213 
214       ctrl = send_write_commit_message << 17 |
215              message_type << 13 |
216              (message_specific_control & 0x1f00) |
217              binding_table_index;
218    }
219 
220    return tsrc_imm_mdesc(tc, eot, message_length,
221          response_length, header_present, ctrl);
222 }
223 
224 static inline struct toy_src
tsrc_imm_mdesc_data_port_scratch(const struct toy_compiler * tc,unsigned message_length,unsigned response_length,bool write_type,bool dword_mode,bool invalidate_after_read,int num_registers,int hword_offset)225 tsrc_imm_mdesc_data_port_scratch(const struct toy_compiler *tc,
226                                  unsigned message_length,
227                                  unsigned response_length,
228                                  bool write_type,
229                                  bool dword_mode,
230                                  bool invalidate_after_read,
231                                  int num_registers,
232                                  int hword_offset)
233 {
234    const bool eot = false;
235    const bool header_present = true;
236    uint32_t ctrl;
237 
238    assert(ilo_dev_gen(tc->dev) >= ILO_GEN(7));
239    assert(num_registers == 1 || num_registers == 2 || num_registers == 4);
240 
241    ctrl = 1 << 18 |
242           write_type << 17 |
243           dword_mode << 16 |
244           invalidate_after_read << 15 |
245           (num_registers - 1) << 12 |
246           hword_offset;
247 
248    return tsrc_imm_mdesc(tc, eot, message_length,
249          response_length, header_present, ctrl);
250 }
251 
252 static inline struct toy_src
tsrc_imm_mdesc_urb(const struct toy_compiler * tc,bool eot,unsigned message_length,unsigned response_length,bool complete,bool used,bool allocate,unsigned swizzle_control,unsigned global_offset,unsigned urb_opcode)253 tsrc_imm_mdesc_urb(const struct toy_compiler *tc,
254                    bool eot,
255                    unsigned message_length,
256                    unsigned response_length,
257                    bool complete,
258                    bool used,
259                    bool allocate,
260                    unsigned swizzle_control,
261                    unsigned global_offset,
262                    unsigned urb_opcode)
263 {
264    const bool header_present = true;
265    uint32_t ctrl;
266 
267    if (ilo_dev_gen(tc->dev) >= ILO_GEN(8)) {
268       const bool per_slot_offset = false;
269 
270       ctrl = per_slot_offset << 17 |
271              swizzle_control << 15 |
272              global_offset << 4 |
273              urb_opcode;
274    } else if (ilo_dev_gen(tc->dev) >= ILO_GEN(7)) {
275       const bool per_slot_offset = false;
276 
277       ctrl = per_slot_offset << 16 |
278              complete << 15 |
279              swizzle_control << 14 |
280              global_offset << 3 |
281              urb_opcode;
282    } else {
283       ctrl = complete << 15 |
284              used << 14 |
285              allocate << 13 |
286              swizzle_control << 10 |
287              global_offset << 4 |
288              urb_opcode;
289    }
290 
291    return tsrc_imm_mdesc(tc, eot, message_length,
292          response_length, header_present, ctrl);
293 }
294 
295 #endif /* TOY_HELPERS_H */
296