Ejemplo n.º 1
0
u32 GPUCommon::DrawSync(int mode) {
    // FIXME: Workaround for displaylists sometimes hanging unprocessed.  Not yet sure of the cause.
    if (g_Config.bSeparateCPUThread) {
        // FIXME: Workaround for displaylists sometimes hanging unprocessed.  Not yet sure of the cause.
        ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
        // Sync first, because the CPU is usually faster than the emulated GPU.
        SyncThread();
    }

    easy_guard guard(listLock);
    if (mode < 0 || mode > 1)
        return SCE_KERNEL_ERROR_INVALID_MODE;

    if (mode == 0) {
        if (!__KernelIsDispatchEnabled()) {
            return SCE_KERNEL_ERROR_CAN_NOT_WAIT;
        }
        if (__IsInInterrupt()) {
            return SCE_KERNEL_ERROR_ILLEGAL_CONTEXT;
        }

        if (drawCompleteTicks > CoreTiming::GetTicks()) {
            __GeWaitCurrentThread(WAITTYPE_GEDRAWSYNC, 1, "GeDrawSync");
        } else {
            for (int i = 0; i < DisplayListMaxCount; ++i) {
                if (dls[i].state == PSP_GE_DL_STATE_COMPLETED) {
                    dls[i].state = PSP_GE_DL_STATE_NONE;
                }
            }
        }
        return 0;
    }

    // If there's no current list, it must be complete.
    DisplayList *top = NULL;
    for (auto it = dlQueue.begin(), end = dlQueue.end(); it != end; ++it) {
        if (dls[*it].state != PSP_GE_DL_STATE_COMPLETED) {
            top = &dls[*it];
            break;
        }
    }
    if (!top || top->state == PSP_GE_DL_STATE_COMPLETED)
        return PSP_GE_LIST_COMPLETED;

    if (currentList->pc == currentList->stall)
        return PSP_GE_LIST_STALLING;

    return PSP_GE_LIST_DRAWING;
}
Ejemplo n.º 2
0
bool DIRECTX9_GPU::FramebufferDirty() {
	// FIXME: Workaround for displaylists sometimes hanging unprocessed.  Not yet sure of the cause.
	if (g_Config.bSeparateCPUThread) {
		// FIXME: Workaround for displaylists sometimes hanging unprocessed.  Not yet sure of the cause.
		ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
		// Allow it to process fully before deciding if it's dirty.
		SyncThread();
	}
	VirtualFramebufferDX9 *vfb = framebufferManager_.GetDisplayFBO();
	if (vfb) {
		bool dirty = vfb->dirtyAfterDisplay;
		vfb->dirtyAfterDisplay = false;
		return dirty;
	}
	return true;
}
Ejemplo n.º 3
0
void AsyncIOManager::DoState(PointerWrap &p) {
	auto s = p.Section("AsyncIoManager", 1, 2);
	if (!s)
		return;

	SyncThread();
	lock_guard guard(resultsLock_);
	p.Do(resultsPending_);
	if (s >= 2) {
		p.Do(results_);
	} else {
		std::map<u32, size_t> oldResults;
		p.Do(oldResults);
		for (auto it = oldResults.begin(), end = oldResults.end(); it != end; ++it) {
			results_[it->first] = AsyncIOResult(it->second);
		}
	}
}
Ejemplo n.º 4
0
int GPUCommon::ListSync(int listid, int mode) {
	// FIXME: Workaround for displaylists sometimes hanging unprocessed.  Not yet sure of the cause.
	ScheduleEvent(GPU_EVENT_PROCESS_QUEUE);
	// Sync first, because the CPU is usually faster than the emulated GPU.
	SyncThread();

	easy_guard guard(listLock);
	if (listid < 0 || listid >= DisplayListMaxCount)
		return SCE_KERNEL_ERROR_INVALID_ID;

	if (mode < 0 || mode > 1)
		return SCE_KERNEL_ERROR_INVALID_MODE;

	DisplayList& dl = dls[listid];
	if (mode == 1) {
		switch (dl.state) {
		case PSP_GE_DL_STATE_QUEUED:
			if (dl.interrupted)
				return PSP_GE_LIST_PAUSED;
			return PSP_GE_LIST_QUEUED;

		case PSP_GE_DL_STATE_RUNNING:
			if (dl.pc == dl.stall)
				return PSP_GE_LIST_STALLING;
			return PSP_GE_LIST_DRAWING;

		case PSP_GE_DL_STATE_COMPLETED:
			return PSP_GE_LIST_COMPLETED;

		case PSP_GE_DL_STATE_PAUSED:
			return PSP_GE_LIST_PAUSED;

		default:
			return SCE_KERNEL_ERROR_INVALID_ID;
		}
	}

	if (dl.waitTicks > CoreTiming::GetTicks()) {
		__GeWaitCurrentThread(WAITTYPE_GELISTSYNC, listid, "GeListSync");
	}
	return PSP_GE_LIST_COMPLETED;
}