mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-30 01:24:17 +01:00
Add CommandExecutor slot count setting
This commit is contained in:
parent
1a0819fb76
commit
576bc6f37e
@ -39,6 +39,7 @@ namespace skyline {
|
|||||||
disableFrameThrottling = ktSettings.GetBool("disableFrameThrottling");
|
disableFrameThrottling = ktSettings.GetBool("disableFrameThrottling");
|
||||||
gpuDriver = ktSettings.GetString("gpuDriver");
|
gpuDriver = ktSettings.GetString("gpuDriver");
|
||||||
gpuDriverLibraryName = ktSettings.GetString("gpuDriverLibraryName");
|
gpuDriverLibraryName = ktSettings.GetString("gpuDriverLibraryName");
|
||||||
|
executorSlotCount = ktSettings.GetInt<u32>("executorSlotCount");
|
||||||
validationLayer = ktSettings.GetBool("validationLayer");
|
validationLayer = ktSettings.GetBool("validationLayer");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -71,6 +71,7 @@ namespace skyline {
|
|||||||
// GPU
|
// GPU
|
||||||
Setting<std::string> gpuDriver; //!< The label of the GPU driver to use
|
Setting<std::string> gpuDriver; //!< The label of the GPU driver to use
|
||||||
Setting<std::string> gpuDriverLibraryName; //!< The name of the GPU driver library to use
|
Setting<std::string> gpuDriverLibraryName; //!< The name of the GPU driver library to use
|
||||||
|
Setting<u32> executorSlotCount; //!< Number of GPU executor slots that can be used concurrently
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
Setting<bool> validationLayer; //!< If the vulkan validation layer is enabled
|
Setting<bool> validationLayer; //!< If the vulkan validation layer is enabled
|
||||||
|
@ -109,8 +109,6 @@ namespace skyline::gpu {
|
|||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
chainedCycles.Iterate([&](const auto &cycle) {
|
chainedCycles.Iterate([&](const auto &cycle) {
|
||||||
if (!cycle->Find(this))
|
|
||||||
raise(SIGTRAP);
|
|
||||||
cycle->WaitSubmit();
|
cycle->WaitSubmit();
|
||||||
});
|
});
|
||||||
lock.lock();
|
lock.lock();
|
||||||
@ -129,7 +127,7 @@ namespace skyline::gpu {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
chainedCycles.Iterate([shouldDestroy, this](auto &cycle) {
|
chainedCycles.Iterate([shouldDestroy](auto &cycle) {
|
||||||
cycle->Wait(shouldDestroy);
|
cycle->Wait(shouldDestroy);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -2,12 +2,17 @@
|
|||||||
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
// Copyright © 2021 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
|
||||||
#include <range/v3/view.hpp>
|
#include <range/v3/view.hpp>
|
||||||
|
#include <common/settings.h>
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
#include <gpu.h>
|
#include <gpu.h>
|
||||||
#include "command_executor.h"
|
#include "command_executor.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect {
|
namespace skyline::gpu::interconnect {
|
||||||
CommandRecordThread::CommandRecordThread(const DeviceState &state) : state{state}, thread{&CommandRecordThread::Run, this} {}
|
CommandRecordThread::CommandRecordThread(const DeviceState &state)
|
||||||
|
: state{state},
|
||||||
|
incoming{*state.settings->executorSlotCount},
|
||||||
|
outgoing{*state.settings->executorSlotCount},
|
||||||
|
thread{&CommandRecordThread::Run, this} {}
|
||||||
|
|
||||||
static vk::raii::CommandBuffer AllocateRaiiCommandBuffer(GPU &gpu, vk::raii::CommandPool &pool) {
|
static vk::raii::CommandBuffer AllocateRaiiCommandBuffer(GPU &gpu, vk::raii::CommandPool &pool) {
|
||||||
return {gpu.vkDevice, (*gpu.vkDevice).allocateCommandBuffers(
|
return {gpu.vkDevice, (*gpu.vkDevice).allocateCommandBuffers(
|
||||||
@ -31,6 +36,13 @@ namespace skyline::gpu::interconnect {
|
|||||||
semaphore{gpu.vkDevice, vk::SemaphoreCreateInfo{}},
|
semaphore{gpu.vkDevice, vk::SemaphoreCreateInfo{}},
|
||||||
cycle{std::make_shared<FenceCycle>(gpu.vkDevice, *fence, *semaphore, true)} {}
|
cycle{std::make_shared<FenceCycle>(gpu.vkDevice, *fence, *semaphore, true)} {}
|
||||||
|
|
||||||
|
CommandRecordThread::Slot::Slot(Slot &&other)
|
||||||
|
: commandPool{std::move(other.commandPool)},
|
||||||
|
commandBuffer{std::move(other.commandBuffer)},
|
||||||
|
fence{std::move(other.fence)},
|
||||||
|
semaphore{std::move(other.semaphore)},
|
||||||
|
cycle{std::move(other.cycle)} {}
|
||||||
|
|
||||||
std::shared_ptr<FenceCycle> CommandRecordThread::Slot::Reset(GPU &gpu) {
|
std::shared_ptr<FenceCycle> CommandRecordThread::Slot::Reset(GPU &gpu) {
|
||||||
cycle->Wait();
|
cycle->Wait();
|
||||||
cycle = std::make_shared<FenceCycle>(*cycle);
|
cycle = std::make_shared<FenceCycle>(*cycle);
|
||||||
@ -79,7 +91,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
|
|
||||||
void CommandRecordThread::Run() {
|
void CommandRecordThread::Run() {
|
||||||
auto &gpu{*state.gpu};
|
auto &gpu{*state.gpu};
|
||||||
std::array<Slot, ActiveRecordSlots> slots{{gpu, gpu, gpu, gpu, gpu, gpu}};
|
|
||||||
|
std::vector<Slot> slots{};
|
||||||
|
std::generate_n(std::back_inserter(slots), *state.settings->executorSlotCount, [&] () -> Slot { return gpu; });
|
||||||
|
|
||||||
outgoing.AppendTranform(span<Slot>(slots), [](auto &slot) { return &slot; });
|
outgoing.AppendTranform(span<Slot>(slots), [](auto &slot) { return &slot; });
|
||||||
|
|
||||||
if (int result{pthread_setname_np(pthread_self(), "Sky-CmdRecord")})
|
if (int result{pthread_setname_np(pthread_self(), "Sky-CmdRecord")})
|
||||||
@ -116,7 +131,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CommandExecutor::CommandExecutor(const DeviceState &state)
|
CommandExecutor::CommandExecutor(const DeviceState &state)
|
||||||
: gpu{*state.gpu},
|
: state{state},
|
||||||
|
gpu{*state.gpu},
|
||||||
recordThread{state},
|
recordThread{state},
|
||||||
tag{AllocateTag()} {
|
tag{AllocateTag()} {
|
||||||
RotateRecordSlot();
|
RotateRecordSlot();
|
||||||
@ -401,7 +417,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
allocator->Reset();
|
allocator->Reset();
|
||||||
|
|
||||||
// Periodically clear preserve attachments just in case there are new waiters which would otherwise end up waiting forever
|
// Periodically clear preserve attachments just in case there are new waiters which would otherwise end up waiting forever
|
||||||
if ((submissionNumber % CommandRecordThread::ActiveRecordSlots * 2) == 0) {
|
if ((submissionNumber % (*state.settings->executorSlotCount * 2)) == 0) {
|
||||||
preserveAttachedBuffers.clear();
|
preserveAttachedBuffers.clear();
|
||||||
preserveAttachedTextures.clear();
|
preserveAttachedTextures.clear();
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ namespace skyline::gpu::interconnect {
|
|||||||
*/
|
*/
|
||||||
class CommandRecordThread {
|
class CommandRecordThread {
|
||||||
public:
|
public:
|
||||||
static constexpr size_t ActiveRecordSlots{6}; //!< Maximum number of simultaneously active slots
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Single execution slot, buffered back and forth between the GPFIFO thread and the record thread
|
* @brief Single execution slot, buffered back and forth between the GPFIFO thread and the record thread
|
||||||
@ -32,6 +31,8 @@ namespace skyline::gpu::interconnect {
|
|||||||
|
|
||||||
Slot(GPU &gpu);
|
Slot(GPU &gpu);
|
||||||
|
|
||||||
|
Slot(Slot &&other);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Waits on the fence and resets the command buffer
|
* @brief Waits on the fence and resets the command buffer
|
||||||
* @note A new fence cycle for the reset command buffer
|
* @note A new fence cycle for the reset command buffer
|
||||||
@ -41,10 +42,10 @@ namespace skyline::gpu::interconnect {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const DeviceState &state;
|
const DeviceState &state;
|
||||||
std::thread thread;
|
CircularQueue<Slot *> incoming; //!< Slots pending recording
|
||||||
|
CircularQueue<Slot *> outgoing; //!< Slots that have been submitted, may still be active on the GPU
|
||||||
|
|
||||||
CircularQueue<Slot *> incoming{ActiveRecordSlots}; //!< Slots pending recording
|
std::thread thread;
|
||||||
CircularQueue<Slot *> outgoing{ActiveRecordSlots}; //!< Slots that have been submitted, may still be active on the GPU
|
|
||||||
|
|
||||||
void ProcessSlot(Slot *slot);
|
void ProcessSlot(Slot *slot);
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ namespace skyline::gpu::interconnect {
|
|||||||
*/
|
*/
|
||||||
class CommandExecutor {
|
class CommandExecutor {
|
||||||
private:
|
private:
|
||||||
|
const DeviceState &state;
|
||||||
GPU &gpu;
|
GPU &gpu;
|
||||||
CommandRecordThread recordThread;
|
CommandRecordThread recordThread;
|
||||||
CommandRecordThread::Slot *slot{};
|
CommandRecordThread::Slot *slot{};
|
||||||
|
@ -25,6 +25,7 @@ class NativeSettings(context : Context, pref : PreferenceSettings) {
|
|||||||
// GPU
|
// GPU
|
||||||
var gpuDriver : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else pref.gpuDriver
|
var gpuDriver : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else pref.gpuDriver
|
||||||
var gpuDriverLibraryName : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else GpuDriverHelper.getLibraryName(context, pref.gpuDriver)
|
var gpuDriverLibraryName : String = if (pref.gpuDriver == PreferenceSettings.SYSTEM_GPU_DRIVER) "" else GpuDriverHelper.getLibraryName(context, pref.gpuDriver)
|
||||||
|
var executorSlotCount : Int = pref.executorSlotCount
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
var validationLayer : Boolean = BuildConfig.BUILD_TYPE != "release" && pref.validationLayer
|
var validationLayer : Boolean = BuildConfig.BUILD_TYPE != "release" && pref.validationLayer
|
||||||
|
@ -38,6 +38,7 @@ class PreferenceSettings @Inject constructor(@ApplicationContext private val con
|
|||||||
|
|
||||||
// GPU
|
// GPU
|
||||||
var gpuDriver by sharedPreferences(context, SYSTEM_GPU_DRIVER)
|
var gpuDriver by sharedPreferences(context, SYSTEM_GPU_DRIVER)
|
||||||
|
var executorSlotCount by sharedPreferences(context, 6)
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
var validationLayer by sharedPreferences(context, false)
|
var validationLayer by sharedPreferences(context, false)
|
||||||
|
@ -70,6 +70,8 @@
|
|||||||
<string name="respect_display_cutout">Respect Display Cutout</string>
|
<string name="respect_display_cutout">Respect Display Cutout</string>
|
||||||
<string name="respect_display_cutout_enabled">Do not draw UI elements in the cutout area</string>
|
<string name="respect_display_cutout_enabled">Do not draw UI elements in the cutout area</string>
|
||||||
<string name="respect_display_cutout_disabled">Allow UI elements to be drawn in the cutout area</string>
|
<string name="respect_display_cutout_disabled">Allow UI elements to be drawn in the cutout area</string>
|
||||||
|
<string name="executor_slot_count">Executor Slot Count</string>
|
||||||
|
<string name="executor_slot_count_desc">Maximum number of simultaneous GPU executions (Higher may sometimes perform better but will use more RAM)</string>
|
||||||
<!-- Settings - Debug -->
|
<!-- Settings - Debug -->
|
||||||
<string name="debug">Debug</string>
|
<string name="debug">Debug</string>
|
||||||
<string name="validation_layer">Enable validation layer</string>
|
<string name="validation_layer">Enable validation layer</string>
|
||||||
|
@ -127,6 +127,14 @@
|
|||||||
android:summaryOn="@string/respect_display_cutout_enabled"
|
android:summaryOn="@string/respect_display_cutout_enabled"
|
||||||
app:key="respect_display_cutout"
|
app:key="respect_display_cutout"
|
||||||
app:title="@string/respect_display_cutout" />
|
app:title="@string/respect_display_cutout" />
|
||||||
|
<SeekBarPreference
|
||||||
|
android:min="1"
|
||||||
|
android:defaultValue="6"
|
||||||
|
android:max="16"
|
||||||
|
android:summary="@string/executor_slot_count_desc"
|
||||||
|
app:key="executor_slot_count"
|
||||||
|
app:title="@string/executor_slot_count"
|
||||||
|
app:showSeekBarValue="true" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
android:key="category_debug"
|
android:key="category_debug"
|
||||||
|
Loading…
Reference in New Issue
Block a user