Merge branch 'master' into multi-draw

Conflicts:
	GPU/GLES/IndexGenerator.cpp
	GPU/GLES/IndexGenerator.h
This commit is contained in:
Henrik Rydgard 2012-12-21 22:58:39 +01:00
commit e26083f702
6 changed files with 67 additions and 25 deletions

View file

@ -58,6 +58,10 @@ inline int usToCycles(int us) {
return (int)(CPU_HZ / 1000000 * us); return (int)(CPU_HZ / 1000000 * us);
} }
inline u64 usToCycles(u64 us) {
return (u64)(CPU_HZ / 1000000ULL * us);
}
inline u64 cyclesToUs(u64 cycles) { inline u64 cyclesToUs(u64 cycles) {
return cycles / (CPU_HZ / 1000000); return cycles / (CPU_HZ / 1000000);
} }

View file

@ -21,6 +21,8 @@
#include "HLE.h" #include "HLE.h"
#include "../../Core/CoreTiming.h" #include "../../Core/CoreTiming.h"
const int NATIVEALARM_SIZE = 20;
struct NativeAlarm struct NativeAlarm
{ {
SceSize size; SceSize size;
@ -38,7 +40,7 @@ struct Alarm : public KernelObject
NativeAlarm alm; NativeAlarm alm;
}; };
void __KernelScheduleAlarm(Alarm *alarm, int ticks); void __KernelScheduleAlarm(Alarm *alarm, u64 ticks);
class AlarmIntrHandler : public SubIntrHandler class AlarmIntrHandler : public SubIntrHandler
{ {
@ -60,11 +62,17 @@ public:
virtual void handleResult(int result) virtual void handleResult(int result)
{ {
// A non-zero result means to reschedule. // A non-zero result means to reschedule.
// TODO: Do sysclock alarms return a different value unit?
if (result > 0) if (result > 0)
__KernelScheduleAlarm(alarm, usToCycles(result)); __KernelScheduleAlarm(alarm, (u64) usToCycles(result));
else if (result < 0) else
WARN_LOG(HLE, "Alarm requested reschedule for negative value %u, ignoring", (unsigned) result); {
if (result < 0)
WARN_LOG(HLE, "Alarm requested reschedule for negative value %u, ignoring", (unsigned) result);
// Delete the alarm if it's not rescheduled.
__ReleaseSubInterruptHandler(PSP_SYSTIMER0_INTR, alarm->GetUID());
kernelObjects.Destroy<Alarm>(alarm->GetUID());
}
} }
Alarm *alarm; Alarm *alarm;
@ -92,9 +100,9 @@ void __KernelTriggerAlarm(u64 userdata, int cyclesLate)
__TriggerInterrupt(PSP_INTR_IMMEDIATE, PSP_SYSTIMER0_INTR, uid); __TriggerInterrupt(PSP_INTR_IMMEDIATE, PSP_SYSTIMER0_INTR, uid);
} }
void __KernelScheduleAlarm(Alarm *alarm, int ticks) void __KernelScheduleAlarm(Alarm *alarm, u64 ticks)
{ {
alarm->alm.schedule = CoreTiming::GetTicks() + ticks; alarm->alm.schedule = (CoreTiming::GetTicks() + ticks) / (u64) CoreTiming::GetClockFrequencyMHz();
CoreTiming::ScheduleEvent((int) ticks, alarmTimer, alarm->GetUID()); CoreTiming::ScheduleEvent((int) ticks, alarmTimer, alarm->GetUID());
} }
@ -103,11 +111,13 @@ SceUID __KernelSetAlarm(u64 ticks, u32 handlerPtr, u32 commonPtr)
if (!alarmInitComplete) if (!alarmInitComplete)
__KernelAlarmInit(); __KernelAlarmInit();
if (!Memory::IsValidAddress(handlerPtr))
return SCE_KERNEL_ERROR_ILLEGAL_ADDR;
Alarm *alarm = new Alarm; Alarm *alarm = new Alarm;
SceUID uid = kernelObjects.Create(alarm); SceUID uid = kernelObjects.Create(alarm);
alarm->alm.size = sizeof(NativeAlarm); alarm->alm.size = NATIVEALARM_SIZE;
alarm->alm.schedule = CoreTiming::GetTicks() + ticks;
alarm->alm.handlerPtr = handlerPtr; alarm->alm.handlerPtr = handlerPtr;
alarm->alm.commonPtr = commonPtr; alarm->alm.commonPtr = commonPtr;
@ -115,29 +125,27 @@ SceUID __KernelSetAlarm(u64 ticks, u32 handlerPtr, u32 commonPtr)
if (error != 0) if (error != 0)
return error; return error;
__KernelScheduleAlarm(alarm, (int) ticks); __KernelScheduleAlarm(alarm, ticks);
return uid; return uid;
} }
SceUID sceKernelSetAlarm(SceUInt micro, u32 handlerPtr, u32 commonPtr) SceUID sceKernelSetAlarm(SceUInt micro, u32 handlerPtr, u32 commonPtr)
{ {
DEBUG_LOG(HLE, "sceKernelSetAlarm(%d, %08x, %08x)", micro, handlerPtr, commonPtr); DEBUG_LOG(HLE, "sceKernelSetAlarm(%d, %08x, %08x)", micro, handlerPtr, commonPtr);
return __KernelSetAlarm(usToCycles((int) micro), handlerPtr, commonPtr); return __KernelSetAlarm(usToCycles((u64) micro), handlerPtr, commonPtr);
} }
SceUID sceKernelSetSysClockAlarm(u32 ticksPtr, u32 handlerPtr, u32 commonPtr) SceUID sceKernelSetSysClockAlarm(u32 microPtr, u32 handlerPtr, u32 commonPtr)
{ {
u64 ticks; u64 micro;
if (Memory::IsValidAddress(ticksPtr)) if (Memory::IsValidAddress(microPtr))
ticks = Memory::Read_U64(ticksPtr); micro = Memory::Read_U64(microPtr);
// TODO: What to do when invalid?
else else
return -1; return -1;
ERROR_LOG(HLE, "UNTESTED sceKernelSetSysClockAlarm(%lld, %08x, %08x)", ticks, handlerPtr, commonPtr); DEBUG_LOG(HLE, "sceKernelSetSysClockAlarm(%lld, %08x, %08x)", micro, handlerPtr, commonPtr);
// TODO: Is this precise or is this relative? return __KernelSetAlarm(usToCycles(micro), handlerPtr, commonPtr);
return __KernelSetAlarm(ticks, handlerPtr, commonPtr);
} }
int sceKernelCancelAlarm(SceUID uid) int sceKernelCancelAlarm(SceUID uid)
@ -152,6 +160,30 @@ int sceKernelCancelAlarm(SceUID uid)
int sceKernelReferAlarmStatus(SceUID uid, u32 infoPtr) int sceKernelReferAlarmStatus(SceUID uid, u32 infoPtr)
{ {
ERROR_LOG(HLE, "UNIMPL sceKernelReferAlarmStatus(%08x, %08x)", uid, infoPtr); u32 error;
return -1; Alarm *alarm = kernelObjects.Get<Alarm>(uid, error);
if (!alarm)
{
ERROR_LOG(HLE, "sceKernelReferAlarmStatus(%08x, %08x): invalid alarm", uid, infoPtr);
return error;
}
DEBUG_LOG(HLE, "sceKernelReferAlarmStatus(%08x, %08x)", uid, infoPtr);
if (!Memory::IsValidAddress(infoPtr))
return -1;
u32 size = Memory::Read_U32(infoPtr);
// Alarms actually respect size and write (kinda) what it can hold.
if (size > 0)
Memory::Write_U32(alarm->alm.size, infoPtr);
if (size > 4)
Memory::Write_U64(alarm->alm.schedule, infoPtr + 4);
if (size > 12)
Memory::Write_U32(alarm->alm.handlerPtr, infoPtr + 12);
if (size > 16)
Memory::Write_U32(alarm->alm.commonPtr, infoPtr + 16);
return 0;
} }

