mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-16 03:59:18 +01:00
Update user code for new megabuffering
This commit is contained in:
parent
cc776ae395
commit
55d77b7eb0
@ -13,15 +13,6 @@
|
|||||||
#include "active_state.h"
|
#include "active_state.h"
|
||||||
|
|
||||||
namespace skyline::gpu::interconnect::maxwell3d {
|
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 */
|
/* Vertex Buffer */
|
||||||
void VertexBufferState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
void VertexBufferState::EngineRegisters::DirtyBind(DirtyManager &manager, dirty::Handle handle) const {
|
||||||
manager.Bind(handle, vertexStream.format, vertexStream.location);
|
manager.Bind(handle, vertexStream.format, vertexStream.location);
|
||||||
@ -36,24 +27,28 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
view.Update(ctx, engine->vertexStream.location, size);
|
view.Update(ctx, engine->vertexStream.location, size);
|
||||||
ctx.executor.AttachBuffer(*view);
|
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);
|
builder.SetVertexBuffer(index, megaBufferBinding);
|
||||||
else
|
else
|
||||||
builder.SetVertexBuffer(index, *view);
|
builder.SetVertexBuffer(index, *view);
|
||||||
} else {
|
} else {
|
||||||
auto nullBinding{ctx.executor.allocator.EmplaceUntracked<BufferBinding>()};
|
// TODO: null descriptor
|
||||||
megaBufferBinding = {};
|
|
||||||
builder.SetVertexBuffer(index, nullBinding);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VertexBufferState::Refresh(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
bool VertexBufferState::Refresh(InterconnectContext &ctx, StateUpdateBuilder &builder) {
|
||||||
if (megaBufferBinding) {
|
if (megaBufferBinding) {
|
||||||
if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding)
|
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
|
||||||
|
newMegaBufferBinding != megaBufferBinding) {
|
||||||
|
|
||||||
|
megaBufferBinding = newMegaBufferBinding;
|
||||||
|
if (megaBufferBinding)
|
||||||
builder.SetVertexBuffer(index, megaBufferBinding);
|
builder.SetVertexBuffer(index, megaBufferBinding);
|
||||||
else
|
else
|
||||||
builder.SetVertexBuffer(index, *view);
|
builder.SetVertexBuffer(index, *view);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
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 */, []() {
|
auto viewSpan{view.GetReadOnlyBackingSpan(false /* We attach above so always false */, []() {
|
||||||
// TODO: see Read()
|
// TODO: see Read()
|
||||||
Logger::Error("Dirty index buffer reads for attached buffers are unimplemented");
|
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);
|
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 */
|
/* Index Buffer */
|
||||||
@ -123,7 +118,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
if (quadConversion)
|
if (quadConversion)
|
||||||
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
|
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
|
||||||
else
|
else
|
||||||
megaBufferBinding = AllocateMegaBufferBinding(ctx, *view);
|
megaBufferBinding = view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber);
|
||||||
|
|
||||||
if (megaBufferBinding)
|
if (megaBufferBinding)
|
||||||
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
||||||
@ -143,11 +138,16 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
|
megaBufferBinding = GenerateQuadConversionIndexBuffer(ctx, indexType, *view, elementCount);
|
||||||
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
||||||
} else if (megaBufferBinding) {
|
} else if (megaBufferBinding) {
|
||||||
if (megaBufferBinding = AllocateMegaBufferBinding(ctx, *view); megaBufferBinding)
|
if (auto newMegaBufferBinding{view->TryMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator(), ctx.executor.executionNumber)};
|
||||||
|
newMegaBufferBinding != megaBufferBinding) {
|
||||||
|
|
||||||
|
megaBufferBinding = newMegaBufferBinding;
|
||||||
|
if (megaBufferBinding)
|
||||||
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
builder.SetIndexBuffer(megaBufferBinding, indexType);
|
||||||
else
|
else
|
||||||
builder.SetIndexBuffer(*view, indexType);
|
builder.SetIndexBuffer(*view, indexType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -174,9 +174,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
builder.SetTransformFeedbackBuffer(index, *view);
|
builder.SetTransformFeedbackBuffer(index, *view);
|
||||||
} else {
|
} else {
|
||||||
// Bind an empty buffer ourselves since Vulkan doesn't support passing a VK_NULL_HANDLE xfb buffer
|
// Bind an empty buffer ourselves since Vulkan doesn't support passing a VK_NULL_HANDLE xfb buffer
|
||||||
auto binding{ctx.executor.allocator.EmplaceUntracked<BufferBinding>(
|
builder.SetTransformFeedbackBuffer(index, {ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer});
|
||||||
ctx.executor.AcquireMegaBufferAllocator().Allocate(ctx.executor.cycle, 0).buffer)};
|
|
||||||
builder.SetTransformFeedbackBuffer(index, binding);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
dirty::BoundSubresource<EngineRegisters> engine;
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
|
|
||||||
CachedMappedBufferView view{};
|
CachedMappedBufferView view{};
|
||||||
BufferBinding *megaBufferBinding{};
|
BufferBinding megaBufferBinding{};
|
||||||
u32 index{};
|
u32 index{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -45,7 +45,7 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
private:
|
private:
|
||||||
dirty::BoundSubresource<EngineRegisters> engine;
|
dirty::BoundSubresource<EngineRegisters> engine;
|
||||||
CachedMappedBufferView view{};
|
CachedMappedBufferView view{};
|
||||||
BufferBinding *megaBufferBinding{};
|
BufferBinding megaBufferBinding{};
|
||||||
vk::IndexType indexType{};
|
vk::IndexType indexType{};
|
||||||
u32 usedElementCount{};
|
u32 usedElementCount{};
|
||||||
bool usedQuadConversion{};
|
bool usedQuadConversion{};
|
||||||
|
@ -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 DynamicBufferBinding = std::variant<BufferBinding, BufferView>;
|
||||||
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
|
using DirtyManager = dirty::Manager<soc::gm20b::engine::EngineMethodsEnd * sizeof(u32), sizeof(u32)>;
|
||||||
|
@ -571,11 +571,16 @@ namespace skyline::gpu::interconnect::maxwell3d {
|
|||||||
const auto &stage{shaderStages[i]};
|
const auto &stage{shaderStages[i]};
|
||||||
writeBufferDescs(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount,
|
writeBufferDescs(vk::DescriptorType::eUniformBuffer, stage.info.constant_buffer_descriptors, descriptorInfo.uniformBufferDescCount,
|
||||||
[&](const Shader::ConstantBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) -> DynamicBufferBinding {
|
[&](const Shader::ConstantBufferDescriptor &desc, size_t descIdx, size_t arrayIdx) -> DynamicBufferBinding {
|
||||||
auto view{constantBuffers[i][desc.index + arrayIdx].view};
|
size_t cbufIdx{desc.index + arrayIdx};
|
||||||
if (auto megaBufferAlloc{view.AcquireMegaBuffer(ctx.executor.cycle, ctx.executor.AcquireMegaBufferAllocator())}) {
|
auto view{constantBuffers[i][cbufIdx].view};
|
||||||
return BufferBinding(megaBufferAlloc.buffer, megaBufferAlloc.offset, view.size);
|
|
||||||
} else {
|
|
||||||
ctx.executor.AttachBuffer(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 {
|
||||||
|
view.GetBuffer()->BlockSequencedCpuBackingWrites();
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user