extract_source_test.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright (c) 2023 Google LLC.
  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 "tools/objdump/extract_source.h"
  15. #include <gtest/gtest.h>
  16. #include <string>
  17. #include "source/opt/build_module.h"
  18. #include "source/opt/ir_context.h"
  19. #include "spirv-tools/libspirv.hpp"
  20. #include "tools/util/cli_consumer.h"
  21. namespace {
  22. constexpr auto kDefaultEnvironment = SPV_ENV_UNIVERSAL_1_6;
  23. std::pair<bool, std::unordered_map<std::string, std::string>> ExtractSource(
  24. const std::string& spv_source) {
  25. std::unique_ptr<spvtools::opt::IRContext> ctx = spvtools::BuildModule(
  26. kDefaultEnvironment, spvtools::utils::CLIMessageConsumer, spv_source,
  27. spvtools::SpirvTools::kDefaultAssembleOption |
  28. SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
  29. std::vector<uint32_t> binary;
  30. ctx->module()->ToBinary(&binary, /* skip_nop = */ false);
  31. std::unordered_map<std::string, std::string> output;
  32. bool result = ExtractSourceFromModule(binary, &output);
  33. return std::make_pair(result, std::move(output));
  34. }
  35. } // namespace
  36. TEST(ExtractSourceTest, no_debug) {
  37. std::string source = R"(
  38. OpCapability Shader
  39. OpCapability Linkage
  40. OpMemoryModel Logical GLSL450
  41. %void = OpTypeVoid
  42. %2 = OpTypeFunction %void
  43. %bool = OpTypeBool
  44. %4 = OpUndef %bool
  45. %5 = OpFunction %void None %2
  46. %6 = OpLabel
  47. OpReturn
  48. OpFunctionEnd
  49. )";
  50. auto[success, result] = ExtractSource(source);
  51. ASSERT_TRUE(success);
  52. ASSERT_TRUE(result.size() == 0);
  53. }
  54. TEST(ExtractSourceTest, SimpleSource) {
  55. std::string source = R"(
  56. OpCapability Shader
  57. OpMemoryModel Logical GLSL450
  58. OpEntryPoint GLCompute %1 "compute_1"
  59. OpExecutionMode %1 LocalSize 1 1 1
  60. %2 = OpString "compute.hlsl"
  61. OpSource HLSL 660 %2 "[numthreads(1, 1, 1)] void compute_1(){ }"
  62. OpName %1 "compute_1"
  63. %3 = OpTypeVoid
  64. %4 = OpTypeFunction %3
  65. %1 = OpFunction %3 None %4
  66. %5 = OpLabel
  67. OpLine %2 1 41
  68. OpReturn
  69. OpFunctionEnd
  70. )";
  71. auto[success, result] = ExtractSource(source);
  72. ASSERT_TRUE(success);
  73. ASSERT_TRUE(result.size() == 1);
  74. ASSERT_TRUE(result["compute.hlsl"] ==
  75. "[numthreads(1, 1, 1)] void compute_1(){ }");
  76. }
  77. TEST(ExtractSourceTest, SourceContinued) {
  78. std::string source = R"(
  79. OpCapability Shader
  80. OpMemoryModel Logical GLSL450
  81. OpEntryPoint GLCompute %1 "compute_1"
  82. OpExecutionMode %1 LocalSize 1 1 1
  83. %2 = OpString "compute.hlsl"
  84. OpSource HLSL 660 %2 "[numthreads(1, 1, 1)] "
  85. OpSourceContinued "void compute_1(){ }"
  86. OpName %1 "compute_1"
  87. %3 = OpTypeVoid
  88. %4 = OpTypeFunction %3
  89. %1 = OpFunction %3 None %4
  90. %5 = OpLabel
  91. OpLine %2 1 41
  92. OpReturn
  93. OpFunctionEnd
  94. )";
  95. auto[success, result] = ExtractSource(source);
  96. ASSERT_TRUE(success);
  97. ASSERT_TRUE(result.size() == 1);
  98. ASSERT_TRUE(result["compute.hlsl"] ==
  99. "[numthreads(1, 1, 1)] void compute_1(){ }");
  100. }
  101. TEST(ExtractSourceTest, OnlyFilename) {
  102. std::string source = R"(
  103. OpCapability Shader
  104. OpMemoryModel Logical GLSL450
  105. OpEntryPoint GLCompute %1 "compute_1"
  106. OpExecutionMode %1 LocalSize 1 1 1
  107. %2 = OpString "compute.hlsl"
  108. OpSource HLSL 660 %2
  109. OpName %1 "compute_1"
  110. %3 = OpTypeVoid
  111. %4 = OpTypeFunction %3
  112. %1 = OpFunction %3 None %4
  113. %5 = OpLabel
  114. OpLine %2 1 41
  115. OpReturn
  116. OpFunctionEnd
  117. )";
  118. auto[success, result] = ExtractSource(source);
  119. ASSERT_TRUE(success);
  120. ASSERT_TRUE(result.size() == 1);
  121. ASSERT_TRUE(result["compute.hlsl"] == "");
  122. }
  123. TEST(ExtractSourceTest, MultipleFiles) {
  124. std::string source = R"(
  125. OpCapability Shader
  126. OpMemoryModel Logical GLSL450
  127. OpEntryPoint GLCompute %1 "compute_1"
  128. OpExecutionMode %1 LocalSize 1 1 1
  129. %2 = OpString "compute1.hlsl"
  130. %3 = OpString "compute2.hlsl"
  131. OpSource HLSL 660 %2 "some instruction"
  132. OpSource HLSL 660 %3 "some other instruction"
  133. OpName %1 "compute_1"
  134. %4 = OpTypeVoid
  135. %5 = OpTypeFunction %4
  136. %1 = OpFunction %4 None %5
  137. %6 = OpLabel
  138. OpLine %2 1 41
  139. OpReturn
  140. OpFunctionEnd
  141. )";
  142. auto[success, result] = ExtractSource(source);
  143. ASSERT_TRUE(success);
  144. ASSERT_TRUE(result.size() == 2);
  145. ASSERT_TRUE(result["compute1.hlsl"] == "some instruction");
  146. ASSERT_TRUE(result["compute2.hlsl"] == "some other instruction");
  147. }
  148. TEST(ExtractSourceTest, MultilineCode) {
  149. std::string source = R"(
  150. OpCapability Shader
  151. OpMemoryModel Logical GLSL450
  152. OpEntryPoint GLCompute %1 "compute_1"
  153. OpExecutionMode %1 LocalSize 1 1 1
  154. %2 = OpString "compute.hlsl"
  155. OpSource HLSL 660 %2 "[numthreads(1, 1, 1)]
  156. void compute_1() {
  157. }
  158. "
  159. OpName %1 "compute_1"
  160. %3 = OpTypeVoid
  161. %4 = OpTypeFunction %3
  162. %1 = OpFunction %3 None %4
  163. %5 = OpLabel
  164. OpLine %2 3 1
  165. OpReturn
  166. OpFunctionEnd
  167. )";
  168. auto[success, result] = ExtractSource(source);
  169. ASSERT_TRUE(success);
  170. ASSERT_TRUE(result.size() == 1);
  171. ASSERT_TRUE(result["compute.hlsl"] ==
  172. "[numthreads(1, 1, 1)]\nvoid compute_1() {\n}\n");
  173. }
  174. TEST(ExtractSourceTest, EmptyFilename) {
  175. std::string source = R"(
  176. OpCapability Shader
  177. OpMemoryModel Logical GLSL450
  178. OpEntryPoint GLCompute %1 "compute_1"
  179. OpExecutionMode %1 LocalSize 1 1 1
  180. %2 = OpString ""
  181. OpSource HLSL 660 %2 "void compute(){}"
  182. OpName %1 "compute_1"
  183. %3 = OpTypeVoid
  184. %4 = OpTypeFunction %3
  185. %1 = OpFunction %3 None %4
  186. %5 = OpLabel
  187. OpLine %2 3 1
  188. OpReturn
  189. OpFunctionEnd
  190. )";
  191. auto[success, result] = ExtractSource(source);
  192. ASSERT_TRUE(success);
  193. ASSERT_TRUE(result.size() == 1);
  194. ASSERT_TRUE(result["unnamed-0.hlsl"] == "void compute(){}");
  195. }
  196. TEST(ExtractSourceTest, EscapeEscaped) {
  197. std::string source = R"(
  198. OpCapability Shader
  199. OpMemoryModel Logical GLSL450
  200. OpEntryPoint GLCompute %1 "compute"
  201. OpExecutionMode %1 LocalSize 1 1 1
  202. %2 = OpString "compute.hlsl"
  203. OpSource HLSL 660 %2 "// check \" escape removed"
  204. OpName %1 "compute"
  205. %3 = OpTypeVoid
  206. %4 = OpTypeFunction %3
  207. %1 = OpFunction %3 None %4
  208. %5 = OpLabel
  209. OpLine %2 6 1
  210. OpReturn
  211. OpFunctionEnd
  212. )";
  213. auto[success, result] = ExtractSource(source);
  214. ASSERT_TRUE(success);
  215. ASSERT_TRUE(result.size() == 1);
  216. ASSERT_TRUE(result["compute.hlsl"] == "// check \" escape removed");
  217. }
  218. TEST(ExtractSourceTest, OpSourceWithNoSource) {
  219. std::string source = R"(
  220. OpCapability Shader
  221. OpMemoryModel Logical GLSL450
  222. OpEntryPoint GLCompute %1 "compute"
  223. OpExecutionMode %1 LocalSize 1 1 1
  224. %2 = OpString "compute.hlsl"
  225. OpSource HLSL 660 %2
  226. OpName %1 "compute"
  227. %3 = OpTypeVoid
  228. %4 = OpTypeFunction %3
  229. %1 = OpFunction %3 None %4
  230. %5 = OpLabel
  231. OpLine %2 6 1
  232. OpReturn
  233. OpFunctionEnd
  234. )";
  235. auto[success, result] = ExtractSource(source);
  236. ASSERT_TRUE(success);
  237. ASSERT_TRUE(result.size() == 1);
  238. ASSERT_TRUE(result["compute.hlsl"] == "");
  239. }