mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-11 00:29:06 +01:00
Remove now redundant buffer/texture/megabuffer manager locks
They have been superseeded by the global channel lock
This commit is contained in:
parent
f5a141a621
commit
05581f2230
@ -11,18 +11,6 @@ namespace skyline::gpu {
|
||||
return it->guest->begin().base() < pointer;
|
||||
}
|
||||
|
||||
void BufferManager::lock() {
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void BufferManager::unlock() {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
bool BufferManager::try_lock() {
|
||||
return mutex.try_lock();
|
||||
}
|
||||
|
||||
BufferManager::LockedBuffer::LockedBuffer(std::shared_ptr<Buffer> pBuffer, ContextTag tag) : buffer{std::move(pBuffer)}, lock{tag, *buffer}, stateLock(buffer->stateMutex) {}
|
||||
|
||||
Buffer *BufferManager::LockedBuffer::operator->() const {
|
||||
|
@ -15,7 +15,6 @@ namespace skyline::gpu {
|
||||
class BufferManager {
|
||||
private:
|
||||
GPU &gpu;
|
||||
std::mutex mutex; //!< Synchronizes access to the buffer mappings
|
||||
std::vector<std::shared_ptr<Buffer>> bufferMappings; //!< A sorted vector of all buffer mappings
|
||||
LinearAllocatorState<> delegateAllocatorState; //!< Linear allocator used to allocate buffer delegates
|
||||
size_t nextBufferId{}; //!< The next unique buffer id to be assigned
|
||||
|
@ -126,33 +126,18 @@ namespace skyline::gpu::interconnect {
|
||||
}
|
||||
|
||||
void CommandExecutor::RotateRecordSlot() {
|
||||
if (slot)
|
||||
if (slot) {
|
||||
slot->capt = capt;
|
||||
recordThread.ReleaseSlot(slot);
|
||||
}
|
||||
|
||||
capt = false;
|
||||
slot = recordThread.AcquireSlot();
|
||||
cycle = slot->Reset(gpu);
|
||||
slot->executionNumber = executionNumber;
|
||||
allocator = &slot->allocator;
|
||||
}
|
||||
|
||||
TextureManager &CommandExecutor::AcquireTextureManager() {
|
||||
if (!textureManagerLock)
|
||||
textureManagerLock.emplace(gpu.texture);
|
||||
return gpu.texture;
|
||||
}
|
||||
|
||||
BufferManager &CommandExecutor::AcquireBufferManager() {
|
||||
if (!bufferManagerLock)
|
||||
bufferManagerLock.emplace(gpu.buffer);
|
||||
return gpu.buffer;
|
||||
}
|
||||
|
||||
MegaBufferAllocator &CommandExecutor::AcquireMegaBufferAllocator() {
|
||||
if (!megaBufferAllocatorLock)
|
||||
megaBufferAllocatorLock.emplace(gpu.megaBufferAllocator);
|
||||
return gpu.megaBufferAllocator;
|
||||
}
|
||||
|
||||
bool CommandExecutor::CreateRenderPassWithSubpass(vk::Rect2D renderArea, span<TextureView *> inputAttachments, span<TextureView *> colorAttachments, TextureView *depthStencilAttachment, bool noSubpassCreation) {
|
||||
auto addSubpass{[&] {
|
||||
renderPass->AddSubpass(inputAttachments, colorAttachments, depthStencilAttachment, gpu);
|
||||
@ -230,10 +215,6 @@ namespace skyline::gpu::interconnect {
|
||||
}
|
||||
|
||||
bool CommandExecutor::AttachTexture(TextureView *view) {
|
||||
if (!textureManagerLock)
|
||||
// Avoids a potential deadlock with this resource being locked while acquiring the TextureManager lock while the thread owning it tries to acquire a lock on this texture
|
||||
textureManagerLock.emplace(gpu.texture);
|
||||
|
||||
bool didLock{view->LockWithTag(tag)};
|
||||
if (didLock) {
|
||||
if (view->texture->FrequentlyLocked())
|
||||
@ -259,10 +240,6 @@ namespace skyline::gpu::interconnect {
|
||||
}
|
||||
|
||||
bool CommandExecutor::AttachBuffer(BufferView &view) {
|
||||
if (!bufferManagerLock)
|
||||
// See AttachTexture(...)
|
||||
bufferManagerLock.emplace(gpu.buffer);
|
||||
|
||||
bool didLock{view.LockWithTag(tag)};
|
||||
if (didLock) {
|
||||
if (view.GetBuffer()->FrequentlyLocked())
|
||||
@ -274,10 +251,6 @@ namespace skyline::gpu::interconnect {
|
||||
}
|
||||
|
||||
void CommandExecutor::AttachLockedBufferView(BufferView &view, ContextLock<BufferView> &&lock) {
|
||||
if (!bufferManagerLock)
|
||||
// See AttachTexture(...)
|
||||
bufferManagerLock.emplace(gpu.buffer);
|
||||
|
||||
if (lock.OwnsLock()) {
|
||||
// Transfer ownership to executor so that the resource will stay locked for the period it is used on the GPU
|
||||
if (view.GetBuffer()->FrequentlyLocked())
|
||||
@ -423,10 +396,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
void CommandExecutor::ResetInternal() {
|
||||
attachedTextures.clear();
|
||||
textureManagerLock.reset();
|
||||
attachedBuffers.clear();
|
||||
bufferManagerLock.reset();
|
||||
megaBufferAllocatorLock.reset();
|
||||
allocator->Reset();
|
||||
|
||||
// Periodically clear preserve attachments just in case there are new waiters which would otherwise end up waiting forever
|
||||
|
@ -74,9 +74,6 @@ namespace skyline::gpu::interconnect {
|
||||
CommandRecordThread::Slot *slot{};
|
||||
node::RenderPassNode *renderPass{};
|
||||
size_t subpassCount{}; //!< The number of subpasses in the current render pass
|
||||
std::optional<std::scoped_lock<TextureManager>> textureManagerLock; //!< The lock on the texture manager, this is locked for the duration of the command execution from the first usage inside an execution to the submission
|
||||
std::optional<std::scoped_lock<BufferManager>> bufferManagerLock; //!< The lock on the buffer manager, see above for details
|
||||
std::optional<std::scoped_lock<MegaBufferAllocator>> megaBufferAllocatorLock; //!< The lock on the megabuffer allocator, see above for details
|
||||
bool preserveLocked{};
|
||||
|
||||
/**
|
||||
@ -160,17 +157,12 @@ namespace skyline::gpu::interconnect {
|
||||
ContextTag tag; //!< The tag associated with this command executor, any tagged resource locking must utilize this tag
|
||||
size_t submissionNumber{};
|
||||
u32 executionNumber{};
|
||||
bool capt{};
|
||||
|
||||
CommandExecutor(const DeviceState &state);
|
||||
|
||||
~CommandExecutor();
|
||||
|
||||
/**
|
||||
* @return A reference to an instance of the Texture Manager which will be locked till execution
|
||||
* @note Any access to the texture manager while recording commands **must** be done via this
|
||||
*/
|
||||
TextureManager &AcquireTextureManager();
|
||||
|
||||
/**
|
||||
* @brief Attach the lifetime of the texture to the command buffer
|
||||
* @return If this is the first usage of the backing of this resource within this execution
|
||||
@ -179,12 +171,6 @@ namespace skyline::gpu::interconnect {
|
||||
*/
|
||||
bool AttachTexture(TextureView *view);
|
||||
|
||||
/**
|
||||
* @return A reference to an instance of the Buffer Manager which will be locked till execution
|
||||
* @note Any access to the buffer manager while recording commands **must** be done via this
|
||||
*/
|
||||
BufferManager &AcquireBufferManager();
|
||||
|
||||
/**
|
||||
* @brief Attach the lifetime of a buffer view to the command buffer
|
||||
* @return If this is the first usage of the backing of this resource within this execution
|
||||
@ -193,12 +179,6 @@ namespace skyline::gpu::interconnect {
|
||||
*/
|
||||
bool AttachBuffer(BufferView &view);
|
||||
|
||||
/**
|
||||
* @return A reference to an instance of the megabuffer allocator which will be locked till execution
|
||||
* @note Any access to the megabuffer allocator while recording commands **must** be done via this
|
||||
*/
|
||||
MegaBufferAllocator &AcquireMegaBufferAllocator();
|
||||
|
||||
/**
|
||||
* @brief Attach the lifetime of a buffer view that's already locked to the command buffer
|
||||
* @note The supplied buffer **must** be locked with the executor's tag
|
||||
|
@ -113,11 +113,10 @@ namespace skyline::gpu::interconnect {
|
||||
auto srcGuestTexture{GetGuestTexture(srcSurface)};
|
||||
auto dstGuestTexture{GetGuestTexture(dstSurface)};
|
||||
|
||||
auto &textureManager{executor.AcquireTextureManager()};
|
||||
auto srcTextureView{textureManager.FindOrCreate(srcGuestTexture, executor.tag)};
|
||||
auto srcTextureView{gpu.texture.FindOrCreate(srcGuestTexture, executor.tag)};
|
||||
executor.AttachTexture(srcTextureView.get());
|
||||
|
||||
auto dstTextureView{textureManager.FindOrCreate(dstGuestTexture, executor.tag)};
|
||||
auto dstTextureView{gpu.texture.FindOrCreate(dstGuestTexture, executor.tag)};
|
||||
executor.AttachTexture(dstTextureView.get());
|
||||
|
||||
// Blit shader always samples from centre so adjust if necessary
|
||||
|
@ -745,7 +745,7 @@ namespace skyline::gpu::interconnect {
|
||||
void ConstantBufferUpdate(span<u32> data, u32 offset) {
|
||||
auto constantBuffer{GetConstantBufferSelector()};
|
||||
if (constantBuffer)
|
||||
constantBuffer->Write<u32>(executor, executor.AcquireMegaBufferAllocator(), data, offset);
|
||||
constantBuffer->Write<u32>(executor, gpu.megaBufferAllocator, data, offset);
|
||||
else
|
||||
throw exception("Attempting to write to invalid constant buffer!");
|
||||
}
|
||||
@ -1148,7 +1148,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
auto &view{*pipelineStage.constantBuffers[constantBuffer.index].view};
|
||||
executor.AttachBuffer(view);
|
||||
if (auto megaBufferAllocation{view.AcquireMegaBuffer(executor.cycle, executor.AcquireMegaBufferAllocator())}) {
|
||||
if (auto megaBufferAllocation{view.AcquireMegaBuffer(executor.cycle, gpu.megaBufferAllocator)}) {
|
||||
// If the buffer is megabuffered then since we don't get out data from the underlying buffer, rather the megabuffer which stays consistent throughout a single execution, we can skip registering usage
|
||||
bufferDescriptors[bufferIndex] = vk::DescriptorBufferInfo{
|
||||
.buffer = megaBufferAllocation.buffer,
|
||||
@ -1741,7 +1741,7 @@ namespace skyline::gpu::interconnect {
|
||||
*/
|
||||
MegaBufferAllocator::Allocation GetIndexedQuadConversionBuffer(u32 count, u32 first) {
|
||||
vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, indexBuffer.GetIndexSize())};
|
||||
auto allocation{executor.AcquireMegaBufferAllocator().Allocate(executor.cycle, size)};
|
||||
auto allocation{gpu.megaBufferAllocator.Allocate(executor.cycle, size)};
|
||||
|
||||
ContextLock lock{executor.tag, indexBuffer.view};
|
||||
auto guestIndexBuffer{indexBuffer.view.GetReadOnlyBackingSpan(lock.IsFirstUsage(), []() {
|
||||
@ -3045,7 +3045,7 @@ namespace skyline::gpu::interconnect {
|
||||
executor.AttachBuffer(indexBufferView);
|
||||
|
||||
boundIndexBuffer->type = indexBuffer.type;
|
||||
if (auto megaBufferAllocation{indexBufferView.AcquireMegaBuffer(executor.cycle, executor.AcquireMegaBufferAllocator())}) {
|
||||
if (auto megaBufferAllocation{indexBufferView.AcquireMegaBuffer(executor.cycle, gpu.megaBufferAllocator)}) {
|
||||
// If the buffer is megabuffered then since we don't get out data from the underlying buffer, rather the megabuffer which stays consistent throughout a single execution, we can skip registering usage
|
||||
boundIndexBuffer->handle = megaBufferAllocation.buffer;
|
||||
boundIndexBuffer->offset = megaBufferAllocation.offset;
|
||||
@ -3088,7 +3088,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
auto &vertexBufferView{vertexBuffer->view};
|
||||
executor.AttachBuffer(vertexBufferView);
|
||||
if (auto megaBufferAllocation{vertexBufferView.AcquireMegaBuffer(executor.cycle, executor.AcquireMegaBufferAllocator())}) {
|
||||
if (auto megaBufferAllocation{vertexBufferView.AcquireMegaBuffer(executor.cycle, gpu.megaBufferAllocator)}) {
|
||||
// If the buffer is megabuffered then since we don't get out data from the underlying buffer, rather the megabuffer which stays consistent throughout a single execution, we can skip registering usage
|
||||
boundVertexBuffers->handles[index] = megaBufferAllocation.buffer;
|
||||
boundVertexBuffers->offsets[index] = megaBufferAllocation.offset;
|
||||
|
@ -29,7 +29,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
if (*view) {
|
||||
ctx.executor.AttachBuffer(*view);
|
||||
|
||||
if (megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber);
|
||||
if (megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber);
|
||||
megaBufferBinding)
|
||||
builder.SetVertexBuffer(index, megaBufferBinding);
|
||||
else
|
||||
@ -43,12 +43,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
// TODO: null descriptor
|
||||
megaBufferBinding = {};
|
||||
builder.SetVertexBuffer(index, {ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer});
|
||||
builder.SetVertexBuffer(index, {ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, 0).buffer});
|
||||
}
|
||||
|
||||
bool VertexBufferState::Refresh(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||
if (megaBufferBinding) {
|
||||
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
|
||||
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber)};
|
||||
newMegaBufferBinding != megaBufferBinding) {
|
||||
|
||||
megaBufferBinding = newMegaBufferBinding;
|
||||
@ -101,7 +101,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
size_t indexSize{1U << static_cast<u32>(indexType)};
|
||||
vk::DeviceSize indexBufferSize{conversion::quads::GetRequiredBufferSize(elementCount, indexSize)};
|
||||
auto quadConversionAllocation{ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, indexBufferSize)};
|
||||
auto quadConversionAllocation{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, indexBufferSize)};
|
||||
|
||||
conversion::quads::GenerateIndexedQuadConversionBuffer(quadConversionAllocation.region.data(), viewSpan.data(), elementCount, ConvertIndexType(indexType));
|
||||
|
||||
@ -133,7 +133,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
if (quadConversion)
|
||||
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, engine->indexBuffer.indexSize, *view, elementCount);
|
||||
else
|
||||
megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber);
|
||||
megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber);
|
||||
|
||||
if (megaBufferBinding)
|
||||
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
||||
@ -153,7 +153,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, engine->indexBuffer.indexSize, *view, elementCount);
|
||||
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
||||
} else if (megaBufferBinding) {
|
||||
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
|
||||
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber)};
|
||||
newMegaBufferBinding != megaBufferBinding) {
|
||||
|
||||
megaBufferBinding = newMegaBufferBinding;
|
||||
@ -196,7 +196,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
// Bind an empty buffer ourselves since Vulkan doesn't support passing a VK_NULL_HANDLE xfb buffer
|
||||
builder.SetTransformFeedbackBuffer(index, {ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer});
|
||||
builder.SetTransformFeedbackBuffer(index, {ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, 0).buffer});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
return;
|
||||
|
||||
// Otherwise perform a full lookup
|
||||
view = ctx.executor.AcquireBufferManager().FindOrCreate(viewMapping, ctx.executor.tag, [&ctx](std::shared_ptr<Buffer> buffer, ContextLock<Buffer> &&lock) {
|
||||
view = ctx.gpu.buffer.FindOrCreate(viewMapping, ctx.executor.tag, [&ctx](std::shared_ptr<Buffer> buffer, ContextLock<Buffer> &&lock) {
|
||||
ctx.executor.AttachLockedBuffer(buffer, std::move(lock));
|
||||
});
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
}
|
||||
|
||||
void ConstantBuffer::Read(CommandExecutor &executor, span<u8> dstBuffer, size_t srcOffset) {
|
||||
executor.AcquireBufferManager();
|
||||
ContextLock lock{executor.tag, view};
|
||||
view.Read(lock.IsFirstUsage(), FlushHostCallback, dstBuffer, srcOffset);
|
||||
}
|
||||
@ -54,7 +53,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
auto &view{*selectorState.UpdateGet(ctx, data.size_bytes()).view};
|
||||
auto srcCpuBuf{data.cast<u8>()};
|
||||
|
||||
ctx.executor.AcquireBufferManager();
|
||||
ContextLock lock{ctx.executor.tag, view};
|
||||
|
||||
// First attempt the write without setting up the gpu copy callback as a fast path
|
||||
@ -73,7 +71,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
// This will prevent any CPU accesses to backing for the duration of the usage
|
||||
callbackData.view.GetBuffer()->BlockAllCpuBackingWrites();
|
||||
|
||||
auto srcGpuAllocation{callbackData.ctx.executor.AcquireMegaBufferAllocator().Push(callbackData.ctx.executor.cycle, callbackData.srcCpuBuf)};
|
||||
auto srcGpuAllocation{callbackData.ctx.gpu.megaBufferAllocator.Push(callbackData.ctx.executor.cycle, callbackData.srcCpuBuf)};
|
||||
callbackData.ctx.executor.AddOutsideRpCommand([=, srcCpuBuf = callbackData.srcCpuBuf, view = callbackData.view, offset = callbackData.offset](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &) {
|
||||
vk::BufferCopy copyRegion{
|
||||
.size = srcCpuBuf.size_bytes(),
|
||||
|
@ -617,12 +617,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
|
||||
static DynamicBufferBinding GetConstantBufferBinding(InterconnectContext &ctx, const Shader::Info &info, BufferView view, size_t idx) {
|
||||
if (!view) // Return a dummy buffer if the constant buffer isn't bound
|
||||
return BufferBinding{ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer, 0, PAGE_SIZE};
|
||||
return BufferBinding{ctx.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, 0).buffer, 0, PAGE_SIZE};
|
||||
|
||||
ctx.executor.AttachBuffer(view);
|
||||
|
||||
size_t sizeOverride{std::min<size_t>(info.constant_buffer_used_sizes[idx], view.size)};
|
||||
if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber, sizeOverride)}) {
|
||||
if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber, sizeOverride)}) {
|
||||
return megaBufferBinding;
|
||||
} else {
|
||||
view.GetBuffer()->BlockSequencedCpuBackingWrites();
|
||||
@ -645,7 +645,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
if (desc.is_written) {
|
||||
view.GetBuffer()->MarkGpuDirty();
|
||||
} else {
|
||||
if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)})
|
||||
if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber)})
|
||||
return megaBufferBinding;
|
||||
}
|
||||
|
||||
|
@ -312,7 +312,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
||||
auto mappings{ctx.channelCtx.asCtx->gmmu.TranslateRange(textureHeader.Iova(), guest.GetSize())};
|
||||
guest.mappings.assign(mappings.begin(), mappings.end());
|
||||
|
||||
texture = ctx.executor.AcquireTextureManager().FindOrCreate(guest, ctx.executor.tag);
|
||||
texture = ctx.gpu.texture.FindOrCreate(guest, ctx.executor.tag);
|
||||
}
|
||||
|
||||
textureHeaderCache[index] = {textureHeader, texture.get(), ctx.executor.executionNumber};
|
||||
|
@ -49,18 +49,6 @@ namespace skyline::gpu {
|
||||
|
||||
MegaBufferAllocator::MegaBufferAllocator(GPU &gpu) : gpu{gpu}, activeChunk{chunks.emplace(chunks.end(), gpu)} {}
|
||||
|
||||
void MegaBufferAllocator::lock() {
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void MegaBufferAllocator::unlock() {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
bool MegaBufferAllocator::try_lock() {
|
||||
return mutex.try_lock();
|
||||
}
|
||||
|
||||
MegaBufferAllocator::Allocation MegaBufferAllocator::Allocate(const std::shared_ptr<FenceCycle> &cycle, vk::DeviceSize size, bool pageAlign) {
|
||||
if (auto allocation{activeChunk->Allocate(cycle, size, pageAlign)}; allocation.first)
|
||||
return {activeChunk->GetBacking(), allocation.first, allocation.second};
|
||||
|
@ -40,7 +40,6 @@ namespace skyline::gpu {
|
||||
class MegaBufferAllocator {
|
||||
private:
|
||||
GPU &gpu;
|
||||
std::mutex mutex;
|
||||
std::list<MegaBufferChunk> chunks; //!< A pool of all allocated megabuffer chunks, these are dynamically utilized
|
||||
decltype(chunks)::iterator activeChunk; //!< Currently active chunk of the megabuffer which is being allocated into
|
||||
|
||||
@ -60,24 +59,6 @@ namespace skyline::gpu {
|
||||
|
||||
MegaBufferAllocator(GPU &gpu);
|
||||
|
||||
/**
|
||||
* @brief Acquires an exclusive lock on the allocator for the calling thread
|
||||
* @note Naming is in accordance to the BasicLockable named requirement
|
||||
*/
|
||||
void lock();
|
||||
|
||||
/**
|
||||
* @brief Relinquishes an existing lock on the allocator by the calling thread
|
||||
* @note Naming is in accordance to the BasicLockable named requirement
|
||||
*/
|
||||
void unlock();
|
||||
|
||||
/**
|
||||
* @brief Attempts to acquire an exclusive lock but returns immediately if it's captured by another thread
|
||||
* @note Naming is in accordance to the Lockable named requirement
|
||||
*/
|
||||
bool try_lock();
|
||||
|
||||
/**
|
||||
* @brief Allocates data in a megabuffer chunk and returns an structure describing the allocation
|
||||
* @param pageAlign Whether the pushed data should be page aligned in the megabuffer
|
||||
|
@ -97,6 +97,8 @@ namespace skyline::gpu {
|
||||
frame.fence.Wait(state.soc->host1x);
|
||||
|
||||
std::scoped_lock textureLock(*frame.textureView);
|
||||
// std::this_thread::sleep_for(std::chrono::milliseconds(64));
|
||||
|
||||
auto texture{frame.textureView->texture};
|
||||
if (frame.textureView->format != swapchainFormat || texture->dimensions != swapchainExtent)
|
||||
UpdateSwapchain(frame.textureView->format, texture->dimensions);
|
||||
|
@ -6,18 +6,6 @@
|
||||
namespace skyline::gpu {
|
||||
TextureManager::TextureManager(GPU &gpu) : gpu(gpu) {}
|
||||
|
||||
void TextureManager::lock() {
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
void TextureManager::unlock() {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
bool TextureManager::try_lock() {
|
||||
return mutex.try_lock();
|
||||
}
|
||||
|
||||
std::shared_ptr<TextureView> TextureManager::FindOrCreate(const GuestTexture &guestTexture, ContextTag tag) {
|
||||
auto guestMapping{guestTexture.mappings.front()};
|
||||
|
||||
|
@ -26,30 +26,11 @@ namespace skyline::gpu {
|
||||
};
|
||||
|
||||
GPU &gpu;
|
||||
std::mutex mutex; //!< Synchronizes access to the texture mappings
|
||||
std::vector<TextureMapping> textures; //!< A sorted vector of all texture mappings
|
||||
|
||||
public:
|
||||
TextureManager(GPU &gpu);
|
||||
|
||||
/**
|
||||
* @brief Acquires an exclusive lock on the texture for the calling thread
|
||||
* @note Naming is in accordance to the BasicLockable named requirement
|
||||
*/
|
||||
void lock();
|
||||
|
||||
/**
|
||||
* @brief Relinquishes an existing lock on the texture by the calling thread
|
||||
* @note Naming is in accordance to the BasicLockable named requirement
|
||||
*/
|
||||
void unlock();
|
||||
|
||||
/**
|
||||
* @brief Attempts to acquire an exclusive lock but returns immediately if it's captured by another thread
|
||||
* @note Naming is in accordance to the Lockable named requirement
|
||||
*/
|
||||
bool try_lock();
|
||||
|
||||
/**
|
||||
* @return A pre-existing or newly created Texture object which matches the specified criteria
|
||||
* @note The texture manager **must** be locked prior to calling this
|
||||
|
@ -345,7 +345,7 @@ namespace skyline::service::hosbinder {
|
||||
gpu::GuestTexture guestTexture(span<u8>{}, dimensions, format, tileConfig, vk::ImageViewType::e2D);
|
||||
guestTexture.mappings[0] = span<u8>(nvMapHandleObj->GetPointer() + surface.offset, guestTexture.GetLayerStride());
|
||||
|
||||
std::scoped_lock textureLock{state.gpu->texture};
|
||||
std::scoped_lock channelLock{state.gpu->channelLock};
|
||||
buffer.texture = state.gpu->texture.FindOrCreate(guestTexture);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user