diff --git a/src.cmake b/src.cmake index 015c647e4f..306a087319 100644 --- a/src.cmake +++ b/src.cmake @@ -147,6 +147,7 @@ set(GLSLSOURCELIST ${ENGINE_DIR}/renderer/glsl_source/cull_cp.glsl ${ENGINE_DIR}/renderer/glsl_source/depthReduction_cp.glsl ${ENGINE_DIR}/renderer/glsl_source/processSurfaces_cp.glsl + ${ENGINE_DIR}/renderer/glsl_source/material_cp.glsl ${ENGINE_DIR}/renderer/glsl_source/material_vp.glsl ${ENGINE_DIR}/renderer/glsl_source/material_fp.glsl ${ENGINE_DIR}/renderer/glsl_source/skybox_vp.glsl diff --git a/src/engine/renderer/Material.cpp b/src/engine/renderer/Material.cpp index 9e4a6fc34b..f9beb9a05f 100644 --- a/src/engine/renderer/Material.cpp +++ b/src/engine/renderer/Material.cpp @@ -1604,9 +1604,11 @@ void MaterialSystem::UpdateDynamicSurfaces() { void MaterialSystem::UpdateFrameData() { atomicCommandCountersBuffer.BindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); + gl_clearSurfacesShader->BindProgram( 0 ); gl_clearSurfacesShader->SetUniform_Frame( nextFrame ); gl_clearSurfacesShader->DispatchCompute( MAX_VIEWS, 1, 1 ); + atomicCommandCountersBuffer.UnBindBufferBase( GL_SHADER_STORAGE_BUFFER, Util::ordinal( BufferBind::COMMAND_COUNTERS_STORAGE ) ); GL_CheckErrors(); @@ -1774,11 +1776,8 @@ void MaterialSystem::StartFrame() { if ( !generatedWorldCommandBuffer ) { return; } + frames[nextFrame].viewCount = 0; - - // renderedMaterials.clear(); - // UpdateDynamicSurfaces(); - // UpdateFrameData(); } void MaterialSystem::EndFrame() { @@ -2059,7 +2058,6 @@ void MaterialSystem::RenderMaterials( const shaderSort_t fromSort, const shaderS renderedMaterials.clear(); UpdateDynamicSurfaces(); UpdateFrameData(); - // StartFrame(); // Make sure compute dispatches from the last frame finished writing to memory glMemoryBarrier( GL_COMMAND_BARRIER_BIT ); diff --git a/src/engine/renderer/glsl_source/common_cp.glsl b/src/engine/renderer/glsl_source/common_cp.glsl index d78714c532..9634075238 100644 --- a/src/engine/renderer/glsl_source/common_cp.glsl +++ b/src/engine/renderer/glsl_source/common_cp.glsl @@ -54,41 +54,9 @@ array must be in the form of uvec4 array[] */ + gl_GlobalInvocationID.y * gl_NumWorkGroups.x * gl_WorkGroupSize.x\ + gl_GlobalInvocationID.x ) -/* Common structs */ +/* Macro combinations for subgroup ops */ -struct BoundingSphere { - vec3 origin; - float radius; -}; - -struct SurfaceDescriptor { - BoundingSphere boundingSphere; - uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; -}; - -struct PortalSurface { - BoundingSphere boundingSphere; - - uint drawSurfID; - float distance; - vec2 padding; -}; - -struct GLIndirectCommand { - uint count; - uint instanceCount; - uint firstIndex; - int baseVertex; - uint baseInstance; -}; - -struct IndirectCompactCommand { - uint count; - uint firstIndex; - uint baseInstance; -}; - -struct SurfaceCommand { - bool enabled; - IndirectCompactCommand drawCommand; -}; +#if defined(HAVE_KHR_shader_subgroup_basic) && defined(HAVE_KHR_shader_subgroup_arithmetic)\ + && defined(HAVE_KHR_shader_subgroup_ballot) && defined(HAVE_ARB_shader_atomic_counter_ops) + #define SUBGROUP_STREAM_COMPACTION +#endif diff --git a/src/engine/renderer/glsl_source/cull_cp.glsl b/src/engine/renderer/glsl_source/cull_cp.glsl index 8c19d55706..1e210e21fc 100644 --- a/src/engine/renderer/glsl_source/cull_cp.glsl +++ b/src/engine/renderer/glsl_source/cull_cp.glsl @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* cull_cp.glsl */ #insert common_cp +#insert material_cp // Keep this to 64 because we don't want extra shared mem etc. to be allocated, and to minimize wasted lanes layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; diff --git a/src/engine/renderer/glsl_source/material_cp.glsl b/src/engine/renderer/glsl_source/material_cp.glsl new file mode 100644 index 0000000000..8156273bd8 --- /dev/null +++ b/src/engine/renderer/glsl_source/material_cp.glsl @@ -0,0 +1,72 @@ +/* +=========================================================================== + +Daemon BSD Source Code +Copyright (c) 2025 Daemon Developers +All rights reserved. + +This file is part of the Daemon BSD Source Code (Daemon Source Code). + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Daemon developers nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=========================================================================== +*/ + +/* material_cp.glsl */ + +struct BoundingSphere { + vec3 origin; + float radius; +}; + +struct SurfaceDescriptor { + BoundingSphere boundingSphere; + uint surfaceCommandIDs[MAX_SURFACE_COMMANDS]; +}; + +struct PortalSurface { + BoundingSphere boundingSphere; + + uint drawSurfID; + float distance; + vec2 padding; +}; + +struct GLIndirectCommand { + uint count; + uint instanceCount; + uint firstIndex; + int baseVertex; + uint baseInstance; +}; + +struct IndirectCompactCommand { + uint count; + uint firstIndex; + uint baseInstance; +}; + +struct SurfaceCommand { + bool enabled; + IndirectCompactCommand drawCommand; +}; diff --git a/src/engine/renderer/glsl_source/processSurfaces_cp.glsl b/src/engine/renderer/glsl_source/processSurfaces_cp.glsl index c5d28513b3..71d8f2d3db 100644 --- a/src/engine/renderer/glsl_source/processSurfaces_cp.glsl +++ b/src/engine/renderer/glsl_source/processSurfaces_cp.glsl @@ -35,6 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /* processSurfaces_cp.glsl */ #insert common_cp +#insert material_cp // Keep this to 64 because we don't want extra shared mem etc. to be allocated, and to minimize wasted lanes layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in; @@ -59,15 +60,10 @@ uniform uint u_Frame; uniform uint u_ViewID; uniform uint u_SurfaceCommandsOffset; -#if defined(HAVE_KHR_shader_subgroup_basic) && defined(HAVE_KHR_shader_subgroup_arithmetic)\ - && defined(HAVE_KHR_shader_subgroup_ballot) && defined(HAVE_ARB_shader_atomic_counter_ops) - #define HAVE_processSurfaces_subgroup -#endif - void AddDrawCommand( in uint commandID, in uvec2 materialID ) { SurfaceCommand command = surfaceCommands[commandID + u_SurfaceCommandsOffset]; - #if defined(HAVE_processSurfaces_subgroup) + #if defined(SUBGROUP_STREAM_COMPACTION) const uint count = subgroupBallotBitCount( subgroupBallot( command.enabled ) ); // Exclusive scan so we can determine the offset for each lane without any synchronization const uint subgroupOffset = subgroupExclusiveAdd( command.enabled ? 1 : 0 ); @@ -83,13 +79,6 @@ void AddDrawCommand( in uint commandID, in uvec2 materialID ) { #endif if( command.enabled ) { - // materialID.x is the global ID of the material - // materialID.y is the offset for the memory allocated to the material's culled commands - #if !defined(HAVE_processSurfaces_subgroup) - const uint atomicCmdID = atomicCounterIncrement( atomicCommandCounters[materialID.x - + MAX_COMMAND_COUNTERS * ( MAX_VIEWS * u_Frame + u_ViewID )] ); - #endif - GLIndirectCommand indirectCommand; indirectCommand.count = command.drawCommand.count; indirectCommand.instanceCount = 1; @@ -97,9 +86,13 @@ void AddDrawCommand( in uint commandID, in uvec2 materialID ) { indirectCommand.baseVertex = 0; indirectCommand.baseInstance = command.drawCommand.baseInstance; - #if defined(HAVE_processSurfaces_subgroup) + // materialID.x is the global ID of the material + // materialID.y is the offset for the memory allocated to the material's culled commands + #if defined(SUBGROUP_STREAM_COMPACTION) culledCommands[atomicCmdID + subgroupOffset + materialID.y * MAX_COMMAND_COUNTERS + u_SurfaceCommandsOffset] = indirectCommand; #else + const uint atomicCmdID = atomicCounterIncrement( atomicCommandCounters[materialID.x + + MAX_COMMAND_COUNTERS * ( MAX_VIEWS * u_Frame + u_ViewID )] ); culledCommands[atomicCmdID + materialID.y * MAX_COMMAND_COUNTERS + u_SurfaceCommandsOffset] = indirectCommand; #endif } diff --git a/src/engine/renderer/shaders.cpp b/src/engine/renderer/shaders.cpp index 8f5dfcd7e7..cba461b06b 100644 --- a/src/engine/renderer/shaders.cpp +++ b/src/engine/renderer/shaders.cpp @@ -51,6 +51,7 @@ #include "shadowFill_fp.glsl.h" #include "shadowFill_vp.glsl.h" #include "skybox_fp.glsl.h" +#include "material_cp.glsl.h" #include "material_vp.glsl.h" #include "material_fp.glsl.h" #include "common.glsl.h" @@ -101,6 +102,7 @@ std::unordered_map shadermap({ { "lighttile_vp.glsl", std::string(reinterpret_cast(lighttile_vp_glsl), sizeof(lighttile_vp_glsl)) }, { "liquid_fp.glsl", std::string(reinterpret_cast(liquid_fp_glsl), sizeof(liquid_fp_glsl)) }, { "liquid_vp.glsl", std::string(reinterpret_cast(liquid_vp_glsl), sizeof(liquid_vp_glsl)) }, + { "material_cp.glsl", std::string( reinterpret_cast< const char* >( material_cp_glsl ), sizeof( material_cp_glsl ) ) }, { "material_vp.glsl", std::string( reinterpret_cast< const char* >( material_vp_glsl ), sizeof( material_vp_glsl ) ) }, { "material_fp.glsl", std::string( reinterpret_cast< const char* >( material_fp_glsl ), sizeof( material_fp_glsl ) ) }, { "motionblur_fp.glsl", std::string(reinterpret_cast(motionblur_fp_glsl), sizeof(motionblur_fp_glsl)) }, diff --git a/src/engine/renderer/tr_bsp.cpp b/src/engine/renderer/tr_bsp.cpp index a5bfab45ee..bfbd75d9b1 100644 --- a/src/engine/renderer/tr_bsp.cpp +++ b/src/engine/renderer/tr_bsp.cpp @@ -3440,6 +3440,12 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) case mapSurfaceType_t::MST_FLARE: Log::Warn( "Surface type not supported: MST_FLARE; firstIndex: %i, numIndexes: %i, shaderNum: %i", in->firstIndex, in->numIndexes, in->shaderNum ); + + // We still have to set these because other code will be checking them + out->data = ( surfaceType_t* ) ri.Hunk_Alloc( sizeof( surfaceType_t ), ha_pref::h_low ); + *out->data = surfaceType_t::SF_BAD; + out->shader = tr.defaultShader; + numFlares++; break;