Пример #1
0
void ShaderManagerVulkan::GetShaders(int prim, u32 vertType, VulkanVertexShader **vshader, VulkanFragmentShader **fshader, bool useHWTransform) {
	VShaderID VSID;
	if (gstate_c.IsDirty(DIRTY_VERTEXSHADER_STATE)) {
		gstate_c.Clean(DIRTY_VERTEXSHADER_STATE);
		ComputeVertexShaderID(&VSID, vertType, useHWTransform);
	} else {
		VSID = lastVSID_;
	}

	FShaderID FSID;
	if (gstate_c.IsDirty(DIRTY_FRAGMENTSHADER_STATE)) {
		gstate_c.Clean(DIRTY_FRAGMENTSHADER_STATE);
		ComputeFragmentShaderID(&FSID);
	} else {
		FSID = lastFSID_;
	}

	_dbg_assert_(G3D, FSID.Bit(FS_BIT_LMODE) == VSID.Bit(VS_BIT_LMODE));
	_dbg_assert_(G3D, FSID.Bit(FS_BIT_DO_TEXTURE) == VSID.Bit(VS_BIT_DO_TEXTURE));
	_dbg_assert_(G3D, FSID.Bit(FS_BIT_ENABLE_FOG) == VSID.Bit(VS_BIT_ENABLE_FOG));
	_dbg_assert_(G3D, FSID.Bit(FS_BIT_FLATSHADE) == VSID.Bit(VS_BIT_FLATSHADE));

	// Just update uniforms if this is the same shader as last time.
	if (lastVShader_ != nullptr && lastFShader_ != nullptr && VSID == lastVSID_ && FSID == lastFSID_) {
		*vshader = lastVShader_;
		*fshader = lastFShader_;
		_dbg_assert_msg_(G3D, (*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was cached");
		// Already all set, no need to look up in shader maps.
		return;
	}

	VulkanVertexShader *vs = vsCache_.Get(VSID);
	if (!vs)	{
		// Vertex shader not in cache. Let's compile it.
		bool usesLighting;
		GenerateVulkanGLSLVertexShader(VSID, codeBuffer_, &usesLighting);
		vs = new VulkanVertexShader(vulkan_, VSID, codeBuffer_, vertType, useHWTransform, usesLighting);
		vsCache_.Insert(VSID, vs);
	}
	lastVSID_ = VSID;

	VulkanFragmentShader *fs = fsCache_.Get(FSID);
	if (!fs) {
		// Fragment shader not in cache. Let's compile it.
		GenerateVulkanGLSLFragmentShader(FSID, codeBuffer_);
		fs = new VulkanFragmentShader(vulkan_, FSID, codeBuffer_, useHWTransform);
		fsCache_.Insert(FSID, fs);
	}

	lastFSID_ = FSID;

	lastVShader_ = vs;
	lastFShader_ = fs;

	*vshader = vs;
	*fshader = fs;
	_dbg_assert_msg_(G3D, (*vshader)->UseHWTransform() == useHWTransform, "Bad vshader was computed");
}
Пример #2
0
	void Jit::Comp_Mftv(u32 op)
	{
		CONDITIONAL_DISABLE;

		int imm = op & 0xFF;
		int rt = _RT;
		switch ((op >> 21) & 0x1f)
		{
		case 3: //mfv / mfvc
			// rt = 0, imm = 255 appears to be used as a CPU interlock by some games.
			if (rt != 0) {
				if (imm < 128) {  //R(rt) = VI(imm);
					fpr.FlushV(imm);
					gpr.MapReg(rt, MAP_NOINIT | MAP_DIRTY);
					LDR(gpr.R(rt), CTXREG, fpr.GetMipsRegOffsetV(imm));
				} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
					DISABLE;
					// In case we have a saved prefix.
					//FlushPrefixV();
					//gpr.BindToRegister(rt, false, true);
					//MOV(32, gpr.R(rt), M(&currentMIPS->vfpuCtrl[imm - 128]));
				} else {
					//ERROR - maybe need to make this value too an "interlock" value?
					_dbg_assert_msg_(CPU,0,"mfv - invalid register");
				}
			}
			break;

		case 7: //mtv
			if (imm < 128) {
				gpr.FlushR(rt);
				fpr.MapRegV(imm, MAP_DIRTY | MAP_NOINIT);
				VLDR(fpr.V(imm), CTXREG, gpr.GetMipsRegOffset(rt));
			} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc //currentMIPS->vfpuCtrl[imm - 128] = R(rt);
				DISABLE; 
				//gpr.BindToRegister(rt, true, false);
				//MOV(32, M(&currentMIPS->vfpuCtrl[imm - 128]), gpr.R(rt));

				// TODO: Optimization if rt is Imm?
				//if (imm - 128 == VFPU_CTRL_SPREFIX) {
				//js.prefixSFlag = JitState::PREFIX_UNKNOWN;
				//} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
				//	js.prefixTFlag = JitState::PREFIX_UNKNOWN;
				//} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
				//	js.prefixDFlag = JitState::PREFIX_UNKNOWN;
				//}
			} else {
				//ERROR
				_dbg_assert_msg_(CPU,0,"mtv - invalid register");
			}
			break;

		default:
			DISABLE;
		}
	}
