buffer_cache: Use dynamic vertex input when available
* Fixes issues when games like dark souls rebind vertex buffers with different stride
This commit is contained in:
parent
594606c1c3
commit
b8084d3ed8
|
@ -8,6 +8,7 @@
|
||||||
#include "video_core/amdgpu/liverpool.h"
|
#include "video_core/amdgpu/liverpool.h"
|
||||||
#include "video_core/buffer_cache/buffer_cache.h"
|
#include "video_core/buffer_cache/buffer_cache.h"
|
||||||
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||||
|
#include "video_core/renderer_vulkan/liverpool_to_vk.h"
|
||||||
#include "video_core/renderer_vulkan/vk_instance.h"
|
#include "video_core/renderer_vulkan/vk_instance.h"
|
||||||
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
#include "video_core/renderer_vulkan/vk_scheduler.h"
|
||||||
|
|
||||||
|
@ -87,6 +88,15 @@ void BufferCache::DownloadBufferMemory(Buffer& buffer, VAddr device_addr, u64 si
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
|
bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
|
||||||
|
boost::container::small_vector<vk::VertexInputAttributeDescription2EXT, 16> attributes;
|
||||||
|
boost::container::small_vector<vk::VertexInputBindingDescription2EXT, 16> bindings;
|
||||||
|
SCOPE_EXIT {
|
||||||
|
if (instance.IsVertexInputDynamicState()) {
|
||||||
|
const auto cmdbuf = scheduler.CommandBuffer();
|
||||||
|
cmdbuf.setVertexInputEXT(bindings, attributes);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (vs_info.vs_inputs.empty()) {
|
if (vs_info.vs_inputs.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +132,20 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
|
||||||
}
|
}
|
||||||
guest_buffers.emplace_back(buffer);
|
guest_buffers.emplace_back(buffer);
|
||||||
ranges.emplace_back(buffer.base_address, buffer.base_address + buffer.GetSize());
|
ranges.emplace_back(buffer.base_address, buffer.base_address + buffer.GetSize());
|
||||||
|
attributes.push_back({
|
||||||
|
.location = input.binding,
|
||||||
|
.binding = input.binding,
|
||||||
|
.format = Vulkan::LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()),
|
||||||
|
.offset = 0,
|
||||||
|
});
|
||||||
|
bindings.push_back({
|
||||||
|
.binding = input.binding,
|
||||||
|
.stride = buffer.GetStride(),
|
||||||
|
.inputRate = input.instance_step_rate == Shader::Info::VsInput::None
|
||||||
|
? vk::VertexInputRate::eVertex
|
||||||
|
: vk::VertexInputRate::eInstance,
|
||||||
|
.divisor = 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ranges::sort(ranges, [](const BufferRange& lhv, const BufferRange& rhv) {
|
std::ranges::sort(ranges, [](const BufferRange& lhv, const BufferRange& rhv) {
|
||||||
|
|
|
@ -145,6 +145,9 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
|
||||||
dynamic_states.push_back(vk::DynamicState::eColorWriteEnableEXT);
|
dynamic_states.push_back(vk::DynamicState::eColorWriteEnableEXT);
|
||||||
dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT);
|
dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT);
|
||||||
}
|
}
|
||||||
|
if (instance.IsVertexInputDynamicState()) {
|
||||||
|
dynamic_states.push_back(vk::DynamicState::eVertexInputEXT);
|
||||||
|
}
|
||||||
|
|
||||||
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
const vk::PipelineDynamicStateCreateInfo dynamic_info = {
|
||||||
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
.dynamicStateCount = static_cast<u32>(dynamic_states.size()),
|
||||||
|
|
|
@ -202,6 +202,8 @@ bool Instance::CreateDevice() {
|
||||||
add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
|
add_extension(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME);
|
||||||
workgroup_memory_explicit_layout =
|
workgroup_memory_explicit_layout =
|
||||||
add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME);
|
add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME);
|
||||||
|
vertex_input_dynamic_state = add_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
|
||||||
|
|
||||||
// The next two extensions are required to be available together in order to support write masks
|
// The next two extensions are required to be available together in order to support write masks
|
||||||
color_write_en = add_extension(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
|
color_write_en = add_extension(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME);
|
||||||
color_write_en &= add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
color_write_en &= add_extension(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||||
|
@ -319,6 +321,9 @@ bool Instance::CreateDevice() {
|
||||||
vk::PhysicalDeviceSynchronization2Features{
|
vk::PhysicalDeviceSynchronization2Features{
|
||||||
.synchronization2 = true,
|
.synchronization2 = true,
|
||||||
},
|
},
|
||||||
|
vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT{
|
||||||
|
.vertexInputDynamicState = true,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!color_write_en) {
|
if (!color_write_en) {
|
||||||
|
@ -331,8 +336,8 @@ bool Instance::CreateDevice() {
|
||||||
} else {
|
} else {
|
||||||
device_chain.unlink<vk::PhysicalDeviceRobustness2FeaturesEXT>();
|
device_chain.unlink<vk::PhysicalDeviceRobustness2FeaturesEXT>();
|
||||||
}
|
}
|
||||||
if (!has_sync2) {
|
if (!vertex_input_dynamic_state) {
|
||||||
device_chain.unlink<vk::PhysicalDeviceSynchronization2Features>();
|
device_chain.unlink<vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -132,6 +132,11 @@ public:
|
||||||
return color_write_en;
|
return color_write_en;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true when VK_EXT_vertex_input_dynamic_state is supported.
|
||||||
|
bool IsVertexInputDynamicState() const {
|
||||||
|
return vertex_input_dynamic_state;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the vendor ID of the physical device
|
/// Returns the vendor ID of the physical device
|
||||||
u32 GetVendorID() const {
|
u32 GetVendorID() const {
|
||||||
return properties.vendorID;
|
return properties.vendorID;
|
||||||
|
@ -257,6 +262,7 @@ private:
|
||||||
bool external_memory_host{};
|
bool external_memory_host{};
|
||||||
bool workgroup_memory_explicit_layout{};
|
bool workgroup_memory_explicit_layout{};
|
||||||
bool color_write_en{};
|
bool color_write_en{};
|
||||||
|
bool vertex_input_dynamic_state{};
|
||||||
u64 min_imported_host_pointer_alignment{};
|
u64 min_imported_host_pointer_alignment{};
|
||||||
u32 subgroup_size{};
|
u32 subgroup_size{};
|
||||||
bool tooling_info{};
|
bool tooling_info{};
|
||||||
|
|
Loading…
Reference in New Issue