77
88namespace FileFormat
99{
10+ std::string DescriptorReflection::ToString () const
11+ {
12+ std::string result = " DescriptorReflection: { " ;
13+ result += " Binding: " + std::to_string (binding) + " , " ;
14+ result += " Name: " + name + " , " ;
15+ result += " Type: " + std::string (DescriptorTypeReflectionNames[static_cast <u32 >(type)]) + " , " ;
16+ result += " SubType: " + std::string (DescriptorTypeReflectionNames[static_cast <u32 >(subType)]) + " , " ;
17+ result += " Count: " + std::to_string (count);
18+ result += " }" ;
19+ return result;
20+ }
21+
22+ DescriptorSetReflection& ShaderReflection::GetDescriptorSetBySlot (u32 slot)
23+ {
24+ if (!descriptorSets.contains (slot))
25+ {
26+ DescriptorSetReflection descriptorSetReflection;
27+ descriptorSetReflection.slot = slot;
28+
29+ descriptorSets[slot] = descriptorSetReflection;
30+ }
31+
32+ return descriptorSets[slot];
33+ }
34+
1035 ShaderRef* ShaderPack::GetShaderRef (std::shared_ptr<Bytebuffer>& buffer, u32 shaderIndex)
1136 {
1237 if (shaderIndex >= manifest.numShaders )
@@ -18,6 +43,79 @@ namespace FileFormat
1843 return shaderRef;
1944 }
2045
46+ bool ShaderPack::GetShaderReflection (std::shared_ptr<Bytebuffer>& buffer, u32 shaderIndex, ShaderReflection& reflection)
47+ {
48+ ShaderRef* shaderRef = GetShaderRef (buffer, shaderIndex);
49+ if (shaderRef == nullptr || shaderRef->reflectionOffset == 0 || shaderRef->reflectionSize == 0 )
50+ return false ;
51+
52+ u64 readOffset = buffer->readData ;
53+
54+ buffer->readData = shaderRef->reflectionOffset ;
55+ u8 numDescriptorSets;
56+ if (!buffer->GetU8 (numDescriptorSets))
57+ return false ;
58+
59+ reflection.descriptorSets .reserve (numDescriptorSets);
60+
61+ for (u32 i = 0 ; i < numDescriptorSets; i++)
62+ {
63+ u8 setSlot;
64+ u8 numDescriptors;
65+
66+ if (!buffer->GetU8 (setSlot))
67+ return false ;
68+
69+ if (!buffer->GetU8 (numDescriptors))
70+ return false ;
71+
72+ DescriptorSetReflection& descriptorSet = reflection.descriptorSets [setSlot];
73+ descriptorSet.slot = setSlot;
74+ descriptorSet.descriptors .reserve (numDescriptors);
75+
76+ for (u32 j = 0 ; j < numDescriptors; j++)
77+ {
78+ u8 binding;
79+ std::string name;
80+ u8 type;
81+ u8 subType;
82+ u16 count;
83+ u8 accessType;
84+ bool isUsed;
85+ u32 byteOffset;
86+ u32 byteSize;
87+
88+ bool failed = false ;
89+ failed |= !buffer->GetU8 (binding);
90+ failed |= !buffer->GetString (name);
91+ failed |= !buffer->GetU8 (type);
92+ failed |= !buffer->GetU8 (subType);
93+ failed |= !buffer->GetU16 (count);
94+ failed |= !buffer->GetU8 (accessType);
95+ failed |= !buffer->Get (isUsed);
96+ failed |= !buffer->GetU32 (byteOffset);
97+ failed |= !buffer->GetU32 (byteSize);
98+
99+ if (failed)
100+ return false ;
101+
102+ DescriptorReflection& descriptor = descriptorSet.descriptors [binding];
103+ descriptor.binding = binding;
104+ descriptor.name = std::move (name);
105+ descriptor.type = static_cast <DescriptorTypeReflection>(type);
106+ descriptor.subType = static_cast <DescriptorTypeReflection>(subType);
107+ descriptor.count = count;
108+ descriptor.accessType = static_cast <DescriptorAccessTypeReflection>(accessType);
109+ descriptor.isUsed = isUsed;
110+ descriptor.byteOffset = byteOffset;
111+ descriptor.byteSize = byteSize;
112+ }
113+ }
114+
115+ buffer->readData = readOffset;
116+ return true ;
117+ }
118+
21119 u8 * ShaderPack::GetShaderDataPtr (std::shared_ptr<Bytebuffer>& buffer, u32 shaderOffset)
22120 {
23121 if (shaderOffset >= buffer->writtenData )
@@ -39,29 +137,74 @@ namespace FileFormat
39137 manifest.numShaders = static_cast <u32 >(shaders.size ());
40138 NC_ASSERT (shaders.size () > 0 , " ShaderPack must have at least one shader" );
41139
42- // Write the Header and manifest to file
43- output.write (reinterpret_cast <char const *>(&header), sizeof (header));
44- output.write (reinterpret_cast <char const *>(&manifest), sizeof (manifest));
140+ std::shared_ptr<Bytebuffer> buffer = Bytebuffer::Borrow<67108864 >();
141+
142+ // Write the Header and manifest to buffer
143+ buffer->Put (header);
144+ buffer->Put (manifest);
45145
46146 // Write the ShaderRefs to file
47- u64 dataOffset = static_cast <u64 >(output.tellp ()) + (sizeof (ShaderRef) * manifest.numShaders );
147+ u64 baseShaderRefOffset = buffer->writtenData ;
148+ u64 dataOffset = baseShaderRefOffset + (sizeof (ShaderRef) * manifest.numShaders );
149+
48150 ShaderRef shaderRef;
49151 for (u32 i = 0 ; i < shaders.size (); i++)
50152 {
51153 shaderRef.permutationNameHash = shaders[i].permutationNameHash ;
52154 shaderRef.dataOffset = dataOffset;
53155 shaderRef.dataSize = shaders[i].size ;
54156
55- output. write ( reinterpret_cast < char const *>(& shaderRef), sizeof (ShaderRef) );
157+ buffer-> Put ( shaderRef);
56158 dataOffset += shaders[i].size ;
57159 }
58160
59161 // Write the shader blobs to file
60162 for (u32 i = 0 ; i < shaders.size (); i++)
61163 {
62- output. write ( reinterpret_cast < char const *> (shaders[i].data ) , shaders[i].size );
164+ buffer-> PutBytes (shaders[i].data , shaders[i].size );
63165 }
64166
167+ // Write the reflection data to file
168+ for (u32 i = 0 ; i < shaders.size (); i++)
169+ {
170+ u64 reflectionDataStartOffset = static_cast <u64 >(buffer->writtenData );
171+
172+ const ShaderInMemory& shader = shaders[i];
173+
174+ // Write reflection data
175+ u8 numDescriptorSets = static_cast <u8 >(shader.reflection .descriptorSets .size ());
176+ buffer->PutU8 (numDescriptorSets);
177+ for (const auto & [setSlot, descriptorSet] : shader.reflection .descriptorSets )
178+ {
179+ buffer->PutU8 (descriptorSet.slot );
180+
181+ u8 numDescriptors = static_cast <u8 >(descriptorSet.descriptors .size ());
182+ buffer->PutU8 (numDescriptors);
183+ for (const auto & [binding, descriptor] : descriptorSet.descriptors )
184+ {
185+ buffer->PutU8 (descriptor.binding );
186+ buffer->PutString (descriptor.name );
187+ buffer->PutU8 (static_cast <u8 >(descriptor.type ));
188+ buffer->PutU8 (static_cast <u8 >(descriptor.subType ));
189+ buffer->PutU16 (descriptor.count );
190+ buffer->PutU8 (static_cast <u8 >(descriptor.accessType ));
191+ buffer->Put (descriptor.isUsed );
192+ buffer->PutU32 (descriptor.byteOffset );
193+ buffer->PutU32 (descriptor.byteSize );
194+ }
195+ }
196+
197+ u64 reflectionDataEndOffset = static_cast <u64 >(buffer->writtenData );
198+
199+ // Patch ShaderRef with reflection data offset and size
200+ u64 shaderRefOffset = baseShaderRefOffset + (i * sizeof (ShaderRef));
201+ ShaderRef* shaderRefInBuffer = reinterpret_cast <ShaderRef*>(buffer->GetDataPointer () + shaderRefOffset);
202+ shaderRefInBuffer->reflectionOffset = reflectionDataStartOffset;
203+ shaderRefInBuffer->reflectionSize = static_cast <u32 >(reflectionDataEndOffset - reflectionDataStartOffset);
204+ }
205+
206+ output.write (reinterpret_cast <char const *>(buffer->GetDataPointer ()), buffer->writtenData );
207+
65208 output.close ();
66209
67210 return true ;
0 commit comments