mirror of
https://github.com/skyline-emu/skyline.git
synced 2025-01-09 20:29:24 +01:00
Flush deferred draws before executing macro HLE and cleanup
This commit is contained in:
parent
c928084bb1
commit
d893777262
@ -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{
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user