From 23e692891efd311d49655e34e1c8bad02e2303f9 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Thu, 1 Feb 2024 23:52:04 +0300 Subject: [PATCH 1/8] xrRender_R2/r2_R_lights.cpp: get rid of indexed erasing in render_lights --- src/Layers/xrRender_R2/r2_R_lights.cpp | 50 +++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 4e8b413619d..95d3c5045a0 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -32,7 +32,8 @@ void CRender::render_lights(light_Package& LP) L->vis_update(); if (!L->vis.visible) { - source.erase(source.begin() + it); + std::swap(source[it], source.back()); + source.pop_back(); it--; } else @@ -42,25 +43,26 @@ void CRender::render_lights(light_Package& LP) } } - // 2. refactor - infact we could go from the backside and sort in ascending order { xr_vector& source = LP.v_shadowed; xr_vector refactored; refactored.reserve(source.size()); const size_t total = source.size(); + std::sort(source.begin(), source.end(), [](light* l1, light* l2) + { + const u32 a0 = l1->X.S.size; + const u32 a1 = l2->X.S.size; + return a0 < a1; // ascending order + }); + for (u16 smap_ID = 0; refactored.size() != total; ++smap_ID) { LP_smap_pool.initialize(RImplementation.o.smapsize); - std::sort(source.begin(), source.end(), [](light* l1, light* l2) - { - const u32 a0 = l1->X.S.size; - const u32 a1 = l2->X.S.size; - return a0 > a1; // reverse -> descending - }); - for (size_t test = 0; test < source.size(); ++test) + for (auto &L : source) { - light* L = source[test]; + if (!L) + continue; SMAP_Rect R{}; if (LP_smap_pool.push(R, L->X.S.size)) { @@ -69,14 +71,12 @@ void CRender::render_lights(light_Package& LP) L->X.S.posY = R.min.y; L->vis.smap_ID = smap_ID; refactored.push_back(L); - source.erase(source.begin() + test); - --test; + L = nullptr; } } } // save (lights are popped from back) - std::reverse(refactored.begin(), refactored.end()); LP.v_shadowed = std::move(refactored); } @@ -129,14 +129,14 @@ void CRender::render_lights(light_Package& LP) } }; - const auto& flush_lights = [&]() + const auto& flush_lights = [] (CRender& render, xr_vector& lights_queue) { for (const auto& [L, task, batch_id] : lights_queue) { VERIFY(task); TaskScheduler->Wait(*task); - auto& dsgraph = get_context(batch_id); + auto& dsgraph = render.get_context(batch_id); const bool bNormal = !dsgraph.mapNormalPasses[0][0].empty() || !dsgraph.mapMatrixPasses[0][0].empty(); const bool bSpecial = !dsgraph.mapNormalPasses[1][0].empty() || !dsgraph.mapMatrixPasses[1][0].empty() || @@ -145,27 +145,27 @@ void CRender::render_lights(light_Package& LP) { PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHT); - Stats.s_merged++; + render.Stats.s_merged++; L_spot_s.push_back(L); - Target->phase_smap_spot(dsgraph.cmd_list, L); + render.Target->phase_smap_spot(dsgraph.cmd_list, L); dsgraph.cmd_list.set_xform_world(Fidentity); dsgraph.cmd_list.set_xform_view(L->X.S.view); dsgraph.cmd_list.set_xform_project(L->X.S.project); dsgraph.render_graph(0); if (ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) { - if (check_grass_shadow(L, ViewBase)) + if (check_grass_shadow(L, render.ViewBase)) { - Details->fade_distance = -1; // Use light position to calc "fade" - Details->light_position.set(L->position); - Details->Render(dsgraph.cmd_list); + render.Details->fade_distance = -1; // Use light position to calc "fade" + render.Details->light_position.set(L->position); + render.Details->Render(dsgraph.cmd_list); } } L->X.S.transluent = FALSE; if (bSpecial) { L->X.S.transluent = TRUE; - Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); + render.Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_GRAPH); dsgraph.render_graph(1); // normal level, secondary priority PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_SORTED); @@ -174,7 +174,7 @@ void CRender::render_lights(light_Package& LP) } else { - Stats.s_finalclip++; + render.Stats.s_finalclip++; } L->svis[batch_id].end(); // NOTE(DX11): occqs are fetched here, this should be done on the imm context only @@ -206,7 +206,7 @@ void CRender::render_lights(light_Package& LP) if (batch_id == R_dsgraph_structure::INVALID_CONTEXT_ID) { VERIFY(!lights_queue.empty()); - flush_lights(); + flush_lights(*this, lights_queue); continue; } @@ -228,7 +228,7 @@ void CRender::render_lights(light_Package& LP) } lights_queue.emplace_back(data); } - flush_lights(); // in case if something left + flush_lights(*this, lights_queue); // in case if something left cmd_list.Invalidate(); From ff3fac7604afefbcbd45821d71f724d503d20de0 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Fri, 2 Feb 2024 00:28:04 +0300 Subject: [PATCH 2/8] xrGame/cover_manager.cpp: optimize allocations, refactor compute_static_cover --- src/xrGame/cover_manager.cpp | 43 ++++++++++++++++++++---------------- src/xrGame/cover_manager.h | 4 +++- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/xrGame/cover_manager.cpp b/src/xrGame/cover_manager.cpp index 3eafe6685d7..8cb9c7d0242 100644 --- a/src/xrGame/cover_manager.cpp +++ b/src/xrGame/cover_manager.cpp @@ -74,37 +74,42 @@ void CCoverManager::compute_static_cover() { clear(); xr_delete(m_covers); - m_covers = xr_new( - ai().level_graph().header().box(), ai().level_graph().header().cell_size() * .5f, 8 * 65536, 4 * 65536); - m_temp.resize(ai().level_graph().header().vertex_count()); - + const CLevelGraph& graph = ai().level_graph(); - const u32 levelVertexCount = ai().level_graph().header().vertex_count(); + const LevelGraph::CHeader &levelGraphHeader = graph.header(); + const u32 levelVertexCount = levelGraphHeader.vertex_count(); + + m_covers = xr_new(levelGraphHeader.box(), levelGraphHeader.cell_size() * .5f, 8 * 65536, 4 * 65536); + // avoiding extra allocations with a static storage for m_covers + static xr_vector> quadTreeStaticStorage; + quadTreeStaticStorage.resize(levelVertexCount); + m_temp.resize(levelVertexCount); + xr_parallel_for(TaskRange(0, levelVertexCount), [&](const TaskRange& range) { for (u32 i = range.begin(); i != range.end(); ++i) { - const CLevelGraph::CLevelVertex& vertex = *graph.vertex(i); - if (vertex.high_cover(0) + vertex.high_cover(1) + vertex.high_cover(2) + vertex.high_cover(3)) - { - m_temp[i] = edge_vertex(i); - continue; - } + m_temp[i] = false; + quadTreeStaticStorage[i] = std::nullopt; - if (vertex.low_cover(0) + vertex.low_cover(1) + vertex.low_cover(2) + vertex.low_cover(3)) + const CLevelGraph::CLevelVertex& vertex = *graph.vertex(i); + const int highCover = vertex.high_cover(0) + vertex.high_cover(1) + vertex.high_cover(2) + vertex.high_cover(3); + const int lowCover = vertex.low_cover(0) + vertex.low_cover(1) + vertex.low_cover(2) + vertex.low_cover(3); + + if (highCover || lowCover) { m_temp[i] = edge_vertex(i); - continue; + if (m_temp[i] && critical_cover(i)) + { + quadTreeStaticStorage[i] = CCoverPoint(graph.vertex_position(graph.vertex(i)), i); + } } - - m_temp[i] = false; } }); - - for (u32 i = 0; i < levelVertexCount; ++i) - if (m_temp[i] && critical_cover(i)) - m_covers->insert(xr_new(ai().level_graph().vertex_position(ai().level_graph().vertex(i)), i)); + for (auto &p : quadTreeStaticStorage) + if (p.has_value()) + m_covers->insert(&p.value()); VERIFY(!m_smart_covers_storage); m_smart_covers_storage = xr_new(); diff --git a/src/xrGame/cover_manager.h b/src/xrGame/cover_manager.h index 35abc233025..3d4cb36417a 100644 --- a/src/xrGame/cover_manager.h +++ b/src/xrGame/cover_manager.h @@ -44,7 +44,9 @@ class CCoverManager protected: CPointQuadTree* m_covers; - xr_vector m_temp; + // vector is not applicable for `m_temp` + // since it is filled in parallel_for (https://timsong-cpp.github.io/cppwp/container.requirements.dataraces). + xr_vector m_temp; mutable PointVector m_nearest; private: From b846569888e9b6f6653f22e34d5fbef1d8032a73 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Fri, 2 Feb 2024 00:45:39 +0300 Subject: [PATCH 3/8] xrGame/space_restriction_shape.h: parallelize iterate_vertices in fill_shape --- src/xrAICore/Navigation/level_graph.h | 1 + src/xrAICore/Navigation/level_graph_inline.h | 11 ++++-- src/xrGame/Level.cpp | 3 +- src/xrGame/space_restriction_shape.cpp | 38 ++++++++++++++++++-- src/xrGame/space_restrictor.cpp | 9 ++++- 5 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/xrAICore/Navigation/level_graph.h b/src/xrAICore/Navigation/level_graph.h index b9793c5aca0..0e062528a98 100644 --- a/src/xrAICore/Navigation/level_graph.h +++ b/src/xrAICore/Navigation/level_graph.h @@ -232,6 +232,7 @@ class XRAICORE_API CLevelGraph IC void assign_y_values(xr_vector& path); template IC void iterate_vertices(const Fvector& min_position, const Fvector& max_position, const P& predicate) const; + IC std::pair get_range(const Fvector& min_position, const Fvector& max_position) const; IC bool check_vertex_in_direction(u32 start_vertex_id, const Fvector2& start_position, u32 finish_vertex_id) const; IC u32 check_position_in_direction( u32 start_vertex_id, const Fvector2& start_position, const Fvector2& finish_position) const; diff --git a/src/xrAICore/Navigation/level_graph_inline.h b/src/xrAICore/Navigation/level_graph_inline.h index 2a79520eb3f..c3a9b49a3f6 100644 --- a/src/xrAICore/Navigation/level_graph_inline.h +++ b/src/xrAICore/Navigation/level_graph_inline.h @@ -571,6 +571,14 @@ IC void CLevelGraph::clear_mask_no_check(u32 vertex_id) { m_access_mask[vertex_i template IC void CLevelGraph::iterate_vertices( const Fvector& min_position, const Fvector& max_position, const P& predicate) const +{ + auto [I, E] = get_range(min_position, max_position); + + for (; I != E; ++I) + predicate(*I); +} + +IC std::pair CLevelGraph::get_range(const Fvector& min_position, const Fvector& max_position) const { const auto begin = m_nodes->begin(), end = m_nodes->end(); @@ -591,8 +599,7 @@ IC void CLevelGraph::iterate_vertices( else E = end; - for (; I != E; ++I) - predicate(*I); + return {I, E}; } IC u32 CLevelGraph::max_x() const { return (m_max_x); } diff --git a/src/xrGame/Level.cpp b/src/xrGame/Level.cpp index 2f34fdfa841..8fd66abe36b 100644 --- a/src/xrGame/Level.cpp +++ b/src/xrGame/Level.cpp @@ -443,8 +443,7 @@ void CLevel::OnFrame() if (g_mt_config.test(mtMap)) { R_ASSERT(m_map_manager); - Device.seqParallel.push_back( - fastdelegate::FastDelegate0<>(m_map_manager, &CMapManager::Update)); + Device.seqParallel.emplace_back(m_map_manager, &CMapManager::Update); } else MapManager().Update(); diff --git a/src/xrGame/space_restriction_shape.cpp b/src/xrGame/space_restriction_shape.cpp index 59b3dcb3cb0..aeaace289b0 100644 --- a/src/xrGame/space_restriction_shape.cpp +++ b/src/xrGame/space_restriction_shape.cpp @@ -12,6 +12,7 @@ #include "xrAICore/Navigation/level_graph.h" #include "space_restrictor.h" #include "xrAICore/Navigation/graph_engine.h" +#include "xrCore/Threading/ParallelFor.hpp" struct CBorderMergePredicate { @@ -79,10 +80,43 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape) } default: NODEFAULT; } - ai().level_graph().iterate_vertices(start, dest, CBorderMergePredicate(this)); + + CLevelGraph& graph = ai().level_graph(); + + std::mutex mergeMutex; + + auto [begin, end] = graph.get_range(start, dest); + xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (auto &range) { + xr_vector m_border_chunk; + m_border_chunk.reserve(range.size()); + for (auto &vertex : range) + { + if (inside(graph.vertex_id(&vertex), true) && + !inside(graph.vertex_id(&vertex), false)) + m_border_chunk.push_back(graph.vertex_id(&vertex)); + } + std::lock_guard lock(mergeMutex); + if (m_border.capacity() < m_border.size() + m_border_chunk.size()) + m_border.reserve(m_border.size() + m_border_chunk.size()); + for (auto x : m_border_chunk) + m_border.push_back(x); + }); #ifdef DEBUG - ai().level_graph().iterate_vertices(start, dest, CShapeTestPredicate(this)); + xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (const auto &range) { + xr_vector m_test_storage_chunk; + m_test_storage_chunk.reserve(range.size()); + for (auto &vertex : range) + { + if (inside(graph.vertex_id(&vertex), false)) + m_test_storage_chunk.push_back(graph.vertex_id(&vertex)); + } + std::lock_guard lock(mergeMutex); + if (m_test_storage.capacity() < m_test_storage.size() + m_test_storage_chunk.size()) + m_test_storage.reserve(m_test_storage.size() + m_test_storage_chunk.size()); + for (auto x : m_test_storage_chunk) + m_test_storage.push_back(x); + }); #endif } diff --git a/src/xrGame/space_restrictor.cpp b/src/xrGame/space_restrictor.cpp index c2287aeb4ce..4f04e87c26b 100644 --- a/src/xrGame/space_restrictor.cpp +++ b/src/xrGame/space_restrictor.cpp @@ -100,7 +100,14 @@ void CSpaceRestrictor::net_Destroy() bool CSpaceRestrictor::inside(const Fsphere& sphere) const { if (!actual()) - prepare(); + { + static std::mutex prepareMutex; + std::lock_guard lock(prepareMutex); + + // Double-checked locking + if (!actual()) + prepare(); + } if (!m_selfbounds.intersect(sphere)) return (false); From 39c3f31122f55000048a79812af299a23a135aa2 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Fri, 2 Feb 2024 01:25:04 +0300 Subject: [PATCH 4/8] fix codestyle issues --- src/Layers/xrRender_R2/r2_R_lights.cpp | 2 +- src/xrAICore/Navigation/level_graph_inline.h | 30 ++++++++++---------- src/xrGame/cover_manager.cpp | 4 +-- src/xrGame/space_restriction_shape.cpp | 4 +-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 95d3c5045a0..d88a8d92785 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -59,7 +59,7 @@ void CRender::render_lights(light_Package& LP) for (u16 smap_ID = 0; refactored.size() != total; ++smap_ID) { LP_smap_pool.initialize(RImplementation.o.smapsize); - for (auto &L : source) + for (auto& L : source) { if (!L) continue; diff --git a/src/xrAICore/Navigation/level_graph_inline.h b/src/xrAICore/Navigation/level_graph_inline.h index c3a9b49a3f6..a9f76def73b 100644 --- a/src/xrAICore/Navigation/level_graph_inline.h +++ b/src/xrAICore/Navigation/level_graph_inline.h @@ -572,34 +572,34 @@ template IC void CLevelGraph::iterate_vertices( const Fvector& min_position, const Fvector& max_position, const P& predicate) const { - auto [I, E] = get_range(min_position, max_position); + auto [begin, end] = get_range(min_position, max_position); - for (; I != E; ++I) - predicate(*I); + for (; begin != end; ++begin) + predicate(*begin); } -IC std::pair CLevelGraph::get_range(const Fvector& min_position, const Fvector& max_position) const +IC std::pair CLevelGraph::get_range(const Fvector& min_position, const Fvector& max_position) const { - const auto begin = m_nodes->begin(), end = m_nodes->end(); + const auto _begin = m_nodes->begin(), _end = m_nodes->end(); - CLevelVertex *I, *E; + CLevelVertex *begin, *end; if (valid_vertex_position(min_position)) - I = std::lower_bound( - begin, end, vertex_position(min_position).xz(), &vertex::predicate2); + begin = std::lower_bound( + _begin, _end, vertex_position(min_position).xz(), &vertex::predicate2); else - I = begin; + begin = _begin; if (valid_vertex_position(max_position)) { - E = std::upper_bound( - begin, end, vertex_position(max_position).xz(), &vertex::predicate); - if (E != (end)) - ++E; + end = std::upper_bound( + _begin, _end, vertex_position(max_position).xz(), &vertex::predicate); + if (end != (_end)) + ++end; } else - E = end; + end = _end; - return {I, E}; + return { begin, end }; } IC u32 CLevelGraph::max_x() const { return (m_max_x); } diff --git a/src/xrGame/cover_manager.cpp b/src/xrGame/cover_manager.cpp index 8cb9c7d0242..95125f88481 100644 --- a/src/xrGame/cover_manager.cpp +++ b/src/xrGame/cover_manager.cpp @@ -76,7 +76,7 @@ void CCoverManager::compute_static_cover() xr_delete(m_covers); const CLevelGraph& graph = ai().level_graph(); - const LevelGraph::CHeader &levelGraphHeader = graph.header(); + const LevelGraph::CHeader& levelGraphHeader = graph.header(); const u32 levelVertexCount = levelGraphHeader.vertex_count(); m_covers = xr_new(levelGraphHeader.box(), levelGraphHeader.cell_size() * .5f, 8 * 65536, 4 * 65536); @@ -107,7 +107,7 @@ void CCoverManager::compute_static_cover() } } }); - for (auto &p : quadTreeStaticStorage) + for (auto& p : quadTreeStaticStorage) if (p.has_value()) m_covers->insert(&p.value()); diff --git a/src/xrGame/space_restriction_shape.cpp b/src/xrGame/space_restriction_shape.cpp index aeaace289b0..b574cdcaf94 100644 --- a/src/xrGame/space_restriction_shape.cpp +++ b/src/xrGame/space_restriction_shape.cpp @@ -86,7 +86,7 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape) std::mutex mergeMutex; auto [begin, end] = graph.get_range(start, dest); - xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (auto &range) { + xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) { xr_vector m_border_chunk; m_border_chunk.reserve(range.size()); for (auto &vertex : range) @@ -103,7 +103,7 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape) }); #ifdef DEBUG - xr_parallel_for(TaskRange{begin, end}, [this, &mergeMutex, &graph] (const auto &range) { + xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) { xr_vector m_test_storage_chunk; m_test_storage_chunk.reserve(range.size()); for (auto &vertex : range) From d9da42f2596272be32b5f4076828f367d326e824 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Fri, 2 Feb 2024 02:47:38 +0300 Subject: [PATCH 5/8] fix codestyle issues 2 --- src/Layers/xrRender_R2/r2_R_lights.cpp | 25 +++++++++++++------------ src/xrGame/space_restriction_shape.cpp | 10 ++++++---- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index d88a8d92785..245615008c0 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -43,6 +43,7 @@ void CRender::render_lights(light_Package& LP) } } + // 2. refactor { xr_vector& source = LP.v_shadowed; xr_vector refactored; @@ -129,14 +130,14 @@ void CRender::render_lights(light_Package& LP) } }; - const auto& flush_lights = [] (CRender& render, xr_vector& lights_queue) + const auto& flush_lights = [] (xr_vector& lights_queue) { for (const auto& [L, task, batch_id] : lights_queue) { VERIFY(task); TaskScheduler->Wait(*task); - auto& dsgraph = render.get_context(batch_id); + auto& dsgraph = RImplementation.get_context(batch_id); const bool bNormal = !dsgraph.mapNormalPasses[0][0].empty() || !dsgraph.mapMatrixPasses[0][0].empty(); const bool bSpecial = !dsgraph.mapNormalPasses[1][0].empty() || !dsgraph.mapMatrixPasses[1][0].empty() || @@ -145,27 +146,27 @@ void CRender::render_lights(light_Package& LP) { PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHT); - render.Stats.s_merged++; + RImplementation.Stats.s_merged++; L_spot_s.push_back(L); - render.Target->phase_smap_spot(dsgraph.cmd_list, L); + RImplementation.Target->phase_smap_spot(dsgraph.cmd_list, L); dsgraph.cmd_list.set_xform_world(Fidentity); dsgraph.cmd_list.set_xform_view(L->X.S.view); dsgraph.cmd_list.set_xform_project(L->X.S.project); dsgraph.render_graph(0); if (ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) { - if (check_grass_shadow(L, render.ViewBase)) + if (check_grass_shadow(L, RImplementation.ViewBase)) { - render.Details->fade_distance = -1; // Use light position to calc "fade" - render.Details->light_position.set(L->position); - render.Details->Render(dsgraph.cmd_list); + RImplementation.Details->fade_distance = -1; // Use light position to calc "fade" + RImplementation.Details->light_position.set(L->position); + RImplementation.Details->Render(dsgraph.cmd_list); } } L->X.S.transluent = FALSE; if (bSpecial) { L->X.S.transluent = TRUE; - render.Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); + RImplementation.Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_GRAPH); dsgraph.render_graph(1); // normal level, secondary priority PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_SORTED); @@ -174,7 +175,7 @@ void CRender::render_lights(light_Package& LP) } else { - render.Stats.s_finalclip++; + RImplementation.Stats.s_finalclip++; } L->svis[batch_id].end(); // NOTE(DX11): occqs are fetched here, this should be done on the imm context only @@ -206,7 +207,7 @@ void CRender::render_lights(light_Package& LP) if (batch_id == R_dsgraph_structure::INVALID_CONTEXT_ID) { VERIFY(!lights_queue.empty()); - flush_lights(*this, lights_queue); + flush_lights(lights_queue); continue; } @@ -228,7 +229,7 @@ void CRender::render_lights(light_Package& LP) } lights_queue.emplace_back(data); } - flush_lights(*this, lights_queue); // in case if something left + flush_lights(lights_queue); // in case if something left cmd_list.Invalidate(); diff --git a/src/xrGame/space_restriction_shape.cpp b/src/xrGame/space_restriction_shape.cpp index b574cdcaf94..dfddf02133f 100644 --- a/src/xrGame/space_restriction_shape.cpp +++ b/src/xrGame/space_restriction_shape.cpp @@ -86,10 +86,11 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape) std::mutex mergeMutex; auto [begin, end] = graph.get_range(start, dest); - xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) { + xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) + { xr_vector m_border_chunk; m_border_chunk.reserve(range.size()); - for (auto &vertex : range) + for (const auto& vertex : range) { if (inside(graph.vertex_id(&vertex), true) && !inside(graph.vertex_id(&vertex), false)) @@ -103,10 +104,11 @@ void CSpaceRestrictionShape::fill_shape(const CCF_Shape::shape_def& shape) }); #ifdef DEBUG - xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) { + xr_parallel_for(TaskRange(begin, end), [this, &mergeMutex, &graph] (const auto& range) + { xr_vector m_test_storage_chunk; m_test_storage_chunk.reserve(range.size()); - for (auto &vertex : range) + for (const auto& vertex : range) { if (inside(graph.vertex_id(&vertex), false)) m_test_storage_chunk.push_back(graph.vertex_id(&vertex)); From 525d793cbead5de6887bcc11aea81449a7493af5 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Sat, 3 Feb 2024 14:52:27 +0300 Subject: [PATCH 6/8] fix codestyle issues 3 --- src/Layers/xrRender_R2/r2_R_lights.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Layers/xrRender_R2/r2_R_lights.cpp b/src/Layers/xrRender_R2/r2_R_lights.cpp index 245615008c0..f0d92eedf1e 100644 --- a/src/Layers/xrRender_R2/r2_R_lights.cpp +++ b/src/Layers/xrRender_R2/r2_R_lights.cpp @@ -130,14 +130,14 @@ void CRender::render_lights(light_Package& LP) } }; - const auto& flush_lights = [] (xr_vector& lights_queue) + const auto& flush_lights = [this] (xr_vector& lights_queue) { for (const auto& [L, task, batch_id] : lights_queue) { VERIFY(task); TaskScheduler->Wait(*task); - auto& dsgraph = RImplementation.get_context(batch_id); + auto& dsgraph = get_context(batch_id); const bool bNormal = !dsgraph.mapNormalPasses[0][0].empty() || !dsgraph.mapMatrixPasses[0][0].empty(); const bool bSpecial = !dsgraph.mapNormalPasses[1][0].empty() || !dsgraph.mapMatrixPasses[1][0].empty() || @@ -146,27 +146,27 @@ void CRender::render_lights(light_Package& LP) { PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHT); - RImplementation.Stats.s_merged++; + Stats.s_merged++; L_spot_s.push_back(L); - RImplementation.Target->phase_smap_spot(dsgraph.cmd_list, L); + Target->phase_smap_spot(dsgraph.cmd_list, L); dsgraph.cmd_list.set_xform_world(Fidentity); dsgraph.cmd_list.set_xform_view(L->X.S.view); dsgraph.cmd_list.set_xform_project(L->X.S.project); dsgraph.render_graph(0); if (ps_r2_ls_flags.test(R2FLAG_SUN_DETAILS)) { - if (check_grass_shadow(L, RImplementation.ViewBase)) + if (check_grass_shadow(L, ViewBase)) { - RImplementation.Details->fade_distance = -1; // Use light position to calc "fade" - RImplementation.Details->light_position.set(L->position); - RImplementation.Details->Render(dsgraph.cmd_list); + Details->fade_distance = -1; // Use light position to calc "fade" + Details->light_position.set(L->position); + Details->Render(dsgraph.cmd_list); } } L->X.S.transluent = FALSE; if (bSpecial) { L->X.S.transluent = TRUE; - RImplementation.Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); + Target->phase_smap_spot_tsh(dsgraph.cmd_list, L); PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_GRAPH); dsgraph.render_graph(1); // normal level, secondary priority PIX_EVENT_CTX(dsgraph.cmd_list, SHADOWED_LIGHTS_RENDER_SORTED); @@ -175,11 +175,11 @@ void CRender::render_lights(light_Package& LP) } else { - RImplementation.Stats.s_finalclip++; + Stats.s_finalclip++; } L->svis[batch_id].end(); // NOTE(DX11): occqs are fetched here, this should be done on the imm context only - RImplementation.release_context(batch_id); + release_context(batch_id); } lights_queue.clear(); From 6f1c24dfea11667da0721461a0e2ea09fcfc7580 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Sat, 3 Feb 2024 15:04:17 +0300 Subject: [PATCH 7/8] Layers/xrRenderDX11/dx11SH_Texture.cpp: aggregate CreateShaderResourceView calls --- src/Layers/xrRenderDX11/dx11SH_Texture.cpp | 24 ++++++++-------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp index 9e70f5b8d73..aed544414ae 100644 --- a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp +++ b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp @@ -117,23 +117,17 @@ void CTexture::surface_set(ID3DBaseTexture* surf) _RELEASE(srv_all); CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, &srv_all)); + if (desc.SampleDesc.Count <= 1) + ViewDesc.Texture2DArray.ArraySize = desc.ArraySize; + else + ViewDesc.Texture2DMSArray.ArraySize = desc.ArraySize; + srv_per_slice.resize(desc.ArraySize); - for (u32 id = 0; id < desc.ArraySize; ++id) - { - _RELEASE(srv_per_slice[id]); + for (auto &x : srv_per_slice) + _RELEASE(x); + + CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, srv_per_slice.data())); - if (desc.SampleDesc.Count <= 1) - { - ViewDesc.Texture2DArray.ArraySize = 1; - ViewDesc.Texture2DArray.FirstArraySlice = id; - } - else - { - ViewDesc.Texture2DMSArray.ArraySize = 1; - ViewDesc.Texture2DMSArray.FirstArraySlice = id; - } - CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, &srv_per_slice[id])); - } set_slice(-1); } else From 95534b81adce97fc7d45a87bd73c53accfeec457 Mon Sep 17 00:00:00 2001 From: Egor Olefirenko Date: Sat, 3 Feb 2024 18:25:57 +0300 Subject: [PATCH 8/8] revert dx11SH_Texture.cpp changes, fix spacing --- src/Layers/xrRenderDX11/dx11SH_Texture.cpp | 24 ++++++++++++++-------- src/xrGame/cover_manager.cpp | 6 +++--- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp index aed544414ae..9e70f5b8d73 100644 --- a/src/Layers/xrRenderDX11/dx11SH_Texture.cpp +++ b/src/Layers/xrRenderDX11/dx11SH_Texture.cpp @@ -117,17 +117,23 @@ void CTexture::surface_set(ID3DBaseTexture* surf) _RELEASE(srv_all); CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, &srv_all)); - if (desc.SampleDesc.Count <= 1) - ViewDesc.Texture2DArray.ArraySize = desc.ArraySize; - else - ViewDesc.Texture2DMSArray.ArraySize = desc.ArraySize; - srv_per_slice.resize(desc.ArraySize); - for (auto &x : srv_per_slice) - _RELEASE(x); - - CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, srv_per_slice.data())); + for (u32 id = 0; id < desc.ArraySize; ++id) + { + _RELEASE(srv_per_slice[id]); + if (desc.SampleDesc.Count <= 1) + { + ViewDesc.Texture2DArray.ArraySize = 1; + ViewDesc.Texture2DArray.FirstArraySlice = id; + } + else + { + ViewDesc.Texture2DMSArray.ArraySize = 1; + ViewDesc.Texture2DMSArray.FirstArraySlice = id; + } + CHK_DX(HW.pDevice->CreateShaderResourceView(pSurface, &ViewDesc, &srv_per_slice[id])); + } set_slice(-1); } else diff --git a/src/xrGame/cover_manager.cpp b/src/xrGame/cover_manager.cpp index 95125f88481..735c763c1fa 100644 --- a/src/xrGame/cover_manager.cpp +++ b/src/xrGame/cover_manager.cpp @@ -74,7 +74,7 @@ void CCoverManager::compute_static_cover() { clear(); xr_delete(m_covers); - + const CLevelGraph& graph = ai().level_graph(); const LevelGraph::CHeader& levelGraphHeader = graph.header(); const u32 levelVertexCount = levelGraphHeader.vertex_count(); @@ -85,7 +85,7 @@ void CCoverManager::compute_static_cover() static xr_vector> quadTreeStaticStorage; quadTreeStaticStorage.resize(levelVertexCount); m_temp.resize(levelVertexCount); - + xr_parallel_for(TaskRange(0, levelVertexCount), [&](const TaskRange& range) { for (u32 i = range.begin(); i != range.end(); ++i) @@ -96,7 +96,7 @@ void CCoverManager::compute_static_cover() const CLevelGraph::CLevelVertex& vertex = *graph.vertex(i); const int highCover = vertex.high_cover(0) + vertex.high_cover(1) + vertex.high_cover(2) + vertex.high_cover(3); const int lowCover = vertex.low_cover(0) + vertex.low_cover(1) + vertex.low_cover(2) + vertex.low_cover(3); - + if (highCover || lowCover) { m_temp[i] = edge_vertex(i);