mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 06:51:52 +01:00
Add partial conditional rendering support
Disabled for cases where the results come from queries rn, however still functional for cases like AC which don't use it with queries.
This commit is contained in:
parent
a2798a9184
commit
c440575a56
@ -616,6 +616,7 @@ namespace skyline::gpu::interconnect {
|
||||
|
||||
slot->nodes.splice(slot->nodes.end(), slot->pendingPostRenderPassNodes);
|
||||
|
||||
|
||||
{
|
||||
slot->WaitReady();
|
||||
|
||||
|
@ -62,6 +62,47 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
beginMethodTopology : type::ConvertPrimitiveTopologyToDrawTopology(*registers.primitiveTopology);
|
||||
}
|
||||
|
||||
bool Maxwell3D::CheckRenderEnable() {
|
||||
if (registers.renderEnableOverride->mode == Registers::RenderEnableOverride::Mode::AlwaysRender)
|
||||
return true;
|
||||
else if (registers.renderEnableOverride->mode == Registers::RenderEnableOverride::Mode::NeverRender)
|
||||
return false;
|
||||
|
||||
|
||||
|
||||
switch (registers.renderEnable->mode) {
|
||||
case Registers::RenderEnable::Mode::True:
|
||||
return true;
|
||||
case Registers::RenderEnable::Mode::False:
|
||||
return false;
|
||||
case Registers::RenderEnable::Mode::Conditional:
|
||||
// TODO: Use indirect draws to emulate conditional rendering with queries, for now just ignore such cases as they would decrease performance anyway by forcing a CPU sync
|
||||
if (interconnect.QueryPresentAtAddress(u64{registers.renderEnable->offset}))
|
||||
return true;
|
||||
|
||||
return channelCtx.asCtx->gmmu.Read<u32>(registers.renderEnable->offset) != 0;
|
||||
case Registers::RenderEnable::Mode::RenderIfEqual:
|
||||
// TODO: See above
|
||||
if (interconnect.QueryPresentAtAddress(u64{registers.renderEnable->offset}) ||
|
||||
interconnect.QueryPresentAtAddress(u64{registers.renderEnable->offset + 16}))
|
||||
return true;
|
||||
|
||||
return channelCtx.asCtx->gmmu.Read<u32>(registers.renderEnable->offset) ==
|
||||
channelCtx.asCtx->gmmu.Read<u32>(registers.renderEnable->offset + 16);
|
||||
case Registers::RenderEnable::Mode::RenderIfNotEqual:
|
||||
// TODO: See above
|
||||
if (interconnect.QueryPresentAtAddress(u64{registers.renderEnable->offset}) ||
|
||||
interconnect.QueryPresentAtAddress(u64{registers.renderEnable->offset + 16}))
|
||||
return true;
|
||||
|
||||
return channelCtx.asCtx->gmmu.Read<u32>(registers.renderEnable->offset) !=
|
||||
channelCtx.asCtx->gmmu.Read<u32>(registers.renderEnable->offset + 16);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Maxwell3D::Maxwell3D(const DeviceState &state, ChannelContext &channelCtx, MacroState ¯oState)
|
||||
: MacroEngineBase{macroState},
|
||||
syncpoints{state.soc->host1x.syncpoints},
|
||||
@ -76,7 +117,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
__attribute__((always_inline)) void Maxwell3D::FlushDeferredDraw() {
|
||||
if (batchEnableState.drawActive) {
|
||||
batchEnableState.drawActive = false;
|
||||
interconnect.Draw(deferredDraw.drawTopology, *registers.streamOutputEnable, deferredDraw.indexed, deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex, deferredDraw.drawBaseInstance);
|
||||
if (CheckRenderEnable())
|
||||
interconnect.Draw(deferredDraw.drawTopology, *registers.streamOutputEnable, deferredDraw.indexed, deferredDraw.drawCount, deferredDraw.drawFirst, deferredDraw.instanceCount, deferredDraw.drawBaseVertex, deferredDraw.drawBaseInstance);
|
||||
deferredDraw.instanceCount = 1;
|
||||
}
|
||||
}
|
||||
@ -229,7 +271,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
})
|
||||
|
||||
ENGINE_CASE(clearSurface, {
|
||||
interconnect.Clear(clearSurface);
|
||||
if (CheckRenderEnable())
|
||||
interconnect.Clear(clearSurface);
|
||||
})
|
||||
|
||||
ENGINE_CASE(begin, {
|
||||
@ -489,23 +532,23 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
auto topology{static_cast<type::DrawTopology>(drawTopology)};
|
||||
registers.globalBaseInstanceIndex = globalBaseInstanceIndex;
|
||||
registers.vertexArrayStart = vertexArrayStart;
|
||||
|
||||
interconnect.Draw(topology, *registers.streamOutputEnable, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex);
|
||||
if (CheckRenderEnable())
|
||||
interconnect.Draw(topology, *registers.streamOutputEnable, false, vertexArrayCount, vertexArrayStart, instanceCount, 0, globalBaseInstanceIndex);
|
||||
registers.globalBaseInstanceIndex = 0;
|
||||
}
|
||||
|
||||
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);
|
||||
if (CheckRenderEnable())
|
||||
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);
|
||||
if (CheckRenderEnable())
|
||||
interconnect.DrawIndirect(topology, *registers.streamOutputEnable, true, indirectBuffer, count, stride);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
}
|
||||
} deferredDraw{};
|
||||
|
||||
bool CheckRenderEnable();
|
||||
|
||||
type::DrawTopology ApplyTopologyOverride(type::DrawTopology beginMethodTopology);
|
||||
|
||||
void FlushDeferredDraw();
|
||||
@ -268,6 +270,19 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x54F, type::MultisampleControl> multisampleControl;
|
||||
|
||||
struct RenderEnable {
|
||||
enum class Mode : u32 {
|
||||
False = 0,
|
||||
True = 1,
|
||||
Conditional = 2,
|
||||
RenderIfEqual = 3,
|
||||
RenderIfNotEqual = 4,
|
||||
};
|
||||
Address offset;
|
||||
Mode mode;
|
||||
};
|
||||
Register<0x554, RenderEnable> renderEnable;
|
||||
|
||||
Register<0x557, TexSamplerPool> texSamplerPool;
|
||||
|
||||
Register<0x55B, float> slopeScaleDepthBias;
|
||||
@ -375,6 +390,19 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x64B, u32> viewportScaleOffsetEnable;
|
||||
Register<0x64F, type::ViewportClipControl> viewportClipControl;
|
||||
|
||||
struct RenderEnableOverride {
|
||||
enum class Mode : u8 {
|
||||
UseRenderEnable = 0,
|
||||
AlwaysRender = 1,
|
||||
NeverRender = 2,
|
||||
};
|
||||
|
||||
Mode mode : 2;
|
||||
u32 _pad_ : 30;
|
||||
};
|
||||
Register<0x651, RenderEnableOverride> renderEnableOverride;
|
||||
|
||||
|
||||
Register<0x652, type::PrimitiveTopologyControl> primitiveTopologyControl;
|
||||
Register<0x65C, type::PrimitiveTopology> primitiveTopology;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user