Compare commits
30 Commits
Author | SHA1 | Date |
---|---|---|
psucien | 4182740384 | |
psucien | ca1613258f | |
georgemoralis | 3d375a28eb | |
jnack | 69d4fecdfe | |
Xphalnos | 7886761476 | |
squidbus | 6080066f75 | |
georgemoralis | f1fe6b9f96 | |
squidbus | 6e552aac6a | |
adjonesey | 0f87d1e3d4 | |
georgemoralis | 68fa5e292f | |
bigol83 | bdfff5e8ea | |
georgemoralis | cdd193d5b1 | |
georgemoralis | 30ab2b7f71 | |
DanielSvoboda | f2b6843f9d | |
squidbus | a17150960f | |
Grégoire Hage | 1651db24fe | |
IndecisiveTurtle | 6bf42aa985 | |
georgemoralis | 8d41695e74 | |
IndecisiveTurtle | cb5190e31a | |
IndecisiveTurtle | cf706f8cc7 | |
IndecisiveTurtle | 6fbbe3d79b | |
IndecisiveTurtle | fab390b860 | |
Plínio Larrubia | 5a96ac1a4f | |
georgemoralis | ac2fa103fa | |
georgemoralis | 7e7854346d | |
DanielSvoboda | 751f6f9bab | |
Flamy | 1c835a1aa4 | |
georgemoralis | 07c8c28000 | |
TheTurtle | 66e96dd944 | |
DanielSvoboda | aef7498c49 |
|
@ -82,3 +82,6 @@
|
|||
path = externals/ffmpeg-core
|
||||
url = https://github.com/shadps4-emu/ext-ffmpeg-core.git
|
||||
shallow = true
|
||||
[submodule "externals/half"]
|
||||
path = externals/half
|
||||
url = https://github.com/ROCm/half.git
|
||||
|
|
|
@ -521,6 +521,8 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
|||
src/video_core/renderer_vulkan/vk_resource_pool.h
|
||||
src/video_core/renderer_vulkan/vk_scheduler.cpp
|
||||
src/video_core/renderer_vulkan/vk_scheduler.h
|
||||
src/video_core/renderer_vulkan/vk_shader_cache.cpp
|
||||
src/video_core/renderer_vulkan/vk_shader_cache.h
|
||||
src/video_core/renderer_vulkan/vk_shader_util.cpp
|
||||
src/video_core/renderer_vulkan/vk_shader_util.h
|
||||
src/video_core/renderer_vulkan/vk_swapchain.cpp
|
||||
|
@ -642,6 +644,9 @@ if (APPLE)
|
|||
|
||||
# Replacement for std::chrono::time_zone
|
||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
||||
|
||||
# Half float conversions for F16C patches
|
||||
target_link_libraries(shadps4 PRIVATE half)
|
||||
endif()
|
||||
|
||||
if (NOT ENABLE_QT_GUI)
|
||||
|
|
|
@ -142,11 +142,17 @@ if (WIN32)
|
|||
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
||||
endif()
|
||||
|
||||
# date
|
||||
if (APPLE AND NOT TARGET date::date-tz)
|
||||
if (APPLE)
|
||||
# half
|
||||
add_library(half INTERFACE)
|
||||
target_include_directories(half INTERFACE half/include)
|
||||
|
||||
# date
|
||||
if (NOT TARGET date::date-tz)
|
||||
option(BUILD_TZ_LIB "" ON)
|
||||
option(USE_SYSTEM_TZ_DB "" ON)
|
||||
add_subdirectory(date)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Tracy
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit d59c84d388c805022e2bddea08aa41cbe7e43e55
|
||||
Subproject commit 12cbda959b6df2af119a76a73ff906c2bed36884
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1ddada225144cac0de8f6b5c0dd9acffd99a2e68
|
|
@ -1 +1 @@
|
|||
Subproject commit 1115dad3ffa0994e3f43b693d9b9cc99944c64c1
|
||||
Subproject commit 2c48a1a50203bbaf1e3d0d64c5d726d56f8d3bb3
|
|
@ -1 +1 @@
|
|||
Subproject commit 8db09231c448b913ae905d5237ce2eca46e3fe87
|
||||
Subproject commit 37090c74cc6e680f2bc334cac8fd182f7634a1f6
|
|
@ -1 +1 @@
|
|||
Subproject commit cc0bee4fd46ea1f5db147d63ea545208cc9e8405
|
||||
Subproject commit 4b740127230472779c4a4d71e1a75aaa3a367a2d
|
|
@ -1 +1 @@
|
|||
Subproject commit aabb091ae37068498751fd58202a9854408ecb0e
|
||||
Subproject commit ccdf68421bc8eb85693f573080fc0a5faad862db
|
|
@ -15,6 +15,7 @@
|
|||
#else
|
||||
#include <pthread.h>
|
||||
#ifdef __APPLE__
|
||||
#include <half.hpp>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
@ -30,6 +31,12 @@ static Xbyak::Reg ZydisToXbyakRegister(const ZydisRegister reg) {
|
|||
if (reg >= ZYDIS_REGISTER_RAX && reg <= ZYDIS_REGISTER_R15) {
|
||||
return Xbyak::Reg64(reg - ZYDIS_REGISTER_RAX + Xbyak::Operand::RAX);
|
||||
}
|
||||
if (reg >= ZYDIS_REGISTER_XMM0 && reg <= ZYDIS_REGISTER_XMM31) {
|
||||
return Xbyak::Xmm(reg - ZYDIS_REGISTER_XMM0 + xmm0.getIdx());
|
||||
}
|
||||
if (reg >= ZYDIS_REGISTER_YMM0 && reg <= ZYDIS_REGISTER_YMM31) {
|
||||
return Xbyak::Ymm(reg - ZYDIS_REGISTER_YMM0 + ymm0.getIdx());
|
||||
}
|
||||
UNREACHABLE_MSG("Unsupported register: {}", static_cast<u32>(reg));
|
||||
}
|
||||
|
||||
|
@ -66,6 +73,12 @@ static Xbyak::Address ZydisToXbyakMemoryOperand(const ZydisDecodedOperand& opera
|
|||
return ptr[expression];
|
||||
}
|
||||
|
||||
static u64 ZydisToXbyakImmediateOperand(const ZydisDecodedOperand& operand) {
|
||||
ASSERT_MSG(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE,
|
||||
"Expected immediate operand, got type: {}", static_cast<u32>(operand.type));
|
||||
return operand.imm.value.u;
|
||||
}
|
||||
|
||||
static std::unique_ptr<Xbyak::Operand> ZydisToXbyakOperand(const ZydisDecodedOperand& operand) {
|
||||
switch (operand.type) {
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER: {
|
||||
|
@ -110,51 +123,135 @@ static Xbyak::Reg AllocateScratchRegister(
|
|||
|
||||
#ifdef __APPLE__
|
||||
|
||||
static constexpr u32 MaxSavedRegisters = 3;
|
||||
static pthread_key_t register_save_slots[MaxSavedRegisters];
|
||||
static std::once_flag register_save_init_flag;
|
||||
static pthread_key_t stack_pointer_slot;
|
||||
static pthread_key_t patch_stack_slot;
|
||||
static std::once_flag patch_context_slots_init_flag;
|
||||
|
||||
static_assert(sizeof(void*) == sizeof(u64),
|
||||
"Cannot fit a register inside a thread local storage slot.");
|
||||
|
||||
static void InitializeRegisterSaveSlots() {
|
||||
for (u32 i = 0; i < MaxSavedRegisters; i++) {
|
||||
ASSERT_MSG(pthread_key_create(®ister_save_slots[i], nullptr) == 0,
|
||||
"Unable to allocate thread-local register save slot {}", i);
|
||||
static void InitializePatchContextSlots() {
|
||||
ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0,
|
||||
"Unable to allocate thread-local register for stack pointer.");
|
||||
ASSERT_MSG(pthread_key_create(&patch_stack_slot, nullptr) == 0,
|
||||
"Unable to allocate thread-local register for patch stack.");
|
||||
}
|
||||
|
||||
void InitializeThreadPatchStack() {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
const auto* patch_stack = std::malloc(0x1000);
|
||||
pthread_setspecific(patch_stack_slot, patch_stack);
|
||||
}
|
||||
|
||||
void CleanupThreadPatchStack() {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
auto* patch_stack = pthread_getspecific(patch_stack_slot);
|
||||
if (patch_stack != nullptr) {
|
||||
std::free(patch_stack);
|
||||
pthread_setspecific(patch_stack_slot, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
|
||||
ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to save {} registers.",
|
||||
regs.size());
|
||||
|
||||
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
|
||||
|
||||
u32 index = 0;
|
||||
for (const auto& reg : regs) {
|
||||
const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
|
||||
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
// Save stack pointer and load patch stack.
|
||||
c.putSeg(gs);
|
||||
c.mov(qword[offset], reg.cvt64());
|
||||
}
|
||||
c.mov(qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))], rsp);
|
||||
c.putSeg(gs);
|
||||
c.mov(rsp, qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))]);
|
||||
}
|
||||
|
||||
/// Restores the stack pointer from thread local storage.
|
||||
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
// Save patch stack pointer and load original stack.
|
||||
c.putSeg(gs);
|
||||
c.mov(qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))], rsp);
|
||||
c.putSeg(gs);
|
||||
c.mov(rsp, qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// These utilities are not implemented as we can't save anything to thread local storage without
|
||||
// temporary registers.
|
||||
void InitializeThreadPatchStack() {
|
||||
// No-op
|
||||
}
|
||||
|
||||
void CleanupThreadPatchStack() {
|
||||
// No-op
|
||||
}
|
||||
|
||||
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
/// Restores the stack pointer from thread local storage.
|
||||
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// Switches to the patch stack, saves registers, and restores the original stack.
|
||||
static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
|
||||
SaveStack(c);
|
||||
for (const auto& reg : regs) {
|
||||
c.push(reg.cvt64());
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
/// Switches to the patch stack, restores registers, and restores the original stack.
|
||||
static void RestoreRegisters(Xbyak::CodeGenerator& c,
|
||||
const std::initializer_list<Xbyak::Reg> regs) {
|
||||
ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to restore {} registers.",
|
||||
regs.size());
|
||||
|
||||
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
|
||||
|
||||
u32 index = 0;
|
||||
SaveStack(c);
|
||||
for (const auto& reg : regs) {
|
||||
const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
|
||||
c.pop(reg.cvt64());
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
c.putSeg(gs);
|
||||
c.mov(reg.cvt64(), qword[offset]);
|
||||
/// Switches to the patch stack and stores all registers.
|
||||
static void SaveContext(Xbyak::CodeGenerator& c) {
|
||||
SaveStack(c);
|
||||
for (int reg = Xbyak::Operand::RAX; reg <= Xbyak::Operand::R15; reg++) {
|
||||
c.push(Xbyak::Reg64(reg));
|
||||
}
|
||||
for (int reg = 0; reg <= 7; reg++) {
|
||||
c.sub(rsp, 32);
|
||||
c.vmovdqu(ptr[rsp], Xbyak::Ymm(reg));
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores all registers and restores the original stack.
|
||||
/// If the destination is a register, it is not restored to preserve the output.
|
||||
static void RestoreContext(Xbyak::CodeGenerator& c, const Xbyak::Operand& dst) {
|
||||
for (int reg = 7; reg >= 0; reg--) {
|
||||
if ((!dst.isXMM() && !dst.isYMM()) || dst.getIdx() != reg) {
|
||||
c.vmovdqu(Xbyak::Ymm(reg), ptr[rsp]);
|
||||
}
|
||||
c.add(rsp, 32);
|
||||
}
|
||||
for (int reg = Xbyak::Operand::R15; reg >= Xbyak::Operand::RAX; reg--) {
|
||||
if (!dst.isREG() || dst.getIdx() != reg) {
|
||||
c.pop(Xbyak::Reg64(reg));
|
||||
} else {
|
||||
c.add(rsp, 4);
|
||||
}
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
|
||||
|
@ -204,9 +301,9 @@ static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
|||
c.and_(dst, scratch2);
|
||||
|
||||
if (dst.getIdx() == shift.getIdx()) {
|
||||
RestoreRegisters(c, {scratch1, scratch2});
|
||||
RestoreRegisters(c, {scratch2, scratch1});
|
||||
} else {
|
||||
RestoreRegisters(c, {scratch1, scratch2, shift});
|
||||
RestoreRegisters(c, {shift, scratch2, scratch1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,10 +355,138 @@ static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
|
|||
RestoreRegisters(c, {scratch});
|
||||
}
|
||||
|
||||
bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
||||
static __attribute__((sysv_abi)) void PerformVCVTPH2PS(float* out, const half_float::half* in,
|
||||
const u32 count) {
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
out[i] = half_float::half_cast<float>(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateVCVTPH2PS(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
|
||||
const auto float_count = dst.getBit() / 32;
|
||||
const auto byte_count = float_count * 4;
|
||||
|
||||
SaveContext(c);
|
||||
|
||||
// Allocate stack space for outputs and load into first parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rdi, rsp);
|
||||
|
||||
if (src->isXMM()) {
|
||||
// Allocate stack space for inputs and load into second parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rsi, rsp);
|
||||
|
||||
// Move input to the allocated space.
|
||||
c.movdqu(ptr[rsp], *reinterpret_cast<Xbyak::Xmm*>(src.get()));
|
||||
} else {
|
||||
c.lea(rsi, src->getAddress());
|
||||
}
|
||||
|
||||
// Load float count into third parameter.
|
||||
c.mov(rdx, float_count);
|
||||
|
||||
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPH2PS));
|
||||
c.call(rax);
|
||||
|
||||
if (src->isXMM()) {
|
||||
// Clean up after inputs space.
|
||||
c.add(rsp, byte_count);
|
||||
}
|
||||
|
||||
// Load outputs into destination register and clean up space.
|
||||
if (dst.isYMM()) {
|
||||
c.vmovdqu(*reinterpret_cast<const Xbyak::Ymm*>(&dst), ptr[rsp]);
|
||||
} else {
|
||||
c.movdqu(*reinterpret_cast<const Xbyak::Xmm*>(&dst), ptr[rsp]);
|
||||
}
|
||||
c.add(rsp, byte_count);
|
||||
|
||||
RestoreContext(c, dst);
|
||||
}
|
||||
|
||||
using SingleToHalfFloatConverter = half_float::half (*)(float);
|
||||
static const SingleToHalfFloatConverter SingleToHalfFloatConverters[4] = {
|
||||
half_float::half_cast<half_float::half, std::round_to_nearest, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_neg_infinity, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_infinity, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_zero, float>,
|
||||
};
|
||||
|
||||
static __attribute__((sysv_abi)) void PerformVCVTPS2PH(half_float::half* out, const float* in,
|
||||
const u32 count, const u8 rounding_mode) {
|
||||
const auto conversion_func = SingleToHalfFloatConverters[rounding_mode];
|
||||
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
out[i] = conversion_func(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateVCVTPS2PH(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakRegisterOperand(operands[1]);
|
||||
const auto ctrl = ZydisToXbyakImmediateOperand(operands[2]);
|
||||
|
||||
const auto float_count = src.getBit() / 32;
|
||||
const auto byte_count = float_count * 4;
|
||||
|
||||
SaveContext(c);
|
||||
|
||||
if (dst->isXMM()) {
|
||||
// Allocate stack space for outputs and load into first parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rdi, rsp);
|
||||
} else {
|
||||
c.lea(rdi, dst->getAddress());
|
||||
}
|
||||
|
||||
// Allocate stack space for inputs and load into second parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rsi, rsp);
|
||||
|
||||
// Move input to the allocated space.
|
||||
if (src.isYMM()) {
|
||||
c.vmovdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Ymm*>(&src));
|
||||
} else {
|
||||
c.movdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Xmm*>(&src));
|
||||
}
|
||||
|
||||
// Load float count into third parameter.
|
||||
c.mov(rdx, float_count);
|
||||
|
||||
// Load rounding mode into fourth parameter.
|
||||
if (ctrl & 4) {
|
||||
// Load from MXCSR.RC.
|
||||
c.stmxcsr(ptr[rsp - 4]);
|
||||
c.mov(rcx, ptr[rsp - 4]);
|
||||
c.shr(rcx, 13);
|
||||
c.and_(rcx, 3);
|
||||
} else {
|
||||
c.mov(rcx, ctrl & 3);
|
||||
}
|
||||
|
||||
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPS2PH));
|
||||
c.call(rax);
|
||||
|
||||
// Clean up after inputs space.
|
||||
c.add(rsp, byte_count);
|
||||
|
||||
if (dst->isXMM()) {
|
||||
// Load outputs into destination register and clean up space.
|
||||
c.movdqu(*reinterpret_cast<Xbyak::Xmm*>(dst.get()), ptr[rsp]);
|
||||
c.add(rsp, byte_count);
|
||||
}
|
||||
|
||||
RestoreContext(c, *dst);
|
||||
}
|
||||
|
||||
static bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
||||
int ret = 0;
|
||||
size_t size = sizeof(ret);
|
||||
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) != 0) {
|
||||
if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) != 0) {
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
|
@ -339,12 +564,16 @@ static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
|||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
// BMI1 instructions that are not supported by Rosetta 2 on Apple Silicon.
|
||||
// Patches for instruction sets not supported by Rosetta 2.
|
||||
// BMI1
|
||||
{ZYDIS_MNEMONIC_ANDN, {FilterRosetta2Only, GenerateANDN, true}},
|
||||
{ZYDIS_MNEMONIC_BEXTR, {FilterRosetta2Only, GenerateBEXTR, true}},
|
||||
{ZYDIS_MNEMONIC_BLSI, {FilterRosetta2Only, GenerateBLSI, true}},
|
||||
{ZYDIS_MNEMONIC_BLSMSK, {FilterRosetta2Only, GenerateBLSMSK, true}},
|
||||
{ZYDIS_MNEMONIC_BLSR, {FilterRosetta2Only, GenerateBLSR, true}},
|
||||
// F16C
|
||||
{ZYDIS_MNEMONIC_VCVTPH2PS, {FilterRosetta2Only, GenerateVCVTPH2PS, true}},
|
||||
{ZYDIS_MNEMONIC_VCVTPS2PH, {FilterRosetta2Only, GenerateVCVTPS2PH, true}},
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,12 @@ class CodeGenerator;
|
|||
|
||||
namespace Core {
|
||||
|
||||
/// Initializes a stack for the current thread for use by patch implementations.
|
||||
void InitializeThreadPatchStack();
|
||||
|
||||
/// Cleans up the patch stack for the current thread.
|
||||
void CleanupThreadPatchStack();
|
||||
|
||||
/// Patches CPU instructions that cannot run as-is on the host.
|
||||
void PatchInstructions(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include <cmath>
|
||||
#include <common/path_util.h>
|
||||
#include <common/singleton.h>
|
||||
#include <core/file_format/psf.h>
|
||||
#include <core/file_sys/fs.h>
|
||||
|
||||
#include "app_content.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/file_format/psf.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <memory>
|
||||
#include <common/assert.h>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "audio_core/sdl_audio.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -650,12 +650,12 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
||||
u32 flags) {
|
||||
LOG_TRACE(Lib_GnmDriver, "called");
|
||||
|
||||
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
||||
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) {
|
||||
|
||||
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexIndirect>(
|
||||
|
@ -665,7 +665,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset,
|
|||
|
||||
cmdbuf[0] = data_offset;
|
||||
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[3] = 0;
|
||||
|
||||
cmdbuf += 4;
|
||||
|
@ -707,11 +707,11 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset,
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags) {
|
||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags) {
|
||||
LOG_TRACE(Lib_GnmDriver, "called");
|
||||
|
||||
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
||||
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) {
|
||||
|
||||
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndirect>(cmdbuf, 4, PM4ShaderType::ShaderGraphics,
|
||||
|
@ -721,7 +721,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32
|
|||
|
||||
cmdbuf[0] = data_offset;
|
||||
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||
cmdbuf[3] = 2; // auto index
|
||||
|
||||
cmdbuf += 4;
|
||||
|
|
|
@ -45,7 +45,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr
|
|||
u32 flags, u32 type);
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags);
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
||||
u32 flags);
|
||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti();
|
||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
||||
|
@ -53,7 +53,7 @@ int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced();
|
|||
s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count,
|
||||
u32 flags);
|
||||
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags);
|
||||
u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags);
|
||||
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
||||
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <common/assert.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "event_flag_obj.h"
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Libraries::Kernel {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/libraries/kernel/event_queue.h"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <bit>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
#include <mutex>
|
||||
#include <semaphore>
|
||||
#include <thread>
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/error.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/cpu_patches.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/libkernel.h"
|
||||
#include "core/libraries/kernel/thread_management.h"
|
||||
|
@ -985,6 +987,7 @@ static void cleanup_thread(void* arg) {
|
|||
destructor(value);
|
||||
}
|
||||
}
|
||||
Core::CleanupThreadPatchStack();
|
||||
thread->is_almost_done = true;
|
||||
}
|
||||
|
||||
|
@ -992,6 +995,7 @@ static void* run_thread(void* arg) {
|
|||
auto* thread = static_cast<ScePthread>(arg);
|
||||
Common::SetCurrentThreadName(thread->name.c_str());
|
||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||
Core::InitializeThreadPatchStack();
|
||||
linker->InitTlsForThread(false);
|
||||
void* ret = nullptr;
|
||||
g_pthread_self = thread;
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <vector>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <condition_variable>
|
||||
#include <list>
|
||||
#include <mutex>
|
||||
#include <utility>
|
||||
#include <boost/intrusive/list.hpp>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
@ -13,9 +13,6 @@
|
|||
|
||||
namespace Libraries::Kernel {
|
||||
|
||||
using ListBaseHook =
|
||||
boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>;
|
||||
|
||||
class Semaphore {
|
||||
public:
|
||||
Semaphore(s32 init_count, s32 max_count, std::string_view name, bool is_fifo)
|
||||
|
@ -37,7 +34,7 @@ public:
|
|||
|
||||
// Create waiting thread object and add it into the list of waiters.
|
||||
WaitingThread waiter{need_count, is_fifo};
|
||||
AddWaiter(waiter);
|
||||
AddWaiter(&waiter);
|
||||
|
||||
// Perform the wait.
|
||||
return waiter.Wait(lk, timeout);
|
||||
|
@ -52,14 +49,14 @@ public:
|
|||
|
||||
// Wake up threads in order of priority.
|
||||
for (auto it = wait_list.begin(); it != wait_list.end();) {
|
||||
auto& waiter = *it;
|
||||
if (waiter.need_count > token_count) {
|
||||
auto* waiter = *it;
|
||||
if (waiter->need_count > token_count) {
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
it = wait_list.erase(it);
|
||||
token_count -= waiter.need_count;
|
||||
waiter.cv.notify_one();
|
||||
token_count -= waiter->need_count;
|
||||
waiter->cv.notify_one();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -70,9 +67,9 @@ public:
|
|||
if (num_waiters) {
|
||||
*num_waiters = wait_list.size();
|
||||
}
|
||||
for (auto& waiter : wait_list) {
|
||||
waiter.was_cancled = true;
|
||||
waiter.cv.notify_one();
|
||||
for (auto* waiter : wait_list) {
|
||||
waiter->was_cancled = true;
|
||||
waiter->cv.notify_one();
|
||||
}
|
||||
wait_list.clear();
|
||||
token_count = set_count < 0 ? init_count : set_count;
|
||||
|
@ -80,7 +77,7 @@ public:
|
|||
}
|
||||
|
||||
public:
|
||||
struct WaitingThread : public ListBaseHook {
|
||||
struct WaitingThread {
|
||||
std::condition_variable cv;
|
||||
u32 priority;
|
||||
s32 need_count;
|
||||
|
@ -132,7 +129,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void AddWaiter(WaitingThread& waiter) {
|
||||
void AddWaiter(WaitingThread* waiter) {
|
||||
// Insert at the end of the list for FIFO order.
|
||||
if (is_fifo) {
|
||||
wait_list.push_back(waiter);
|
||||
|
@ -140,16 +137,13 @@ public:
|
|||
}
|
||||
// Find the first with priority less then us and insert right before it.
|
||||
auto it = wait_list.begin();
|
||||
while (it != wait_list.end() && it->priority > waiter.priority) {
|
||||
while (it != wait_list.end() && (*it)->priority > waiter->priority) {
|
||||
it++;
|
||||
}
|
||||
wait_list.insert(it, waiter);
|
||||
}
|
||||
|
||||
using WaitingThreads =
|
||||
boost::intrusive::list<WaitingThread, boost::intrusive::base_hook<ListBaseHook>,
|
||||
boost::intrusive::constant_time_size<false>>;
|
||||
WaitingThreads wait_list;
|
||||
std::list<WaitingThread*> wait_list;
|
||||
std::string name;
|
||||
std::atomic<s32> token_count;
|
||||
std::mutex mutex;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/native_clock.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -2,13 +2,18 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/config.h"
|
||||
#include "core/libraries/ajm/ajm.h"
|
||||
#include "core/libraries/app_content/app_content.h"
|
||||
#include "core/libraries/audio/audioin.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
#include "core/libraries/avplayer/avplayer.h"
|
||||
#include "core/libraries/dialogs/error_dialog.h"
|
||||
#include "core/libraries/dialogs/ime_dialog.h"
|
||||
#include "core/libraries/disc_map/disc_map.h"
|
||||
#include "core/libraries/gnmdriver/gnmdriver.h"
|
||||
#include "core/libraries/kernel/libkernel.h"
|
||||
#include "core/libraries/libc_internal/libc_internal.h"
|
||||
#include "core/libraries/libpng/pngdec.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/network/http.h"
|
||||
#include "core/libraries/network/net.h"
|
||||
|
@ -32,11 +37,6 @@
|
|||
#include "core/libraries/system/userservice.h"
|
||||
#include "core/libraries/usbd/usbd.h"
|
||||
#include "core/libraries/videoout/video_out.h"
|
||||
#include "src/core/libraries/ajm/ajm.h"
|
||||
#include "src/core/libraries/avplayer/avplayer.h"
|
||||
#include "src/core/libraries/dialogs/error_dialog.h"
|
||||
#include "src/core/libraries/dialogs/ime_dialog.h"
|
||||
#include "src/core/libraries/libpng/pngdec.h"
|
||||
|
||||
namespace Libraries {
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/loader/elf.h"
|
||||
#include "core/loader/symbols_resolver.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include <unordered_map>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include <common/assert.h>
|
||||
#include <common/singleton.h>
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "input/controller.h"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <core/file_format/playgo_chunk.h>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/file_format/playgo_chunk.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/system/systemservice.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include "playgo_types.h"
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include <chrono>
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -3,12 +3,13 @@
|
|||
|
||||
#include <span>
|
||||
#include <vector>
|
||||
#include <common/path_util.h>
|
||||
#include <common/singleton.h>
|
||||
#include <core/file_format/psf.h>
|
||||
#include <core/file_sys/fs.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/file_format/psf.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/save_data/savedata.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
// Generated By moduleGenerator
|
||||
#include "common/logging/log.h"
|
||||
#include "common/singleton.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/types.h"
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/debug.h"
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "common/thread.h"
|
||||
#include "core/aerolib/aerolib.h"
|
||||
#include "core/aerolib/stubs.h"
|
||||
#include "core/cpu_patches.h"
|
||||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "core/libraries/kernel/thread_management.h"
|
||||
#include "core/linker.h"
|
||||
|
@ -85,6 +86,7 @@ void Linker::Execute() {
|
|||
// Init primary thread.
|
||||
Common::SetCurrentThreadName("GAME_MainThread");
|
||||
Libraries::Kernel::pthreadInitSelfMainThread();
|
||||
InitializeThreadPatchStack();
|
||||
InitTlsForThread(true);
|
||||
|
||||
// Start shared library modules
|
||||
|
@ -104,6 +106,8 @@ void Linker::Execute() {
|
|||
RunMainEntry(m->GetEntryAddress(), &p, ProgramExitFunc);
|
||||
}
|
||||
}
|
||||
|
||||
CleanupThreadPatchStack();
|
||||
}
|
||||
|
||||
s32 Linker::LoadModule(const std::filesystem::path& elf_name, bool is_dynamic) {
|
||||
|
|
|
@ -130,7 +130,7 @@ void CheatsPatches::setupUI() {
|
|||
// Call the method to fill the list of cheat files
|
||||
populateFileListCheats();
|
||||
|
||||
QLabel* repositoryLabel = new QLabel("Repository:");
|
||||
QLabel* repositoryLabel = new QLabel(tr("Repository:"));
|
||||
repositoryLabel->setAlignment(Qt::AlignLeft);
|
||||
repositoryLabel->setAlignment(Qt::AlignVCenter);
|
||||
|
||||
|
@ -175,7 +175,8 @@ void CheatsPatches::setupUI() {
|
|||
|
||||
int ret = QMessageBox::warning(
|
||||
this, tr("Delete File"),
|
||||
QString(tr("Do you want to delete the selected file?\n%1")).arg(selectedFileName),
|
||||
QString(tr("Do you want to delete the selected file?\\n%1").replace("\\n", "\n"))
|
||||
.arg(selectedFileName),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (ret == QMessageBox::Yes) {
|
||||
|
@ -1123,7 +1124,7 @@ void CheatsPatches::addPatchesToLayout(const QString& filePath) {
|
|||
void CheatsPatches::updateNoteTextEdit(const QString& patchName) {
|
||||
if (m_patchInfos.contains(patchName)) {
|
||||
const PatchInfo& patchInfo = m_patchInfos[patchName];
|
||||
QString text = QString(tr("Name:") + " %1\n" + tr("Author:") + " %2\n\n%3")
|
||||
QString text = QString(tr("Name:") + " %1\n" + tr("Author: ") + "%2\n\n%3")
|
||||
.arg(patchInfo.name)
|
||||
.arg(patchInfo.author)
|
||||
.arg(patchInfo.note);
|
||||
|
|
|
@ -36,6 +36,7 @@ public:
|
|||
void downloadCheats(const QString& source, const QString& m_gameSerial,
|
||||
const QString& m_gameVersion, bool showMessageBox);
|
||||
void downloadPatches(const QString repository, const bool showMessageBox);
|
||||
void createFilesJson(const QString& repository);
|
||||
|
||||
signals:
|
||||
void downloadFinished();
|
||||
|
@ -58,7 +59,6 @@ private:
|
|||
void applyCheat(const QString& modName, bool enabled);
|
||||
void applyPatch(const QString& patchName, bool enabled);
|
||||
|
||||
void createFilesJson(const QString& repository);
|
||||
void uncheckAllCheatCheckBoxes();
|
||||
void updateNoteTextEdit(const QString& patchName);
|
||||
|
||||
|
|
|
@ -140,7 +140,7 @@ public:
|
|||
new CheatsPatches(gameName, gameSerial, gameVersion, gameSize, gameImage);
|
||||
cheatsPatches->show();
|
||||
connect(widget->parent(), &QWidget::destroyed, cheatsPatches,
|
||||
[widget, cheatsPatches]() { cheatsPatches->deleteLater(); });
|
||||
[cheatsPatches]() { cheatsPatches->deleteLater(); });
|
||||
}
|
||||
|
||||
if (selected == &openTrophyViewer) {
|
||||
|
|
|
@ -366,7 +366,7 @@ void MainWindow::CreateConnects() {
|
|||
|
||||
panelDialog->accept();
|
||||
});
|
||||
connect(downloadAllPatchesButton, &QPushButton::clicked, this, [this, panelDialog]() {
|
||||
connect(downloadAllPatchesButton, &QPushButton::clicked, [panelDialog]() {
|
||||
QEventLoop eventLoop;
|
||||
int pendingDownloads = 0;
|
||||
|
||||
|
@ -391,6 +391,8 @@ void MainWindow::CreateConnects() {
|
|||
nullptr, tr("Download Complete"),
|
||||
QString(tr("Patches Downloaded Successfully!") + "\n" +
|
||||
tr("All Patches available for all games have been downloaded.")));
|
||||
cheatsPatches->createFilesJson("GoldHEN");
|
||||
cheatsPatches->createFilesJson("shadPS4");
|
||||
panelDialog->accept();
|
||||
});
|
||||
panelDialog->exec();
|
||||
|
@ -640,24 +642,24 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
double appD = game_app_version.toDouble();
|
||||
double pkgD = pkg_app_version.toDouble();
|
||||
if (pkgD == appD) {
|
||||
msgBox.setText(QString(tr("Patch detected!\nPKG and Game versions match!: "
|
||||
"%1\nWould you like ") +
|
||||
tr("to overwrite?"))
|
||||
.arg(pkg_app_version));
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("PKG and Game versions match: ") + pkg_app_version +
|
||||
"\n" + tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
} else if (pkgD < appD) {
|
||||
msgBox.setText(QString(tr("Patch detected!\nPKG Version %1 is older ") +
|
||||
tr("than installed version!: %2\nWould you like ") +
|
||||
tr("to overwrite?"))
|
||||
.arg(pkg_app_version, game_app_version));
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("PKG Version %1 is older than installed version: ")
|
||||
.arg(pkg_app_version) +
|
||||
game_app_version + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
} else {
|
||||
msgBox.setText(
|
||||
QString(tr("Patch detected!\nGame is installed: %1\nWould you like ") +
|
||||
tr("to install Patch: %2?"))
|
||||
.arg(game_app_version, pkg_app_version));
|
||||
msgBox.setText(QString(tr("Patch detected!") + "\n" +
|
||||
tr("Game is installed: ") + game_app_version + "\n" +
|
||||
tr("Would you like to install Patch: ") +
|
||||
pkg_app_version + " ?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
}
|
||||
|
@ -683,9 +685,9 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(
|
||||
QString("DLC already installed\n%1\nWould you like to overwrite?")
|
||||
.arg(QString::fromStdString(addon_extract_path.string())));
|
||||
msgBox.setText(QString(tr("DLC already installed:") + "\n" +
|
||||
QString::fromStdString(addon_extract_path.string()) +
|
||||
"\n\n" + tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
int result = msgBox.exec();
|
||||
|
@ -696,9 +698,9 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
}
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(
|
||||
QString(tr("Game already installed\n%1\nWould you like to overwrite?"))
|
||||
.arg(QString::fromStdString(extract_path.string())));
|
||||
msgBox.setText(QString(tr("Game already installed") + "\n" +
|
||||
QString::fromStdString(extract_path.string()) + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
int result = msgBox.exec();
|
||||
|
|
|
@ -566,44 +566,34 @@
|
|||
<translation>PKG-udtrækning</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch opdaget!\nPKG- og spilversioner stemmer overens!: %1\nVil du </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch opdaget!\nPKG-version %1 er ældre </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>end installeret version!: %2\nVil du </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overskrive?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Opdatering detekteret!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch opdaget!\nSpillet er installeret: %1\nVil du </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG og spilversioner matcher: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>installere patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Vil du overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Spil allerede installeret\n%1\nVil du overskrive?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Version %1 er ældre end den installerede version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spillet er installeret: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Vil du installere opdateringen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
|
@ -613,7 +603,17 @@
|
|||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Vil du installere DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC allerede installeret:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spillet er allerede installeret</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG-Extraktion</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch erkannt!\nPKG- und Spielversion stimmen überein!: %1\nMöchten Sie </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>überschreiben?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch erkannt!\nPKG-Version %1 ist älter </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>als die installierte Version!: %2\nMöchten Sie </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>überschreiben?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch erkannt!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch erkannt!\nSpiel ist installiert: %1\nMöchten Sie </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- und Spielversionen stimmen überein: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>Patch installieren: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Würden Sie gerne überschreiben?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Spiel bereits installiert\n%1\nMöchten Sie überschreiben?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-Version %1 ist älter als die installierte Version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spiel ist installiert: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Möchten Sie den Patch installieren: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC-Installation</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Würden Sie gerne DLC installieren: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC bereits installiert:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spiel bereits installiert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Εξαγωγή PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Ανίχνευση Patch!\nΟι εκδόσεις PKG και παιχνιδιού ταιριάζουν!: %1\nΘέλετε </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>να αντικαταστήσετε;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Ανίχνευση Patch!\nΗ έκδοση PKG %1 είναι παλαιότερη </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>από την εγκατεστημένη έκδοση!: %2\nΘέλετε </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>να αντικαταστήσετε;</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Αναγνώριση ενημέρωσης!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Ανίχνευση Patch!\nΤο παιχνίδι είναι εγκατεστημένο: %1\nΘέλετε </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Οι εκδόσεις PKG και παιχνιδιού ταιριάζουν: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>να εγκαταστήσετε το Patch: %2;</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Θέλετε να αντικαταστήσετε;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Το παιχνίδι είναι ήδη εγκατεστημένο\n%1\nΘέλετε να αντικαταστήσετε;</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Η έκδοση PKG %1 είναι παλαιότερη από την εγκατεστημένη έκδοση: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Το παιχνίδι είναι εγκατεστημένο: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Θέλετε να εγκαταστήσετε την ενημέρωση: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Εγκατάσταση DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Θέλετε να εγκαταστήσετε το DLC: %1;</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC ήδη εγκατεστημένο:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Παιχνίδι ήδη εγκατεστημένο</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,44 +566,34 @@
|
|||
<translation>PKG Extraction</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch detected!\nPKG and Game versions match!: %1\nWould you like </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch detected!\nPKG Version %1 is older </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>than installed version!: %2\nWould you like </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>to overwrite?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch detected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch detected!\nGame is installed: %1\nWould you like </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG and Game versions match: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>to install Patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Would you like to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Game already installed\n%1\nWould you like to overwrite?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Version %1 is older than installed version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game is installed: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Would you like to install Patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
|
@ -615,6 +605,16 @@
|
|||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC already installed:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game already installed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>PKG is a patch, please install the game first!</source>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Extracción de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>¡Parche detectado!\n¡La versión de PKG y del juego coinciden!: %1\n¿Te gustaría </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>¿sobrescribir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>¡Parche detectado!\nLa versión de PKG %1 es más antigua </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>que la versión instalada!: %2\n¿Te gustaría </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>¿sobrescribir?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>¡Actualización detectada!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>¡Parche detectado!\nJuego está instalado: %1\n¿Te gustaría </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Las versiones de PKG y del juego coinciden: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>¿instalar el parche: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>¿Desea sobrescribir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Juego ya instalado\n%1\n¿Te gustaría sobrescribirlo?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La versión de PKG %1 es más antigua que la versión instalada: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>El juego está instalado: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>¿Desea instalar la actualización: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Instalación de DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>¿Desea instalar el DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC ya instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Juego ya instalado</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG:n purku</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Korjaus havaittu!\nPKG:n ja pelin versiot vastaavat!: %1\nHaluatko </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>korvata?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Korjaus havaittu!\nPKG Version %1 on vanhempi </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>kuin asennettu versio!: %2\nHaluatko </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>korvata?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Päivitys havaittu!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Korjaus havaittu!\nPeli on asennettu: %1\nHaluatko </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- ja peliversiot vastaavat: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>asentaa korjaus: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Haluatko korvata?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Peli on jo asennettu\n%1\nHaluatko korvata sen?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versio %1 on vanhempi kuin asennettu versio: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Peli on asennettu: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Haluatko asentaa päivityksen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC-asennus</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Haluatko asentaa DLC:n: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC on jo asennettu:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Peli on jo asennettu</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Extraction du PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch détecté !\nLa version du PKG et du jeu correspondent : %1\nSouhaitez-vous </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>écraser ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch détecté !\nVersion PKG %1 est plus ancienne </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>que la version installée ! : %2\nSouhaitez-vous </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>écraser ?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch détecté !</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch détecté !\nJeu est installé : %1\nSouhaitez-vous </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Les versions PKG et jeu correspondent : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>installer le patch : %2 ?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Souhaitez-vous remplacer ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Jeu déjà installé\n%1\nSouhaitez-vous écraser ?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La version PKG %1 est plus ancienne que la version installée : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Jeu installé : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Souhaitez-vous installer le patch : </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Installation du DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Souhaitez-vous installer le DLC : %1 ?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC déjà installé :</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Jeu déjà installé</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG kicsomagolás</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Javítás észlelve!\nA PKG és a játék verziók egyeznek: %1\nSzeretnéd </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>felülírni?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Javítás észlelve!\nA PKG verzió %1 régebbi </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>mint a telepített verzió: %2\nSzeretnéd </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>felülírni?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Frissítés észlelve!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Javítás észlelve!\nA játék telepítve van: %1\nSzeretnéd </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>A PKG és a játék verziói egyeznek: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>a javítást telepíteni: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Szeretné felülírni?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>A játék már telepítve van\n%1\nSzeretnéd felülírni?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>A %1-es PKG verzió régebbi, mint a telepített verzió: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>A játék telepítve van: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Szeretné telepíteni a frissítést: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC Telepítés</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Szeretné telepíteni a DLC-t: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC már telepítve:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>A játék már telepítve van</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Ekstraksi PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch terdeteksi!\nVersi PKG dan Game cocok!: %1\nApakah Anda ingin </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>menimpa?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch terdeteksi!\nVersi PKG %1 lebih lama </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>daripada versi yang terpasang!: %2\nApakah Anda ingin </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>menimpa?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch terdeteksi!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch terdeteksi!\nGame terpasang: %1\nApakah Anda ingin </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Versi PKG dan Game cocok: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>memasang Patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Apakah Anda ingin menimpa?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Game sudah terpasang\n%1\nApakah Anda ingin menimpa?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Versi PKG %1 lebih lama dari versi yang terpasang: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game telah terpasang: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Apakah Anda ingin menginstal patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Instalasi DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Apakah Anda ingin menginstal DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC sudah terpasang:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game sudah terpasang</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -181,7 +181,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="318"/>
|
||||
<source>Install application from a .pkg file</source>
|
||||
<translation>Installa applicazione da un file .pkg file</translation>
|
||||
<translation>Installa applicazione da un file .pkg</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window_ui.h" line="320"/>
|
||||
|
@ -236,7 +236,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="338"/>
|
||||
<source>List View</source>
|
||||
<translation>Visualizzazione lista</translation>
|
||||
<translation>Visualizzazione Lista</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window_ui.h" line="340"/>
|
||||
|
@ -341,7 +341,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="364"/>
|
||||
<source>toolBar</source>
|
||||
<translation>barra strumenti</translation>
|
||||
<translation>Barra strumenti</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -566,44 +566,34 @@
|
|||
<translation>Estrazione file PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch rilevata! Il\nPKG e la versione del gioco coincidono!: %1\nVuoi </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>sovrascrivere?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch rilevata! La \nPKG Versione %1 è più vecchia </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>della versione installata!: %2\nVuoi </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>sovrascrivere?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch rilevata!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch rilevata!\nGioco installato: %1\Vuoi </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Le versioni di PKG e del gioco corrispondono: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>installare la Patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Vuoi sovrascrivere?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Gioco già installato\n%1\nVuoi sovrascrivere??</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>La versione PKG %1 è più vecchia rispetto alla versione installata: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Gioco installato: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Vuoi installare la patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
|
@ -615,6 +605,16 @@
|
|||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Vuoi installare il DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC già installato:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Gioco già installato</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>PKG is a patch, please install the game first!</source>
|
||||
|
@ -651,12 +651,12 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="44"/>
|
||||
<source>Cheats / Patches</source>
|
||||
<translation>Cheat / Patch</translation>
|
||||
<translation>Trucchi / Patch</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="50"/>
|
||||
<source>defaultTextEdit_MSG</source>
|
||||
<translation>I cheats/patches sono sperimentali.\nUtilizzali con cautela.\n\nScarica i cheats singolarmente selezionando il repository e cliccando sul pulsante di download.\nNella scheda Patches, puoi scaricare tutti i patch in una volta sola, scegliere quali vuoi utilizzare e salvare la tua selezione.\n\nPoiché non sviluppiamo i Cheats/Patches,\nper favore segnala i problemi all'autore del cheat.\n\nHai creato un nuovo cheat? Visita:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
<translation>I trucchi e le patch sono sperimentali.\nUtilizzali con cautela.\n\nScarica i trucchi singolarmente selezionando l'archivio e cliccando sul pulsante di download.\nNella scheda Patch, puoi scaricare tutte le patch in una volta sola, scegliere quali vuoi utilizzare e salvare la tua selezione.\n\nPoiché non sviluppiamo i trucchi e le patch,\nper favore segnala i problemi all'autore dei trucchi.\n\nHai creato un nuovo trucco? Visita:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="69"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG抽出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>パッチが検出されました!\nPKGとゲームバージョンが一致しています!: %1\n上書きしますか</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>上書きしますか?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>パッチが検出されました!\nPKGバージョン %1 は古い </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>インストールされているバージョンよりも古いです!: %2\n上書きしますか</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>上書きしますか?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>パッチが検出されました!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>パッチが検出されました!\nゲームがインストールされています: %1\nインストールしますか</translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKGとゲームのバージョンが一致しています: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>パッチをインストールしますか: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>上書きしてもよろしいですか?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>ゲームはすでにインストールされています\n%1\n上書きしますか?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKGバージョン %1 はインストールされているバージョンよりも古いです: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>ゲームはインストール済みです: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>パッチをインストールしてもよろしいですか: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLCのインストール</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>DLCをインストールしてもよろしいですか: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLCはすでにインストールされています:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>ゲームはすでにインストールされています</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,44 +566,34 @@
|
|||
<translation>PKG Extraction</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch detected!\nPKG and Game versions match!: %1\nWould you like </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch detected!\nPKG Version %1 is older </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>than installed version!: %2\nWould you like </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>to overwrite?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch detected!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch detected!\nGame is installed: %1\nWould you like </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG and Game versions match: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>to install Patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Would you like to overwrite?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Game already installed\n%1\nWould you like to overwrite?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Version %1 is older than installed version: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game is installed: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Would you like to install Patch: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
|
@ -615,6 +605,16 @@
|
|||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC already installed:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game already installed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>PKG is a patch, please install the game first!</source>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG ištraukimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Pataisa aptikta!\nPKG ir žaidimo versijos atitinka!: %1\nAr norėtumėte </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>perrašyti?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Pataisa aptikta!\nPKG versija %1 yra senesnė </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>nei įdiegta versija!: %2\nAr norėtumėte </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>perrašyti?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Rasta atnaujinimą!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Pataisa aptikta!\nŽaidimas įdiegtas: %1\nAr norėtumėte </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG ir žaidimo versijos sutampa: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>įdiegti pataisą: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Ar norite perrašyti?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Žaidimas jau įdiegtas\n%1\nAr norėtumėte perrašyti?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG versija %1 yra senesnė nei įdiegta versija: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Žaidimas įdiegtas: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Ar norite įdiegti atnaujinimą: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC diegimas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Ar norite įdiegti DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC jau įdiegtas:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Žaidimas jau įdiegtas</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG-ekstraksjon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Oppdatering oppdaget!\nPKG og spillversjoner stemmer!: %1\nØnsker du å </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Oppdatering oppdaget!\nPKG-versjon %1 er eldre </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>enn installert versjon!: %2\nØnsker du å </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overskrive?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Oppdatering oppdaget!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Oppdatering oppdaget!\nSpillet er installert: %1\nØnsker du å </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- og spillversjoner stemmer overens: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>installere oppdateringen: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Ønsker du å overskrive?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Spill allerede installert\n%1\nØnsker du å overskrive?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versjon %1 er eldre enn installert versjon: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Spillet er installert: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Ønsker du å installere oppdateringen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC-installasjon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Ønsker du å installere DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC allerede installert:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Spillet er allerede installert</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG-extractie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch gedetecteerd!\nPKG en spelversies komen overeen!: %1\nWil je </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overschrijven?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch gedetecteerd!\nPKG-versie %1 is ouder </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>dan de geïnstalleerde versie!: %2\nWil je </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>overschrijven?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch gedetecteerd!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch gedetecteerd!\nSpel is geïnstalleerd: %1\nWil je </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG- en gameversies komen overeen: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>de patch installeren: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Wilt u overschrijven?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Spel al geïnstalleerd\n%1\nWil je het overschrijven?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG-versie %1 is ouder dan de geïnstalleerde versie: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Game is geïnstalleerd: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Wilt u de patch installeren: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC-installatie</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Wilt u DLC installeren: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC al geïnstalleerd:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Game al geïnstalleerd</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Ekstrakcja PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Wykryto poprawkę!\nWersje PKG i gry pasują do siebie!: %1\nCzy chcesz </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>nadpisać?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Wykryto poprawkę!\nWersja PKG %1 jest starsza </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>niż zainstalowana wersja!: %2\nCzy chcesz </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>nadpisać?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Wykryto łatkę!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Wykryto poprawkę!\nGra jest zainstalowana: %1\nCzy chcesz </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Wersje PKG i gry są zgodne: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>zainstalować poprawkę: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Czy chcesz nadpisać?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Gra już zainstalowana\n%1\nCzy chcesz ją nadpisać?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Wersja PKG %1 jest starsza niż zainstalowana wersja: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Gra jest zainstalowana: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Czy chcesz zainstalować łatkę: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>Instalacja dodadkowej zawartości (DLC)</translation>
|
||||
<translation>Instalacja DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Czy na pewno chcesz zainstalować dodatkową zawartość (DLC): %1?</translation>
|
||||
<translation>Czy chcesz zainstalować DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC już zainstalowane:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Gra już zainstalowana</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<message>
|
||||
<location filename="../game_info.cpp" line="26"/>
|
||||
<source>Loading game list, please wait :3</source>
|
||||
<translation>Carregando lista de jogos, por favor aguarde :3</translation>
|
||||
<translation>Carregando a lista de jogos, por favor aguarde :3</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../game_info.cpp" line="26"/>
|
||||
|
@ -256,7 +256,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="343"/>
|
||||
<source>Download Cheats/Patches</source>
|
||||
<translation>Baixar Trapaças / Patches</translation>
|
||||
<translation>Baixar Cheats/Patches</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window_ui.h" line="345"/>
|
||||
|
@ -291,7 +291,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="354"/>
|
||||
<source>Game List Mode</source>
|
||||
<translation>Modo de Lista de Jogos</translation>
|
||||
<translation>Modo da Lista de Jogos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window_ui.h" line="355"/>
|
||||
|
@ -425,7 +425,7 @@
|
|||
<message>
|
||||
<location filename="../settings_dialog.ui" line="235"/>
|
||||
<source>Log Filter</source>
|
||||
<translation>Filtro</translation>
|
||||
<translation>Filtro do Registro</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../settings_dialog.ui" line="272"/>
|
||||
|
@ -508,12 +508,12 @@
|
|||
<message>
|
||||
<location filename="../main_window.cpp" line="326"/>
|
||||
<source>Download Cheats For All Installed Games</source>
|
||||
<translation>Baixar Trapaças para todos os jogos instalados</translation>
|
||||
<translation>Baixar Cheats para Todos os Jogos Instalados</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="328"/>
|
||||
<source>Download Patches For All Games</source>
|
||||
<translation>Baixar Patches para todos os jogos</translation>
|
||||
<translation>Baixar Patches para Todos os Jogos</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="363"/>
|
||||
|
@ -523,7 +523,7 @@
|
|||
<message>
|
||||
<location filename="../main_window.cpp" line="364"/>
|
||||
<source>You have downloaded cheats for all the games you have installed.</source>
|
||||
<translation>Você baixou trapaças para todos os jogos que instalou.</translation>
|
||||
<translation>Você baixou cheats para todos os jogos que instalou.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="391"/>
|
||||
|
@ -566,64 +566,64 @@
|
|||
<translation>Extração de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch detectado!\nVersões PKG e do Jogo correspondem!: %1\nGostaria de </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>substituir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch detectado!\nVersão PKG %1 é mais antiga </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>do que a versão instalada!: %2\nGostaria de </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>substituir?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Atualização detectada!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch detectado!\nJogo está instalado: %1\nGostaria de </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>As versões do PKG e do Jogo são igual: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>instalar o Patch: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Gostaria de substituir?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Jogo já instalado\n%1\nGostaria de substituir?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Versão do PKG %1 é mais antiga do que a versão instalada: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Jogo instalado: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Você gostaria de instalar a atualização: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Instalação de DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Você gostaria de instalar o DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC já instalada:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>O jogo já está instalado:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>PKG is a patch, please install the game first!</source>
|
||||
<translation>PKG é um patch, por favor, instale o jogo primeiro!</translation>
|
||||
<translation>O PKG é um patch, por favor, instale o jogo primeiro!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="681"/>
|
||||
<source>PKG ERROR</source>
|
||||
<translation>ERRO PKG</translation>
|
||||
<translation>ERRO de PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="693"/>
|
||||
|
@ -651,12 +651,12 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="44"/>
|
||||
<source>Cheats / Patches</source>
|
||||
<translation>Trapaças / Patches</translation>
|
||||
<translation>Cheats / Patches</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="50"/>
|
||||
<source>defaultTextEdit_MSG</source>
|
||||
<translation>Trapaças/Patches são experimentais.\nUse com cautela.\n\nBaixe as trapaças individualmente selecionando o repositório e clicando no botão de download.\nNa aba Patches, você pode baixar todos os Patches de uma vez, escolher qual deseja usar e salvar a opção.\n\nComo não desenvolvemos as Trapaças/Patches,\npor favor, reporte problemas relacionados ao autor da trapaça.\n\nCriou uma nova trapaça? Visite:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
<translation>Cheats/Patches são experimentais.\nUse com cautela.\n\nBaixe os cheats individualmente selecionando o repositório e clicando no botão de download.\nNa aba Patches, você pode baixar todos os Patches de uma vez, escolha qual deseja usar e salve a opção.\n\nComo não desenvolvemos os Cheats/Patches,\npor favor, reporte problemas relacionados ao autor do cheat.\n\nCriou um novo cheat? Visite:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="69"/>
|
||||
|
@ -666,7 +666,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="79"/>
|
||||
<source>Serial: </source>
|
||||
<translation>Série: </translation>
|
||||
<translation>Serial: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="83"/>
|
||||
|
@ -681,7 +681,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="126"/>
|
||||
<source>Select Cheat File:</source>
|
||||
<translation>Selecione o Arquivo de Trapaça:</translation>
|
||||
<translation>Selecione o Arquivo de Cheat:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="133"/>
|
||||
|
@ -691,7 +691,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="149"/>
|
||||
<source>Download Cheats</source>
|
||||
<translation>Baixar Trapaças</translation>
|
||||
<translation>Baixar Cheats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="155"/>
|
||||
|
@ -706,7 +706,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="170"/>
|
||||
<source>You can delete the cheats you don't want after downloading them.</source>
|
||||
<translation>Você pode excluir as trapaças que não deseja após baixá-las.</translation>
|
||||
<translation>Você pode excluir os cheats que não deseja após baixá-las.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="178"/>
|
||||
|
@ -731,7 +731,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="256"/>
|
||||
<source>Cheats</source>
|
||||
<translation>Trapaças</translation>
|
||||
<translation>Cheats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="257"/>
|
||||
|
@ -756,7 +756,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="316"/>
|
||||
<source>No patch file found for the current serial.</source>
|
||||
<translation>Nenhum arquivo de patch encontrado para a série atual.</translation>
|
||||
<translation>Nenhum arquivo de patch encontrado para o serial atual.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="323"/>
|
||||
|
@ -816,22 +816,22 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="556"/>
|
||||
<source>Cheats Not Found</source>
|
||||
<translation>Trapaças Não Encontradas</translation>
|
||||
<translation>Cheats Não Encontrados</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="556"/>
|
||||
<source>CheatsNotFound_MSG</source>
|
||||
<translation>Nenhuma trapaça encontrada para este jogo nesta versão do repositório selecionado, tente outro repositório ou uma versão diferente do jogo.</translation>
|
||||
<translation>Nenhum cheat encontrado para este jogo nesta versão do repositório selecionado, tente outro repositório ou uma versão diferente do jogo.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="593"/>
|
||||
<source>Cheats Downloaded Successfully</source>
|
||||
<translation>Trapaças Baixadas com Sucesso</translation>
|
||||
<translation>Cheats Baixados com Sucesso</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="594"/>
|
||||
<source>CheatsDownloadedSuccessfully_MSG</source>
|
||||
<translation>Você baixou as trapaças com sucesso. Para esta versão do jogo a partir do repositório selecionado.Você pode tentar baixar de outro repositório, se estiver disponível, também será possível usá-lo selecionando o arquivo da lista.</translation>
|
||||
<translation>Você baixou os cheats com sucesso. Para esta versão do jogo a partir do repositório selecionado. Você pode tentar baixar de outro repositório, se estiver disponível, também será possível usá-lo selecionando o arquivo da lista.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="747"/>
|
||||
|
@ -851,7 +851,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="763"/>
|
||||
<source>DownloadComplete_MSG</source>
|
||||
<translation>Patches Baixados com Sucesso! Todos os patches disponíveis para todos os jogos foram baixados, não é necessário baixá-los individualmente para cada jogo como acontece com as Trapaças.</translation>
|
||||
<translation>Patches Baixados com Sucesso! Todos os patches disponíveis para todos os jogos foram baixados, não é necessário baixá-los individualmente para cada jogo como acontece com os Cheats.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="773"/>
|
||||
|
@ -871,7 +871,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="819"/>
|
||||
<source>XML ERROR:</source>
|
||||
<translation>ERRO XML:</translation>
|
||||
<translation>ERRO de XML:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="826"/>
|
||||
|
@ -886,7 +886,7 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="997"/>
|
||||
<source>Directory does not exist:</source>
|
||||
<translation>Diretório não existe:</translation>
|
||||
<translation>O Diretório não existe:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="1006"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Extracție PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Patch detectat!\nVersiunile PKG și Joc se potrivesc!: %1\nAi dori să </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>să suprascrii?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Patch detectat!\nVersiunea PKG %1 este mai veche </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>decât versiunea instalată!: %2\nAi dori să </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>să suprascrii?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Patch detectat!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Patch detectat!\nJocul este instalat: %1\nAi dori să </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Versiunile PKG și ale jocului sunt compatibile: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>să instalezi Patch-ul: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Doriți să suprascrieți?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Jocul este deja instalat\n%1\nAi dori să suprascrii?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Versiunea PKG %1 este mai veche decât versiunea instalată: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Jocul este instalat: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Doriți să instalați patch-ul: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Instalare DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Doriți să instalați DLC-ul: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC deja instalat:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Jocul deja instalat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<message>
|
||||
<location filename="../gui_context_menus.h" line="48"/>
|
||||
<source>Cheats / Patches</source>
|
||||
<translation>Читы / Патчи</translation>
|
||||
<translation>Читы и патчи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../gui_context_menus.h" line="49"/>
|
||||
|
@ -256,7 +256,7 @@
|
|||
<message>
|
||||
<location filename="../main_window_ui.h" line="343"/>
|
||||
<source>Download Cheats/Patches</source>
|
||||
<translation>Скачать Читы / Патчи</translation>
|
||||
<translation>Скачать читы или патчи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window_ui.h" line="345"/>
|
||||
|
@ -566,54 +566,54 @@
|
|||
<translation>Извлечение PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Обнаружен патч!\nВерсии PKG и игры совпадают!: %1\nХотите </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>перезаписать?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Обнаружен патч!\nВерсия PKG %1 устарела </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>по сравнению с установленной версией!: %2\nХотите </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>перезаписать?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Обнаружен патч!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Обнаружен патч!\nИгра установлена: %1\nХотите </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Версии PKG и игры совпадают: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>установить патч: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Хотите перезаписать?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Игра уже установлена\n%1\nХотите перезаписать?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Версия PKG %1 старее установленной версии: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Игра установлена: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Хотите установить патч: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Установка DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Вы хотите установить DLC: %1??</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC уже установлен:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Игра уже установлена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
@ -638,7 +638,7 @@
|
|||
<message>
|
||||
<location filename="../main_window.cpp" line="704"/>
|
||||
<source>Game successfully installed at %1</source>
|
||||
<translation>Игра успешно установлена по адресу %1</translation>
|
||||
<translation>Игра успешно установлена в %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="725"/>
|
||||
|
@ -651,12 +651,12 @@
|
|||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="44"/>
|
||||
<source>Cheats / Patches</source>
|
||||
<translation>Читы / Патчи</translation>
|
||||
<translation>Читы и патчи</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="50"/>
|
||||
<source>defaultTextEdit_MSG</source>
|
||||
<translation>Cheats/Patches sunt experimentale.\nUtilizați cu prudență.\n\nDescărcați cheats individual prin selectarea depozitului și făcând clic pe butonul de descărcare.\nÎn fila Patches, puteți descărca toate patch-urile deodată, alege pe cele pe care doriți să le utilizați și salvați selecția.\n\nDeoarece nu dezvoltăm Cheats/Patches,\nte rugăm să raportezi problemele autorului cheat-ului.\n\nAi creat un nou cheat? Vizitează:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
<translation>Читы и патчи экспериментальны.\nИспользуйте с осторожностью.\n\nСкачивайте читы, выбрав репозиторий и нажав на кнопку загрузки.\nВо вкладке "Патчи" вы можете скачать все патчи сразу, выбирать какие вы хотите использовать, и сохранять выбор.\n\nПоскольку мы не разрабатываем читы/патчи,\nпожалуйста сообщайте о проблемах автору чита/патча.\n\nСоздали новый чит? Посетите:\nhttps://github.com/shadps4-emu/ps4_cheats</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../cheats_patches.cpp" line="69"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG Çıkartma</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Yama tespit edildi!\nPKG ve Oyun sürümleri uyuyor!: %1\nÜzerine yazmak ister misiniz?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>üzerine yazmak?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Yama tespit edildi!\nPKG Sürümü %1 daha eski </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>yüklü sürümden!: %2\nÜzerine yazmak ister misiniz?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>üzerine yazmak?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Yamanın tespit edildi!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Yama tespit edildi!\nOyun yüklü: %1\nÜzerine yazmak ister misiniz?</translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG ve oyun sürümleri uyumlu: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>Yamayı kurmak ister misiniz: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Üzerine yazmak ister misiniz?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Oyun zaten yüklü\n%1\nÜzerine yazmak ister misiniz?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG Sürümü %1, kurulu sürümden daha eski: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Oyun yüklendi: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Yamanın yüklenmesini ister misiniz: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC Yükleme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>DLC'yi yüklemek ister misiniz: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC zaten yüklü:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Oyun zaten yüklü</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>Giải nén PKG</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>Đã phát hiện bản vá!\nPhiên bản PKG và trò chơi khớp!: %1\nBạn có muốn </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>ghi đè không?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>Đã phát hiện bản vá!\nPhiên bản PKG %1 cũ hơn </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>so với phiên bản đã cài đặt!: %2\nBạn có muốn </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>ghi đè không?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>Đã phát hiện bản vá!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>Đã phát hiện bản vá!\nTrò chơi đã được cài đặt: %1\nBạn có muốn </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>Các phiên bản PKG và trò chơi khớp nhau: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>cài đặt bản vá: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>Bạn có muốn ghi đè không?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>Trò chơi đã được cài đặt\n%1\nBạn có muốn ghi đè không?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>Phiên bản PKG %1 cũ hơn phiên bản đã cài đặt: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>Trò chơi đã được cài đặt: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>Bạn có muốn cài đặt bản vá: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>Cài đặt DLC</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>Bạn có muốn cài đặt DLC: %1?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC đã được cài đặt:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>Trò chơi đã được cài đặt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG 解压</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>检测到补丁!\nPKG 和游戏版本匹配:%1\n您想要 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>覆盖吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>检测到补丁!\nPKG 版本 %1 较旧 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>与已安装版本相比:%2\n您想要 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>覆盖吗?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>检测到补丁!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>检测到补丁!\n游戏已安装:%1\n您想要 </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG 和游戏版本匹配: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>安装补丁:%2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>您想要覆盖吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>游戏已安装\n%1\n您想要覆盖吗?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG 版本 %1 比已安装版本更旧: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>游戏已安装: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>您想安装补丁吗: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC 安装</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>您想安装 DLC: %1 吗?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC 已经安装:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>游戏已经安装</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -566,54 +566,54 @@
|
|||
<translation>PKG 解壓縮</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="633"/>
|
||||
<source>Patch detected!\nPKG and Game versions match!: %1\nWould you like </source>
|
||||
<translation>偵測到修補檔!\nPKG 和遊戲版本匹配!: %1\n您是否希望 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="634"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>覆蓋嗎?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>Patch detected!\nPKG Version %1 is older </source>
|
||||
<translation>偵測到修補檔!\nPKG 版本 %1 較舊 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="640"/>
|
||||
<source>than installed version!: %2\nWould you like </source>
|
||||
<translation>比安裝的版本舊!: %2\n您是否希望 </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="641"/>
|
||||
<source>to overwrite?</source>
|
||||
<translation>覆蓋嗎?</translation>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!</source>
|
||||
<translation>檢測到補丁!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="646"/>
|
||||
<source>Patch detected!\nGame is installed: %1\nWould you like </source>
|
||||
<translation>偵測到修補檔!\n遊戲已安裝: %1\n您是否希望 </translation>
|
||||
<source>PKG and Game versions match: </source>
|
||||
<translation>PKG 和遊戲版本匹配: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="647"/>
|
||||
<source>to install Patch: %2?</source>
|
||||
<translation>安裝修補檔: %2?</translation>
|
||||
<source>Would you like to overwrite?</source>
|
||||
<translation>您想要覆蓋嗎?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="659"/>
|
||||
<source>Game already installed\n%1\nWould you like to overwrite?</source>
|
||||
<translation>遊戲已經安裝\n%1\n您是否希望覆蓋?</translation>
|
||||
<location filename="../main_window.cpp" line="639"/>
|
||||
<source>PKG Version %1 is older than installed version: </source>
|
||||
<translation>PKG 版本 %1 比已安裝版本更舊: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Game is installed: </source>
|
||||
<translation>遊戲已安裝: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="660"/>
|
||||
<source>Would you like to install Patch: </source>
|
||||
<translation>您想要安裝補丁嗎: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="673"/>
|
||||
<source>DLC Installation</source>
|
||||
<translation>DLC Installation</translation>
|
||||
<translation>DLC 安裝</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
<source>Would you like to install DLC: %1?</source>
|
||||
<translation>Would you like to install DLC: %1?</translation>
|
||||
<translation>您想要安裝 DLC: %1 嗎?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="688"/>
|
||||
<source>DLC already installed:</source>
|
||||
<translation>DLC 已經安裝:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="701"/>
|
||||
<source>Game already installed</source>
|
||||
<translation>遊戲已經安裝</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../main_window.cpp" line="674"/>
|
||||
|
|
|
@ -99,7 +99,7 @@ Id TypeId(const EmitContext& ctx, IR::Type type) {
|
|||
}
|
||||
}
|
||||
|
||||
void Traverse(EmitContext& ctx, IR::Program& program) {
|
||||
void Traverse(EmitContext& ctx, const IR::Program& program) {
|
||||
IR::Block* current_block{};
|
||||
for (const IR::AbstractSyntaxNode& node : program.syntax_list) {
|
||||
switch (node.type) {
|
||||
|
@ -162,7 +162,7 @@ void Traverse(EmitContext& ctx, IR::Program& program) {
|
|||
}
|
||||
}
|
||||
|
||||
Id DefineMain(EmitContext& ctx, IR::Program& program) {
|
||||
Id DefineMain(EmitContext& ctx, const IR::Program& program) {
|
||||
const Id void_function{ctx.TypeFunction(ctx.void_id)};
|
||||
const Id main{ctx.OpFunction(ctx.void_id, spv::FunctionControlMask::MaskNone, void_function)};
|
||||
for (IR::Block* const block : program.blocks) {
|
||||
|
@ -185,8 +185,28 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||
ctx.AddCapability(spv::Capability::Int16);
|
||||
}
|
||||
ctx.AddCapability(spv::Capability::Int64);
|
||||
if (info.has_storage_images) {
|
||||
if (info.has_storage_images || info.has_image_buffers) {
|
||||
ctx.AddCapability(spv::Capability::StorageImageExtendedFormats);
|
||||
ctx.AddCapability(spv::Capability::StorageImageReadWithoutFormat);
|
||||
ctx.AddCapability(spv::Capability::StorageImageWriteWithoutFormat);
|
||||
}
|
||||
if (info.has_texel_buffers) {
|
||||
ctx.AddCapability(spv::Capability::SampledBuffer);
|
||||
}
|
||||
if (info.has_image_buffers) {
|
||||
ctx.AddCapability(spv::Capability::ImageBuffer);
|
||||
}
|
||||
if (info.has_image_gather) {
|
||||
ctx.AddCapability(spv::Capability::ImageGatherExtended);
|
||||
}
|
||||
if (info.has_image_query) {
|
||||
ctx.AddCapability(spv::Capability::ImageQuery);
|
||||
}
|
||||
if (info.uses_lane_id) {
|
||||
ctx.AddCapability(spv::Capability::GroupNonUniform);
|
||||
}
|
||||
if (info.uses_group_quad) {
|
||||
ctx.AddCapability(spv::Capability::GroupNonUniformQuad);
|
||||
}
|
||||
switch (program.info.stage) {
|
||||
case Stage::Compute: {
|
||||
|
@ -206,19 +226,9 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||
} else {
|
||||
ctx.AddExecutionMode(main, spv::ExecutionMode::OriginUpperLeft);
|
||||
}
|
||||
ctx.AddCapability(spv::Capability::GroupNonUniform);
|
||||
if (info.uses_group_quad) {
|
||||
ctx.AddCapability(spv::Capability::GroupNonUniformQuad);
|
||||
}
|
||||
if (info.has_discard) {
|
||||
ctx.AddCapability(spv::Capability::DemoteToHelperInvocationEXT);
|
||||
}
|
||||
if (info.has_image_gather) {
|
||||
ctx.AddCapability(spv::Capability::ImageGatherExtended);
|
||||
}
|
||||
if (info.has_image_query) {
|
||||
ctx.AddCapability(spv::Capability::ImageQuery);
|
||||
}
|
||||
if (info.stores.Get(IR::Attribute::Depth)) {
|
||||
ctx.AddExecutionMode(main, spv::ExecutionMode::DepthReplacing);
|
||||
}
|
||||
|
@ -229,7 +239,7 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
|
|||
ctx.AddEntryPoint(execution_model, main, "main", interfaces);
|
||||
}
|
||||
|
||||
void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
||||
void PatchPhiNodes(const IR::Program& program, EmitContext& ctx) {
|
||||
auto inst{program.blocks.front()->begin()};
|
||||
size_t block_index{0};
|
||||
ctx.PatchDeferredPhi([&](size_t phi_arg) {
|
||||
|
@ -248,8 +258,8 @@ void PatchPhiNodes(IR::Program& program, EmitContext& ctx) {
|
|||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program, u32& binding) {
|
||||
EmitContext ctx{profile, program, binding};
|
||||
std::vector<u32> EmitSPIRV(const Profile& profile, const IR::Program& program, u32& binding) {
|
||||
EmitContext ctx{profile, program.info, binding};
|
||||
const Id main{DefineMain(ctx, program)};
|
||||
DefineEntryPoint(program, ctx, main);
|
||||
if (program.info.stage == Stage::Vertex) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Shader::Backend::SPIRV {
|
||||
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, IR::Program& program,
|
||||
[[nodiscard]] std::vector<u32> EmitSPIRV(const Profile& profile, const IR::Program& program,
|
||||
u32& binding);
|
||||
|
||||
} // namespace Shader::Backend::SPIRV
|
||||
|
|
|
@ -262,171 +262,16 @@ Id EmitLoadBufferF32x4(EmitContext& ctx, IR::Inst*, u32 handle, Id address) {
|
|||
return EmitLoadBufferF32xN<4>(ctx, handle, address);
|
||||
}
|
||||
|
||||
static bool IsSignedInteger(AmdGpu::NumberFormat format) {
|
||||
switch (format) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Uscaled:
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
return false;
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::Sscaled:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
return true;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static u32 UXBitsMax(u32 bit_width) {
|
||||
return (1u << bit_width) - 1u;
|
||||
}
|
||||
|
||||
static u32 SXBitsMax(u32 bit_width) {
|
||||
return (1u << (bit_width - 1u)) - 1u;
|
||||
}
|
||||
|
||||
static Id ConvertValue(EmitContext& ctx, Id value, AmdGpu::NumberFormat format, u32 bit_width) {
|
||||
switch (format) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
return ctx.OpFDiv(ctx.F32[1], value, ctx.ConstF32(float(UXBitsMax(bit_width))));
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
return ctx.OpFDiv(ctx.F32[1], value, ctx.ConstF32(float(SXBitsMax(bit_width))));
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
// (x * 2 + 1) / (Format::SMAX * 2)
|
||||
value = ctx.OpFMul(ctx.F32[1], value, ctx.ConstF32(2.f));
|
||||
value = ctx.OpFAdd(ctx.F32[1], value, ctx.ConstF32(1.f));
|
||||
return ctx.OpFDiv(ctx.F32[1], value, ctx.ConstF32(float(SXBitsMax(bit_width) * 2)));
|
||||
case AmdGpu::NumberFormat::Uscaled:
|
||||
case AmdGpu::NumberFormat::Sscaled:
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
return value;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unsupported number format for conversion: {}",
|
||||
magic_enum::enum_name(format));
|
||||
}
|
||||
}
|
||||
|
||||
static Id ComponentOffset(EmitContext& ctx, Id address, u32 stride, u32 bit_offset) {
|
||||
Id comp_offset = ctx.ConstU32(bit_offset);
|
||||
if (stride < 4) {
|
||||
// comp_offset += (address % 4) * 8;
|
||||
const Id byte_offset = ctx.OpUMod(ctx.U32[1], address, ctx.ConstU32(4u));
|
||||
const Id bit_offset = ctx.OpShiftLeftLogical(ctx.U32[1], byte_offset, ctx.ConstU32(3u));
|
||||
comp_offset = ctx.OpIAdd(ctx.U32[1], comp_offset, bit_offset);
|
||||
}
|
||||
return comp_offset;
|
||||
}
|
||||
|
||||
static Id GetBufferFormatValue(EmitContext& ctx, u32 handle, Id address, u32 comp) {
|
||||
auto& buffer = ctx.buffers[handle];
|
||||
const auto format = buffer.dfmt;
|
||||
switch (format) {
|
||||
case AmdGpu::DataFormat::FormatInvalid:
|
||||
return ctx.f32_zero_value;
|
||||
case AmdGpu::DataFormat::Format8:
|
||||
case AmdGpu::DataFormat::Format16:
|
||||
case AmdGpu::DataFormat::Format32:
|
||||
case AmdGpu::DataFormat::Format8_8:
|
||||
case AmdGpu::DataFormat::Format16_16:
|
||||
case AmdGpu::DataFormat::Format10_11_11:
|
||||
case AmdGpu::DataFormat::Format11_11_10:
|
||||
case AmdGpu::DataFormat::Format10_10_10_2:
|
||||
case AmdGpu::DataFormat::Format2_10_10_10:
|
||||
case AmdGpu::DataFormat::Format8_8_8_8:
|
||||
case AmdGpu::DataFormat::Format32_32:
|
||||
case AmdGpu::DataFormat::Format16_16_16_16:
|
||||
case AmdGpu::DataFormat::Format32_32_32:
|
||||
case AmdGpu::DataFormat::Format32_32_32_32: {
|
||||
const u32 num_components = AmdGpu::NumComponents(format);
|
||||
if (comp >= num_components) {
|
||||
return ctx.f32_zero_value;
|
||||
}
|
||||
|
||||
// uint index = address / 4;
|
||||
Id index = ctx.OpShiftRightLogical(ctx.U32[1], address, ctx.ConstU32(2u));
|
||||
const u32 stride = buffer.stride;
|
||||
if (stride > 4) {
|
||||
const u32 index_offset = u32(AmdGpu::ComponentOffset(format, comp) / 32);
|
||||
if (index_offset > 0) {
|
||||
// index += index_offset;
|
||||
index = ctx.OpIAdd(ctx.U32[1], index, ctx.ConstU32(index_offset));
|
||||
}
|
||||
}
|
||||
const Id ptr = ctx.OpAccessChain(buffer.pointer_type, buffer.id, ctx.u32_zero_value, index);
|
||||
|
||||
const u32 bit_offset = AmdGpu::ComponentOffset(format, comp) % 32;
|
||||
const u32 bit_width = AmdGpu::ComponentBits(format, comp);
|
||||
const auto num_format = buffer.nfmt;
|
||||
if (num_format == AmdGpu::NumberFormat::Float) {
|
||||
if (bit_width == 32) {
|
||||
return ctx.OpLoad(ctx.F32[1], ptr);
|
||||
} else if (bit_width == 16) {
|
||||
const Id comp_offset = ComponentOffset(ctx, address, stride, bit_offset);
|
||||
Id value = ctx.OpLoad(ctx.U32[1], ptr);
|
||||
value =
|
||||
ctx.OpBitFieldSExtract(ctx.S32[1], value, comp_offset, ctx.ConstU32(bit_width));
|
||||
value = ctx.OpSConvert(ctx.U16, value);
|
||||
value = ctx.OpBitcast(ctx.F16[1], value);
|
||||
return ctx.OpFConvert(ctx.F32[1], value);
|
||||
} else {
|
||||
UNREACHABLE_MSG("Invalid float bit width {}", bit_width);
|
||||
}
|
||||
} else {
|
||||
Id value = ctx.OpLoad(ctx.U32[1], ptr);
|
||||
const bool is_signed = IsSignedInteger(num_format);
|
||||
if (bit_width < 32) {
|
||||
const Id comp_offset = ComponentOffset(ctx, address, stride, bit_offset);
|
||||
if (is_signed) {
|
||||
value = ctx.OpBitFieldSExtract(ctx.S32[1], value, comp_offset,
|
||||
ctx.ConstU32(bit_width));
|
||||
} else {
|
||||
value = ctx.OpBitFieldUExtract(ctx.U32[1], value, comp_offset,
|
||||
ctx.ConstU32(bit_width));
|
||||
}
|
||||
}
|
||||
value = ctx.OpBitcast(ctx.F32[1], value);
|
||||
return ConvertValue(ctx, value, num_format, bit_width);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid format for conversion: {}", magic_enum::enum_name(format));
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 N>
|
||||
static Id EmitLoadBufferFormatF32xN(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
auto& buffer = ctx.buffers[handle];
|
||||
address = ctx.OpIAdd(ctx.U32[1], address, buffer.offset);
|
||||
if constexpr (N == 1) {
|
||||
return GetBufferFormatValue(ctx, handle, address, 0);
|
||||
} else {
|
||||
boost::container::static_vector<Id, N> ids;
|
||||
for (u32 i = 0; i < N; i++) {
|
||||
ids.push_back(GetBufferFormatValue(ctx, handle, address, i));
|
||||
}
|
||||
return ctx.OpCompositeConstruct(ctx.F32[N], ids);
|
||||
}
|
||||
}
|
||||
|
||||
Id EmitLoadBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
return EmitLoadBufferFormatF32xN<1>(ctx, inst, handle, address);
|
||||
}
|
||||
|
||||
Id EmitLoadBufferFormatF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
return EmitLoadBufferFormatF32xN<2>(ctx, inst, handle, address);
|
||||
}
|
||||
|
||||
Id EmitLoadBufferFormatF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
return EmitLoadBufferFormatF32xN<3>(ctx, inst, handle, address);
|
||||
}
|
||||
|
||||
Id EmitLoadBufferFormatF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address) {
|
||||
return EmitLoadBufferFormatF32xN<4>(ctx, inst, handle, address);
|
||||
const auto& buffer = ctx.texture_buffers[handle];
|
||||
const Id tex_buffer = ctx.OpLoad(buffer.image_type, buffer.id);
|
||||
const Id coord = ctx.OpIAdd(ctx.U32[1], address, buffer.coord_offset);
|
||||
Id texel = buffer.is_storage ? ctx.OpImageRead(buffer.result_type, tex_buffer, coord)
|
||||
: ctx.OpImageFetch(buffer.result_type, tex_buffer, coord);
|
||||
if (buffer.is_integer) {
|
||||
texel = ctx.OpBitcast(ctx.F32[4], texel);
|
||||
}
|
||||
return texel;
|
||||
}
|
||||
|
||||
template <u32 N>
|
||||
|
@ -467,97 +312,14 @@ void EmitStoreBufferU32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address
|
|||
EmitStoreBufferF32xN<1>(ctx, handle, address, value);
|
||||
}
|
||||
|
||||
static Id ConvertF32ToFormat(EmitContext& ctx, Id value, AmdGpu::NumberFormat format,
|
||||
u32 bit_width) {
|
||||
switch (format) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
return ctx.OpConvertFToU(
|
||||
ctx.U32[1], ctx.OpFMul(ctx.F32[1], value, ctx.ConstF32(float(UXBitsMax(bit_width)))));
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
return ctx.OpBitcast(ctx.U32[1], value);
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
return value;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unsupported number format for conversion: {}",
|
||||
magic_enum::enum_name(format));
|
||||
}
|
||||
}
|
||||
|
||||
template <u32 N>
|
||||
static void EmitStoreBufferFormatF32xN(EmitContext& ctx, u32 handle, Id address, Id value) {
|
||||
auto& buffer = ctx.buffers[handle];
|
||||
const auto format = buffer.dfmt;
|
||||
const auto num_format = buffer.nfmt;
|
||||
|
||||
switch (format) {
|
||||
case AmdGpu::DataFormat::FormatInvalid:
|
||||
return;
|
||||
case AmdGpu::DataFormat::Format8_8_8_8:
|
||||
case AmdGpu::DataFormat::Format16:
|
||||
case AmdGpu::DataFormat::Format32:
|
||||
case AmdGpu::DataFormat::Format32_32:
|
||||
case AmdGpu::DataFormat::Format32_32_32_32: {
|
||||
ASSERT(N == AmdGpu::NumComponents(format));
|
||||
|
||||
address = ctx.OpIAdd(ctx.U32[1], address, buffer.offset);
|
||||
const Id index = ctx.OpShiftRightLogical(ctx.U32[1], address, ctx.ConstU32(2u));
|
||||
const Id ptr = ctx.OpAccessChain(buffer.pointer_type, buffer.id, ctx.u32_zero_value, index);
|
||||
|
||||
Id packed_value{};
|
||||
for (u32 i = 0; i < N; i++) {
|
||||
const u32 bit_width = AmdGpu::ComponentBits(format, i);
|
||||
const u32 bit_offset = AmdGpu::ComponentOffset(format, i) % 32;
|
||||
|
||||
const Id comp{ConvertF32ToFormat(
|
||||
ctx, N == 1 ? value : ctx.OpCompositeExtract(ctx.F32[1], value, i), num_format,
|
||||
bit_width)};
|
||||
|
||||
if (bit_width == 32) {
|
||||
if constexpr (N == 1) {
|
||||
ctx.OpStore(ptr, comp);
|
||||
} else {
|
||||
const Id index_i = ctx.OpIAdd(ctx.U32[1], index, ctx.ConstU32(i));
|
||||
const Id ptr = ctx.OpAccessChain(buffer.pointer_type, buffer.id,
|
||||
ctx.u32_zero_value, index_i);
|
||||
ctx.OpStore(ptr, comp);
|
||||
}
|
||||
} else {
|
||||
if (i == 0) {
|
||||
packed_value = comp;
|
||||
} else {
|
||||
packed_value =
|
||||
ctx.OpBitFieldInsert(ctx.U32[1], packed_value, comp,
|
||||
ctx.ConstU32(bit_offset), ctx.ConstU32(bit_width));
|
||||
}
|
||||
|
||||
if (i == N - 1) {
|
||||
ctx.OpStore(ptr, packed_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid format for conversion: {}", magic_enum::enum_name(format));
|
||||
}
|
||||
}
|
||||
|
||||
void EmitStoreBufferFormatF32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
EmitStoreBufferFormatF32xN<1>(ctx, handle, address, value);
|
||||
}
|
||||
|
||||
void EmitStoreBufferFormatF32x2(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address,
|
||||
Id value) {
|
||||
EmitStoreBufferFormatF32xN<2>(ctx, handle, address, value);
|
||||
}
|
||||
|
||||
void EmitStoreBufferFormatF32x3(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address,
|
||||
Id value) {
|
||||
EmitStoreBufferFormatF32xN<3>(ctx, handle, address, value);
|
||||
}
|
||||
|
||||
void EmitStoreBufferFormatF32x4(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address,
|
||||
Id value) {
|
||||
EmitStoreBufferFormatF32xN<4>(ctx, handle, address, value);
|
||||
const auto& buffer = ctx.texture_buffers[handle];
|
||||
const Id tex_buffer = ctx.OpLoad(buffer.image_type, buffer.id);
|
||||
const Id coord = ctx.OpIAdd(ctx.U32[1], address, buffer.coord_offset);
|
||||
if (buffer.is_integer) {
|
||||
value = ctx.OpBitcast(ctx.U32[4], value);
|
||||
}
|
||||
ctx.OpImageWrite(tex_buffer, coord, value);
|
||||
}
|
||||
|
||||
} // namespace Shader::Backend::SPIRV
|
||||
|
|
|
@ -41,13 +41,14 @@ void Name(EmitContext& ctx, Id object, std::string_view format_str, Args&&... ar
|
|||
|
||||
} // Anonymous namespace
|
||||
|
||||
EmitContext::EmitContext(const Profile& profile_, IR::Program& program, u32& binding_)
|
||||
: Sirit::Module(profile_.supported_spirv), info{program.info}, profile{profile_},
|
||||
stage{program.info.stage}, binding{binding_} {
|
||||
EmitContext::EmitContext(const Profile& profile_, const Shader::Info& info_, u32& binding_)
|
||||
: Sirit::Module(profile_.supported_spirv), info{info_}, profile{profile_}, stage{info.stage},
|
||||
binding{binding_} {
|
||||
AddCapability(spv::Capability::Shader);
|
||||
DefineArithmeticTypes();
|
||||
DefineInterfaces();
|
||||
DefineBuffers();
|
||||
DefineTextureBuffers();
|
||||
DefineImagesAndSamplers();
|
||||
DefineSharedMemory();
|
||||
}
|
||||
|
@ -123,25 +124,24 @@ void EmitContext::DefineInterfaces() {
|
|||
DefineOutputs();
|
||||
}
|
||||
|
||||
Id GetAttributeType(EmitContext& ctx, AmdGpu::NumberFormat fmt) {
|
||||
const VectorIds& GetAttributeType(EmitContext& ctx, AmdGpu::NumberFormat fmt) {
|
||||
switch (fmt) {
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
return ctx.F32[4];
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
return ctx.S32[4];
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
return ctx.U32[4];
|
||||
case AmdGpu::NumberFormat::Sscaled:
|
||||
return ctx.F32[4];
|
||||
case AmdGpu::NumberFormat::Uscaled:
|
||||
return ctx.F32[4];
|
||||
case AmdGpu::NumberFormat::Srgb:
|
||||
return ctx.F32;
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
return ctx.S32;
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
return ctx.U32;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw InvalidArgument("Invalid attribute type {}", fmt);
|
||||
UNREACHABLE_MSG("Invalid attribute type {}", fmt);
|
||||
}
|
||||
|
||||
EmitContext::SpirvAttribute EmitContext::GetAttributeInfo(AmdGpu::NumberFormat fmt, Id id) {
|
||||
|
@ -162,7 +162,7 @@ EmitContext::SpirvAttribute EmitContext::GetAttributeInfo(AmdGpu::NumberFormat f
|
|||
default:
|
||||
break;
|
||||
}
|
||||
throw InvalidArgument("Invalid attribute type {}", fmt);
|
||||
UNREACHABLE_MSG("Invalid attribute type {}", fmt);
|
||||
}
|
||||
|
||||
void EmitContext::DefineBufferOffsets() {
|
||||
|
@ -177,6 +177,16 @@ void EmitContext::DefineBufferOffsets() {
|
|||
buffer.offset = OpBitFieldUExtract(U32[1], value, ConstU32(offset), ConstU32(8U));
|
||||
buffer.offset_dwords = OpShiftRightLogical(U32[1], buffer.offset, ConstU32(2U));
|
||||
}
|
||||
for (auto& tex_buffer : texture_buffers) {
|
||||
const u32 binding = tex_buffer.binding;
|
||||
const u32 half = Shader::PushData::BufOffsetIndex + (binding >> 4);
|
||||
const u32 comp = (binding & 0xf) >> 2;
|
||||
const u32 offset = (binding & 0x3) << 3;
|
||||
const Id ptr{OpAccessChain(TypePointer(spv::StorageClass::PushConstant, U32[1]),
|
||||
push_data_block, ConstU32(half), ConstU32(comp))};
|
||||
const Id value{OpLoad(U32[1], ptr)};
|
||||
tex_buffer.coord_offset = OpBitFieldUExtract(U32[1], value, ConstU32(offset), ConstU32(8U));
|
||||
}
|
||||
}
|
||||
|
||||
Id MakeDefaultValue(EmitContext& ctx, u32 default_value) {
|
||||
|
@ -195,6 +205,11 @@ Id MakeDefaultValue(EmitContext& ctx, u32 default_value) {
|
|||
}
|
||||
|
||||
void EmitContext::DefineInputs() {
|
||||
if (info.uses_lane_id) {
|
||||
subgroup_local_invocation_id = DefineVariable(
|
||||
U32[1], spv::BuiltIn::SubgroupLocalInvocationId, spv::StorageClass::Input);
|
||||
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
|
||||
}
|
||||
switch (stage) {
|
||||
case Stage::Vertex: {
|
||||
vertex_index = DefineVariable(U32[1], spv::BuiltIn::VertexIndex, spv::StorageClass::Input);
|
||||
|
@ -202,7 +217,7 @@ void EmitContext::DefineInputs() {
|
|||
instance_id = DefineVariable(U32[1], spv::BuiltIn::InstanceIndex, spv::StorageClass::Input);
|
||||
|
||||
for (const auto& input : info.vs_inputs) {
|
||||
const Id type{GetAttributeType(*this, input.fmt)};
|
||||
const Id type{GetAttributeType(*this, input.fmt)[4]};
|
||||
if (input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 ||
|
||||
input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate1) {
|
||||
|
||||
|
@ -229,15 +244,12 @@ void EmitContext::DefineInputs() {
|
|||
break;
|
||||
}
|
||||
case Stage::Fragment:
|
||||
subgroup_local_invocation_id = DefineVariable(
|
||||
U32[1], spv::BuiltIn::SubgroupLocalInvocationId, spv::StorageClass::Input);
|
||||
Decorate(subgroup_local_invocation_id, spv::Decoration::Flat);
|
||||
frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input);
|
||||
frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output);
|
||||
front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input);
|
||||
for (const auto& input : info.ps_inputs) {
|
||||
const u32 semantic = input.param_index;
|
||||
if (input.is_default) {
|
||||
if (input.is_default && !input.is_flat) {
|
||||
input_params[semantic] = {MakeDefaultValue(*this, input.default_value), F32[1],
|
||||
F32[1], 4, true};
|
||||
continue;
|
||||
|
@ -328,47 +340,75 @@ void EmitContext::DefinePushDataBlock() {
|
|||
|
||||
void EmitContext::DefineBuffers() {
|
||||
boost::container::small_vector<Id, 8> type_ids;
|
||||
for (u32 i = 0; const auto& buffer : info.buffers) {
|
||||
const auto* data_types = True(buffer.used_types & IR::Type::F32) ? &F32 : &U32;
|
||||
const Id data_type = (*data_types)[1];
|
||||
const Id record_array_type{buffer.is_storage
|
||||
? TypeRuntimeArray(data_type)
|
||||
: TypeArray(data_type, ConstU32(buffer.length))};
|
||||
const auto define_struct = [&](Id record_array_type, bool is_instance_data) {
|
||||
const Id struct_type{TypeStruct(record_array_type)};
|
||||
if (std::ranges::find(type_ids, record_array_type.value, &Id::value) == type_ids.end()) {
|
||||
if (std::ranges::find(type_ids, record_array_type.value, &Id::value) != type_ids.end()) {
|
||||
return struct_type;
|
||||
}
|
||||
Decorate(record_array_type, spv::Decoration::ArrayStride, 4);
|
||||
const auto name =
|
||||
buffer.is_instance_data
|
||||
? fmt::format("{}_instance_data{}_{}{}", stage, i, 'f',
|
||||
sizeof(float) * CHAR_BIT)
|
||||
: fmt::format("{}_cbuf_block_{}{}", stage, 'f', sizeof(float) * CHAR_BIT);
|
||||
const auto name = is_instance_data ? fmt::format("{}_instance_data_f32", stage)
|
||||
: fmt::format("{}_cbuf_block_f32", stage);
|
||||
Name(struct_type, name);
|
||||
Decorate(struct_type, spv::Decoration::Block);
|
||||
MemberName(struct_type, 0, "data");
|
||||
MemberDecorate(struct_type, 0, spv::Decoration::Offset, 0U);
|
||||
type_ids.push_back(record_array_type);
|
||||
}
|
||||
return struct_type;
|
||||
};
|
||||
|
||||
for (const auto& desc : info.buffers) {
|
||||
const auto sharp = desc.GetSharp(info);
|
||||
const bool is_storage = desc.IsStorage(sharp);
|
||||
const auto* data_types = True(desc.used_types & IR::Type::F32) ? &F32 : &U32;
|
||||
const Id data_type = (*data_types)[1];
|
||||
const Id record_array_type{is_storage ? TypeRuntimeArray(data_type)
|
||||
: TypeArray(data_type, ConstU32(sharp.NumDwords()))};
|
||||
const Id struct_type{define_struct(record_array_type, desc.is_instance_data)};
|
||||
|
||||
const auto storage_class =
|
||||
buffer.is_storage ? spv::StorageClass::StorageBuffer : spv::StorageClass::Uniform;
|
||||
is_storage ? spv::StorageClass::StorageBuffer : spv::StorageClass::Uniform;
|
||||
const Id struct_pointer_type{TypePointer(storage_class, struct_type)};
|
||||
const Id pointer_type = TypePointer(storage_class, data_type);
|
||||
const Id id{AddGlobalVariable(struct_pointer_type, storage_class)};
|
||||
Decorate(id, spv::Decoration::Binding, binding);
|
||||
Decorate(id, spv::Decoration::DescriptorSet, 0U);
|
||||
Name(id, fmt::format("{}_{}", buffer.is_storage ? "ssbo" : "cbuf", buffer.sgpr_base));
|
||||
if (is_storage && !desc.is_written) {
|
||||
Decorate(id, spv::Decoration::NonWritable);
|
||||
}
|
||||
Name(id, fmt::format("{}_{}", is_storage ? "ssbo" : "cbuf", desc.sgpr_base));
|
||||
|
||||
buffers.push_back({
|
||||
.id = id,
|
||||
.binding = binding++,
|
||||
.data_types = data_types,
|
||||
.pointer_type = pointer_type,
|
||||
.dfmt = buffer.dfmt,
|
||||
.nfmt = buffer.nfmt,
|
||||
.stride = buffer.GetVsharp(info).GetStride(),
|
||||
});
|
||||
interfaces.push_back(id);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void EmitContext::DefineTextureBuffers() {
|
||||
for (const auto& desc : info.texture_buffers) {
|
||||
const bool is_integer =
|
||||
desc.nfmt == AmdGpu::NumberFormat::Uint || desc.nfmt == AmdGpu::NumberFormat::Sint;
|
||||
const VectorIds& sampled_type{GetAttributeType(*this, desc.nfmt)};
|
||||
const u32 sampled = desc.is_written ? 2 : 1;
|
||||
const Id image_type{TypeImage(sampled_type[1], spv::Dim::Buffer, false, false, false,
|
||||
sampled, spv::ImageFormat::Unknown)};
|
||||
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
|
||||
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
|
||||
Decorate(id, spv::Decoration::Binding, binding);
|
||||
Decorate(id, spv::Decoration::DescriptorSet, 0U);
|
||||
Name(id, fmt::format("{}_{}", desc.is_written ? "imgbuf" : "texbuf", desc.sgpr_base));
|
||||
texture_buffers.push_back({
|
||||
.id = id,
|
||||
.binding = binding++,
|
||||
.image_type = image_type,
|
||||
.result_type = sampled_type[4],
|
||||
.is_integer = is_integer,
|
||||
.is_storage = desc.is_written,
|
||||
});
|
||||
interfaces.push_back(id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,7 +487,7 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
|
|||
|
||||
Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
|
||||
const auto image = ctx.info.ReadUd<AmdGpu::Image>(desc.sgpr_base, desc.dword_offset);
|
||||
const auto format = desc.is_storage ? GetFormat(image) : spv::ImageFormat::Unknown;
|
||||
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
|
||||
const u32 sampled = desc.is_storage ? 2 : 1;
|
||||
switch (desc.type) {
|
||||
case AmdGpu::ImageType::Color1D:
|
||||
|
@ -470,17 +510,8 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
|
|||
|
||||
void EmitContext::DefineImagesAndSamplers() {
|
||||
for (const auto& image_desc : info.images) {
|
||||
const VectorIds* data_types = [&] {
|
||||
switch (image_desc.nfmt) {
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
return &U32;
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
return &S32;
|
||||
default:
|
||||
return &F32;
|
||||
}
|
||||
}();
|
||||
const Id sampled_type = data_types->Get(1);
|
||||
const VectorIds& data_types = GetAttributeType(*this, image_desc.nfmt);
|
||||
const Id sampled_type = data_types[1];
|
||||
const Id image_type{ImageType(*this, image_desc, sampled_type)};
|
||||
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};
|
||||
const Id id{AddGlobalVariable(pointer_type, spv::StorageClass::UniformConstant)};
|
||||
|
@ -489,7 +520,7 @@ void EmitContext::DefineImagesAndSamplers() {
|
|||
Name(id, fmt::format("{}_{}{}_{:02x}", stage, "img", image_desc.sgpr_base,
|
||||
image_desc.dword_offset));
|
||||
images.push_back({
|
||||
.data_types = data_types,
|
||||
.data_types = &data_types,
|
||||
.id = id,
|
||||
.sampled_type = image_desc.is_storage ? sampled_type : TypeSampledImage(image_type),
|
||||
.pointer_type = pointer_type,
|
||||
|
@ -498,13 +529,12 @@ void EmitContext::DefineImagesAndSamplers() {
|
|||
interfaces.push_back(id);
|
||||
++binding;
|
||||
}
|
||||
|
||||
if (std::ranges::any_of(info.images, &ImageResource::is_atomic)) {
|
||||
image_u32 = TypePointer(spv::StorageClass::Image, U32[1]);
|
||||
|
||||
}
|
||||
if (info.samplers.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sampler_type = TypeSampler();
|
||||
sampler_pointer_type = TypePointer(spv::StorageClass::UniformConstant, sampler_type);
|
||||
for (const auto& samp_desc : info.samplers) {
|
||||
|
@ -520,14 +550,15 @@ void EmitContext::DefineImagesAndSamplers() {
|
|||
}
|
||||
|
||||
void EmitContext::DefineSharedMemory() {
|
||||
static constexpr size_t DefaultSharedMemSize = 16_KB;
|
||||
static constexpr size_t DefaultSharedMemSize = 2_KB;
|
||||
if (!info.uses_shared) {
|
||||
return;
|
||||
}
|
||||
if (info.shared_memory_size == 0) {
|
||||
info.shared_memory_size = DefaultSharedMemSize;
|
||||
u32 shared_memory_size = info.shared_memory_size;
|
||||
if (shared_memory_size == 0) {
|
||||
shared_memory_size = DefaultSharedMemSize;
|
||||
}
|
||||
const u32 num_elements{Common::DivCeil(info.shared_memory_size, 4U)};
|
||||
const u32 num_elements{Common::DivCeil(shared_memory_size, 4U)};
|
||||
const Id type{TypeArray(U32[1], ConstU32(num_elements))};
|
||||
shared_memory_u32_type = TypePointer(spv::StorageClass::Workgroup, type);
|
||||
shared_u32 = TypePointer(spv::StorageClass::Workgroup, U32[1]);
|
||||
|
|
|
@ -36,7 +36,7 @@ struct VectorIds {
|
|||
|
||||
class EmitContext final : public Sirit::Module {
|
||||
public:
|
||||
explicit EmitContext(const Profile& profile, IR::Program& program, u32& binding);
|
||||
explicit EmitContext(const Profile& profile, const Shader::Info& info, u32& binding);
|
||||
~EmitContext();
|
||||
|
||||
Id Def(const IR::Value& value);
|
||||
|
@ -124,7 +124,7 @@ public:
|
|||
return ConstantComposite(type, constituents);
|
||||
}
|
||||
|
||||
Info& info;
|
||||
const Info& info;
|
||||
const Profile& profile;
|
||||
Stage stage{};
|
||||
|
||||
|
@ -207,13 +207,20 @@ public:
|
|||
u32 binding;
|
||||
const VectorIds* data_types;
|
||||
Id pointer_type;
|
||||
AmdGpu::DataFormat dfmt;
|
||||
AmdGpu::NumberFormat nfmt;
|
||||
u32 stride;
|
||||
};
|
||||
struct TextureBufferDefinition {
|
||||
Id id;
|
||||
Id coord_offset;
|
||||
u32 binding;
|
||||
Id image_type;
|
||||
Id result_type;
|
||||
bool is_integer;
|
||||
bool is_storage;
|
||||
};
|
||||
|
||||
u32& binding;
|
||||
boost::container::small_vector<BufferDefinition, 16> buffers;
|
||||
boost::container::small_vector<TextureBufferDefinition, 8> texture_buffers;
|
||||
boost::container::small_vector<TextureDefinition, 8> images;
|
||||
boost::container::small_vector<Id, 4> samplers;
|
||||
|
||||
|
@ -238,6 +245,7 @@ private:
|
|||
void DefineOutputs();
|
||||
void DefinePushDataBlock();
|
||||
void DefineBuffers();
|
||||
void DefineTextureBuffers();
|
||||
void DefineImagesAndSamplers();
|
||||
void DefineSharedMemory();
|
||||
|
||||
|
|
|
@ -18,25 +18,31 @@ void Translator::EmitDataShare(const GcnInst& inst) {
|
|||
case Opcode::DS_READ2_B64:
|
||||
return DS_READ(64, false, true, inst);
|
||||
case Opcode::DS_WRITE_B32:
|
||||
return DS_WRITE(32, false, false, inst);
|
||||
return DS_WRITE(32, false, false, false, inst);
|
||||
case Opcode::DS_WRITE2ST64_B32:
|
||||
return DS_WRITE(32, false, true, true, inst);
|
||||
case Opcode::DS_WRITE_B64:
|
||||
return DS_WRITE(64, false, false, inst);
|
||||
return DS_WRITE(64, false, false, false, inst);
|
||||
case Opcode::DS_WRITE2_B32:
|
||||
return DS_WRITE(32, false, true, inst);
|
||||
return DS_WRITE(32, false, true, false, inst);
|
||||
case Opcode::DS_WRITE2_B64:
|
||||
return DS_WRITE(64, false, true, inst);
|
||||
return DS_WRITE(64, false, true, false, inst);
|
||||
case Opcode::DS_ADD_U32:
|
||||
return DS_ADD_U32(inst, false);
|
||||
case Opcode::DS_MIN_U32:
|
||||
return DS_MIN_U32(inst, false);
|
||||
return DS_MIN_U32(inst, false, false);
|
||||
case Opcode::DS_MIN_I32:
|
||||
return DS_MIN_U32(inst, true, false);
|
||||
case Opcode::DS_MAX_U32:
|
||||
return DS_MAX_U32(inst, false);
|
||||
return DS_MAX_U32(inst, false, false);
|
||||
case Opcode::DS_MAX_I32:
|
||||
return DS_MAX_U32(inst, true, false);
|
||||
case Opcode::DS_ADD_RTN_U32:
|
||||
return DS_ADD_U32(inst, true);
|
||||
case Opcode::DS_MIN_RTN_U32:
|
||||
return DS_MIN_U32(inst, true);
|
||||
return DS_MIN_U32(inst, false, true);
|
||||
case Opcode::DS_MAX_RTN_U32:
|
||||
return DS_MAX_U32(inst, true);
|
||||
return DS_MAX_U32(inst, false, true);
|
||||
default:
|
||||
LogMissingOpcode(inst);
|
||||
}
|
||||
|
@ -89,12 +95,13 @@ void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, const GcnIn
|
|||
}
|
||||
}
|
||||
|
||||
void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst) {
|
||||
void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool stride64,
|
||||
const GcnInst& inst) {
|
||||
const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))};
|
||||
const IR::VectorReg data0{inst.src[1].code};
|
||||
const IR::VectorReg data1{inst.src[2].code};
|
||||
if (is_pair) {
|
||||
const u32 adj = bit_size == 32 ? 4 : 8;
|
||||
const u32 adj = (bit_size == 32 ? 4 : 8) * (stride64 ? 64 : 1);
|
||||
const IR::U32 addr0 = ir.IAdd(addr, ir.Imm32(u32(inst.control.ds.offset0 * adj)));
|
||||
if (bit_size == 32) {
|
||||
ir.WriteShared(32, ir.GetVectorReg(data0), addr0);
|
||||
|
@ -133,23 +140,23 @@ void Translator::DS_ADD_U32(const GcnInst& inst, bool rtn) {
|
|||
}
|
||||
}
|
||||
|
||||
void Translator::DS_MIN_U32(const GcnInst& inst, bool rtn) {
|
||||
void Translator::DS_MIN_U32(const GcnInst& inst, bool is_signed, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
const IR::Value original_val = ir.SharedAtomicIMin(addr_offset, data, false);
|
||||
const IR::Value original_val = ir.SharedAtomicIMin(addr_offset, data, is_signed);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_MAX_U32(const GcnInst& inst, bool rtn) {
|
||||
void Translator::DS_MAX_U32(const GcnInst& inst, bool is_signed, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset = ir.Imm32(u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
const IR::Value original_val = ir.SharedAtomicIMax(addr_offset, data, false);
|
||||
const IR::Value original_val = ir.SharedAtomicIMax(addr_offset, data, is_signed);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "shader_recompiler/frontend/translate/translate.h"
|
||||
|
||||
namespace Shader::Gcn {
|
||||
|
||||
void Translator::EmitExport(const GcnInst& inst) {
|
||||
if (ir.block->has_multiple_predecessors && info.stage == Stage::Fragment) {
|
||||
LOG_WARNING(Render_Recompiler, "An ambiguous export appeared in translation");
|
||||
ir.Discard(ir.LogicalNot(ir.GetExec()));
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
|
|||
return S_OR_B64(NegateMode::Result, false, inst);
|
||||
case Opcode::S_XOR_B64:
|
||||
return S_OR_B64(NegateMode::None, true, inst);
|
||||
case Opcode::S_XNOR_B64:
|
||||
return S_OR_B64(NegateMode::Result, true, inst);
|
||||
case Opcode::S_ORN2_B64:
|
||||
return S_OR_B64(NegateMode::Src1, false, inst);
|
||||
case Opcode::S_AND_B64:
|
||||
|
|
|
@ -354,7 +354,7 @@ void Translator::EmitFetch(const GcnInst& inst) {
|
|||
if (!std::filesystem::exists(dump_dir)) {
|
||||
std::filesystem::create_directories(dump_dir);
|
||||
}
|
||||
const auto filename = fmt::format("vs_fetch_{:#018x}.bin", info.pgm_hash);
|
||||
const auto filename = fmt::format("vs_{:#018x}_fetch.bin", info.pgm_hash);
|
||||
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
|
||||
file.WriteRaw<u8>(code, fetch_size);
|
||||
}
|
||||
|
@ -399,9 +399,7 @@ void Translator::EmitFetch(const GcnInst& inst) {
|
|||
info.buffers.push_back({
|
||||
.sgpr_base = attrib.sgpr_base,
|
||||
.dword_offset = attrib.dword_offset,
|
||||
.length = buffer.num_records,
|
||||
.used_types = IR::Type::F32,
|
||||
.is_storage = true, // we may not fit into UBO with large meshes
|
||||
.is_instance_data = true,
|
||||
});
|
||||
instance_buf_handle = s32(info.buffers.size() - 1);
|
||||
|
@ -438,6 +436,7 @@ void Translator::EmitFlowControl(u32 pc, const GcnInst& inst) {
|
|||
case Opcode::S_CBRANCH_SCC1:
|
||||
case Opcode::S_CBRANCH_VCCNZ:
|
||||
case Opcode::S_CBRANCH_VCCZ:
|
||||
case Opcode::S_CBRANCH_EXECNZ:
|
||||
case Opcode::S_BRANCH:
|
||||
return;
|
||||
default:
|
||||
|
|
|
@ -191,8 +191,10 @@ public:
|
|||
void V_MBCNT_U32_B32(bool is_low, const GcnInst& inst);
|
||||
|
||||
// Vector Memory
|
||||
void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst);
|
||||
void BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_format, const GcnInst& inst);
|
||||
void BUFFER_LOAD(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
||||
void BUFFER_LOAD_FORMAT(u32 num_dwords, const GcnInst& inst);
|
||||
void BUFFER_STORE(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
||||
void BUFFER_STORE_FORMAT(u32 num_dwords, const GcnInst& inst);
|
||||
void BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst);
|
||||
|
||||
// Vector interpolation
|
||||
|
@ -202,10 +204,10 @@ public:
|
|||
// Data share
|
||||
void DS_SWIZZLE_B32(const GcnInst& inst);
|
||||
void DS_READ(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
||||
void DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
||||
void DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool stride64, const GcnInst& inst);
|
||||
void DS_ADD_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_MIN_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_MAX_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_MIN_U32(const GcnInst& inst, bool is_signed, bool rtn);
|
||||
void DS_MAX_U32(const GcnInst& inst, bool is_signed, bool rtn);
|
||||
void V_READFIRSTLANE_B32(const GcnInst& inst);
|
||||
void V_READLANE_B32(const GcnInst& inst);
|
||||
void V_WRITELANE_B32(const GcnInst& inst);
|
||||
|
|
|
@ -415,14 +415,20 @@ void Translator::V_ADDC_U32(const GcnInst& inst) {
|
|||
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
|
||||
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
|
||||
|
||||
IR::U32 scarry;
|
||||
IR::U1 carry;
|
||||
if (inst.src_count == 3) { // VOP3
|
||||
IR::U1 thread_bit{ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[2].code))};
|
||||
scarry = IR::U32{ir.Select(thread_bit, ir.Imm32(1), ir.Imm32(0))};
|
||||
if (inst.src[2].field == OperandField::VccLo) {
|
||||
carry = ir.GetVcc();
|
||||
} else if (inst.src[2].field == OperandField::ScalarGPR) {
|
||||
carry = ir.GetThreadBitScalarReg(IR::ScalarReg(inst.src[2].code));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
} else { // VOP2
|
||||
scarry = ir.GetVccLo();
|
||||
carry = ir.GetVcc();
|
||||
}
|
||||
|
||||
const IR::U32 scarry = IR::U32{ir.Select(carry, ir.Imm32(1), ir.Imm32(0))};
|
||||
const IR::U32 result = ir.IAdd(ir.IAdd(src0, src1), scarry);
|
||||
|
||||
const IR::VectorReg dst_reg{inst.dst[0].code};
|
||||
|
|
|
@ -56,57 +56,57 @@ void Translator::EmitVectorMemory(const GcnInst& inst) {
|
|||
|
||||
// Buffer load operations
|
||||
case Opcode::TBUFFER_LOAD_FORMAT_X:
|
||||
return BUFFER_LOAD_FORMAT(1, true, true, inst);
|
||||
return BUFFER_LOAD(1, true, inst);
|
||||
case Opcode::TBUFFER_LOAD_FORMAT_XY:
|
||||
return BUFFER_LOAD_FORMAT(2, true, true, inst);
|
||||
return BUFFER_LOAD(2, true, inst);
|
||||
case Opcode::TBUFFER_LOAD_FORMAT_XYZ:
|
||||
return BUFFER_LOAD_FORMAT(3, true, true, inst);
|
||||
return BUFFER_LOAD(3, true, inst);
|
||||
case Opcode::TBUFFER_LOAD_FORMAT_XYZW:
|
||||
return BUFFER_LOAD_FORMAT(4, true, true, inst);
|
||||
return BUFFER_LOAD(4, true, inst);
|
||||
|
||||
case Opcode::BUFFER_LOAD_FORMAT_X:
|
||||
return BUFFER_LOAD_FORMAT(1, false, true, inst);
|
||||
return BUFFER_LOAD_FORMAT(1, inst);
|
||||
case Opcode::BUFFER_LOAD_FORMAT_XY:
|
||||
return BUFFER_LOAD_FORMAT(2, false, true, inst);
|
||||
return BUFFER_LOAD_FORMAT(2, inst);
|
||||
case Opcode::BUFFER_LOAD_FORMAT_XYZ:
|
||||
return BUFFER_LOAD_FORMAT(3, false, true, inst);
|
||||
return BUFFER_LOAD_FORMAT(3, inst);
|
||||
case Opcode::BUFFER_LOAD_FORMAT_XYZW:
|
||||
return BUFFER_LOAD_FORMAT(4, false, true, inst);
|
||||
return BUFFER_LOAD_FORMAT(4, inst);
|
||||
|
||||
case Opcode::BUFFER_LOAD_DWORD:
|
||||
return BUFFER_LOAD_FORMAT(1, false, false, inst);
|
||||
return BUFFER_LOAD(1, false, inst);
|
||||
case Opcode::BUFFER_LOAD_DWORDX2:
|
||||
return BUFFER_LOAD_FORMAT(2, false, false, inst);
|
||||
return BUFFER_LOAD(2, false, inst);
|
||||
case Opcode::BUFFER_LOAD_DWORDX3:
|
||||
return BUFFER_LOAD_FORMAT(3, false, false, inst);
|
||||
return BUFFER_LOAD(3, false, inst);
|
||||
case Opcode::BUFFER_LOAD_DWORDX4:
|
||||
return BUFFER_LOAD_FORMAT(4, false, false, inst);
|
||||
return BUFFER_LOAD(4, false, inst);
|
||||
|
||||
// Buffer store operations
|
||||
case Opcode::BUFFER_STORE_FORMAT_X:
|
||||
return BUFFER_STORE_FORMAT(1, false, true, inst);
|
||||
return BUFFER_STORE_FORMAT(1, inst);
|
||||
case Opcode::BUFFER_STORE_FORMAT_XY:
|
||||
return BUFFER_STORE_FORMAT(2, false, true, inst);
|
||||
return BUFFER_STORE_FORMAT(2, inst);
|
||||
case Opcode::BUFFER_STORE_FORMAT_XYZ:
|
||||
return BUFFER_STORE_FORMAT(3, false, true, inst);
|
||||
return BUFFER_STORE_FORMAT(3, inst);
|
||||
case Opcode::BUFFER_STORE_FORMAT_XYZW:
|
||||
return BUFFER_STORE_FORMAT(4, false, true, inst);
|
||||
return BUFFER_STORE_FORMAT(4, inst);
|
||||
|
||||
case Opcode::TBUFFER_STORE_FORMAT_X:
|
||||
return BUFFER_STORE_FORMAT(1, true, true, inst);
|
||||
return BUFFER_STORE(1, true, inst);
|
||||
case Opcode::TBUFFER_STORE_FORMAT_XY:
|
||||
return BUFFER_STORE_FORMAT(2, true, true, inst);
|
||||
return BUFFER_STORE(2, true, inst);
|
||||
case Opcode::TBUFFER_STORE_FORMAT_XYZ:
|
||||
return BUFFER_STORE_FORMAT(3, true, true, inst);
|
||||
return BUFFER_STORE(3, true, inst);
|
||||
|
||||
case Opcode::BUFFER_STORE_DWORD:
|
||||
return BUFFER_STORE_FORMAT(1, false, false, inst);
|
||||
return BUFFER_STORE(1, false, inst);
|
||||
case Opcode::BUFFER_STORE_DWORDX2:
|
||||
return BUFFER_STORE_FORMAT(2, false, false, inst);
|
||||
return BUFFER_STORE(2, false, inst);
|
||||
case Opcode::BUFFER_STORE_DWORDX3:
|
||||
return BUFFER_STORE_FORMAT(3, false, false, inst);
|
||||
return BUFFER_STORE(3, false, inst);
|
||||
case Opcode::BUFFER_STORE_DWORDX4:
|
||||
return BUFFER_STORE_FORMAT(4, false, false, inst);
|
||||
return BUFFER_STORE(4, false, inst);
|
||||
|
||||
// Buffer atomic operations
|
||||
case Opcode::BUFFER_ATOMIC_ADD:
|
||||
|
@ -349,8 +349,7 @@ void Translator::IMAGE_STORE(const GcnInst& inst) {
|
|||
ir.ImageWrite(handle, body, value, {});
|
||||
}
|
||||
|
||||
void Translator::BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_format,
|
||||
const GcnInst& inst) {
|
||||
void Translator::BUFFER_LOAD(u32 num_dwords, bool is_typed, const GcnInst& inst) {
|
||||
const auto& mtbuf = inst.control.mtbuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
const IR::ScalarReg sharp{inst.src[2].code * 4};
|
||||
|
@ -370,22 +369,19 @@ void Translator::BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_forma
|
|||
info.index_enable.Assign(mtbuf.idxen);
|
||||
info.offset_enable.Assign(mtbuf.offen);
|
||||
info.inst_offset.Assign(mtbuf.offset);
|
||||
info.is_typed.Assign(is_typed);
|
||||
if (is_typed) {
|
||||
info.dmft.Assign(static_cast<AmdGpu::DataFormat>(mtbuf.dfmt));
|
||||
info.nfmt.Assign(static_cast<AmdGpu::NumberFormat>(mtbuf.nfmt));
|
||||
ASSERT(info.nfmt == AmdGpu::NumberFormat::Float &&
|
||||
(info.dmft == AmdGpu::DataFormat::Format32_32_32_32 ||
|
||||
info.dmft == AmdGpu::DataFormat::Format32_32_32 ||
|
||||
info.dmft == AmdGpu::DataFormat::Format32_32 ||
|
||||
info.dmft == AmdGpu::DataFormat::Format32));
|
||||
const auto dmft = static_cast<AmdGpu::DataFormat>(mtbuf.dfmt);
|
||||
const auto nfmt = static_cast<AmdGpu::NumberFormat>(mtbuf.nfmt);
|
||||
ASSERT(nfmt == AmdGpu::NumberFormat::Float &&
|
||||
(dmft == AmdGpu::DataFormat::Format32_32_32_32 ||
|
||||
dmft == AmdGpu::DataFormat::Format32_32_32 ||
|
||||
dmft == AmdGpu::DataFormat::Format32_32 || dmft == AmdGpu::DataFormat::Format32));
|
||||
}
|
||||
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1),
|
||||
ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3));
|
||||
const IR::Value value = is_format ? ir.LoadBufferFormat(num_dwords, handle, address, info)
|
||||
: ir.LoadBuffer(num_dwords, handle, address, info);
|
||||
const IR::Value value = ir.LoadBuffer(num_dwords, handle, address, info);
|
||||
const IR::VectorReg dst_reg{inst.src[1].code};
|
||||
if (num_dwords == 1) {
|
||||
ir.SetVectorReg(dst_reg, IR::F32{value});
|
||||
|
@ -396,8 +392,34 @@ void Translator::BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, bool is_forma
|
|||
}
|
||||
}
|
||||
|
||||
void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_format,
|
||||
const GcnInst& inst) {
|
||||
void Translator::BUFFER_LOAD_FORMAT(u32 num_dwords, const GcnInst& inst) {
|
||||
const auto& mubuf = inst.control.mubuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
const IR::ScalarReg sharp{inst.src[2].code * 4};
|
||||
ASSERT_MSG(!mubuf.offen && mubuf.offset == 0, "Offsets for image buffers are not supported");
|
||||
const IR::Value address = [&] -> IR::Value {
|
||||
if (mubuf.idxen) {
|
||||
return ir.GetVectorReg(vaddr);
|
||||
}
|
||||
return {};
|
||||
}();
|
||||
const IR::Value soffset{GetSrc(inst.src[3])};
|
||||
ASSERT_MSG(soffset.IsImmediate() && soffset.U32() == 0, "Non immediate offset not supported");
|
||||
|
||||
IR::BufferInstInfo info{};
|
||||
info.index_enable.Assign(mubuf.idxen);
|
||||
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1),
|
||||
ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3));
|
||||
const IR::Value value = ir.LoadBufferFormat(handle, address, info);
|
||||
const IR::VectorReg dst_reg{inst.src[1].code};
|
||||
for (u32 i = 0; i < num_dwords; i++) {
|
||||
ir.SetVectorReg(dst_reg + i, IR::F32{ir.CompositeExtract(value, i)});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::BUFFER_STORE(u32 num_dwords, bool is_typed, const GcnInst& inst) {
|
||||
const auto& mtbuf = inst.control.mtbuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
const IR::ScalarReg sharp{inst.src[2].code * 4};
|
||||
|
@ -417,45 +439,76 @@ void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, bool is_form
|
|||
info.index_enable.Assign(mtbuf.idxen);
|
||||
info.offset_enable.Assign(mtbuf.offen);
|
||||
info.inst_offset.Assign(mtbuf.offset);
|
||||
info.is_typed.Assign(is_typed);
|
||||
if (is_typed) {
|
||||
info.dmft.Assign(static_cast<AmdGpu::DataFormat>(mtbuf.dfmt));
|
||||
info.nfmt.Assign(static_cast<AmdGpu::NumberFormat>(mtbuf.nfmt));
|
||||
const auto dmft = static_cast<AmdGpu::DataFormat>(mtbuf.dfmt);
|
||||
const auto nfmt = static_cast<AmdGpu::NumberFormat>(mtbuf.nfmt);
|
||||
ASSERT(nfmt == AmdGpu::NumberFormat::Float &&
|
||||
(dmft == AmdGpu::DataFormat::Format32_32_32_32 ||
|
||||
dmft == AmdGpu::DataFormat::Format32_32_32 ||
|
||||
dmft == AmdGpu::DataFormat::Format32_32 || dmft == AmdGpu::DataFormat::Format32));
|
||||
}
|
||||
|
||||
IR::Value value{};
|
||||
const IR::VectorReg src_reg{inst.src[1].code};
|
||||
switch (num_dwords) {
|
||||
case 1:
|
||||
value = ir.GetVectorReg<Shader::IR::F32>(src_reg);
|
||||
value = ir.GetVectorReg<IR::F32>(src_reg);
|
||||
break;
|
||||
case 2:
|
||||
value = ir.CompositeConstruct(ir.GetVectorReg<Shader::IR::F32>(src_reg),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 1));
|
||||
value = ir.CompositeConstruct(ir.GetVectorReg<IR::F32>(src_reg),
|
||||
ir.GetVectorReg<IR::F32>(src_reg + 1));
|
||||
break;
|
||||
case 3:
|
||||
value = ir.CompositeConstruct(ir.GetVectorReg<Shader::IR::F32>(src_reg),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 1),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 2));
|
||||
value = ir.CompositeConstruct(ir.GetVectorReg<IR::F32>(src_reg),
|
||||
ir.GetVectorReg<IR::F32>(src_reg + 1),
|
||||
ir.GetVectorReg<IR::F32>(src_reg + 2));
|
||||
break;
|
||||
case 4:
|
||||
value = ir.CompositeConstruct(ir.GetVectorReg<Shader::IR::F32>(src_reg),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 1),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 2),
|
||||
ir.GetVectorReg<Shader::IR::F32>(src_reg + 3));
|
||||
value = ir.CompositeConstruct(
|
||||
ir.GetVectorReg<IR::F32>(src_reg), ir.GetVectorReg<IR::F32>(src_reg + 1),
|
||||
ir.GetVectorReg<IR::F32>(src_reg + 2), ir.GetVectorReg<IR::F32>(src_reg + 3));
|
||||
break;
|
||||
}
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1),
|
||||
ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3));
|
||||
if (is_format) {
|
||||
ir.StoreBufferFormat(num_dwords, handle, address, value, info);
|
||||
} else {
|
||||
ir.StoreBuffer(num_dwords, handle, address, value, info);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: U64
|
||||
void Translator::BUFFER_STORE_FORMAT(u32 num_dwords, const GcnInst& inst) {
|
||||
const auto& mubuf = inst.control.mubuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
const IR::ScalarReg sharp{inst.src[2].code * 4};
|
||||
ASSERT_MSG(!mubuf.offen && mubuf.offset == 0, "Offsets for image buffers are not supported");
|
||||
const IR::Value address = [&] -> IR::Value {
|
||||
if (mubuf.idxen) {
|
||||
return ir.GetVectorReg(vaddr);
|
||||
}
|
||||
return {};
|
||||
}();
|
||||
const IR::Value soffset{GetSrc(inst.src[3])};
|
||||
ASSERT_MSG(soffset.IsImmediate() && soffset.U32() == 0, "Non immediate offset not supported");
|
||||
|
||||
IR::BufferInstInfo info{};
|
||||
info.index_enable.Assign(mubuf.idxen);
|
||||
|
||||
const IR::VectorReg src_reg{inst.src[1].code};
|
||||
|
||||
std::array<IR::Value, 4> comps{};
|
||||
for (u32 i = 0; i < num_dwords; i++) {
|
||||
comps[i] = ir.GetVectorReg<IR::F32>(src_reg + i);
|
||||
}
|
||||
for (u32 i = num_dwords; i < 4; i++) {
|
||||
comps[i] = ir.Imm32(0.f);
|
||||
}
|
||||
|
||||
const IR::Value value = ir.CompositeConstruct(comps[0], comps[1], comps[2], comps[3]);
|
||||
const IR::Value handle =
|
||||
ir.CompositeConstruct(ir.GetScalarReg(sharp), ir.GetScalarReg(sharp + 1),
|
||||
ir.GetScalarReg(sharp + 2), ir.GetScalarReg(sharp + 3));
|
||||
ir.StoreBufferFormat(handle, address, value, info);
|
||||
}
|
||||
|
||||
void Translator::BUFFER_ATOMIC(AtomicOp op, const GcnInst& inst) {
|
||||
const auto& mubuf = inst.control.mubuf;
|
||||
const IR::VectorReg vaddr{inst.src[0].code};
|
||||
|
|
|
@ -325,20 +325,8 @@ Value IREmitter::LoadBuffer(int num_dwords, const Value& handle, const Value& ad
|
|||
}
|
||||
}
|
||||
|
||||
Value IREmitter::LoadBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
BufferInstInfo info) {
|
||||
switch (num_dwords) {
|
||||
case 1:
|
||||
Value IREmitter::LoadBufferFormat(const Value& handle, const Value& address, BufferInstInfo info) {
|
||||
return Inst(Opcode::LoadBufferFormatF32, Flags{info}, handle, address);
|
||||
case 2:
|
||||
return Inst(Opcode::LoadBufferFormatF32x2, Flags{info}, handle, address);
|
||||
case 3:
|
||||
return Inst(Opcode::LoadBufferFormatF32x3, Flags{info}, handle, address);
|
||||
case 4:
|
||||
return Inst(Opcode::LoadBufferFormatF32x4, Flags{info}, handle, address);
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords);
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::StoreBuffer(int num_dwords, const Value& handle, const Value& address,
|
||||
|
@ -409,24 +397,9 @@ Value IREmitter::BufferAtomicSwap(const Value& handle, const Value& address, con
|
|||
return Inst(Opcode::BufferAtomicSwap32, Flags{info}, handle, address, value);
|
||||
}
|
||||
|
||||
void IREmitter::StoreBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
const Value& data, BufferInstInfo info) {
|
||||
switch (num_dwords) {
|
||||
case 1:
|
||||
void IREmitter::StoreBufferFormat(const Value& handle, const Value& address, const Value& data,
|
||||
BufferInstInfo info) {
|
||||
Inst(Opcode::StoreBufferFormatF32, Flags{info}, handle, address, data);
|
||||
break;
|
||||
case 2:
|
||||
Inst(Opcode::StoreBufferFormatF32x2, Flags{info}, handle, address, data);
|
||||
break;
|
||||
case 3:
|
||||
Inst(Opcode::StoreBufferFormatF32x3, Flags{info}, handle, address, data);
|
||||
break;
|
||||
case 4:
|
||||
Inst(Opcode::StoreBufferFormatF32x4, Flags{info}, handle, address, data);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Invalid number of dwords {}", num_dwords);
|
||||
}
|
||||
}
|
||||
|
||||
U32 IREmitter::LaneId() {
|
||||
|
|
|
@ -92,12 +92,12 @@ public:
|
|||
|
||||
[[nodiscard]] Value LoadBuffer(int num_dwords, const Value& handle, const Value& address,
|
||||
BufferInstInfo info);
|
||||
[[nodiscard]] Value LoadBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
[[nodiscard]] Value LoadBufferFormat(const Value& handle, const Value& address,
|
||||
BufferInstInfo info);
|
||||
void StoreBuffer(int num_dwords, const Value& handle, const Value& address, const Value& data,
|
||||
BufferInstInfo info);
|
||||
void StoreBufferFormat(int num_dwords, const Value& handle, const Value& address,
|
||||
const Value& data, BufferInstInfo info);
|
||||
void StoreBufferFormat(const Value& handle, const Value& address, const Value& data,
|
||||
BufferInstInfo info);
|
||||
|
||||
[[nodiscard]] Value BufferAtomicIAdd(const Value& handle, const Value& address,
|
||||
const Value& value, BufferInstInfo info);
|
||||
|
|
|
@ -56,9 +56,6 @@ bool Inst::MayHaveSideEffects() const noexcept {
|
|||
case Opcode::StoreBufferF32x3:
|
||||
case Opcode::StoreBufferF32x4:
|
||||
case Opcode::StoreBufferFormatF32:
|
||||
case Opcode::StoreBufferFormatF32x2:
|
||||
case Opcode::StoreBufferFormatF32x3:
|
||||
case Opcode::StoreBufferFormatF32x4:
|
||||
case Opcode::StoreBufferU32:
|
||||
case Opcode::BufferAtomicIAdd32:
|
||||
case Opcode::BufferAtomicSMin32:
|
||||
|
|
|
@ -79,19 +79,13 @@ OPCODE(LoadBufferF32, F32, Opaq
|
|||
OPCODE(LoadBufferF32x2, F32x2, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferF32x3, F32x3, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferF32x4, F32x4, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferFormatF32, F32, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferFormatF32x2, F32x2, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferFormatF32x3, F32x3, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferFormatF32x4, F32x4, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferFormatF32, F32x4, Opaque, Opaque, )
|
||||
OPCODE(LoadBufferU32, U32, Opaque, Opaque, )
|
||||
OPCODE(StoreBufferF32, Void, Opaque, Opaque, F32, )
|
||||
OPCODE(StoreBufferF32x2, Void, Opaque, Opaque, F32x2, )
|
||||
OPCODE(StoreBufferF32x3, Void, Opaque, Opaque, F32x3, )
|
||||
OPCODE(StoreBufferF32x4, Void, Opaque, Opaque, F32x4, )
|
||||
OPCODE(StoreBufferFormatF32, Void, Opaque, Opaque, F32, )
|
||||
OPCODE(StoreBufferFormatF32x2, Void, Opaque, Opaque, F32x2, )
|
||||
OPCODE(StoreBufferFormatF32x3, Void, Opaque, Opaque, F32x3, )
|
||||
OPCODE(StoreBufferFormatF32x4, Void, Opaque, Opaque, F32x4, )
|
||||
OPCODE(StoreBufferFormatF32, Void, Opaque, Opaque, F32x4, )
|
||||
OPCODE(StoreBufferU32, Void, Opaque, Opaque, U32, )
|
||||
|
||||
// Buffer atomic operations
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include "common/alignment.h"
|
||||
#include "shader_recompiler/ir/basic_block.h"
|
||||
#include "shader_recompiler/ir/breadth_first_search.h"
|
||||
#include "shader_recompiler/ir/ir_emitter.h"
|
||||
|
@ -45,10 +46,6 @@ bool IsBufferStore(const IR::Inst& inst) {
|
|||
case IR::Opcode::StoreBufferF32x2:
|
||||
case IR::Opcode::StoreBufferF32x3:
|
||||
case IR::Opcode::StoreBufferF32x4:
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
case IR::Opcode::StoreBufferFormatF32x2:
|
||||
case IR::Opcode::StoreBufferFormatF32x3:
|
||||
case IR::Opcode::StoreBufferFormatF32x4:
|
||||
case IR::Opcode::StoreBufferU32:
|
||||
return true;
|
||||
default:
|
||||
|
@ -62,10 +59,6 @@ bool IsBufferInstruction(const IR::Inst& inst) {
|
|||
case IR::Opcode::LoadBufferF32x2:
|
||||
case IR::Opcode::LoadBufferF32x3:
|
||||
case IR::Opcode::LoadBufferF32x4:
|
||||
case IR::Opcode::LoadBufferFormatF32:
|
||||
case IR::Opcode::LoadBufferFormatF32x2:
|
||||
case IR::Opcode::LoadBufferFormatF32x3:
|
||||
case IR::Opcode::LoadBufferFormatF32x4:
|
||||
case IR::Opcode::LoadBufferU32:
|
||||
case IR::Opcode::ReadConstBuffer:
|
||||
case IR::Opcode::ReadConstBufferU32:
|
||||
|
@ -75,6 +68,11 @@ bool IsBufferInstruction(const IR::Inst& inst) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsTextureBufferInstruction(const IR::Inst& inst) {
|
||||
return inst.GetOpcode() == IR::Opcode::LoadBufferFormatF32 ||
|
||||
inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32;
|
||||
}
|
||||
|
||||
static bool UseFP16(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_format) {
|
||||
switch (num_format) {
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
|
@ -100,28 +98,6 @@ static bool UseFP16(AmdGpu::DataFormat data_format, AmdGpu::NumberFormat num_for
|
|||
|
||||
IR::Type BufferDataType(const IR::Inst& inst, AmdGpu::NumberFormat num_format) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::LoadBufferFormatF32:
|
||||
case IR::Opcode::LoadBufferFormatF32x2:
|
||||
case IR::Opcode::LoadBufferFormatF32x3:
|
||||
case IR::Opcode::LoadBufferFormatF32x4:
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
case IR::Opcode::StoreBufferFormatF32x2:
|
||||
case IR::Opcode::StoreBufferFormatF32x3:
|
||||
case IR::Opcode::StoreBufferFormatF32x4:
|
||||
switch (num_format) {
|
||||
case AmdGpu::NumberFormat::Unorm:
|
||||
case AmdGpu::NumberFormat::Snorm:
|
||||
case AmdGpu::NumberFormat::Uscaled:
|
||||
case AmdGpu::NumberFormat::Sscaled:
|
||||
case AmdGpu::NumberFormat::Uint:
|
||||
case AmdGpu::NumberFormat::Sint:
|
||||
case AmdGpu::NumberFormat::SnormNz:
|
||||
return IR::Type::U32;
|
||||
case AmdGpu::NumberFormat::Float:
|
||||
return IR::Type::F32;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
case IR::Opcode::LoadBufferF32:
|
||||
case IR::Opcode::LoadBufferF32x2:
|
||||
case IR::Opcode::LoadBufferF32x3:
|
||||
|
@ -143,20 +119,8 @@ IR::Type BufferDataType(const IR::Inst& inst, AmdGpu::NumberFormat num_format) {
|
|||
}
|
||||
}
|
||||
|
||||
bool IsImageInstruction(const IR::Inst& inst) {
|
||||
bool IsImageAtomicInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageSampleExplicitLod:
|
||||
case IR::Opcode::ImageSampleImplicitLod:
|
||||
case IR::Opcode::ImageSampleDrefExplicitLod:
|
||||
case IR::Opcode::ImageSampleDrefImplicitLod:
|
||||
case IR::Opcode::ImageFetch:
|
||||
case IR::Opcode::ImageGather:
|
||||
case IR::Opcode::ImageGatherDref:
|
||||
case IR::Opcode::ImageQueryDimensions:
|
||||
case IR::Opcode::ImageQueryLod:
|
||||
case IR::Opcode::ImageGradient:
|
||||
case IR::Opcode::ImageRead:
|
||||
case IR::Opcode::ImageWrite:
|
||||
case IR::Opcode::ImageAtomicIAdd32:
|
||||
case IR::Opcode::ImageAtomicSMin32:
|
||||
case IR::Opcode::ImageAtomicUMin32:
|
||||
|
@ -178,20 +142,27 @@ bool IsImageStorageInstruction(const IR::Inst& inst) {
|
|||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageWrite:
|
||||
case IR::Opcode::ImageRead:
|
||||
case IR::Opcode::ImageAtomicIAdd32:
|
||||
case IR::Opcode::ImageAtomicSMin32:
|
||||
case IR::Opcode::ImageAtomicUMin32:
|
||||
case IR::Opcode::ImageAtomicSMax32:
|
||||
case IR::Opcode::ImageAtomicUMax32:
|
||||
case IR::Opcode::ImageAtomicInc32:
|
||||
case IR::Opcode::ImageAtomicDec32:
|
||||
case IR::Opcode::ImageAtomicAnd32:
|
||||
case IR::Opcode::ImageAtomicOr32:
|
||||
case IR::Opcode::ImageAtomicXor32:
|
||||
case IR::Opcode::ImageAtomicExchange32:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return IsImageAtomicInstruction(inst);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsImageInstruction(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::ImageSampleExplicitLod:
|
||||
case IR::Opcode::ImageSampleImplicitLod:
|
||||
case IR::Opcode::ImageSampleDrefExplicitLod:
|
||||
case IR::Opcode::ImageSampleDrefImplicitLod:
|
||||
case IR::Opcode::ImageFetch:
|
||||
case IR::Opcode::ImageGather:
|
||||
case IR::Opcode::ImageGatherDref:
|
||||
case IR::Opcode::ImageQueryDimensions:
|
||||
case IR::Opcode::ImageQueryLod:
|
||||
case IR::Opcode::ImageGradient:
|
||||
return true;
|
||||
default:
|
||||
return IsImageStorageInstruction(inst);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +185,8 @@ u32 ImageOffsetArgumentPosition(const IR::Inst& inst) {
|
|||
class Descriptors {
|
||||
public:
|
||||
explicit Descriptors(Info& info_)
|
||||
: info{info_}, buffer_resources{info_.buffers}, image_resources{info_.images},
|
||||
: info{info_}, buffer_resources{info_.buffers},
|
||||
texture_buffer_resources{info_.texture_buffers}, image_resources{info_.images},
|
||||
sampler_resources{info_.samplers} {}
|
||||
|
||||
u32 Add(const BufferResource& desc) {
|
||||
|
@ -224,13 +196,21 @@ public:
|
|||
desc.inline_cbuf == existing.inline_cbuf;
|
||||
})};
|
||||
auto& buffer = buffer_resources[index];
|
||||
ASSERT(buffer.length == desc.length);
|
||||
buffer.is_storage |= desc.is_storage;
|
||||
buffer.used_types |= desc.used_types;
|
||||
buffer.is_written |= desc.is_written;
|
||||
return index;
|
||||
}
|
||||
|
||||
u32 Add(const TextureBufferResource& desc) {
|
||||
const u32 index{Add(texture_buffer_resources, desc, [&desc](const auto& existing) {
|
||||
return desc.sgpr_base == existing.sgpr_base &&
|
||||
desc.dword_offset == existing.dword_offset;
|
||||
})};
|
||||
auto& buffer = texture_buffer_resources[index];
|
||||
buffer.is_written |= desc.is_written;
|
||||
return index;
|
||||
}
|
||||
|
||||
u32 Add(const ImageResource& desc) {
|
||||
const u32 index{Add(image_resources, desc, [&desc](const auto& existing) {
|
||||
return desc.sgpr_base == existing.sgpr_base &&
|
||||
|
@ -247,7 +227,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
// Samplers with different bindings might still be the same.
|
||||
return existing.GetSsharp(info) == desc.GetSsharp(info);
|
||||
return existing.GetSharp(info) == desc.GetSharp(info);
|
||||
})};
|
||||
return index;
|
||||
}
|
||||
|
@ -265,6 +245,7 @@ private:
|
|||
|
||||
const Info& info;
|
||||
BufferResourceList& buffer_resources;
|
||||
TextureBufferResourceList& texture_buffer_resources;
|
||||
ImageResourceList& image_resources;
|
||||
SamplerResourceList& sampler_resources;
|
||||
};
|
||||
|
@ -361,33 +342,6 @@ SharpLocation TrackSharp(const IR::Inst* inst) {
|
|||
};
|
||||
}
|
||||
|
||||
static constexpr size_t MaxUboSize = 65536;
|
||||
|
||||
static bool IsLoadBufferFormat(const IR::Inst& inst) {
|
||||
switch (inst.GetOpcode()) {
|
||||
case IR::Opcode::LoadBufferFormatF32:
|
||||
case IR::Opcode::LoadBufferFormatF32x2:
|
||||
case IR::Opcode::LoadBufferFormatF32x3:
|
||||
case IR::Opcode::LoadBufferFormatF32x4:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 BufferLength(const AmdGpu::Buffer& buffer) {
|
||||
const auto stride = buffer.GetStride();
|
||||
if (stride < sizeof(f32)) {
|
||||
ASSERT(sizeof(f32) % stride == 0);
|
||||
return (((buffer.num_records - 1) / sizeof(f32)) + 1) * stride;
|
||||
} else if (stride == sizeof(f32)) {
|
||||
return buffer.num_records;
|
||||
} else {
|
||||
ASSERT(stride % sizeof(f32) == 0);
|
||||
return buffer.num_records * (stride / sizeof(f32));
|
||||
}
|
||||
}
|
||||
|
||||
s32 TryHandleInlineCbuf(IR::Inst& inst, Info& info, Descriptors& descriptors,
|
||||
AmdGpu::Buffer& cbuf) {
|
||||
|
||||
|
@ -414,10 +368,8 @@ s32 TryHandleInlineCbuf(IR::Inst& inst, Info& info, Descriptors& descriptors,
|
|||
return descriptors.Add(BufferResource{
|
||||
.sgpr_base = std::numeric_limits<u32>::max(),
|
||||
.dword_offset = 0,
|
||||
.length = BufferLength(cbuf),
|
||||
.used_types = BufferDataType(inst, cbuf.GetNumberFmt()),
|
||||
.inline_cbuf = cbuf,
|
||||
.is_storage = IsBufferStore(inst) || cbuf.GetSize() > MaxUboSize,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -429,28 +381,17 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
|||
IR::Inst* handle = inst.Arg(0).InstRecursive();
|
||||
IR::Inst* producer = handle->Arg(0).InstRecursive();
|
||||
const auto sharp = TrackSharp(producer);
|
||||
const bool is_store = IsBufferStore(inst);
|
||||
buffer = info.ReadUd<AmdGpu::Buffer>(sharp.sgpr_base, sharp.dword_offset);
|
||||
binding = descriptors.Add(BufferResource{
|
||||
.sgpr_base = sharp.sgpr_base,
|
||||
.dword_offset = sharp.dword_offset,
|
||||
.length = BufferLength(buffer),
|
||||
.used_types = BufferDataType(inst, buffer.GetNumberFmt()),
|
||||
.is_storage = is_store || buffer.GetSize() > MaxUboSize,
|
||||
.is_written = is_store,
|
||||
.is_written = IsBufferStore(inst),
|
||||
});
|
||||
}
|
||||
|
||||
// Update buffer descriptor format.
|
||||
const auto inst_info = inst.Flags<IR::BufferInstInfo>();
|
||||
auto& buffer_desc = info.buffers[binding];
|
||||
if (inst_info.is_typed) {
|
||||
buffer_desc.dfmt = inst_info.dmft;
|
||||
buffer_desc.nfmt = inst_info.nfmt;
|
||||
} else {
|
||||
buffer_desc.dfmt = buffer.GetDataFmt();
|
||||
buffer_desc.nfmt = buffer.GetNumberFmt();
|
||||
}
|
||||
|
||||
// Replace handle with binding index in buffer resource list.
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
|
@ -463,20 +404,7 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
|||
return;
|
||||
}
|
||||
|
||||
if (IsLoadBufferFormat(inst)) {
|
||||
if (UseFP16(buffer.GetDataFmt(), buffer.GetNumberFmt())) {
|
||||
info.uses_fp16 = true;
|
||||
}
|
||||
} else {
|
||||
const u32 stride = buffer.GetStride();
|
||||
if (stride < 4) {
|
||||
LOG_WARNING(Render_Vulkan,
|
||||
"non-formatting load_buffer_* is not implemented for stride {}", stride);
|
||||
}
|
||||
}
|
||||
|
||||
// Compute address of the buffer using the stride.
|
||||
// Todo: What if buffer is rebound with different stride?
|
||||
IR::U32 address = ir.Imm32(inst_info.inst_offset.Value());
|
||||
if (inst_info.index_enable) {
|
||||
const IR::U32 index = inst_info.offset_enable ? IR::U32{ir.CompositeExtract(inst.Arg(1), 0)}
|
||||
|
@ -491,8 +419,31 @@ void PatchBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
|||
inst.SetArg(1, address);
|
||||
}
|
||||
|
||||
void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
|
||||
Descriptors& descriptors) {
|
||||
const IR::Inst* handle = inst.Arg(0).InstRecursive();
|
||||
const IR::Inst* producer = handle->Arg(0).InstRecursive();
|
||||
const auto sharp = TrackSharp(producer);
|
||||
const auto buffer = info.ReadUd<AmdGpu::Buffer>(sharp.sgpr_base, sharp.dword_offset);
|
||||
const s32 binding = descriptors.Add(TextureBufferResource{
|
||||
.sgpr_base = sharp.sgpr_base,
|
||||
.dword_offset = sharp.dword_offset,
|
||||
.nfmt = buffer.GetNumberFmt(),
|
||||
.is_written = inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32,
|
||||
});
|
||||
|
||||
// Replace handle with binding index in texture buffer resource list.
|
||||
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};
|
||||
inst.SetArg(0, ir.Imm32(binding));
|
||||
ASSERT(!buffer.swizzle_enable && !buffer.add_tid_enable);
|
||||
}
|
||||
|
||||
IR::Value PatchCubeCoord(IR::IREmitter& ir, const IR::Value& s, const IR::Value& t,
|
||||
const IR::Value& z) {
|
||||
const IR::Value& z, bool is_storage) {
|
||||
// When cubemap is written with imageStore it is treated like 2DArray.
|
||||
if (is_storage) {
|
||||
return ir.CompositeConstruct(s, t, z);
|
||||
}
|
||||
// We need to fix x and y coordinate,
|
||||
// because the s and t coordinate will be scaled and plus 1.5 by v_madak_f32.
|
||||
// We already force the scale value to be 1.0 when handling v_cubema_f32,
|
||||
|
@ -530,13 +481,15 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
return;
|
||||
}
|
||||
ASSERT(image.GetType() != AmdGpu::ImageType::Invalid);
|
||||
const bool is_storage = IsImageStorageInstruction(inst);
|
||||
u32 image_binding = descriptors.Add(ImageResource{
|
||||
.sgpr_base = tsharp.sgpr_base,
|
||||
.dword_offset = tsharp.dword_offset,
|
||||
.type = image.GetType(),
|
||||
.nfmt = static_cast<AmdGpu::NumberFormat>(image.GetNumberFmt()),
|
||||
.is_storage = IsImageStorageInstruction(inst),
|
||||
.is_storage = is_storage,
|
||||
.is_depth = bool(inst_info.is_depth),
|
||||
.is_atomic = IsImageAtomicInstruction(inst),
|
||||
});
|
||||
|
||||
// Read sampler sharp. This doesn't exist for IMAGE_LOAD/IMAGE_STORE instructions
|
||||
|
@ -593,7 +546,8 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
|
|||
case AmdGpu::ImageType::Color3D: // x, y, z
|
||||
return {ir.CompositeConstruct(body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)};
|
||||
case AmdGpu::ImageType::Cube: // x, y, face
|
||||
return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2)), body->Arg(3)};
|
||||
return {PatchCubeCoord(ir, body->Arg(0), body->Arg(1), body->Arg(2), is_storage),
|
||||
body->Arg(3)};
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown image type {}", image.GetType());
|
||||
}
|
||||
|
@ -668,6 +622,10 @@ void ResourceTrackingPass(IR::Program& program) {
|
|||
PatchBufferInstruction(*block, inst, info, descriptors);
|
||||
continue;
|
||||
}
|
||||
if (IsTextureBufferInstruction(inst)) {
|
||||
PatchTextureBufferInstruction(*block, inst, info, descriptors);
|
||||
continue;
|
||||
}
|
||||
if (IsImageInstruction(inst)) {
|
||||
PatchImageInstruction(*block, inst, info, descriptors);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ void Visit(Info& info, IR::Inst& inst) {
|
|||
case IR::Opcode::ImageWrite:
|
||||
info.has_storage_images = true;
|
||||
break;
|
||||
case IR::Opcode::LoadBufferFormatF32:
|
||||
info.has_texel_buffers = true;
|
||||
break;
|
||||
case IR::Opcode::StoreBufferFormatF32:
|
||||
info.has_image_buffers = true;
|
||||
break;
|
||||
case IR::Opcode::QuadShuffle:
|
||||
info.uses_group_quad = true;
|
||||
break;
|
||||
|
@ -44,6 +50,9 @@ void Visit(Info& info, IR::Inst& inst) {
|
|||
case IR::Opcode::ImageQueryLod:
|
||||
info.has_image_query = true;
|
||||
break;
|
||||
case IR::Opcode::LaneId:
|
||||
info.uses_lane_id = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -12,11 +12,13 @@
|
|||
namespace Shader::IR {
|
||||
|
||||
struct Program {
|
||||
explicit Program(Info& info_) : info{info_} {}
|
||||
|
||||
AbstractSyntaxList syntax_list;
|
||||
BlockList blocks;
|
||||
BlockList post_order_blocks;
|
||||
std::vector<Gcn::GcnInst> ins_list;
|
||||
Info info;
|
||||
Info& info;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::string DumpProgram(const Program& program);
|
||||
|
|
|
@ -66,9 +66,6 @@ union BufferInstInfo {
|
|||
BitField<0, 1, u32> index_enable;
|
||||
BitField<1, 1, u32> offset_enable;
|
||||
BitField<2, 12, u32> inst_offset;
|
||||
BitField<14, 4, AmdGpu::DataFormat> dmft;
|
||||
BitField<18, 3, AmdGpu::NumberFormat> nfmt;
|
||||
BitField<21, 1, u32> is_typed;
|
||||
};
|
||||
|
||||
enum class ScalarReg : u32 {
|
||||
|
|
|
@ -29,7 +29,7 @@ IR::BlockList GenerateBlocks(const IR::AbstractSyntaxList& syntax_list) {
|
|||
|
||||
IR::Program TranslateProgram(Common::ObjectPool<IR::Inst>& inst_pool,
|
||||
Common::ObjectPool<IR::Block>& block_pool, std::span<const u32> token,
|
||||
const Info&& info, const Profile& profile) {
|
||||
Info& info, const Profile& profile) {
|
||||
// Ensure first instruction is expected.
|
||||
constexpr u32 token_mov_vcchi = 0xBEEB03FF;
|
||||
ASSERT_MSG(token[0] == token_mov_vcchi, "First instruction is not s_mov_b32 vcc_hi, #imm");
|
||||
|
@ -38,7 +38,7 @@ IR::Program TranslateProgram(Common::ObjectPool<IR::Inst>& inst_pool,
|
|||
Gcn::GcnDecodeContext decoder;
|
||||
|
||||
// Decode and save instructions
|
||||
IR::Program program;
|
||||
IR::Program program{info};
|
||||
program.ins_list.reserve(token.size());
|
||||
while (!slice.atEnd()) {
|
||||
program.ins_list.emplace_back(decoder.decodeInstruction(slice));
|
||||
|
@ -49,7 +49,6 @@ IR::Program TranslateProgram(Common::ObjectPool<IR::Inst>& inst_pool,
|
|||
Gcn::CFG cfg{gcn_block_pool, program.ins_list};
|
||||
|
||||
// Structurize control flow graph and create program.
|
||||
program.info = std::move(info);
|
||||
program.syntax_list = Shader::Gcn::BuildASL(inst_pool, block_pool, cfg, program.info, profile);
|
||||
program.blocks = GenerateBlocks(program.syntax_list);
|
||||
program.post_order_blocks = Shader::IR::PostOrder(program.syntax_list.front());
|
||||
|
|
|
@ -13,7 +13,7 @@ struct Profile;
|
|||
|
||||
[[nodiscard]] IR::Program TranslateProgram(Common::ObjectPool<IR::Inst>& inst_pool,
|
||||
Common::ObjectPool<IR::Block>& block_pool,
|
||||
std::span<const u32> code, const Info&& info,
|
||||
std::span<const u32> code, Info& info,
|
||||
const Profile& profile);
|
||||
|
||||
} // namespace Shader
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <span>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
#include "common/assert.h"
|
||||
#include "common/types.h"
|
||||
|
@ -74,18 +75,29 @@ struct Info;
|
|||
struct BufferResource {
|
||||
u32 sgpr_base;
|
||||
u32 dword_offset;
|
||||
u32 length;
|
||||
IR::Type used_types;
|
||||
AmdGpu::Buffer inline_cbuf;
|
||||
AmdGpu::DataFormat dfmt;
|
||||
AmdGpu::NumberFormat nfmt;
|
||||
bool is_storage{};
|
||||
bool is_instance_data{};
|
||||
bool is_written{};
|
||||
|
||||
constexpr AmdGpu::Buffer GetVsharp(const Info& info) const noexcept;
|
||||
bool IsStorage(AmdGpu::Buffer buffer) const noexcept {
|
||||
static constexpr size_t MaxUboSize = 65536;
|
||||
return buffer.GetSize() > MaxUboSize || is_written;
|
||||
}
|
||||
|
||||
constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;
|
||||
};
|
||||
using BufferResourceList = boost::container::static_vector<BufferResource, 16>;
|
||||
using BufferResourceList = boost::container::small_vector<BufferResource, 16>;
|
||||
|
||||
struct TextureBufferResource {
|
||||
u32 sgpr_base;
|
||||
u32 dword_offset;
|
||||
AmdGpu::NumberFormat nfmt;
|
||||
bool is_written{};
|
||||
|
||||
constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;
|
||||
};
|
||||
using TextureBufferResourceList = boost::container::small_vector<TextureBufferResource, 16>;
|
||||
|
||||
struct ImageResource {
|
||||
u32 sgpr_base;
|
||||
|
@ -94,8 +106,11 @@ struct ImageResource {
|
|||
AmdGpu::NumberFormat nfmt;
|
||||
bool is_storage;
|
||||
bool is_depth;
|
||||
bool is_atomic{};
|
||||
|
||||
constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;
|
||||
};
|
||||
using ImageResourceList = boost::container::static_vector<ImageResource, 16>;
|
||||
using ImageResourceList = boost::container::small_vector<ImageResource, 16>;
|
||||
|
||||
struct SamplerResource {
|
||||
u32 sgpr_base;
|
||||
|
@ -104,9 +119,9 @@ struct SamplerResource {
|
|||
u32 associated_image : 4;
|
||||
u32 disable_aniso : 1;
|
||||
|
||||
constexpr AmdGpu::Sampler GetSsharp(const Info& info) const noexcept;
|
||||
constexpr AmdGpu::Sampler GetSharp(const Info& info) const noexcept;
|
||||
};
|
||||
using SamplerResourceList = boost::container::static_vector<SamplerResource, 16>;
|
||||
using SamplerResourceList = boost::container::small_vector<SamplerResource, 16>;
|
||||
|
||||
struct PushData {
|
||||
static constexpr size_t BufOffsetIndex = 2;
|
||||
|
@ -179,6 +194,7 @@ struct Info {
|
|||
s8 instance_offset_sgpr = -1;
|
||||
|
||||
BufferResourceList buffers;
|
||||
TextureBufferResourceList texture_buffers;
|
||||
ImageResourceList images;
|
||||
SamplerResourceList samplers;
|
||||
|
||||
|
@ -194,9 +210,12 @@ struct Info {
|
|||
u64 pgm_hash{};
|
||||
u32 shared_memory_size{};
|
||||
bool has_storage_images{};
|
||||
bool has_image_buffers{};
|
||||
bool has_texel_buffers{};
|
||||
bool has_discard{};
|
||||
bool has_image_gather{};
|
||||
bool has_image_query{};
|
||||
bool uses_lane_id{};
|
||||
bool uses_group_quad{};
|
||||
bool uses_shared{};
|
||||
bool uses_fp16{};
|
||||
|
@ -214,6 +233,10 @@ struct Info {
|
|||
return data;
|
||||
}
|
||||
|
||||
size_t NumBindings() const noexcept {
|
||||
return buffers.size() + texture_buffers.size() + images.size() + samplers.size();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::pair<u32, u32> GetDrawOffsets() const noexcept {
|
||||
u32 vertex_offset = 0;
|
||||
u32 instance_offset = 0;
|
||||
|
@ -227,11 +250,19 @@ struct Info {
|
|||
}
|
||||
};
|
||||
|
||||
constexpr AmdGpu::Buffer BufferResource::GetVsharp(const Info& info) const noexcept {
|
||||
constexpr AmdGpu::Buffer BufferResource::GetSharp(const Info& info) const noexcept {
|
||||
return inline_cbuf ? inline_cbuf : info.ReadUd<AmdGpu::Buffer>(sgpr_base, dword_offset);
|
||||
}
|
||||
|
||||
constexpr AmdGpu::Sampler SamplerResource::GetSsharp(const Info& info) const noexcept {
|
||||
constexpr AmdGpu::Buffer TextureBufferResource::GetSharp(const Info& info) const noexcept {
|
||||
return info.ReadUd<AmdGpu::Buffer>(sgpr_base, dword_offset);
|
||||
}
|
||||
|
||||
constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept {
|
||||
return info.ReadUd<AmdGpu::Image>(sgpr_base, dword_offset);
|
||||
}
|
||||
|
||||
constexpr AmdGpu::Sampler SamplerResource::GetSharp(const Info& info) const noexcept {
|
||||
return inline_sampler ? inline_sampler : info.ReadUd<AmdGpu::Sampler>(sgpr_base, dword_offset);
|
||||
}
|
||||
|
||||
|
|
|
@ -368,6 +368,36 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||
}
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DrawIndirect: {
|
||||
const auto* draw_indirect = reinterpret_cast<const PM4CmdDrawIndirect*>(header);
|
||||
const auto offset = draw_indirect->data_offset;
|
||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||
const auto size = sizeof(PM4CmdDrawIndirect::DrawInstancedArgs);
|
||||
if (rasterizer) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
rasterizer->ScopeMarkerBegin(fmt::format("dcb:{}:DrawIndirect", cmd_address));
|
||||
rasterizer->Breadcrumb(u64(cmd_address));
|
||||
rasterizer->DrawIndirect(false, ib_address, offset, size);
|
||||
rasterizer->ScopeMarkerEnd();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DrawIndexIndirect: {
|
||||
const auto* draw_index_indirect =
|
||||
reinterpret_cast<const PM4CmdDrawIndexIndirect*>(header);
|
||||
const auto offset = draw_index_indirect->data_offset;
|
||||
const auto ib_address = mapped_queues[GfxQueueId].indirect_args_addr;
|
||||
const auto size = sizeof(PM4CmdDrawIndexIndirect::DrawIndexInstancedArgs);
|
||||
if (rasterizer) {
|
||||
const auto cmd_address = reinterpret_cast<const void*>(header);
|
||||
rasterizer->ScopeMarkerBegin(
|
||||
fmt::format("dcb:{}:DrawIndexIndirect", cmd_address));
|
||||
rasterizer->Breadcrumb(u64(cmd_address));
|
||||
rasterizer->DrawIndirect(true, ib_address, offset, size);
|
||||
rasterizer->ScopeMarkerEnd();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PM4ItOpcode::DispatchDirect: {
|
||||
const auto* dispatch_direct = reinterpret_cast<const PM4CmdDispatchDirect*>(header);
|
||||
regs.cs_program.dim_x = dispatch_direct->dim_x;
|
||||
|
@ -488,6 +518,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
|
|||
break;
|
||||
}
|
||||
case PM4ItOpcode::PfpSyncMe: {
|
||||
rasterizer->CpSync();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -167,7 +167,7 @@ struct Liverpool {
|
|||
static constexpr auto* GetBinaryInfo(const Shader& sh) {
|
||||
const auto* code = sh.template Address<u32*>();
|
||||
const auto* bininfo = std::bit_cast<const BinaryInfo*>(code + (code[1] + 1) * 2);
|
||||
ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header");
|
||||
// ASSERT_MSG(bininfo->Valid(), "Invalid shader binary header");
|
||||
return bininfo;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,6 +61,10 @@ enum class NumberFormat : u32 {
|
|||
Ubscaled = 13,
|
||||
};
|
||||
|
||||
[[nodiscard]] constexpr bool IsInteger(NumberFormat nfmt) {
|
||||
return nfmt == AmdGpu::NumberFormat::Sint || nfmt == AmdGpu::NumberFormat::Uint;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string_view NameOf(DataFormat fmt);
|
||||
[[nodiscard]] std::string_view NameOf(NumberFormat fmt);
|
||||
|
||||
|
|
|
@ -253,20 +253,6 @@ struct PM4CmdDrawIndexAuto {
|
|||
u32 draw_initiator;
|
||||
};
|
||||
|
||||
struct PM4CmdDrawIndirect {
|
||||
PM4Type3Header header; ///< header
|
||||
u32 data_offset; ///< DWORD aligned offset
|
||||
union {
|
||||
u32 dw2;
|
||||
BitField<0, 16, u32> base_vtx_loc; ///< base vertex location
|
||||
};
|
||||
union {
|
||||
u32 dw3;
|
||||
BitField<0, 16, u32> start_inst_loc; ///< start instance location
|
||||
};
|
||||
u32 draw_initiator; ///< Draw Initiator Register
|
||||
};
|
||||
|
||||
enum class DataSelect : u32 {
|
||||
None = 0,
|
||||
Data32Low = 1,
|
||||
|
@ -740,4 +726,51 @@ struct PM4CmdDispatchIndirect {
|
|||
u32 dispatch_initiator; ///< Dispatch Initiator Register
|
||||
};
|
||||
|
||||
struct PM4CmdDrawIndirect {
|
||||
struct DrawInstancedArgs {
|
||||
u32 vertex_count_per_instance;
|
||||
u32 instance_count;
|
||||
u32 start_vertex_location;
|
||||
u32 start_instance_location;
|
||||
};
|
||||
|
||||
PM4Type3Header header; ///< header
|
||||
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
||||
union {
|
||||
u32 dw2;
|
||||
BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the
|
||||
///< BaseVertexLocation it fetched from memory
|
||||
};
|
||||
union {
|
||||
u32 dw3;
|
||||
BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the
|
||||
///< StartInstanceLocation it fetched from memory
|
||||
};
|
||||
u32 draw_initiator; ///< Draw Initiator Register
|
||||
};
|
||||
|
||||
struct PM4CmdDrawIndexIndirect {
|
||||
struct DrawIndexInstancedArgs {
|
||||
u32 index_count_per_instance;
|
||||
u32 instance_count;
|
||||
u32 start_index_location;
|
||||
u32 base_vertex_location;
|
||||
u32 start_instance_location;
|
||||
};
|
||||
|
||||
PM4Type3Header header; ///< header
|
||||
u32 data_offset; ///< Byte aligned offset where the required data structure starts
|
||||
union {
|
||||
u32 dw2;
|
||||
BitField<0, 16, u32> base_vtx_loc; ///< Offset where the CP will write the
|
||||
///< BaseVertexLocation it fetched from memory
|
||||
};
|
||||
union { // NOTE: this one is undocumented in AMD spec, but Gnm driver writes this field
|
||||
u32 dw3;
|
||||
BitField<0, 16, u32> start_inst_loc; ///< Offset where the CP will write the
|
||||
///< StartInstanceLocation it fetched from memory
|
||||
};
|
||||
u32 draw_initiator; ///< Draw Initiator Register
|
||||
};
|
||||
|
||||
} // namespace AmdGpu
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue