From 6f6a3126929fc0f72369ce0d6e4d09155919e2dc Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Fri, 18 Nov 2022 21:24:35 +0000 Subject: [PATCH] Commonise maxwell3d pipeline binding handling code A lot of pipeline code is difficult to commonise due to the inherent difference between compute and graphics pipelines, however the binding layout is shared so we can at least commonise that --- .../gpu/interconnect/common/pipeline.inc | 93 +++++++++++++++++++ .../maxwell_3d/pipeline_manager.cpp | 83 +---------------- 2 files changed, 94 insertions(+), 82 deletions(-) create mode 100644 app/src/main/cpp/skyline/gpu/interconnect/common/pipeline.inc diff --git a/app/src/main/cpp/skyline/gpu/interconnect/common/pipeline.inc b/app/src/main/cpp/skyline/gpu/interconnect/common/pipeline.inc new file mode 100644 index 00000000..98f2de1d --- /dev/null +++ b/app/src/main/cpp/skyline/gpu/interconnect/common/pipeline.inc @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#pragma once + +#include +#include "samplers.h" +#include "textures.h" + +namespace skyline::gpu::interconnect { + union BindlessHandle { + u32 raw; + + struct { + u32 textureIndex : 20; + u32 samplerIndex : 12; + }; + }; + + 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.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, 0).buffer, 0, PAGE_SIZE}; + + ctx.executor.AttachBuffer(view); + + size_t sizeOverride{std::min(info.constant_buffer_used_sizes[idx], view.size)}; + if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber, sizeOverride)}) { + return megaBufferBinding; + } else { + view.GetBuffer()->BlockSequencedCpuBackingWrites(); + return view; + } + } + + static DynamicBufferBinding GetStorageBufferBinding(InterconnectContext &ctx, const Shader::StorageBufferDescriptor &desc, ConstantBuffer &cbuf, CachedMappedBufferView &cachedView) { + struct SsboDescriptor { + u64 address; + u32 size; + }; + + auto ssbo{cbuf.Read(ctx.executor, desc.cbuf_offset)}; + cachedView.Update(ctx, ssbo.address, ssbo.size); + + auto view{cachedView.view}; + ctx.executor.AttachBuffer(view); + + if (desc.is_written) { + view.GetBuffer()->MarkGpuDirty(); + } else { + if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber)}) + return megaBufferBinding; + } + + view.GetBuffer()->BlockSequencedCpuBackingWrites(); + + return view; + } + + template + static BindlessHandle ReadBindlessHandle(InterconnectContext &ctx, CbufSetT &constantBuffers, const auto &desc, size_t arrayIdx) { + ConstantBuffer &primaryCbuf{constantBuffers[desc.cbuf_index]}; + size_t elemOffset{arrayIdx << desc.size_shift}; + size_t primaryCbufOffset{desc.cbuf_offset + elemOffset}; + u32 primaryVal{primaryCbuf.Read(ctx.executor, primaryCbufOffset)}; + + if constexpr (requires { desc.has_secondary; }) { + if (desc.has_secondary) { + ConstantBuffer &secondaryCbuf{constantBuffers[desc.secondary_cbuf_index]}; + size_t secondaryCbufOffset{desc.secondary_cbuf_offset + elemOffset}; + u32 secondaryVal{secondaryCbuf.Read(ctx.executor, secondaryCbufOffset)}; + return {primaryVal | secondaryVal}; + } + } + + return {.raw = primaryVal}; + } + + static std::pair GetTextureBinding(InterconnectContext &ctx, const Shader::TextureDescriptor &desc, Samplers &samplers, Textures &textures, BindlessHandle handle) { + auto sampler{samplers.GetSampler(ctx, handle.samplerIndex, handle.textureIndex)}; + auto texture{textures.GetTexture(ctx, handle.textureIndex, desc.type)}; + ctx.executor.AttachTexture(texture); + auto view{texture->GetView()}; + + return { + vk::DescriptorImageInfo{ + .sampler = **sampler, + .imageView = view, + .imageLayout = texture->texture->layout + }, + texture + }; + } +} 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 40a9792a..de0db9e7 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 @@ -3,21 +3,13 @@ #include #include +#include #include #include #include #include "pipeline_manager.h" namespace skyline::gpu::interconnect::maxwell3d { - union BindlessHandle { - u32 raw; - - struct { - u32 textureIndex : 20; - u32 samplerIndex : 12; - }; - }; - static constexpr Shader::Stage ConvertCompilerShaderStage(engine::Pipeline::Shader::Type stage) { switch (stage) { case engine::Pipeline::Shader::Type::VertexCullBeforeFetch: @@ -642,79 +634,6 @@ namespace skyline::gpu::interconnect::maxwell3d { return descriptorInfo.totalCombinedImageSamplerCount; } - 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.gpu.megaBufferAllocator.Allocate(ctx.executor.cycle, 0).buffer, 0, PAGE_SIZE}; - - ctx.executor.AttachBuffer(view); - - size_t sizeOverride{std::min(info.constant_buffer_used_sizes[idx], view.size)}; - if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber, sizeOverride)}) { - return megaBufferBinding; - } else { - view.GetBuffer()->BlockSequencedCpuBackingWrites(); - return view; - } - } - - static DynamicBufferBinding GetStorageBufferBinding(InterconnectContext &ctx, const Shader::StorageBufferDescriptor &desc, ConstantBuffer &cbuf, CachedMappedBufferView &cachedView) { - struct SsboDescriptor { - u64 address; - u32 size; - }; - - auto ssbo{cbuf.Read(ctx.executor, desc.cbuf_offset)}; - cachedView.Update(ctx, ssbo.address, ssbo.size); - - auto view{cachedView.view}; - ctx.executor.AttachBuffer(view); - - if (desc.is_written) { - view.GetBuffer()->MarkGpuDirty(); - } else { - if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.gpu.megaBufferAllocator, ctx.executor.executionNumber)}) - return megaBufferBinding; - } - - view.GetBuffer()->BlockSequencedCpuBackingWrites(); - - return view; - } - - static BindlessHandle ReadBindlessHandle(InterconnectContext &ctx, std::array &constantBuffers, const auto &desc, size_t arrayIdx) { - ConstantBuffer &primaryCbuf{constantBuffers[desc.cbuf_index]}; - size_t elemOffset{arrayIdx << desc.size_shift}; - size_t primaryCbufOffset{desc.cbuf_offset + elemOffset}; - u32 primaryVal{primaryCbuf.Read(ctx.executor, primaryCbufOffset)}; - - if constexpr (requires { desc.has_secondary; }) { - if (desc.has_secondary) { - ConstantBuffer &secondaryCbuf{constantBuffers[desc.secondary_cbuf_index]}; - size_t secondaryCbufOffset{desc.secondary_cbuf_offset + elemOffset}; - u32 secondaryVal{secondaryCbuf.Read(ctx.executor, secondaryCbufOffset)}; - return {primaryVal | secondaryVal}; - } - } - - return {.raw = primaryVal}; - } - - static std::pair GetTextureBinding(InterconnectContext &ctx, const Shader::TextureDescriptor &desc, Samplers &samplers, Textures &textures, BindlessHandle handle) { - auto sampler{samplers.GetSampler(ctx, handle.samplerIndex, handle.textureIndex)}; - auto texture{textures.GetTexture(ctx, handle.textureIndex, desc.type)}; - ctx.executor.AttachTexture(texture); - auto view{texture->GetView()}; - - return { - vk::DescriptorImageInfo{ - .sampler = **sampler, - .imageView = view, - .imageLayout = texture->texture->layout - }, - texture - }; - } - DescriptorUpdateInfo *Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, Samplers &samplers, Textures &textures, span sampledImages) { SyncCachedStorageBufferViews(ctx.executor.executionNumber);