View file

@ -52,15 +52,14 @@ public:
void TranslateRectangles(int numVerts, const u8 *inds, int offset); void TranslateRectangles(int numVerts, const u8 *inds, int offset);
void TranslateRectangles(int numVerts, const u16 *inds, int offset); void TranslateRectangles(int numVerts, const u16 *inds, int offset);
void TranslateList(int numVerts, const u8 *inds, int offset); void TranslateList(int numVerts, const u8 *inds, int offset);
void TranslateStrip(int numVerts, const u8 *inds, int offset); void TranslateStrip(int numVerts, const u8 *inds, int offset);
void TranslateFan(int numVerts, const u8 *inds, int offset); void TranslateFan(int numVerts, const u8 *inds, int offset);
void TranslateList(int numVerts, const u16 *inds, int offset); void TranslateList(int numVerts, const u16 *inds, int offset);
void TranslateStrip(int numVerts, const u16 *inds, int offset); void TranslateStrip(int numVerts, const u16 *inds, int offset);
void TranslateFan(int numVerts, const u16 *inds, int offset); void TranslateFan(int numVerts, const u16 *inds, int offset);
int MaxIndex() { return index_; } int MaxIndex() { return index_; }
int VertexCount() { return count_; } int VertexCount() { return count_; }
bool Empty() { return index_ == 0; } bool Empty() { return index_ == 0; }

View file

@ -498,6 +498,10 @@ namespace MainWindow
g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer; g_Config.bDisplayFramebuffer = !g_Config.bDisplayFramebuffer;
UpdateMenus(); UpdateMenus();
break; break;
case ID_OPTIONS_FASTMEMORY:
g_Config.bFastMemory = !g_Config.bFastMemory;
UpdateMenus();
break;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

@ -1 +1 @@
Subproject commit 6bd9d261e6014d371b917e50d2e18d5fc986a8c3 Subproject commit 54acddd54469a88aadbaf0e69088aad504b5e1e4

View file

@ -59,6 +59,9 @@ tests_good = [
"string/string", "string/string",
"gpu/callbacks/ge_callbacks", "gpu/callbacks/ge_callbacks",
"threads/alarm/alarm", "threads/alarm/alarm",
"threads/alarm/cancel/cancel",
"threads/alarm/refer/refer",
"threads/alarm/set/set",
"threads/events/events", "threads/events/events",
"threads/events/cancel/cancel", "threads/events/cancel/cancel",
"threads/events/clear/clear", "threads/events/clear/clear",