mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 09:48:58 +02:00
[vulkan] Adjusted dynamic state handling + update state tracker for extended dynamic states
This commit is contained in:
parent
d1466b0e9d
commit
6985aaf614
6 changed files with 74 additions and 45 deletions
|
|
@ -131,15 +131,11 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
|||
}
|
||||
dynamic_state.raw1 = 0;
|
||||
dynamic_state.raw2 = 0;
|
||||
if (!extended_dynamic_state) {
|
||||
dynamic_state.Refresh(regs);
|
||||
}
|
||||
dynamic_state.Refresh(regs);
|
||||
std::ranges::transform(regs.vertex_streams, vertex_strides.begin(), [](const auto& array) {
|
||||
return static_cast<u16>(array.stride.Value());
|
||||
});
|
||||
if (!extended_dynamic_state_2) {
|
||||
dynamic_state.Refresh2(regs, topology_, extended_dynamic_state_2);
|
||||
}
|
||||
dynamic_state.Refresh2(regs, topology_, false);
|
||||
if (maxwell3d.dirty.flags[Dirty::Blending]) {
|
||||
maxwell3d.dirty.flags[Dirty::Blending] = false;
|
||||
for (size_t index = 0; index < attachments.size(); ++index) {
|
||||
|
|
|
|||
|
|
@ -254,11 +254,9 @@ struct FixedPipelineState {
|
|||
// When transform feedback is enabled, use the whole struct
|
||||
return sizeof(*this);
|
||||
}
|
||||
if (extended_dynamic_state) {
|
||||
// Exclude dynamic state
|
||||
return offsetof(FixedPipelineState, vertex_strides);
|
||||
}
|
||||
// Default
|
||||
// Always include the cached dynamic-state payload in the key. Some members of
|
||||
// `dynamic_state` still feed static pipeline state even when EDS is enabled,
|
||||
// and excluding the whole block causes incorrect pipeline reuse.
|
||||
return offsetof(FixedPipelineState, xfb_state);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -531,12 +531,7 @@ void GraphicsPipeline::ConfigureDraw(const RescalingPushConstant& rescaling,
|
|||
}
|
||||
|
||||
const void* const descriptor_data{guest_descriptor_queue.UpdateData()};
|
||||
FixedPipelineState::DynamicState dynamic_state{};
|
||||
if (!key.state.extended_dynamic_state) {
|
||||
dynamic_state = key.state.dynamic_state;
|
||||
} else {
|
||||
dynamic_state.raw1 = key.state.dynamic_state.raw1;
|
||||
}
|
||||
const FixedPipelineState::DynamicState dynamic_state{key.state.dynamic_state};
|
||||
scheduler.Record([this, descriptor_data, bind_pipeline, rescaling_data = rescaling.Data(),
|
||||
is_rescaling, update_rescaling,
|
||||
uses_render_area = render_area.uses_render_area,
|
||||
|
|
@ -687,9 +682,9 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.viewportCount = num_viewports,
|
||||
.viewportCount = key.state.extended_dynamic_state ? 0u : num_viewports,
|
||||
.pViewports = nullptr,
|
||||
.scissorCount = num_viewports,
|
||||
.scissorCount = key.state.extended_dynamic_state ? 0u : num_viewports,
|
||||
.pScissors = nullptr,
|
||||
};
|
||||
if (device.IsNvViewportSwizzleSupported()) {
|
||||
|
|
@ -901,6 +896,11 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
}
|
||||
if (key.state.extended_dynamic_state) {
|
||||
static constexpr std::array extended{
|
||||
VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
|
||||
VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
|
||||
VK_DYNAMIC_STATE_CULL_MODE_EXT,
|
||||
VK_DYNAMIC_STATE_FRONT_FACE_EXT,
|
||||
VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
|
||||
VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
|
||||
|
|
@ -914,11 +914,6 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
}
|
||||
|
||||
if (key.state.extended_dynamic_state) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
}
|
||||
|
||||
// EDS2 - Core (3 states)
|
||||
if (key.state.extended_dynamic_state_2) {
|
||||
static constexpr std::array extended2{
|
||||
|
|
|
|||
|
|
@ -277,8 +277,9 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
|
|||
if (!pipeline->Configure(is_indexed))
|
||||
return;
|
||||
|
||||
if (pipeline->UsesExtendedDynamicState()) {
|
||||
state_tracker.InvalidateStateEnableFlag();
|
||||
if (pipeline->UsesExtendedDynamicState() || pipeline->UsesExtendedDynamicState2() ||
|
||||
pipeline->UsesExtendedDynamicState2LogicOp()) {
|
||||
state_tracker.InvalidateExtendedDynamicStates();
|
||||
}
|
||||
|
||||
HandleTransformFeedback();
|
||||
|
|
@ -1078,16 +1079,18 @@ void RasterizerVulkan::UpdateDynamicStates() {
|
|||
UpdateLineWidth(regs);
|
||||
UpdateLineStipple(regs);
|
||||
|
||||
// EDS1: DepthCompare, StencilOp, DepthBoundsTest, DepthTest, DepthWrite, StencilTest
|
||||
// EDS1: CullMode, DepthCompare, FrontFace, PrimitiveTopology, StencilOp,
|
||||
// DepthBoundsTest, DepthTest, DepthWrite, StencilTest
|
||||
if (device.IsExtExtendedDynamicStateSupported() && pipeline && pipeline->UsesExtendedDynamicState()) {
|
||||
UpdateCullMode(regs);
|
||||
UpdateDepthCompareOp(regs);
|
||||
UpdateFrontFace(regs);
|
||||
UpdatePrimitiveTopology(regs);
|
||||
UpdateStencilOp(regs);
|
||||
if (state_tracker.TouchStateEnable()) {
|
||||
UpdateDepthBoundsTestEnable(regs);
|
||||
UpdateDepthTestEnable(regs);
|
||||
UpdateDepthWriteEnable(regs);
|
||||
UpdateStencilTestEnable(regs);
|
||||
}
|
||||
UpdateDepthBoundsTestEnable(regs);
|
||||
UpdateDepthTestEnable(regs);
|
||||
UpdateDepthWriteEnable(regs);
|
||||
UpdateStencilTestEnable(regs);
|
||||
}
|
||||
|
||||
UpdateStencilFaces(regs);
|
||||
|
|
@ -1157,8 +1160,16 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
|||
.minDepth = 0.0f,
|
||||
.maxDepth = 1.0f,
|
||||
};
|
||||
scheduler.Record([viewport](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetViewport(0, viewport);
|
||||
GraphicsPipeline* pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
||||
const bool use_viewport_with_count = device.IsExtExtendedDynamicStateSupported() &&
|
||||
pipeline && pipeline->UsesExtendedDynamicState();
|
||||
scheduler.Record([viewport, use_viewport_with_count](vk::CommandBuffer cmdbuf) {
|
||||
if (use_viewport_with_count) {
|
||||
std::array viewports{viewport};
|
||||
cmdbuf.SetViewportWithCountEXT(viewports);
|
||||
} else {
|
||||
cmdbuf.SetViewport(0, viewport);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -1174,10 +1185,17 @@ void RasterizerVulkan::UpdateViewportsState(Tegra::Engines::Maxwell3D::Regs& reg
|
|||
GetViewportState(device, regs, 12, scale), GetViewportState(device, regs, 13, scale),
|
||||
GetViewportState(device, regs, 14, scale), GetViewportState(device, regs, 15, scale),
|
||||
};
|
||||
scheduler.Record([this, viewport_list](vk::CommandBuffer cmdbuf) {
|
||||
GraphicsPipeline* pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
||||
const bool use_viewport_with_count = device.IsExtExtendedDynamicStateSupported() &&
|
||||
pipeline && pipeline->UsesExtendedDynamicState();
|
||||
scheduler.Record([this, viewport_list, use_viewport_with_count](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_viewports = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
const vk::Span<VkViewport> viewports(viewport_list.data(), num_viewports);
|
||||
cmdbuf.SetViewport(0, viewports);
|
||||
if (use_viewport_with_count) {
|
||||
cmdbuf.SetViewportWithCountEXT(viewports);
|
||||
} else {
|
||||
cmdbuf.SetViewport(0, viewports);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1198,8 +1216,16 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
|
|||
scissor.offset.y = static_cast<int32_t>(y);
|
||||
scissor.extent.width = width;
|
||||
scissor.extent.height = height;
|
||||
scheduler.Record([scissor](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetScissor(0, scissor);
|
||||
GraphicsPipeline* pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
||||
const bool use_scissor_with_count = device.IsExtExtendedDynamicStateSupported() &&
|
||||
pipeline && pipeline->UsesExtendedDynamicState();
|
||||
scheduler.Record([scissor, use_scissor_with_count](vk::CommandBuffer cmdbuf) {
|
||||
if (use_scissor_with_count) {
|
||||
std::array scissors{scissor};
|
||||
cmdbuf.SetScissorWithCountEXT(scissors);
|
||||
} else {
|
||||
cmdbuf.SetScissor(0, scissor);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -1227,10 +1253,17 @@ void RasterizerVulkan::UpdateScissorsState(Tegra::Engines::Maxwell3D::Regs& regs
|
|||
GetScissorState(regs, 14, up_scale, down_shift),
|
||||
GetScissorState(regs, 15, up_scale, down_shift),
|
||||
};
|
||||
scheduler.Record([this, scissor_list](vk::CommandBuffer cmdbuf) {
|
||||
GraphicsPipeline* pipeline = pipeline_cache.CurrentGraphicsPipeline();
|
||||
const bool use_scissor_with_count = device.IsExtExtendedDynamicStateSupported() &&
|
||||
pipeline && pipeline->UsesExtendedDynamicState();
|
||||
scheduler.Record([this, scissor_list, use_scissor_with_count](vk::CommandBuffer cmdbuf) {
|
||||
const u32 num_scissors = std::min<u32>(device.GetMaxViewports(), Maxwell::NumViewports);
|
||||
const vk::Span<VkRect2D> scissors(scissor_list.data(), num_scissors);
|
||||
cmdbuf.SetScissor(0, scissors);
|
||||
if (use_scissor_with_count) {
|
||||
cmdbuf.SetScissorWithCountEXT(scissors);
|
||||
} else {
|
||||
cmdbuf.SetScissor(0, scissors);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -154,9 +154,11 @@ void Scheduler::RequestOutsideRenderPassOperationContext() {
|
|||
|
||||
bool Scheduler::UpdateGraphicsPipeline(GraphicsPipeline* pipeline) {
|
||||
if (state.graphics_pipeline == pipeline) {
|
||||
if (pipeline && pipeline->UsesExtendedDynamicState() &&
|
||||
if (pipeline &&
|
||||
(pipeline->UsesExtendedDynamicState() || pipeline->UsesExtendedDynamicState2() ||
|
||||
pipeline->UsesExtendedDynamicState2LogicOp()) &&
|
||||
state.needs_state_enable_refresh) {
|
||||
state_tracker.InvalidateStateEnableFlag();
|
||||
state_tracker.InvalidateExtendedDynamicStates();
|
||||
state.needs_state_enable_refresh = false;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -173,10 +175,11 @@ bool Scheduler::UpdateGraphicsPipeline(GraphicsPipeline* pipeline) {
|
|||
state_tracker.InvalidateExtendedDynamicStates();
|
||||
}
|
||||
|
||||
if (!pipeline->UsesExtendedDynamicState()) {
|
||||
if (!pipeline->UsesExtendedDynamicState() && !pipeline->UsesExtendedDynamicState2() &&
|
||||
!pipeline->UsesExtendedDynamicState2LogicOp()) {
|
||||
state.needs_state_enable_refresh = true;
|
||||
} else if (state.needs_state_enable_refresh) {
|
||||
state_tracker.InvalidateStateEnableFlag();
|
||||
state_tracker.InvalidateExtendedDynamicStates();
|
||||
state.needs_state_enable_refresh = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,9 +98,13 @@ public:
|
|||
(*flags)[Dirty::Viewports] = true;
|
||||
(*flags)[Dirty::Scissors] = true;
|
||||
(*flags)[Dirty::CullMode] = true;
|
||||
(*flags)[Dirty::DepthBoundsEnable] = true;
|
||||
(*flags)[Dirty::DepthTestEnable] = true;
|
||||
(*flags)[Dirty::DepthWriteEnable] = true;
|
||||
(*flags)[Dirty::DepthCompareOp] = true;
|
||||
(*flags)[Dirty::FrontFace] = true;
|
||||
(*flags)[Dirty::StencilOp] = true;
|
||||
(*flags)[Dirty::StencilTestEnable] = true;
|
||||
(*flags)[Dirty::StateEnable] = true;
|
||||
(*flags)[Dirty::PrimitiveRestartEnable] = true;
|
||||
(*flags)[Dirty::RasterizerDiscardEnable] = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue