mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-09 22:58:54 +02:00
Compare commits
5 commits
3d0eb4b5d7
...
3ca8bdce0d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ca8bdce0d | ||
|
|
415a62c37b | ||
|
|
636f4e4e4b | ||
|
|
b20773db0e | ||
|
|
adb8ecfec5 |
6 changed files with 94 additions and 122 deletions
|
|
@ -10,6 +10,7 @@
|
||||||
#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"
|
||||||
|
|
||||||
|
|
@ -334,6 +335,9 @@ 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;
|
||||||
|
|
@ -556,7 +560,10 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, VkBuffer buffer, u32 offset
|
||||||
if (index >= device.GetMaxVertexInputBindings()) {
|
if (index >= device.GetMaxVertexInputBindings()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
const bool use_bind_vertex_buffers2_stride =
|
||||||
|
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;
|
||||||
|
|
@ -596,7 +603,10 @@ void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bi
|
||||||
if (binding_count == 0) {
|
if (binding_count == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (device.IsExtExtendedDynamicStateSupported()) {
|
const bool use_bind_vertex_buffers2_stride =
|
||||||
|
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,6 +183,7 @@ 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,39 +1732,54 @@ 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;
|
||||||
|
|
||||||
// There seems to be a bug on Nvidia's driver where updating only higher attributes ends up
|
std::array<bool, Maxwell::NumVertexArrays> used_bindings{};
|
||||||
// generating dirty state. Track the highest dirty attribute and update all attributes until
|
for (size_t index = 0; index < max_vertex_attributes; ++index) {
|
||||||
// that one.
|
|
||||||
size_t highest_dirty_attr{};
|
|
||||||
for (size_t index = 0; index < Maxwell::NumVertexAttributes; ++index) {
|
|
||||||
if (dirty[Dirty::VertexAttribute0 + index]) {
|
|
||||||
highest_dirty_attr = index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (size_t index = 0; index < highest_dirty_attr; ++index) {
|
|
||||||
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
|
||||||
const u32 binding{attribute.buffer};
|
|
||||||
dirty[Dirty::VertexAttribute0 + index] = false;
|
dirty[Dirty::VertexAttribute0 + index] = false;
|
||||||
dirty[Dirty::VertexBinding0 + static_cast<size_t>(binding)] = true;
|
|
||||||
if (!attribute.constant) {
|
const Maxwell::VertexAttribute attribute{regs.vertex_attrib_format[index]};
|
||||||
attributes.push_back({
|
if (attribute.constant) {
|
||||||
.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 < max_vertex_bindings; ++index) {
|
||||||
dirty[Dirty::VertexBinding0 + index] = false;
|
dirty[Dirty::VertexBinding0 + index] = false;
|
||||||
|
if (!used_bindings[index]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
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]};
|
||||||
|
|
@ -1778,6 +1793,10 @@ 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);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2300,23 +2300,18 @@ vk::ImageView ImageView::MakeView(VkFormat vk_format, VkImageAspectFlags aspect_
|
||||||
|
|
||||||
Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) {
|
Sampler::Sampler(TextureCacheRuntime& runtime, const Tegra::Texture::TSCEntry& tsc) {
|
||||||
const auto& device = runtime.device;
|
const auto& device = runtime.device;
|
||||||
// Check if custom border colors are supported
|
const bool has_custom_border_extension = runtime.device.IsExtCustomBorderColorSupported();
|
||||||
const bool has_custom_border_colors = runtime.device.IsCustomBorderColorsSupported();
|
const bool has_format_undefined =
|
||||||
const bool has_format_undefined = runtime.device.IsCustomBorderColorWithoutFormatSupported();
|
has_custom_border_extension && runtime.device.IsCustomBorderColorWithoutFormatSupported();
|
||||||
|
const bool has_custom_border_colors =
|
||||||
|
has_format_undefined && runtime.device.IsCustomBorderColorsSupported();
|
||||||
const auto color = tsc.BorderColor();
|
const auto color = tsc.BorderColor();
|
||||||
|
|
||||||
// Determine border format based on available features:
|
|
||||||
// - If customBorderColorWithoutFormat is available: use VK_FORMAT_UNDEFINED (most flexible)
|
|
||||||
// - If only customBorderColors is available: use concrete format (R8G8B8A8_UNORM)
|
|
||||||
// - If neither is available: use standard border colors (handled by ConvertBorderColor)
|
|
||||||
const VkFormat border_format = has_format_undefined ? VK_FORMAT_UNDEFINED
|
|
||||||
: VK_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
|
|
||||||
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
const VkSamplerCustomBorderColorCreateInfoEXT border_ci{
|
||||||
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT,
|
||||||
.pNext = nullptr,
|
.pNext = nullptr,
|
||||||
.customBorderColor = std::bit_cast<VkClearColorValue>(color),
|
.customBorderColor = std::bit_cast<VkClearColorValue>(color),
|
||||||
.format = border_format,
|
.format = VK_FORMAT_UNDEFINED,
|
||||||
};
|
};
|
||||||
const void* pnext = nullptr;
|
const void* pnext = nullptr;
|
||||||
if (has_custom_border_colors) {
|
if (has_custom_border_colors) {
|
||||||
|
|
|
||||||
|
|
@ -919,6 +919,17 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||||
FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION);
|
FOR_EACH_VK_FEATURE_EXT(FEATURE_EXTENSION);
|
||||||
FOR_EACH_VK_EXTENSION(EXTENSION);
|
FOR_EACH_VK_EXTENSION(EXTENSION);
|
||||||
|
|
||||||
|
if (supported_extensions.contains(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME)) {
|
||||||
|
loaded_extensions.erase(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||||
|
loaded_extensions.insert(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME);
|
||||||
|
extensions.robustness_2 = true;
|
||||||
|
} else if (supported_extensions.contains(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME)) {
|
||||||
|
loaded_extensions.insert(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
||||||
|
extensions.robustness_2 = true;
|
||||||
|
} else {
|
||||||
|
extensions.robustness_2 = false;
|
||||||
|
}
|
||||||
|
|
||||||
#undef FEATURE_EXTENSION
|
#undef FEATURE_EXTENSION
|
||||||
#undef EXTENSION
|
#undef EXTENSION
|
||||||
|
|
||||||
|
|
@ -1101,38 +1112,13 @@ 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.custom_border_color.customBorderColors = false;
|
|
||||||
features.custom_border_color.customBorderColorWithoutFormat = false;
|
|
||||||
features.extended_dynamic_state.extendedDynamicState = false;
|
features.extended_dynamic_state.extendedDynamicState = false;
|
||||||
features.extended_dynamic_state2.extendedDynamicState2 = false;
|
features.extended_dynamic_state2.extendedDynamicState2 = false;
|
||||||
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
features.extended_dynamic_state3.extendedDynamicState3ColorBlendEnable = false;
|
||||||
|
|
@ -1148,24 +1134,13 @@ bool Device::GetSuitability(bool requires_swapchain) {
|
||||||
|
|
||||||
void Device::RemoveUnsuitableExtensions() {
|
void Device::RemoveUnsuitableExtensions() {
|
||||||
// VK_EXT_custom_border_color
|
// VK_EXT_custom_border_color
|
||||||
// Enable extension if driver supports it, then check individual features
|
|
||||||
// - customBorderColors: Required to use VK_BORDER_COLOR_FLOAT_CUSTOM_EXT
|
|
||||||
// - customBorderColorWithoutFormat: Optional, allows VK_FORMAT_UNDEFINED
|
|
||||||
// If only customBorderColors is available, we must provide a specific format
|
|
||||||
if (extensions.custom_border_color) {
|
if (extensions.custom_border_color) {
|
||||||
// Verify that at least customBorderColors is available
|
extensions.custom_border_color =
|
||||||
if (!features.custom_border_color.customBorderColors) {
|
features.custom_border_color.customBorderColors &&
|
||||||
LOG_WARNING(Render_Vulkan,
|
features.custom_border_color.customBorderColorWithoutFormat;
|
||||||
"VK_EXT_custom_border_color reported but customBorderColors feature not available, disabling");
|
|
||||||
extensions.custom_border_color = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color,
|
RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color,
|
||||||
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME);
|
||||||
// VK_KHR_unified_image_layouts
|
|
||||||
extensions.unified_image_layouts = features.unified_image_layouts.unifiedImageLayouts;
|
|
||||||
RemoveExtensionFeatureIfUnsuitable(extensions.unified_image_layouts, features.unified_image_layouts,
|
|
||||||
VK_KHR_UNIFIED_IMAGE_LAYOUTS_EXTENSION_NAME);
|
|
||||||
|
|
||||||
// VK_EXT_depth_bias_control
|
// VK_EXT_depth_bias_control
|
||||||
extensions.depth_bias_control =
|
extensions.depth_bias_control =
|
||||||
|
|
@ -1251,16 +1226,22 @@ void Device::RemoveUnsuitableExtensions() {
|
||||||
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
|
||||||
|
|
||||||
// VK_EXT_robustness2
|
// VK_EXT_robustness2
|
||||||
extensions.robustness_2 = features.robustness2.robustBufferAccess2 ||
|
features.robustness2.robustBufferAccess2 = VK_FALSE;
|
||||||
features.robustness2.robustImageAccess2 ||
|
features.robustness2.robustImageAccess2 = VK_FALSE;
|
||||||
features.robustness2.nullDescriptor;
|
extensions.robustness_2 = features.robustness2.nullDescriptor;
|
||||||
|
|
||||||
|
const char* robustness2_extension_name =
|
||||||
|
loaded_extensions.contains(VK_KHR_ROBUSTNESS_2_EXTENSION_NAME)
|
||||||
|
? VK_KHR_ROBUSTNESS_2_EXTENSION_NAME
|
||||||
|
: VK_EXT_ROBUSTNESS_2_EXTENSION_NAME;
|
||||||
|
|
||||||
RemoveExtensionFeatureIfUnsuitable(extensions.robustness_2, features.robustness2,
|
RemoveExtensionFeatureIfUnsuitable(extensions.robustness_2, features.robustness2,
|
||||||
VK_EXT_ROBUSTNESS_2_EXTENSION_NAME);
|
robustness2_extension_name);
|
||||||
|
|
||||||
// VK_EXT_image_robustness
|
// Image robustness
|
||||||
extensions.image_robustness = features.image_robustness.robustImageAccess;
|
extensions.robust_image_access = features.robust_image_access.robustImageAccess;
|
||||||
RemoveExtensionFeatureIfUnsuitable(extensions.image_robustness, features.image_robustness,
|
RemoveExtensionFeatureIfUnsuitable(extensions.robust_image_access,
|
||||||
|
features.robust_image_access,
|
||||||
VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME);
|
VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME);
|
||||||
|
|
||||||
// VK_KHR_shader_atomic_int64
|
// VK_KHR_shader_atomic_int64
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore)
|
FEATURE(KHR, TimelineSemaphore, TIMELINE_SEMAPHORE, timeline_semaphore)
|
||||||
|
|
||||||
#define FOR_EACH_VK_FEATURE_1_3(FEATURE) \
|
#define FOR_EACH_VK_FEATURE_1_3(FEATURE) \
|
||||||
FEATURE(EXT, ImageRobustness, IMAGE_ROBUSTNESS, image_robustness) \
|
FEATURE(EXT, ImageRobustness, IMAGE_ROBUSTNESS, robust_image_access) \
|
||||||
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
|
FEATURE(EXT, ShaderDemoteToHelperInvocation, SHADER_DEMOTE_TO_HELPER_INVOCATION, \
|
||||||
shader_demote_to_helper_invocation) \
|
shader_demote_to_helper_invocation) \
|
||||||
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
|
FEATURE(EXT, SubgroupSizeControl, SUBGROUP_SIZE_CONTROL, subgroup_size_control) \
|
||||||
|
|
@ -68,8 +68,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
|
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
|
||||||
pipeline_executable_properties) \
|
pipeline_executable_properties) \
|
||||||
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
|
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
|
||||||
workgroup_memory_explicit_layout) \
|
workgroup_memory_explicit_layout)
|
||||||
FEATURE(KHR, UnifiedImageLayouts, UNIFIED_IMAGE_LAYOUTS, unified_image_layouts)
|
|
||||||
|
|
||||||
|
|
||||||
// Define miscellaneous extensions which may be used by the implementation here.
|
// Define miscellaneous extensions which may be used by the implementation here.
|
||||||
|
|
@ -124,7 +123,6 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_4444_FORMATS_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME) \
|
|
||||||
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) \
|
||||||
EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
|
EXTENSION_NAME(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME) \
|
||||||
|
|
@ -174,13 +172,11 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||||
FEATURE_NAME(depth_bias_control, depthBiasExact) \
|
FEATURE_NAME(depth_bias_control, depthBiasExact) \
|
||||||
FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \
|
FEATURE_NAME(extended_dynamic_state, extendedDynamicState) \
|
||||||
FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \
|
FEATURE_NAME(format_a4b4g4r4, formatA4B4G4R4) \
|
||||||
FEATURE_NAME(image_robustness, robustImageAccess) \
|
FEATURE_NAME(robust_image_access, robustImageAccess) \
|
||||||
FEATURE_NAME(index_type_uint8, indexTypeUint8) \
|
FEATURE_NAME(index_type_uint8, indexTypeUint8) \
|
||||||
FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \
|
FEATURE_NAME(primitive_topology_list_restart, primitiveTopologyListRestart) \
|
||||||
FEATURE_NAME(provoking_vertex, provokingVertexLast) \
|
FEATURE_NAME(provoking_vertex, provokingVertexLast) \
|
||||||
FEATURE_NAME(robustness2, nullDescriptor) \
|
FEATURE_NAME(robustness2, nullDescriptor) \
|
||||||
FEATURE_NAME(robustness2, robustBufferAccess2) \
|
|
||||||
FEATURE_NAME(robustness2, robustImageAccess2) \
|
|
||||||
FEATURE_NAME(shader_float16_int8, shaderFloat16) \
|
FEATURE_NAME(shader_float16_int8, shaderFloat16) \
|
||||||
FEATURE_NAME(shader_float16_int8, shaderInt8) \
|
FEATURE_NAME(shader_float16_int8, shaderInt8) \
|
||||||
FEATURE_NAME(timeline_semaphore, timelineSemaphore) \
|
FEATURE_NAME(timeline_semaphore, timelineSemaphore) \
|
||||||
|
|
@ -552,36 +548,6 @@ public:
|
||||||
return extensions.custom_border_color;
|
return extensions.custom_border_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the device supports VK_EXT_image_robustness.
|
|
||||||
bool IsExtImageRobustnessSupported() const {
|
|
||||||
return extensions.image_robustness;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if robustImageAccess is supported.
|
|
||||||
bool IsRobustImageAccessSupported() const {
|
|
||||||
return features.image_robustness.robustImageAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if the device supports VK_EXT_robustness2.
|
|
||||||
bool IsExtRobustness2Supported() const {
|
|
||||||
return extensions.robustness_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if robustBufferAccess2 is supported.
|
|
||||||
bool IsRobustBufferAccess2Supported() const {
|
|
||||||
return features.robustness2.robustBufferAccess2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if robustImageAccess2 is supported.
|
|
||||||
bool IsRobustImageAccess2Supported() const {
|
|
||||||
return features.robustness2.robustImageAccess2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if nullDescriptor is supported.
|
|
||||||
bool IsNullDescriptorSupported() const {
|
|
||||||
return features.robustness2.nullDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if customBorderColors feature is available.
|
/// Returns true if customBorderColors feature is available.
|
||||||
bool IsCustomBorderColorsSupported() const {
|
bool IsCustomBorderColorsSupported() const {
|
||||||
return features.custom_border_color.customBorderColors;
|
return features.custom_border_color.customBorderColors;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue