@@ -12,11 +12,15 @@ public class ShaderProcessor : IProcessor, IDisposable
1212 {
1313 SQLiteCommand m_InsertCommand ;
1414 SQLiteCommand m_InsertSubProgramCommand ;
15+ SQLiteCommand m_InsertKeywordCommand ;
16+ SQLiteCommand m_InsertSubProgramKeywordsCommand ;
1517
16- Dictionary < int , string > m_KeywordNames = new Dictionary < int , string > ( ) ;
17- StringBuilder m_Keywords = new StringBuilder ( ) ;
18- HashSet < string > m_UniqueKeywords = new HashSet < string > ( ) ;
19- HashSet < uint > m_UniquePrograms = new HashSet < uint > ( ) ;
18+ List < int > m_Keywords = new ( ) ;
19+ Dictionary < int , string > m_KeywordNames = new ( ) ;
20+ HashSet < uint > m_UniquePrograms = new ( ) ;
21+
22+ static Dictionary < string , int > s_Keywords = new ( ) ;
23+ static long s_SubProgramId = 0 ;
2024
2125 static readonly List < ( string fieldName , string typeName ) > s_progTypes = new ( )
2226 {
@@ -36,37 +40,43 @@ public void Init(SQLiteConnection db)
3640 command . ExecuteNonQuery ( ) ;
3741
3842 m_InsertCommand = new SQLiteCommand ( db ) ;
39- m_InsertCommand . CommandText = "INSERT INTO shaders(id, decompressed_size, sub_shaders, unique_programs, keywords ) VALUES(@id, @decompressed_size, @sub_shaders, @ unique_programs, @keywords )" ;
43+ m_InsertCommand . CommandText = "INSERT INTO shaders(id, decompressed_size, unique_programs) VALUES(@id, @decompressed_size, @unique_programs)" ;
4044 m_InsertCommand . Parameters . Add ( "@id" , DbType . Int64 ) ;
4145 m_InsertCommand . Parameters . Add ( "@decompressed_size" , DbType . Int32 ) ;
42- m_InsertCommand . Parameters . Add ( "@sub_shaders" , DbType . Int32 ) ;
4346 m_InsertCommand . Parameters . Add ( "@unique_programs" , DbType . Int32 ) ;
44- m_InsertCommand . Parameters . Add ( "@keywords" , DbType . String ) ;
4547
4648 m_InsertSubProgramCommand = new SQLiteCommand ( db ) ;
47- m_InsertSubProgramCommand . CommandText = "INSERT INTO shader_subprograms(shader, pass, sub_program, hw_tier, shader_type, api, keywords) VALUES(@shader, @pass, @sub_program, @hw_tier, @shader_type, @api, @keywords)" ;
49+ m_InsertSubProgramCommand . CommandText = "INSERT INTO shader_subprograms(shader, sub_shader, pass, pass_name, sub_program, hw_tier, shader_type, api) VALUES(@shader, @sub_shader, @pass, @pass_name, @sub_program, @hw_tier, @shader_type, @api)" ;
50+ m_InsertSubProgramCommand . Parameters . Add ( "@id" , DbType . Int64 ) ;
4851 m_InsertSubProgramCommand . Parameters . Add ( "@shader" , DbType . Int64 ) ;
52+ m_InsertSubProgramCommand . Parameters . Add ( "@sub_shader" , DbType . Int32 ) ;
4953 m_InsertSubProgramCommand . Parameters . Add ( "@pass" , DbType . Int32 ) ;
54+ m_InsertSubProgramCommand . Parameters . Add ( "@pass_name" , DbType . String ) ;
5055 m_InsertSubProgramCommand . Parameters . Add ( "@sub_program" , DbType . Int32 ) ;
5156 m_InsertSubProgramCommand . Parameters . Add ( "@hw_tier" , DbType . Int32 ) ;
5257 m_InsertSubProgramCommand . Parameters . Add ( "@shader_type" , DbType . String ) ;
5358 m_InsertSubProgramCommand . Parameters . Add ( "@api" , DbType . Int32 ) ;
54- m_InsertSubProgramCommand . Parameters . Add ( "@keywords" , DbType . String ) ;
59+
60+ m_InsertKeywordCommand = new SQLiteCommand ( db ) ;
61+ m_InsertKeywordCommand . CommandText = "INSERT INTO shader_keywords(id, keyword) VALUES(@id, @keyword)" ;
62+ m_InsertKeywordCommand . Parameters . Add ( "@id" , DbType . Int32 ) ;
63+ m_InsertKeywordCommand . Parameters . Add ( "@keyword" , DbType . String ) ;
64+
65+ m_InsertSubProgramKeywordsCommand = new SQLiteCommand ( db ) ;
66+ m_InsertSubProgramKeywordsCommand . CommandText = "INSERT INTO shader_subprogram_keywords(subprogram_id, keyword_id) VALUES (@subprogram_id, @keyword_id)" ;
67+ m_InsertSubProgramKeywordsCommand . Parameters . Add ( "@subprogram_id" , DbType . Int64 ) ;
68+ m_InsertSubProgramKeywordsCommand . Parameters . Add ( "@keyword_id" , DbType . Int32 ) ;
5569 }
5670
5771 public void Process ( AnalyzerTool analyzer , long objectId , Dictionary < int , int > localToDbFileId , RandomAccessReader reader , out string name , out long streamedDataSize )
5872 {
59- int currentProgram = 0 ;
60-
6173 streamedDataSize = 0 ;
6274
63- m_UniqueKeywords . Clear ( ) ;
6475 m_UniquePrograms . Clear ( ) ;
6576
6677 var parsedForm = reader [ "m_ParsedForm" ] ;
6778
6879 m_InsertCommand . Parameters [ "@id" ] . Value = objectId ;
69- m_InsertCommand . Parameters [ "@sub_shaders" ] . Value = parsedForm [ "m_SubShaders" ] . GetArraySize ( ) ;
7080
7181 // Starting in some Unity 2021 version, keyword names are stored in m_KeywordNames.
7282 bool keywordsUnity2021 = false ;
@@ -84,10 +94,13 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
8494 }
8595 }
8696
97+ int subShaderNum = 0 ;
8798 foreach ( var subShader in parsedForm [ "m_SubShaders" ] )
8899 {
89100 int passNum = 0 ;
90101
102+ m_InsertSubProgramCommand . Parameters [ "@sub_shader" ] . Value = subShaderNum ++ ;
103+
91104 foreach ( var pass in subShader [ "m_Passes" ] )
92105 {
93106 if ( ! keywordsUnity2021 )
@@ -102,6 +115,16 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
102115 }
103116 }
104117
118+ string passName = "" ;
119+ if ( pass . HasChild ( "m_State" ) )
120+ {
121+ passName = pass [ "m_State" ] [ "m_Name" ] . GetValue < string > ( ) ;
122+ }
123+
124+ m_InsertSubProgramCommand . Parameters [ "@shader" ] . Value = objectId ;
125+ m_InsertSubProgramCommand . Parameters [ "@pass" ] . Value = passNum ;
126+ m_InsertSubProgramCommand . Parameters [ "@pass_name" ] . Value = passName ;
127+
105128 foreach ( var progType in s_progTypes )
106129 {
107130 if ( ! pass . HasChild ( progType . fieldName ) )
@@ -111,6 +134,8 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
111134
112135 var program = pass [ progType . fieldName ] ;
113136
137+ m_InsertSubProgramCommand . Parameters [ "@shader_type" ] . Value = progType . typeName ;
138+
114139 // Sarting in some Unity 2021.3 version, programs are stored in m_PlayerSubPrograms instead of m_SubPrograms.
115140 if ( program . HasChild ( "m_PlayerSubPrograms" ) )
116141 {
@@ -119,12 +144,12 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
119144 // And they are stored per hardware tiers.
120145 foreach ( var tierProgram in program [ "m_PlayerSubPrograms" ] )
121146 {
122- ProcessProgram ( objectId , passNum , ref currentProgram , tierProgram , progType . typeName , hwTier ++ ) ;
147+ ProcessProgram ( tierProgram , hwTier ++ ) ;
123148 }
124149 }
125150 else
126151 {
127- ProcessProgram ( objectId , passNum , ref currentProgram , program [ "m_SubPrograms" ] , progType . typeName ) ;
152+ ProcessProgram ( program [ "m_SubPrograms" ] ) ;
128153 }
129154 }
130155
@@ -136,7 +161,7 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
136161
137162 if ( ! reader [ "decompressedLengths" ] . TypeTreeNode . Children [ 1 ] . IsLeaf )
138163 {
139- // The decompressed lengths are now stored per graphics API.
164+ // The decompressed lengths are stored per graphics API.
140165 foreach ( var apiLengths in reader [ "decompressedLengths" ] )
141166 {
142167 foreach ( var blockSize in apiLengths . GetValue < int [ ] > ( ) )
@@ -156,20 +181,15 @@ public void Process(AnalyzerTool analyzer, long objectId, Dictionary<int, int> l
156181 }
157182 }
158183
159- m_Keywords . Clear ( ) ;
160- m_Keywords . AppendJoin ( ' ' , m_UniqueKeywords ) ;
161-
162184 m_InsertCommand . Parameters [ "@id" ] . Value = objectId ;
163185 m_InsertCommand . Parameters [ "@decompressed_size" ] . Value = decompressedSize ;
164- m_InsertCommand . Parameters [ "@sub_shaders" ] . Value = parsedForm [ "m_SubShaders" ] . GetArraySize ( ) ;
165186 m_InsertCommand . Parameters [ "@unique_programs" ] . Value = m_UniquePrograms . Count ;
166- m_InsertCommand . Parameters [ "@keywords" ] . Value = m_Keywords . ToString ( ) ;
167187 m_InsertCommand . ExecuteNonQuery ( ) ;
168188
169189 name = parsedForm [ "m_Name" ] . GetValue < string > ( ) ;
170190 }
171191
172- void ProcessProgram ( long objectId , int passNum , ref int currentProgram , RandomAccessReader subPrograms , string shaderType , int hwTier = - 1 )
192+ void ProcessProgram ( RandomAccessReader subPrograms , int hwTier = - 1 )
173193 {
174194 int progNum = 0 ;
175195
@@ -187,9 +207,7 @@ void ProcessProgram(long objectId, int passNum, ref int currentProgram, RandomAc
187207 {
188208 if ( m_KeywordNames . TryGetValue ( index , out var name ) )
189209 {
190- m_Keywords . Append ( name ) ;
191- m_Keywords . Append ( ' ' ) ;
192- m_UniqueKeywords . Add ( name ) ;
210+ m_Keywords . Add ( GetKeywordId ( name ) ) ;
193211 }
194212 }
195213 }
@@ -199,38 +217,59 @@ void ProcessProgram(long objectId, int passNum, ref int currentProgram, RandomAc
199217 {
200218 if ( m_KeywordNames . TryGetValue ( index , out var name ) )
201219 {
202- m_Keywords . Append ( name ) ;
203- m_Keywords . Append ( ' ' ) ;
204- m_UniqueKeywords . Add ( name ) ;
220+ m_Keywords . Add ( GetKeywordId ( name ) ) ;
205221 }
206222 }
207223
208224 foreach ( var index in subProgram [ "m_LocalKeywordIndices" ] . GetValue < ushort [ ] > ( ) )
209225 {
210226 if ( m_KeywordNames . TryGetValue ( index , out var name ) )
211227 {
212- m_Keywords . Append ( name ) ;
213- m_Keywords . Append ( ' ' ) ;
214- m_UniqueKeywords . Add ( name ) ;
228+ m_Keywords . Add ( GetKeywordId ( name ) ) ;
215229 }
216230 }
217231 }
218232
219- m_InsertSubProgramCommand . Parameters [ "@shader" ] . Value = objectId ;
220- m_InsertSubProgramCommand . Parameters [ "@pass" ] . Value = passNum ;
233+ m_InsertSubProgramCommand . Parameters [ "@id" ] . Value = s_SubProgramId ;
221234 m_InsertSubProgramCommand . Parameters [ "@sub_program" ] . Value = progNum ++ ;
222235 m_InsertSubProgramCommand . Parameters [ "@hw_tier" ] . Value = hwTier != - 1 ? hwTier : subProgram [ "m_ShaderHardwareTier" ] . GetValue < sbyte > ( ) ;
223- m_InsertSubProgramCommand . Parameters [ "@shader_type" ] . Value = shaderType ;
224236 m_InsertSubProgramCommand . Parameters [ "@api" ] . Value = subProgram [ "m_GpuProgramType" ] . GetValue < sbyte > ( ) ;
225- m_InsertSubProgramCommand . Parameters [ "@keywords" ] . Value = m_Keywords . ToString ( ) ;
226237 m_InsertSubProgramCommand . ExecuteNonQuery ( ) ;
238+
239+ m_InsertSubProgramKeywordsCommand . Parameters [ "@subprogram_id" ] . Value = s_SubProgramId ;
240+ foreach ( var keyword in m_Keywords )
241+ {
242+ m_InsertSubProgramKeywordsCommand . Parameters [ "@keyword_id" ] . Value = keyword ;
243+ m_InsertSubProgramKeywordsCommand . ExecuteNonQuery ( ) ;
244+ }
245+
246+ ++ s_SubProgramId ;
227247 }
228248 }
229249
250+ int GetKeywordId ( string keyword )
251+ {
252+ int id ;
253+
254+ if ( ! s_Keywords . TryGetValue ( keyword , out id ) )
255+ {
256+ id = s_Keywords . Count ;
257+ s_Keywords [ keyword ] = id ;
258+
259+ m_InsertKeywordCommand . Parameters [ "@id" ] . Value = id ;
260+ m_InsertKeywordCommand . Parameters [ "@keyword" ] . Value = keyword ;
261+ m_InsertKeywordCommand . ExecuteNonQuery ( ) ;
262+ }
263+
264+ return id ;
265+ }
266+
230267 void IDisposable . Dispose ( )
231268 {
232269 m_InsertCommand . Dispose ( ) ;
233270 m_InsertSubProgramCommand . Dispose ( ) ;
271+ m_InsertKeywordCommand . Dispose ( ) ;
272+ m_InsertSubProgramKeywordsCommand . Dispose ( ) ;
234273 }
235274 }
236275}
0 commit comments