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
This commit is contained in:
Billy Laws 2022-11-18 21:24:35 +00:00
parent be8cbabd97
commit 6f6a312692
2 changed files with 94 additions and 82 deletions

View File

@ -0,0 +1,93 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <gpu/interconnect/command_executor.h>
#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<size_t>(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<SsboDescriptor>(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<typename CbufSetT>
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<u32>(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<u32>(ctx.executor, secondaryCbufOffset)};
return {primaryVal | secondaryVal};
}
}
return {.raw = primaryVal};
}
static std::pair<vk::DescriptorImageInfo, TextureView *> 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
};
}
}

View File

@ -3,21 +3,13 @@
#include <gpu/texture/texture.h> #include <gpu/texture/texture.h>
#include <gpu/interconnect/command_executor.h> #include <gpu/interconnect/command_executor.h>
#include <gpu/interconnect/common/pipeline.inc>
#include <gpu/cache/graphics_pipeline_cache.h> #include <gpu/cache/graphics_pipeline_cache.h>
#include <gpu/shader_manager.h> #include <gpu/shader_manager.h>
#include <gpu.h> #include <gpu.h>
#include "pipeline_manager.h" #include "pipeline_manager.h"
namespace skyline::gpu::interconnect::maxwell3d { 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) { static constexpr Shader::Stage ConvertCompilerShaderStage(engine::Pipeline::Shader::Type stage) {
switch (stage) { switch (stage) {
case engine::Pipeline::Shader::Type::VertexCullBeforeFetch: case engine::Pipeline::Shader::Type::VertexCullBeforeFetch:
@ -642,79 +634,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
return descriptorInfo.totalCombinedImageSamplerCount; 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<size_t>(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<SsboDescriptor>(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<ConstantBuffer, engine::ShaderStageConstantBufferCount> &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<u32>(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<u32>(ctx.executor, secondaryCbufOffset)};
return {primaryVal | secondaryVal};
}
}
return {.raw = primaryVal};
}
static std::pair<vk::DescriptorImageInfo, TextureView *> 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<TextureView *> sampledImages) { DescriptorUpdateInfo *Pipeline::SyncDescriptors(InterconnectContext &ctx, ConstantBufferSet &constantBuffers, Samplers &samplers, Textures &textures, span<TextureView *> sampledImages) {
SyncCachedStorageBufferViews(ctx.executor.executionNumber); SyncCachedStorageBufferViews(ctx.executor.executionNumber);