early-access version 3000
This commit is contained in:
parent
f06a13adf3
commit
0357df2594
6 changed files with 62 additions and 41 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2998.
|
This is the source code for early-access 3000.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,55 @@ Loader::ResultStatus ProgramMetadata::Load(VirtualFile file) {
|
||||||
return Loader::ResultStatus::ErrorBadACIHeader;
|
return Loader::ResultStatus::ErrorBadACIHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeof(FileAccessControl) != file->ReadObject(&acid_file_access, acid_header.fac_offset)) {
|
// Load acid_file_access per-component instead of the entire struct, since this struct does not
|
||||||
|
// reflect the layout of the real data.
|
||||||
|
std::size_t current_offset = acid_header.fac_offset;
|
||||||
|
if (sizeof(FileAccessControl::version) != file->ReadBytes(&acid_file_access.version,
|
||||||
|
sizeof(FileAccessControl::version),
|
||||||
|
current_offset)) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessControl;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessControl::permissions) !=
|
||||||
|
file->ReadBytes(&acid_file_access.permissions, sizeof(FileAccessControl::permissions),
|
||||||
|
current_offset += sizeof(FileAccessControl::version) + 3)) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessControl;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessControl::unknown) !=
|
||||||
|
file->ReadBytes(&acid_file_access.unknown, sizeof(FileAccessControl::unknown),
|
||||||
|
current_offset + sizeof(FileAccessControl::permissions))) {
|
||||||
return Loader::ResultStatus::ErrorBadFileAccessControl;
|
return Loader::ResultStatus::ErrorBadFileAccessControl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeof(FileAccessHeader) != file->ReadObject(&aci_file_access, aci_header.fah_offset)) {
|
// Load aci_file_access per-component instead of the entire struct, same as acid_file_access
|
||||||
|
current_offset = aci_header.fah_offset;
|
||||||
|
if (sizeof(FileAccessHeader::version) != file->ReadBytes(&aci_file_access.version,
|
||||||
|
sizeof(FileAccessHeader::version),
|
||||||
|
current_offset)) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessHeader::permissions) !=
|
||||||
|
file->ReadBytes(&aci_file_access.permissions, sizeof(FileAccessHeader::permissions),
|
||||||
|
current_offset += sizeof(FileAccessHeader::version) + 3)) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessHeader::unk_offset) !=
|
||||||
|
file->ReadBytes(&aci_file_access.unk_offset, sizeof(FileAccessHeader::unk_offset),
|
||||||
|
current_offset += sizeof(FileAccessHeader::permissions))) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessHeader::unk_size) !=
|
||||||
|
file->ReadBytes(&aci_file_access.unk_size, sizeof(FileAccessHeader::unk_size),
|
||||||
|
current_offset += sizeof(FileAccessHeader::unk_offset))) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessHeader::unk_offset_2) !=
|
||||||
|
file->ReadBytes(&aci_file_access.unk_offset_2, sizeof(FileAccessHeader::unk_offset_2),
|
||||||
|
current_offset += sizeof(FileAccessHeader::unk_size))) {
|
||||||
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
|
}
|
||||||
|
if (sizeof(FileAccessHeader::unk_size_2) !=
|
||||||
|
file->ReadBytes(&aci_file_access.unk_size_2, sizeof(FileAccessHeader::unk_size_2),
|
||||||
|
current_offset + sizeof(FileAccessHeader::unk_offset_2))) {
|
||||||
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
return Loader::ResultStatus::ErrorBadFileAccessHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,9 +196,7 @@ void ProgramMetadata::Print() const {
|
||||||
LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
|
LOG_DEBUG(Service_FS, " > Is Retail: {}", acid_header.is_retail ? "YES" : "NO");
|
||||||
LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
|
LOG_DEBUG(Service_FS, "Title ID Min: 0x{:016X}", acid_header.title_id_min);
|
||||||
LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
|
LOG_DEBUG(Service_FS, "Title ID Max: 0x{:016X}", acid_header.title_id_max);
|
||||||
u64_le permissions_l; // local copy to fix alignment error
|
LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", acid_file_access.permissions);
|
||||||
std::memcpy(&permissions_l, &acid_file_access.permissions, sizeof(permissions_l));
|
|
||||||
LOG_DEBUG(Service_FS, "Filesystem Access: 0x{:016X}\n", permissions_l);
|
|
||||||
|
|
||||||
// Begin ACI0 printing (actual perms, unsigned)
|
// Begin ACI0 printing (actual perms, unsigned)
|
||||||
LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
|
LOG_DEBUG(Service_FS, "Magic: {:.4}", aci_header.magic.data());
|
||||||
|
|
|
@ -144,20 +144,18 @@ private:
|
||||||
|
|
||||||
static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong");
|
static_assert(sizeof(AciHeader) == 0x40, "ACI0 header structure size is wrong");
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
// FileAccessControl and FileAccessHeader need loaded per-component: this layout does not
|
||||||
|
// reflect the real layout to avoid reference binding to misaligned addresses
|
||||||
struct FileAccessControl {
|
struct FileAccessControl {
|
||||||
u8 version;
|
u8 version;
|
||||||
INSERT_PADDING_BYTES(3);
|
// 3 padding bytes
|
||||||
u64_le permissions;
|
u64_le permissions;
|
||||||
std::array<u8, 0x20> unknown;
|
std::array<u8, 0x20> unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(FileAccessControl) == 0x2C, "FS access control structure size is wrong");
|
|
||||||
|
|
||||||
struct FileAccessHeader {
|
struct FileAccessHeader {
|
||||||
u8 version;
|
u8 version;
|
||||||
INSERT_PADDING_BYTES(3);
|
// 3 padding bytes
|
||||||
u64_le permissions;
|
u64_le permissions;
|
||||||
u32_le unk_offset;
|
u32_le unk_offset;
|
||||||
u32_le unk_size;
|
u32_le unk_size;
|
||||||
|
@ -165,10 +163,6 @@ private:
|
||||||
u32_le unk_size_2;
|
u32_le unk_size_2;
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(FileAccessHeader) == 0x1C, "FS access header structure size is wrong");
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
Header npdm_header;
|
Header npdm_header;
|
||||||
AciHeader aci_header;
|
AciHeader aci_header;
|
||||||
AcidHeader acid_header;
|
AcidHeader acid_header;
|
||||||
|
|
|
@ -145,6 +145,11 @@ VkSemaphore BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer,
|
||||||
// Finish any pending renderpass
|
// Finish any pending renderpass
|
||||||
scheduler.RequestOutsideRenderPassOperationContext();
|
scheduler.RequestOutsideRenderPassOperationContext();
|
||||||
|
|
||||||
|
if (const auto swapchain_images = swapchain.GetImageCount(); swapchain_images != image_count) {
|
||||||
|
image_count = swapchain_images;
|
||||||
|
Recreate();
|
||||||
|
}
|
||||||
|
|
||||||
const std::size_t image_index = swapchain.GetImageIndex();
|
const std::size_t image_index = swapchain.GetImageIndex();
|
||||||
|
|
||||||
scheduler.Wait(resource_ticks[image_index]);
|
scheduler.Wait(resource_ticks[image_index]);
|
||||||
|
@ -448,15 +453,15 @@ vk::Framebuffer BlitScreen::CreateFramebuffer(const VkImageView& image_view, VkE
|
||||||
|
|
||||||
void BlitScreen::CreateStaticResources() {
|
void BlitScreen::CreateStaticResources() {
|
||||||
CreateShaders();
|
CreateShaders();
|
||||||
|
CreateSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlitScreen::CreateDynamicResources() {
|
||||||
CreateSemaphores();
|
CreateSemaphores();
|
||||||
CreateDescriptorPool();
|
CreateDescriptorPool();
|
||||||
CreateDescriptorSetLayout();
|
CreateDescriptorSetLayout();
|
||||||
CreateDescriptorSets();
|
CreateDescriptorSets();
|
||||||
CreatePipelineLayout();
|
CreatePipelineLayout();
|
||||||
CreateSampler();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlitScreen::CreateDynamicResources() {
|
|
||||||
CreateRenderPass();
|
CreateRenderPass();
|
||||||
CreateFramebuffers();
|
CreateFramebuffers();
|
||||||
CreateGraphicsPipeline();
|
CreateGraphicsPipeline();
|
||||||
|
|
|
@ -109,7 +109,7 @@ private:
|
||||||
MemoryAllocator& memory_allocator;
|
MemoryAllocator& memory_allocator;
|
||||||
Swapchain& swapchain;
|
Swapchain& swapchain;
|
||||||
Scheduler& scheduler;
|
Scheduler& scheduler;
|
||||||
const std::size_t image_count;
|
std::size_t image_count;
|
||||||
const ScreenInfo& screen_info;
|
const ScreenInfo& screen_info;
|
||||||
|
|
||||||
vk::ShaderModule vertex_shader;
|
vk::ShaderModule vertex_shader;
|
||||||
|
|
|
@ -519,9 +519,7 @@ public:
|
||||||
dld{rhs.dld} {}
|
dld{rhs.dld} {}
|
||||||
|
|
||||||
/// Assign an allocation transfering ownership from another allocation.
|
/// Assign an allocation transfering ownership from another allocation.
|
||||||
/// Releases any previously held allocation.
|
|
||||||
PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
|
PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
|
||||||
Release();
|
|
||||||
allocations = std::move(rhs.allocations);
|
allocations = std::move(rhs.allocations);
|
||||||
num = rhs.num;
|
num = rhs.num;
|
||||||
device = rhs.device;
|
device = rhs.device;
|
||||||
|
@ -530,11 +528,6 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys any held allocation.
|
|
||||||
~PoolAllocations() {
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the number of allocations.
|
/// Returns the number of allocations.
|
||||||
std::size_t size() const noexcept {
|
std::size_t size() const noexcept {
|
||||||
return num;
|
return num;
|
||||||
|
@ -557,19 +550,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Destroys the held allocations if they exist.
|
|
||||||
void Release() noexcept {
|
|
||||||
if (!allocations) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const Span<AllocationType> span(allocations.get(), num);
|
|
||||||
const VkResult result = Free(device, pool, span, *dld);
|
|
||||||
// There's no way to report errors from a destructor.
|
|
||||||
if (result != VK_SUCCESS) {
|
|
||||||
std::terminate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<AllocationType[]> allocations;
|
std::unique_ptr<AllocationType[]> allocations;
|
||||||
std::size_t num = 0;
|
std::size_t num = 0;
|
||||||
VkDevice device = nullptr;
|
VkDevice device = nullptr;
|
||||||
|
|
Loading…
Reference in a new issue