1 // Copyright 2021 The ANGLE Project Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // spirv_types.cpp:
6 // Helper SPIR-V functions.
7
8 #include "spirv_types.h"
9
10 // SPIR-V tools include for AST validation.
11 #include <spirv-tools/libspirv.hpp>
12
13 #if defined(ANGLE_ENABLE_ASSERTS)
14 constexpr bool kAngleAssertEnabled = true;
15 #else
16 constexpr bool kAngleAssertEnabled = false;
17 #endif
18
19 namespace angle
20 {
21 namespace spirv
22 {
23
24 namespace
25 {
ValidateSpirvMessage(spv_message_level_t level,const char * source,const spv_position_t & position,const char * message)26 void ValidateSpirvMessage(spv_message_level_t level,
27 const char *source,
28 const spv_position_t &position,
29 const char *message)
30 {
31 WARN() << "Level" << level << ": " << message;
32 }
33
GetEnv(const Blob & blob)34 spv_target_env GetEnv(const Blob &blob)
35 {
36 switch (blob[kHeaderIndexVersion])
37 {
38 case kVersion_1_4:
39 return SPV_ENV_VULKAN_1_1_SPIRV_1_4;
40 default:
41 return SPV_ENV_VULKAN_1_1;
42 }
43 }
44 } // anonymous namespace
45
Validate(const Blob & blob)46 bool Validate(const Blob &blob)
47 {
48 if (kAngleAssertEnabled)
49 {
50 spvtools::SpirvTools spirvTools(GetEnv(blob));
51
52 spvtools::ValidatorOptions options;
53 options.SetFriendlyNames(false);
54
55 spirvTools.SetMessageConsumer(ValidateSpirvMessage);
56 const bool result = spirvTools.Validate(blob.data(), blob.size(), options);
57
58 if (!result)
59 {
60 std::string readableSpirv;
61 spirvTools.Disassemble(blob, &readableSpirv, 0);
62 WARN() << "Invalid SPIR-V:\n" << readableSpirv;
63 }
64
65 return result;
66 }
67
68 // "Validate()" is only used inside an ASSERT().
69 // Return false to indicate an error in case this is ever accidentally used somewhere else.
70 return false;
71 }
72
Print(const Blob & blob)73 void Print(const Blob &blob)
74 {
75 spvtools::SpirvTools spirvTools(GetEnv(blob));
76 std::string readableSpirv;
77 spirvTools.Disassemble(blob, &readableSpirv,
78 SPV_BINARY_TO_TEXT_OPTION_COMMENT | SPV_BINARY_TO_TEXT_OPTION_INDENT |
79 SPV_BINARY_TO_TEXT_OPTION_NESTED_INDENT);
80 INFO() << "Disassembled SPIR-V:\n" << readableSpirv.c_str();
81 }
82
83 } // namespace spirv
84 } // namespace angle
85