Compare commits

..

1 Commits

Author SHA1 Message Date
lizzie c454e30249 2026-09-06 20:58:56
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-09-06 20:58:56 +00:00
4 changed files with 38 additions and 21 deletions
@@ -73,16 +73,20 @@ Result DisplayLayerManager::CreateManagedDisplayLayer(u64* out_layer_id) {
R_TRY(m_manager_display_service->CreateManagedLayer( R_TRY(m_manager_display_service->CreateManagedLayer(
out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()})); out_layer_id, 0, display_id, Service::AppletResourceUserId{m_process->GetProcessId()}));
m_manager_display_service->SetLayerVisibility(m_visible, *out_layer_id);
(void)m_display_service->GetContainer()->SetLayerStackMask(*out_layer_id,
this->GetLayerStackMask());
if (m_applet_id != AppletId::Application) { if (m_applet_id != AppletId::Application) {
(void)m_manager_display_service->SetLayerBlending(m_blending_enabled, *out_layer_id); (void)m_manager_display_service->SetLayerBlending(m_blending_enabled, *out_layer_id);
if (m_applet_id == AppletId::OverlayDisplay) { if (m_applet_id == AppletId::OverlayDisplay) {
(void)m_manager_display_service->SetLayerZIndex(-1, *out_layer_id); (void)m_manager_display_service->SetLayerZIndex(Overlay, *out_layer_id);
(void)m_display_service->GetContainer()->SetLayerIsOverlay(*out_layer_id, true); (void)m_display_service->GetContainer()->SetLayerIsOverlay(*out_layer_id, true);
} else { } else {
(void)m_manager_display_service->SetLayerZIndex(1, *out_layer_id); (void)m_manager_display_service->SetLayerZIndex(Foreground, *out_layer_id);
} }
} }
(void)m_display_service->GetContainer()->SetLayerZIndex(*out_layer_id, true);
m_managed_display_layers.emplace(*out_layer_id); m_managed_display_layers.emplace(*out_layer_id);
R_SUCCEED(); R_SUCCEED();
@@ -122,11 +126,12 @@ Result DisplayLayerManager::IsSystemBufferSharingEnabled() {
// Ensure the overlay layer is visible // Ensure the overlay layer is visible
m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id); m_manager_display_service->SetLayerVisibility(m_visible, m_system_shared_layer_id);
(void)m_display_service->GetContainer()->SetLayerStackMask(m_system_shared_layer_id,
this->GetLayerStackMask());
m_manager_display_service->SetLayerBlending(m_blending_enabled, m_system_shared_layer_id); m_manager_display_service->SetLayerBlending(m_blending_enabled, m_system_shared_layer_id);
s32 initial_z = 1; s32 initial_z = Foreground;
(void)m_display_service->GetContainer()->SetLayerZIndex(m_system_shared_layer_id, true);
if (m_applet_id == AppletId::OverlayDisplay) { if (m_applet_id == AppletId::OverlayDisplay) {
initial_z = -1; initial_z = Overlay;
(void)m_display_service->GetContainer()->SetLayerIsOverlay(m_system_shared_layer_id, true); (void)m_display_service->GetContainer()->SetLayerIsOverlay(m_system_shared_layer_id, true);
} }
m_manager_display_service->SetLayerZIndex(initial_z, m_system_shared_layer_id); m_manager_display_service->SetLayerZIndex(initial_z, m_system_shared_layer_id);
@@ -300,6 +300,28 @@ Result SharedBufferManager::CreateSession(Kernel::KProcess* owner_process, u64*
} }
} }
// Claim a presentation slot range.
u32 slot_base = 0;
std::array<bool, SharedBufferMaxSessions> in_use{};
for (const auto& [existing_aruid, existing] : m_sessions) {
const u32 index = existing.presentation_slot_base / SharedBufferSlotsPerSession;
if (index < in_use.size())
in_use[index] = true;
}
u32 index = 0;
while (index < in_use.size() && in_use[index])
index++;
if (index >= in_use.size()) {
LOG_ERROR(Service_VI, "Out of shared buffer presentation slots ({} sessions)", SharedBufferMaxSessions);
R_THROW(VI::ResultOperationFailed);
}
slot_base = index * SharedBufferSlotsPerSession;
// Map into process. // Map into process.
Common::ProcessAddress map_address{}; Common::ProcessAddress map_address{};
R_TRY(MapSharedBufferIntoProcessAddressSpace(std::addressof(map_address), m_buffer_page_group, R_TRY(MapSharedBufferIntoProcessAddressSpace(std::addressof(map_address), m_buffer_page_group,
@@ -308,6 +330,7 @@ Result SharedBufferManager::CreateSession(Kernel::KProcess* owner_process, u64*
// Create new session. // Create new session.
auto [it, was_emplaced] = m_sessions.emplace(aruid, SharedBufferSession{}); auto [it, was_emplaced] = m_sessions.emplace(aruid, SharedBufferSession{});
auto& session = it->second; auto& session = it->second;
session.presentation_slot_base = slot_base;
auto& container = m_nvdrv->GetContainer(); auto& container = m_nvdrv->GetContainer();
session.session_id = container.OpenSession(owner_process); session.session_id = container.OpenSession(owner_process);
+2 -11
View File
@@ -39,16 +39,8 @@ Block::iterator Block::PrependNewInst(iterator insertion_point, Opcode opcode, s
// just pool it!!! - reason why there is an inline buffer is because many small blocks are created // just pool it!!! - reason why there is an inline buffer is because many small blocks are created
// with few instructions due to subpar optimisations on other passes... plus branch-heavy code will // with few instructions due to subpar optimisations on other passes... plus branch-heavy code will
// hugely benefit from the coherency of faster allocations... // hugely benefit from the coherency of faster allocations...
IR::Inst* inst; inlined_inst.emplace_back(opcode);
if (inlined_inst.size() < inlined_inst.max_size()) { auto* inst = &inlined_inst[inlined_inst.size() - 1];
inlined_inst.emplace_back(opcode);
inst = &inlined_inst[inlined_inst.size() - 1];
} else {
if (pooled_inst.empty() || pooled_inst.back().size() == pooled_inst.back().max_size())
pooled_inst.emplace_back();
pooled_inst.back().emplace_back(opcode);
inst = &pooled_inst.back()[pooled_inst.back().size() - 1];
}
DEBUG_ASSERT(args.size() == inst->NumArgs()); DEBUG_ASSERT(args.size() == inst->NumArgs());
std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable { std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable {
inst->SetArg(index, arg); inst->SetArg(index, arg);
@@ -61,7 +53,6 @@ void Block::Reset(LocationDescriptor location_) noexcept {
mcl::intrusive_list<IR::Inst> tmp = {}; mcl::intrusive_list<IR::Inst> tmp = {};
instructions.swap(tmp); instructions.swap(tmp);
inlined_inst.clear(); inlined_inst.clear();
pooled_inst.clear();
cond_failed.reset(); cond_failed.reset();
location = location_; location = location_;
end_location = location_; end_location = location_;
+2 -4
View File
@@ -142,11 +142,9 @@ public:
} }
/// "Hot cache" for small blocks so we don't call global allocator /// "Hot cache" for small blocks so we don't call global allocator
boost::container::static_vector<Inst, 30> inlined_inst; boost::container::static_vector<Inst, 4096> inlined_inst = {};
/// List of instructions in this block. /// List of instructions in this block.
instruction_list_type instructions; instruction_list_type instructions;
/// "Long/far" memory pool
boost::container::stable_vector<boost::container::static_vector<Inst, 32>> pooled_inst;
/// Block to execute next if `cond` did not pass. /// Block to execute next if `cond` did not pass.
std::optional<LocationDescriptor> cond_failed = {}; std::optional<LocationDescriptor> cond_failed = {};
/// Description of the starting location of this block /// Description of the starting location of this block
@@ -162,7 +160,7 @@ public:
/// Number of cycles this block takes to execute. /// Number of cycles this block takes to execute.
size_t cycle_count = 0; size_t cycle_count = 0;
}; };
static_assert(sizeof(Block) == 4096); //static_assert(sizeof(Block) == 4096);
/// Returns a string representation of the contents of block. Intended for debugging. /// Returns a string representation of the contents of block. Intended for debugging.
std::string DumpBlock(const IR::Block& block) noexcept; std::string DumpBlock(const IR::Block& block) noexcept;