mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 12:21:51 +01:00
Implement the draw(...)BeginEnd Maxwell3D draw registers
Used by guest Vulkan games and nouveau.
This commit is contained in:
parent
270ef3e0d2
commit
c50852e546
@ -56,9 +56,9 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
}
|
||||
#undef REGTYPE
|
||||
|
||||
type::DrawTopology Maxwell3D::GetCurrentTopology() {
|
||||
type::DrawTopology Maxwell3D::ApplyTopologyOverride(type::DrawTopology beginMethodTopology) {
|
||||
return registers.primitiveTopologyControl->override == type::PrimitiveTopologyControl::Override::UseTopologyInBeginMethods ?
|
||||
registers.begin->op : type::ConvertPrimitiveTopologyToDrawTopology(*registers.primitiveTopology);
|
||||
beginMethodTopology : type::ConvertPrimitiveTopologyToDrawTopology(*registers.primitiveTopology);
|
||||
}
|
||||
|
||||
Maxwell3D::Maxwell3D(const DeviceState &state, ChannelContext &channelCtx, MacroState ¯oState)
|
||||
@ -149,6 +149,26 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
return;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawVertexArrayBeginEndInstanceSubsequent, {
|
||||
deferredDraw.instanceCount++;
|
||||
return;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer32BeginEndInstanceSubsequent, {
|
||||
deferredDraw.instanceCount++;
|
||||
return;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer16BeginEndInstanceSubsequent, {
|
||||
deferredDraw.instanceCount++;
|
||||
return;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer8BeginEndInstanceSubsequent, {
|
||||
deferredDraw.instanceCount++;
|
||||
return;
|
||||
})
|
||||
|
||||
// Once we stop calling draw methods flush the current draw since drawing is dependent on the register state not changing
|
||||
default:
|
||||
FlushDeferredDraw();
|
||||
@ -210,13 +230,99 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
ENGINE_STRUCT_CASE(drawVertexArray, count, {
|
||||
// Defer the draw until the first non-draw operation to allow for detecting instanced draws (see DeferredDrawState comment)
|
||||
deferredDraw.Set(count, *registers.vertexArrayStart, 0, *registers.globalBaseInstanceIndex, GetCurrentTopology(), false);
|
||||
deferredDraw.Set(count, *registers.vertexArrayStart, 0,
|
||||
*registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(registers.begin->op),
|
||||
false);
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawVertexArrayBeginEndInstanceFirst, {
|
||||
deferredDraw.Set(drawVertexArrayBeginEndInstanceFirst.count, drawVertexArrayBeginEndInstanceFirst.startIndex, 0,
|
||||
*registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawVertexArrayBeginEndInstanceFirst.topology),
|
||||
false);
|
||||
deferredDraw.instanceCount = 1;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawVertexArrayBeginEndInstanceSubsequent, {
|
||||
deferredDraw.Set(drawVertexArrayBeginEndInstanceSubsequent.count, drawVertexArrayBeginEndInstanceSubsequent.startIndex, 0,
|
||||
*registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawVertexArrayBeginEndInstanceSubsequent.topology),
|
||||
false);
|
||||
deferredDraw.instanceCount++;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_STRUCT_CASE(drawInlineIndex4X8, index0, {
|
||||
throw exception("drawInlineIndex4X8 not implemented!");
|
||||
})
|
||||
|
||||
ENGINE_STRUCT_CASE(drawInlineIndex2X16, even, {
|
||||
throw exception("drawInlineIndex2X16 not implemented!");
|
||||
})
|
||||
|
||||
ENGINE_STRUCT_CASE(drawIndexBuffer, count, {
|
||||
// Defer the draw until the first non-draw operation to allow for detecting instanced draws (see DeferredDrawState comment)
|
||||
deferredDraw.Set(count, registers.indexBuffer->first, *registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex, GetCurrentTopology(), true);
|
||||
deferredDraw.Set(count, registers.indexBuffer->first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(registers.begin->op),
|
||||
true);
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer32BeginEndInstanceFirst, {
|
||||
deferredDraw.Set(drawIndexBuffer32BeginEndInstanceFirst.count, drawIndexBuffer32BeginEndInstanceFirst.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer32BeginEndInstanceFirst.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount = 1;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer16BeginEndInstanceFirst, {
|
||||
deferredDraw.Set(drawIndexBuffer16BeginEndInstanceFirst.count, drawIndexBuffer16BeginEndInstanceFirst.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer16BeginEndInstanceFirst.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount = 1;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer8BeginEndInstanceFirst, {
|
||||
deferredDraw.Set(drawIndexBuffer8BeginEndInstanceFirst.count, drawIndexBuffer8BeginEndInstanceFirst.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer8BeginEndInstanceFirst.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount = 1;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer32BeginEndInstanceSubsequent, {
|
||||
deferredDraw.Set(drawIndexBuffer32BeginEndInstanceSubsequent.count, drawIndexBuffer32BeginEndInstanceSubsequent.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer32BeginEndInstanceSubsequent.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount++;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer16BeginEndInstanceSubsequent, {
|
||||
deferredDraw.Set(drawIndexBuffer16BeginEndInstanceSubsequent.count, drawIndexBuffer16BeginEndInstanceSubsequent.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer16BeginEndInstanceSubsequent.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount++;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
ENGINE_CASE(drawIndexBuffer8BeginEndInstanceSubsequent, {
|
||||
deferredDraw.Set(drawIndexBuffer8BeginEndInstanceSubsequent.count, drawIndexBuffer8BeginEndInstanceSubsequent.first,
|
||||
*registers.globalBaseVertexIndex, *registers.globalBaseInstanceIndex,
|
||||
ApplyTopologyOverride(drawIndexBuffer8BeginEndInstanceSubsequent.topology),
|
||||
true);
|
||||
deferredDraw.instanceCount++;
|
||||
batchEnableState.drawActive = true;
|
||||
})
|
||||
|
||||
|
@ -70,7 +70,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
}
|
||||
} deferredDraw{};
|
||||
|
||||
type::DrawTopology GetCurrentTopology();
|
||||
type::DrawTopology ApplyTopologyOverride(type::DrawTopology beginMethodTopology);
|
||||
|
||||
void FlushDeferredDraw();
|
||||
|
||||
@ -114,6 +114,11 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0xB2, type::SyncpointAction> syncpointAction;
|
||||
|
||||
struct DrawZeroIndex {
|
||||
u32 count;
|
||||
};
|
||||
Register<0xC1, DrawZeroIndex> drawZeroIndex;
|
||||
|
||||
Register<0xC8, type::TessellationParameters> tessellationParameters;
|
||||
|
||||
Register<0xDF, u32> rasterEnable;
|
||||
@ -184,6 +189,18 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x458, std::array<type::VertexAttribute, type::VertexAttributeCount>> vertexAttributes;
|
||||
|
||||
Register<0x484, u32> invalidateSamplerCacheAll;
|
||||
Register<0x485, u32> invalidateTextureHeaderCacheAll;
|
||||
|
||||
struct DrawVertexArrayBeginEndInstance {
|
||||
u16 startIndex;
|
||||
u16 count : 12;
|
||||
type::DrawTopology topology : 4;
|
||||
};
|
||||
|
||||
Register<0x485, DrawVertexArrayBeginEndInstance> drawVertexArrayBeginEndInstanceFirst;
|
||||
Register<0x486, DrawVertexArrayBeginEndInstance> drawVertexArrayBeginEndInstanceSubsequent;
|
||||
|
||||
Register<0x487, type::CtSelect> ctSelect;
|
||||
|
||||
Register<0x48A, type::ZtSize> ztSize;
|
||||
@ -196,9 +213,25 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
Register<0x4B9, u32> blendStatePerTargetEnable;
|
||||
Register<0x4BA, u32> depthWriteEnable;
|
||||
Register<0x4BB, u32> alphaTestEnable;
|
||||
|
||||
struct InlineIndexAlign {
|
||||
u32 count : 30;
|
||||
u8 start : 2;
|
||||
};
|
||||
|
||||
struct DrawInlineIndex {
|
||||
u8 index0;
|
||||
u8 index1;
|
||||
u8 index2;
|
||||
u8 index3;
|
||||
};
|
||||
|
||||
Register<0x4C1, DrawInlineIndex> drawInlineIndex4X8;
|
||||
|
||||
Register<0x4C3, type::CompareFunc> depthFunc;
|
||||
Register<0x4C4, float> alphaRef;
|
||||
Register<0x4C5, type::CompareFunc> alphaFunc;
|
||||
|
||||
Register<0x4C6, u32> drawAutoStride;
|
||||
|
||||
struct BlendConstant {
|
||||
@ -247,7 +280,24 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
|
||||
Register<0x56F, float> depthBias;
|
||||
|
||||
Register<0x57A, u32> drawInlineIndex;
|
||||
|
||||
struct InlineIndex2X16Align {
|
||||
u32 count : 31;
|
||||
bool startOdd : 1;
|
||||
};
|
||||
|
||||
Register<0x57B, InlineIndex2X16Align> inlineIndex2X16Align;
|
||||
|
||||
struct DrawInlineIndex2X16 {
|
||||
u16 even;
|
||||
u16 odd;
|
||||
};
|
||||
|
||||
Register<0x57C, DrawInlineIndex2X16> drawInlineIndex2X16;
|
||||
|
||||
Register<0x581, type::PointCoordReplace> pointCoordReplace;
|
||||
|
||||
Register<0x582, Address> programRegion;
|
||||
|
||||
Register<0x585, u32> end; //!< Method-only register with no real value, used after calling vertexBeginGl to invoke the draw
|
||||
@ -299,6 +349,19 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
||||
};
|
||||
Register<0x5F8, DrawIndexBuffer> drawIndexBuffer;
|
||||
|
||||
struct DrawIndexBufferBeginEndInstance {
|
||||
u16 first;
|
||||
u16 count : 12;
|
||||
type::DrawTopology topology : 4;
|
||||
};
|
||||
|
||||
Register<0x5F9, DrawIndexBufferBeginEndInstance> drawIndexBuffer32BeginEndInstanceFirst;
|
||||
Register<0x5FA, DrawIndexBufferBeginEndInstance> drawIndexBuffer16BeginEndInstanceFirst;
|
||||
Register<0x5FB, DrawIndexBufferBeginEndInstance> drawIndexBuffer8BeginEndInstanceFirst;
|
||||
Register<0x5FC, DrawIndexBufferBeginEndInstance> drawIndexBuffer32BeginEndInstanceSubsequent;
|
||||
Register<0x5FD, DrawIndexBufferBeginEndInstance> drawIndexBuffer16BeginEndInstanceSubsequent;
|
||||
Register<0x5FE, DrawIndexBufferBeginEndInstance> drawIndexBuffer8BeginEndInstanceSubsequent;
|
||||
|
||||
Register<0x61F, float> depthBiasClamp;
|
||||
|
||||
Register<0x620, std::array<type::VertexStreamInstance, type::VertexStreamCount>> vertexStreamInstance; //!< A per-VBO boolean denoting if the vertex input rate should be per vertex or per instance
|
||||
|
Loading…
Reference in New Issue
Block a user