Implement constant buffer and storage buffer pipeline descriptor types

This commit is contained in:
Billy Laws 2022-09-15 22:32:19 +01:00
parent 25255b01c7
commit 2360ca24da
4 changed files with 71 additions and 1 deletions

View File

@ -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<BufferBinding, BufferView>;
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
/**

View File

@ -40,6 +40,8 @@ namespace skyline::gpu::interconnect::maxwell3d {
}
};
using ConstantBufferSet = std::array<std::array<ConstantBuffer, engine::ShaderStageConstantBufferCount>, 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<ConstantBufferSelectorState> selectorState;
public:
std::array<std::array<ConstantBuffer, engine::ShaderStageConstantBufferCount>, engine::ShaderStageCount> boundConstantBuffers;
ConstantBufferSet boundConstantBuffers;
ConstantBuffers(DirtyManager &manager, const ConstantBufferSelectorState::EngineRegisters &constantBufferSelectorRegisters);

View File

@ -4,6 +4,7 @@
#include <gpu/texture/texture.h>
#include <gpu/shader_manager.h>
#include <gpu.h>
#include <gpu/interconnect/command_executor.h>
#include <vulkan/vulkan_handles.hpp>
#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<vk::WriteDescriptorSet>(descriptorInfo.writeDescCount)};
auto bufferDescs{ctx.executor.allocator.AllocateUntracked<vk::DescriptorBufferInfo>(descriptorInfo.totalBufferDescCount)};
auto bufferDescViews{ctx.executor.allocator.AllocateUntracked<DynamicBufferBinding>(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<SsboDescriptor>(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;
});
}
}
}

View File

@ -8,6 +8,7 @@
#include <gpu/cache/graphics_pipeline_cache.h>
#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<CachedMappedBufferView> storageBufferViews;
std::array<ShaderStage, engine::ShaderStageCount> 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 {