Пример #3
0
void Jit::EatInstruction(u32 op)
{
	u32 info = MIPSGetInfo(op);
	_dbg_assert_msg_(JIT, !(info & DELAYSLOT), "Never eat a branch op.");
	_dbg_assert_msg_(JIT, !js.inDelaySlot, "Never eat an instruction inside a delayslot.");

	CheckJitBreakpoint(js.compilerPC + 4, 0);
	js.numInstructions++;
	js.compilerPC += 4;
	js.downcountAmount += MIPSGetInstructionCycleEstimate(op);
}
Пример #4
0
void hleReSchedule(const char *reason)
{
	_dbg_assert_msg_(HLE, reason != 0, "hleReSchedule: Expecting a valid reason.");
	_dbg_assert_msg_(HLE, reason != 0 && strlen(reason) < 256, "hleReSchedule: Not too long reason.");

	hleAfterSyscall |= HLE_AFTER_RESCHED;

	if (!reason)
		hleAfterSyscallReschedReason = "Invalid reason";
	else
		hleAfterSyscallReschedReason = reason;
}
Пример #5
0
void MIPSEmitter::SetJumpTarget(const FixupBranch &branch, const void *dst) {
	const intptr_t srcp = (intptr_t)branch.ptr;
	const intptr_t dstp = (intptr_t)dst;
	u32 *fixup = (u32 *)branch.ptr;

	_dbg_assert_msg_(JIT, (dstp & 3) == 0, "Destination should be aligned");

	if (branch.type == BRANCH_16) {
		// The distance is encoded as words from the delay slot.
		ptrdiff_t distance = (dstp - srcp - 4) >> 2;
		_dbg_assert_msg_(JIT, BInRange(branch.ptr, dst), "Destination is too far away (%p -> %p)", branch.ptr, dst);
		*fixup = (*fixup & 0xffff0000) | (distance & 0x0000ffff);
	} else {
Пример #6
0
void FPURegCache::MapRegsVS(const u8 *r, VectorSize vsz, int flags) {
	const int n = GetNumVectorElements(vsz);

	_dbg_assert_msg_(JIT, jo_->enableVFPUSIMD, "Should not map simd regs when option is off.");

	if (!TryMapRegsVS(r, vsz, flags)) {
		// TODO: Could be more optimal.
		for (int i = 0; i < n; ++i) {
			StoreFromRegisterV(r[i]);
		}
		if (!TryMapRegsVS(r, vsz, flags)) {
			_dbg_assert_msg_(JIT, false, "MapRegsVS() failed on second try.");
		}
	}
}
void ConsoleListener::LetterSpace(int Width, int Height)
{
	_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#if defined(_WIN32) && !defined(_XBOX) && !defined(__MINGW32__)
	// Get console info
	CONSOLE_SCREEN_BUFFER_INFO ConInfo;
	GetConsoleScreenBufferInfo(hConsole, &ConInfo);

	//
	int OldBufferWidth = ConInfo.dwSize.X;
	int OldBufferHeight = ConInfo.dwSize.Y;
	int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left);
	int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top);
	//
	int NewBufferWidth = Width;
	int NewBufferHeight = Height;
	int NewScreenWidth = NewBufferWidth - 1;
	int NewScreenHeight = OldScreenHeight;

	// Width
	BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1));
	// Height
	BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1));

	// Resize the window too
	//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
