1 /*========================== begin_copyright_notice ============================
2 
3 Copyright (C) 2021 Intel Corporation
4 
5 SPDX-License-Identifier: MIT
6 
7 ============================= end_copyright_notice ===========================*/
8 
9 //
10 // Class provides methods needed for construct kernel names
11 // and represents state of overriding process.
12 //
13 
14 #include <common/debug/Dump.hpp>
15 #include <common/shaderHash.hpp>
16 #include <common/shaderOverride.hpp>
17 
18 #include "vc/igcdeps/ShaderOverride.h"
19 
20 using Extensions = vc::ShaderOverrider::Extensions;
21 namespace {
22 
23 class VC_IGCShaderOverrider final : public vc::ShaderOverrider {
24   IGC::Debug::DumpName NamePrefix;
25   PLATFORM const &Platform;
26   IGC::Debug::OutputFolderName Folder;
27 
28   // Gets full kernel name:
29   // VC_<HASH>_<ShaderName>
30   IGC::Debug::DumpName composeShaderName(std::string const &ShaderName) const;
31 
32   // Gets full path to file with extension:
33   // "/path/to/shaderOverride/VC_<HASH>_<ShaderName>.Ext"
34   std::string path(std::string const &ShaderName,
35                    vc::ShaderOverrider::Extensions Ext) const;
36 
37 public:
38   VC_IGCShaderOverrider(ShaderHash const &Hash, PLATFORM const &Platform);
39 
40   // Overrides .asm or .dat files
41   bool override(void *&GenXBin, int &GenXBinSize, llvm::StringRef FunctionName,
42                 Extensions Ext) const override;
43 };
44 
45 } // namespace
46 
VC_IGCShaderOverrider(ShaderHash const & InHash,PLATFORM const & InPlatform)47 VC_IGCShaderOverrider::VC_IGCShaderOverrider(ShaderHash const &InHash,
48                                              PLATFORM const &InPlatform)
49     : NamePrefix{IGC::Debug::DumpName("VC").Hash(InHash)}, Platform{InPlatform},
50       Folder{IGC::Debug::GetShaderOverridePath()} {}
51 
52 // Returns appropriate Name with no special symbols. They are replaced with
53 // '_'.
54 // Name = gjdn&85Lg -> return =  gjdn_85Lg
legalizeName(std::string Name)55 static std::string legalizeName(std::string Name) {
56   std::replace_if(Name.begin(), Name.end(),
57                   [](unsigned char c) { return (!isalnum(c) && c != '_'); },
58                   '_');
59   return Name;
60 }
61 
override(void * & GenXBin,int & GenXBinSize,llvm::StringRef FunctionName,Extensions Ext) const62 bool VC_IGCShaderOverrider::override(void *&GenXBin, int &GenXBinSize,
63                                      llvm::StringRef FunctionName,
64                                      Extensions Ext) const {
65   std::string const LegalizedShaderName = legalizeName(FunctionName.str());
66   std::string const FullPath = path(LegalizedShaderName, Ext);
67   bool Status = false;
68 
69   switch (Ext) {
70   case Extensions::ASM:
71     overrideShaderIGA(Platform, GenXBin, GenXBinSize, FullPath, Status);
72     break;
73   case Extensions::DAT:
74     overrideShaderBinary(GenXBin, GenXBinSize, FullPath, Status);
75     break;
76   default:
77     IGC_ASSERT_EXIT_MESSAGE(0, "Unexpected extension");
78   }
79   return Status;
80 }
81 
82 // Returns name with added postfix
addPostfix(IGC::Debug::DumpName const & Name,std::string const & Postfix)83 static IGC::Debug::DumpName addPostfix(IGC::Debug::DumpName const &Name,
84                                        std::string const &Postfix) {
85   return Name.PostFix(Postfix);
86 }
87 
88 IGC::Debug::DumpName
composeShaderName(std::string const & ShaderName) const89 VC_IGCShaderOverrider::composeShaderName(std::string const &ShaderName) const {
90   return addPostfix(NamePrefix, ShaderName);
91 }
92 
93 std::string
path(std::string const & ShaderName,vc::ShaderOverrider::Extensions Ext) const94 VC_IGCShaderOverrider::path(std::string const &ShaderName,
95                             vc::ShaderOverrider::Extensions Ext) const {
96   IGC::Debug::DumpName FullPath{composeShaderName(ShaderName)};
97 
98   switch (Ext) {
99   case Extensions::VISAASM:
100     FullPath = FullPath.Extension("visaasm");
101     break;
102   case Extensions::ASM:
103     FullPath = FullPath.Extension("asm");
104     break;
105   case Extensions::DAT:
106     FullPath = FullPath.Extension("dat");
107     break;
108   case Extensions::LL:
109     FullPath = FullPath.Extension("ll");
110     break;
111   default:
112     IGC_ASSERT_EXIT_MESSAGE(0, "Unexpected extension");
113   }
114 
115   return FullPath.AbsolutePath(Folder);
116 }
117 
118 namespace vc {
119 std::unique_ptr<ShaderOverrider>
createVC_IGCShaderOverrider(ShaderHash const & Hash,PLATFORM const & Platform)120 createVC_IGCShaderOverrider(ShaderHash const &Hash, PLATFORM const &Platform) {
121   return std::make_unique<VC_IGCShaderOverrider>(Hash, Platform);
122 }
123 } // namespace vc
124