renderer_vulkan: Handle rasterization discard

This commit is contained in:
IndecisiveTurtle 2025-07-14 00:29:17 +03:00
parent 3393694b44
commit 23ebe5e0e9
5 changed files with 24 additions and 15 deletions

View File

@ -513,9 +513,9 @@ struct Liverpool {
BitField<19, 1, ClipSpace> clip_space; BitField<19, 1, ClipSpace> clip_space;
BitField<21, 1, PrimKillCond> vtx_kill_or; BitField<21, 1, PrimKillCond> vtx_kill_or;
BitField<22, 1, u32> dx_rasterization_kill; BitField<22, 1, u32> dx_rasterization_kill;
BitField<23, 1, u32> dx_linear_attr_clip_enable; BitField<24, 1, u32> dx_linear_attr_clip_enable;
BitField<26, 1, u32> zclip_near_disable; BitField<26, 1, u32> zclip_near_disable;
BitField<26, 1, u32> zclip_far_disable; BitField<27, 1, u32> zclip_far_disable;
}; };
enum class PolygonMode : u32 { enum class PolygonMode : u32 {
@ -738,12 +738,7 @@ struct Liverpool {
u32 data_w; u32 data_w;
}; };
struct BlendConstants { using BlendConstants = std::array<float, 4>;
float red;
float green;
float blue;
float alpha;
};
union BlendControl { union BlendControl {
enum class BlendFactor : u32 { enum class BlendFactor : u32 {

View File

@ -144,7 +144,7 @@ GraphicsPipeline::GraphicsPipeline(
vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference, vk::DynamicState::eStencilTestEnable, vk::DynamicState::eStencilReference,
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode, vk::DynamicState::eStencilOp, vk::DynamicState::eCullMode,
vk::DynamicState::eFrontFace, vk::DynamicState::eFrontFace, vk::DynamicState::eRasterizerDiscardEnable,
}; };
if (instance.IsPrimitiveRestartDisableSupported()) { if (instance.IsPrimitiveRestartDisableSupported()) {

View File

@ -1016,7 +1016,7 @@ void Rasterizer::UpdateDynamicState(const GraphicsPipeline& pipeline) const {
UpdatePrimitiveState(); UpdatePrimitiveState();
auto& dynamic_state = scheduler.GetDynamicState(); auto& dynamic_state = scheduler.GetDynamicState();
dynamic_state.SetBlendConstants(&liverpool->regs.blend_constants.red); dynamic_state.SetBlendConstants(liverpool->regs.blend_constants);
dynamic_state.SetColorWriteMasks(pipeline.GetWriteMasks()); dynamic_state.SetColorWriteMasks(pipeline.GetWriteMasks());
// Commit new dynamic state to the command buffer. // Commit new dynamic state to the command buffer.
@ -1231,6 +1231,7 @@ void Rasterizer::UpdatePrimitiveState() const {
const auto front_face = LiverpoolToVK::FrontFace(regs.polygon_control.front_face); const auto front_face = LiverpoolToVK::FrontFace(regs.polygon_control.front_face);
dynamic_state.SetPrimitiveRestartEnabled(prim_restart); dynamic_state.SetPrimitiveRestartEnabled(prim_restart);
dynamic_state.SetRasterizerDiscardEnabled(regs.clipper_control.dx_rasterization_kill);
dynamic_state.SetCullMode(cull_mode); dynamic_state.SetCullMode(cull_mode);
dynamic_state.SetFrontFace(front_face); dynamic_state.SetFrontFace(front_face);
} }

View File

@ -308,6 +308,10 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable); cmdbuf.setPrimitiveRestartEnable(primitive_restart_enable);
} }
} }
if (dirty_state.rasterizer_discard_enable) {
dirty_state.rasterizer_discard_enable = false;
cmdbuf.setRasterizerDiscardEnable(rasterizer_discard_enable);
}
if (dirty_state.cull_mode) { if (dirty_state.cull_mode) {
dirty_state.cull_mode = false; dirty_state.cull_mode = false;
cmdbuf.setCullMode(cull_mode); cmdbuf.setCullMode(cull_mode);
@ -318,7 +322,7 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd
} }
if (dirty_state.blend_constants) { if (dirty_state.blend_constants) {
dirty_state.blend_constants = false; dirty_state.blend_constants = false;
cmdbuf.setBlendConstants(blend_constants); cmdbuf.setBlendConstants(blend_constants.data());
} }
if (dirty_state.color_write_masks) { if (dirty_state.color_write_masks) {
dirty_state.color_write_masks = false; dirty_state.color_write_masks = false;

View File

@ -96,6 +96,7 @@ struct DynamicState {
bool stencil_back_compare_mask : 1; bool stencil_back_compare_mask : 1;
bool primitive_restart_enable : 1; bool primitive_restart_enable : 1;
bool rasterizer_discard_enable : 1;
bool cull_mode : 1; bool cull_mode : 1;
bool front_face : 1; bool front_face : 1;
@ -130,10 +131,11 @@ struct DynamicState {
u32 stencil_back_compare_mask{}; u32 stencil_back_compare_mask{};
bool primitive_restart_enable{}; bool primitive_restart_enable{};
bool rasterizer_discard_enable{};
vk::CullModeFlags cull_mode{}; vk::CullModeFlags cull_mode{};
vk::FrontFace front_face{}; vk::FrontFace front_face{};
float blend_constants[4]{}; std::array<float, 4> blend_constants{};
ColorWriteMasks color_write_masks{}; ColorWriteMasks color_write_masks{};
/// Commits the dynamic state to the provided command buffer. /// Commits the dynamic state to the provided command buffer.
@ -283,13 +285,20 @@ struct DynamicState {
} }
} }
void SetBlendConstants(const float blend_constants_[4]) { void SetBlendConstants(const std::array<float, 4> blend_constants_) {
if (!std::equal(blend_constants, std::end(blend_constants), blend_constants_)) { if (blend_constants != blend_constants_) {
std::memcpy(blend_constants, blend_constants_, sizeof(blend_constants)); blend_constants = blend_constants_;
dirty_state.blend_constants = true; dirty_state.blend_constants = true;
} }
} }
void SetRasterizerDiscardEnabled(const bool enabled) {
if (rasterizer_discard_enable != enabled) {
rasterizer_discard_enable = enabled;
dirty_state.rasterizer_discard_enable = true;
}
}
void SetColorWriteMasks(const ColorWriteMasks& color_write_masks_) { void SetColorWriteMasks(const ColorWriteMasks& color_write_masks_) {
if (!std::ranges::equal(color_write_masks, color_write_masks_)) { if (!std::ranges::equal(color_write_masks, color_write_masks_)) {
color_write_masks = color_write_masks_; color_write_masks = color_write_masks_;