val_ray_tracing_test.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. // Copyright (c) 2022 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. // Tests ray tracing instructions from SPV_KHR_ray_tracing.
  15. #include <sstream>
  16. #include <string>
  17. #include "gmock/gmock.h"
  18. #include "test/val/val_fixtures.h"
  19. namespace spvtools {
  20. namespace val {
  21. namespace {
  22. using ::testing::HasSubstr;
  23. using ::testing::Values;
  24. using ValidateRayTracing = spvtest::ValidateBase<bool>;
  25. TEST_F(ValidateRayTracing, IgnoreIntersectionSuccess) {
  26. const std::string body = R"(
  27. OpCapability RayTracingKHR
  28. OpExtension "SPV_KHR_ray_tracing"
  29. OpMemoryModel Logical GLSL450
  30. OpEntryPoint AnyHitKHR %main "main"
  31. OpName %main "main"
  32. %void = OpTypeVoid
  33. %func = OpTypeFunction %void
  34. %main = OpFunction %void None %func
  35. %label = OpLabel
  36. OpIgnoreIntersectionKHR
  37. OpFunctionEnd
  38. )";
  39. CompileSuccessfully(body.c_str());
  40. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  41. }
  42. TEST_F(ValidateRayTracing, IgnoreIntersectionExecutionModel) {
  43. const std::string body = R"(
  44. OpCapability RayTracingKHR
  45. OpExtension "SPV_KHR_ray_tracing"
  46. OpMemoryModel Logical GLSL450
  47. OpEntryPoint CallableKHR %main "main"
  48. OpName %main "main"
  49. %void = OpTypeVoid
  50. %func = OpTypeFunction %void
  51. %main = OpFunction %void None %func
  52. %label = OpLabel
  53. OpIgnoreIntersectionKHR
  54. OpFunctionEnd
  55. )";
  56. CompileSuccessfully(body.c_str());
  57. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  58. EXPECT_THAT(
  59. getDiagnosticString(),
  60. HasSubstr("OpIgnoreIntersectionKHR requires AnyHitKHR execution model"));
  61. }
  62. TEST_F(ValidateRayTracing, TerminateRaySuccess) {
  63. const std::string body = R"(
  64. OpCapability RayTracingKHR
  65. OpExtension "SPV_KHR_ray_tracing"
  66. OpMemoryModel Logical GLSL450
  67. OpEntryPoint AnyHitKHR %main "main"
  68. OpName %main "main"
  69. %void = OpTypeVoid
  70. %func = OpTypeFunction %void
  71. %main = OpFunction %void None %func
  72. %label = OpLabel
  73. OpIgnoreIntersectionKHR
  74. OpFunctionEnd
  75. )";
  76. CompileSuccessfully(body.c_str());
  77. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  78. }
  79. TEST_F(ValidateRayTracing, TerminateRayExecutionModel) {
  80. const std::string body = R"(
  81. OpCapability RayTracingKHR
  82. OpExtension "SPV_KHR_ray_tracing"
  83. OpMemoryModel Logical GLSL450
  84. OpEntryPoint MissKHR %main "main"
  85. OpName %main "main"
  86. %void = OpTypeVoid
  87. %func = OpTypeFunction %void
  88. %main = OpFunction %void None %func
  89. %label = OpLabel
  90. OpTerminateRayKHR
  91. OpFunctionEnd
  92. )";
  93. CompileSuccessfully(body.c_str());
  94. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  95. EXPECT_THAT(
  96. getDiagnosticString(),
  97. HasSubstr("OpTerminateRayKHR requires AnyHitKHR execution model"));
  98. }
  99. TEST_F(ValidateRayTracing, ReportIntersectionRaySuccess) {
  100. const std::string body = R"(
  101. OpCapability RayTracingKHR
  102. OpExtension "SPV_KHR_ray_tracing"
  103. OpMemoryModel Logical GLSL450
  104. OpEntryPoint IntersectionKHR %main "main"
  105. OpName %main "main"
  106. %void = OpTypeVoid
  107. %func = OpTypeFunction %void
  108. %float = OpTypeFloat 32
  109. %float_1 = OpConstant %float 1
  110. %uint = OpTypeInt 32 0
  111. %uint_1 = OpConstant %uint 1
  112. %bool = OpTypeBool
  113. %main = OpFunction %void None %func
  114. %label = OpLabel
  115. %report = OpReportIntersectionKHR %bool %float_1 %uint_1
  116. OpReturn
  117. OpFunctionEnd
  118. )";
  119. CompileSuccessfully(body.c_str());
  120. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  121. }
  122. TEST_F(ValidateRayTracing, ReportIntersectionExecutionModel) {
  123. const std::string body = R"(
  124. OpCapability RayTracingKHR
  125. OpExtension "SPV_KHR_ray_tracing"
  126. OpMemoryModel Logical GLSL450
  127. OpEntryPoint MissKHR %main "main"
  128. OpName %main "main"
  129. %void = OpTypeVoid
  130. %func = OpTypeFunction %void
  131. %float = OpTypeFloat 32
  132. %float_1 = OpConstant %float 1
  133. %uint = OpTypeInt 32 0
  134. %uint_1 = OpConstant %uint 1
  135. %bool = OpTypeBool
  136. %main = OpFunction %void None %func
  137. %label = OpLabel
  138. %report = OpReportIntersectionKHR %bool %float_1 %uint_1
  139. OpReturn
  140. OpFunctionEnd
  141. )";
  142. CompileSuccessfully(body.c_str());
  143. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  144. EXPECT_THAT(
  145. getDiagnosticString(),
  146. HasSubstr(
  147. "OpReportIntersectionKHR requires IntersectionKHR execution model"));
  148. }
  149. TEST_F(ValidateRayTracing, ReportIntersectionReturnType) {
  150. const std::string body = R"(
  151. OpCapability RayTracingKHR
  152. OpExtension "SPV_KHR_ray_tracing"
  153. OpMemoryModel Logical GLSL450
  154. OpEntryPoint IntersectionKHR %main "main"
  155. OpName %main "main"
  156. %void = OpTypeVoid
  157. %func = OpTypeFunction %void
  158. %float = OpTypeFloat 32
  159. %float_1 = OpConstant %float 1
  160. %uint = OpTypeInt 32 0
  161. %uint_1 = OpConstant %uint 1
  162. %main = OpFunction %void None %func
  163. %label = OpLabel
  164. %report = OpReportIntersectionKHR %uint %float_1 %uint_1
  165. OpReturn
  166. OpFunctionEnd
  167. )";
  168. CompileSuccessfully(body.c_str());
  169. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  170. EXPECT_THAT(getDiagnosticString(),
  171. HasSubstr("expected Result Type to be bool scalar type"));
  172. }
  173. TEST_F(ValidateRayTracing, ReportIntersectionHit) {
  174. const std::string body = R"(
  175. OpCapability RayTracingKHR
  176. OpCapability Float64
  177. OpExtension "SPV_KHR_ray_tracing"
  178. OpMemoryModel Logical GLSL450
  179. OpEntryPoint IntersectionKHR %main "main"
  180. OpName %main "main"
  181. %void = OpTypeVoid
  182. %func = OpTypeFunction %void
  183. %float64 = OpTypeFloat 64
  184. %float64_1 = OpConstant %float64 1
  185. %uint = OpTypeInt 32 0
  186. %uint_1 = OpConstant %uint 1
  187. %bool = OpTypeBool
  188. %main = OpFunction %void None %func
  189. %label = OpLabel
  190. %report = OpReportIntersectionKHR %bool %float64_1 %uint_1
  191. OpReturn
  192. OpFunctionEnd
  193. )";
  194. CompileSuccessfully(body.c_str());
  195. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  196. EXPECT_THAT(getDiagnosticString(),
  197. HasSubstr("Hit must be a 32-bit int scalar"));
  198. }
  199. TEST_F(ValidateRayTracing, ReportIntersectionHitKind) {
  200. const std::string body = R"(
  201. OpCapability RayTracingKHR
  202. OpExtension "SPV_KHR_ray_tracing"
  203. OpMemoryModel Logical GLSL450
  204. OpEntryPoint IntersectionKHR %main "main"
  205. OpName %main "main"
  206. %void = OpTypeVoid
  207. %func = OpTypeFunction %void
  208. %float = OpTypeFloat 32
  209. %float_1 = OpConstant %float 1
  210. %sint = OpTypeInt 32 1
  211. %sint_1 = OpConstant %sint 1
  212. %bool = OpTypeBool
  213. %main = OpFunction %void None %func
  214. %label = OpLabel
  215. %report = OpReportIntersectionKHR %bool %float_1 %sint_1
  216. OpReturn
  217. OpFunctionEnd
  218. )";
  219. CompileSuccessfully(body.c_str());
  220. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  221. EXPECT_THAT(getDiagnosticString(),
  222. HasSubstr("Hit Kind must be a 32-bit unsigned int scalar"));
  223. }
  224. TEST_F(ValidateRayTracing, ExecuteCallableSuccess) {
  225. const std::string body = R"(
  226. OpCapability RayTracingKHR
  227. OpExtension "SPV_KHR_ray_tracing"
  228. OpMemoryModel Logical GLSL450
  229. OpEntryPoint CallableKHR %main "main"
  230. OpName %main "main"
  231. %void = OpTypeVoid
  232. %func = OpTypeFunction %void
  233. %int = OpTypeInt 32 1
  234. %uint = OpTypeInt 32 0
  235. %uint_0 = OpConstant %uint 0
  236. %data_ptr = OpTypePointer CallableDataKHR %int
  237. %data = OpVariable %data_ptr CallableDataKHR
  238. %inData_ptr = OpTypePointer IncomingCallableDataKHR %int
  239. %inData = OpVariable %inData_ptr IncomingCallableDataKHR
  240. %main = OpFunction %void None %func
  241. %label = OpLabel
  242. OpExecuteCallableKHR %uint_0 %data
  243. OpExecuteCallableKHR %uint_0 %inData
  244. OpReturn
  245. OpFunctionEnd
  246. )";
  247. CompileSuccessfully(body.c_str());
  248. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  249. }
  250. TEST_F(ValidateRayTracing, ExecuteCallableExecutionModel) {
  251. const std::string body = R"(
  252. OpCapability RayTracingKHR
  253. OpExtension "SPV_KHR_ray_tracing"
  254. OpMemoryModel Logical GLSL450
  255. OpEntryPoint AnyHitKHR %main "main"
  256. OpName %main "main"
  257. %void = OpTypeVoid
  258. %func = OpTypeFunction %void
  259. %int = OpTypeInt 32 1
  260. %uint = OpTypeInt 32 0
  261. %uint_0 = OpConstant %uint 0
  262. %data_ptr = OpTypePointer CallableDataKHR %int
  263. %data = OpVariable %data_ptr CallableDataKHR
  264. %inData_ptr = OpTypePointer IncomingCallableDataKHR %int
  265. %inData = OpVariable %inData_ptr IncomingCallableDataKHR
  266. %main = OpFunction %void None %func
  267. %label = OpLabel
  268. OpExecuteCallableKHR %uint_0 %data
  269. OpExecuteCallableKHR %uint_0 %inData
  270. OpReturn
  271. OpFunctionEnd
  272. )";
  273. CompileSuccessfully(body.c_str());
  274. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  275. EXPECT_THAT(
  276. getDiagnosticString(),
  277. HasSubstr("OpExecuteCallableKHR requires RayGenerationKHR, "
  278. "ClosestHitKHR, MissKHR and CallableKHR execution models"));
  279. }
  280. TEST_F(ValidateRayTracing, ExecuteCallableStorageClass) {
  281. const std::string body = R"(
  282. OpCapability RayTracingKHR
  283. OpExtension "SPV_KHR_ray_tracing"
  284. OpMemoryModel Logical GLSL450
  285. OpEntryPoint RayGenerationKHR %main "main"
  286. OpName %main "main"
  287. %void = OpTypeVoid
  288. %func = OpTypeFunction %void
  289. %int = OpTypeInt 32 1
  290. %uint = OpTypeInt 32 0
  291. %uint_0 = OpConstant %uint 0
  292. %data_ptr = OpTypePointer RayPayloadKHR %int
  293. %data = OpVariable %data_ptr RayPayloadKHR
  294. %main = OpFunction %void None %func
  295. %label = OpLabel
  296. OpExecuteCallableKHR %uint_0 %data
  297. OpReturn
  298. OpFunctionEnd
  299. )";
  300. CompileSuccessfully(body.c_str());
  301. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  302. EXPECT_THAT(getDiagnosticString(),
  303. HasSubstr("Callable Data must have storage class CallableDataKHR "
  304. "or IncomingCallableDataKHR"));
  305. }
  306. TEST_F(ValidateRayTracing, ExecuteCallableSbtIndex) {
  307. const std::string body = R"(
  308. OpCapability RayTracingKHR
  309. OpExtension "SPV_KHR_ray_tracing"
  310. OpMemoryModel Logical GLSL450
  311. OpEntryPoint CallableKHR %main "main"
  312. OpName %main "main"
  313. %void = OpTypeVoid
  314. %func = OpTypeFunction %void
  315. %int = OpTypeInt 32 1
  316. %uint = OpTypeInt 32 0
  317. %uint_0 = OpConstant %uint 0
  318. %int_1 = OpConstant %int 1
  319. %data_ptr = OpTypePointer CallableDataKHR %int
  320. %data = OpVariable %data_ptr CallableDataKHR
  321. %main = OpFunction %void None %func
  322. %label = OpLabel
  323. OpExecuteCallableKHR %int_1 %data
  324. OpReturn
  325. OpFunctionEnd
  326. )";
  327. CompileSuccessfully(body.c_str());
  328. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  329. EXPECT_THAT(getDiagnosticString(),
  330. HasSubstr("SBT Index must be a 32-bit unsigned int scalar"));
  331. }
  332. std::string GenerateRayTraceCode(
  333. const std::string& body,
  334. const std::string execution_model = "RayGenerationKHR") {
  335. std::ostringstream ss;
  336. ss << R"(
  337. OpCapability RayTracingKHR
  338. OpCapability Float64
  339. OpExtension "SPV_KHR_ray_tracing"
  340. OpMemoryModel Logical GLSL450
  341. OpEntryPoint )"
  342. << execution_model << R"( %main "main"
  343. OpDecorate %top_level_as DescriptorSet 0
  344. OpDecorate %top_level_as Binding 0
  345. %void = OpTypeVoid
  346. %func = OpTypeFunction %void
  347. %type_as = OpTypeAccelerationStructureKHR
  348. %as_uc_ptr = OpTypePointer UniformConstant %type_as
  349. %top_level_as = OpVariable %as_uc_ptr UniformConstant
  350. %uint = OpTypeInt 32 0
  351. %uint_1 = OpConstant %uint 1
  352. %float = OpTypeFloat 32
  353. %float64 = OpTypeFloat 64
  354. %f32vec3 = OpTypeVector %float 3
  355. %f32vec4 = OpTypeVector %float 4
  356. %float_0 = OpConstant %float 0
  357. %float64_0 = OpConstant %float64 0
  358. %v3composite = OpConstantComposite %f32vec3 %float_0 %float_0 %float_0
  359. %v4composite = OpConstantComposite %f32vec4 %float_0 %float_0 %float_0 %float_0
  360. %int = OpTypeInt 32 1
  361. %int_1 = OpConstant %int 1
  362. %payload_ptr = OpTypePointer RayPayloadKHR %int
  363. %payload = OpVariable %payload_ptr RayPayloadKHR
  364. %callable_ptr = OpTypePointer CallableDataKHR %int
  365. %callable = OpVariable %callable_ptr CallableDataKHR
  366. %ptr_uint = OpTypePointer Private %uint
  367. %var_uint = OpVariable %ptr_uint Private
  368. %ptr_float = OpTypePointer Private %float
  369. %var_float = OpVariable %ptr_float Private
  370. %ptr_f32vec3 = OpTypePointer Private %f32vec3
  371. %var_f32vec3 = OpVariable %ptr_f32vec3 Private
  372. %main = OpFunction %void None %func
  373. %label = OpLabel
  374. )";
  375. ss << body;
  376. ss << R"(
  377. OpReturn
  378. OpFunctionEnd)";
  379. return ss.str();
  380. }
  381. TEST_F(ValidateRayTracing, TraceRaySuccess) {
  382. const std::string body = R"(
  383. %as = OpLoad %type_as %top_level_as
  384. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  385. %_uint = OpLoad %uint %var_uint
  386. %_float = OpLoad %float %var_float
  387. %_f32vec3 = OpLoad %f32vec3 %var_f32vec3
  388. OpTraceRayKHR %as %_uint %_uint %_uint %_uint %_uint %_f32vec3 %_float %_f32vec3 %_float %payload
  389. )";
  390. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  391. EXPECT_EQ(SPV_SUCCESS, ValidateInstructions());
  392. }
  393. TEST_F(ValidateRayTracing, TraceRayExecutionModel) {
  394. const std::string body = R"(
  395. %as = OpLoad %type_as %top_level_as
  396. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  397. )";
  398. CompileSuccessfully(GenerateRayTraceCode(body, "CallableKHR").c_str());
  399. EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions());
  400. EXPECT_THAT(getDiagnosticString(),
  401. HasSubstr("OpTraceRayKHR requires RayGenerationKHR, "
  402. "ClosestHitKHR and MissKHR execution models"));
  403. }
  404. TEST_F(ValidateRayTracing, TraceRayAccelerationStructure) {
  405. const std::string body = R"(
  406. %_uint = OpLoad %uint %var_uint
  407. OpTraceRayKHR %_uint %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  408. )";
  409. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  410. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  411. EXPECT_THAT(getDiagnosticString(),
  412. HasSubstr("Expected Acceleration Structure to be of type "
  413. "OpTypeAccelerationStructureKHR"));
  414. }
  415. TEST_F(ValidateRayTracing, TraceRayRayFlags) {
  416. const std::string body = R"(
  417. %as = OpLoad %type_as %top_level_as
  418. OpTraceRayKHR %as %float_0 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  419. )";
  420. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  421. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  422. EXPECT_THAT(getDiagnosticString(),
  423. HasSubstr("Ray Flags must be a 32-bit int scalar"));
  424. }
  425. TEST_F(ValidateRayTracing, TraceRayCullMask) {
  426. const std::string body = R"(
  427. %as = OpLoad %type_as %top_level_as
  428. OpTraceRayKHR %as %uint_1 %float_0 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  429. )";
  430. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  431. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  432. EXPECT_THAT(getDiagnosticString(),
  433. HasSubstr("Cull Mask must be a 32-bit int scalar"));
  434. }
  435. TEST_F(ValidateRayTracing, TraceRaySbtOffest) {
  436. const std::string body = R"(
  437. %as = OpLoad %type_as %top_level_as
  438. OpTraceRayKHR %as %uint_1 %uint_1 %float_0 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  439. )";
  440. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  441. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  442. EXPECT_THAT(getDiagnosticString(),
  443. HasSubstr("SBT Offset must be a 32-bit int scalar"));
  444. }
  445. TEST_F(ValidateRayTracing, TraceRaySbtStride) {
  446. const std::string body = R"(
  447. %as = OpLoad %type_as %top_level_as
  448. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %float_0 %uint_1 %v3composite %float_0 %v3composite %float_0 %payload
  449. )";
  450. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  451. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  452. EXPECT_THAT(getDiagnosticString(),
  453. HasSubstr("SBT Stride must be a 32-bit int scalar"));
  454. }
  455. TEST_F(ValidateRayTracing, TraceRayMissIndex) {
  456. const std::string body = R"(
  457. %as = OpLoad %type_as %top_level_as
  458. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %float_0 %v3composite %float_0 %v3composite %float_0 %payload
  459. )";
  460. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  461. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  462. EXPECT_THAT(getDiagnosticString(),
  463. HasSubstr("Miss Index must be a 32-bit int scalar"));
  464. }
  465. TEST_F(ValidateRayTracing, TraceRayRayOrigin) {
  466. const std::string body = R"(
  467. %as = OpLoad %type_as %top_level_as
  468. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %float_0 %float_0 %v3composite %float_0 %payload
  469. )";
  470. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  471. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  472. EXPECT_THAT(
  473. getDiagnosticString(),
  474. HasSubstr("Ray Origin must be a 32-bit float 3-component vector"));
  475. }
  476. TEST_F(ValidateRayTracing, TraceRayRayTMin) {
  477. const std::string body = R"(
  478. %as = OpLoad %type_as %top_level_as
  479. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %uint_1 %v3composite %float_0 %payload
  480. )";
  481. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  482. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  483. EXPECT_THAT(getDiagnosticString(),
  484. HasSubstr("Ray TMin must be a 32-bit float scalar"));
  485. }
  486. TEST_F(ValidateRayTracing, TraceRayRayDirection) {
  487. const std::string body = R"(
  488. %as = OpLoad %type_as %top_level_as
  489. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v4composite %float_0 %payload
  490. )";
  491. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  492. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  493. EXPECT_THAT(
  494. getDiagnosticString(),
  495. HasSubstr("Ray Direction must be a 32-bit float 3-component vector"));
  496. }
  497. TEST_F(ValidateRayTracing, TraceRayRayTMax) {
  498. const std::string body = R"(
  499. %as = OpLoad %type_as %top_level_as
  500. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float64_0 %payload
  501. )";
  502. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  503. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  504. EXPECT_THAT(getDiagnosticString(),
  505. HasSubstr("Ray TMax must be a 32-bit float scalar"));
  506. }
  507. TEST_F(ValidateRayTracing, TraceRayPayload) {
  508. const std::string body = R"(
  509. %as = OpLoad %type_as %top_level_as
  510. OpTraceRayKHR %as %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %v3composite %float_0 %v3composite %float_0 %callable
  511. )";
  512. CompileSuccessfully(GenerateRayTraceCode(body).c_str());
  513. EXPECT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
  514. EXPECT_THAT(getDiagnosticString(),
  515. HasSubstr("Payload must have storage class RayPayloadKHR or "
  516. "IncomingRayPayloadKHR"));
  517. }
  518. TEST_F(ValidateRayTracing, InterfaceIncomingRayPayload) {
  519. const std::string body = R"(
  520. OpCapability RayTracingKHR
  521. OpExtension "SPV_KHR_ray_tracing"
  522. OpMemoryModel Logical GLSL450
  523. OpEntryPoint CallableKHR %main "main" %inData1 %inData2
  524. OpName %main "main"
  525. %void = OpTypeVoid
  526. %func = OpTypeFunction %void
  527. %int = OpTypeInt 32 1
  528. %inData_ptr = OpTypePointer IncomingRayPayloadKHR %int
  529. %inData1 = OpVariable %inData_ptr IncomingRayPayloadKHR
  530. %inData2 = OpVariable %inData_ptr IncomingRayPayloadKHR
  531. %main = OpFunction %void None %func
  532. %label = OpLabel
  533. OpReturn
  534. OpFunctionEnd
  535. )";
  536. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  537. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  538. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  539. EXPECT_THAT(getDiagnosticString(),
  540. AnyVUID("VUID-StandaloneSpirv-IncomingRayPayloadKHR-04700"));
  541. EXPECT_THAT(
  542. getDiagnosticString(),
  543. HasSubstr("Entry-point has more than one variable with the "
  544. "IncomingRayPayloadKHR storage class in the interface"));
  545. }
  546. TEST_F(ValidateRayTracing, InterfaceHitAttribute) {
  547. const std::string body = R"(
  548. OpCapability RayTracingKHR
  549. OpExtension "SPV_KHR_ray_tracing"
  550. OpMemoryModel Logical GLSL450
  551. OpEntryPoint CallableKHR %main "main" %inData1 %inData2
  552. OpName %main "main"
  553. %void = OpTypeVoid
  554. %func = OpTypeFunction %void
  555. %int = OpTypeInt 32 1
  556. %inData_ptr = OpTypePointer HitAttributeKHR %int
  557. %inData1 = OpVariable %inData_ptr HitAttributeKHR
  558. %inData2 = OpVariable %inData_ptr HitAttributeKHR
  559. %main = OpFunction %void None %func
  560. %label = OpLabel
  561. OpReturn
  562. OpFunctionEnd
  563. )";
  564. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  565. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  566. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  567. EXPECT_THAT(getDiagnosticString(),
  568. AnyVUID("VUID-StandaloneSpirv-HitAttributeKHR-04702"));
  569. EXPECT_THAT(getDiagnosticString(),
  570. HasSubstr("Entry-point has more than one variable with the "
  571. "HitAttributeKHR storage class in the interface"));
  572. }
  573. TEST_F(ValidateRayTracing, InterfaceIncomingCallableData) {
  574. const std::string body = R"(
  575. OpCapability RayTracingKHR
  576. OpExtension "SPV_KHR_ray_tracing"
  577. OpMemoryModel Logical GLSL450
  578. OpEntryPoint CallableKHR %main "main" %inData1 %inData2
  579. OpName %main "main"
  580. %void = OpTypeVoid
  581. %func = OpTypeFunction %void
  582. %int = OpTypeInt 32 1
  583. %inData_ptr = OpTypePointer IncomingCallableDataKHR %int
  584. %inData1 = OpVariable %inData_ptr IncomingCallableDataKHR
  585. %inData2 = OpVariable %inData_ptr IncomingCallableDataKHR
  586. %main = OpFunction %void None %func
  587. %label = OpLabel
  588. OpReturn
  589. OpFunctionEnd
  590. )";
  591. CompileSuccessfully(body.c_str(), SPV_ENV_VULKAN_1_2);
  592. EXPECT_EQ(SPV_ERROR_INVALID_DATA,
  593. ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_2));
  594. EXPECT_THAT(getDiagnosticString(),
  595. AnyVUID("VUID-StandaloneSpirv-IncomingCallableDataKHR-04706"));
  596. EXPECT_THAT(
  597. getDiagnosticString(),
  598. HasSubstr("Entry-point has more than one variable with the "
  599. "IncomingCallableDataKHR storage class in the interface"));
  600. }
  601. } // namespace
  602. } // namespace val
  603. } // namespace spvtools