mirror of
https://github.com/SysRay/psOff_public.git
synced 2024-11-27 00:20:54 +00:00
dump
This commit is contained in:
parent
fbf46eb9aa
commit
935df442ad
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.24)
|
|||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
set(PSOFF_LIB_VERSION v.0.0)
|
set(PSOFF_LIB_VERSION v.0.0)
|
||||||
|
set(PSOFF_RENDER_VERSION v.0.5-nightly_17.04.24)
|
||||||
|
|
||||||
set(ProjectName psOff_${CMAKE_BUILD_TYPE})
|
set(ProjectName psOff_${CMAKE_BUILD_TYPE})
|
||||||
project(${ProjectName} VERSION 0.0.1)
|
project(${ProjectName} VERSION 0.0.1)
|
||||||
@ -66,6 +67,19 @@ ExternalProject_Add(third_party
|
|||||||
URL https://github.com/SysRay/psOff_thirdParty/releases/download/${PSOFF_LIB_VERSION}/psOff-3rd.zip
|
URL https://github.com/SysRay/psOff_thirdParty/releases/download/${PSOFF_LIB_VERSION}/psOff-3rd.zip
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
ExternalProject_Add(renderer
|
||||||
|
CONFIGURE_COMMAND ""
|
||||||
|
BUILD_COMMAND ""
|
||||||
|
INSTALL_COMMAND ""
|
||||||
|
PREFIX ${CMAKE_BINARY_DIR}/renderer
|
||||||
|
BUILD_IN_SOURCE 1
|
||||||
|
URL https://github.com/SysRay/psOff_Renderer/releases/download/${PSOFF_RENDER_VERSION}/psOff-renderer.zip
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/renderer/src/renderer/emulator.exe DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||||
|
endif()
|
||||||
|
|
||||||
set(TEST_BENCH OFF CACHE BOOL "Enable testing")
|
set(TEST_BENCH OFF CACHE BOOL "Enable testing")
|
||||||
|
|
||||||
if(TEST_BENCH)
|
if(TEST_BENCH)
|
||||||
|
@ -39,6 +39,8 @@ target_link_libraries(core PRIVATE
|
|||||||
OptickCore
|
OptickCore
|
||||||
psOff_utility
|
psOff_utility
|
||||||
config_emu.lib
|
config_emu.lib
|
||||||
|
onecore.lib
|
||||||
|
VulkanMemoryAllocator
|
||||||
${Vulkan_LIBRARIES}
|
${Vulkan_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -48,4 +50,4 @@ ADD_CUSTOM_COMMAND(TARGET core POST_BUILD
|
|||||||
${CMAKE_BINARY_DIR}/lib)
|
${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
install(FILES $<TARGET_PDB_FILE:core> DESTINATION debug OPTIONAL)
|
install(FILES $<TARGET_PDB_FILE:core> DESTINATION debug OPTIONAL)
|
||||||
install(TARGETS core LIBRARY DESTINATION .)
|
install(TARGETS core LIBRARY DESTINATION .)
|
@ -1,5 +1,10 @@
|
|||||||
add_library(dmem OBJECT
|
add_library(dmem OBJECT
|
||||||
dmem.cpp
|
dmem.cpp
|
||||||
|
directmem.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_dependencies(dmem third_party psOff_utility)
|
add_dependencies(dmem third_party psOff_utility)
|
||||||
|
|
||||||
|
target_include_directories(dmem PRIVATE
|
||||||
|
${Vulkan_INCLUDE_DIRS}
|
||||||
|
)
|
419
core/dmem/directmem.cpp
Normal file
419
core/dmem/directmem.cpp
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
#define __APICALL_EXTERN
|
||||||
|
#include "dmem.h"
|
||||||
|
#undef __APICALL_EXTERN
|
||||||
|
|
||||||
|
#include "core/imports/exports/procParam.h"
|
||||||
|
#include "core/imports/imports_runtime.h"
|
||||||
|
#include "core/kernel/filesystem.h"
|
||||||
|
#include "core/videoout/videoout.h"
|
||||||
|
#include "logging.h"
|
||||||
|
#include "modules/libkernel/codes.h"
|
||||||
|
#include "modules/libkernel/dmem.h"
|
||||||
|
#include "utility/utility.h"
|
||||||
|
|
||||||
|
#include <boost/thread.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <vk_mem_alloc.h>
|
||||||
|
#include <vulkan/vk_enum_string_helper.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#undef min
|
||||||
|
LOG_DEFINE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr uint64_t DIRECTMEM_START = 0x100000000u;
|
||||||
|
|
||||||
|
enum class MemoryState {
|
||||||
|
Free,
|
||||||
|
Reserved,
|
||||||
|
Commited,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemoryMapping {
|
||||||
|
uint64_t addr = 0;
|
||||||
|
|
||||||
|
uint64_t heapAddr = 0; // addr for MemoryInfo
|
||||||
|
|
||||||
|
uint64_t size = 0;
|
||||||
|
uint64_t alignment = 0;
|
||||||
|
|
||||||
|
VmaVirtualAllocation vmaAlloc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MemoryInfo {
|
||||||
|
uint64_t addr = 0;
|
||||||
|
void* allocAddr = nullptr;
|
||||||
|
|
||||||
|
uint64_t size = 0;
|
||||||
|
uint64_t alignment = 0;
|
||||||
|
|
||||||
|
int memoryType = 0;
|
||||||
|
int prot = 0;
|
||||||
|
|
||||||
|
VmaVirtualAllocation vmaAlloc;
|
||||||
|
VmaVirtualBlock vmaBlock = nullptr;
|
||||||
|
|
||||||
|
MemoryState state = MemoryState::Free;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool checkIsGPU(int protection) {
|
||||||
|
return (protection & 0xf0) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD convProtection(int prot) {
|
||||||
|
switch (prot & 0xf) {
|
||||||
|
case 0: return PAGE_NOACCESS;
|
||||||
|
case 1: return PAGE_READONLY;
|
||||||
|
case 2:
|
||||||
|
case 3: return PAGE_READWRITE;
|
||||||
|
case 4: return PAGE_EXECUTE;
|
||||||
|
case 5: return PAGE_EXECUTE_READ;
|
||||||
|
case 6:
|
||||||
|
case 7: return PAGE_EXECUTE_READWRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkIsGPU(prot)) {
|
||||||
|
return PAGE_READWRITE; // special case: cpu read/writes gpumemory on host memory
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_NOACCESS;
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
class DirectMemory: public IDirectMemory {
|
||||||
|
boost::mutex m_mutexInt;
|
||||||
|
|
||||||
|
std::map<uint64_t, MemoryInfo> m_objects;
|
||||||
|
std::map<uint64_t, MemoryMapping> m_mappings;
|
||||||
|
|
||||||
|
uint64_t m_allocSize = 0;
|
||||||
|
uint64_t m_usedSize = 0;
|
||||||
|
|
||||||
|
uint64_t m_sdkVersion = 0;
|
||||||
|
|
||||||
|
VmaVirtualBlock m_virtualDeviceMemory;
|
||||||
|
|
||||||
|
uint64_t getSDKVersion() {
|
||||||
|
if (m_sdkVersion == 0) {
|
||||||
|
auto* procParam = (ProcParam*)accessRuntimeExport()->mainModuleInfo().procParamAddr;
|
||||||
|
m_sdkVersion = procParam->header.sdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m_sdkVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retNoMem() {
|
||||||
|
if (m_sdkVersion < 0x3500000) return getErr(ErrCode::_EINVAL);
|
||||||
|
return getErr(ErrCode::_ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryInfo* getMemoryInfo(uint64_t len, uint64_t alignment, int prot, VmaVirtualAllocation& outAlloc, uint64_t& outAddr);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DirectMemory() {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
VmaVirtualBlockCreateInfo blockCreateInfo = {
|
||||||
|
.size = SCE_KERNEL_MAIN_DMEM_SIZE,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto result = vmaCreateVirtualBlock(&blockCreateInfo, &m_virtualDeviceMemory); result != VK_SUCCESS) {
|
||||||
|
LOG_CRIT(L"vmaCreateVirtualBlock err:%S", string_VkResult(result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~DirectMemory() { deinit(); }
|
||||||
|
|
||||||
|
// ### Interface
|
||||||
|
int alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) final;
|
||||||
|
int free(off_t start, size_t len) final;
|
||||||
|
|
||||||
|
int map(uint64_t vaddr, off_t directMemoryOffset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) final;
|
||||||
|
int unmap(uint64_t vaddr, uint64_t size) final;
|
||||||
|
|
||||||
|
virtual int reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) final;
|
||||||
|
|
||||||
|
uint64_t size() const final;
|
||||||
|
|
||||||
|
int getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) final;
|
||||||
|
|
||||||
|
void deinit() final;
|
||||||
|
};
|
||||||
|
|
||||||
|
IDirectMemory& accessDirectMemory() {
|
||||||
|
static DirectMemory obj;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryInfo* DirectMemory::getMemoryInfo(uint64_t len, uint64_t alignment, int prot, VmaVirtualAllocation& outAlloc, uint64_t& outAddr) {
|
||||||
|
if (m_objects.empty()) return nullptr;
|
||||||
|
|
||||||
|
VmaVirtualAllocationCreateInfo allocCreateInfo = {
|
||||||
|
.size = len,
|
||||||
|
.alignment = alignment,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (auto& item: m_objects) {
|
||||||
|
if (item.second.state == MemoryState::Reserved) continue;
|
||||||
|
|
||||||
|
if (item.second.state == MemoryState::Commited && prot != item.second.prot) continue;
|
||||||
|
|
||||||
|
if (auto result = vmaVirtualAllocate(item.second.vmaBlock, &allocCreateInfo, &outAlloc, &outAddr); result == VK_SUCCESS) {
|
||||||
|
return &item.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
if ((alignment > 0 && !util::isPowerOfTwo(alignment)) || (len % SCE_KERNEL_PAGE_SIZE != 0) || (alignment % SCE_KERNEL_PAGE_SIZE != 0))
|
||||||
|
return getErr(ErrCode::_EINVAL);
|
||||||
|
|
||||||
|
boost::unique_lock lock(m_mutexInt);
|
||||||
|
|
||||||
|
VmaVirtualAllocationCreateInfo allocCreateInfo = {
|
||||||
|
.size = len,
|
||||||
|
.alignment = alignment,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get block from device memory
|
||||||
|
VmaVirtualAllocation alloc;
|
||||||
|
|
||||||
|
if (auto result = vmaVirtualAllocate(m_virtualDeviceMemory, &allocCreateInfo, &alloc, outAddr); result != VK_SUCCESS) {
|
||||||
|
LOG_ERR(L"Alloc Error| len:0x%08llx alignment:0x%08llx memorytype:%d err:%d", len, alignment, memoryType, GetLastError());
|
||||||
|
return getErr(ErrCode::_ENOMEM);
|
||||||
|
}
|
||||||
|
// - check devicememory
|
||||||
|
|
||||||
|
*outAddr += DIRECTMEM_START; // For debugging info
|
||||||
|
|
||||||
|
// Device has space -> Create allocation
|
||||||
|
VmaVirtualBlockCreateInfo blockCreateInfo = {
|
||||||
|
.size = len,
|
||||||
|
};
|
||||||
|
VmaVirtualBlock block;
|
||||||
|
|
||||||
|
if (auto result = vmaCreateVirtualBlock(&blockCreateInfo, &block); result != VK_SUCCESS) {
|
||||||
|
LOG_ERR(L"Alloc Error| len:0x%08llx alignment:0x%08llx memorytype:%d err:%d", len, alignment, memoryType, GetLastError());
|
||||||
|
return getErr(ErrCode::_ENOMEM);
|
||||||
|
}
|
||||||
|
// -
|
||||||
|
|
||||||
|
m_allocSize += len;
|
||||||
|
m_objects.emplace(std::make_pair(
|
||||||
|
*outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = memoryType, .vmaAlloc = alloc, .vmaBlock = block}));
|
||||||
|
|
||||||
|
LOG_DEBUG(L"-> Allocated: len:0x%08llx alignment:0x%08llx memorytype:%d -> 0x%08llx", len, alignment, memoryType, *outAddr);
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::free(off_t start, size_t len) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
boost::unique_lock lock(m_mutexInt);
|
||||||
|
|
||||||
|
uint64_t addr = DIRECTMEM_START + start;
|
||||||
|
|
||||||
|
m_allocSize -= len;
|
||||||
|
|
||||||
|
// Find the object
|
||||||
|
if (m_objects.empty()) return Ok;
|
||||||
|
|
||||||
|
auto itHeap = m_objects.lower_bound(addr);
|
||||||
|
if (itHeap == m_objects.end() || (itHeap != m_objects.begin() && itHeap->first != addr)) --itHeap; // Get the correct item
|
||||||
|
|
||||||
|
if (!(itHeap->first <= addr && (itHeap->first + itHeap->second.size >= addr))) return Ok; // Can't be found
|
||||||
|
//-
|
||||||
|
|
||||||
|
LOG_DEBUG(L"free| addr:0x%08llx len:0x%08llx heap -> addr:0x%08llx len:0x%08llx", addr, len, itHeap->first, itHeap->second.size);
|
||||||
|
|
||||||
|
// special: Check reserve if full reservation or commits
|
||||||
|
if (itHeap->second.state == MemoryState::Reserved) {
|
||||||
|
// todo
|
||||||
|
VirtualFree((void*)itHeap->second.addr, itHeap->second.size, 0);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itHeap->first != addr || itHeap->second.size != len) {
|
||||||
|
LOG_ERR(L"free Error| start:0x%08llx len:0x%08llx != start:0x%08llx len:0x%08llx", addr, len, itHeap->first, itHeap->second.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkIsGPU(itHeap->second.prot)) {
|
||||||
|
// todo
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (itHeap->second.allocAddr != 0) VirtualFree(itHeap->second.allocAddr, itHeap->second.size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::list<uint64_t> dump;
|
||||||
|
for (auto& item: m_mappings) {
|
||||||
|
if (item.second.heapAddr == itHeap->first) {
|
||||||
|
m_usedSize -= item.second.size;
|
||||||
|
LOG_TRACE(L"Missing unmap for addr:0x%08llx len:0x%08llx, force unmap", item.second.addr, item.second.size);
|
||||||
|
|
||||||
|
vmaVirtualFree(itHeap->second.vmaBlock, item.second.vmaAlloc);
|
||||||
|
unregisterMapping(item.first);
|
||||||
|
dump.push_back(item.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto item: dump) {
|
||||||
|
m_mappings.erase(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vmaDestroyVirtualBlock(itHeap->second.vmaBlock);
|
||||||
|
vmaVirtualFree(m_virtualDeviceMemory, itHeap->second.vmaAlloc);
|
||||||
|
|
||||||
|
m_objects.erase(itHeap);
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::map(uint64_t vaddr, off_t offset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
boost::unique_lock lock(m_mutexInt);
|
||||||
|
if (flags & (int)filesystem::SceMapMode::VOID_) {
|
||||||
|
LOG_CRIT(L"todo void map");
|
||||||
|
}
|
||||||
|
if (flags & (int)filesystem::SceMapMode::FIXED) {
|
||||||
|
LOG_CRIT(L"todo fixed map");
|
||||||
|
}
|
||||||
|
|
||||||
|
VmaVirtualAllocation alloc = nullptr;
|
||||||
|
|
||||||
|
// search for free space
|
||||||
|
uint64_t fakeAddrOffset = 0;
|
||||||
|
MemoryInfo* info = getMemoryInfo(len, alignment, prot, alloc, fakeAddrOffset);
|
||||||
|
if (info == nullptr) return retNoMem();
|
||||||
|
// -
|
||||||
|
|
||||||
|
// Check if Commit needed
|
||||||
|
if (info->state == MemoryState::Free) {
|
||||||
|
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
|
||||||
|
MEM_EXTENDED_PARAMETER extendedParams = {0};
|
||||||
|
|
||||||
|
addressReqs.Alignment = 0; // 64 KB alignment
|
||||||
|
addressReqs.LowestStartingAddress = (PVOID)DIRECTMEM_START;
|
||||||
|
addressReqs.HighestEndingAddress = (PVOID)0;
|
||||||
|
|
||||||
|
extendedParams.Type = MemExtendedParameterAddressRequirements;
|
||||||
|
extendedParams.Pointer = &addressReqs;
|
||||||
|
|
||||||
|
void* ptr = VirtualAlloc2(NULL, 0, info->size, MEM_RESERVE | MEM_COMMIT | MEM_WRITE_WATCH, convProtection(prot), &extendedParams, 1);
|
||||||
|
if (ptr == 0) {
|
||||||
|
auto const err = GetLastError();
|
||||||
|
LOG_ERR(L"Commit Error| addr:0x%08llx len:0x%08llx err:%d", info->addr, info->size, GetLastError());
|
||||||
|
return getErr(ErrCode::_EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
info->allocAddr = ptr;
|
||||||
|
info->state = MemoryState::Commited;
|
||||||
|
LOG_DEBUG(L"Commit| addr:0x%08llx len:0x%08llx prot:%d ->", info->addr, info->size, prot, ptr);
|
||||||
|
}
|
||||||
|
// - commit
|
||||||
|
|
||||||
|
*outAddr = (uint64_t)info->allocAddr + fakeAddrOffset;
|
||||||
|
m_mappings.emplace(
|
||||||
|
std::make_pair(*outAddr, MemoryMapping {.addr = *outAddr, .heapAddr = info->addr, .size = len, .alignment = alignment, .vmaAlloc = alloc}));
|
||||||
|
registerMapping(*outAddr, MappingType::Direct);
|
||||||
|
m_usedSize += len;
|
||||||
|
|
||||||
|
LOG_DEBUG(L"-> Map: start:0x%08llx(0x%lx) len:0x%08llx alignment:0x%08llx prot:%d -> 0x%08llx", vaddr, offset, len, alignment, prot, *outAddr);
|
||||||
|
|
||||||
|
if (checkIsGPU(prot)) {
|
||||||
|
if (!accessVideoOut().notify_allocHeap(*outAddr, len, prot)) {
|
||||||
|
return getErr(ErrCode::_EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
boost::unique_lock lock(m_mutexInt);
|
||||||
|
|
||||||
|
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
|
||||||
|
MEM_EXTENDED_PARAMETER extendedParams = {0};
|
||||||
|
|
||||||
|
addressReqs.Alignment = alignment;
|
||||||
|
addressReqs.LowestStartingAddress = (PVOID)0x100000000;
|
||||||
|
addressReqs.HighestEndingAddress = (PVOID)0;
|
||||||
|
|
||||||
|
extendedParams.Type = MemExtendedParameterAddressRequirements;
|
||||||
|
extendedParams.Pointer = &addressReqs;
|
||||||
|
|
||||||
|
*outAddr = (uint64_t)VirtualAlloc2(NULL, 0, len, MEM_RESERVE | MEM_WRITE_WATCH, PAGE_NOACCESS, &extendedParams, 1);
|
||||||
|
if (*outAddr == 0) {
|
||||||
|
auto const err = GetLastError();
|
||||||
|
LOG_ERR(L"Reserve Error| addr:0x%08llx len:0x%08llx align:0x%08llx flags:0x%x err:%d", start, len, alignment, flags, GetLastError());
|
||||||
|
return getErr(ErrCode::_EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(L"-> Reserve: start:0x%08llx len:0x%08llx alignment:0x%08llx flags:0x%x -> 0x%08llx", start, len, alignment, flags, *outAddr);
|
||||||
|
|
||||||
|
m_objects.emplace(
|
||||||
|
std::make_pair(*outAddr, MemoryInfo {.addr = *outAddr, .size = len, .alignment = alignment, .memoryType = 0, .state = MemoryState::Reserved}));
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::unmap(uint64_t vaddr, uint64_t size) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
|
||||||
|
boost::unique_lock lock(m_mutexInt);
|
||||||
|
|
||||||
|
// Find the object
|
||||||
|
if (m_mappings.empty()) return Ok;
|
||||||
|
|
||||||
|
auto itItem = m_mappings.lower_bound(vaddr);
|
||||||
|
if (itItem == m_mappings.end() || (itItem != m_mappings.begin() && itItem->first != vaddr)) --itItem; // Get the correct item
|
||||||
|
|
||||||
|
if (!(itItem->first <= vaddr && (itItem->first + itItem->second.size >= vaddr))) {
|
||||||
|
LOG_ERR(L"Couldn't find mapping for 0x%08llx 0x%08llx", vaddr, size);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//-
|
||||||
|
|
||||||
|
if (auto it = m_objects.find(itItem->second.heapAddr); it != m_objects.end()) {
|
||||||
|
vmaVirtualFree(it->second.vmaBlock, itItem->second.vmaAlloc);
|
||||||
|
} else {
|
||||||
|
LOG_ERR(L"Couldn't find Heap for 0x%08llx", itItem->second.heapAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(L"unmap| 0x%08llx 0x%08llx", vaddr, size);
|
||||||
|
m_usedSize -= itItem->second.size;
|
||||||
|
|
||||||
|
m_mappings.erase(itItem);
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DirectMemory::size() const {
|
||||||
|
return m_allocSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DirectMemory::getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
||||||
|
LOG_USE_MODULE(DirectMemory);
|
||||||
|
LOG_ERR(L"availableSize: start:0x%08llx end:0x%08llx alignment:0x%08llx", start, end, alignment);
|
||||||
|
|
||||||
|
*startOut = m_usedSize;
|
||||||
|
*sizeOut = m_allocSize - m_usedSize;
|
||||||
|
|
||||||
|
return Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirectMemory::deinit() {
|
||||||
|
for (auto& item: m_objects) {
|
||||||
|
if (checkIsGPU(item.second.prot)) {
|
||||||
|
// done by gpuMemoryManager
|
||||||
|
} else {
|
||||||
|
// memory::free(item.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_objects.clear();
|
||||||
|
}
|
@ -36,159 +36,6 @@ auto getData() {
|
|||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// Allocates the sections (memory pool is done internally (in app))
|
|
||||||
class PhysicalMemory: public IPhysicalMemory {
|
|
||||||
std::mutex m_mutex_int;
|
|
||||||
|
|
||||||
std::unordered_map<uint64_t, MemoryInfo> m_objects;
|
|
||||||
|
|
||||||
public:
|
|
||||||
PhysicalMemory() = default;
|
|
||||||
|
|
||||||
virtual ~PhysicalMemory() { deinit(); }
|
|
||||||
|
|
||||||
uint64_t alloc(uint64_t vaddr, size_t len, int memoryTye) final;
|
|
||||||
bool reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) final;
|
|
||||||
uintptr_t commit(uint64_t base, uint64_t offset, size_t len, size_t alignment, int prot) final;
|
|
||||||
bool Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) final;
|
|
||||||
bool Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) final;
|
|
||||||
bool Unmap(uint64_t vaddr, uint64_t size) final;
|
|
||||||
void deinit() final;
|
|
||||||
};
|
|
||||||
|
|
||||||
IPhysicalMemory& accessPysicalMemory() {
|
|
||||||
static PhysicalMemory inst;
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t PhysicalMemory::alloc(uint64_t vaddr, size_t len, int prot) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
m_allocSize += len;
|
|
||||||
LOG_DEBUG(L"Alloc: 0x%08llx len:0x%08llx prot:%d curSize=0x%08llx", vaddr, len, prot, m_allocSize);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicalMemory::reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
|
|
||||||
auto const isGpu = memoryType == 3;
|
|
||||||
*outAddr = memory::reserve(start, len, alignment, isGpu);
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock const lock(m_mutex_int);
|
|
||||||
m_availableSize -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG(L"Reserve| start:0x%08llx size:%08llx alignment:%llu memType:%d -> @%08llx", start, len, alignment, memoryType, *outAddr);
|
|
||||||
return *outAddr != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t PhysicalMemory::commit(uint64_t base, uint64_t vaddr, size_t len, size_t alignment, int prot) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
|
|
||||||
uintptr_t addr = 0;
|
|
||||||
|
|
||||||
auto [protCPU, protGPU] = util::getMemoryProtection(prot);
|
|
||||||
|
|
||||||
if (protGPU != 0) {
|
|
||||||
addr = memory::allocGPUMemory(base, 0, len, alignment);
|
|
||||||
} else {
|
|
||||||
addr = memory::commit(base, 0, len, alignment, prot);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_objects[addr] = MemoryInfo {.isGpu = protGPU != 0, .size = len};
|
|
||||||
|
|
||||||
if (protGPU != 0) {
|
|
||||||
if (!accessVideoOut().notify_allocHeap(addr, len, prot)) {
|
|
||||||
LOG_ERR(L"Commit| Couldn't allocHeap| base:0x%08llx offset:0x%08llx size:%08llx alignment:%llu prot:%d -> @%08llx", base, vaddr, len, alignment, prot,
|
|
||||||
addr);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LOG_DEBUG(L"Commit| base:0x%08llx offset:0x%08llx size:%08llx alignment:%llu prot:%d -> @%08llx", base, vaddr, len, alignment, prot, addr);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicalMemory::Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
|
|
||||||
bool mapped = false;
|
|
||||||
*outAddr = 0;
|
|
||||||
{
|
|
||||||
std::unique_lock const lock(m_mutex_int);
|
|
||||||
|
|
||||||
auto [protCPU, protGPU] = util::getMemoryProtection(prot);
|
|
||||||
|
|
||||||
if (allocFixed) {
|
|
||||||
if (memory::allocFixed(physAddr, len, prot)) {
|
|
||||||
*outAddr = physAddr;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*outAddr = memory::allocAligned(physAddr, len, prot, alignment);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_objects[*outAddr] = MemoryInfo {.isGpu = protGPU != 0, .size = len};
|
|
||||||
|
|
||||||
if (protGPU != 0) {
|
|
||||||
if (!accessVideoOut().notify_allocHeap(*outAddr, len, prot)) {
|
|
||||||
LOG_ERR(L"Map| Couldn't allocHeap vaddr:0x%08llx physAddr:0x%08llx len:0x%08llx prot:0x%x -> out:0x%08llx", vaddr, physAddr, len, prot, *outAddr);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*outAddr == NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
m_availableSize -= len;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(L"Map| vaddr:0x%08llx physAddr:0x%08llx len:0x%08llx prot:0x%x -> out:0x%08llx", vaddr, physAddr, len, prot, *outAddr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicalMemory::Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
LOG_ERR(L"todo %S", __FUNCTION__);
|
|
||||||
m_allocSize -= len;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicalMemory::Unmap(uint64_t vaddr, uint64_t size) {
|
|
||||||
LOG_USE_MODULE(MemoryManager);
|
|
||||||
|
|
||||||
if (auto it = m_objects.find(vaddr); it != m_objects.end()) {
|
|
||||||
if (it->second.isGpu) {
|
|
||||||
// if(isGPU) accessGpuMemory().freeHeap(vaddr); // todo, notify free (should free host memory aswell)
|
|
||||||
memory::free(vaddr);
|
|
||||||
} else {
|
|
||||||
memory::free(vaddr);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LOG_ERR(L"Unmap not in map: vaddr:0x%08llx len:%lld", vaddr, size);
|
|
||||||
memory::free(vaddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
std::unique_lock const lock(m_mutex_int);
|
|
||||||
m_availableSize += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(L"Unmap: vaddr:0x%08llx len:%lld", vaddr, size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicalMemory::deinit() {
|
|
||||||
for (auto& item: m_objects) {
|
|
||||||
if (item.second.isGpu) {
|
|
||||||
// done by gpuMemoryManager
|
|
||||||
} else {
|
|
||||||
memory::free(item.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_objects.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
class FlexibleMemory: public IFlexibleMemory {
|
class FlexibleMemory: public IFlexibleMemory {
|
||||||
uint64_t m_totalAllocated = 0;
|
uint64_t m_totalAllocated = 0;
|
||||||
std::mutex m_mutex_int;
|
std::mutex m_mutex_int;
|
||||||
|
@ -4,35 +4,30 @@
|
|||||||
|
|
||||||
enum class GpuMemoryMode { NoAccess, Read, Write, ReadWrite };
|
enum class GpuMemoryMode { NoAccess, Read, Write, ReadWrite };
|
||||||
|
|
||||||
enum class MappingType { None, File, Flexible, Fixed };
|
enum class MappingType { None, File, Flexible, Fixed, Direct };
|
||||||
|
|
||||||
class IPhysicalMemory {
|
class IDirectMemory {
|
||||||
CLASS_NO_COPY(IPhysicalMemory);
|
CLASS_NO_COPY(IDirectMemory);
|
||||||
|
CLASS_NO_MOVE(IDirectMemory);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IPhysicalMemory() = default;
|
IDirectMemory() = default;
|
||||||
uint64_t m_availableSize = 5000000000llu; // todo get from system memory
|
|
||||||
size_t m_allocSize = 0;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~IPhysicalMemory() = default;
|
virtual ~IDirectMemory() = default;
|
||||||
|
|
||||||
void getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
virtual int alloc(size_t len, size_t alignment, int memoryType, uint64_t* outAddr) = 0;
|
||||||
*startOut = size() - m_availableSize;
|
virtual int free(off_t start, size_t len) = 0;
|
||||||
*sizeOut = m_availableSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual uint64_t alloc(uint64_t vaddr, size_t len, int memoryType) = 0;
|
virtual int map(uint64_t vaddr, off_t directMemoryOffset, size_t len, int prot, int flags, size_t alignment, uint64_t* outAddr) = 0;
|
||||||
|
virtual int unmap(uint64_t vaddr, uint64_t size) = 0;
|
||||||
|
|
||||||
virtual bool reserve(uint64_t start, size_t len, size_t alignment, uint64_t* outAddr, int memoryType) = 0;
|
virtual int reserve(uint64_t start, size_t len, size_t alignment, int flags, uint64_t* outAddr) = 0;
|
||||||
virtual uintptr_t commit(uint64_t base, uint64_t offset, size_t len, size_t alignment, int prot) = 0;
|
|
||||||
|
|
||||||
virtual bool Map(uint64_t vaddr, uint64_t physAddr, size_t len, int prot, bool allocFixed, size_t alignment, uint64_t* outAddr) = 0;
|
virtual uint64_t size() const = 0;
|
||||||
virtual bool Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size) = 0;
|
virtual int getAvailableSize(uint32_t start, uint32_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) = 0;
|
||||||
virtual bool Unmap(uint64_t vaddr, uint64_t size) = 0;
|
|
||||||
virtual void deinit() = 0;
|
|
||||||
|
|
||||||
uint64_t const size() const { return m_allocSize; } // use system ram
|
virtual void deinit() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IFlexibleMemory {
|
class IFlexibleMemory {
|
||||||
@ -82,6 +77,7 @@ __APICALL void registerMapping(uint64_t vaddr, MappingType type);
|
|||||||
*/
|
*/
|
||||||
__APICALL MappingType unregisterMapping(uint64_t vaddr);
|
__APICALL MappingType unregisterMapping(uint64_t vaddr);
|
||||||
|
|
||||||
__APICALL IPhysicalMemory& accessPysicalMemory();
|
__APICALL IDirectMemory& accessDirectMemory();
|
||||||
|
|
||||||
__APICALL IFlexibleMemory& accessFlexibleMemory();
|
__APICALL IFlexibleMemory& accessFlexibleMemory();
|
||||||
#undef __APICALL
|
#undef __APICALL
|
@ -157,6 +157,10 @@ int munmap(void* addr, size_t len) {
|
|||||||
return UnmapViewOfFile(addr) != 0 ? Ok : -1;
|
return UnmapViewOfFile(addr) != 0 ? Ok : -1;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case MappingType::Direct: {
|
||||||
|
return accessDirectMemory().unmap((uint64_t)addr, len);
|
||||||
|
} break;
|
||||||
|
|
||||||
case MappingType::Flexible: {
|
case MappingType::Flexible: {
|
||||||
return accessFlexibleMemory().destroy((uint64_t)addr, len) != 0 ? Ok : -1;
|
return accessFlexibleMemory().destroy((uint64_t)addr, len) != 0 ? Ok : -1;
|
||||||
} break;
|
} break;
|
||||||
@ -166,7 +170,7 @@ int munmap(void* addr, size_t len) {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MappingType::None: {
|
case MappingType::None: {
|
||||||
LOG_ERR(L"munmap unkown 0x%08llx 0x%08llx", addr, len);
|
LOG_ERR(L"munmap unkown 0x%08llx 0x%08llx type:%d", addr, len, type);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
@ -729,4 +733,4 @@ int64_t lwfsLseek(int fd, int64_t offset, int whence) {
|
|||||||
size_t lwfsWrite(int fd, const void* buf, size_t nbytes) {
|
size_t lwfsWrite(int fd, const void* buf, size_t nbytes) {
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
} // namespace filesystem
|
} // namespace filesystem
|
@ -126,12 +126,17 @@ std::optional<ImageData> ImageHandler::getImage_blocking() {
|
|||||||
|
|
||||||
VkResult result = VK_SUCCESS;
|
VkResult result = VK_SUCCESS;
|
||||||
for (; numTries >= 0; --numTries) {
|
for (; numTries >= 0; --numTries) {
|
||||||
if (result = vkAcquireNextImageKHR(m_device, m_swapchain, UINT64_MAX, imageData.semImageReady, VK_NULL_HANDLE, &imageData.index); result != VK_SUCCESS) {
|
// toggle every 1ms
|
||||||
|
if (result = vkAcquireNextImageKHR(m_device, m_swapchain, (uint64_t)1e6, imageData.semImageReady, VK_NULL_HANDLE, &imageData.index);
|
||||||
|
result != VK_SUCCESS) {
|
||||||
if (result == VK_NOT_READY) {
|
if (result == VK_NOT_READY) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::microseconds(100));
|
||||||
} else if (result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_OUT_OF_DATE_KHR) {
|
} else if (result == VK_SUBOPTIMAL_KHR || result == VK_ERROR_OUT_OF_DATE_KHR) {
|
||||||
recreate();
|
recreate();
|
||||||
++numTries;
|
++numTries;
|
||||||
|
} else if (result == VK_TIMEOUT) {
|
||||||
|
if (m_stop) return {};
|
||||||
|
++numTries;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
@ -303,4 +308,4 @@ void ImageHandler::deinit() {
|
|||||||
if (m_swapchain != nullptr) vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
|
if (m_swapchain != nullptr) vkDestroySwapchainKHR(m_device, m_swapchain, nullptr);
|
||||||
|
|
||||||
printf("deinit ImageHandler| done\n");
|
printf("deinit ImageHandler| done\n");
|
||||||
}
|
}
|
@ -278,7 +278,10 @@ class VideoOut: public IVideoOut, private IEventsGraphics {
|
|||||||
|
|
||||||
void getSafeAreaRatio(float* area) final {
|
void getSafeAreaRatio(float* area) final {
|
||||||
auto ext = m_imageHandler.get()->getExtent();
|
auto ext = m_imageHandler.get()->getExtent();
|
||||||
if (area != nullptr) *area = ext.width / (float)ext.height;
|
if (area != nullptr) {
|
||||||
|
*area = 0.781298f; // todo check what's up here
|
||||||
|
//*area = (float)ext.height / (float)ext.width;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vulkan::DeviceInfo* getDeviceInfo() final { return &m_vulkanObj->deviceInfo; }
|
vulkan::DeviceInfo* getDeviceInfo() final { return &m_vulkanObj->deviceInfo; }
|
||||||
@ -489,8 +492,8 @@ int VideoOut::SDLInit(uint32_t flags) {
|
|||||||
m_condSDL2.notify_one();
|
m_condSDL2.notify_one();
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
m_condDone.wait(lock, [=] { return result; });
|
m_condDone.wait(lock, [=] { return result >= 0; });
|
||||||
return result;
|
return result == 0 ? Ok : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoOut::transferDisplay(ImageData const& imageData, vulkan::SwapchainData::DisplayBuffers& displayBufferMeta, VkSemaphore waitSema, size_t waitValue) {
|
void VideoOut::transferDisplay(ImageData const& imageData, vulkan::SwapchainData::DisplayBuffers& displayBufferMeta, VkSemaphore waitSema, size_t waitValue) {
|
||||||
@ -670,7 +673,7 @@ int VideoOut::registerBuffers(int handle, int startIndex, void* const* addresses
|
|||||||
bufferSet.buffers[n].bufferAlign = displaySizeAlign;
|
bufferSet.buffers[n].bufferAlign = displaySizeAlign;
|
||||||
LOG_INFO(L"+bufferset[%d] buffer:%d vaddr:0x%08llx-0x%08llx", setIndex, n, (uint64_t)addresses[n], (uint64_t)addresses[n] + displaySizeAlign);
|
LOG_INFO(L"+bufferset[%d] buffer:%d vaddr:0x%08llx-0x%08llx", setIndex, n, (uint64_t)addresses[n], (uint64_t)addresses[n] + displaySizeAlign);
|
||||||
|
|
||||||
auto [format, colorSpace] = vulkan::getDisplayFormat(m_vulkanObj);
|
auto [format, _] = vulkan::getDisplayFormat(m_vulkanObj);
|
||||||
if (!m_graphics->registerDisplayBuffer(bufferSet.buffers[n].bufferVaddr, VkExtent2D {.width = _att->width, .height = _att->height}, _att->pitchInPixel,
|
if (!m_graphics->registerDisplayBuffer(bufferSet.buffers[n].bufferVaddr, VkExtent2D {.width = _att->width, .height = _att->height}, _att->pitchInPixel,
|
||||||
format))
|
format))
|
||||||
return -1;
|
return -1;
|
||||||
@ -986,4 +989,4 @@ uint64_t getImageAlignment(VkFormat format, VkExtent3D const& extent) {
|
|||||||
vkGetImageMemoryRequirements(device, image, &reqs);
|
vkGetImageMemoryRequirements(device, image, &reqs);
|
||||||
vkDestroyImage(device, image, nullptr);
|
vkDestroyImage(device, image, nullptr);
|
||||||
return reqs.alignment;
|
return reqs.alignment;
|
||||||
}
|
}
|
@ -34,17 +34,21 @@ std::pair<VkFormat, VkColorSpaceKHR> getDisplayFormat(VulkanObj* obj) {
|
|||||||
if (obj->surfaceCapabilities.formats.empty()) {
|
if (obj->surfaceCapabilities.formats.empty()) {
|
||||||
return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
return {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||||
}
|
}
|
||||||
|
bool found = false;
|
||||||
VkFormat format = obj->surfaceCapabilities.formats[0].format;
|
for (auto const& format: obj->surfaceCapabilities.formats) {
|
||||||
VkColorSpaceKHR imageColorSpace = obj->surfaceCapabilities.formats[0].colorSpace;
|
if (format.format == VK_FORMAT_R8G8B8A8_SRGB) {
|
||||||
if (obj->surfaceCapabilities.format_unorm_bgra32) {
|
found = true;
|
||||||
format = VK_FORMAT_B8G8R8A8_UNORM;
|
}
|
||||||
imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
|
||||||
} else if (obj->surfaceCapabilities.format_srgb_bgra32) {
|
|
||||||
format = VK_FORMAT_B8G8R8A8_SRGB;
|
|
||||||
imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
|
||||||
}
|
}
|
||||||
return {format, imageColorSpace};
|
|
||||||
|
if (!found) {
|
||||||
|
LOG_USE_MODULE(vulkanHelper);
|
||||||
|
for (auto const& format: obj->surfaceCapabilities.formats) {
|
||||||
|
LOG_ERR(L"format %S", string_VkFormat(format.format));
|
||||||
|
}
|
||||||
|
LOG_CRIT(L"VK_FORMAT_B8G8R8A8_SRGB not supported");
|
||||||
|
}
|
||||||
|
return {VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR};
|
||||||
}
|
}
|
||||||
|
|
||||||
void submitDisplayTransfer(SwapchainData::DisplayBuffers const* displayBuffer, ImageData const& imageData, QueueInfo const* queue, VkSemaphore waitSema,
|
void submitDisplayTransfer(SwapchainData::DisplayBuffers const* displayBuffer, ImageData const& imageData, QueueInfo const* queue, VkSemaphore waitSema,
|
||||||
@ -217,4 +221,4 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(VkDevice devi
|
|||||||
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) {
|
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties) {
|
||||||
static auto fn = (PFN_vkGetMemoryHostPointerPropertiesEXT)vkGetInstanceProcAddr(vulkan::getVkInstance(), "vkGetMemoryHostPointerPropertiesEXT");
|
static auto fn = (PFN_vkGetMemoryHostPointerPropertiesEXT)vkGetInstanceProcAddr(vulkan::getVkInstance(), "vkGetMemoryHostPointerPropertiesEXT");
|
||||||
return fn(device, handleType, pHostPointer, pMemoryHostPointerProperties);
|
return fn(device, handleType, pHostPointer, pMemoryHostPointerProperties);
|
||||||
}
|
}
|
@ -14,7 +14,8 @@ constexpr uint8_t SCE_KERNEL_PROT_GPU_WRITE = 0x20;
|
|||||||
constexpr uint8_t SCE_KERNEL_PROT_GPU_RW = 0x30;
|
constexpr uint8_t SCE_KERNEL_PROT_GPU_RW = 0x30;
|
||||||
constexpr uint8_t SCE_KERNEL_PROT_GPU_ALL = 0x30;
|
constexpr uint8_t SCE_KERNEL_PROT_GPU_ALL = 0x30;
|
||||||
|
|
||||||
constexpr uint32_t SCE_KERNEL_PAGE_SIZE = 16384;
|
constexpr uint32_t SCE_KERNEL_PAGE_SIZE = 16384;
|
||||||
|
constexpr uint64_t SCE_KERNEL_MAIN_DMEM_SIZE = 0x180000000;
|
||||||
|
|
||||||
constexpr uint32_t SCE_KERNEL_AIO_SCHED_WINDOW_MAX = 128;
|
constexpr uint32_t SCE_KERNEL_AIO_SCHED_WINDOW_MAX = 128;
|
||||||
constexpr uint32_t SCE_KERNEL_AIO_DELAYED_COUNT_MAX = 128;
|
constexpr uint32_t SCE_KERNEL_AIO_DELAYED_COUNT_MAX = 128;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "core/dmem/dmem.h"
|
#include "core/dmem/dmem.h"
|
||||||
|
#include "core/kernel/filesystem.h"
|
||||||
#include "core/memory/memory.h"
|
#include "core/memory/memory.h"
|
||||||
#include "core/videoout/videoout.h"
|
#include "core/videoout/videoout.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
@ -18,7 +19,7 @@ extern "C" {
|
|||||||
EXPORT SYSV_ABI size_t sceKernelGetDirectMemorySize() {
|
EXPORT SYSV_ABI size_t sceKernelGetDirectMemorySize() {
|
||||||
LOG_USE_MODULE(dmem);
|
LOG_USE_MODULE(dmem);
|
||||||
|
|
||||||
auto size = accessPysicalMemory().size();
|
auto size = accessDirectMemory().size();
|
||||||
LOG_DEBUG(L"%S size:0x%08llx", __FUNCTION__, size);
|
LOG_DEBUG(L"%S size:0x%08llx", __FUNCTION__, size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@ -56,56 +57,41 @@ EXPORT SYSV_ABI int32_t sceKernelGetPrtAperture(int index, void** addr, size_t*
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelAllocateDirectMemory(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, int memoryType, off_t* physAddrOut) {
|
EXPORT SYSV_ABI int32_t sceKernelAllocateDirectMemory(uint64_t searchStart, uint64_t searchEnd, size_t len, size_t alignment, int memoryType,
|
||||||
|
uint64_t* physAddrOut) {
|
||||||
if (len == 0 || physAddrOut == nullptr) {
|
if (len == 0 || physAddrOut == nullptr) {
|
||||||
return getErr(ErrCode::_EINVAL);
|
return getErr(ErrCode::_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
accessPysicalMemory().alloc(0, len, memoryType);
|
return accessDirectMemory().alloc(len, alignment, memoryType, physAddrOut);
|
||||||
*physAddrOut = 1; // done with map
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, off_t* physAddrOut) {
|
EXPORT SYSV_ABI int32_t sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, uint64_t* physAddrOut) {
|
||||||
if (len == 0 || physAddrOut == nullptr) {
|
if (len == 0 || physAddrOut == nullptr) {
|
||||||
return getErr(ErrCode::_EINVAL);
|
return getErr(ErrCode::_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
*physAddrOut = 1; // done with map
|
return accessDirectMemory().alloc(len, alignment, memoryType, physAddrOut);
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelReleaseDirectMemory(off_t start, size_t len) {
|
EXPORT SYSV_ABI int32_t sceKernelReleaseDirectMemory(off_t start, size_t len) {
|
||||||
uint64_t vaddr = 0;
|
return accessDirectMemory().free(start, len);
|
||||||
uint64_t size = 0;
|
|
||||||
|
|
||||||
bool result = accessPysicalMemory().Release(start, len, &vaddr, &size);
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelCheckedReleaseDirectMemory(off_t start, size_t len) {
|
EXPORT SYSV_ABI int32_t sceKernelCheckedReleaseDirectMemory(off_t start, size_t len) {
|
||||||
uint64_t vaddr = 0;
|
return accessDirectMemory().free(start, len);
|
||||||
uint64_t size = 0;
|
|
||||||
|
|
||||||
bool result = accessPysicalMemory().Release(start, len, &vaddr, &size);
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelMapNamedDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t alignment,
|
EXPORT SYSV_ABI int32_t sceKernelMapNamedDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t offset, size_t alignment, const char* name) {
|
||||||
const char* name) {
|
return accessDirectMemory().map(*addr, offset, len, prot, flags, alignment, addr);
|
||||||
if (!accessPysicalMemory().Map(*addr, directMemoryStart, len, prot, flags == 0x10, alignment, addr)) {
|
|
||||||
return getErr(ErrCode::_EINVAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t directMemoryStart, size_t maxPageSize) {
|
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory(uint64_t* addr, size_t len, int prot, int flags, off_t offset, size_t maxPageSize) {
|
||||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, directMemoryStart, maxPageSize, nullptr);
|
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, offset, maxPageSize, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory2(uint64_t* addr, size_t len, int type, int prot, int flags, off_t directMemoryStart, size_t maxPageSize) {
|
EXPORT SYSV_ABI int32_t sceKernelMapDirectMemory2(uint64_t* addr, size_t len, int type, int prot, int flags, off_t offset, size_t maxPageSize) {
|
||||||
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, directMemoryStart, maxPageSize, nullptr);
|
return sceKernelMapNamedDirectMemory(addr, len, prot, flags, offset, maxPageSize, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelGetDirectMemoryType(off_t start, int* memoryType, off_t* regionStartOut, off_t* regionEndOut) {
|
EXPORT SYSV_ABI int32_t sceKernelGetDirectMemoryType(off_t start, int* memoryType, off_t* regionStartOut, off_t* regionEndOut) {
|
||||||
@ -114,30 +100,38 @@ EXPORT SYSV_ABI int32_t sceKernelGetDirectMemoryType(off_t start, int* memoryTyp
|
|||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap(SceKernelBatchMapEntry* items, int size, int* count) {
|
EXPORT SYSV_ABI int32_t sceKernelBatchMap2(SceKernelBatchMapEntry* entries, int numberOfEntries, int* numberOfEntriesOut, int flags) {
|
||||||
struct BatchMapEntry {
|
LOG_USE_MODULE(dmem);
|
||||||
uint64_t start;
|
for (*numberOfEntriesOut = 0; *numberOfEntriesOut < numberOfEntries; ++*numberOfEntriesOut) {
|
||||||
uint32_t physAddr;
|
auto& batchEntry = (entries)[*numberOfEntriesOut];
|
||||||
size_t length;
|
|
||||||
uint8_t prot;
|
|
||||||
uint8_t type;
|
|
||||||
short pad1;
|
|
||||||
int operation;
|
|
||||||
};
|
|
||||||
|
|
||||||
for (*count = 0; *count < size; ++*count) {
|
switch (batchEntry.operation) {
|
||||||
auto& batchEntry = ((BatchMapEntry*)items)[*count];
|
case SceKernelMapOp::MAP_DIRECT: {
|
||||||
|
auto res = accessDirectMemory().map(batchEntry.start, batchEntry.physAddr, batchEntry.length, batchEntry.prot, flags, 0, &batchEntry.start);
|
||||||
uint64_t addr = accessPysicalMemory().commit(batchEntry.start, batchEntry.physAddr, batchEntry.length, 0, batchEntry.prot);
|
if (res != Ok) {
|
||||||
if (addr == 0) {
|
return res;
|
||||||
return getErr(ErrCode::_ENOMEM);
|
}
|
||||||
|
} break;
|
||||||
|
case SceKernelMapOp::UNMAP: {
|
||||||
|
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||||
|
} break;
|
||||||
|
case SceKernelMapOp::PROTECT: {
|
||||||
|
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||||
|
} break;
|
||||||
|
case SceKernelMapOp::MAP_FLEXIBLE: {
|
||||||
|
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||||
|
} break;
|
||||||
|
case SceKernelMapOp::TYPE_PROTECT: {
|
||||||
|
LOG_ERR(L"todo %S op:%d", __FUNCTION__, batchEntry.operation);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelBatchMap2(SceKernelBatchMapEntry* entries, int numberOfEntries, int* numberOfEntriesOut, int flags) {
|
EXPORT SYSV_ABI int32_t sceKernelBatchMap(SceKernelBatchMapEntry* items, int size, int* count) {
|
||||||
return sceKernelBatchMap(entries, numberOfEntries, numberOfEntriesOut);
|
return sceKernelBatchMap2(items, size, count, (int)filesystem::SceMapMode::NO_OVERWRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelJitCreateSharedMemory(const char* name, size_t len, int maxProt, int* fdOut) {
|
EXPORT SYSV_ABI int32_t sceKernelJitCreateSharedMemory(const char* name, size_t len, int maxProt, int* fdOut) {
|
||||||
@ -226,17 +220,11 @@ EXPORT SYSV_ABI int32_t sceKernelSetVirtualRangeName(void* start, size_t len, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int sceKernelReserveVirtualRange(uintptr_t* addr, size_t len, int flags, size_t alignment) {
|
EXPORT SYSV_ABI int sceKernelReserveVirtualRange(uintptr_t* addr, size_t len, int flags, size_t alignment) {
|
||||||
auto const inAddr = *addr;
|
if (addr == nullptr || len == 0) {
|
||||||
|
|
||||||
if (len == 0) {
|
|
||||||
return getErr(ErrCode::_EINVAL);
|
return getErr(ErrCode::_EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!accessPysicalMemory().reserve(inAddr, len, alignment, addr, 1)) {
|
return accessDirectMemory().reserve(*addr, len, alignment, flags, addr);
|
||||||
return getErr(ErrCode::_EAGAIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueryInfo {
|
struct QueryInfo {
|
||||||
@ -278,7 +266,7 @@ EXPORT SYSV_ABI int32_t sceKernelMtypeprotect(const void* addr, size_t size, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelAvailableDirectMemorySize(off_t start, off_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
EXPORT SYSV_ABI int32_t sceKernelAvailableDirectMemorySize(off_t start, off_t end, size_t alignment, uint32_t* startOut, size_t* sizeOut) {
|
||||||
accessPysicalMemory().getAvailableSize(start, end, alignment, startOut, sizeOut);
|
accessDirectMemory().getAvailableSize(start, end, alignment, startOut, sizeOut);
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +306,8 @@ EXPORT SYSV_ABI int32_t sceKernelMemoryPoolDecommit(void* addr, size_t len, int
|
|||||||
|
|
||||||
EXPORT SYSV_ABI int32_t sceKernelMemoryPoolExpand(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, off_t* physAddrOut) {
|
EXPORT SYSV_ABI int32_t sceKernelMemoryPoolExpand(off_t searchStart, off_t searchEnd, size_t len, size_t alignment, off_t* physAddrOut) {
|
||||||
LOG_USE_MODULE(dmem);
|
LOG_USE_MODULE(dmem);
|
||||||
LOG_ERR(L"todo %S| start:0x%08llx end:0x%08llx, len:0x%08llx align:0x%08llx", __FUNCTION__, searchStart, searchEnd, len, alignment);
|
*physAddrOut = memory::reserve(0, len, alignment, false);
|
||||||
|
LOG_DEBUG(L"PoolReserve| start:0x%08llx, len:0x%08llx align:0x%08llx-> out:0x%08llx", searchStart, len, alignment, *physAddrOut);
|
||||||
return Ok;
|
return Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,15 +2,22 @@
|
|||||||
#include <modules_include/common.h>
|
#include <modules_include/common.h>
|
||||||
|
|
||||||
enum class SceKernelMemoryType { WB_ONION = 0, WC_GARLIC = 3, WB_GARLIC, MEMORY_TYPE_END };
|
enum class SceKernelMemoryType { WB_ONION = 0, WC_GARLIC = 3, WB_GARLIC, MEMORY_TYPE_END };
|
||||||
|
enum class SceKernelMapOp : int {
|
||||||
|
MAP_DIRECT,
|
||||||
|
UNMAP,
|
||||||
|
PROTECT,
|
||||||
|
MAP_FLEXIBLE,
|
||||||
|
TYPE_PROTECT,
|
||||||
|
};
|
||||||
|
|
||||||
struct SceKernelBatchMapEntry {
|
struct SceKernelBatchMapEntry {
|
||||||
uint64_t start;
|
uint64_t start;
|
||||||
uint32_t physAddr;
|
uint32_t physAddr;
|
||||||
size_t length;
|
size_t length;
|
||||||
uint8_t prot;
|
uint8_t prot;
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
short pad1;
|
short pad1;
|
||||||
int operation;
|
SceKernelMapOp operation;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SceKernelVirtualQueryInfo {
|
struct SceKernelVirtualQueryInfo {
|
||||||
@ -78,4 +85,4 @@ struct SceKernelMemoryPoolBlockStats {
|
|||||||
int availableCachedBlocks;
|
int availableCachedBlocks;
|
||||||
int allocatedFlushedBlocks;
|
int allocatedFlushedBlocks;
|
||||||
int allocatedCachedBlocks;
|
int allocatedCachedBlocks;
|
||||||
};
|
};
|
@ -18,4 +18,6 @@ include_directories(
|
|||||||
${PRJ_SRC_DIR}/tools/logging
|
${PRJ_SRC_DIR}/tools/logging
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
|
|
||||||
|
install(TARGETS semaphore_test RUNTIME DESTINATION .)
|
@ -14,12 +14,4 @@ target_link_libraries(semaphore_test PRIVATE
|
|||||||
logging_stub.lib
|
logging_stub.lib
|
||||||
libboost_thread
|
libboost_thread
|
||||||
libboost_chrono
|
libboost_chrono
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(semaphore_test
|
|
||||||
PROPERTIES
|
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
|
||||||
PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/."
|
|
||||||
)
|
)
|
@ -52,8 +52,11 @@ void setThreadName(std::string_view name, void* nativeHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getPageSize(void) {
|
int getPageSize(void) {
|
||||||
SYSTEM_INFO si;
|
static int pageSize = [] {
|
||||||
GetSystemInfo(&si);
|
SYSTEM_INFO si;
|
||||||
return si.dwPageSize;
|
GetSystemInfo(&si);
|
||||||
|
return si.dwPageSize;
|
||||||
|
}();
|
||||||
|
return pageSize;
|
||||||
}
|
}
|
||||||
} // namespace util
|
} // namespace util
|
@ -88,6 +88,11 @@ constexpr std::uint64_t alignDown(uint64_t value, uint64_t alignment) {
|
|||||||
return value & ~(alignment - 1);
|
return value & ~(alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr bool isPowerOfTwo(int n) {
|
||||||
|
if (n == 0) return false;
|
||||||
|
return (n & (n - 1)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void setThreadName(std::string_view name);
|
void setThreadName(std::string_view name);
|
||||||
void setThreadName(std::string_view name, void* nativeHandle);
|
void setThreadName(std::string_view name, void* nativeHandle);
|
||||||
|
|
||||||
@ -103,4 +108,4 @@ int getPageSize(void);
|
|||||||
|
|
||||||
#define CLASS_NO_MOVE(name) \
|
#define CLASS_NO_MOVE(name) \
|
||||||
name(name&&) noexcept = delete; \
|
name(name&&) noexcept = delete; \
|
||||||
name& operator=(name&&) noexcept = delete
|
name& operator=(name&&) noexcept = delete
|
Loading…
Reference in New Issue
Block a user