11using CathodeLib ;
22using System ;
33using System . Collections . Generic ;
4+ using System . Collections . Specialized ;
45using System . IO ;
6+ using System . Runtime . CompilerServices ;
57using System . Runtime . InteropServices ;
68using static CATHODE . LEGACY . ShadersPAK ;
79
@@ -27,18 +29,237 @@ override protected bool LoadInternal()
2729 if ( ! File . Exists ( _filepathBIN ) ) return false ;
2830 if ( ! File . Exists ( _filepathIDX ) ) return false ;
2931
32+ int vertexShaderCount = 0 ;
33+ int pixelShaderCount = 0 ;
34+ int hullShaderCount = 0 ;
35+ int domainShaderCount = 0 ;
36+ int geometryShaderCount = 0 ;
37+ int computeShaderCount = 0 ;
38+
3039 List < Utilities . PAKContent > content = Utilities . ReadPAK ( _filepathBIN , FileIdentifiers . SHADER_DATA ) ;
3140 for ( int i = 0 ; i < content . Count ; i ++ )
3241 {
3342 if ( content [ i ] . BinIndex != i ) return false ;
3443
3544 using ( BinaryReader reader = new BinaryReader ( new MemoryStream ( content [ i ] . Data ) ) )
3645 {
46+ //The first entry here acts as an additional header
47+ if ( i == 0 )
48+ {
49+ vertexShaderCount = reader . ReadInt32 ( ) ;
50+ pixelShaderCount = reader . ReadInt32 ( ) ;
51+ hullShaderCount = reader . ReadInt32 ( ) ;
52+ domainShaderCount = reader . ReadInt32 ( ) ;
53+ geometryShaderCount = reader . ReadInt32 ( ) ;
54+ computeShaderCount = reader . ReadInt32 ( ) ;
55+ continue ;
56+ }
57+
58+ fourcc fourcc = Utilities . Consume < fourcc > ( reader ) ;
59+ if ( fourcc . ToString ( ) != "DXBC" )
60+ {
61+ throw new Exception ( "Unexpected" ) ;
62+ }
63+
64+ int [ ] checksums = Utilities . ConsumeArray < int > ( reader , 4 ) ;
65+
66+ int one = reader . ReadInt32 ( ) ;
67+ if ( one != 1 )
68+ {
69+ throw new Exception ( "Unexpected" ) ;
70+ }
3771
72+ int size = reader . ReadInt32 ( ) ;
73+ int chunkCount = reader . ReadInt32 ( ) ;
74+ int [ ] chunkOffsets = Utilities . ConsumeArray < int > ( reader , chunkCount ) ;
75+
76+ for ( int x = 0 ; x < chunkCount ; x ++ )
77+ {
78+ if ( reader . BaseStream . Position != chunkOffsets [ x ] )
79+ {
80+ string sdffsd = "" ;
81+ }
82+ reader . BaseStream . Position = chunkOffsets [ x ] ;
83+
84+ fourcc chunkFourcc = Utilities . Consume < fourcc > ( reader ) ;
85+ int chunkSize = reader . ReadInt32 ( ) ;
86+
87+ //TODO: should actually parse this eventually
88+ byte [ ] chunkContent = reader . ReadBytes ( chunkSize ) ;
89+ using ( BinaryReader chunkReader = new BinaryReader ( new MemoryStream ( chunkContent ) ) )
90+ {
91+ switch ( chunkFourcc . ToString ( ) )
92+ {
93+ case "RDEF" :
94+ {
95+ int constantBufferCount = chunkReader . ReadInt32 ( ) ;
96+ int constantBufferOffset = chunkReader . ReadInt32 ( ) ;
97+ int resourceBindingCount = chunkReader . ReadInt32 ( ) ;
98+ int resourceBindingOffset = chunkReader . ReadInt32 ( ) ;
99+
100+ chunkReader . BaseStream . Position += 2 ; //0, 5
101+
102+ int type = chunkReader . ReadInt16 ( ) ;
103+ if ( type != - 2 && type != - 1 )
104+ {
105+ //Console.WriteLine(type);
106+ string sdffd = "" ;
107+ }
108+ else
109+ {
110+ string sfgsdfsf = "" ;
111+ }
112+ //DXBCType programType = (DXBCType)chunkReader.ReadInt32();
113+
114+ int flags = chunkReader . ReadInt32 ( ) ;
115+ int creatorStringOffset = chunkReader . ReadInt32 ( ) ;
116+
117+ chunkReader . BaseStream . Position += 28 ; //RD11, 60, 24, 32, 40, 36, 12
118+
119+ int interfaceSlotCount = chunkReader . ReadInt32 ( ) ;
120+
121+ if ( resourceBindingCount != 0 && chunkReader . BaseStream . Position != resourceBindingOffset )
122+ throw new Exception ( "Unexpected" ) ;
123+
124+ int [ ] resourceNameOffsets = new int [ resourceBindingCount ] ;
125+ for ( int z = 0 ; z < resourceBindingCount ; z ++ )
126+ {
127+ resourceNameOffsets [ z ] = chunkReader . ReadInt32 ( ) ;
128+ int ShaderInputType = chunkReader . ReadInt32 ( ) ;
129+ int ResourceReturnType = chunkReader . ReadInt32 ( ) ;
130+ int ResourceViewDimension = chunkReader . ReadInt32 ( ) ;
131+ int SampleCount = chunkReader . ReadInt32 ( ) ;
132+ int BindPoint = chunkReader . ReadInt32 ( ) ;
133+ int BindCount = chunkReader . ReadInt32 ( ) ;
134+ int ShaderInputFlags = chunkReader . ReadInt32 ( ) ;
135+ }
136+ for ( int z = 0 ; z < resourceBindingCount ; z ++ )
137+ {
138+ if ( chunkReader . BaseStream . Position != resourceNameOffsets [ z ] )
139+ throw new Exception ( "Unexpected" ) ;
140+
141+ string name = Utilities . ReadString ( chunkReader ) ;
142+ //Console.WriteLine("Resource Binding Name: " + name);
143+ }
144+
145+ Utilities . Align ( chunkReader ) ;
146+
147+ //chunkReader.BaseStream.Position = constantBufferOffset;
148+ if ( constantBufferCount != 0 && chunkReader . BaseStream . Position != constantBufferOffset )
149+ throw new Exception ( "Unexpected" ) ;
150+
151+ int [ ] cbNameOffsets = new int [ constantBufferCount ] ;
152+ int [ ] cbVariableCounts = new int [ constantBufferCount ] ;
153+ int [ ] cbVariableOffsets = new int [ constantBufferCount ] ;
154+ int [ ] [ ] cbVariableNameOffsets = new int [ constantBufferCount ] [ ] ;
155+ for ( int z = 0 ; z < constantBufferCount ; z ++ )
156+ {
157+ cbNameOffsets [ z ] = chunkReader . ReadInt32 ( ) ;
158+ cbVariableCounts [ z ] = chunkReader . ReadInt32 ( ) ;
159+ cbVariableOffsets [ z ] = chunkReader . ReadInt32 ( ) ;
160+ int SizeInBytes = chunkReader . ReadInt32 ( ) ;
161+ int Flags = chunkReader . ReadInt32 ( ) ;
162+ int Type = chunkReader . ReadInt32 ( ) ;
163+
164+ if ( Type != 0 || Flags != 0 )
165+ {
166+ string sdfsdf = "" ;
167+ }
168+ }
169+ for ( int z = 0 ; z < constantBufferCount ; z ++ )
170+ {
171+ //string name = Utilities.ReadString(chunkReader, cbNameOffsets[z]);
172+ //Console.WriteLine("Constant Bufffer Name: " + name);
173+
174+ chunkReader . BaseStream . Position = cbVariableOffsets [ z ] ;
175+ //if (chunkReader.BaseStream.Position != cbVariableOffsets[z])
176+ // throw new Exception("Unexpected");
177+
178+ cbVariableNameOffsets [ z ] = new int [ cbVariableCounts [ z ] ] ;
179+ int [ ] typeOffsets = new int [ cbVariableCounts [ z ] ] ;
180+ for ( int p = 0 ; p < cbVariableCounts [ z ] ; p ++ )
181+ {
182+ cbVariableNameOffsets [ z ] [ p ] = chunkReader . ReadInt32 ( ) ;
183+ int DataOffset = chunkReader . ReadInt32 ( ) ;
184+ int DataSize = chunkReader . ReadInt32 ( ) ;
185+ int Flags = chunkReader . ReadInt32 ( ) ;
186+ typeOffsets [ p ] = chunkReader . ReadInt32 ( ) ;
187+ int DefaultValueOffset = chunkReader . ReadInt32 ( ) ;
188+
189+ if ( DefaultValueOffset != 0 )
190+ {
191+ string sdfsdf = "" ;
192+ }
193+
194+ // TODO: I think the version 5 is different than 4. This is not there on Version 4.
195+ int [ ] unk = Utilities . ConsumeArray < int > ( chunkReader , 4 ) ;
196+ }
197+ for ( int p = 0 ; p < cbVariableCounts [ z ] ; p ++ )
198+ {
199+ chunkReader . BaseStream . Position = typeOffsets [ p ] ;
200+ //if (chunkReader.BaseStream.Position != typeOffsets[p])
201+ // throw new Exception("Unexpected");
202+
203+ int Class = chunkReader . ReadInt16 ( ) ;
204+ int Type = chunkReader . ReadInt16 ( ) ;
205+ int RowCount = chunkReader . ReadInt16 ( ) ;
206+ int ColumnCount = chunkReader . ReadInt16 ( ) ;
207+ int ArrayCount = chunkReader . ReadInt16 ( ) ;
208+ int MemberCount = chunkReader . ReadInt16 ( ) ;
209+ int MembersOffset = chunkReader . ReadInt16 ( ) ;
210+
211+ if ( MembersOffset != 0 )
212+ {
213+ string sdfsdf = "" ;
214+ }
215+
216+ // TODO: I think the version 5 is different than 4. This is not there on Version 4.
217+ short [ ] Unknown_ = Utilities . ConsumeArray < Int16 > ( chunkReader , 9 ) ;
218+ int NameStringOffset = chunkReader . ReadInt32 ( ) ;
219+ }
220+ }
221+ break ;
222+ }
223+
224+ case "PCSG" :
225+ case "ISGN" :
226+ case "OSGN" :
227+ {
228+ break ;
229+ }
230+
231+ case "SHEX" :
232+ {
233+ chunkReader . BaseStream . Position += 2 ; //80
234+
235+ dxbc_chunk_shex_type type = ( dxbc_chunk_shex_type ) chunkReader . ReadInt16 ( ) ;
236+ int count = chunkReader . ReadInt32 ( ) ;
237+ byte [ ] contentBytes = chunkReader . ReadBytes ( ( count - 2 ) * 4 ) ;
238+
239+ if ( chunkReader . BaseStream . Length != chunkReader . BaseStream . Position )
240+ throw new Exception ( "" ) ;
241+ break ;
242+ }
243+
244+
245+ case "STAT" :
246+ {
247+ dxbc_chunk_stat stat = Utilities . Consume < dxbc_chunk_stat > ( chunkReader ) ;
248+
249+ if ( chunkReader . BaseStream . Length != chunkReader . BaseStream . Position )
250+ throw new Exception ( "" ) ;
251+ break ;
252+ }
253+
254+ default :
255+ throw new Exception ( "Unexpected" ) ;
256+ }
257+ }
258+ }
38259 }
39260 }
40261
41- //Read the index remapping pak ( this is actually just an incrementing count lol)
262+ //I don't think we need to read this really, it's just a count.
42263 content = Utilities . ReadPAK ( _filepathIDX , FileIdentifiers . SHADER_DATA ) ;
43264 for ( int i = 0 ; i < content . Count ; i ++ )
44265 {
@@ -54,6 +275,13 @@ override protected bool LoadInternal()
54275 content = Utilities . ReadPAK ( _filepath , FileIdentifiers . SHADER_DATA ) ;
55276 for ( int i = 0 ; i < content . Count ; i ++ )
56277 {
278+ //Console.WriteLine(content[i].BinIndex);
279+
280+ if ( content [ i ] . BinIndex != i )
281+ {
282+ string sdfsdf = "" ;
283+ }
284+
57285 using ( BinaryReader reader = new BinaryReader ( new MemoryStream ( content [ i ] . Data ) ) )
58286 {
59287 Entries . Add ( new Shader ( ) ) ;
@@ -176,21 +404,80 @@ override protected bool SaveInternal()
176404 #endregion
177405
178406 #region STRUCTURES
407+
408+ public enum DXBCType
409+ {
410+ VERTEX = - 2 ,
411+ PIXEL = - 1 ,
412+ }
413+
414+ enum dxbc_chunk_shex_type
415+ {
416+ SHEXShader_Pixel ,
417+ SHEXShader_Vertex ,
418+ SHEXShader_Geometry ,
419+ SHEXShader_Hull ,
420+ SHEXShader_Domain ,
421+ SHEXShader_Compute ,
422+ } ;
423+
424+ struct dxbc_chunk_stat
425+ {
426+ public int InstructionCount ;
427+ public int TempRegisterCount ;
428+ public int DefineCount ;
429+ public int DeclarationCount ;
430+ public int FloatInstructionCount ;
431+ public int IntInstructionCount ;
432+ public int UIntInstructionCount ;
433+ public int StaticFlowControlCount ;
434+ public int DynamicFlowControlCount ;
435+ public int MacroInstructionCount ; // Not sure.
436+ public int TempArrayCount ;
437+ public int ArrayInstructionCount ;
438+ public int CutInstructionCount ;
439+ public int EmitInstructionCount ;
440+ public int TextureNormalInstructionCount ;
441+ public int TextureLoadInstructionCount ;
442+ public int TextureComparisonInstructionCount ;
443+ public int TextureBiasInstructionCount ;
444+ public int TextureGradientInstructionCount ;
445+ public int MovInstructionCount ;
446+ public int MovCInstructionCount ;
447+ public int Unknown0_ ;
448+ public int InputPrimitiveForGeometryShaders ;
449+ public int PrimitiveTopologyForGeometryShaders ;
450+ public int MaxOutputVertexCountForGeometryShaders ;
451+
452+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 2 ) ]
453+ public int [ ] unk0 ; //zeros
454+
455+ public int IsSampleFrequencyShader ; // 1 for sample frequency shadeer, otherwise 0.
456+
457+ [ MarshalAs ( UnmanagedType . ByValArray , SizeConst = 9 ) ]
458+ public int [ ] unk1 ;
459+ } ;
460+
179461 public class Shader
180462 {
181- public string FileName = "" ; //The name of the file in the shader archive (unsure how to get this right now with the weird _BIN/PAK way of working)
182463
183- public int FileLength = 0 ; //The length of the file in the archive for this header
184- public int FileLengthWithPadding = 0 ; //The length of the file in the archive for this header, with any padding at the end of the file included
464+ }
465+
466+ public class VertexShader : Shader
467+ {
468+
469+ }
470+ public class PixelShader : Shader
471+ {
185472
186- public int FileOffset = 0 ; //Position in archive from end of header list
187- public int FileIndex = 0 ; //The index of the file
473+ }
474+ public class HullShader : Shader
475+ {
188476
189- public byte [ ] FileContent ; //The content for the file
477+ }
478+ public class DomainShader : Shader
479+ {
190480
191- //I think this is just garbage that got dumped by accident
192- public byte [ ] StringPart1 ; //4 bytes that look like they're part of a filepath
193- public byte [ ] StringPart2 ; //4 bytes that look like they're part of a filepath
194481 }
195482 #endregion
196483 }
0 commit comments