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 85b5a82f..3eb39725 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 @@ -78,6 +78,7 @@ namespace skyline::gpu::interconnect::maxwell3d { 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/constant_buffers.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h index f754b6f7..cda23b9f 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/constant_buffers.h @@ -40,6 +40,8 @@ namespace skyline::gpu::interconnect::maxwell3d { } }; + using ConstantBufferSet = std::array, engine::ShaderStageCount>; + /** * @brief Holds the state of all bound constant buffers and the selector, abstracting out operations on them */ @@ -48,7 +50,7 @@ namespace skyline::gpu::interconnect::maxwell3d { dirty::ManualDirtyState selectorState; public: - std::array, engine::ShaderStageCount> boundConstantBuffers; + ConstantBufferSet boundConstantBuffers; ConstantBuffers(DirtyManager &manager, const ConstantBufferSelectorState::EngineRegisters &constantBufferSelectorRegisters); 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 c342c961..95ecba57 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 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "gpu/cache/graphics_pipeline_cache.h" #include "pipeline_manager.h" @@ -537,5 +538,67 @@ namespace skyline::gpu::interconnect::maxwell3d { transitionCache[transitionCacheNextIdx] = next; transitionCacheNextIdx = (transitionCacheNextIdx + 1) % transitionCache.size(); } + + // TODO: EXEC ID FOR STORAGE BUFS PURGE REMAP + void Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers) { + u32 bindingIdx{}; + u32 writeIdx{}; + u32 bufferIdx{}; + u32 imageIdx{}; + + auto writes{ctx.executor.allocator.AllocateUntracked(descriptorInfo.writeDescCount)}; + auto bufferDescs{ctx.executor.allocator.AllocateUntracked(descriptorInfo.totalBufferDescCount)}; + auto bufferDescViews{ctx.executor.allocator.AllocateUntracked(descriptorInfo.totalBufferDescCount)}; + + auto writeBufferDescs{[&](vk::DescriptorType type, const auto &descs, u32 count, auto getBufferCb) { + if (!descs.empty()) { + writes[writeIdx++] = { + .dstBinding = bindingIdx, + .descriptorCount = count, + .descriptorType = type, + .pBufferInfo = &bufferDescs[bufferIdx], + }; + + for (size_t descIdx{}; descIdx < descs.size(); descIdx++) { + const auto &shaderDesc{descs[descIdx]}; + for (size_t arrayIdx{}; arrayIdx < shaderDesc.count; arrayIdx++) + bufferDescViews[bufferIdx++] = getBufferCb(shaderDesc, descIdx, arrayIdx); + } + } + }}; + + for (size_t i{}; i < shaderStages.size(); i++) { + 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); + } else { + ctx.executor.AttachBuffer(view); + return view; + } + }); + + writeBufferDescs(vk::DescriptorType::eStorageBuffer, stage.info.storage_buffers_descriptors, descriptorInfo.storageBufferDescCount, [&](const Shader::StorageBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) { + struct SsboDescriptor { + u64 address; + u32 size; + }; + + auto &cbuf{constantBuffers[i][desc.cbuf_index]}; + auto ssbo{cbuf.Read(ctx.executor, desc.cbuf_offset)}; + storageBufferViews[descIdx].Update(ctx, ssbo.address, ssbo.size); + + auto view{storageBufferViews[descIdx].view}; + ctx.executor.AttachBuffer(view); + + if (desc.is_written) + view.GetBuffer()->MarkGpuDirty(); + + return view; + }); + } + } } diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.h index b1880596..57da4d29 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/pipeline_manager.h @@ -8,6 +8,7 @@ #include #include "common.h" #include "packed_pipeline_state.h" +#include "constant_buffers.h" namespace skyline::gpu { class TextureView; @@ -42,6 +43,7 @@ namespace skyline::gpu::interconnect::maxwell3d { }; private: + std::vector storageBufferViews; std::array shaderStages; cache::GraphicsPipelineCache::CompiledPipeline compiledPipeline; DescriptorInfo descriptorInfo; @@ -57,6 +59,8 @@ namespace skyline::gpu::interconnect::maxwell3d { Pipeline *LookupNext(const PackedPipelineState &packedState); void AddTransition(Pipeline *next); + + void SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers); }; class PipelineManager {