46 VkPhysicalDeviceFeatures2 features = {};
47 VkPhysicalDeviceDynamicRenderingFeatures dynamic_rendering = {};
49 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
50 dynamic_rendering.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES;
51 features.pNext = &dynamic_rendering;
53 vkGetPhysicalDeviceFeatures2(vk_physical_device, &features);
55 if (features.features.geometryShader == VK_FALSE) {
56 missing_capabilities.
append(
"geometry shaders");
58 if (features.features.logicOp == VK_FALSE) {
59 missing_capabilities.
append(
"logical operations");
62 if (features.features.dualSrcBlend == VK_FALSE) {
63 missing_capabilities.
append(
"dual source blending");
65 if (features.features.imageCubeArray == VK_FALSE) {
66 missing_capabilities.
append(
"image cube array");
68 if (features.features.multiDrawIndirect == VK_FALSE) {
69 missing_capabilities.
append(
"multi draw indirect");
71 if (features.features.multiViewport == VK_FALSE) {
72 missing_capabilities.
append(
"multi viewport");
74 if (features.features.shaderClipDistance == VK_FALSE) {
75 missing_capabilities.
append(
"shader clip distance");
77 if (features.features.drawIndirectFirstInstance == VK_FALSE) {
78 missing_capabilities.
append(
"draw indirect first instance");
80 if (features.features.fragmentStoresAndAtomics == VK_FALSE) {
81 missing_capabilities.
append(
"fragment stores and atomics");
83 if (dynamic_rendering.dynamicRendering == VK_FALSE) {
84 missing_capabilities.
append(
"dynamic rendering");
89 vkEnumerateDeviceExtensionProperties(vk_physical_device,
nullptr, &vk_extension_count,
nullptr);
92 vkEnumerateDeviceExtensionProperties(
93 vk_physical_device,
nullptr, &vk_extension_count, vk_extensions.
data());
95 for (VkExtensionProperties &vk_extension : vk_extensions) {
96 extensions.
add(vk_extension.extensionName);
99 if (!extensions.
contains(VK_KHR_SWAPCHAIN_EXTENSION_NAME)) {
100 missing_capabilities.
append(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
102 if (!extensions.
contains(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME)) {
103 missing_capabilities.
append(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
107 VkPhysicalDeviceProperties2 vk_physical_device_properties = {};
108 VkPhysicalDeviceDriverProperties vk_physical_device_driver_properties = {};
109 vk_physical_device_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
110 vk_physical_device_driver_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES;
111 vk_physical_device_properties.pNext = &vk_physical_device_driver_properties;
112 vkGetPhysicalDeviceProperties2(vk_physical_device, &vk_physical_device_properties);
123 uint32_t conformance_version = VK_MAKE_API_VERSION(
124 vk_physical_device_driver_properties.conformanceVersion.major,
125 vk_physical_device_driver_properties.conformanceVersion.minor,
126 vk_physical_device_driver_properties.conformanceVersion.subminor,
127 vk_physical_device_driver_properties.conformanceVersion.patch);
128 if (vk_physical_device_driver_properties.driverID == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS &&
129 vk_physical_device_properties.properties.deviceType ==
130 VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU &&
131 conformance_version < VK_MAKE_API_VERSION(1, 3, 2, 0))
136 return missing_capabilities;
144 VkApplicationInfo vk_application_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO};
145 vk_application_info.pApplicationName =
"Blender";
146 vk_application_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
147 vk_application_info.pEngineName =
"Blender";
148 vk_application_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
149 vk_application_info.apiVersion = VK_API_VERSION_1_2;
151 VkInstanceCreateInfo vk_instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
152 vk_instance_info.pApplicationInfo = &vk_application_info;
154 VkInstance vk_instance = VK_NULL_HANDLE;
155 vkCreateInstance(&vk_instance_info,
nullptr, &vk_instance);
156 if (vk_instance == VK_NULL_HANDLE) {
157 CLOG_ERROR(&
LOG,
"Unable to initialize a Vulkan 1.2 instance.");
162 uint32_t physical_devices_count = 0;
163 vkEnumeratePhysicalDevices(vk_instance, &physical_devices_count,
nullptr);
165 vkEnumeratePhysicalDevices(vk_instance, &physical_devices_count, vk_physical_devices.
data());
167 for (VkPhysicalDevice vk_physical_device : vk_physical_devices) {
170 VkPhysicalDeviceProperties vk_properties = {};
171 vkGetPhysicalDeviceProperties(vk_physical_device, &vk_properties);
174 if (missing_capabilities.
is_empty()) {
178 "Device [%s] supports minimum requirements. Skip checking other GPUs. Another GPU "
179 "can still be selected during auto-detection.",
180 vk_properties.deviceName);
182 vkDestroyInstance(vk_instance,
nullptr);
186 std::stringstream ss;
187 ss <<
"Device [" << vk_properties.deviceName
188 <<
"] does not meet minimum requirements. Missing features are [";
190 ss << feature <<
", ";
192 ss.seekp(-2, std::ios_base::end);
199 vkDestroyInstance(vk_instance,
nullptr);
201 "No Vulkan device found that meets the minimum requirements. "
202 "Updating GPU driver can improve compatibility.");
210#elif defined(__APPLE__)
217void VKBackend::platform_init()
230 VkApplicationInfo vk_application_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO};
231 vk_application_info.pApplicationName =
"Blender";
232 vk_application_info.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
233 vk_application_info.pEngineName =
"Blender";
234 vk_application_info.engineVersion = VK_MAKE_VERSION(1, 0, 0);
235 vk_application_info.apiVersion = VK_API_VERSION_1_2;
237 VkInstanceCreateInfo vk_instance_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
238 vk_instance_info.pApplicationInfo = &vk_application_info;
240 VkInstance vk_instance = VK_NULL_HANDLE;
241 vkCreateInstance(&vk_instance_info,
nullptr, &vk_instance);
244 uint32_t physical_devices_count = 0;
245 vkEnumeratePhysicalDevices(vk_instance, &physical_devices_count,
nullptr);
246 Array<VkPhysicalDevice> vk_physical_devices(physical_devices_count);
247 vkEnumeratePhysicalDevices(vk_instance, &physical_devices_count, vk_physical_devices.data());
249 for (VkPhysicalDevice vk_physical_device : vk_physical_devices) {
251 VkPhysicalDeviceProperties vk_properties = {};
252 vkGetPhysicalDeviceProperties(vk_physical_device, &vk_properties);
253 std::stringstream identifier;
254 identifier << std::hex << vk_properties.vendorID <<
"/" << vk_properties.deviceID <<
"/"
258 vk_properties.vendorID,
259 vk_properties.deviceID,
260 std::string(vk_properties.deviceName)});
264 vkDestroyInstance(vk_instance,
nullptr);
266 if (a.name == b.name) {
267 return a.index < b.index;
269 return a.
name <
b.name;
273void VKBackend::platform_init(
const VKDevice &device)
295 properties.deviceName,
296 driver_version.c_str(),
302 "Using vendor [%s] device [%s] driver version [%s].",
304 device.vk_physical_device_properties_.deviceName,
305 driver_version.c_str());
308void VKBackend::detect_workarounds(
VKDevice &device)
314 printf(
"VK: Forcing workaround usage and disabling features and extensions.\n");
326 device.workarounds_ = workarounds;
342 VkFormatProperties format_properties = {};
343 vkGetPhysicalDeviceFormatProperties(
346 VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT) == 0;
349 VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME);
352 VK_EXT_DYNAMIC_RENDERING_UNUSED_ATTACHMENTS_EXTENSION_NAME);
354 device.workarounds_ = workarounds;
357void VKBackend::platform_exit()
360 VKDevice &device = VKBackend::get().device;
361 if (device.is_initialized()) {
366void VKBackend::delete_resources() {}
368void VKBackend::samplers_update()
370 VKDevice &device = VKBackend::get().device;
376void VKBackend::compute_dispatch(
int groups_x_len,
int groups_y_len,
int groups_z_len)
385 context.render_graph.add_node(dispatch_info);
388void VKBackend::compute_dispatch_indirect(
StorageBuf *indirect_buf)
398 context.render_graph.add_node(dispatch_indirect_info);
401Context *VKBackend::context_alloc(
void *ghost_window,
void *ghost_context)
409 if (!device.is_initialized()) {
410 device.init(ghost_context);
414 device.context_register(*context);
415 GHOST_SetVulkanSwapBuffersCallbacks((GHOST_ContextHandle)ghost_context,
416 VKContext::swap_buffers_pre_callback,
417 VKContext::swap_buffers_post_callback);
421Batch *VKBackend::batch_alloc()
426DrawList *VKBackend::drawlist_alloc(
int list_length)
456Shader *VKBackend::shader_alloc(
const char *name)
461Texture *VKBackend::texture_alloc(
const char *name)
466UniformBuf *VKBackend::uniformbuf_alloc(
size_t size,
const char *name)
481void VKBackend::render_begin()
483 VKThreadData &thread_data = device.current_thread_data();
488void VKBackend::render_end()
490 VKThreadData &thread_data = device.current_thread_data();
499 device.orphaned_data.destroy_discarded_resources(device);
500 device.orphaned_data.move_data(resource_pool.
discard_pool);
501 resource_pool.
reset();
510 device.orphaned_data.move_data(resource_pool.
discard_pool);
511 resource_pool.
reset();
516void VKBackend::render_step() {}
521 const VkPhysicalDeviceLimits &limits = properties.limits;
528 VK_EXT_SHADER_STENCIL_EXPORT_EXTENSION_NAME);
537 limits.maxPerStageDescriptorSampledImages, INT_MAX);
540 for (
int i = 0; i < 3; i++) {
545 limits.maxPerStageDescriptorUniformBuffers, INT_MAX);
551 limits.maxPerStageDescriptorStorageBuffers, INT_MAX);
557 detect_workarounds(device);
@ G_DEBUG_GPU_FORCE_WORKAROUNDS
#define BLI_assert_msg(a, msg)
MINLINE uint min_uu(uint a, uint b)
MINLINE int max_ii(int a, int b)
int BLI_system_thread_count(void)
int BLI_thread_is_main(void)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
void CLG_logref_init(CLG_LogRef *clg_ref)
#define CLOG_INFO(clg_ref, level,...)
GHOST C-API function and type declarations.
GHOST_ContextHandle GHOST_GetDrawingContext(GHOST_WindowHandle windowhandle)
bool contains(const Key &key) const
void append(const T &value)
static bool is_supported()
bool supports_extension(const char *extension_name) const
const VkPhysicalDeviceProperties & physical_device_properties_get() const
std::string vendor_name() const
std::string driver_version() const
eGPUDriverType driver_type() const
bool is_initialized() const
VkPhysicalDevice physical_device_get() const
const VkPhysicalDeviceVulkan12Features & physical_device_vulkan_12_features_get() const
const VkPhysicalDeviceVulkan11Features & physical_device_vulkan_11_features_get() const
eGPUDeviceType device_type() const
VKDiscardPool discard_pool
VkBuffer vk_handle() const
VKResourcePool & resource_pool_get()
local_group_size(16, 16) .push_constant(Type b
static eGPUOSType determine_os_type()
VKBatch * unwrap(Batch *batch)
static const char * KNOWN_CRASHING_DRIVER
static Vector< StringRefNull > missing_capabilities_get(VkPhysicalDevice vk_physical_device)
int max_shader_storage_buffer_bindings
int max_parallel_compilations
bool geometry_shader_support
int max_work_group_size[3]
int max_work_group_count[3]
bool shader_draw_parameters_support
int max_compute_shader_storage_blocks
bool stencil_export_support
bool texture_view_support
size_t max_storage_buffer_size
bool not_aligned_pixel_formats
struct blender::gpu::VKWorkarounds::@669 vertex_formats
bool dynamic_rendering_unused_attachments
bool shader_output_viewport_index
bool fragment_shader_barycentric
VKDispatchData dispatch_node
VKPipelineData pipeline_data
VKDispatchIndirectData dispatch_indirect_node
VKPipelineData pipeline_data