1 // 2 // Copyright 2012 Francisco Jerez 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 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 // SOFTWARE. 21 // 22 23 #include <sstream> 24 25 #include "core/compiler.hpp" 26 27 #include "tgsi/tgsi_parse.h" 28 #include "tgsi/tgsi_text.h" 29 #include "util/u_memory.h" 30 31 using namespace clover; 32 33 namespace { 34 void 35 read_header(const std::string &header, module &m) { 36 std::istringstream ls(header); 37 std::string line; 38 39 while (getline(ls, line)) { 40 std::istringstream ts(line); 41 std::string name, tok; 42 module::size_t offset; 43 compat::vector<module::argument> args; 44 45 if (!(ts >> name)) 46 continue; 47 48 if (!(ts >> offset)) 49 throw build_error("invalid kernel start address"); 50 51 while (ts >> tok) { 52 if (tok == "scalar") 53 args.push_back({ module::argument::scalar, 4 }); 54 else if (tok == "global") 55 args.push_back({ module::argument::global, 4 }); 56 else if (tok == "local") 57 args.push_back({ module::argument::local, 4 }); 58 else if (tok == "constant") 59 args.push_back({ module::argument::constant, 4 }); 60 else if (tok == "image2d_rd") 61 args.push_back({ module::argument::image2d_rd, 4 }); 62 else if (tok == "image2d_wr") 63 args.push_back({ module::argument::image2d_wr, 4 }); 64 else if (tok == "image3d_rd") 65 args.push_back({ module::argument::image3d_rd, 4 }); 66 else if (tok == "image3d_wr") 67 args.push_back({ module::argument::image3d_wr, 4 }); 68 else if (tok == "sampler") 69 args.push_back({ module::argument::sampler, 0 }); 70 else 71 throw build_error("invalid kernel argument"); 72 } 73 74 m.syms.push_back({ name, 0, offset, args }); 75 } 76 } 77 78 void 79 read_body(const char *source, module &m) { 80 tgsi_token prog[1024]; 81 82 if (!tgsi_text_translate(source, prog, Elements(prog))) 83 throw build_error("translate failed"); 84 85 unsigned sz = tgsi_num_tokens(prog) * sizeof(tgsi_token); 86 m.secs.push_back({ 0, module::section::text, sz, { (char *)prog, sz } }); 87 } 88 } 89 90 module 91 clover::compile_program_tgsi(const compat::string &source) { 92 const char *body = source.find("COMP\n"); 93 module m; 94 95 read_header({ source.begin(), body }, m); 96 read_body(body, m); 97 98 return m; 99 } 100