As far as I can tell, it has nothing to do with the mipmap/half_scale functionality, but does change based on the width of the destination texture (and the destination texture is half the width if half_scale is set). The comment that was there (which dates back to the initial megacommit) seems to not have accounted for the width aspect; it was first used as an actual stride in bbbe898839 (the first commit that used it at all).
Since ccf92a3e56, recording fifologs multiple times after launching dolphin caused all initial state to not be saved (the initial contents of bpmem, cpmem, etc were all zeroed out). For some games, this was not noticeable, as most registers were set each frame, but for others, this resulted in completely broken fifologs. (Note that recording fifologs also required 05181f6b88 and 9e0755a598 to be cherry-picked due to other, since fixed, regressions.)
This was because previously, `Renderer::CheckFifoRecording` was called every frame, but ccf92a3e56 changed it into a callback (`m_end_of_frame_event`) that was removed when recording ended. Thus, before, `OpcodeDecoder::g_record_fifo_data = IsRecording()` was called when `IsRecording()` returned false, but after that commit `g_record_fifo_data` never got changed back to false, so the check for `was_recording` only ever passed on the first fifolog recorded (even after stopping and starting a game).
There may still be another issue lurking, as I'm not sure if all broken fifologs were caused by recording multiple fifologs (for instance, on https://bugs.dolphin-emu.org/issues/13377, only one fifolog was initially uploaded, but it was affected by an issue with the same symptoms as this).
The old calculation was stride * (max_index + 1), which fails if stride is less than the size of a component (for instance, if float XYZ positions are used, and the stride was set to 4 (i.e. sizeof(float)) instead of 12 (i.e. 3 * sizeof(float)), it would be missing the last 8 bytes of the final element in the array. Or, if stride was set to 0, then no bytes would be recorded at all (though that's not a useful configuration so it's unlikely to actually exist).
I'm not aware of any games affected by this issue.
This should fix recording the wall in the staircase leading to the basement in Luigi's Mansion (though I haven't tested it, as I don't own a copy of Luigi's Mansion). This uses NormalIndex3, and the index for the normal vector (generally 0x02XX or 0x01XX) there is always lower than the tangent or binormal (generally 0x07XX). Other games seem to usually have a similar range of indices for the normal, tangent, and binormal, so this issue wouldn't affect them.
In most cases, games will use the same type for all vertex components (either Index8 or Index16 or Direct). However, RS2's deflection towers use Index16 for the texture coordinate and Index8 for everything else, meaning the texture coordinates were recorded incorrectly (the first byte was used, so only indices 0 and 1 were recorded instead of 0 through 0x0192). Worse still, some background elements in RS2 use direct positions but indexed normals or texture coordinates, and those would not be recorded at all.
This is a regression from b5fd35f951.
This also changes the behavior for the invalid gamma value, which was confirmed to behave the same as 2.2.
Note that currently, the gamma value is only used for XFB copies, even though hardware testing indicates it also works for EFB copies. This will be changed in a later commit.
The size variable started to be unused when I created std::array variants of ReadArray, but we should follow it in case any files have fewer registers stored than they should (otherwise the remaining registers would end up with garbage data from later in the fifolog). Though, there probably aren't many fifologs where this is relevant.
This option has always existed since it's used by FifoCI, but now it can be changed at runtime. Looping is something that should almost always be on, but it can be useful to turn it off when frame-dumping is enabled so that hundreds of copies of the same frame aren't created. Before, turning it off required restarting Dolphin.
The actual values don't matter since we overwrite all of the relevant fields, but other bits were not initialized (e.g. the top 12 bits of X10Y10), so the warning was semi-valid.
Previously, EFB copies would be in the middle of other objects, as objects were only split on primitive data. A distinct object for each EFB copy makes them easier to spot, but does also mean there are more objects that do nothing when disabled (as disabling an object only skips primitive data, and there is no primitive data for EFB copies).
This also adds the commands after the last primitive data but before the next frame as a unique object; this is mainly just the XFB copy. It's nice to have these visible, though disabling the object does nothing since only primitive data is disabled and there is no primitive data in this case.
This fixes the bad rendering on the first frame when using the software renderer: the software renderer's Z buffer started out at 0, but most games clear it to 0xffffff instead; this means that things don't render correctly except for in the regions where the screen was cleared by an EFB copy earlier in the frame.
SPDX standardizes how source code conveys its copyright and licensing
information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX
tags are adopted in many large projects, including things like the Linux
kernel.
If the number of objects varied, this would result in either missing objects on some frames, or too many objects on some frames; the latter case could cause crashes. Since it used the current frame to get the count, if the FIFO is started before the FIFO analyzer is opened, then the current frame is effectively random, making it hard to reproduce consistently.
This issue has existed since the FIFO analyzer was implemented for Qt.
The 'zero frames in the range' check can be removed because now there is always at least 1 frame; of course that might be the same frame over and over again, but that's still useful for e.g. Free Look (and the 1 frame repeating effect already occurred when frame count was exclusive).
A single object can be selected instead of 2 (it was already inclusive internally), and the maximum value is the highest number of objects in any frame (minus 1) to reduce jank when multiple frames are being played back.