public static void reset() { cycles = 0; line = 0; gpustate = GPUState.VISIBLE; old_dispstat = 0; }
public GPUExecutor(GPUState state) { _State = state; // tiled rendering handling :) _TileMask = 0xFFFFFFFF; _TileSelector = 0xFFFFFFFF; }
public GPUStateCapture(GPUState captureFrom) { _RegValues = new UInt32[captureFrom.RegValues.Length]; for (UInt32 i = 0; i < _RegValues.Length; ++i) { _RegValues[i] = captureFrom.RegValues[i]; } _PixelShader = captureFrom.PixelShader; _VertexShader = captureFrom.VertexShader; }
public static void work() { cycles += CPU.newticks; bool runagain = true; while (runagain) { runagain = false; switch (gpustate) { case GPUState.VISIBLE: if (cycles >= 1008) // 960 is drawing time { runagain = true; cycles -= 1008; gpustate = GPUState.HBLANK; GBRegs.Sect_display.DISPSTAT_H_Blank_flag.write(1); DMA.new_hblank = true; if (GBRegs.Sect_display.DISPSTAT_H_Blank_IRQ_Enable.on()) { IRP.set_irp_bit(IRP.IRPMASK_LCD_H_Blank); } old_dispstat = GBRegs.data[4]; GPU.once_per_hblank(); GPU.next_line(line); } break; case GPUState.HBLANK: if (cycles >= 224) // 272 { runagain = true; cycles -= 224; nextline(); GBRegs.Sect_display.DISPSTAT_H_Blank_flag.write(0); DMA.new_hblank = false; if (line < 160) { gpustate = GPUState.VISIBLE; } else { gpustate = GPUState.VBLANK; GPU.refpoint_update_all(); Cheats.apply_cheats(); GBRegs.Sect_display.DISPSTAT_V_Blank_flag.write(1); DMA.new_vblank = true; if (GBRegs.Sect_display.DISPSTAT_V_Blank_IRQ_Enable.on()) { IRP.set_irp_bit(IRP.IRPMASK_LCD_V_Blank); } } old_dispstat = GBRegs.data[4]; } break; case GPUState.VBLANK: if (cycles >= 1008) { runagain = true; cycles -= 1008; gpustate = GPUState.VBLANKHBLANK; GBRegs.Sect_display.DISPSTAT_H_Blank_flag.write(1); //DMA.new_hblank = true; //!!! don't do here! if (GBRegs.Sect_display.DISPSTAT_H_Blank_IRQ_Enable.on()) { IRP.set_irp_bit(IRP.IRPMASK_LCD_H_Blank); // Note that no H-Blank interrupts are generated within V-Blank period. Really? } old_dispstat = GBRegs.data[4]; } break; case GPUState.VBLANKHBLANK: if (cycles >= 224) { runagain = true; cycles -= 224; nextline(); GBRegs.Sect_display.DISPSTAT_H_Blank_flag.write(0); DMA.new_hblank = false; GPU.once_per_hblank(); if (line == 0) { gpio.framecount++; gpio.update_time(); gpustate = GPUState.VISIBLE; //GPU.next_line(line); GBRegs.Sect_display.DISPSTAT_V_Blank_flag.write(0); DMA.new_vblank = false; } else { gpustate = GPUState.VBLANK; if (line == 227) { //GBRegs.Sect_display.DISPSTAT_V_Blank_flag.write(0); } } old_dispstat = GBRegs.data[4]; } break; } } }
static public ParsedData Parse(RawDumpData raw) { ParsedData ret = new ParsedData(); var packetsMap = new Dictionary <RawPacket, ParsedPacket>(); // create drawcall list ret._ShaderCache = new GPUShaderCache(); ret._DrawCalls = new List <ParsedDrawCall>(); ret._DrawGroups = new List <ParsedDrawGroup>(); // prepare GPU state for the duration of parsing GPUState parseState = new GPUState(ret._ShaderCache); GPUExecutor parseExec = new GPUExecutor(parseState); // parse all packets int packedIndex = 1; int drawCallIndex = 1; int drawGroupIndex = 1; ParsedDrawCall drawCall = null; ParsedDrawGroup drawGroup = null; foreach (var rawPacket in raw.Packets) { // start new drawcall if (drawCall == null) { drawCall = new ParsedDrawCall(drawCallIndex); ret._DrawCalls.Add(drawCall); drawCallIndex += 1; } // execute packet GPUCommandOutput executeOutput = new GPUCommandOutput(); var executionResult = parseExec.ExecutePacket(rawPacket, executeOutput); if (executionResult != GPUExecutorResult.Invalid) { // add data packetsMap[rawPacket] = ParsedPacket.Parse(rawPacket, packedIndex, drawCall, executeOutput); ++packedIndex; } // restart after each drawcall if (packetsMap[rawPacket].Output.IsDraw()) { // capture final state at each drawcall if (drawCall != null) { drawCall.CapturedState = new GPUStateCapture(parseState); // extract the viewport/render target settings for the draw call - required to match it to the draw group var stateRenderTargets = new GPUStateRenderTargets(drawCall.CapturedState); var stateViewport = new GPUStateCaptureViewport(drawCall.CapturedState); // determine if we should add this draw call to current draw group if ((drawGroup != null) && drawGroup.Compatible(stateViewport, stateRenderTargets)) { drawGroup.AddDrawCall(drawCall); } else { drawGroup = new ParsedDrawGroup(drawGroupIndex++, stateViewport, stateRenderTargets); drawGroup.AddDrawCall(drawCall); ret._DrawGroups.Add(drawGroup); } } // reset drawCall = null; } } return(ret); }