#endif
}
/*
  LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are
	dependent on each other, that's the reason for the additional checks.  
*/
void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst)
{
	_dbg_assert_msg_(COMMON, IsOpen(), "Don't call this before opening the console.");
#if defined(_WIN32) && !defined(_XBOX) && !defined(__MINGW32__)
	BOOL SB, SW;
	if (BufferFirst)
	{
		// Change screen buffer size
		COORD Co = {BufferWidth, BufferHeight};
		SB = SetConsoleScreenBufferSize(hConsole, Co);
		// Change the screen buffer window size
		SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
	}
	else
	{
		// Change the screen buffer window size
		SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
		// Change screen buffer size
		COORD Co = {BufferWidth, BufferHeight};
		SB = SetConsoleScreenBufferSize(hConsole, Co);
	}
#endif
}
Пример #9
0
	void Int_SVQ(u32 op)
	{
		int imm = (signed short)(op&0xFFFC);
		int rs = _RS;
		int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);

		u32 addr = R(rs) + imm;

		switch (op >> 26)
		{
		case 53: //lvl.q/lvr.q
			if (addr & 0x3)
			{
				_dbg_assert_msg_(CPU, 0, "Misaligned lvX.q");
			}
			if ((op&2) == 0)
			{
				// It's an LVL
				float d[4];
				ReadVector(d, V_Quad, vt);
				int offset = (addr >> 2) & 3;
				for (int i = 0; i < offset + 1; i++)
				{
					d[3 - i] = Memory::Read_Float(addr - i * 4);
				}
				WriteVector(d, V_Quad, vt);
			}
			else
			{
Пример #10
0
void __UmdBeginCallback(SceUID threadID, SceUID prevCallbackId)
{
	SceUID pauseKey = prevCallbackId == 0 ? threadID : prevCallbackId;

	if (HLEKernel::VerifyWait(threadID, WAITTYPE_UMD, 1))
	{
		// This means two callbacks in a row.  PSP crashes if the same callback runs inside itself.
		// TODO: Handle this better?
		if (umdPausedWaits.find(pauseKey) != umdPausedWaits.end())
			return;

		_dbg_assert_msg_(SCEIO, umdStatTimeoutEvent != -1, "Must have a umd timer");
		s64 cyclesLeft = CoreTiming::UnscheduleEvent(umdStatTimeoutEvent, threadID);
		if (cyclesLeft != 0)
			umdPausedWaits[pauseKey] = CoreTiming::GetTicks() + cyclesLeft;
		else
			umdPausedWaits[pauseKey] = 0;

		HLEKernel::RemoveWaitingThread(umdWaitingThreads, threadID);

		DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatCB: Suspending lock wait for callback");
	}
	else
		WARN_LOG_REPORT(SCEIO, "sceUmdWaitDriveStatCB: beginning callback with bad wait id?");
}
Пример #11
0
 std::function<void(u32, T)> InvalidWriteLambda() const
 {
     return [](u32, T) {
         _dbg_assert_msg_(MEMMAP, 0, "Called the write lambda on a read "
                          "complex handler.");
     };
 }
Пример #12
0
void Jit::Comp_Generic(MIPSOpcode op)
{
	FlushAll();
	MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
	_dbg_assert_msg_(JIT, (MIPSGetInfo(op) & DELAYSLOT) == 0, "Cannot use interpreter for branch ops.");

	if (func)
	{
		MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
		if (USE_JIT_MISSMAP)
			ABI_CallFunctionC(&JitLogMiss, op.encoding);
		else
			ABI_CallFunctionC(func, op.encoding);
	}
	else
		ERROR_LOG_REPORT(JIT, "Trying to compile instruction %08x that can't be interpreted", op.encoding);

	const MIPSInfo info = MIPSGetInfo(op);
	if ((info & IS_VFPU) != 0 && (info & VFPU_NO_PREFIX) == 0)
	{
		// If it does eat them, it'll happen in MIPSCompileOp().
		if ((info & OUT_EAT_PREFIX) == 0)
			js.PrefixUnknown();
	}
}
Пример #13
0
void Jit::FlushPrefixV()
{
	if ((js.prefixSFlag & JitState::PREFIX_DIRTY) != 0)
	{
		MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_SPREFIX]), Imm32(js.prefixS));
		js.prefixSFlag = (JitState::PrefixState) (js.prefixSFlag & ~JitState::PREFIX_DIRTY);
	}

	if ((js.prefixTFlag & JitState::PREFIX_DIRTY) != 0)
	{
		MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_TPREFIX]), Imm32(js.prefixT));
		js.prefixTFlag = (JitState::PrefixState) (js.prefixTFlag & ~JitState::PREFIX_DIRTY);
	}

	if ((js.prefixDFlag & JitState::PREFIX_DIRTY) != 0)
	{
		MOV(32, M((void *)&mips_->vfpuCtrl[VFPU_CTRL_DPREFIX]), Imm32(js.prefixD));

		_dbg_assert_msg_(JIT, sizeof(bool) <= 4, "Bools shouldn't be that big?");
		const size_t bool_stride = 4 / sizeof(bool);
		for (size_t i = 0; i < ARRAY_SIZE(mips_->vfpuWriteMask); i += bool_stride)
			MOV(32, M((void *)&mips_->vfpuWriteMask[i]), Imm32(*(u32 *)&js.writeMask[i]));

		js.prefixDFlag = (JitState::PrefixState) (js.prefixDFlag & ~JitState::PREFIX_DIRTY);
	}
}
Пример #14
0
void Reschedule(const char *reason) {
#ifdef _DEBUG
    _dbg_assert_msg_(HLE, reason != 0 && strlen(reason) < 256, "Reschedule: Invalid or too long reason.");
#endif
    Core::g_app_core->PrepareReschedule();
    g_reschedule = true;
}
Пример #15
0
void __UmdBeginCallback(SceUID threadID, SceUID prevCallbackId)
{
	SceUID pauseKey = prevCallbackId == 0 ? threadID : prevCallbackId;

	u32 error;
	SceUID waitID = __KernelGetWaitID(threadID, WAITTYPE_UMD, error);
	if (waitID == 1)
	{
		// This means two callbacks in a row.  PSP crashes if the same callback runs inside itself.
		// TODO: Handle this better?
		if (umdPausedWaitTimeouts.find(pauseKey) != umdPausedWaitTimeouts.end())
			return;

		_dbg_assert_msg_(HLE, umdStatTimeoutEvent != -1, "Must have a umd timer");
		s64 cyclesLeft = CoreTiming::UnscheduleEvent(umdStatTimeoutEvent, threadID);
		if (cyclesLeft != 0)
			umdPausedWaitTimeouts[pauseKey] = CoreTiming::GetTicks() + cyclesLeft;
		else
			umdPausedWaitTimeouts[pauseKey] = 0;

		for (auto it = umdWaitingThreads.begin(); it < umdWaitingThreads.end(); ++it)
		{
			if (threadID == threadID)
				umdWaitingThreads.erase(it--);
		}

		DEBUG_LOG(HLE, "sceUmdWaitDriveStatCB: Suspending lock wait for callback");
	}
	else
		WARN_LOG_REPORT(HLE, "sceUmdWaitDriveStatCB: beginning callback with bad wait id?");
}
Пример #16
0
	bool Get(IniFile::Section *section) {
		switch (type_) {
		case TYPE_BOOL:
			if (cb_.b) {
				default_.b = cb_.b();
			}
			return section->Get(ini_, ptr_.b, default_.b);
		case TYPE_INT:
			if (cb_.i) {
				default_.i = cb_.i();
			}
			return section->Get(ini_, ptr_.i, default_.i);
		case TYPE_FLOAT:
			if (cb_.f) {
				default_.f = cb_.f();
			}
			return section->Get(ini_, ptr_.f, default_.f);
		case TYPE_STRING:
			if (cb_.s) {
				default_.s = cb_.s();
			}
			return section->Get(ini_, ptr_.s, default_.s);
		default:
			_dbg_assert_msg_(LOADER, false, "Unexpected ini setting type");
			return false;
		}
	}
