[vulkan] Fixing DynamicState wrong core feature callings
This commit is contained in:
parent
90b312617b
commit
6e17a47120
|
|
@ -5,6 +5,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "video_core/renderer_vulkan/vk_texture_cache.h"
|
||||
|
||||
|
|
@ -761,10 +762,24 @@ void BlitImageHelper::ClearDepthStencil(const Framebuffer* dst_framebuffer, bool
|
|||
const VkPipeline pipeline = FindOrEmplaceClearStencilPipeline(key);
|
||||
const VkPipelineLayout layout = *clear_color_pipeline_layout;
|
||||
scheduler.RequestRenderpass(dst_framebuffer);
|
||||
scheduler.Record([pipeline, layout, clear_depth, dst_region](vk::CommandBuffer cmdbuf) {
|
||||
scheduler.Record([pipeline, layout, clear_depth, dst_region, stencil_mask, stencil_ref,
|
||||
stencil_compare_mask, dyn_stencil_compare, dyn_stencil_write,
|
||||
dyn_stencil_ref, this](vk::CommandBuffer cmdbuf) {
|
||||
constexpr std::array blend_constants{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
cmdbuf.SetBlendConstants(blend_constants.data());
|
||||
cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
if (dyn_stencil_compare) {
|
||||
cmdbuf.SetStencilCompareMask(VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT,
|
||||
stencil_compare_mask);
|
||||
}
|
||||
if (dyn_stencil_write) {
|
||||
cmdbuf.SetStencilWriteMask(VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT,
|
||||
stencil_mask);
|
||||
}
|
||||
if (dyn_stencil_ref) {
|
||||
cmdbuf.SetStencilReference(VK_STENCIL_FACE_FRONT_BIT | VK_STENCIL_FACE_BACK_BIT,
|
||||
stencil_ref);
|
||||
}
|
||||
BindBlitState(cmdbuf, dst_region);
|
||||
cmdbuf.PushConstants(layout, VK_SHADER_STAGE_FRAGMENT_BIT, clear_depth);
|
||||
cmdbuf.Draw(3, 1, 0, 0);
|
||||
|
|
@ -1010,14 +1025,19 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
|||
}
|
||||
clear_stencil_keys.push_back(key);
|
||||
const std::array stages = MakeStages(*clear_color_vert, *clear_stencil_frag);
|
||||
// Allow using dynamic stencil masks if the device supports them.
|
||||
const bool dyn_stencil_compare = device.SupportsDynamicStateStencilCompareMask();
|
||||
const bool dyn_stencil_write = device.SupportsDynamicStateStencilWriteMask();
|
||||
const bool dyn_stencil_ref = device.SupportsDynamicStateStencilReference();
|
||||
|
||||
const auto stencil = VkStencilOpState{
|
||||
.failOp = VK_STENCIL_OP_KEEP,
|
||||
.passOp = VK_STENCIL_OP_REPLACE,
|
||||
.depthFailOp = VK_STENCIL_OP_KEEP,
|
||||
.compareOp = VK_COMPARE_OP_ALWAYS,
|
||||
.compareMask = key.stencil_compare_mask,
|
||||
.writeMask = key.stencil_mask,
|
||||
.reference = key.stencil_ref,
|
||||
.compareMask = dyn_stencil_compare ? 0u : key.stencil_compare_mask,
|
||||
.writeMask = dyn_stencil_write ? 0u : key.stencil_mask,
|
||||
.reference = dyn_stencil_ref ? 0u : key.stencil_ref,
|
||||
};
|
||||
const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
|
|
@ -1034,6 +1054,29 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
|||
.maxDepthBounds = 0.0f,
|
||||
};
|
||||
const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci = GetPipelineInputAssemblyStateCreateInfo(device);
|
||||
|
||||
// Build dynamic state list for this pipeline (base + optional stencil/linewidth)
|
||||
std::vector<VkDynamicState> dyn_states(DYNAMIC_STATES.begin(), DYNAMIC_STATES.end());
|
||||
if (device.SupportsDynamicStateLineWidth()) {
|
||||
dyn_states.push_back(VK_DYNAMIC_STATE_LINE_WIDTH);
|
||||
}
|
||||
if (dyn_stencil_compare) {
|
||||
dyn_states.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
|
||||
}
|
||||
if (dyn_stencil_write) {
|
||||
dyn_states.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
|
||||
}
|
||||
if (dyn_stencil_ref) {
|
||||
dyn_states.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
|
||||
}
|
||||
const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.dynamicStateCount = static_cast<u32>(dyn_states.size()),
|
||||
.pDynamicStates = dyn_states.data(),
|
||||
};
|
||||
|
||||
clear_stencil_pipelines.push_back(device.GetLogical().CreateGraphicsPipeline({
|
||||
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
|
|
@ -1048,7 +1091,7 @@ VkPipeline BlitImageHelper::FindOrEmplaceClearStencilPipeline(
|
|||
.pMultisampleState = &PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
|
||||
.pDepthStencilState = &depth_stencil_ci,
|
||||
.pColorBlendState = &PIPELINE_COLOR_BLEND_STATE_GENERIC_CREATE_INFO,
|
||||
.pDynamicState = &PIPELINE_DYNAMIC_STATE_CREATE_INFO,
|
||||
.pDynamicState = &dynamic_state_ci,
|
||||
.layout = *clear_color_pipeline_layout,
|
||||
.renderPass = key.renderpass,
|
||||
.subpass = 0,
|
||||
|
|
|
|||
|
|
@ -171,6 +171,15 @@ void FixedPipelineState::Refresh(Tegra::Engines::Maxwell3D& maxwell3d, DynamicFe
|
|||
if (!extended_dynamic_state_3_enables) {
|
||||
dynamic_state.Refresh3(regs);
|
||||
}
|
||||
if (features.has_depth_bounds) {
|
||||
depth_bounds_min = 0;
|
||||
depth_bounds_max = 0;
|
||||
dynamic_state.depth_bounds_enable.Assign(0);
|
||||
}
|
||||
|
||||
if (features.has_depth_bias) {
|
||||
dynamic_state.depth_bias_enable.Assign(0);
|
||||
}
|
||||
if (xfb_enabled) {
|
||||
RefreshXfbState(xfb_state, regs);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,15 @@ namespace Vulkan {
|
|||
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
||||
|
||||
struct DynamicFeatures {
|
||||
bool has_viewport;
|
||||
bool has_scissor;
|
||||
bool has_depth_bias;
|
||||
bool has_blend_constants;
|
||||
bool has_depth_bounds;
|
||||
bool has_stencil_compare_mask;
|
||||
bool has_stencil_write_mask;
|
||||
bool has_stencil_reference;
|
||||
bool has_line_width;
|
||||
bool has_extended_dynamic_state;
|
||||
bool has_extended_dynamic_state_2;
|
||||
bool has_extended_dynamic_state_2_logic_op;
|
||||
|
|
|
|||
|
|
@ -815,13 +815,35 @@ void GraphicsPipeline::MakePipeline(VkRenderPass render_pass) {
|
|||
.pAttachments = cb_attachments.data(),
|
||||
.blendConstants = {}
|
||||
};
|
||||
static_vector<VkDynamicState, 34> dynamic_states{
|
||||
VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
|
||||
VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
|
||||
VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
|
||||
VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
|
||||
VK_DYNAMIC_STATE_LINE_WIDTH,
|
||||
};
|
||||
static_vector<VkDynamicState, 34> dynamic_states;
|
||||
|
||||
if (device.SupportsDynamicStateViewport()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||
}
|
||||
if (device.SupportsDynamicStateScissor()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_SCISSOR);
|
||||
}
|
||||
if (device.SupportsDynamicStateDepthBias()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BIAS);
|
||||
}
|
||||
if (device.SupportsDynamicStateBlendConstants()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_BLEND_CONSTANTS);
|
||||
}
|
||||
if (device.SupportsDynamicStateDepthBounds()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_DEPTH_BOUNDS);
|
||||
}
|
||||
if (device.SupportsDynamicStateStencilCompareMask()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK);
|
||||
}
|
||||
if (device.SupportsDynamicStateStencilWriteMask()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_WRITE_MASK);
|
||||
}
|
||||
if (device.SupportsDynamicStateStencilReference()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_STENCIL_REFERENCE);
|
||||
}
|
||||
if (device.SupportsDynamicStateLineWidth()) {
|
||||
dynamic_states.push_back(VK_DYNAMIC_STATE_LINE_WIDTH);
|
||||
}
|
||||
if (key.state.extended_dynamic_state) {
|
||||
static constexpr std::array extended{
|
||||
VK_DYNAMIC_STATE_CULL_MODE_EXT,
|
||||
|
|
|
|||
|
|
@ -418,12 +418,24 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
|
||||
dynamic_features = {};
|
||||
|
||||
// User granularity enforced in vulkan_device.cpp switch statement:
|
||||
// Level 0: Core Dynamic States only
|
||||
// Level 1: Core + EDS1
|
||||
// Level 2: Core + EDS1 + EDS2 (accumulative)
|
||||
// Level 3: Core + EDS1 + EDS2 + EDS3 (accumulative)
|
||||
// Here we only verify if extensions were successfully loaded by the device
|
||||
dynamic_features.has_viewport =
|
||||
device.SupportsDynamicStateViewport();
|
||||
dynamic_features.has_scissor =
|
||||
device.SupportsDynamicStateScissor();
|
||||
dynamic_features.has_depth_bias =
|
||||
device.SupportsDynamicStateDepthBias();
|
||||
dynamic_features.has_blend_constants =
|
||||
device.SupportsDynamicStateBlendConstants();
|
||||
dynamic_features.has_depth_bounds =
|
||||
device.SupportsDynamicStateDepthBounds();
|
||||
dynamic_features.has_stencil_compare_mask =
|
||||
device.SupportsDynamicStateStencilCompareMask();
|
||||
dynamic_features.has_stencil_write_mask =
|
||||
device.SupportsDynamicStateStencilWriteMask();
|
||||
dynamic_features.has_stencil_reference =
|
||||
device.SupportsDynamicStateStencilReference();
|
||||
dynamic_features.has_line_width =
|
||||
device.SupportsDynamicStateLineWidth();
|
||||
|
||||
dynamic_features.has_extended_dynamic_state =
|
||||
device.IsExtExtendedDynamicStateSupported();
|
||||
|
|
@ -439,7 +451,6 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
|
|||
dynamic_features.has_extended_dynamic_state_3_enables =
|
||||
device.IsExtExtendedDynamicState3EnablesSupported();
|
||||
|
||||
// VIDS: Independent toggle (not affected by dyna_state levels)
|
||||
dynamic_features.has_dynamic_vertex_input =
|
||||
device.IsExtVertexInputDynamicStateSupported() &&
|
||||
Settings::values.vertex_input_dynamic_state.GetValue();
|
||||
|
|
|
|||
|
|
@ -682,13 +682,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
|
||||
const auto dyna_state = Settings::values.dyna_state.GetValue();
|
||||
|
||||
// Base dynamic states (VIEWPORT, SCISSOR, DEPTH_BIAS, etc.) are ALWAYS active in vk_graphics_pipeline.cpp
|
||||
// This slider controls EXTENDED dynamic states with accumulative levels per Vulkan specs:
|
||||
// Level 0 = Core Dynamic States only (Vulkan 1.0)
|
||||
// Level 1 = Core + VK_EXT_extended_dynamic_state
|
||||
// Level 2 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2
|
||||
// Level 3 = Core + VK_EXT_extended_dynamic_state + VK_EXT_extended_dynamic_state2 + VK_EXT_extended_dynamic_state3
|
||||
|
||||
switch (dyna_state) {
|
||||
case Settings::ExtendedDynamicState::Disabled:
|
||||
// Level 0: Disable all extended dynamic state extensions
|
||||
|
|
@ -723,8 +716,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
|||
break;
|
||||
}
|
||||
|
||||
// VK_EXT_vertex_input_dynamic_state is independent from EDS
|
||||
// It can be enabled even without extended_dynamic_state
|
||||
// VK_EXT_vertex_input_dynamic_state is independent from ExtendedDynamicState level
|
||||
if (!Settings::values.vertex_input_dynamic_state.GetValue()) {
|
||||
RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -704,6 +704,43 @@ public:
|
|||
return dynamic_state3_alpha_to_one;
|
||||
}
|
||||
|
||||
// Core dynamic state support checks
|
||||
bool SupportsDynamicStateViewport() const {
|
||||
return dld.vkCmdSetViewport != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateScissor() const {
|
||||
return dld.vkCmdSetScissor != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateDepthBias() const {
|
||||
return dld.vkCmdSetDepthBias != nullptr || dld.vkCmdSetDepthBias2EXT != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateBlendConstants() const {
|
||||
return dld.vkCmdSetBlendConstants != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateDepthBounds() const {
|
||||
return dld.vkCmdSetDepthBounds != nullptr && IsDepthBoundsSupported();
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateStencilCompareMask() const {
|
||||
return dld.vkCmdSetStencilCompareMask != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateStencilWriteMask() const {
|
||||
return dld.vkCmdSetStencilWriteMask != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateStencilReference() const {
|
||||
return dld.vkCmdSetStencilReference != nullptr;
|
||||
}
|
||||
|
||||
bool SupportsDynamicStateLineWidth() const {
|
||||
return dld.vkCmdSetLineWidth != nullptr;
|
||||
}
|
||||
|
||||
/// Returns true if the device supports VK_EXT_vertex_input_dynamic_state.
|
||||
bool IsExtVertexInputDynamicStateSupported() const {
|
||||
return extensions.vertex_input_dynamic_state;
|
||||
|
|
|
|||
Loading…
Reference in New Issue