summaryrefslogtreecommitdiffstats
path: root/src/video_core/vulkan_common
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/vulkan_common')
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp56
-rw-r--r--src/video_core/vulkan_common/vulkan_memory_allocator.cpp21
-rw-r--r--src/video_core/vulkan_common/vulkan_memory_allocator.h14
3 files changed, 75 insertions, 16 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 3960b135a..876cec2e8 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -84,9 +84,12 @@ constexpr std::array VK_FORMAT_A4B4G4R4_UNORM_PACK16{
} // namespace Alternatives
enum class NvidiaArchitecture {
- AmpereOrNewer,
+ KeplerOrOlder,
+ Maxwell,
+ Pascal,
+ Volta,
Turing,
- VoltaOrOlder,
+ AmpereOrNewer,
};
template <typename T>
@@ -200,6 +203,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica
VK_FORMAT_BC7_UNORM_BLOCK,
VK_FORMAT_D16_UNORM,
VK_FORMAT_D16_UNORM_S8_UINT,
+ VK_FORMAT_X8_D24_UNORM_PACK32,
VK_FORMAT_D24_UNORM_S8_UINT,
VK_FORMAT_D32_SFLOAT,
VK_FORMAT_D32_SFLOAT_S8_UINT,
@@ -321,13 +325,38 @@ NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
physical.GetProperties2(physical_properties);
if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) {
// Only Ampere and newer support this feature
+ // TODO: Find a way to differentiate Ampere and Ada
return NvidiaArchitecture::AmpereOrNewer;
}
- }
- if (exts.contains(VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME)) {
return NvidiaArchitecture::Turing;
}
- return NvidiaArchitecture::VoltaOrOlder;
+
+ if (exts.contains(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME)) {
+ VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT advanced_blending_props{};
+ advanced_blending_props.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
+ VkPhysicalDeviceProperties2 physical_properties{};
+ physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ physical_properties.pNext = &advanced_blending_props;
+ physical.GetProperties2(physical_properties);
+ if (advanced_blending_props.advancedBlendMaxColorAttachments == 1) {
+ return NvidiaArchitecture::Maxwell;
+ }
+
+ if (exts.contains(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME)) {
+ VkPhysicalDeviceConservativeRasterizationPropertiesEXT conservative_raster_props{};
+ conservative_raster_props.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT;
+ physical_properties.pNext = &conservative_raster_props;
+ physical.GetProperties2(physical_properties);
+ if (conservative_raster_props.degenerateLinesRasterized) {
+ return NvidiaArchitecture::Volta;
+ }
+ return NvidiaArchitecture::Pascal;
+ }
+ }
+
+ return NvidiaArchitecture::KeplerOrOlder;
}
std::vector<const char*> ExtensionListForVulkan(
@@ -504,19 +533,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
if (is_nvidia) {
const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff;
const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
- switch (arch) {
- case NvidiaArchitecture::AmpereOrNewer:
+ if (arch >= NvidiaArchitecture::AmpereOrNewer) {
LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math");
features.shader_float16_int8.shaderFloat16 = false;
- break;
- case NvidiaArchitecture::Turing:
- break;
- case NvidiaArchitecture::VoltaOrOlder:
+ } else if (arch <= NvidiaArchitecture::Volta) {
if (nv_major_version < 527) {
LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
}
- break;
}
if (nv_major_version >= 510) {
LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits");
@@ -661,7 +685,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
"ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor");
RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
}
+ } else if (extensions.push_descriptor && is_nvidia) {
+ const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
+ if (arch <= NvidiaArchitecture::Pascal) {
+ LOG_WARNING(Render_Vulkan,
+ "Pascal and older architectures have broken VK_KHR_push_descriptor");
+ RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
+ }
}
+
if (is_mvk) {
LOG_WARNING(Render_Vulkan,
"MVK driver breaks when using more than 16 vertex attributes/bindings");
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
index 3ef381a38..82767fdf0 100644
--- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
+++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp
@@ -9,6 +9,7 @@
#include "common/alignment.h"
#include "common/assert.h"
#include "common/common_types.h"
+#include "common/literals.h"
#include "common/logging/log.h"
#include "common/polyfill_ranges.h"
#include "video_core/vulkan_common/vma.h"
@@ -69,8 +70,7 @@ struct Range {
case MemoryUsage::Download:
return VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT;
case MemoryUsage::DeviceLocal:
- return VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
- VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT;
+ return {};
}
return {};
}
@@ -212,7 +212,20 @@ MemoryAllocator::MemoryAllocator(const Device& device_)
: device{device_}, allocator{device.GetAllocator()},
properties{device_.GetPhysical().GetMemoryProperties().memoryProperties},
buffer_image_granularity{
- device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {}
+ device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {
+ // GPUs not supporting rebar may only have a region with less than 256MB host visible/device
+ // local memory. In that case, opening 2 RenderDoc captures side-by-side is not possible due to
+ // the heap running out of memory. With RenderDoc attached and only a small host/device region,
+ // only allow the stream buffer in this memory heap.
+ if (device.HasDebuggingToolAttached()) {
+ using namespace Common::Literals;
+ ForEachDeviceLocalHostVisibleHeap(device, [this](size_t index, VkMemoryHeap& heap) {
+ if (heap.size <= 256_MiB) {
+ valid_memory_types &= ~(1u << index);
+ }
+ });
+ }
+}
MemoryAllocator::~MemoryAllocator() = default;
@@ -244,7 +257,7 @@ vk::Buffer MemoryAllocator::CreateBuffer(const VkBufferCreateInfo& ci, MemoryUsa
.usage = MemoryUsageVma(usage),
.requiredFlags = 0,
.preferredFlags = MemoryUsagePreferedVmaFlags(usage),
- .memoryTypeBits = 0,
+ .memoryTypeBits = usage == MemoryUsage::Stream ? 0u : valid_memory_types,
.pool = VK_NULL_HANDLE,
.pUserData = nullptr,
.priority = 0.f,
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h
index f449bc8d0..38a182bcb 100644
--- a/src/video_core/vulkan_common/vulkan_memory_allocator.h
+++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h
@@ -7,6 +7,7 @@
#include <span>
#include <vector>
#include "common/common_types.h"
+#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
VK_DEFINE_HANDLE(VmaAllocator)
@@ -26,6 +27,18 @@ enum class MemoryUsage {
Stream, ///< Requests device local host visible buffer, falling back host memory.
};
+template <typename F>
+void ForEachDeviceLocalHostVisibleHeap(const Device& device, F&& f) {
+ auto memory_props = device.GetPhysical().GetMemoryProperties().memoryProperties;
+ for (size_t i = 0; i < memory_props.memoryTypeCount; i++) {
+ auto& memory_type = memory_props.memoryTypes[i];
+ if ((memory_type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
+ (memory_type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
+ f(memory_type.heapIndex, memory_props.memoryHeaps[memory_type.heapIndex]);
+ }
+ }
+}
+
/// Ownership handle of a memory commitment.
/// Points to a subregion of a memory allocation.
class MemoryCommit {
@@ -124,6 +137,7 @@ private:
std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations.
VkDeviceSize buffer_image_granularity; // The granularity for adjacent offsets between buffers
// and optimal images
+ u32 valid_memory_types{~0u};
};
} // namespace Vulkan