Skip to content

Commit c044476

Browse files
committed
shaders continued
1 parent 8eaf5dc commit c044476

2 files changed

Lines changed: 318 additions & 10 deletions

File tree

CathodeLib/Scripts/CATHODE/Shaders.cs

Lines changed: 297 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using CathodeLib;
22
using System;
33
using System.Collections.Generic;
4+
using System.Collections.Specialized;
45
using System.IO;
6+
using System.Runtime.CompilerServices;
57
using System.Runtime.InteropServices;
68
using 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
}

CathodeLib/Scripts/Utilities.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ public static string ReadString(byte[] bytes, int position)
7676
}
7777
return to_return;
7878
}
79+
public static string ReadString(BinaryReader reader, int position, bool resetPosition = true)
80+
{
81+
long startPos = reader.BaseStream.Position;
82+
reader.BaseStream.Position = position;
83+
84+
string to_return = "";
85+
for (int i = 0; i < int.MaxValue; i++)
86+
{
87+
byte this_byte = reader.ReadByte();
88+
if (this_byte == 0x00) break;
89+
to_return += (char)this_byte;
90+
}
91+
92+
if (resetPosition) reader.BaseStream.Position = startPos;
93+
return to_return;
94+
}
7995
public static string ReadString(BinaryReader reader)
8096
{
8197
string to_return = "";
@@ -509,5 +525,10 @@ public struct fourcc
509525
{
510526
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
511527
public char[] V;
528+
529+
public override string ToString()
530+
{
531+
return new string(V);
532+
}
512533
}
513534
}

0 commit comments

Comments
 (0)