[vulkan] Adjusting provoking vertex last.

This commit is contained in:
CamilleLaVey 2026-02-01 23:21:24 -04:00
parent 0d518e7303
commit dbcbce57b0
9 changed files with 41 additions and 7 deletions

View File

@ -84,7 +84,6 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
depth_enabled.Assign(regs.zeta_enable != 0 ? 1 : 0);
depth_format.Assign(static_cast<u32>(regs.zeta.format));
y_negate.Assign(regs.window_origin.mode != Maxwell::WindowOrigin::Mode::UpperLeft ? 1 : 0);
provoking_vertex_last.Assign(regs.provoking_vertex == Maxwell::ProvokingVertex::Last ? 1 : 0);
conservative_raster_enable.Assign(regs.conservative_raster_enable != 0 ? 1 : 0);
smooth_lines.Assign(regs.line_anti_alias_enable != 0 ? 1 : 0);
alpha_to_coverage_enabled.Assign(regs.anti_alias_alpha_control.alpha_to_coverage != 0 ? 1 : 0);

View File

@ -214,9 +214,8 @@ struct FixedPipelineState {
BitField<5, 1, u32> depth_enabled;
BitField<6, 5, u32> depth_format;
BitField<11, 1, u32> y_negate;
BitField<12, 1, u32> provoking_vertex_last;
BitField<13, 1, u32> conservative_raster_enable;
BitField<14, 1, u32> smooth_lines;
BitField<12, 1, u32> conservative_raster_enable;
BitField<13, 1, u32> smooth_lines;
BitField<15, 1, u32> alpha_to_coverage_enabled;
BitField<16, 1, u32> alpha_to_one_enabled;
BitField<17, 3, Tegra::Engines::Maxwell3D::EngineHint> app_stage;

View File

@ -741,9 +741,7 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
VkPipelineRasterizationProvokingVertexStateCreateInfoEXT provoking_vertex{
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT,
.pNext = nullptr,
.provokingVertexMode = key.state.provoking_vertex_last != 0
? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT
: VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
.provokingVertexMode = VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT,
};
if (IsLine(input_assembly_topology) && device.IsExtLineRasterizationSupported()) {
@ -918,6 +916,10 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
}
}
if (device.IsExtProvokingVertexSupported()) {
dynamic_states.push_back(VK_DYNAMIC_STATE_PROVOKING_VERTEX_EXT);
}
const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
.pNext = nullptr,

View File

@ -1042,6 +1042,10 @@ void RasterizerVulkan::UpdateDynamicStates() {
UpdateLogicOp(regs);
}
if (device.IsExtProvokingVertexSupported()) {
UpdateProvokingVertex(regs);
}
if (device.IsExtExtendedDynamicState3EnablesSupported()) {
using namespace Tegra::Engines;
if (device.GetDriverID() == VkDriverIdKHR::VK_DRIVER_ID_AMD_OPEN_SOURCE ||
@ -1617,6 +1621,20 @@ void RasterizerVulkan::UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs) {
[front_face](vk::CommandBuffer cmdbuf) { cmdbuf.SetFrontFaceEXT(front_face); });
}
void RasterizerVulkan::UpdateProvokingVertex(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!device.IsExtProvokingVertexSupported()) {
return;
}
if (!state_tracker.TouchProvokingVertex()) {
return;
}
const auto mode = regs.provoking_vertex == Maxwell::ProvokingVertex::Last
? VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT
: VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
scheduler.Record([mode](vk::CommandBuffer cmdbuf) { cmdbuf.SetProvokingVertexEXT(mode); });
}
void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) {
if (!state_tracker.TouchStencilOp()) {
return;

View File

@ -186,6 +186,7 @@ private:
void UpdateAlphaToCoverageEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateAlphaToOneEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateFrontFace(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateProvokingVertex(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateStencilTestEnable(Tegra::Engines::Maxwell3D::Regs& regs);
void UpdateLogicOp(Tegra::Engines::Maxwell3D::Regs& regs);

View File

@ -166,6 +166,10 @@ void SetupDirtyFrontFace(Tables& tables) {
table[OFF(window_origin)] = FrontFace;
}
void SetupDirtyProvokingVertex(Tables& tables) {
tables[0][OFF(provoking_vertex)] = ProvokingVertex;
}
void SetupDirtyStencilOp(Tables& tables) {
auto& table = tables[0];
table[OFF(stencil_front_op.fail)] = StencilOp;
@ -250,6 +254,7 @@ void StateTracker::SetupTables(Tegra::Control::ChannelState& channel_state) {
SetupDirtyStateEnable(tables);
SetupDirtyDepthCompareOp(tables);
SetupDirtyFrontFace(tables);
SetupDirtyProvokingVertex(tables);
SetupDirtyStencilOp(tables);
SetupDirtyBlending(tables);
SetupDirtyViewportSwizzles(tables);

View File

@ -248,6 +248,10 @@ public:
return Exchange(Dirty::FrontFace, false);
}
bool TouchProvokingVertex() {
return Exchange(Dirty::ProvokingVertex, false);
}
bool TouchStencilOp() {
return Exchange(Dirty::StencilOp, false);
}

View File

@ -159,6 +159,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
X(vkCmdSetPatchControlPointsEXT);
X(vkCmdSetLineWidth);
X(vkCmdSetPrimitiveTopologyEXT);
X(vkCmdSetProvokingVertexEXT);
X(vkCmdSetStencilOpEXT);
X(vkCmdSetStencilTestEnableEXT);
X(vkCmdSetVertexInputEXT);

View File

@ -254,6 +254,7 @@ struct DeviceDispatch : InstanceDispatch {
PFN_vkCmdSetLogicOpEXT vkCmdSetLogicOpEXT{};
PFN_vkCmdSetLineWidth vkCmdSetLineWidth{};
PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{};
PFN_vkCmdSetProvokingVertexEXT vkCmdSetProvokingVertexEXT{};
PFN_vkCmdSetScissor vkCmdSetScissor{};
PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask{};
PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT{};
@ -1529,6 +1530,10 @@ public:
dld->vkCmdSetPrimitiveTopologyEXT(handle, primitive_topology);
}
void SetProvokingVertexEXT(VkProvokingVertexModeEXT provoking_vertex_mode) const noexcept {
dld->vkCmdSetProvokingVertexEXT(handle, provoking_vertex_mode);
}
void SetStencilOpEXT(VkStencilFaceFlags face_mask, VkStencilOp fail_op, VkStencilOp pass_op,
VkStencilOp depth_fail_op, VkCompareOp compare_op) const noexcept {
dld->vkCmdSetStencilOpEXT(handle, face_mask, fail_op, pass_op, depth_fail_op, compare_op);