@@ -152,7 +152,10 @@ struct Image {
152152static std::unordered_map<std::string, Image> images;
153153static uint32_t imageID = 0 ;
154154
155- void ProcessImages ( const std::string& shaderText ) {
155+ static std::unordered_map<std::string, std::string> buffers;
156+ static uint32_t bufferID = 0 ;
157+
158+ void ProcessImagesBuffers ( const std::string& shaderText ) {
156159 std::string out;
157160 std::istringstream shaderTextStream ( StripLicense ( shaderText ) );
158161
@@ -198,7 +201,14 @@ void ProcessImages( const std::string& shaderText ) {
198201 }
199202
200203 if ( img != IMG_NONE ) {
201- uint32_t offset = imgOffset + 1 ;
204+ uint32_t offset = line.find_last_of ( " " ) + 1 ;
205+ std::string name = line.substr ( offset, line.size () - offset - 1 );
206+
207+ if ( images.find ( name ) != images.end () ) {
208+ continue ;
209+ }
210+
211+ offset = imgOffset + 1 ;
202212 std::string format = line.substr ( offset, line.find ( " " , offset + 1 ) - offset );
203213
204214 std::transform ( format.begin (), format.end (), format.begin (), ::toupper );
@@ -227,16 +237,47 @@ void ProcessImages( const std::string& shaderText ) {
227237
228238 image += img == IMG_CUBE ? " true" : " false" ;
229239
230- offset = line.find_last_of ( " " ) + 1 ;
231- std::string name = line.substr ( offset, line.size () - offset - 1 );
232-
233240 images[name] = { image, " images[" + std::to_string ( imageID ) + " ]" };
234241
235242 imageID++;
236243
237244 continue ;
238245 }
239246
247+ const uint64_t bufferOffset = line.find ( " Buffer" );
248+
249+ if ( bufferOffset == line.find_first_not_of ( " \t " ) && line.find ( " {" ) == std::string::npos && line.find ( " ;" ) != std::string::npos ) {
250+ uint64_t offset = line.find ( " Buffer resource" );
251+
252+ std::string buffer = std::to_string ( bufferID ) + " , " ;
253+
254+ if ( offset != std::string::npos ) {
255+ offset += 16 ;
256+
257+ buffer += line.substr ( offset, line.find ( " " , offset ) - offset ) + " , 0, " ;
258+ } else {
259+ offset = bufferOffset + 7 ;
260+
261+ buffer += " 0.0f, " ;
262+
263+ buffer += line.substr ( offset, line.find ( " " , offset ) - offset ) + " , " ;
264+ }
265+
266+ const uint64_t usageEnd = line.find_last_of ( " " );
267+
268+ offset = line.find ( " " , offset ) + 1 ;
269+
270+ if ( usageEnd > offset ) {
271+ buffer += line.substr ( offset, usageEnd - offset );
272+ } else {
273+ buffer += " 0" ;
274+ }
275+
276+ buffers[line.substr ( usageEnd + 1 , line.size () - usageEnd - 2 )] = buffer;
277+
278+ bufferID++;
279+ };
280+
240281 const std::string::size_type posInsert = line.find ( " #insert" );
241282 const std::string::size_type position = posInsert == std::string::npos ? line.find ( " #include" ) : posInsert;
242283
@@ -255,7 +296,7 @@ void ProcessImages( const std::string& shaderText ) {
255296 shaderInsertPath += " .glsl" ;
256297 }
257298
258- if ( shaderInsertPath == " Images.glsl" ) {
299+ if ( shaderInsertPath == " Images.glsl" || shaderInsertPath == " Buffers.glsl " ) {
259300 continue ;
260301 }
261302
@@ -266,12 +307,20 @@ void ProcessImages( const std::string& shaderText ) {
266307 glslSrc.resize ( strlen ( glslSrc.c_str () ) );
267308 glslSrc.shrink_to_fit ();
268309
269- ProcessImages ( glslSrc );
310+ ProcessImagesBuffers ( glslSrc );
270311 }
271312}
272313
273314static std::unordered_set<std::string> inserts;
274315
316+ struct BufferPushIDs {
317+ uint32_t count = 0 ;
318+ uint32_t ids[16 ];
319+ };
320+
321+ struct std ::unordered_map<uint32_t , BufferPushIDs> bufferPushIDs;
322+ static uint32_t currentSPIRVID = 0 ;
323+
275324std::string ProcessInserts ( const std::string& shaderText, Stage* stage, uint32_t * pushConstSize,
276325 int insertCount = 0 , int lineCount = 0 ) {
277326 std::string out;
@@ -311,13 +360,24 @@ std::string ProcessInserts( const std::string& shaderText, Stage* stage, uint32_
311360 } else if ( pushConstStart ) {
312361 pushConstStart = false ;
313362 } else {
314- const uint32_t start = line.find_first_not_of ( " \t " );
315- const uint32_t end = std::min ( line.find ( " " , start ), line.find ( " \t " , start ) );
363+ uint32_t start = line.find_first_not_of ( " \t " );
364+ uint32_t end = std::min ( line.find ( " " , start ), line.find ( " \t " , start ) );
316365
317366 const std::string type = line.substr ( start, end - start );
367+
368+ start = line.find_first_not_of ( " \t " , end );
369+ end = line.find ( " ;" , start );
370+
371+ const std::string name = line.substr ( start, end - start );
318372
319373 if ( type == " uint" || type == " uint32" || type == " float" ) {
320374 *pushConstSize += 4 ;
375+ } else if ( buffers.find ( name ) != buffers.end () ) {
376+ *pushConstSize += 8 ;
377+
378+ BufferPushIDs& pushIDs = bufferPushIDs[currentSPIRVID];
379+ pushIDs.ids [pushIDs.count ] = stoi ( buffers[name].substr ( 0 , buffers[name].find ( " ," ) ) );
380+ pushIDs.count ++;
321381 } else {
322382 // Assumed BDA
323383 *pushConstSize += 8 ;
@@ -330,6 +390,11 @@ std::string ProcessInserts( const std::string& shaderText, Stage* stage, uint32_
330390 continue ;
331391 }
332392
393+ if ( line.find ( " Buffer" ) == line.find_first_not_of ( " \t " )
394+ && line.find ( " {" ) == std::string::npos && line.find ( " ;" ) != std::string::npos ) {
395+ continue ;
396+ }
397+
333398 uint64_t longestName = 0 ;
334399 uint64_t bestOffset = std::string::npos;
335400
@@ -403,6 +468,20 @@ std::string ProcessInserts( const std::string& shaderText, Stage* stage, uint32_
403468 return out;
404469}
405470
471+ std::string BufferIDsToString ( const BufferPushIDs& buffer ) {
472+ std::string out;
473+
474+ for ( uint32_t i = 0 ; i < buffer.count ; i++ ) {
475+ out += std::to_string ( buffer.ids [i] ) + ( i < 15 ? " , " : " " );
476+ }
477+
478+ for ( uint32_t i = buffer.count ; i < 16 ; i++ ) {
479+ out += i < 15 ? " 0, " : " 0" ;
480+ }
481+
482+ return out;
483+ }
484+
406485int main ( int argc, char ** argv ) {
407486 #ifdef _MSC_VER
408487 std::replace ( graphicsCorePath.begin (), graphicsCorePath.end (), ' /' , ' \\ ' );
@@ -474,7 +553,7 @@ int main( int argc, char** argv ) {
474553 glslSrc.resize ( strlen ( glslSrc.c_str () ) );
475554 glslSrc.shrink_to_fit ();
476555
477- ProcessImages ( glslSrc );
556+ ProcessImagesBuffers ( glslSrc );
478557 }
479558
480559 {
@@ -499,7 +578,8 @@ int main( int argc, char** argv ) {
499578
500579 uint32_t i = 0 ;
501580 for ( const std::pair<std::string, Image>& image : images ) {
502- fprintf ( imageBinds.file , " \t ImageCfg( %s )%s\n " , image.second .src .c_str (), i < imageCount - 1 ? " ," : " " );
581+ fprintf ( imageBinds.file , " \t ImageCfg( %s )%s // %s\n " , image.second .src .c_str (), i < imageCount - 1 ? " ," : " " ,
582+ image.first .c_str () );
503583 i++;
504584 }
505585
@@ -519,6 +599,9 @@ int main( int argc, char** argv ) {
519599
520600 Stage stage = FRAGMENT;
521601 uint32_t pushConstID = 0 ;
602+
603+ currentSPIRVID = i - 3 ;
604+
522605 {
523606 File processedGLSL { srcPath + name, " w" };
524607
@@ -598,11 +681,65 @@ int main( int argc, char** argv ) {
598681 inserts.clear ();
599682 }
600683
684+ {
685+ File bufferBinds { graphicsEnginePath + " Buffers.glsl" , " w" };
686+
687+ fprintf ( bufferBinds.file , " // Auto-generated by VulkanShaderParser, do not modify\n\n " );
688+
689+ fprintf ( bufferBinds.file , " struct BufferCfg {\n " );
690+ fprintf ( bufferBinds.file , " \t uint id;\n " );
691+ fprintf ( bufferBinds.file , " \t float relativeSize;\n " );
692+ fprintf ( bufferBinds.file , " \t uint size;\n " );
693+ fprintf ( bufferBinds.file , " \t uint usage;\n " );
694+ fprintf ( bufferBinds.file , " };\n\n " );
695+
696+ uint32_t bufferCount = buffers.size ();
697+
698+ fprintf ( bufferBinds.file , " BufferCfg bufferConfigs[%u] = BufferCfg[%u] (\n " , bufferCount, bufferCount );
699+
700+ uint32_t i = 0 ;
701+ for ( const std::pair<std::string, std::string>& buffer : buffers ) {
702+ fprintf ( bufferBinds.file , " \t BufferCfg( %s )%s // %s\n " , buffer.second .c_str (), i < bufferCount - 1 ? " ," : " " ,
703+ buffer.first .c_str () );
704+ i++;
705+ }
706+
707+ fprintf ( bufferBinds.file , " );\n\n " );
708+
709+ fprintf ( bufferBinds.file , " const uint bufferCount = %u;\n\n " , bufferCount );
710+
711+ fprintf ( bufferBinds.file , " struct SPIRVBufferCfg {\n " );
712+ fprintf ( bufferBinds.file , " \t uint id;\n " );
713+ fprintf ( bufferBinds.file , " \t uint count;\n " );
714+ fprintf ( bufferBinds.file , " \t uint buffers[16];\n " );
715+ fprintf ( bufferBinds.file , " };\n\n " );
716+
717+ fprintf ( bufferBinds.file , " SPIRVBufferCfg SPIRVBufferConfigs[%u] = SPIRVBufferCfg[%u] (\n " , argc - 3 , argc - 3 );
718+
719+ for ( int i = 0 ; i < argc - 3 ; i++ ) {
720+ if ( !bufferPushIDs.contains ( i ) ) {
721+ static constexpr BufferPushIDs emptyBufferIDs {};
722+
723+ fprintf ( bufferBinds.file , " \t SPIRVBufferCfg( %i, 0, uint[16] ( %s ) )%s\n " , i, BufferIDsToString ( emptyBufferIDs ).c_str (),
724+ i < argc - 4 ? " ," : " " );
725+
726+ continue ;
727+ }
728+
729+ fprintf ( bufferBinds.file , " \t SPIRVBufferCfg( %i, %u, uint[16] ( %s ) )%s\n " , i, bufferPushIDs[i].count ,
730+ BufferIDsToString ( bufferPushIDs[i] ).c_str (), i < argc - 4 ? " ," : " " );
731+ }
732+
733+ fprintf ( bufferBinds.file , " );\n\n " );
734+
735+ fprintf ( bufferBinds.file , " const uint SPIRVCount = %u;" , argc - 3 );
736+ }
737+
601738 fprintf ( spirvH.file , " \n };\n\n " );
602739
603740 fprintf ( spirvH.file , " const std::unordered_map<std::string, uint32> SPIRVMap {\n " );
604741
605- for ( int i = 0 ; i < argc - 3 ; i++ ) {
742+ for ( int i = 0 ; i < argc - 3 ; i++ ) {
606743 fprintf ( spirvH.file , " \t { \" %s\" , %s }%s\n " , SPIRVMap[i].c_str (), SPIRVMap[i].c_str (), i < argc - 4 ? " ," : " " );
607744 }
608745
0 commit comments