Home | History | Annotate | Line # | Download | only in sfn
      1 /* -*- mesa-c++  -*-
      2  *
      3  * Copyright (c) 2018 Collabora LTD
      4  *
      5  * Author: Gert Wollny <gert.wollny (at) collabora.com>
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a
      8  * copy of this software and associated documentation files (the "Software"),
      9  * to deal in the Software without restriction, including without limitation
     10  * on the rights to use, copy, modify, merge, publish, distribute, sub
     11  * license, and/or sell copies of the Software, and to permit persons to whom
     12  * the Software is furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice (including the next
     15  * paragraph) shall be included in all copies or substantial portions of the
     16  * Software.
     17  *
     18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     21  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
     25  */
     26 
     27 #include "sfn_instruction_fetch.h"
     28 
     29 #include "gallium/drivers/r600/r600_pipe.h"
     30 
     31 namespace r600 {
     32 
     33 /* refactor this to add status create methods for specific tasks */
     34 FetchInstruction::FetchInstruction(EVFetchInstr op,
     35                                    EVFetchType type,
     36                                    GPRVector dst,
     37                                    PValue src, int offset,
     38                                    int buffer_id, PValue buffer_offset,
     39                                    EBufferIndexMode cp_rel,
     40                                    bool use_const_field):
     41    Instruction(vtx),
     42    m_vc_opcode(op),
     43    m_fetch_type(type),
     44    m_endian_swap(vtx_es_none),
     45    m_src(src),
     46    m_dst(dst),
     47    m_offset(offset),
     48    m_is_mega_fetch(1),
     49    m_mega_fetch_count(16),
     50    m_buffer_id(buffer_id),
     51    m_semantic_id(0),
     52    m_buffer_index_mode(cp_rel),
     53    m_flags(0),
     54    m_uncached(false),
     55    m_indexed(false),
     56    m_array_base(0),
     57    m_array_size(0),
     58    m_elm_size(0),
     59    m_buffer_offset(buffer_offset),
     60    m_dest_swizzle({0,1,2,3})
     61 {
     62    if (use_const_field) {
     63       m_flags.set(vtx_use_const_field);
     64       m_data_format = fmt_invalid;
     65       m_num_format = vtx_nf_norm;
     66    } else {
     67       m_flags.set(vtx_format_comp_signed);
     68       m_data_format = fmt_32_32_32_32_float;
     69       m_num_format = vtx_nf_scaled;
     70    }
     71 
     72    add_remappable_src_value(&m_src);
     73    add_remappable_src_value(&m_buffer_offset);
     74 
     75    add_remappable_dst_value(&m_dst);
     76 }
     77 
     78 /* Resource query */
     79 FetchInstruction::FetchInstruction(EVFetchInstr vc_opcode,
     80                                    EVFetchType fetch_type,
     81                                    EVTXDataFormat data_format,
     82                                    EVFetchNumFormat num_format,
     83                                    EVFetchEndianSwap endian_swap,
     84                                    const PValue src,
     85                                    const GPRVector dst,
     86                                    uint32_t offset,
     87                                    bool is_mega_fetch,
     88                                    uint32_t mega_fetch_count,
     89                                    uint32_t buffer_id,
     90                                    uint32_t semantic_id,
     91 
     92                                    EBufferIndexMode buffer_index_mode,
     93                                    bool uncached,
     94                                    bool indexed,
     95                                    int array_base,
     96                                    int array_size,
     97                                    int elm_size,
     98                                    PValue buffer_offset,
     99                                    const std::array<int, 4>& dest_swizzle):
    100    Instruction(vtx),
    101    m_vc_opcode(vc_opcode),
    102    m_fetch_type(fetch_type),
    103    m_data_format(data_format),
    104    m_num_format(num_format),
    105    m_endian_swap(endian_swap),
    106    m_src(src),
    107    m_dst(dst),
    108    m_offset(offset),
    109    m_is_mega_fetch(is_mega_fetch),
    110    m_mega_fetch_count(mega_fetch_count),
    111    m_buffer_id(buffer_id),
    112    m_semantic_id(semantic_id),
    113    m_buffer_index_mode(buffer_index_mode),
    114    m_uncached(uncached),
    115    m_indexed(indexed),
    116    m_array_base(array_base),
    117    m_array_size(array_size),
    118    m_elm_size(elm_size),
    119    m_buffer_offset(buffer_offset),
    120    m_dest_swizzle(dest_swizzle)
    121 {
    122    add_remappable_src_value(&m_src);
    123    add_remappable_dst_value(&m_dst);
    124    add_remappable_src_value(&m_buffer_offset);
    125 }
    126 
    127 FetchInstruction::FetchInstruction(GPRVector dst,
    128                                    PValue src,
    129                                    int buffer_id, PValue buffer_offset,
    130                                    EVTXDataFormat format,
    131                                    EVFetchNumFormat num_format):
    132    Instruction(vtx),
    133    m_vc_opcode(vc_fetch),
    134    m_fetch_type(no_index_offset),
    135    m_data_format(format),
    136    m_num_format(num_format),
    137    m_endian_swap(vtx_es_none),
    138    m_src(src),
    139    m_dst(dst),
    140    m_offset(0),
    141    m_is_mega_fetch(0),
    142    m_mega_fetch_count(0),
    143    m_buffer_id(buffer_id),
    144    m_semantic_id(0),
    145    m_buffer_index_mode(bim_none),
    146    m_flags(0),
    147    m_uncached(false),
    148    m_indexed(false),
    149    m_array_base(0),
    150    m_array_size(0),
    151    m_elm_size(1),
    152    m_buffer_offset(buffer_offset),
    153    m_dest_swizzle({0,1,2,3})
    154 {
    155    m_flags.set(vtx_format_comp_signed);
    156 
    157    add_remappable_src_value(&m_src);
    158    add_remappable_dst_value(&m_dst);
    159    add_remappable_src_value(&m_buffer_offset);
    160 }
    161 
    162 
    163 /* Resource query */
    164 FetchInstruction::FetchInstruction(GPRVector dst,
    165                                    PValue src,
    166                                    int buffer_id,
    167                                    EBufferIndexMode cp_rel):
    168    Instruction(vtx),
    169    m_vc_opcode(vc_get_buf_resinfo),
    170    m_fetch_type(no_index_offset),
    171    m_data_format(fmt_32_32_32_32),
    172    m_num_format(vtx_nf_norm),
    173    m_endian_swap(vtx_es_none),
    174    m_src(src),
    175    m_dst(dst),
    176    m_offset(0),
    177    m_is_mega_fetch(0),
    178    m_mega_fetch_count(16),
    179    m_buffer_id(buffer_id),
    180    m_semantic_id(0),
    181    m_buffer_index_mode(cp_rel),
    182    m_flags(0),
    183    m_uncached(false),
    184    m_indexed(false),
    185    m_array_base(0),
    186    m_array_size(0),
    187    m_elm_size(0),
    188    m_dest_swizzle({0,1,2,3})
    189 {
    190    m_flags.set(vtx_format_comp_signed);
    191    add_remappable_src_value(&m_src);
    192    add_remappable_dst_value(&m_dst);
    193    add_remappable_src_value(&m_buffer_offset);
    194 }
    195 
    196 FetchInstruction::FetchInstruction(GPRVector dst, PValue src, int scratch_size):
    197    Instruction(vtx),
    198    m_vc_opcode(vc_read_scratch),
    199    m_fetch_type(vertex_data),
    200    m_data_format(fmt_32_32_32_32),
    201    m_num_format(vtx_nf_int),
    202    m_endian_swap(vtx_es_none),
    203    m_dst(dst),
    204    m_offset(0),
    205    m_is_mega_fetch(0),
    206    m_mega_fetch_count(16),
    207    m_buffer_id(0),
    208    m_semantic_id(0),
    209    m_buffer_index_mode(bim_none),
    210    m_flags(0),
    211    m_uncached(true),
    212    m_array_base(0),
    213    m_array_size(0),
    214    m_elm_size(3),
    215    m_dest_swizzle({0,1,2,3})
    216 {
    217    if (src->type() == Value::literal) {
    218       const auto& lv = static_cast<const LiteralValue&>(*src);
    219       m_array_base = lv.value();
    220       m_indexed = false;
    221       m_src.reset(new GPRValue(0,0));
    222       m_array_size = 0;
    223    } else {
    224       m_array_base = 0;
    225       m_src = src;
    226       m_indexed = true;
    227       m_array_size = scratch_size - 1;
    228    }
    229    add_remappable_src_value(&m_src);
    230    add_remappable_dst_value(&m_dst);
    231    add_remappable_src_value(&m_buffer_offset);
    232 }
    233 
    234 void FetchInstruction::replace_values(const ValueSet& candidates, PValue new_value)
    235 {
    236    if (!m_src)
    237       return;
    238    for (auto c: candidates) {
    239       for (int i = 0; i < 4; ++i) {
    240          if (*c == *m_dst.reg_i(i))
    241             m_dst.set_reg_i(i, new_value);
    242       }
    243       if (*m_src == *c)
    244          m_src = new_value;
    245    }
    246 }
    247 
    248 
    249 bool FetchInstruction::is_equal_to(const Instruction& lhs) const
    250 {
    251    auto& l = static_cast<const FetchInstruction&>(lhs);
    252    if (m_src) {
    253       if (!l.m_src)
    254          return false;
    255       if (*m_src != *l.m_src)
    256          return false;
    257    } else {
    258       if (l.m_src)
    259          return false;
    260    }
    261 
    262    return m_vc_opcode == l.m_vc_opcode &&
    263          m_fetch_type == l.m_fetch_type &&
    264          m_data_format == l.m_data_format &&
    265          m_num_format == l.m_num_format &&
    266          m_endian_swap == l.m_endian_swap &&
    267          m_dst == l.m_dst &&
    268          m_offset == l.m_offset &&
    269          m_buffer_id == l.m_buffer_id &&
    270          m_semantic_id == l.m_semantic_id &&
    271          m_buffer_index_mode == l.m_buffer_index_mode &&
    272          m_flags == l.m_flags &&
    273          m_indexed == l.m_indexed &&
    274          m_uncached == l.m_uncached;
    275 }
    276 
    277 void FetchInstruction::set_format(EVTXDataFormat fmt)
    278 {
    279    m_data_format = fmt;
    280 }
    281 
    282 
    283 void FetchInstruction::set_dest_swizzle(const std::array<int,4>& swz)
    284 {
    285    m_dest_swizzle = swz;
    286 }
    287 
    288 void FetchInstruction::prelude_append(Instruction *instr)
    289 {
    290    assert(instr);
    291    m_prelude.push_back(PInstruction(instr));
    292 }
    293 
    294 const std::vector<PInstruction>& FetchInstruction::prelude() const
    295 {
    296    return m_prelude;
    297 }
    298 
    299 LoadFromScratch::LoadFromScratch(GPRVector dst, PValue src, int scratch_size):
    300    FetchInstruction(dst, src, scratch_size)
    301 {
    302 }
    303 
    304 FetchGDSOpResult::FetchGDSOpResult(const GPRVector dst, const PValue src):
    305    FetchInstruction(vc_fetch,
    306                     no_index_offset,
    307                     fmt_32,
    308                     vtx_nf_int,
    309                     vtx_es_none,
    310                     src,
    311                     dst,
    312                     0,
    313                     false,
    314                     0xf,
    315                     R600_IMAGE_IMMED_RESOURCE_OFFSET,
    316                     0,
    317                     bim_none,
    318                     false,
    319                     false,
    320                     0,
    321                     0,
    322                     0,
    323                     PValue(),
    324                     {0,7,7,7})
    325 {
    326    set_flag(vtx_srf_mode);
    327    set_flag(vtx_vpm);
    328 }
    329 
    330 FetchTCSIOParam::FetchTCSIOParam(GPRVector dst, PValue src, int offset):
    331    FetchInstruction(vc_fetch,
    332                     no_index_offset,
    333                     fmt_32_32_32_32,
    334                     vtx_nf_scaled,
    335                     vtx_es_none,
    336                     src,
    337                     dst,
    338                     offset,
    339                     false,
    340                     16,
    341                     R600_LDS_INFO_CONST_BUFFER,
    342                     0,
    343                     bim_none,
    344                     false,
    345                     false,
    346                     0,
    347                     0,
    348                     0,
    349                     PValue(),
    350                     {0,1,2,3})
    351 {
    352    set_flag(vtx_srf_mode);
    353    set_flag(vtx_format_comp_signed);
    354 }
    355 
    356 
    357 static const char *fmt_descr[64] = {
    358    "INVALID",
    359    "8",
    360    "4_4",
    361    "3_3_2",
    362    "RESERVED_4",
    363    "16",
    364    "16F",
    365    "8_8",
    366    "5_6_5",
    367    "6_5_5",
    368    "1_5_5_5",
    369    "4_4_4_4",
    370    "5_5_5_1",
    371    "32",
    372    "32F",
    373    "16_16",
    374    "16_16F",
    375    "8_24",
    376    "8_24F",
    377    "24_8",
    378    "24_8F",
    379    "10_11_11",
    380    "10_11_11F",
    381    "11_11_10",
    382    "11_11_10F",
    383    "2_10_10_10",
    384    "8_8_8_8",
    385    "10_10_10_2",
    386    "X24_8_32F",
    387    "32_32",
    388    "32_32F",
    389    "16_16_16_16",
    390    "16_16_16_16F",
    391    "RESERVED_33",
    392    "32_32_32_32",
    393    "32_32_32_32F",
    394    "RESERVED_36",
    395    "1",
    396    "1_REVERSED",
    397    "GB_GR",
    398    "BG_RG",
    399    "32_AS_8",
    400    "32_AS_8_8",
    401    "5_9_9_9_SHAREDEXP",
    402    "8_8_8",
    403    "16_16_16",
    404    "16_16_16F",
    405    "32_32_32",
    406    "32_32_32F",
    407    "BC1",
    408    "BC2",
    409    "BC3",
    410    "BC4",
    411    "BC5",
    412    "APC0",
    413    "APC1",
    414    "APC2",
    415    "APC3",
    416    "APC4",
    417    "APC5",
    418    "APC6",
    419    "APC7",
    420    "CTX1",
    421    "RESERVED_63"
    422 };
    423 
    424 
    425 void FetchInstruction::do_print(std::ostream& os) const
    426 {
    427    static const std::string num_format_char[] = {"norm", "int", "scaled"};
    428    static const std::string endian_swap_code[] = {
    429       "noswap", "8in16", "8in32"
    430    };
    431    static const char buffer_index_mode_char[] = "_01E";
    432    static const char *flag_string[] = {"WQM",  "CF", "signed", "no_zero",
    433                                        "nostride", "AC", "TC", "VPM"};
    434    switch (m_vc_opcode) {
    435    case vc_fetch:
    436       os << "Fetch " << m_dst;
    437       break;
    438    case vc_semantic:
    439       os << "Fetch Semantic ID:" << m_semantic_id;
    440       break;
    441    case vc_get_buf_resinfo:
    442       os << "Fetch BufResinfo:" << m_dst;
    443       break;
    444    case vc_read_scratch:
    445       os << "MEM_READ_SCRATCH:" << m_dst;
    446       break;
    447    default:
    448       os << "Fetch ERROR";
    449       return;
    450    }
    451 
    452    os << ", " << *m_src;
    453 
    454    if (m_offset)
    455       os << "+" << m_offset;
    456 
    457    os << " BUFID:" << m_buffer_id
    458       << " FMT:(" << fmt_descr[m_data_format]
    459       << " " << num_format_char[m_num_format]
    460       << " " << endian_swap_code[m_endian_swap]
    461       << ")";
    462    if (m_buffer_index_mode > 0)
    463       os << " IndexMode:" << buffer_index_mode_char[m_buffer_index_mode];
    464 
    465 
    466    if (m_is_mega_fetch)
    467       os << " MFC:" << m_mega_fetch_count;
    468    else
    469       os << " mfc*:" << m_mega_fetch_count;
    470 
    471    if (m_flags.any()) {
    472       os << " Flags:";
    473       for( int i = 0; i < vtx_unknown; ++i) {
    474          if (m_flags.test(i))
    475             os << ' ' << flag_string[i];
    476       }
    477    }
    478 }
    479 
    480 }
    481