Home | History | Annotate | Download | only in shader
      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 (at) 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
     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
     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
    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
    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
    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
    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
    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