mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-05-14 15:06:57 +02:00
Revert "[vulkan] Adjusted VK_EXT_vertex_input_dynamic_state"
This commit is contained in:
parent
d6e2fd0b4b
commit
0b3fdb5797
4 changed files with 51 additions and 58 deletions
|
|
@ -10,7 +10,6 @@
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common/settings.h"
|
|
||||||
#include "video_core/buffer_cache/buffer_cache_base.h"
|
#include "video_core/buffer_cache/buffer_cache_base.h"
|
||||||
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
|
#include "video_core/renderer_vulkan/vk_buffer_cache.h"
|
||||||
|
|
||||||
|
|
@ -335,9 +334,6 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m
|
||||||
staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_},
|
staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_},
|
||||||
quad_index_pass(device, scheduler, descriptor_pool, staging_pool,
|
quad_index_pass(device, scheduler, descriptor_pool, staging_pool,
|
||||||
compute_pass_descriptor_queue) {
|
compute_pass_descriptor_queue) {
|
||||||
use_vertex_input_dynamic_state = device.IsExtVertexInputDynamicStateSupported() &&
|
|
||||||
Settings::values.vertex_input_dynamic_state.GetValue();
|
|
||||||
|
|
||||||
const VkDriverIdKHR driver_id = device.GetDriverID();
|
const VkDriverIdKHR driver_id = device.GetDriverID();
|
||||||
limit_dynamic_storage_buffers = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
limit_dynamic_storage_buffers = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY ||
|
||||||
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
|
driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
|
||||||
|
|
@ -560,10 +556,7 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
|
||||||
if (index >= device.GetMaxVertexInputBindings()) {
|
if (index >= device.GetMaxVertexInputBindings()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool use_bind_vertex_buffers2_stride =
|
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||||
device.IsExtExtendedDynamicStateSupported() && !use_vertex_input_dynamic_state;
|
|
||||||
|
|
||||||
if (use_bind_vertex_buffers2_stride) {
|
|
||||||
scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([index, buffer, offset, size, stride](vk::CommandBuffer cmdbuf) {
|
||||||
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
|
const VkDeviceSize vk_offset = buffer != VK_NULL_HANDLE ? offset : 0;
|
||||||
const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE;
|
const VkDeviceSize vk_size = buffer != VK_NULL_HANDLE ? size : VK_WHOLE_SIZE;
|
||||||
|
|
@ -603,10 +596,7 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi
|
||||||
if (binding_count == 0) {
|
if (binding_count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const bool use_bind_vertex_buffers2_stride =
|
if (device.IsExtExtendedDynamicStateSupported()) {
|
||||||
device.IsExtExtendedDynamicStateSupported() && !use_vertex_input_dynamic_state;
|
|
||||||
|
|
||||||
if (use_bind_vertex_buffers2_stride) {
|
|
||||||
scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([bindings_ = std::move(bindings), buffer_handles_ = std::move(buffer_handles), binding_count](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, binding_count, buffer_handles_.data(), bindings_.offsets.data(), bindings_.sizes.data(), bindings_.strides.data());
|
cmdbuf.BindVertexBuffers2EXT(bindings_.min_index, binding_count, buffer_handles_.data(), bindings_.offsets.data(), bindings_.sizes.data(), bindings_.strides.data());
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,6 @@ private:
|
||||||
std::unique_ptr<Uint8Pass> uint8_pass;
|
std::unique_ptr<Uint8Pass> uint8_pass;
|
||||||
QuadIndexedPass quad_index_pass;
|
QuadIndexedPass quad_index_pass;
|
||||||
|
|
||||||
bool use_vertex_input_dynamic_state = false;
|
|
||||||
bool limit_dynamic_storage_buffers = false;
|
bool limit_dynamic_storage_buffers = false;
|
||||||
u32 max_dynamic_storage_buffers = (std::numeric_limits<u32>::max)();
|
u32 max_dynamic_storage_buffers = (std::numeric_limits<u32>::max)();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1732,54 +1732,39 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
||||||
}
|
}
|
||||||
dirty[Dirty::VertexInput] = false;
|
dirty[Dirty::VertexInput] = false;
|
||||||
|
|
||||||
const size_t max_vertex_attributes =
|
|
||||||
(std::min)(Maxwell::NumVertexAttributes,
|
|
||||||
static_cast<size_t>(device.GetMaxVertexInputAttributes()));
|
|
||||||
const size_t max_vertex_bindings =
|
|
||||||
(std::min)(Maxwell::NumVertexArrays,
|
|
||||||
static_cast<size_t>(device.GetMaxVertexInputBindings()));
|
|
||||||
|
|
||||||
// Dynamic state path must respect device limits, same as static pipeline creation.
|
|
||||||
for (size_t index = max_vertex_attributes; index < Maxwell::NumVertexAttributes; ++index) {
|
|
||||||
dirty[Dirty::VertexAttribute0 + index] = false;
|
|
||||||
}
|
|
||||||
for (size_t index = max_vertex_bindings; index < Maxwell::NumVertexArrays; ++index) {
|
|
||||||
dirty[Dirty::VertexBinding0 + index] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings;
|
boost::container::static_vector<VkVertexInputBindingDescription2EXT, 32> bindings;
|
||||||
boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes;
|
boost::container::static_vector<VkVertexInputAttributeDescription2EXT, 32> attributes;
|
||||||
|
|
||||||
std::array<bool, Maxwell::NumVertexArrays> used_bindings{};
|
// There seems to be a bug on Nvidia's driver where updating only higher attributes ends up
|
||||||
for (size_t index = 0; index < max_vertex_attributes; ++index) {
|
// generating dirty state. Track the highest dirty attribute and update all attributes until
|
||||||
dirty[Dirty::VertexAttribute0 + index] = false;
|
// that one.
|
||||||
|
size_t highest_dirty_attr{};
|
||||||
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||||
if (attribute.constant) {
|
if (dirty[Dirty::VertexAttribute0 + index]) {
|
||||||
continue;
|
highest_dirty_attr = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t binding{attribute.buffer};
|
|
||||||
if (binding >= max_vertex_bindings) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
used_bindings[binding] = true;
|
|
||||||
attributes.push_back({
|
|
||||||
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
|
|
||||||
.pNext = nullptr,
|
|
||||||
.location = static_cast<u32>(index),
|
|
||||||
.binding = static_cast<u32>(binding),
|
|
||||||
.format = MaxwellToVK::VertexFormat(device, attribute.type, attribute.size),
|
|
||||||
.offset = attribute.offset,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
for (size_t index = 0; index < highest_dirty_attr; ++index) {
|
||||||
for (size_t index = 0; index < max_vertex_bindings; ++index) {
|
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
||||||
dirty[Dirty::VertexBinding0 + index] = false;
|
const u32 binding{attribute.buffer};
|
||||||
if (!used_bindings[index]) {
|
dirty[Dirty::VertexAttribute0 + index] = false;
|
||||||
|
dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true;
|
||||||
|
if (!attribute.constant) {
|
||||||
|
attributes.push_back({
|
||||||
|
.sType = VK_STRUCTURE_TYPE_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION_2_EXT,
|
||||||
|
.pNext = nullptr,
|
||||||
|
.location = static_cast<u32>(index),
|
||||||
|
.binding = binding,
|
||||||
|
.format = MaxwellToVK::VertexFormat(device, attribute.type, attribute.size),
|
||||||
|
.offset = attribute.offset,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
||||||
|
if (!dirty[Dirty::VertexBinding0 + index]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
dirty[Dirty::VertexBinding0 + index] = false;
|
||||||
|
|
||||||
const u32 binding{static_cast<u32>(index)};
|
const u32 binding{static_cast<u32>(index)};
|
||||||
const auto& input_binding{regs.vertex_streams[binding]};
|
const auto& input_binding{regs.vertex_streams[binding]};
|
||||||
|
|
@ -1793,10 +1778,6 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
|
||||||
.divisor = is_instanced ? input_binding.frequency : 1,
|
.divisor = is_instanced ? input_binding.frequency : 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(attributes.size() <= max_vertex_attributes);
|
|
||||||
ASSERT(bindings.size() <= max_vertex_bindings);
|
|
||||||
|
|
||||||
scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) {
|
scheduler.Record([bindings, attributes](vk::CommandBuffer cmdbuf) {
|
||||||
cmdbuf.SetVertexInputEXT(bindings, attributes);
|
cmdbuf.SetVertexInputEXT(bindings, attributes);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1112,11 +1112,34 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||||
// VK_DYNAMIC_STATE
|
// VK_DYNAMIC_STATE
|
||||||
|
|
||||||
// Driver detection variables for workarounds in GetSuitability
|
// Driver detection variables for workarounds in GetSuitability
|
||||||
|
const VkDriverId driver_id = properties.driver.driverID;
|
||||||
|
|
||||||
// VK_EXT_extended_dynamic_state2 below this will appear drivers that need workarounds.
|
// VK_EXT_extended_dynamic_state2 below this will appear drivers that need workarounds.
|
||||||
|
|
||||||
// VK_EXT_extended_dynamic_state3 below this will appear drivers that need workarounds.
|
// VK_EXT_extended_dynamic_state3 below this will appear drivers that need workarounds.
|
||||||
|
|
||||||
|
// Samsung: Broken extendedDynamicState3ColorBlendEquation
|
||||||
|
// Disable blend equation dynamic state, force static pipeline state
|
||||||
|
if (extensions.extended_dynamic_state3 &&
|
||||||
|
(driver_id == VK_DRIVER_ID_SAMSUNG_PROPRIETARY)) {
|
||||||
|
LOG_WARNING(Render_Vulkan,
|
||||||
|
"Samsung: Disabling broken extendedDynamicState3ColorBlendEquation");
|
||||||
|
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
||||||
|
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEquation = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intel Windows < 27.20.100.0: Broken VertexInputDynamicState
|
||||||
|
// Same for NVIDIA Proprietary < 580.119.02, unknown when VIDS was first NOT broken
|
||||||
|
// Disable VertexInputDynamicState on old Intel Windows drivers
|
||||||
|
if (extensions.vertex_input_dynamic_state) {
|
||||||
|
const u32 version = (properties.properties.driverVersion << 3) >> 3;
|
||||||
|
if ((driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS && version < VK_MAKE_API_VERSION(27, 20, 100, 0))
|
||||||
|
|| (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY && version < VK_MAKE_API_VERSION(580, 119, 02, 0))) {
|
||||||
|
LOG_WARNING(Render_Vulkan, "Disabling broken VK_EXT_vertex_input_dynamic_state");
|
||||||
|
RemoveExtensionFeature(extensions.vertex_input_dynamic_state, features.vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (u32(Settings::values.dyna_state.GetValue()) == 0) {
|
if (u32(Settings::values.dyna_state.GetValue()) == 0) {
|
||||||
LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features");
|
LOG_INFO(Render_Vulkan, "Extended Dynamic State disabled by user setting, clearing all EDS features");
|
||||||
features.extended_dynamic_state.extendedDynamicState = false;
|
features.extended_dynamic_state.extendedDynamicState = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue