2015-05-08 22:32:37 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2015 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
|
* IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <assert.h>
|
2021-10-30 17:02:41 -05:00
|
|
|
#include <inttypes.h>
|
2015-05-08 22:32:37 -07:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <string.h>
|
2021-06-22 00:29:40 +00:00
|
|
|
#ifdef MAJOR_IN_MKDEV
|
|
|
|
|
#include <sys/mkdev.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef MAJOR_IN_SYSMACROS
|
2021-01-22 12:38:41 +02:00
|
|
|
#include <sys/sysmacros.h>
|
2021-06-22 00:29:40 +00:00
|
|
|
#endif
|
2016-11-07 17:24:24 -08:00
|
|
|
#include <sys/mman.h>
|
2021-01-22 12:38:41 +02:00
|
|
|
#include <sys/stat.h>
|
2015-05-08 22:32:37 -07:00
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
2019-02-12 18:18:03 +00:00
|
|
|
#include "drm-uapi/drm_fourcc.h"
|
2019-08-06 15:56:40 +03:00
|
|
|
#include "drm-uapi/drm.h"
|
|
|
|
|
#include <xf86drm.h>
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-17 15:04:27 -07:00
|
|
|
#include "anv_private.h"
|
2021-01-05 19:34:51 -08:00
|
|
|
#include "anv_measure.h"
|
2022-09-13 12:49:56 +03:00
|
|
|
#include "util/u_debug.h"
|
2017-02-14 08:21:43 -08:00
|
|
|
#include "util/build_id.h"
|
2018-06-29 17:08:30 -07:00
|
|
|
#include "util/disk_cache.h"
|
2017-02-24 16:36:00 -08:00
|
|
|
#include "util/mesa-sha1.h"
|
2019-01-08 12:45:38 +00:00
|
|
|
#include "util/os_file.h"
|
2019-11-30 17:36:01 +11:00
|
|
|
#include "util/os_misc.h"
|
2019-01-08 12:45:38 +00:00
|
|
|
#include "util/u_atomic.h"
|
2018-10-23 15:27:51 +01:00
|
|
|
#include "util/u_string.h"
|
2020-06-12 11:42:32 +02:00
|
|
|
#include "util/driconf.h"
|
2018-06-19 20:27:36 -07:00
|
|
|
#include "git_sha1.h"
|
2017-06-06 12:31:05 +01:00
|
|
|
#include "vk_util.h"
|
2020-06-22 11:57:32 -05:00
|
|
|
#include "vk_deferred_operation.h"
|
2021-10-20 09:44:02 -05:00
|
|
|
#include "vk_drm_syncobj.h"
|
2021-03-03 13:20:06 -08:00
|
|
|
#include "common/intel_aux_map.h"
|
|
|
|
|
#include "common/intel_uuid.h"
|
2021-04-05 17:24:14 -07:00
|
|
|
#include "perf/intel_perf.h"
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2022-10-05 11:01:32 -07:00
|
|
|
#include "i915/anv_device.h"
|
2023-02-09 08:44:04 -08:00
|
|
|
#include "xe/anv_device.h"
|
2022-10-05 11:01:32 -07:00
|
|
|
|
2016-02-18 10:19:02 -08:00
|
|
|
#include "genxml/gen7_pack.h"
|
2021-02-05 21:16:38 +02:00
|
|
|
#include "genxml/genX_bits.h"
|
2015-11-16 12:29:07 -08:00
|
|
|
|
2020-09-25 12:56:22 -07:00
|
|
|
static const driOptionDescription anv_dri_options[] = {
|
2019-08-29 23:55:29 +01:00
|
|
|
DRI_CONF_SECTION_PERFORMANCE
|
2021-12-28 10:39:46 +02:00
|
|
|
DRI_CONF_ADAPTIVE_SYNC(true)
|
2019-08-29 23:55:29 +01:00
|
|
|
DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
|
2020-09-29 09:28:18 -07:00
|
|
|
DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false)
|
2022-10-24 13:48:30 +02:00
|
|
|
DRI_CONF_VK_KHR_PRESENT_WAIT(false)
|
2021-09-07 15:06:46 +02:00
|
|
|
DRI_CONF_VK_XWAYLAND_WAIT_READY(true)
|
2022-03-31 16:44:15 +03:00
|
|
|
DRI_CONF_ANV_ASSUME_FULL_SUBGROUPS(false)
|
2022-05-17 09:36:26 +03:00
|
|
|
DRI_CONF_ANV_SAMPLE_MASK_OUT_OPENGL_BEHAVIOUR(false)
|
2022-10-20 17:49:34 +03:00
|
|
|
DRI_CONF_ANV_FP64_WORKAROUND_ENABLED(false)
|
2022-02-25 16:56:04 +02:00
|
|
|
DRI_CONF_ANV_GENERATED_INDIRECT_THRESHOLD(4)
|
2023-03-07 10:44:01 -08:00
|
|
|
DRI_CONF_NO_16BIT(false)
|
2023-03-22 22:08:09 +00:00
|
|
|
DRI_CONF_ANV_QUERY_CLEAR_WITH_BLORP_THRESHOLD(6)
|
2019-08-29 23:55:29 +01:00
|
|
|
DRI_CONF_SECTION_END
|
2019-11-11 12:46:33 -06:00
|
|
|
|
|
|
|
|
DRI_CONF_SECTION_DEBUG
|
2020-09-29 09:28:18 -07:00
|
|
|
DRI_CONF_ALWAYS_FLUSH_CACHE(false)
|
|
|
|
|
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
|
2022-05-06 18:52:47 +03:00
|
|
|
DRI_CONF_LIMIT_TRIG_INPUT_RANGE(false)
|
2022-07-06 17:17:42 +02:00
|
|
|
DRI_CONF_ANV_MESH_CONV_PRIM_ATTRS_TO_VERT_ATTRS(-2)
|
2019-11-11 12:46:33 -06:00
|
|
|
DRI_CONF_SECTION_END
|
2022-09-13 12:22:33 +03:00
|
|
|
|
|
|
|
|
DRI_CONF_SECTION_QUALITY
|
|
|
|
|
DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE()
|
|
|
|
|
DRI_CONF_SECTION_END
|
2020-09-25 12:56:22 -07:00
|
|
|
};
|
2019-04-24 16:42:25 +01:00
|
|
|
|
2019-02-18 15:40:49 +11:00
|
|
|
/* This is probably far to big but it reflects the max size used for messages
|
|
|
|
|
* in OpenGLs KHR_debug.
|
|
|
|
|
*/
|
|
|
|
|
#define MAX_DEBUG_MESSAGE_LENGTH 4096
|
|
|
|
|
|
2018-10-30 20:38:03 +03:00
|
|
|
/* The "RAW" clocks on Linux are called "FAST" on FreeBSD */
|
|
|
|
|
#if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST)
|
|
|
|
|
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST
|
|
|
|
|
#endif
|
|
|
|
|
|
2015-10-19 22:06:59 -07:00
|
|
|
static void
|
2021-07-29 14:13:27 -07:00
|
|
|
compiler_debug_log(void *data, UNUSED unsigned *id, const char *fmt, ...)
|
2019-02-18 15:40:49 +11:00
|
|
|
{
|
|
|
|
|
char str[MAX_DEBUG_MESSAGE_LENGTH];
|
|
|
|
|
struct anv_device *device = (struct anv_device *)data;
|
2021-10-26 13:27:19 -04:00
|
|
|
UNUSED struct anv_instance *instance = device->physical->instance;
|
2019-02-18 15:40:49 +11:00
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
|
(void) vsnprintf(str, MAX_DEBUG_MESSAGE_LENGTH, fmt, args);
|
|
|
|
|
va_end(args);
|
|
|
|
|
|
2021-10-26 13:27:19 -04:00
|
|
|
//vk_logd(VK_LOG_NO_OBJS(&instance->vk), "%s", str);
|
2019-02-18 15:40:49 +11:00
|
|
|
}
|
2015-10-19 22:06:59 -07:00
|
|
|
|
|
|
|
|
static void
|
2021-07-29 14:27:57 -07:00
|
|
|
compiler_perf_log(UNUSED void *data, UNUSED unsigned *id, const char *fmt, ...)
|
2015-10-19 22:06:59 -07:00
|
|
|
{
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start(args, fmt);
|
|
|
|
|
|
2021-10-13 11:21:41 +02:00
|
|
|
if (INTEL_DEBUG(DEBUG_PERF))
|
mesa: Promote Intel's simple logging façade for Android to util/
I'm bringing up freedreno Vulkan on an Android phone, and my pains are
exactly what Chad said when working on Intel's vulkan for Android in
aa716db0f64d ("intel: Add simple logging façade for Android (v2)"):
On Android, stdio goes to /dev/null. On Android, remote gdb is even
more painful than the usual remote gdb. On Android, nothing works like
you expect and debugging is hell. I need logging.
This patch introduces a small, simple logging API that can easily wrap
Android's API. On non-Android platforms, this logger does nothing
fancy. It follows the time-honored Unix tradition of spewing
everything to stderr with minimal fuss.
My goal here is not perfection. My goal is to make a minimal, clean API,
that people hate merely a little instead of a lot, and that's good
enough to let me bring up Android Vulkan. And it needs to be fast,
which means it must be small. No one wants to their game to miss frames
while aiming a flaming bow into the jaws of an angry robot t-rex, and
thus become t-rex breakfast, because some fool had too much fun desiging
a bloated, ideal logging API.
Compared to trusty fprintf, _mesa_log[ewi]() is actually usable on
Android. Compared to os_log_message(), this has different error levels
and supports format arguments.
The only code change in the move is wrapping flockfile/funlockfile in
!DETECT_OS_WINDOWS, since mingw32 doesn't have it. Windows likely wants
different logging code, anyway.
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Kristian H. Kristensen <hoegsberg@google.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6806>
2020-09-21 12:53:14 -07:00
|
|
|
mesa_logd_v(fmt, args);
|
2015-10-19 22:06:59 -07:00
|
|
|
|
|
|
|
|
va_end(args);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-29 22:40:39 -06:00
|
|
|
#if defined(VK_USE_PLATFORM_WAYLAND_KHR) || \
|
|
|
|
|
defined(VK_USE_PLATFORM_XCB_KHR) || \
|
|
|
|
|
defined(VK_USE_PLATFORM_XLIB_KHR) || \
|
|
|
|
|
defined(VK_USE_PLATFORM_DISPLAY_KHR)
|
|
|
|
|
#define ANV_USE_WSI_PLATFORM
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef ANDROID
|
|
|
|
|
#define ANV_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
|
|
|
|
|
#else
|
2021-09-07 10:45:16 -05:00
|
|
|
#define ANV_API_VERSION VK_MAKE_VERSION(1, 3, VK_HEADER_VERSION)
|
2021-01-29 22:40:39 -06:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
VkResult anv_EnumerateInstanceVersion(
|
|
|
|
|
uint32_t* pApiVersion)
|
|
|
|
|
{
|
|
|
|
|
*pApiVersion = ANV_API_VERSION;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct vk_instance_extension_table instance_extensions = {
|
|
|
|
|
.KHR_device_group_creation = true,
|
|
|
|
|
.KHR_external_fence_capabilities = true,
|
|
|
|
|
.KHR_external_memory_capabilities = true,
|
|
|
|
|
.KHR_external_semaphore_capabilities = true,
|
|
|
|
|
.KHR_get_physical_device_properties2 = true,
|
|
|
|
|
.EXT_debug_report = true,
|
2022-03-24 11:33:19 -05:00
|
|
|
.EXT_debug_utils = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
|
|
|
|
|
#ifdef ANV_USE_WSI_PLATFORM
|
|
|
|
|
.KHR_get_surface_capabilities2 = true,
|
|
|
|
|
.KHR_surface = true,
|
|
|
|
|
.KHR_surface_protected_capabilities = true,
|
2022-11-14 12:18:26 +00:00
|
|
|
.EXT_swapchain_colorspace = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
#endif
|
|
|
|
|
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
|
|
|
|
|
.KHR_wayland_surface = true,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef VK_USE_PLATFORM_XCB_KHR
|
|
|
|
|
.KHR_xcb_surface = true,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef VK_USE_PLATFORM_XLIB_KHR
|
|
|
|
|
.KHR_xlib_surface = true,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef VK_USE_PLATFORM_XLIB_XRANDR_EXT
|
|
|
|
|
.EXT_acquire_xlib_display = true,
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
|
|
|
|
|
.KHR_display = true,
|
|
|
|
|
.KHR_get_display_properties2 = true,
|
|
|
|
|
.EXT_direct_mode_display = true,
|
|
|
|
|
.EXT_display_surface_counter = true,
|
2021-07-06 13:04:09 -04:00
|
|
|
.EXT_acquire_drm_display = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
get_device_extensions(const struct anv_physical_device *device,
|
|
|
|
|
struct vk_device_extension_table *ext)
|
|
|
|
|
{
|
2021-11-12 09:51:59 -06:00
|
|
|
const bool has_syncobj_wait =
|
|
|
|
|
(device->sync_syncobj_type.features & VK_SYNC_FEATURE_CPU_WAIT) != 0;
|
|
|
|
|
|
2022-11-25 13:08:28 +02:00
|
|
|
const bool rt_enabled = ANV_SUPPORT_RT && device->info.has_ray_tracing;
|
2023-05-08 14:22:15 -07:00
|
|
|
|
|
|
|
|
/* We are seeing hangs on other workloads when something using mesh
|
|
|
|
|
* shaders runs at the same time, so it's disabled by default.
|
|
|
|
|
*/
|
|
|
|
|
const bool mesh_shader_enabled = device->info.has_mesh_shading &&
|
|
|
|
|
debug_get_bool_option("ANV_MESH_SHADER", false);
|
2021-05-19 09:35:22 -07:00
|
|
|
const bool nv_mesh_shading_enabled =
|
2022-09-13 12:49:56 +03:00
|
|
|
debug_get_bool_option("ANV_EXPERIMENTAL_NV_MESH_SHADER", false);
|
2021-05-19 09:35:22 -07:00
|
|
|
|
2021-01-29 22:40:39 -06:00
|
|
|
*ext = (struct vk_device_extension_table) {
|
2022-08-30 14:50:51 -07:00
|
|
|
.KHR_8bit_storage = true,
|
2023-03-07 10:44:01 -08:00
|
|
|
.KHR_16bit_storage = !device->instance->no_16bit,
|
2022-11-25 13:08:28 +02:00
|
|
|
.KHR_acceleration_structure = rt_enabled,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_bind_memory2 = true,
|
2022-08-30 19:01:33 -07:00
|
|
|
.KHR_buffer_device_address = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_copy_commands2 = true,
|
|
|
|
|
.KHR_create_renderpass2 = true,
|
|
|
|
|
.KHR_dedicated_allocation = true,
|
|
|
|
|
.KHR_deferred_host_operations = true,
|
|
|
|
|
.KHR_depth_stencil_resolve = true,
|
|
|
|
|
.KHR_descriptor_update_template = true,
|
|
|
|
|
.KHR_device_group = true,
|
|
|
|
|
.KHR_draw_indirect_count = true,
|
|
|
|
|
.KHR_driver_properties = true,
|
2021-11-04 12:19:07 -07:00
|
|
|
.KHR_dynamic_rendering = true,
|
2021-11-12 09:51:59 -06:00
|
|
|
.KHR_external_fence = has_syncobj_wait,
|
|
|
|
|
.KHR_external_fence_fd = has_syncobj_wait,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_external_memory = true,
|
|
|
|
|
.KHR_external_memory_fd = true,
|
|
|
|
|
.KHR_external_semaphore = true,
|
|
|
|
|
.KHR_external_semaphore_fd = true,
|
2021-07-07 19:15:15 +03:00
|
|
|
.KHR_format_feature_flags2 = true,
|
2020-10-19 10:12:43 +03:00
|
|
|
.KHR_fragment_shading_rate = device->info.ver >= 11,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_get_memory_requirements2 = true,
|
|
|
|
|
.KHR_image_format_list = true,
|
|
|
|
|
.KHR_imageless_framebuffer = true,
|
|
|
|
|
#ifdef ANV_USE_WSI_PLATFORM
|
|
|
|
|
.KHR_incremental_present = true,
|
|
|
|
|
#endif
|
|
|
|
|
.KHR_maintenance1 = true,
|
|
|
|
|
.KHR_maintenance2 = true,
|
|
|
|
|
.KHR_maintenance3 = true,
|
2021-07-28 14:57:51 +03:00
|
|
|
.KHR_maintenance4 = true,
|
2023-03-20 17:02:45 -05:00
|
|
|
.KHR_map_memory2 = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_multiview = true,
|
|
|
|
|
.KHR_performance_query =
|
2022-08-30 15:12:27 -07:00
|
|
|
device->perf &&
|
2021-01-29 22:40:39 -06:00
|
|
|
(device->perf->i915_perf_version >= 3 ||
|
2021-10-13 11:21:41 +02:00
|
|
|
INTEL_DEBUG(DEBUG_NO_OACONFIG)) &&
|
2021-01-29 22:40:39 -06:00
|
|
|
device->use_call_secondary,
|
|
|
|
|
.KHR_pipeline_executable_properties = true,
|
2020-09-07 02:24:20 -05:00
|
|
|
.KHR_pipeline_library = true,
|
2022-10-24 13:48:30 +02:00
|
|
|
/* Hide these behind dri configs for now since we cannot implement it reliably on
|
|
|
|
|
* all surfaces yet. There is no surface capability query for present wait/id,
|
|
|
|
|
* but the feature is useful enough to hide behind an opt-in mechanism for now.
|
|
|
|
|
* If the instance only enables surface extensions that unconditionally support present wait,
|
|
|
|
|
* we can also expose the extension that way. */
|
|
|
|
|
.KHR_present_id =
|
|
|
|
|
driQueryOptionb(&device->instance->dri_options, "vk_khr_present_wait") ||
|
|
|
|
|
wsi_common_vk_instance_supports_present_wait(&device->instance->vk),
|
|
|
|
|
.KHR_present_wait =
|
|
|
|
|
driQueryOptionb(&device->instance->dri_options, "vk_khr_present_wait") ||
|
|
|
|
|
wsi_common_vk_instance_supports_present_wait(&device->instance->vk),
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_push_descriptor = true,
|
2022-11-25 13:08:28 +02:00
|
|
|
.KHR_ray_query = rt_enabled,
|
|
|
|
|
.KHR_ray_tracing_maintenance1 = rt_enabled,
|
|
|
|
|
.KHR_ray_tracing_pipeline = rt_enabled,
|
2022-12-01 23:30:59 +02:00
|
|
|
.KHR_ray_tracing_position_fetch = rt_enabled,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_relaxed_block_layout = true,
|
|
|
|
|
.KHR_sampler_mirror_clamp_to_edge = true,
|
|
|
|
|
.KHR_sampler_ycbcr_conversion = true,
|
|
|
|
|
.KHR_separate_depth_stencil_layouts = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.KHR_shader_atomic_int64 = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_shader_clock = true,
|
|
|
|
|
.KHR_shader_draw_parameters = true,
|
2023-03-07 10:44:01 -08:00
|
|
|
.KHR_shader_float16_int8 = !device->instance->no_16bit,
|
2022-08-30 14:50:51 -07:00
|
|
|
.KHR_shader_float_controls = true,
|
2021-06-14 19:49:32 -07:00
|
|
|
.KHR_shader_integer_dot_product = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_shader_non_semantic_info = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.KHR_shader_subgroup_extended_types = true,
|
2021-06-23 15:58:40 -07:00
|
|
|
.KHR_shader_subgroup_uniform_control_flow = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_shader_terminate_invocation = true,
|
|
|
|
|
.KHR_spirv_1_4 = true,
|
|
|
|
|
.KHR_storage_buffer_storage_class = true,
|
|
|
|
|
#ifdef ANV_USE_WSI_PLATFORM
|
|
|
|
|
.KHR_swapchain = true,
|
|
|
|
|
.KHR_swapchain_mutable_format = true,
|
|
|
|
|
#endif
|
2020-11-11 21:38:25 +02:00
|
|
|
.KHR_synchronization2 = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_timeline_semaphore = true,
|
|
|
|
|
.KHR_uniform_buffer_standard_layout = true,
|
|
|
|
|
.KHR_variable_pointers = true,
|
2023-02-08 17:24:28 +02:00
|
|
|
.KHR_video_queue = device->video_decode_enabled,
|
|
|
|
|
.KHR_video_decode_queue = device->video_decode_enabled,
|
|
|
|
|
.KHR_video_decode_h264 = VIDEO_CODEC_H264DEC && device->video_decode_enabled,
|
2021-01-29 22:40:39 -06:00
|
|
|
.KHR_vulkan_memory_model = true,
|
|
|
|
|
.KHR_workgroup_memory_explicit_layout = true,
|
|
|
|
|
.KHR_zero_initialize_workgroup_memory = true,
|
|
|
|
|
.EXT_4444_formats = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_border_color_swizzle = true,
|
2022-08-30 19:01:33 -07:00
|
|
|
.EXT_buffer_device_address = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_calibrated_timestamps = device->has_reg_timestamp,
|
2021-03-31 19:40:21 +03:00
|
|
|
.EXT_color_write_enable = true,
|
2022-08-03 12:38:39 +03:00
|
|
|
.EXT_conditional_rendering = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_conservative_rasterization = true,
|
|
|
|
|
.EXT_custom_border_color = true,
|
2022-09-02 13:30:40 +03:00
|
|
|
.EXT_depth_clamp_zero_one = true,
|
2022-03-09 12:35:26 +02:00
|
|
|
.EXT_depth_clip_control = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_depth_clip_enable = true,
|
2022-08-30 19:55:53 -07:00
|
|
|
.EXT_descriptor_indexing = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
#ifdef VK_USE_PLATFORM_DISPLAY_KHR
|
|
|
|
|
.EXT_display_control = true,
|
|
|
|
|
#endif
|
|
|
|
|
.EXT_extended_dynamic_state = true,
|
2021-04-06 09:59:52 +03:00
|
|
|
.EXT_extended_dynamic_state2 = true,
|
2022-09-04 19:38:10 +03:00
|
|
|
.EXT_extended_dynamic_state3 = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_external_memory_dma_buf = true,
|
|
|
|
|
.EXT_external_memory_host = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_fragment_shader_interlock = true,
|
2021-05-25 10:30:49 -05:00
|
|
|
.EXT_global_priority = device->max_context_priority >=
|
2022-08-17 12:44:29 -07:00
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR,
|
2021-05-25 10:30:49 -05:00
|
|
|
.EXT_global_priority_query = device->max_context_priority >=
|
2022-08-17 12:44:29 -07:00
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR,
|
2023-05-09 11:53:37 -07:00
|
|
|
.EXT_graphics_pipeline_library = !debug_get_bool_option("ANV_NO_GPL", false),
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_host_query_reset = true,
|
2022-04-05 08:40:34 -04:00
|
|
|
.EXT_image_2d_view_of_3d = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_image_robustness = true,
|
2021-03-22 22:27:21 -07:00
|
|
|
.EXT_image_drm_format_modifier = true,
|
2023-02-17 10:03:38 +02:00
|
|
|
.EXT_image_sliced_view_of_3d = true,
|
2021-07-06 10:59:49 -05:00
|
|
|
.EXT_image_view_min_lod = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_index_type_uint8 = true,
|
|
|
|
|
.EXT_inline_uniform_block = true,
|
|
|
|
|
.EXT_line_rasterization = true,
|
2023-01-31 15:47:48 +01:00
|
|
|
.EXT_load_store_op_none = true,
|
2022-08-19 23:31:08 +03:00
|
|
|
/* Enable the extension only if we have support on both the local &
|
|
|
|
|
* system memory
|
|
|
|
|
*/
|
|
|
|
|
.EXT_memory_budget = (!device->info.has_local_mem ||
|
|
|
|
|
device->vram_mappable.available > 0) &&
|
|
|
|
|
device->sys.available,
|
2023-05-08 14:22:15 -07:00
|
|
|
.EXT_mesh_shader = mesh_shader_enabled,
|
2022-09-06 21:18:17 +03:00
|
|
|
.EXT_mutable_descriptor_type = true,
|
2021-08-29 19:58:36 +02:00
|
|
|
.EXT_non_seamless_cube_map = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_pci_bus_info = true,
|
2021-01-22 12:38:41 +02:00
|
|
|
.EXT_physical_device_drm = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_pipeline_creation_cache_control = true,
|
|
|
|
|
.EXT_pipeline_creation_feedback = true,
|
2023-03-13 14:00:50 +02:00
|
|
|
.EXT_pipeline_library_group_handles = rt_enabled,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_post_depth_coverage = true,
|
2022-01-26 12:43:51 +02:00
|
|
|
.EXT_primitives_generated_query = true,
|
2021-08-30 15:27:16 -04:00
|
|
|
.EXT_primitive_topology_list_restart = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_private_data = true,
|
2020-07-10 14:09:48 -05:00
|
|
|
.EXT_provoking_vertex = true,
|
2021-03-22 22:27:21 -07:00
|
|
|
.EXT_queue_family_foreign = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_robustness2 = true,
|
|
|
|
|
.EXT_sample_locations = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_sampler_filter_minmax = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_scalar_block_layout = true,
|
|
|
|
|
.EXT_separate_stencil_usage = true,
|
|
|
|
|
.EXT_shader_atomic_float = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_shader_atomic_float2 = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_shader_demote_to_helper_invocation = true,
|
2022-05-24 12:39:16 -05:00
|
|
|
.EXT_shader_module_identifier = true,
|
2022-08-30 14:50:51 -07:00
|
|
|
.EXT_shader_stencil_export = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_shader_subgroup_ballot = true,
|
|
|
|
|
.EXT_shader_subgroup_vote = true,
|
|
|
|
|
.EXT_shader_viewport_index_layer = true,
|
|
|
|
|
.EXT_subgroup_size_control = true,
|
|
|
|
|
.EXT_texel_buffer_alignment = true,
|
2022-03-21 19:57:09 +02:00
|
|
|
.EXT_tooling_info = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_transform_feedback = true,
|
|
|
|
|
.EXT_vertex_attribute_divisor = true,
|
2023-01-31 22:15:11 +01:00
|
|
|
.EXT_vertex_input_dynamic_state = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.EXT_ycbcr_image_arrays = true,
|
|
|
|
|
#ifdef ANDROID
|
|
|
|
|
.ANDROID_external_memory_android_hardware_buffer = true,
|
|
|
|
|
.ANDROID_native_buffer = true,
|
|
|
|
|
#endif
|
|
|
|
|
.GOOGLE_decorate_string = true,
|
|
|
|
|
.GOOGLE_hlsl_functionality1 = true,
|
|
|
|
|
.GOOGLE_user_type = true,
|
|
|
|
|
.INTEL_performance_query = device->perf &&
|
|
|
|
|
device->perf->i915_perf_version >= 3,
|
2022-08-30 14:50:51 -07:00
|
|
|
.INTEL_shader_integer_functions2 = true,
|
2021-06-22 12:53:15 -04:00
|
|
|
.EXT_multi_draw = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
.NV_compute_shader_derivatives = true,
|
2023-05-08 14:22:15 -07:00
|
|
|
.NV_mesh_shader = mesh_shader_enabled &&
|
2021-05-19 09:35:22 -07:00
|
|
|
nv_mesh_shading_enabled,
|
2022-01-14 15:02:17 +01:00
|
|
|
.VALVE_mutable_descriptor_type = true,
|
2021-01-29 22:40:39 -06:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static void
|
|
|
|
|
get_features(const struct anv_physical_device *pdevice,
|
|
|
|
|
struct vk_features *features)
|
2021-08-18 09:35:53 -05:00
|
|
|
{
|
2023-04-29 02:09:16 +03:00
|
|
|
struct vk_app_info *app_info = &pdevice->instance->vk.app_info;
|
2021-08-18 09:35:53 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Just pick one; they're all the same */
|
|
|
|
|
const bool has_astc_ldr =
|
|
|
|
|
isl_format_supports_sampling(&pdevice->info,
|
|
|
|
|
ISL_FORMAT_ASTC_LDR_2D_4X4_FLT16);
|
2021-08-18 09:40:37 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
const bool rt_enabled = ANV_SUPPORT_RT && pdevice->info.has_ray_tracing;
|
2021-08-18 09:35:53 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
const bool mesh_shader =
|
|
|
|
|
pdevice->vk.supported_extensions.EXT_mesh_shader ||
|
|
|
|
|
pdevice->vk.supported_extensions.NV_mesh_shader;
|
2021-08-18 09:35:53 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
*features = (struct vk_features) {
|
|
|
|
|
/* Vulkan 1.0 */
|
|
|
|
|
.robustBufferAccess = true,
|
|
|
|
|
.fullDrawIndexUint32 = true,
|
|
|
|
|
.imageCubeArray = true,
|
|
|
|
|
.independentBlend = true,
|
|
|
|
|
.geometryShader = true,
|
|
|
|
|
.tessellationShader = true,
|
|
|
|
|
.sampleRateShading = true,
|
|
|
|
|
.dualSrcBlend = true,
|
|
|
|
|
.logicOp = true,
|
|
|
|
|
.multiDrawIndirect = true,
|
|
|
|
|
.drawIndirectFirstInstance = true,
|
|
|
|
|
.depthClamp = true,
|
|
|
|
|
.depthBiasClamp = true,
|
|
|
|
|
.fillModeNonSolid = true,
|
|
|
|
|
.depthBounds = pdevice->info.ver >= 12,
|
|
|
|
|
.wideLines = true,
|
|
|
|
|
.largePoints = true,
|
|
|
|
|
.alphaToOne = true,
|
|
|
|
|
.multiViewport = true,
|
|
|
|
|
.samplerAnisotropy = true,
|
|
|
|
|
.textureCompressionETC2 = true,
|
|
|
|
|
.textureCompressionASTC_LDR = has_astc_ldr,
|
|
|
|
|
.textureCompressionBC = true,
|
|
|
|
|
.occlusionQueryPrecise = true,
|
|
|
|
|
.pipelineStatisticsQuery = true,
|
|
|
|
|
/* We can't do image stores in vec4 shaders */
|
|
|
|
|
.vertexPipelineStoresAndAtomics =
|
|
|
|
|
pdevice->compiler->scalar_stage[MESA_SHADER_VERTEX] &&
|
|
|
|
|
pdevice->compiler->scalar_stage[MESA_SHADER_GEOMETRY],
|
|
|
|
|
.fragmentStoresAndAtomics = true,
|
|
|
|
|
.shaderTessellationAndGeometryPointSize = true,
|
|
|
|
|
.shaderImageGatherExtended = true,
|
|
|
|
|
.shaderStorageImageExtendedFormats = true,
|
|
|
|
|
.shaderStorageImageMultisample = false,
|
|
|
|
|
/* Gfx12.5 has all the required format supported in HW for typed
|
|
|
|
|
* read/writes
|
|
|
|
|
*/
|
|
|
|
|
.shaderStorageImageReadWithoutFormat = pdevice->info.verx10 >= 125,
|
|
|
|
|
.shaderStorageImageWriteWithoutFormat = true,
|
|
|
|
|
.shaderUniformBufferArrayDynamicIndexing = true,
|
|
|
|
|
.shaderSampledImageArrayDynamicIndexing = true,
|
|
|
|
|
.shaderStorageBufferArrayDynamicIndexing = true,
|
|
|
|
|
.shaderStorageImageArrayDynamicIndexing = true,
|
|
|
|
|
.shaderClipDistance = true,
|
|
|
|
|
.shaderCullDistance = true,
|
|
|
|
|
.shaderFloat64 = pdevice->info.has_64bit_float,
|
|
|
|
|
.shaderInt64 = true,
|
|
|
|
|
.shaderInt16 = true,
|
|
|
|
|
.shaderResourceMinLod = true,
|
|
|
|
|
.variableMultisampleRate = true,
|
|
|
|
|
.inheritedQueries = true,
|
2021-07-07 14:32:23 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Vulkan 1.1 */
|
|
|
|
|
.storageBuffer16BitAccess = !pdevice->instance->no_16bit,
|
|
|
|
|
.uniformAndStorageBuffer16BitAccess = !pdevice->instance->no_16bit,
|
|
|
|
|
.storagePushConstant16 = true,
|
|
|
|
|
.storageInputOutput16 = false,
|
|
|
|
|
.multiview = true,
|
|
|
|
|
.multiviewGeometryShader = true,
|
|
|
|
|
.multiviewTessellationShader = true,
|
|
|
|
|
.variablePointersStorageBuffer = true,
|
|
|
|
|
.variablePointers = true,
|
|
|
|
|
.protectedMemory = false,
|
|
|
|
|
.samplerYcbcrConversion = true,
|
|
|
|
|
.shaderDrawParameters = true,
|
2021-02-08 12:23:38 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Vulkan 1.2 */
|
|
|
|
|
.samplerMirrorClampToEdge = true,
|
|
|
|
|
.drawIndirectCount = true,
|
|
|
|
|
.storageBuffer8BitAccess = true,
|
|
|
|
|
.uniformAndStorageBuffer8BitAccess = true,
|
|
|
|
|
.storagePushConstant8 = true,
|
|
|
|
|
.shaderBufferInt64Atomics = true,
|
|
|
|
|
.shaderSharedInt64Atomics = false,
|
|
|
|
|
.shaderFloat16 = !pdevice->instance->no_16bit,
|
|
|
|
|
.shaderInt8 = !pdevice->instance->no_16bit,
|
2022-05-02 12:38:16 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
.descriptorIndexing = true,
|
|
|
|
|
.shaderInputAttachmentArrayDynamicIndexing = false,
|
|
|
|
|
.shaderUniformTexelBufferArrayDynamicIndexing = true,
|
|
|
|
|
.shaderStorageTexelBufferArrayDynamicIndexing = true,
|
|
|
|
|
.shaderUniformBufferArrayNonUniformIndexing = true,
|
|
|
|
|
.shaderSampledImageArrayNonUniformIndexing = true,
|
|
|
|
|
.shaderStorageBufferArrayNonUniformIndexing = true,
|
|
|
|
|
.shaderStorageImageArrayNonUniformIndexing = true,
|
|
|
|
|
.shaderInputAttachmentArrayNonUniformIndexing = false,
|
|
|
|
|
.shaderUniformTexelBufferArrayNonUniformIndexing = true,
|
|
|
|
|
.shaderStorageTexelBufferArrayNonUniformIndexing = true,
|
|
|
|
|
.descriptorBindingUniformBufferUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingSampledImageUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingStorageImageUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingStorageBufferUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingUniformTexelBufferUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingStorageTexelBufferUpdateAfterBind = true,
|
|
|
|
|
.descriptorBindingUpdateUnusedWhilePending = true,
|
|
|
|
|
.descriptorBindingPartiallyBound = true,
|
|
|
|
|
.descriptorBindingVariableDescriptorCount = true,
|
|
|
|
|
.runtimeDescriptorArray = true,
|
2021-08-18 09:40:37 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
.samplerFilterMinmax = true,
|
|
|
|
|
.scalarBlockLayout = true,
|
|
|
|
|
.imagelessFramebuffer = true,
|
|
|
|
|
.uniformBufferStandardLayout = true,
|
|
|
|
|
.shaderSubgroupExtendedTypes = true,
|
|
|
|
|
.separateDepthStencilLayouts = true,
|
|
|
|
|
.hostQueryReset = true,
|
|
|
|
|
.timelineSemaphore = true,
|
|
|
|
|
.bufferDeviceAddress = true,
|
|
|
|
|
.bufferDeviceAddressCaptureReplay = true,
|
|
|
|
|
.bufferDeviceAddressMultiDevice = false,
|
|
|
|
|
.vulkanMemoryModel = true,
|
|
|
|
|
.vulkanMemoryModelDeviceScope = true,
|
|
|
|
|
.vulkanMemoryModelAvailabilityVisibilityChains = true,
|
|
|
|
|
.shaderOutputViewportIndex = true,
|
|
|
|
|
.shaderOutputLayer = true,
|
|
|
|
|
.subgroupBroadcastDynamicId = true,
|
2021-02-08 12:23:38 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Vulkan 1.3 */
|
|
|
|
|
.robustImageAccess = true,
|
|
|
|
|
.inlineUniformBlock = true,
|
|
|
|
|
.descriptorBindingInlineUniformBlockUpdateAfterBind = true,
|
|
|
|
|
.pipelineCreationCacheControl = true,
|
|
|
|
|
.privateData = true,
|
|
|
|
|
.shaderDemoteToHelperInvocation = true,
|
|
|
|
|
.shaderTerminateInvocation = true,
|
|
|
|
|
.subgroupSizeControl = true,
|
|
|
|
|
.computeFullSubgroups = true,
|
|
|
|
|
.synchronization2 = true,
|
|
|
|
|
.textureCompressionASTC_HDR = false,
|
|
|
|
|
.shaderZeroInitializeWorkgroupMemory = true,
|
|
|
|
|
.dynamicRendering = true,
|
|
|
|
|
.shaderIntegerDotProduct = true,
|
|
|
|
|
.maintenance4 = true,
|
2022-05-18 09:52:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_4444_formats */
|
|
|
|
|
.formatA4R4G4B4 = true,
|
|
|
|
|
.formatA4B4G4R4 = false,
|
2021-08-17 18:23:11 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_acceleration_structure */
|
|
|
|
|
.accelerationStructure = rt_enabled,
|
|
|
|
|
.accelerationStructureCaptureReplay = false, /* TODO */
|
|
|
|
|
.accelerationStructureIndirectBuild = false, /* TODO */
|
|
|
|
|
.accelerationStructureHostCommands = false,
|
|
|
|
|
.descriptorBindingAccelerationStructureUpdateAfterBind = rt_enabled,
|
2021-08-17 18:23:11 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_border_color_swizzle */
|
|
|
|
|
.borderColorSwizzle = true,
|
|
|
|
|
.borderColorSwizzleFromImage = true,
|
2021-08-18 09:40:37 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_color_write_enable */
|
|
|
|
|
.colorWriteEnable = true,
|
2017-05-17 10:55:41 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_image_2d_view_of_3d */
|
|
|
|
|
.image2DViewOf3D = true,
|
|
|
|
|
.sampler2DViewOf3D = true,
|
2021-02-08 12:23:38 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_image_sliced_view_of_3d */
|
|
|
|
|
.imageSlicedViewOf3D = true,
|
2017-02-24 16:36:00 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_NV_compute_shader_derivatives */
|
|
|
|
|
.computeDerivativeGroupQuads = true,
|
|
|
|
|
.computeDerivativeGroupLinear = true,
|
2017-02-24 16:36:00 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_conditional_rendering */
|
|
|
|
|
.conditionalRendering = true,
|
|
|
|
|
.inheritedConditionalRendering = true,
|
2017-02-28 10:58:31 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_custom_border_color */
|
|
|
|
|
.customBorderColors = true,
|
|
|
|
|
.customBorderColorWithoutFormat = true,
|
2016-11-24 20:30:38 +00:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_depth_clamp_zero_one */
|
|
|
|
|
.depthClampZeroOne = true,
|
2018-06-29 17:08:30 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_depth_clip_enable */
|
|
|
|
|
.depthClipEnable = true,
|
2018-06-29 17:08:30 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_fragment_shader_interlock */
|
|
|
|
|
.fragmentShaderSampleInterlock = true,
|
|
|
|
|
.fragmentShaderPixelInterlock = true,
|
|
|
|
|
.fragmentShaderShadingRateInterlock = false,
|
2018-06-29 17:08:30 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_global_priority_query */
|
|
|
|
|
.globalPriorityQuery = true,
|
2018-06-29 17:08:30 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_graphics_pipeline_library */
|
2023-05-09 11:53:37 -07:00
|
|
|
.graphicsPipelineLibrary =
|
2023-05-15 15:10:39 -07:00
|
|
|
pdevice->vk.supported_extensions.EXT_graphics_pipeline_library,
|
2021-01-25 12:33:19 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_fragment_shading_rate */
|
|
|
|
|
.pipelineFragmentShadingRate = true,
|
|
|
|
|
.primitiveFragmentShadingRate =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb,
|
|
|
|
|
.attachmentFragmentShadingRate =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb,
|
2021-01-25 12:33:19 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_image_view_min_lod */
|
|
|
|
|
.minLod = true,
|
2021-01-25 12:33:19 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_index_type_uint8 */
|
|
|
|
|
.indexTypeUint8 = true,
|
2019-03-24 01:00:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_line_rasterization */
|
|
|
|
|
/* Rectangular lines must use the strict algorithm, which is not
|
|
|
|
|
* supported for wide lines prior to ICL. See rasterization_mode for
|
|
|
|
|
* details and how the HW states are programmed.
|
|
|
|
|
*/
|
|
|
|
|
.rectangularLines = pdevice->info.ver >= 10,
|
|
|
|
|
.bresenhamLines = true,
|
|
|
|
|
/* Support for Smooth lines with MSAA was removed on gfx11. From the
|
|
|
|
|
* BSpec section "Multisample ModesState" table for "AA Line Support
|
|
|
|
|
* Requirements":
|
|
|
|
|
*
|
|
|
|
|
* GFX10:BUG:######## NUM_MULTISAMPLES == 1
|
|
|
|
|
*
|
|
|
|
|
* Fortunately, this isn't a case most people care about.
|
|
|
|
|
*/
|
|
|
|
|
.smoothLines = pdevice->info.ver < 10,
|
|
|
|
|
.stippledRectangularLines = false,
|
|
|
|
|
.stippledBresenhamLines = true,
|
|
|
|
|
.stippledSmoothLines = false,
|
2021-01-26 10:38:47 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_NV_mesh_shader */
|
|
|
|
|
.taskShaderNV = mesh_shader,
|
|
|
|
|
.meshShaderNV = mesh_shader,
|
2021-01-25 12:33:19 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_mesh_shader */
|
|
|
|
|
.taskShader = mesh_shader,
|
|
|
|
|
.meshShader = mesh_shader,
|
|
|
|
|
.multiviewMeshShader = false,
|
|
|
|
|
.primitiveFragmentShadingRateMeshShader = mesh_shader,
|
|
|
|
|
.meshShaderQueries = false,
|
2021-01-26 01:13:36 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_mutable_descriptor_type */
|
|
|
|
|
.mutableDescriptorType = true,
|
2022-08-08 13:26:59 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_performance_query */
|
|
|
|
|
.performanceCounterQueryPools = true,
|
|
|
|
|
/* HW only supports a single configuration at a time. */
|
|
|
|
|
.performanceCounterMultipleQueryPools = false,
|
2022-07-26 11:40:03 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_pipeline_executable_properties */
|
|
|
|
|
.pipelineExecutableInfo = true,
|
2022-07-26 11:40:03 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_primitives_generated_query */
|
|
|
|
|
.primitivesGeneratedQuery = true,
|
|
|
|
|
.primitivesGeneratedQueryWithRasterizerDiscard = false,
|
|
|
|
|
.primitivesGeneratedQueryWithNonZeroStreams = false,
|
2015-07-21 13:09:25 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_pipeline_library_group_handles */
|
|
|
|
|
.pipelineLibraryGroupHandles = true,
|
2017-08-29 08:44:54 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_provoking_vertex */
|
|
|
|
|
.provokingVertexLast = true,
|
|
|
|
|
.transformFeedbackPreservesProvokingVertex = true,
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_ray_query */
|
|
|
|
|
.rayQuery = rt_enabled,
|
2018-10-14 13:12:50 +01:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_ray_tracing_maintenance1 */
|
|
|
|
|
.rayTracingMaintenance1 = rt_enabled,
|
|
|
|
|
.rayTracingPipelineTraceRaysIndirect2 = rt_enabled,
|
2020-01-17 23:52:50 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_ray_tracing_pipeline */
|
|
|
|
|
.rayTracingPipeline = rt_enabled,
|
|
|
|
|
.rayTracingPipelineShaderGroupHandleCaptureReplay = false,
|
|
|
|
|
.rayTracingPipelineShaderGroupHandleCaptureReplayMixed = false,
|
|
|
|
|
.rayTracingPipelineTraceRaysIndirect = rt_enabled,
|
|
|
|
|
.rayTraversalPrimitiveCulling = rt_enabled,
|
2015-11-02 12:14:37 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_robustness2 */
|
|
|
|
|
.robustBufferAccess2 = true,
|
|
|
|
|
.robustImageAccess2 = true,
|
|
|
|
|
.nullDescriptor = true,
|
2021-01-23 04:57:21 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_shader_atomic_float */
|
|
|
|
|
.shaderBufferFloat32Atomics = true,
|
|
|
|
|
.shaderBufferFloat32AtomicAdd = pdevice->info.has_lsc,
|
|
|
|
|
.shaderBufferFloat64Atomics =
|
|
|
|
|
pdevice->info.has_64bit_float && pdevice->info.has_lsc,
|
|
|
|
|
.shaderBufferFloat64AtomicAdd = false,
|
|
|
|
|
.shaderSharedFloat32Atomics = true,
|
|
|
|
|
.shaderSharedFloat32AtomicAdd = false,
|
|
|
|
|
.shaderSharedFloat64Atomics = false,
|
|
|
|
|
.shaderSharedFloat64AtomicAdd = false,
|
|
|
|
|
.shaderImageFloat32Atomics = true,
|
|
|
|
|
.shaderImageFloat32AtomicAdd = false,
|
|
|
|
|
.sparseImageFloat32Atomics = false,
|
|
|
|
|
.sparseImageFloat32AtomicAdd = false,
|
2020-01-17 23:48:12 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_shader_atomic_float2 */
|
|
|
|
|
.shaderBufferFloat16Atomics = pdevice->info.has_lsc,
|
|
|
|
|
.shaderBufferFloat16AtomicAdd = false,
|
|
|
|
|
.shaderBufferFloat16AtomicMinMax = pdevice->info.has_lsc,
|
|
|
|
|
.shaderBufferFloat32AtomicMinMax = true,
|
|
|
|
|
.shaderBufferFloat64AtomicMinMax =
|
|
|
|
|
pdevice->info.has_64bit_float && pdevice->info.has_lsc,
|
|
|
|
|
.shaderSharedFloat16Atomics = pdevice->info.has_lsc,
|
|
|
|
|
.shaderSharedFloat16AtomicAdd = false,
|
|
|
|
|
.shaderSharedFloat16AtomicMinMax = pdevice->info.has_lsc,
|
|
|
|
|
.shaderSharedFloat32AtomicMinMax = true,
|
|
|
|
|
.shaderSharedFloat64AtomicMinMax = false,
|
|
|
|
|
.shaderImageFloat32AtomicMinMax = false,
|
|
|
|
|
.sparseImageFloat32AtomicMinMax = false,
|
2020-01-17 23:48:12 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_shader_clock */
|
|
|
|
|
.shaderSubgroupClock = true,
|
|
|
|
|
.shaderDeviceClock = false,
|
2020-01-17 23:48:12 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_INTEL_shader_integer_functions2 */
|
|
|
|
|
.shaderIntegerFunctions2 = true,
|
2018-01-23 14:01:00 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_shader_module_identifier */
|
|
|
|
|
.shaderModuleIdentifier = true,
|
2021-11-03 08:59:53 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_shader_subgroup_uniform_control_flow */
|
|
|
|
|
.shaderSubgroupUniformControlFlow = true,
|
2021-11-03 08:59:53 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_texel_buffer_alignment */
|
|
|
|
|
.texelBufferAlignment = true,
|
2020-12-16 14:09:55 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_transform_feedback */
|
|
|
|
|
.transformFeedback = true,
|
|
|
|
|
.geometryStreams = true,
|
2019-11-25 21:55:51 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_vertex_attribute_divisor */
|
|
|
|
|
.vertexAttributeInstanceRateDivisor = true,
|
|
|
|
|
.vertexAttributeInstanceRateZeroDivisor = true,
|
2019-08-06 15:56:40 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_KHR_workgroup_memory_explicit_layout */
|
|
|
|
|
.workgroupMemoryExplicitLayout = true,
|
|
|
|
|
.workgroupMemoryExplicitLayoutScalarBlockLayout = true,
|
|
|
|
|
.workgroupMemoryExplicitLayout8BitAccess = true,
|
|
|
|
|
.workgroupMemoryExplicitLayout16BitAccess = true,
|
2022-02-25 16:56:04 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_ycbcr_image_arrays */
|
|
|
|
|
.ycbcrImageArrays = true,
|
2022-02-25 16:56:04 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_extended_dynamic_state */
|
|
|
|
|
.extendedDynamicState = true,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_extended_dynamic_state2 */
|
|
|
|
|
.extendedDynamicState2 = true,
|
|
|
|
|
.extendedDynamicState2LogicOp = true,
|
|
|
|
|
.extendedDynamicState2PatchControlPoints = false,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_extended_dynamic_state3 */
|
|
|
|
|
.extendedDynamicState3PolygonMode = true,
|
|
|
|
|
.extendedDynamicState3TessellationDomainOrigin = true,
|
|
|
|
|
.extendedDynamicState3RasterizationStream = true,
|
|
|
|
|
.extendedDynamicState3LineStippleEnable = true,
|
|
|
|
|
.extendedDynamicState3LineRasterizationMode = true,
|
|
|
|
|
.extendedDynamicState3LogicOpEnable = true,
|
|
|
|
|
.extendedDynamicState3AlphaToOneEnable = true,
|
|
|
|
|
.extendedDynamicState3DepthClipEnable = true,
|
|
|
|
|
.extendedDynamicState3DepthClampEnable = true,
|
|
|
|
|
.extendedDynamicState3DepthClipNegativeOneToOne = true,
|
|
|
|
|
.extendedDynamicState3ProvokingVertexMode = true,
|
|
|
|
|
.extendedDynamicState3ColorBlendEnable = true,
|
|
|
|
|
.extendedDynamicState3ColorWriteMask = true,
|
|
|
|
|
.extendedDynamicState3ColorBlendEquation = true,
|
|
|
|
|
.extendedDynamicState3SampleLocationsEnable = true,
|
|
|
|
|
.extendedDynamicState3SampleMask = true,
|
|
|
|
|
|
|
|
|
|
.extendedDynamicState3RasterizationSamples = false,
|
|
|
|
|
.extendedDynamicState3AlphaToCoverageEnable = false,
|
|
|
|
|
.extendedDynamicState3ConservativeRasterizationMode = false,
|
|
|
|
|
.extendedDynamicState3ExtraPrimitiveOverestimationSize = false,
|
|
|
|
|
.extendedDynamicState3ViewportWScalingEnable = false,
|
|
|
|
|
.extendedDynamicState3ViewportSwizzle = false,
|
|
|
|
|
.extendedDynamicState3ShadingRateImageEnable = false,
|
|
|
|
|
.extendedDynamicState3CoverageToColorEnable = false,
|
|
|
|
|
.extendedDynamicState3CoverageToColorLocation = false,
|
|
|
|
|
.extendedDynamicState3CoverageModulationMode = false,
|
|
|
|
|
.extendedDynamicState3CoverageModulationTableEnable = false,
|
|
|
|
|
.extendedDynamicState3CoverageModulationTable = false,
|
|
|
|
|
.extendedDynamicState3CoverageReductionMode = false,
|
|
|
|
|
.extendedDynamicState3RepresentativeFragmentTestEnable = false,
|
|
|
|
|
.extendedDynamicState3ColorBlendAdvanced = false,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_multi_draw */
|
|
|
|
|
.multiDraw = true,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_non_seamless_cube_map */
|
|
|
|
|
.nonSeamlessCubeMap = true,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_primitive_topology_list_restart */
|
|
|
|
|
.primitiveTopologyListRestart = true,
|
|
|
|
|
.primitiveTopologyPatchListRestart = true,
|
|
|
|
|
|
|
|
|
|
/* VK_EXT_depth_clip_control */
|
|
|
|
|
.depthClipControl = true,
|
|
|
|
|
|
|
|
|
|
/* VK_KHR_present_id */
|
|
|
|
|
.presentId = pdevice->vk.supported_extensions.KHR_present_id,
|
|
|
|
|
|
|
|
|
|
/* VK_KHR_present_wait */
|
|
|
|
|
.presentWait = pdevice->vk.supported_extensions.KHR_present_wait,
|
2023-04-06 15:57:43 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* VK_EXT_vertex_input_dynamic_state */
|
|
|
|
|
.vertexInputDynamicState = true,
|
2022-12-01 23:30:59 +02:00
|
|
|
|
|
|
|
|
/* VK_KHR_ray_tracing_position_fetch */
|
|
|
|
|
.rayTracingPositionFetch = rt_enabled,
|
2023-04-29 02:09:16 +03:00
|
|
|
};
|
2021-11-12 09:51:59 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* The new DOOM and Wolfenstein games require depthBounds without
|
|
|
|
|
* checking for it. They seem to run fine without it so just claim it's
|
|
|
|
|
* there and accept the consequences.
|
|
|
|
|
*/
|
|
|
|
|
if (app_info->engine_name && strcmp(app_info->engine_name, "idTech") == 0)
|
|
|
|
|
features->depthBounds = true;
|
|
|
|
|
}
|
2021-11-12 09:51:59 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static uint64_t
|
|
|
|
|
anv_compute_sys_heap_size(struct anv_physical_device *device,
|
|
|
|
|
uint64_t total_ram)
|
|
|
|
|
{
|
|
|
|
|
/* We don't want to burn too much ram with the GPU. If the user has 4GiB
|
|
|
|
|
* or less, we use at most half. If they have more than 4GiB, we use 3/4.
|
|
|
|
|
*/
|
|
|
|
|
uint64_t available_ram;
|
|
|
|
|
if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
|
|
|
|
|
available_ram = total_ram / 2;
|
|
|
|
|
else
|
|
|
|
|
available_ram = total_ram * 3 / 4;
|
2022-09-15 06:46:23 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* We also want to leave some padding for things we allocate in the driver,
|
|
|
|
|
* so don't go over 3/4 of the GTT either.
|
|
|
|
|
*/
|
|
|
|
|
available_ram = MIN2(available_ram, device->gtt_size * 3 / 4);
|
2021-11-12 09:51:59 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return available_ram;
|
|
|
|
|
}
|
2021-10-04 13:38:19 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static VkResult MUST_CHECK
|
|
|
|
|
anv_init_meminfo(struct anv_physical_device *device, int fd)
|
|
|
|
|
{
|
|
|
|
|
const struct intel_device_info *devinfo = &device->info;
|
2019-02-25 13:59:07 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->sys.region = &devinfo->mem.sram.mem;
|
|
|
|
|
device->sys.size =
|
|
|
|
|
anv_compute_sys_heap_size(device, devinfo->mem.sram.mappable.size);
|
|
|
|
|
device->sys.available = devinfo->mem.sram.mappable.free;
|
2020-06-08 20:33:14 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->vram_mappable.region = &devinfo->mem.vram.mem;
|
|
|
|
|
device->vram_mappable.size = devinfo->mem.vram.mappable.size;
|
|
|
|
|
device->vram_mappable.available = devinfo->mem.vram.mappable.free;
|
2023-02-08 17:24:28 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->vram_non_mappable.region = &devinfo->mem.vram.mem;
|
|
|
|
|
device->vram_non_mappable.size = devinfo->mem.vram.unmappable.size;
|
|
|
|
|
device->vram_non_mappable.available = devinfo->mem.vram.unmappable.free;
|
2020-01-22 15:29:51 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2019-05-15 11:30:36 +01:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static void
|
|
|
|
|
anv_update_meminfo(struct anv_physical_device *device, int fd)
|
|
|
|
|
{
|
|
|
|
|
if (!intel_device_info_update_memory_info(&device->info, fd))
|
|
|
|
|
return;
|
2019-11-11 12:46:33 -06:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
const struct intel_device_info *devinfo = &device->info;
|
|
|
|
|
device->sys.available = devinfo->mem.sram.mappable.free;
|
|
|
|
|
device->vram_mappable.available = devinfo->mem.vram.mappable.free;
|
|
|
|
|
device->vram_non_mappable.available = devinfo->mem.vram.unmappable.free;
|
|
|
|
|
}
|
2015-10-19 20:21:45 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static VkResult
|
|
|
|
|
anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
|
|
|
|
|
{
|
|
|
|
|
VkResult result = anv_init_meminfo(device, fd);
|
2017-02-28 10:58:31 -08:00
|
|
|
if (result != VK_SUCCESS)
|
2023-04-29 02:09:16 +03:00
|
|
|
return result;
|
2017-02-28 10:58:31 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
assert(device->sys.size != 0);
|
2018-06-29 17:08:30 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (anv_physical_device_has_vram(device)) {
|
|
|
|
|
/* We can create 2 or 3 different heaps when we have local memory
|
|
|
|
|
* support, first heap with local memory size and second with system
|
|
|
|
|
* memory size and the third is added only if part of the vram is
|
|
|
|
|
* mappable to the host.
|
|
|
|
|
*/
|
|
|
|
|
device->memory.heap_count = 2;
|
|
|
|
|
device->memory.heaps[0] = (struct anv_memory_heap) {
|
|
|
|
|
/* If there is a vram_non_mappable, use that for the device only
|
|
|
|
|
* heap. Otherwise use the vram_mappable.
|
|
|
|
|
*/
|
|
|
|
|
.size = device->vram_non_mappable.size != 0 ?
|
|
|
|
|
device->vram_non_mappable.size : device->vram_mappable.size,
|
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
.is_local_mem = true,
|
|
|
|
|
};
|
|
|
|
|
device->memory.heaps[1] = (struct anv_memory_heap) {
|
|
|
|
|
.size = device->sys.size,
|
|
|
|
|
.flags = 0,
|
|
|
|
|
.is_local_mem = false,
|
|
|
|
|
};
|
|
|
|
|
/* Add an additional smaller vram mappable heap if we can't map all the
|
|
|
|
|
* vram to the host.
|
|
|
|
|
*/
|
|
|
|
|
if (device->vram_non_mappable.size > 0) {
|
|
|
|
|
device->memory.heap_count++;
|
|
|
|
|
device->memory.heaps[2] = (struct anv_memory_heap) {
|
|
|
|
|
.size = device->vram_mappable.size,
|
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
.is_local_mem = true,
|
|
|
|
|
};
|
2018-02-07 10:31:44 -08:00
|
|
|
}
|
2023-04-29 02:09:16 +03:00
|
|
|
} else {
|
|
|
|
|
device->memory.heap_count = 1;
|
|
|
|
|
device->memory.heaps[0] = (struct anv_memory_heap) {
|
|
|
|
|
.size = device->sys.size,
|
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
.is_local_mem = false,
|
|
|
|
|
};
|
2023-04-27 14:14:22 -07:00
|
|
|
}
|
2022-07-06 19:51:03 -05:00
|
|
|
|
2023-04-27 14:14:22 -07:00
|
|
|
switch (device->info.kmd_type) {
|
|
|
|
|
case INTEL_KMD_TYPE_XE:
|
|
|
|
|
result = anv_xe_physical_device_init_memory_types(device);
|
|
|
|
|
break;
|
|
|
|
|
case INTEL_KMD_TYPE_I915:
|
|
|
|
|
default:
|
|
|
|
|
result = anv_i915_physical_device_init_memory_types(device);
|
|
|
|
|
break;
|
2023-04-29 02:09:16 +03:00
|
|
|
}
|
|
|
|
|
|
2023-04-27 14:14:22 -07:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
for (unsigned i = 0; i < device->memory.type_count; i++) {
|
|
|
|
|
VkMemoryPropertyFlags props = device->memory.types[i].propertyFlags;
|
|
|
|
|
if ((props & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) &&
|
|
|
|
|
!(props & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
|
|
|
|
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
|
|
|
|
|
device->memory.need_clflush = true;
|
|
|
|
|
#else
|
|
|
|
|
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
|
|
|
|
|
"Memory configuration requires flushing, but it's not implemented for this architecture");
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2022-07-06 19:51:03 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2021-06-27 19:29:08 +00:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static VkResult
|
|
|
|
|
anv_physical_device_init_uuids(struct anv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
const struct build_id_note *note =
|
|
|
|
|
build_id_find_nhdr_for_addr(anv_physical_device_init_uuids);
|
|
|
|
|
if (!note) {
|
|
|
|
|
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
|
|
|
|
|
"Failed to find build-id");
|
2021-06-27 19:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
unsigned build_id_len = build_id_length(note);
|
|
|
|
|
if (build_id_len < 20) {
|
|
|
|
|
return vk_errorf(device, VK_ERROR_INITIALIZATION_FAILED,
|
|
|
|
|
"build-id too short. It needs to be a SHA");
|
2021-06-27 19:29:08 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
memcpy(device->driver_build_sha1, build_id_data(note), 20);
|
2022-10-21 12:25:18 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
struct mesa_sha1 sha1_ctx;
|
|
|
|
|
uint8_t sha1[20];
|
|
|
|
|
STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));
|
2022-10-21 12:25:18 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* The pipeline cache UUID is used for determining when a pipeline cache is
|
|
|
|
|
* invalid. It needs both a driver build and the PCI ID of the device.
|
|
|
|
|
*/
|
|
|
|
|
_mesa_sha1_init(&sha1_ctx);
|
|
|
|
|
_mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
|
|
|
|
|
_mesa_sha1_update(&sha1_ctx, &device->info.pci_device_id,
|
|
|
|
|
sizeof(device->info.pci_device_id));
|
|
|
|
|
_mesa_sha1_update(&sha1_ctx, &device->always_use_bindless,
|
|
|
|
|
sizeof(device->always_use_bindless));
|
|
|
|
|
_mesa_sha1_final(&sha1_ctx, sha1);
|
|
|
|
|
memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE);
|
2022-10-21 12:25:18 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
intel_uuid_compute_driver_id(device->driver_uuid, &device->info, VK_UUID_SIZE);
|
|
|
|
|
intel_uuid_compute_device_id(device->device_uuid, &device->info, VK_UUID_SIZE);
|
2022-10-21 12:25:18 +03:00
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-19 20:21:45 -07:00
|
|
|
static void
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_physical_device_init_disk_cache(struct anv_physical_device *device)
|
2015-10-19 20:21:45 -07:00
|
|
|
{
|
2023-04-29 02:09:16 +03:00
|
|
|
#ifdef ENABLE_SHADER_CACHE
|
|
|
|
|
char renderer[10];
|
|
|
|
|
ASSERTED int len = snprintf(renderer, sizeof(renderer), "anv_%04x",
|
|
|
|
|
device->info.pci_device_id);
|
|
|
|
|
assert(len == sizeof(renderer) - 2);
|
2022-07-26 11:40:03 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
char timestamp[41];
|
|
|
|
|
_mesa_sha1_format(timestamp, device->driver_build_sha1);
|
|
|
|
|
|
|
|
|
|
const uint64_t driver_flags =
|
|
|
|
|
brw_get_compiler_config_value(device->compiler);
|
|
|
|
|
device->vk.disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
|
|
|
|
|
#endif
|
2015-10-19 20:21:45 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static void
|
|
|
|
|
anv_physical_device_free_disk_cache(struct anv_physical_device *device)
|
2018-01-16 15:49:28 -08:00
|
|
|
{
|
2023-04-29 02:09:16 +03:00
|
|
|
#ifdef ENABLE_SHADER_CACHE
|
|
|
|
|
if (device->vk.disk_cache) {
|
|
|
|
|
disk_cache_destroy(device->vk.disk_cache);
|
|
|
|
|
device->vk.disk_cache = NULL;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
assert(device->vk.disk_cache == NULL);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
2018-01-16 15:49:28 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* The ANV_QUEUE_OVERRIDE environment variable is a comma separated list of
|
|
|
|
|
* queue overrides.
|
|
|
|
|
*
|
|
|
|
|
* To override the number queues:
|
|
|
|
|
* * "gc" is for graphics queues with compute support
|
|
|
|
|
* * "g" is for graphics queues with no compute support
|
|
|
|
|
* * "c" is for compute queues with no graphics support
|
|
|
|
|
* * "v" is for video queues with no graphics support
|
|
|
|
|
*
|
|
|
|
|
* For example, ANV_QUEUE_OVERRIDE=gc=2,c=1 would override the number of
|
|
|
|
|
* advertised queues to be 2 queues with graphics+compute support, and 1 queue
|
|
|
|
|
* with compute-only support.
|
|
|
|
|
*
|
|
|
|
|
* ANV_QUEUE_OVERRIDE=c=1 would override the number of advertised queues to
|
|
|
|
|
* include 1 queue with compute-only support, but it will not change the
|
|
|
|
|
* number of graphics+compute queues.
|
|
|
|
|
*
|
|
|
|
|
* ANV_QUEUE_OVERRIDE=gc=0,c=1 would override the number of advertised queues
|
|
|
|
|
* to include 1 queue with compute-only support, and it would override the
|
|
|
|
|
* number of graphics+compute queues to be 0.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
anv_override_engine_counts(int *gc_count, int *g_count, int *c_count, int *v_count)
|
|
|
|
|
{
|
|
|
|
|
int gc_override = -1;
|
|
|
|
|
int g_override = -1;
|
|
|
|
|
int c_override = -1;
|
|
|
|
|
int v_override = -1;
|
|
|
|
|
char *env = getenv("ANV_QUEUE_OVERRIDE");
|
|
|
|
|
|
|
|
|
|
if (env == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
env = strdup(env);
|
|
|
|
|
char *save = NULL;
|
|
|
|
|
char *next = strtok_r(env, ",", &save);
|
|
|
|
|
while (next != NULL) {
|
|
|
|
|
if (strncmp(next, "gc=", 3) == 0) {
|
|
|
|
|
gc_override = strtol(next + 3, NULL, 0);
|
|
|
|
|
} else if (strncmp(next, "g=", 2) == 0) {
|
|
|
|
|
g_override = strtol(next + 2, NULL, 0);
|
|
|
|
|
} else if (strncmp(next, "c=", 2) == 0) {
|
|
|
|
|
c_override = strtol(next + 2, NULL, 0);
|
|
|
|
|
} else if (strncmp(next, "v=", 2) == 0) {
|
|
|
|
|
v_override = strtol(next + 2, NULL, 0);
|
|
|
|
|
} else {
|
|
|
|
|
mesa_logw("Ignoring unsupported ANV_QUEUE_OVERRIDE token: %s", next);
|
|
|
|
|
}
|
|
|
|
|
next = strtok_r(NULL, ",", &save);
|
|
|
|
|
}
|
|
|
|
|
free(env);
|
|
|
|
|
if (gc_override >= 0)
|
|
|
|
|
*gc_count = gc_override;
|
|
|
|
|
if (g_override >= 0)
|
|
|
|
|
*g_count = g_override;
|
|
|
|
|
if (*g_count > 0 && *gc_count <= 0 && (gc_override >= 0 || g_override >= 0))
|
|
|
|
|
mesa_logw("ANV_QUEUE_OVERRIDE: gc=0 with g > 0 violates the "
|
|
|
|
|
"Vulkan specification");
|
|
|
|
|
if (c_override >= 0)
|
|
|
|
|
*c_count = c_override;
|
|
|
|
|
if (v_override >= 0)
|
|
|
|
|
*v_count = v_override;
|
2018-01-16 15:49:28 -08:00
|
|
|
}
|
|
|
|
|
|
2020-09-14 12:21:41 -07:00
|
|
|
static void
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_physical_device_init_queue_families(struct anv_physical_device *pdevice)
|
2020-09-14 12:21:41 -07:00
|
|
|
{
|
2023-04-29 02:09:16 +03:00
|
|
|
uint32_t family_count = 0;
|
2022-03-31 16:44:15 +03:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (pdevice->engine_info) {
|
|
|
|
|
int gc_count =
|
|
|
|
|
intel_engines_count(pdevice->engine_info,
|
|
|
|
|
INTEL_ENGINE_CLASS_RENDER);
|
|
|
|
|
int v_count =
|
|
|
|
|
intel_engines_count(pdevice->engine_info, INTEL_ENGINE_CLASS_VIDEO);
|
|
|
|
|
int g_count = 0;
|
|
|
|
|
int c_count = 0;
|
|
|
|
|
if (debug_get_bool_option("INTEL_COMPUTE_CLASS", false))
|
|
|
|
|
c_count = intel_engines_count(pdevice->engine_info,
|
|
|
|
|
INTEL_ENGINE_CLASS_COMPUTE);
|
|
|
|
|
enum intel_engine_class compute_class =
|
|
|
|
|
c_count < 1 ? INTEL_ENGINE_CLASS_RENDER : INTEL_ENGINE_CLASS_COMPUTE;
|
|
|
|
|
|
|
|
|
|
anv_override_engine_counts(&gc_count, &g_count, &c_count, &v_count);
|
|
|
|
|
|
|
|
|
|
if (gc_count > 0) {
|
|
|
|
|
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
|
|
|
|
|
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
|
|
|
|
|
VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT,
|
|
|
|
|
.queueCount = gc_count,
|
|
|
|
|
.engine_class = INTEL_ENGINE_CLASS_RENDER,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (g_count > 0) {
|
|
|
|
|
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
|
|
|
|
|
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT,
|
|
|
|
|
.queueCount = g_count,
|
|
|
|
|
.engine_class = INTEL_ENGINE_CLASS_RENDER,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (c_count > 0) {
|
|
|
|
|
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
|
|
|
|
|
.queueFlags = VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT,
|
|
|
|
|
.queueCount = c_count,
|
|
|
|
|
.engine_class = compute_class,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (v_count > 0 && pdevice->video_decode_enabled) {
|
|
|
|
|
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
|
|
|
|
|
.queueFlags = VK_QUEUE_VIDEO_DECODE_BIT_KHR,
|
|
|
|
|
.queueCount = v_count,
|
|
|
|
|
.engine_class = INTEL_ENGINE_CLASS_VIDEO,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
/* Increase count below when other families are added as a reminder to
|
|
|
|
|
* increase the ANV_MAX_QUEUE_FAMILIES value.
|
|
|
|
|
*/
|
|
|
|
|
STATIC_ASSERT(ANV_MAX_QUEUE_FAMILIES >= 4);
|
|
|
|
|
} else {
|
|
|
|
|
/* Default to a single render queue */
|
|
|
|
|
pdevice->queue.families[family_count++] = (struct anv_queue_family) {
|
|
|
|
|
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
|
|
|
|
|
VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT,
|
|
|
|
|
.queueCount = 1,
|
|
|
|
|
.engine_class = INTEL_ENGINE_CLASS_RENDER,
|
|
|
|
|
};
|
|
|
|
|
family_count = 1;
|
|
|
|
|
}
|
|
|
|
|
assert(family_count <= ANV_MAX_QUEUE_FAMILIES);
|
|
|
|
|
pdevice->queue.family_count = family_count;
|
2020-09-14 12:21:41 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static VkResult
|
|
|
|
|
anv_physical_device_get_parameters(struct anv_physical_device *device)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2023-04-29 02:09:16 +03:00
|
|
|
switch (device->info.kmd_type) {
|
|
|
|
|
case INTEL_KMD_TYPE_I915:
|
|
|
|
|
return anv_i915_physical_device_get_parameters(device);
|
|
|
|
|
case INTEL_KMD_TYPE_XE:
|
|
|
|
|
return anv_xe_physical_device_get_parameters(device);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Missing");
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
2018-01-16 18:08:09 -08:00
|
|
|
}
|
2023-04-29 02:09:16 +03:00
|
|
|
}
|
2018-01-16 18:08:09 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static VkResult
|
|
|
|
|
anv_physical_device_try_create(struct vk_instance *vk_instance,
|
|
|
|
|
struct _drmDevice *drm_device,
|
|
|
|
|
struct vk_physical_device **out)
|
|
|
|
|
{
|
|
|
|
|
struct anv_instance *instance =
|
|
|
|
|
container_of(vk_instance, struct anv_instance, vk);
|
2019-04-24 16:42:25 +01:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (!(drm_device->available_nodes & (1 << DRM_NODE_RENDER)) ||
|
|
|
|
|
drm_device->bustype != DRM_BUS_PCI ||
|
|
|
|
|
drm_device->deviceinfo.pci->vendor_id != 0x8086)
|
|
|
|
|
return VK_ERROR_INCOMPATIBLE_DRIVER;
|
2021-11-21 18:23:57 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
|
|
|
|
|
const char *path = drm_device->nodes[DRM_NODE_RENDER];
|
|
|
|
|
VkResult result;
|
|
|
|
|
int fd;
|
|
|
|
|
int master_fd = -1;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
brw_process_intel_debug_variable();
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
fd = open(path, O_RDWR | O_CLOEXEC);
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
if (errno == ENOMEM) {
|
|
|
|
|
return vk_errorf(instance, VK_ERROR_OUT_OF_HOST_MEMORY,
|
|
|
|
|
"Unable to open device %s: out of memory", path);
|
|
|
|
|
}
|
|
|
|
|
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
|
|
|
|
|
"Unable to open device %s: %m", path);
|
|
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
struct intel_device_info devinfo;
|
|
|
|
|
if (!intel_get_device_info_from_fd(fd, &devinfo)) {
|
|
|
|
|
result = vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
}
|
2017-03-01 08:39:49 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (devinfo.ver > 12) {
|
|
|
|
|
result = vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
|
|
|
|
|
"Vulkan not yet supported on %s", devinfo.name);
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
} else if (devinfo.ver < 9) {
|
|
|
|
|
/* Silently fail here, hasvk should pick up this device. */
|
|
|
|
|
result = VK_ERROR_INCOMPATIBLE_DRIVER;
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
}
|
2015-07-31 10:18:00 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
struct anv_physical_device *device =
|
|
|
|
|
vk_zalloc(&instance->vk.alloc, sizeof(*device), 8,
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
|
|
|
|
if (device == NULL) {
|
|
|
|
|
result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
}
|
2019-04-24 16:42:25 +01:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
struct vk_physical_device_dispatch_table dispatch_table;
|
|
|
|
|
vk_physical_device_dispatch_table_from_entrypoints(
|
|
|
|
|
&dispatch_table, &anv_physical_device_entrypoints, true);
|
|
|
|
|
vk_physical_device_dispatch_table_from_entrypoints(
|
|
|
|
|
&dispatch_table, &wsi_physical_device_entrypoints, false);
|
2015-07-31 10:13:24 -07:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
result = vk_physical_device_init(&device->vk, &instance->vk,
|
|
|
|
|
NULL, NULL, /* We set up extensions later */
|
|
|
|
|
&dispatch_table);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
vk_error(instance, result);
|
|
|
|
|
goto fail_alloc;
|
|
|
|
|
}
|
|
|
|
|
device->instance = instance;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
assert(strlen(path) < ARRAY_SIZE(device->path));
|
|
|
|
|
snprintf(device->path, ARRAY_SIZE(device->path), "%s", path);
|
2021-10-05 16:19:49 -05:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->info = devinfo;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->local_fd = fd;
|
|
|
|
|
result = anv_physical_device_get_parameters(device);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_base;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->gtt_size = device->info.gtt_size ? device->info.gtt_size :
|
|
|
|
|
device->info.aperture_bytes;
|
2016-04-15 14:53:16 -07:00
|
|
|
|
2023-02-23 09:16:40 +02:00
|
|
|
if (device->gtt_size < (4ULL << 30 /* GiB */)) {
|
|
|
|
|
vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
|
2023-05-05 21:45:45 -07:00
|
|
|
"GTT size too small: 0x%016"PRIx64, device->gtt_size);
|
2023-02-23 09:16:40 +02:00
|
|
|
goto fail_base;
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* We currently only have the right bits for instructions in Gen12+. If the
|
|
|
|
|
* kernel ever starts supporting that feature on previous generations,
|
|
|
|
|
* we'll need to edit genxml prior to enabling here.
|
|
|
|
|
*/
|
|
|
|
|
device->has_protected_contexts = device->info.ver >= 12 &&
|
|
|
|
|
intel_gem_supports_protected_context(fd, device->info.kmd_type);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
result = anv_physical_device_init_heaps(device, fd);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_base;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (debug_get_bool_option("ANV_QUEUE_THREAD_DISABLE", false))
|
|
|
|
|
device->has_exec_timeline = false;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->generated_indirect_draws =
|
|
|
|
|
debug_get_bool_option("ANV_ENABLE_GENERATED_INDIRECT_DRAWS",
|
|
|
|
|
true);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
unsigned st_idx = 0;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->sync_syncobj_type = vk_drm_syncobj_get_type(fd);
|
|
|
|
|
if (!device->has_exec_timeline)
|
|
|
|
|
device->sync_syncobj_type.features &= ~VK_SYNC_FEATURE_TIMELINE;
|
|
|
|
|
device->sync_types[st_idx++] = &device->sync_syncobj_type;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* anv_bo_sync_type is only supported with i915 for now */
|
|
|
|
|
if (device->info.kmd_type == INTEL_KMD_TYPE_I915) {
|
|
|
|
|
if (!(device->sync_syncobj_type.features & VK_SYNC_FEATURE_CPU_WAIT))
|
|
|
|
|
device->sync_types[st_idx++] = &anv_bo_sync_type;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (!(device->sync_syncobj_type.features & VK_SYNC_FEATURE_TIMELINE)) {
|
|
|
|
|
device->sync_timeline_type = vk_sync_timeline_get_type(&anv_bo_sync_type);
|
|
|
|
|
device->sync_types[st_idx++] = &device->sync_timeline_type.sync;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
assert(device->sync_syncobj_type.features & VK_SYNC_FEATURE_TIMELINE);
|
|
|
|
|
assert(device->sync_syncobj_type.features & VK_SYNC_FEATURE_CPU_WAIT);
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->sync_types[st_idx++] = NULL;
|
|
|
|
|
assert(st_idx <= ARRAY_SIZE(device->sync_types));
|
|
|
|
|
device->vk.supported_sync_types = device->sync_types;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->vk.pipeline_cache_import_ops = anv_cache_import_ops;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->always_use_bindless =
|
|
|
|
|
debug_get_bool_option("ANV_ALWAYS_BINDLESS", false);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->use_call_secondary =
|
|
|
|
|
!debug_get_bool_option("ANV_DISABLE_SECONDARY_CMD_BUFFER_CALLS", false);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->has_implicit_ccs = device->info.has_aux_map ||
|
|
|
|
|
device->info.verx10 >= 125;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->video_decode_enabled = debug_get_bool_option("ANV_VIDEO_DECODE", false);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Check if we can read the GPU timestamp register from the CPU */
|
|
|
|
|
uint64_t u64_ignore;
|
|
|
|
|
device->has_reg_timestamp = intel_gem_read_render_timestamp(fd,
|
|
|
|
|
device->info.kmd_type,
|
|
|
|
|
&u64_ignore);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->always_flush_cache = INTEL_DEBUG(DEBUG_STALL) ||
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "always_flush_cache");
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->compiler = brw_compiler_create(NULL, &device->info);
|
|
|
|
|
if (device->compiler == NULL) {
|
|
|
|
|
result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
goto fail_base;
|
|
|
|
|
}
|
|
|
|
|
device->compiler->shader_debug_log = compiler_debug_log;
|
|
|
|
|
device->compiler->shader_perf_log = compiler_perf_log;
|
|
|
|
|
device->compiler->constant_buffer_0_is_relative =
|
|
|
|
|
!device->info.has_context_isolation;
|
|
|
|
|
device->compiler->supports_shader_constants = true;
|
|
|
|
|
device->compiler->indirect_ubos_use_sampler = device->info.ver < 12;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
isl_device_init(&device->isl_dev, &device->info);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
result = anv_physical_device_init_uuids(device);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_compiler;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-02-23 09:59:45 +02:00
|
|
|
anv_physical_device_init_va_ranges(device);
|
|
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_physical_device_init_disk_cache(device);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (instance->vk.enabled_extensions.KHR_display) {
|
|
|
|
|
master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
|
|
|
|
|
if (master_fd >= 0) {
|
|
|
|
|
/* fail if we don't have permission to even render on this device */
|
|
|
|
|
if (!intel_gem_can_render_on_fd(master_fd, device->info.kmd_type)) {
|
|
|
|
|
close(master_fd);
|
|
|
|
|
master_fd = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
device->master_fd = master_fd;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
device->engine_info = intel_engine_get_info(fd, device->info.kmd_type);
|
|
|
|
|
device->info.has_compute_engine = intel_engines_count(device->engine_info,
|
|
|
|
|
INTEL_ENGINE_CLASS_COMPUTE);
|
|
|
|
|
anv_physical_device_init_queue_families(device);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_physical_device_init_perf(device, fd);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
get_device_extensions(device, &device->vk.supported_extensions);
|
|
|
|
|
get_features(device, &device->vk.supported_features);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
/* Gather major/minor before WSI. */
|
|
|
|
|
struct stat st;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (stat(primary_path, &st) == 0) {
|
|
|
|
|
device->has_master = true;
|
|
|
|
|
device->master_major = major(st.st_rdev);
|
|
|
|
|
device->master_minor = minor(st.st_rdev);
|
|
|
|
|
} else {
|
|
|
|
|
device->has_master = false;
|
|
|
|
|
device->master_major = 0;
|
|
|
|
|
device->master_minor = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (stat(path, &st) == 0) {
|
|
|
|
|
device->has_local = true;
|
|
|
|
|
device->local_major = major(st.st_rdev);
|
|
|
|
|
device->local_minor = minor(st.st_rdev);
|
|
|
|
|
} else {
|
|
|
|
|
device->has_local = false;
|
|
|
|
|
device->local_major = 0;
|
|
|
|
|
device->local_minor = 0;
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
result = anv_init_wsi(device);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_perf;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_measure_device_init(device);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_genX(&device->info, init_physical_device_state)(device);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
*out = &device->vk;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return VK_SUCCESS;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
fail_perf:
|
|
|
|
|
ralloc_free(device->perf);
|
|
|
|
|
free(device->engine_info);
|
|
|
|
|
anv_physical_device_free_disk_cache(device);
|
|
|
|
|
fail_compiler:
|
|
|
|
|
ralloc_free(device->compiler);
|
|
|
|
|
fail_base:
|
|
|
|
|
vk_physical_device_finish(&device->vk);
|
|
|
|
|
fail_alloc:
|
|
|
|
|
vk_free(&instance->vk.alloc, device);
|
|
|
|
|
fail_fd:
|
|
|
|
|
close(fd);
|
|
|
|
|
if (master_fd != -1)
|
|
|
|
|
close(master_fd);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static void
|
|
|
|
|
anv_physical_device_destroy(struct vk_physical_device *vk_device)
|
|
|
|
|
{
|
|
|
|
|
struct anv_physical_device *device =
|
|
|
|
|
container_of(vk_device, struct anv_physical_device, vk);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_finish_wsi(device);
|
|
|
|
|
anv_measure_device_destroy(device);
|
|
|
|
|
free(device->engine_info);
|
|
|
|
|
anv_physical_device_free_disk_cache(device);
|
|
|
|
|
ralloc_free(device->compiler);
|
|
|
|
|
ralloc_free(device->perf);
|
|
|
|
|
close(device->local_fd);
|
|
|
|
|
if (device->master_fd >= 0)
|
|
|
|
|
close(device->master_fd);
|
|
|
|
|
vk_physical_device_finish(&device->vk);
|
|
|
|
|
vk_free(&device->instance->vk.alloc, device);
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
VkResult anv_EnumerateInstanceExtensionProperties(
|
|
|
|
|
const char* pLayerName,
|
|
|
|
|
uint32_t* pPropertyCount,
|
|
|
|
|
VkExtensionProperties* pProperties)
|
|
|
|
|
{
|
|
|
|
|
if (pLayerName)
|
|
|
|
|
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return vk_enumerate_instance_extension_properties(
|
|
|
|
|
&instance_extensions, pPropertyCount, pProperties);
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
static void
|
|
|
|
|
anv_init_dri_options(struct anv_instance *instance)
|
|
|
|
|
{
|
|
|
|
|
driParseOptionInfo(&instance->available_dri_options, anv_dri_options,
|
|
|
|
|
ARRAY_SIZE(anv_dri_options));
|
|
|
|
|
driParseConfigFiles(&instance->dri_options,
|
|
|
|
|
&instance->available_dri_options, 0, "anv", NULL, NULL,
|
|
|
|
|
instance->vk.app_info.app_name,
|
|
|
|
|
instance->vk.app_info.app_version,
|
|
|
|
|
instance->vk.app_info.engine_name,
|
|
|
|
|
instance->vk.app_info.engine_version);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
instance->assume_full_subgroups =
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "anv_assume_full_subgroups");
|
|
|
|
|
instance->limit_trig_input_range =
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "limit_trig_input_range");
|
|
|
|
|
instance->sample_mask_out_opengl_behaviour =
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "anv_sample_mask_out_opengl_behaviour");
|
|
|
|
|
instance->lower_depth_range_rate =
|
|
|
|
|
driQueryOptionf(&instance->dri_options, "lower_depth_range_rate");
|
|
|
|
|
instance->no_16bit =
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "no_16bit");
|
|
|
|
|
instance->mesh_conv_prim_attrs_to_vert_attrs =
|
|
|
|
|
driQueryOptioni(&instance->dri_options, "anv_mesh_conv_prim_attrs_to_vert_attrs");
|
|
|
|
|
instance->fp64_workaround_enabled =
|
|
|
|
|
driQueryOptionb(&instance->dri_options, "fp64_workaround_enabled");
|
|
|
|
|
instance->generated_indirect_threshold =
|
|
|
|
|
driQueryOptioni(&instance->dri_options, "generated_indirect_threshold");
|
|
|
|
|
instance->query_clear_with_blorp_threshold =
|
|
|
|
|
driQueryOptioni(&instance->dri_options, "query_clear_with_blorp_threshold");
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
VkResult anv_CreateInstance(
|
|
|
|
|
const VkInstanceCreateInfo* pCreateInfo,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
VkInstance* pInstance)
|
|
|
|
|
{
|
|
|
|
|
struct anv_instance *instance;
|
|
|
|
|
VkResult result;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (pAllocator == NULL)
|
|
|
|
|
pAllocator = vk_default_allocator();
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
instance = vk_alloc(pAllocator, sizeof(*instance), 8,
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
|
|
|
|
if (!instance)
|
|
|
|
|
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
struct vk_instance_dispatch_table dispatch_table;
|
|
|
|
|
vk_instance_dispatch_table_from_entrypoints(
|
|
|
|
|
&dispatch_table, &anv_instance_entrypoints, true);
|
|
|
|
|
vk_instance_dispatch_table_from_entrypoints(
|
|
|
|
|
&dispatch_table, &wsi_instance_entrypoints, false);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
result = vk_instance_init(&instance->vk, &instance_extensions,
|
|
|
|
|
&dispatch_table, pCreateInfo, pAllocator);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
vk_free(pAllocator, instance);
|
|
|
|
|
return vk_error(NULL, result);
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
instance->vk.physical_devices.try_create_for_drm = anv_physical_device_try_create;
|
|
|
|
|
instance->vk.physical_devices.destroy = anv_physical_device_destroy;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
anv_init_dri_options(instance);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
intel_driver_ds_init();
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
*pInstance = anv_instance_to_handle(instance);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
void anv_DestroyInstance(
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_instance, instance, _instance);
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
if (!instance)
|
|
|
|
|
return;
|
2023-03-09 09:18:12 +02:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
VG(VALGRIND_DESTROY_MEMPOOL(instance));
|
2018-01-29 18:41:15 -08:00
|
|
|
|
2023-04-29 02:09:16 +03:00
|
|
|
driDestroyOptionCache(&instance->dri_options);
|
|
|
|
|
driDestroyOptionInfo(&instance->available_dri_options);
|
|
|
|
|
|
|
|
|
|
vk_instance_finish(&instance->vk);
|
|
|
|
|
vk_free(&instance->vk.alloc, instance);
|
2017-01-25 12:12:20 -08:00
|
|
|
}
|
|
|
|
|
|
2019-05-09 01:01:19 -07:00
|
|
|
#define MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS 64
|
|
|
|
|
|
|
|
|
|
#define MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS 64
|
|
|
|
|
#define MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS 256
|
|
|
|
|
|
2020-04-22 17:08:22 -07:00
|
|
|
#define MAX_CUSTOM_BORDER_COLORS 4096
|
|
|
|
|
|
2023-04-26 10:32:12 -07:00
|
|
|
static VkDeviceSize
|
|
|
|
|
anx_get_physical_device_max_heap_size(struct anv_physical_device *pdevice)
|
|
|
|
|
{
|
|
|
|
|
VkDeviceSize ret = 0;
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pdevice->memory.heap_count; i++) {
|
|
|
|
|
if (pdevice->memory.heaps[i].size > ret)
|
|
|
|
|
ret = pdevice->memory.heaps[i].size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 12:21:19 -08:00
|
|
|
void anv_GetPhysicalDeviceProperties(
|
2015-07-09 15:38:30 -07:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2015-10-07 10:36:46 -07:00
|
|
|
VkPhysicalDeviceProperties* pProperties)
|
2015-07-09 15:38:30 -07:00
|
|
|
{
|
2015-10-07 10:36:46 -07:00
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
2021-04-05 13:19:39 -07:00
|
|
|
const struct intel_device_info *devinfo = &pdevice->info;
|
2015-07-09 15:38:30 -07:00
|
|
|
|
2022-08-30 19:01:33 -07:00
|
|
|
const uint32_t max_ssbos = UINT16_MAX;
|
2022-08-30 19:55:53 -07:00
|
|
|
const uint32_t max_textures = UINT16_MAX;
|
|
|
|
|
const uint32_t max_samplers = UINT16_MAX;
|
|
|
|
|
const uint32_t max_images = UINT16_MAX;
|
2023-04-26 10:32:12 -07:00
|
|
|
const VkDeviceSize max_heap_size = anx_get_physical_device_max_heap_size(pdevice);
|
2022-08-30 19:55:53 -07:00
|
|
|
|
|
|
|
|
/* Claim a high per-stage limit since we have bindless. */
|
|
|
|
|
const uint32_t max_per_stage = UINT32_MAX;
|
2019-01-09 16:04:22 -06:00
|
|
|
|
2021-10-27 01:40:36 -05:00
|
|
|
const uint32_t max_workgroup_size =
|
|
|
|
|
MIN2(1024, 32 * devinfo->max_cs_workgroup_threads);
|
2019-09-03 10:00:23 -05:00
|
|
|
|
2015-12-02 16:58:54 -08:00
|
|
|
VkSampleCountFlags sample_counts =
|
2016-01-20 16:04:28 -08:00
|
|
|
isl_device_get_sample_counts(&pdevice->isl_dev);
|
2015-12-02 16:58:54 -08:00
|
|
|
|
2019-01-10 13:34:07 +01:00
|
|
|
|
2015-10-07 10:36:46 -07:00
|
|
|
VkPhysicalDeviceLimits limits = {
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxImageDimension1D = (1 << 14),
|
|
|
|
|
.maxImageDimension2D = (1 << 14),
|
2016-03-05 15:17:00 -08:00
|
|
|
.maxImageDimension3D = (1 << 11),
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxImageDimensionCube = (1 << 14),
|
2016-03-05 15:17:00 -08:00
|
|
|
.maxImageArrayLayers = (1 << 11),
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxTexelBufferElements = 128 * 1024 * 1024,
|
2022-02-04 01:13:52 -08:00
|
|
|
.maxUniformBufferRange = pdevice->compiler->indirect_ubos_use_sampler ? (1u << 27) : (1u << 30),
|
2023-04-26 10:32:12 -07:00
|
|
|
.maxStorageBufferRange = MIN3(pdevice->isl_dev.max_buffer_size, max_heap_size, UINT32_MAX),
|
2015-08-26 15:01:38 -07:00
|
|
|
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxMemoryAllocationCount = UINT32_MAX,
|
2016-01-20 14:36:52 -08:00
|
|
|
.maxSamplerAllocationCount = 64 * 1024,
|
2022-02-17 02:08:33 -08:00
|
|
|
.bufferImageGranularity = 1,
|
2015-10-07 09:57:51 -07:00
|
|
|
.sparseAddressSpaceSize = 0,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxBoundDescriptorSets = MAX_SETS,
|
2017-06-05 15:49:05 +01:00
|
|
|
.maxPerStageDescriptorSamplers = max_samplers,
|
2019-05-09 01:01:19 -07:00
|
|
|
.maxPerStageDescriptorUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS,
|
2019-01-09 16:04:22 -06:00
|
|
|
.maxPerStageDescriptorStorageBuffers = max_ssbos,
|
2019-02-07 14:10:33 -06:00
|
|
|
.maxPerStageDescriptorSampledImages = max_textures,
|
2019-02-12 01:02:28 -06:00
|
|
|
.maxPerStageDescriptorStorageImages = max_images,
|
2019-05-09 01:01:19 -07:00
|
|
|
.maxPerStageDescriptorInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS,
|
2019-01-09 16:04:22 -06:00
|
|
|
.maxPerStageResources = max_per_stage,
|
2018-01-10 09:15:50 +01:00
|
|
|
.maxDescriptorSetSamplers = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSamplers */
|
2019-05-09 01:01:19 -07:00
|
|
|
.maxDescriptorSetUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS, /* number of stages * maxPerStageDescriptorUniformBuffers */
|
2017-03-04 10:52:43 -08:00
|
|
|
.maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
|
2019-01-09 16:04:22 -06:00
|
|
|
.maxDescriptorSetStorageBuffers = 6 * max_ssbos, /* number of stages * maxPerStageDescriptorStorageBuffers */
|
2017-03-04 10:52:43 -08:00
|
|
|
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
|
2019-02-07 14:10:33 -06:00
|
|
|
.maxDescriptorSetSampledImages = 6 * max_textures, /* number of stages * maxPerStageDescriptorSampledImages */
|
2019-02-12 01:02:28 -06:00
|
|
|
.maxDescriptorSetStorageImages = 6 * max_images, /* number of stages * maxPerStageDescriptorStorageImages */
|
2019-05-09 01:01:19 -07:00
|
|
|
.maxDescriptorSetInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS,
|
anv: Raise vertex input bindings and attributes limits slightly
This raises our vertex input bindings limit from 28 to 31, and our
vertex input attribute limit from 28 to 29. We could theoretically
go higher, but it will take additional work.
The 3DSTATE_VERTEX_BUFFERS and 3DSTATE_VERTEX_ELEMENTS limits are 33
vertex buffers, and 34 vertex elements. But we need up to two vertex
elements for system values (FirstVertex, BaseVertex, BaseInstance,
DrawID), and we currently use two vertex bindings for those.
There is another hidden limit: our compiler backend only supports the
push model for VS inputs currently. 3DSTATE_VS only allows URB Read
Lengths between [0, 15], which is measured in pairs of inputs, which
means we can theoretically push no more than 32 vertex elements. This
is no artifical limit either, as a vec4 element takes up 4 registers
in the payload, and 32 * 4 = 128, the entire size of our register file.
Plus, the VS Thread payload needs at least g0 and g1 for other things,
so we can really only push 31.
We can theoretically support one additional binding, by combining our
two SGV bindings into a single upload. In order to support additional
vertex elements, we would need to add support to the backend compiler
for the pull model for VS inputs.
References: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5917
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14991>
2022-02-10 15:45:23 -08:00
|
|
|
.maxVertexInputAttributes = MAX_VES,
|
2017-01-29 02:44:32 +00:00
|
|
|
.maxVertexInputBindings = MAX_VBS,
|
2022-02-09 23:11:50 +02:00
|
|
|
/* Broadwell PRMs: Volume 2d: Command Reference: Structures:
|
|
|
|
|
*
|
|
|
|
|
* VERTEX_ELEMENT_STATE::Source Element Offset: [0,2047]
|
|
|
|
|
*/
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxVertexInputAttributeOffset = 2047,
|
2022-08-30 14:50:51 -07:00
|
|
|
/* Skylake PRMs: Volume 2d: Command Reference: Structures:
|
2022-02-09 23:11:50 +02:00
|
|
|
*
|
|
|
|
|
* VERTEX_BUFFER_STATE::Buffer Pitch: [0,4095]
|
|
|
|
|
*/
|
2022-08-30 14:50:51 -07:00
|
|
|
.maxVertexInputBindingStride = 4095,
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxVertexOutputComponents = 128,
|
2016-09-29 18:11:21 -07:00
|
|
|
.maxTessellationGenerationLevel = 64,
|
|
|
|
|
.maxTessellationPatchSize = 32,
|
|
|
|
|
.maxTessellationControlPerVertexInputComponents = 128,
|
|
|
|
|
.maxTessellationControlPerVertexOutputComponents = 128,
|
|
|
|
|
.maxTessellationControlPerPatchOutputComponents = 128,
|
|
|
|
|
.maxTessellationControlTotalOutputComponents = 2048,
|
|
|
|
|
.maxTessellationEvaluationInputComponents = 128,
|
|
|
|
|
.maxTessellationEvaluationOutputComponents = 128,
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxGeometryShaderInvocations = 32,
|
2022-08-30 14:50:51 -07:00
|
|
|
.maxGeometryInputComponents = 128,
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxGeometryOutputComponents = 128,
|
|
|
|
|
.maxGeometryOutputVertices = 256,
|
|
|
|
|
.maxGeometryTotalOutputComponents = 1024,
|
2019-04-29 00:46:10 -05:00
|
|
|
.maxFragmentInputComponents = 116, /* 128 components - (PSIZ, CLIP_DIST0, CLIP_DIST1) */
|
2015-12-02 16:58:54 -08:00
|
|
|
.maxFragmentOutputAttachments = 8,
|
2016-11-29 11:16:56 +10:00
|
|
|
.maxFragmentDualSrcAttachments = 1,
|
2021-12-28 20:04:48 +01:00
|
|
|
.maxFragmentCombinedOutputResources = MAX_RTS + max_ssbos + max_images,
|
2019-07-08 10:36:59 -07:00
|
|
|
.maxComputeSharedMemorySize = 64 * 1024,
|
2016-01-26 23:09:45 -08:00
|
|
|
.maxComputeWorkGroupCount = { 65535, 65535, 65535 },
|
2019-09-03 10:00:23 -05:00
|
|
|
.maxComputeWorkGroupInvocations = max_workgroup_size,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxComputeWorkGroupSize = {
|
2019-09-03 10:00:23 -05:00
|
|
|
max_workgroup_size,
|
|
|
|
|
max_workgroup_size,
|
|
|
|
|
max_workgroup_size,
|
2015-07-09 15:38:30 -07:00
|
|
|
},
|
anv: advertise 8 subpixel precision bits
On one side, when emitting 3DSTATE_SF, VertexSubPixelPrecisionSelect is
used to select between 8 bit subpixel precision (value 0) or 4 bit
subpixel precision (value 1). As this value is not set, means it is
taking the value 0, so 8 bit are used.
On the other side, in the Vulkan CTS tests, if the reference rasterizer,
which uses 8 bit precision, as it is used to check what should be the
expected value for the tests, is changed to use 4 bit as ANV was
advertising so far, some of the tests will fail.
So it seems ANV is actually using 8 bits.
v2: explicitly set 3DSTATE_SF::VertexSubPixelPrecisionSelect (Jason)
v3: use _8Bit definition as value (Jason)
v4: (by Jason)
anv: Explicitly set 3DSTATE_CLIP::VertexSubPixelPrecisionSelect
This field was added on gen8 even though there's an identically defined
one in 3DSTATE_SF.
CC: Jason Ekstrand <jason@jlekstrand.net>
CC: Kenneth Graunke <kenneth@whitecape.org>
CC: 18.3 19.0 <mesa-stable@lists.freedesktop.org>
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
2019-02-22 16:47:53 +01:00
|
|
|
.subPixelPrecisionBits = 8,
|
2019-04-09 15:28:42 +00:00
|
|
|
.subTexelPrecisionBits = 8,
|
|
|
|
|
.mipmapPrecisionBits = 8,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxDrawIndexedIndexValue = UINT32_MAX,
|
2015-12-02 16:58:54 -08:00
|
|
|
.maxDrawIndirectCount = UINT32_MAX,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxSamplerLodBias = 16,
|
|
|
|
|
.maxSamplerAnisotropy = 16,
|
2015-10-06 17:21:44 -07:00
|
|
|
.maxViewports = MAX_VIEWPORTS,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxViewportDimensions = { (1 << 14), (1 << 14) },
|
2016-05-17 15:28:01 -07:00
|
|
|
.viewportBoundsRange = { INT16_MIN, INT16_MAX },
|
2015-07-09 15:38:30 -07:00
|
|
|
.viewportSubPixelBits = 13, /* We take a float? */
|
2016-01-01 09:26:06 -08:00
|
|
|
.minMemoryMapAlignment = 4096, /* A page */
|
2019-06-06 15:45:57 -05:00
|
|
|
/* The dataport requires texel alignment so we need to assume a worst
|
|
|
|
|
* case of R32G32B32A32 which is 16 bytes.
|
|
|
|
|
*/
|
|
|
|
|
.minTexelBufferOffsetAlignment = 16,
|
2020-05-07 12:25:50 +03:00
|
|
|
.minUniformBufferOffsetAlignment = ANV_UBO_ALIGNMENT,
|
2020-08-28 15:42:45 -05:00
|
|
|
.minStorageBufferOffsetAlignment = ANV_SSBO_ALIGNMENT,
|
2016-01-26 23:09:45 -08:00
|
|
|
.minTexelOffset = -8,
|
|
|
|
|
.maxTexelOffset = 7,
|
2016-11-27 21:05:36 -05:00
|
|
|
.minTexelGatherOffset = -32,
|
|
|
|
|
.maxTexelGatherOffset = 31,
|
2016-07-28 17:37:20 -07:00
|
|
|
.minInterpolationOffset = -0.5,
|
|
|
|
|
.maxInterpolationOffset = 0.4375,
|
|
|
|
|
.subPixelInterpolationOffsetBits = 4,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxFramebufferWidth = (1 << 14),
|
|
|
|
|
.maxFramebufferHeight = (1 << 14),
|
2016-11-28 19:49:51 -05:00
|
|
|
.maxFramebufferLayers = (1 << 11),
|
2015-12-02 16:58:54 -08:00
|
|
|
.framebufferColorSampleCounts = sample_counts,
|
|
|
|
|
.framebufferDepthSampleCounts = sample_counts,
|
|
|
|
|
.framebufferStencilSampleCounts = sample_counts,
|
|
|
|
|
.framebufferNoAttachmentsSampleCounts = sample_counts,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxColorAttachments = MAX_RTS,
|
2015-12-02 16:58:54 -08:00
|
|
|
.sampledImageColorSampleCounts = sample_counts,
|
2019-12-23 22:19:29 -06:00
|
|
|
.sampledImageIntegerSampleCounts = sample_counts,
|
2015-12-02 16:58:54 -08:00
|
|
|
.sampledImageDepthSampleCounts = sample_counts,
|
|
|
|
|
.sampledImageStencilSampleCounts = sample_counts,
|
|
|
|
|
.storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
|
2015-07-09 15:38:30 -07:00
|
|
|
.maxSampleMaskWords = 1,
|
2019-07-17 08:46:53 +03:00
|
|
|
.timestampComputeAndGraphics = true,
|
2017-07-02 00:23:29 +01:00
|
|
|
.timestampPeriod = 1000000000.0 / devinfo->timestamp_frequency,
|
2016-10-03 20:44:38 -07:00
|
|
|
.maxClipDistances = 8,
|
|
|
|
|
.maxCullDistances = 8,
|
|
|
|
|
.maxCombinedClipAndCullDistances = 8,
|
2018-08-26 21:48:01 +03:00
|
|
|
.discreteQueuePriorities = 2,
|
2015-07-09 15:38:30 -07:00
|
|
|
.pointSizeRange = { 0.125, 255.875 },
|
2021-04-22 11:14:02 -07:00
|
|
|
/* While SKL and up support much wider lines than we are setting here,
|
|
|
|
|
* in practice we run into conformance issues if we go past this limit.
|
|
|
|
|
* Since the Windows driver does the same, it's probably fair to assume
|
|
|
|
|
* that no one needs more than this.
|
|
|
|
|
*/
|
2022-08-30 14:50:51 -07:00
|
|
|
.lineWidthRange = { 0.0, 8.0 },
|
2015-07-09 15:38:30 -07:00
|
|
|
.pointSizeGranularity = (1.0 / 8.0),
|
|
|
|
|
.lineWidthGranularity = (1.0 / 128.0),
|
2019-05-22 22:44:59 -05:00
|
|
|
.strictLines = false,
|
2016-01-26 10:56:06 -08:00
|
|
|
.standardSampleLocations = true,
|
2015-12-02 16:58:54 -08:00
|
|
|
.optimalBufferCopyOffsetAlignment = 128,
|
|
|
|
|
.optimalBufferCopyRowPitchAlignment = 128,
|
|
|
|
|
.nonCoherentAtomSize = 64,
|
2015-07-09 15:38:30 -07:00
|
|
|
};
|
|
|
|
|
|
2015-07-09 15:53:03 -07:00
|
|
|
*pProperties = (VkPhysicalDeviceProperties) {
|
2021-01-29 22:40:39 -06:00
|
|
|
.apiVersion = ANV_API_VERSION,
|
2017-06-06 10:42:41 +01:00
|
|
|
.driverVersion = vk_get_driver_version(),
|
2015-11-30 21:10:14 -08:00
|
|
|
.vendorID = 0x8086,
|
2022-01-10 11:59:10 -08:00
|
|
|
.deviceID = pdevice->info.pci_device_id,
|
2021-06-23 15:15:03 -05:00
|
|
|
.deviceType = pdevice->info.has_local_mem ?
|
|
|
|
|
VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU :
|
|
|
|
|
VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
|
2015-10-07 10:36:46 -07:00
|
|
|
.limits = limits,
|
|
|
|
|
.sparseProperties = {0}, /* Broadwell doesn't do sparse. */
|
2015-07-09 15:53:03 -07:00
|
|
|
};
|
|
|
|
|
|
2017-07-16 15:28:09 +01:00
|
|
|
snprintf(pProperties->deviceName, sizeof(pProperties->deviceName),
|
2021-07-13 17:56:01 -05:00
|
|
|
"%s", pdevice->info.name);
|
2017-02-27 09:36:20 -08:00
|
|
|
memcpy(pProperties->pipelineCacheUUID,
|
|
|
|
|
pdevice->pipeline_cache_uuid, VK_UUID_SIZE);
|
2015-07-09 15:53:03 -07:00
|
|
|
}
|
|
|
|
|
|
2020-01-13 13:44:16 -06:00
|
|
|
static void
|
|
|
|
|
anv_get_physical_device_properties_1_1(struct anv_physical_device *pdevice,
|
|
|
|
|
VkPhysicalDeviceVulkan11Properties *p)
|
|
|
|
|
{
|
|
|
|
|
assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);
|
|
|
|
|
|
|
|
|
|
memcpy(p->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
|
|
|
|
|
memcpy(p->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
|
|
|
|
|
memset(p->deviceLUID, 0, VK_LUID_SIZE);
|
|
|
|
|
p->deviceNodeMask = 0;
|
|
|
|
|
p->deviceLUIDValid = false;
|
|
|
|
|
|
|
|
|
|
p->subgroupSize = BRW_SUBGROUP_SIZE;
|
|
|
|
|
VkShaderStageFlags scalar_stages = 0;
|
2021-07-14 14:37:40 -07:00
|
|
|
for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
|
2020-01-13 13:44:16 -06:00
|
|
|
if (pdevice->compiler->scalar_stage[stage])
|
|
|
|
|
scalar_stages |= mesa_to_vk_shader_stage(stage);
|
|
|
|
|
}
|
2021-07-14 14:37:40 -07:00
|
|
|
if (pdevice->vk.supported_extensions.KHR_ray_tracing_pipeline) {
|
2022-01-28 00:57:03 -08:00
|
|
|
scalar_stages |= VK_SHADER_STAGE_RAYGEN_BIT_KHR |
|
|
|
|
|
VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
|
|
|
|
|
VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
|
|
|
|
|
VK_SHADER_STAGE_MISS_BIT_KHR |
|
|
|
|
|
VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
|
|
|
|
|
VK_SHADER_STAGE_CALLABLE_BIT_KHR;
|
2021-07-14 14:37:40 -07:00
|
|
|
}
|
2022-05-08 02:19:35 +02:00
|
|
|
if (pdevice->vk.supported_extensions.NV_mesh_shader ||
|
|
|
|
|
pdevice->vk.supported_extensions.EXT_mesh_shader) {
|
2022-05-08 02:24:48 +02:00
|
|
|
scalar_stages |= VK_SHADER_STAGE_TASK_BIT_EXT |
|
|
|
|
|
VK_SHADER_STAGE_MESH_BIT_EXT;
|
2021-05-20 12:07:34 -07:00
|
|
|
}
|
2020-01-13 13:44:16 -06:00
|
|
|
p->subgroupSupportedStages = scalar_stages;
|
|
|
|
|
p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_VOTE_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_BALLOT_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT |
|
2022-08-30 14:50:51 -07:00
|
|
|
VK_SUBGROUP_FEATURE_QUAD_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_CLUSTERED_BIT;
|
|
|
|
|
p->subgroupQuadOperationsInAllStages = true;
|
2020-01-13 13:44:16 -06:00
|
|
|
|
|
|
|
|
p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_USER_CLIP_PLANES_ONLY;
|
|
|
|
|
p->maxMultiviewViewCount = 16;
|
|
|
|
|
p->maxMultiviewInstanceIndex = UINT32_MAX / 16;
|
|
|
|
|
p->protectedNoFault = false;
|
|
|
|
|
/* This value doesn't matter for us today as our per-stage descriptors are
|
|
|
|
|
* the real limit.
|
|
|
|
|
*/
|
|
|
|
|
p->maxPerSetDescriptors = 1024;
|
2023-03-14 16:39:34 -07:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pdevice->memory.heap_count; i++) {
|
|
|
|
|
p->maxMemoryAllocationSize = MAX2(p->maxMemoryAllocationSize,
|
|
|
|
|
pdevice->memory.heaps[i].size);
|
|
|
|
|
}
|
2020-01-13 13:44:16 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
anv_get_physical_device_properties_1_2(struct anv_physical_device *pdevice,
|
|
|
|
|
VkPhysicalDeviceVulkan12Properties *p)
|
|
|
|
|
{
|
|
|
|
|
assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES);
|
|
|
|
|
|
2022-07-01 13:03:31 +01:00
|
|
|
p->driverID = VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
|
2020-01-13 13:44:16 -06:00
|
|
|
memset(p->driverName, 0, sizeof(p->driverName));
|
2022-07-01 13:03:31 +01:00
|
|
|
snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE,
|
2020-01-13 13:44:16 -06:00
|
|
|
"Intel open-source Mesa driver");
|
|
|
|
|
memset(p->driverInfo, 0, sizeof(p->driverInfo));
|
2022-07-01 13:03:31 +01:00
|
|
|
snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE,
|
2020-01-13 13:44:16 -06:00
|
|
|
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1);
|
2021-10-13 16:06:51 -07:00
|
|
|
|
2022-08-03 11:58:09 +03:00
|
|
|
p->conformanceVersion = (VkConformanceVersion) {
|
|
|
|
|
.major = 1,
|
|
|
|
|
.minor = 3,
|
|
|
|
|
.subminor = 0,
|
|
|
|
|
.patch = 0,
|
|
|
|
|
};
|
2020-01-13 13:44:16 -06:00
|
|
|
|
|
|
|
|
p->denormBehaviorIndependence =
|
2022-07-01 13:03:31 +01:00
|
|
|
VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL;
|
2020-01-13 13:44:16 -06:00
|
|
|
p->roundingModeIndependence =
|
2022-07-01 13:03:31 +01:00
|
|
|
VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE;
|
2020-01-13 13:44:16 -06:00
|
|
|
|
|
|
|
|
/* Broadwell does not support HF denorms and there are restrictions
|
|
|
|
|
* other gens. According to Kabylake's PRM:
|
|
|
|
|
*
|
|
|
|
|
* "math - Extended Math Function
|
|
|
|
|
* [...]
|
|
|
|
|
* Restriction : Half-float denorms are always retained."
|
|
|
|
|
*/
|
|
|
|
|
p->shaderDenormFlushToZeroFloat16 = false;
|
2022-12-15 20:28:21 +02:00
|
|
|
p->shaderDenormPreserveFloat16 = true;
|
2020-01-13 13:44:16 -06:00
|
|
|
p->shaderRoundingModeRTEFloat16 = true;
|
|
|
|
|
p->shaderRoundingModeRTZFloat16 = true;
|
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat16 = true;
|
|
|
|
|
|
|
|
|
|
p->shaderDenormFlushToZeroFloat32 = true;
|
|
|
|
|
p->shaderDenormPreserveFloat32 = true;
|
|
|
|
|
p->shaderRoundingModeRTEFloat32 = true;
|
|
|
|
|
p->shaderRoundingModeRTZFloat32 = true;
|
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat32 = true;
|
|
|
|
|
|
|
|
|
|
p->shaderDenormFlushToZeroFloat64 = true;
|
|
|
|
|
p->shaderDenormPreserveFloat64 = true;
|
|
|
|
|
p->shaderRoundingModeRTEFloat64 = true;
|
|
|
|
|
p->shaderRoundingModeRTZFloat64 = true;
|
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat64 = true;
|
|
|
|
|
|
|
|
|
|
/* It's a bit hard to exactly map our implementation to the limits
|
2020-10-15 20:33:12 -05:00
|
|
|
* described by Vulkan. The bindless surface handle in the extended
|
2020-01-13 13:44:16 -06:00
|
|
|
* message descriptors is 20 bits and it's an index into the table of
|
|
|
|
|
* RENDER_SURFACE_STATE structs that starts at bindless surface base
|
2020-10-15 20:33:12 -05:00
|
|
|
* address. This means that we can have at must 1M surface states
|
|
|
|
|
* allocated at any given time. Since most image views take two
|
|
|
|
|
* descriptors, this means we have a limit of about 500K image views.
|
2020-01-13 13:44:16 -06:00
|
|
|
*
|
2020-10-15 20:33:12 -05:00
|
|
|
* However, since we allocate surface states at vkCreateImageView time,
|
|
|
|
|
* this means our limit is actually something on the order of 500K image
|
|
|
|
|
* views allocated at any time. The actual limit describe by Vulkan, on
|
|
|
|
|
* the other hand, is a limit of how many you can have in a descriptor set.
|
|
|
|
|
* Assuming anyone using 1M descriptors will be using the same image view
|
|
|
|
|
* twice a bunch of times (or a bunch of null descriptors), we can safely
|
|
|
|
|
* advertise a larger limit here.
|
2020-01-13 13:44:16 -06:00
|
|
|
*/
|
2020-10-15 20:33:12 -05:00
|
|
|
const unsigned max_bindless_views = 1 << 20;
|
2020-01-13 13:44:16 -06:00
|
|
|
p->maxUpdateAfterBindDescriptorsInAllPools = max_bindless_views;
|
|
|
|
|
p->shaderUniformBufferArrayNonUniformIndexingNative = false;
|
|
|
|
|
p->shaderSampledImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
p->shaderStorageBufferArrayNonUniformIndexingNative = true;
|
|
|
|
|
p->shaderStorageImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
p->shaderInputAttachmentArrayNonUniformIndexingNative = false;
|
|
|
|
|
p->robustBufferAccessUpdateAfterBind = true;
|
|
|
|
|
p->quadDivergentImplicitLod = false;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindSamplers = max_bindless_views;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = UINT32_MAX;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_bindless_views;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_bindless_views;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindInputAttachments = MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS;
|
|
|
|
|
p->maxPerStageUpdateAfterBindResources = UINT32_MAX;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindSamplers = max_bindless_views;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindUniformBuffers = 6 * MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageBuffers = UINT32_MAX;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindSampledImages = max_bindless_views;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageImages = max_bindless_views;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindInputAttachments = MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS;
|
|
|
|
|
|
|
|
|
|
/* We support all of the depth resolve modes */
|
2022-07-01 13:03:31 +01:00
|
|
|
p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
|
|
|
|
|
VK_RESOLVE_MODE_AVERAGE_BIT |
|
|
|
|
|
VK_RESOLVE_MODE_MIN_BIT |
|
|
|
|
|
VK_RESOLVE_MODE_MAX_BIT;
|
2020-01-13 13:44:16 -06:00
|
|
|
/* Average doesn't make sense for stencil so we don't support that */
|
2022-08-30 14:50:51 -07:00
|
|
|
p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT |
|
|
|
|
|
VK_RESOLVE_MODE_MIN_BIT |
|
|
|
|
|
VK_RESOLVE_MODE_MAX_BIT;
|
2020-01-13 13:44:16 -06:00
|
|
|
p->independentResolveNone = true;
|
|
|
|
|
p->independentResolve = true;
|
|
|
|
|
|
2022-08-30 14:50:51 -07:00
|
|
|
p->filterMinmaxSingleComponentFormats = true;
|
|
|
|
|
p->filterMinmaxImageComponentMapping = true;
|
2020-01-13 13:44:16 -06:00
|
|
|
|
|
|
|
|
p->maxTimelineSemaphoreValueDifference = UINT64_MAX;
|
|
|
|
|
|
|
|
|
|
p->framebufferIntegerColorSampleCounts =
|
|
|
|
|
isl_device_get_sample_counts(&pdevice->isl_dev);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-12 12:17:27 -08:00
|
|
|
static void
|
|
|
|
|
anv_get_physical_device_properties_1_3(struct anv_physical_device *pdevice,
|
|
|
|
|
VkPhysicalDeviceVulkan13Properties *p)
|
|
|
|
|
{
|
|
|
|
|
assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES);
|
|
|
|
|
|
|
|
|
|
p->minSubgroupSize = 8;
|
|
|
|
|
p->maxSubgroupSize = 32;
|
|
|
|
|
p->maxComputeWorkgroupSubgroups = pdevice->info.max_cs_workgroup_threads;
|
2022-02-10 11:22:56 -08:00
|
|
|
p->requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT |
|
2022-05-08 02:24:48 +02:00
|
|
|
VK_SHADER_STAGE_TASK_BIT_EXT |
|
|
|
|
|
VK_SHADER_STAGE_MESH_BIT_EXT;
|
2022-01-12 12:17:27 -08:00
|
|
|
|
|
|
|
|
p->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;
|
|
|
|
|
p->maxPerStageDescriptorInlineUniformBlocks =
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
|
|
|
|
|
p->maxDescriptorSetInlineUniformBlocks =
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
|
|
|
|
|
p->maxInlineUniformTotalSize = UINT16_MAX;
|
|
|
|
|
|
|
|
|
|
p->integerDotProduct8BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct8BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct8BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProduct4x8BitPackedUnsignedAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProduct4x8BitPackedSignedAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProduct4x8BitPackedMixedSignednessAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProduct16BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct16BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct16BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProduct32BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct32BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct32BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProduct64BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct64BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProduct64BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating8BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating8BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating8BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating4x8BitPackedUnsignedAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating4x8BitPackedSignedAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating4x8BitPackedMixedSignednessAccelerated = pdevice->info.ver >= 12;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating16BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating16BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating16BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating32BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating32BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating32BitMixedSignednessAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating64BitUnsignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating64BitSignedAccelerated = false;
|
|
|
|
|
p->integerDotProductAccumulatingSaturating64BitMixedSignednessAccelerated = false;
|
|
|
|
|
|
|
|
|
|
/* From the SKL PRM Vol. 2d, docs for RENDER_SURFACE_STATE::Surface
|
|
|
|
|
* Base Address:
|
|
|
|
|
*
|
|
|
|
|
* "For SURFTYPE_BUFFER non-rendertarget surfaces, this field
|
|
|
|
|
* specifies the base address of the first element of the surface,
|
|
|
|
|
* computed in software by adding the surface base address to the
|
|
|
|
|
* byte offset of the element in the buffer. The base address must
|
|
|
|
|
* be aligned to element size."
|
|
|
|
|
*
|
|
|
|
|
* The typed dataport messages require that things be texel aligned.
|
|
|
|
|
* Otherwise, we may just load/store the wrong data or, in the worst
|
|
|
|
|
* case, there may be hangs.
|
|
|
|
|
*/
|
|
|
|
|
p->storageTexelBufferOffsetAlignmentBytes = 16;
|
|
|
|
|
p->storageTexelBufferOffsetSingleTexelAlignment = true;
|
|
|
|
|
|
|
|
|
|
/* The sampler, however, is much more forgiving and it can handle
|
|
|
|
|
* arbitrary byte alignment for linear and buffer surfaces. It's
|
|
|
|
|
* hard to find a good PRM citation for this but years of empirical
|
|
|
|
|
* experience demonstrate that this is true.
|
|
|
|
|
*/
|
|
|
|
|
p->uniformTexelBufferOffsetAlignmentBytes = 1;
|
|
|
|
|
p->uniformTexelBufferOffsetSingleTexelAlignment = false;
|
|
|
|
|
|
|
|
|
|
p->maxBufferSize = pdevice->isl_dev.max_buffer_size;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-20 12:18:10 -07:00
|
|
|
void anv_GetPhysicalDeviceProperties2(
|
2017-01-25 12:12:20 -08:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2017-09-20 13:16:26 -07:00
|
|
|
VkPhysicalDeviceProperties2* pProperties)
|
2017-01-25 12:12:20 -08:00
|
|
|
{
|
2017-07-13 12:18:15 -07:00
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
2017-01-25 12:12:20 -08:00
|
|
|
anv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
|
|
|
|
|
|
2020-01-13 13:44:16 -06:00
|
|
|
VkPhysicalDeviceVulkan11Properties core_1_1 = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
|
|
|
|
|
};
|
|
|
|
|
anv_get_physical_device_properties_1_1(pdevice, &core_1_1);
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Properties core_1_2 = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
|
|
|
|
|
};
|
|
|
|
|
anv_get_physical_device_properties_1_2(pdevice, &core_1_2);
|
|
|
|
|
|
2022-01-12 12:17:27 -08:00
|
|
|
VkPhysicalDeviceVulkan13Properties core_1_3 = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_PROPERTIES,
|
|
|
|
|
};
|
|
|
|
|
anv_get_physical_device_properties_1_3(pdevice, &core_1_3);
|
|
|
|
|
|
2017-02-14 14:29:19 -08:00
|
|
|
vk_foreach_struct(ext, pProperties->pNext) {
|
2021-09-21 15:04:38 -07:00
|
|
|
if (vk_get_physical_device_core_1_1_property_ext(ext, &core_1_1))
|
|
|
|
|
continue;
|
|
|
|
|
if (vk_get_physical_device_core_1_2_property_ext(ext, &core_1_2))
|
|
|
|
|
continue;
|
2022-01-12 12:17:27 -08:00
|
|
|
if (vk_get_physical_device_core_1_3_property_ext(ext, &core_1_3))
|
|
|
|
|
continue;
|
2021-09-21 15:04:38 -07:00
|
|
|
|
2017-02-14 14:29:19 -08:00
|
|
|
switch (ext->sType) {
|
2020-05-13 16:22:02 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDeviceAccelerationStructurePropertiesKHR *props = (void *)ext;
|
|
|
|
|
props->maxGeometryCount = (1u << 24) - 1;
|
|
|
|
|
props->maxInstanceCount = (1u << 24) - 1;
|
|
|
|
|
props->maxPrimitiveCount = (1u << 29) - 1;
|
2020-08-05 17:28:48 -05:00
|
|
|
props->maxPerStageDescriptorAccelerationStructures = UINT16_MAX;
|
|
|
|
|
props->maxPerStageDescriptorUpdateAfterBindAccelerationStructures = UINT16_MAX;
|
|
|
|
|
props->maxDescriptorSetAccelerationStructures = UINT16_MAX;
|
|
|
|
|
props->maxDescriptorSetUpdateAfterBindAccelerationStructures = UINT16_MAX;
|
2020-05-13 16:22:02 -05:00
|
|
|
props->minAccelerationStructureScratchOffsetAlignment = 64;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-31 17:45:42 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT: {
|
|
|
|
|
/* TODO: Real limits */
|
|
|
|
|
VkPhysicalDeviceConservativeRasterizationPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceConservativeRasterizationPropertiesEXT *)ext;
|
|
|
|
|
/* There's nothing in the public docs about this value as far as I
|
|
|
|
|
* can tell. However, this is the value the Windows driver reports
|
|
|
|
|
* and there's a comment on a rejected HW feature in the internal
|
|
|
|
|
* docs that says:
|
|
|
|
|
*
|
|
|
|
|
* "This is similar to conservative rasterization, except the
|
|
|
|
|
* primitive area is not extended by 1/512 and..."
|
|
|
|
|
*
|
|
|
|
|
* That's a bit of an obtuse reference but it's the best we've got
|
|
|
|
|
* for now.
|
|
|
|
|
*/
|
|
|
|
|
properties->primitiveOverestimationSize = 1.0f / 512.0f;
|
|
|
|
|
properties->maxExtraPrimitiveOverestimationSize = 0.0f;
|
|
|
|
|
properties->extraPrimitiveOverestimationSizeGranularity = 0.0f;
|
|
|
|
|
properties->primitiveUnderestimation = false;
|
|
|
|
|
properties->conservativePointAndLineRasterization = false;
|
|
|
|
|
properties->degenerateTrianglesRasterized = true;
|
|
|
|
|
properties->degenerateLinesRasterized = false;
|
|
|
|
|
properties->fullyCoveredFragmentShaderInputVariable = false;
|
|
|
|
|
properties->conservativeRasterizationPostDepthCoverage = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 17:08:22 -07:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceCustomBorderColorPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
|
|
|
|
|
properties->maxCustomBorderColorSamplers = MAX_CUSTOM_BORDER_COLORS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-19 10:12:43 +03:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRatePropertiesKHR *props =
|
|
|
|
|
(VkPhysicalDeviceFragmentShadingRatePropertiesKHR *)ext;
|
2021-02-05 21:16:38 +02:00
|
|
|
props->primitiveFragmentShadingRateWithMultipleViewports =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb;
|
|
|
|
|
props->layeredShadingRateAttachments = pdevice->info.has_coarse_pixel_primitive_and_cb;
|
|
|
|
|
props->fragmentShadingRateNonTrivialCombinerOps =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb;
|
2021-05-04 09:46:08 +03:00
|
|
|
props->maxFragmentSize = (VkExtent2D) { 4, 4 };
|
2021-02-05 21:16:38 +02:00
|
|
|
props->maxFragmentSizeAspectRatio =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb ?
|
|
|
|
|
2 : 4;
|
|
|
|
|
props->maxFragmentShadingRateCoverageSamples = 4 * 4 *
|
|
|
|
|
(pdevice->info.has_coarse_pixel_primitive_and_cb ? 4 : 16);
|
|
|
|
|
props->maxFragmentShadingRateRasterizationSamples =
|
|
|
|
|
pdevice->info.has_coarse_pixel_primitive_and_cb ?
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_16_BIT;
|
2021-05-04 09:46:08 +03:00
|
|
|
props->fragmentShadingRateWithShaderDepthStencilWrites = false;
|
|
|
|
|
props->fragmentShadingRateWithSampleMask = true;
|
|
|
|
|
props->fragmentShadingRateWithShaderSampleMask = false;
|
|
|
|
|
props->fragmentShadingRateWithConservativeRasterization = true;
|
|
|
|
|
props->fragmentShadingRateWithFragmentShaderInterlock = true;
|
|
|
|
|
props->fragmentShadingRateWithCustomSampleLocations = true;
|
2021-02-05 21:16:38 +02:00
|
|
|
|
|
|
|
|
/* Fix in DG2_G10_C0 and DG2_G11_B0. Consider any other Sku as having
|
|
|
|
|
* the fix.
|
|
|
|
|
*/
|
|
|
|
|
props->fragmentShadingRateStrictMultiplyCombiner =
|
|
|
|
|
pdevice->info.platform == INTEL_PLATFORM_DG2_G10 ?
|
|
|
|
|
pdevice->info.revision >= 8 :
|
|
|
|
|
pdevice->info.platform == INTEL_PLATFORM_DG2_G11 ?
|
|
|
|
|
pdevice->info.revision >= 4 : true;
|
|
|
|
|
|
|
|
|
|
if (pdevice->info.has_coarse_pixel_primitive_and_cb) {
|
|
|
|
|
props->minFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 8, 8 };
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 8, 8 };
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 1;
|
|
|
|
|
} else {
|
|
|
|
|
/* Those must be 0 if attachmentFragmentShadingRate is not
|
|
|
|
|
* supported.
|
|
|
|
|
*/
|
|
|
|
|
props->minFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 0;
|
|
|
|
|
}
|
2020-10-19 10:12:43 +03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-22 12:38:41 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRM_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceDrmPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceDrmPropertiesEXT *)ext;
|
|
|
|
|
|
2021-06-27 19:29:08 +00:00
|
|
|
props->hasPrimary = pdevice->has_master;
|
|
|
|
|
props->primaryMajor = pdevice->master_major;
|
|
|
|
|
props->primaryMinor = pdevice->master_minor;
|
|
|
|
|
|
|
|
|
|
props->hasRender = pdevice->has_local;
|
|
|
|
|
props->renderMajor = pdevice->local_major;
|
|
|
|
|
props->renderMinor = pdevice->local_minor;
|
|
|
|
|
|
2021-01-22 12:38:41 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 16:38:06 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_3_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceExtendedDynamicState3PropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceExtendedDynamicState3PropertiesEXT *) ext;
|
|
|
|
|
props->dynamicPrimitiveTopologyUnrestricted = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-01 13:15:31 -08:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceExternalMemoryHostPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext;
|
|
|
|
|
/* Userptr needs page aligned memory. */
|
|
|
|
|
props->minImportedHostPointerAlignment = 4096;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-28 15:42:27 +03:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GRAPHICS_PIPELINE_LIBRARY_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceGraphicsPipelineLibraryPropertiesEXT *)ext;
|
|
|
|
|
props->graphicsPipelineLibraryFastLinking = true;
|
|
|
|
|
props->graphicsPipelineLibraryIndependentInterpolationDecoration = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 22:44:59 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
|
|
|
|
|
/* In the Skylake PRM Vol. 7, subsection titled "GIQ (Diamond)
|
|
|
|
|
* Sampling Rules - Legacy Mode", it says the following:
|
|
|
|
|
*
|
|
|
|
|
* "Note that the device divides a pixel into a 16x16 array of
|
|
|
|
|
* subpixels, referenced by their upper left corners."
|
|
|
|
|
*
|
|
|
|
|
* This is the only known reference in the PRMs to the subpixel
|
|
|
|
|
* precision of line rasterization and a "16x16 array of subpixels"
|
|
|
|
|
* implies 4 subpixel precision bits. Empirical testing has shown
|
|
|
|
|
* that 4 subpixel precision bits applies to all line rasterization
|
|
|
|
|
* types.
|
|
|
|
|
*/
|
|
|
|
|
props->lineSubPixelPrecisionBits = 4;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-01 13:03:31 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_4_PROPERTIES: {
|
|
|
|
|
VkPhysicalDeviceMaintenance4Properties *properties =
|
|
|
|
|
(VkPhysicalDeviceMaintenance4Properties *)ext;
|
2021-07-28 14:57:51 +03:00
|
|
|
properties->maxBufferSize = pdevice->isl_dev.max_buffer_size;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-18 12:13:52 -07:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV: {
|
|
|
|
|
VkPhysicalDeviceMeshShaderPropertiesNV *props =
|
|
|
|
|
(VkPhysicalDeviceMeshShaderPropertiesNV *)ext;
|
|
|
|
|
|
2021-05-19 09:35:22 -07:00
|
|
|
/* Bounded by the maximum representable size in
|
|
|
|
|
* 3DSTATE_MESH_SHADER_BODY::SharedLocalMemorySize. Same for Task.
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t max_slm_size = 64 * 1024;
|
|
|
|
|
|
|
|
|
|
/* Bounded by the maximum representable size in
|
|
|
|
|
* 3DSTATE_MESH_SHADER_BODY::LocalXMaximum. Same for Task.
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t max_workgroup_size = 1 << 10;
|
|
|
|
|
|
|
|
|
|
/* Bounded by the maximum representable count in
|
|
|
|
|
* 3DSTATE_MESH_SHADER_BODY::MaximumPrimitiveCount.
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t max_primitives = 1024;
|
|
|
|
|
|
|
|
|
|
/* TODO(mesh): Multiview. */
|
|
|
|
|
const uint32_t max_view_count = 1;
|
2021-05-18 12:13:52 -07:00
|
|
|
|
2021-05-19 09:35:22 -07:00
|
|
|
props->maxDrawMeshTasksCount = UINT32_MAX;
|
|
|
|
|
|
|
|
|
|
/* TODO(mesh): Implement workgroup Y and Z sizes larger than one by
|
|
|
|
|
* mapping them to/from the single value that HW provides us
|
|
|
|
|
* (currently used for X).
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
props->maxTaskWorkGroupInvocations = max_workgroup_size;
|
|
|
|
|
props->maxTaskWorkGroupSize[0] = max_workgroup_size;
|
2021-05-18 12:13:52 -07:00
|
|
|
props->maxTaskWorkGroupSize[1] = 1;
|
|
|
|
|
props->maxTaskWorkGroupSize[2] = 1;
|
2021-05-19 09:35:22 -07:00
|
|
|
props->maxTaskTotalMemorySize = max_slm_size;
|
2021-05-18 12:13:52 -07:00
|
|
|
props->maxTaskOutputCount = UINT16_MAX;
|
|
|
|
|
|
2021-05-19 09:35:22 -07:00
|
|
|
props->maxMeshWorkGroupInvocations = max_workgroup_size;
|
|
|
|
|
props->maxMeshWorkGroupSize[0] = max_workgroup_size;
|
2021-05-18 12:13:52 -07:00
|
|
|
props->maxMeshWorkGroupSize[1] = 1;
|
|
|
|
|
props->maxMeshWorkGroupSize[2] = 1;
|
2021-05-19 09:35:22 -07:00
|
|
|
props->maxMeshTotalMemorySize = max_slm_size / max_view_count;
|
|
|
|
|
props->maxMeshOutputPrimitives = max_primitives / max_view_count;
|
|
|
|
|
props->maxMeshMultiviewViewCount = max_view_count;
|
|
|
|
|
|
|
|
|
|
/* Depends on what indices can be represented with IndexFormat. For
|
|
|
|
|
* now we always use U32, so bound to the maximum unique vertices we
|
|
|
|
|
* need for the maximum primitives.
|
|
|
|
|
*
|
|
|
|
|
* TODO(mesh): Revisit this if we drop "U32" IndexFormat when adding
|
|
|
|
|
* support for others.
|
|
|
|
|
*/
|
|
|
|
|
props->maxMeshOutputVertices = 3 * props->maxMeshOutputPrimitives;
|
|
|
|
|
|
2021-05-18 12:13:52 -07:00
|
|
|
|
|
|
|
|
props->meshOutputPerVertexGranularity = 32;
|
|
|
|
|
props->meshOutputPerPrimitiveGranularity = 32;
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-30 13:10:22 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceMeshShaderPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceMeshShaderPropertiesEXT *)ext;
|
|
|
|
|
|
|
|
|
|
/* Bounded by the maximum representable size in
|
|
|
|
|
* 3DSTATE_MESH_SHADER_BODY::SharedLocalMemorySize. Same for Task.
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t max_slm_size = 64 * 1024;
|
|
|
|
|
|
|
|
|
|
/* Bounded by the maximum representable size in
|
|
|
|
|
* 3DSTATE_MESH_SHADER_BODY::LocalXMaximum. Same for Task.
|
|
|
|
|
*/
|
|
|
|
|
const uint32_t max_workgroup_size = 1 << 10;
|
|
|
|
|
|
|
|
|
|
/* 3DMESH_3D limitation. */
|
|
|
|
|
const uint32_t max_threadgroup_count = 1 << 22;
|
|
|
|
|
|
|
|
|
|
/* 3DMESH_3D limitation. */
|
|
|
|
|
const uint32_t max_threadgroup_xyz = 65535;
|
|
|
|
|
|
|
|
|
|
const uint32_t max_urb_size = 64 * 1024;
|
|
|
|
|
|
|
|
|
|
properties->maxTaskWorkGroupTotalCount = max_threadgroup_count;
|
|
|
|
|
properties->maxTaskWorkGroupCount[0] = max_threadgroup_xyz;
|
|
|
|
|
properties->maxTaskWorkGroupCount[1] = max_threadgroup_xyz;
|
|
|
|
|
properties->maxTaskWorkGroupCount[2] = max_threadgroup_xyz;
|
|
|
|
|
|
|
|
|
|
properties->maxTaskWorkGroupInvocations = max_workgroup_size;
|
|
|
|
|
properties->maxTaskWorkGroupSize[0] = max_workgroup_size;
|
|
|
|
|
properties->maxTaskWorkGroupSize[1] = max_workgroup_size;
|
|
|
|
|
properties->maxTaskWorkGroupSize[2] = max_workgroup_size;
|
|
|
|
|
|
|
|
|
|
/* TUE header with padding */
|
|
|
|
|
const uint32_t task_payload_reserved = 32;
|
|
|
|
|
|
|
|
|
|
properties->maxTaskPayloadSize = max_urb_size - task_payload_reserved;
|
|
|
|
|
properties->maxTaskSharedMemorySize = max_slm_size;
|
|
|
|
|
properties->maxTaskPayloadAndSharedMemorySize =
|
|
|
|
|
properties->maxTaskPayloadSize +
|
|
|
|
|
properties->maxTaskSharedMemorySize;
|
|
|
|
|
|
|
|
|
|
properties->maxMeshWorkGroupTotalCount = max_threadgroup_count;
|
|
|
|
|
properties->maxMeshWorkGroupCount[0] = max_threadgroup_xyz;
|
|
|
|
|
properties->maxMeshWorkGroupCount[1] = max_threadgroup_xyz;
|
|
|
|
|
properties->maxMeshWorkGroupCount[2] = max_threadgroup_xyz;
|
|
|
|
|
|
|
|
|
|
properties->maxMeshWorkGroupInvocations = max_workgroup_size;
|
|
|
|
|
properties->maxMeshWorkGroupSize[0] = max_workgroup_size;
|
|
|
|
|
properties->maxMeshWorkGroupSize[1] = max_workgroup_size;
|
|
|
|
|
properties->maxMeshWorkGroupSize[2] = max_workgroup_size;
|
|
|
|
|
|
|
|
|
|
properties->maxMeshSharedMemorySize = max_slm_size;
|
|
|
|
|
properties->maxMeshPayloadAndSharedMemorySize =
|
|
|
|
|
properties->maxTaskPayloadSize +
|
|
|
|
|
properties->maxMeshSharedMemorySize;
|
|
|
|
|
|
|
|
|
|
/* Unfortunately spec's formula for the max output size doesn't match our hardware
|
|
|
|
|
* (because some per-primitive and per-vertex attributes have alignment restrictions),
|
|
|
|
|
* so we have to advertise the minimum value mandated by the spec to not overflow it.
|
|
|
|
|
*/
|
|
|
|
|
properties->maxMeshOutputPrimitives = 256;
|
|
|
|
|
properties->maxMeshOutputVertices = 256;
|
|
|
|
|
|
|
|
|
|
/* NumPrim + Primitive Data List */
|
|
|
|
|
const uint32_t max_indices_memory =
|
|
|
|
|
ALIGN(sizeof(uint32_t) +
|
|
|
|
|
sizeof(uint32_t) * properties->maxMeshOutputVertices, 32);
|
|
|
|
|
|
|
|
|
|
properties->maxMeshOutputMemorySize = MIN2(max_urb_size - max_indices_memory, 32768);
|
|
|
|
|
|
|
|
|
|
properties->maxMeshPayloadAndOutputMemorySize =
|
|
|
|
|
properties->maxTaskPayloadSize +
|
|
|
|
|
properties->maxMeshOutputMemorySize;
|
|
|
|
|
|
|
|
|
|
properties->maxMeshOutputComponents = 128;
|
|
|
|
|
|
|
|
|
|
/* RTAIndex is 11-bits wide */
|
|
|
|
|
properties->maxMeshOutputLayers = 1 << 11;
|
|
|
|
|
|
|
|
|
|
properties->maxMeshMultiviewViewCount = 1;
|
|
|
|
|
|
|
|
|
|
/* Elements in Vertex Data Array must be aligned to 32 bytes (8 dwords). */
|
|
|
|
|
properties->meshOutputPerVertexGranularity = 8;
|
|
|
|
|
/* Elements in Primitive Data Array must be aligned to 32 bytes (8 dwords). */
|
|
|
|
|
properties->meshOutputPerPrimitiveGranularity = 8;
|
|
|
|
|
|
|
|
|
|
/* SIMD16 */
|
|
|
|
|
properties->maxPreferredTaskWorkGroupInvocations = 16;
|
|
|
|
|
properties->maxPreferredMeshWorkGroupInvocations = 16;
|
|
|
|
|
|
|
|
|
|
properties->prefersLocalInvocationVertexOutput = false;
|
|
|
|
|
properties->prefersLocalInvocationPrimitiveOutput = false;
|
|
|
|
|
properties->prefersCompactVertexOutput = false;
|
|
|
|
|
properties->prefersCompactPrimitiveOutput = false;
|
|
|
|
|
|
|
|
|
|
/* Spec minimum values */
|
|
|
|
|
assert(properties->maxTaskWorkGroupTotalCount >= (1U << 22));
|
|
|
|
|
assert(properties->maxTaskWorkGroupCount[0] >= 65535);
|
|
|
|
|
assert(properties->maxTaskWorkGroupCount[1] >= 65535);
|
|
|
|
|
assert(properties->maxTaskWorkGroupCount[2] >= 65535);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxTaskWorkGroupInvocations >= 128);
|
|
|
|
|
assert(properties->maxTaskWorkGroupSize[0] >= 128);
|
|
|
|
|
assert(properties->maxTaskWorkGroupSize[1] >= 128);
|
|
|
|
|
assert(properties->maxTaskWorkGroupSize[2] >= 128);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxTaskPayloadSize >= 16384);
|
|
|
|
|
assert(properties->maxTaskSharedMemorySize >= 32768);
|
|
|
|
|
assert(properties->maxTaskPayloadAndSharedMemorySize >= 32768);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(properties->maxMeshWorkGroupTotalCount >= (1U << 22));
|
|
|
|
|
assert(properties->maxMeshWorkGroupCount[0] >= 65535);
|
|
|
|
|
assert(properties->maxMeshWorkGroupCount[1] >= 65535);
|
|
|
|
|
assert(properties->maxMeshWorkGroupCount[2] >= 65535);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxMeshWorkGroupInvocations >= 128);
|
|
|
|
|
assert(properties->maxMeshWorkGroupSize[0] >= 128);
|
|
|
|
|
assert(properties->maxMeshWorkGroupSize[1] >= 128);
|
|
|
|
|
assert(properties->maxMeshWorkGroupSize[2] >= 128);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxMeshSharedMemorySize >= 28672);
|
|
|
|
|
assert(properties->maxMeshPayloadAndSharedMemorySize >= 28672);
|
|
|
|
|
assert(properties->maxMeshOutputMemorySize >= 32768);
|
|
|
|
|
assert(properties->maxMeshPayloadAndOutputMemorySize >= 48128);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxMeshOutputComponents >= 128);
|
|
|
|
|
|
|
|
|
|
assert(properties->maxMeshOutputVertices >= 256);
|
|
|
|
|
assert(properties->maxMeshOutputPrimitives >= 256);
|
|
|
|
|
assert(properties->maxMeshOutputLayers >= 8);
|
|
|
|
|
assert(properties->maxMeshMultiviewViewCount >= 1);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-14 13:12:50 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDevicePCIBusInfoPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDevicePCIBusInfoPropertiesEXT *)ext;
|
2022-01-06 10:43:13 -08:00
|
|
|
properties->pciDomain = pdevice->info.pci_domain;
|
|
|
|
|
properties->pciBus = pdevice->info.pci_bus;
|
|
|
|
|
properties->pciDevice = pdevice->info.pci_dev;
|
|
|
|
|
properties->pciFunction = pdevice->info.pci_func;
|
2018-10-14 13:12:50 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-06 19:12:34 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PERFORMANCE_QUERY_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDevicePerformanceQueryPropertiesKHR *properties =
|
|
|
|
|
(VkPhysicalDevicePerformanceQueryPropertiesKHR *)ext;
|
|
|
|
|
/* We could support this by spawning a shader to do the equation
|
|
|
|
|
* normalization.
|
|
|
|
|
*/
|
|
|
|
|
properties->allowCommandBufferQueryCopies = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-08 14:57:14 +03:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
|
#pragma GCC diagnostic ignored "-Wswitch"
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID: {
|
|
|
|
|
VkPhysicalDevicePresentationPropertiesANDROID *props =
|
|
|
|
|
(VkPhysicalDevicePresentationPropertiesANDROID *)ext;
|
|
|
|
|
props->sharedImage = VK_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#pragma GCC diagnostic pop
|
|
|
|
|
|
2020-07-10 14:09:48 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROVOKING_VERTEX_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceProvokingVertexPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceProvokingVertexPropertiesEXT *)ext;
|
|
|
|
|
properties->provokingVertexModePerPipeline = true;
|
|
|
|
|
properties->transformFeedbackPreservesTriangleFanProvokingVertex = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-07 10:51:59 -06:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
|
|
|
|
|
(VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
|
|
|
|
|
properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 15:45:06 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDeviceRayTracingPipelinePropertiesKHR *props = (void *)ext;
|
|
|
|
|
/* TODO */
|
|
|
|
|
props->shaderGroupHandleSize = 32;
|
|
|
|
|
props->maxRayRecursionDepth = 31;
|
|
|
|
|
/* MemRay::hitGroupSRStride is 16 bits */
|
|
|
|
|
props->maxShaderGroupStride = UINT16_MAX;
|
|
|
|
|
/* MemRay::hitGroupSRBasePtr requires 16B alignment */
|
|
|
|
|
props->shaderGroupBaseAlignment = 16;
|
|
|
|
|
props->shaderGroupHandleAlignment = 16;
|
|
|
|
|
props->shaderGroupHandleCaptureReplaySize = 32;
|
|
|
|
|
props->maxRayDispatchInvocationCount = 1U << 30; /* required min limit */
|
|
|
|
|
props->maxRayHitAttributeSize = BRW_RT_SIZEOF_HIT_ATTRIB_DATA;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-13 10:14:01 -06:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceRobustness2PropertiesEXT *properties = (void *)ext;
|
|
|
|
|
properties->robustStorageBufferAccessSizeAlignment =
|
|
|
|
|
ANV_SSBO_BOUNDS_CHECK_ALIGNMENT;
|
|
|
|
|
properties->robustUniformBufferAccessSizeAlignment =
|
2020-05-07 12:25:50 +03:00
|
|
|
ANV_UBO_ALIGNMENT;
|
2020-01-13 10:14:01 -06:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-14 21:52:00 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceSampleLocationsPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;
|
|
|
|
|
|
|
|
|
|
props->sampleLocationSampleCounts =
|
|
|
|
|
isl_device_get_sample_counts(&pdevice->isl_dev);
|
|
|
|
|
|
|
|
|
|
/* See also anv_GetPhysicalDeviceMultisamplePropertiesEXT */
|
|
|
|
|
props->maxSampleLocationGridSize.width = 1;
|
|
|
|
|
props->maxSampleLocationGridSize.height = 1;
|
|
|
|
|
|
|
|
|
|
props->sampleLocationCoordinateRange[0] = 0;
|
|
|
|
|
props->sampleLocationCoordinateRange[1] = 0.9375;
|
|
|
|
|
props->sampleLocationSubPixelBits = 4;
|
|
|
|
|
|
|
|
|
|
props->variableSampleLocations = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-24 12:39:16 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *)ext;
|
|
|
|
|
STATIC_ASSERT(sizeof(vk_shaderModuleIdentifierAlgorithmUUID) ==
|
|
|
|
|
sizeof(props->shaderModuleIdentifierAlgorithmUUID));
|
|
|
|
|
memcpy(props->shaderModuleIdentifierAlgorithmUUID,
|
|
|
|
|
vk_shaderModuleIdentifierAlgorithmUUID,
|
|
|
|
|
sizeof(props->shaderModuleIdentifierAlgorithmUUID));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-10 16:17:37 -05:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
|
|
|
|
|
|
|
|
|
|
props->maxTransformFeedbackStreams = MAX_XFB_STREAMS;
|
|
|
|
|
props->maxTransformFeedbackBuffers = MAX_XFB_BUFFERS;
|
|
|
|
|
props->maxTransformFeedbackBufferSize = (1ull << 32);
|
|
|
|
|
props->maxTransformFeedbackStreamDataSize = 128 * 4;
|
|
|
|
|
props->maxTransformFeedbackBufferDataSize = 128 * 4;
|
|
|
|
|
props->maxTransformFeedbackBufferDataStride = 2048;
|
2019-03-12 15:22:19 -05:00
|
|
|
props->transformFeedbackQueries = true;
|
|
|
|
|
props->transformFeedbackStreamsLinesTriangles = false;
|
|
|
|
|
props->transformFeedbackRasterizationStreamSelect = false;
|
2022-08-03 12:38:39 +03:00
|
|
|
props->transformFeedbackDraw = true;
|
2018-09-10 16:17:37 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-02 12:57:44 -07:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
|
|
|
|
|
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
|
|
|
|
|
/* We have to restrict this a bit for multiview */
|
|
|
|
|
props->maxVertexAttribDivisor = UINT32_MAX / 16;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-22 12:53:15 -04:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceMultiDrawPropertiesEXT *props = (VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
|
|
|
|
|
props->maxMultiDrawCount = 2048;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-25 12:12:20 -08:00
|
|
|
default:
|
2017-02-14 14:29:19 -08:00
|
|
|
anv_debug_ignored_stype(ext->sType);
|
2017-01-25 12:12:20 -08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-05 13:15:06 -08:00
|
|
|
static const VkQueueFamilyProperties
|
2021-01-26 01:13:36 -06:00
|
|
|
anv_queue_family_properties_template = {
|
2017-03-05 13:15:06 -08:00
|
|
|
.timestampValidBits = 36, /* XXX: Real value here */
|
2017-03-16 08:50:36 -07:00
|
|
|
.minImageTransferGranularity = { 1, 1, 1 },
|
2017-03-05 13:15:06 -08:00
|
|
|
};
|
2017-01-25 12:12:19 -08:00
|
|
|
|
2017-09-20 12:18:10 -07:00
|
|
|
void anv_GetPhysicalDeviceQueueFamilyProperties2(
|
2017-01-25 12:12:20 -08:00
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t* pQueueFamilyPropertyCount,
|
2017-09-20 13:16:26 -07:00
|
|
|
VkQueueFamilyProperties2* pQueueFamilyProperties)
|
2017-01-25 12:12:20 -08:00
|
|
|
{
|
2021-01-26 01:13:36 -06:00
|
|
|
ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
|
2022-03-23 13:50:34 +01:00
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkQueueFamilyProperties2, out,
|
|
|
|
|
pQueueFamilyProperties, pQueueFamilyPropertyCount);
|
2017-01-25 12:12:20 -08:00
|
|
|
|
2021-01-26 01:13:36 -06:00
|
|
|
for (uint32_t i = 0; i < pdevice->queue.family_count; i++) {
|
|
|
|
|
struct anv_queue_family *queue_family = &pdevice->queue.families[i];
|
2022-03-23 13:50:34 +01:00
|
|
|
vk_outarray_append_typed(VkQueueFamilyProperties2, &out, p) {
|
2021-01-26 01:13:36 -06:00
|
|
|
p->queueFamilyProperties = anv_queue_family_properties_template;
|
|
|
|
|
p->queueFamilyProperties.queueFlags = queue_family->queueFlags;
|
|
|
|
|
p->queueFamilyProperties.queueCount = queue_family->queueCount;
|
2017-01-25 12:12:20 -08:00
|
|
|
|
2021-05-25 10:30:49 -05:00
|
|
|
vk_foreach_struct(ext, p->pNext) {
|
|
|
|
|
switch (ext->sType) {
|
2022-07-01 13:03:31 +01:00
|
|
|
case VK_STRUCTURE_TYPE_QUEUE_FAMILY_GLOBAL_PRIORITY_PROPERTIES_KHR: {
|
|
|
|
|
VkQueueFamilyGlobalPriorityPropertiesKHR *properties =
|
|
|
|
|
(VkQueueFamilyGlobalPriorityPropertiesKHR *)ext;
|
2021-05-25 10:30:49 -05:00
|
|
|
|
|
|
|
|
/* Deliberately sorted low to high */
|
2022-07-01 13:03:31 +01:00
|
|
|
VkQueueGlobalPriorityKHR all_priorities[] = {
|
|
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_LOW_KHR,
|
|
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_KHR,
|
|
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_HIGH_KHR,
|
|
|
|
|
VK_QUEUE_GLOBAL_PRIORITY_REALTIME_KHR,
|
2021-05-25 10:30:49 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
uint32_t count = 0;
|
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(all_priorities); i++) {
|
2022-08-17 12:44:29 -07:00
|
|
|
if (all_priorities[i] > pdevice->max_context_priority)
|
2021-05-25 10:30:49 -05:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
properties->priorities[count++] = all_priorities[i];
|
|
|
|
|
}
|
|
|
|
|
properties->priorityCount = count;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-01-20 14:19:33 +10:00
|
|
|
case VK_STRUCTURE_TYPE_QUEUE_FAMILY_QUERY_RESULT_STATUS_PROPERTIES_KHR: {
|
|
|
|
|
VkQueueFamilyQueryResultStatusPropertiesKHR *prop =
|
|
|
|
|
(VkQueueFamilyQueryResultStatusPropertiesKHR *)ext;
|
|
|
|
|
prop->queryResultStatusSupport = VK_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-11-15 09:22:11 +10:00
|
|
|
case VK_STRUCTURE_TYPE_QUEUE_FAMILY_VIDEO_PROPERTIES_KHR: {
|
|
|
|
|
VkQueueFamilyVideoPropertiesKHR *prop =
|
|
|
|
|
(VkQueueFamilyVideoPropertiesKHR *)ext;
|
|
|
|
|
if (queue_family->queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR)
|
|
|
|
|
prop->videoCodecOperations = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-05-25 10:30:49 -05:00
|
|
|
default:
|
|
|
|
|
anv_debug_ignored_stype(ext->sType);
|
|
|
|
|
}
|
2021-01-26 01:13:36 -06:00
|
|
|
}
|
2017-01-25 12:12:20 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 12:21:19 -08:00
|
|
|
void anv_GetPhysicalDeviceMemoryProperties(
|
2015-07-09 19:49:19 -07:00
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceMemoryProperties* pMemoryProperties)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
2017-05-17 10:55:41 -07:00
|
|
|
pMemoryProperties->memoryTypeCount = physical_device->memory.type_count;
|
|
|
|
|
for (uint32_t i = 0; i < physical_device->memory.type_count; i++) {
|
|
|
|
|
pMemoryProperties->memoryTypes[i] = (VkMemoryType) {
|
|
|
|
|
.propertyFlags = physical_device->memory.types[i].propertyFlags,
|
|
|
|
|
.heapIndex = physical_device->memory.types[i].heapIndex,
|
2015-12-03 23:09:09 -08:00
|
|
|
};
|
|
|
|
|
}
|
2015-07-09 19:49:19 -07:00
|
|
|
|
2017-05-17 10:55:41 -07:00
|
|
|
pMemoryProperties->memoryHeapCount = physical_device->memory.heap_count;
|
|
|
|
|
for (uint32_t i = 0; i < physical_device->memory.heap_count; i++) {
|
|
|
|
|
pMemoryProperties->memoryHeaps[i] = (VkMemoryHeap) {
|
|
|
|
|
.size = physical_device->memory.heaps[i].size,
|
|
|
|
|
.flags = physical_device->memory.heaps[i].flags,
|
|
|
|
|
};
|
|
|
|
|
}
|
2015-07-09 19:49:19 -07:00
|
|
|
}
|
|
|
|
|
|
2019-01-08 12:45:38 +00:00
|
|
|
static void
|
|
|
|
|
anv_get_memory_budget(VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceMemoryBudgetPropertiesEXT *memoryBudget)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice);
|
|
|
|
|
|
2022-08-19 23:31:08 +03:00
|
|
|
if (!device->vk.supported_extensions.EXT_memory_budget)
|
|
|
|
|
return;
|
|
|
|
|
|
2021-08-17 18:23:11 -07:00
|
|
|
anv_update_meminfo(device, device->local_fd);
|
|
|
|
|
|
|
|
|
|
VkDeviceSize total_sys_heaps_size = 0, total_vram_heaps_size = 0;
|
|
|
|
|
for (size_t i = 0; i < device->memory.heap_count; i++) {
|
|
|
|
|
if (device->memory.heaps[i].is_local_mem) {
|
|
|
|
|
total_vram_heaps_size += device->memory.heaps[i].size;
|
|
|
|
|
} else {
|
|
|
|
|
total_sys_heaps_size += device->memory.heaps[i].size;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-08 12:45:38 +00:00
|
|
|
|
|
|
|
|
for (size_t i = 0; i < device->memory.heap_count; i++) {
|
|
|
|
|
VkDeviceSize heap_size = device->memory.heaps[i].size;
|
|
|
|
|
VkDeviceSize heap_used = device->memory.heaps[i].used;
|
2021-08-17 18:23:11 -07:00
|
|
|
VkDeviceSize heap_budget, total_heaps_size;
|
|
|
|
|
uint64_t mem_available = 0;
|
|
|
|
|
|
|
|
|
|
if (device->memory.heaps[i].is_local_mem) {
|
|
|
|
|
total_heaps_size = total_vram_heaps_size;
|
2022-07-26 20:20:24 -07:00
|
|
|
if (device->vram_non_mappable.size > 0 && i == 0) {
|
|
|
|
|
mem_available = device->vram_non_mappable.available;
|
|
|
|
|
} else {
|
|
|
|
|
mem_available = device->vram_mappable.available;
|
|
|
|
|
}
|
2021-08-17 18:23:11 -07:00
|
|
|
} else {
|
|
|
|
|
total_heaps_size = total_sys_heaps_size;
|
|
|
|
|
mem_available = device->sys.available;
|
|
|
|
|
}
|
2019-01-08 12:45:38 +00:00
|
|
|
|
|
|
|
|
double heap_proportion = (double) heap_size / total_heaps_size;
|
2021-08-17 18:23:11 -07:00
|
|
|
VkDeviceSize available_prop = mem_available * heap_proportion;
|
2019-01-08 12:45:38 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Let's not incite the app to starve the system: report at most 90% of
|
2021-08-17 18:23:11 -07:00
|
|
|
* the available heap memory.
|
2019-01-08 12:45:38 +00:00
|
|
|
*/
|
2021-08-17 18:23:11 -07:00
|
|
|
uint64_t heap_available = available_prop * 9 / 10;
|
2019-01-08 12:45:38 +00:00
|
|
|
heap_budget = MIN2(heap_size, heap_used + heap_available);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Round down to the nearest MB
|
|
|
|
|
*/
|
|
|
|
|
heap_budget &= ~((1ull << 20) - 1);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The heapBudget value must be non-zero for array elements less than
|
|
|
|
|
* VkPhysicalDeviceMemoryProperties::memoryHeapCount. The heapBudget
|
|
|
|
|
* value must be less than or equal to VkMemoryHeap::size for each heap.
|
|
|
|
|
*/
|
|
|
|
|
assert(0 < heap_budget && heap_budget <= heap_size);
|
|
|
|
|
|
|
|
|
|
memoryBudget->heapUsage[i] = heap_used;
|
|
|
|
|
memoryBudget->heapBudget[i] = heap_budget;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* The heapBudget and heapUsage values must be zero for array elements
|
|
|
|
|
* greater than or equal to VkPhysicalDeviceMemoryProperties::memoryHeapCount
|
|
|
|
|
*/
|
|
|
|
|
for (uint32_t i = device->memory.heap_count; i < VK_MAX_MEMORY_HEAPS; i++) {
|
|
|
|
|
memoryBudget->heapBudget[i] = 0;
|
|
|
|
|
memoryBudget->heapUsage[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-20 12:18:10 -07:00
|
|
|
void anv_GetPhysicalDeviceMemoryProperties2(
|
2017-01-25 12:12:20 -08:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2017-09-20 13:16:26 -07:00
|
|
|
VkPhysicalDeviceMemoryProperties2* pMemoryProperties)
|
2017-01-25 12:12:20 -08:00
|
|
|
{
|
|
|
|
|
anv_GetPhysicalDeviceMemoryProperties(physicalDevice,
|
|
|
|
|
&pMemoryProperties->memoryProperties);
|
|
|
|
|
|
2017-02-14 14:29:19 -08:00
|
|
|
vk_foreach_struct(ext, pMemoryProperties->pNext) {
|
|
|
|
|
switch (ext->sType) {
|
2019-01-08 12:45:38 +00:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT:
|
|
|
|
|
anv_get_memory_budget(physicalDevice, (void*)ext);
|
|
|
|
|
break;
|
2017-01-25 12:12:20 -08:00
|
|
|
default:
|
2017-02-14 14:29:19 -08:00
|
|
|
anv_debug_ignored_stype(ext->sType);
|
2017-01-25 12:12:20 -08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-21 13:54:55 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-07 18:51:53 -07:00
|
|
|
PFN_vkVoidFunction anv_GetInstanceProcAddr(
|
2018-01-16 16:14:25 -08:00
|
|
|
VkInstance _instance,
|
2015-07-07 18:51:53 -07:00
|
|
|
const char* pName)
|
|
|
|
|
{
|
2018-01-16 16:14:25 -08:00
|
|
|
ANV_FROM_HANDLE(anv_instance, instance, _instance);
|
2021-01-23 04:57:21 -06:00
|
|
|
return vk_instance_get_proc_addr(&instance->vk,
|
|
|
|
|
&anv_instance_entrypoints,
|
|
|
|
|
pName);
|
2015-07-07 18:51:53 -07:00
|
|
|
}
|
|
|
|
|
|
2016-07-28 14:40:08 +01:00
|
|
|
/* With version 1+ of the loader interface the ICD should expose
|
|
|
|
|
* vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps.
|
2016-02-11 21:18:02 -08:00
|
|
|
*/
|
2016-07-28 14:40:08 +01:00
|
|
|
PUBLIC
|
2016-02-11 21:18:02 -08:00
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
|
|
|
|
|
VkInstance instance,
|
|
|
|
|
const char* pName);
|
|
|
|
|
|
2016-07-28 14:40:08 +01:00
|
|
|
PUBLIC
|
2016-02-11 21:18:02 -08:00
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
|
|
|
|
|
VkInstance instance,
|
|
|
|
|
const char* pName)
|
|
|
|
|
{
|
|
|
|
|
return anv_GetInstanceProcAddr(instance, pName);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-08 00:11:01 +03:00
|
|
|
/* With version 4+ of the loader interface the ICD should expose
|
|
|
|
|
* vk_icdGetPhysicalDeviceProcAddr()
|
|
|
|
|
*/
|
|
|
|
|
PUBLIC
|
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
const char* pName);
|
|
|
|
|
|
|
|
|
|
PFN_vkVoidFunction vk_icdGetPhysicalDeviceProcAddr(
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
const char* pName)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_instance, instance, _instance);
|
2021-01-23 04:57:21 -06:00
|
|
|
return vk_instance_get_physical_device_proc_addr(&instance->vk, pName);
|
2019-09-08 00:11:01 +03:00
|
|
|
}
|
|
|
|
|
|
2015-12-01 15:37:12 -08:00
|
|
|
static struct anv_state
|
|
|
|
|
anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, const void *p)
|
|
|
|
|
{
|
|
|
|
|
struct anv_state state;
|
|
|
|
|
|
|
|
|
|
state = anv_state_pool_alloc(pool, size, align);
|
|
|
|
|
memcpy(state.map, p, size);
|
|
|
|
|
|
|
|
|
|
return state;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-29 16:06:06 -07:00
|
|
|
static void
|
|
|
|
|
anv_device_init_border_colors(struct anv_device *device)
|
|
|
|
|
{
|
2022-12-16 13:07:28 +02:00
|
|
|
static const struct gfx8_border_color border_colors[] = {
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } },
|
|
|
|
|
[VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } },
|
|
|
|
|
};
|
2019-06-18 10:15:24 -05:00
|
|
|
|
2022-12-16 13:07:28 +02:00
|
|
|
device->border_colors =
|
|
|
|
|
anv_state_pool_emit_data(&device->dynamic_state_pool,
|
|
|
|
|
sizeof(border_colors), 64, border_colors);
|
2015-05-29 16:06:06 -07:00
|
|
|
}
|
|
|
|
|
|
2019-10-28 17:28:09 -05:00
|
|
|
static VkResult
|
2017-02-27 16:34:13 -08:00
|
|
|
anv_device_init_trivial_batch(struct anv_device *device)
|
|
|
|
|
{
|
2020-06-17 15:37:33 +03:00
|
|
|
VkResult result = anv_device_alloc_bo(device, "trivial-batch", 4096,
|
2019-10-28 17:28:09 -05:00
|
|
|
ANV_BO_ALLOC_MAPPED,
|
2019-12-02 15:22:38 -06:00
|
|
|
0 /* explicit_address */,
|
2019-10-28 17:28:09 -05:00
|
|
|
&device->trivial_batch_bo);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2017-02-27 16:34:13 -08:00
|
|
|
|
|
|
|
|
struct anv_batch batch = {
|
2019-10-28 17:28:09 -05:00
|
|
|
.start = device->trivial_batch_bo->map,
|
|
|
|
|
.next = device->trivial_batch_bo->map,
|
|
|
|
|
.end = device->trivial_batch_bo->map + 4096,
|
2017-02-27 16:34:13 -08:00
|
|
|
};
|
|
|
|
|
|
2021-03-29 15:16:59 -07:00
|
|
|
anv_batch_emit(&batch, GFX7_MI_BATCH_BUFFER_END, bbe);
|
|
|
|
|
anv_batch_emit(&batch, GFX7_MI_NOOP, noop);
|
2017-02-27 16:34:13 -08:00
|
|
|
|
2022-11-22 07:26:58 -08:00
|
|
|
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
|
2022-04-06 22:56:00 +03:00
|
|
|
if (device->physical->memory.need_clflush)
|
2021-04-07 13:22:19 -07:00
|
|
|
intel_clflush_range(batch.start, batch.next - batch.start);
|
2022-11-22 07:26:58 -08:00
|
|
|
#endif
|
2017-02-27 16:34:13 -08:00
|
|
|
|
2019-10-28 17:28:09 -05:00
|
|
|
return VK_SUCCESS;
|
2017-02-27 16:34:13 -08:00
|
|
|
}
|
|
|
|
|
|
2019-02-23 23:27:17 +00:00
|
|
|
static bool
|
2021-03-03 13:49:18 -08:00
|
|
|
get_bo_from_pool(struct intel_batch_decode_bo *ret,
|
2019-02-23 23:27:17 +00:00
|
|
|
struct anv_block_pool *pool,
|
|
|
|
|
uint64_t address)
|
|
|
|
|
{
|
2019-10-25 16:42:47 -05:00
|
|
|
anv_block_pool_foreach_bo(bo, pool) {
|
2021-03-03 13:49:18 -08:00
|
|
|
uint64_t bo_address = intel_48b_address(bo->offset);
|
2019-10-25 16:42:47 -05:00
|
|
|
if (address >= bo_address && address < (bo_address + bo->size)) {
|
2021-03-03 13:49:18 -08:00
|
|
|
*ret = (struct intel_batch_decode_bo) {
|
2019-02-23 23:27:17 +00:00
|
|
|
.addr = bo_address,
|
2019-10-25 16:42:47 -05:00
|
|
|
.size = bo->size,
|
|
|
|
|
.map = bo->map,
|
2019-02-23 23:27:17 +00:00
|
|
|
};
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Finding a buffer for batch decoding */
|
2021-03-03 13:49:18 -08:00
|
|
|
static struct intel_batch_decode_bo
|
2018-08-28 11:41:42 +01:00
|
|
|
decode_get_bo(void *v_batch, bool ppgtt, uint64_t address)
|
2019-02-23 23:27:17 +00:00
|
|
|
{
|
|
|
|
|
struct anv_device *device = v_batch;
|
2021-03-03 13:49:18 -08:00
|
|
|
struct intel_batch_decode_bo ret_bo = {};
|
2019-02-23 23:27:17 +00:00
|
|
|
|
2018-08-28 11:41:42 +01:00
|
|
|
assert(ppgtt);
|
|
|
|
|
|
2019-02-23 23:27:17 +00:00
|
|
|
if (get_bo_from_pool(&ret_bo, &device->dynamic_state_pool.block_pool, address))
|
|
|
|
|
return ret_bo;
|
|
|
|
|
if (get_bo_from_pool(&ret_bo, &device->instruction_state_pool.block_pool, address))
|
|
|
|
|
return ret_bo;
|
|
|
|
|
if (get_bo_from_pool(&ret_bo, &device->binding_table_pool.block_pool, address))
|
|
|
|
|
return ret_bo;
|
2022-11-14 15:54:01 +02:00
|
|
|
if (get_bo_from_pool(&ret_bo, &device->scratch_surface_state_pool.block_pool, address))
|
2022-10-24 14:12:28 +03:00
|
|
|
return ret_bo;
|
|
|
|
|
if (get_bo_from_pool(&ret_bo, &device->bindless_surface_state_pool.block_pool, address))
|
2019-02-23 23:27:17 +00:00
|
|
|
return ret_bo;
|
2022-11-14 15:54:01 +02:00
|
|
|
if (get_bo_from_pool(&ret_bo, &device->internal_surface_state_pool.block_pool, address))
|
|
|
|
|
return ret_bo;
|
2019-02-23 23:27:17 +00:00
|
|
|
|
|
|
|
|
if (!device->cmd_buffer_being_decoded)
|
2021-03-03 13:49:18 -08:00
|
|
|
return (struct intel_batch_decode_bo) { };
|
2019-02-23 23:27:17 +00:00
|
|
|
|
|
|
|
|
struct anv_batch_bo **bo;
|
|
|
|
|
|
|
|
|
|
u_vector_foreach(bo, &device->cmd_buffer_being_decoded->seen_bbos) {
|
|
|
|
|
/* The decoder zeroes out the top 16 bits, so we need to as well */
|
2019-10-28 15:42:20 -05:00
|
|
|
uint64_t bo_address = (*bo)->bo->offset & (~0ull >> 16);
|
2019-02-23 23:27:17 +00:00
|
|
|
|
2019-10-28 15:42:20 -05:00
|
|
|
if (address >= bo_address && address < bo_address + (*bo)->bo->size) {
|
2021-03-03 13:49:18 -08:00
|
|
|
return (struct intel_batch_decode_bo) {
|
2019-02-23 23:27:17 +00:00
|
|
|
.addr = bo_address,
|
2019-10-28 15:42:20 -05:00
|
|
|
.size = (*bo)->bo->size,
|
|
|
|
|
.map = (*bo)->bo->map,
|
2019-02-23 23:27:17 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
return (struct intel_batch_decode_bo) { };
|
2019-02-23 23:27:17 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
struct intel_aux_map_buffer {
|
|
|
|
|
struct intel_buffer base;
|
2018-04-01 13:57:13 -07:00
|
|
|
struct anv_state state;
|
|
|
|
|
};
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
static struct intel_buffer *
|
|
|
|
|
intel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size)
|
2018-04-01 13:57:13 -07:00
|
|
|
{
|
2021-03-03 13:49:18 -08:00
|
|
|
struct intel_aux_map_buffer *buf = malloc(sizeof(struct intel_aux_map_buffer));
|
2018-04-01 13:57:13 -07:00
|
|
|
if (!buf)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
struct anv_device *device = (struct anv_device*)driver_ctx;
|
|
|
|
|
|
|
|
|
|
struct anv_state_pool *pool = &device->dynamic_state_pool;
|
|
|
|
|
buf->state = anv_state_pool_alloc(pool, size, size);
|
|
|
|
|
|
|
|
|
|
buf->base.gpu = pool->block_pool.bo->offset + buf->state.offset;
|
|
|
|
|
buf->base.gpu_end = buf->base.gpu + buf->state.alloc_size;
|
|
|
|
|
buf->base.map = buf->state.map;
|
|
|
|
|
buf->base.driver_bo = &buf->state;
|
|
|
|
|
return &buf->base;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2021-03-03 13:49:18 -08:00
|
|
|
intel_aux_map_buffer_free(void *driver_ctx, struct intel_buffer *buffer)
|
2018-04-01 13:57:13 -07:00
|
|
|
{
|
2021-03-03 13:49:18 -08:00
|
|
|
struct intel_aux_map_buffer *buf = (struct intel_aux_map_buffer*)buffer;
|
2018-04-01 13:57:13 -07:00
|
|
|
struct anv_device *device = (struct anv_device*)driver_ctx;
|
|
|
|
|
struct anv_state_pool *pool = &device->dynamic_state_pool;
|
|
|
|
|
anv_state_pool_free(pool, buf->state);
|
|
|
|
|
free(buf);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-07 13:22:19 -07:00
|
|
|
static struct intel_mapped_pinned_buffer_alloc aux_map_allocator = {
|
2021-03-03 13:49:18 -08:00
|
|
|
.alloc = intel_aux_map_buffer_alloc,
|
|
|
|
|
.free = intel_aux_map_buffer_free,
|
2018-04-01 13:57:13 -07:00
|
|
|
};
|
|
|
|
|
|
2023-02-09 08:44:04 -08:00
|
|
|
static VkResult
|
|
|
|
|
anv_device_setup_context_or_vm(struct anv_device *device,
|
|
|
|
|
const VkDeviceCreateInfo *pCreateInfo,
|
|
|
|
|
const uint32_t num_queues)
|
|
|
|
|
{
|
2023-02-09 08:57:11 -08:00
|
|
|
switch (device->info->kmd_type) {
|
2023-02-09 08:44:04 -08:00
|
|
|
case INTEL_KMD_TYPE_I915:
|
|
|
|
|
return anv_i915_device_setup_context(device, pCreateInfo, num_queues);
|
|
|
|
|
case INTEL_KMD_TYPE_XE:
|
|
|
|
|
return anv_xe_device_setup_vm(device);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Missing");
|
|
|
|
|
return VK_ERROR_UNKNOWN;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool
|
|
|
|
|
anv_device_destroy_context_or_vm(struct anv_device *device)
|
|
|
|
|
{
|
2023-02-09 08:57:11 -08:00
|
|
|
switch (device->info->kmd_type) {
|
2023-02-09 08:44:04 -08:00
|
|
|
case INTEL_KMD_TYPE_I915:
|
|
|
|
|
return intel_gem_destroy_context(device->fd, device->context_id);
|
|
|
|
|
case INTEL_KMD_TYPE_XE:
|
|
|
|
|
return anv_xe_device_destroy_vm(device);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Missing");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateDevice(
|
2015-07-09 18:20:10 -07:00
|
|
|
VkPhysicalDevice physicalDevice,
|
2015-05-08 22:32:37 -07:00
|
|
|
const VkDeviceCreateInfo* pCreateInfo,
|
2015-12-02 03:28:27 -08:00
|
|
|
const VkAllocationCallbacks* pAllocator,
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice* pDevice)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
2016-01-03 22:43:47 -08:00
|
|
|
VkResult result;
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_device *device;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
|
|
|
|
|
|
2018-02-06 10:37:16 +01:00
|
|
|
/* Check requested queues and fail if we are requested to create any
|
|
|
|
|
* queues with flags we don't support.
|
|
|
|
|
*/
|
|
|
|
|
assert(pCreateInfo->queueCreateInfoCount > 0);
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
|
|
|
|
|
if (pCreateInfo->pQueueCreateInfos[i].flags != 0)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(physical_device, VK_ERROR_INITIALIZATION_FAILED);
|
2018-02-06 10:37:16 +01:00
|
|
|
}
|
|
|
|
|
|
2021-10-06 13:14:20 +02:00
|
|
|
device = vk_zalloc2(&physical_device->instance->vk.alloc, pAllocator,
|
2015-12-02 03:28:27 -08:00
|
|
|
sizeof(*device), 8,
|
2016-01-18 14:04:13 -08:00
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
2015-05-08 22:32:37 -07:00
|
|
|
if (!device)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(physical_device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2021-01-23 04:57:21 -06:00
|
|
|
struct vk_device_dispatch_table dispatch_table;
|
2022-08-23 10:06:11 +03:00
|
|
|
|
|
|
|
|
bool override_initial_entrypoints = true;
|
|
|
|
|
if (physical_device->instance->vk.app_info.app_name &&
|
|
|
|
|
!strcmp(physical_device->instance->vk.app_info.app_name, "HITMAN3.exe")) {
|
|
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table, &hitman3_device_entrypoints, true);
|
|
|
|
|
override_initial_entrypoints = false;
|
|
|
|
|
}
|
2022-11-03 01:41:53 +02:00
|
|
|
if (physical_device->info.ver < 12 &&
|
|
|
|
|
physical_device->instance->vk.app_info.app_name &&
|
|
|
|
|
!strcmp(physical_device->instance->vk.app_info.app_name, "DOOM 64")) {
|
|
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table, &doom64_device_entrypoints, true);
|
|
|
|
|
override_initial_entrypoints = false;
|
|
|
|
|
}
|
2023-05-03 07:13:07 +03:00
|
|
|
#ifdef ANDROID
|
|
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table, &android_device_entrypoints, true);
|
|
|
|
|
override_initial_entrypoints = false;
|
|
|
|
|
#endif
|
2021-01-23 04:57:21 -06:00
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table,
|
2022-08-23 10:06:11 +03:00
|
|
|
anv_genX(&physical_device->info, device_entrypoints),
|
|
|
|
|
override_initial_entrypoints);
|
2021-01-23 04:57:21 -06:00
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table,
|
|
|
|
|
&anv_device_entrypoints, false);
|
2021-10-06 11:21:55 -05:00
|
|
|
vk_device_dispatch_table_from_entrypoints(&dispatch_table,
|
|
|
|
|
&wsi_device_entrypoints, false);
|
2021-01-23 04:57:21 -06:00
|
|
|
|
|
|
|
|
result = vk_device_init(&device->vk, &physical_device->vk,
|
2021-01-29 12:30:34 -06:00
|
|
|
&dispatch_table, pCreateInfo, pAllocator);
|
2021-09-24 16:04:51 -05:00
|
|
|
if (result != VK_SUCCESS)
|
2021-01-24 09:26:24 -06:00
|
|
|
goto fail_alloc;
|
2020-04-21 12:42:59 -05:00
|
|
|
|
2021-10-13 11:21:41 +02:00
|
|
|
if (INTEL_DEBUG(DEBUG_BATCH)) {
|
2023-01-30 14:46:26 -08:00
|
|
|
for (unsigned i = 0; i < physical_device->queue.family_count; i++) {
|
|
|
|
|
struct intel_batch_decode_ctx *decoder = &device->decoder[i];
|
|
|
|
|
|
|
|
|
|
const unsigned decode_flags =
|
|
|
|
|
INTEL_BATCH_DECODE_FULL |
|
|
|
|
|
(INTEL_DEBUG(DEBUG_COLOR) ? INTEL_BATCH_DECODE_IN_COLOR : 0) |
|
|
|
|
|
INTEL_BATCH_DECODE_OFFSETS |
|
|
|
|
|
INTEL_BATCH_DECODE_FLOATS;
|
|
|
|
|
|
|
|
|
|
intel_batch_decode_ctx_init(decoder,
|
|
|
|
|
&physical_device->compiler->isa,
|
|
|
|
|
&physical_device->info,
|
|
|
|
|
stderr, decode_flags, NULL,
|
|
|
|
|
decode_get_bo, NULL, device);
|
|
|
|
|
|
|
|
|
|
decoder->engine = physical_device->queue.families[i].engine_class;
|
2023-02-23 09:59:45 +02:00
|
|
|
decoder->dynamic_base = physical_device->va.dynamic_state_pool.addr;
|
|
|
|
|
decoder->surface_base = physical_device->va.internal_surface_state_pool.addr;
|
|
|
|
|
decoder->instruction_base = physical_device->va.instruction_state_pool.addr;
|
2023-01-30 14:46:26 -08:00
|
|
|
}
|
2019-06-12 12:41:36 +03:00
|
|
|
}
|
2019-02-23 23:27:17 +00:00
|
|
|
|
2022-08-22 20:07:21 +08:00
|
|
|
anv_device_set_physical(device, physical_device);
|
2023-01-26 11:06:46 -08:00
|
|
|
device->kmd_backend = anv_kmd_backend_get(device->info->kmd_type);
|
2015-07-09 16:31:39 -07:00
|
|
|
|
|
|
|
|
/* XXX(chadv): Can we dup() physicalDevice->fd here? */
|
2015-07-09 18:20:10 -07:00
|
|
|
device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
|
2016-01-03 22:43:47 -08:00
|
|
|
if (device->fd == -1) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail_device;
|
2016-01-03 22:43:47 -08:00
|
|
|
}
|
2015-11-13 10:12:18 -08:00
|
|
|
|
2023-02-09 12:34:50 -08:00
|
|
|
switch (device->info->kmd_type) {
|
|
|
|
|
case INTEL_KMD_TYPE_I915:
|
|
|
|
|
device->vk.check_status = anv_i915_device_check_status;
|
|
|
|
|
break;
|
|
|
|
|
case INTEL_KMD_TYPE_XE:
|
|
|
|
|
device->vk.check_status = anv_xe_device_check_status;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Missing");
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-30 13:42:58 -05:00
|
|
|
device->vk.command_buffer_ops = &anv_cmd_buffer_ops;
|
2021-12-16 14:14:19 -06:00
|
|
|
device->vk.create_sync_for_memory = anv_create_sync_for_memory;
|
2022-09-15 06:46:23 -07:00
|
|
|
if (physical_device->info.kmd_type == INTEL_KMD_TYPE_I915)
|
|
|
|
|
device->vk.create_sync_for_memory = anv_create_sync_for_memory;
|
2021-10-20 09:44:02 -05:00
|
|
|
vk_device_set_drm_fd(&device->vk, device->fd);
|
2021-11-08 12:53:10 -06:00
|
|
|
|
2019-03-24 01:00:37 -07:00
|
|
|
uint32_t num_queues = 0;
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++)
|
|
|
|
|
num_queues += pCreateInfo->pQueueCreateInfos[i].queueCount;
|
|
|
|
|
|
2023-02-09 08:44:04 -08:00
|
|
|
result = anv_device_setup_context_or_vm(device, pCreateInfo, num_queues);
|
2022-08-09 13:37:13 -07:00
|
|
|
if (result != VK_SUCCESS)
|
2015-05-08 22:32:37 -07:00
|
|
|
goto fail_fd;
|
2021-08-19 10:51:17 -05:00
|
|
|
|
2018-08-14 02:34:16 -07:00
|
|
|
device->queues =
|
|
|
|
|
vk_zalloc(&device->vk.alloc, num_queues * sizeof(*device->queues), 8,
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
|
|
|
|
if (device->queues == NULL) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2019-08-23 12:30:42 +02:00
|
|
|
goto fail_context_id;
|
2018-08-14 02:34:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
device->queue_count = 0;
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
|
|
|
|
|
const VkDeviceQueueCreateInfo *queueCreateInfo =
|
|
|
|
|
&pCreateInfo->pQueueCreateInfos[i];
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < queueCreateInfo->queueCount; j++) {
|
2019-03-24 01:00:37 -07:00
|
|
|
/* When using legacy contexts, we use I915_EXEC_RENDER but, with
|
|
|
|
|
* engine-based contexts, the bottom 6 bits of exec_flags are used
|
|
|
|
|
* for the engine ID.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t exec_flags = device->physical->engine_info ?
|
|
|
|
|
device->queue_count : I915_EXEC_RENDER;
|
|
|
|
|
|
2018-08-14 02:34:16 -07:00
|
|
|
result = anv_queue_init(device, &device->queues[device->queue_count],
|
2021-09-23 11:14:36 -05:00
|
|
|
exec_flags, queueCreateInfo, j);
|
2018-08-14 02:34:16 -07:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_queues;
|
|
|
|
|
|
|
|
|
|
device->queue_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-08-23 12:30:42 +02:00
|
|
|
|
2022-08-30 15:12:27 -07:00
|
|
|
if (pthread_mutex_init(&device->vma_mutex, NULL) != 0) {
|
|
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
|
|
|
|
goto fail_queues;
|
|
|
|
|
}
|
2018-03-07 09:18:37 -08:00
|
|
|
|
2022-08-30 15:12:27 -07:00
|
|
|
/* keep the page with address zero out of the allocator */
|
|
|
|
|
util_vma_heap_init(&device->vma_lo,
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.low_heap.addr,
|
|
|
|
|
device->physical->va.low_heap.size);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
2023-02-23 09:59:45 +02:00
|
|
|
util_vma_heap_init(&device->vma_cva,
|
|
|
|
|
device->physical->va.client_visible_heap.addr,
|
|
|
|
|
device->physical->va.client_visible_heap.size);
|
2019-12-02 16:03:56 -06:00
|
|
|
|
2023-02-23 09:59:45 +02:00
|
|
|
util_vma_heap_init(&device->vma_hi,
|
|
|
|
|
device->physical->va.high_heap.addr,
|
|
|
|
|
device->physical->va.high_heap.size);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
2019-02-26 18:05:34 -06:00
|
|
|
list_inithead(&device->memory_objects);
|
2023-05-11 12:43:00 +03:00
|
|
|
list_inithead(&device->image_private_objects);
|
2019-02-26 18:05:34 -06:00
|
|
|
|
2016-11-30 06:59:15 +09:00
|
|
|
if (pthread_mutex_init(&device->mutex, NULL) != 0) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
2022-08-15 08:45:26 -07:00
|
|
|
goto fail_vmas;
|
2016-11-30 06:59:15 +09:00
|
|
|
}
|
2015-09-17 18:23:21 -07:00
|
|
|
|
2016-11-02 09:11:11 -07:00
|
|
|
pthread_condattr_t condattr;
|
2016-11-30 06:59:15 +09:00
|
|
|
if (pthread_condattr_init(&condattr) != 0) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
2016-11-30 06:59:15 +09:00
|
|
|
goto fail_mutex;
|
|
|
|
|
}
|
|
|
|
|
if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) {
|
|
|
|
|
pthread_condattr_destroy(&condattr);
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
2016-11-30 06:59:15 +09:00
|
|
|
goto fail_mutex;
|
|
|
|
|
}
|
2019-04-18 17:39:36 +01:00
|
|
|
if (pthread_cond_init(&device->queue_submit, &condattr) != 0) {
|
2016-11-30 06:59:15 +09:00
|
|
|
pthread_condattr_destroy(&condattr);
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INITIALIZATION_FAILED);
|
2016-11-30 06:59:15 +09:00
|
|
|
goto fail_mutex;
|
|
|
|
|
}
|
2016-11-02 09:11:11 -07:00
|
|
|
pthread_condattr_destroy(&condattr);
|
|
|
|
|
|
2021-09-24 12:06:32 -05:00
|
|
|
result = anv_bo_cache_init(&device->bo_cache, device);
|
2017-03-13 17:20:15 -07:00
|
|
|
if (result != VK_SUCCESS)
|
2019-10-28 15:42:20 -05:00
|
|
|
goto fail_queue_cond;
|
|
|
|
|
|
2020-06-17 15:37:33 +03:00
|
|
|
anv_bo_pool_init(&device->batch_bo_pool, device, "batch");
|
2017-03-13 17:20:15 -07:00
|
|
|
|
2020-05-04 17:08:00 -05:00
|
|
|
/* Because scratch is also relative to General State Base Address, we leave
|
|
|
|
|
* the base address 0 and start the pool memory at an offset. This way we
|
|
|
|
|
* get the correct offsets in the anv_states that get allocated from it.
|
|
|
|
|
*/
|
|
|
|
|
result = anv_state_pool_init(&device->general_state_pool, device,
|
2020-06-17 15:37:33 +03:00
|
|
|
"general pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
0, device->physical->va.general_state_pool.addr, 16384);
|
2020-05-04 17:08:00 -05:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_batch_bo_pool;
|
|
|
|
|
|
2018-03-01 09:25:44 -08:00
|
|
|
result = anv_state_pool_init(&device->dynamic_state_pool, device,
|
2020-06-17 15:37:33 +03:00
|
|
|
"dynamic pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.dynamic_state_pool.addr, 0, 16384);
|
2016-11-30 06:59:15 +09:00
|
|
|
if (result != VK_SUCCESS)
|
2020-05-04 17:08:00 -05:00
|
|
|
goto fail_general_state_pool;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2022-08-30 14:50:51 -07:00
|
|
|
/* The border color pointer is limited to 24 bits, so we need to make
|
|
|
|
|
* sure that any such color used at any point in the program doesn't
|
|
|
|
|
* exceed that limit.
|
|
|
|
|
* We achieve that by reserving all the custom border colors we support
|
|
|
|
|
* right off the bat, so they are close to the base address.
|
|
|
|
|
*/
|
|
|
|
|
anv_state_reserved_pool_init(&device->custom_border_colors,
|
|
|
|
|
&device->dynamic_state_pool,
|
|
|
|
|
MAX_CUSTOM_BORDER_COLORS,
|
|
|
|
|
sizeof(struct gfx8_border_color), 64);
|
2020-04-22 17:08:22 -07:00
|
|
|
|
2018-03-01 09:25:44 -08:00
|
|
|
result = anv_state_pool_init(&device->instruction_state_pool, device,
|
2020-06-17 15:37:33 +03:00
|
|
|
"instruction pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.instruction_state_pool.addr,
|
|
|
|
|
0, 16384);
|
2016-11-30 06:59:15 +09:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_dynamic_state_pool;
|
|
|
|
|
|
2022-11-14 15:54:01 +02:00
|
|
|
if (device->info->verx10 >= 125) {
|
|
|
|
|
/* Put the scratch surface states at the beginning of the internal
|
|
|
|
|
* surface state pool.
|
|
|
|
|
*/
|
|
|
|
|
result = anv_state_pool_init(&device->scratch_surface_state_pool, device,
|
|
|
|
|
"scratch surface state pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.scratch_surface_state_pool.addr,
|
|
|
|
|
0, 4096);
|
2022-11-14 15:54:01 +02:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_instruction_state_pool;
|
|
|
|
|
|
|
|
|
|
result = anv_state_pool_init(&device->internal_surface_state_pool, device,
|
|
|
|
|
"internal surface state pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.internal_surface_state_pool.addr,
|
|
|
|
|
device->physical->va.scratch_surface_state_pool.size,
|
|
|
|
|
4096);
|
2022-11-14 15:54:01 +02:00
|
|
|
} else {
|
|
|
|
|
result = anv_state_pool_init(&device->internal_surface_state_pool, device,
|
|
|
|
|
"internal surface state pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.internal_surface_state_pool.addr,
|
|
|
|
|
0, 4096);
|
2022-11-14 15:54:01 +02:00
|
|
|
}
|
2016-11-30 06:59:15 +09:00
|
|
|
if (result != VK_SUCCESS)
|
2022-11-14 15:54:01 +02:00
|
|
|
goto fail_scratch_surface_state_pool;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2022-10-24 14:12:28 +03:00
|
|
|
result = anv_state_pool_init(&device->bindless_surface_state_pool, device,
|
|
|
|
|
"bindless surface state pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.bindless_surface_state_pool.addr,
|
|
|
|
|
0, 4096);
|
2022-10-24 14:12:28 +03:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_internal_surface_state_pool;
|
|
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->info->verx10 >= 125) {
|
2022-03-25 11:53:56 -07:00
|
|
|
/* We're using 3DSTATE_BINDING_TABLE_POOL_ALLOC to give the binding
|
|
|
|
|
* table its own base address separately from surface state base.
|
|
|
|
|
*/
|
|
|
|
|
result = anv_state_pool_init(&device->binding_table_pool, device,
|
|
|
|
|
"binding table pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.binding_table_pool.addr, 0,
|
2022-03-25 11:53:56 -07:00
|
|
|
BINDING_TABLE_POOL_BLOCK_SIZE);
|
2022-08-30 15:12:27 -07:00
|
|
|
} else {
|
2023-02-23 09:59:45 +02:00
|
|
|
/* The binding table should be in front of the surface states in virtual
|
|
|
|
|
* address space so that all surface states can be express as relative
|
|
|
|
|
* offsets from the binding table location.
|
|
|
|
|
*/
|
|
|
|
|
assert(device->physical->va.binding_table_pool.addr <
|
|
|
|
|
device->physical->va.internal_surface_state_pool.addr);
|
|
|
|
|
int64_t bt_pool_offset = (int64_t)device->physical->va.binding_table_pool.addr -
|
|
|
|
|
(int64_t)device->physical->va.internal_surface_state_pool.addr;
|
2020-05-04 17:27:22 -05:00
|
|
|
assert(INT32_MIN < bt_pool_offset && bt_pool_offset < 0);
|
2018-03-14 10:31:16 -07:00
|
|
|
result = anv_state_pool_init(&device->binding_table_pool, device,
|
2020-06-17 15:37:33 +03:00
|
|
|
"binding table pool",
|
2023-02-23 09:59:45 +02:00
|
|
|
device->physical->va.internal_surface_state_pool.addr,
|
2021-12-19 22:22:26 -08:00
|
|
|
bt_pool_offset,
|
|
|
|
|
BINDING_TABLE_POOL_BLOCK_SIZE);
|
2018-03-14 10:31:16 -07:00
|
|
|
}
|
2022-03-25 11:53:56 -07:00
|
|
|
if (result != VK_SUCCESS)
|
2022-10-24 14:12:28 +03:00
|
|
|
goto fail_bindless_surface_state_pool;
|
2018-03-14 10:31:16 -07:00
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->info->has_aux_map) {
|
2021-03-03 13:49:18 -08:00
|
|
|
device->aux_map_ctx = intel_aux_map_init(device, &aux_map_allocator,
|
2021-03-09 09:44:02 -08:00
|
|
|
&physical_device->info);
|
2018-03-28 01:42:50 -07:00
|
|
|
if (!device->aux_map_ctx)
|
|
|
|
|
goto fail_binding_table_pool;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-17 15:37:33 +03:00
|
|
|
result = anv_device_alloc_bo(device, "workaround", 4096,
|
2020-08-28 13:01:53 -07:00
|
|
|
ANV_BO_ALLOC_CAPTURE |
|
2020-08-28 13:01:53 -07:00
|
|
|
ANV_BO_ALLOC_MAPPED |
|
|
|
|
|
(device->info->has_local_mem ?
|
|
|
|
|
ANV_BO_ALLOC_WRITE_COMBINE : 0),
|
2019-12-02 15:22:38 -06:00
|
|
|
0 /* explicit_address */,
|
|
|
|
|
&device->workaround_bo);
|
2016-11-30 06:59:15 +09:00
|
|
|
if (result != VK_SUCCESS)
|
2018-03-28 01:42:50 -07:00
|
|
|
goto fail_surface_aux_map_pool;
|
2015-11-10 16:42:34 -08:00
|
|
|
|
2020-02-21 17:36:36 +02:00
|
|
|
device->workaround_address = (struct anv_address) {
|
|
|
|
|
.bo = device->workaround_bo,
|
2022-12-02 00:44:57 +05:30
|
|
|
.offset = align(intel_debug_write_identifiers(device->workaround_bo->map,
|
|
|
|
|
device->workaround_bo->size,
|
2023-02-22 15:48:10 -08:00
|
|
|
"Anv"), 32),
|
2020-02-21 17:36:36 +02:00
|
|
|
};
|
|
|
|
|
|
2022-11-03 01:41:53 +02:00
|
|
|
device->workarounds.doom64_images = NULL;
|
|
|
|
|
|
2021-01-21 02:18:32 -06:00
|
|
|
device->rt_uuid_addr = anv_address_add(device->workaround_address, 8);
|
|
|
|
|
memcpy(device->rt_uuid_addr.bo->map + device->rt_uuid_addr.offset,
|
|
|
|
|
physical_device->rt_uuid,
|
|
|
|
|
sizeof(physical_device->rt_uuid));
|
|
|
|
|
|
2020-03-05 01:15:57 +02:00
|
|
|
device->debug_frame_desc =
|
|
|
|
|
intel_debug_get_identifier_block(device->workaround_bo->map,
|
|
|
|
|
device->workaround_bo->size,
|
2021-04-05 11:13:16 -07:00
|
|
|
INTEL_DEBUG_BLOCK_TYPE_FRAME);
|
2019-12-25 23:26:48 +02:00
|
|
|
|
2021-06-08 16:24:54 +03:00
|
|
|
if (device->vk.enabled_extensions.KHR_ray_query) {
|
|
|
|
|
uint32_t ray_queries_size =
|
2022-12-02 00:44:57 +05:30
|
|
|
align(brw_rt_ray_queries_hw_stacks_size(device->info), 4096);
|
2021-06-08 16:24:54 +03:00
|
|
|
|
|
|
|
|
result = anv_device_alloc_bo(device, "ray queries",
|
|
|
|
|
ray_queries_size,
|
2022-08-02 16:17:31 +03:00
|
|
|
0,
|
2021-06-08 16:24:54 +03:00
|
|
|
0 /* explicit_address */,
|
|
|
|
|
&device->ray_query_bo);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_workaround_bo;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-28 17:28:09 -05:00
|
|
|
result = anv_device_init_trivial_batch(device);
|
|
|
|
|
if (result != VK_SUCCESS)
|
2021-06-08 16:24:54 +03:00
|
|
|
goto fail_ray_query_bo;
|
2018-05-30 20:16:30 -07:00
|
|
|
|
2022-11-19 03:35:27 +02:00
|
|
|
/* Emit the CPS states before running the initialization batch as those
|
|
|
|
|
* structures are referenced.
|
|
|
|
|
*/
|
|
|
|
|
if (device->info->ver >= 12) {
|
2021-02-05 21:16:38 +02:00
|
|
|
uint32_t n_cps_states = 3 * 3; /* All combinaisons of X by Y CP sizes (1, 2, 4) */
|
|
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->info->has_coarse_pixel_primitive_and_cb)
|
2021-02-05 21:16:38 +02:00
|
|
|
n_cps_states *= 5 * 5; /* 5 combiners by 2 operators */
|
|
|
|
|
|
|
|
|
|
n_cps_states += 1; /* Disable CPS */
|
|
|
|
|
|
|
|
|
|
/* Each of the combinaison must be replicated on all viewports */
|
|
|
|
|
n_cps_states *= MAX_VIEWPORTS;
|
|
|
|
|
|
|
|
|
|
device->cps_states =
|
|
|
|
|
anv_state_pool_alloc(&device->dynamic_state_pool,
|
2022-08-04 12:56:17 -07:00
|
|
|
n_cps_states * CPS_STATE_length(device->info) * 4,
|
2021-02-05 21:16:38 +02:00
|
|
|
32);
|
|
|
|
|
if (device->cps_states.map == NULL)
|
|
|
|
|
goto fail_trivial_batch;
|
|
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
anv_genX(device->info, init_cps_device_state)(device);
|
2021-02-05 21:16:38 +02:00
|
|
|
}
|
|
|
|
|
|
2020-02-06 21:18:59 -06:00
|
|
|
/* Allocate a null surface state at surface state offset 0. This makes
|
|
|
|
|
* NULL descriptor handling trivial because we can just memset structures
|
|
|
|
|
* to zero and they have a valid descriptor.
|
|
|
|
|
*/
|
|
|
|
|
device->null_surface_state =
|
2023-01-27 11:21:54 +02:00
|
|
|
anv_state_pool_alloc(&device->bindless_surface_state_pool,
|
2020-02-06 21:18:59 -06:00
|
|
|
device->isl_dev.ss.size,
|
|
|
|
|
device->isl_dev.ss.align);
|
|
|
|
|
isl_null_fill_state(&device->isl_dev, device->null_surface_state.map,
|
2021-06-07 05:26:05 +10:00
|
|
|
.size = isl_extent3d(1, 1, 1) /* This shouldn't matter */);
|
2020-02-06 21:18:59 -06:00
|
|
|
assert(device->null_surface_state.offset == 0);
|
|
|
|
|
|
2016-06-16 15:26:54 -07:00
|
|
|
anv_scratch_pool_init(device, &device->scratch_pool);
|
2015-06-19 15:41:30 -07:00
|
|
|
|
2020-08-06 22:53:06 -05:00
|
|
|
/* TODO(RT): Do we want some sort of data structure for this? */
|
|
|
|
|
memset(device->rt_scratch_bos, 0, sizeof(device->rt_scratch_bos));
|
|
|
|
|
|
2020-05-13 15:45:06 -05:00
|
|
|
if (ANV_SUPPORT_RT && device->info->has_ray_tracing) {
|
2020-11-09 15:33:17 -06:00
|
|
|
/* The docs say to always allocate 128KB per DSS */
|
|
|
|
|
const uint32_t btd_fifo_bo_size =
|
|
|
|
|
128 * 1024 * intel_device_info_dual_subslice_id_bound(device->info);
|
|
|
|
|
result = anv_device_alloc_bo(device,
|
|
|
|
|
"rt-btd-fifo",
|
|
|
|
|
btd_fifo_bo_size,
|
|
|
|
|
0 /* alloc_flags */,
|
|
|
|
|
0 /* explicit_address */,
|
|
|
|
|
&device->btd_fifo_bo);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_trivial_batch_bo_and_scratch_pool;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
result = anv_genX(device->info, init_device_state)(device);
|
2016-02-05 16:11:12 -08:00
|
|
|
if (result != VK_SUCCESS)
|
2020-11-09 15:33:17 -06:00
|
|
|
goto fail_btd_fifo_bo;
|
2016-02-05 16:11:12 -08:00
|
|
|
|
2023-05-04 12:48:08 +02:00
|
|
|
struct vk_pipeline_cache_create_info pcc_info = {
|
|
|
|
|
.internal = true,
|
|
|
|
|
};
|
2021-10-04 13:38:19 -05:00
|
|
|
device->default_pipeline_cache =
|
|
|
|
|
vk_pipeline_cache_create(&device->vk, &pcc_info, NULL);
|
|
|
|
|
if (!device->default_pipeline_cache) {
|
|
|
|
|
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2020-11-09 15:33:17 -06:00
|
|
|
goto fail_btd_fifo_bo;
|
2021-10-04 13:38:19 -05:00
|
|
|
}
|
2018-06-29 17:29:35 -07:00
|
|
|
|
2022-05-27 11:27:55 +03:00
|
|
|
/* Internal shaders need their own pipeline cache because, unlike the rest
|
|
|
|
|
* of ANV, it won't work at all without the cache. It depends on it for
|
|
|
|
|
* shaders to remain resident while it runs. Therefore, we need a special
|
|
|
|
|
* cache just for BLORP/RT that's forced to always be enabled.
|
|
|
|
|
*/
|
|
|
|
|
pcc_info.force_enable = true;
|
|
|
|
|
device->internal_cache =
|
|
|
|
|
vk_pipeline_cache_create(&device->vk, &pcc_info, NULL);
|
|
|
|
|
if (device->internal_cache == NULL) {
|
|
|
|
|
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2021-10-04 14:13:33 -05:00
|
|
|
goto fail_default_pipeline_cache;
|
2022-05-27 11:27:55 +03:00
|
|
|
}
|
2021-04-02 17:03:13 +03:00
|
|
|
|
2022-09-28 05:12:19 +03:00
|
|
|
/* The device (currently is ICL/TGL) does not have float64 support. */
|
|
|
|
|
if (!device->info->has_64bit_float &&
|
|
|
|
|
device->physical->instance->fp64_workaround_enabled)
|
|
|
|
|
anv_load_fp64_shader(device);
|
|
|
|
|
|
2022-05-27 11:27:55 +03:00
|
|
|
result = anv_device_init_rt_shaders(device);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2021-10-04 13:38:19 -05:00
|
|
|
result = vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2022-05-27 11:27:55 +03:00
|
|
|
goto fail_internal_cache;
|
2021-10-04 13:38:19 -05:00
|
|
|
}
|
2016-08-22 21:37:28 -07:00
|
|
|
|
2022-05-27 11:27:55 +03:00
|
|
|
anv_device_init_blorp(device);
|
|
|
|
|
|
2015-05-29 16:06:06 -07:00
|
|
|
anv_device_init_border_colors(device);
|
|
|
|
|
|
2022-02-25 16:56:04 +02:00
|
|
|
anv_device_init_generated_indirect_draws(device);
|
|
|
|
|
|
2018-06-07 18:02:03 +01:00
|
|
|
anv_device_perf_init(device);
|
|
|
|
|
|
2021-11-18 17:45:57 +02:00
|
|
|
anv_device_utrace_init(device);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pDevice = anv_device_to_handle(device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
2022-05-27 11:27:55 +03:00
|
|
|
fail_internal_cache:
|
|
|
|
|
vk_pipeline_cache_destroy(device->internal_cache, NULL);
|
2021-10-04 14:13:33 -05:00
|
|
|
fail_default_pipeline_cache:
|
2021-10-04 13:38:19 -05:00
|
|
|
vk_pipeline_cache_destroy(device->default_pipeline_cache, NULL);
|
2020-11-09 15:33:17 -06:00
|
|
|
fail_btd_fifo_bo:
|
2020-05-13 15:45:06 -05:00
|
|
|
if (ANV_SUPPORT_RT && device->info->has_ray_tracing)
|
2020-11-09 15:33:17 -06:00
|
|
|
anv_device_release_bo(device, device->btd_fifo_bo);
|
2021-04-07 14:05:21 -07:00
|
|
|
fail_trivial_batch_bo_and_scratch_pool:
|
2019-12-25 22:08:51 +02:00
|
|
|
anv_scratch_pool_finish(device, &device->scratch_pool);
|
2021-02-05 21:16:38 +02:00
|
|
|
fail_trivial_batch:
|
2019-10-28 17:28:09 -05:00
|
|
|
anv_device_release_bo(device, device->trivial_batch_bo);
|
2021-06-08 16:24:54 +03:00
|
|
|
fail_ray_query_bo:
|
|
|
|
|
if (device->ray_query_bo)
|
|
|
|
|
anv_device_release_bo(device, device->ray_query_bo);
|
2019-12-25 22:08:51 +02:00
|
|
|
fail_workaround_bo:
|
|
|
|
|
anv_device_release_bo(device, device->workaround_bo);
|
2018-03-28 01:42:50 -07:00
|
|
|
fail_surface_aux_map_pool:
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->info->has_aux_map) {
|
2021-03-03 13:49:18 -08:00
|
|
|
intel_aux_map_finish(device->aux_map_ctx);
|
2018-03-28 01:42:50 -07:00
|
|
|
device->aux_map_ctx = NULL;
|
|
|
|
|
}
|
2018-03-14 10:31:16 -07:00
|
|
|
fail_binding_table_pool:
|
2022-08-30 15:12:27 -07:00
|
|
|
anv_state_pool_finish(&device->binding_table_pool);
|
2022-10-24 14:12:28 +03:00
|
|
|
fail_bindless_surface_state_pool:
|
|
|
|
|
anv_state_pool_finish(&device->bindless_surface_state_pool);
|
|
|
|
|
fail_internal_surface_state_pool:
|
|
|
|
|
anv_state_pool_finish(&device->internal_surface_state_pool);
|
2022-11-14 15:54:01 +02:00
|
|
|
fail_scratch_surface_state_pool:
|
|
|
|
|
if (device->info->verx10 >= 125)
|
|
|
|
|
anv_state_pool_finish(&device->scratch_surface_state_pool);
|
2016-11-30 06:59:15 +09:00
|
|
|
fail_instruction_state_pool:
|
|
|
|
|
anv_state_pool_finish(&device->instruction_state_pool);
|
|
|
|
|
fail_dynamic_state_pool:
|
2022-08-30 14:50:51 -07:00
|
|
|
anv_state_reserved_pool_finish(&device->custom_border_colors);
|
2016-11-30 06:59:15 +09:00
|
|
|
anv_state_pool_finish(&device->dynamic_state_pool);
|
2020-05-04 17:08:00 -05:00
|
|
|
fail_general_state_pool:
|
|
|
|
|
anv_state_pool_finish(&device->general_state_pool);
|
2016-11-30 06:59:15 +09:00
|
|
|
fail_batch_bo_pool:
|
|
|
|
|
anv_bo_pool_finish(&device->batch_bo_pool);
|
2019-10-28 15:42:20 -05:00
|
|
|
anv_bo_cache_finish(&device->bo_cache);
|
|
|
|
|
fail_queue_cond:
|
2016-11-30 06:59:15 +09:00
|
|
|
pthread_cond_destroy(&device->queue_submit);
|
|
|
|
|
fail_mutex:
|
|
|
|
|
pthread_mutex_destroy(&device->mutex);
|
2019-10-18 15:28:30 +03:00
|
|
|
fail_vmas:
|
2022-08-30 15:12:27 -07:00
|
|
|
util_vma_heap_finish(&device->vma_hi);
|
|
|
|
|
util_vma_heap_finish(&device->vma_cva);
|
|
|
|
|
util_vma_heap_finish(&device->vma_lo);
|
2018-08-14 02:34:16 -07:00
|
|
|
fail_queues:
|
|
|
|
|
for (uint32_t i = 0; i < device->queue_count; i++)
|
|
|
|
|
anv_queue_finish(&device->queues[i]);
|
|
|
|
|
vk_free(&device->vk.alloc, device->queues);
|
2019-10-22 15:34:12 +03:00
|
|
|
fail_context_id:
|
2023-02-09 08:44:04 -08:00
|
|
|
anv_device_destroy_context_or_vm(device);
|
2015-05-08 22:32:37 -07:00
|
|
|
fail_fd:
|
|
|
|
|
close(device->fd);
|
|
|
|
|
fail_device:
|
2021-01-23 04:33:02 -06:00
|
|
|
vk_device_finish(&device->vk);
|
2021-01-24 09:26:24 -06:00
|
|
|
fail_alloc:
|
2020-04-21 12:42:59 -05:00
|
|
|
vk_free(&device->vk.alloc, device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2016-01-03 22:43:47 -08:00
|
|
|
return result;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-05 20:50:51 -07:00
|
|
|
void anv_DestroyDevice(
|
2015-12-02 03:28:27 -08:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2017-03-01 08:39:49 -08:00
|
|
|
if (!device)
|
|
|
|
|
return;
|
|
|
|
|
|
2023-01-30 14:46:26 -08:00
|
|
|
struct anv_physical_device *pdevice = device->physical;
|
|
|
|
|
|
2021-11-18 17:45:57 +02:00
|
|
|
anv_device_utrace_finish(device);
|
|
|
|
|
|
2016-08-22 21:37:28 -07:00
|
|
|
anv_device_finish_blorp(device);
|
|
|
|
|
|
2021-04-02 17:03:13 +03:00
|
|
|
anv_device_finish_rt_shaders(device);
|
|
|
|
|
|
2022-02-25 16:56:04 +02:00
|
|
|
anv_device_finish_generated_indirect_draws(device);
|
|
|
|
|
|
2022-05-27 11:27:55 +03:00
|
|
|
vk_pipeline_cache_destroy(device->internal_cache, NULL);
|
2021-10-04 13:38:19 -05:00
|
|
|
vk_pipeline_cache_destroy(device->default_pipeline_cache, NULL);
|
2018-06-29 17:29:35 -07:00
|
|
|
|
2020-05-13 15:45:06 -05:00
|
|
|
if (ANV_SUPPORT_RT && device->info->has_ray_tracing)
|
2020-11-09 15:33:17 -06:00
|
|
|
anv_device_release_bo(device, device->btd_fifo_bo);
|
|
|
|
|
|
2015-06-09 11:41:31 -07:00
|
|
|
#ifdef HAVE_VALGRIND
|
|
|
|
|
/* We only need to free these to prevent valgrind errors. The backing
|
|
|
|
|
* BO will go away in a couple of lines so we don't actually leak.
|
|
|
|
|
*/
|
2022-08-30 14:50:51 -07:00
|
|
|
anv_state_reserved_pool_finish(&device->custom_border_colors);
|
2015-07-08 11:44:52 -07:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
|
2019-07-22 10:56:53 -07:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, device->slice_hash);
|
2021-02-05 21:16:38 +02:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, device->cps_states);
|
2015-06-09 11:41:31 -07:00
|
|
|
#endif
|
|
|
|
|
|
2020-08-06 22:53:06 -05:00
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(device->rt_scratch_bos); i++) {
|
|
|
|
|
if (device->rt_scratch_bos[i] != NULL)
|
|
|
|
|
anv_device_release_bo(device, device->rt_scratch_bos[i]);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-25 23:34:46 +09:00
|
|
|
anv_scratch_pool_finish(device, &device->scratch_pool);
|
|
|
|
|
|
2021-06-08 16:24:54 +03:00
|
|
|
if (device->vk.enabled_extensions.KHR_ray_query) {
|
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(device->ray_query_shadow_bos); i++) {
|
|
|
|
|
if (device->ray_query_shadow_bos[i] != NULL)
|
|
|
|
|
anv_device_release_bo(device, device->ray_query_shadow_bos[i]);
|
|
|
|
|
}
|
|
|
|
|
anv_device_release_bo(device, device->ray_query_bo);
|
|
|
|
|
}
|
2019-10-28 17:28:09 -05:00
|
|
|
anv_device_release_bo(device, device->workaround_bo);
|
|
|
|
|
anv_device_release_bo(device, device->trivial_batch_bo);
|
2017-02-27 16:34:13 -08:00
|
|
|
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->info->has_aux_map) {
|
2021-03-03 13:49:18 -08:00
|
|
|
intel_aux_map_finish(device->aux_map_ctx);
|
2018-03-28 01:42:50 -07:00
|
|
|
device->aux_map_ctx = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-30 15:12:27 -07:00
|
|
|
anv_state_pool_finish(&device->binding_table_pool);
|
2022-11-14 15:54:01 +02:00
|
|
|
if (device->info->verx10 >= 125)
|
|
|
|
|
anv_state_pool_finish(&device->scratch_surface_state_pool);
|
2022-10-24 14:12:28 +03:00
|
|
|
anv_state_pool_finish(&device->internal_surface_state_pool);
|
|
|
|
|
anv_state_pool_finish(&device->bindless_surface_state_pool);
|
2016-11-25 23:34:46 +09:00
|
|
|
anv_state_pool_finish(&device->instruction_state_pool);
|
|
|
|
|
anv_state_pool_finish(&device->dynamic_state_pool);
|
2020-05-04 17:08:00 -05:00
|
|
|
anv_state_pool_finish(&device->general_state_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2016-11-25 23:34:46 +09:00
|
|
|
anv_bo_pool_finish(&device->batch_bo_pool);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2019-10-28 15:42:20 -05:00
|
|
|
anv_bo_cache_finish(&device->bo_cache);
|
|
|
|
|
|
2022-08-30 15:12:27 -07:00
|
|
|
util_vma_heap_finish(&device->vma_hi);
|
|
|
|
|
util_vma_heap_finish(&device->vma_cva);
|
|
|
|
|
util_vma_heap_finish(&device->vma_lo);
|
2019-10-18 15:28:30 +03:00
|
|
|
|
2016-11-25 23:34:46 +09:00
|
|
|
pthread_cond_destroy(&device->queue_submit);
|
2016-01-05 11:43:25 -08:00
|
|
|
pthread_mutex_destroy(&device->mutex);
|
|
|
|
|
|
2018-08-14 02:34:16 -07:00
|
|
|
for (uint32_t i = 0; i < device->queue_count; i++)
|
|
|
|
|
anv_queue_finish(&device->queues[i]);
|
|
|
|
|
vk_free(&device->vk.alloc, device->queues);
|
|
|
|
|
|
2023-02-09 08:44:04 -08:00
|
|
|
anv_device_destroy_context_or_vm(device);
|
2016-11-25 23:34:46 +09:00
|
|
|
|
2023-01-30 14:46:26 -08:00
|
|
|
if (INTEL_DEBUG(DEBUG_BATCH)) {
|
|
|
|
|
for (unsigned i = 0; i < pdevice->queue.family_count; i++)
|
|
|
|
|
intel_batch_decode_ctx_finish(&device->decoder[i]);
|
|
|
|
|
}
|
2019-02-23 23:27:17 +00:00
|
|
|
|
2016-11-25 23:34:46 +09:00
|
|
|
close(device->fd);
|
|
|
|
|
|
2020-04-21 12:42:59 -05:00
|
|
|
vk_device_finish(&device->vk);
|
|
|
|
|
vk_free(&device->vk.alloc, device);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-06 09:25:03 -07:00
|
|
|
VkResult anv_EnumerateInstanceLayerProperties(
|
2015-11-30 16:28:36 -08:00
|
|
|
uint32_t* pPropertyCount,
|
2015-07-14 16:11:21 -07:00
|
|
|
VkLayerProperties* pProperties)
|
|
|
|
|
{
|
|
|
|
|
if (pProperties == NULL) {
|
2015-11-30 16:28:36 -08:00
|
|
|
*pPropertyCount = 0;
|
2015-07-14 16:11:21 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* None supported at this time */
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
|
2015-07-14 16:11:21 -07:00
|
|
|
}
|
|
|
|
|
|
2017-03-27 16:03:57 -07:00
|
|
|
VkResult
|
|
|
|
|
anv_device_wait(struct anv_device *device, struct anv_bo *bo,
|
|
|
|
|
int64_t timeout)
|
|
|
|
|
{
|
|
|
|
|
int ret = anv_gem_wait(device, bo->gem_handle, &timeout);
|
|
|
|
|
if (ret == -1 && errno == ETIME) {
|
|
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
} else if (ret == -1) {
|
|
|
|
|
/* We don't know the real error. */
|
2021-10-19 18:44:01 -05:00
|
|
|
return vk_device_set_lost(&device->vk, "gem wait failed: %m");
|
2021-11-08 12:53:10 -06:00
|
|
|
} else {
|
|
|
|
|
return VK_SUCCESS;
|
2017-03-27 16:03:57 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-12-06 16:32:49 +02:00
|
|
|
static struct util_vma_heap *
|
|
|
|
|
anv_vma_heap_for_flags(struct anv_device *device,
|
|
|
|
|
enum anv_bo_alloc_flags alloc_flags)
|
|
|
|
|
{
|
|
|
|
|
if (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS)
|
|
|
|
|
return &device->vma_cva;
|
|
|
|
|
|
|
|
|
|
if (alloc_flags & ANV_BO_ALLOC_32BIT_ADDRESS)
|
|
|
|
|
return &device->vma_lo;
|
|
|
|
|
|
|
|
|
|
return &device->vma_hi;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-22 16:40:13 -06:00
|
|
|
uint64_t
|
|
|
|
|
anv_vma_alloc(struct anv_device *device,
|
|
|
|
|
uint64_t size, uint64_t align,
|
|
|
|
|
enum anv_bo_alloc_flags alloc_flags,
|
2022-12-06 16:32:49 +02:00
|
|
|
uint64_t client_address,
|
|
|
|
|
struct util_vma_heap **out_vma_heap)
|
2018-03-07 09:18:37 -08:00
|
|
|
{
|
|
|
|
|
pthread_mutex_lock(&device->vma_mutex);
|
|
|
|
|
|
2020-01-22 16:40:13 -06:00
|
|
|
uint64_t addr = 0;
|
2022-12-06 16:32:49 +02:00
|
|
|
*out_vma_heap = anv_vma_heap_for_flags(device, alloc_flags);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
2020-01-22 16:40:13 -06:00
|
|
|
if (alloc_flags & ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS) {
|
2019-12-02 16:03:56 -06:00
|
|
|
if (client_address) {
|
2022-12-06 16:32:49 +02:00
|
|
|
if (util_vma_heap_alloc_addr(*out_vma_heap,
|
2020-01-22 16:40:13 -06:00
|
|
|
client_address, size)) {
|
|
|
|
|
addr = client_address;
|
2019-12-02 16:03:56 -06:00
|
|
|
}
|
|
|
|
|
} else {
|
2022-12-06 16:32:49 +02:00
|
|
|
addr = util_vma_heap_alloc(*out_vma_heap, size, align);
|
2019-12-02 16:03:56 -06:00
|
|
|
}
|
|
|
|
|
/* We don't want to fall back to other heaps */
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(client_address == 0);
|
|
|
|
|
|
2022-12-06 16:32:49 +02:00
|
|
|
addr = util_vma_heap_alloc(*out_vma_heap, size, align);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
2019-12-02 16:03:56 -06:00
|
|
|
done:
|
2018-03-07 09:18:37 -08:00
|
|
|
pthread_mutex_unlock(&device->vma_mutex);
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
assert(addr == intel_48b_address(addr));
|
|
|
|
|
return intel_canonical_address(addr);
|
2018-03-07 09:18:37 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2020-01-22 16:40:13 -06:00
|
|
|
anv_vma_free(struct anv_device *device,
|
2022-12-06 16:32:49 +02:00
|
|
|
struct util_vma_heap *vma_heap,
|
2020-01-22 16:40:13 -06:00
|
|
|
uint64_t address, uint64_t size)
|
2018-03-07 09:18:37 -08:00
|
|
|
{
|
2022-12-06 16:32:49 +02:00
|
|
|
assert(vma_heap == &device->vma_lo ||
|
|
|
|
|
vma_heap == &device->vma_cva ||
|
|
|
|
|
vma_heap == &device->vma_hi);
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
const uint64_t addr_48b = intel_48b_address(address);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
|
|
|
|
pthread_mutex_lock(&device->vma_mutex);
|
|
|
|
|
|
2022-12-06 16:32:49 +02:00
|
|
|
util_vma_heap_free(vma_heap, addr_48b, size);
|
2018-03-07 09:18:37 -08:00
|
|
|
|
|
|
|
|
pthread_mutex_unlock(&device->vma_mutex);
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-02 03:28:27 -08:00
|
|
|
VkResult anv_AllocateMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2015-12-02 03:28:27 -08:00
|
|
|
const VkMemoryAllocateInfo* pAllocateInfo,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDeviceMemory* pMem)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2020-01-17 22:23:30 -06:00
|
|
|
struct anv_physical_device *pdevice = device->physical;
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_device_memory *mem;
|
2017-02-28 10:58:40 -08:00
|
|
|
VkResult result = VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-12-02 03:28:27 -08:00
|
|
|
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2016-11-17 12:45:26 -08:00
|
|
|
/* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */
|
|
|
|
|
assert(pAllocateInfo->allocationSize > 0);
|
2015-12-17 11:00:38 -08:00
|
|
|
|
2019-12-02 14:37:56 -06:00
|
|
|
VkDeviceSize aligned_alloc_size =
|
2022-12-02 14:37:31 +05:30
|
|
|
align64(pAllocateInfo->allocationSize, 4096);
|
2017-04-11 08:33:19 -07:00
|
|
|
|
2019-12-02 14:37:56 -06:00
|
|
|
assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.type_count);
|
2023-01-18 09:01:15 -07:00
|
|
|
const struct anv_memory_type *mem_type =
|
2019-12-02 14:37:56 -06:00
|
|
|
&pdevice->memory.types[pAllocateInfo->memoryTypeIndex];
|
|
|
|
|
assert(mem_type->heapIndex < pdevice->memory.heap_count);
|
|
|
|
|
struct anv_memory_heap *mem_heap =
|
|
|
|
|
&pdevice->memory.heaps[mem_type->heapIndex];
|
|
|
|
|
|
2023-03-14 16:39:34 -07:00
|
|
|
if (aligned_alloc_size > mem_heap->size)
|
|
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
|
|
|
|
|
2019-12-02 14:37:56 -06:00
|
|
|
uint64_t mem_heap_used = p_atomic_read(&mem_heap->used);
|
|
|
|
|
if (mem_heap_used + aligned_alloc_size > mem_heap->size)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2015-07-09 19:59:44 -07:00
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
mem = vk_device_memory_create(&device->vk, pAllocateInfo,
|
|
|
|
|
pAllocator, sizeof(*mem));
|
2015-05-08 22:32:37 -07:00
|
|
|
if (mem == NULL)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2019-12-02 14:37:56 -06:00
|
|
|
mem->type = mem_type;
|
2021-11-15 11:32:38 -06:00
|
|
|
mem->map = NULL;
|
|
|
|
|
mem->map_size = 0;
|
|
|
|
|
mem->map_delta = 0;
|
2016-11-07 17:25:07 -08:00
|
|
|
|
2019-10-25 17:45:28 -05:00
|
|
|
enum anv_bo_alloc_flags alloc_flags = 0;
|
2018-05-30 15:34:25 -07:00
|
|
|
|
2019-06-26 18:02:19 -05:00
|
|
|
const VkImportMemoryFdInfoKHR *fd_info = NULL;
|
|
|
|
|
const VkMemoryDedicatedAllocateInfo *dedicated_info = NULL;
|
2019-12-02 16:28:58 -06:00
|
|
|
uint64_t client_address = 0;
|
2018-05-30 15:34:25 -07:00
|
|
|
|
2019-06-26 18:02:19 -05:00
|
|
|
vk_foreach_struct_const(ext, pAllocateInfo->pNext) {
|
|
|
|
|
switch (ext->sType) {
|
2023-04-05 10:44:31 +02:00
|
|
|
case VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO:
|
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID:
|
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT:
|
|
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR:
|
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO:
|
|
|
|
|
/* handled by vk_device_memory_create */
|
|
|
|
|
break;
|
|
|
|
|
|
2019-06-26 18:02:19 -05:00
|
|
|
case VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR:
|
|
|
|
|
fd_info = (void *)ext;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO:
|
|
|
|
|
dedicated_info = (void *)ext;
|
|
|
|
|
break;
|
|
|
|
|
|
2022-07-01 13:03:31 +01:00
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_OPAQUE_CAPTURE_ADDRESS_ALLOCATE_INFO: {
|
|
|
|
|
const VkMemoryOpaqueCaptureAddressAllocateInfo *addr_info =
|
|
|
|
|
(const VkMemoryOpaqueCaptureAddressAllocateInfo *)ext;
|
2019-12-02 16:28:58 -06:00
|
|
|
client_address = addr_info->opaqueCaptureAddress;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-26 18:02:19 -05:00
|
|
|
default:
|
2023-03-03 11:03:18 -08:00
|
|
|
/* VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA isn't a real
|
|
|
|
|
* enum value, so use conditional to avoid compiler warn
|
|
|
|
|
*/
|
|
|
|
|
if (ext->sType == VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA) {
|
|
|
|
|
/* TODO: Android, ChromeOS and other applications may need another
|
|
|
|
|
* way to allocate buffers that can be scanout to display but it
|
|
|
|
|
* should pretty easy to catch those as Xe KMD driver will print
|
|
|
|
|
* warnings in dmesg when scanning buffers allocated without
|
|
|
|
|
* proper flag set.
|
2022-01-26 15:46:36 -05:00
|
|
|
*/
|
2023-03-03 11:03:18 -08:00
|
|
|
alloc_flags |= ANV_BO_ALLOC_SCANOUT;
|
|
|
|
|
} else {
|
2022-01-26 15:46:36 -05:00
|
|
|
anv_debug_ignored_stype(ext->sType);
|
2023-03-03 11:03:18 -08:00
|
|
|
}
|
2019-06-26 18:02:19 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-11-08 10:20:35 +02:00
|
|
|
|
2020-01-22 15:29:51 -06:00
|
|
|
/* By default, we want all VkDeviceMemory objects to support CCS */
|
2022-08-04 12:56:17 -07:00
|
|
|
if (device->physical->has_implicit_ccs && device->info->has_aux_map)
|
2020-01-22 15:29:51 -06:00
|
|
|
alloc_flags |= ANV_BO_ALLOC_IMPLICIT_CCS;
|
|
|
|
|
|
2022-05-02 12:38:16 +03:00
|
|
|
/* If i915 reported a mappable/non_mappable vram regions and the
|
|
|
|
|
* application want lmem mappable, then we need to use the
|
|
|
|
|
* I915_GEM_CREATE_EXT_FLAG_NEEDS_CPU_ACCESS flag to create our BO.
|
|
|
|
|
*/
|
|
|
|
|
if (pdevice->vram_mappable.size > 0 &&
|
|
|
|
|
pdevice->vram_non_mappable.size > 0 &&
|
|
|
|
|
(mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) &&
|
|
|
|
|
(mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
|
|
|
|
|
alloc_flags |= ANV_BO_ALLOC_LOCAL_MEM_CPU_VISIBLE;
|
|
|
|
|
|
2022-09-02 21:53:18 +03:00
|
|
|
if (!(mem_type->propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT))
|
|
|
|
|
alloc_flags |= ANV_BO_ALLOC_NO_LOCAL_MEM;
|
|
|
|
|
|
2022-09-23 22:21:10 +03:00
|
|
|
/* If the allocated buffer might end up in local memory and it's host
|
2023-01-18 09:01:15 -07:00
|
|
|
* visible and uncached, enable CPU write-combining. It should be faster.
|
2022-09-23 22:21:10 +03:00
|
|
|
*/
|
|
|
|
|
if (!(alloc_flags & ANV_BO_ALLOC_NO_LOCAL_MEM) &&
|
2023-01-18 09:01:15 -07:00
|
|
|
(mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT) == 0 &&
|
2022-09-23 22:21:10 +03:00
|
|
|
(mem_type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT))
|
|
|
|
|
alloc_flags |= ANV_BO_ALLOC_WRITE_COMBINE;
|
|
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem->vk.alloc_flags & VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT)
|
2019-12-02 16:28:58 -06:00
|
|
|
alloc_flags |= ANV_BO_ALLOC_CLIENT_VISIBLE_ADDRESS;
|
|
|
|
|
|
2023-05-10 05:38:58 +00:00
|
|
|
/* Anything imported or exported is EXTERNAL. Apply implicit sync to be
|
|
|
|
|
* compatible with clients relying on implicit fencing. This matches the
|
|
|
|
|
* behavior in iris i915_batch_submit. An example client is VA-API.
|
|
|
|
|
*/
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem->vk.export_handle_types || mem->vk.import_handle_type)
|
2023-05-10 05:38:58 +00:00
|
|
|
alloc_flags |= (ANV_BO_ALLOC_EXTERNAL | ANV_BO_ALLOC_IMPLICIT_SYNC);
|
2018-11-08 10:20:35 +02:00
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem->vk.ahardware_buffer) {
|
|
|
|
|
result = anv_import_ahw_memory(_device, mem);
|
2018-11-08 10:20:35 +02:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-13 12:18:15 -07:00
|
|
|
/* The Vulkan spec permits handleType to be 0, in which case the struct is
|
|
|
|
|
* ignored.
|
|
|
|
|
*/
|
|
|
|
|
if (fd_info && fd_info->handleType) {
|
2017-11-27 18:33:44 -08:00
|
|
|
/* At the moment, we support only the below handle types. */
|
2017-07-13 12:18:15 -07:00
|
|
|
assert(fd_info->handleType ==
|
2017-09-20 13:16:26 -07:00
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2017-11-27 18:33:44 -08:00
|
|
|
fd_info->handleType ==
|
|
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
2017-07-13 12:18:15 -07:00
|
|
|
|
2019-10-25 17:45:28 -05:00
|
|
|
result = anv_device_import_bo(device, fd_info->fd, alloc_flags,
|
2019-12-02 16:28:58 -06:00
|
|
|
client_address, &mem->bo);
|
2017-07-13 12:18:15 -07:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
2017-09-11 16:41:21 -07:00
|
|
|
|
anv: Move size check from anv_bo_cache_import() to caller (v2)
This change prepares for VK_ANDROID_native_buffer. When the user imports
a gralloc hande into a VkImage using VK_ANDROID_native_buffer, the user
provides no size. The driver must infer the size from the internals of
the gralloc buffer.
The patch is essentially a refactor patch, but it does change behavior
in some edge cases, described below. In what follows, the "nominal size"
of the bo refers to anv_bo::size, which may not match the bo's "actual
size" according to the kernel.
Post-patch, the nominal size of the bo returned from
anv_bo_cache_import() is always the size of imported dma-buf according
to lseek(). Pre-patch, the bo's nominal size was difficult to predict.
If the imported dma-buf's gem handle was not resident in the cache, then
the bo's nominal size was align(VkMemoryAllocateInfo::allocationSize,
4096). If it *was* resident, then the bo's nominal size was whatever
the cache returned. As a consequence, the first cache insert decided the
bo's nominal size, which could be significantly smaller compared to the
dma-buf's actual size, as the nominal size was determined by
VkMemoryAllocationInfo::allocationSize and not lseek().
I believe this patch cleans up that messy behavior. For an imported or
exported VkDeviceMemory, anv_bo::size should now be the true size of the
bo, if I correctly understand the problem (which I possibly don't).
v2:
- Preserve behavior of aligning size to 4096 before checking. [for
jekstrand]
- Check size with < instead of <=, to match behavior of commit c0a4f56
"anv: bo_cache: allow importing a BO larger than needed". [for
chadv]
2017-09-12 14:05:08 -07:00
|
|
|
/* For security purposes, we reject importing the bo if it's smaller
|
|
|
|
|
* than the requested allocation size. This prevents a malicious client
|
|
|
|
|
* from passing a buffer to a trusted client, lying about the size, and
|
|
|
|
|
* telling the trusted client to try and texture from an image that goes
|
|
|
|
|
* out-of-bounds. This sort of thing could lead to GPU hangs or worse
|
|
|
|
|
* in the trusted client. The trusted client can protect itself against
|
|
|
|
|
* this sort of attack but only if it can trust the buffer size.
|
|
|
|
|
*/
|
|
|
|
|
if (mem->bo->size < aligned_alloc_size) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_errorf(device, VK_ERROR_INVALID_EXTERNAL_HANDLE,
|
anv: Move size check from anv_bo_cache_import() to caller (v2)
This change prepares for VK_ANDROID_native_buffer. When the user imports
a gralloc hande into a VkImage using VK_ANDROID_native_buffer, the user
provides no size. The driver must infer the size from the internals of
the gralloc buffer.
The patch is essentially a refactor patch, but it does change behavior
in some edge cases, described below. In what follows, the "nominal size"
of the bo refers to anv_bo::size, which may not match the bo's "actual
size" according to the kernel.
Post-patch, the nominal size of the bo returned from
anv_bo_cache_import() is always the size of imported dma-buf according
to lseek(). Pre-patch, the bo's nominal size was difficult to predict.
If the imported dma-buf's gem handle was not resident in the cache, then
the bo's nominal size was align(VkMemoryAllocateInfo::allocationSize,
4096). If it *was* resident, then the bo's nominal size was whatever
the cache returned. As a consequence, the first cache insert decided the
bo's nominal size, which could be significantly smaller compared to the
dma-buf's actual size, as the nominal size was determined by
VkMemoryAllocationInfo::allocationSize and not lseek().
I believe this patch cleans up that messy behavior. For an imported or
exported VkDeviceMemory, anv_bo::size should now be the true size of the
bo, if I correctly understand the problem (which I possibly don't).
v2:
- Preserve behavior of aligning size to 4096 before checking. [for
jekstrand]
- Check size with < instead of <=, to match behavior of commit c0a4f56
"anv: bo_cache: allow importing a BO larger than needed". [for
chadv]
2017-09-12 14:05:08 -07:00
|
|
|
"aligned allocationSize too large for "
|
2019-01-08 18:04:54 +00:00
|
|
|
"VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: "
|
anv: Move size check from anv_bo_cache_import() to caller (v2)
This change prepares for VK_ANDROID_native_buffer. When the user imports
a gralloc hande into a VkImage using VK_ANDROID_native_buffer, the user
provides no size. The driver must infer the size from the internals of
the gralloc buffer.
The patch is essentially a refactor patch, but it does change behavior
in some edge cases, described below. In what follows, the "nominal size"
of the bo refers to anv_bo::size, which may not match the bo's "actual
size" according to the kernel.
Post-patch, the nominal size of the bo returned from
anv_bo_cache_import() is always the size of imported dma-buf according
to lseek(). Pre-patch, the bo's nominal size was difficult to predict.
If the imported dma-buf's gem handle was not resident in the cache, then
the bo's nominal size was align(VkMemoryAllocateInfo::allocationSize,
4096). If it *was* resident, then the bo's nominal size was whatever
the cache returned. As a consequence, the first cache insert decided the
bo's nominal size, which could be significantly smaller compared to the
dma-buf's actual size, as the nominal size was determined by
VkMemoryAllocationInfo::allocationSize and not lseek().
I believe this patch cleans up that messy behavior. For an imported or
exported VkDeviceMemory, anv_bo::size should now be the true size of the
bo, if I correctly understand the problem (which I possibly don't).
v2:
- Preserve behavior of aligning size to 4096 before checking. [for
jekstrand]
- Check size with < instead of <=, to match behavior of commit c0a4f56
"anv: bo_cache: allow importing a BO larger than needed". [for
chadv]
2017-09-12 14:05:08 -07:00
|
|
|
"%"PRIu64"B > %"PRIu64"B",
|
|
|
|
|
aligned_alloc_size, mem->bo->size);
|
2019-10-25 17:45:28 -05:00
|
|
|
anv_device_release_bo(device, mem->bo);
|
anv: Move size check from anv_bo_cache_import() to caller (v2)
This change prepares for VK_ANDROID_native_buffer. When the user imports
a gralloc hande into a VkImage using VK_ANDROID_native_buffer, the user
provides no size. The driver must infer the size from the internals of
the gralloc buffer.
The patch is essentially a refactor patch, but it does change behavior
in some edge cases, described below. In what follows, the "nominal size"
of the bo refers to anv_bo::size, which may not match the bo's "actual
size" according to the kernel.
Post-patch, the nominal size of the bo returned from
anv_bo_cache_import() is always the size of imported dma-buf according
to lseek(). Pre-patch, the bo's nominal size was difficult to predict.
If the imported dma-buf's gem handle was not resident in the cache, then
the bo's nominal size was align(VkMemoryAllocateInfo::allocationSize,
4096). If it *was* resident, then the bo's nominal size was whatever
the cache returned. As a consequence, the first cache insert decided the
bo's nominal size, which could be significantly smaller compared to the
dma-buf's actual size, as the nominal size was determined by
VkMemoryAllocationInfo::allocationSize and not lseek().
I believe this patch cleans up that messy behavior. For an imported or
exported VkDeviceMemory, anv_bo::size should now be the true size of the
bo, if I correctly understand the problem (which I possibly don't).
v2:
- Preserve behavior of aligning size to 4096 before checking. [for
jekstrand]
- Check size with < instead of <=, to match behavior of commit c0a4f56
"anv: bo_cache: allow importing a BO larger than needed". [for
chadv]
2017-09-12 14:05:08 -07:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-11 16:41:21 -07:00
|
|
|
/* From the Vulkan spec:
|
|
|
|
|
*
|
|
|
|
|
* "Importing memory from a file descriptor transfers ownership of
|
|
|
|
|
* the file descriptor from the application to the Vulkan
|
|
|
|
|
* implementation. The application must not perform any operations on
|
|
|
|
|
* the file descriptor after a successful import."
|
|
|
|
|
*
|
|
|
|
|
* If the import fails, we leave the file descriptor open.
|
|
|
|
|
*/
|
|
|
|
|
close(fd_info->fd);
|
2018-10-09 09:53:55 +03:00
|
|
|
goto success;
|
|
|
|
|
}
|
2017-11-28 08:49:29 -08:00
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem->vk.host_ptr) {
|
|
|
|
|
if (mem->vk.import_handle_type ==
|
2019-03-01 13:15:31 -08:00
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT) {
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
2019-03-01 13:15:31 -08:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
assert(mem->vk.import_handle_type ==
|
2019-03-01 13:15:31 -08:00
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
|
|
|
|
|
|
2019-10-25 17:45:28 -05:00
|
|
|
result = anv_device_import_bo_from_host_ptr(device,
|
2023-03-20 18:00:38 -05:00
|
|
|
mem->vk.host_ptr,
|
|
|
|
|
mem->vk.size,
|
2019-10-25 17:45:28 -05:00
|
|
|
alloc_flags,
|
2019-12-02 16:28:58 -06:00
|
|
|
client_address,
|
2019-10-25 17:45:28 -05:00
|
|
|
&mem->bo);
|
2019-03-01 13:15:31 -08:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-09 09:53:55 +03:00
|
|
|
/* Regular allocate (not importing memory). */
|
2017-11-28 08:49:29 -08:00
|
|
|
|
2020-06-17 15:37:33 +03:00
|
|
|
result = anv_device_alloc_bo(device, "user", pAllocateInfo->allocationSize,
|
2019-12-02 16:28:58 -06:00
|
|
|
alloc_flags, client_address, &mem->bo);
|
2018-10-09 09:53:55 +03:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);
|
|
|
|
|
|
|
|
|
|
/* Some legacy (non-modifiers) consumers need the tiling to be set on
|
|
|
|
|
* the BO. In this case, we have a dedicated allocation.
|
|
|
|
|
*/
|
2021-07-22 16:24:59 -05:00
|
|
|
if (image->vk.wsi_legacy_scanout) {
|
2021-10-30 15:47:38 -05:00
|
|
|
const struct isl_surf *surf = &image->planes[0].primary_surface.isl;
|
|
|
|
|
result = anv_device_set_bo_tiling(device, mem->bo,
|
|
|
|
|
surf->row_pitch_B,
|
|
|
|
|
surf->tiling);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2019-10-25 17:45:28 -05:00
|
|
|
anv_device_release_bo(device, mem->bo);
|
2019-12-02 13:51:59 -06:00
|
|
|
goto fail;
|
2017-11-28 08:49:29 -08:00
|
|
|
}
|
|
|
|
|
}
|
2017-07-13 12:18:15 -07:00
|
|
|
}
|
2017-02-28 10:58:40 -08:00
|
|
|
|
2018-10-09 09:53:55 +03:00
|
|
|
success:
|
2019-12-02 14:37:56 -06:00
|
|
|
mem_heap_used = p_atomic_add_return(&mem_heap->used, mem->bo->size);
|
|
|
|
|
if (mem_heap_used > mem_heap->size) {
|
|
|
|
|
p_atomic_add(&mem_heap->used, -mem->bo->size);
|
|
|
|
|
anv_device_release_bo(device, mem->bo);
|
2021-09-24 12:06:32 -05:00
|
|
|
result = vk_errorf(device, VK_ERROR_OUT_OF_DEVICE_MEMORY,
|
2019-12-02 14:37:56 -06:00
|
|
|
"Out of heap memory");
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-26 18:05:34 -06:00
|
|
|
pthread_mutex_lock(&device->mutex);
|
|
|
|
|
list_addtail(&mem->link, &device->memory_objects);
|
|
|
|
|
pthread_mutex_unlock(&device->mutex);
|
|
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pMem = anv_device_memory_to_handle(mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 18:20:10 -07:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
fail:
|
2023-03-20 18:00:38 -05:00
|
|
|
vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-13 12:18:15 -07:00
|
|
|
VkResult anv_GetMemoryFdKHR(
|
|
|
|
|
VkDevice device_h,
|
|
|
|
|
const VkMemoryGetFdInfoKHR* pGetFdInfo,
|
|
|
|
|
int* pFd)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, dev, device_h);
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pGetFdInfo->memory);
|
|
|
|
|
|
|
|
|
|
assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
|
|
|
|
|
|
2017-09-20 13:16:26 -07:00
|
|
|
assert(pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2017-11-27 18:33:44 -08:00
|
|
|
pGetFdInfo->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
2017-07-13 12:18:15 -07:00
|
|
|
|
2019-10-25 17:45:28 -05:00
|
|
|
return anv_device_export_bo(dev, mem->bo, pFd);
|
2017-07-13 12:18:15 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetMemoryFdPropertiesKHR(
|
2017-11-27 18:33:44 -08:00
|
|
|
VkDevice _device,
|
2019-01-08 18:04:54 +00:00
|
|
|
VkExternalMemoryHandleTypeFlagBits handleType,
|
2017-07-13 12:18:15 -07:00
|
|
|
int fd,
|
|
|
|
|
VkMemoryFdPropertiesKHR* pMemoryFdProperties)
|
|
|
|
|
{
|
2017-11-27 18:33:44 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
switch (handleType) {
|
2017-12-05 21:19:51 +01:00
|
|
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
2017-11-27 18:33:44 -08:00
|
|
|
/* dma-buf can be imported as any memory type */
|
|
|
|
|
pMemoryFdProperties->memoryTypeBits =
|
2020-01-17 22:23:30 -06:00
|
|
|
(1 << device->physical->memory.type_count) - 1;
|
2017-11-27 18:33:44 -08:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
/* The valid usage section for this function says:
|
|
|
|
|
*
|
|
|
|
|
* "handleType must not be one of the handle types defined as
|
|
|
|
|
* opaque."
|
|
|
|
|
*
|
|
|
|
|
* So opaque handle types fall into the default "unsupported" case.
|
|
|
|
|
*/
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
2017-11-27 18:33:44 -08:00
|
|
|
}
|
2017-07-13 12:18:15 -07:00
|
|
|
}
|
|
|
|
|
|
2019-03-01 13:15:31 -08:00
|
|
|
VkResult anv_GetMemoryHostPointerPropertiesEXT(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkExternalMemoryHandleTypeFlagBits handleType,
|
|
|
|
|
const void* pHostPointer,
|
|
|
|
|
VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
assert(pMemoryHostPointerProperties->sType ==
|
|
|
|
|
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT);
|
|
|
|
|
|
|
|
|
|
switch (handleType) {
|
2020-01-17 22:23:30 -06:00
|
|
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
|
2019-03-01 13:15:31 -08:00
|
|
|
/* Host memory can be imported as any memory type. */
|
|
|
|
|
pMemoryHostPointerProperties->memoryTypeBits =
|
2020-01-17 22:23:30 -06:00
|
|
|
(1ull << device->physical->memory.type_count) - 1;
|
2019-03-01 13:15:31 -08:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2020-01-17 22:23:30 -06:00
|
|
|
|
2019-03-01 13:15:31 -08:00
|
|
|
default:
|
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 20:50:51 -07:00
|
|
|
void anv_FreeMemory(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2015-12-02 03:28:27 -08:00
|
|
|
VkDeviceMemory _mem,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-12-17 11:00:38 -08:00
|
|
|
if (mem == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-02-26 18:05:34 -06:00
|
|
|
pthread_mutex_lock(&device->mutex);
|
|
|
|
|
list_del(&mem->link);
|
|
|
|
|
pthread_mutex_unlock(&device->mutex);
|
|
|
|
|
|
2023-03-20 17:02:45 -05:00
|
|
|
if (mem->map) {
|
|
|
|
|
const VkMemoryUnmapInfoKHR unmap = {
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_MEMORY_UNMAP_INFO_KHR,
|
|
|
|
|
.memory = _mem,
|
|
|
|
|
};
|
|
|
|
|
anv_UnmapMemory2KHR(_device, &unmap);
|
|
|
|
|
}
|
2021-11-15 11:32:38 -06:00
|
|
|
|
2020-01-17 22:23:30 -06:00
|
|
|
p_atomic_add(&device->physical->memory.heaps[mem->type->heapIndex].used,
|
2019-05-08 11:39:09 +01:00
|
|
|
-mem->bo->size);
|
|
|
|
|
|
2019-10-25 17:45:28 -05:00
|
|
|
anv_device_release_bo(device, mem->bo);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
vk_device_memory_destroy(&device->vk, pAllocator, &mem->vk);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2023-03-20 17:02:45 -05:00
|
|
|
VkResult anv_MapMemory2KHR(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2023-03-20 17:02:45 -05:00
|
|
|
const VkMemoryMapInfoKHR* pMemoryMapInfo,
|
2015-05-08 22:32:37 -07:00
|
|
|
void** ppData)
|
|
|
|
|
{
|
2015-07-09 18:20:10 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2023-03-20 17:02:45 -05:00
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryMapInfo->memory);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-12-17 11:00:38 -08:00
|
|
|
if (mem == NULL) {
|
|
|
|
|
*ppData = NULL;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem->vk.host_ptr) {
|
|
|
|
|
*ppData = mem->vk.host_ptr + pMemoryMapInfo->offset;
|
2019-03-01 13:15:31 -08:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-02 13:09:44 +03:00
|
|
|
/* From the Vulkan spec version 1.0.32 docs for MapMemory:
|
|
|
|
|
*
|
|
|
|
|
* * memory must have been created with a memory type that reports
|
|
|
|
|
* VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
|
|
|
|
*/
|
|
|
|
|
if (!(mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) {
|
|
|
|
|
return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED,
|
|
|
|
|
"Memory object not mappable.");
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
assert(pMemoryMapInfo->size > 0);
|
2023-03-20 17:02:45 -05:00
|
|
|
const VkDeviceSize offset = pMemoryMapInfo->offset;
|
2023-03-20 18:00:38 -05:00
|
|
|
const VkDeviceSize size =
|
|
|
|
|
vk_device_memory_range(&mem->vk, pMemoryMapInfo->offset,
|
|
|
|
|
pMemoryMapInfo->size);
|
2016-11-07 17:23:44 -08:00
|
|
|
|
2021-10-30 16:32:47 -05:00
|
|
|
if (size != (size_t)size) {
|
|
|
|
|
return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED,
|
|
|
|
|
"requested size 0x%"PRIx64" does not fit in %u bits",
|
|
|
|
|
size, (unsigned)(sizeof(size_t) * 8));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* From the Vulkan 1.2.194 spec:
|
|
|
|
|
*
|
|
|
|
|
* "memory must not be currently host mapped"
|
|
|
|
|
*/
|
2021-11-15 11:32:38 -06:00
|
|
|
if (mem->map != NULL) {
|
2021-10-30 16:32:47 -05:00
|
|
|
return vk_errorf(device, VK_ERROR_MEMORY_MAP_FAILED,
|
|
|
|
|
"Memory object already mapped.");
|
|
|
|
|
}
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2016-01-01 09:26:06 -08:00
|
|
|
/* GEM will fail to map if the offset isn't 4k-aligned. Round down. */
|
2019-01-18 15:05:55 -08:00
|
|
|
uint64_t map_offset;
|
2022-10-06 10:04:32 -07:00
|
|
|
if (!device->physical->info.has_mmap_offset)
|
2019-01-18 15:05:55 -08:00
|
|
|
map_offset = offset & ~4095ull;
|
|
|
|
|
else
|
|
|
|
|
map_offset = 0;
|
2016-01-01 09:26:06 -08:00
|
|
|
assert(offset >= map_offset);
|
|
|
|
|
uint64_t map_size = (offset + size) - map_offset;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2016-01-01 09:26:06 -08:00
|
|
|
/* Let's map whole pages */
|
2022-12-02 14:37:31 +05:30
|
|
|
map_size = align64(map_size, 4096);
|
2016-01-01 09:26:06 -08:00
|
|
|
|
2021-10-30 17:02:41 -05:00
|
|
|
void *map;
|
2023-02-09 06:29:28 -08:00
|
|
|
VkResult result = anv_device_map_bo(device, mem->bo, map_offset, map_size,
|
|
|
|
|
mem->type->propertyFlags, &map);
|
2021-10-30 17:02:41 -05:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2016-11-07 17:24:24 -08:00
|
|
|
|
2021-11-15 11:32:38 -06:00
|
|
|
mem->map = map;
|
|
|
|
|
mem->map_size = map_size;
|
2021-10-30 16:57:02 -05:00
|
|
|
mem->map_delta = (offset - map_offset);
|
2021-11-15 11:32:38 -06:00
|
|
|
*ppData = mem->map + mem->map_delta;
|
2015-11-13 10:12:18 -08:00
|
|
|
|
2015-05-08 22:32:37 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-20 17:02:45 -05:00
|
|
|
VkResult anv_UnmapMemory2KHR(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
2023-03-20 17:02:45 -05:00
|
|
|
const VkMemoryUnmapInfoKHR* pMemoryUnmapInfo)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2019-02-20 15:26:43 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2023-03-20 17:02:45 -05:00
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryUnmapInfo->memory);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2023-03-20 18:00:38 -05:00
|
|
|
if (mem == NULL || mem->vk.host_ptr)
|
2023-03-20 17:02:45 -05:00
|
|
|
return VK_SUCCESS;
|
2015-12-17 11:00:38 -08:00
|
|
|
|
2021-11-15 11:32:38 -06:00
|
|
|
anv_device_unmap_bo(device, mem->bo, mem->map, mem->map_size);
|
2016-11-07 17:25:07 -08:00
|
|
|
|
2021-11-15 11:32:38 -06:00
|
|
|
mem->map = NULL;
|
|
|
|
|
mem->map_size = 0;
|
2021-10-30 16:57:02 -05:00
|
|
|
mem->map_delta = 0;
|
2023-03-20 17:02:45 -05:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-07-07 17:22:29 -07:00
|
|
|
VkResult anv_FlushMappedMemoryRanges(
|
2015-12-01 15:25:07 -08:00
|
|
|
VkDevice _device,
|
2015-11-30 21:18:12 -08:00
|
|
|
uint32_t memoryRangeCount,
|
|
|
|
|
const VkMappedMemoryRange* pMemoryRanges)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2022-11-22 07:26:58 -08:00
|
|
|
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
|
2015-12-01 15:25:07 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
2021-06-14 15:10:17 -05:00
|
|
|
if (!device->physical->memory.need_clflush)
|
2015-12-01 15:25:07 -08:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
/* Make sure the writes we're flushing have landed. */
|
2016-01-29 12:10:12 -08:00
|
|
|
__builtin_ia32_mfence();
|
2015-12-01 15:25:07 -08:00
|
|
|
|
2022-06-12 22:18:45 +03:00
|
|
|
for (uint32_t i = 0; i < memoryRangeCount; i++) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryRanges[i].memory);
|
2022-07-12 11:21:57 +03:00
|
|
|
if (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
2022-06-12 22:18:45 +03:00
|
|
|
continue;
|
|
|
|
|
|
2022-07-12 11:21:57 +03:00
|
|
|
uint64_t map_offset = pMemoryRanges[i].offset + mem->map_delta;
|
|
|
|
|
if (map_offset >= mem->map_size)
|
2022-06-12 22:18:45 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_clflush_range(mem->map + map_offset,
|
|
|
|
|
MIN2(pMemoryRanges[i].size,
|
|
|
|
|
mem->map_size - map_offset));
|
|
|
|
|
}
|
2022-11-22 07:26:58 -08:00
|
|
|
#endif
|
2015-05-08 22:32:37 -07:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-07 17:22:29 -07:00
|
|
|
VkResult anv_InvalidateMappedMemoryRanges(
|
2015-12-01 15:25:07 -08:00
|
|
|
VkDevice _device,
|
2015-11-30 21:18:12 -08:00
|
|
|
uint32_t memoryRangeCount,
|
|
|
|
|
const VkMappedMemoryRange* pMemoryRanges)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2022-11-22 07:26:58 -08:00
|
|
|
#ifdef SUPPORT_INTEL_INTEGRATED_GPUS
|
2015-12-01 15:25:07 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
2021-06-14 15:10:17 -05:00
|
|
|
if (!device->physical->memory.need_clflush)
|
2015-12-01 15:25:07 -08:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
2022-06-12 22:18:45 +03:00
|
|
|
for (uint32_t i = 0; i < memoryRangeCount; i++) {
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pMemoryRanges[i].memory);
|
2022-07-12 11:21:57 +03:00
|
|
|
if (mem->type->propertyFlags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
2022-06-12 22:18:45 +03:00
|
|
|
continue;
|
|
|
|
|
|
2022-07-12 11:21:57 +03:00
|
|
|
uint64_t map_offset = pMemoryRanges[i].offset + mem->map_delta;
|
|
|
|
|
if (map_offset >= mem->map_size)
|
2022-06-12 22:18:45 +03:00
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
intel_invalidate_range(mem->map + map_offset,
|
|
|
|
|
MIN2(pMemoryRanges[i].size,
|
|
|
|
|
mem->map_size - map_offset));
|
|
|
|
|
}
|
2015-12-01 15:25:07 -08:00
|
|
|
|
|
|
|
|
/* Make sure no reads get moved up above the invalidate. */
|
2016-01-29 12:10:12 -08:00
|
|
|
__builtin_ia32_mfence();
|
2022-11-22 07:26:58 -08:00
|
|
|
#endif
|
2015-12-01 15:25:07 -08:00
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-11-30 12:21:19 -08:00
|
|
|
void anv_GetDeviceMemoryCommitment(
|
2015-07-14 17:06:11 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
VkDeviceMemory memory,
|
|
|
|
|
VkDeviceSize* pCommittedMemoryInBytes)
|
|
|
|
|
{
|
|
|
|
|
*pCommittedMemoryInBytes = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-18 09:02:53 -07:00
|
|
|
static void
|
2017-09-20 13:16:26 -07:00
|
|
|
anv_bind_buffer_memory(const VkBindBufferMemoryInfo *pBindInfo)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2017-07-18 09:02:53 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device_memory, mem, pBindInfo->memory);
|
|
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, pBindInfo->buffer);
|
|
|
|
|
|
2017-09-20 13:16:26 -07:00
|
|
|
assert(pBindInfo->sType == VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-12-17 11:00:38 -08:00
|
|
|
if (mem) {
|
2023-03-20 18:00:38 -05:00
|
|
|
assert(pBindInfo->memoryOffset < mem->vk.size);
|
|
|
|
|
assert(mem->vk.size - pBindInfo->memoryOffset >= buffer->vk.size);
|
2018-05-30 18:05:54 -07:00
|
|
|
buffer->address = (struct anv_address) {
|
|
|
|
|
.bo = mem->bo,
|
|
|
|
|
.offset = pBindInfo->memoryOffset,
|
|
|
|
|
};
|
2015-12-17 11:00:38 -08:00
|
|
|
} else {
|
2018-05-30 18:05:54 -07:00
|
|
|
buffer->address = ANV_NULL_ADDRESS;
|
2015-12-17 11:00:38 -08:00
|
|
|
}
|
2017-07-18 09:02:53 -07:00
|
|
|
}
|
|
|
|
|
|
2017-09-20 12:18:10 -07:00
|
|
|
VkResult anv_BindBufferMemory2(
|
2017-07-18 09:02:53 -07:00
|
|
|
VkDevice device,
|
|
|
|
|
uint32_t bindInfoCount,
|
2017-09-20 13:16:26 -07:00
|
|
|
const VkBindBufferMemoryInfo* pBindInfos)
|
2017-07-18 09:02:53 -07:00
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; i++)
|
|
|
|
|
anv_bind_buffer_memory(&pBindInfos[i]);
|
2015-07-14 14:59:39 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-30 16:42:12 -08:00
|
|
|
VkResult anv_QueueBindSparse(
|
2017-03-22 09:18:56 +01:00
|
|
|
VkQueue _queue,
|
2015-11-30 16:42:12 -08:00
|
|
|
uint32_t bindInfoCount,
|
|
|
|
|
const VkBindSparseInfo* pBindInfo,
|
|
|
|
|
VkFence fence)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2017-03-22 09:18:56 +01:00
|
|
|
ANV_FROM_HANDLE(anv_queue, queue, _queue);
|
2021-10-19 18:44:01 -05:00
|
|
|
if (vk_device_is_lost(&queue->device->vk))
|
2017-03-22 09:18:56 +01:00
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(queue, VK_ERROR_FEATURE_NOT_PRESENT);
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Event functions
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateEvent(
|
2015-12-19 22:17:19 -08:00
|
|
|
VkDevice _device,
|
2015-05-08 22:32:37 -07:00
|
|
|
const VkEventCreateInfo* pCreateInfo,
|
2015-12-02 03:28:27 -08:00
|
|
|
const VkAllocationCallbacks* pAllocator,
|
2015-05-08 22:32:37 -07:00
|
|
|
VkEvent* pEvent)
|
|
|
|
|
{
|
2015-12-19 22:17:19 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
struct anv_event *event;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO);
|
|
|
|
|
|
2021-04-08 16:12:27 -05:00
|
|
|
event = vk_object_alloc(&device->vk, pAllocator, sizeof(*event),
|
|
|
|
|
VK_OBJECT_TYPE_EVENT);
|
2020-04-22 12:23:24 -05:00
|
|
|
if (event == NULL)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2020-04-22 12:23:24 -05:00
|
|
|
|
|
|
|
|
event->state = anv_state_pool_alloc(&device->dynamic_state_pool,
|
|
|
|
|
sizeof(uint64_t), 8);
|
|
|
|
|
*(uint64_t *)event->state.map = VK_EVENT_RESET;
|
2015-12-19 22:17:19 -08:00
|
|
|
|
|
|
|
|
*pEvent = anv_event_to_handle(event);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-05 20:50:51 -07:00
|
|
|
void anv_DestroyEvent(
|
2015-12-19 22:17:19 -08:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkEvent _event,
|
2015-12-02 03:28:27 -08:00
|
|
|
const VkAllocationCallbacks* pAllocator)
|
2015-07-14 09:33:47 -07:00
|
|
|
{
|
2015-12-19 22:17:19 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_event, event, _event);
|
|
|
|
|
|
2016-11-10 21:32:32 -08:00
|
|
|
if (!event)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-12-19 22:17:19 -08:00
|
|
|
anv_state_pool_free(&device->dynamic_state_pool, event->state);
|
2020-04-21 12:33:16 -05:00
|
|
|
|
2021-04-08 16:12:27 -05:00
|
|
|
vk_object_free(&device->vk, pAllocator, event);
|
2015-07-14 09:33:47 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_GetEventStatus(
|
2015-12-19 22:17:19 -08:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkEvent _event)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-12-19 22:17:19 -08:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_event, event, _event);
|
|
|
|
|
|
2021-10-19 18:44:01 -05:00
|
|
|
if (vk_device_is_lost(&device->vk))
|
2017-03-22 09:18:56 +01:00
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
2020-04-22 12:23:24 -05:00
|
|
|
return *(uint64_t *)event->state.map;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_SetEvent(
|
2015-12-19 22:17:19 -08:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkEvent _event)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-12-19 22:17:19 -08:00
|
|
|
ANV_FROM_HANDLE(anv_event, event, _event);
|
|
|
|
|
|
2020-04-22 12:23:24 -05:00
|
|
|
*(uint64_t *)event->state.map = VK_EVENT_SET;
|
2015-12-19 22:17:19 -08:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_ResetEvent(
|
2015-12-19 22:17:19 -08:00
|
|
|
VkDevice _device,
|
|
|
|
|
VkEvent _event)
|
2015-05-08 22:32:37 -07:00
|
|
|
{
|
2015-12-19 22:17:19 -08:00
|
|
|
ANV_FROM_HANDLE(anv_event, event, _event);
|
|
|
|
|
|
2020-04-22 12:23:24 -05:00
|
|
|
*(uint64_t *)event->state.map = VK_EVENT_RESET;
|
2015-12-19 22:17:19 -08:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Buffer functions
|
|
|
|
|
|
2021-07-28 12:29:35 +03:00
|
|
|
static void
|
|
|
|
|
anv_get_buffer_memory_requirements(struct anv_device *device,
|
|
|
|
|
VkDeviceSize size,
|
|
|
|
|
VkBufferUsageFlags usage,
|
|
|
|
|
VkMemoryRequirements2* pMemoryRequirements)
|
2021-07-28 12:20:02 +03:00
|
|
|
{
|
|
|
|
|
/* The Vulkan spec (git aaed022) says:
|
|
|
|
|
*
|
|
|
|
|
* memoryTypeBits is a bitfield and contains one bit set for every
|
|
|
|
|
* supported memory type for the resource. The bit `1<<i` is set if and
|
|
|
|
|
* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
|
|
|
|
|
* structure for the physical device is supported.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1;
|
|
|
|
|
|
|
|
|
|
/* Base alignment requirement of a cache line */
|
|
|
|
|
uint32_t alignment = 16;
|
|
|
|
|
|
2021-07-28 12:29:35 +03:00
|
|
|
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
|
2021-07-28 12:20:02 +03:00
|
|
|
alignment = MAX2(alignment, ANV_UBO_ALIGNMENT);
|
|
|
|
|
|
2021-07-28 12:29:35 +03:00
|
|
|
pMemoryRequirements->memoryRequirements.size = size;
|
2021-07-28 12:20:02 +03:00
|
|
|
pMemoryRequirements->memoryRequirements.alignment = alignment;
|
|
|
|
|
|
|
|
|
|
/* Storage and Uniform buffers should have their size aligned to
|
|
|
|
|
* 32-bits to avoid boundary checks when last DWord is not complete.
|
|
|
|
|
* This would ensure that not internal padding would be needed for
|
|
|
|
|
* 16-bit types.
|
|
|
|
|
*/
|
2023-02-15 18:35:14 +02:00
|
|
|
if (device->vk.enabled_features.robustBufferAccess &&
|
2021-07-28 12:29:35 +03:00
|
|
|
(usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
|
|
|
|
|
usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT))
|
2022-12-02 14:37:31 +05:30
|
|
|
pMemoryRequirements->memoryRequirements.size = align64(size, 4);
|
2021-07-28 12:20:02 +03:00
|
|
|
|
|
|
|
|
pMemoryRequirements->memoryRequirements.memoryTypeBits = memory_types;
|
|
|
|
|
|
|
|
|
|
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
|
|
|
|
|
switch (ext->sType) {
|
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
|
|
|
|
VkMemoryDedicatedRequirements *requirements = (void *)ext;
|
|
|
|
|
requirements->prefersDedicatedAllocation = false;
|
|
|
|
|
requirements->requiresDedicatedAllocation = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
anv_debug_ignored_stype(ext->sType);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-28 12:29:35 +03:00
|
|
|
void anv_GetDeviceBufferMemoryRequirementsKHR(
|
|
|
|
|
VkDevice _device,
|
2022-07-01 13:03:31 +01:00
|
|
|
const VkDeviceBufferMemoryRequirements* pInfo,
|
2021-07-28 12:29:35 +03:00
|
|
|
VkMemoryRequirements2* pMemoryRequirements)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
anv_get_buffer_memory_requirements(device,
|
|
|
|
|
pInfo->pCreateInfo->size,
|
|
|
|
|
pInfo->pCreateInfo->usage,
|
|
|
|
|
pMemoryRequirements);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-17 16:33:48 -07:00
|
|
|
VkResult anv_CreateBuffer(
|
2015-05-08 22:32:37 -07:00
|
|
|
VkDevice _device,
|
|
|
|
|
const VkBufferCreateInfo* pCreateInfo,
|
2015-12-02 03:28:27 -08:00
|
|
|
const VkAllocationCallbacks* pAllocator,
|
2015-05-08 22:32:37 -07:00
|
|
|
VkBuffer* pBuffer)
|
|
|
|
|
{
|
2015-07-08 14:24:12 -07:00
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2015-05-08 22:32:37 -07:00
|
|
|
struct anv_buffer *buffer;
|
|
|
|
|
|
2019-11-25 10:27:02 -06:00
|
|
|
/* Don't allow creating buffers bigger than our address space. The real
|
|
|
|
|
* issue here is that we may align up the buffer size and we don't want
|
|
|
|
|
* doing so to cause roll-over. However, no one has any business
|
|
|
|
|
* allocating a buffer larger than our GTT size.
|
|
|
|
|
*/
|
2020-01-17 22:23:30 -06:00
|
|
|
if (pCreateInfo->size > device->physical->gtt_size)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2019-11-25 10:27:02 -06:00
|
|
|
|
2022-05-19 09:00:30 -05:00
|
|
|
buffer = vk_buffer_create(&device->vk, pCreateInfo,
|
|
|
|
|
pAllocator, sizeof(*buffer));
|
2015-05-08 22:32:37 -07:00
|
|
|
if (buffer == NULL)
|
2021-09-24 12:06:32 -05:00
|
|
|
return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2018-05-30 18:05:54 -07:00
|
|
|
buffer->address = ANV_NULL_ADDRESS;
|
2015-05-08 22:32:37 -07:00
|
|
|
|
2015-07-09 18:41:27 -07:00
|
|
|
*pBuffer = anv_buffer_to_handle(buffer);
|
2015-05-08 22:32:37 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2015-10-05 20:50:51 -07:00
|
|
|
void anv_DestroyBuffer(
|
2015-07-14 09:47:45 -07:00
|
|
|
VkDevice _device,
|
2015-12-02 03:28:27 -08:00
|
|
|
VkBuffer _buffer,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
2015-07-14 09:47:45 -07:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
|
|
|
|
|
|
2016-11-10 21:32:32 -08:00
|
|
|
if (!buffer)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-05-19 09:00:30 -05:00
|
|
|
vk_buffer_destroy(&device->vk, pAllocator, &buffer->vk);
|
2015-07-14 09:47:45 -07:00
|
|
|
}
|
|
|
|
|
|
2019-09-16 15:41:45 -07:00
|
|
|
VkDeviceAddress anv_GetBufferDeviceAddress(
|
2019-01-19 08:54:32 -06:00
|
|
|
VkDevice device,
|
2022-07-01 13:03:31 +01:00
|
|
|
const VkBufferDeviceAddressInfo* pInfo)
|
2019-01-19 08:54:32 -06:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer);
|
|
|
|
|
|
2019-12-02 16:28:58 -06:00
|
|
|
assert(!anv_address_is_null(buffer->address));
|
2019-01-19 08:54:32 -06:00
|
|
|
|
|
|
|
|
return anv_address_physical(buffer->address);
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-16 15:41:45 -07:00
|
|
|
uint64_t anv_GetBufferOpaqueCaptureAddress(
|
2019-12-02 16:28:58 -06:00
|
|
|
VkDevice device,
|
2022-07-01 13:03:31 +01:00
|
|
|
const VkBufferDeviceAddressInfo* pInfo)
|
2019-12-02 16:28:58 -06:00
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-16 15:41:45 -07:00
|
|
|
uint64_t anv_GetDeviceMemoryOpaqueCaptureAddress(
|
2019-12-02 16:28:58 -06:00
|
|
|
VkDevice device,
|
2022-07-01 13:03:31 +01:00
|
|
|
const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo)
|
2019-12-02 16:28:58 -06:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device_memory, memory, pInfo->memory);
|
|
|
|
|
|
|
|
|
|
assert(memory->bo->has_client_visible_address);
|
|
|
|
|
|
2021-03-03 13:49:18 -08:00
|
|
|
return intel_48b_address(memory->bo->offset);
|
2019-12-02 16:28:58 -06:00
|
|
|
}
|
|
|
|
|
|
2015-08-19 16:01:33 -07:00
|
|
|
void
|
2016-01-26 14:50:52 -08:00
|
|
|
anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state,
|
2015-12-14 16:14:20 -08:00
|
|
|
enum isl_format format,
|
2022-07-06 17:48:27 +03:00
|
|
|
struct isl_swizzle swizzle,
|
2020-10-07 07:44:56 -07:00
|
|
|
isl_surf_usage_flags_t usage,
|
2018-05-30 17:36:49 -07:00
|
|
|
struct anv_address address,
|
|
|
|
|
uint32_t range, uint32_t stride)
|
2015-08-19 16:01:33 -07:00
|
|
|
{
|
2016-02-22 16:54:25 -08:00
|
|
|
isl_buffer_fill_state(&device->isl_dev, state.map,
|
2018-05-30 17:36:49 -07:00
|
|
|
.address = anv_address_physical(address),
|
2020-12-14 11:11:59 +02:00
|
|
|
.mocs = isl_mocs(&device->isl_dev, usage,
|
|
|
|
|
address.bo && address.bo->is_external),
|
2018-09-05 14:02:12 -05:00
|
|
|
.size_B = range,
|
2016-02-22 16:54:25 -08:00
|
|
|
.format = format,
|
2022-07-06 17:48:27 +03:00
|
|
|
.swizzle = swizzle,
|
2018-09-05 14:02:12 -05:00
|
|
|
.stride_B = stride);
|
2015-08-19 16:01:33 -07:00
|
|
|
}
|
|
|
|
|
|
2015-10-05 20:50:51 -07:00
|
|
|
void anv_DestroySampler(
|
2015-07-14 10:34:00 -07:00
|
|
|
VkDevice _device,
|
2015-12-02 03:28:27 -08:00
|
|
|
VkSampler _sampler,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
2015-07-14 10:34:00 -07:00
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
|
|
|
|
ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
|
|
|
|
|
|
2016-11-10 21:32:32 -08:00
|
|
|
if (!sampler)
|
|
|
|
|
return;
|
|
|
|
|
|
2019-02-07 14:10:33 -06:00
|
|
|
if (sampler->bindless_state.map) {
|
|
|
|
|
anv_state_pool_free(&device->dynamic_state_pool,
|
|
|
|
|
sampler->bindless_state);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-22 17:08:22 -07:00
|
|
|
if (sampler->custom_border_color.map) {
|
|
|
|
|
anv_state_reserved_pool_free(&device->custom_border_colors,
|
|
|
|
|
sampler->custom_border_color);
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-08 16:12:27 -05:00
|
|
|
vk_object_free(&device->vk, pAllocator, sampler);
|
2015-07-14 10:34:00 -07:00
|
|
|
}
|
|
|
|
|
|
2018-10-11 16:05:18 -07:00
|
|
|
static const VkTimeDomainEXT anv_time_domains[] = {
|
|
|
|
|
VK_TIME_DOMAIN_DEVICE_EXT,
|
|
|
|
|
VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
|
2020-09-01 12:13:43 +10:00
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2018-10-11 16:05:18 -07:00
|
|
|
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
|
2020-09-01 12:13:43 +10:00
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t *pTimeDomainCount,
|
|
|
|
|
VkTimeDomainEXT *pTimeDomains)
|
|
|
|
|
{
|
|
|
|
|
int d;
|
2022-03-23 13:50:34 +01:00
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains, pTimeDomainCount);
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
|
2022-03-23 13:50:34 +01:00
|
|
|
vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {
|
2018-10-11 16:05:18 -07:00
|
|
|
*i = anv_time_domains[d];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult anv_GetCalibratedTimestampsEXT(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
uint32_t timestampCount,
|
|
|
|
|
const VkCalibratedTimestampInfoEXT *pTimestampInfos,
|
|
|
|
|
uint64_t *pTimestamps,
|
|
|
|
|
uint64_t *pMaxDeviation)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_device, device, _device);
|
2022-08-04 12:56:17 -07:00
|
|
|
uint64_t timestamp_frequency = device->info->timestamp_frequency;
|
2018-10-11 16:05:18 -07:00
|
|
|
int d;
|
|
|
|
|
uint64_t begin, end;
|
|
|
|
|
uint64_t max_clock_period = 0;
|
|
|
|
|
|
2020-09-01 12:13:43 +10:00
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2022-08-29 14:29:31 -03:00
|
|
|
begin = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
|
2020-09-01 12:13:43 +10:00
|
|
|
#else
|
2022-08-29 14:29:31 -03:00
|
|
|
begin = vk_clock_gettime(CLOCK_MONOTONIC);
|
2020-09-01 12:13:43 +10:00
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
for (d = 0; d < timestampCount; d++) {
|
|
|
|
|
switch (pTimestampInfos[d].timeDomain) {
|
|
|
|
|
case VK_TIME_DOMAIN_DEVICE_EXT:
|
2022-10-06 13:33:15 -07:00
|
|
|
if (!intel_gem_read_render_timestamp(device->fd,
|
|
|
|
|
device->info->kmd_type,
|
|
|
|
|
&pTimestamps[d])) {
|
2021-10-19 18:44:01 -05:00
|
|
|
return vk_device_set_lost(&device->vk, "Failed to read the "
|
|
|
|
|
"TIMESTAMP register: %m");
|
2018-10-11 16:05:18 -07:00
|
|
|
}
|
|
|
|
|
uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
|
|
|
|
|
max_clock_period = MAX2(max_clock_period, device_period);
|
|
|
|
|
break;
|
|
|
|
|
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
|
2022-08-29 14:29:31 -03:00
|
|
|
pTimestamps[d] = vk_clock_gettime(CLOCK_MONOTONIC);
|
2018-10-11 16:05:18 -07:00
|
|
|
max_clock_period = MAX2(max_clock_period, 1);
|
|
|
|
|
break;
|
|
|
|
|
|
2020-09-01 12:13:43 +10:00
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2018-10-11 16:05:18 -07:00
|
|
|
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
|
|
|
|
|
pTimestamps[d] = begin;
|
|
|
|
|
break;
|
2020-09-01 12:13:43 +10:00
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
default:
|
|
|
|
|
pTimestamps[d] = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 12:13:43 +10:00
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2022-08-29 14:29:31 -03:00
|
|
|
end = vk_clock_gettime(CLOCK_MONOTONIC_RAW);
|
2020-09-01 12:13:43 +10:00
|
|
|
#else
|
2022-08-29 14:29:31 -03:00
|
|
|
end = vk_clock_gettime(CLOCK_MONOTONIC);
|
2020-09-01 12:13:43 +10:00
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
|
2022-08-29 14:29:31 -03:00
|
|
|
*pMaxDeviation = vk_time_max_deviation(begin, end, max_clock_period);
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-14 21:52:00 +02:00
|
|
|
void anv_GetPhysicalDeviceMultisamplePropertiesEXT(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkSampleCountFlagBits samples,
|
|
|
|
|
VkMultisamplePropertiesEXT* pMultisampleProperties)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
|
|
|
|
assert(pMultisampleProperties->sType ==
|
|
|
|
|
VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT);
|
|
|
|
|
|
|
|
|
|
VkExtent2D grid_size;
|
|
|
|
|
if (samples & isl_device_get_sample_counts(&physical_device->isl_dev)) {
|
|
|
|
|
grid_size.width = 1;
|
|
|
|
|
grid_size.height = 1;
|
|
|
|
|
} else {
|
|
|
|
|
grid_size.width = 0;
|
|
|
|
|
grid_size.height = 0;
|
|
|
|
|
}
|
|
|
|
|
pMultisampleProperties->maxSampleLocationGridSize = grid_size;
|
|
|
|
|
|
|
|
|
|
vk_foreach_struct(ext, pMultisampleProperties->pNext)
|
|
|
|
|
anv_debug_ignored_stype(ext->sType);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-10 17:29:08 -08:00
|
|
|
/* vk_icd.h does not declare this function, so we declare it here to
|
|
|
|
|
* suppress Wmissing-prototypes.
|
|
|
|
|
*/
|
|
|
|
|
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
|
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion);
|
|
|
|
|
|
|
|
|
|
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
|
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t* pSupportedVersion)
|
|
|
|
|
{
|
|
|
|
|
/* For the full details on loader interface versioning, see
|
|
|
|
|
* <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
|
|
|
|
|
* What follows is a condensed summary, to help you navigate the large and
|
|
|
|
|
* confusing official doc.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v0 is incompatible with later versions. We don't
|
|
|
|
|
* support it.
|
|
|
|
|
*
|
|
|
|
|
* - In loader interface v1:
|
|
|
|
|
* - The first ICD entrypoint called by the loader is
|
|
|
|
|
* vk_icdGetInstanceProcAddr(). The ICD must statically expose this
|
|
|
|
|
* entrypoint.
|
|
|
|
|
* - The ICD must statically expose no other Vulkan symbol unless it is
|
|
|
|
|
* linked with -Bsymbolic.
|
|
|
|
|
* - Each dispatchable Vulkan handle created by the ICD must be
|
|
|
|
|
* a pointer to a struct whose first member is VK_LOADER_DATA. The
|
|
|
|
|
* ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.
|
|
|
|
|
* - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
|
|
|
|
|
* vkDestroySurfaceKHR(). The ICD must be capable of working with
|
|
|
|
|
* such loader-managed surfaces.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v2 differs from v1 in:
|
|
|
|
|
* - The first ICD entrypoint called by the loader is
|
|
|
|
|
* vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
|
|
|
|
|
* statically expose this entrypoint.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v3 differs from v2 in:
|
|
|
|
|
* - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
|
|
|
|
|
* vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
|
|
|
|
|
* because the loader no longer does so.
|
2019-09-08 00:11:01 +03:00
|
|
|
*
|
|
|
|
|
* - Loader interface v4 differs from v3 in:
|
|
|
|
|
* - The ICD must implement vk_icdGetPhysicalDeviceProcAddr().
|
2020-11-09 15:33:17 -06:00
|
|
|
*
|
2022-01-14 12:07:25 -06:00
|
|
|
* - Loader interface v5 differs from v4 in:
|
2020-11-09 15:33:17 -06:00
|
|
|
* - The ICD must support Vulkan API version 1.1 and must not return
|
2022-01-14 12:07:25 -06:00
|
|
|
* VK_ERROR_INCOMPATIBLE_DRIVER from vkCreateInstance() unless a
|
|
|
|
|
* Vulkan Loader with interface v4 or smaller is being used and the
|
|
|
|
|
* application provides an API version that is greater than 1.0.
|
2017-01-10 17:29:08 -08:00
|
|
|
*/
|
2022-01-14 12:07:25 -06:00
|
|
|
*pSupportedVersion = MIN2(*pSupportedVersion, 5u);
|
2017-01-10 17:29:08 -08:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
2020-10-19 10:12:43 +03:00
|
|
|
|
|
|
|
|
VkResult anv_GetPhysicalDeviceFragmentShadingRatesKHR(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t* pFragmentShadingRateCount,
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates)
|
|
|
|
|
{
|
|
|
|
|
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
|
2022-03-23 13:50:34 +01:00
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceFragmentShadingRateKHR, out,
|
|
|
|
|
pFragmentShadingRates, pFragmentShadingRateCount);
|
|
|
|
|
|
|
|
|
|
#define append_rate(_samples, _width, _height) \
|
|
|
|
|
do { \
|
|
|
|
|
vk_outarray_append_typed(VkPhysicalDeviceFragmentShadingRateKHR, &out, __r) { \
|
|
|
|
|
__r->sampleCounts = _samples; \
|
|
|
|
|
__r->fragmentSize = (VkExtent2D) { \
|
|
|
|
|
.width = _width, \
|
|
|
|
|
.height = _height, \
|
|
|
|
|
}; \
|
|
|
|
|
} \
|
2020-10-19 10:12:43 +03:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
VkSampleCountFlags sample_counts =
|
|
|
|
|
isl_device_get_sample_counts(&physical_device->isl_dev);
|
|
|
|
|
|
2021-02-05 21:16:38 +02:00
|
|
|
/* BSpec 47003: There are a number of restrictions on the sample count
|
|
|
|
|
* based off the coarse pixel size.
|
|
|
|
|
*/
|
|
|
|
|
static const VkSampleCountFlags cp_size_sample_limits[] = {
|
|
|
|
|
[1] = ISL_SAMPLE_COUNT_16_BIT | ISL_SAMPLE_COUNT_8_BIT |
|
|
|
|
|
ISL_SAMPLE_COUNT_4_BIT | ISL_SAMPLE_COUNT_2_BIT | ISL_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
[2] = ISL_SAMPLE_COUNT_4_BIT | ISL_SAMPLE_COUNT_2_BIT | ISL_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
[4] = ISL_SAMPLE_COUNT_4_BIT | ISL_SAMPLE_COUNT_2_BIT | ISL_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
[8] = ISL_SAMPLE_COUNT_2_BIT | ISL_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
[16] = ISL_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
};
|
|
|
|
|
|
2020-10-19 10:12:43 +03:00
|
|
|
for (uint32_t x = 4; x >= 1; x /= 2) {
|
|
|
|
|
for (uint32_t y = 4; y >= 1; y /= 2) {
|
2021-02-05 21:16:38 +02:00
|
|
|
if (physical_device->info.has_coarse_pixel_primitive_and_cb) {
|
|
|
|
|
/* BSpec 47003:
|
|
|
|
|
* "CPsize 1x4 and 4x1 are not supported"
|
|
|
|
|
*/
|
|
|
|
|
if ((x == 1 && y == 4) || (x == 4 && y == 1))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* For size {1, 1}, the sample count must be ~0
|
|
|
|
|
*
|
|
|
|
|
* 4x2 is also a specially case.
|
|
|
|
|
*/
|
|
|
|
|
if (x == 1 && y == 1)
|
|
|
|
|
append_rate(~0, x, y);
|
|
|
|
|
else if (x == 4 && y == 2)
|
|
|
|
|
append_rate(ISL_SAMPLE_COUNT_1_BIT, x, y);
|
|
|
|
|
else
|
|
|
|
|
append_rate(cp_size_sample_limits[x * y], x, y);
|
|
|
|
|
} else {
|
|
|
|
|
/* For size {1, 1}, the sample count must be ~0 */
|
|
|
|
|
if (x == 1 && y == 1)
|
|
|
|
|
append_rate(~0, x, y);
|
|
|
|
|
else
|
|
|
|
|
append_rate(sample_counts, x, y);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-10-19 10:12:43 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef append_rate
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
}
|