Allow attempting to write to buffers without passing a GPU copy callback

Constructing the GPU copy callback in `ConstantBuffers::Load()` ended up taking a fair amount of time despite it almost never being used in practice. By making it optional it can be skipped most of the time and only done when it's actually neccessary by calling `Write()` again if the initial call returned true.
This commit is contained in:
Billy Laws 2022-08-31 14:45:55 +01:00
parent 5dca5cc10e
commit f7a726e452
2 changed files with 14 additions and 6 deletions

View File

@ -223,7 +223,7 @@ namespace skyline::gpu {
std::memcpy(data.data(), mirror.data() + offset, data.size());
}
void Buffer::Write(bool isFirstUsage, const std::function<void()> &flushHostCallback, const std::function<void()> &gpuCopyCallback, span<u8> data, vk::DeviceSize offset) {
bool Buffer::Write(bool isFirstUsage, const std::function<void()> &flushHostCallback, span<u8> data, vk::DeviceSize offset, const std::function<void()> &gpuCopyCallback) {
AdvanceSequence(); // We are modifying GPU backing contents so advance to the next sequence
everHadInlineUpdate = true;
@ -238,12 +238,19 @@ namespace skyline::gpu {
std::memcpy(mirror.data() + offset, data.data(), data.size()); // Always copy to mirror since any CPU side reads will need the up-to-date contents
if (!SequencedCpuBackingWritesBlocked() && PollFence())
if (!SequencedCpuBackingWritesBlocked() && PollFence()) {
// We can write directly to the backing as long as this resource isn't being actively used by a past workload (in the current context or another)
std::memcpy(backing.data() + offset, data.data(), data.size());
else
} else {
// If this buffer is host immutable, perform a GPU-side inline update for the buffer contents since we can't directly modify the backing
gpuCopyCallback();
// If no copy callback is supplied, return true to indicate that the caller should repeat the write with an appropriate callback
if (gpuCopyCallback)
gpuCopyCallback();
else
return true;
}
return false;
}
BufferView Buffer::GetView(vk::DeviceSize offset, vk::DeviceSize size) {

View File

@ -245,9 +245,10 @@ namespace skyline::gpu {
* @brief Writes data at the specified offset in the buffer, falling back to GPU side copies if the buffer is host immutable
* @param isFirstUsage If this is the first usage of this resource in the context as returned from LockWithTag(...)
* @param flushHostCallback Callback to flush and execute all pending GPU work to allow for synchronisation of GPU dirty buffers
* @param gpuCopyCallback Callback to perform a GPU-side copy for this Write
* @param gpuCopyCallback Optional callback to perform a GPU-side copy for this Write if necessary, if such a copy is needed and this is not supplied `true` will be returned to indicate that the write needs to be repeated with the callback present
* @return Whether the write needs to be repeated with `gpuCopyCallback` provided, always false if `gpuCopyCallback` is provided
*/
void Write(bool isFirstUsage, const std::function<void()> &flushHostCallback, const std::function<void()> &gpuCopyCallback, span<u8> data, vk::DeviceSize offset);
bool Write(bool isFirstUsage, const std::function<void()> &flushHostCallback, span<u8> data, vk::DeviceSize offset, const std::function<void()> &gpuCopyCallback = {});
/**
* @return A view into this buffer with the supplied attributes