Пример #17
0
USBHost::USBHost(Kernel& ios, const std::string& device_name) : Device(ios, device_name)
{
#ifdef __LIBUSB__
  const int ret = libusb_init(&m_libusb_context);
  _dbg_assert_msg_(IOS_USB, ret == 0, "Failed to init libusb for USB passthrough.");
#endif
}
Пример #18
0
FixupBranch MIPSEmitter::BGTZ(MIPSReg rs, std::function<void ()> delaySlot) {
	// 000111 sssss xxxxx iiiiiiiiiiiiiii (fix up)
	_dbg_assert_msg_(JIT, rs < F_BASE, "Bad emitter arguments");
	FixupBranch b = MakeFixupBranch(BRANCH_16);
	Write32Fields(26, 0x07, 21, rs);
	ApplyDelaySlot(delaySlot);
	return b;
}
Пример #19
0
static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) {
    _dbg_assert_msg_(GSP, screen_index < 2, "Invalid screen index");

    // For each thread there are two FrameBufferUpdate fields
    u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate);
    ResultVal<u8*> ptr = Kernel::GetSharedMemoryPointer(g_shared_memory, offset);
    return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr));
}
Пример #20
0
void Jit::Comp_Generic(u32 op)
{
	FlushAll();
	MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
	_dbg_assert_msg_(JIT, (MIPSGetInfo(op) & DELAYSLOT) == 0, "Cannot use interpreter for branch ops.");

	if (func)
	{
		MOV(32, M(&mips_->pc), Imm32(js.compilerPC));
		if (USE_JIT_MISSMAP)
			ABI_CallFunctionC((void *)&JitLogMiss, op);
		else
			ABI_CallFunctionC((void *)func, op);
	}
	else
		_dbg_assert_msg_(JIT, 0, "Trying to compile instruction that can't be interpreted");
}
Пример #21
0
FixupBranch MIPSEmitter::BNE(MIPSReg rs, MIPSReg rt, std::function<void ()> delaySlot) {
	// 000101 sssss ttttt iiiiiiiiiiiiiii (fix up)
	_dbg_assert_msg_(JIT, rs < F_BASE && rt < F_BASE, "Bad emitter arguments");
	FixupBranch b = MakeFixupBranch(BRANCH_16);
	Write32Fields(26, 0x05, 21, rs, 16, rt);
	ApplyDelaySlot(delaySlot);
	return b;
}
Пример #22
0
void __CtrlTimerUpdate(u64 userdata, int cyclesLate)
{
	// This only runs in timer mode (ctrlCycle > 0.)
	_dbg_assert_msg_(SCECTRL, ctrlCycle > 0, "Ctrl: sampling cycle should be > 0");

	__CtrlDoSample();
	CoreTiming::ScheduleEvent(usToCycles(ctrlCycle), ctrlTimer, 0);
}
Пример #23
0
 std::function<T(u32)> InvalidReadLambda() const
 {
     return [](u32) {
         _dbg_assert_msg_(MEMMAP, 0, "Called the read lambda on a write "
                          "complex handler.");
         return 0;
     };
 }
