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 != '' }}
|
IS_BUILD_SIGNED: ${{ secrets.KEYSTORE != '' }}
|
||||||
UPLOAD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci') }}
|
UPLOAD_ARTIFACTS: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'ci') }}
|
||||||
CMAKE_VERSION: "3.22.1"
|
CMAKE_VERSION: "3.22.1"
|
||||||
NDK_VERSION: "26.1.10909125"
|
NDK_VERSION: "27.2.12479018"
|
||||||
BUILD_TYPE: release
|
BUILD_TYPE: release
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
@ -15,7 +15,7 @@ idea.module {
|
|||||||
|
|
||||||
android {
|
android {
|
||||||
namespace 'emu.skyline'
|
namespace 'emu.skyline'
|
||||||
compileSdk 34
|
compileSdk 35
|
||||||
|
|
||||||
var isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_BUILD_SIGNED") == "true")
|
var isBuildSigned = (System.getenv("CI") == "true") && (System.getenv("IS_BUILD_SIGNED") == "true")
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ android {
|
|||||||
applicationId "io.github.pine.emu"
|
applicationId "io.github.pine.emu"
|
||||||
|
|
||||||
minSdk 29
|
minSdk 29
|
||||||
targetSdk 34
|
targetSdk 35
|
||||||
|
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0.0"
|
versionName "1.0.0"
|
||||||
@ -76,7 +76,8 @@ android {
|
|||||||
debuggable true
|
debuggable true
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DCMAKE_BUILD_TYPE=RELEASE"
|
arguments "-DCMAKE_BUILD_TYPE=RELEASE",
|
||||||
|
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
@ -90,7 +91,8 @@ android {
|
|||||||
debuggable true
|
debuggable true
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO"
|
arguments "-DCMAKE_BUILD_TYPE=RELWITHDEBINFO",
|
||||||
|
"-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
minifyEnabled false
|
minifyEnabled false
|
||||||
@ -132,7 +134,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* NDK and CMake */
|
/* NDK and CMake */
|
||||||
ndkVersion '26.1.10909125'
|
ndkVersion '27.2.12479018'
|
||||||
externalNativeBuild {
|
externalNativeBuild {
|
||||||
cmake {
|
cmake {
|
||||||
version '3.22.1+'
|
version '3.22.1+'
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit f99f0b337c97a84abdf152710a9b81e10f3d4ae8
|
Subproject commit e1ccbd4d4f9757856e4998b1c6087c265c62605d
|
@ -1,43 +1,62 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <variant>
|
#include <unistd.h>
|
||||||
|
#include <stdexcept>
|
||||||
namespace skyline {
|
#include <variant>
|
||||||
using u128 = __uint128_t; //!< Unsigned 128-bit integer
|
|
||||||
using u64 = __uint64_t; //!< Unsigned 64-bit integer
|
namespace skyline {
|
||||||
using u32 = __uint32_t; //!< Unsigned 32-bit integer
|
using u128 = __uint128_t; //!< Unsigned 128-bit integer
|
||||||
using u16 = __uint16_t; //!< Unsigned 16-bit integer
|
using u64 = __uint64_t; //!< Unsigned 64-bit integer
|
||||||
using u8 = __uint8_t; //!< Unsigned 8-bit integer
|
using u32 = __uint32_t; //!< Unsigned 32-bit integer
|
||||||
using i128 = __int128_t; //!< Signed 128-bit integer
|
using u16 = __uint16_t; //!< Unsigned 16-bit integer
|
||||||
using i64 = __int64_t; //!< Signed 64-bit integer
|
using u8 = __uint8_t; //!< Unsigned 8-bit integer
|
||||||
using i32 = __int32_t; //!< Signed 32-bit integer
|
using i128 = __int128_t; //!< Signed 128-bit integer
|
||||||
using i16 = __int16_t; //!< Signed 16-bit integer
|
using i64 = __int64_t; //!< Signed 64-bit integer
|
||||||
using i8 = __int8_t; //!< Signed 8-bit integer
|
using i32 = __int32_t; //!< Signed 32-bit integer
|
||||||
|
using i16 = __int16_t; //!< Signed 16-bit integer
|
||||||
using KHandle = u32; //!< The type of a kernel handle
|
using i8 = __int8_t; //!< Signed 8-bit integer
|
||||||
|
|
||||||
namespace constant {
|
using KHandle = u32; //!< The type of a kernel handle
|
||||||
// Time
|
|
||||||
constexpr i64 NsInMicrosecond{1000}; //!< The amount of nanoseconds in a microsecond
|
namespace constant {
|
||||||
constexpr i64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
|
// Time
|
||||||
constexpr i64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
|
constexpr i64 NsInMicrosecond{1000}; //!< The amount of nanoseconds in a microsecond
|
||||||
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
constexpr i64 NsInSecond{1000000000}; //!< The amount of nanoseconds in a second
|
||||||
|
constexpr i64 NsInMillisecond{1000000}; //!< The amount of nanoseconds in a millisecond
|
||||||
constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the host CPU AS in bytes
|
constexpr i64 NsInDay{86400000000000UL}; //!< The amount of nanoseconds in a day
|
||||||
constexpr size_t PageSize{0x1000}; //!< The size of a host page
|
|
||||||
constexpr size_t PageSizeBits{12}; //!< log2(PageSize)
|
constexpr size_t AddressSpaceSize{1ULL << 39}; //!< The size of the host CPU AS in bytes
|
||||||
|
|
||||||
static_assert(PageSize == PAGE_SIZE);
|
constexpr u16 TlsSlotSize{0x200};
|
||||||
}
|
|
||||||
|
inline size_t getDynamicPageSize() {
|
||||||
/**
|
size_t pageSize = getpagesize();
|
||||||
* @brief A deduction guide for overloads required for std::visit with std::variant
|
if (pageSize == 0) {
|
||||||
*/
|
throw std::runtime_error("Failed to retrieve page size");
|
||||||
template<class... Ts>
|
}
|
||||||
struct VariantVisitor : Ts ... { using Ts::operator()...; };
|
return pageSize;
|
||||||
template<class... Ts> VariantVisitor(Ts...) -> VariantVisitor<Ts...>;
|
}
|
||||||
}
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A deduction guide for overloads required for std::visit with std::variant
|
||||||
|
*/
|
||||||
|
template<class... Ts>
|
||||||
|
struct VariantVisitor : Ts ... { using Ts::operator()...; };
|
||||||
|
template<class... Ts> VariantVisitor(Ts...) -> VariantVisitor<Ts...>;
|
||||||
|
}
|
||||||
|
@ -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
|
* @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
|
* @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(std::size_t Alignment, Interval interval) {
|
||||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(Interval interval) {
|
|
||||||
std::vector<std::reference_wrapper<EntryType>> queryEntries;
|
std::vector<std::reference_wrapper<EntryType>> queryEntries;
|
||||||
std::vector<Interval> intervals;
|
std::vector<Interval> intervals;
|
||||||
|
|
||||||
@ -242,9 +241,8 @@ namespace skyline {
|
|||||||
return std::pair{queryEntries, intervals};
|
return std::pair{queryEntries, intervals};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<size_t Alignment>
|
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(std::size_t Alignment, AddressType address) {
|
||||||
std::pair<std::vector<std::reference_wrapper<EntryType>>, std::vector<Interval>> GetAlignedRecursiveRange(AddressType address) {
|
return GetAlignedRecursiveRange(Alignment, Interval{address, address + 1});
|
||||||
return GetAlignedRecursiveRange<Alignment>(Interval{address, address + 1});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ namespace skyline {
|
|||||||
std::scoped_lock lock(trapMutex);
|
std::scoped_lock lock(trapMutex);
|
||||||
|
|
||||||
// Retrieve any callbacks for the page that was faulted
|
// 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())
|
if (entries.empty())
|
||||||
return false; // There's no callbacks associated with this page
|
return false; // There's no callbacks associated with this page
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <gpu/interconnect/command_executor.h>
|
#include <gpu/interconnect/command_executor.h>
|
||||||
#include "samplers.h"
|
#include "samplers.h"
|
||||||
|
#include <unistd.h>
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect {
|
namespace skyline::gpu::interconnect {
|
||||||
@ -23,7 +24,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
vk::PipelineStageFlagBits dstStage,
|
vk::PipelineStageFlagBits dstStage,
|
||||||
vk::PipelineStageFlags &srcStageMask, vk::PipelineStageFlags &dstStageMask) {
|
vk::PipelineStageFlags &srcStageMask, vk::PipelineStageFlags &dstStageMask) {
|
||||||
if (!view) // Return a dummy buffer if the constant buffer isn't bound
|
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);
|
ctx.executor.AttachBuffer(view);
|
||||||
view.GetBuffer()->PopulateReadBarrier(dstStage, srcStageMask, dstStageMask);
|
view.GetBuffer()->PopulateReadBarrier(dstStage, srcStageMask, dstStageMask);
|
||||||
@ -47,12 +48,12 @@ namespace skyline::gpu::interconnect {
|
|||||||
};
|
};
|
||||||
auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)};
|
auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)};
|
||||||
if (ssbo.size == 0)
|
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)};
|
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));
|
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
|
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};
|
auto view{cachedView.view};
|
||||||
ctx.executor.AttachBuffer(view);
|
ctx.executor.AttachBuffer(view);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <gpu/interconnect/conversion/quads.h>
|
#include <gpu/interconnect/conversion/quads.h>
|
||||||
#include <gpu/interconnect/common/state_updater.h>
|
#include <gpu/interconnect/common/state_updater.h>
|
||||||
#include <soc/gm20b/channel.h>
|
#include <soc/gm20b/channel.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "common/utils.h"
|
#include "common/utils.h"
|
||||||
#include "maxwell_3d.h"
|
#include "maxwell_3d.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
@ -53,7 +54,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, sizeof(u32)) + offset};
|
vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, sizeof(u32)) + offset};
|
||||||
|
|
||||||
if (!quadConversionBuffer || quadConversionBuffer->size_bytes() < size) {
|
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);
|
conversion::quads::GenerateQuadListConversionBuffer(quadConversionBuffer->cast<u32>().data(), firstVertex + count);
|
||||||
quadConversionBufferAttached = false;
|
quadConversionBufferAttached = false;
|
||||||
}
|
}
|
||||||
|
@ -1,69 +1,70 @@
|
|||||||
// SPDX-License-Identifier: MPL-2.0
|
// SPDX-License-Identifier: MPL-2.0
|
||||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include "megabuffer.h"
|
#include <unistd.h>
|
||||||
|
#include "megabuffer.h"
|
||||||
namespace skyline::gpu {
|
|
||||||
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(PAGE_SIZE)} {}
|
namespace skyline::gpu {
|
||||||
|
MegaBufferChunk::MegaBufferChunk(GPU &gpu) : backing{gpu.memory.AllocateBuffer(MegaBufferChunkSize)}, freeRegion{backing.subspan(getpagesize())} {}
|
||||||
bool MegaBufferChunk::TryReset() {
|
|
||||||
if (cycle && cycle->Poll(true)) {
|
bool MegaBufferChunk::TryReset() {
|
||||||
freeRegion = backing.subspan(PAGE_SIZE);
|
if (cycle && cycle->Poll(true)) {
|
||||||
cycle = nullptr;
|
freeRegion = backing.subspan(getpagesize());
|
||||||
return true;
|
cycle = nullptr;
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
return cycle == nullptr;
|
|
||||||
}
|
return cycle == nullptr;
|
||||||
|
}
|
||||||
vk::Buffer MegaBufferChunk::GetBacking() const {
|
|
||||||
return backing.vkBuffer;
|
vk::Buffer MegaBufferChunk::GetBacking() const {
|
||||||
}
|
return backing.vkBuffer;
|
||||||
|
}
|
||||||
std::pair<vk::DeviceSize, span<u8>> MegaBufferChunk::Allocate(const std::shared_ptr<FenceCycle> &newCycle, vk::DeviceSize size, bool pageAlign) {
|
|
||||||
if (pageAlign) {
|
std::pair<vk::DeviceSize, span<u8>> MegaBufferChunk::Allocate(const std::shared_ptr<FenceCycle> &newCycle, vk::DeviceSize size, bool pageAlign) {
|
||||||
// If page aligned data was requested then align the free
|
if (pageAlign) {
|
||||||
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), PAGE_SIZE)};
|
// If page aligned data was requested then align the free
|
||||||
freeRegion = backing.subspan(alignedFreeBase);
|
auto alignedFreeBase{util::AlignUp(static_cast<size_t>(freeRegion.data() - backing.data()), getpagesize())};
|
||||||
}
|
freeRegion = backing.subspan(alignedFreeBase);
|
||||||
|
}
|
||||||
if (size > freeRegion.size())
|
|
||||||
return {0, {}};
|
if (size > freeRegion.size())
|
||||||
|
return {0, {}};
|
||||||
if (cycle != newCycle) {
|
|
||||||
newCycle->ChainCycle(cycle);
|
if (cycle != newCycle) {
|
||||||
cycle = newCycle;
|
newCycle->ChainCycle(cycle);
|
||||||
}
|
cycle = newCycle;
|
||||||
|
}
|
||||||
// Allocate space for data from the free region
|
|
||||||
auto resultSpan{freeRegion.subspan(0, size)};
|
// Allocate space for data from the free region
|
||||||
|
auto resultSpan{freeRegion.subspan(0, size)};
|
||||||
// Move the free region along
|
|
||||||
freeRegion = freeRegion.subspan(size);
|
// Move the free region along
|
||||||
|
freeRegion = freeRegion.subspan(size);
|
||||||
return {static_cast<vk::DeviceSize>(resultSpan.data() - backing.data()), resultSpan};
|
|
||||||
}
|
return {static_cast<vk::DeviceSize>(resultSpan.data() - backing.data()), resultSpan};
|
||||||
|
}
|
||||||
MegaBufferAllocator::MegaBufferAllocator(GPU &gpu) : gpu{gpu}, activeChunk{chunks.emplace(chunks.end(), gpu)} {}
|
|
||||||
|
MegaBufferAllocator::MegaBufferAllocator(GPU &gpu) : gpu{gpu}, activeChunk{chunks.emplace(chunks.end(), gpu)} {}
|
||||||
MegaBufferAllocator::Allocation MegaBufferAllocator::Allocate(const std::shared_ptr<FenceCycle> &cycle, vk::DeviceSize size, bool pageAlign) {
|
|
||||||
if (auto allocation{activeChunk->Allocate(cycle, size, pageAlign)}; allocation.first)
|
MegaBufferAllocator::Allocation MegaBufferAllocator::Allocate(const std::shared_ptr<FenceCycle> &cycle, vk::DeviceSize size, bool pageAlign) {
|
||||||
return {activeChunk->GetBacking(), allocation.first, allocation.second};
|
if (auto allocation{activeChunk->Allocate(cycle, size, pageAlign)}; allocation.first)
|
||||||
|
return {activeChunk->GetBacking(), allocation.first, allocation.second};
|
||||||
activeChunk = ranges::find_if(chunks, [&](auto &chunk) { return chunk.TryReset(); });
|
|
||||||
if (activeChunk == chunks.end()) // If there are no chunks available, allocate a new one
|
activeChunk = ranges::find_if(chunks, [&](auto &chunk) { return chunk.TryReset(); });
|
||||||
activeChunk = chunks.emplace(chunks.end(), gpu);
|
if (activeChunk == chunks.end()) // If there are no chunks available, allocate a new one
|
||||||
|
activeChunk = chunks.emplace(chunks.end(), gpu);
|
||||||
if (auto allocation{activeChunk->Allocate(cycle, size, pageAlign)}; allocation.first)
|
|
||||||
return {activeChunk->GetBacking(), allocation.first, allocation.second};
|
if (auto allocation{activeChunk->Allocate(cycle, size, pageAlign)}; allocation.first)
|
||||||
else
|
return {activeChunk->GetBacking(), allocation.first, allocation.second};
|
||||||
throw exception("Failed to to allocate megabuffer space for size: 0x{:X}", size);
|
else
|
||||||
}
|
throw exception("Failed to to allocate megabuffer space for size: 0x{:X}", size);
|
||||||
|
}
|
||||||
MegaBufferAllocator::Allocation MegaBufferAllocator::Push(const std::shared_ptr<FenceCycle> &cycle, span<u8> data, bool pageAlign) {
|
|
||||||
auto allocation{Allocate(cycle, data.size(), pageAlign)};
|
MegaBufferAllocator::Allocation MegaBufferAllocator::Push(const std::shared_ptr<FenceCycle> &cycle, span<u8> data, bool pageAlign) {
|
||||||
allocation.region.copy_from(data);
|
auto allocation{Allocate(cycle, data.size(), pageAlign)};
|
||||||
return allocation;
|
allocation.region.copy_from(data);
|
||||||
}
|
return allocation;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -78,11 +78,14 @@ namespace skyline::gpu {
|
|||||||
try {
|
try {
|
||||||
choreographerLooper = ALooper_prepare(0);
|
choreographerLooper = ALooper_prepare(0);
|
||||||
AChoreographer_postFrameCallback64(AChoreographer_getInstance(), reinterpret_cast<AChoreographer_frameCallback64>(&ChoreographerCallback), this);
|
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)) {
|
while (paused.load(std::memory_order_acquire)) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const signal::SignalException &e) {
|
} catch (const signal::SignalException &e) {
|
||||||
LOGE("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
|
LOGE("{}\nStack Trace:{}", e.what(), state.loader->GetStackTrace(e.frames));
|
||||||
if (state.process)
|
if (state.process)
|
||||||
|
@ -12,8 +12,7 @@
|
|||||||
|
|
||||||
namespace skyline {
|
namespace skyline {
|
||||||
namespace constant {
|
namespace constant {
|
||||||
constexpr u16 TlsSlotSize{0x200}; //!< The size of a single TLS slot
|
const u8 TlsSlots{constant::getTlsSlots()}; //!< The amount of TLS slots in a single page
|
||||||
constexpr u8 TlsSlots{constant::PageSize / TlsSlotSize}; //!< The amount of TLS slots in a single page
|
|
||||||
constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle
|
constexpr KHandle BaseHandleIndex{0xD000}; //!< The index of the base handle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <os.h>
|
#include <os.h>
|
||||||
#include <kernel/types/KProcess.h>
|
#include <kernel/types/KProcess.h>
|
||||||
#include <kernel/memory.h>
|
#include <kernel/memory.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "loader.h"
|
#include "loader.h"
|
||||||
|
|
||||||
namespace skyline::loader {
|
namespace skyline::loader {
|
||||||
@ -45,7 +46,7 @@ namespace skyline::loader {
|
|||||||
size_t hookSize{0};
|
size_t hookSize{0};
|
||||||
if (enableSymbolHooking && dynamicallyLinked) {
|
if (enableSymbolHooking && dynamicallyLinked) {
|
||||||
executableSymbols = hle::GetExecutableSymbols(dynsym.cast<Elf64_Sym>(), dynstr);
|
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
|
// Reserve patch + hook size only if we need to patch
|
||||||
|
Loading…
x
Reference in New Issue
Block a user