diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp index 97c3fe28..d8931004 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.cpp @@ -3,6 +3,7 @@ // Copyright © 2022 Skyline Team and Contributors (https://github.com/skyline-emu/) #include +#include #include #include "common/utils.h" #include "maxwell_3d.h" @@ -27,6 +28,7 @@ namespace skyline::gpu::interconnect::maxwell3d { activeState.MarkAllDirty(); constantBuffers.MarkAllDirty(); samplers.MarkAllDirty(); + quadConversionBufferAttached = false; }); executor.AddPipelineChangeCallback([this] { @@ -34,6 +36,24 @@ namespace skyline::gpu::interconnect::maxwell3d { }); } + vk::DeviceSize Maxwell3D::UpdateQuadConversionBuffer(u32 count, u32 firstVertex) { + vk::DeviceSize offset{conversion::quads::GetRequiredBufferSize(firstVertex, sizeof(u32))}; + vk::DeviceSize size{conversion::quads::GetRequiredBufferSize(count, sizeof(u32)) + offset}; + + if (!quadConversionBuffer || quadConversionBuffer->size_bytes() < size) { + quadConversionBuffer = std::make_shared(ctx.gpu.memory.AllocateBuffer(util::AlignUp(size, PAGE_SIZE))); + conversion::quads::GenerateQuadListConversionBuffer(quadConversionBuffer->cast().data(), firstVertex + count); + quadConversionBufferAttached = false; + } + + if (!quadConversionBufferAttached) { + ctx.executor.AttachDependency(quadConversionBuffer); + quadConversionBufferAttached = true; + } + + return offset; + } + vk::Rect2D Maxwell3D::GetClearScissor() { const auto &clearSurfaceControl{clearEngineRegisters.clearSurfaceControl}; @@ -173,6 +193,18 @@ namespace skyline::gpu::interconnect::maxwell3d { Pipeline *oldPipeline{activeState.GetPipeline()}; activeState.Update(ctx, builder, indexed, topology, count); + if (directState.inputAssembly.NeedsQuadConversion()) { + count = conversion::quads::GetIndexCount(count); + first = 0; + + if (!indexed) { + // Use an index buffer to emulate quad lists with a triangle list input topology + vk::DeviceSize offset{UpdateQuadConversionBuffer(count, first)}; + builder.SetIndexBuffer(BufferBinding{quadConversionBuffer->vkBuffer, offset}, vk::IndexType::eUint32); + indexed = true; + } + } + Pipeline *pipeline{activeState.GetPipeline()}; auto *descUpdateInfo{[&]() -> DescriptorUpdateInfo * { diff --git a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h index 9ee4fbda..e37eb55a 100644 --- a/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h +++ b/app/src/main/cpp/skyline/gpu/interconnect/maxwell_3d/maxwell_3d.h @@ -42,9 +42,13 @@ namespace skyline::gpu::interconnect::maxwell3d { ClearEngineRegisters clearEngineRegisters; ConstantBuffers constantBuffers; Samplers samplers; + std::shared_ptr quadConversionBuffer{}; + bool quadConversionBufferAttached{}; DescriptorAllocator::ActiveDescriptorSet *activeDescriptorSet{}; + size_t UpdateQuadConversionBuffer(u32 count, u32 firstVertex); + vk::Rect2D GetClearScissor(); public: