Beispiel #1
0
u32 GPUCommon::UpdateStall(int listid, u32 newstall)
{
	if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE)
		return SCE_KERNEL_ERROR_INVALID_ID;

	dls[listid].stall = newstall & 0xFFFFFFF;
	
	ProcessDLQueue();

	return 0;
}
u32 GLES_GPU::EnqueueList(u32 listpc, u32 stall)
{
	DisplayList dl;
	dl.id = dlIdGenerator++;
	dl.listpc = listpc&0xFFFFFFF;
	dl.stall = stall&0xFFFFFFF;
	dlQueue.push_back(dl);
	if (!ProcessDLQueue())
		return dl.id;
	else
		return 0;
}
Beispiel #3
0
void GPUCommon::UpdateStall(int listid, u32 newstall)
{
	for (auto iter = dlQueue.begin(); iter != dlQueue.end(); ++iter)
	{
		DisplayList &cur = *iter;
		if (cur.id == listid)
		{
			cur.stall = newstall & 0xFFFFFFF;
		}
	}
	
	ProcessDLQueue();
}
void GLES_GPU::UpdateStall(int listid, u32 newstall)
{
	// this needs improvement....
	for (std::vector<DisplayList>::iterator iter = dlQueue.begin(); iter != dlQueue.end(); iter++)
	{
		DisplayList &l = *iter;
		if (l.id == listid)
		{
			l.stall = newstall & 0xFFFFFFF;
		}
	}
	
	ProcessDLQueue();
}
Beispiel #5
0
u32 GPUCommon::UpdateStall(int listid, u32 newstall)
{
	if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE)
		return SCE_KERNEL_ERROR_INVALID_ID;

	dls[listid].stall = newstall & 0xFFFFFFF;

	if (dls[listid].signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
		dls[listid].signal = PSP_GE_SIGNAL_HANDLER_SUSPEND;
	
	ProcessDLQueue();

	return 0;
}
Beispiel #6
0
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head)
{
	DisplayList dl;
	dl.id = dlIdGenerator++;
	dl.pc = listpc & 0xFFFFFFF;
	dl.stall = stall & 0xFFFFFFF;
	dl.status = PSP_GE_LIST_QUEUED;
	dl.subIntrBase = subIntrBase;
	if(head)
		dlQueue.push_front(dl);
    else
		dlQueue.push_back(dl);
	ProcessDLQueue();
	return dl.id;
}
Beispiel #7
0
u32 GPUCommon::UpdateStall(int listid, u32 newstall) {
	easy_guard guard(listLock);
	if (listid < 0 || listid >= DisplayListMaxCount || dls[listid].state == PSP_GE_DL_STATE_NONE)
		return SCE_KERNEL_ERROR_INVALID_ID;
	auto &dl = dls[listid];
	if (dl.state == PSP_GE_DL_STATE_COMPLETED)
		return SCE_KERNEL_ERROR_ALREADY;

	dl.stall = newstall & 0x0FFFFFFF;

	if (dl.signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
		dl.signal = PSP_GE_SIGNAL_HANDLER_SUSPEND;
	
	guard.unlock();
	ProcessDLQueue();

	return 0;
}
Beispiel #8
0
u32 GPUCommon::Continue() {
	easy_guard guard(listLock);
	if (!currentList)
		return 0;

	if (currentList->state == PSP_GE_DL_STATE_PAUSED)
	{
		if (!isbreak)
		{
			if (currentList->signal == PSP_GE_SIGNAL_HANDLER_PAUSE)
				return 0x80000021;

			currentList->state = PSP_GE_DL_STATE_RUNNING;
			currentList->signal = PSP_GE_SIGNAL_NONE;

			// TODO Restore context of DL is necessary
			// TODO Restore BASE

			// We have a list now, so it's not complete.
			drawCompleteTicks = (u64)-1;
		}
		else
			currentList->state = PSP_GE_DL_STATE_QUEUED;
	}
	else if (currentList->state == PSP_GE_DL_STATE_RUNNING)
	{
		if (sceKernelGetCompiledSdkVersion() >= 0x02000000)
			return 0x80000020;
		return -1;
	}
	else
	{
		if (sceKernelGetCompiledSdkVersion() >= 0x02000000)
			return 0x80000004;
		return -1;
	}

	guard.unlock();
	ProcessDLQueue();
	return 0;
}
Beispiel #9
0
u32 GPUCommon::EnqueueList(u32 listpc, u32 stall, int subIntrBase, bool head) {
	easy_guard guard(listLock);
	// TODO Check the stack values in missing arg and ajust the stack depth

	// Check alignment
	// TODO Check the context and stack alignement too
	if (((listpc | stall) & 3) != 0)
		return 0x80000103;

	int id = -1;
	bool oldCompatibility = true;
	if (sceKernelGetCompiledSdkVersion() > 0x01FFFFFF) {
		//numStacks = 0;
		//stack = NULL;
		oldCompatibility = false;
	}

	u64 currentTicks = CoreTiming::GetTicks();
	for (int i = 0; i < DisplayListMaxCount; ++i)
	{
		if (dls[i].state != PSP_GE_DL_STATE_NONE && dls[i].state != PSP_GE_DL_STATE_COMPLETED) {
			if (dls[i].pc == listpc && !oldCompatibility) {
				ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list address %08X already used", listpc);
				return 0x80000021;
			}
			//if(dls[i].stack == stack) {
			//	ERROR_LOG(G3D, "sceGeListEnqueue: can't enqueue, list stack %08X already used", context);
			//	return 0x80000021;
			//}
		}
		if (dls[i].state == PSP_GE_DL_STATE_NONE && !dls[i].pendingInterrupt)
		{
			// Prefer a list that isn't used
			id = i;
			break;
		}
		if (id < 0 && dls[i].state == PSP_GE_DL_STATE_COMPLETED && !dls[i].pendingInterrupt && dls[i].waitTicks < currentTicks)
		{
			id = i;
		}
	}
	if (id < 0)
	{
		ERROR_LOG_REPORT(G3D, "No DL ID available to enqueue");
		for(auto it = dlQueue.begin(); it != dlQueue.end(); ++it) {
			DisplayList &dl = dls[*it];
			DEBUG_LOG(G3D, "DisplayList %d status %d pc %08x stall %08x", *it, dl.state, dl.pc, dl.stall);
		}
		return SCE_KERNEL_ERROR_OUT_OF_MEMORY;
	}

	DisplayList &dl = dls[id];
	dl.id = id;
	dl.startpc = listpc & 0x0FFFFFFF;
	dl.pc = listpc & 0x0FFFFFFF;
	dl.stall = stall & 0x0FFFFFFF;
	dl.subIntrBase = std::max(subIntrBase, -1);
	dl.stackptr = 0;
	dl.signal = PSP_GE_SIGNAL_NONE;
	dl.interrupted = false;
	dl.waitTicks = (u64)-1;
	dl.interruptsEnabled = interruptsEnabled_;

	if (head) {
		if (currentList) {
			if (currentList->state != PSP_GE_DL_STATE_PAUSED)
				return SCE_KERNEL_ERROR_INVALID_VALUE;
			currentList->state = PSP_GE_DL_STATE_QUEUED;
		}

		dl.state = PSP_GE_DL_STATE_PAUSED;

		currentList = &dl;
		dlQueue.push_front(id);
	} else if (currentList) {
		dl.state = PSP_GE_DL_STATE_QUEUED;
		dlQueue.push_back(id);
	} else {
		dl.state = PSP_GE_DL_STATE_RUNNING;
		currentList = &dl;
		dlQueue.push_front(id);

		drawCompleteTicks = (u64)-1;

		// TODO save context when starting the list if param is set
		guard.unlock();
		ProcessDLQueue();
	}

	return id;
}