There was a race condition between the video thread and the host thread,
if corrections need to be made by VerifyValidity(). Briefly, the config
will contain invalid values. Instead, pause emulation first, which will
flush the video thread, update the config and correct it, then resume
emulation, after which the video thread will detect the config has
changed and act accordingly.
Drivers can return VK_ERROR_OUT_OF_DATE_KHR from vkQueuePresentKHR, and
we should resize the image in this case, as well as when getting it back
from vkAcquireNextImageKHR.
Change the repair logic to fix issues more aggressively by deleting bad
titles. This is necessary because of a bug in Dolphin's WAD boot code.
The UI code was updated to inform the user about titles that will be
deleted if they continue a repair, before deleting anything.
Old versions of Dolphin are so broken regarding NAND handling that
we need this to repair common issues and avoid issues with titles
like the System Menu or the Wii Shop.
This isn't an exhaustive check, but this will catch most issues
and offer to fix them automatically (if possible).
Some of my WiiWare games does not have a maker :
- Blue's Journey : EAFPJ8
- Magician Lord : EACPJ8
- The King of Fighters '94 : EAGPJ8
- The Last Ninja : C9XPGX
- World Games : C9ZPGX
Other than what action they send back to
EmulationActivity.handleMenuAction(), they are the same.
Change the menu-handling logic in EmulationActivity to keep track of a
boolean for whether the submenu is visible, rather than keeping the
fragment tag. There's only one fragment visible, so this makes more
sense.
I noticed the Strong Bad games, FAST - Racing League, and Tetris Party
were lacking info in the game lists' maker column.
This adds the information based on the games' MakerID.
Some toolchains provide enough of C++17 to conflict with Dolphin's
included backport of std::variant and std::optional. Specifically,
the recently-released macOS 10.13 SDK does not provide the <optional>
or <variant> headers, but does provide `in_place_t` in the <utility>
header.
The newer title dumpers don't clobber tickets anymore (that's good!),
which means personalised tickets still have the console specific data
used to decrypt the title key in them. Dolphin should ignore that data
when importing WADs, because the title key has already been decrypted,
and we must not try to decrypt it *again*.
Prefixing everything with a constant packagename is not needed for
internal keys, and just adds complexity.
Rename ARGUMENT_ prefix to ARG_ to match (most) of the rest of the
codebase.
Restrict visiblity of above as much as possible.
Makes the toolbar look more comfortable instead of all squished
together, and more similar to our current look.
Instead of setting a hardcoded minimal size for buttons, MakeActions()
now uses the maximum size hint width.
* remove useless units after 'zero' values
* reduce the size of 'Dolphin' to be more reasonable and look better
* avoid hardcoding the normal and small font sizes
Just create the AboutDialog on the stack -- the actual object lives on
the heap anyway, since Qt uses the pimpl idiom. Removes the need for
an explicit new and a special delete on close attribute.
FRAGMENT_ID wasn't actually the fragment's ID (that's misleading, and
sounds like the tag). It's actually the layout resource ID. There's no point in making that a static constant.
EmulationStateChanged is functionally correct right now, but
ConfigChanged expresses more semantically why the config setting gets
re-read and the widgets updated.
There are two special cases that the DSP accelerator handles in a
special way: when the end address is of the form xxxxxxx0 or
xxxxxxx1.
For these two cases, the normal overflow handling doesn't apply.
Instead, the overflow check is different, the ACCOV exception never
fires at all, the predscale register is not updated, reads are not
suspended, and if the end address is 16-byte aligned, the DSP loops
back to start_address + 1 instead of the regular start_address.
When an ACCOV is triggered, the accelerator stops reading back anything
and updating the current address until the YN2 register is set.
This is kept track of internally by the DSP; this state is not exposed
via any register.
However, we need to emulate this behaviour correctly because some
ucodes rely on it (notably AX GC); failure to emulate it will result
in reading past the end and start address for non-looped voices.
When the current address is xxxxxxxf, after doing the standard ADPCM
decoding and incrementing the current address as usual to get the
next address, the DSP will update the predscale register by reading
2 bytes from memory, and add two to get the next address.
This means xxxxxx10 cannot be a current address, as the DSP goes
from 0f to 12 directly.
A more serious issue with the old code is that if the start address
is 16-byte aligned, some samples will always be skipped, even when
that should not be the case.
An easy way to test whether this behaviour is correct is to check
the current address register and the predscale after each read.
Old code:
...
ACCA=00000002, predscale=<value>
ACCA=00000003, predscale=<value>
...
ACCA=0000000f, predscale=<value>
ACCA=00000010, predscale=<another value>
ACCA=00000013, predscale=<another value>
ACCA=00000014, predscale=<another value>
...
New code (and console):
...
ACCA=00000002, predscale=<value>
ACCA=00000003, predscale=<value>
...
ACCA=0000000f, predscale=<value>
ACCA=00000012, predscale=<another value>
ACCA=00000013, predscale=<another value>
...
Slightly cleaner, allows DSP accelerator behaviour to be
added to both HLE and LLE pretty easily, and makes the accelerator
easier to unit test.
I chose to include all accelerator state as private members, and
to expose state that is accessible via registers with getters/setters.
It's more verbose, yes, but it makes it very clear what is part of
the accelerator state and what isn't (e.g. coefs).
This works quite well for registers, since the accelerator can do
whatever it wants internally. For example, the start/end/current
addresses are masked -- having a getter/setter makes it easier to
enforce the mask.
This adds a test ucode that can be used to check the accelerator loop
behaviour with various start/end addresses.
It's actually more of a test template than a ready to use test.
const char[1] and wxString() can both be converted to multiple common
types, so this results in an ambiguous conditional expression
compilation error (C2445)
These rely on instance state, or are used within instance-based class
member functions, so they should belong to the instance itself instead
of being file statics.
The logic is entirely the same; only the inputs and outputs are
different, so deduplicating makes sense.
This will make fixing accelerator issues easier.
Ideally Common.h wouldn't be a header in the Common library, and instead be renamed to something else, like PlatformCompatibility.h or something, but even then, there's still some things in the header that don't really fall under that label
This moves the version strings out to their own version header that doesn't dump a bunch of other unrelated things into scope, like what Common.h was doing.
This also places them into the Common namespace, as opposed to letting them sit in the global namespace.
SetFormat() is only ever used internally. ResetBuffer() is only
used to implement the VertexManagerBase class interface, so
there's no need to make it protected.
The "X.h" header *just* contains protocol constants, not functions or
typedefs - so stuff like "Display" and "Window" are not defined unless
you include "Xlib.h".
"Xrandr.h" happens to include "Xlib.h" itself, so enabling xrandr
effectively worked around this issue.
If we allocate a large amount of memory (A), commit a smaller amount,
then allocate memory smaller than allocation A, we will have already
waited for these fences in A, but not used the space. In this case,
don't set m_free_iterator to a position before that which we know is
safe to use, which would result in waiting on the same fence(s) next
time.
If a SettingsFile had at least one section, it was assumed all sections
were correctly filled out. This caused crashes when opening the settings
menus if that was not the case - for example the GFX.ini settings empty
sections are removed by the main dolphin app, putting the .ini file in a
state that would crash the settings window if at least one setting was
changed in it from the default, some sections were left as default.
This adds a subclass of HashMap<String, SettingSection> that constructs a
new SettingSection instead of returning 'null' if the key isn't found,
so the mSettings.get(FILE).get(SECTION).get(SETTING) pattern can be
safely used.
Calling vkCmdClearAttachments with a partial rect, or specifying a
render area in a render pass with the load op set to clear can cause the
GPU to lock up, or raise a bounds violation. This only occurs on MSAA
framebuffers, and it seems when there are multiple clears in a single
command buffer. Worked around by back to the slow path (drawing quads)
when MSAA is enabled.
Before this change, we simply fail if the device does not expose one
queue family that supports both graphics and present. Currently this is
fine, since devices tend to lay out their queues in this way. NV, for
instance, tends to have one queue family for all graphics operations and
one more for transfer only. However, it's not a hard requirement, and it
is cheap to use a separate queue, so we might as well.
Currently, this is only the logic op bit, but this will be extended to
the framebuffer fetch/blend modes. In the future, when/if we move to
VideoCommon pipelines, this state will be part of the pipeline UID
anyway, and we can mask it out in the backend by using a two-level map,
so the shaders/programs are shared.
Based on hardware tests, masking occurs for the accelerator registers.
This fixes Red Steel and Far Cry Vengeance, which rely on this behavior
when reading back the current playback position from the DSP.
This reverts commit d23fd17e1a.
Dynamic sampler indexing is broken in VK_NV_glsl as of 385.41. The
performance gap doesn't seem to be as wide with the updated driver, so
to save maintaining two code paths, it's easier to just drop the
extension support completely.
ImgTec's driver uses a major.minor@changeID versioning system
This is packed into a double so "1.9@4850625" becomes "109.4850625"
The next release brnach is expected to be 1.10, hence the need for 2
digits for the branch minor.
The changeID should be unique for each build, but is shared over all
branches, so only makes sense to compare withing a branch.
It's likely branch 'major' versions will be used for major hardware
revisions, and the drivers for both maintained in parallel. Thus it
may not make sense to compare versions between different major
verisons - if/when this happens we can hook up a DriverDetails::Family
as needed.
CNTVCT_EL0 is force-enabled on all linux plattforms.
Windows is untested, but as this is the best way to get *any* low
overhead performance counters, they likely use it as well.
Within Cleanup(), it is called at *every* end of the block. This generates bigger code,
but it is the only way to handle blocks with multiple exit nodes.
This optimisation doesn't work on PowerVR's Vulkan implementation. We
(incorrectly) disallow Framebuffer objects to be used with a different
load or store op than that which they were created with, despite the
spec allowing such.
This fixes the windwaker intro "smearing"
Modernizes the arrays and makes future simplifications possible (e.g. usages within the software renderer).
It also makes cases where we use array->pointer decay explicit.
This apparently fixes https://bugs.dolphin-emu.org/issues/10499 somehow.
The first changed line of this commit is just for performance - the
second changed line is where the difference in behavior is.
Since all queues are FIFO data structures, the name wasn't informative
as to why you'd use it over a normal queue. I originally thought it had
something to do with the hardware graphics FIFO.
This renames it using the common acronym SPSC, which stands for
single-producer single-consumer, and is most commonly used to talk about
lock-free data structures, both of which this is.
It would fail on lines line "Value =" - IE a value set to emptystring.
This would cause the app to crash when trying to open the corresponding
settings window.
Prevents resource managers that shouldn't be visible from being exposed
to titles.
This adds a new function to get features for an IOS version, and also
moves the version checks from the modules themselves to VersionInfo.
This hopefully documents some of the differences between IOS better
and should be slightly cleaner than having random version checks.
* IOCTL_WFSI_PREPARE_DEVICE -> IOCTL_WFSI_IMPORT_TITLE_INIT
(equivalent of ES_ImportTitleInit, also the official name)
* IOCTL_WFSI_IMPORT_TITLE -> IOCTL_WFSI_IMPORT_TITLE_CANCEL
(equivalent of ES_ImportTitleCancel)
The class NonCopyable is, like the name says, supposed to disallow
copying. But should it allow moving?
For a long time, NonCopyable used to not allow moving. (It declared
a deleted copy constructor and assigment operator without declaring
a move constructor and assignment operator, making the compiler
implicitly delete the move constructor and assignment operator.)
That's fine if the classes that inherit from NonCopyable don't need
to be movable or if writing the move constructor and assignment
operator by hand is fine, but that's not the case for all classes,
as I discovered when I was working on the DirectoryBlob PR.
Because of that, I decided to make NonCopyable movable in c7602cc,
allowing me to use NonCopyable in DirectoryBlob.h. That was however
an unfortunate decision, because some of the classes that inherit
from NonCopyable have incorrect behavior when moved by default-
generated move constructors and assignment operators, and do not
explicitly delete the move constructors and assignment operators,
relying on NonCopyable being non-movable.
So what can we do about this? There are four solutions that I can
think of:
1. Make NonCopyable non-movable and tell DirectoryBlob to suck it.
2. Keep allowing moving NonCopyable, and expect that classes that
don't support moving will delete the move constructor and
assignment operator manually. Not only is this inconsistent
(having classes disallow copying one way and disallow moving
another way), but deleting the move constructor and assignment
operator manually is too easy to forget compared to how tricky
the resulting problems are.
3. Have one "MovableNonCopyable" and one "NonMovableNonCopyable".
It works, but it feels rather silly...
4. Don't have a NonCopyable class at all. Considering that deleting
the copy constructor and assignment operator only takes two lines
of code, I don't see much of a reason to keep NonCopyable. I
suppose that there was more of a point in having NonCopyable back
in the pre-C++11 days, when it wasn't possible to use "= delete".
I decided to go with the fourth one (like the commit title says).
The implementation of the commit is fairly straight-forward, though
I would like to point out that I skipped adding "= delete" lines
for classes whose only reason for being uncopyable is that they
contain uncopyable classes like File::IOFile and std::unique_ptr,
because the compiler makes such classes uncopyable automatically.
I'm not sure why this hasn't popped up as an error on the buildbots,
but the build fails on my new install of VS2017. The error is C2445:
result type of conditional expression is ambiguous: types 'wxString'
and 'const char [1]' can be converted to multiple common types
to get bigger, breaking an optimization. This forces the emitter to use a
32bit pointer instead of an 8bit one, fixing the issue at the expense of
efficiency.
Seems like I was wrong that ANDI2R doesn't require a temporary register here.
There is *one* case when the mask won't fit in the ARM AND instruction:
mask = 0xFFFFFFFF
But let's just use MOV instead of AND here for this case...
Currently, GameFile returns a generic banner if the file didn't have one
available (either because the file format doesn't support it, or because
it's a Wii file without an associated save).
It makes more sense to handle the lack of banner in the UI layer. The
game list will use the generic missing banner explicitly (no change from before), and the game info window now omits the banner display entirely if the file didn't have one (since it's not useful to display/allow the user to save the "missing banner" banner).
Given a relatively recent proposal (P0657R0), which calls for deprecation of putting stuff into the global namespace when using C++ headers, this just futureproofs our code a little more.
Technically this is what we should have been doing initially, since an
implementation is allowed to not provide these types in the global
namespace and still be compliant.
It's strange to see GameTracker add its own initial paths in
construction, because you might expect a race condition where the
GameLoaded signal is emitted before it gets connected to in
GameListModel.
In fact, this doesn't happen, but only because of how it abuses the Qt
signals mechanism to load files asynchronously: GameLoader emits a
GameLoaded signal which gets forwarded to the GameTracker::GameLoaded
signal _after_ control returns to the event loop, at which point
GameListModel has connected.
This commit moves the logic of adding initial paths out of GameTracker
to a point after the signals are connected, which is more obvious and
doesn't rely on how GameTracker implements concurrency.
ifstream::read() sets the failbit if trying to read over the end, which
means that (!input) would be hit for the 'last' block if it wasn't
exactly BSIZE (1024) bytes.
Makes it easier to turn off general IOS messages that can be
distracting (e.g. /dev/net/ssl being opened hundreds of time...)
without losing the ability to view WFS messages.
The opagent library was (incorrectly) marked as a dependency for "Core"
instead of "Common".
When linked with --as-needed, any symbols the linker can tell are not
used are discarded. As the link is done in command-line order, and the
Core library (and dependencies) are processed before Common, it would
link in Core, then opagent, but as at that point no opagent symbols are
used the whole opagent library would be discarded.
Moving the opagent library to be a dependency of Common fixes this, as
after the Common library is linked, there *are* opagent symbols used.