summaryrefslogtreecommitdiff
path: root/src/video_core/vulkan_common
diff options
context:
space:
mode:
authorGravatar bunnei2021-07-25 11:39:04 -0700
committerGravatar GitHub2021-07-25 11:39:04 -0700
commit98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f (patch)
tree816faa96c2c4d291825063433331a8ea4b3d08f1 /src/video_core/vulkan_common
parentMerge pull request #6699 from lat9nq/common-threads (diff)
parentshader: Support out of bound local memory reads and immediate writes (diff)
downloadyuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.tar.gz
yuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.tar.xz
yuzu-98b26b6e126d4775fdf3f773fe8a8ac808a8ff8f.zip
Merge pull request #6585 from ameerj/hades
Shader Decompiler Rewrite
Diffstat (limited to 'src/video_core/vulkan_common')
-rw-r--r--src/video_core/vulkan_common/nsight_aftermath_tracker.cpp7
-rw-r--r--src/video_core/vulkan_common/nsight_aftermath_tracker.h21
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp362
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h161
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.cpp5
-rw-r--r--src/video_core/vulkan_common/vulkan_wrapper.h44
6 files changed, 497 insertions, 103 deletions
diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
index 758c038ba..fdd1a5081 100644
--- a/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
+++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.cpp
@@ -73,12 +73,11 @@ NsightAftermathTracker::~NsightAftermathTracker() {
73 } 73 }
74} 74}
75 75
76void NsightAftermathTracker::SaveShader(const std::vector<u32>& spirv) const { 76void NsightAftermathTracker::SaveShader(std::span<const u32> spirv) const {
77 if (!initialized) { 77 if (!initialized) {
78 return; 78 return;
79 } 79 }
80 80 std::vector<u32> spirv_copy(spirv.begin(), spirv.end());
81 std::vector<u32> spirv_copy = spirv;
82 GFSDK_Aftermath_SpirvCode shader; 81 GFSDK_Aftermath_SpirvCode shader;
83 shader.pData = spirv_copy.data(); 82 shader.pData = spirv_copy.data();
84 shader.size = static_cast<u32>(spirv_copy.size() * 4); 83 shader.size = static_cast<u32>(spirv_copy.size() * 4);
@@ -100,7 +99,7 @@ void NsightAftermathTracker::SaveShader(const std::vector<u32>& spirv) const {
100 LOG_ERROR(Render_Vulkan, "Failed to dump SPIR-V module with hash={:016x}", hash.hash); 99 LOG_ERROR(Render_Vulkan, "Failed to dump SPIR-V module with hash={:016x}", hash.hash);
101 return; 100 return;
102 } 101 }
103 if (file.Write(spirv) != spirv.size()) { 102 if (file.WriteSpan(spirv) != spirv.size()) {
104 LOG_ERROR(Render_Vulkan, "Failed to write SPIR-V module with hash={:016x}", hash.hash); 103 LOG_ERROR(Render_Vulkan, "Failed to write SPIR-V module with hash={:016x}", hash.hash);
105 return; 104 return;
106 } 105 }
diff --git a/src/video_core/vulkan_common/nsight_aftermath_tracker.h b/src/video_core/vulkan_common/nsight_aftermath_tracker.h
index 4fe2b14d9..eae1891dd 100644
--- a/src/video_core/vulkan_common/nsight_aftermath_tracker.h
+++ b/src/video_core/vulkan_common/nsight_aftermath_tracker.h
@@ -6,6 +6,7 @@
6 6
7#include <filesystem> 7#include <filesystem>
8#include <mutex> 8#include <mutex>
9#include <span>
9#include <string> 10#include <string>
10#include <vector> 11#include <vector>
11 12
@@ -33,7 +34,7 @@ public:
33 NsightAftermathTracker(NsightAftermathTracker&&) = delete; 34 NsightAftermathTracker(NsightAftermathTracker&&) = delete;
34 NsightAftermathTracker& operator=(NsightAftermathTracker&&) = delete; 35 NsightAftermathTracker& operator=(NsightAftermathTracker&&) = delete;
35 36
36 void SaveShader(const std::vector<u32>& spirv) const; 37 void SaveShader(std::span<const u32> spirv) const;
37 38
38private: 39private:
39#ifdef HAS_NSIGHT_AFTERMATH 40#ifdef HAS_NSIGHT_AFTERMATH
@@ -61,21 +62,21 @@ private:
61 bool initialized = false; 62 bool initialized = false;
62 63
63 Common::DynamicLibrary dl; 64 Common::DynamicLibrary dl;
64 PFN_GFSDK_Aftermath_DisableGpuCrashDumps GFSDK_Aftermath_DisableGpuCrashDumps; 65 PFN_GFSDK_Aftermath_DisableGpuCrashDumps GFSDK_Aftermath_DisableGpuCrashDumps{};
65 PFN_GFSDK_Aftermath_EnableGpuCrashDumps GFSDK_Aftermath_EnableGpuCrashDumps; 66 PFN_GFSDK_Aftermath_EnableGpuCrashDumps GFSDK_Aftermath_EnableGpuCrashDumps{};
66 PFN_GFSDK_Aftermath_GetShaderDebugInfoIdentifier GFSDK_Aftermath_GetShaderDebugInfoIdentifier; 67 PFN_GFSDK_Aftermath_GetShaderDebugInfoIdentifier GFSDK_Aftermath_GetShaderDebugInfoIdentifier{};
67 PFN_GFSDK_Aftermath_GetShaderHashSpirv GFSDK_Aftermath_GetShaderHashSpirv; 68 PFN_GFSDK_Aftermath_GetShaderHashSpirv GFSDK_Aftermath_GetShaderHashSpirv{};
68 PFN_GFSDK_Aftermath_GpuCrashDump_CreateDecoder GFSDK_Aftermath_GpuCrashDump_CreateDecoder; 69 PFN_GFSDK_Aftermath_GpuCrashDump_CreateDecoder GFSDK_Aftermath_GpuCrashDump_CreateDecoder{};
69 PFN_GFSDK_Aftermath_GpuCrashDump_DestroyDecoder GFSDK_Aftermath_GpuCrashDump_DestroyDecoder; 70 PFN_GFSDK_Aftermath_GpuCrashDump_DestroyDecoder GFSDK_Aftermath_GpuCrashDump_DestroyDecoder{};
70 PFN_GFSDK_Aftermath_GpuCrashDump_GenerateJSON GFSDK_Aftermath_GpuCrashDump_GenerateJSON; 71 PFN_GFSDK_Aftermath_GpuCrashDump_GenerateJSON GFSDK_Aftermath_GpuCrashDump_GenerateJSON{};
71 PFN_GFSDK_Aftermath_GpuCrashDump_GetJSON GFSDK_Aftermath_GpuCrashDump_GetJSON; 72 PFN_GFSDK_Aftermath_GpuCrashDump_GetJSON GFSDK_Aftermath_GpuCrashDump_GetJSON{};
72#endif 73#endif
73}; 74};
74 75
75#ifndef HAS_NSIGHT_AFTERMATH 76#ifndef HAS_NSIGHT_AFTERMATH
76inline NsightAftermathTracker::NsightAftermathTracker() = default; 77inline NsightAftermathTracker::NsightAftermathTracker() = default;
77inline NsightAftermathTracker::~NsightAftermathTracker() = default; 78inline NsightAftermathTracker::~NsightAftermathTracker() = default;
78inline void NsightAftermathTracker::SaveShader(const std::vector<u32>&) const {} 79inline void NsightAftermathTracker::SaveShader(std::span<const u32>) const {}
79#endif 80#endif
80 81
81} // namespace Vulkan 82} // namespace Vulkan
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index f214510da..44afdc1cd 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <bitset> 6#include <bitset>
6#include <chrono> 7#include <chrono>
7#include <optional> 8#include <optional>
@@ -33,6 +34,12 @@ constexpr std::array DEPTH16_UNORM_STENCIL8_UINT{
33}; 34};
34} // namespace Alternatives 35} // namespace Alternatives
35 36
37enum class NvidiaArchitecture {
38 AmpereOrNewer,
39 Turing,
40 VoltaOrOlder,
41};
42
36constexpr std::array REQUIRED_EXTENSIONS{ 43constexpr std::array REQUIRED_EXTENSIONS{
37 VK_KHR_MAINTENANCE1_EXTENSION_NAME, 44 VK_KHR_MAINTENANCE1_EXTENSION_NAME,
38 VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME, 45 VK_KHR_STORAGE_BUFFER_STORAGE_CLASS_EXTENSION_NAME,
@@ -43,11 +50,14 @@ constexpr std::array REQUIRED_EXTENSIONS{
43 VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, 50 VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME,
44 VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME, 51 VK_KHR_TIMELINE_SEMAPHORE_EXTENSION_NAME,
45 VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, 52 VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
53 VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
54 VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME,
46 VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, 55 VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME,
47 VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME, 56 VK_EXT_SHADER_SUBGROUP_BALLOT_EXTENSION_NAME,
48 VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME, 57 VK_EXT_SHADER_SUBGROUP_VOTE_EXTENSION_NAME,
49 VK_EXT_ROBUSTNESS_2_EXTENSION_NAME, 58 VK_EXT_ROBUSTNESS_2_EXTENSION_NAME,
50 VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME, 59 VK_EXT_HOST_QUERY_RESET_EXTENSION_NAME,
60 VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME,
51#ifdef _WIN32 61#ifdef _WIN32
52 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, 62 VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME,
53#endif 63#endif
@@ -112,6 +122,7 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica
112 VK_FORMAT_R16G16_SFLOAT, 122 VK_FORMAT_R16G16_SFLOAT,
113 VK_FORMAT_R16G16_SINT, 123 VK_FORMAT_R16G16_SINT,
114 VK_FORMAT_R16_UNORM, 124 VK_FORMAT_R16_UNORM,
125 VK_FORMAT_R16_SNORM,
115 VK_FORMAT_R16_UINT, 126 VK_FORMAT_R16_UINT,
116 VK_FORMAT_R8G8B8A8_SRGB, 127 VK_FORMAT_R8G8B8A8_SRGB,
117 VK_FORMAT_R8G8_UNORM, 128 VK_FORMAT_R8G8_UNORM,
@@ -191,15 +202,47 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica
191 return format_properties; 202 return format_properties;
192} 203}
193 204
205std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
206 const std::vector extensions = physical.EnumerateDeviceExtensionProperties();
207 std::vector<std::string> supported_extensions;
208 supported_extensions.reserve(extensions.size());
209 for (const auto& extension : extensions) {
210 supported_extensions.emplace_back(extension.extensionName);
211 }
212 return supported_extensions;
213}
214
215NvidiaArchitecture GetNvidiaArchitecture(vk::PhysicalDevice physical,
216 std::span<const std::string> exts) {
217 if (std::ranges::find(exts, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME) != exts.end()) {
218 VkPhysicalDeviceFragmentShadingRatePropertiesKHR shading_rate_props{};
219 shading_rate_props.sType =
220 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR;
221 VkPhysicalDeviceProperties2KHR physical_properties{};
222 physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
223 physical_properties.pNext = &shading_rate_props;
224 physical.GetProperties2KHR(physical_properties);
225 if (shading_rate_props.primitiveFragmentShadingRateWithMultipleViewports) {
226 // Only Ampere and newer support this feature
227 return NvidiaArchitecture::AmpereOrNewer;
228 }
229 }
230 if (std::ranges::find(exts, VK_NV_SHADING_RATE_IMAGE_EXTENSION_NAME) != exts.end()) {
231 return NvidiaArchitecture::Turing;
232 }
233 return NvidiaArchitecture::VoltaOrOlder;
234}
194} // Anonymous namespace 235} // Anonymous namespace
195 236
196Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface, 237Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface,
197 const vk::InstanceDispatch& dld_) 238 const vk::InstanceDispatch& dld_)
198 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()}, 239 : instance{instance_}, dld{dld_}, physical{physical_}, properties{physical.GetProperties()},
199 format_properties{GetFormatProperties(physical)} { 240 supported_extensions{GetSupportedExtensions(physical)},
241 format_properties(GetFormatProperties(physical)) {
200 CheckSuitability(surface != nullptr); 242 CheckSuitability(surface != nullptr);
201 SetupFamilies(surface); 243 SetupFamilies(surface);
202 SetupFeatures(); 244 SetupFeatures();
245 SetupProperties();
203 246
204 const auto queue_cis = GetDeviceQueueCreateInfos(); 247 const auto queue_cis = GetDeviceQueueCreateInfos();
205 const std::vector extensions = LoadExtensions(surface != nullptr); 248 const std::vector extensions = LoadExtensions(surface != nullptr);
@@ -214,16 +257,16 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
214 .independentBlend = true, 257 .independentBlend = true,
215 .geometryShader = true, 258 .geometryShader = true,
216 .tessellationShader = true, 259 .tessellationShader = true,
217 .sampleRateShading = false, 260 .sampleRateShading = true,
218 .dualSrcBlend = false, 261 .dualSrcBlend = true,
219 .logicOp = false, 262 .logicOp = false,
220 .multiDrawIndirect = false, 263 .multiDrawIndirect = false,
221 .drawIndirectFirstInstance = false, 264 .drawIndirectFirstInstance = false,
222 .depthClamp = true, 265 .depthClamp = true,
223 .depthBiasClamp = true, 266 .depthBiasClamp = true,
224 .fillModeNonSolid = false, 267 .fillModeNonSolid = true,
225 .depthBounds = false, 268 .depthBounds = is_depth_bounds_supported,
226 .wideLines = false, 269 .wideLines = true,
227 .largePoints = true, 270 .largePoints = true,
228 .alphaToOne = false, 271 .alphaToOne = false,
229 .multiViewport = true, 272 .multiViewport = true,
@@ -245,11 +288,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
245 .shaderSampledImageArrayDynamicIndexing = false, 288 .shaderSampledImageArrayDynamicIndexing = false,
246 .shaderStorageBufferArrayDynamicIndexing = false, 289 .shaderStorageBufferArrayDynamicIndexing = false,
247 .shaderStorageImageArrayDynamicIndexing = false, 290 .shaderStorageImageArrayDynamicIndexing = false,
248 .shaderClipDistance = false, 291 .shaderClipDistance = true,
249 .shaderCullDistance = false, 292 .shaderCullDistance = true,
250 .shaderFloat64 = false, 293 .shaderFloat64 = is_shader_float64_supported,
251 .shaderInt64 = false, 294 .shaderInt64 = is_shader_int64_supported,
252 .shaderInt16 = false, 295 .shaderInt16 = is_shader_int16_supported,
253 .shaderResourceResidency = false, 296 .shaderResourceResidency = false,
254 .shaderResourceMinLod = false, 297 .shaderResourceMinLod = false,
255 .sparseBinding = false, 298 .sparseBinding = false,
@@ -278,7 +321,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
278 VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage{ 321 VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage{
279 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, 322 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
280 .pNext = nullptr, 323 .pNext = nullptr,
281 .storageBuffer16BitAccess = false, 324 .storageBuffer16BitAccess = true,
282 .uniformAndStorageBuffer16BitAccess = true, 325 .uniformAndStorageBuffer16BitAccess = true,
283 .storagePushConstant16 = false, 326 .storagePushConstant16 = false,
284 .storageInputOutput16 = false, 327 .storageInputOutput16 = false,
@@ -310,6 +353,21 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
310 }; 353 };
311 SetNext(next, host_query_reset); 354 SetNext(next, host_query_reset);
312 355
356 VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{
357 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR,
358 .pNext = nullptr,
359 .variablePointersStorageBuffer = VK_TRUE,
360 .variablePointers = VK_TRUE,
361 };
362 SetNext(next, variable_pointers);
363
364 VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote{
365 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT,
366 .pNext = nullptr,
367 .shaderDemoteToHelperInvocation = true,
368 };
369 SetNext(next, demote);
370
313 VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8; 371 VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8;
314 if (is_float16_supported) { 372 if (is_float16_supported) {
315 float16_int8 = { 373 float16_int8 = {
@@ -327,6 +385,14 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
327 LOG_INFO(Render_Vulkan, "Device doesn't support viewport swizzles"); 385 LOG_INFO(Render_Vulkan, "Device doesn't support viewport swizzles");
328 } 386 }
329 387
388 if (!nv_viewport_array2) {
389 LOG_INFO(Render_Vulkan, "Device doesn't support viewport masks");
390 }
391
392 if (!nv_geometry_shader_passthrough) {
393 LOG_INFO(Render_Vulkan, "Device doesn't support passthrough geometry shaders");
394 }
395
330 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; 396 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout;
331 if (khr_uniform_buffer_standard_layout) { 397 if (khr_uniform_buffer_standard_layout) {
332 std430_layout = { 398 std430_layout = {
@@ -389,12 +455,83 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
389 LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state"); 455 LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state");
390 } 456 }
391 457
458 VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster;
459 if (ext_line_rasterization) {
460 line_raster = {
461 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT,
462 .pNext = nullptr,
463 .rectangularLines = VK_TRUE,
464 .bresenhamLines = VK_FALSE,
465 .smoothLines = VK_TRUE,
466 .stippledRectangularLines = VK_FALSE,
467 .stippledBresenhamLines = VK_FALSE,
468 .stippledSmoothLines = VK_FALSE,
469 };
470 SetNext(next, line_raster);
471 } else {
472 LOG_INFO(Render_Vulkan, "Device doesn't support smooth lines");
473 }
474
475 if (!ext_conservative_rasterization) {
476 LOG_INFO(Render_Vulkan, "Device doesn't support conservative rasterization");
477 }
478
479 VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex;
480 if (ext_provoking_vertex) {
481 provoking_vertex = {
482 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT,
483 .pNext = nullptr,
484 .provokingVertexLast = VK_TRUE,
485 .transformFeedbackPreservesProvokingVertex = VK_TRUE,
486 };
487 SetNext(next, provoking_vertex);
488 } else {
489 LOG_INFO(Render_Vulkan, "Device doesn't support provoking vertex last");
490 }
491
492 VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT vertex_input_dynamic;
493 if (ext_vertex_input_dynamic_state) {
494 vertex_input_dynamic = {
495 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT,
496 .pNext = nullptr,
497 .vertexInputDynamicState = VK_TRUE,
498 };
499 SetNext(next, vertex_input_dynamic);
500 } else {
501 LOG_INFO(Render_Vulkan, "Device doesn't support vertex input dynamic state");
502 }
503
504 VkPhysicalDeviceShaderAtomicInt64FeaturesKHR atomic_int64;
505 if (ext_shader_atomic_int64) {
506 atomic_int64 = {
507 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR,
508 .pNext = nullptr,
509 .shaderBufferInt64Atomics = VK_TRUE,
510 .shaderSharedInt64Atomics = VK_TRUE,
511 };
512 SetNext(next, atomic_int64);
513 }
514
515 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR workgroup_layout;
516 if (khr_workgroup_memory_explicit_layout) {
517 workgroup_layout = {
518 .sType =
519 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR,
520 .pNext = nullptr,
521 .workgroupMemoryExplicitLayout = VK_TRUE,
522 .workgroupMemoryExplicitLayoutScalarBlockLayout = VK_TRUE,
523 .workgroupMemoryExplicitLayout8BitAccess = VK_TRUE,
524 .workgroupMemoryExplicitLayout16BitAccess = VK_TRUE,
525 };
526 SetNext(next, workgroup_layout);
527 }
528
392 if (!ext_depth_range_unrestricted) { 529 if (!ext_depth_range_unrestricted) {
393 LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted"); 530 LOG_INFO(Render_Vulkan, "Device doesn't support depth range unrestricted");
394 } 531 }
395 532
396 VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv; 533 VkDeviceDiagnosticsConfigCreateInfoNV diagnostics_nv;
397 if (nv_device_diagnostics_config) { 534 if (Settings::values.enable_nsight_aftermath && nv_device_diagnostics_config) {
398 nsight_aftermath_tracker = std::make_unique<NsightAftermathTracker>(); 535 nsight_aftermath_tracker = std::make_unique<NsightAftermathTracker>();
399 536
400 diagnostics_nv = { 537 diagnostics_nv = {
@@ -412,11 +549,33 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
412 CollectTelemetryParameters(); 549 CollectTelemetryParameters();
413 CollectToolingInfo(); 550 CollectToolingInfo();
414 551
552 if (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) {
553 const auto arch = GetNvidiaArchitecture(physical, supported_extensions);
554 switch (arch) {
555 case NvidiaArchitecture::AmpereOrNewer:
556 LOG_WARNING(Render_Vulkan, "Blacklisting Ampere devices from float16 math");
557 is_float16_supported = false;
558 break;
559 case NvidiaArchitecture::Turing:
560 break;
561 case NvidiaArchitecture::VoltaOrOlder:
562 LOG_WARNING(Render_Vulkan, "Blacklisting Volta and older from VK_KHR_push_descriptor");
563 khr_push_descriptor = false;
564 break;
565 }
566 }
415 if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_MESA_RADV) { 567 if (ext_extended_dynamic_state && driver_id == VK_DRIVER_ID_MESA_RADV) {
416 LOG_WARNING( 568 // Mask driver version variant
417 Render_Vulkan, 569 const u32 version = (properties.driverVersion << 3) >> 3;
418 "Blacklisting RADV for VK_EXT_extended_dynamic state, likely due to a bug in yuzu"); 570 if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) {
419 ext_extended_dynamic_state = false; 571 LOG_WARNING(Render_Vulkan,
572 "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state");
573 ext_extended_dynamic_state = false;
574 }
575 }
576 if (ext_vertex_input_dynamic_state && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
577 LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state");
578 ext_vertex_input_dynamic_state = false;
420 } 579 }
421 if (is_float16_supported && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { 580 if (is_float16_supported && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) {
422 // Intel's compiler crashes when using fp16 on Astral Chain, disable it for the time being. 581 // Intel's compiler crashes when using fp16 on Astral Chain, disable it for the time being.
@@ -426,8 +585,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
426 585
427 graphics_queue = logical.GetQueue(graphics_family); 586 graphics_queue = logical.GetQueue(graphics_family);
428 present_queue = logical.GetQueue(present_family); 587 present_queue = logical.GetQueue(present_family);
429
430 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue();
431} 588}
432 589
433Device::~Device() = default; 590Device::~Device() = default;
@@ -471,7 +628,7 @@ void Device::ReportLoss() const {
471 std::this_thread::sleep_for(std::chrono::seconds{15}); 628 std::this_thread::sleep_for(std::chrono::seconds{15});
472} 629}
473 630
474void Device::SaveShader(const std::vector<u32>& spirv) const { 631void Device::SaveShader(std::span<const u32> spirv) const {
475 if (nsight_aftermath_tracker) { 632 if (nsight_aftermath_tracker) {
476 nsight_aftermath_tracker->SaveShader(spirv); 633 nsight_aftermath_tracker->SaveShader(spirv);
477 } 634 }
@@ -597,10 +754,20 @@ void Device::CheckSuitability(bool requires_swapchain) const {
597 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT); 754 throw vk::Exception(VK_ERROR_FEATURE_NOT_PRESENT);
598 } 755 }
599 } 756 }
757 VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT demote{};
758 demote.sType =
759 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT;
760 demote.pNext = nullptr;
761
762 VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointers{};
763 variable_pointers.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES_KHR;
764 variable_pointers.pNext = &demote;
765
600 VkPhysicalDeviceRobustness2FeaturesEXT robustness2{}; 766 VkPhysicalDeviceRobustness2FeaturesEXT robustness2{};
601 robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT; 767 robustness2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
768 robustness2.pNext = &variable_pointers;
602 769
603 VkPhysicalDeviceFeatures2 features2{}; 770 VkPhysicalDeviceFeatures2KHR features2{};
604 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 771 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
605 features2.pNext = &robustness2; 772 features2.pNext = &robustness2;
606 773
@@ -610,7 +777,6 @@ void Device::CheckSuitability(bool requires_swapchain) const {
610 const std::array feature_report{ 777 const std::array feature_report{
611 std::make_pair(features.robustBufferAccess, "robustBufferAccess"), 778 std::make_pair(features.robustBufferAccess, "robustBufferAccess"),
612 std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"), 779 std::make_pair(features.vertexPipelineStoresAndAtomics, "vertexPipelineStoresAndAtomics"),
613 std::make_pair(features.robustBufferAccess, "robustBufferAccess"),
614 std::make_pair(features.imageCubeArray, "imageCubeArray"), 780 std::make_pair(features.imageCubeArray, "imageCubeArray"),
615 std::make_pair(features.independentBlend, "independentBlend"), 781 std::make_pair(features.independentBlend, "independentBlend"),
616 std::make_pair(features.depthClamp, "depthClamp"), 782 std::make_pair(features.depthClamp, "depthClamp"),
@@ -618,13 +784,23 @@ void Device::CheckSuitability(bool requires_swapchain) const {
618 std::make_pair(features.largePoints, "largePoints"), 784 std::make_pair(features.largePoints, "largePoints"),
619 std::make_pair(features.multiViewport, "multiViewport"), 785 std::make_pair(features.multiViewport, "multiViewport"),
620 std::make_pair(features.depthBiasClamp, "depthBiasClamp"), 786 std::make_pair(features.depthBiasClamp, "depthBiasClamp"),
787 std::make_pair(features.fillModeNonSolid, "fillModeNonSolid"),
788 std::make_pair(features.wideLines, "wideLines"),
621 std::make_pair(features.geometryShader, "geometryShader"), 789 std::make_pair(features.geometryShader, "geometryShader"),
622 std::make_pair(features.tessellationShader, "tessellationShader"), 790 std::make_pair(features.tessellationShader, "tessellationShader"),
791 std::make_pair(features.sampleRateShading, "sampleRateShading"),
792 std::make_pair(features.dualSrcBlend, "dualSrcBlend"),
623 std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"), 793 std::make_pair(features.occlusionQueryPrecise, "occlusionQueryPrecise"),
624 std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"), 794 std::make_pair(features.fragmentStoresAndAtomics, "fragmentStoresAndAtomics"),
625 std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"), 795 std::make_pair(features.shaderImageGatherExtended, "shaderImageGatherExtended"),
626 std::make_pair(features.shaderStorageImageWriteWithoutFormat, 796 std::make_pair(features.shaderStorageImageWriteWithoutFormat,
627 "shaderStorageImageWriteWithoutFormat"), 797 "shaderStorageImageWriteWithoutFormat"),
798 std::make_pair(features.shaderClipDistance, "shaderClipDistance"),
799 std::make_pair(features.shaderCullDistance, "shaderCullDistance"),
800 std::make_pair(demote.shaderDemoteToHelperInvocation, "shaderDemoteToHelperInvocation"),
801 std::make_pair(variable_pointers.variablePointers, "variablePointers"),
802 std::make_pair(variable_pointers.variablePointersStorageBuffer,
803 "variablePointersStorageBuffer"),
628 std::make_pair(robustness2.robustBufferAccess2, "robustBufferAccess2"), 804 std::make_pair(robustness2.robustBufferAccess2, "robustBufferAccess2"),
629 std::make_pair(robustness2.robustImageAccess2, "robustImageAccess2"), 805 std::make_pair(robustness2.robustImageAccess2, "robustImageAccess2"),
630 std::make_pair(robustness2.nullDescriptor, "nullDescriptor"), 806 std::make_pair(robustness2.nullDescriptor, "nullDescriptor"),
@@ -647,14 +823,19 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
647 } 823 }
648 824
649 bool has_khr_shader_float16_int8{}; 825 bool has_khr_shader_float16_int8{};
826 bool has_khr_workgroup_memory_explicit_layout{};
650 bool has_ext_subgroup_size_control{}; 827 bool has_ext_subgroup_size_control{};
651 bool has_ext_transform_feedback{}; 828 bool has_ext_transform_feedback{};
652 bool has_ext_custom_border_color{}; 829 bool has_ext_custom_border_color{};
653 bool has_ext_extended_dynamic_state{}; 830 bool has_ext_extended_dynamic_state{};
654 for (const VkExtensionProperties& extension : physical.EnumerateDeviceExtensionProperties()) { 831 bool has_ext_shader_atomic_int64{};
832 bool has_ext_provoking_vertex{};
833 bool has_ext_vertex_input_dynamic_state{};
834 bool has_ext_line_rasterization{};
835 for (const std::string& extension : supported_extensions) {
655 const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name, 836 const auto test = [&](std::optional<std::reference_wrapper<bool>> status, const char* name,
656 bool push) { 837 bool push) {
657 if (extension.extensionName != std::string_view(name)) { 838 if (extension != name) {
658 return; 839 return;
659 } 840 }
660 if (push) { 841 if (push) {
@@ -665,8 +846,13 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
665 } 846 }
666 }; 847 };
667 test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true); 848 test(nv_viewport_swizzle, VK_NV_VIEWPORT_SWIZZLE_EXTENSION_NAME, true);
849 test(nv_viewport_array2, VK_NV_VIEWPORT_ARRAY2_EXTENSION_NAME, true);
850 test(nv_geometry_shader_passthrough, VK_NV_GEOMETRY_SHADER_PASSTHROUGH_EXTENSION_NAME,
851 true);
668 test(khr_uniform_buffer_standard_layout, 852 test(khr_uniform_buffer_standard_layout,
669 VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true); 853 VK_KHR_UNIFORM_BUFFER_STANDARD_LAYOUT_EXTENSION_NAME, true);
854 test(khr_spirv_1_4, VK_KHR_SPIRV_1_4_EXTENSION_NAME, true);
855 test(khr_push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, true);
670 test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false); 856 test(has_khr_shader_float16_int8, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME, false);
671 test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true); 857 test(ext_depth_range_unrestricted, VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME, true);
672 test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true); 858 test(ext_index_type_uint8, VK_EXT_INDEX_TYPE_UINT8_EXTENSION_NAME, true);
@@ -675,16 +861,25 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
675 true); 861 true);
676 test(ext_tooling_info, VK_EXT_TOOLING_INFO_EXTENSION_NAME, true); 862 test(ext_tooling_info, VK_EXT_TOOLING_INFO_EXTENSION_NAME, true);
677 test(ext_shader_stencil_export, VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, true); 863 test(ext_shader_stencil_export, VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME, true);
864 test(ext_conservative_rasterization, VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME,
865 true);
678 test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false); 866 test(has_ext_transform_feedback, VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME, false);
679 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false); 867 test(has_ext_custom_border_color, VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME, false);
680 test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false); 868 test(has_ext_extended_dynamic_state, VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME, false);
681 test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false); 869 test(has_ext_subgroup_size_control, VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME, false);
682 if (Settings::values.renderer_debug) { 870 test(has_ext_provoking_vertex, VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME, false);
871 test(has_ext_vertex_input_dynamic_state, VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME,
872 false);
873 test(has_ext_shader_atomic_int64, VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME, false);
874 test(has_khr_workgroup_memory_explicit_layout,
875 VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME, false);
876 test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false);
877 if (Settings::values.enable_nsight_aftermath) {
683 test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, 878 test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME,
684 true); 879 true);
685 } 880 }
686 } 881 }
687 VkPhysicalDeviceFeatures2KHR features; 882 VkPhysicalDeviceFeatures2KHR features{};
688 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 883 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR;
689 884
690 VkPhysicalDeviceProperties2KHR physical_properties; 885 VkPhysicalDeviceProperties2KHR physical_properties;
@@ -722,10 +917,49 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
722 subgroup_properties.maxSubgroupSize >= GuestWarpSize) { 917 subgroup_properties.maxSubgroupSize >= GuestWarpSize) {
723 extensions.push_back(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); 918 extensions.push_back(VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME);
724 guest_warp_stages = subgroup_properties.requiredSubgroupSizeStages; 919 guest_warp_stages = subgroup_properties.requiredSubgroupSizeStages;
920 ext_subgroup_size_control = true;
725 } 921 }
726 } else { 922 } else {
727 is_warp_potentially_bigger = true; 923 is_warp_potentially_bigger = true;
728 } 924 }
925 if (has_ext_provoking_vertex) {
926 VkPhysicalDeviceProvokingVertexFeaturesEXT provoking_vertex;
927 provoking_vertex.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_FEATURES_EXT;
928 provoking_vertex.pNext = nullptr;
929 features.pNext = &provoking_vertex;
930 physical.GetFeatures2KHR(features);
931
932 if (provoking_vertex.provokingVertexLast &&
933 provoking_vertex.transformFeedbackPreservesProvokingVertex) {
934 extensions.push_back(VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME);
935 ext_provoking_vertex = true;
936 }
937 }
938 if (has_ext_vertex_input_dynamic_state) {
939 VkPhysicalDeviceVertexInputDynamicStateFeaturesEXT vertex_input;
940 vertex_input.sType =
941 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_INPUT_DYNAMIC_STATE_FEATURES_EXT;
942 vertex_input.pNext = nullptr;
943 features.pNext = &vertex_input;
944 physical.GetFeatures2KHR(features);
945
946 if (vertex_input.vertexInputDynamicState) {
947 extensions.push_back(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME);
948 ext_vertex_input_dynamic_state = true;
949 }
950 }
951 if (has_ext_shader_atomic_int64) {
952 VkPhysicalDeviceShaderAtomicInt64Features atomic_int64;
953 atomic_int64.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;
954 atomic_int64.pNext = nullptr;
955 features.pNext = &atomic_int64;
956 physical.GetFeatures2KHR(features);
957
958 if (atomic_int64.shaderBufferInt64Atomics && atomic_int64.shaderSharedInt64Atomics) {
959 extensions.push_back(VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME);
960 ext_shader_atomic_int64 = true;
961 }
962 }
729 if (has_ext_transform_feedback) { 963 if (has_ext_transform_feedback) {
730 VkPhysicalDeviceTransformFeedbackFeaturesEXT tfb_features; 964 VkPhysicalDeviceTransformFeedbackFeaturesEXT tfb_features;
731 tfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; 965 tfb_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT;
@@ -760,17 +994,55 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) {
760 } 994 }
761 } 995 }
762 if (has_ext_extended_dynamic_state) { 996 if (has_ext_extended_dynamic_state) {
763 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state; 997 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT extended_dynamic_state;
764 dynamic_state.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; 998 extended_dynamic_state.sType =
765 dynamic_state.pNext = nullptr; 999 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT;
766 features.pNext = &dynamic_state; 1000 extended_dynamic_state.pNext = nullptr;
1001 features.pNext = &extended_dynamic_state;
767 physical.GetFeatures2KHR(features); 1002 physical.GetFeatures2KHR(features);
768 1003
769 if (dynamic_state.extendedDynamicState) { 1004 if (extended_dynamic_state.extendedDynamicState) {
770 extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); 1005 extensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
771 ext_extended_dynamic_state = true; 1006 ext_extended_dynamic_state = true;
772 } 1007 }
773 } 1008 }
1009 if (has_ext_line_rasterization) {
1010 VkPhysicalDeviceLineRasterizationFeaturesEXT line_raster;
1011 line_raster.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT;
1012 line_raster.pNext = nullptr;
1013 features.pNext = &line_raster;
1014 physical.GetFeatures2KHR(features);
1015 if (line_raster.rectangularLines && line_raster.smoothLines) {
1016 extensions.push_back(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME);
1017 ext_line_rasterization = true;
1018 }
1019 }
1020 if (has_khr_workgroup_memory_explicit_layout) {
1021 VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR layout;
1022 layout.sType =
1023 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR;
1024 layout.pNext = nullptr;
1025 features.pNext = &layout;
1026 physical.GetFeatures2KHR(features);
1027
1028 if (layout.workgroupMemoryExplicitLayout &&
1029 layout.workgroupMemoryExplicitLayout8BitAccess &&
1030 layout.workgroupMemoryExplicitLayout16BitAccess &&
1031 layout.workgroupMemoryExplicitLayoutScalarBlockLayout) {
1032 extensions.push_back(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME);
1033 khr_workgroup_memory_explicit_layout = true;
1034 }
1035 }
1036 if (khr_push_descriptor) {
1037 VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor;
1038 push_descriptor.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR;
1039 push_descriptor.pNext = nullptr;
1040
1041 physical_properties.pNext = &push_descriptor;
1042 physical.GetProperties2KHR(physical_properties);
1043
1044 max_push_descriptors = push_descriptor.maxPushDescriptors;
1045 }
774 return extensions; 1046 return extensions;
775} 1047}
776 1048
@@ -806,11 +1078,25 @@ void Device::SetupFamilies(VkSurfaceKHR surface) {
806} 1078}
807 1079
808void Device::SetupFeatures() { 1080void Device::SetupFeatures() {
809 const auto supported_features{physical.GetFeatures()}; 1081 const VkPhysicalDeviceFeatures features{physical.GetFeatures()};
810 is_formatless_image_load_supported = supported_features.shaderStorageImageReadWithoutFormat; 1082 is_depth_bounds_supported = features.depthBounds;
811 is_shader_storage_image_multisample = supported_features.shaderStorageImageMultisample; 1083 is_formatless_image_load_supported = features.shaderStorageImageReadWithoutFormat;
1084 is_shader_float64_supported = features.shaderFloat64;
1085 is_shader_int64_supported = features.shaderInt64;
1086 is_shader_int16_supported = features.shaderInt16;
1087 is_shader_storage_image_multisample = features.shaderStorageImageMultisample;
812 is_blit_depth_stencil_supported = TestDepthStencilBlits(); 1088 is_blit_depth_stencil_supported = TestDepthStencilBlits();
813 is_optimal_astc_supported = IsOptimalAstcSupported(supported_features); 1089 is_optimal_astc_supported = IsOptimalAstcSupported(features);
1090}
1091
1092void Device::SetupProperties() {
1093 float_controls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
1094
1095 VkPhysicalDeviceProperties2KHR properties2{};
1096 properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR;
1097 properties2.pNext = &float_controls;
1098
1099 physical.GetProperties2KHR(properties2);
814} 1100}
815 1101
816void Device::CollectTelemetryParameters() { 1102void Device::CollectTelemetryParameters() {
@@ -832,12 +1118,6 @@ void Device::CollectTelemetryParameters() {
832 1118
833 driver_id = driver.driverID; 1119 driver_id = driver.driverID;
834 vendor_name = driver.driverName; 1120 vendor_name = driver.driverName;
835
836 const std::vector extensions = physical.EnumerateDeviceExtensionProperties();
837 reported_extensions.reserve(std::size(extensions));
838 for (const auto& extension : extensions) {
839 reported_extensions.emplace_back(extension.extensionName);
840 }
841} 1121}
842 1122
843void Device::CollectPhysicalMemoryInfo() { 1123void Device::CollectPhysicalMemoryInfo() {
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index 96c0f8c60..df394e384 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <span>
7#include <string> 8#include <string>
8#include <string_view> 9#include <string_view>
9#include <unordered_map> 10#include <unordered_map>
@@ -43,7 +44,7 @@ public:
43 void ReportLoss() const; 44 void ReportLoss() const;
44 45
45 /// Reports a shader to Nsight Aftermath. 46 /// Reports a shader to Nsight Aftermath.
46 void SaveShader(const std::vector<u32>& spirv) const; 47 void SaveShader(std::span<const u32> spirv) const;
47 48
48 /// Returns the name of the VkDriverId reported from Vulkan. 49 /// Returns the name of the VkDriverId reported from Vulkan.
49 std::string GetDriverName() const; 50 std::string GetDriverName() const;
@@ -128,6 +129,11 @@ public:
128 return properties.limits.maxComputeSharedMemorySize; 129 return properties.limits.maxComputeSharedMemorySize;
129 } 130 }
130 131
132 /// Returns float control properties of the device.
133 const VkPhysicalDeviceFloatControlsPropertiesKHR& FloatControlProperties() const {
134 return float_controls;
135 }
136
131 /// Returns true if ASTC is natively supported. 137 /// Returns true if ASTC is natively supported.
132 bool IsOptimalAstcSupported() const { 138 bool IsOptimalAstcSupported() const {
133 return is_optimal_astc_supported; 139 return is_optimal_astc_supported;
@@ -148,11 +154,31 @@ public:
148 return guest_warp_stages & stage; 154 return guest_warp_stages & stage;
149 } 155 }
150 156
157 /// Returns the maximum number of push descriptors.
158 u32 MaxPushDescriptors() const {
159 return max_push_descriptors;
160 }
161
151 /// Returns true if formatless image load is supported. 162 /// Returns true if formatless image load is supported.
152 bool IsFormatlessImageLoadSupported() const { 163 bool IsFormatlessImageLoadSupported() const {
153 return is_formatless_image_load_supported; 164 return is_formatless_image_load_supported;
154 } 165 }
155 166
167 /// Returns true if shader int64 is supported.
168 bool IsShaderInt64Supported() const {
169 return is_shader_int64_supported;
170 }
171
172 /// Returns true if shader int16 is supported.
173 bool IsShaderInt16Supported() const {
174 return is_shader_int16_supported;
175 }
176
177 // Returns true if depth bounds is supported.
178 bool IsDepthBoundsSupported() const {
179 return is_depth_bounds_supported;
180 }
181
156 /// Returns true when blitting from and to depth stencil images is supported. 182 /// Returns true when blitting from and to depth stencil images is supported.
157 bool IsBlitDepthStencilSupported() const { 183 bool IsBlitDepthStencilSupported() const {
158 return is_blit_depth_stencil_supported; 184 return is_blit_depth_stencil_supported;
@@ -163,11 +189,36 @@ public:
163 return nv_viewport_swizzle; 189 return nv_viewport_swizzle;
164 } 190 }
165 191
166 /// Returns true if the device supports VK_EXT_scalar_block_layout. 192 /// Returns true if the device supports VK_NV_viewport_array2.
193 bool IsNvViewportArray2Supported() const {
194 return nv_viewport_array2;
195 }
196
197 /// Returns true if the device supports VK_NV_geometry_shader_passthrough.
198 bool IsNvGeometryShaderPassthroughSupported() const {
199 return nv_geometry_shader_passthrough;
200 }
201
202 /// Returns true if the device supports VK_KHR_uniform_buffer_standard_layout.
167 bool IsKhrUniformBufferStandardLayoutSupported() const { 203 bool IsKhrUniformBufferStandardLayoutSupported() const {
168 return khr_uniform_buffer_standard_layout; 204 return khr_uniform_buffer_standard_layout;
169 } 205 }
170 206
207 /// Returns true if the device supports VK_KHR_spirv_1_4.
208 bool IsKhrSpirv1_4Supported() const {
209 return khr_spirv_1_4;
210 }
211
212 /// Returns true if the device supports VK_KHR_push_descriptor.
213 bool IsKhrPushDescriptorSupported() const {
214 return khr_push_descriptor;
215 }
216
217 /// Returns true if the device supports VK_KHR_workgroup_memory_explicit_layout.
218 bool IsKhrWorkgroupMemoryExplicitLayoutSupported() const {
219 return khr_workgroup_memory_explicit_layout;
220 }
221
171 /// Returns true if the device supports VK_EXT_index_type_uint8. 222 /// Returns true if the device supports VK_EXT_index_type_uint8.
172 bool IsExtIndexTypeUint8Supported() const { 223 bool IsExtIndexTypeUint8Supported() const {
173 return ext_index_type_uint8; 224 return ext_index_type_uint8;
@@ -188,6 +239,11 @@ public:
188 return ext_shader_viewport_index_layer; 239 return ext_shader_viewport_index_layer;
189 } 240 }
190 241
242 /// Returns true if the device supports VK_EXT_subgroup_size_control.
243 bool IsExtSubgroupSizeControlSupported() const {
244 return ext_subgroup_size_control;
245 }
246
191 /// Returns true if the device supports VK_EXT_transform_feedback. 247 /// Returns true if the device supports VK_EXT_transform_feedback.
192 bool IsExtTransformFeedbackSupported() const { 248 bool IsExtTransformFeedbackSupported() const {
193 return ext_transform_feedback; 249 return ext_transform_feedback;
@@ -203,11 +259,36 @@ public:
203 return ext_extended_dynamic_state; 259 return ext_extended_dynamic_state;
204 } 260 }
205 261
262 /// Returns true if the device supports VK_EXT_line_rasterization.
263 bool IsExtLineRasterizationSupported() const {
264 return ext_line_rasterization;
265 }
266
267 /// Returns true if the device supports VK_EXT_vertex_input_dynamic_state.
268 bool IsExtVertexInputDynamicStateSupported() const {
269 return ext_vertex_input_dynamic_state;
270 }
271
206 /// Returns true if the device supports VK_EXT_shader_stencil_export. 272 /// Returns true if the device supports VK_EXT_shader_stencil_export.
207 bool IsExtShaderStencilExportSupported() const { 273 bool IsExtShaderStencilExportSupported() const {
208 return ext_shader_stencil_export; 274 return ext_shader_stencil_export;
209 } 275 }
210 276
277 /// Returns true if the device supports VK_EXT_conservative_rasterization.
278 bool IsExtConservativeRasterizationSupported() const {
279 return ext_conservative_rasterization;
280 }
281
282 /// Returns true if the device supports VK_EXT_provoking_vertex.
283 bool IsExtProvokingVertexSupported() const {
284 return ext_provoking_vertex;
285 }
286
287 /// Returns true if the device supports VK_KHR_shader_atomic_int64.
288 bool IsExtShaderAtomicInt64Supported() const {
289 return ext_shader_atomic_int64;
290 }
291
211 /// Returns true when a known debugging tool is attached. 292 /// Returns true when a known debugging tool is attached.
212 bool HasDebuggingToolAttached() const { 293 bool HasDebuggingToolAttached() const {
213 return has_renderdoc || has_nsight_graphics; 294 return has_renderdoc || has_nsight_graphics;
@@ -220,12 +301,7 @@ public:
220 301
221 /// Returns the list of available extensions. 302 /// Returns the list of available extensions.
222 const std::vector<std::string>& GetAvailableExtensions() const { 303 const std::vector<std::string>& GetAvailableExtensions() const {
223 return reported_extensions; 304 return supported_extensions;
224 }
225
226 /// Returns true if the setting for async shader compilation is enabled.
227 bool UseAsynchronousShaders() const {
228 return use_asynchronous_shaders;
229 } 305 }
230 306
231 u64 GetDeviceLocalMemory() const { 307 u64 GetDeviceLocalMemory() const {
@@ -245,6 +321,9 @@ private:
245 /// Sets up device features. 321 /// Sets up device features.
246 void SetupFeatures(); 322 void SetupFeatures();
247 323
324 /// Sets up device properties.
325 void SetupProperties();
326
248 /// Collects telemetry information from the device. 327 /// Collects telemetry information from the device.
249 void CollectTelemetryParameters(); 328 void CollectTelemetryParameters();
250 329
@@ -267,46 +346,60 @@ private:
267 bool IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage, 346 bool IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
268 FormatType format_type) const; 347 FormatType format_type) const;
269 348
270 VkInstance instance; ///< Vulkan instance. 349 VkInstance instance; ///< Vulkan instance.
271 vk::DeviceDispatch dld; ///< Device function pointers. 350 vk::DeviceDispatch dld; ///< Device function pointers.
272 vk::PhysicalDevice physical; ///< Physical device. 351 vk::PhysicalDevice physical; ///< Physical device.
273 VkPhysicalDeviceProperties properties; ///< Device properties. 352 VkPhysicalDeviceProperties properties; ///< Device properties.
274 vk::Device logical; ///< Logical device. 353 VkPhysicalDeviceFloatControlsPropertiesKHR float_controls{}; ///< Float control properties.
275 vk::Queue graphics_queue; ///< Main graphics queue. 354 vk::Device logical; ///< Logical device.
276 vk::Queue present_queue; ///< Main present queue. 355 vk::Queue graphics_queue; ///< Main graphics queue.
277 u32 instance_version{}; ///< Vulkan onstance version. 356 vk::Queue present_queue; ///< Main present queue.
357 u32 instance_version{}; ///< Vulkan onstance version.
278 u32 graphics_family{}; ///< Main graphics queue family index. 358 u32 graphics_family{}; ///< Main graphics queue family index.
279 u32 present_family{}; ///< Main present queue family index. 359 u32 present_family{}; ///< Main present queue family index.
280 VkDriverIdKHR driver_id{}; ///< Driver ID. 360 VkDriverIdKHR driver_id{}; ///< Driver ID.
281 VkShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced. 361 VkShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced.
282 u64 device_access_memory{}; ///< Total size of device local memory in bytes. 362 u64 device_access_memory{}; ///< Total size of device local memory in bytes.
363 u32 max_push_descriptors{}; ///< Maximum number of push descriptors
283 bool is_optimal_astc_supported{}; ///< Support for native ASTC. 364 bool is_optimal_astc_supported{}; ///< Support for native ASTC.
284 bool is_float16_supported{}; ///< Support for float16 arithmetics. 365 bool is_float16_supported{}; ///< Support for float16 arithmetics.
285 bool is_warp_potentially_bigger{}; ///< Host warp size can be bigger than guest. 366 bool is_warp_potentially_bigger{}; ///< Host warp size can be bigger than guest.
286 bool is_formatless_image_load_supported{}; ///< Support for shader image read without format. 367 bool is_formatless_image_load_supported{}; ///< Support for shader image read without format.
368 bool is_depth_bounds_supported{}; ///< Support for depth bounds.
369 bool is_shader_float64_supported{}; ///< Support for float64.
370 bool is_shader_int64_supported{}; ///< Support for int64.
371 bool is_shader_int16_supported{}; ///< Support for int16.
287 bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images. 372 bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images.
288 bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil. 373 bool is_blit_depth_stencil_supported{}; ///< Support for blitting from and to depth stencil.
289 bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. 374 bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle.
290 bool khr_uniform_buffer_standard_layout{}; ///< Support for std430 on UBOs. 375 bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2.
291 bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8. 376 bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough.
292 bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax. 377 bool khr_uniform_buffer_standard_layout{}; ///< Support for scalar uniform buffer layouts.
293 bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted. 378 bool khr_spirv_1_4{}; ///< Support for VK_KHR_spirv_1_4.
294 bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer. 379 bool khr_workgroup_memory_explicit_layout{}; ///< Support for explicit workgroup layouts.
295 bool ext_tooling_info{}; ///< Support for VK_EXT_tooling_info. 380 bool khr_push_descriptor{}; ///< Support for VK_KHR_push_descritor.
296 bool ext_transform_feedback{}; ///< Support for VK_EXT_transform_feedback. 381 bool ext_index_type_uint8{}; ///< Support for VK_EXT_index_type_uint8.
297 bool ext_custom_border_color{}; ///< Support for VK_EXT_custom_border_color. 382 bool ext_sampler_filter_minmax{}; ///< Support for VK_EXT_sampler_filter_minmax.
298 bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state. 383 bool ext_depth_range_unrestricted{}; ///< Support for VK_EXT_depth_range_unrestricted.
299 bool ext_shader_stencil_export{}; ///< Support for VK_EXT_shader_stencil_export. 384 bool ext_shader_viewport_index_layer{}; ///< Support for VK_EXT_shader_viewport_index_layer.
300 bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. 385 bool ext_tooling_info{}; ///< Support for VK_EXT_tooling_info.
301 bool has_renderdoc{}; ///< Has RenderDoc attached 386 bool ext_subgroup_size_control{}; ///< Support for VK_EXT_subgroup_size_control.
302 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached 387 bool ext_transform_feedback{}; ///< Support for VK_EXT_transform_feedback.
303 388 bool ext_custom_border_color{}; ///< Support for VK_EXT_custom_border_color.
304 // Asynchronous Graphics Pipeline setting 389 bool ext_extended_dynamic_state{}; ///< Support for VK_EXT_extended_dynamic_state.
305 bool use_asynchronous_shaders{}; ///< Setting to use asynchronous shaders/graphics pipeline 390 bool ext_line_rasterization{}; ///< Support for VK_EXT_line_rasterization.
391 bool ext_vertex_input_dynamic_state{}; ///< Support for VK_EXT_vertex_input_dynamic_state.
392 bool ext_shader_stencil_export{}; ///< Support for VK_EXT_shader_stencil_export.
393 bool ext_shader_atomic_int64{}; ///< Support for VK_KHR_shader_atomic_int64.
394 bool ext_conservative_rasterization{}; ///< Support for VK_EXT_conservative_rasterization.
395 bool ext_provoking_vertex{}; ///< Support for VK_EXT_provoking_vertex.
396 bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config.
397 bool has_renderdoc{}; ///< Has RenderDoc attached
398 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
306 399
307 // Telemetry parameters 400 // Telemetry parameters
308 std::string vendor_name; ///< Device's driver name. 401 std::string vendor_name; ///< Device's driver name.
309 std::vector<std::string> reported_extensions; ///< Reported Vulkan extensions. 402 std::vector<std::string> supported_extensions; ///< Reported Vulkan extensions.
310 403
311 /// Format properties dictionary. 404 /// Format properties dictionary.
312 std::unordered_map<VkFormat, VkFormatProperties> format_properties; 405 std::unordered_map<VkFormat, VkFormatProperties> format_properties;
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index 2aa0ffbe6..bbf0fccae 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -103,6 +103,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
103 X(vkCmdFillBuffer); 103 X(vkCmdFillBuffer);
104 X(vkCmdPipelineBarrier); 104 X(vkCmdPipelineBarrier);
105 X(vkCmdPushConstants); 105 X(vkCmdPushConstants);
106 X(vkCmdPushDescriptorSetWithTemplateKHR);
106 X(vkCmdSetBlendConstants); 107 X(vkCmdSetBlendConstants);
107 X(vkCmdSetDepthBias); 108 X(vkCmdSetDepthBias);
108 X(vkCmdSetDepthBounds); 109 X(vkCmdSetDepthBounds);
@@ -120,9 +121,11 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept {
120 X(vkCmdSetDepthTestEnableEXT); 121 X(vkCmdSetDepthTestEnableEXT);
121 X(vkCmdSetDepthWriteEnableEXT); 122 X(vkCmdSetDepthWriteEnableEXT);
122 X(vkCmdSetFrontFaceEXT); 123 X(vkCmdSetFrontFaceEXT);
124 X(vkCmdSetLineWidth);
123 X(vkCmdSetPrimitiveTopologyEXT); 125 X(vkCmdSetPrimitiveTopologyEXT);
124 X(vkCmdSetStencilOpEXT); 126 X(vkCmdSetStencilOpEXT);
125 X(vkCmdSetStencilTestEnableEXT); 127 X(vkCmdSetStencilTestEnableEXT);
128 X(vkCmdSetVertexInputEXT);
126 X(vkCmdResolveImage); 129 X(vkCmdResolveImage);
127 X(vkCreateBuffer); 130 X(vkCreateBuffer);
128 X(vkCreateBufferView); 131 X(vkCreateBufferView);
@@ -311,8 +314,6 @@ const char* ToString(VkResult result) noexcept {
311 return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT"; 314 return "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT";
312 case VkResult::VK_ERROR_UNKNOWN: 315 case VkResult::VK_ERROR_UNKNOWN:
313 return "VK_ERROR_UNKNOWN"; 316 return "VK_ERROR_UNKNOWN";
314 case VkResult::VK_ERROR_INCOMPATIBLE_VERSION_KHR:
315 return "VK_ERROR_INCOMPATIBLE_VERSION_KHR";
316 case VkResult::VK_THREAD_IDLE_KHR: 317 case VkResult::VK_THREAD_IDLE_KHR:
317 return "VK_THREAD_IDLE_KHR"; 318 return "VK_THREAD_IDLE_KHR";
318 case VkResult::VK_THREAD_DONE_KHR: 319 case VkResult::VK_THREAD_DONE_KHR:
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 3e36d356a..d76bb4324 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -193,15 +193,16 @@ struct DeviceDispatch : InstanceDispatch {
193 PFN_vkBeginCommandBuffer vkBeginCommandBuffer{}; 193 PFN_vkBeginCommandBuffer vkBeginCommandBuffer{};
194 PFN_vkBindBufferMemory vkBindBufferMemory{}; 194 PFN_vkBindBufferMemory vkBindBufferMemory{};
195 PFN_vkBindImageMemory vkBindImageMemory{}; 195 PFN_vkBindImageMemory vkBindImageMemory{};
196 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT{};
196 PFN_vkCmdBeginQuery vkCmdBeginQuery{}; 197 PFN_vkCmdBeginQuery vkCmdBeginQuery{};
197 PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass{}; 198 PFN_vkCmdBeginRenderPass vkCmdBeginRenderPass{};
198 PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT{}; 199 PFN_vkCmdBeginTransformFeedbackEXT vkCmdBeginTransformFeedbackEXT{};
199 PFN_vkCmdBeginDebugUtilsLabelEXT vkCmdBeginDebugUtilsLabelEXT{};
200 PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets{}; 200 PFN_vkCmdBindDescriptorSets vkCmdBindDescriptorSets{};
201 PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer{}; 201 PFN_vkCmdBindIndexBuffer vkCmdBindIndexBuffer{};
202 PFN_vkCmdBindPipeline vkCmdBindPipeline{}; 202 PFN_vkCmdBindPipeline vkCmdBindPipeline{};
203 PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT{}; 203 PFN_vkCmdBindTransformFeedbackBuffersEXT vkCmdBindTransformFeedbackBuffersEXT{};
204 PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers{}; 204 PFN_vkCmdBindVertexBuffers vkCmdBindVertexBuffers{};
205 PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT{};
205 PFN_vkCmdBlitImage vkCmdBlitImage{}; 206 PFN_vkCmdBlitImage vkCmdBlitImage{};
206 PFN_vkCmdClearAttachments vkCmdClearAttachments{}; 207 PFN_vkCmdClearAttachments vkCmdClearAttachments{};
207 PFN_vkCmdCopyBuffer vkCmdCopyBuffer{}; 208 PFN_vkCmdCopyBuffer vkCmdCopyBuffer{};
@@ -211,34 +212,36 @@ struct DeviceDispatch : InstanceDispatch {
211 PFN_vkCmdDispatch vkCmdDispatch{}; 212 PFN_vkCmdDispatch vkCmdDispatch{};
212 PFN_vkCmdDraw vkCmdDraw{}; 213 PFN_vkCmdDraw vkCmdDraw{};
213 PFN_vkCmdDrawIndexed vkCmdDrawIndexed{}; 214 PFN_vkCmdDrawIndexed vkCmdDrawIndexed{};
215 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
214 PFN_vkCmdEndQuery vkCmdEndQuery{}; 216 PFN_vkCmdEndQuery vkCmdEndQuery{};
215 PFN_vkCmdEndRenderPass vkCmdEndRenderPass{}; 217 PFN_vkCmdEndRenderPass vkCmdEndRenderPass{};
216 PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{}; 218 PFN_vkCmdEndTransformFeedbackEXT vkCmdEndTransformFeedbackEXT{};
217 PFN_vkCmdEndDebugUtilsLabelEXT vkCmdEndDebugUtilsLabelEXT{};
218 PFN_vkCmdFillBuffer vkCmdFillBuffer{}; 219 PFN_vkCmdFillBuffer vkCmdFillBuffer{};
219 PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{}; 220 PFN_vkCmdPipelineBarrier vkCmdPipelineBarrier{};
220 PFN_vkCmdPushConstants vkCmdPushConstants{}; 221 PFN_vkCmdPushConstants vkCmdPushConstants{};
222 PFN_vkCmdPushDescriptorSetWithTemplateKHR vkCmdPushDescriptorSetWithTemplateKHR{};
223 PFN_vkCmdResolveImage vkCmdResolveImage{};
221 PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants{}; 224 PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants{};
225 PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT{};
222 PFN_vkCmdSetDepthBias vkCmdSetDepthBias{}; 226 PFN_vkCmdSetDepthBias vkCmdSetDepthBias{};
223 PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds{}; 227 PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds{};
224 PFN_vkCmdSetEvent vkCmdSetEvent{};
225 PFN_vkCmdSetScissor vkCmdSetScissor{};
226 PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask{};
227 PFN_vkCmdSetStencilReference vkCmdSetStencilReference{};
228 PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask{};
229 PFN_vkCmdSetViewport vkCmdSetViewport{};
230 PFN_vkCmdWaitEvents vkCmdWaitEvents{};
231 PFN_vkCmdBindVertexBuffers2EXT vkCmdBindVertexBuffers2EXT{};
232 PFN_vkCmdSetCullModeEXT vkCmdSetCullModeEXT{};
233 PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT{}; 228 PFN_vkCmdSetDepthBoundsTestEnableEXT vkCmdSetDepthBoundsTestEnableEXT{};
234 PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT{}; 229 PFN_vkCmdSetDepthCompareOpEXT vkCmdSetDepthCompareOpEXT{};
235 PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT{}; 230 PFN_vkCmdSetDepthTestEnableEXT vkCmdSetDepthTestEnableEXT{};
236 PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT{}; 231 PFN_vkCmdSetDepthWriteEnableEXT vkCmdSetDepthWriteEnableEXT{};
232 PFN_vkCmdSetEvent vkCmdSetEvent{};
237 PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{}; 233 PFN_vkCmdSetFrontFaceEXT vkCmdSetFrontFaceEXT{};
234 PFN_vkCmdSetLineWidth vkCmdSetLineWidth{};
238 PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{}; 235 PFN_vkCmdSetPrimitiveTopologyEXT vkCmdSetPrimitiveTopologyEXT{};
236 PFN_vkCmdSetScissor vkCmdSetScissor{};
237 PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask{};
239 PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT{}; 238 PFN_vkCmdSetStencilOpEXT vkCmdSetStencilOpEXT{};
239 PFN_vkCmdSetStencilReference vkCmdSetStencilReference{};
240 PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT{}; 240 PFN_vkCmdSetStencilTestEnableEXT vkCmdSetStencilTestEnableEXT{};
241 PFN_vkCmdResolveImage vkCmdResolveImage{}; 241 PFN_vkCmdSetStencilWriteMask vkCmdSetStencilWriteMask{};
242 PFN_vkCmdSetVertexInputEXT vkCmdSetVertexInputEXT{};
243 PFN_vkCmdSetViewport vkCmdSetViewport{};
244 PFN_vkCmdWaitEvents vkCmdWaitEvents{};
242 PFN_vkCreateBuffer vkCreateBuffer{}; 245 PFN_vkCreateBuffer vkCreateBuffer{};
243 PFN_vkCreateBufferView vkCreateBufferView{}; 246 PFN_vkCreateBufferView vkCreateBufferView{};
244 PFN_vkCreateCommandPool vkCreateCommandPool{}; 247 PFN_vkCreateCommandPool vkCreateCommandPool{};
@@ -989,6 +992,12 @@ public:
989 dynamic_offsets.size(), dynamic_offsets.data()); 992 dynamic_offsets.size(), dynamic_offsets.data());
990 } 993 }
991 994
995 void PushDescriptorSetWithTemplateKHR(VkDescriptorUpdateTemplateKHR update_template,
996 VkPipelineLayout layout, u32 set,
997 const void* data) const noexcept {
998 dld->vkCmdPushDescriptorSetWithTemplateKHR(handle, update_template, layout, set, data);
999 }
1000
992 void BindPipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline) const noexcept { 1001 void BindPipeline(VkPipelineBindPoint bind_point, VkPipeline pipeline) const noexcept {
993 dld->vkCmdBindPipeline(handle, bind_point, pipeline); 1002 dld->vkCmdBindPipeline(handle, bind_point, pipeline);
994 } 1003 }
@@ -1190,6 +1199,10 @@ public:
1190 dld->vkCmdSetFrontFaceEXT(handle, front_face); 1199 dld->vkCmdSetFrontFaceEXT(handle, front_face);
1191 } 1200 }
1192 1201
1202 void SetLineWidth(float line_width) const noexcept {
1203 dld->vkCmdSetLineWidth(handle, line_width);
1204 }
1205
1193 void SetPrimitiveTopologyEXT(VkPrimitiveTopology primitive_topology) const noexcept { 1206 void SetPrimitiveTopologyEXT(VkPrimitiveTopology primitive_topology) const noexcept {
1194 dld->vkCmdSetPrimitiveTopologyEXT(handle, primitive_topology); 1207 dld->vkCmdSetPrimitiveTopologyEXT(handle, primitive_topology);
1195 } 1208 }
@@ -1203,6 +1216,13 @@ public:
1203 dld->vkCmdSetStencilTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE); 1216 dld->vkCmdSetStencilTestEnableEXT(handle, enable ? VK_TRUE : VK_FALSE);
1204 } 1217 }
1205 1218
1219 void SetVertexInputEXT(
1220 vk::Span<VkVertexInputBindingDescription2EXT> bindings,
1221 vk::Span<VkVertexInputAttributeDescription2EXT> attributes) const noexcept {
1222 dld->vkCmdSetVertexInputEXT(handle, bindings.size(), bindings.data(), attributes.size(),
1223 attributes.data());
1224 }
1225
1206 void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers, 1226 void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers,
1207 const VkDeviceSize* offsets, 1227 const VkDeviceSize* offsets,
1208 const VkDeviceSize* sizes) const noexcept { 1228 const VkDeviceSize* sizes) const noexcept {