Update user code for new megabuffering

This commit is contained in:
Billy Laws 2022-09-17 13:09:06 +01:00
parent cc776ae395
commit 55d77b7eb0
4 changed files with 36 additions and 45 deletions

View File

@ -13,15 +13,6 @@
#include "active_state.h"
namespace skyline::gpu::interconnect::maxwell3d {
/* General Buffer Helpers */
static BufferBinding *AllocateMegaBufferBinding(InterconnectContext &ctx, BufferView &view) {
auto megaBufferAllocation{view.AcquireMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator())};
if (megaBufferAllocation)
return ctx.executor.allocator.EmplaceUntracked<BufferBinding>(megaBufferAllocation.buffer, megaBufferAllocation.offset, view.size);
else
return nullptr;
}
/* Vertex Buffer */
void VertexBufferState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
manager.Bind(handle, vertexStream.format, vertexStream.location);
@ -36,23 +27,27 @@ namespace skyline::gpu::interconnect::maxwell3d {
view.Update(ctx, engine->vertexStream.location, size);
ctx.executor.AttachBuffer(*view);
if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding)
if (megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber);
megaBufferBinding)
builder.SetVertexBuffer(index, megaBufferBinding);
else
builder.SetVertexBuffer(index, *view);
} else {
auto nullBinding{ctx.executor.allocator.EmplaceUntracked<BufferBinding>()};
megaBufferBinding = {};
builder.SetVertexBuffer(index, nullBinding);
// TODO: null descriptor
}
}
bool VertexBufferState::Refresh(InterconnectContext &ctx, StateUpdateBuilder &builder) {
if (megaBufferBinding) {
if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding)
builder.SetVertexBuffer(index, megaBufferBinding);
else
builder.SetVertexBuffer(index, *view);
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
newMegaBufferBinding != megaBufferBinding) {
megaBufferBinding = newMegaBufferBinding;
if (megaBufferBinding)
builder.SetVertexBuffer(index, megaBufferBinding);
else
builder.SetVertexBuffer(index, *view);
}
}
return false;
}
@ -89,7 +84,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
}
}
static BufferBinding *GenerateQuadConversionIndexBuffer(InterconnectContext &ctx, vk::IndexType indexType, BufferView &view, u32 elementCount) {
static BufferBinding GenerateQuadConversionIndexBuffer(InterconnectContext &ctx, vk::IndexType indexType, BufferView &view, u32 elementCount) {
auto viewSpan{view.GetReadOnlyBackingSpan(false /* We attach above so always false */, []() {
// TODO: see Read()
Logger::Error("Dirty index buffer reads for attached buffers are unimplemented");
@ -100,7 +95,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
conversion::quads::GenerateIndexedQuadConversionBuffer(quadConversionAllocation.region.data(), viewSpan.data(), elementCount, indexType);
return ctx.executor.allocator.EmplaceUntracked<BufferBinding>(quadConversionAllocation.buffer, quadConversionAllocation.offset, indexBufferSize);
return {quadConversionAllocation.buffer, quadConversionAllocation.offset, indexBufferSize};
}
/* Index Buffer */
@ -123,7 +118,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
if (quadConversion)
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
else
megaBufferBinding = AllocateMegaBufferBinding(ctx, *view);
megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber);
if (megaBufferBinding)
builder.SetIndexBuffer(megaBufferBinding, indexType);
@ -143,10 +138,15 @@ namespace skyline::gpu::interconnect::maxwell3d {
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
builder.SetIndexBuffer(megaBufferBinding, indexType);
} else if (megaBufferBinding) {
if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding)
builder.SetIndexBuffer(megaBufferBinding, indexType);
else
builder.SetIndexBuffer(*view, indexType);
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
newMegaBufferBinding != megaBufferBinding) {
megaBufferBinding = newMegaBufferBinding;
if (megaBufferBinding)
builder.SetIndexBuffer(megaBufferBinding, indexType);
else
builder.SetIndexBuffer(*view, indexType);
}
}
return false;
@ -174,9 +174,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
builder.SetTransformFeedbackBuffer(index, *view);
} else {
// Bind an empty buffer ourselves since Vulkan doesn't support passing a VK_NULL_HANDLE xfb buffer
auto binding{ctx.executor.allocator.EmplaceUntracked<BufferBinding>(
ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer)};
builder.SetTransformFeedbackBuffer(index, binding);
builder.SetTransformFeedbackBuffer(index, {ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer});
}
}
}

View File

@ -21,7 +21,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
dirty::BoundSubresource<EngineRegisters> engine;
CachedMappedBufferView view{};
BufferBinding *megaBufferBinding{};
BufferBinding megaBufferBinding{};
u32 index{};
public:
@ -45,7 +45,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
private:
dirty::BoundSubresource<EngineRegisters> engine;
CachedMappedBufferView view{};
BufferBinding *megaBufferBinding{};
BufferBinding megaBufferBinding{};
vk::IndexType indexType{};
u32 usedElementCount{};
bool usedQuadConversion{};

View File

@ -65,18 +65,6 @@ namespace skyline::gpu::interconnect::maxwell3d {
}
};
/**
* @brief Represents a bound Vulkan buffer that can be used for state updates
*/
struct BufferBinding {
vk::Buffer buffer{};
vk::DeviceSize offset{};
vk::DeviceSize size{};
BufferBinding() = default;
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

@ -571,11 +571,16 @@ namespace skyline::gpu::interconnect::maxwell3d {
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);
size_t cbufIdx{desc.index + arrayIdx};
auto view{constantBuffers[i][cbufIdx].view};
ctx.executor.AttachBuffer(view);
size_t sizeOverride{std::min<size_t>(stage.info.constant_buffer_used_sizes[cbufIdx], view.size)};
if (auto megaBufferBinding{view.TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber, sizeOverride)}) {
return megaBufferBinding;
} else {
ctx.executor.AttachBuffer(view);
view.GetBuffer()->BlockSequencedCpuBackingWrites();
return view;
}
});