renderer: cache dynamic graphics state

This commit is contained in:
nmzik
2026-10-10 00:28:51 +02:00
parent 5559cfcbb2
commit 93452b24e3
6 changed files with 442 additions and 32 deletions
+28 -30
View File
@@ -312,9 +312,9 @@ static void LogDrawInputState(const CommandBuffer& buffer, const RenderColorInfo
}
}
static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuffer vk_buffer,
const ShaderVertexInputInfo& vs_input_info,
const RenderDepthInfo& depth, const RenderState& rendering) {
static void UpdateGraphicsDynamicState(const CommandBuffer& buffer, DynamicState& dynamic_state,
const ShaderVertexInputInfo& vs_input_info,
const RenderDepthInfo& depth, const RenderState& rendering) {
KYTY_PROFILER_FUNCTION();
const auto& ctx = buffer.GetRegisters();
@@ -358,8 +358,8 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
scissor.extent = {0, 0};
}
}
vk_buffer.setViewportWithCount(viewport_count, viewports.data());
vk_buffer.setScissorWithCount(viewport_count, scissors.data());
dynamic_state.SetViewports(std::span {viewports}.first(viewport_count));
dynamic_state.SetScissors(std::span {scissors}.first(viewport_count));
float line_width = ctx.GetLineWidth();
if (line_width != 1.0f) {
@@ -372,17 +372,17 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
}
line_width = 1.0f;
}
vk_buffer.setLineWidth(line_width);
dynamic_state.SetLineWidth(line_width);
const auto& blend = ctx.GetBlendColor();
const std::array blend_constants {blend.red, blend.green, blend.blue, blend.alpha};
vk_buffer.setBlendConstants(blend_constants.data());
vk_buffer.setDepthTestEnable(depth.depth_test_enable ? VK_TRUE : VK_FALSE);
vk_buffer.setDepthWriteEnable(depth.depth_write_enable ? VK_TRUE : VK_FALSE);
vk_buffer.setDepthCompareOp(depth.depth_compare_op);
dynamic_state.SetBlendConstants(blend_constants);
dynamic_state.SetDepthTestEnabled(depth.depth_test_enable);
dynamic_state.SetDepthWriteEnabled(depth.depth_write_enable);
dynamic_state.SetDepthCompareOp(depth.depth_compare_op);
#if !defined(__APPLE__)
vk_buffer.setDepthBoundsTestEnable(depth.depth_bounds_test_enable ? VK_TRUE : VK_FALSE);
dynamic_state.SetDepthBoundsTestEnabled(depth.depth_bounds_test_enable);
if (depth.depth_bounds_test_enable) {
vk_buffer.setDepthBounds(ctx.GetDepthBoundsMin(), ctx.GetDepthBoundsMax());
dynamic_state.SetDepthBounds(ctx.GetDepthBoundsMin(), ctx.GetDepthBoundsMax());
}
#endif
@@ -391,7 +391,7 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
const bool use_front = mode.poly_offset_front_enable && !mode.cull_front;
const bool use_back = mode.poly_offset_back_enable && !mode.cull_back;
const bool depth_bias_enable = use_front || use_back;
vk_buffer.setDepthBiasEnable(depth_bias_enable ? VK_TRUE : VK_FALSE);
dynamic_state.SetDepthBiasEnabled(depth_bias_enable);
if (depth_bias_enable) {
// Vulkan has one bias for both faces. Prefer a visible front face when both are enabled.
const float guest_constant_factor =
@@ -400,19 +400,18 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
guest_constant_factor, poly_offset, depth.desc.view_info.format);
const float slope_factor =
(use_front ? poly_offset.front_scale : poly_offset.back_scale) / 16.0f;
vk_buffer.setDepthBias(constant_factor, poly_offset.clamp, slope_factor);
dynamic_state.SetDepthBias(constant_factor, poly_offset.clamp, slope_factor);
}
vk_buffer.setStencilTestEnable(depth.stencil_test_enable ? VK_TRUE : VK_FALSE);
dynamic_state.SetStencilTestEnabled(depth.stencil_test_enable);
if (depth.stencil_test_enable) {
const auto set_stencil = [&](vk::StencilFaceFlagBits face, const vk::StencilOpState& state) {
vk_buffer.setStencilOp(face, state.failOp, state.passOp, state.depthFailOp, state.compareOp);
vk_buffer.setStencilCompareMask(face, state.compareMask);
vk_buffer.setStencilWriteMask(face, state.writeMask);
vk_buffer.setStencilReference(face, state.reference);
};
set_stencil(vk::StencilFaceFlagBits::eFront, depth.stencil_front);
set_stencil(vk::StencilFaceFlagBits::eBack, depth.stencil_back);
const auto& front = depth.stencil_front;
const auto& back = depth.stencil_back;
dynamic_state.SetStencilOps({front.failOp, front.passOp, front.depthFailOp, front.compareOp},
{back.failOp, back.passOp, back.depthFailOp, back.compareOp});
dynamic_state.SetStencilCompareMasks(front.compareMask, back.compareMask);
dynamic_state.SetStencilWriteMasks(front.writeMask, back.writeMask);
dynamic_state.SetStencilReferences(front.reference, back.reference);
}
#if defined(__APPLE__)
@@ -423,9 +422,7 @@ static void SetGraphicsDynamicParams(const CommandBuffer& buffer, vk::CommandBuf
for (uint32_t slot = 0; slot < rendering.num_color_attachments; slot++) {
enable[slot] = rendering.color_attachments[slot].image_view != nullptr;
}
if (rendering.num_color_attachments != 0) {
vk_buffer.setColorWriteEnableEXT(rendering.num_color_attachments, enable);
}
dynamic_state.SetColorWriteEnables(std::span {enable}.first(rendering.num_color_attachments));
#endif
}
@@ -1139,10 +1136,11 @@ void RenderExecutor::ExecutePreparedDraw(uint64_t submit_id, CommandBuffer& buff
CommitIndexBuffer(vk_buffer, index_binding);
}
SetGraphicsDynamicParams(buffer, vk_buffer, vertex_stages.back(), state.depth_info, rendering);
if (m_context.GetGraphics().attachment_feedback_loop_enabled) {
vk_buffer.setAttachmentFeedbackLoopEnableEXT(feedback_aspects);
}
auto& dynamic_state = m_context.GetCommandScheduler().GetDynamicState();
UpdateGraphicsDynamicState(buffer, dynamic_state, vertex_stages.back(), state.depth_info,
rendering);
dynamic_state.SetAttachmentFeedbackLoopAspects(feedback_aspects);
dynamic_state.Commit(m_context.GetGraphics(), vk_buffer);
LogDrawPhase(draw.Name(), "BeginRendering");
if (!draw.IsIndexed()) {