Bunch of cleanup/bugfixes for initial pipeline desc set impl

Cleans up code slightly, fixes keeping track of per-stage descriptor counts and fixes storage buffer caching + more random stuff.
This commit is contained in:
Billy Laws 2022-09-23 22:10:36 +01:00
parent eb4a9bab11
commit 68b6b20f78
3 changed files with 93 additions and 68 deletions

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include <gpu/descriptor_allocator.h>
#include "common.h" #include "common.h"
#include "active_state.h" #include "active_state.h"
#include "constant_buffers.h" #include "constant_buffers.h"

View File

@ -226,10 +226,10 @@ namespace skyline::gpu::interconnect::maxwell3d {
if (!stage.module) if (!stage.module)
continue; continue;
auto &stageCbufUsage{descriptorInfo.cbufUsages[i]}; auto &stageDescInfo{descriptorInfo.stages[i]};
auto pushBindings{[&](vk::DescriptorType type, const auto &descs, u32 &count, auto &&descCb, bool individualDescWrites = false) { auto pushBindings{[&](vk::DescriptorType type, const auto &descs, u32 &count, auto &&descCb, bool individualDescWrites = false) {
descriptorInfo.writeDescCount += individualDescWrites ? descs.size() : ((descs.size() > 0) ? 1 : 0); descriptorInfo.totalWriteDescCount += individualDescWrites ? descs.size() : ((descs.size() > 0) ? 1 : 0);
for (u32 descIdx{}; descIdx < descs.size(); descIdx++) { for (u32 descIdx{}; descIdx < descs.size(); descIdx++) {
const auto &desc{descs[descIdx]}; const auto &desc{descs[descIdx]};
@ -246,29 +246,30 @@ namespace skyline::gpu::interconnect::maxwell3d {
} }
}}; }};
pushBindings(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount, [&](const Shader::ConstantBufferDescriptor &desc, u32 descIdx) { pushBindings(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, stageDescInfo.uniformBufferDescCount, [&](const Shader::ConstantBufferDescriptor &desc, u32 descIdx) {
for (u32 cbufIdx{desc.index}; cbufIdx < desc.index + desc.count; cbufIdx++) { for (u32 cbufIdx{desc.index}; cbufIdx < desc.index + desc.count; cbufIdx++) {
auto &usage{stageCbufUsage[cbufIdx]}; auto &usage{stageDescInfo.cbufUsages[cbufIdx]};
usage.uniformBuffers.push_back({bindingIndex, descIdx}); usage.uniformBuffers.push_back({bindingIndex, descIdx});
usage.totalBufferDescCount += desc.count; usage.totalBufferDescCount += desc.count;
usage.writeDescCount++; usage.writeDescCount++;
} }
}); });
pushBindings(vk::DescriptorType::eStorageBuffer, stage.info.storage_buffers_descriptors, descriptorInfo.storageBufferDescCount, [&](const Shader::StorageBufferDescriptor &desc, u32 descIdx) { pushBindings(vk::DescriptorType::eStorageBuffer, stage.info.storage_buffers_descriptors, stageDescInfo.storageBufferDescCount, [&](const Shader::StorageBufferDescriptor &desc, u32 descIdx) {
auto &usage{stageCbufUsage[desc.cbuf_index]}; auto &usage{stageDescInfo.cbufUsages[desc.cbuf_index]};
usage.storageBuffers.push_back({bindingIndex, descIdx}); usage.storageBuffers.push_back({bindingIndex, descIdx, descriptorInfo.totalStorageBufferCount + descIdx});
usage.totalBufferDescCount += desc.count; usage.totalBufferDescCount += desc.count;
usage.writeDescCount++; usage.writeDescCount++;
}); });
descriptorInfo.totalBufferDescCount += descriptorInfo.uniformBufferDescCount + descriptorInfo.storageBufferDescCount; descriptorInfo.totalBufferDescCount += stageDescInfo.uniformBufferDescCount + stageDescInfo.storageBufferDescCount;
descriptorInfo.totalStorageBufferCount += stageDescInfo.storageBufferDescCount;
pushBindings(vk::DescriptorType::eUniformTexelBuffer, stage.info.texture_buffer_descriptors, descriptorInfo.uniformTexelBufferDescCount, [](const auto &, u32) {}); pushBindings(vk::DescriptorType::eUniformTexelBuffer, stage.info.texture_buffer_descriptors, stageDescInfo.uniformTexelBufferDescCount, [](const auto &, u32) {});
pushBindings(vk::DescriptorType::eStorageTexelBuffer, stage.info.image_buffer_descriptors, descriptorInfo.storageTexelBufferDescCount, [](const auto &, u32) {}); pushBindings(vk::DescriptorType::eStorageTexelBuffer, stage.info.image_buffer_descriptors, stageDescInfo.storageTexelBufferDescCount, [](const auto &, u32) {});
descriptorInfo.totalTexelBufferDescCount += descriptorInfo.uniformTexelBufferDescCount + descriptorInfo.storageTexelBufferDescCount; descriptorInfo.totalTexelBufferDescCount += stageDescInfo.uniformTexelBufferDescCount + stageDescInfo.storageTexelBufferDescCount;
pushBindings(vk::DescriptorType::eCombinedImageSampler, stage.info.texture_descriptors, descriptorInfo.combinedImageSamplerDescCount, [](const auto &, u32) {}, needsIndividualTextureBindingWrites); pushBindings(vk::DescriptorType::eCombinedImageSampler, stage.info.texture_descriptors, stageDescInfo.combinedImageSamplerDescCount, [](const auto &, u32) {}, needsIndividualTextureBindingWrites);
pushBindings(vk::DescriptorType::eStorageImage, stage.info.image_descriptors, descriptorInfo.storageImageDescCount, [](const auto &, u32) {}); pushBindings(vk::DescriptorType::eStorageImage, stage.info.image_descriptors, stageDescInfo.storageImageDescCount, [](const auto &, u32) {});
descriptorInfo.totalImageDescCount += descriptorInfo.combinedImageSamplerDescCount + descriptorInfo.storageImageDescCount; descriptorInfo.totalImageDescCount += stageDescInfo.combinedImageSamplerDescCount + stageDescInfo.storageImageDescCount;
} }
descriptorInfo.totalElemCount = descriptorInfo.totalBufferDescCount + descriptorInfo.totalTexelBufferDescCount + descriptorInfo.totalImageDescCount; descriptorInfo.totalElemCount = descriptorInfo.totalBufferDescCount + descriptorInfo.totalTexelBufferDescCount + descriptorInfo.totalImageDescCount;
@ -539,7 +540,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
descriptorInfo{MakePipelineDescriptorInfo(shaderStages, ctx.gpu.traits.quirks.needsIndividualTextureBindingWrites)}, descriptorInfo{MakePipelineDescriptorInfo(shaderStages, ctx.gpu.traits.quirks.needsIndividualTextureBindingWrites)},
compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorInfo.descriptorSetLayoutBindings, colorAttachments, depthAttachment)}, compiledPipeline{MakeCompiledPipeline(ctx, packedState, shaderStages, descriptorInfo.descriptorSetLayoutBindings, colorAttachments, depthAttachment)},
sourcePackedState{packedState} { sourcePackedState{packedState} {
storageBufferViews.resize(descriptorInfo.storageBufferDescCount); storageBufferViews.resize(descriptorInfo.totalStorageBufferCount);
} }
Pipeline *Pipeline::LookupNext(const PackedPipelineState &packedState) { Pipeline *Pipeline::LookupNext(const PackedPipelineState &packedState) {
@ -588,13 +589,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
} }
} }
static DynamicBufferBinding GetStorageBufferBinding(InterconnectContext &ctx, const Shader::Info &info, ConstantBuffer &cbuf, CachedMappedBufferView &cachedView, size_t idx) { static DynamicBufferBinding GetStorageBufferBinding(InterconnectContext &ctx, const Shader::StorageBufferDescriptor &desc, ConstantBuffer &cbuf, CachedMappedBufferView &cachedView) {
struct SsboDescriptor { struct SsboDescriptor {
u64 address; u64 address;
u32 size; u32 size;
}; };
const auto &desc{info.storage_buffers_descriptors[idx]};
auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)}; auto ssbo{cbuf.Read<SsboDescriptor>(ctx.executor, desc.cbuf_offset)};
cachedView.Update(ctx, ssbo.address, ssbo.size); cachedView.Update(ctx, ssbo.address, ssbo.size);
@ -611,11 +611,12 @@ namespace skyline::gpu::interconnect::maxwell3d {
// TODO: EXEC ID FOR STORAGE BUFS PURGE REMAP // TODO: EXEC ID FOR STORAGE BUFS PURGE REMAP
DescriptorUpdateInfo *Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers) { DescriptorUpdateInfo *Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers) {
u32 bindingIdx{}; u32 bindingIdx{};
u32 writeIdx{}; size_t writeIdx{};
u32 bufferIdx{}; size_t bufferIdx{};
u32 imageIdx{}; size_t imageIdx{};
size_t storageBufferIdx{};
auto writes{ctx.executor.allocator->AllocateUntracked<vk::WriteDescriptorSet>(descriptorInfo.writeDescCount)}; auto writes{ctx.executor.allocator->AllocateUntracked<vk::WriteDescriptorSet>(descriptorInfo.totalWriteDescCount)};
auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(descriptorInfo.totalBufferDescCount)}; auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(descriptorInfo.totalBufferDescCount)};
auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(descriptorInfo.totalBufferDescCount)}; auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(descriptorInfo.totalBufferDescCount)};
@ -628,11 +629,11 @@ namespace skyline::gpu::interconnect::maxwell3d {
.pBufferInfo = &bufferDescs[bufferIdx], .pBufferInfo = &bufferDescs[bufferIdx],
}; };
for (size_t descIdx{}; descIdx < descs.size(); descIdx++) { bindingIdx += descs.size();
const auto &shaderDesc{descs[descIdx]};
for (size_t arrayIdx{}; arrayIdx < shaderDesc.count; arrayIdx++) for (const auto &desc : descs)
bufferDescDynamicBindings[bufferIdx++] = getBufferCb(shaderDesc, descIdx, arrayIdx); for (size_t arrayIdx{}; arrayIdx < desc.count; arrayIdx++)
} bufferDescDynamicBindings[bufferIdx++] = getBufferCb(desc, arrayIdx);
} }
}}; }};
@ -641,22 +642,29 @@ namespace skyline::gpu::interconnect::maxwell3d {
if (!stage.module) if (!stage.module)
continue; continue;
writeBufferDescs(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount, const auto &stageDescInfo{descriptorInfo.stages[i]};
[&](const Shader::ConstantBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) {
writeBufferDescs(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, stageDescInfo.uniformBufferDescCount,
[&](const Shader::ConstantBufferDescriptor &desc, size_t arrayIdx) {
size_t cbufIdx{desc.index + arrayIdx}; size_t cbufIdx{desc.index + arrayIdx};
return GetConstantBufferBinding(ctx, stage.info, constantBuffers[i][cbufIdx].view, cbufIdx); return GetConstantBufferBinding(ctx, stage.info, constantBuffers[i][cbufIdx].view, cbufIdx);
}); });
writeBufferDescs(vk::DescriptorType::eStorageBuffer, stage.info.storage_buffers_descriptors, descriptorInfo.storageBufferDescCount, writeBufferDescs(vk::DescriptorType::eStorageBuffer, stage.info.storage_buffers_descriptors, stageDescInfo.storageBufferDescCount,
[&](const Shader::StorageBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) { [&](const Shader::StorageBufferDescriptor &desc, size_t arrayIdx) {
return GetStorageBufferBinding(ctx, stage.info, constantBuffers[i][desc.cbuf_index], storageBufferViews[descIdx], descIdx); auto binding{GetStorageBufferBinding(ctx, desc, constantBuffers[i][desc.cbuf_index], storageBufferViews[storageBufferIdx])};
storageBufferIdx += arrayIdx ? 0 : 1;
return binding;
}); });
} }
if (!writeIdx)
return nullptr;
return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{ return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{
.writes = writes, .writes = writes.first(writeIdx),
.bufferDescs = bufferDescs, .bufferDescs = bufferDescs.first(bufferIdx),
.bufferDescDynamicBindings = bufferDescDynamicBindings, .bufferDescDynamicBindings = bufferDescDynamicBindings.first(bufferIdx),
.pipelineLayout = compiledPipeline.pipelineLayout, .pipelineLayout = compiledPipeline.pipelineLayout,
.descriptorSetLayout = compiledPipeline.descriptorSetLayout, .descriptorSetLayout = compiledPipeline.descriptorSetLayout,
.bindPoint = vk::PipelineBindPoint::eGraphics, .bindPoint = vk::PipelineBindPoint::eGraphics,
@ -666,8 +674,11 @@ namespace skyline::gpu::interconnect::maxwell3d {
DescriptorUpdateInfo *Pipeline::SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind) { DescriptorUpdateInfo *Pipeline::SyncDescriptorsQuickBind(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, ConstantBuffers::QuickBind quickBind) {
size_t stageIndex{static_cast<size_t>(quickBind.stage)}; size_t stageIndex{static_cast<size_t>(quickBind.stage)};
const auto &stageDescInfo{descriptorInfo.stages[stageIndex]};
const auto &cbufUsageInfo{stageDescInfo.cbufUsages[quickBind.index]};
if (!cbufUsageInfo.writeDescCount)
return nullptr;
const auto &cbufUsageInfo{descriptorInfo.cbufUsages[stageIndex][quickBind.index]};
const auto &shaderInfo{shaderStages[stageIndex].info}; const auto &shaderInfo{shaderStages[stageIndex].info};
auto &stageConstantBuffers{constantBuffers[stageIndex]}; auto &stageConstantBuffers{constantBuffers[stageIndex]};
auto copies{ctx.executor.allocator->AllocateUntracked<vk::CopyDescriptorSet>(1)}; auto copies{ctx.executor.allocator->AllocateUntracked<vk::CopyDescriptorSet>(1)};
@ -675,6 +686,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
size_t writeIdx{}; size_t writeIdx{};
size_t bufferIdx{}; size_t bufferIdx{};
size_t imageIdx{};
auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(cbufUsageInfo.totalBufferDescCount)}; auto bufferDescs{ctx.executor.allocator->AllocateUntracked<vk::DescriptorBufferInfo>(cbufUsageInfo.totalBufferDescCount)};
auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(cbufUsageInfo.totalBufferDescCount)}; auto bufferDescDynamicBindings{ctx.executor.allocator->AllocateUntracked<DynamicBufferBinding>(cbufUsageInfo.totalBufferDescCount)};
@ -688,7 +700,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
.descriptorCount = descriptorInfo.totalElemCount, .descriptorCount = descriptorInfo.totalElemCount,
}; };
auto writeBufferDescs{[&](vk::DescriptorType type, const auto &usages, const auto &descs, u32 count, auto getBufferCb) { auto writeBufferDescs{[&](vk::DescriptorType type, const auto &usages, const auto &descs, auto getBufferCb) {
for (const auto &usage : usages) { for (const auto &usage : usages) {
const auto &shaderDesc{descs[usage.shaderDescIdx]}; const auto &shaderDesc{descs[usage.shaderDescIdx]};
@ -700,26 +712,29 @@ namespace skyline::gpu::interconnect::maxwell3d {
}; };
for (size_t i{}; i < shaderDesc.count; i++) for (size_t i{}; i < shaderDesc.count; i++)
bufferDescDynamicBindings[bufferIdx++] = getBufferCb(shaderDesc, usage.shaderDescIdx, i); bufferDescDynamicBindings[bufferIdx++] = getBufferCb(usage, shaderDesc, i);
} }
}}; }};
writeBufferDescs(vk::DescriptorType::eUniformBuffer, cbufUsageInfo.uniformBuffers, shaderInfo.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount, writeBufferDescs(vk::DescriptorType::eUniformBuffer, cbufUsageInfo.uniformBuffers, shaderInfo.constant_buffer_descriptors,
[&](const Shader::ConstantBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) -> DynamicBufferBinding { [&](auto usage, const Shader::ConstantBufferDescriptor &desc, size_t arrayIdx) -> DynamicBufferBinding {
size_t cbufIdx{desc.index + arrayIdx}; size_t cbufIdx{desc.index + arrayIdx};
return GetConstantBufferBinding(ctx, shaderInfo, stageConstantBuffers[cbufIdx].view, cbufIdx); return GetConstantBufferBinding(ctx, shaderInfo, stageConstantBuffers[cbufIdx].view, cbufIdx);
}); });
writeBufferDescs(vk::DescriptorType::eStorageBuffer, cbufUsageInfo.storageBuffers, shaderInfo.storage_buffers_descriptors, descriptorInfo.storageBufferDescCount, writeBufferDescs(vk::DescriptorType::eStorageBuffer, cbufUsageInfo.storageBuffers, shaderInfo.storage_buffers_descriptors,
[&](const Shader::StorageBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) { [&](auto usage, const Shader::StorageBufferDescriptor &desc, size_t arrayIdx) {
return GetStorageBufferBinding(ctx, shaderInfo, stageConstantBuffers[desc.cbuf_index], storageBufferViews[bufferIdx], descIdx); return GetStorageBufferBinding(ctx, desc, stageConstantBuffers[desc.cbuf_index], storageBufferViews[usage.storageBufferIdx]);
}); });
if (!writeIdx)
return nullptr;
return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{ return ctx.executor.allocator->EmplaceUntracked<DescriptorUpdateInfo>(DescriptorUpdateInfo{
.copies = copies, .copies = copies,
.writes = writes, .writes = writes.first(writeIdx),
.bufferDescs = bufferDescs, .bufferDescs = bufferDescs.first(bufferIdx),
.bufferDescDynamicBindings = bufferDescDynamicBindings, .bufferDescDynamicBindings = bufferDescDynamicBindings.first(bufferIdx),
.pipelineLayout = compiledPipeline.pipelineLayout, .pipelineLayout = compiledPipeline.pipelineLayout,
.descriptorSetLayout = compiledPipeline.descriptorSetLayout, .descriptorSetLayout = compiledPipeline.descriptorSetLayout,
.bindPoint = vk::PipelineBindPoint::eGraphics, .bindPoint = vk::PipelineBindPoint::eGraphics,

View File

@ -42,17 +42,14 @@ namespace skyline::gpu::interconnect::maxwell3d {
struct DescriptorInfo { struct DescriptorInfo {
std::vector<vk::DescriptorSetLayoutBinding> descriptorSetLayoutBindings; std::vector<vk::DescriptorSetLayoutBinding> descriptorSetLayoutBindings;
u32 writeDescCount{};
u32 uniformBufferDescCount{}; struct StageDescriptorInfo {
u32 storageBufferDescCount{}; u32 uniformBufferDescCount;
u32 totalBufferDescCount{}; u32 storageBufferDescCount;
u32 uniformTexelBufferDescCount{}; u32 uniformTexelBufferDescCount;
u32 storageTexelBufferDescCount{}; u32 storageTexelBufferDescCount;
u32 totalTexelBufferDescCount{}; u32 combinedImageSamplerDescCount;
u32 combinedImageSamplerDescCount{}; u32 storageImageDescCount;
u32 storageImageDescCount{};
u32 totalImageDescCount{};
u32 totalElemCount{};
/** /**
* @brief Keeps track of all bindings that are dependent on a given constant buffer index to allow for quick binding * @brief Keeps track of all bindings that are dependent on a given constant buffer index to allow for quick binding
@ -61,15 +58,27 @@ namespace skyline::gpu::interconnect::maxwell3d {
struct Usage { struct Usage {
u32 binding; //!< Vulkan binding index u32 binding; //!< Vulkan binding index
u32 shaderDescIdx; //!< Index of the descriptor in the appropriate shader info member u32 shaderDescIdx; //!< Index of the descriptor in the appropriate shader info member
u32 storageBufferIdx; //!< Index of the storage buffer in the per-pipeline storage buffer cache
}; };
boost::container::small_vector<Usage, 2> uniformBuffers; boost::container::small_vector<Usage, 2> uniformBuffers;
boost::container::small_vector<Usage, 2> storageBuffers; boost::container::small_vector<Usage, 2> storageBuffers;
u32 totalBufferDescCount{}; u32 totalBufferDescCount;
u32 writeDescCount{}; u32 writeDescCount;
}; };
std::array<std::array<ConstantBufferDescriptorUsages, engine::ShaderStageConstantBufferCount>, engine::ShaderStageCount> cbufUsages{}; std::array<ConstantBufferDescriptorUsages, engine::ShaderStageConstantBufferCount> cbufUsages;
};
std::array<StageDescriptorInfo, 5> stages;
u32 totalStorageBufferCount;
u32 totalWriteDescCount;
u32 totalBufferDescCount;
u32 totalTexelBufferDescCount;
u32 totalImageDescCount;
u32 totalElemCount;
}; };
private: private: