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);
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) {
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 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");
}
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");
}

View File

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

View File

@ -30,21 +30,11 @@ namespace skyline::soc::gm20b {
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;
}
bool DrawIndexedInstanced(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) {
bool DrawInstancedIndexedIndirect(size_t offset, span<GpfifoArgument> args, engine::MacroEngineBase *targetEngine, const std::function<void(void)> &flushCallback) {
u32 topology{*args[0]};
bool topologyConversion{TopologyRequiresConversion(static_cast<engine::maxwell3d::type::DrawTopology>(topology))};
@ -54,7 +44,7 @@ namespace skyline::soc::gm20b {
if (topologyConversion || !args[1].dirty) {
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 {
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{{
{DrawInstanced, 0x12, 0x2FDD711},
{DrawIndexedInstanced, 0x17, 0xDBC3B762},
{DrawInstancedIndexedIndirectWithConstantBuffer, 0x1F, 0xDA07F4E5}
{DrawInstancedIndexedIndirect, 0x17, 0xDBC3B762},
{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) {