diff options
| author | Ryan Houdek <Sonicadvance1@gmail.com> | 2013-04-14 20:43:42 -0500 |
|---|---|---|
| committer | Ryan Houdek <Sonicadvance1@gmail.com> | 2013-04-14 20:43:42 -0500 |
| commit | 37b67971e7def8dcd0dae3209afc6c69b52d0609 (patch) | |
| tree | 510eccb41b0653225ec3af6bf02b425c72a195e1 /Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp | |
| parent | bde7ea00ef9fd625a4e453ee9598fc20382a35a5 (diff) | |
| parent | b91930a2d4742ec001d0b1df1abe938da7527d03 (diff) | |
Merge remote-tracking branch 'origin/master' into Android-trash
Conflicts:
Source/Plugins/Plugin_VideoSoftware/Src/SWRenderer.cpp
Diffstat (limited to 'Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp | 411 |
1 files changed, 207 insertions, 204 deletions
diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp index 1cd92708a4..20deca971a 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWCommandProcessor.cpp @@ -12,7 +12,7 @@ // A copy of the GPL 2.0 should have been included with the program. // If not, see http://www.gnu.org/licenses/ -// Official SVN repository and contact information can be found at +// Official Git repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ #include "Common.h" @@ -37,7 +37,7 @@ namespace SWCommandProcessor enum { GATHER_PIPE_SIZE = 32, - INT_CAUSE_CP = 0x800 + INT_CAUSE_CP = 0x800 }; // STATE_TO_SAVE @@ -83,17 +83,17 @@ void UpdateInterrupts_Wrapper(u64 userdata, int cyclesLate) inline bool AtBreakpoint() { - return cpreg.ctrl.BPEnable && (cpreg.readptr == cpreg.breakpt); + return cpreg.ctrl.BPEnable && (cpreg.readptr == cpreg.breakpt); } void Init() { - cpreg.status.Hex = 0; + cpreg.status.Hex = 0; cpreg.status.CommandIdle = 1; cpreg.status.ReadIdle = 1; - cpreg.ctrl.Hex = 0; - cpreg.clear.Hex = 0; + cpreg.ctrl.Hex = 0; + cpreg.clear.Hex = 0; cpreg.bboxleft = 0; cpreg.bboxtop = 0; @@ -104,15 +104,15 @@ void Init() et_UpdateInterrupts = CoreTiming::RegisterEvent("UpdateInterrupts", UpdateInterrupts_Wrapper); - // internal buffer position - readPos = 0; - writePos = 0; + // internal buffer position + readPos = 0; + writePos = 0; - interruptSet = false; - interruptWaiting = false; + interruptSet = false; + interruptWaiting = false; - g_pVideoData = 0; - g_bSkipCurrentFrame = false; + g_pVideoData = 0; + g_bSkipCurrentFrame = false; } void Shutdown() @@ -121,31 +121,32 @@ void Shutdown() void RunGpu() { - if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - { - // We are going to do FP math on the main thread so have to save the current state - FPURoundMode::SaveSIMDState(); - FPURoundMode::LoadDefaultSIMDState(); - - // run the opcode decoder - do { - RunBuffer(); - } while (cpreg.ctrl.GPReadEnable && !AtBreakpoint() && cpreg.readptr != cpreg.writeptr); - - FPURoundMode::LoadSIMDState(); - } + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) + { + // We are going to do FP math on the main thread so have to save the current state + FPURoundMode::SaveSIMDState(); + FPURoundMode::LoadDefaultSIMDState(); + + // run the opcode decoder + do + { + RunBuffer(); + } while (cpreg.ctrl.GPReadEnable && !AtBreakpoint() && cpreg.readptr != cpreg.writeptr); + + FPURoundMode::LoadSIMDState(); + } } void Read16(u16& _rReturnValue, const u32 _Address) { - u32 regAddr = (_Address & 0xFFF) >> 1; - - DEBUG_LOG(COMMANDPROCESSOR, "(r): 0x%08x : 0x%08x", _Address, ((u16*)&cpreg)[regAddr]); - - if (regAddr < 0x20) - _rReturnValue = ((u16*)&cpreg)[regAddr]; - else - _rReturnValue = 0; + u32 regAddr = (_Address & 0xFFF) >> 1; + + DEBUG_LOG(COMMANDPROCESSOR, "(r): 0x%08x : 0x%08x", _Address, ((u16*)&cpreg)[regAddr]); + + if (regAddr < 0x20) + _rReturnValue = ((u16*)&cpreg)[regAddr]; + else + _rReturnValue = 0; } void Write16(const u16 _Value, const u32 _Address) @@ -162,14 +163,14 @@ void Write16(const u16 _Value, const u32 _Address) case CTRL_REGISTER: { - cpreg.ctrl.Hex = _Value; + cpreg.ctrl.Hex = _Value; DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | CPULINK %s | BP %s || BPIntEnable %s | OvF %s | UndF %s" - , cpreg.ctrl.GPReadEnable ? "ON" : "OFF" - , cpreg.ctrl.GPLinkEnable ? "ON" : "OFF" - , cpreg.ctrl.BPEnable ? "ON" : "OFF" - , cpreg.ctrl.BreakPointIntEnable ? "ON" : "OFF" + , cpreg.ctrl.GPReadEnable ? "ON" : "OFF" + , cpreg.ctrl.GPLinkEnable ? "ON" : "OFF" + , cpreg.ctrl.BPEnable ? "ON" : "OFF" + , cpreg.ctrl.BreakPointIntEnable ? "ON" : "OFF" , cpreg.ctrl.FifoOverflowIntEnable ? "ON" : "OFF" , cpreg.ctrl.FifoUnderflowIntEnable ? "ON" : "OFF" ); @@ -178,14 +179,14 @@ void Write16(const u16 _Value, const u32 _Address) case CLEAR_REGISTER: { - UCPClearReg tmpClear(_Value); + UCPClearReg tmpClear(_Value); - if (tmpClear.ClearFifoOverflow) - cpreg.status.OverflowHiWatermark = 0; - if (tmpClear.ClearFifoUnderflow) - cpreg.status.UnderflowLoWatermark = 0; + if (tmpClear.ClearFifoOverflow) + cpreg.status.OverflowHiWatermark = 0; + if (tmpClear.ClearFifoUnderflow) + cpreg.status.UnderflowLoWatermark = 0; - INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value); + INFO_LOG(COMMANDPROCESSOR,"\t write to CLEAR_REGISTER : %04x",_Value); } break; @@ -195,77 +196,77 @@ void Write16(const u16 _Value, const u32 _Address) DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_TOKEN_REGISTER : %04x", _Value); break; - case FIFO_BASE_LO: - WriteLow ((u32 &)cpreg.fifobase, _Value & 0xFFE0); + case FIFO_BASE_LO: + WriteLow ((u32 &)cpreg.fifobase, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_LO. FIFO base is : %08x", cpreg.fifobase); break; - case FIFO_BASE_HI: - WriteHigh((u32 &)cpreg.fifobase, _Value); + case FIFO_BASE_HI: + WriteHigh((u32 &)cpreg.fifobase, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BASE_HI. FIFO base is : %08x", cpreg.fifobase); break; - case FIFO_END_LO: - WriteLow ((u32 &)cpreg.fifoend, _Value & 0xFFE0); + case FIFO_END_LO: + WriteLow ((u32 &)cpreg.fifoend, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_LO. FIFO end is : %08x", cpreg.fifoend); break; case FIFO_END_HI: - WriteHigh((u32 &)cpreg.fifoend, _Value); + WriteHigh((u32 &)cpreg.fifoend, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_END_HI. FIFO end is : %08x", cpreg.fifoend); break; case FIFO_WRITE_POINTER_LO: - WriteLow ((u32 &)cpreg.writeptr, _Value & 0xFFE0); + WriteLow ((u32 &)cpreg.writeptr, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_LO. write ptr is : %08x", cpreg.writeptr); break; case FIFO_WRITE_POINTER_HI: - WriteHigh ((u32 &)cpreg.writeptr, _Value); + WriteHigh ((u32 &)cpreg.writeptr, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_WRITE_POINTER_HI. write ptr is : %08x", cpreg.writeptr); break; case FIFO_READ_POINTER_LO: - WriteLow ((u32 &)cpreg.readptr, _Value & 0xFFE0); + WriteLow ((u32 &)cpreg.readptr, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_LO. read ptr is : %08x", cpreg.readptr); break; case FIFO_READ_POINTER_HI: - WriteHigh ((u32 &)cpreg.readptr, _Value); + WriteHigh ((u32 &)cpreg.readptr, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_READ_POINTER_HI. read ptr is : %08x", cpreg.readptr); break; - case FIFO_HI_WATERMARK_LO: - WriteLow ((u32 &)cpreg.hiwatermark, _Value); + case FIFO_HI_WATERMARK_LO: + WriteLow ((u32 &)cpreg.hiwatermark, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_LO. hiwatermark is : %08x", cpreg.hiwatermark); break; case FIFO_HI_WATERMARK_HI: - WriteHigh ((u32 &)cpreg.hiwatermark, _Value); + WriteHigh ((u32 &)cpreg.hiwatermark, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI. hiwatermark is : %08x", cpreg.hiwatermark); break; case FIFO_LO_WATERMARK_LO: - WriteLow ((u32 &)cpreg.lowatermark, _Value); + WriteLow ((u32 &)cpreg.lowatermark, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_LO. lowatermark is : %08x", cpreg.lowatermark); break; case FIFO_LO_WATERMARK_HI: - WriteHigh ((u32 &)cpreg.lowatermark, _Value); + WriteHigh ((u32 &)cpreg.lowatermark, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_LO_WATERMARK_HI. lowatermark is : %08x", cpreg.lowatermark); break; - case FIFO_BP_LO: - WriteLow ((u32 &)cpreg.breakpt, _Value & 0xFFE0); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_LO. breakpt is : %08x", cpreg.breakpt); + case FIFO_BP_LO: + WriteLow ((u32 &)cpreg.breakpt, _Value & 0xFFE0); + DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_LO. breakpoint is : %08x", cpreg.breakpt); break; case FIFO_BP_HI: - WriteHigh ((u32 &)cpreg.breakpt, _Value); - DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_HI. breakpt is : %08x", cpreg.breakpt); + WriteHigh ((u32 &)cpreg.breakpt, _Value); + DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_BP_HI. breakpoint is : %08x", cpreg.breakpt); break; - case FIFO_RW_DISTANCE_LO: - WriteLow ((u32 &)cpreg.rwdistance, _Value & 0xFFE0); + case FIFO_RW_DISTANCE_LO: + WriteLow ((u32 &)cpreg.rwdistance, _Value & 0xFFE0); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_LO. rwdistance is : %08x", cpreg.rwdistance); break; case FIFO_RW_DISTANCE_HI: - WriteHigh ((u32 &)cpreg.rwdistance, _Value); + WriteHigh ((u32 &)cpreg.rwdistance, _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_RW_DISTANCE_HI. rwdistance is : %08x", cpreg.rwdistance); break; - } + } - RunGpu(); + RunGpu(); } void Read32(u32& _rReturnValue, const u32 _Address) @@ -282,35 +283,35 @@ void Write32(const u32 _Data, const u32 _Address) void STACKALIGN GatherPipeBursted() { if (cpreg.ctrl.GPLinkEnable) - { - DEBUG_LOG(COMMANDPROCESSOR,"\t WGP burst. write thru : %08x", cpreg.writeptr); + { + DEBUG_LOG(COMMANDPROCESSOR,"\t WGP burst. write thru : %08x", cpreg.writeptr); - if (cpreg.writeptr == cpreg.fifoend) - cpreg.writeptr = cpreg.fifobase; - else - cpreg.writeptr += GATHER_PIPE_SIZE; + if (cpreg.writeptr == cpreg.fifoend) + cpreg.writeptr = cpreg.fifobase; + else + cpreg.writeptr += GATHER_PIPE_SIZE; - Common::AtomicAdd(cpreg.rwdistance, GATHER_PIPE_SIZE); - } + Common::AtomicAdd(cpreg.rwdistance, GATHER_PIPE_SIZE); + } - RunGpu(); + RunGpu(); } void UpdateInterrupts(u64 userdata) { - if (userdata) + if (userdata) { interruptSet = true; - INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true); + INFO_LOG(COMMANDPROCESSOR,"Interrupt set"); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true); } else { - interruptSet = false; + interruptSet = false; INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared"); - ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); + ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false); } - interruptWaiting = false; + interruptWaiting = false; } void UpdateInterruptsFromVideoBackend(u64 userdata) @@ -320,136 +321,138 @@ void UpdateInterruptsFromVideoBackend(u64 userdata) void ReadFifo() { - bool canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; - bool atBreakpoint = AtBreakpoint(); - - if (canRead && !atBreakpoint) - { - // read from fifo - u8 *ptr = Memory::GetPointer(cpreg.readptr); - int bytesRead = 0; - - do - { - // copy to buffer - memcpy(&commandBuffer[writePos], ptr, GATHER_PIPE_SIZE); - writePos += GATHER_PIPE_SIZE; - bytesRead += GATHER_PIPE_SIZE; - - if (cpreg.readptr == cpreg.fifoend) - { - cpreg.readptr = cpreg.fifobase; - ptr = Memory::GetPointer(cpreg.readptr); - } - else - { - cpreg.readptr += GATHER_PIPE_SIZE; - ptr += GATHER_PIPE_SIZE; - } - - canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; - atBreakpoint = AtBreakpoint(); - } while (canRead && !atBreakpoint); - - Common::AtomicAdd(cpreg.rwdistance, -bytesRead); - } + bool canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; + bool atBreakpoint = AtBreakpoint(); + + if (canRead && !atBreakpoint) + { + // read from fifo + u8 *ptr = Memory::GetPointer(cpreg.readptr); + int bytesRead = 0; + + do + { + // copy to buffer + memcpy(&commandBuffer[writePos], ptr, GATHER_PIPE_SIZE); + writePos += GATHER_PIPE_SIZE; + bytesRead += GATHER_PIPE_SIZE; + + if (cpreg.readptr == cpreg.fifoend) + { + cpreg.readptr = cpreg.fifobase; + ptr = Memory::GetPointer(cpreg.readptr); + } + else + { + cpreg.readptr += GATHER_PIPE_SIZE; + ptr += GATHER_PIPE_SIZE; + } + + canRead = cpreg.readptr != cpreg.writeptr && writePos < (int)maxCommandBufferWrite; + atBreakpoint = AtBreakpoint(); + } while (canRead && !atBreakpoint); + + Common::AtomicAdd(cpreg.rwdistance, -bytesRead); + } } void SetStatus() { - // overflow check - if (cpreg.rwdistance > cpreg.hiwatermark) - cpreg.status.OverflowHiWatermark = 1; - - // underflow check - if (cpreg.rwdistance < cpreg.lowatermark) - cpreg.status.UnderflowLoWatermark = 1; - - // breakpoint - if (cpreg.ctrl.BPEnable) - { - if (cpreg.breakpt == cpreg.readptr) - { - if (!cpreg.status.Breakpoint) - INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %x", cpreg.readptr); - cpreg.status.Breakpoint = 1; - } - } - else - { - if (cpreg.status.Breakpoint) - INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %x", cpreg.readptr); - cpreg.status.Breakpoint = 0; - } - - cpreg.status.ReadIdle = cpreg.readptr == cpreg.writeptr; - - bool bpInt = cpreg.status.Breakpoint && cpreg.ctrl.BreakPointIntEnable; - bool ovfInt = cpreg.status.OverflowHiWatermark && cpreg.ctrl.FifoOverflowIntEnable; - bool undfInt = cpreg.status.UnderflowLoWatermark && cpreg.ctrl.FifoUnderflowIntEnable; - - bool interrupt = bpInt || ovfInt || undfInt; - - if (interrupt != interruptSet && !interruptWaiting) - { - u64 userdata = interrupt?1:0; - if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) - { - interruptWaiting = true; - SWCommandProcessor::UpdateInterruptsFromVideoBackend(userdata); - } - else - SWCommandProcessor::UpdateInterrupts(userdata); - } + // overflow check + if (cpreg.rwdistance > cpreg.hiwatermark) + cpreg.status.OverflowHiWatermark = 1; + + // underflow check + if (cpreg.rwdistance < cpreg.lowatermark) + cpreg.status.UnderflowLoWatermark = 1; + + // breakpoint + if (cpreg.ctrl.BPEnable) + { + if (cpreg.breakpt == cpreg.readptr) + { + if (!cpreg.status.Breakpoint) + INFO_LOG(COMMANDPROCESSOR, "Hit breakpoint at %x", cpreg.readptr); + cpreg.status.Breakpoint = 1; + } + } + else + { + if (cpreg.status.Breakpoint) + INFO_LOG(COMMANDPROCESSOR, "Cleared breakpoint at %x", cpreg.readptr); + cpreg.status.Breakpoint = 0; + } + + cpreg.status.ReadIdle = cpreg.readptr == cpreg.writeptr; + + bool bpInt = cpreg.status.Breakpoint && cpreg.ctrl.BreakPointIntEnable; + bool ovfInt = cpreg.status.OverflowHiWatermark && cpreg.ctrl.FifoOverflowIntEnable; + bool undfInt = cpreg.status.UnderflowLoWatermark && cpreg.ctrl.FifoUnderflowIntEnable; + + bool interrupt = bpInt || ovfInt || undfInt; + + if (interrupt != interruptSet && !interruptWaiting) + { + u64 userdata = interrupt?1:0; + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread) + { + interruptWaiting = true; + SWCommandProcessor::UpdateInterruptsFromVideoBackend(userdata); + } + else + { + SWCommandProcessor::UpdateInterrupts(userdata); + } + } } bool RunBuffer() { - // fifo is read 32 bytes at a time - // read fifo data to internal buffer - if (cpreg.ctrl.GPReadEnable) - ReadFifo(); - - SetStatus(); - - _dbg_assert_(COMMANDPROCESSOR, writePos >= readPos); - - g_pVideoData = &commandBuffer[readPos]; - - u32 availableBytes = writePos - readPos; - - while (OpcodeDecoder::CommandRunnable(availableBytes)) - { - cpreg.status.CommandIdle = 0; - - OpcodeDecoder::Run(availableBytes); - - // if data was read by the opcode decoder then the video data pointer changed - readPos = (u32)(g_pVideoData - &commandBuffer[0]); - _dbg_assert_(VIDEO, writePos >= readPos); - availableBytes = writePos - readPos; - } - - cpreg.status.CommandIdle = 1; - - bool ranDecoder = false; - - // move data remaing in command buffer - if (readPos > 0) - { - memmove(&commandBuffer[0], &commandBuffer[readPos], availableBytes); - writePos -= readPos; - readPos = 0; - - ranDecoder = true; - } - - return ranDecoder; + // fifo is read 32 bytes at a time + // read fifo data to internal buffer + if (cpreg.ctrl.GPReadEnable) + ReadFifo(); + + SetStatus(); + + _dbg_assert_(COMMANDPROCESSOR, writePos >= readPos); + + g_pVideoData = &commandBuffer[readPos]; + + u32 availableBytes = writePos - readPos; + + while (OpcodeDecoder::CommandRunnable(availableBytes)) + { + cpreg.status.CommandIdle = 0; + + OpcodeDecoder::Run(availableBytes); + + // if data was read by the opcode decoder then the video data pointer changed + readPos = (u32)(g_pVideoData - &commandBuffer[0]); + _dbg_assert_(VIDEO, writePos >= readPos); + availableBytes = writePos - readPos; + } + + cpreg.status.CommandIdle = 1; + + bool ranDecoder = false; + + // move data remaing in command buffer + if (readPos > 0) + { + memmove(&commandBuffer[0], &commandBuffer[readPos], availableBytes); + writePos -= readPos; + readPos = 0; + + ranDecoder = true; + } + + return ranDecoder; } void SetRendering(bool enabled) { - g_bSkipCurrentFrame = !enabled; + g_bSkipCurrentFrame = !enabled; } } // end of namespace SWCommandProcessor |