Пример #24
0
void Jit::Comp_FPULS(MIPSOpcode op)
{
	CONDITIONAL_DISABLE;
	s32 offset = _IMM16;
	int ft = _FT;
	MIPSGPReg rs = _RS;

	switch(op >> 26)
	{
	case 49: //FI(ft) = Memory::Read_U32(addr); break; //lwc1
		{
			gpr.Lock(rs);
			fpr.SpillLock(ft);
			fpr.MapReg(ft, false, true);

			JitSafeMem safe(this, rs, offset);
			OpArg src;
			if (safe.PrepareRead(src, 4))
				MOVSS(fpr.RX(ft), src);
			if (safe.PrepareSlowRead(&Memory::Read_U32))
			{
				MOV(32, M(&ssLoadStoreTemp), R(EAX));
				MOVSS(fpr.RX(ft), M(&ssLoadStoreTemp));
			}
			safe.Finish();

			gpr.UnlockAll();
			fpr.ReleaseSpillLocks();
		}
		break;
	case 57: //Memory::Write_U32(FI(ft), addr); break; //swc1
		{
			gpr.Lock(rs);
			fpr.SpillLock(ft);
			fpr.MapReg(ft, true, false);

			JitSafeMem safe(this, rs, offset);
			OpArg dest;
			if (safe.PrepareWrite(dest, 4))
				MOVSS(dest, fpr.RX(ft));
			if (safe.PrepareSlowWrite())
			{
				MOVSS(M(&ssLoadStoreTemp), fpr.RX(ft));
				safe.DoSlowWrite(&Memory::Write_U32, M(&ssLoadStoreTemp));
			}
			safe.Finish();

			gpr.UnlockAll();
			fpr.ReleaseSpillLocks();
		}
		break;

	default:
		_dbg_assert_msg_(CPU,0,"Trying to interpret FPULS instruction that can't be interpreted");
		break;
	}
}
Пример #25
0
s32 GCMemcardDirectory::Read(u32 address, s32 length, u8 *destaddress)
{

	s32 block = address / BLOCK_SIZE;
	u32 offset = address % BLOCK_SIZE;
	s32 extra = 0; // used for read calls that are across multiple blocks

	if (offset + length > BLOCK_SIZE)
	{
		extra = length + offset - BLOCK_SIZE;
		length -= extra;

		// verify that we haven't calculated a length beyond BLOCK_SIZE
		_dbg_assert_msg_(EXPANSIONINTERFACE, (address + length) % BLOCK_SIZE == 0,
						 "Memcard directory Read Logic Error");
	}

	if (m_LastBlock != block)
	{
		switch (block)
		{
		case 0:
			m_LastBlock = block;
			m_LastBlockAddress = (u8 *)&m_hdr;
			break;
		case 1:
			m_LastBlock = -1;
			m_LastBlockAddress = (u8 *)&m_dir1;
			break;
		case 2:
			m_LastBlock = -1;
			m_LastBlockAddress = (u8 *)&m_dir2;
			break;
		case 3:
			m_LastBlock = block;
			m_LastBlockAddress = (u8 *)&m_bat1;
			break;
		case 4:
			m_LastBlock = block;
			m_LastBlockAddress = (u8 *)&m_bat2;
			break;
		default:
			m_LastBlock = SaveAreaRW(block);

			if (m_LastBlock == -1)
			{
				memset(destaddress, 0xFF, length);
				return 0;
			}
		}
	}

	memcpy(destaddress, m_LastBlockAddress + offset, length);
	if (extra)
		extra = Read(address + length, extra, destaddress + length);
	return length + extra;
}
Пример #26
0
void OpenGL_CreateAttributelessVAO()
{
	glGenVertexArrays(1, &attributelessVAO);
	_dbg_assert_msg_(VIDEO, attributelessVAO != 0, "Attributeless VAO should have been created successfully.")

	// In a compatibility context, we require a valid, bound array buffer.
	glGenBuffers(1, &attributelessVBO);
	_dbg_assert_msg_(VIDEO, attributelessVBO != 0, "Attributeless VBO should have been created successfully.")

	// Initialize the buffer with nothing.  16 floats is an arbitrary size that may work around driver issues.
	glBindBuffer(GL_ARRAY_BUFFER, attributelessVBO);
	glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 16, nullptr, GL_STATIC_DRAW);

	// We must also define vertex attribute 0.
	glBindVertexArray(attributelessVAO);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
	glEnableVertexAttribArray(0);
}
Пример #27
0
IPCCommandResult CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
{
	SIOCtlVBuffer CommandBuffer(_CommandAddress);

	// Prepare the out buffer(s) with zeros as a safety precaution
	// to avoid returning bad values
	for (u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++)
	{
		Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0,
			CommandBuffer.PayloadBuffer[i].m_Size);
	}

	u32 ReturnValue = 0;
	switch (CommandBuffer.Parameter)
	{
	case DVDInterface::DVDLowOpenPartition:
		{
			_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, "DVDLowOpenPartition with ticket");
			_dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, "DVDLowOpenPartition with cert chain");

			u64 const partition_offset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2);
			DVDInterface::ChangePartition(partition_offset);

			INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: partition_offset 0x%016" PRIx64, partition_offset);

			// Read TMD to the buffer
			u32 tmd_size;
			std::unique_ptr<u8[]> tmd_buf = DVDInterface::GetVolume().GetTMD(&tmd_size);
			Memory::CopyToEmu(CommandBuffer.PayloadBuffer[0].m_Address, tmd_buf.get(), tmd_size);
			WII_IPC_HLE_Interface::ES_DIVerify(tmd_buf.get(), tmd_size);

			ReturnValue = 1;
		}
		break;

	default:
		ERROR_LOG(WII_IPC_DVD, "IOCtlV: %i", CommandBuffer.Parameter);
		_dbg_assert_msg_(WII_IPC_DVD, 0, "IOCtlV: %i", CommandBuffer.Parameter);
		break;
	}

	Memory::Write_U32(ReturnValue, _CommandAddress + 4);
	return GetDefaultReply();
}
Пример #28
0
void SimpleGLWindow::Draw(u8 *data, int w, int h, bool flipped, Format fmt) {
	wglMakeCurrent(hDC_, hGLRC_);

	GLint components = GL_RGBA;
	GLenum glfmt;
	if (fmt == FORMAT_8888) {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
		glfmt = GL_UNSIGNED_BYTE;
	} else if (fmt == FORMAT_FLOAT) {
		glfmt = GL_FLOAT;
		components = GL_RED;
	} else {
		glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
		if (fmt == FORMAT_4444) {
			glfmt = GL_UNSIGNED_SHORT_4_4_4_4;
		} else if (fmt == FORMAT_5551) {
			glfmt = GL_UNSIGNED_SHORT_5_5_5_1;
		} else if (fmt == FORMAT_565) {
			glfmt = GL_UNSIGNED_SHORT_5_6_5;
			components = GL_RGB;
		} else if (fmt == FORMAT_4444_REV) {
			glfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;
		} else if (fmt == FORMAT_5551_REV) {
			glfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;
		} else if (fmt == FORMAT_565_REV) {
			glfmt = GL_UNSIGNED_SHORT_5_6_5_REV;
			components = GL_RGB;
		} else if (fmt == FORMAT_16BIT) {
			glfmt = GL_UNSIGNED_SHORT;
			components = GL_RED;
		} else if (fmt == FORMAT_8BIT) {
			glfmt = GL_UNSIGNED_BYTE;
			components = GL_RED;
		} else {
			_dbg_assert_msg_(COMMON, false, "Invalid SimpleGLWindow format.");
		}
	}

	glBindTexture(GL_TEXTURE_2D, tex_);
	glTexImage2D(GL_TEXTURE_2D, 0, components, w, h, 0, components, glfmt, data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	// Reset offset when the texture size changes.
	if (tw_ != w || th_ != h) {
		tw_ = w;
		th_ = h;
		offsetX_ = 0;
		offsetY_ = 0;
	}
	tflipped_ = flipped;

	Redraw();
}
Пример #29
0
// TODO(yuriks): This might be what the fs:REG service is for. See the Register/Unregister calls in
// http://3dbrew.org/wiki/Filesystem_services#ProgramRegistry_service_.22fs:REG.22
ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) {
    auto result = id_code_map.emplace(id_code, Common::make_unique<Archive>(std::move(backend), id_code));

    bool inserted = result.second;
    _dbg_assert_msg_(Service_FS, inserted, "Tried to register more than one archive with same id code");

    auto& archive = result.first->second;
    LOG_DEBUG(Service_FS, "Registered archive %s with id code 0x%08X", archive->GetName().c_str(), id_code);
    return RESULT_SUCCESS;
}
Пример #30
0
std::vector<MbxWaitingThread>::iterator __KernelMbxFindPriority(std::vector<MbxWaitingThread> &waiting)
{
	_dbg_assert_msg_(HLE, !waiting.empty(), "__KernelMutexFindPriority: Trying to find best of no threads.");

	std::vector<MbxWaitingThread>::iterator iter, end, best = waiting.end();
	u32 best_prio = 0xFFFFFFFF;
	for (iter = waiting.begin(), end = waiting.end(); iter != end; ++iter)
	{
		u32 iter_prio = __KernelGetThreadPrio(iter->first);
		if (iter_prio < best_prio)
		{
			best = iter;
			best_prio = iter_prio;
		}
	}

	_dbg_assert_msg_(HLE, best != waiting.end(), "__KernelMutexFindPriority: Returning invalid best thread.");
	return best;
}