xref: /aosp_15_r20/external/angle/src/common/spirv/angle_spirv_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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