summaryrefslogtreecommitdiffstats
path: root/src/video_core/vulkan_common/vulkan_device.h
blob: 96c0f8c600375d944e9b8ea1dfa795d3d7391f67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
// Copyright 2018 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

#include "common/common_types.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"

namespace Vulkan {

class NsightAftermathTracker;

/// Format usage descriptor.
enum class FormatType { Linear, Optimal, Buffer };

/// Subgroup size of the guest emulated hardware (Nvidia has 32 threads per subgroup).
const u32 GuestWarpSize = 32;

/// Handles data specific to a physical device.
class Device {
public:
    explicit Device(VkInstance instance, vk::PhysicalDevice physical, VkSurfaceKHR surface,
                    const vk::InstanceDispatch& dld);
    ~Device();

    /**
     * Returns a format supported by the device for the passed requeriments.
     * @param wanted_format The ideal format to be returned. It may not be the returned format.
     * @param wanted_usage The usage that must be fulfilled even if the format is not supported.
     * @param format_type Format type usage.
     * @returns A format supported by the device.
     */
    VkFormat GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
                                FormatType format_type) const;

    /// Reports a device loss.
    void ReportLoss() const;

    /// Reports a shader to Nsight Aftermath.
    void SaveShader(const std::vector<u32>& spirv) const;

    /// Returns the name of the VkDriverId reported from Vulkan.
    std::string GetDriverName() const;

    /// Returns the dispatch loader with direct function pointers of the device.
    const vk::DeviceDispatch& GetDispatchLoader() const {
        return dld;
    }

    /// Returns the logical device.
    const vk::Device& GetLogical() const {
        return logical;
    }

    /// Returns the physical device.
    vk::PhysicalDevice GetPhysical() const {
        return physical;
    }

    /// Returns the main graphics queue.
    vk::Queue GetGraphicsQueue() const {
        return graphics_queue;
    }

    /// Returns the main present queue.
    vk::Queue GetPresentQueue() const {
        return present_queue;
    }

    /// Returns main graphics queue family index.
    u32 GetGraphicsFamily() const {
        return graphics_family;
    }

    /// Returns main present queue family index.
    u32 GetPresentFamily() const {
        return present_family;
    }

    /// Returns the current Vulkan API version provided in Vulkan-formatted version numbers.
    u32 ApiVersion() const {
        return properties.apiVersion;
    }

    /// Returns the current driver version provided in Vulkan-formatted version numbers.
    u32 GetDriverVersion() const {
        return properties.driverVersion;
    }

    /// Returns the device name.
    std::string_view GetModelName() const {
        return properties.deviceName;
    }

    /// Returns the driver ID.
    VkDriverIdKHR GetDriverID() const {
        return driver_id;
    }

    /// Returns uniform buffer alignment requeriment.
    VkDeviceSize GetUniformBufferAlignment() const {
        return properties.limits.minUniformBufferOffsetAlignment;
    }

    /// Returns storage alignment requeriment.
    VkDeviceSize GetStorageBufferAlignment() const {
        return properties.limits.minStorageBufferOffsetAlignment;
    }

    /// Returns the maximum range for storage buffers.
    VkDeviceSize GetMaxStorageBufferRange() const {
        return properties.limits.maxStorageBufferRange;
    }

    /// Returns the maximum size for push constants.
    VkDeviceSize GetMaxPushConstantsSize() const {
        return properties.limits.maxPushConstantsSize;
    }

    /// Returns the maximum size for shared memory.
    u32 GetMaxComputeSharedMemorySize() const {
        return properties.limits.maxComputeSharedMemorySize;
    }

    /// Returns true if ASTC is natively supported.
    bool IsOptimalAstcSupported() const {
        return is_optimal_astc_supported;
    }

    /// Returns true if the device supports float16 natively
    bool IsFloat16Supported() const {
        return is_float16_supported;
    }

    /// Returns true if the device warp size can potentially be bigger than guest's warp size.
    bool IsWarpSizePotentiallyBiggerThanGuest() const {
        return is_warp_potentially_bigger;
    }

    /// Returns true if the device can be forced to use the guest warp size.
    bool IsGuestWarpSizeSupported(VkShaderStageFlagBits stage) const {
        return guest_warp_stages & stage;
    }

    /// Returns true if formatless image load is supported.
    bool IsFormatlessImageLoadSupported() const {
        return is_formatless_image_load_supported;
    }

    /// Returns true when blitting from and to depth stencil images is supported.
    bool IsBlitDepthStencilSupported() const {
        return is_blit_depth_stencil_supported;
    }

    /// Returns true if the device supports VK_NV_viewport_swizzle.
    bool IsNvViewportSwizzleSupported() const {
        return nv_viewport_swizzle;
    }

    /// Returns true if the device supports VK_EXT_scalar_block_layout.
    bool IsKhrUniformBufferStandardLayoutSupported() const {
        return khr_uniform_buffer_standard_layout;
    }

    /// Returns true if the device supports VK_EXT_index_type_uint8.
    bool IsExtIndexTypeUint8Supported() const {
        return ext_index_type_uint8;
    }

    /// Returns true if the device supports VK_EXT_sampler_filter_minmax.
    bool IsExtSamplerFilterMinmaxSupported() const {
        return ext_sampler_filter_minmax;
    }

    /// Returns true if the device supports VK_EXT_depth_range_unrestricted.
    bool IsExtDepthRangeUnrestrictedSupported() const {
        return ext_depth_range_unrestricted;
    }

    /// Returns true if the device supports VK_EXT_shader_viewport_index_layer.
    bool IsExtShaderViewportIndexLayerSupported() const {
        return ext_shader_viewport_index_layer;
    }

