mirror of
https://github.com/Ishan09811/pine.git
synced 2025-04-24 08:55:10 +00:00
Implement Android 15 16kib page size support (#40)
This commit is contained in:
parent
3ff78af28e
commit
55efa7dc96
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
IS_BUILD_SIGNED: ${{ secrets.KEYSTORE != '' }}
|
||||
UPLOAD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci') }}
|
||||
CMAKE_VERSION: "3.22.1"
|
||||
NDK_VERSION: "26.1.10909125"
|
||||
NDK_VERSION: "27.2.12479018"
|
||||
BUILD_TYPE: release
|
||||
|
||||
steps:
|
||||
|
@ -15,7 +15,7 @@ idea.module {
|
||||
|
||||
android {
|
||||
namespace 'emu.skyline'
|
||||
compileSdk 34
|
||||
compileSdk 35
|
||||
|
||||
var isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_BUILD_SIGNED") == "true")
|
||||
|
||||
@ -23,7 +23,7 @@ android {
|
||||
applicationId "io.github.pine.emu"
|
||||
|
||||
minSdk 29
|
||||
targetSdk 34
|
||||
targetSdk 35
|
||||
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
@ -76,7 +76,8 @@ android {
|
||||
debuggable true
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DCMAKE_BUILD_TYPE=RELEASE"
|
||||
arguments "-DCMAKE_BUILD_TYPE=RELEASE",
|
||||
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||
}
|
||||
}
|
||||
minifyEnabled true
|
||||
@ -90,7 +91,8 @@ android {
|
||||
debuggable true
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO"
|
||||
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO",
|
||||
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||
}
|
||||
}
|
||||
minifyEnabled false
|
||||
@ -132,7 +134,7 @@ android {
|
||||
}
|
||||
|
||||
/* NDK and CMake */
|
||||
ndkVersion '26.1.10909125'
|
||||
ndkVersion '27.2.12479018'
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
version '3.22.1+'
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit f99f0b337c97a84abdf152710a9b81e10f3d4ae8
|
||||
Subproject commit e1ccbd4d4f9757856e4998b1c6087c265c62605d
|
@ -4,6 +4,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <unistd.h>
|
||||
#include <stdexcept>
|
||||
#include <variant>
|
||||
|
||||
namespace skyline {
|
||||
@ -28,10 +30,27 @@ namespace skyline {
|
||||
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
||||
|
||||
constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the host CPU AS in bytes
|
||||
constexpr size_t PageSize{0x1000}; //!< The size of a host page
|
||||
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
|
||||
|
||||
static_assert(PageSize == PAGE_SIZE);
|
||||
constexpr u16 TlsSlotSize{0x200};
|
||||
|
||||
inline size_t getDynamicPageSize() {
|
||||
size_t pageSize = getpagesize();
|
||||
if (pageSize == 0) {
|
||||
throw std::runtime_error("Failed to retrieve page size");
|
||||
}
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
inline u8 getTlsSlots() {
|
||||
size_t slots = getDynamicPageSize() / TlsSlotSize;
|
||||
if (slots > 255) {
|
||||
throw std::runtime_error("TlsSlots exceeds u8 capacity!");
|
||||
}
|
||||
return static_cast<u8>(slots);
|
||||
}
|
||||
|
||||
const size_t PageSize{getDynamicPageSize()}; //!< The size of a host page
|
||||
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,8 +158,7 @@ namespace skyline {
|
||||
* @return All entries overlapping with the given interval and a list of intervals they recursively cover with alignment for page-based lookup semantics
|
||||
* @note This function is specifically designed for memory faulting lookups and has design-decisions that correspond to that which might not work for other uses
|
||||
*/
|
||||
template<size_t Alignment>
|
||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(Interval interval) {
|
||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(std::size_t Alignment, Interval interval) {
|
||||
std::vector<std::reference_wrapper<EntryType>> queryEntries;
|
||||
std::vector<Interval> intervals;
|
||||
|
||||
@ -242,9 +241,8 @@ namespace skyline {
|
||||
return std::pair{queryEntries, intervals};
|
||||
}
|
||||
|
||||
template<size_t Alignment>
|
||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(AddressType address) {
|
||||
return GetAlignedRecursiveRange<Alignment>(Interval{address, address + 1});
|
||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(std::size_t Alignment, AddressType address) {
|
||||
return GetAlignedRecursiveRange(Alignment, Interval{address, address + 1});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ namespace skyline {
|
||||
std::scoped_lock lock(trapMutex);
|
||||
|
||||
// Retrieve any callbacks for the page that was faulted
|
||||
auto [entries, intervals]{trapMap.GetAlignedRecursiveRange<constant::PageSize>(address)};
|
||||
auto [entries, intervals]{trapMap.GetAlignedRecursiveRange(constant::PageSize, address)};
|
||||
if (entries.empty())
|
||||
return false; // There's no callbacks associated with this page
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <gpu/interconnect/command_executor.h>
|
||||
#include "samplers.h"
|
||||
#include <unistd.h>
|
||||
#include "textures.h"
|
||||
|
||||
namespace skyline::gpu::interconnect {
|
||||
@ -23,7 +24,7 @@ namespace skyline::gpu::interconnect {
|
||||
vk::PipelineStageFlagBits dstStage,
|
||||
vk::PipelineStageFlags &srcStageMask, vk::PipelineStageFlags &dstStageMask) {
|
||||
if (!view) // Return a dummy buffer if the constant buffer isn't bound
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
|
||||
|
||||
ctx.executor.AttachBuffer(view);
|
||||
view.GetBuffer()->PopulateReadBarrier(dstStage, srcStageMask, dstStageMask);
|
||||
@ -47,12 +48,12 @@ namespace skyline::gpu::interconnect {
|
||||
};
|
||||
auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)};
|
||||
if (ssbo.size == 0)
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
|
||||
|
||||
size_t padding{ssbo.address & (ctx.gpu.traits.minimumStorageBufferAlignment - 1)};
|
||||
cachedView.Update(ctx, ssbo.address - padding, util::AlignUp(ssbo.size + padding, ctx.gpu.traits.minimumStorageBufferAlignment));
|
||||
if (!cachedView.view) // Return a dummy buffer if the SSBO isn't bound
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, PAGE_SIZE).buffer, 0, PAGE_SIZE};
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, getpagesize()).buffer, 0, static_cast<vk::DeviceSize>(getpagesize())};
|
||||
|
||||
auto view{cachedView.view};
|
||||
ctx.executor.AttachBuffer(view);
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <gpu/interconnect/conversion/quads.h>
|
||||
#include <gpu/interconnect/common/state_updater.h>
|
||||
#include <soc/gm20b/channel.h>
|
||||
#include <unistd.h>
|
||||
#include "common/utils.h"
|
||||
#include "maxwell_3d.h"
|
||||
#include "common.h"
|
||||
@ -53,7 +54,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, sizeof(u32)) + offset};
|
||||
|
||||
if (!quadConversionBuffer || quadConversionBuffer->size_bytes() < size) {
|
||||
quadConversionBuffer = std::make_shared<memory::Buffer>(ctx.gpu.memory.AllocateBuffer(util::AlignUp(size, PAGE_SIZE)));
|
||||
quadConversionBuffer = std::make_shared<memory::Buffer>(ctx.gpu.memory.AllocateBuffer(util::AlignUp(size, getpagesize())));
|
||||
conversion::quads::GenerateQuadListConversionBuffer(quadConversionBuffer->cast<u32>().data(), firstVertex + count);
|
||||
quadConversionBufferAttached = false;
|
||||
}
|
||||
|
@ -2,14 +2,15 @@
|
||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||
|
||||
#include <gpu.h>
|
||||
#include <unistd.h>
|
||||
#include "megabuffer.h"
|
||||
|
||||
namespace skyline::gpu {
|
||||
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(PAGE_SIZE)} {}
|
||||
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(getpagesize())} {}
|
||||
|
||||
bool MegaBufferChunk::TryReset() {
|
||||
if (cycle && cycle->Poll(true)) {
|
||||
freeRegion = backing.subspan(PAGE_SIZE);
|
||||
freeRegion = backing.subspan(getpagesize());
|
||||
cycle = nullptr;
|
||||
return true;
|
||||
}
|
||||
@ -24,7 +25,7 @@ namespace skyline::gpu {
|
||||
std::pair<vk::DeviceSize, span<u8>> MegaBufferChunk::Allocate(const std::shared_ptr<FenceCycle> &newCycle, vk::DeviceSize size, bool pageAlign) {
|
||||
if (pageAlign) {
|
||||
// If page aligned data was requested then align the free
|
||||
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), PAGE_SIZE)};
|
||||
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), getpagesize())};
|
||||
freeRegion = backing.subspan(alignedFreeBase);
|
||||
}
|
||||
|
||||
|
@ -78,11 +78,14 @@ namespace skyline::gpu {
|
||||
try {
|
||||
choreographerLooper = ALooper_prepare(0);
|
||||
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), this);
|
||||
while (ALooper_pollAll(-1, nullptr, nullptr, nullptr) == ALOOPER_POLL_WAKE && !choreographerStop) {
|
||||
|
||||
|
||||
while (ALooper_pollOnce(-1, nullptr, nullptr, nullptr) == ALOOPER_POLL_WAKE && !choreographerStop) {
|
||||
while (paused.load(std::memory_order_acquire)) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (const signal::SignalException &e) {
|
||||
LOGE("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
|
||||
if (state.process)
|
||||
|
@ -12,8 +12,7 @@
|
||||
|
||||
namespace skyline {
|
||||
namespace constant {
|
||||
constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot
|
||||
constexpr u8 TlsSlots{constant::PageSize / TlsSlotSize}; //!< The amount of TLS slots in a single page
|
||||
const u8 TlsSlots{constant::getTlsSlots()}; //!< The amount of TLS slots in a single page
|
||||
constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <os.h>
|
||||
#include <kernel/types/KProcess.h>
|
||||
#include <kernel/memory.h>
|
||||
#include <unistd.h>
|
||||
#include "loader.h"
|
||||
|
||||
namespace skyline::loader {
|
||||
@ -45,7 +46,7 @@ namespace skyline::loader {
|
||||
size_t hookSize{0};
|
||||
if (enableSymbolHooking && dynamicallyLinked) {
|
||||
executableSymbols = hle::GetExecutableSymbols(dynsym.cast<Elf64_Sym>(), dynstr);
|
||||
hookSize = util::AlignUp(state.nce->GetHookSectionSize(executableSymbols), PAGE_SIZE);
|
||||
hookSize = util::AlignUp(state.nce->GetHookSectionSize(executableSymbols), getpagesize());
|
||||
}
|
||||
|
||||
// Reserve patch + hook size only if we need to patch
|
||||
|
Loading…
x
Reference in New Issue
Block a user