Yeah
This commit is contained in:
5
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
5
external/parallel-rdp/ParallelRDPWrapper.cpp
vendored
@@ -11,7 +11,6 @@ using namespace Vulkan;
|
|||||||
using namespace RDP;
|
using namespace RDP;
|
||||||
|
|
||||||
static CommandProcessor* command_processor;
|
static CommandProcessor* command_processor;
|
||||||
static WSI* wsi;
|
|
||||||
static std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
static std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
||||||
|
|
||||||
VkQueue GetGraphicsQueue() {
|
VkQueue GetGraphicsQueue() {
|
||||||
@@ -125,13 +124,13 @@ private:
|
|||||||
|
|
||||||
Program* fullscreen_quad_program;
|
Program* fullscreen_quad_program;
|
||||||
|
|
||||||
WSI* LoadWSIPlatform(Vulkan::WSIPlatform* wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo) {
|
WSI* LoadWSIPlatform(Vulkan::InstanceFactory* instanceFactory, Vulkan::WSIPlatform* wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo) {
|
||||||
wsi = new WSI();
|
wsi = new WSI();
|
||||||
wsi->set_backbuffer_srgb(false);
|
wsi->set_backbuffer_srgb(false);
|
||||||
wsi->set_platform(wsi_platform);
|
wsi->set_platform(wsi_platform);
|
||||||
wsi->set_present_mode(PresentMode::SyncToVBlank);
|
wsi->set_present_mode(PresentMode::SyncToVBlank);
|
||||||
Context::SystemHandles handles;
|
Context::SystemHandles handles;
|
||||||
if (!wsi->init_simple(1, handles)) {
|
if (!wsi->init_simple(instanceFactory, 1, handles)) {
|
||||||
Util::panic("Failed to initialize WSI!");
|
Util::panic("Failed to initialize WSI!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
4
external/parallel-rdp/ParallelRDPWrapper.hpp
vendored
4
external/parallel-rdp/ParallelRDPWrapper.hpp
vendored
@@ -23,6 +23,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Vulkan::WSI* wsi;
|
||||||
|
|
||||||
VkRenderPass GetVkRenderPass();
|
VkRenderPass GetVkRenderPass();
|
||||||
VkQueue GetGraphicsQueue();
|
VkQueue GetGraphicsQueue();
|
||||||
VkInstance GetVkInstance();
|
VkInstance GetVkInstance();
|
||||||
@@ -33,7 +35,7 @@ VkFormat GetVkFormat();
|
|||||||
VkCommandBuffer GetVkCommandBuffer();
|
VkCommandBuffer GetVkCommandBuffer();
|
||||||
void SubmitRequestedVkCommandBuffer();
|
void SubmitRequestedVkCommandBuffer();
|
||||||
void LoadParallelRDP(const u8* rdram);
|
void LoadParallelRDP(const u8* rdram);
|
||||||
Vulkan::WSI* LoadWSIPlatform(Vulkan::WSIPlatform* wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo);
|
Vulkan::WSI* LoadWSIPlatform(Vulkan::InstanceFactory*, Vulkan::WSIPlatform* wsi_platform, std::unique_ptr<ParallelRdpWindowInfo>&& newWindowInfo);
|
||||||
void UpdateScreenParallelRdp(n64::Core& core, n64::VI& vi);
|
void UpdateScreenParallelRdp(n64::Core& core, n64::VI& vi);
|
||||||
void ParallelRdpEnqueueCommand(int command_length, u32* buffer);
|
void ParallelRdpEnqueueCommand(int command_length, u32* buffer);
|
||||||
void ParallelRdpOnFullSync();
|
void ParallelRdpOnFullSync();
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <SDL2/SDL_events.h>
|
#include <SDL2/SDL_events.h>
|
||||||
#include <backend/core/Interpreter.hpp>
|
#include <backend/core/Interpreter.hpp>
|
||||||
#include <backend/core/JIT.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <SDL2/SDL_timer.h>
|
#include <SDL2/SDL_timer.h>
|
||||||
|
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
#include <Cop0.hpp>
|
|
||||||
#include <JIT.hpp>
|
|
||||||
|
|
||||||
namespace n64 {
|
|
||||||
using namespace Xbyak;
|
|
||||||
JIT::JIT() : CodeGenerator(32*1024*1024, AutoGrow) { }
|
|
||||||
|
|
||||||
void JIT::Reset() {
|
|
||||||
reset();
|
|
||||||
regs.Reset();
|
|
||||||
mem.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool JIT::ShouldServiceInterrupt() {
|
|
||||||
bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0;
|
|
||||||
bool interrupts_enabled = regs.cop0.status.ie == 1;
|
|
||||||
bool currently_handling_exception = regs.cop0.status.exl == 1;
|
|
||||||
bool currently_handling_error = regs.cop0.status.erl == 1;
|
|
||||||
|
|
||||||
return interrupts_pending && interrupts_enabled &&
|
|
||||||
!currently_handling_exception && !currently_handling_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::CheckCompareInterrupt() {
|
|
||||||
regs.cop0.count++;
|
|
||||||
regs.cop0.count &= 0x1FFFFFFFF;
|
|
||||||
if(regs.cop0.count == (u64)regs.cop0.compare << 1) {
|
|
||||||
regs.cop0.cause.ip7 = 1;
|
|
||||||
UpdateInterrupt(mem.mmio.mi, regs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Fn JIT::Recompile() {
|
|
||||||
bool stable = true;
|
|
||||||
cycles = 0;
|
|
||||||
prologue();
|
|
||||||
mov(rbp, u64(this));
|
|
||||||
mov(rdi, u64(this) + THIS_OFFSET(regs));
|
|
||||||
while(stable) {
|
|
||||||
cycles++;
|
|
||||||
CheckCompareInterrupt();
|
|
||||||
|
|
||||||
mov(rax, REG(byte, delaySlot));
|
|
||||||
mov(REG(byte, prevDelaySlot), rax);
|
|
||||||
mov(REG(byte, delaySlot), 0);
|
|
||||||
|
|
||||||
u32 paddr = 0;
|
|
||||||
if (!MapVAddr(regs, LOAD, regs.pc, paddr)) {
|
|
||||||
mov(rsi, regs.pc);
|
|
||||||
emitCall(HandleTLBException);
|
|
||||||
mov(rsi, u64(GetTLBExceptionCode(regs.cop0.tlbError, LOAD)));
|
|
||||||
CodeGenerator::xor_(rdx, rdx);
|
|
||||||
CodeGenerator::xor_(rcx, rcx);
|
|
||||||
emitCall(FireException);
|
|
||||||
goto _epilogue;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 instr = mem.Read<u32>(regs, paddr);
|
|
||||||
stable = isStable(instr);
|
|
||||||
Emit(instr);
|
|
||||||
|
|
||||||
if (ShouldServiceInterrupt()) {
|
|
||||||
mov(rsi, u64(ExceptionCode::Interrupt));
|
|
||||||
CodeGenerator::xor_(rdx, rdx);
|
|
||||||
CodeGenerator::xor_(rcx, rcx);
|
|
||||||
push(rax);
|
|
||||||
call(FireException);
|
|
||||||
goto _epilogue;
|
|
||||||
}
|
|
||||||
|
|
||||||
mov(rax, REG(qword, pc));
|
|
||||||
mov(REG(qword, oldPC), rax);
|
|
||||||
mov(rax, REG(qword, nextPC));
|
|
||||||
mov(REG(qword, pc), rax);
|
|
||||||
CodeGenerator::add(REG(qword, nextPC), 4);
|
|
||||||
}
|
|
||||||
_epilogue:
|
|
||||||
epilogue();
|
|
||||||
ready();
|
|
||||||
return getCode<Fn>();
|
|
||||||
}
|
|
||||||
|
|
||||||
int JIT::Step() {
|
|
||||||
if(!blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)]) {
|
|
||||||
blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)] = (Fn*)calloc(BLOCKCACHE_INNER_SIZE, 1);
|
|
||||||
blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)][BLOCKCACHE_INNER_INDEX(regs.pc)] = Recompile();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)][BLOCKCACHE_INNER_INDEX(regs.pc)]) {
|
|
||||||
blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)][BLOCKCACHE_INNER_INDEX(regs.pc)] = Recompile();
|
|
||||||
}
|
|
||||||
|
|
||||||
return blocks[BLOCKCACHE_OUTER_INDEX(regs.pc)][BLOCKCACHE_INNER_INDEX(regs.pc)]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <Mem.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <BaseCPU.hpp>
|
|
||||||
#include <xbyak.h>
|
|
||||||
#include "CpuDefinitions.hpp"
|
|
||||||
|
|
||||||
namespace n64 {
|
|
||||||
using Fn = int(*)();
|
|
||||||
#define THIS_OFFSET(x) ((uintptr_t)(&x) - (uintptr_t)this)
|
|
||||||
#define GPR_OFFSET(x) ((uintptr_t)®s.gpr[(x)] - (uintptr_t)this)
|
|
||||||
#define REG_OFFSET(member) ((uintptr_t)®s.member - (uintptr_t)this)
|
|
||||||
#define GPR(ptr, x) ptr[rdi + GPR_OFFSET(x)]
|
|
||||||
#define REG(ptr, member) ptr[rdi + REG_OFFSET(member)]
|
|
||||||
// 4KiB aligned pages
|
|
||||||
#define BLOCKCACHE_OUTER_SHIFT 12
|
|
||||||
#define BLOCKCACHE_PAGE_SIZE (1 << BLOCKCACHE_OUTER_SHIFT)
|
|
||||||
#define BLOCKCACHE_OUTER_SIZE (0x80000000 >> BLOCKCACHE_OUTER_SHIFT)
|
|
||||||
// word aligned instructions
|
|
||||||
#define BLOCKCACHE_INNER_SIZE (BLOCKCACHE_PAGE_SIZE >> 2)
|
|
||||||
#define BLOCKCACHE_INNER_INDEX(physical) (((physical) & (BLOCKCACHE_PAGE_SIZE - 1)) >> 2)
|
|
||||||
#define BLOCKCACHE_OUTER_INDEX(physical) ((physical) >> BLOCKCACHE_OUTER_SHIFT)
|
|
||||||
|
|
||||||
struct JIT : BaseCPU, Xbyak::CodeGenerator {
|
|
||||||
JIT();
|
|
||||||
~JIT() override = default;
|
|
||||||
int Step() override;
|
|
||||||
void Reset() override;
|
|
||||||
friend struct Cop1;
|
|
||||||
friend struct Cop0;
|
|
||||||
private:
|
|
||||||
int cycles = 0;
|
|
||||||
bool ShouldServiceInterrupt() override;
|
|
||||||
void CheckCompareInterrupt() override;
|
|
||||||
Fn Recompile();
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void emitMemberCall(T func, void* thisObj) {
|
|
||||||
T* funcPtr;
|
|
||||||
auto thisPtr = reinterpret_cast<uintptr_t>(thisObj);
|
|
||||||
#ifdef ABI_WINDOWS
|
|
||||||
static_assert(sizeof(T) == 8, "[JIT]: Invalid size for member function pointer");
|
|
||||||
std::memcpy(&funcPtr, &func, sizeof(T));
|
|
||||||
#elif defined(ABI_UNIX)
|
|
||||||
static_assert(sizeof(T) == 16, "[JIT]: Invalid size for member function pointer");
|
|
||||||
uintptr_t tmpArr[2];
|
|
||||||
std::memcpy(tmpArr, &func, sizeof(T));
|
|
||||||
funcPtr = reinterpret_cast<void*>(tmpArr[0]);
|
|
||||||
thisPtr += tmpArr[1];
|
|
||||||
#else
|
|
||||||
Util::panic("Huh?!");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
push(rdi);
|
|
||||||
if(thisPtr == reinterpret_cast<uintptr_t>(this)) {
|
|
||||||
mov(rdi, rbp);
|
|
||||||
} else {
|
|
||||||
mov(rdi, (uintptr_t)thisPtr);
|
|
||||||
}
|
|
||||||
call(funcPtr);
|
|
||||||
pop(rdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
void emitCall(T func) {
|
|
||||||
T* funcPtr;
|
|
||||||
#ifdef ABI_WINDOWS
|
|
||||||
std::memcpy(&funcPtr, &func, sizeof(T));
|
|
||||||
#elif defined(ABI_UNIX)
|
|
||||||
uintptr_t tmpArr[2];
|
|
||||||
std::memcpy(tmpArr, &func, sizeof(T));
|
|
||||||
funcPtr = reinterpret_cast<void*>(tmpArr[0]);
|
|
||||||
#else
|
|
||||||
Util::panic("Huh?!");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
push(rdi);
|
|
||||||
call(funcPtr);
|
|
||||||
pop(rdi);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isStable(u32 instr) {
|
|
||||||
u8 mask = (instr >> 26) & 0x3f;
|
|
||||||
switch(mask) {
|
|
||||||
case SPECIAL:
|
|
||||||
mask = instr & 0x3f;
|
|
||||||
switch(mask) {
|
|
||||||
case JR ... JALR:
|
|
||||||
case SYSCALL: case BREAK:
|
|
||||||
case TGE ... TNE:
|
|
||||||
return false;
|
|
||||||
default: return true;
|
|
||||||
}
|
|
||||||
case REGIMM:
|
|
||||||
case J ... BGTZ:
|
|
||||||
case BEQL ... BGTZL:
|
|
||||||
return false;
|
|
||||||
case COP1:
|
|
||||||
mask = (instr >> 16) & 0x1f;
|
|
||||||
if(mask >= 0 && mask <= 3) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
default: return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void prologue() {
|
|
||||||
const Xbyak::Reg64 allRegs[]{rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15};
|
|
||||||
for(auto r : allRegs) {
|
|
||||||
push(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_INLINE void epilogue() {
|
|
||||||
const Xbyak::Reg64 allRegs[]{r15, r14, r13, r12, r11, r10, r9, r8, rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax};
|
|
||||||
for(auto r : allRegs) {
|
|
||||||
pop(r);
|
|
||||||
}
|
|
||||||
mov(rax, cycles);
|
|
||||||
ret();
|
|
||||||
}
|
|
||||||
|
|
||||||
Fn* blocks[BLOCKCACHE_OUTER_SIZE]{};
|
|
||||||
|
|
||||||
std::vector<u8> Serialize() override { return {}; }
|
|
||||||
void Deserialize(const std::vector<u8>&) override { }
|
|
||||||
|
|
||||||
void cop2Decode(u32);
|
|
||||||
void special(u32);
|
|
||||||
void regimm(u32);
|
|
||||||
void Emit(u32);
|
|
||||||
void add(u32);
|
|
||||||
void addu(u32);
|
|
||||||
void addi(u32);
|
|
||||||
void addiu(u32);
|
|
||||||
void andi(u32);
|
|
||||||
void and_(u32);
|
|
||||||
void bltz(u32);
|
|
||||||
void bgez(u32);
|
|
||||||
void bltzl(u32);
|
|
||||||
void bgezl(u32);
|
|
||||||
void bltzal(u32);
|
|
||||||
void bgezal(u32);
|
|
||||||
void bltzall(u32);
|
|
||||||
void bgezall(u32);
|
|
||||||
void beq(u32);
|
|
||||||
void bne(u32);
|
|
||||||
void blez(u32);
|
|
||||||
void bgtz(u32);
|
|
||||||
void beql(u32);
|
|
||||||
void bnel(u32);
|
|
||||||
void blezl(u32);
|
|
||||||
void bgtzl(u32);
|
|
||||||
void dadd(u32);
|
|
||||||
void daddu(u32);
|
|
||||||
void daddi(u32);
|
|
||||||
void daddiu(u32);
|
|
||||||
void ddiv(u32);
|
|
||||||
void ddivu(u32);
|
|
||||||
void div(u32);
|
|
||||||
void divu(u32);
|
|
||||||
void dmult(u32);
|
|
||||||
void dmultu(u32);
|
|
||||||
void dsll(u32);
|
|
||||||
void dsllv(u32);
|
|
||||||
void dsll32(u32);
|
|
||||||
void dsra(u32);
|
|
||||||
void dsrav(u32);
|
|
||||||
void dsra32(u32);
|
|
||||||
void dsrl(u32);
|
|
||||||
void dsrlv(u32);
|
|
||||||
void dsrl32(u32);
|
|
||||||
void dsub(u32);
|
|
||||||
void dsubu(u32);
|
|
||||||
void j(u32);
|
|
||||||
void jr(u32);
|
|
||||||
void jal(u32);
|
|
||||||
void jalr(u32);
|
|
||||||
void lui(u32);
|
|
||||||
void lbu(u32);
|
|
||||||
void lb(u32);
|
|
||||||
void ld(u32);
|
|
||||||
void ldl(u32);
|
|
||||||
void ldr(u32);
|
|
||||||
void lh(u32);
|
|
||||||
void lhu(u32);
|
|
||||||
void ll(u32);
|
|
||||||
void lld(u32);
|
|
||||||
void lw(u32);
|
|
||||||
void lwl(u32);
|
|
||||||
void lwu(u32);
|
|
||||||
void lwr(u32);
|
|
||||||
void mfhi(u32);
|
|
||||||
void mflo(u32);
|
|
||||||
void mult(u32);
|
|
||||||
void multu(u32);
|
|
||||||
void mthi(u32);
|
|
||||||
void mtlo(u32);
|
|
||||||
void nor(u32);
|
|
||||||
void sb(u32);
|
|
||||||
void sc(u32);
|
|
||||||
void scd(u32);
|
|
||||||
void sd(u32);
|
|
||||||
void sdl(u32);
|
|
||||||
void sdr(u32);
|
|
||||||
void sh(u32);
|
|
||||||
void sw(u32);
|
|
||||||
void swl(u32);
|
|
||||||
void swr(u32);
|
|
||||||
void slti(u32);
|
|
||||||
void sltiu(u32);
|
|
||||||
void slt(u32);
|
|
||||||
void sltu(u32);
|
|
||||||
void sll(u32);
|
|
||||||
void sllv(u32);
|
|
||||||
void sub(u32);
|
|
||||||
void subu(u32);
|
|
||||||
void sra(u32);
|
|
||||||
void srav(u32);
|
|
||||||
void srl(u32);
|
|
||||||
void srlv(u32);
|
|
||||||
void tgei(u32);
|
|
||||||
void tgeiu(u32);
|
|
||||||
void tlti(u32);
|
|
||||||
void tltiu(u32);
|
|
||||||
void teqi(u32);
|
|
||||||
void tnei(u32);
|
|
||||||
void tge(u32);
|
|
||||||
void tgeu(u32);
|
|
||||||
void tlt(u32);
|
|
||||||
void tltu(u32);
|
|
||||||
void teq(u32);
|
|
||||||
void tne(u32);
|
|
||||||
void or_(u32);
|
|
||||||
void ori(u32);
|
|
||||||
void xor_(u32);
|
|
||||||
void xori(u32);
|
|
||||||
|
|
||||||
void mtc2(u32);
|
|
||||||
void mfc2(u32);
|
|
||||||
void dmtc2(u32);
|
|
||||||
void dmfc2(u32);
|
|
||||||
void ctc2(u32);
|
|
||||||
void cfc2(u32);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
file(GLOB_RECURSE SOURCES *.cpp)
|
|
||||||
file(GLOB_RECURSE HEADERS *.hpp)
|
|
||||||
|
|
||||||
add_library(jit ${SOURCES} ${HEADERS})
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
#include <core/JIT.hpp>
|
|
||||||
#include <log.hpp>
|
|
||||||
|
|
||||||
namespace n64 {
|
|
||||||
void JIT::special(u32 instr) {
|
|
||||||
u8 mask = (instr & 0x3F);
|
|
||||||
// 00rr_rccc
|
|
||||||
switch (mask) { // TODO: named constants for clearer code
|
|
||||||
case SLL:
|
|
||||||
if (instr != 0) {
|
|
||||||
sll(instr);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SRL: srl(instr); break;
|
|
||||||
case SRA: sra(instr); break;
|
|
||||||
case SLLV: sllv(instr); break;
|
|
||||||
case SRLV: srlv(instr); break;
|
|
||||||
case SRAV: srav(instr); break;
|
|
||||||
case JR: jr(instr); break;
|
|
||||||
case JALR: jalr(instr); break;
|
|
||||||
case SYSCALL: FireException(regs, ExceptionCode::Syscall, 0, regs.oldPC); break;
|
|
||||||
case BREAK: FireException(regs, ExceptionCode::Breakpoint, 0, regs.oldPC); break;
|
|
||||||
case SYNC: break; // SYNC
|
|
||||||
case MFHI: mfhi(instr); break;
|
|
||||||
case MTHI: mthi(instr); break;
|
|
||||||
case MFLO: mflo(instr); break;
|
|
||||||
case MTLO: mtlo(instr); break;
|
|
||||||
case DSLLV: dsllv(instr); break;
|
|
||||||
case DSRLV: dsrlv(instr); break;
|
|
||||||
case DSRAV: dsrav(instr); break;
|
|
||||||
case MULT: mult(instr); break;
|
|
||||||
case MULTU: multu(instr); break;
|
|
||||||
case DIV: div(instr); break;
|
|
||||||
case DIVU: divu(instr); break;
|
|
||||||
case DMULT: dmult(instr); break;
|
|
||||||
case DMULTU: dmultu(instr); break;
|
|
||||||
case DDIV: ddiv(instr); break;
|
|
||||||
case DDIVU: ddivu(instr); break;
|
|
||||||
case ADD: add(instr); break;
|
|
||||||
case ADDU: addu(instr); break;
|
|
||||||
case SUB: sub(instr); break;
|
|
||||||
case SUBU: subu(instr); break;
|
|
||||||
case AND: and_(instr); break;
|
|
||||||
case OR: or_(instr); break;
|
|
||||||
case XOR: xor_(instr); break;
|
|
||||||
case NOR: nor(instr); break;
|
|
||||||
case SLT: slt(instr); break;
|
|
||||||
case SLTU: sltu(instr); break;
|
|
||||||
case DADD: dadd(instr); break;
|
|
||||||
case DADDU: daddu(instr); break;
|
|
||||||
case DSUB: dsub(instr); break;
|
|
||||||
case DSUBU: dsubu(instr); break;
|
|
||||||
case TGE: tge(instr); break;
|
|
||||||
case TGEU: tgeu(instr); break;
|
|
||||||
case TLT: tlt(instr); break;
|
|
||||||
case TLTU: tltu(instr); break;
|
|
||||||
case TEQ: teq(instr); break;
|
|
||||||
case TNE: tne(instr); break;
|
|
||||||
case DSLL: dsll(instr); break;
|
|
||||||
case DSRL: dsrl(instr); break;
|
|
||||||
case DSRA: dsra(instr); break;
|
|
||||||
case DSLL32: dsll32(instr); break;
|
|
||||||
case DSRL32: dsrl32(instr); break;
|
|
||||||
case DSRA32: dsra32(instr); break;
|
|
||||||
default:
|
|
||||||
Util::panic("Unimplemented special {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 7, mask & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::regimm(u32 instr) {
|
|
||||||
u8 mask = ((instr >> 16) & 0x1F);
|
|
||||||
// 000r_rccc
|
|
||||||
switch (mask) { // TODO: named constants for clearer code
|
|
||||||
case BLTZ: bltz(instr); break;
|
|
||||||
case BGEZ: bgez(instr); break;
|
|
||||||
case BLTZL: bltzl(instr); break;
|
|
||||||
case BGEZL: bgezl(instr); break;
|
|
||||||
case TGEI: tgei(instr); break;
|
|
||||||
case TGEIU: tgeiu(instr); break;
|
|
||||||
case TLTI: tlti(instr); break;
|
|
||||||
case TLTIU: tltiu(instr); break;
|
|
||||||
case TEQI: teqi(instr); break;
|
|
||||||
case TNEI: tnei(instr); break;
|
|
||||||
case BLTZAL: bltzal(instr); break;
|
|
||||||
case BGEZAL: bgezal(instr); break;
|
|
||||||
case BLTZALL: bltzall(instr); break;
|
|
||||||
case BGEZALL: bgezall(instr); break;
|
|
||||||
default:
|
|
||||||
Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::cop2Decode(u32 instr) {
|
|
||||||
if(!regs.cop0.status.cu2) {
|
|
||||||
FireException(regs, ExceptionCode::CoprocessorUnusable, 2, regs.oldPC);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
switch(RS(instr)) {
|
|
||||||
case 0x00: mfc2(instr); break;
|
|
||||||
case 0x01: dmfc2(instr); break;
|
|
||||||
case 0x02: cfc2(instr); break;
|
|
||||||
case 0x04: mtc2(instr); break;
|
|
||||||
case 0x05: dmtc2(instr); break;
|
|
||||||
case 0x06: ctc2(instr); break;
|
|
||||||
default:
|
|
||||||
FireException(regs, ExceptionCode::ReservedInstruction, 2, regs.oldPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void JIT::Emit(u32 instr) {
|
|
||||||
u8 mask = (instr >> 26) & 0x3f;
|
|
||||||
// 00rr_rccc
|
|
||||||
switch(mask) { // TODO: named constants for clearer code
|
|
||||||
case SPECIAL: special(instr); break;
|
|
||||||
case REGIMM: regimm(instr); break;
|
|
||||||
case J: j(instr); break;
|
|
||||||
case JAL: jal(instr); break;
|
|
||||||
case BEQ: beq(instr); break;
|
|
||||||
case BNE: bne(instr); break;
|
|
||||||
case BLEZ: blez(instr); break;
|
|
||||||
case BGTZ: bgtz(instr); break;
|
|
||||||
case ADDI: addi(instr); break;
|
|
||||||
case ADDIU: addiu(instr); break;
|
|
||||||
case SLTI: slti(instr); break;
|
|
||||||
case SLTIU: sltiu(instr); break;
|
|
||||||
case ANDI: andi(instr); break;
|
|
||||||
case ORI: ori(instr); break;
|
|
||||||
case XORI: xori(instr); break;
|
|
||||||
case LUI: lui(instr); break;
|
|
||||||
case COP0: regs.cop0.decode(*this, instr); break;
|
|
||||||
case COP1: regs.cop1.decode(*this, instr); break;
|
|
||||||
case COP2: cop2Decode(instr); break;
|
|
||||||
case BEQL: beql(instr); break;
|
|
||||||
case BNEL: bnel(instr); break;
|
|
||||||
case BLEZL: blezl(instr); break;
|
|
||||||
case BGTZL: bgtzl(instr); break;
|
|
||||||
case DADDI: daddi(instr); break;
|
|
||||||
case DADDIU: daddiu(instr); break;
|
|
||||||
case LDL: ldl(instr); break;
|
|
||||||
case LDR: ldr(instr); break;
|
|
||||||
case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); break;
|
|
||||||
case LB: lb(instr); break;
|
|
||||||
case LH: lh(instr); break;
|
|
||||||
case LWL: lwl(instr); break;
|
|
||||||
case LW: lw(instr); break;
|
|
||||||
case LBU: lbu(instr); break;
|
|
||||||
case LHU: lhu(instr); break;
|
|
||||||
case LWR: lwr(instr); break;
|
|
||||||
case LWU: lwu(instr); break;
|
|
||||||
case SB: sb(instr); break;
|
|
||||||
case SH: sh(instr); break;
|
|
||||||
case SWL: swl(instr); break;
|
|
||||||
case SW: sw(instr); break;
|
|
||||||
case SDL: sdl(instr); break;
|
|
||||||
case SDR: sdr(instr); break;
|
|
||||||
case SWR: swr(instr); break;
|
|
||||||
case CACHE: break; // CACHE
|
|
||||||
case LL: ll(instr); break;
|
|
||||||
case LWC1: regs.cop1.lwc1(*this, mem, instr); break;
|
|
||||||
case LLD: lld(instr); break;
|
|
||||||
case LDC1: regs.cop1.ldc1(*this, mem, instr); break;
|
|
||||||
case LD: ld(instr); break;
|
|
||||||
case SC: sc(instr); break;
|
|
||||||
case SWC1: regs.cop1.swc1(*this, mem, instr); break;
|
|
||||||
case SCD: scd(instr); break;
|
|
||||||
case SDC1: regs.cop1.sdc1(*this, mem, instr); break;
|
|
||||||
case SD: sd(instr); break;
|
|
||||||
default:
|
|
||||||
Util::panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", mask, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,7 @@ void Flash::CommandExecute() {
|
|||||||
case FlashState::Erase:
|
case FlashState::Erase:
|
||||||
if(saveData.is_mapped()) {
|
if(saveData.is_mapped()) {
|
||||||
for (int i = 0; i < 128; i++) {
|
for (int i = 0; i < 128; i++) {
|
||||||
saveData[eraseOffs + i] = 0xFFi8;
|
saveData[eraseOffs + i] = 0xFF;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Util::panic("Accessing flash when not mapped!");
|
Util::panic("Accessing flash when not mapped!");
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <GameDB.hpp>
|
#include <GameDB.hpp>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <mio/mmap.hpp>
|
#include <mio/mmap.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
#include <core/registers/Cop1.hpp>
|
#include <core/registers/Cop1.hpp>
|
||||||
#include <core/registers/Registers.hpp>
|
#include <core/registers/Registers.hpp>
|
||||||
#include <core/Interpreter.hpp>
|
#include <core/Interpreter.hpp>
|
||||||
#include <core/JIT.hpp>
|
|
||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
using namespace Xbyak;
|
|
||||||
Cop1::Cop1() {
|
Cop1::Cop1() {
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
@@ -20,8 +18,6 @@ template <class T>
|
|||||||
void Cop1::decode(T& cpu, u32 instr) {
|
void Cop1::decode(T& cpu, u32 instr) {
|
||||||
if constexpr (std::is_same_v<decltype(cpu), Interpreter&>) {
|
if constexpr (std::is_same_v<decltype(cpu), Interpreter&>) {
|
||||||
decodeInterp(cpu, instr);
|
decodeInterp(cpu, instr);
|
||||||
} else if constexpr (std::is_same_v<decltype(cpu), JIT&>) {
|
|
||||||
decodeJIT(cpu, instr);
|
|
||||||
} else {
|
} else {
|
||||||
Util::panic("What the fuck did you just give me?!");
|
Util::panic("What the fuck did you just give me?!");
|
||||||
}
|
}
|
||||||
@@ -152,157 +148,4 @@ void Cop1::decodeInterp(Interpreter &cpu, u32 instr) {
|
|||||||
default: Util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7);
|
default: Util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef REG
|
|
||||||
#undef REG
|
|
||||||
#define REG(ptr, member) cpu.ptr[cpu.rdi + offsetof(Registers, member)]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Cop1::decodeJIT(JIT &cpu, u32 instr) {
|
|
||||||
Registers ®s = cpu.regs;
|
|
||||||
if(!regs.cop0.status.cu1) {
|
|
||||||
FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 mask_sub = (instr >> 21) & 0x1F;
|
|
||||||
u8 mask_fun = instr & 0x3F;
|
|
||||||
u8 mask_branch = (instr >> 16) & 0x1F;
|
|
||||||
switch(mask_sub) {
|
|
||||||
// 000r_rccc
|
|
||||||
case 0x00: mfc1(regs, instr); break;
|
|
||||||
case 0x01: dmfc1(regs, instr); break;
|
|
||||||
case 0x02: cfc1(regs, instr); break;
|
|
||||||
case 0x03: unimplemented(regs); break;
|
|
||||||
case 0x04: mtc1(regs, instr); break;
|
|
||||||
case 0x05: dmtc1(regs, instr); break;
|
|
||||||
case 0x06: ctc1(regs, instr); break;
|
|
||||||
case 0x07: unimplemented(regs); break;
|
|
||||||
case 0x08:
|
|
||||||
/*switch(mask_branch) {
|
|
||||||
case 0: {
|
|
||||||
cpu.mov(cpu.rax, REG(byte, cop1.fcr31.compare));
|
|
||||||
cpu.b(instr, !regs.cop1.fcr31.compare);
|
|
||||||
} break;
|
|
||||||
case 1: {
|
|
||||||
cpu.b(instr, regs.cop1.fcr31.compare);
|
|
||||||
} break;
|
|
||||||
case 2: {
|
|
||||||
cpu.bl(instr, !regs.cop1.fcr31.compare);
|
|
||||||
} break;
|
|
||||||
case 3: {
|
|
||||||
cpu.bl(instr, regs.cop1.fcr31.compare);
|
|
||||||
} break;
|
|
||||||
default: Util::panic("Undefined BC COP1 {:02X}", mask_branch);
|
|
||||||
}*/
|
|
||||||
break;
|
|
||||||
case 0x10: // s
|
|
||||||
switch(mask_fun) {
|
|
||||||
case 0x00: adds(regs, instr); break;
|
|
||||||
case 0x01: subs(regs, instr); break;
|
|
||||||
case 0x02: muls(regs, instr); break;
|
|
||||||
case 0x03: divs(regs, instr); break;
|
|
||||||
case 0x04: sqrts(regs, instr); break;
|
|
||||||
case 0x05: abss(regs, instr); break;
|
|
||||||
case 0x06: movs(regs, instr); break;
|
|
||||||
case 0x07: negs(regs, instr); break;
|
|
||||||
case 0x08: roundls(regs, instr); break;
|
|
||||||
case 0x09: truncls(regs, instr); break;
|
|
||||||
case 0x0A: ceills(regs, instr); break;
|
|
||||||
case 0x0B: floorls(regs, instr); break;
|
|
||||||
case 0x0C: roundws(regs, instr); break;
|
|
||||||
case 0x0D: truncws(regs, instr); break;
|
|
||||||
case 0x0E: ceilws(regs, instr); break;
|
|
||||||
case 0x0F: floorws(regs, instr); break;
|
|
||||||
case 0x20:
|
|
||||||
unimplemented(regs);
|
|
||||||
break;
|
|
||||||
case 0x21: cvtds(regs, instr); break;
|
|
||||||
case 0x24: cvtws(regs, instr); break;
|
|
||||||
case 0x25: cvtls(regs, instr); break;
|
|
||||||
case 0x30://ccond<float>(regs, instr, F); break;
|
|
||||||
case 0x31://ccond<float>(regs, instr, UN); break;
|
|
||||||
case 0x32://ccond<float>(regs, instr, EQ); break;
|
|
||||||
case 0x33://ccond<float>(regs, instr, UEQ); break;
|
|
||||||
case 0x34://ccond<float>(regs, instr, OLT); break;
|
|
||||||
case 0x35://ccond<float>(regs, instr, ULT); break;
|
|
||||||
case 0x36://ccond<float>(regs, instr, OLE); break;
|
|
||||||
case 0x37://ccond<float>(regs, instr, ULE); break;
|
|
||||||
case 0x38://ccond<float>(regs, instr, SF); break;
|
|
||||||
case 0x39://ccond<float>(regs, instr, NGLE); break;
|
|
||||||
case 0x3A://ccond<float>(regs, instr, SEQ); break;
|
|
||||||
case 0x3B://ccond<float>(regs, instr, NGL); break;
|
|
||||||
case 0x3C://ccond<float>(regs, instr, LT); break;
|
|
||||||
case 0x3D://ccond<float>(regs, instr, NGE); break;
|
|
||||||
case 0x3E://ccond<float>(regs, instr, LE); break;
|
|
||||||
case 0x3F://ccond<float>(regs, instr, NGT); break;
|
|
||||||
default: Util::panic("Unimplemented COP1 function S[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x11: // d
|
|
||||||
switch(mask_fun) {
|
|
||||||
case 0x00: addd(regs, instr); break;
|
|
||||||
case 0x01: subd(regs, instr); break;
|
|
||||||
case 0x02: muld(regs, instr); break;
|
|
||||||
case 0x03: divd(regs, instr); break;
|
|
||||||
case 0x04: sqrtd(regs, instr); break;
|
|
||||||
case 0x05: absd(regs, instr); break;
|
|
||||||
case 0x06: movd(regs, instr); break;
|
|
||||||
case 0x07: negd(regs, instr); break;
|
|
||||||
case 0x08: roundld(regs, instr); break;
|
|
||||||
case 0x09: truncld(regs, instr); break;
|
|
||||||
case 0x0A: ceilld(regs, instr); break;
|
|
||||||
case 0x0B: floorld(regs, instr); break;
|
|
||||||
case 0x0C: roundwd(regs, instr); break;
|
|
||||||
case 0x0D: truncwd(regs, instr); break;
|
|
||||||
case 0x0E: ceilwd(regs, instr); break;
|
|
||||||
case 0x0F: floorwd(regs, instr); break;
|
|
||||||
case 0x20: cvtsd(regs, instr); break;
|
|
||||||
case 0x21:
|
|
||||||
unimplemented(regs);
|
|
||||||
break;
|
|
||||||
case 0x24: cvtwd(regs, instr); break;
|
|
||||||
case 0x25: cvtld(regs, instr); break;
|
|
||||||
case 0x30: //ccond<double>(regs, instr, F); break;
|
|
||||||
case 0x31: //ccond<double>(regs, instr, UN); break;
|
|
||||||
case 0x32: //ccond<double>(regs, instr, EQ); break;
|
|
||||||
case 0x33: //ccond<double>(regs, instr, UEQ); break;
|
|
||||||
case 0x34: //ccond<double>(regs, instr, OLT); break;
|
|
||||||
case 0x35: //ccond<double>(regs, instr, ULT); break;
|
|
||||||
case 0x36: //ccond<double>(regs, instr, OLE); break;
|
|
||||||
case 0x37: //ccond<double>(regs, instr, ULE); break;
|
|
||||||
case 0x38: //ccond<double>(regs, instr, SF); break;
|
|
||||||
case 0x39: //ccond<double>(regs, instr, NGLE); break;
|
|
||||||
case 0x3A: //ccond<double>(regs, instr, SEQ); break;
|
|
||||||
case 0x3B: //ccond<double>(regs, instr, NGL); break;
|
|
||||||
case 0x3C: //ccond<double>(regs, instr, LT); break;
|
|
||||||
case 0x3D: //ccond<double>(regs, instr, NGE); break;
|
|
||||||
case 0x3E: //ccond<double>(regs, instr, LE); break;
|
|
||||||
case 0x3F: //ccond<double>(regs, instr, NGT); break;
|
|
||||||
default: Util::panic("Unimplemented COP1 function D[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x14: // w
|
|
||||||
switch(mask_fun) {
|
|
||||||
case 0x20: cvtsw(regs, instr); break;
|
|
||||||
case 0x21: cvtdw(regs, instr); break;
|
|
||||||
case 0x24:
|
|
||||||
unimplemented(regs);
|
|
||||||
break;
|
|
||||||
default: Util::panic("Unimplemented COP1 function W[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x15: // l
|
|
||||||
switch(mask_fun) {
|
|
||||||
case 0x20: cvtsl(regs, instr); break;
|
|
||||||
case 0x21: cvtdl(regs, instr); break;
|
|
||||||
case 0x24: case 0x25:
|
|
||||||
unimplemented(regs);
|
|
||||||
break;
|
|
||||||
default: Util::panic("Unimplemented COP1 function L[{} {}] ({:08X}) ({:016X})", mask_fun >> 3, mask_fun & 7, instr, (u64)regs.oldPC);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default: Util::panic("Unimplemented COP1 instruction {} {}", mask_sub >> 3, mask_sub & 7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include <core/registers/Cop1.hpp>
|
#include <core/registers/Cop1.hpp>
|
||||||
#include <core/registers/Registers.hpp>
|
#include <core/registers/Registers.hpp>
|
||||||
#include <core/Interpreter.hpp>
|
#include <core/Interpreter.hpp>
|
||||||
#include <core/JIT.hpp>
|
|
||||||
#include <core/Mem.hpp>
|
#include <core/Mem.hpp>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cfenv>
|
#include <cfenv>
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
#include <KaizenQt.hpp>
|
#include <KaizenQt.hpp>
|
||||||
|
|
||||||
RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) {
|
RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) {
|
||||||
if (volkInitialize() != VK_SUCCESS) {
|
|
||||||
Util::panic("Could not initialize Vulkan loader!");
|
|
||||||
}
|
|
||||||
|
|
||||||
create();
|
create();
|
||||||
|
|
||||||
setAttribute(Qt::WA_NativeWindow);
|
setAttribute(Qt::WA_NativeWindow);
|
||||||
@@ -21,11 +17,14 @@ RenderWidget::RenderWidget(QWidget* parent) : QWidget(parent) {
|
|||||||
windowHandle()->setSurfaceType(QWindow::VulkanSurface);
|
windowHandle()->setSurfaceType(QWindow::VulkanSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
instance.create();
|
if(!Vulkan::Context::init_loader(nullptr)) {
|
||||||
windowHandle()->setVulkanInstance(&instance);
|
Util::panic("Could not initialize Vulkan ICD");
|
||||||
|
}
|
||||||
|
|
||||||
|
windowHandle()->setVulkanInstance(&instance.get_qvkinstance());
|
||||||
|
|
||||||
wsiPlatform = new QtWSIPlatform(windowHandle());
|
wsiPlatform = new QtWSIPlatform(windowHandle());
|
||||||
windowInfo = std::make_unique<QtParallelRdpWindowInfo>(windowHandle());
|
windowInfo = std::make_unique<QtParallelRdpWindowInfo>(windowHandle());
|
||||||
|
|
||||||
LoadWSIPlatform(wsiPlatform, std::move(windowInfo));
|
LoadWSIPlatform(&instance, wsiPlatform, std::move(windowInfo));
|
||||||
}
|
}
|
||||||
@@ -5,11 +5,35 @@
|
|||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QVulkanInstance>
|
#include <QVulkanInstance>
|
||||||
|
|
||||||
|
struct QtInstanceFactory : Vulkan::InstanceFactory {
|
||||||
|
VkInstance create_instance(const VkInstanceCreateInfo *info) override {
|
||||||
|
instance.setApiVersion({1,3,0});
|
||||||
|
QByteArrayList exts;
|
||||||
|
for(int i = 0; i < info->enabledExtensionCount; i++) {
|
||||||
|
exts.push_back(QByteArray::fromStdString(info->ppEnabledExtensionNames[i]));
|
||||||
|
}
|
||||||
|
QByteArrayList layers;
|
||||||
|
for(int i = 0; i < info->enabledLayerCount; i++) {
|
||||||
|
layers.push_back(QByteArray::fromStdString(info->ppEnabledLayerNames[i]));
|
||||||
|
}
|
||||||
|
instance.setExtensions(exts);
|
||||||
|
instance.setLayers(layers);
|
||||||
|
instance.setApiVersion({1,3,0});
|
||||||
|
instance.create();
|
||||||
|
|
||||||
|
return instance.vkInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVulkanInstance& get_qvkinstance() { return instance; }
|
||||||
|
private:
|
||||||
|
QVulkanInstance instance;
|
||||||
|
};
|
||||||
|
|
||||||
class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo {
|
class QtParallelRdpWindowInfo : public ParallelRdpWindowInfo {
|
||||||
public:
|
public:
|
||||||
QtParallelRdpWindowInfo(QWindow* window) : window(window) {}
|
explicit QtParallelRdpWindowInfo(QWindow* window) : window(window) {}
|
||||||
CoordinatePair get_window_size() {
|
CoordinatePair get_window_size() override {
|
||||||
CoordinatePair{ static_cast<float>(window->width()), static_cast<float>(window->height()) };
|
return CoordinatePair{ static_cast<float>(window->width()), static_cast<float>(window->height()) };
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
QWindow* window;
|
QWindow* window;
|
||||||
@@ -17,7 +41,7 @@ private:
|
|||||||
|
|
||||||
class QtWSIPlatform final : public Vulkan::WSIPlatform {
|
class QtWSIPlatform final : public Vulkan::WSIPlatform {
|
||||||
public:
|
public:
|
||||||
QtWSIPlatform(QWindow* window) : window(window) {}
|
explicit QtWSIPlatform(QWindow* window) : window(window) {}
|
||||||
|
|
||||||
std::vector<const char*> get_instance_extensions() override {
|
std::vector<const char*> get_instance_extensions() override {
|
||||||
auto vec = std::vector<const char*>();
|
auto vec = std::vector<const char*>();
|
||||||
@@ -29,7 +53,7 @@ public:
|
|||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceKHR create_surface(VkInstance, VkPhysicalDevice) override {
|
VkSurfaceKHR create_surface(VkInstance instance, VkPhysicalDevice) override {
|
||||||
return QVulkanInstance::surfaceForWindow(window);
|
return QVulkanInstance::surfaceForWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,11 +89,11 @@ class RenderWidget : public QWidget {
|
|||||||
public:
|
public:
|
||||||
explicit RenderWidget(QWidget* parent);
|
explicit RenderWidget(QWidget* parent);
|
||||||
|
|
||||||
QPaintEngine* paintEngine() const override {
|
[[nodiscard]] QPaintEngine* paintEngine() const override {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
std::unique_ptr<ParallelRdpWindowInfo> windowInfo;
|
||||||
QtWSIPlatform* wsiPlatform;
|
QtWSIPlatform* wsiPlatform;
|
||||||
QVulkanInstance instance;
|
QtInstanceFactory instance;
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user