    /// Returns true if the device supports VK_EXT_transform_feedback.
    bool IsExtTransformFeedbackSupported() const {
        return ext_transform_feedback;
    }

    /// Returns true if the device supports VK_EXT_custom_border_color.
    bool IsExtCustomBorderColorSupported() const {
        return ext_custom_border_color;
    }

    /// Returns true if the device supports VK_EXT_extended_dynamic_state.
    bool IsExtExtendedDynamicStateSupported() const {
        return ext_extended_dynamic_state;
    }

    /// Returns true if the device supports VK_EXT_shader_stencil_export.
    bool IsExtShaderStencilExportSupported() const {
        return ext_shader_stencil_export;
    }

    /// Returns true when a known debugging tool is attached.
    bool HasDebuggingToolAttached() const {
        return has_renderdoc || has_nsight_graphics;
    }

    /// Returns the vendor name reported from Vulkan.
    std::string_view GetVendorName() const {
        return vendor_name;
    }

    /// Returns the list of available extensions.
    const std::vector<std::string>& GetAvailableExtensions() const {
        return reported_extensions;
    }

    /// Returns true if the setting for async shader compilation is enabled.
    bool UseAsynchronousShaders() const {
        return use_asynchronous_shaders;
    }

    u64 GetDeviceLocalMemory() const {
        return device_access_memory;
    }

private:
    /// Checks if the physical device is suitable.
    void CheckSuitability(bool requires_swapchain) const;

    /// Loads extensions into a vector and stores available ones in this object.
    std::vector<const char*> LoadExtensions(bool requires_surface);

    /// Sets up queue families.
    void SetupFamilies(VkSurfaceKHR surface);

    /// Sets up device features.
    void SetupFeatures();

    /// Collects telemetry information from the device.
    void CollectTelemetryParameters();

    /// Collects information about attached tools.
    void CollectToolingInfo();

    /// Collects information about the device's local memory.
    void CollectPhysicalMemoryInfo();

    /// Returns a list of queue initialization descriptors.
    std::vector<VkDeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const;

    /// Returns true if ASTC textures are natively supported.
    bool IsOptimalAstcSupported(const VkPhysicalDeviceFeatures& features) const;

    /// Returns true if the device natively supports blitting depth stencil images.
    bool TestDepthStencilBlits() const;

    /// Returns true if a format is supported.
    bool IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags wanted_usage,
                           FormatType format_type) const;

    VkInstance instance;                        ///< Vulkan instance.
    vk::DeviceDispatch dld;                     ///< Device function pointers.
    vk::PhysicalDevice physical;                ///< Physical device.
    VkPhysicalDeviceProperties properties;      ///< Device properties.
    vk::Device logical;                         ///< Logical device.
    vk::Queue graphics_queue;                   ///< Main graphics queue.
    vk::Queue present_queue;                    ///< Main present queue.
    u32 instance_version{};                     ///< Vulkan onstance version.
    u32 graphics_family{};                      ///< Main graphics queue family index.
    u32 present_family{};                       ///< Main present queue family index.
    VkDriverIdKHR driver_id{};                  ///< Driver ID.
    VkShaderStageFlags guest_warp_stages{};     ///< Stages where the guest warp size can be forced.
    u64 device_access_memory{};                 ///< Total size of device local memory in bytes.
    bool is_optimal_astc_supported{};           ///< Support for native ASTC.
    bool is_float16_supported{};                ///< Support for float16 arithmetics.
    bool is_warp_potentially_bigger{};          ///< Host warp size can be bigger than guest.
    bool is_formatless_image_load_supported{};  ///< Support for shader image read without format.
    bool is_shader_storage_image_multisample{}; ///< Support for image operations on MSAA images.
    bool is_blit_depth_stencil_supported{};     ///< Support for blitting from and to depth stencil.
    bool nv_viewport_swizzle{};                 ///< Support for VK_NV_viewport_swizzle.
    bool khr_uniform_buffer_standard_layout{};  ///< Support for std430 on UBOs.
    bool ext_index_type_uint8{};                ///< Support for VK_EXT_index_type_uint8.
    bool ext_sampler_filter_minmax{};           ///< Support for VK_EXT_sampler_filter_minmax.
    bool ext_depth_range_unrestricted{};        ///< Support for VK_EXT_depth_range_unrestricted.
    bool ext_shader_viewport_index_layer{};     ///< Support for VK_EXT_shader_viewport_index_layer.
    bool ext_tooling_info{};                    ///< Support for VK_EXT_tooling_info.
    bool ext_transform_feedback{};              ///< Support for VK_EXT_transform_feedback.
    bool ext_custom_border_color{};             ///< Support for VK_EXT_custom_border_color.
    bool ext_extended_dynamic_state{};          ///< Support for VK_EXT_extended_dynamic_state.
    bool ext_shader_stencil_export{};           ///< Support for VK_EXT_shader_stencil_export.
    bool nv_device_diagnostics_config{};        ///< Support for VK_NV_device_diagnostics_config.
    bool has_renderdoc{};                       ///< Has RenderDoc attached
    bool has_nsight_graphics{};                 ///< Has Nsight Graphics attached

    // Asynchronous Graphics Pipeline setting
    bool use_asynchronous_shaders{}; ///< Setting to use asynchronous shaders/graphics pipeline

    // Telemetry parameters
    std::string vendor_name;                      ///< Device's driver name.
    std::vector<std::string> reported_extensions; ///< Reported Vulkan extensions.

    /// Format properties dictionary.
    std::unordered_map<VkFormat, VkFormatProperties> format_properties;

    /// Nsight Aftermath GPU crash tracker
    std::unique_ptr<NsightAftermathTracker> nsight_aftermath_tracker;
};

} // namespace Vulkan