diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.cpp index 31c37c95..ef0aeefe 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.cpp @@ -13,15 +13,6 @@ #include "active_state.h" namespace skyline::gpu::interconnect::maxwell3d { - /* General Buffer Helpers */ - static BufferBinding *AllocateMegaBufferBinding(InterconnectContext &ctx, BufferView &view) { - auto megaBufferAllocation{view.AcquireMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator())}; - if (megaBufferAllocation) - return ctx.executor.allocator.EmplaceUntracked(megaBufferAllocation.buffer, megaBufferAllocation.offset, view.size); - else - return nullptr; - } - /* Vertex Buffer */ void VertexBufferState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const { manager.Bind(handle, vertexStream.format, vertexStream.location); @@ -36,23 +27,27 @@ namespace skyline::gpu::interconnect::maxwell3d { view.Update(ctx, engine->vertexStream.location, size); ctx.executor.AttachBuffer(*view); - if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding) + if (megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber); + megaBufferBinding) builder.SetVertexBuffer(index, megaBufferBinding); else builder.SetVertexBuffer(index, *view); } else { - auto nullBinding{ctx.executor.allocator.EmplaceUntracked()}; - megaBufferBinding = {}; - builder.SetVertexBuffer(index, nullBinding); + // TODO: null descriptor } } bool VertexBufferState::Refresh(InterconnectContext &ctx, StateUpdateBuilder &builder) { if (megaBufferBinding) { - if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding) - builder.SetVertexBuffer(index, megaBufferBinding); - else - builder.SetVertexBuffer(index, *view); + if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)}; + newMegaBufferBinding != megaBufferBinding) { + + megaBufferBinding = newMegaBufferBinding; + if (megaBufferBinding) + builder.SetVertexBuffer(index, megaBufferBinding); + else + builder.SetVertexBuffer(index, *view); + } } return false; } @@ -89,7 +84,7 @@ namespace skyline::gpu::interconnect::maxwell3d { } } - static BufferBinding *GenerateQuadConversionIndexBuffer(InterconnectContext &ctx, vk::IndexType indexType, BufferView &view, u32 elementCount) { + static BufferBinding GenerateQuadConversionIndexBuffer(InterconnectContext &ctx, vk::IndexType indexType, BufferView &view, u32 elementCount) { auto viewSpan{view.GetReadOnlyBackingSpan(false /* We attach above so always false */, []() { // TODO: see Read() Logger::Error("Dirty index buffer reads for attached buffers are unimplemented"); @@ -100,7 +95,7 @@ namespace skyline::gpu::interconnect::maxwell3d { conversion::quads::GenerateIndexedQuadConversionBuffer(quadConversionAllocation.region.data(), viewSpan.data(), elementCount, indexType); - return ctx.executor.allocator.EmplaceUntracked(quadConversionAllocation.buffer, quadConversionAllocation.offset, indexBufferSize); + return {quadConversionAllocation.buffer, quadConversionAllocation.offset, indexBufferSize}; } /* Index Buffer */ @@ -123,7 +118,7 @@ namespace skyline::gpu::interconnect::maxwell3d { if (quadConversion) megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount); else - megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); + megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber); if (megaBufferBinding) builder.SetIndexBuffer(megaBufferBinding, indexType); @@ -143,10 +138,15 @@ namespace skyline::gpu::interconnect::maxwell3d { megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount); builder.SetIndexBuffer(megaBufferBinding, indexType); } else if (megaBufferBinding) { - if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding) - builder.SetIndexBuffer(megaBufferBinding, indexType); - else - builder.SetIndexBuffer(*view, indexType); + if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)}; + newMegaBufferBinding != megaBufferBinding) { + + megaBufferBinding = newMegaBufferBinding; + if (megaBufferBinding) + builder.SetIndexBuffer(megaBufferBinding, indexType); + else + builder.SetIndexBuffer(*view, indexType); + } } return false; @@ -174,9 +174,7 @@ namespace skyline::gpu::interconnect::maxwell3d { builder.SetTransformFeedbackBuffer(index, *view); } else { // Bind an empty buffer ourselves since Vulkan doesn't support passing a VK_NULL_HANDLE xfb buffer - auto binding{ctx.executor.allocator.EmplaceUntracked( - ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer)}; - builder.SetTransformFeedbackBuffer(index, binding); + builder.SetTransformFeedbackBuffer(index, {ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer}); } } } diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.h index 500c10a0..18a88add 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/active_state.h @@ -21,7 +21,7 @@ namespace skyline::gpu::interconnect::maxwell3d { dirty::BoundSubresource engine; CachedMappedBufferView view{}; - BufferBinding *megaBufferBinding{}; + BufferBinding megaBufferBinding{}; u32 index{}; public: @@ -45,7 +45,7 @@ namespace skyline::gpu::interconnect::maxwell3d { private: dirty::BoundSubresource engine; CachedMappedBufferView view{}; - BufferBinding *megaBufferBinding{}; + BufferBinding megaBufferBinding{}; vk::IndexType indexType{}; u32 usedElementCount{}; bool usedQuadConversion{}; diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h index 3eb39725..0af10252 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/common.h @@ -65,18 +65,6 @@ namespace skyline::gpu::interconnect::maxwell3d { } }; - /** - * @brief Represents a bound Vulkan buffer that can be used for state updates - */ - struct BufferBinding { - vk::Buffer buffer{}; - vk::DeviceSize offset{}; - vk::DeviceSize size{}; - - BufferBinding() = default; - - BufferBinding(vk::Buffer buffer, vk::DeviceSize offset = 0, vk::DeviceSize size = 0) : buffer{buffer}, offset{offset}, size{size} {} - }; using DynamicBufferBinding = std::variant; using DirtyManager = dirty::Manager; diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.cpp index 95ecba57..87469d09 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.cpp @@ -571,11 +571,16 @@ namespace skyline::gpu::interconnect::maxwell3d { const auto &stage{shaderStages[i]}; writeBufferDescs(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount, [&](const Shader::ConstantBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) -> DynamicBufferBinding { - auto view{constantBuffers[i][desc.index + arrayIdx].view}; - if (auto megaBufferAlloc{view.AcquireMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator())}) { - return BufferBinding(megaBufferAlloc.buffer, megaBufferAlloc.offset, view.size); + size_t cbufIdx{desc.index + arrayIdx}; + auto view{constantBuffers[i][cbufIdx].view}; + + ctx.executor.AttachBuffer(view); + + size_t sizeOverride{std::min(stage.info.constant_buffer_used_sizes[cbufIdx], view.size)}; + if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber, sizeOverride)}) { + return megaBufferBinding; } else { - ctx.executor.AttachBuffer(view); + view.GetBuffer()->BlockSequencedCpuBackingWrites(); return view; } });