Example #1
0
 public static void reset()
 {
     cycles       = 0;
     line         = 0;
     gpustate     = GPUState.VISIBLE;
     old_dispstat = 0;
 }
Example #2
0
        public GPUExecutor(GPUState state)
        {
            _State = state;

            // tiled rendering handling :)
            _TileMask     = 0xFFFFFFFF;
            _TileSelector = 0xFFFFFFFF;
        }
Example #3
0
        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;
        }
Example #4
0
        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;
                }
            }
        }
Example #5
0
        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);
        }