@@ -501,46 +501,7 @@ void MaterialSystem::GenerateTexturesBuffer( std::vector<TextureData>& textures,
501501void MaterialSystem::GenerateWorldCommandBuffer ( std::vector<MaterialSurface>& surfaces ) {
502502 Log::Debug ( " Generating world command buffer" );
503503
504- totalBatchCount = 0 ;
505-
506- for ( MaterialSurface& surface : surfaces ) {
507- if ( surface.skyBrush ) {
508- continue ;
509- }
510-
511- for ( uint8_t stage = 0 ; stage < surface.stages ; stage++ ) {
512- Material* material = &materialPacks[surface.materialPackIDs [stage]].materials [surface.materialIDs [stage]];
513- material->drawCommandCount ++;
514- }
515- }
516-
517- uint32_t batchOffset = 0 ;
518- uint32_t globalID = 0 ;
519- for ( MaterialPack& pack : materialPacks ) {
520- for ( Material& material : pack.materials ) {
521- material.surfaceCommandBatchOffset = batchOffset;
522-
523- const uint32_t cmdCount = material.drawCommandCount ;
524- const uint32_t batchCount = cmdCount % SURFACE_COMMANDS_PER_BATCH == 0 ? cmdCount / SURFACE_COMMANDS_PER_BATCH
525- : cmdCount / SURFACE_COMMANDS_PER_BATCH + 1 ;
526-
527- material.surfaceCommandBatchOffset = batchOffset;
528- material.surfaceCommandBatchCount = batchCount;
529-
530- batchOffset += batchCount;
531- material.globalID = globalID;
532-
533- material.drawCommandCount = 0 ;
534-
535- totalBatchCount += batchCount;
536- globalID++;
537- }
538- }
539-
540- Log::Debug ( " Total batch count: %u" , totalBatchCount );
541-
542- totalDrawSurfs = surfaces.size ();
543-
504+ // TexBundles
544505 if ( glConfig2.maxUniformBlockSize >= MIN_MATERIAL_UBO_SIZE ) {
545506 texDataBufferType = GL_UNIFORM_BUFFER;
546507 texDataBindingPoint = BufferBind::TEX_DATA;
@@ -566,6 +527,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
566527 dynamicTexDataOffset = texData.size () * TEX_BUNDLE_SIZE;
567528 dynamicTexDataSize = dynamicTexData.size () * TEX_BUNDLE_SIZE;
568529
530+ // Lightmaps/Deluxemaps
569531 lightMapDataUBO.BufferStorage ( MAX_LIGHTMAPS * LIGHTMAP_SIZE, 1 , nullptr );
570532
571533 uint64_t * lightMapData = ( uint64_t * ) stagingBuffer.MapBuffer ( MAX_LIGHTMAPS * LIGHTMAP_SIZE );
@@ -605,14 +567,43 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
605567
606568 stagingBuffer.QueueStagingCopy ( &lightMapDataUBO, 0 );
607569
608- surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH;
570+ // Surface batches
571+ for ( MaterialSurface& surface : surfaces ) {
572+ if ( surface.skyBrush ) {
573+ continue ;
574+ }
609575
610- culledCommandsBuffer.BufferStorage ( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1 , nullptr );
611- GLIndirectCommand* culledCommands =
612- ( GLIndirectCommand* ) stagingBuffer.MapBuffer ( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES );
613- memset ( culledCommands, 0 , surfaceCommandsCount * sizeof ( GLIndirectCommand ) * MAX_VIEWFRAMES );
576+ for ( uint8_t stage = 0 ; stage < surface.stages ; stage++ ) {
577+ Material* material = &materialPacks[surface.materialPackIDs [stage]].materials [surface.materialIDs [stage]];
578+ material->drawCommandCount ++;
579+ }
580+ }
581+
582+ totalBatchCount = 0 ;
583+ uint32_t batchOffset = 0 ;
584+ uint32_t globalID = 0 ;
585+ for ( MaterialPack& pack : materialPacks ) {
586+ for ( Material& material : pack.materials ) {
587+ material.surfaceCommandBatchOffset = batchOffset;
588+
589+ const uint32_t cmdCount = material.drawCommandCount ;
590+ const uint32_t batchCount = cmdCount % SURFACE_COMMANDS_PER_BATCH == 0 ? cmdCount / SURFACE_COMMANDS_PER_BATCH
591+ : cmdCount / SURFACE_COMMANDS_PER_BATCH + 1 ;
592+
593+ material.surfaceCommandBatchOffset = batchOffset;
594+ material.surfaceCommandBatchCount = batchCount;
595+
596+ batchOffset += batchCount;
597+ material.globalID = globalID;
598+
599+ material.drawCommandCount = 0 ;
600+
601+ totalBatchCount += batchCount;
602+ globalID++;
603+ }
604+ }
614605
615- stagingBuffer. QueueStagingCopy ( &culledCommandsBuffer, 0 );
606+ Log::Debug ( " Total batch count: %u " , totalBatchCount );
616607
617608 surfaceBatchesUBO.BufferStorage ( MAX_SURFACE_COMMAND_BATCHES * SURFACE_COMMAND_BATCH_SIZE, 1 , nullptr );
618609 SurfaceCommandBatch* surfaceCommandBatches =
@@ -639,12 +630,6 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
639630
640631 stagingBuffer.QueueStagingCopy ( &surfaceBatchesUBO, 0 );
641632
642- atomicCommandCountersBuffer.BufferStorage ( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr );
643- uint32_t * atomicCommandCounters = stagingBuffer.MapBuffer ( MAX_COMMAND_COUNTERS * MAX_VIEWS );
644- memset ( atomicCommandCounters, 0 , MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof ( uint32_t ) );
645-
646- stagingBuffer.QueueStagingCopy ( &atomicCommandCountersBuffer, 0 );
647-
648633 /* For use in debugging compute shaders
649634 Intended for use with Nsight Graphics to format the output */
650635 if ( r_materialDebug.Get () ) {
@@ -656,21 +641,31 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
656641 debugSSBO.UnmapBuffer ();
657642 }
658643
644+ // Surfaces
645+ surfaceCommandsCount = totalBatchCount * SURFACE_COMMANDS_PER_BATCH;
646+
647+ culledCommandsBuffer.BufferStorage ( surfaceCommandsCount * INDIRECT_COMMAND_SIZE * MAX_VIEWFRAMES, 1 , nullptr );
648+
649+ atomicCommandCountersBuffer.BufferStorage ( MAX_COMMAND_COUNTERS * MAX_VIEWS, MAX_FRAMES, nullptr );
650+ uint32_t * atomicCommandCounters = stagingBuffer.MapBuffer ( MAX_COMMAND_COUNTERS * MAX_VIEWS );
651+ memset ( atomicCommandCounters, 0 , MAX_COMMAND_COUNTERS * MAX_VIEWFRAMES * sizeof ( uint32_t ) );
652+
653+ stagingBuffer.QueueStagingCopy ( &atomicCommandCountersBuffer, 0 );
654+
659655 stagingBuffer.FlushAll ();
660656
661- surfaceDescriptorsCount = totalDrawSurfs;
657+ surfaceDescriptorsCount = surfaces.size ();
658+
662659 descriptorSize = BOUNDING_SPHERE_SIZE + maxStages;
663- surfaceDescriptorsSSBO.BufferStorage ( surfaceDescriptorsCount* descriptorSize, 1 , nullptr );
660+ surfaceDescriptorsSSBO.BufferStorage ( surfaceDescriptorsCount * descriptorSize, 1 , nullptr );
664661 uint32_t * surfaceDescriptors = stagingBuffer.MapBuffer ( surfaceDescriptorsCount * descriptorSize );
665662
666663 stagingBuffer.QueueStagingCopy ( &surfaceDescriptorsSSBO, 0 );
667664
668665 surfaceCommandsSSBO.BufferStorage ( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES, 1 , nullptr );
669666 SurfaceCommand* surfaceCommands =
670- ( SurfaceCommand* ) stagingBuffer.MapBuffer ( surfaceCommandsCount * SURFACE_COMMAND_SIZE * MAX_VIEWFRAMES );
671- memset ( surfaceCommands, 0 , surfaceCommandsCount * sizeof ( SurfaceCommand ) * MAX_VIEWFRAMES );
672-
673- stagingBuffer.QueueStagingCopy ( &surfaceCommandsSSBO, 0 );
667+ ( SurfaceCommand* ) stagingBuffer.MapBuffer ( surfaceCommandsCount * SURFACE_COMMAND_SIZE );
668+ memset ( surfaceCommands, 0 , surfaceCommandsCount * sizeof ( SurfaceCommand ) );
674669
675670 for ( MaterialSurface& surface : surfaces ) {
676671 if ( surface.skyBrush ) {
@@ -713,7 +708,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
713708 }
714709
715710 for ( int i = 0 ; i < MAX_VIEWFRAMES; i++ ) {
716- memcpy ( surfaceCommands + surfaceCommandsCount * i, surfaceCommands, surfaceCommandsCount * sizeof ( SurfaceCommand ) );
711+ stagingBuffer. QueueStagingCopy ( &surfaceCommandsSSBO, i * surfaceCommandsCount * SURFACE_COMMAND_SIZE );
717712 }
718713
719714 stagingBuffer.FlushAll ();
@@ -722,7 +717,7 @@ void MaterialSystem::GenerateWorldCommandBuffer( std::vector<MaterialSurface>& s
722717 for ( MaterialPack& pack : materialPacks ) {
723718 totalCount += pack.materials .size ();
724719 }
725- Log::Notice ( " Generated %u BSP materials from %u BSP surfaces" , totalCount, totalDrawSurfs );
720+ Log::Notice ( " Generated %u BSP materials from %u BSP surfaces" , totalCount, surfaceDescriptorsCount );
726721 Log::Notice ( " Materials UBO: total: %.2f kb, dynamic: %.2f kb, texData: %.2f kb" ,
727722 totalStageSize * 4 / 1024 .0f , dynamicStagesSize * 4 / 1024 .0f ,
728723 ( texData.size () + dynamicTexData.size () ) * TEX_BUNDLE_SIZE * 4 / 1024 .0f );
@@ -1584,12 +1579,12 @@ void MaterialSystem::CullSurfaces() {
15841579 }
15851580
15861581 gl_cullShader->BindProgram ( 0 );
1587- uint32_t globalWorkGroupX = totalDrawSurfs % MAX_COMMAND_COUNTERS == 0 ?
1588- totalDrawSurfs / MAX_COMMAND_COUNTERS : totalDrawSurfs / MAX_COMMAND_COUNTERS + 1 ;
1582+ uint32_t globalWorkGroupX = surfaceDescriptorsCount % MAX_COMMAND_COUNTERS == 0 ?
1583+ surfaceDescriptorsCount / MAX_COMMAND_COUNTERS : surfaceDescriptorsCount / MAX_COMMAND_COUNTERS + 1 ;
15891584 GL_Bind ( depthImage );
15901585 gl_cullShader->SetUniform_Frame ( nextFrame );
15911586 gl_cullShader->SetUniform_ViewID ( view );
1592- gl_cullShader->SetUniform_TotalDrawSurfs ( totalDrawSurfs );
1587+ gl_cullShader->SetUniform_SurfaceDescriptorsCount ( surfaceDescriptorsCount );
15931588 gl_cullShader->SetUniform_UseFrustumCulling ( r_gpuFrustumCulling.Get () );
15941589 gl_cullShader->SetUniform_UseOcclusionCulling ( r_gpuOcclusionCulling.Get () );
15951590 gl_cullShader->SetUniform_CameraPosition ( origin );
@@ -1753,7 +1748,7 @@ void MaterialSystem::Free() {
17531748
17541749 buildOneShader = true ;
17551750
1756- totalDrawSurfs = 0 ;
1751+ surfaceDescriptorsCount = 0 ;
17571752
17581753 currentFrame = 0 ;
17591754 nextFrame = 1 ;
0 commit comments