Simplify BufferView locking by requiring buffer manager be locked

Avoids the need to repeat the lookup after locking since recreations are impossible if buffer manager is locked.
This commit is contained in:
Billy Laws 2022-09-18 15:30:24 +01:00
parent 9449b52f36
commit aae957819e
2 changed files with 12 additions and 31 deletions

View File

@ -382,45 +382,24 @@ namespace skyline::gpu {
vk::DeviceSize GetOffset() const; vk::DeviceSize GetOffset() const;
/** /**
* @brief Templated lock function that ensures correct locking of the delegate's underlying buffer * @note The buffer manager **MUST** be locked prior to calling this
*/ */
template<bool TryLock, typename LockFunction, typename UnlockFunction>
std::conditional_t<TryLock, bool, void> LockWithFunction(LockFunction lock, UnlockFunction unlock) {
while (true) {
auto preLockBuffer{delegate->GetBuffer()};
if constexpr (TryLock) {
if (!lock(preLockBuffer))
return false;
} else {
lock(preLockBuffer);
}
auto postLockBuffer{delegate->GetBuffer()};
if (preLockBuffer == postLockBuffer)
break;
preLockBuffer->unlock();
};
ResolveDelegate();
if constexpr (TryLock)
return true;
else
return;
}
void lock() { void lock() {
LockWithFunction<false>([](Buffer *buffer) { buffer->lock(); }, [](Buffer *buffer) { buffer->unlock(); }); delegate->GetBuffer()->lock();
} }
/**
* @note The buffer manager **MUST** be locked prior to calling this
*/
bool try_lock() { bool try_lock() {
return LockWithFunction<true>([](Buffer *buffer) { return buffer->try_lock(); }, [](Buffer *buffer) { buffer->unlock(); }); return delegate->GetBuffer()->try_lock();
} }
/**
* @note The buffer manager **MUST** be locked prior to calling this
*/
bool LockWithTag(ContextTag tag) { bool LockWithTag(ContextTag tag) {
bool result{}; return delegate->GetBuffer()->LockWithTag(tag);
LockWithFunction<false>([&result, tag](Buffer *buffer) { result = buffer->LockWithTag(tag); }, [](Buffer *buffer) { buffer->unlock(); });
return result;
} }
void unlock() { void unlock() {

View File

@ -30,6 +30,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
} }
void ConstantBuffer::Read(CommandExecutor &executor, span<u8> dstBuffer, size_t srcOffset) { void ConstantBuffer::Read(CommandExecutor &executor, span<u8> dstBuffer, size_t srcOffset) {
executor.AcquireBufferManager();
ContextLock lock{executor.tag, view}; ContextLock lock{executor.tag, view};
view.Read(lock.IsFirstUsage(), FlushHostCallback, dstBuffer, srcOffset); view.Read(lock.IsFirstUsage(), FlushHostCallback, dstBuffer, srcOffset);
} }
@ -44,6 +45,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
auto &view{*selectorState.UpdateGet(ctx).view}; auto &view{*selectorState.UpdateGet(ctx).view};
auto srcCpuBuf{data.cast<u8>()}; auto srcCpuBuf{data.cast<u8>()};
ctx.executor.AcquireBufferManager();
ContextLock lock{ctx.executor.tag, view}; ContextLock lock{ctx.executor.tag, view};
// First attempt the write without setting up the gpu copy callback as a fast path // First attempt the write without setting up the gpu copy callback as a fast path