as.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (c) 2015-2016 The Khronos Group Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include <cstdio>
  15. #include <cstring>
  16. #include <vector>
  17. #include "source/spirv_target_env.h"
  18. #include "spirv-tools/libspirv.h"
  19. #include "tools/io.h"
  20. void print_usage(char* argv0) {
  21. printf(
  22. R"(%s - Create a SPIR-V binary module from SPIR-V assembly text
  23. Usage: %s [options] [<filename>]
  24. The SPIR-V assembly text is read from <filename>. If no file is specified,
  25. or if the filename is "-", then the assembly text is read from standard input.
  26. The SPIR-V binary module is written to file "out.spv", unless the -o option
  27. is used.
  28. Options:
  29. -h, --help Print this help.
  30. -o <filename> Set the output filename. Use '-' to mean stdout.
  31. --version Display assembler version information.
  32. --preserve-numeric-ids
  33. Numeric IDs in the binary will have the same values as in the
  34. source. Non-numeric IDs are allocated by filling in the gaps,
  35. starting with 1 and going up.
  36. --target-env {vulkan1.0|vulkan1.1|spv1.0|spv1.1|spv1.2|spv1.3}
  37. Use Vulkan 1.0, Vulkan 1.1, SPIR-V 1.0, SPIR-V 1.1,
  38. SPIR-V 1.2, or SPIR-V 1.3
  39. )",
  40. argv0, argv0);
  41. }
  42. static const auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_3;
  43. int main(int argc, char** argv) {
  44. const char* inFile = nullptr;
  45. const char* outFile = nullptr;
  46. uint32_t options = 0;
  47. spv_target_env target_env = kDefaultEnvironment;
  48. for (int argi = 1; argi < argc; ++argi) {
  49. if ('-' == argv[argi][0]) {
  50. switch (argv[argi][1]) {
  51. case 'h': {
  52. print_usage(argv[0]);
  53. return 0;
  54. }
  55. case 'o': {
  56. if (!outFile && argi + 1 < argc) {
  57. outFile = argv[++argi];
  58. } else {
  59. print_usage(argv[0]);
  60. return 1;
  61. }
  62. } break;
  63. case 0: {
  64. // Setting a filename of "-" to indicate stdin.
  65. if (!inFile) {
  66. inFile = argv[argi];
  67. } else {
  68. fprintf(stderr, "error: More than one input file specified\n");
  69. return 1;
  70. }
  71. } break;
  72. case '-': {
  73. // Long options
  74. if (0 == strcmp(argv[argi], "--version")) {
  75. printf("%s\n", spvSoftwareVersionDetailsString());
  76. printf("Target: %s\n",
  77. spvTargetEnvDescription(kDefaultEnvironment));
  78. return 0;
  79. } else if (0 == strcmp(argv[argi], "--help")) {
  80. print_usage(argv[0]);
  81. return 0;
  82. } else if (0 == strcmp(argv[argi], "--preserve-numeric-ids")) {
  83. options |= SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS;
  84. } else if (0 == strcmp(argv[argi], "--target-env")) {
  85. if (argi + 1 < argc) {
  86. const auto env_str = argv[++argi];
  87. if (!spvParseTargetEnv(env_str, &target_env)) {
  88. fprintf(stderr, "error: Unrecognized target env: %s\n",
  89. env_str);
  90. return 1;
  91. }
  92. } else {
  93. fprintf(stderr, "error: Missing argument to --target-env\n");
  94. return 1;
  95. }
  96. } else {
  97. fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]);
  98. print_usage(argv[0]);
  99. return 1;
  100. }
  101. } break;
  102. default:
  103. fprintf(stderr, "error: Unrecognized option: %s\n\n", argv[argi]);
  104. print_usage(argv[0]);
  105. return 1;
  106. }
  107. } else {
  108. if (!inFile) {
  109. inFile = argv[argi];
  110. } else {
  111. fprintf(stderr, "error: More than one input file specified\n");
  112. return 1;
  113. }
  114. }
  115. }
  116. if (!outFile) {
  117. outFile = "out.spv";
  118. }
  119. std::vector<char> contents;
  120. if (!ReadFile<char>(inFile, "r", &contents)) return 1;
  121. spv_binary binary;
  122. spv_diagnostic diagnostic = nullptr;
  123. spv_context context = spvContextCreate(target_env);
  124. spv_result_t error = spvTextToBinaryWithOptions(
  125. context, contents.data(), contents.size(), options, &binary, &diagnostic);
  126. spvContextDestroy(context);
  127. if (error) {
  128. spvDiagnosticPrint(diagnostic);
  129. spvDiagnosticDestroy(diagnostic);
  130. return error;
  131. }
  132. if (!WriteFile<uint32_t>(outFile, "wb", binary->code, binary->wordCount)) {
  133. spvBinaryDestroy(binary);
  134. return 1;
  135. }
  136. spvBinaryDestroy(binary);
  137. return 0;
  138. }