Flush deferred draws before executing macro HLE and cleanup

This commit is contained in:
Billy Laws 2023-03-11 20:49:34 +00:00
parent c928084bb1
commit d893777262
5 changed files with 21 additions and 36 deletions

View File

@ -63,7 +63,7 @@ namespace skyline::gpu::interconnect {
executor.AttachBuffer(clearBuf); executor.AttachBuffer(clearBuf);
clearBuf.GetBuffer()->BlockSequencedCpuBackingWrites(); clearBuf.GetBuffer()->BlockSequencedCpuBackingWrites();
clearBuf.GetBuffer()->MarkGpuDirty(); clearBuf.GetBuffer()->MarkGpuDirty(executor.usageTracker);
executor.AddOutsideRpCommand([clearBuf, value](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &gpu) { executor.AddOutsideRpCommand([clearBuf, value](vk::raii::CommandBuffer &commandBuffer, const std::shared_ptr<FenceCycle> &, GPU &gpu) {
commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, {}, vk::MemoryBarrier{ commandBuffer.pipelineBarrier(vk::PipelineStageFlagBits::eAllCommands, vk::PipelineStageFlagBits::eTransfer, {}, vk::MemoryBarrier{

View File

@ -106,11 +106,11 @@ namespace skyline::soc::gm20b::engine {
*/ */
virtual u32 ReadMethodFromMacro(u32 method) = 0; virtual u32 ReadMethodFromMacro(u32 method) = 0;
virtual void DrawInstanced(bool setRegs, u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) { virtual void DrawInstanced(u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) {
throw exception("DrawInstanced is not implemented for this engine"); throw exception("DrawInstanced is not implemented for this engine");
} }
virtual void DrawIndexedInstanced(bool setRegs, u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) { virtual void DrawIndexedInstanced(u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) {
throw exception("DrawIndexedInstanced is not implemented for this engine"); throw exception("DrawIndexedInstanced is not implemented for this engine");
} }

View File

@ -475,32 +475,27 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
return registers.raw[method]; return registers.raw[method];
} }
void Maxwell3D::DrawInstanced(bool setRegs, u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) { void Maxwell3D::DrawInstanced(u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) {
FlushEngineState();
auto topology{static_cast<type::DrawTopology>(drawTopology)}; auto topology{static_cast<type::DrawTopology>(drawTopology)};
if (setRegs) { registers.globalBaseInstanceIndex = globalBaseInstanceIndex;
registers.begin->op = topology; registers.vertexArrayStart = vertexArrayStart;
registers.drawVertexArray->count = vertexArrayCount;
registers.vertexArrayStart = vertexArrayStart;
registers.globalBaseInstanceIndex = globalBaseInstanceIndex;
}
interconnect.Draw(topology, *registers.streamOutputEnable, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex); interconnect.Draw(topology, *registers.streamOutputEnable, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex);
registers.globalBaseInstanceIndex = 0;
} }
void Maxwell3D::DrawIndexedInstanced(bool setRegs, u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) { void Maxwell3D::DrawIndexedInstanced(u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) {
auto topology{static_cast<type::DrawTopology>(drawTopology)}; FlushEngineState();
if (setRegs) {
registers.begin->op = topology;
registers.drawIndexBuffer->count = indexBufferCount;
registers.indexBuffer->first = indexBufferFirst;
registers.globalBaseVertexIndex = globalBaseVertexIndex;
registers.globalBaseInstanceIndex = globalBaseInstanceIndex;
}
auto topology{static_cast<type::DrawTopology>(drawTopology)};
interconnect.Draw(topology, *registers.streamOutputEnable, true, indexBufferCount, indexBufferFirst, instanceCount, globalBaseVertexIndex, globalBaseInstanceIndex); interconnect.Draw(topology, *registers.streamOutputEnable, true, indexBufferCount, indexBufferFirst, instanceCount, globalBaseVertexIndex, globalBaseInstanceIndex);
} }
void Maxwell3D::DrawIndexedIndirect(u32 drawTopology, span<u8> indirectBuffer, u32 count, u32 stride) { void Maxwell3D::DrawIndexedIndirect(u32 drawTopology, span<u8> indirectBuffer, u32 count, u32 stride) {
FlushEngineState();
auto topology{static_cast<type::DrawTopology>(drawTopology)}; auto topology{static_cast<type::DrawTopology>(drawTopology)};
interconnect.DrawIndirect(topology, *registers.streamOutputEnable, true, indirectBuffer, count, stride); interconnect.DrawIndirect(topology, *registers.streamOutputEnable, true, indirectBuffer, count, stride);
} }

View File

@ -453,9 +453,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
u32 ReadMethodFromMacro(u32 method) override; u32 ReadMethodFromMacro(u32 method) override;
void DrawInstanced(bool setRegs, u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) override; void DrawInstanced(u32 drawTopology, u32 vertexArrayCount, u32 instanceCount, u32 vertexArrayStart, u32 globalBaseInstanceIndex) override;
void DrawIndexedInstanced(bool setRegs, u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) override; void DrawIndexedInstanced(u32 drawTopology, u32 indexBufferCount, u32 instanceCount, u32 globalBaseVertexIndex, u32 indexBufferFirst, u32 globalBaseInstanceIndex) override;
void DrawIndexedIndirect(u32 drawTopology, span<u8> indirectBuffer, u32 count, u32 stride) override; void DrawIndexedIndirect(u32 drawTopology, span<u8> indirectBuffer, u32 count, u32 stride) override;
}; };

View File

@ -30,21 +30,11 @@ namespace skyline::soc::gm20b {
u32 instanceCount{targetEngine->ReadMethodFromMacro(0xD1B) & *args[2]}; u32 instanceCount{targetEngine->ReadMethodFromMacro(0xD1B) & *args[2]};
targetEngine->DrawInstanced(true, *args[0], *args[1], instanceCount, *args[3], *args[4]); targetEngine->DrawInstanced(*args[0], *args[1], instanceCount, *args[3], *args[4]);
return true; return true;
} }
bool DrawIndexedInstanced(size_t offset, span<GpfifoArgument> args, engine::MacroEngineBase *targetEngine, const std::function<void(void)> &flushCallback) { bool DrawInstancedIndexedIndirect(size_t offset, span<GpfifoArgument> args, engine::MacroEngineBase *targetEngine, const std::function<void(void)> &flushCallback) {
if (AnyArgsDirty(args))
flushCallback();
u32 instanceCount{targetEngine->ReadMethodFromMacro(0xD1B) & *args[2]};
targetEngine->DrawIndexedInstanced(true, *args[0], *args[1], instanceCount, *args[3], *args[4], *args[5]);
return true;
}
bool DrawInstancedIndexedIndirectWithConstantBuffer(size_t offset, span<GpfifoArgument> args, engine::MacroEngineBase *targetEngine, const std::function<void(void)> &flushCallback) {
u32 topology{*args[0]}; u32 topology{*args[0]};
bool topologyConversion{TopologyRequiresConversion(static_cast<engine::maxwell3d::type::DrawTopology>(topology))}; bool topologyConversion{TopologyRequiresConversion(static_cast<engine::maxwell3d::type::DrawTopology>(topology))};
@ -54,7 +44,7 @@ namespace skyline::soc::gm20b {
if (topologyConversion || !args[1].dirty) { if (topologyConversion || !args[1].dirty) {
u32 instanceCount{targetEngine->ReadMethodFromMacro(0xD1B) & *args[2]}; u32 instanceCount{targetEngine->ReadMethodFromMacro(0xD1B) & *args[2]};
targetEngine->DrawIndexedInstanced(false, topology, *args[1], instanceCount, *args[4], *args[3], *args[5]); targetEngine->DrawIndexedInstanced(topology, *args[1], instanceCount, *args[4], *args[3], *args[5]);
} else { } else {
targetEngine->DrawIndexedIndirect(topology, span(args[1].argumentPtr, 5).cast<u8>(), 1, 0); targetEngine->DrawIndexedIndirect(topology, span(args[1].argumentPtr, 5).cast<u8>(), 1, 0);
} }
@ -70,8 +60,8 @@ namespace skyline::soc::gm20b {
constexpr std::array<HleFunctionInfo, 0x4> functions{{ constexpr std::array<HleFunctionInfo, 0x4> functions{{
{DrawInstanced, 0x12, 0x2FDD711}, {DrawInstanced, 0x12, 0x2FDD711},
{DrawIndexedInstanced, 0x17, 0xDBC3B762}, {DrawInstancedIndexedIndirect, 0x17, 0xDBC3B762},
{DrawInstancedIndexedIndirectWithConstantBuffer, 0x1F, 0xDA07F4E5} {DrawInstancedIndexedIndirect, 0x1F, 0xDA07F4E5} // This macro is the same as above but it writes draw params to a cbuf, which are unnecessary due to hades HLE
}}; }};
static Function LookupFunction(span<u32> code) { static Function LookupFunction(span<u32> code) {