Implement Display Settings + Attach Texture to FenceCycle

This commit is contained in:
PixelyIon 2021-06-20 03:44:43 +05:30
parent 16f875bab6
commit a1598dcae2
10 changed files with 178 additions and 157 deletions

View File

@ -19,6 +19,8 @@ namespace skyline {
PREF_ELEM("log_level", logLevel, static_cast<Logger::LogLevel>(element.text().as_uint(static_cast<unsigned int>(Logger::LogLevel::Info)))),
PREF_ELEM("username_value", username, element.text().as_string()),
PREF_ELEM("operation_mode", operationMode, element.attribute("value").as_bool()),
PREF_ELEM("force_triple_buffering", forceTripleBuffering, element.attribute("value").as_bool()),
PREF_ELEM("disable_frame_throttling", disableFrameThrottling, element.attribute("value").as_bool()),
};
#undef PREF_ELEM

View File

@ -14,7 +14,8 @@ namespace skyline {
Logger::LogLevel logLevel; //!< The minimum level that logs need to be for them to be printed
std::string username; //!< The name set by the user to be supplied to the guest
bool operationMode; //!< If the emulated Switch should be handheld or docked
bool forceTripleBuffering{true}; //!< If the presentation should always triple buffer even if the game double buffers
bool forceTripleBuffering; //!< If the presentation engine should always triple buffer even if the swapchain supports double buffering
bool disableFrameThrottling; //!< Allow the guest to submit frames without any blocking calls
/**
* @param fd An FD to the preference XML file

View File

@ -114,35 +114,20 @@ namespace skyline::gpu {
*/
void AttachObjects(std::initializer_list<std::shared_ptr<FenceCycleDependency>> dependencies) {
if (!signalled.test(std::memory_order_consume)) {
{
auto it{dependencies.begin()};
while (it != dependencies.end()) {
auto next{std::next(it)};
auto it{dependencies.begin()}, next{std::next(it)};
if (it != dependencies.end()) {
while (next != dependencies.end()) {
(*it)->next = *next;
it = next;
next = std::next(next);
}
}
const auto &first{*dependencies.begin()};
const auto &last{*dependencies.end()};
std::shared_ptr<FenceCycleDependency> next{std::atomic_load_explicit(&list, std::memory_order_consume)};
do {
last->next = next;
if (!next && signalled.test(std::memory_order_consume)) {
std::shared_ptr<FenceCycleDependency> current{first};
while (current) {
next.swap(first->next);
current.swap(next);
next.reset();
}
return;
}
} while (std::atomic_compare_exchange_strong(&list, &next, first));
AttachObject(*dependencies.begin());
}
}
template<typename... Dependencies>
void AttachObjects(Dependencies... dependencies) {
void AttachObjects(Dependencies &&... dependencies) {
AttachObjects(std::initializer_list<std::shared_ptr<FenceCycleDependency>>{std::forward<Dependencies>(dependencies)...});
}
};

View File

@ -69,7 +69,7 @@ namespace skyline::gpu {
}
void PresentationEngine::UpdateSwapchain(texture::Format format, texture::Dimensions extent) {
auto minImageCount{std::max(vkSurfaceCapabilities.minImageCount, state.settings->forceTripleBuffering ? 3U : 0U)};
auto minImageCount{std::max(vkSurfaceCapabilities.minImageCount, state.settings->forceTripleBuffering ? 3U : 2U)};
if (minImageCount > MaxSwapchainImageCount)
throw exception("Requesting swapchain with higher image count ({}) than maximum slot count ({})", minImageCount, MaxSwapchainImageCount);
@ -99,13 +99,14 @@ namespace skyline::gpu {
.imageUsage = presentUsage,
.imageSharingMode = vk::SharingMode::eExclusive,
.compositeAlpha = vk::CompositeAlphaFlagBitsKHR::eInherit,
.presentMode = vk::PresentModeKHR::eMailbox,
.presentMode = state.settings->disableFrameThrottling ? vk::PresentModeKHR::eMailbox : vk::PresentModeKHR::eFifo,
.clipped = true,
});
auto vkImages{vkSwapchain->getImages()};
if (vkImages.size() > MaxSwapchainImageCount)
throw exception("Swapchain has higher image count ({}) than maximum slot count ({})", minImageCount, MaxSwapchainImageCount);
state.logger->Error("Buffer Count: {}", vkImages.size());
for (size_t index{}; index < vkImages.size(); index++) {
auto &slot{images[index]};

View File

@ -262,8 +262,7 @@ namespace skyline::gpu {
},
});
});
cycle->AttachObject(stagingBuffer);
cycle->AttachObjects(stagingBuffer, shared_from_this());
}
}
@ -376,6 +375,6 @@ namespace skyline::gpu {
},
});
});
cycle->AttachObject(source);
cycle->AttachObjects(source, shared_from_this());
}
}

View File

@ -224,7 +224,7 @@ namespace skyline::gpu {
* @brief A texture which is backed by host constructs while being synchronized with the underlying guest texture
* @note This class conforms to the Lockable and BasicLockable C++ named requirements
*/
class Texture : public FenceCycleDependency {
class Texture : public std::enable_shared_from_this<Texture>, public FenceCycleDependency {
private:
GPU &gpu;
std::mutex mutex; //!< Synchronizes any mutations to the texture or its backing

View File

@ -212,7 +212,10 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
}
@Suppress("DEPRECATION") val display = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) display!! else windowManager.defaultDisplay
if (settings.maxRefreshRate)
display?.supportedModes?.maxByOrNull { it.refreshRate * it.physicalHeight * it.physicalWidth }?.let { window.attributes.preferredDisplayModeId = it.modeId }
else
display?.supportedModes?.minByOrNull { abs(it.refreshRate - 60f) }?.let { window.attributes.preferredDisplayModeId = it.modeId }
binding.gameView.setOnTouchListener(this)

View File

@ -35,4 +35,6 @@ class Settings @Inject constructor(@ApplicationContext private val context : Con
var logLevel by sharedPreferences(context, "3")
var filter by sharedPreferences(context, 0)
var maxRefreshRate by sharedPreferences(context, false)
}

View File

@ -25,7 +25,7 @@
<string name="file_missing">The log file was not found</string>
<string name="upload_logs">The logs are being uploaded</string>
<string name="cleared">The logs have been cleared</string>
<!-- Settings -->
<!-- Settings - Emulator -->
<string name="emulator">Emulator</string>
<string name="search_location">Search Location</string>
<string name="theme">Theme</string>
@ -40,17 +40,30 @@
<string name="log_compact">Compact Logs</string>
<string name="log_compact_desc_on">Logs will be displayed in a compact form factor</string>
<string name="log_compact_desc_off">Logs will be displayed in a verbose form factor</string>
<!-- Settings - System -->
<string name="system">System</string>
<string name="use_docked">Use Docked Mode</string>
<string name="handheld_enabled">The system will emulate being in handheld mode</string>
<string name="docked_enabled">The system will emulate being in docked mode</string>
<string name="username">Username</string>
<string name="username_default">@string/app_name</string>
<!-- Settings - Keys -->
<string name="keys">Keys</string>
<string name="prod_keys">Production Keys</string>
<string name="title_keys">Title Keys</string>
<string name="import_keys_success">Successfully imported keys</string>
<string name="import_keys_failed">Failed to import keys</string>
<!-- Settings - Display -->
<string name="display">Display</string>
<string name="force_triple_buffering">Force Triple Buffering</string>
<string name="triple_buffering_enabled">Utilize at least 3 swapchain buffers (Higher FPS with higher input lag)</string>
<string name="triple_buffering_disabled">Utilize at least 2 swapchain buffers (Lower FPS with lower input lag)</string>
<string name="disable_frame_throttling">Disable Frame Throttling</string>
<string name="disable_frame_throttling_enabled">Game is allowed to submit frames as fast as possible (Only for benchmarking)</string>
<string name="disable_frame_throttling_disabled">Only allow the game to submit frames at the display refresh rate</string>
<string name="max_refresh_rate">Use Maximum Display Refresh Rate</string>
<string name="max_refresh_rate_enabled">Sets the display refresh rate as high as possible (Will break most games)</string>
<string name="max_refresh_rate_disabled">Sets the display refresh rate to 60Hz</string>
<!-- Input -->
<string name="input">Input</string>
<string name="osc">On-Screen Controls</string>

View File

@ -45,11 +45,6 @@
android:summaryOn="@string/log_compact_desc_on"
app:key="log_compact"
app:title="@string/log_compact" />
<emu.skyline.preference.CustomEditTextPreference
android:defaultValue="@string/username_default"
app:key="username_value"
app:limit="31"
app:title="@string/username" />
</PreferenceCategory>
<PreferenceCategory
android:key="category_keys"
@ -72,19 +67,39 @@
android:summaryOn="@string/docked_enabled"
app:key="operation_mode"
app:title="@string/use_docked" />
<emu.skyline.preference.CustomEditTextPreference
android:defaultValue="@string/username_default"
app:key="username_value"
app:limit="31"
app:title="@string/username" />
</PreferenceCategory>
<PreferenceCategory
android:key="category_presentation"
android:title="@string/display">
<CheckBoxPreference
android:defaultValue="true"
android:summaryOff="@string/triple_buffering_disabled"
android:summaryOn="@string/triple_buffering_enabled"
app:key="force_triple_buffering"
app:title="@string/force_triple_buffering" />
<CheckBoxPreference
android:defaultValue="false"
android:dependency="force_triple_buffering"
android:summaryOff="@string/disable_frame_throttling_disabled"
android:summaryOn="@string/disable_frame_throttling_enabled"
app:key="disable_frame_throttling"
app:title="@string/disable_frame_throttling" />
<CheckBoxPreference
android:defaultValue="false"
android:summaryOff="@string/max_refresh_rate_disabled"
android:summaryOn="@string/max_refresh_rate_enabled"
app:key="max_refresh_rate"
app:title="@string/max_refresh_rate" />
</PreferenceCategory>
<PreferenceCategory
android:key="category_input"
android:title="@string/input"
app:initialExpandedChildrenCount="4">
<!--
<CheckBoxPreference
android:defaultValue="true"
android:summaryOff="@string/osc_not_shown"
android:summaryOn="@string/osc_shown"
app:key="show_osc"
app:title="@string/show_osc" />
-->
<emu.skyline.preference.ControllerPreference index="0" />
<emu.skyline.preference.ControllerPreference index="1" />
<emu.skyline.preference.ControllerPreference index="2" />