mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-20 09:26:53 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a599d95d8f | |||
| fb974f8278 | |||
| 6407e1e5a3 | |||
| ac5ce3e9bb | |||
| 8bc31c8561 |
@@ -1,6 +1,3 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
@@ -38,7 +35,7 @@ void CircularBufferSinkInfo::Update(BehaviorInfo::ErrorInfo& error_info, OutStat
|
||||
auto current_params{reinterpret_cast<CircularBufferInParameter*>(parameter.data())};
|
||||
auto current_state{reinterpret_cast<CircularBufferState*>(state.data())};
|
||||
|
||||
if (in_use == bool(buffer_params->in_use) && !buffer_unmapped) {
|
||||
if (in_use == buffer_params->in_use && !buffer_unmapped) {
|
||||
error_info.error_code = ResultSuccess;
|
||||
error_info.address = CpuAddr(0);
|
||||
out_status.writeOffset = current_state->last_pos2;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
@@ -31,10 +31,10 @@ public:
|
||||
};
|
||||
|
||||
struct DeviceInParameter {
|
||||
/* 0x000 */ u8 name[0x100];
|
||||
/* 0x000 */ char name[0x100];
|
||||
/* 0x100 */ u32 input_count;
|
||||
/* 0x104 */ std::array<s8, MaxChannels> inputs;
|
||||
/* 0x10A */ u8 unk10A[0x1];
|
||||
/* 0x10A */ char unk10A[0x1];
|
||||
/* 0x10B */ bool downmix_enabled;
|
||||
/* 0x10C */ std::array<f32, 4> downmix_coeff;
|
||||
};
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
struct DeviceState {
|
||||
/* 0x00 */ UpsamplerInfo* upsampler_info;
|
||||
/* 0x08 */ std::array<Common::FixedPoint<16, 16>, 4> downmix_coeff;
|
||||
/* 0x18 */ u8 unk18[0x18];
|
||||
/* 0x18 */ char unk18[0x18];
|
||||
};
|
||||
static_assert(sizeof(DeviceState) == 0x30, "DeviceState has the wrong size!");
|
||||
|
||||
@@ -55,8 +55,8 @@ public:
|
||||
/* 0x14 */ u32 previous_pos;
|
||||
/* 0x18 */ SampleFormat format;
|
||||
/* 0x1C */ std::array<s8, MaxChannels> inputs;
|
||||
/* 0x22 */ u8 in_use;
|
||||
/* 0x23 */ u8 unk23[0x5];
|
||||
/* 0x22 */ bool in_use;
|
||||
/* 0x23 */ char unk23[0x5];
|
||||
};
|
||||
static_assert(sizeof(CircularBufferInParameter) == 0x28,
|
||||
"CircularBufferInParameter has the wrong size!");
|
||||
@@ -65,16 +65,16 @@ public:
|
||||
/* 0x00 */ u32 last_pos2;
|
||||
/* 0x04 */ s32 current_pos;
|
||||
/* 0x08 */ u32 last_pos;
|
||||
/* 0x0C */ u8 unk0C[0x4];
|
||||
/* 0x0C */ char unk0C[0x4];
|
||||
/* 0x10 */ AddressInfo address_info;
|
||||
};
|
||||
static_assert(sizeof(CircularBufferState) == 0x30, "CircularBufferState has the wrong size!");
|
||||
|
||||
struct InParameter {
|
||||
/* 0x000 */ Type type;
|
||||
/* 0x001 */ u8 in_use;
|
||||
/* 0x001 */ bool in_use;
|
||||
/* 0x004 */ u32 node_id;
|
||||
/* 0x008 */ u8 unk08[0x18];
|
||||
/* 0x008 */ char unk08[0x18];
|
||||
union {
|
||||
/* 0x020 */ DeviceInParameter device;
|
||||
/* 0x020 */ CircularBufferInParameter circular_buffer;
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
struct OutStatus {
|
||||
/* 0x00 */ u32 writeOffset;
|
||||
/* 0x04 */ u8 unk04[0x1C];
|
||||
/* 0x04 */ char unk04[0x1C];
|
||||
}; // size == 0x20
|
||||
static_assert(sizeof(OutStatus) == 0x20, "SinkInfoBase::OutStatus has the wrong size!");
|
||||
|
||||
@@ -162,18 +162,19 @@ public:
|
||||
u8* GetParameter();
|
||||
|
||||
protected:
|
||||
/// Type of this sink
|
||||
Type type{Type::Invalid};
|
||||
/// Is this sink in use?
|
||||
bool in_use{};
|
||||
/// Is this sink's buffer unmapped? Circular only
|
||||
bool buffer_unmapped{};
|
||||
/// Node id for this sink
|
||||
u32 node_id{};
|
||||
/// State buffer for this sink
|
||||
std::array<u8, (std::max)(sizeof(DeviceState), sizeof(CircularBufferState))> state{};
|
||||
/// Parameter buffer for this sink
|
||||
std::array<u8, (std::max)(sizeof(DeviceInParameter), sizeof(CircularBufferInParameter))> parameter{};
|
||||
/// Type of this sink
|
||||
Type type{Type::Invalid};
|
||||
/// Node id for this sink
|
||||
u32 node_id{};
|
||||
/// Is this sink in use?
|
||||
bool in_use : 1 = false;
|
||||
/// Is this sink's buffer unmapped? Circular only
|
||||
bool buffer_unmapped : 1 = false;
|
||||
std::array<u8, (std::max)(sizeof(DeviceInParameter), sizeof(CircularBufferInParameter))>
|
||||
parameter{};
|
||||
};
|
||||
|
||||
} // namespace AudioCore::Renderer
|
||||
|
||||
@@ -170,19 +170,13 @@ template<>
|
||||
|
||||
// check for marked bit, use as unmapped if marked
|
||||
if (ctx.conf.page_table_marked_bit) {
|
||||
auto const marked_bit = *ctx.conf.page_table_marked_bit;
|
||||
if (s64(s32(1 << marked_bit)) == s64(1 << marked_bit)) {
|
||||
code.test(page, s32(1 << marked_bit));
|
||||
code.jnz(abort, code.T_NEAR);
|
||||
} else {
|
||||
code.bt(page, marked_bit);
|
||||
code.jc(abort, code.T_NEAR);
|
||||
}
|
||||
code.bt(page, *ctx.conf.page_table_marked_bit);
|
||||
code.jc(abort, code.T_NEAR);
|
||||
}
|
||||
// mask away attributes
|
||||
if (ctx.conf.page_table_pointer_mask == 0) {
|
||||
code.test(page, page);
|
||||
} else if (s64(s32(ctx.conf.page_table_pointer_mask)) == s64(ctx.conf.page_table_pointer_mask)) {
|
||||
} else if (std::in_range<s32>(ctx.conf.page_table_pointer_mask)) {
|
||||
code.and_(page, ctx.conf.page_table_pointer_mask);
|
||||
} else {
|
||||
code.mov(tmp, ctx.conf.page_table_pointer_mask);
|
||||
|
||||
@@ -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
|
||||
// with few instructions due to subpar optimisations on other passes... plus branch-heavy code will
|
||||
// hugely benefit from the coherency of faster allocations...
|
||||
IR::Inst* inst;
|
||||
if (inlined_inst.size() < inlined_inst.max_size()) {
|
||||
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];
|
||||
}
|
||||
inlined_inst.emplace_back(opcode);
|
||||
auto* inst = &inlined_inst[inlined_inst.size() - 1];
|
||||
DEBUG_ASSERT(args.size() == inst->NumArgs());
|
||||
std::for_each(args.begin(), args.end(), [&inst, index = size_t(0)](const auto& arg) mutable {
|
||||
inst->SetArg(index, arg);
|
||||
@@ -61,7 +53,6 @@ void Block::Reset(LocationDescriptor location_) noexcept {
|
||||
mcl::intrusive_list<IR::Inst> tmp = {};
|
||||
instructions.swap(tmp);
|
||||
inlined_inst.clear();
|
||||
pooled_inst.clear();
|
||||
cond_failed.reset();
|
||||
location = location_;
|
||||
end_location = location_;
|
||||
|
||||
@@ -142,11 +142,9 @@ public:
|
||||
}
|
||||
|
||||
/// "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, 65536> inlined_inst = {};
|
||||
/// List of instructions in this block.
|
||||
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.
|
||||
std::optional<LocationDescriptor> cond_failed = {};
|
||||
/// Description of the starting location of this block
|
||||
@@ -162,7 +160,7 @@ public:
|
||||
/// Number of cycles this block takes to execute.
|
||||
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.
|
||||
std::string DumpBlock(const IR::Block& block) noexcept;
|
||||
|
||||
@@ -79,10 +79,8 @@ void NpadAbstractButtonHandler::UpdateAllButtonLifo() {
|
||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
||||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
||||
if (auto const shfmt = data->shared_memory_format; shfmt) {
|
||||
auto& npad_entry = shfmt->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, data->aruid);
|
||||
}
|
||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, data->aruid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,19 +88,19 @@ void NpadAbstractButtonHandler::UpdateCoreBatteryState() {
|
||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||
for (std::size_t i = 0; i < AruidIndexMax; i++) {
|
||||
auto* data = applet_resource_holder->applet_resource->GetAruidDataByIndex(i);
|
||||
if (auto const shfmt = data->shared_memory_format; shfmt) {
|
||||
auto& npad_entry = shfmt->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, data->aruid);
|
||||
}
|
||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, data->aruid);
|
||||
}
|
||||
}
|
||||
|
||||
void NpadAbstractButtonHandler::UpdateButtonState(u64 aruid) {
|
||||
Core::HID::NpadIdType npad_id = properties_handler->GetNpadId();
|
||||
if (auto data = applet_resource_holder->applet_resource->GetAruidData(aruid); data) {
|
||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, aruid);
|
||||
auto* data = applet_resource_holder->applet_resource->GetAruidData(aruid);
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto& npad_entry = data->shared_memory_format->npad.npad_entry[NpadIdTypeToIndex(npad_id)];
|
||||
UpdateButtonLifo(npad_entry, aruid);
|
||||
}
|
||||
|
||||
Result NpadAbstractButtonHandler::SetHomeProtection(bool is_enabled, u64 aruid) {
|
||||
|
||||
@@ -496,30 +496,31 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
|
||||
}
|
||||
|
||||
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||
// Flatten all leading PHIs from each block into a vector
|
||||
std::vector<IR::Inst*> phi_instructions;
|
||||
for (IR::Block* block : program.blocks) {
|
||||
for (auto it = block->begin(); it != block->end(); ++it) {
|
||||
if (it->GetOpcode() != IR::Opcode::Phi)
|
||||
break;
|
||||
phi_instructions.push_back(&*it);
|
||||
}
|
||||
}
|
||||
// Flatten all leading PHIs from each block into a vector
|
||||
std::vector<IR::Inst*> phi_instructions;
|
||||
for (IR::Block* block : program.blocks) {
|
||||
for (auto it = block->begin(); it != block->end(); ++it) {
|
||||
if (it->GetOpcode() != IR::Opcode::Phi)
|
||||
break;
|
||||
phi_instructions.push_back(&*it);
|
||||
}
|
||||
}
|
||||
|
||||
if (phi_instructions.empty()) {
|
||||
return; // nothing to patch
|
||||
}
|
||||
if (phi_instructions.empty()) {
|
||||
return; // nothing to patch
|
||||
}
|
||||
|
||||
// Start "before" first PHI; advance on phi_arg == 0
|
||||
size_t phi_index = size_t(-1);
|
||||
ctx.PatchDeferredPhi([&ctx, &phi_index, phi_insts = std::move(phi_instructions)](size_t phi_arg, Id parent) -> std::pair<Id, Id> {
|
||||
if (phi_arg == 0) {
|
||||
++phi_index;
|
||||
// Start "before" first PHI; advance on phi_arg == 0
|
||||
size_t phi_index = static_cast<size_t>(-1);
|
||||
|
||||
ctx.PatchDeferredPhi([&](size_t phi_arg, Id parent) -> std::pair<Id, Id> {
|
||||
if (phi_arg == 0) {
|
||||
++phi_index;
|
||||
}
|
||||
IR::Inst* phi = phi_instructions[phi_index];
|
||||
return { ctx.Def(phi->Arg(phi_arg)), parent };
|
||||
});
|
||||
}
|
||||
IR::Inst* phi = phi_insts[phi_index];
|
||||
return { ctx.Def(phi->Arg(phi_arg)), parent };
|
||||
});
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_info, IR::Program& program, Bindings& bindings) {
|
||||
|
||||
Reference in New Issue
Block a user