mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-29 13:35:30 +03: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
|
#undef REGTYPE
|
||||||
|
|
||||||
type::DrawTopology Maxwell3D::GetCurrentTopology() {
|
type::DrawTopology Maxwell3D::ApplyTopologyOverride(type::DrawTopology beginMethodTopology) {
|
||||||
return registers.primitiveTopologyControl->override == type::PrimitiveTopologyControl::Override::UseTopologyInBeginMethods ?
|
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)
|
Maxwell3D::Maxwell3D(const DeviceState &state, ChannelContext &channelCtx, MacroState ¯oState)
|
||||||
@ -149,6 +149,26 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
return;
|
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
|
// Once we stop calling draw methods flush the current draw since drawing is dependent on the register state not changing
|
||||||
default:
|
default:
|
||||||
FlushDeferredDraw();
|
FlushDeferredDraw();
|
||||||
@ -210,13 +230,99 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
ENGINE_STRUCT_CASE(drawVertexArray, count, {
|
ENGINE_STRUCT_CASE(drawVertexArray, count, {
|
||||||
// Defer the draw until the first non-draw operation to allow for detecting instanced draws (see DeferredDrawState comment)
|
// 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;
|
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, {
|
ENGINE_STRUCT_CASE(drawIndexBuffer, count, {
|
||||||
// Defer the draw until the first non-draw operation to allow for detecting instanced draws (see DeferredDrawState comment)
|
// 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;
|
batchEnableState.drawActive = true;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
}
|
}
|
||||||
} deferredDraw{};
|
} deferredDraw{};
|
||||||
|
|
||||||
type::DrawTopology GetCurrentTopology();
|
type::DrawTopology ApplyTopologyOverride(type::DrawTopology beginMethodTopology);
|
||||||
|
|
||||||
void FlushDeferredDraw();
|
void FlushDeferredDraw();
|
||||||
|
|
||||||
@ -114,6 +114,11 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0xB2, type::SyncpointAction> syncpointAction;
|
Register<0xB2, type::SyncpointAction> syncpointAction;
|
||||||
|
|
||||||
|
struct DrawZeroIndex {
|
||||||
|
u32 count;
|
||||||
|
};
|
||||||
|
Register<0xC1, DrawZeroIndex> drawZeroIndex;
|
||||||
|
|
||||||
Register<0xC8, type::TessellationParameters> tessellationParameters;
|
Register<0xC8, type::TessellationParameters> tessellationParameters;
|
||||||
|
|
||||||
Register<0xDF, u32> rasterEnable;
|
Register<0xDF, u32> rasterEnable;
|
||||||
@ -184,6 +189,18 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x458, std::array<type::VertexAttribute, type::VertexAttributeCount>> vertexAttributes;
|
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<0x487, type::CtSelect> ctSelect;
|
||||||
|
|
||||||
Register<0x48A, type::ZtSize> ztSize;
|
Register<0x48A, type::ZtSize> ztSize;
|
||||||
@ -196,9 +213,25 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
Register<0x4B9, u32> blendStatePerTargetEnable;
|
Register<0x4B9, u32> blendStatePerTargetEnable;
|
||||||
Register<0x4BA, u32> depthWriteEnable;
|
Register<0x4BA, u32> depthWriteEnable;
|
||||||
Register<0x4BB, u32> alphaTestEnable;
|
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<0x4C3, type::CompareFunc> depthFunc;
|
||||||
Register<0x4C4, float> alphaRef;
|
Register<0x4C4, float> alphaRef;
|
||||||
Register<0x4C5, type::CompareFunc> alphaFunc;
|
Register<0x4C5, type::CompareFunc> alphaFunc;
|
||||||
|
|
||||||
Register<0x4C6, u32> drawAutoStride;
|
Register<0x4C6, u32> drawAutoStride;
|
||||||
|
|
||||||
struct BlendConstant {
|
struct BlendConstant {
|
||||||
@ -247,7 +280,24 @@ namespace skyline::soc::gm20b::engine::maxwell3d {
|
|||||||
|
|
||||||
Register<0x56F, float> depthBias;
|
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<0x581, type::PointCoordReplace> pointCoordReplace;
|
||||||
|
|
||||||
Register<0x582, Address> programRegion;
|
Register<0x582, Address> programRegion;
|
||||||
|
|
||||||
Register<0x585, u32> end; //!< Method-only register with no real value, used after calling vertexBeginGl to invoke the draw
|
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;
|
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<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
|
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