2016-10-07 09:16:09 +10:00
|
|
|
|
/*
|
|
|
|
|
|
* Copyright © 2016 Red Hat.
|
|
|
|
|
|
* Copyright © 2016 Bas Nieuwenhuizen
|
|
|
|
|
|
*
|
|
|
|
|
|
* based in part on anv driver which is:
|
|
|
|
|
|
* 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 <stdbool.h>
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
#include <fcntl.h>
|
2019-07-31 14:03:53 +10:00
|
|
|
|
|
2017-08-30 15:12:20 +02:00
|
|
|
|
#include "radv_debug.h"
|
2016-10-07 09:16:09 +10:00
|
|
|
|
#include "radv_private.h"
|
2017-09-01 11:41:18 +02:00
|
|
|
|
#include "radv_shader.h"
|
2017-01-29 13:53:05 +01:00
|
|
|
|
#include "radv_cs.h"
|
2017-02-10 13:02:22 +11:00
|
|
|
|
#include "util/disk_cache.h"
|
2021-01-17 13:37:50 +01:00
|
|
|
|
#include "vk_deferred_operation.h"
|
2017-06-06 12:31:05 +01:00
|
|
|
|
#include "vk_util.h"
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
typedef void* drmDevicePtr;
|
|
|
|
|
|
#else
|
2016-10-11 15:21:25 +10:00
|
|
|
|
#include <xf86drm.h>
|
2016-10-07 09:16:09 +10:00
|
|
|
|
#include <amdgpu.h>
|
2020-04-25 20:03:15 +02:00
|
|
|
|
#include "drm-uapi/amdgpu_drm.h"
|
2016-10-07 09:16:09 +10:00
|
|
|
|
#include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2020-02-17 14:45:47 +01:00
|
|
|
|
#include "winsys/null/radv_null_winsys_public.h"
|
2016-10-07 09:16:09 +10:00
|
|
|
|
#include "ac_llvm_util.h"
|
|
|
|
|
|
#include "vk_format.h"
|
|
|
|
|
|
#include "sid.h"
|
2018-09-30 20:02:04 +02:00
|
|
|
|
#include "git_sha1.h"
|
2018-09-16 02:50:34 +02:00
|
|
|
|
#include "util/build_id.h"
|
2016-10-07 09:16:09 +10:00
|
|
|
|
#include "util/debug.h"
|
2018-09-16 02:50:34 +02:00
|
|
|
|
#include "util/mesa-sha1.h"
|
2019-10-22 10:18:06 +02:00
|
|
|
|
#include "util/timespec.h"
|
2019-10-28 02:44:54 +01:00
|
|
|
|
#include "util/u_atomic.h"
|
2019-03-15 09:47:49 +02:00
|
|
|
|
#include "compiler/glsl_types.h"
|
2020-06-12 11:42:32 +02:00
|
|
|
|
#include "util/driconf.h"
|
2018-09-16 02:50:34 +02:00
|
|
|
|
|
2020-11-01 00:04:42 -07:00
|
|
|
|
/* The number of IBs per submit isn't infinite, it depends on the ring type
|
|
|
|
|
|
* (ie. some initial setup needed for a submit) and the number of IBs (4 DW).
|
|
|
|
|
|
* This limit is arbitrary but should be safe for now. Ideally, we should get
|
|
|
|
|
|
* this limit from the KMD.
|
|
|
|
|
|
*/
|
|
|
|
|
|
#define RADV_MAX_IBS_PER_SUBMIT 192
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
static struct radv_timeline_point *
|
|
|
|
|
|
radv_timeline_find_point_at_least_locked(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline,
|
|
|
|
|
|
uint64_t p);
|
|
|
|
|
|
|
|
|
|
|
|
static struct radv_timeline_point *
|
|
|
|
|
|
radv_timeline_add_point_locked(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline,
|
|
|
|
|
|
uint64_t p);
|
|
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_timeline_trigger_waiters_locked(struct radv_timeline *timeline,
|
|
|
|
|
|
struct list_head *processing_list);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2019-10-20 22:50:58 +02:00
|
|
|
|
static
|
|
|
|
|
|
void radv_destroy_semaphore_part(struct radv_device *device,
|
|
|
|
|
|
struct radv_semaphore_part *part);
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
uint64_t radv_get_current_time(void)
|
|
|
|
|
|
{
|
2020-10-31 16:18:34 -07:00
|
|
|
|
return os_time_get_nano();
|
2020-06-22 22:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint64_t radv_get_absolute_timeout(uint64_t timeout)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint64_t current_time = radv_get_current_time();
|
|
|
|
|
|
|
|
|
|
|
|
timeout = MIN2(UINT64_MAX - current_time, timeout);
|
|
|
|
|
|
|
|
|
|
|
|
return current_time + timeout;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-11-22 00:19:30 +01:00
|
|
|
|
static int
|
2016-11-22 00:39:50 +01:00
|
|
|
|
radv_device_get_cache_uuid(enum radeon_family family, void *uuid)
|
2016-11-22 00:31:44 +01:00
|
|
|
|
{
|
2018-09-16 02:50:34 +02:00
|
|
|
|
struct mesa_sha1 ctx;
|
|
|
|
|
|
unsigned char sha1[20];
|
|
|
|
|
|
unsigned ptr_size = sizeof(void*);
|
2018-09-20 19:15:58 +02:00
|
|
|
|
|
2016-11-22 00:31:44 +01:00
|
|
|
|
memset(uuid, 0, VK_UUID_SIZE);
|
2018-09-20 19:15:58 +02:00
|
|
|
|
_mesa_sha1_init(&ctx);
|
2018-09-16 02:50:34 +02:00
|
|
|
|
|
2018-10-23 21:51:09 -03:00
|
|
|
|
if (!disk_cache_get_function_identifier(radv_device_get_cache_uuid, &ctx) ||
|
|
|
|
|
|
!disk_cache_get_function_identifier(LLVMInitializeAMDGPUTargetInfo, &ctx))
|
2016-11-22 00:19:30 +01:00
|
|
|
|
return -1;
|
|
|
|
|
|
|
2018-09-16 02:50:34 +02:00
|
|
|
|
_mesa_sha1_update(&ctx, &family, sizeof(family));
|
|
|
|
|
|
_mesa_sha1_update(&ctx, &ptr_size, sizeof(ptr_size));
|
|
|
|
|
|
_mesa_sha1_final(&ctx, sha1);
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(uuid, sha1, VK_UUID_SIZE);
|
2016-11-22 00:19:30 +01:00
|
|
|
|
return 0;
|
2016-11-22 00:31:44 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-07-12 18:45:31 -04:00
|
|
|
|
static void
|
|
|
|
|
|
radv_get_driver_uuid(void *uuid)
|
|
|
|
|
|
{
|
|
|
|
|
|
ac_compute_driver_uuid(uuid, VK_UUID_SIZE);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-23 09:22:09 +02:00
|
|
|
|
static void
|
2017-07-12 18:45:30 -04:00
|
|
|
|
radv_get_device_uuid(struct radeon_info *info, void *uuid)
|
|
|
|
|
|
{
|
|
|
|
|
|
ac_compute_device_uuid(info, uuid, VK_UUID_SIZE);
|
2017-05-23 09:22:09 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-08 02:02:09 +02:00
|
|
|
|
static uint64_t
|
|
|
|
|
|
radv_get_adjusted_vram_size(struct radv_physical_device *device)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ov = driQueryOptioni(&device->instance->dri_options,
|
|
|
|
|
|
"override_vram_size");
|
|
|
|
|
|
if (ov >= 0)
|
|
|
|
|
|
return MIN2(device->rad_info.vram_size, (uint64_t)ov << 20);
|
|
|
|
|
|
return device->rad_info.vram_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-07 17:38:08 +01:00
|
|
|
|
static uint64_t
|
|
|
|
|
|
radv_get_visible_vram_size(struct radv_physical_device *device)
|
|
|
|
|
|
{
|
2020-09-08 02:02:09 +02:00
|
|
|
|
return MIN2(radv_get_adjusted_vram_size(device) , device->rad_info.vram_vis_size);
|
2019-01-07 17:38:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint64_t
|
|
|
|
|
|
radv_get_vram_size(struct radv_physical_device *device)
|
|
|
|
|
|
{
|
2020-09-08 02:02:09 +02:00
|
|
|
|
return radv_get_adjusted_vram_size(device) - device->rad_info.vram_vis_size;
|
2019-01-07 17:38:08 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-23 02:14:30 +02:00
|
|
|
|
enum radv_heap {
|
|
|
|
|
|
RADV_HEAP_VRAM = 1 << 0,
|
|
|
|
|
|
RADV_HEAP_GTT = 1 << 1,
|
|
|
|
|
|
RADV_HEAP_VRAM_VIS = 1 << 2,
|
|
|
|
|
|
RADV_HEAP_MAX = 1 << 3,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_physical_device_init_mem_types(struct radv_physical_device *device)
|
|
|
|
|
|
{
|
2019-01-07 17:38:08 +01:00
|
|
|
|
uint64_t visible_vram_size = radv_get_visible_vram_size(device);
|
|
|
|
|
|
uint64_t vram_size = radv_get_vram_size(device);
|
2017-11-01 09:26:48 +01:00
|
|
|
|
int vram_index = -1, visible_vram_index = -1, gart_index = -1;
|
|
|
|
|
|
device->memory_properties.memoryHeapCount = 0;
|
2020-09-23 02:14:30 +02:00
|
|
|
|
device->heaps = 0;
|
2020-09-23 02:13:00 +02:00
|
|
|
|
|
|
|
|
|
|
/* Only get a VRAM heap if it is significant, not if it is a 16 MiB
|
|
|
|
|
|
* remainder above visible VRAM. */
|
|
|
|
|
|
if (vram_size > 0 && vram_size * 9 >= visible_vram_size) {
|
2017-11-01 09:26:48 +01:00
|
|
|
|
vram_index = device->memory_properties.memoryHeapCount++;
|
2020-09-23 02:14:30 +02:00
|
|
|
|
device->heaps |= RADV_HEAP_VRAM;
|
2017-11-01 09:26:48 +01:00
|
|
|
|
device->memory_properties.memoryHeaps[vram_index] = (VkMemoryHeap) {
|
2019-01-07 17:38:08 +01:00
|
|
|
|
.size = vram_size,
|
2017-11-01 09:26:48 +01:00
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2020-04-22 16:54:28 +02:00
|
|
|
|
|
|
|
|
|
|
if (device->rad_info.gart_size > 0) {
|
|
|
|
|
|
gart_index = device->memory_properties.memoryHeapCount++;
|
2020-09-23 02:14:30 +02:00
|
|
|
|
device->heaps |= RADV_HEAP_GTT;
|
2020-04-22 16:54:28 +02:00
|
|
|
|
device->memory_properties.memoryHeaps[gart_index] = (VkMemoryHeap) {
|
|
|
|
|
|
.size = device->rad_info.gart_size,
|
|
|
|
|
|
.flags = 0,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
if (visible_vram_size) {
|
|
|
|
|
|
visible_vram_index = device->memory_properties.memoryHeapCount++;
|
2020-09-23 02:14:30 +02:00
|
|
|
|
device->heaps |= RADV_HEAP_VRAM_VIS;
|
2017-11-01 09:26:48 +01:00
|
|
|
|
device->memory_properties.memoryHeaps[visible_vram_index] = (VkMemoryHeap) {
|
|
|
|
|
|
.size = visible_vram_size,
|
|
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned type_count = 0;
|
2020-04-22 16:54:28 +02:00
|
|
|
|
|
2020-06-02 22:14:44 -07:00
|
|
|
|
if (vram_index >= 0 || visible_vram_index >= 0) {
|
|
|
|
|
|
device->memory_domains[type_count] = RADEON_DOMAIN_VRAM;
|
|
|
|
|
|
device->memory_flags[type_count] = RADEON_FLAG_NO_CPU_ACCESS;
|
|
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
|
|
|
|
|
.heapIndex = vram_index >= 0 ? vram_index : visible_vram_index,
|
|
|
|
|
|
};
|
2017-11-01 09:26:48 +01:00
|
|
|
|
}
|
2020-04-22 16:54:28 +02:00
|
|
|
|
|
|
|
|
|
|
if (gart_index >= 0) {
|
2020-04-25 23:52:44 +02:00
|
|
|
|
device->memory_domains[type_count] = RADEON_DOMAIN_GTT;
|
|
|
|
|
|
device->memory_flags[type_count] = RADEON_FLAG_GTT_WC | RADEON_FLAG_CPU_ACCESS;
|
2017-11-01 09:26:48 +01:00
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
2019-06-02 11:32:06 +01:00
|
|
|
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
2017-11-01 09:26:48 +01:00
|
|
|
|
.heapIndex = gart_index,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
if (visible_vram_index >= 0) {
|
2020-04-25 23:52:44 +02:00
|
|
|
|
device->memory_domains[type_count] = RADEON_DOMAIN_VRAM;
|
|
|
|
|
|
device->memory_flags[type_count] = RADEON_FLAG_CPU_ACCESS;
|
2017-11-01 09:26:48 +01:00
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
|
|
|
|
|
|
.heapIndex = visible_vram_index,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2020-04-22 16:54:28 +02:00
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
if (gart_index >= 0) {
|
2020-04-25 23:52:44 +02:00
|
|
|
|
device->memory_domains[type_count] = RADEON_DOMAIN_GTT;
|
|
|
|
|
|
device->memory_flags[type_count] = RADEON_FLAG_CPU_ACCESS;
|
2017-11-01 09:26:48 +01:00
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
2020-04-22 16:54:28 +02:00
|
|
|
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
|
2017-11-01 09:26:48 +01:00
|
|
|
|
.heapIndex = gart_index,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
device->memory_properties.memoryTypeCount = type_count;
|
2019-11-13 08:58:37 +01:00
|
|
|
|
|
|
|
|
|
|
if (device->rad_info.has_l2_uncached) {
|
|
|
|
|
|
for (int i = 0; i < device->memory_properties.memoryTypeCount; i++) {
|
|
|
|
|
|
VkMemoryType mem_type = device->memory_properties.memoryTypes[i];
|
|
|
|
|
|
|
|
|
|
|
|
if ((mem_type.propertyFlags & (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) ||
|
|
|
|
|
|
mem_type.propertyFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
|
|
|
|
|
|
|
|
|
|
|
|
VkMemoryPropertyFlags property_flags = mem_type.propertyFlags |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
|
|
|
|
|
|
VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD;
|
|
|
|
|
|
|
2020-04-25 23:52:44 +02:00
|
|
|
|
device->memory_domains[type_count] = device->memory_domains[i];
|
|
|
|
|
|
device->memory_flags[type_count] = device->memory_flags[i] | RADEON_FLAG_VA_UNCACHED;
|
2019-11-13 08:58:37 +01:00
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
|
.propertyFlags = property_flags,
|
|
|
|
|
|
.heapIndex = mem_type.heapIndex,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
device->memory_properties.memoryTypeCount = type_count;
|
|
|
|
|
|
}
|
2017-11-01 09:26:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-11 09:54:11 +02:00
|
|
|
|
static const char *
|
|
|
|
|
|
radv_get_compiler_string(struct radv_physical_device *pdevice)
|
|
|
|
|
|
{
|
2020-06-11 10:43:02 +01:00
|
|
|
|
if (!pdevice->use_llvm) {
|
2020-05-11 09:54:11 +02:00
|
|
|
|
/* Some games like SotTR apply shader workarounds if the LLVM
|
|
|
|
|
|
* version is too old or if the LLVM version string is
|
|
|
|
|
|
* missing. This gives 2-5% performance with SotTR and ACO.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (driQueryOptionb(&pdevice->instance->dri_options,
|
|
|
|
|
|
"radv_report_llvm9_version_string")) {
|
|
|
|
|
|
return "ACO/LLVM 9.0.1";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return "ACO";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return "LLVM " MESA_LLVM_VERSION_STRING;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
static VkResult
|
2020-04-29 13:53:35 +02:00
|
|
|
|
radv_physical_device_try_create(struct radv_instance *instance,
|
|
|
|
|
|
drmDevicePtr drm_device,
|
|
|
|
|
|
struct radv_physical_device **device_out)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
VkResult result;
|
2020-02-17 14:45:47 +01:00
|
|
|
|
int fd = -1;
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 10:31:44 -08:00
|
|
|
|
int master_fd = -1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
assert(drm_device == NULL);
|
|
|
|
|
|
#else
|
2020-02-17 14:45:47 +01:00
|
|
|
|
if (drm_device) {
|
|
|
|
|
|
const char *path = drm_device->nodes[DRM_NODE_RENDER];
|
|
|
|
|
|
drmVersionPtr version;
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
fd = open(path, O_RDWR | O_CLOEXEC);
|
|
|
|
|
|
if (fd < 0) {
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
|
radv_logi("Could not open device '%s'", path);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
|
|
|
|
|
|
}
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
version = drmGetVersion(fd);
|
|
|
|
|
|
if (!version) {
|
|
|
|
|
|
close(fd);
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
|
radv_logi("Could not get the kernel driver version for device '%s'", path);
|
2016-10-11 15:21:25 +10:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
|
|
|
|
|
|
"failed to get version %s: %m", path);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (strcmp(version->name, "amdgpu")) {
|
|
|
|
|
|
drmFreeVersion(version);
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
|
radv_logi("Device '%s' is not using the amdgpu kernel driver.", path);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_ERROR_INCOMPATIBLE_DRIVER;
|
|
|
|
|
|
}
|
2016-10-11 15:21:25 +10:00
|
|
|
|
drmFreeVersion(version);
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
2020-02-17 14:45:47 +01:00
|
|
|
|
radv_logi("Found compatible device '%s'.", path);
|
2016-10-11 15:21:25 +10:00
|
|
|
|
}
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
struct radv_physical_device *device =
|
|
|
|
|
|
vk_zalloc2(&instance->alloc, NULL, sizeof(*device), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
|
|
|
|
|
if (!device) {
|
|
|
|
|
|
result = vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
goto fail_fd;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
|
|
|
|
|
|
device->instance = instance;
|
|
|
|
|
|
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
device->ws = radv_null_winsys_create();
|
|
|
|
|
|
#else
|
2020-02-17 14:45:47 +01:00
|
|
|
|
if (drm_device) {
|
|
|
|
|
|
device->ws = radv_amdgpu_winsys_create(fd, instance->debug_flags,
|
|
|
|
|
|
instance->perftest_flags);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
device->ws = radv_null_winsys_create();
|
|
|
|
|
|
}
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2020-02-17 14:45:47 +01:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!device->ws) {
|
2020-04-29 14:09:10 +02:00
|
|
|
|
result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
|
|
|
|
|
|
"failed to initialize winsys");
|
2020-04-29 13:53:35 +02:00
|
|
|
|
goto fail_alloc;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
2017-02-19 15:27:47 +10:00
|
|
|
|
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifndef _WIN32
|
2020-02-26 10:21:24 +01:00
|
|
|
|
if (drm_device && instance->enabled_extensions.KHR_display) {
|
2018-02-07 10:31:44 -08:00
|
|
|
|
master_fd = open(drm_device->nodes[DRM_NODE_PRIMARY], O_RDWR | O_CLOEXEC);
|
|
|
|
|
|
if (master_fd >= 0) {
|
|
|
|
|
|
uint32_t accel_working = 0;
|
|
|
|
|
|
struct drm_amdgpu_info request = {
|
|
|
|
|
|
.return_pointer = (uintptr_t)&accel_working,
|
|
|
|
|
|
.return_size = sizeof(accel_working),
|
|
|
|
|
|
.query = AMDGPU_INFO_ACCEL_WORKING
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
if (drmCommandWrite(master_fd, DRM_AMDGPU_INFO, &request, sizeof (struct drm_amdgpu_info)) < 0 || !accel_working) {
|
|
|
|
|
|
close(master_fd);
|
|
|
|
|
|
master_fd = -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2018-02-07 10:31:44 -08:00
|
|
|
|
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 10:31:44 -08:00
|
|
|
|
device->master_fd = master_fd;
|
2017-02-19 15:27:47 +10:00
|
|
|
|
device->local_fd = fd;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
device->ws->query_info(device->ws, &device->rad_info);
|
|
|
|
|
|
|
2019-09-19 13:43:35 +02:00
|
|
|
|
device->use_llvm = instance->debug_flags & RADV_DEBUG_LLVM;
|
2019-09-17 14:35:22 +02:00
|
|
|
|
|
2019-10-09 18:15:42 +02:00
|
|
|
|
snprintf(device->name, sizeof(device->name),
|
2020-05-06 09:32:27 +02:00
|
|
|
|
"AMD RADV %s (%s)",
|
2020-05-11 09:54:11 +02:00
|
|
|
|
device->rad_info.name, radv_get_compiler_string(device));
|
2017-10-25 02:23:08 +01:00
|
|
|
|
|
2020-11-26 19:16:51 -08:00
|
|
|
|
#ifdef ENABLE_SHADER_CACHE
|
2017-07-12 18:45:29 -04:00
|
|
|
|
if (radv_device_get_cache_uuid(device->rad_info.family, device->cache_uuid)) {
|
2018-05-31 01:06:41 +02:00
|
|
|
|
result = vk_errorf(instance, VK_ERROR_INITIALIZATION_FAILED,
|
2016-11-24 20:30:45 +00:00
|
|
|
|
"cannot generate UUID");
|
2020-04-29 14:03:24 +02:00
|
|
|
|
goto fail_wsi;
|
2016-11-22 00:19:30 +01:00
|
|
|
|
}
|
2016-11-22 00:31:44 +01:00
|
|
|
|
|
2017-10-11 12:00:27 +11:00
|
|
|
|
/* These flags affect shader compilation. */
|
2020-06-11 10:43:02 +01:00
|
|
|
|
uint64_t shader_env_flags = (device->use_llvm ? 0 : 0x2);
|
2017-10-11 12:00:27 +11:00
|
|
|
|
|
2018-05-10 00:26:21 +03:00
|
|
|
|
/* The gpu id is already embedded in the uuid so we just pass "radv"
|
2017-10-11 12:00:27 +11:00
|
|
|
|
* when creating the cache.
|
|
|
|
|
|
*/
|
2017-10-25 03:43:00 +02:00
|
|
|
|
char buf[VK_UUID_SIZE * 2 + 1];
|
|
|
|
|
|
disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
|
2017-10-25 02:23:08 +01:00
|
|
|
|
device->disk_cache = disk_cache_create(device->name, buf, shader_env_flags);
|
2020-11-26 19:16:51 -08:00
|
|
|
|
#endif
|
2017-10-11 12:00:27 +11:00
|
|
|
|
|
2020-12-04 09:29:43 +01:00
|
|
|
|
if (device->rad_info.chip_class < GFX8 ||
|
|
|
|
|
|
device->rad_info.chip_class > GFX10)
|
2018-03-07 16:38:32 +01:00
|
|
|
|
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
|
2017-02-19 15:27:47 +10:00
|
|
|
|
|
2019-03-12 16:07:10 +01:00
|
|
|
|
radv_get_driver_uuid(&device->driver_uuid);
|
2017-07-12 18:45:30 -04:00
|
|
|
|
radv_get_device_uuid(&device->rad_info, &device->device_uuid);
|
2017-05-23 09:22:09 +02:00
|
|
|
|
|
2019-08-20 17:16:41 +02:00
|
|
|
|
device->out_of_order_rast_allowed = device->rad_info.has_out_of_order_rast &&
|
2018-04-24 17:06:19 +02:00
|
|
|
|
!(device->instance->debug_flags & RADV_DEBUG_NO_OUT_OF_ORDER);
|
2018-03-28 19:03:00 +02:00
|
|
|
|
|
2018-06-14 11:06:02 +02:00
|
|
|
|
device->dcc_msaa_allowed =
|
|
|
|
|
|
(device->instance->perftest_flags & RADV_PERFTEST_DCC_MSAA);
|
2018-04-17 16:05:18 +02:00
|
|
|
|
|
2019-09-18 09:01:38 +02:00
|
|
|
|
device->use_ngg = device->rad_info.chip_class >= GFX10 &&
|
|
|
|
|
|
device->rad_info.family != CHIP_NAVI14 &&
|
|
|
|
|
|
!(device->instance->debug_flags & RADV_DEBUG_NO_NGG);
|
|
|
|
|
|
|
2019-09-09 10:23:30 +02:00
|
|
|
|
device->use_ngg_streamout = false;
|
|
|
|
|
|
|
2019-07-30 18:32:42 +02:00
|
|
|
|
/* Determine the number of threads per wave for all stages. */
|
|
|
|
|
|
device->cs_wave_size = 64;
|
2019-08-01 10:43:41 +02:00
|
|
|
|
device->ps_wave_size = 64;
|
2019-08-01 10:43:42 +02:00
|
|
|
|
device->ge_wave_size = 64;
|
2019-07-30 18:32:42 +02:00
|
|
|
|
|
|
|
|
|
|
if (device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
if (device->instance->perftest_flags & RADV_PERFTEST_CS_WAVE_32)
|
|
|
|
|
|
device->cs_wave_size = 32;
|
2019-08-01 10:43:41 +02:00
|
|
|
|
|
|
|
|
|
|
/* For pixel shaders, wave64 is recommanded. */
|
|
|
|
|
|
if (device->instance->perftest_flags & RADV_PERFTEST_PS_WAVE_32)
|
|
|
|
|
|
device->ps_wave_size = 32;
|
2019-08-01 10:43:42 +02:00
|
|
|
|
|
|
|
|
|
|
if (device->instance->perftest_flags & RADV_PERFTEST_GE_WAVE_32)
|
|
|
|
|
|
device->ge_wave_size = 32;
|
2019-07-30 18:32:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
radv_physical_device_init_mem_types(device);
|
2020-05-11 11:33:00 +02:00
|
|
|
|
|
|
|
|
|
|
radv_physical_device_get_supported_extensions(device,
|
|
|
|
|
|
&device->supported_extensions);
|
2017-11-18 15:30:34 -08:00
|
|
|
|
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifndef _WIN32
|
2020-02-17 14:45:47 +01:00
|
|
|
|
if (drm_device)
|
|
|
|
|
|
device->bus_info = *drm_device->businfo.pci;
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2018-10-19 11:51:47 +02:00
|
|
|
|
|
|
|
|
|
|
if ((device->instance->debug_flags & RADV_DEBUG_INFO))
|
2020-10-19 16:11:25 +02:00
|
|
|
|
ac_print_gpu_info(&device->rad_info, stdout);
|
2018-10-19 11:51:47 +02:00
|
|
|
|
|
|
|
|
|
|
/* The WSI is structured as a layer on top of the driver, so this has
|
|
|
|
|
|
* to be the last part of initialization (at least until we get other
|
|
|
|
|
|
* semi-layers).
|
|
|
|
|
|
*/
|
2017-11-18 15:30:34 -08:00
|
|
|
|
result = radv_init_wsi(device);
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2018-05-31 01:49:38 +02:00
|
|
|
|
vk_error(instance, result);
|
2020-04-29 14:03:24 +02:00
|
|
|
|
goto fail_disk_cache;
|
2017-11-18 15:30:34 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
*device_out = device;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
2020-04-29 14:03:24 +02:00
|
|
|
|
fail_disk_cache:
|
|
|
|
|
|
disk_cache_destroy(device->disk_cache);
|
|
|
|
|
|
fail_wsi:
|
|
|
|
|
|
device->ws->destroy(device->ws);
|
2020-04-29 13:53:35 +02:00
|
|
|
|
fail_alloc:
|
|
|
|
|
|
vk_free(&instance->alloc, device);
|
2020-04-29 14:03:24 +02:00
|
|
|
|
fail_fd:
|
2020-05-23 02:36:03 +02:00
|
|
|
|
if (fd != -1)
|
|
|
|
|
|
close(fd);
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 10:31:44 -08:00
|
|
|
|
if (master_fd != -1)
|
|
|
|
|
|
close(master_fd);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2020-04-29 13:53:35 +02:00
|
|
|
|
radv_physical_device_destroy(struct radv_physical_device *device)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
radv_finish_wsi(device);
|
|
|
|
|
|
device->ws->destroy(device->ws);
|
2017-10-11 12:00:27 +11:00
|
|
|
|
disk_cache_destroy(device->disk_cache);
|
2020-08-29 11:35:29 -07:00
|
|
|
|
if (device->local_fd != -1)
|
|
|
|
|
|
close(device->local_fd);
|
vulkan: Add KHR_display extension using DRM [v10]
This adds support for the KHR_display extension support to the vulkan
WSI layer. Driver support will be added separately.
v2:
* fix double ;; in wsi_common_display.c
* Move mode list from wsi_display to wsi_display_connector
* Fix scope for wsi_display_mode andwsi_display_connector
allocs
* Switch all allocations to vk_zalloc instead of vk_alloc.
* Fix DRM failure in
wsi_display_get_physical_device_display_properties
When DRM fails, or when we don't have a master fd
(presumably due to application errors), just return 0
properties from this function, which is at least a valid
response.
* Use vk_outarray for all property queries
This is a bit less error-prone than open-coding the same
stuff.
* Remove VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR from surface caps
Until we have multi-plane support, we shouldn't pretend to
have any multi-plane semantics, even if undefined.
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
* Simplify addition of VK_USE_PLATFORM_DISPLAY_KHR to
vulkan_wsi_args
Suggested-by: Eric Engestrom <eric.engestrom@imgtec.com>
v3:
Add separate 'display_fd' and 'render_fd' arguments to
wsi_device_init API. This allows drivers to use different FDs
for the different aspects of the device.
Use largest mode as display size when no preferred mode.
If the display doesn't provide a preferred mode, we'll assume
that the largest supported mode is the "physical size" of the
device and report that.
v4:
Make wsi_image_state enumeration values uppercase.
Follow more common mesa conventions.
Remove 'render_fd' from wsi_device_init API. The
wsi_common_display code doesn't use this fd at all, so stop
passing it in. This avoids any potential confusion over which
fd to use when creating display-relative object handles.
Remove call to wsi_create_prime_image which would never have
been reached as the necessary condition (use_prime_blit) is
never set.
whitespace cleanups in wsi_common_display.c
Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
Add depth/bpp info to available surface formats. Instead of
hard-coding depth 24 bpp 32 in the drmModeAddFB call, use the
requested format to find suitable values.
Destroy kernel buffers and FBs when swapchain is destroyed. We
were leaking both of these kernel objects across swapchain
destruction.
Note that wsi_display_wait_for_event waits for anything to
happen. wsi_display_wait_for_event is simply a yield so that
the caller can then check to see if the desired state change
has occurred.
Record swapchain failures in chain for later return. If some
asynchronous swapchain activity fails, we need to tell the
application eventually. Record the failure in the swapchain
and report it at the next acquire_next_image or queue_present
call.
Fix error returns from wsi_display_setup_connector. If a
malloc failed, then the result should be
VK_ERROR_OUT_OF_HOST_MEMORY. Otherwise, the associated ioctl
failed and we're either VT switched away, or our lease has
been revoked, in which case we should return
VK_ERROR_OUT_OF_DATE_KHR.
Make sure both sides of if/else brace use matches
Note that we assume drmModeSetCrtc is synchronous. Add a
comment explaining why we can idle any previous displayed
image as soon as the mode set returns.
Note that EACCES from drmModePageFlip means VT inactive. When
vt switched away drmModePageFlip returns EACCES. Poll once a
second waiting until we get some other return value back.
Clean up after alloc failure in
wsi_display_surface_create_swapchain. Destroy any created
images, free the swapchain.
Remove physical_device from wsi_display_init_wsi. We never
need this value, so remove it from the API and from the
internal wsi_display structure.
Use drmModeAddFB2 in wsi_display_image_init. This takes a drm
format instead of depth/bpp, which provides more control over
the format of the data.
v5:
Set the 'currentStackIndex' member of the
VkDisplayPlanePropertiesKHR record to zero, instead of
indexing across all displays. This value is the stack depth of
the plane within an individual display, and as the current
code supports only a single plane per display, should be set
to zero for all elements
Discovered-by: David Mao <David.Mao@amd.com>
v6:
Remove 'platform_display' bits from the build and use the
existing 'platform_drm' instead.
v7:
Ensure VK_ICD_WSI_PLATFORM_MAX is large enough by
setting to VK_ICD_WSI_PLATFORM_DISPLAY + 1
v8:
Simplify wsi_device_init failure from wsi_display_init_wsi
by using the same pattern as the other wsi layers.
Adopt Jason Ekstrand's white space and variable declaration
suggestions. Declare variables at first use, eliminate extra
whitespace between types and names, add list iterator helpers,
switch to lower-case list_ macros.
Respond to Jason's April 8 review:
* Create a function to convert relative to absolute timeouts
to catch overflow issues in one place
* use VK_NULL_HANDLE to clear prop->currentDisplay
* Get rid of available_present_modes array.
* return OUT_OF_DATE_KHR when display_queue_next called after
display has been released.
* Make errors from mode setting fatal in display_queue_next
* Remove duplicate pthread_mutex_init call
* Add wsi_init_pthread_cond_monotonic helper function to
isolate pthread error handling from wsi_display_init_wsi
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v9:
Fix vscan handling by using MAX2(vscan, 1) everywhere. Vscan
can be zero anywhere, which is treated the same as 1.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
v10:
Respond to Vulkan CTS failures.
1. Initialize planeReorderPossible in display_properties code
2. Only report connected displays in
get_display_plane_supported_displays
3. Return VK_ERROR_OUT_OF_HOST_MEMORY when pthread cond
initialization fails.
Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
4. Add vkCreateDisplayModeKHR. This doesn't actually create
new modes, it only looks to see if the requested parameters
matches an existing mode and returns that.
Suggested-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
2018-02-07 10:31:44 -08:00
|
|
|
|
if (device->master_fd != -1)
|
|
|
|
|
|
close(device->master_fd);
|
2020-04-29 13:53:35 +02:00
|
|
|
|
vk_free(&device->instance->alloc, device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
default_alloc_func(void *pUserData, size_t size, size_t align,
|
|
|
|
|
|
VkSystemAllocationScope allocationScope)
|
|
|
|
|
|
{
|
|
|
|
|
|
return malloc(size);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void *
|
|
|
|
|
|
default_realloc_func(void *pUserData, void *pOriginal, size_t size,
|
|
|
|
|
|
size_t align, VkSystemAllocationScope allocationScope)
|
|
|
|
|
|
{
|
|
|
|
|
|
return realloc(pOriginal, size);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
default_free_func(void *pUserData, void *pMemory)
|
|
|
|
|
|
{
|
|
|
|
|
|
free(pMemory);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const VkAllocationCallbacks default_alloc = {
|
|
|
|
|
|
.pUserData = NULL,
|
|
|
|
|
|
.pfnAllocation = default_alloc_func,
|
|
|
|
|
|
.pfnReallocation = default_realloc_func,
|
|
|
|
|
|
.pfnFree = default_free_func,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-01-02 18:57:02 +01:00
|
|
|
|
static const struct debug_control radv_debug_options[] = {
|
2017-02-07 00:36:41 +01:00
|
|
|
|
{"nofastclears", RADV_DEBUG_NO_FAST_CLEARS},
|
2017-01-02 18:57:02 +01:00
|
|
|
|
{"nodcc", RADV_DEBUG_NO_DCC},
|
|
|
|
|
|
{"shaders", RADV_DEBUG_DUMP_SHADERS},
|
|
|
|
|
|
{"nocache", RADV_DEBUG_NO_CACHE},
|
|
|
|
|
|
{"shaderstats", RADV_DEBUG_DUMP_SHADER_STATS},
|
|
|
|
|
|
{"nohiz", RADV_DEBUG_NO_HIZ},
|
|
|
|
|
|
{"nocompute", RADV_DEBUG_NO_COMPUTE_QUEUE},
|
2017-03-05 20:58:31 +01:00
|
|
|
|
{"allbos", RADV_DEBUG_ALL_BOS},
|
|
|
|
|
|
{"noibs", RADV_DEBUG_NO_IBS},
|
2017-08-30 15:12:21 +02:00
|
|
|
|
{"spirv", RADV_DEBUG_DUMP_SPIRV},
|
2017-09-07 22:12:50 +02:00
|
|
|
|
{"vmfaults", RADV_DEBUG_VM_FAULTS},
|
2017-02-15 01:17:02 +00:00
|
|
|
|
{"zerovram", RADV_DEBUG_ZERO_VRAM},
|
2017-09-11 15:00:41 +02:00
|
|
|
|
{"syncshaders", RADV_DEBUG_SYNC_SHADERS},
|
2018-01-19 12:12:02 +01:00
|
|
|
|
{"preoptir", RADV_DEBUG_PREOPTIR},
|
2018-04-19 07:29:03 +02:00
|
|
|
|
{"nodynamicbounds", RADV_DEBUG_NO_DYNAMIC_BOUNDS},
|
2018-04-24 17:06:19 +02:00
|
|
|
|
{"nooutoforder", RADV_DEBUG_NO_OUT_OF_ORDER},
|
2018-05-16 15:52:37 +02:00
|
|
|
|
{"info", RADV_DEBUG_INFO},
|
2018-05-31 01:06:41 +02:00
|
|
|
|
{"errors", RADV_DEBUG_ERRORS},
|
2018-05-31 01:49:38 +02:00
|
|
|
|
{"startup", RADV_DEBUG_STARTUP},
|
2018-06-14 14:28:58 +02:00
|
|
|
|
{"checkir", RADV_DEBUG_CHECKIR},
|
2018-06-27 11:34:25 +10:00
|
|
|
|
{"nothreadllvm", RADV_DEBUG_NOTHREADLLVM},
|
2018-11-14 17:23:12 +01:00
|
|
|
|
{"nobinning", RADV_DEBUG_NOBINNING},
|
2019-07-17 14:19:10 +02:00
|
|
|
|
{"nongg", RADV_DEBUG_NO_NGG},
|
2019-09-18 14:39:10 +02:00
|
|
|
|
{"metashaders", RADV_DEBUG_DUMP_META_SHADERS},
|
2019-10-28 15:12:03 +01:00
|
|
|
|
{"nomemorycache", RADV_DEBUG_NO_MEMORY_CACHE},
|
2020-10-19 18:42:22 +02:00
|
|
|
|
{"discardtodemote", RADV_DEBUG_DISCARD_TO_DEMOTE},
|
2020-06-12 17:55:00 +01:00
|
|
|
|
{"llvm", RADV_DEBUG_LLVM},
|
2020-08-10 00:10:38 +02:00
|
|
|
|
{"forcecompress", RADV_DEBUG_FORCE_COMPRESS},
|
2020-10-19 18:37:26 +02:00
|
|
|
|
{"hang", RADV_DEBUG_HANG},
|
2020-07-03 15:16:00 +02:00
|
|
|
|
{"img", RADV_DEBUG_IMG},
|
2020-11-20 09:56:59 +01:00
|
|
|
|
{"noumr", RADV_DEBUG_NO_UMR},
|
2020-12-14 21:54:28 +00:00
|
|
|
|
{"invariantgeom", RADV_DEBUG_INVARIANT_GEOM},
|
2017-01-02 18:57:02 +01:00
|
|
|
|
{NULL, 0}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-09-11 22:28:42 +02:00
|
|
|
|
const char *
|
|
|
|
|
|
radv_get_debug_option_name(int id)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(id < ARRAY_SIZE(radv_debug_options) - 1);
|
|
|
|
|
|
return radv_debug_options[id].string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-09 04:17:30 +01:00
|
|
|
|
static const struct debug_control radv_perftest_options[] = {
|
2017-12-28 09:49:32 +10:00
|
|
|
|
{"localbos", RADV_PERFTEST_LOCAL_BOS},
|
2018-04-17 16:05:18 +02:00
|
|
|
|
{"dccmsaa", RADV_PERFTEST_DCC_MSAA},
|
2019-04-10 00:37:54 +02:00
|
|
|
|
{"bolist", RADV_PERFTEST_BO_LIST},
|
2018-11-14 16:24:02 +01:00
|
|
|
|
{"tccompatcmask", RADV_PERFTEST_TC_COMPAT_CMASK},
|
2019-07-30 18:32:42 +02:00
|
|
|
|
{"cswave32", RADV_PERFTEST_CS_WAVE_32},
|
2019-08-01 10:43:41 +02:00
|
|
|
|
{"pswave32", RADV_PERFTEST_PS_WAVE_32},
|
2019-08-01 10:43:42 +02:00
|
|
|
|
{"gewave32", RADV_PERFTEST_GE_WAVE_32},
|
2019-09-15 15:57:52 +02:00
|
|
|
|
{"dfsm", RADV_PERFTEST_DFSM},
|
2020-12-08 00:25:56 +01:00
|
|
|
|
{"nosam", RADV_PERFTEST_NO_SAM},
|
2017-05-09 04:17:30 +01:00
|
|
|
|
{NULL, 0}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2017-09-11 22:28:42 +02:00
|
|
|
|
const char *
|
|
|
|
|
|
radv_get_perftest_option_name(int id)
|
|
|
|
|
|
{
|
2018-10-18 15:32:31 -04:00
|
|
|
|
assert(id < ARRAY_SIZE(radv_perftest_options) - 1);
|
2017-09-11 22:28:42 +02:00
|
|
|
|
return radv_perftest_options[id].string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-07 10:02:32 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_handle_per_app_options(struct radv_instance *instance,
|
|
|
|
|
|
const VkApplicationInfo *info)
|
|
|
|
|
|
{
|
|
|
|
|
|
const char *name = info ? info->pApplicationName : NULL;
|
2020-05-29 20:26:00 +02:00
|
|
|
|
const char *engine_name = info ? info->pEngineName : NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (name) {
|
|
|
|
|
|
if (!strcmp(name, "DOOM_VFR")) {
|
|
|
|
|
|
/* Work around a Doom VFR game bug */
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_NO_DYNAMIC_BOUNDS;
|
|
|
|
|
|
} else if (!strcmp(name, "Fledge")) {
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Zero VRAM for "The Surge 2"
|
|
|
|
|
|
*
|
|
|
|
|
|
* This avoid a hang when when rendering any level. Likely
|
|
|
|
|
|
* uninitialized data in an indirect draw.
|
|
|
|
|
|
*/
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM;
|
|
|
|
|
|
} else if (!strcmp(name, "No Man's Sky")) {
|
|
|
|
|
|
/* Work around a NMS game bug */
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_DISCARD_TO_DEMOTE;
|
|
|
|
|
|
} else if (!strcmp(name, "DOOMEternal")) {
|
|
|
|
|
|
/* Zero VRAM for Doom Eternal to fix rendering issues. */
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM;
|
2020-12-14 22:00:23 +00:00
|
|
|
|
} else if (!strcmp(name, "ShadowOfTheTomb")) {
|
|
|
|
|
|
/* Work around flickering foliage for native Shadow of the Tomb Raider
|
|
|
|
|
|
* on GFX10.3 */
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_INVARIANT_GEOM;
|
2020-05-29 20:26:00 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-11-07 10:02:32 +01:00
|
|
|
|
|
2020-05-29 20:26:00 +02:00
|
|
|
|
if (engine_name) {
|
|
|
|
|
|
if (!strcmp(engine_name, "vkd3d")) {
|
|
|
|
|
|
/* Zero VRAM for all VKD3D (DX12->VK) games to fix
|
|
|
|
|
|
* rendering issues.
|
2019-08-20 16:50:57 +02:00
|
|
|
|
*/
|
2020-05-29 20:26:00 +02:00
|
|
|
|
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM;
|
2020-07-01 16:00:55 +01:00
|
|
|
|
} else if (!strcmp(engine_name, "Quantic Dream Engine")) {
|
|
|
|
|
|
/* Fix various artifacts in Detroit: Become Human */
|
2020-07-20 16:54:22 +01:00
|
|
|
|
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM |
|
|
|
|
|
|
RADV_DEBUG_DISCARD_TO_DEMOTE;
|
2021-01-07 08:38:01 +01:00
|
|
|
|
|
|
|
|
|
|
/* Fix rendering issues in Detroit: Become Human
|
|
|
|
|
|
* because the game uses render loops (it
|
|
|
|
|
|
* samples/renders from/to the same depth/stencil
|
|
|
|
|
|
* texture inside the same draw) without input
|
|
|
|
|
|
* attachments and that is invalid Vulkan usage.
|
|
|
|
|
|
*/
|
|
|
|
|
|
instance->disable_tc_compat_htile_in_general = true;
|
2019-08-20 16:50:57 +02:00
|
|
|
|
}
|
2017-11-07 10:02:32 +01:00
|
|
|
|
}
|
2020-06-05 14:24:33 +02:00
|
|
|
|
|
|
|
|
|
|
instance->enable_mrt_output_nan_fixup =
|
|
|
|
|
|
driQueryOptionb(&instance->dri_options,
|
|
|
|
|
|
"radv_enable_mrt_output_nan_fixup");
|
2020-06-19 23:59:49 +01:00
|
|
|
|
|
|
|
|
|
|
if (driQueryOptionb(&instance->dri_options, "radv_no_dynamic_bounds"))
|
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_NO_DYNAMIC_BOUNDS;
|
2017-11-07 10:02:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-25 12:56:22 -07:00
|
|
|
|
static const driOptionDescription radv_dri_options[] = {
|
2019-08-30 17:03:12 +01:00
|
|
|
|
DRI_CONF_SECTION_PERFORMANCE
|
2020-09-29 09:28:18 -07:00
|
|
|
|
DRI_CONF_ADAPTIVE_SYNC(true)
|
2019-08-29 23:52:52 +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)
|
|
|
|
|
|
DRI_CONF_VK_X11_ENSURE_MIN_IMAGE_COUNT(false)
|
|
|
|
|
|
DRI_CONF_RADV_REPORT_LLVM9_VERSION_STRING(false)
|
|
|
|
|
|
DRI_CONF_RADV_ENABLE_MRT_OUTPUT_NAN_FIXUP(false)
|
|
|
|
|
|
DRI_CONF_RADV_NO_DYNAMIC_BOUNDS(false)
|
2020-07-30 02:49:33 +02:00
|
|
|
|
DRI_CONF_RADV_OVERRIDE_UNIFORM_OFFSET_ALIGNMENT(0)
|
2019-04-17 01:51:10 +02:00
|
|
|
|
DRI_CONF_SECTION_END
|
2020-01-10 13:16:25 -06:00
|
|
|
|
|
|
|
|
|
|
DRI_CONF_SECTION_DEBUG
|
2020-09-08 02:02:09 +02:00
|
|
|
|
DRI_CONF_OVERRIDE_VRAM_SIZE()
|
2020-09-29 09:28:18 -07:00
|
|
|
|
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
|
2020-01-10 13:16:25 -06:00
|
|
|
|
DRI_CONF_SECTION_END
|
2020-09-25 12:56:22 -07:00
|
|
|
|
};
|
2019-04-15 00:32:27 +02:00
|
|
|
|
|
|
|
|
|
|
static void radv_init_dri_options(struct radv_instance *instance)
|
|
|
|
|
|
{
|
2020-09-25 12:56:22 -07:00
|
|
|
|
driParseOptionInfo(&instance->available_dri_options, radv_dri_options, ARRAY_SIZE(radv_dri_options));
|
2019-04-15 00:32:27 +02:00
|
|
|
|
driParseConfigFiles(&instance->dri_options,
|
|
|
|
|
|
&instance->available_dri_options,
|
2019-09-08 12:59:32 +03:00
|
|
|
|
0, "radv", NULL,
|
2020-07-30 02:33:01 +02:00
|
|
|
|
instance->applicationName,
|
|
|
|
|
|
instance->applicationVersion,
|
2019-09-08 12:59:32 +03:00
|
|
|
|
instance->engineName,
|
|
|
|
|
|
instance->engineVersion);
|
2019-04-15 00:32:27 +02:00
|
|
|
|
}
|
2018-02-11 00:32:34 +01:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateInstance(
|
|
|
|
|
|
const VkInstanceCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkInstance* pInstance)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_instance *instance;
|
2018-01-09 03:35:53 +01:00
|
|
|
|
VkResult result;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-11-10 09:18:02 +01:00
|
|
|
|
instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!instance)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
if (pAllocator)
|
|
|
|
|
|
instance->alloc = *pAllocator;
|
|
|
|
|
|
else
|
|
|
|
|
|
instance->alloc = default_alloc;
|
|
|
|
|
|
|
2020-05-06 08:25:38 +02:00
|
|
|
|
if (pCreateInfo->pApplicationInfo) {
|
|
|
|
|
|
const VkApplicationInfo *app = pCreateInfo->pApplicationInfo;
|
|
|
|
|
|
|
2020-07-30 02:33:01 +02:00
|
|
|
|
instance->applicationName =
|
|
|
|
|
|
vk_strdup(&instance->alloc, app->pApplicationName,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
|
|
|
|
|
instance->applicationVersion = app->applicationVersion;
|
|
|
|
|
|
|
2020-05-06 08:25:38 +02:00
|
|
|
|
instance->engineName =
|
|
|
|
|
|
vk_strdup(&instance->alloc, app->pEngineName,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
|
|
|
|
|
|
instance->engineVersion = app->engineVersion;
|
|
|
|
|
|
instance->apiVersion = app->apiVersion;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (instance->apiVersion == 0)
|
|
|
|
|
|
instance->apiVersion = VK_API_VERSION_1_0;
|
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
|
instance->debug_flags = parse_debug_string(getenv("RADV_DEBUG"),
|
|
|
|
|
|
radv_debug_options);
|
|
|
|
|
|
|
2020-06-26 12:12:18 +02:00
|
|
|
|
const char *radv_perftest_str = getenv("RADV_PERFTEST");
|
|
|
|
|
|
instance->perftest_flags = parse_debug_string(radv_perftest_str,
|
|
|
|
|
|
radv_perftest_options);
|
|
|
|
|
|
|
|
|
|
|
|
if (radv_perftest_str) {
|
|
|
|
|
|
/* Output warnings for famous RADV_PERFTEST options that no
|
|
|
|
|
|
* longer exist or are deprecated.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (strstr(radv_perftest_str, "aco")) {
|
|
|
|
|
|
fprintf(stderr, "*******************************************************************************\n");
|
|
|
|
|
|
fprintf(stderr, "* WARNING: Unknown option RADV_PERFTEST='aco'. ACO is enabled by default now. *\n");
|
|
|
|
|
|
fprintf(stderr, "*******************************************************************************\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
if (strstr(radv_perftest_str, "llvm")) {
|
|
|
|
|
|
fprintf(stderr, "*********************************************************************************\n");
|
|
|
|
|
|
fprintf(stderr, "* WARNING: Unknown option 'RADV_PERFTEST=llvm'. Did you mean 'RADV_DEBUG=llvm'? *\n");
|
|
|
|
|
|
fprintf(stderr, "*********************************************************************************\n");
|
|
|
|
|
|
abort();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-05-31 01:06:41 +02:00
|
|
|
|
|
2018-05-31 01:49:38 +02:00
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
|
radv_logi("Created an instance");
|
|
|
|
|
|
|
2018-02-11 00:32:34 +01:00
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
|
2020-05-06 08:25:38 +02:00
|
|
|
|
int idx;
|
|
|
|
|
|
for (idx = 0; idx < RADV_INSTANCE_EXTENSION_COUNT; idx++) {
|
|
|
|
|
|
if (!strcmp(pCreateInfo->ppEnabledExtensionNames[i],
|
|
|
|
|
|
radv_instance_extensions[idx].extensionName))
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-02-11 00:32:34 +01:00
|
|
|
|
|
2020-05-06 08:25:38 +02:00
|
|
|
|
if (idx >= RADV_INSTANCE_EXTENSION_COUNT ||
|
2020-05-11 11:33:00 +02:00
|
|
|
|
!radv_instance_extensions_supported.extensions[idx]) {
|
2020-07-12 13:40:14 +02:00
|
|
|
|
vk_object_base_finish(&instance->base);
|
2018-02-11 00:32:34 +01:00
|
|
|
|
vk_free2(&default_alloc, pAllocator, instance);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(instance, VK_ERROR_EXTENSION_NOT_PRESENT);
|
2018-02-11 00:32:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-06 08:25:38 +02:00
|
|
|
|
instance->enabled_extensions.extensions[idx] = true;
|
2018-02-11 00:32:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(instance->dispatch.entrypoints); i++) {
|
|
|
|
|
|
/* Vulkan requires that entrypoints for extensions which have
|
|
|
|
|
|
* not been enabled must not be advertised.
|
|
|
|
|
|
*/
|
2021-01-25 11:32:22 +10:00
|
|
|
|
if (!radv_instance_entrypoint_is_enabled(i, instance->apiVersion,
|
2020-02-24 17:24:03 +01:00
|
|
|
|
&instance->enabled_extensions)) {
|
|
|
|
|
|
instance->dispatch.entrypoints[i] = NULL;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
instance->dispatch.entrypoints[i] =
|
|
|
|
|
|
radv_instance_dispatch_table.entrypoints[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(instance->physical_device_dispatch.entrypoints); i++) {
|
|
|
|
|
|
/* Vulkan requires that entrypoints for extensions which have
|
|
|
|
|
|
* not been enabled must not be advertised.
|
|
|
|
|
|
*/
|
2021-01-25 11:32:22 +10:00
|
|
|
|
if (!radv_physical_device_entrypoint_is_enabled(i, instance->apiVersion,
|
2020-02-24 17:24:03 +01:00
|
|
|
|
&instance->enabled_extensions)) {
|
|
|
|
|
|
instance->physical_device_dispatch.entrypoints[i] = NULL;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
instance->physical_device_dispatch.entrypoints[i] =
|
|
|
|
|
|
radv_physical_device_dispatch_table.entrypoints[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) {
|
|
|
|
|
|
/* Vulkan requires that entrypoints for extensions which have
|
|
|
|
|
|
* not been enabled must not be advertised.
|
|
|
|
|
|
*/
|
2021-01-25 11:32:22 +10:00
|
|
|
|
if (!radv_device_entrypoint_is_enabled(i, instance->apiVersion,
|
2020-02-24 17:24:03 +01:00
|
|
|
|
&instance->enabled_extensions, NULL)) {
|
|
|
|
|
|
instance->device_dispatch.entrypoints[i] = NULL;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
instance->device_dispatch.entrypoints[i] =
|
|
|
|
|
|
radv_device_dispatch_table.entrypoints[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
instance->physical_devices_enumerated = false;
|
|
|
|
|
|
list_inithead(&instance->physical_devices);
|
|
|
|
|
|
|
2018-01-09 03:35:53 +01:00
|
|
|
|
result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2020-07-12 13:40:14 +02:00
|
|
|
|
vk_object_base_finish(&instance->base);
|
2018-01-09 03:35:53 +01:00
|
|
|
|
vk_free2(&default_alloc, pAllocator, instance);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(instance, result);
|
2018-01-09 03:35:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-15 09:47:49 +02:00
|
|
|
|
glsl_type_singleton_init_or_ref();
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
|
|
|
|
|
|
|
2019-04-15 00:32:27 +02:00
|
|
|
|
radv_init_dri_options(instance);
|
2017-11-07 10:02:32 +01:00
|
|
|
|
radv_handle_per_app_options(instance, pCreateInfo->pApplicationInfo);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
*pInstance = radv_instance_to_handle(instance);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyInstance(
|
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
|
2017-03-06 15:40:16 +10:00
|
|
|
|
if (!instance)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
list_for_each_entry_safe(struct radv_physical_device, pdevice,
|
|
|
|
|
|
&instance->physical_devices, link) {
|
|
|
|
|
|
radv_physical_device_destroy(pdevice);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-08 12:57:16 +03:00
|
|
|
|
vk_free(&instance->alloc, instance->engineName);
|
2020-07-30 02:33:01 +02:00
|
|
|
|
vk_free(&instance->alloc, instance->applicationName);
|
2019-09-08 12:57:16 +03:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VG(VALGRIND_DESTROY_MEMPOOL(instance));
|
|
|
|
|
|
|
2019-03-15 09:47:49 +02:00
|
|
|
|
glsl_type_singleton_decref();
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-04-15 00:32:27 +02:00
|
|
|
|
driDestroyOptionCache(&instance->dri_options);
|
|
|
|
|
|
driDestroyOptionInfo(&instance->available_dri_options);
|
|
|
|
|
|
|
2018-01-09 03:35:53 +01:00
|
|
|
|
vk_debug_report_instance_destroy(&instance->debug_report_callbacks);
|
|
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_finish(&instance->base);
|
2016-10-14 13:36:45 +10:00
|
|
|
|
vk_free(&instance->alloc, instance);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-12-01 20:58:20 +00:00
|
|
|
|
static VkResult
|
2020-04-29 11:56:50 +02:00
|
|
|
|
radv_enumerate_physical_devices(struct radv_instance *instance)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
2020-04-29 13:53:35 +02:00
|
|
|
|
if (instance->physical_devices_enumerated)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
instance->physical_devices_enumerated = true;
|
|
|
|
|
|
|
2020-04-29 13:23:22 +02:00
|
|
|
|
VkResult result = VK_SUCCESS;
|
2016-12-01 20:58:20 +00:00
|
|
|
|
|
2020-02-17 14:45:47 +01:00
|
|
|
|
if (getenv("RADV_FORCE_FAMILY")) {
|
|
|
|
|
|
/* When RADV_FORCE_FAMILY is set, the driver creates a nul
|
|
|
|
|
|
* device that allows to test the compiler without having an
|
|
|
|
|
|
* AMDGPU instance.
|
|
|
|
|
|
*/
|
2020-04-29 13:53:35 +02:00
|
|
|
|
struct radv_physical_device *pdevice;
|
|
|
|
|
|
|
|
|
|
|
|
result = radv_physical_device_try_create(instance, NULL, &pdevice);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2020-02-17 14:45:47 +01:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
list_addtail(&pdevice->link, &instance->physical_devices);
|
2020-02-17 14:45:47 +01:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
|
/* TODO: Check for more devices ? */
|
|
|
|
|
|
drmDevicePtr devices[8];
|
|
|
|
|
|
int max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
|
radv_logi("Found %d drm nodes", max_devices);
|
|
|
|
|
|
|
2016-12-01 20:58:20 +00:00
|
|
|
|
if (max_devices < 1)
|
2020-04-29 13:23:22 +02:00
|
|
|
|
return vk_error(instance, VK_SUCCESS);
|
2016-12-01 20:58:20 +00:00
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < (unsigned)max_devices; i++) {
|
|
|
|
|
|
if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
|
|
|
|
|
|
devices[i]->bustype == DRM_BUS_PCI &&
|
2017-09-22 18:21:33 +02:00
|
|
|
|
devices[i]->deviceinfo.pci->vendor_id == ATI_VENDOR_ID) {
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
struct radv_physical_device *pdevice;
|
|
|
|
|
|
result = radv_physical_device_try_create(instance, devices[i],
|
|
|
|
|
|
&pdevice);
|
2020-04-29 13:23:22 +02:00
|
|
|
|
/* Incompatible DRM device, skip. */
|
|
|
|
|
|
if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
|
|
|
|
|
|
result = VK_SUCCESS;
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Error creating the physical device, report the error. */
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
2017-05-02 20:05:07 +03:00
|
|
|
|
break;
|
2020-04-29 13:23:22 +02:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
list_addtail(&pdevice->link, &instance->physical_devices);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-05-02 20:05:07 +03:00
|
|
|
|
drmFreeDevices(devices, max_devices);
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2017-05-02 20:05:07 +03:00
|
|
|
|
|
2020-04-29 13:23:22 +02:00
|
|
|
|
/* If we successfully enumerated any devices, call it success */
|
2016-12-01 20:58:20 +00:00
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_EnumeratePhysicalDevices(
|
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
|
uint32_t* pPhysicalDeviceCount,
|
|
|
|
|
|
VkPhysicalDevice* pPhysicalDevices)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
2020-08-06 20:57:10 -07:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkPhysicalDevice, out, pPhysicalDevices,
|
|
|
|
|
|
pPhysicalDeviceCount);
|
2016-12-01 20:58:20 +00:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
VkResult result = radv_enumerate_physical_devices(instance);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
list_for_each_entry(struct radv_physical_device, pdevice,
|
|
|
|
|
|
&instance->physical_devices, link) {
|
2020-08-06 20:57:10 -07:00
|
|
|
|
vk_outarray_append_typed(VkPhysicalDevice , &out, i) {
|
2020-04-29 13:53:35 +02:00
|
|
|
|
*i = radv_physical_device_to_handle(pdevice);
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 13:53:35 +02:00
|
|
|
|
return vk_outarray_status(&out);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 17:13:26 +01:00
|
|
|
|
VkResult radv_EnumeratePhysicalDeviceGroups(
|
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
|
uint32_t* pPhysicalDeviceGroupCount,
|
|
|
|
|
|
VkPhysicalDeviceGroupProperties* pPhysicalDeviceGroupProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
2020-08-06 20:57:10 -07:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceGroupProperties, out,
|
|
|
|
|
|
pPhysicalDeviceGroupProperties,
|
|
|
|
|
|
pPhysicalDeviceGroupCount);
|
2020-04-29 13:53:35 +02:00
|
|
|
|
|
|
|
|
|
|
VkResult result = radv_enumerate_physical_devices(instance);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(struct radv_physical_device, pdevice,
|
|
|
|
|
|
&instance->physical_devices, link) {
|
2020-08-06 20:57:10 -07:00
|
|
|
|
vk_outarray_append_typed(VkPhysicalDeviceGroupProperties, &out, p) {
|
2020-04-29 13:53:35 +02:00
|
|
|
|
p->physicalDeviceCount = 1;
|
|
|
|
|
|
memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
|
|
|
|
|
|
p->physicalDevices[0] = radv_physical_device_to_handle(pdevice);
|
|
|
|
|
|
p->subsetAllocation = false;
|
2018-01-21 17:13:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-04-29 13:53:35 +02:00
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
2018-01-21 17:13:26 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_GetPhysicalDeviceFeatures(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
VkPhysicalDeviceFeatures* pFeatures)
|
|
|
|
|
|
{
|
2018-01-04 01:32:04 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
memset(pFeatures, 0, sizeof(*pFeatures));
|
|
|
|
|
|
|
|
|
|
|
|
*pFeatures = (VkPhysicalDeviceFeatures) {
|
|
|
|
|
|
.robustBufferAccess = true,
|
|
|
|
|
|
.fullDrawIndexUint32 = true,
|
|
|
|
|
|
.imageCubeArray = true,
|
|
|
|
|
|
.independentBlend = true,
|
2019-07-11 08:44:20 +02:00
|
|
|
|
.geometryShader = true,
|
2019-07-08 23:50:09 +02:00
|
|
|
|
.tessellationShader = true,
|
2016-11-24 00:44:28 +00:00
|
|
|
|
.sampleRateShading = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.dualSrcBlend = true,
|
|
|
|
|
|
.logicOp = true,
|
|
|
|
|
|
.multiDrawIndirect = true,
|
|
|
|
|
|
.drawIndirectFirstInstance = true,
|
|
|
|
|
|
.depthClamp = true,
|
|
|
|
|
|
.depthBiasClamp = true,
|
|
|
|
|
|
.fillModeNonSolid = true,
|
|
|
|
|
|
.depthBounds = true,
|
|
|
|
|
|
.wideLines = true,
|
|
|
|
|
|
.largePoints = true,
|
2020-12-07 12:38:46 +01:00
|
|
|
|
.alphaToOne = false,
|
2017-01-20 12:42:26 +10:00
|
|
|
|
.multiViewport = true,
|
2016-11-23 23:04:58 +01:00
|
|
|
|
.samplerAnisotropy = true,
|
2019-02-20 02:19:42 +01:00
|
|
|
|
.textureCompressionETC2 = radv_device_supports_etc(pdevice),
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.textureCompressionASTC_LDR = false,
|
|
|
|
|
|
.textureCompressionBC = true,
|
|
|
|
|
|
.occlusionQueryPrecise = true,
|
2017-04-10 22:20:19 +02:00
|
|
|
|
.pipelineStatisticsQuery = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.vertexPipelineStoresAndAtomics = true,
|
|
|
|
|
|
.fragmentStoresAndAtomics = true,
|
|
|
|
|
|
.shaderTessellationAndGeometryPointSize = true,
|
2016-12-22 09:45:39 +10:00
|
|
|
|
.shaderImageGatherExtended = true,
|
2016-12-22 10:20:32 +10:00
|
|
|
|
.shaderStorageImageExtendedFormats = true,
|
2020-02-13 09:00:22 +01:00
|
|
|
|
.shaderStorageImageMultisample = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.shaderUniformBufferArrayDynamicIndexing = true,
|
|
|
|
|
|
.shaderSampledImageArrayDynamicIndexing = true,
|
|
|
|
|
|
.shaderStorageBufferArrayDynamicIndexing = true,
|
|
|
|
|
|
.shaderStorageImageArrayDynamicIndexing = true,
|
2017-02-15 01:00:07 +01:00
|
|
|
|
.shaderStorageImageReadWithoutFormat = true,
|
2017-02-15 00:55:19 +01:00
|
|
|
|
.shaderStorageImageWriteWithoutFormat = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.shaderClipDistance = true,
|
|
|
|
|
|
.shaderCullDistance = true,
|
2017-01-29 23:07:10 +01:00
|
|
|
|
.shaderFloat64 = true,
|
2017-02-15 04:58:48 +00:00
|
|
|
|
.shaderInt64 = true,
|
2020-05-07 10:54:12 +02:00
|
|
|
|
.shaderInt16 = true,
|
2017-01-31 23:59:02 +01:00
|
|
|
|
.sparseBinding = true,
|
2021-01-21 08:46:17 +01:00
|
|
|
|
.sparseResidencyBuffer = pdevice->rad_info.family >= CHIP_POLARIS10,
|
|
|
|
|
|
.sparseResidencyImage2D = pdevice->rad_info.family >= CHIP_POLARIS10,
|
|
|
|
|
|
.sparseResidencyAliased = pdevice->rad_info.family >= CHIP_POLARIS10,
|
2017-04-12 23:29:58 +02:00
|
|
|
|
.variableMultisampleRate = true,
|
2020-05-08 19:26:19 +02:00
|
|
|
|
.shaderResourceMinLod = true,
|
2020-11-24 23:02:54 +01:00
|
|
|
|
.shaderResourceResidency = true,
|
2017-04-12 23:17:14 +02:00
|
|
|
|
.inheritedQueries = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-20 09:07:49 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_get_physical_device_features_1_1(struct radv_physical_device *pdevice,
|
|
|
|
|
|
VkPhysicalDeviceVulkan11Features *f)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES);
|
|
|
|
|
|
|
2020-05-05 09:07:33 +02:00
|
|
|
|
f->storageBuffer16BitAccess = true;
|
|
|
|
|
|
f->uniformAndStorageBuffer16BitAccess = true;
|
|
|
|
|
|
f->storagePushConstant16 = true;
|
2020-06-11 10:43:02 +01:00
|
|
|
|
f->storageInputOutput16 = pdevice->rad_info.has_packed_math_16bit && (LLVM_VERSION_MAJOR >= 9 || !pdevice->use_llvm);
|
2020-05-20 09:07:49 +02:00
|
|
|
|
f->multiview = true;
|
|
|
|
|
|
f->multiviewGeometryShader = true;
|
|
|
|
|
|
f->multiviewTessellationShader = true;
|
|
|
|
|
|
f->variablePointersStorageBuffer = true;
|
|
|
|
|
|
f->variablePointers = true;
|
|
|
|
|
|
f->protectedMemory = false;
|
|
|
|
|
|
f->samplerYcbcrConversion = true;
|
|
|
|
|
|
f->shaderDrawParameters = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_get_physical_device_features_1_2(struct radv_physical_device *pdevice,
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Features *f)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(f->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES);
|
|
|
|
|
|
|
|
|
|
|
|
f->samplerMirrorClampToEdge = true;
|
|
|
|
|
|
f->drawIndirectCount = true;
|
2020-05-05 09:07:33 +02:00
|
|
|
|
f->storageBuffer8BitAccess = true;
|
|
|
|
|
|
f->uniformAndStorageBuffer8BitAccess = true;
|
|
|
|
|
|
f->storagePushConstant8 = true;
|
2020-06-11 10:43:02 +01:00
|
|
|
|
f->shaderBufferInt64Atomics = LLVM_VERSION_MAJOR >= 9 || !pdevice->use_llvm;
|
|
|
|
|
|
f->shaderSharedInt64Atomics = LLVM_VERSION_MAJOR >= 9 || !pdevice->use_llvm;
|
2020-06-05 09:27:01 +02:00
|
|
|
|
f->shaderFloat16 = pdevice->rad_info.has_packed_math_16bit;
|
2020-06-04 11:33:28 +02:00
|
|
|
|
f->shaderInt8 = true;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
|
|
|
|
|
|
f->descriptorIndexing = true;
|
|
|
|
|
|
f->shaderInputAttachmentArrayDynamicIndexing = true;
|
|
|
|
|
|
f->shaderUniformTexelBufferArrayDynamicIndexing = true;
|
|
|
|
|
|
f->shaderStorageTexelBufferArrayDynamicIndexing = true;
|
|
|
|
|
|
f->shaderUniformBufferArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderSampledImageArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderStorageBufferArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderStorageImageArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderInputAttachmentArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderUniformTexelBufferArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->shaderStorageTexelBufferArrayNonUniformIndexing = true;
|
|
|
|
|
|
f->descriptorBindingUniformBufferUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingSampledImageUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingStorageImageUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingStorageBufferUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
|
|
|
|
|
|
f->descriptorBindingUpdateUnusedWhilePending = true;
|
|
|
|
|
|
f->descriptorBindingPartiallyBound = true;
|
|
|
|
|
|
f->descriptorBindingVariableDescriptorCount = true;
|
|
|
|
|
|
f->runtimeDescriptorArray = true;
|
|
|
|
|
|
|
|
|
|
|
|
f->samplerFilterMinmax = true;
|
|
|
|
|
|
f->scalarBlockLayout = pdevice->rad_info.chip_class >= GFX7;
|
|
|
|
|
|
f->imagelessFramebuffer = true;
|
|
|
|
|
|
f->uniformBufferStandardLayout = true;
|
2020-06-04 10:41:50 +02:00
|
|
|
|
f->shaderSubgroupExtendedTypes = true;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
f->separateDepthStencilLayouts = true;
|
|
|
|
|
|
f->hostQueryReset = true;
|
|
|
|
|
|
f->timelineSemaphore = pdevice->rad_info.has_syncobj_wait_for_submit;
|
|
|
|
|
|
f->bufferDeviceAddress = true;
|
|
|
|
|
|
f->bufferDeviceAddressCaptureReplay = false;
|
|
|
|
|
|
f->bufferDeviceAddressMultiDevice = false;
|
2020-07-30 11:07:22 +01:00
|
|
|
|
f->vulkanMemoryModel = true;
|
|
|
|
|
|
f->vulkanMemoryModelDeviceScope = true;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
f->vulkanMemoryModelAvailabilityVisibilityChains = false;
|
|
|
|
|
|
f->shaderOutputViewportIndex = true;
|
|
|
|
|
|
f->shaderOutputLayer = true;
|
|
|
|
|
|
f->subgroupBroadcastDynamicId = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceFeatures2(
|
2016-11-11 02:27:21 +00:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkPhysicalDeviceFeatures2 *pFeatures)
|
2016-11-11 02:27:21 +00:00
|
|
|
|
{
|
2018-05-15 17:10:12 +02:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
2020-05-20 09:07:49 +02:00
|
|
|
|
radv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
|
|
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceVulkan11Features core_1_1 = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_features_1_1(pdevice, &core_1_1);
|
|
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Features core_1_2 = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_features_1_2(pdevice, &core_1_2);
|
|
|
|
|
|
|
|
|
|
|
|
#define CORE_FEATURE(major, minor, feature) \
|
|
|
|
|
|
features->feature = core_##major##_##minor.feature
|
|
|
|
|
|
|
2017-07-19 23:55:58 +02:00
|
|
|
|
vk_foreach_struct(ext, pFeatures->pNext) {
|
|
|
|
|
|
switch (ext->sType) {
|
2019-04-23 13:47:10 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTERS_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceVariablePointersFeatures *features = (void *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, variablePointersStorageBuffer);
|
|
|
|
|
|
CORE_FEATURE(1, 1, variablePointers);
|
2017-07-19 23:55:58 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceMultiviewFeatures *features = (VkPhysicalDeviceMultiviewFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, multiview);
|
|
|
|
|
|
CORE_FEATURE(1, 1, multiviewGeometryShader);
|
|
|
|
|
|
CORE_FEATURE(1, 1, multiviewTessellationShader);
|
2017-08-16 09:20:53 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-04-23 13:47:10 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceShaderDrawParametersFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderDrawParametersFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, shaderDrawParameters);
|
2018-01-21 15:57:59 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-21 15:59:45 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceProtectedMemoryFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceProtectedMemoryFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, protectedMemory);
|
2018-01-21 15:59:45 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-22 00:34:08 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
|
|
|
|
|
VkPhysicalDevice16BitStorageFeatures *features =
|
|
|
|
|
|
(VkPhysicalDevice16BitStorageFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, storageBuffer16BitAccess);
|
|
|
|
|
|
CORE_FEATURE(1, 1, uniformAndStorageBuffer16BitAccess);
|
|
|
|
|
|
CORE_FEATURE(1, 1, storagePushConstant16);
|
|
|
|
|
|
CORE_FEATURE(1, 1, storageInputOutput16);
|
2018-01-22 00:34:08 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-22 22:22:41 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceSamplerYcbcrConversionFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceSamplerYcbcrConversionFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 1, samplerYcbcrConversion);
|
2018-01-22 22:22:41 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 14:01:43 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceDescriptorIndexingFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceDescriptorIndexingFeatures*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, shaderInputAttachmentArrayDynamicIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderUniformTexelBufferArrayDynamicIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderStorageTexelBufferArrayDynamicIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderUniformBufferArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderSampledImageArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderStorageBufferArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderStorageImageArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderInputAttachmentArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderUniformTexelBufferArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderStorageTexelBufferArrayNonUniformIndexing);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingUniformBufferUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingSampledImageUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingStorageImageUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingStorageBufferUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingUniformTexelBufferUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingStorageTexelBufferUpdateAfterBind);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingUpdateUnusedWhilePending);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingPartiallyBound);
|
|
|
|
|
|
CORE_FEATURE(1, 2, descriptorBindingVariableDescriptorCount);
|
|
|
|
|
|
CORE_FEATURE(1, 2, runtimeDescriptorArray);
|
2018-04-11 19:08:30 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-07-09 11:37:15 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;
|
|
|
|
|
|
features->conditionalRendering = true;
|
|
|
|
|
|
features->inheritedConditionalRendering = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-09-10 20:34:00 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
|
2019-12-05 18:04:32 +01:00
|
|
|
|
features->vertexAttributeInstanceRateDivisor = true;
|
|
|
|
|
|
features->vertexAttributeInstanceRateZeroDivisor = true;
|
2018-09-10 20:34:00 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-10-05 18:04:56 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceTransformFeedbackFeaturesEXT*)ext;
|
|
|
|
|
|
features->transformFeedback = true;
|
2019-09-11 09:22:29 +02:00
|
|
|
|
features->geometryStreams = !pdevice->use_ngg_streamout;
|
2018-10-05 18:04:56 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 09:00:19 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceScalarBlockLayoutFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceScalarBlockLayoutFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, scalarBlockLayout);
|
2018-12-05 13:48:36 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-28 02:09:07 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceMemoryPriorityFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceMemoryPriorityFeaturesEXT *)ext;
|
2019-12-05 18:04:32 +01:00
|
|
|
|
features->memoryPriority = true;
|
2019-01-28 02:09:07 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-04-23 13:47:10 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceBufferDeviceAddressFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceBufferDeviceAddressFeaturesEXT *)ext;
|
2019-01-24 02:06:27 +01:00
|
|
|
|
features->bufferDeviceAddress = true;
|
|
|
|
|
|
features->bufferDeviceAddressCaptureReplay = false;
|
|
|
|
|
|
features->bufferDeviceAddressMultiDevice = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 09:59:27 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceBufferDeviceAddressFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceBufferDeviceAddressFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, bufferDeviceAddress);
|
|
|
|
|
|
CORE_FEATURE(1, 2, bufferDeviceAddressCaptureReplay);
|
|
|
|
|
|
CORE_FEATURE(1, 2, bufferDeviceAddressMultiDevice);
|
2019-11-26 01:00:20 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-26 02:28:08 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
|
|
|
|
|
|
features->depthClipEnable = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 08:55:07 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceHostQueryResetFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceHostQueryResetFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, hostQueryReset);
|
2018-11-17 18:39:24 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 09:03:28 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: {
|
|
|
|
|
|
VkPhysicalDevice8BitStorageFeatures *features =
|
|
|
|
|
|
(VkPhysicalDevice8BitStorageFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, storageBuffer8BitAccess);
|
|
|
|
|
|
CORE_FEATURE(1, 2, uniformAndStorageBuffer8BitAccess);
|
|
|
|
|
|
CORE_FEATURE(1, 2, storagePushConstant8);
|
2018-12-06 13:33:48 +00:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 14:05:13 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceShaderFloat16Int8Features *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderFloat16Int8Features*)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, shaderFloat16);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderInt8);
|
2019-04-01 16:18:11 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 10:16:37 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceShaderAtomicInt64Features *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderAtomicInt64Features *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, shaderBufferInt64Atomics);
|
|
|
|
|
|
CORE_FEATURE(1, 2, shaderSharedInt64Atomics);
|
2019-04-16 10:38:24 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-09-17 17:09:52 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderDemoteToHelperInvocationFeaturesEXT *)ext;
|
2020-06-11 10:43:02 +01:00
|
|
|
|
features->shaderDemoteToHelperInvocation = LLVM_VERSION_MAJOR >= 9 || !pdevice->use_llvm;
|
2019-09-17 17:09:52 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-03-14 11:20:53 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceInlineUniformBlockFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)ext;
|
|
|
|
|
|
|
|
|
|
|
|
features->inlineUniformBlock = true;
|
|
|
|
|
|
features->descriptorBindingInlineUniformBlockUpdateAfterBind = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-04-19 12:40:37 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV: {
|
|
|
|
|
|
VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *features =
|
|
|
|
|
|
(VkPhysicalDeviceComputeShaderDerivativesFeaturesNV *)ext;
|
|
|
|
|
|
features->computeDerivativeGroupQuads = false;
|
|
|
|
|
|
features->computeDerivativeGroupLinear = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-04-07 23:01:36 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceYcbcrImageArraysFeaturesEXT*)ext;
|
|
|
|
|
|
features->ycbcrImageArrays = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 10:21:20 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceUniformBufferStandardLayoutFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceUniformBufferStandardLayoutFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, uniformBufferStandardLayout);
|
2019-05-13 18:43:55 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-07-29 10:50:56 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceIndexTypeUint8FeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceIndexTypeUint8FeaturesEXT *)ext;
|
|
|
|
|
|
features->indexTypeUint8 = pdevice->rad_info.chip_class >= GFX8;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 10:15:04 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceImagelessFramebufferFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceImagelessFramebufferFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, imagelessFramebuffer);
|
2019-08-02 14:45:49 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-06-01 21:08:20 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_EXECUTABLE_PROPERTIES_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDevicePipelineExecutablePropertiesFeaturesKHR *)ext;
|
|
|
|
|
|
features->pipelineExecutableInfo = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-07 10:26:22 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CLOCK_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceShaderClockFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderClockFeaturesKHR *)ext;
|
|
|
|
|
|
features->shaderSubgroupClock = true;
|
2020-05-20 10:02:49 +02:00
|
|
|
|
features->shaderDeviceClock = pdevice->rad_info.chip_class >= GFX8;
|
2019-10-07 10:26:22 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-10 11:40:27 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceTexelBufferAlignmentFeaturesEXT *)ext;
|
|
|
|
|
|
features->texelBufferAlignment = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-25 20:50:12 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceTimelineSemaphoreFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceTimelineSemaphoreFeatures *) ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, timelineSemaphore);
|
2019-10-25 10:26:50 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-31 10:55:37 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *)ext;
|
|
|
|
|
|
features->subgroupSizeControl = true;
|
|
|
|
|
|
features->computeFullSubgroups = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-13 08:58:37 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD: {
|
|
|
|
|
|
VkPhysicalDeviceCoherentMemoryFeaturesAMD *features =
|
|
|
|
|
|
(VkPhysicalDeviceCoherentMemoryFeaturesAMD *)ext;
|
|
|
|
|
|
features->deviceCoherentMemory = pdevice->rad_info.has_l2_uncached;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 14:08:00 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES: {
|
|
|
|
|
|
VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, shaderSubgroupExtendedTypes);
|
2019-11-08 12:45:03 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-12-09 13:56:24 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;
|
2020-05-20 09:07:49 +02:00
|
|
|
|
CORE_FEATURE(1, 2, separateDepthStencilLayouts);
|
2019-12-09 13:56:24 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 08:13:14 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
|
2020-05-20 09:07:49 +02:00
|
|
|
|
radv_get_physical_device_features_1_1(pdevice, (void *)ext);
|
2019-11-26 08:13:14 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 08:34:33 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
|
2020-05-20 09:07:49 +02:00
|
|
|
|
radv_get_physical_device_features_1_2(pdevice, (void *)ext);
|
2019-11-26 08:34:33 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-09-13 13:40:44 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
|
|
|
|
|
|
features->rectangularLines = false;
|
|
|
|
|
|
features->bresenhamLines = true;
|
|
|
|
|
|
features->smoothLines = false;
|
|
|
|
|
|
features->stippledRectangularLines = false;
|
2020-12-28 08:44:03 +01:00
|
|
|
|
/* FIXME: Some stippled Bresenham CTS fails on Vega10
|
|
|
|
|
|
* but work on Raven.
|
|
|
|
|
|
*/
|
|
|
|
|
|
features->stippledBresenhamLines = pdevice->rad_info.chip_class != GFX9;
|
2019-09-13 13:40:44 +02:00
|
|
|
|
features->stippledSmoothLines = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-25 15:51:03 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD: {
|
|
|
|
|
|
VkDeviceMemoryOverallocationCreateInfoAMD *features =
|
|
|
|
|
|
(VkDeviceMemoryOverallocationCreateInfoAMD *)ext;
|
|
|
|
|
|
features->overallocationBehavior = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-15 11:39:28 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceRobustness2FeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceRobustness2FeaturesEXT *)ext;
|
|
|
|
|
|
features->robustBufferAccess2 = true;
|
|
|
|
|
|
features->robustImageAccess2 = true;
|
|
|
|
|
|
features->nullDescriptor = true;
|
2020-05-20 19:52:34 +02:00
|
|
|
|
break;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceCustomBorderColorFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceCustomBorderColorFeaturesEXT *)ext;
|
|
|
|
|
|
features->customBorderColors = true;
|
|
|
|
|
|
features->customBorderColorWithoutFormat = true;
|
2020-04-15 11:39:28 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-29 10:19:11 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRIVATE_DATA_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDevicePrivateDataFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDevicePrivateDataFeaturesEXT *)ext;
|
|
|
|
|
|
features->privateData = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-05-17 02:56:04 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_CREATION_CACHE_CONTROL_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDevicePipelineCreationCacheControlFeaturesEXT *)ext;
|
|
|
|
|
|
features-> pipelineCreationCacheControl = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-24 17:11:45 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceVulkanMemoryModelFeaturesKHR *)ext;
|
|
|
|
|
|
CORE_FEATURE(1, 2, vulkanMemoryModel);
|
|
|
|
|
|
CORE_FEATURE(1, 2, vulkanMemoryModelDeviceScope);
|
|
|
|
|
|
CORE_FEATURE(1, 2, vulkanMemoryModelAvailabilityVisibilityChains);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-13 11:00:02 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *) ext;
|
|
|
|
|
|
features->extendedDynamicState = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-20 14:54:58 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceImageRobustnessFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceImageRobustnessFeaturesEXT *)ext;
|
|
|
|
|
|
features->robustImageAccess = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-20 18:38:17 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceShaderAtomicFloatFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderAtomicFloatFeaturesEXT *)ext;
|
|
|
|
|
|
features->shaderBufferFloat32Atomics = true;
|
|
|
|
|
|
features->shaderBufferFloat32AtomicAdd = false;
|
|
|
|
|
|
features->shaderBufferFloat64Atomics = true;
|
|
|
|
|
|
features->shaderBufferFloat64AtomicAdd = false;
|
|
|
|
|
|
features->shaderSharedFloat32Atomics = true;
|
|
|
|
|
|
features->shaderSharedFloat32AtomicAdd = pdevice->rad_info.chip_class >= GFX8 &&
|
|
|
|
|
|
(!pdevice->use_llvm || LLVM_VERSION_MAJOR >= 10);
|
|
|
|
|
|
features->shaderSharedFloat64Atomics = true;
|
|
|
|
|
|
features->shaderSharedFloat64AtomicAdd = false;
|
|
|
|
|
|
features->shaderImageFloat32Atomics = true;
|
|
|
|
|
|
features->shaderImageFloat32AtomicAdd = false;
|
2021-01-22 11:26:16 +01:00
|
|
|
|
features->sparseImageFloat32Atomics = true;
|
2020-07-20 18:38:17 +02:00
|
|
|
|
features->sparseImageFloat32AtomicAdd = false;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-15 11:21:23 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDevice4444FormatsFeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDevice4444FormatsFeaturesEXT *)ext;
|
|
|
|
|
|
features->formatA4R4G4B4 = true;
|
|
|
|
|
|
features->formatA4B4G4R4 = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-09-18 03:11:18 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TERMINATE_INVOCATION_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderTerminateInvocationFeaturesKHR *)ext;
|
|
|
|
|
|
features->shaderTerminateInvocation = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-10-19 18:02:35 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_ATOMIC_INT64_FEATURES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT *features =
|
|
|
|
|
|
(VkPhysicalDeviceShaderImageAtomicInt64FeaturesEXT *)ext;
|
|
|
|
|
|
features->shaderImageInt64Atomics = LLVM_VERSION_MAJOR >= 11 || !pdevice->use_llvm;
|
2021-01-22 11:26:16 +01:00
|
|
|
|
features->sparseImageInt64Atomics = LLVM_VERSION_MAJOR >= 11 || !pdevice->use_llvm;
|
2020-10-19 18:02:35 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-12-07 13:41:26 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_VALVE: {
|
|
|
|
|
|
VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *features =
|
|
|
|
|
|
(VkPhysicalDeviceMutableDescriptorTypeFeaturesVALVE *)ext;
|
|
|
|
|
|
features->mutableDescriptorType = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-11-30 18:54:06 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRateFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceFragmentShadingRateFeaturesKHR *)ext;
|
|
|
|
|
|
features->pipelineFragmentShadingRate = true;
|
|
|
|
|
|
features->primitiveFragmentShadingRate = true;
|
|
|
|
|
|
features->attachmentFragmentShadingRate = false; /* TODO */
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-11-07 00:38:39 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_FEATURES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *features =
|
|
|
|
|
|
(VkPhysicalDeviceWorkgroupMemoryExplicitLayoutFeaturesKHR *)ext;
|
|
|
|
|
|
features->workgroupMemoryExplicitLayout = true;
|
|
|
|
|
|
features->workgroupMemoryExplicitLayoutScalarBlockLayout = true;
|
|
|
|
|
|
features->workgroupMemoryExplicitLayout8BitAccess = true;
|
|
|
|
|
|
features->workgroupMemoryExplicitLayout16BitAccess = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-07-19 23:55:58 +02:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-20 09:07:49 +02:00
|
|
|
|
#undef CORE_FEATURE
|
2016-11-11 02:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-28 00:36:24 +01:00
|
|
|
|
static size_t
|
|
|
|
|
|
radv_max_descriptor_set_size()
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
2017-04-13 22:34:33 +02:00
|
|
|
|
/* make sure that the entire descriptor set is addressable with a signed
|
|
|
|
|
|
* 32-bit int. So the sum of all limits scaled by descriptor size has to
|
|
|
|
|
|
* be at most 2 GiB. the combined image & samples object count as one of
|
|
|
|
|
|
* both. This limit is for the pipeline layout, not for the set layout, but
|
|
|
|
|
|
* there is no set limit, so we just set a pipeline limit. I don't think
|
|
|
|
|
|
* any app is going to hit this soon. */
|
2019-11-28 00:36:24 +01:00
|
|
|
|
return ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS
|
|
|
|
|
|
- MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
|
2018-01-10 13:01:29 +01:00
|
|
|
|
(32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
|
|
|
|
|
|
32 /* storage buffer, 32 due to potential space wasted on alignment */ +
|
2017-04-13 22:34:33 +02:00
|
|
|
|
32 /* sampler, largest when combined with image */ +
|
|
|
|
|
|
64 /* sampled image */ +
|
|
|
|
|
|
64 /* storage image */);
|
2019-11-28 00:36:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-30 02:49:33 +02:00
|
|
|
|
static uint32_t
|
|
|
|
|
|
radv_uniform_buffer_offset_alignment(const struct radv_physical_device *pdevice)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t uniform_offset_alignment = driQueryOptioni(&pdevice->instance->dri_options,
|
|
|
|
|
|
"radv_override_uniform_offset_alignment");
|
|
|
|
|
|
if (!util_is_power_of_two_or_zero(uniform_offset_alignment)) {
|
|
|
|
|
|
fprintf(stderr, "ERROR: invalid radv_override_uniform_offset_alignment setting %d:"
|
|
|
|
|
|
"not a power of two\n", uniform_offset_alignment);
|
|
|
|
|
|
uniform_offset_alignment = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Take at least the hardware limit. */
|
|
|
|
|
|
return MAX2(uniform_offset_alignment, 4);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-28 00:36:24 +01:00
|
|
|
|
void radv_GetPhysicalDeviceProperties(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
VkPhysicalDeviceProperties* pProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
VkSampleCountFlags sample_counts = 0xf;
|
|
|
|
|
|
|
|
|
|
|
|
size_t max_descriptor_set_size = radv_max_descriptor_set_size();
|
2017-04-13 22:34:33 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkPhysicalDeviceLimits limits = {
|
|
|
|
|
|
.maxImageDimension1D = (1 << 14),
|
|
|
|
|
|
.maxImageDimension2D = (1 << 14),
|
|
|
|
|
|
.maxImageDimension3D = (1 << 11),
|
|
|
|
|
|
.maxImageDimensionCube = (1 << 14),
|
|
|
|
|
|
.maxImageArrayLayers = (1 << 11),
|
2020-04-28 17:04:25 +02:00
|
|
|
|
.maxTexelBufferElements = UINT32_MAX,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxUniformBufferRange = UINT32_MAX,
|
|
|
|
|
|
.maxStorageBufferRange = UINT32_MAX,
|
|
|
|
|
|
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
|
|
|
|
|
|
.maxMemoryAllocationCount = UINT32_MAX,
|
|
|
|
|
|
.maxSamplerAllocationCount = 64 * 1024,
|
|
|
|
|
|
.bufferImageGranularity = 64, /* A cache line */
|
2020-04-08 10:57:28 +02:00
|
|
|
|
.sparseAddressSpaceSize = RADV_MAX_MEMORY_ALLOCATION_SIZE, /* buffer max size */
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxBoundDescriptorSets = MAX_SETS,
|
2017-04-13 22:34:33 +02:00
|
|
|
|
.maxPerStageDescriptorSamplers = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageDescriptorStorageBuffers = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageDescriptorSampledImages = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageDescriptorStorageImages = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageDescriptorInputAttachments = max_descriptor_set_size,
|
|
|
|
|
|
.maxPerStageResources = max_descriptor_set_size,
|
|
|
|
|
|
.maxDescriptorSetSamplers = max_descriptor_set_size,
|
|
|
|
|
|
.maxDescriptorSetUniformBuffers = max_descriptor_set_size,
|
2018-03-09 17:18:03 +01:00
|
|
|
|
.maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS,
|
2017-04-13 22:34:33 +02:00
|
|
|
|
.maxDescriptorSetStorageBuffers = max_descriptor_set_size,
|
2018-03-09 17:18:03 +01:00
|
|
|
|
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS,
|
2017-04-13 22:34:33 +02:00
|
|
|
|
.maxDescriptorSetSampledImages = max_descriptor_set_size,
|
|
|
|
|
|
.maxDescriptorSetStorageImages = max_descriptor_set_size,
|
|
|
|
|
|
.maxDescriptorSetInputAttachments = max_descriptor_set_size,
|
2019-02-12 15:09:30 +01:00
|
|
|
|
.maxVertexInputAttributes = MAX_VERTEX_ATTRIBS,
|
|
|
|
|
|
.maxVertexInputBindings = MAX_VBS,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxVertexInputAttributeOffset = 2047,
|
|
|
|
|
|
.maxVertexInputBindingStride = 2048,
|
|
|
|
|
|
.maxVertexOutputComponents = 128,
|
2017-03-30 08:48:49 +01:00
|
|
|
|
.maxTessellationGenerationLevel = 64,
|
|
|
|
|
|
.maxTessellationPatchSize = 32,
|
|
|
|
|
|
.maxTessellationControlPerVertexInputComponents = 128,
|
|
|
|
|
|
.maxTessellationControlPerVertexOutputComponents = 128,
|
|
|
|
|
|
.maxTessellationControlPerPatchOutputComponents = 120,
|
|
|
|
|
|
.maxTessellationControlTotalOutputComponents = 4096,
|
|
|
|
|
|
.maxTessellationEvaluationInputComponents = 128,
|
|
|
|
|
|
.maxTessellationEvaluationOutputComponents = 128,
|
2017-04-14 05:28:52 +10:00
|
|
|
|
.maxGeometryShaderInvocations = 127,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxGeometryInputComponents = 64,
|
|
|
|
|
|
.maxGeometryOutputComponents = 128,
|
|
|
|
|
|
.maxGeometryOutputVertices = 256,
|
|
|
|
|
|
.maxGeometryTotalOutputComponents = 1024,
|
|
|
|
|
|
.maxFragmentInputComponents = 128,
|
|
|
|
|
|
.maxFragmentOutputAttachments = 8,
|
2016-11-29 11:16:56 +10:00
|
|
|
|
.maxFragmentDualSrcAttachments = 1,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxFragmentCombinedOutputResources = 8,
|
|
|
|
|
|
.maxComputeSharedMemorySize = 32768,
|
|
|
|
|
|
.maxComputeWorkGroupCount = { 65535, 65535, 65535 },
|
2019-12-18 10:21:40 +01:00
|
|
|
|
.maxComputeWorkGroupInvocations = 1024,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxComputeWorkGroupSize = {
|
2019-12-18 10:21:40 +01:00
|
|
|
|
1024,
|
|
|
|
|
|
1024,
|
|
|
|
|
|
1024
|
2016-10-07 09:16:09 +10:00
|
|
|
|
},
|
2019-01-02 17:53:41 +01:00
|
|
|
|
.subPixelPrecisionBits = 8,
|
|
|
|
|
|
.subTexelPrecisionBits = 8,
|
|
|
|
|
|
.mipmapPrecisionBits = 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxDrawIndexedIndexValue = UINT32_MAX,
|
|
|
|
|
|
.maxDrawIndirectCount = UINT32_MAX,
|
|
|
|
|
|
.maxSamplerLodBias = 16,
|
|
|
|
|
|
.maxSamplerAnisotropy = 16,
|
|
|
|
|
|
.maxViewports = MAX_VIEWPORTS,
|
|
|
|
|
|
.maxViewportDimensions = { (1 << 14), (1 << 14) },
|
|
|
|
|
|
.viewportBoundsRange = { INT16_MIN, INT16_MAX },
|
2018-04-11 00:11:57 +02:00
|
|
|
|
.viewportSubPixelBits = 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.minMemoryMapAlignment = 4096, /* A page */
|
2019-10-09 10:37:04 +02:00
|
|
|
|
.minTexelBufferOffsetAlignment = 4,
|
2020-07-30 02:49:33 +02:00
|
|
|
|
.minUniformBufferOffsetAlignment = radv_uniform_buffer_offset_alignment(pdevice),
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.minStorageBufferOffsetAlignment = 4,
|
2016-12-22 10:35:46 +10:00
|
|
|
|
.minTexelOffset = -32,
|
|
|
|
|
|
.maxTexelOffset = 31,
|
|
|
|
|
|
.minTexelGatherOffset = -32,
|
|
|
|
|
|
.maxTexelGatherOffset = 31,
|
2016-12-22 11:52:30 +10:00
|
|
|
|
.minInterpolationOffset = -2,
|
|
|
|
|
|
.maxInterpolationOffset = 2,
|
|
|
|
|
|
.subPixelInterpolationOffsetBits = 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxFramebufferWidth = (1 << 14),
|
|
|
|
|
|
.maxFramebufferHeight = (1 << 14),
|
|
|
|
|
|
.maxFramebufferLayers = (1 << 10),
|
|
|
|
|
|
.framebufferColorSampleCounts = sample_counts,
|
|
|
|
|
|
.framebufferDepthSampleCounts = sample_counts,
|
|
|
|
|
|
.framebufferStencilSampleCounts = sample_counts,
|
|
|
|
|
|
.framebufferNoAttachmentsSampleCounts = sample_counts,
|
|
|
|
|
|
.maxColorAttachments = MAX_RTS,
|
|
|
|
|
|
.sampledImageColorSampleCounts = sample_counts,
|
2019-12-24 14:44:03 +01:00
|
|
|
|
.sampledImageIntegerSampleCounts = sample_counts,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.sampledImageDepthSampleCounts = sample_counts,
|
|
|
|
|
|
.sampledImageStencilSampleCounts = sample_counts,
|
2020-02-13 09:00:22 +01:00
|
|
|
|
.storageImageSampleCounts = sample_counts,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxSampleMaskWords = 1,
|
2017-04-14 23:59:28 +03:00
|
|
|
|
.timestampComputeAndGraphics = true,
|
2017-04-14 20:00:26 +03:00
|
|
|
|
.timestampPeriod = 1000000.0 / pdevice->rad_info.clock_crystal_freq,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.maxClipDistances = 8,
|
|
|
|
|
|
.maxCullDistances = 8,
|
|
|
|
|
|
.maxCombinedClipAndCullDistances = 8,
|
2018-10-15 14:53:00 +02:00
|
|
|
|
.discreteQueuePriorities = 2,
|
2020-06-30 18:45:08 +02:00
|
|
|
|
.pointSizeRange = { 0.0, 8191.875 },
|
|
|
|
|
|
.lineWidthRange = { 0.0, 8191.875 },
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.pointSizeGranularity = (1.0 / 8.0),
|
2019-12-05 17:28:47 +01:00
|
|
|
|
.lineWidthGranularity = (1.0 / 8.0),
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.strictLines = false, /* FINISHME */
|
|
|
|
|
|
.standardSampleLocations = true,
|
|
|
|
|
|
.optimalBufferCopyOffsetAlignment = 128,
|
|
|
|
|
|
.optimalBufferCopyRowPitchAlignment = 128,
|
|
|
|
|
|
.nonCoherentAtomSize = 64,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
*pProperties = (VkPhysicalDeviceProperties) {
|
2017-10-17 15:18:36 +10:00
|
|
|
|
.apiVersion = radv_physical_device_api_version(pdevice),
|
2017-06-06 16:09:07 +01:00
|
|
|
|
.driverVersion = vk_get_driver_version(),
|
2017-09-22 18:21:33 +02:00
|
|
|
|
.vendorID = ATI_VENDOR_ID,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.deviceID = pdevice->rad_info.pci_id,
|
2017-05-15 11:27:10 +10:00
|
|
|
|
.deviceType = pdevice->rad_info.has_dedicated_vram ? VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU : VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
.limits = limits,
|
2020-11-24 23:02:54 +01:00
|
|
|
|
.sparseProperties = {
|
2021-01-21 08:46:17 +01:00
|
|
|
|
.residencyNonResidentStrict = pdevice->rad_info.family >= CHIP_POLARIS10,
|
|
|
|
|
|
.residencyStandard2DBlockShape = pdevice->rad_info.family >= CHIP_POLARIS10,
|
2020-11-24 23:02:54 +01:00
|
|
|
|
},
|
2016-10-07 09:16:09 +10:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
strcpy(pProperties->deviceName, pdevice->name);
|
2017-07-12 18:45:29 -04:00
|
|
|
|
memcpy(pProperties->pipelineCacheUUID, pdevice->cache_uuid, VK_UUID_SIZE);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-01-29 15:02:26 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_get_physical_device_properties_1_1(struct radv_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);
|
|
|
|
|
|
/* The LUID is for Windows. */
|
|
|
|
|
|
p->deviceLUIDValid = false;
|
|
|
|
|
|
p->deviceNodeMask = 0;
|
|
|
|
|
|
|
|
|
|
|
|
p->subgroupSize = RADV_SUBGROUP_SIZE;
|
2020-04-22 15:26:17 +02:00
|
|
|
|
p->subgroupSupportedStages = VK_SHADER_STAGE_ALL_GRAPHICS |
|
|
|
|
|
|
VK_SHADER_STAGE_COMPUTE_BIT;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_VOTE_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_BALLOT_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_CLUSTERED_BIT |
|
2020-05-27 01:31:35 +02:00
|
|
|
|
VK_SUBGROUP_FEATURE_QUAD_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
|
|
|
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->subgroupQuadOperationsInAllStages = true;
|
|
|
|
|
|
|
|
|
|
|
|
p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
|
|
|
|
|
|
p->maxMultiviewViewCount = MAX_VIEWS;
|
|
|
|
|
|
p->maxMultiviewInstanceIndex = INT_MAX;
|
|
|
|
|
|
p->protectedNoFault = false;
|
|
|
|
|
|
p->maxPerSetDescriptors = RADV_MAX_PER_SET_DESCRIPTORS;
|
|
|
|
|
|
p->maxMemoryAllocationSize = RADV_MAX_MEMORY_ALLOCATION_SIZE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_get_physical_device_properties_1_2(struct radv_physical_device *pdevice,
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Properties *p)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES);
|
|
|
|
|
|
|
|
|
|
|
|
p->driverID = VK_DRIVER_ID_MESA_RADV;
|
|
|
|
|
|
snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE, "radv");
|
|
|
|
|
|
snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE,
|
2020-05-06 09:32:27 +02:00
|
|
|
|
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1 " (%s)",
|
2020-05-11 09:54:11 +02:00
|
|
|
|
radv_get_compiler_string(pdevice));
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->conformanceVersion = (VkConformanceVersion) {
|
|
|
|
|
|
.major = 1,
|
|
|
|
|
|
.minor = 2,
|
2020-08-25 13:41:20 +02:00
|
|
|
|
.subminor = 3,
|
2020-01-29 15:02:26 +01:00
|
|
|
|
.patch = 0,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* On AMD hardware, denormals and rounding modes for fp16/fp64 are
|
|
|
|
|
|
* controlled by the same config register.
|
|
|
|
|
|
*/
|
2020-05-03 19:27:27 -04:00
|
|
|
|
if (pdevice->rad_info.has_packed_math_16bit) {
|
2020-04-05 09:42:50 +02:00
|
|
|
|
p->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
|
|
|
|
|
|
p->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
p->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
|
|
|
|
|
|
p->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
|
|
|
|
|
|
}
|
2020-01-29 15:02:26 +01:00
|
|
|
|
|
2020-07-02 13:38:18 +01:00
|
|
|
|
/* With LLVM, do not allow both preserving and flushing denorms because
|
|
|
|
|
|
* different shaders in the same pipeline can have different settings and
|
|
|
|
|
|
* this won't work for merged shaders. To make it work, this requires LLVM
|
2020-01-29 15:02:26 +01:00
|
|
|
|
* support for changing the register. The same logic applies for the
|
|
|
|
|
|
* rounding modes because they are configured with the same config
|
2020-07-02 13:38:18 +01:00
|
|
|
|
* register.
|
2020-01-29 15:02:26 +01:00
|
|
|
|
*/
|
|
|
|
|
|
p->shaderDenormFlushToZeroFloat32 = true;
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderDenormPreserveFloat32 = !pdevice->use_llvm;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->shaderRoundingModeRTEFloat32 = true;
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderRoundingModeRTZFloat32 = !pdevice->use_llvm;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat32 = true;
|
|
|
|
|
|
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderDenormFlushToZeroFloat16 = pdevice->rad_info.has_packed_math_16bit && !pdevice->use_llvm;
|
2020-05-03 19:27:27 -04:00
|
|
|
|
p->shaderDenormPreserveFloat16 = pdevice->rad_info.has_packed_math_16bit;
|
|
|
|
|
|
p->shaderRoundingModeRTEFloat16 = pdevice->rad_info.has_packed_math_16bit;
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderRoundingModeRTZFloat16 = pdevice->rad_info.has_packed_math_16bit && !pdevice->use_llvm;
|
2020-05-03 19:27:27 -04:00
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat16 = pdevice->rad_info.has_packed_math_16bit;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderDenormFlushToZeroFloat64 = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_llvm;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->shaderDenormPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
|
|
|
|
|
|
p->shaderRoundingModeRTEFloat64 = pdevice->rad_info.chip_class >= GFX8;
|
2020-07-02 13:38:18 +01:00
|
|
|
|
p->shaderRoundingModeRTZFloat64 = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_llvm;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
p->shaderSignedZeroInfNanPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
|
|
|
|
|
|
|
|
|
|
|
|
p->maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX / 64;
|
|
|
|
|
|
p->shaderUniformBufferArrayNonUniformIndexingNative = false;
|
|
|
|
|
|
p->shaderSampledImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
|
p->shaderStorageBufferArrayNonUniformIndexingNative = false;
|
|
|
|
|
|
p->shaderStorageImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
|
p->shaderInputAttachmentArrayNonUniformIndexingNative = false;
|
|
|
|
|
|
p->robustBufferAccessUpdateAfterBind = false;
|
|
|
|
|
|
p->quadDivergentImplicitLod = false;
|
|
|
|
|
|
|
|
|
|
|
|
size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS -
|
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
|
|
|
|
|
|
(32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
|
|
|
|
|
|
32 /* storage buffer, 32 due to potential space wasted on alignment */ +
|
|
|
|
|
|
32 /* sampler, largest when combined with image */ +
|
|
|
|
|
|
64 /* sampled image */ +
|
|
|
|
|
|
64 /* storage image */);
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindSamplers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
|
|
|
|
|
|
p->maxPerStageUpdateAfterBindResources = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindSamplers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindUniformBuffers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageBuffers = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindSampledImages = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
|
|
|
|
|
|
p->maxDescriptorSetUpdateAfterBindInputAttachments = max_descriptor_set_size;
|
|
|
|
|
|
|
|
|
|
|
|
/* We support all of the depth resolve modes */
|
|
|
|
|
|
p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |
|
|
|
|
|
|
VK_RESOLVE_MODE_AVERAGE_BIT_KHR |
|
|
|
|
|
|
VK_RESOLVE_MODE_MIN_BIT_KHR |
|
|
|
|
|
|
VK_RESOLVE_MODE_MAX_BIT_KHR;
|
|
|
|
|
|
|
|
|
|
|
|
/* Average doesn't make sense for stencil so we don't support that */
|
|
|
|
|
|
p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |
|
|
|
|
|
|
VK_RESOLVE_MODE_MIN_BIT_KHR |
|
|
|
|
|
|
VK_RESOLVE_MODE_MAX_BIT_KHR;
|
|
|
|
|
|
|
|
|
|
|
|
p->independentResolveNone = true;
|
|
|
|
|
|
p->independentResolve = true;
|
|
|
|
|
|
|
|
|
|
|
|
/* GFX6-8 only support single channel min/max filter. */
|
|
|
|
|
|
p->filterMinmaxImageComponentMapping = pdevice->rad_info.chip_class >= GFX9;
|
|
|
|
|
|
p->filterMinmaxSingleComponentFormats = true;
|
|
|
|
|
|
|
|
|
|
|
|
p->maxTimelineSemaphoreValueDifference = UINT64_MAX;
|
|
|
|
|
|
|
|
|
|
|
|
p->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceProperties2(
|
2016-11-11 02:27:21 +00:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkPhysicalDeviceProperties2 *pProperties)
|
2016-11-11 02:27:21 +00:00
|
|
|
|
{
|
2017-07-15 02:08:01 +02:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
2017-03-29 18:12:44 +02:00
|
|
|
|
radv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
|
|
|
|
|
|
|
2020-01-29 15:02:26 +01:00
|
|
|
|
VkPhysicalDeviceVulkan11Properties core_1_1 = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_properties_1_1(pdevice, &core_1_1);
|
|
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceVulkan12Properties core_1_2 = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_properties_1_2(pdevice, &core_1_2);
|
|
|
|
|
|
|
|
|
|
|
|
#define CORE_RENAMED_PROPERTY(major, minor, ext_property, core_property) \
|
|
|
|
|
|
memcpy(&properties->ext_property, &core_##major##_##minor.core_property, \
|
|
|
|
|
|
sizeof(core_##major##_##minor.core_property))
|
|
|
|
|
|
|
|
|
|
|
|
#define CORE_PROPERTY(major, minor, property) \
|
|
|
|
|
|
CORE_RENAMED_PROPERTY(major, minor, property, property)
|
|
|
|
|
|
|
2017-03-29 18:12:44 +02:00
|
|
|
|
vk_foreach_struct(ext, pProperties->pNext) {
|
|
|
|
|
|
switch (ext->sType) {
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
|
|
|
|
|
|
VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
|
|
|
|
|
|
(VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
|
|
|
|
|
|
properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceIDProperties *properties = (VkPhysicalDeviceIDProperties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, deviceUUID);
|
|
|
|
|
|
CORE_PROPERTY(1, 1, driverUUID);
|
|
|
|
|
|
CORE_PROPERTY(1, 1, deviceLUID);
|
|
|
|
|
|
CORE_PROPERTY(1, 1, deviceLUIDValid);
|
2017-07-15 02:08:01 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceMultiviewProperties *properties = (VkPhysicalDeviceMultiviewProperties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, maxMultiviewViewCount);
|
|
|
|
|
|
CORE_PROPERTY(1, 1, maxMultiviewInstanceIndex);
|
2017-08-16 09:20:53 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDevicePointClippingProperties *properties =
|
|
|
|
|
|
(VkPhysicalDevicePointClippingProperties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, pointClippingBehavior);
|
2017-10-06 00:50:15 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-10 02:41:30 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceDiscardRectanglePropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceDiscardRectanglePropertiesEXT*)ext;
|
|
|
|
|
|
properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-25 18:12:14 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceExternalMemoryHostPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext;
|
|
|
|
|
|
properties->minImportedHostPointerAlignment = 4096;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-21 15:06:10 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceSubgroupProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceSubgroupProperties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, subgroupSize);
|
|
|
|
|
|
CORE_RENAMED_PROPERTY(1, 1, supportedStages,
|
|
|
|
|
|
subgroupSupportedStages);
|
|
|
|
|
|
CORE_RENAMED_PROPERTY(1, 1, supportedOperations,
|
|
|
|
|
|
subgroupSupportedOperations);
|
|
|
|
|
|
CORE_RENAMED_PROPERTY(1, 1, quadOperationsInAllStages,
|
|
|
|
|
|
subgroupQuadOperationsInAllStages);
|
2018-01-21 15:06:10 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-01-21 15:53:03 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceMaintenance3Properties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceMaintenance3Properties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, maxPerSetDescriptors);
|
|
|
|
|
|
CORE_PROPERTY(1, 1, maxMemoryAllocationSize);
|
2018-01-21 15:53:03 +01:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 08:58:55 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceSamplerFilterMinmaxProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceSamplerFilterMinmaxProperties *)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, filterMinmaxImageComponentMapping);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, filterMinmaxSingleComponentFormats);
|
2018-03-25 20:05:42 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-04-06 12:40:33 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD: {
|
|
|
|
|
|
VkPhysicalDeviceShaderCorePropertiesAMD *properties =
|
|
|
|
|
|
(VkPhysicalDeviceShaderCorePropertiesAMD *)ext;
|
|
|
|
|
|
|
|
|
|
|
|
/* Shader engines. */
|
|
|
|
|
|
properties->shaderEngineCount =
|
|
|
|
|
|
pdevice->rad_info.max_se;
|
|
|
|
|
|
properties->shaderArraysPerEngineCount =
|
2020-11-10 21:37:39 -05:00
|
|
|
|
pdevice->rad_info.max_sa_per_se;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->computeUnitsPerShaderArray =
|
2020-05-22 08:04:07 -04:00
|
|
|
|
pdevice->rad_info.min_good_cu_per_sa;
|
2020-02-20 09:24:38 +01:00
|
|
|
|
properties->simdPerComputeUnit =
|
|
|
|
|
|
pdevice->rad_info.num_simd_per_compute_unit;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->wavefrontsPerSimd =
|
2020-02-20 09:27:07 +01:00
|
|
|
|
pdevice->rad_info.max_wave64_per_simd;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->wavefrontSize = 64;
|
|
|
|
|
|
|
|
|
|
|
|
/* SGPR. */
|
|
|
|
|
|
properties->sgprsPerSimd =
|
2019-09-12 19:46:02 -04:00
|
|
|
|
pdevice->rad_info.num_physical_sgprs_per_simd;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->minSgprAllocation =
|
2020-02-20 09:25:44 +01:00
|
|
|
|
pdevice->rad_info.min_sgpr_alloc;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->maxSgprAllocation =
|
2020-02-20 09:25:44 +01:00
|
|
|
|
pdevice->rad_info.max_sgpr_alloc;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
properties->sgprAllocationGranularity =
|
2020-02-20 09:25:44 +01:00
|
|
|
|
pdevice->rad_info.sgpr_alloc_granularity;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
|
|
|
|
|
|
/* VGPR. */
|
2020-02-20 09:25:44 +01:00
|
|
|
|
properties->vgprsPerSimd =
|
|
|
|
|
|
pdevice->rad_info.num_physical_wave64_vgprs_per_simd;
|
|
|
|
|
|
properties->minVgprAllocation =
|
2020-03-02 09:07:52 +01:00
|
|
|
|
pdevice->rad_info.min_wave64_vgpr_alloc;
|
2020-02-20 09:25:44 +01:00
|
|
|
|
properties->maxVgprAllocation =
|
|
|
|
|
|
pdevice->rad_info.max_vgpr_alloc;
|
|
|
|
|
|
properties->vgprAllocationGranularity =
|
2020-02-27 08:47:54 +01:00
|
|
|
|
pdevice->rad_info.wave64_vgpr_alloc_granularity;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-08-21 09:04:46 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD: {
|
|
|
|
|
|
VkPhysicalDeviceShaderCoreProperties2AMD *properties =
|
|
|
|
|
|
(VkPhysicalDeviceShaderCoreProperties2AMD *)ext;
|
|
|
|
|
|
|
|
|
|
|
|
properties->shaderCoreFeatures = 0;
|
|
|
|
|
|
properties->activeComputeUnitCount =
|
|
|
|
|
|
pdevice->rad_info.num_good_compute_units;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-04-08 10:15:21 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
|
|
|
|
|
|
properties->maxVertexAttribDivisor = UINT32_MAX;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 14:01:43 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceDescriptorIndexingProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceDescriptorIndexingProperties*)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, maxUpdateAfterBindDescriptorsInAllPools);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderUniformBufferArrayNonUniformIndexingNative);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderSampledImageArrayNonUniformIndexingNative);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderStorageBufferArrayNonUniformIndexingNative);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderStorageImageArrayNonUniformIndexingNative);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderInputAttachmentArrayNonUniformIndexingNative);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, robustBufferAccessUpdateAfterBind);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, quadDivergentImplicitLod);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSamplers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindUniformBuffers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageBuffers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSampledImages);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageImages);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindInputAttachments);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxPerStageUpdateAfterBindResources);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSamplers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffers);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSampledImages);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageImages);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindInputAttachments);
|
2018-04-11 19:08:30 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-08-30 11:43:47 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceProtectedMemoryProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceProtectedMemoryProperties *)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 1, protectedNoFault);
|
2018-08-30 11:43:47 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-09-17 16:34:11 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceConservativeRasterizationPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceConservativeRasterizationPropertiesEXT *)ext;
|
|
|
|
|
|
properties->primitiveOverestimationSize = 0;
|
|
|
|
|
|
properties->maxExtraPrimitiveOverestimationSize = 0;
|
|
|
|
|
|
properties->extraPrimitiveOverestimationSizeGranularity = 0;
|
2019-12-05 18:04:32 +01:00
|
|
|
|
properties->primitiveUnderestimation = false;
|
|
|
|
|
|
properties->conservativePointAndLineRasterization = false;
|
|
|
|
|
|
properties->degenerateTrianglesRasterized = false;
|
|
|
|
|
|
properties->degenerateLinesRasterized = false;
|
|
|
|
|
|
properties->fullyCoveredFragmentShaderInputVariable = false;
|
|
|
|
|
|
properties->conservativeRasterizationPostDepthCoverage = false;
|
2018-09-17 16:34:11 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#ifndef _WIN32
|
2018-10-13 19:20:02 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDevicePCIBusInfoPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDevicePCIBusInfoPropertiesEXT *)ext;
|
|
|
|
|
|
properties->pciDomain = pdevice->bus_info.domain;
|
|
|
|
|
|
properties->pciBus = pdevice->bus_info.bus;
|
|
|
|
|
|
properties->pciDevice = pdevice->bus_info.dev;
|
|
|
|
|
|
properties->pciFunction = pdevice->bus_info.func;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-12-03 02:15:50 -08:00
|
|
|
|
#endif
|
2019-10-15 09:24:07 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES: {
|
2020-01-29 15:02:26 +01:00
|
|
|
|
VkPhysicalDeviceDriverProperties *properties =
|
2019-10-15 09:24:07 +02:00
|
|
|
|
(VkPhysicalDeviceDriverProperties *) ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, driverID);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, driverName);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, driverInfo);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, conformanceVersion);
|
2018-09-30 20:02:04 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2018-10-05 18:04:56 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceTransformFeedbackPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
|
|
|
|
|
|
properties->maxTransformFeedbackStreams = MAX_SO_STREAMS;
|
|
|
|
|
|
properties->maxTransformFeedbackBuffers = MAX_SO_BUFFERS;
|
|
|
|
|
|
properties->maxTransformFeedbackBufferSize = UINT32_MAX;
|
|
|
|
|
|
properties->maxTransformFeedbackStreamDataSize = 512;
|
2020-12-03 16:15:46 +01:00
|
|
|
|
properties->maxTransformFeedbackBufferDataSize = 512;
|
2018-10-05 18:04:56 +02:00
|
|
|
|
properties->maxTransformFeedbackBufferDataStride = 512;
|
2019-09-11 09:22:29 +02:00
|
|
|
|
properties->transformFeedbackQueries = !pdevice->use_ngg_streamout;
|
|
|
|
|
|
properties->transformFeedbackStreamsLinesTriangles = !pdevice->use_ngg_streamout;
|
2018-10-05 18:04:56 +02:00
|
|
|
|
properties->transformFeedbackRasterizationStreamSelect = false;
|
|
|
|
|
|
properties->transformFeedbackDraw = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-03-14 11:20:53 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceInlineUniformBlockPropertiesEXT *props =
|
|
|
|
|
|
(VkPhysicalDeviceInlineUniformBlockPropertiesEXT *)ext;
|
|
|
|
|
|
|
|
|
|
|
|
props->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;
|
|
|
|
|
|
props->maxPerStageDescriptorInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_SETS;
|
|
|
|
|
|
props->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_SETS;
|
|
|
|
|
|
props->maxDescriptorSetInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_COUNT;
|
|
|
|
|
|
props->maxDescriptorSetUpdateAfterBindInlineUniformBlocks = MAX_INLINE_UNIFORM_BLOCK_COUNT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-05-16 11:55:02 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceSampleLocationsPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceSampleLocationsPropertiesEXT *)ext;
|
2020-12-01 12:33:05 +01:00
|
|
|
|
|
|
|
|
|
|
VkSampleCountFlagBits supported_samples = VK_SAMPLE_COUNT_2_BIT |
|
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT;
|
|
|
|
|
|
if (pdevice->rad_info.chip_class < GFX10) {
|
|
|
|
|
|
/* FIXME: Some MSAA8x tests fail for weird
|
|
|
|
|
|
* reasons on GFX10+ when the same pattern is
|
|
|
|
|
|
* used inside the same render pass.
|
|
|
|
|
|
*/
|
|
|
|
|
|
supported_samples |= VK_SAMPLE_COUNT_8_BIT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
properties->sampleLocationSampleCounts = supported_samples;
|
2019-05-16 11:55:02 +02:00
|
|
|
|
properties->maxSampleLocationGridSize = (VkExtent2D){ 2 , 2 };
|
|
|
|
|
|
properties->sampleLocationCoordinateRange[0] = 0.0f;
|
|
|
|
|
|
properties->sampleLocationCoordinateRange[1] = 0.9375f;
|
|
|
|
|
|
properties->sampleLocationSubPixelBits = 4;
|
2019-12-05 18:04:32 +01:00
|
|
|
|
properties->variableSampleLocations = false;
|
2019-05-16 11:55:02 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-15 09:20:48 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES: {
|
|
|
|
|
|
VkPhysicalDeviceDepthStencilResolveProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceDepthStencilResolveProperties *)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, supportedDepthResolveModes);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, supportedStencilResolveModes);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, independentResolveNone);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, independentResolve);
|
2019-05-20 11:46:33 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-10 11:40:27 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT *)ext;
|
|
|
|
|
|
properties->storageTexelBufferOffsetAlignmentBytes = 4;
|
|
|
|
|
|
properties->storageTexelBufferOffsetSingleTexelAlignment = true;
|
|
|
|
|
|
properties->uniformTexelBufferOffsetAlignmentBytes = 4;
|
|
|
|
|
|
properties->uniformTexelBufferOffsetSingleTexelAlignment = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-26 14:07:07 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES : {
|
|
|
|
|
|
VkPhysicalDeviceFloatControlsProperties *properties =
|
|
|
|
|
|
(VkPhysicalDeviceFloatControlsProperties *)ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, denormBehaviorIndependence);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, roundingModeIndependence);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat16);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormPreserveFloat16);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat16);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat16);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat16);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat32);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormPreserveFloat32);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat32);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat32);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat32);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat64);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderDenormPreserveFloat64);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat64);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat64);
|
|
|
|
|
|
CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat64);
|
2019-10-14 11:27:32 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-11-25 20:50:12 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES: {
|
2020-01-29 15:02:26 +01:00
|
|
|
|
VkPhysicalDeviceTimelineSemaphoreProperties *properties =
|
2019-11-25 20:50:12 +01:00
|
|
|
|
(VkPhysicalDeviceTimelineSemaphoreProperties *) ext;
|
2020-01-29 15:02:26 +01:00
|
|
|
|
CORE_PROPERTY(1, 2, maxTimelineSemaphoreValueDifference);
|
2019-10-25 10:26:50 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-31 10:55:37 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *props =
|
|
|
|
|
|
(VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *)ext;
|
|
|
|
|
|
props->minSubgroupSize = 64;
|
|
|
|
|
|
props->maxSubgroupSize = 64;
|
|
|
|
|
|
props->maxComputeWorkgroupSubgroups = UINT32_MAX;
|
|
|
|
|
|
props->requiredSubgroupSizeStages = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (pdevice->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
/* Only GFX10+ supports wave32. */
|
|
|
|
|
|
props->minSubgroupSize = 32;
|
|
|
|
|
|
props->requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-01-29 15:02:26 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
|
|
|
|
|
|
radv_get_physical_device_properties_1_1(pdevice, (void *)ext);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
|
|
|
|
|
|
radv_get_physical_device_properties_1_2(pdevice, (void *)ext);
|
2019-11-26 08:34:33 +01:00
|
|
|
|
break;
|
2019-09-13 13:40:44 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
|
|
|
|
|
|
(VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
|
|
|
|
|
|
props->lineSubPixelPrecisionBits = 4;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-15 11:39:28 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceRobustness2PropertiesEXT *properties =
|
|
|
|
|
|
(VkPhysicalDeviceRobustness2PropertiesEXT *)ext;
|
|
|
|
|
|
properties->robustStorageBufferAccessSizeAlignment = 4;
|
|
|
|
|
|
properties->robustUniformBufferAccessSizeAlignment = 4;
|
2020-05-19 11:53:13 +02:00
|
|
|
|
break;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_PROPERTIES_EXT: {
|
|
|
|
|
|
VkPhysicalDeviceCustomBorderColorPropertiesEXT *props =
|
|
|
|
|
|
(VkPhysicalDeviceCustomBorderColorPropertiesEXT *)ext;
|
|
|
|
|
|
props->maxCustomBorderColorSamplers = RADV_BORDER_COLOR_COUNT;
|
2020-04-15 11:39:28 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-11-30 18:54:06 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR: {
|
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRatePropertiesKHR *props =
|
|
|
|
|
|
(VkPhysicalDeviceFragmentShadingRatePropertiesKHR *)ext;
|
|
|
|
|
|
props->minFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };
|
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSize = (VkExtent2D) { 0, 0 };
|
|
|
|
|
|
props->maxFragmentShadingRateAttachmentTexelSizeAspectRatio = 0;
|
|
|
|
|
|
props->primitiveFragmentShadingRateWithMultipleViewports = true;
|
|
|
|
|
|
props->layeredShadingRateAttachments = false;
|
|
|
|
|
|
props->fragmentShadingRateNonTrivialCombinerOps = true;
|
|
|
|
|
|
props->maxFragmentSize = (VkExtent2D) { 2, 2 };
|
|
|
|
|
|
props->maxFragmentSizeAspectRatio = 1;
|
2020-12-14 17:30:11 +01:00
|
|
|
|
props->maxFragmentShadingRateCoverageSamples = 2 * 2;
|
2020-12-15 10:34:59 +01:00
|
|
|
|
props->maxFragmentShadingRateRasterizationSamples = VK_SAMPLE_COUNT_8_BIT;
|
2020-11-30 18:54:06 +01:00
|
|
|
|
props->fragmentShadingRateWithShaderDepthStencilWrites = false;
|
|
|
|
|
|
props->fragmentShadingRateWithSampleMask = true;
|
|
|
|
|
|
props->fragmentShadingRateWithShaderSampleMask = false;
|
|
|
|
|
|
props->fragmentShadingRateWithConservativeRasterization = true;
|
|
|
|
|
|
props->fragmentShadingRateWithFragmentShaderInterlock = false;
|
|
|
|
|
|
props->fragmentShadingRateWithCustomSampleLocations = true;
|
|
|
|
|
|
props->fragmentShadingRateStrictMultiplyCombiner = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2017-03-29 18:12:44 +02:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-11-11 02:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-10 21:23:04 +01:00
|
|
|
|
static void radv_get_physical_device_queue_family_properties(
|
|
|
|
|
|
struct radv_physical_device* pdevice,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
uint32_t* pCount,
|
2017-02-10 21:23:04 +01:00
|
|
|
|
VkQueueFamilyProperties** pQueueFamilyProperties)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
2016-11-30 04:08:10 +00:00
|
|
|
|
int num_queue_families = 1;
|
|
|
|
|
|
int idx;
|
2019-11-14 17:43:12 -05:00
|
|
|
|
if (pdevice->rad_info.num_rings[RING_COMPUTE] > 0 &&
|
2017-01-02 18:57:02 +01:00
|
|
|
|
!(pdevice->instance->debug_flags & RADV_DEBUG_NO_COMPUTE_QUEUE))
|
|
|
|
|
|
num_queue_families++;
|
2016-11-30 04:08:10 +00:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (pQueueFamilyProperties == NULL) {
|
2016-11-30 04:08:10 +00:00
|
|
|
|
*pCount = num_queue_families;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2016-11-30 04:08:10 +00:00
|
|
|
|
|
|
|
|
|
|
if (!*pCount)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
idx = 0;
|
|
|
|
|
|
if (*pCount >= 1) {
|
2017-02-10 21:23:04 +01:00
|
|
|
|
*pQueueFamilyProperties[idx] = (VkQueueFamilyProperties) {
|
2016-11-30 04:08:10 +00:00
|
|
|
|
.queueFlags = VK_QUEUE_GRAPHICS_BIT |
|
2017-01-31 23:59:02 +01:00
|
|
|
|
VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT |
|
|
|
|
|
|
VK_QUEUE_SPARSE_BINDING_BIT,
|
2016-11-30 04:08:10 +00:00
|
|
|
|
.queueCount = 1,
|
|
|
|
|
|
.timestampValidBits = 64,
|
|
|
|
|
|
.minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
|
|
|
|
|
|
};
|
|
|
|
|
|
idx++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-14 17:43:12 -05:00
|
|
|
|
if (pdevice->rad_info.num_rings[RING_COMPUTE] > 0 &&
|
2017-01-02 18:57:02 +01:00
|
|
|
|
!(pdevice->instance->debug_flags & RADV_DEBUG_NO_COMPUTE_QUEUE)) {
|
2016-11-30 04:08:10 +00:00
|
|
|
|
if (*pCount > idx) {
|
2017-02-10 21:23:04 +01:00
|
|
|
|
*pQueueFamilyProperties[idx] = (VkQueueFamilyProperties) {
|
2017-01-31 23:59:02 +01:00
|
|
|
|
.queueFlags = VK_QUEUE_COMPUTE_BIT |
|
|
|
|
|
|
VK_QUEUE_TRANSFER_BIT |
|
|
|
|
|
|
VK_QUEUE_SPARSE_BINDING_BIT,
|
2019-11-14 17:43:12 -05:00
|
|
|
|
.queueCount = pdevice->rad_info.num_rings[RING_COMPUTE],
|
2016-11-30 04:08:10 +00:00
|
|
|
|
.timestampValidBits = 64,
|
|
|
|
|
|
.minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
|
|
|
|
|
|
};
|
|
|
|
|
|
idx++;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-12-25 00:41:45 +01:00
|
|
|
|
*pCount = idx;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-10 21:23:04 +01:00
|
|
|
|
void radv_GetPhysicalDeviceQueueFamilyProperties(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
uint32_t* pCount,
|
|
|
|
|
|
VkQueueFamilyProperties* pQueueFamilyProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
if (!pQueueFamilyProperties) {
|
2019-01-09 14:40:28 +01:00
|
|
|
|
radv_get_physical_device_queue_family_properties(pdevice, pCount, NULL);
|
2017-02-10 21:23:04 +01:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
VkQueueFamilyProperties *properties[] = {
|
|
|
|
|
|
pQueueFamilyProperties + 0,
|
|
|
|
|
|
pQueueFamilyProperties + 1,
|
|
|
|
|
|
pQueueFamilyProperties + 2,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_queue_family_properties(pdevice, pCount, properties);
|
|
|
|
|
|
assert(*pCount <= 3);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceQueueFamilyProperties2(
|
2016-11-11 02:27:21 +00:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
uint32_t* pCount,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkQueueFamilyProperties2 *pQueueFamilyProperties)
|
2016-11-11 02:27:21 +00:00
|
|
|
|
{
|
2017-02-10 21:23:04 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
if (!pQueueFamilyProperties) {
|
2019-01-09 14:40:28 +01:00
|
|
|
|
radv_get_physical_device_queue_family_properties(pdevice, pCount, NULL);
|
2017-02-10 21:23:04 +01:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
VkQueueFamilyProperties *properties[] = {
|
|
|
|
|
|
&pQueueFamilyProperties[0].queueFamilyProperties,
|
|
|
|
|
|
&pQueueFamilyProperties[1].queueFamilyProperties,
|
|
|
|
|
|
&pQueueFamilyProperties[2].queueFamilyProperties,
|
|
|
|
|
|
};
|
|
|
|
|
|
radv_get_physical_device_queue_family_properties(pdevice, pCount, properties);
|
|
|
|
|
|
assert(*pCount <= 3);
|
2016-11-11 02:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_GetPhysicalDeviceMemoryProperties(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2016-11-11 02:27:21 +00:00
|
|
|
|
VkPhysicalDeviceMemoryProperties *pMemoryProperties)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
*pMemoryProperties = physical_device->memory_properties;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-09 14:40:00 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_get_memory_budget_properties(VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
VkPhysicalDeviceMemoryBudgetPropertiesEXT *memoryBudget)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
|
|
|
|
|
|
VkPhysicalDeviceMemoryProperties *memory_properties = &device->memory_properties;
|
|
|
|
|
|
|
|
|
|
|
|
/* For all memory heaps, the computation of budget is as follow:
|
|
|
|
|
|
* heap_budget = heap_size - global_heap_usage + app_heap_usage
|
|
|
|
|
|
*
|
|
|
|
|
|
* The Vulkan spec 1.1.97 says that the budget should include any
|
|
|
|
|
|
* currently allocated device memory.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Note that the application heap usages are not really accurate (eg.
|
|
|
|
|
|
* in presence of shared buffers).
|
|
|
|
|
|
*/
|
2020-09-23 02:14:30 +02:00
|
|
|
|
unsigned mask = device->heaps;
|
|
|
|
|
|
unsigned heap = 0;
|
|
|
|
|
|
while (mask) {
|
|
|
|
|
|
uint64_t internal_usage = 0, total_usage = 0;
|
|
|
|
|
|
unsigned type = 1u << u_bit_scan(&mask);
|
|
|
|
|
|
|
|
|
|
|
|
switch(type) {
|
|
|
|
|
|
case RADV_HEAP_VRAM:
|
|
|
|
|
|
internal_usage = device->ws->query_value(device->ws, RADEON_ALLOCATED_VRAM);
|
|
|
|
|
|
total_usage = device->ws->query_value(device->ws, RADEON_VRAM_USAGE);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_HEAP_VRAM_VIS:
|
|
|
|
|
|
internal_usage = device->ws->query_value(device->ws, RADEON_ALLOCATED_VRAM_VIS);
|
|
|
|
|
|
if (!(device->heaps & RADV_HEAP_VRAM))
|
|
|
|
|
|
internal_usage += device->ws->query_value(device->ws, RADEON_ALLOCATED_VRAM);
|
|
|
|
|
|
total_usage = device->ws->query_value(device->ws, RADEON_VRAM_VIS_USAGE);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_HEAP_GTT:
|
|
|
|
|
|
internal_usage = device->ws->query_value(device->ws, RADEON_ALLOCATED_GTT);
|
|
|
|
|
|
total_usage = device->ws->query_value(device->ws, RADEON_GTT_USAGE);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t free_space = device->memory_properties.memoryHeaps[heap].size -
|
|
|
|
|
|
MIN2(device->memory_properties.memoryHeaps[heap].size,
|
|
|
|
|
|
total_usage);
|
|
|
|
|
|
memoryBudget->heapBudget[heap] = free_space + internal_usage;
|
|
|
|
|
|
memoryBudget->heapUsage[heap] = internal_usage;
|
|
|
|
|
|
++heap;
|
2019-01-09 14:40:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-23 02:14:30 +02:00
|
|
|
|
assert(heap == memory_properties->memoryHeapCount);
|
|
|
|
|
|
|
2019-01-09 14:40:00 +01:00
|
|
|
|
/* The heapBudget and heapUsage values must be zero for array elements
|
|
|
|
|
|
* greater than or equal to
|
|
|
|
|
|
* VkPhysicalDeviceMemoryProperties::memoryHeapCount.
|
|
|
|
|
|
*/
|
|
|
|
|
|
for (uint32_t i = memory_properties->memoryHeapCount; i < VK_MAX_MEMORY_HEAPS; i++) {
|
|
|
|
|
|
memoryBudget->heapBudget[i] = 0;
|
|
|
|
|
|
memoryBudget->heapUsage[i] = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceMemoryProperties2(
|
2016-11-11 02:27:21 +00:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
|
2016-11-11 02:27:21 +00:00
|
|
|
|
{
|
2019-01-09 14:40:28 +01:00
|
|
|
|
radv_GetPhysicalDeviceMemoryProperties(physicalDevice,
|
|
|
|
|
|
&pMemoryProperties->memoryProperties);
|
2019-01-09 14:40:00 +01:00
|
|
|
|
|
|
|
|
|
|
VkPhysicalDeviceMemoryBudgetPropertiesEXT *memory_budget =
|
|
|
|
|
|
vk_find_struct(pMemoryProperties->pNext,
|
|
|
|
|
|
PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT);
|
|
|
|
|
|
if (memory_budget)
|
|
|
|
|
|
radv_get_memory_budget_properties(physicalDevice, memory_budget);
|
2016-11-11 02:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-25 18:12:14 +01:00
|
|
|
|
VkResult radv_GetMemoryHostPointerPropertiesEXT(
|
|
|
|
|
|
VkDevice _device,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkExternalMemoryHandleTypeFlagBits handleType,
|
2018-01-25 18:12:14 +01:00
|
|
|
|
const void *pHostPointer,
|
|
|
|
|
|
VkMemoryHostPointerPropertiesEXT *pMemoryHostPointerProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
|
|
switch (handleType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: {
|
|
|
|
|
|
const struct radv_physical_device *physical_device = device->physical_device;
|
|
|
|
|
|
uint32_t memoryTypeBits = 0;
|
|
|
|
|
|
for (int i = 0; i < physical_device->memory_properties.memoryTypeCount; i++) {
|
2020-04-25 23:52:44 +02:00
|
|
|
|
if (physical_device->memory_domains[i] == RADEON_DOMAIN_GTT &&
|
|
|
|
|
|
!(physical_device->memory_flags[i] & RADEON_FLAG_GTT_WC)) {
|
2018-01-25 18:12:14 +01:00
|
|
|
|
memoryTypeBits = (1 << i);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
pMemoryHostPointerProperties->memoryTypeBits = memoryTypeBits;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
2019-01-08 14:30:32 +01:00
|
|
|
|
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
2018-01-25 18:12:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-20 18:02:14 -04:00
|
|
|
|
static enum radeon_ctx_priority
|
|
|
|
|
|
radv_get_queue_global_priority(const VkDeviceQueueGlobalPriorityCreateInfoEXT *pObj)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Default to MEDIUM when a specific global priority isn't requested */
|
|
|
|
|
|
if (!pObj)
|
|
|
|
|
|
return RADEON_CTX_PRIORITY_MEDIUM;
|
|
|
|
|
|
|
|
|
|
|
|
switch(pObj->globalPriority) {
|
2017-11-27 18:28:51 -08:00
|
|
|
|
case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
|
2017-10-20 18:02:14 -04:00
|
|
|
|
return RADEON_CTX_PRIORITY_REALTIME;
|
2017-11-27 18:28:51 -08:00
|
|
|
|
case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
|
2017-10-20 18:02:14 -04:00
|
|
|
|
return RADEON_CTX_PRIORITY_HIGH;
|
2017-11-27 18:28:51 -08:00
|
|
|
|
case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
|
2017-10-20 18:02:14 -04:00
|
|
|
|
return RADEON_CTX_PRIORITY_MEDIUM;
|
2017-11-27 18:28:51 -08:00
|
|
|
|
case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
|
2017-10-20 18:02:14 -04:00
|
|
|
|
return RADEON_CTX_PRIORITY_LOW;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Illegal global priority value");
|
|
|
|
|
|
return RADEON_CTX_PRIORITY_INVALID;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
static int
|
2016-11-30 04:30:06 +00:00
|
|
|
|
radv_queue_init(struct radv_device *device, struct radv_queue *queue,
|
2017-11-14 17:29:18 +01:00
|
|
|
|
uint32_t queue_family_index, int idx,
|
2018-03-13 21:54:53 +01:00
|
|
|
|
VkDeviceQueueCreateFlags flags,
|
2017-10-20 18:02:14 -04:00
|
|
|
|
const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
queue->device = device;
|
2016-11-30 04:30:06 +00:00
|
|
|
|
queue->queue_family_index = queue_family_index;
|
|
|
|
|
|
queue->queue_idx = idx;
|
2017-10-20 18:02:14 -04:00
|
|
|
|
queue->priority = radv_get_queue_global_priority(global_priority);
|
2018-03-13 21:54:53 +01:00
|
|
|
|
queue->flags = flags;
|
2017-01-13 18:44:15 -05:00
|
|
|
|
|
2021-01-25 11:23:58 +10:00
|
|
|
|
vk_object_base_init(&device->vk, &queue->base, VK_OBJECT_TYPE_QUEUE);
|
|
|
|
|
|
|
2020-04-29 23:13:17 +02:00
|
|
|
|
VkResult result = device->ws->ctx_create(device->ws, queue->priority, &queue->hw_ctx);
|
2021-01-25 11:23:58 +10:00
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
|
vk_object_base_finish(&queue->base);
|
2020-04-29 23:13:17 +02:00
|
|
|
|
return vk_error(device->instance, result);
|
2021-01-25 11:23:58 +10:00
|
|
|
|
}
|
2017-01-13 18:44:15 -05:00
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
list_inithead(&queue->pending_submissions);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_init(&queue->pending_mutex, mtx_plain);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_init(&queue->thread_mutex, mtx_plain);
|
2020-10-31 16:18:34 -07:00
|
|
|
|
if (u_cnd_monotonic_init(&queue->thread_cond)) {
|
2021-01-25 11:23:58 +10:00
|
|
|
|
device->ws->ctx_destroy(queue->hw_ctx);
|
|
|
|
|
|
vk_object_base_finish(&queue->base);
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_INITIALIZATION_FAILED);
|
2020-10-31 16:18:34 -07:00
|
|
|
|
}
|
2020-11-12 23:08:17 -08:00
|
|
|
|
queue->cond_created = true;
|
2020-06-22 22:07:46 +02:00
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
return VK_SUCCESS;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_queue_finish(struct radv_queue *queue)
|
|
|
|
|
|
{
|
2020-11-12 23:08:17 -08:00
|
|
|
|
if (queue->hw_ctx) {
|
|
|
|
|
|
if (queue->cond_created) {
|
|
|
|
|
|
if (queue->thread_running) {
|
|
|
|
|
|
p_atomic_set(&queue->thread_exit, true);
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_broadcast(&queue->thread_cond);
|
2020-11-26 19:31:42 -08:00
|
|
|
|
thrd_join(queue->submission_thread, NULL);
|
2020-11-12 23:08:17 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_destroy(&queue->thread_cond);
|
2020-11-12 23:08:17 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_destroy(&queue->pending_mutex);
|
|
|
|
|
|
mtx_destroy(&queue->thread_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
queue->device->ws->ctx_destroy(queue->hw_ctx);
|
2020-11-12 23:08:17 -08:00
|
|
|
|
}
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
if (queue->initial_full_flush_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->initial_full_flush_preamble_cs);
|
2017-02-20 09:26:00 +01:00
|
|
|
|
if (queue->initial_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->initial_preamble_cs);
|
|
|
|
|
|
if (queue->continue_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->continue_preamble_cs);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (queue->descriptor_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->descriptor_bo);
|
|
|
|
|
|
if (queue->scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->scratch_bo);
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (queue->esgs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->esgs_ring_bo);
|
|
|
|
|
|
if (queue->gsvs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->gsvs_ring_bo);
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (queue->tess_rings_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->tess_rings_bo);
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (queue->gds_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->gds_bo);
|
|
|
|
|
|
if (queue->gds_oa_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->gds_oa_bo);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (queue->compute_scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->compute_scratch_bo);
|
2021-01-25 11:23:58 +10:00
|
|
|
|
|
|
|
|
|
|
vk_object_base_finish(&queue->base);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_bo_list_init(struct radv_bo_list *bo_list)
|
|
|
|
|
|
{
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_init(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
bo_list->list.count = bo_list->capacity = 0;
|
|
|
|
|
|
bo_list->list.bos = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_bo_list_finish(struct radv_bo_list *bo_list)
|
|
|
|
|
|
{
|
|
|
|
|
|
free(bo_list->list.bos);
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_destroy(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-24 17:59:26 +01:00
|
|
|
|
VkResult radv_bo_list_add(struct radv_device *device,
|
|
|
|
|
|
struct radeon_winsys_bo *bo)
|
2018-04-09 12:46:49 +02:00
|
|
|
|
{
|
2018-04-19 13:48:33 +02:00
|
|
|
|
struct radv_bo_list *bo_list = &device->bo_list;
|
|
|
|
|
|
|
2019-01-25 01:56:45 +01:00
|
|
|
|
if (bo->is_local)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
|
if (unlikely(!device->use_global_bo_list))
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_wrlock(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
if (bo_list->list.count == bo_list->capacity) {
|
|
|
|
|
|
unsigned capacity = MAX2(4, bo_list->capacity * 2);
|
|
|
|
|
|
void *data = realloc(bo_list->list.bos, capacity * sizeof(struct radeon_winsys_bo*));
|
|
|
|
|
|
|
|
|
|
|
|
if (!data) {
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_wrunlock(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bo_list->list.bos = (struct radeon_winsys_bo**)data;
|
|
|
|
|
|
bo_list->capacity = capacity;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bo_list->list.bos[bo_list->list.count++] = bo;
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_wrunlock(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-24 17:59:26 +01:00
|
|
|
|
void radv_bo_list_remove(struct radv_device *device,
|
|
|
|
|
|
struct radeon_winsys_bo *bo)
|
2018-04-09 12:46:49 +02:00
|
|
|
|
{
|
2018-04-19 13:48:33 +02:00
|
|
|
|
struct radv_bo_list *bo_list = &device->bo_list;
|
|
|
|
|
|
|
2019-01-25 01:56:45 +01:00
|
|
|
|
if (bo->is_local)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
|
if (unlikely(!device->use_global_bo_list))
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_wrlock(&bo_list->rwlock);
|
2020-03-24 17:59:26 +01:00
|
|
|
|
/* Loop the list backwards so we find the most recently added
|
|
|
|
|
|
* memory first. */
|
|
|
|
|
|
for(unsigned i = bo_list->list.count; i-- > 0;) {
|
2018-04-09 12:46:49 +02:00
|
|
|
|
if (bo_list->list.bos[i] == bo) {
|
|
|
|
|
|
bo_list->list.bos[i] = bo_list->list.bos[bo_list->list.count - 1];
|
|
|
|
|
|
--bo_list->list.count;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_wrunlock(&bo_list->rwlock);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-18 13:54:17 +10:00
|
|
|
|
static void
|
|
|
|
|
|
radv_device_init_gs_info(struct radv_device *device)
|
|
|
|
|
|
{
|
2018-04-23 09:57:10 +10:00
|
|
|
|
device->gs_table_depth = ac_get_gs_table_depth(device->physical_device->rad_info.chip_class,
|
|
|
|
|
|
device->physical_device->rad_info.family);
|
2017-01-18 13:54:17 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-11 00:32:34 +01:00
|
|
|
|
static int radv_get_device_extension_index(const char *name)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (unsigned i = 0; i < RADV_DEVICE_EXTENSION_COUNT; ++i) {
|
|
|
|
|
|
if (strcmp(name, radv_device_extensions[i].extensionName) == 0)
|
|
|
|
|
|
return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-17 22:23:19 +02:00
|
|
|
|
static int
|
|
|
|
|
|
radv_get_int_debug_option(const char *name, int default_value)
|
|
|
|
|
|
{
|
|
|
|
|
|
const char *str;
|
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
|
|
|
|
str = getenv(name);
|
|
|
|
|
|
if (!str) {
|
|
|
|
|
|
result = default_value;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
char *endptr;
|
|
|
|
|
|
|
|
|
|
|
|
result = strtol(str, &endptr, 0);
|
|
|
|
|
|
if (str == endptr) {
|
|
|
|
|
|
/* No digits founs. */
|
|
|
|
|
|
result = default_value;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-01 14:49:35 +02:00
|
|
|
|
static bool radv_thread_trace_enabled()
|
|
|
|
|
|
{
|
2020-09-01 14:59:55 +02:00
|
|
|
|
return radv_get_int_debug_option("RADV_THREAD_TRACE", -1) >= 0 ||
|
|
|
|
|
|
getenv("RADV_THREAD_TRACE_TRIGGER");
|
2020-09-01 14:49:35 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_device_init_dispatch(struct radv_device *device)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct radv_instance *instance = device->physical_device->instance;
|
2020-02-26 13:59:05 +01:00
|
|
|
|
const struct radv_device_dispatch_table *dispatch_table_layer = NULL;
|
|
|
|
|
|
|
2020-09-01 14:49:35 +02:00
|
|
|
|
if (radv_thread_trace_enabled()) {
|
2020-02-26 13:59:05 +01:00
|
|
|
|
/* Use device entrypoints from the SQTT layer if enabled. */
|
|
|
|
|
|
dispatch_table_layer = &sqtt_device_dispatch_table;
|
|
|
|
|
|
}
|
2020-02-24 17:24:03 +01:00
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < ARRAY_SIZE(device->dispatch.entrypoints); i++) {
|
|
|
|
|
|
/* Vulkan requires that entrypoints for extensions which have not been
|
|
|
|
|
|
* enabled must not be advertised.
|
|
|
|
|
|
*/
|
2021-01-25 11:32:22 +10:00
|
|
|
|
if (!radv_device_entrypoint_is_enabled(i, instance->apiVersion,
|
2020-02-24 17:24:03 +01:00
|
|
|
|
&instance->enabled_extensions,
|
|
|
|
|
|
&device->enabled_extensions)) {
|
|
|
|
|
|
device->dispatch.entrypoints[i] = NULL;
|
2020-02-26 13:59:05 +01:00
|
|
|
|
} else if (dispatch_table_layer &&
|
|
|
|
|
|
dispatch_table_layer->entrypoints[i]) {
|
|
|
|
|
|
device->dispatch.entrypoints[i] =
|
|
|
|
|
|
dispatch_table_layer->entrypoints[i];
|
2020-02-24 17:24:03 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
device->dispatch.entrypoints[i] =
|
|
|
|
|
|
radv_device_dispatch_table.entrypoints[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-23 14:05:07 +02:00
|
|
|
|
static VkResult
|
|
|
|
|
|
check_physical_device_features(VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
const VkPhysicalDeviceFeatures *features)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
VkPhysicalDeviceFeatures supported_features;
|
|
|
|
|
|
radv_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
|
|
|
|
|
|
VkBool32 *supported_feature = (VkBool32 *)&supported_features;
|
|
|
|
|
|
VkBool32 *enabled_feature = (VkBool32 *)features;
|
|
|
|
|
|
unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
|
|
|
|
|
|
for (uint32_t i = 0; i < num_features; i++) {
|
|
|
|
|
|
if (enabled_feature[i] && !supported_feature[i])
|
|
|
|
|
|
return vk_error(physical_device->instance, VK_ERROR_FEATURE_NOT_PRESENT);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
static VkResult radv_device_init_border_color(struct radv_device *device)
|
|
|
|
|
|
{
|
|
|
|
|
|
device->border_color_data.bo =
|
|
|
|
|
|
device->ws->buffer_create(device->ws,
|
|
|
|
|
|
RADV_BORDER_COLOR_BUFFER_SIZE,
|
|
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
|
|
|
|
|
RADEON_FLAG_CPU_ACCESS |
|
|
|
|
|
|
RADEON_FLAG_READ_ONLY |
|
|
|
|
|
|
RADEON_FLAG_NO_INTERPROCESS_SHARING,
|
|
|
|
|
|
RADV_BO_PRIORITY_SHADER);
|
|
|
|
|
|
|
|
|
|
|
|
if (device->border_color_data.bo == NULL)
|
|
|
|
|
|
return vk_error(device->physical_device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
|
|
|
|
|
|
|
|
|
|
|
device->border_color_data.colors_gpu_ptr =
|
|
|
|
|
|
device->ws->buffer_map(device->border_color_data.bo);
|
2020-06-20 21:12:01 +02:00
|
|
|
|
if (!device->border_color_data.colors_gpu_ptr)
|
|
|
|
|
|
return vk_error(device->physical_device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_init(&device->border_color_data.mutex, mtx_plain);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void radv_device_finish_border_color(struct radv_device *device)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (device->border_color_data.bo) {
|
|
|
|
|
|
device->ws->buffer_destroy(device->border_color_data.bo);
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_destroy(&device->border_color_data.mutex);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
VkResult
|
|
|
|
|
|
_radv_device_set_lost(struct radv_device *device,
|
|
|
|
|
|
const char *file, int line,
|
|
|
|
|
|
const char *msg, ...)
|
|
|
|
|
|
{
|
|
|
|
|
|
VkResult err;
|
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
|
|
p_atomic_inc(&device->lost);
|
|
|
|
|
|
|
|
|
|
|
|
va_start(ap, msg);
|
|
|
|
|
|
err = __vk_errorv(device->physical_device->instance, device,
|
|
|
|
|
|
VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT,
|
|
|
|
|
|
VK_ERROR_DEVICE_LOST, file, line, msg, ap);
|
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateDevice(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
const VkDeviceCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkDevice* pDevice)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
struct radv_device *device;
|
|
|
|
|
|
|
2017-10-27 14:25:05 +01:00
|
|
|
|
bool keep_shader_info = false;
|
2020-04-23 14:05:07 +02:00
|
|
|
|
bool robust_buffer_access = false;
|
2020-11-30 15:29:31 +00:00
|
|
|
|
bool robust_buffer_access2 = false;
|
2020-04-28 13:10:56 +02:00
|
|
|
|
bool overallocation_disallowed = false;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
bool custom_border_colors = false;
|
2020-12-11 13:35:45 +01:00
|
|
|
|
bool vrs_enabled = false;
|
2017-10-27 14:25:05 +01:00
|
|
|
|
|
2017-07-24 07:16:40 +01:00
|
|
|
|
/* Check enabled features */
|
|
|
|
|
|
if (pCreateInfo->pEnabledFeatures) {
|
2020-04-23 14:05:07 +02:00
|
|
|
|
result = check_physical_device_features(physicalDevice,
|
|
|
|
|
|
pCreateInfo->pEnabledFeatures);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
if (pCreateInfo->pEnabledFeatures->robustBufferAccess)
|
|
|
|
|
|
robust_buffer_access = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vk_foreach_struct_const(ext, pCreateInfo->pNext) {
|
|
|
|
|
|
switch (ext->sType) {
|
|
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
|
|
|
|
|
|
const VkPhysicalDeviceFeatures2 *features = (const void *)ext;
|
|
|
|
|
|
result = check_physical_device_features(physicalDevice,
|
|
|
|
|
|
&features->features);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
if (features->features.robustBufferAccess)
|
|
|
|
|
|
robust_buffer_access = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-28 13:10:56 +02:00
|
|
|
|
case VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD: {
|
|
|
|
|
|
const VkDeviceMemoryOverallocationCreateInfoAMD *overallocation = (const void *)ext;
|
|
|
|
|
|
if (overallocation->overallocationBehavior == VK_MEMORY_OVERALLOCATION_BEHAVIOR_DISALLOWED_AMD)
|
|
|
|
|
|
overallocation_disallowed = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-07 06:11:24 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT: {
|
|
|
|
|
|
const VkPhysicalDeviceCustomBorderColorFeaturesEXT *border_color_features = (const void *)ext;
|
|
|
|
|
|
custom_border_colors = border_color_features->customBorderColors;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-12-11 13:35:45 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR: {
|
|
|
|
|
|
const VkPhysicalDeviceFragmentShadingRateFeaturesKHR *vrs = (const void *)ext;
|
|
|
|
|
|
vrs_enabled = vrs->pipelineFragmentShadingRate ||
|
|
|
|
|
|
vrs->primitiveFragmentShadingRate ||
|
|
|
|
|
|
vrs->attachmentFragmentShadingRate;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-11-30 15:29:31 +00:00
|
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT: {
|
|
|
|
|
|
const VkPhysicalDeviceRobustness2FeaturesEXT *features = (const void *)ext;
|
|
|
|
|
|
if (features->robustBufferAccess2)
|
|
|
|
|
|
robust_buffer_access2 = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-04-23 14:05:07 +02:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
2017-07-24 07:16:40 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-10 09:18:02 +01:00
|
|
|
|
device = vk_zalloc2(&physical_device->instance->alloc, pAllocator,
|
|
|
|
|
|
sizeof(*device), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!device)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(physical_device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2021-01-23 13:06:02 -06:00
|
|
|
|
result = vk_device_init(&device->vk, NULL, NULL, pCreateInfo,
|
2021-01-24 09:26:24 -06:00
|
|
|
|
&physical_device->instance->alloc, pAllocator);
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
|
vk_free(&device->vk.alloc, device);
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
2020-04-29 10:16:32 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
device->instance = physical_device->instance;
|
2017-01-16 21:23:48 +01:00
|
|
|
|
device->physical_device = physical_device;
|
2017-01-02 18:57:02 +01:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
device->ws = physical_device->ws;
|
|
|
|
|
|
|
2018-02-11 00:32:34 +01:00
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
|
|
|
|
|
|
const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
|
|
|
|
|
|
int index = radv_get_device_extension_index(ext_name);
|
|
|
|
|
|
if (index < 0 || !physical_device->supported_extensions.extensions[index]) {
|
2021-01-23 04:23:51 -06:00
|
|
|
|
vk_device_finish(&device->vk);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free(&device->vk.alloc, device);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(physical_device->instance, VK_ERROR_EXTENSION_NOT_PRESENT);
|
2018-02-11 00:32:34 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
device->enabled_extensions.extensions[index] = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
radv_device_init_dispatch(device);
|
|
|
|
|
|
|
2018-02-11 00:32:34 +01:00
|
|
|
|
keep_shader_info = device->enabled_extensions.AMD_shader_info;
|
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
|
/* With update after bind we can't attach bo's to the command buffer
|
|
|
|
|
|
* from the descriptor set anymore, so we have to use a global BO list.
|
|
|
|
|
|
*/
|
|
|
|
|
|
device->use_global_bo_list =
|
2019-04-10 00:37:54 +02:00
|
|
|
|
(device->instance->perftest_flags & RADV_PERFTEST_BO_LIST) ||
|
2019-01-24 02:06:27 +01:00
|
|
|
|
device->enabled_extensions.EXT_descriptor_indexing ||
|
2019-11-26 01:00:20 +01:00
|
|
|
|
device->enabled_extensions.EXT_buffer_device_address ||
|
|
|
|
|
|
device->enabled_extensions.KHR_buffer_device_address;
|
2018-04-19 13:48:33 +02:00
|
|
|
|
|
2020-11-30 15:29:31 +00:00
|
|
|
|
device->robust_buffer_access = robust_buffer_access || robust_buffer_access2;
|
|
|
|
|
|
device->robust_buffer_access2 = robust_buffer_access2;
|
2019-08-02 12:40:17 +02:00
|
|
|
|
|
2020-12-11 13:35:45 +01:00
|
|
|
|
device->adjust_frag_coord_z = (vrs_enabled ||
|
|
|
|
|
|
device->enabled_extensions.KHR_fragment_shading_rate) &&
|
|
|
|
|
|
(device->physical_device->rad_info.family == CHIP_SIENNA_CICHLID ||
|
|
|
|
|
|
device->physical_device->rad_info.family == CHIP_NAVY_FLOUNDER ||
|
|
|
|
|
|
device->physical_device->rad_info.family == CHIP_VANGOGH);
|
|
|
|
|
|
|
2017-03-12 22:43:51 +01:00
|
|
|
|
mtx_init(&device->shader_slab_mutex, mtx_plain);
|
|
|
|
|
|
list_inithead(&device->shader_slabs);
|
|
|
|
|
|
|
2020-04-28 13:10:56 +02:00
|
|
|
|
device->overallocation_disallowed = overallocation_disallowed;
|
|
|
|
|
|
mtx_init(&device->overallocation_mutex, mtx_plain);
|
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
|
radv_bo_list_init(&device->bo_list);
|
|
|
|
|
|
|
2016-11-30 04:30:06 +00:00
|
|
|
|
for (unsigned i = 0; i < pCreateInfo->queueCreateInfoCount; i++) {
|
|
|
|
|
|
const VkDeviceQueueCreateInfo *queue_create = &pCreateInfo->pQueueCreateInfos[i];
|
|
|
|
|
|
uint32_t qfi = queue_create->queueFamilyIndex;
|
2017-10-20 18:02:14 -04:00
|
|
|
|
const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority =
|
|
|
|
|
|
vk_find_struct_const(queue_create->pNext, DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT);
|
2016-11-30 04:30:06 +00:00
|
|
|
|
|
2017-10-20 18:02:16 -04:00
|
|
|
|
assert(!global_priority || device->physical_device->rad_info.has_ctx_priority);
|
|
|
|
|
|
|
2020-04-29 10:16:32 +02:00
|
|
|
|
device->queues[qfi] = vk_alloc(&device->vk.alloc,
|
2016-11-30 04:30:06 +00:00
|
|
|
|
queue_create->queueCount * sizeof(struct radv_queue), 8, VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
|
|
|
|
|
|
if (!device->queues[qfi]) {
|
|
|
|
|
|
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
memset(device->queues[qfi], 0, queue_create->queueCount * sizeof(struct radv_queue));
|
2016-11-30 04:30:06 +00:00
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
device->queue_count[qfi] = queue_create->queueCount;
|
2016-11-30 04:30:06 +00:00
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
|
for (unsigned q = 0; q < queue_create->queueCount; q++) {
|
2018-03-13 21:54:53 +01:00
|
|
|
|
result = radv_queue_init(device, &device->queues[qfi][q],
|
|
|
|
|
|
qfi, q, queue_create->flags,
|
|
|
|
|
|
global_priority);
|
2017-01-13 18:44:15 -05:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-21 03:40:00 +02:00
|
|
|
|
device->pbb_allowed = device->physical_device->rad_info.chip_class >= GFX9 &&
|
2018-11-15 09:58:52 +01:00
|
|
|
|
!(device->instance->debug_flags & RADV_DEBUG_NOBINNING);
|
2017-12-30 17:31:15 +01:00
|
|
|
|
|
2019-09-15 15:57:52 +02:00
|
|
|
|
/* Disable DFSM by default. As of 2019-09-15 Talos on Low is still 3% slower on Raven. */
|
2018-07-14 14:28:23 +02:00
|
|
|
|
device->dfsm_allowed = device->pbb_allowed &&
|
2019-09-15 15:57:52 +02:00
|
|
|
|
(device->instance->perftest_flags & RADV_PERFTEST_DFSM);
|
2017-12-30 17:31:15 +01:00
|
|
|
|
|
2018-01-04 18:38:32 +01:00
|
|
|
|
device->always_use_syncobj = device->physical_device->rad_info.has_syncobj_wait_for_submit;
|
2017-12-30 17:31:15 +01:00
|
|
|
|
|
2017-01-29 15:20:03 +01:00
|
|
|
|
/* The maximum number of scratch waves. Scratch space isn't divided
|
|
|
|
|
|
* evenly between CUs. The number is only a function of the number of CUs.
|
|
|
|
|
|
* We can decrease the constant to decrease the scratch buffer size.
|
|
|
|
|
|
*
|
2018-05-10 00:26:21 +03:00
|
|
|
|
* sctx->scratch_waves must be >= the maximum possible size of
|
2017-01-29 15:20:03 +01:00
|
|
|
|
* 1 threadgroup, so that the hw doesn't hang from being unable
|
|
|
|
|
|
* to start any.
|
|
|
|
|
|
*
|
|
|
|
|
|
* The recommended value is 4 per CU at most. Higher numbers don't
|
|
|
|
|
|
* bring much benefit, but they still occupy chip resources (think
|
|
|
|
|
|
* async compute). I've seen ~2% performance difference between 4 and 32.
|
|
|
|
|
|
*/
|
|
|
|
|
|
uint32_t max_threads_per_block = 2048;
|
|
|
|
|
|
device->scratch_waves = MAX2(32 * physical_device->rad_info.num_good_compute_units,
|
|
|
|
|
|
max_threads_per_block / 64);
|
|
|
|
|
|
|
2019-10-31 09:30:47 +01:00
|
|
|
|
device->dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1);
|
2017-12-14 15:51:18 +01:00
|
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7) {
|
2017-12-14 15:51:18 +01:00
|
|
|
|
/* If the KMD allows it (there is a KMD hw register for it),
|
|
|
|
|
|
* allow launching waves out-of-order.
|
|
|
|
|
|
*/
|
|
|
|
|
|
device->dispatch_initiator |= S_00B800_ORDER_MODE(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-18 13:54:17 +10:00
|
|
|
|
radv_device_init_gs_info(device);
|
|
|
|
|
|
|
2017-03-30 07:58:22 +01:00
|
|
|
|
device->tess_offchip_block_dw_size =
|
|
|
|
|
|
device->physical_device->rad_info.family == CHIP_HAWAII ? 4096 : 8192;
|
|
|
|
|
|
|
2017-09-22 15:16:22 +02:00
|
|
|
|
if (getenv("RADV_TRACE_FILE")) {
|
2020-10-19 18:37:26 +02:00
|
|
|
|
fprintf(stderr, "***********************************************************************************\n");
|
|
|
|
|
|
fprintf(stderr, "* WARNING: RADV_TRACE_FILE=<file> is deprecated and replaced by RADV_DEBUG=hang *\n");
|
|
|
|
|
|
fprintf(stderr, "***********************************************************************************\n");
|
|
|
|
|
|
abort();
|
|
|
|
|
|
}
|
2018-03-14 12:02:13 +01:00
|
|
|
|
|
2020-10-19 18:37:26 +02:00
|
|
|
|
if (device->instance->debug_flags & RADV_DEBUG_HANG) {
|
|
|
|
|
|
/* Enable GPU hangs detection and dump logs if a GPU hang is
|
|
|
|
|
|
* detected.
|
|
|
|
|
|
*/
|
2017-10-27 14:25:05 +01:00
|
|
|
|
keep_shader_info = true;
|
|
|
|
|
|
|
2017-09-22 15:16:22 +02:00
|
|
|
|
if (!radv_init_trace(device))
|
|
|
|
|
|
goto fail;
|
2018-03-14 12:02:13 +01:00
|
|
|
|
|
2018-07-20 18:47:03 +02:00
|
|
|
|
fprintf(stderr, "*****************************************************************************\n");
|
2020-10-19 18:37:26 +02:00
|
|
|
|
fprintf(stderr, "* WARNING: RADV_DEBUG=hang is costly and should only be used for debugging! *\n");
|
2018-07-20 18:47:03 +02:00
|
|
|
|
fprintf(stderr, "*****************************************************************************\n");
|
|
|
|
|
|
|
2020-08-26 17:28:46 +02:00
|
|
|
|
/* Wait for idle after every draw/dispatch to identify the
|
|
|
|
|
|
* first bad call.
|
|
|
|
|
|
*/
|
|
|
|
|
|
device->instance->debug_flags |= RADV_DEBUG_SYNC_SHADERS;
|
|
|
|
|
|
|
2018-03-14 12:02:13 +01:00
|
|
|
|
radv_dump_enabled_options(device, stderr);
|
2017-09-22 15:16:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-09-01 14:49:35 +02:00
|
|
|
|
if (radv_thread_trace_enabled()) {
|
2020-03-02 16:25:33 +01:00
|
|
|
|
fprintf(stderr, "*************************************************\n");
|
|
|
|
|
|
fprintf(stderr, "* WARNING: Thread trace support is experimental *\n");
|
|
|
|
|
|
fprintf(stderr, "*************************************************\n");
|
2020-02-20 13:22:31 +01:00
|
|
|
|
|
2020-12-11 15:54:20 +01:00
|
|
|
|
if (device->physical_device->rad_info.chip_class < GFX8 ||
|
|
|
|
|
|
device->physical_device->rad_info.chip_class > GFX10_3) {
|
2020-03-02 16:25:33 +01:00
|
|
|
|
fprintf(stderr, "GPU hardware not supported: refer to "
|
|
|
|
|
|
"the RGP documentation for the list of "
|
|
|
|
|
|
"supported GPUs!\n");
|
|
|
|
|
|
abort();
|
|
|
|
|
|
}
|
2020-02-20 13:22:31 +01:00
|
|
|
|
|
|
|
|
|
|
/* Default buffer size set to 1MB per SE. */
|
2020-12-08 11:06:48 +01:00
|
|
|
|
device->thread_trace.buffer_size =
|
2020-02-20 13:22:31 +01:00
|
|
|
|
radv_get_int_debug_option("RADV_THREAD_TRACE_BUFFER_SIZE", 1024 * 1024);
|
2020-12-08 11:06:48 +01:00
|
|
|
|
device->thread_trace.start_frame = radv_get_int_debug_option("RADV_THREAD_TRACE", -1);
|
2020-02-20 13:22:31 +01:00
|
|
|
|
|
2020-09-01 14:59:55 +02:00
|
|
|
|
const char *trigger_file = getenv("RADV_THREAD_TRACE_TRIGGER");
|
|
|
|
|
|
if (trigger_file)
|
2020-12-08 11:06:48 +01:00
|
|
|
|
device->thread_trace.trigger_file = strdup(trigger_file);
|
2020-09-01 14:59:55 +02:00
|
|
|
|
|
2020-02-20 13:22:31 +01:00
|
|
|
|
if (!radv_thread_trace_init(device))
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-18 18:51:46 +02:00
|
|
|
|
if (getenv("RADV_TRAP_HANDLER")) {
|
|
|
|
|
|
/* TODO: Add support for more hardware. */
|
|
|
|
|
|
assert(device->physical_device->rad_info.chip_class == GFX8);
|
|
|
|
|
|
|
2020-08-26 10:07:45 +02:00
|
|
|
|
fprintf(stderr, "**********************************************************************\n");
|
|
|
|
|
|
fprintf(stderr, "* WARNING: RADV_TRAP_HANDLER is experimental and only for debugging! *\n");
|
|
|
|
|
|
fprintf(stderr, "**********************************************************************\n");
|
|
|
|
|
|
|
2020-08-18 18:51:46 +02:00
|
|
|
|
/* To get the disassembly of the faulty shaders, we have to
|
|
|
|
|
|
* keep some shader info around.
|
|
|
|
|
|
*/
|
|
|
|
|
|
keep_shader_info = true;
|
|
|
|
|
|
|
|
|
|
|
|
if (!radv_trap_handler_init(device))
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-31 14:03:53 +10:00
|
|
|
|
device->keep_shader_info = keep_shader_info;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
result = radv_device_init_meta(device);
|
2017-01-13 18:44:15 -05:00
|
|
|
|
if (result != VK_SUCCESS)
|
2016-11-30 04:30:06 +00:00
|
|
|
|
goto fail;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
radv_device_init_msaa(device);
|
2016-12-17 21:53:38 +01:00
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
/* If the border color extension is enabled, let's create the buffer we need. */
|
|
|
|
|
|
if (custom_border_colors) {
|
|
|
|
|
|
result = radv_device_init_border_color(device);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-12-17 21:53:38 +01:00
|
|
|
|
for (int family = 0; family < RADV_MAX_QUEUE_FAMILIES; ++family) {
|
|
|
|
|
|
device->empty_cs[family] = device->ws->cs_create(device->ws, family);
|
2020-07-12 18:35:25 +02:00
|
|
|
|
if (!device->empty_cs[family])
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
2016-12-17 21:53:38 +01:00
|
|
|
|
switch (family) {
|
|
|
|
|
|
case RADV_QUEUE_GENERAL:
|
2019-10-15 14:40:51 +02:00
|
|
|
|
radeon_emit(device->empty_cs[family], PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
|
2020-02-05 16:55:41 -05:00
|
|
|
|
radeon_emit(device->empty_cs[family], CC0_UPDATE_LOAD_ENABLES(1));
|
|
|
|
|
|
radeon_emit(device->empty_cs[family], CC1_UPDATE_SHADOW_ENABLES(1));
|
2016-12-17 21:53:38 +01:00
|
|
|
|
break;
|
|
|
|
|
|
case RADV_QUEUE_COMPUTE:
|
|
|
|
|
|
radeon_emit(device->empty_cs[family], PKT3(PKT3_NOP, 0, 0));
|
|
|
|
|
|
radeon_emit(device->empty_cs[family], 0);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-12 18:35:25 +02:00
|
|
|
|
|
|
|
|
|
|
result = device->ws->cs_finalize(device->empty_cs[family]);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
2016-12-17 21:53:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7)
|
2017-02-13 04:00:24 +00:00
|
|
|
|
cik_create_gfx_config(device);
|
|
|
|
|
|
|
2017-03-15 14:14:24 +11:00
|
|
|
|
VkPipelineCacheCreateInfo ci;
|
|
|
|
|
|
ci.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
|
|
|
|
|
|
ci.pNext = NULL;
|
|
|
|
|
|
ci.flags = 0;
|
|
|
|
|
|
ci.pInitialData = NULL;
|
|
|
|
|
|
ci.initialDataSize = 0;
|
|
|
|
|
|
VkPipelineCache pc;
|
|
|
|
|
|
result = radv_CreatePipelineCache(radv_device_to_handle(device),
|
|
|
|
|
|
&ci, NULL, &pc);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
2018-01-21 21:47:31 +01:00
|
|
|
|
goto fail_meta;
|
2017-03-15 14:14:24 +11:00
|
|
|
|
|
|
|
|
|
|
device->mem_cache = radv_pipeline_cache_from_handle(pc);
|
|
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
if (u_cnd_monotonic_init(&device->timeline_cond)) {
|
|
|
|
|
|
result = VK_ERROR_INITIALIZATION_FAILED;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
goto fail_mem_cache;
|
2020-10-31 16:18:34 -07:00
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2018-09-17 22:23:19 +02:00
|
|
|
|
device->force_aniso =
|
|
|
|
|
|
MIN2(16, radv_get_int_debug_option("RADV_TEX_ANISO", -1));
|
|
|
|
|
|
if (device->force_aniso >= 0) {
|
|
|
|
|
|
fprintf(stderr, "radv: Forcing anisotropy filter to %ix\n",
|
|
|
|
|
|
1 << util_logbase2(device->force_aniso));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
*pDevice = radv_device_to_handle(device);
|
|
|
|
|
|
return VK_SUCCESS;
|
2016-11-30 04:30:06 +00:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
fail_mem_cache:
|
|
|
|
|
|
radv_DestroyPipelineCache(radv_device_to_handle(device), pc, NULL);
|
2018-01-21 21:47:31 +01:00
|
|
|
|
fail_meta:
|
|
|
|
|
|
radv_device_finish_meta(device);
|
2016-11-30 04:30:06 +00:00
|
|
|
|
fail:
|
2018-04-09 12:46:49 +02:00
|
|
|
|
radv_bo_list_finish(&device->bo_list);
|
|
|
|
|
|
|
2020-02-20 13:22:31 +01:00
|
|
|
|
radv_thread_trace_finish(device);
|
2020-12-08 11:06:48 +01:00
|
|
|
|
free(device->thread_trace.trigger_file);
|
2020-02-20 13:22:31 +01:00
|
|
|
|
|
2020-08-18 18:51:46 +02:00
|
|
|
|
radv_trap_handler_finish(device);
|
|
|
|
|
|
|
2016-12-23 23:51:18 +01:00
|
|
|
|
if (device->trace_bo)
|
|
|
|
|
|
device->ws->buffer_destroy(device->trace_bo);
|
|
|
|
|
|
|
2017-02-13 04:00:24 +00:00
|
|
|
|
if (device->gfx_init)
|
|
|
|
|
|
device->ws->buffer_destroy(device->gfx_init);
|
|
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
radv_device_finish_border_color(device);
|
|
|
|
|
|
|
2016-11-30 04:30:06 +00:00
|
|
|
|
for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
|
|
|
|
|
|
for (unsigned q = 0; q < device->queue_count[i]; q++)
|
|
|
|
|
|
radv_queue_finish(&device->queues[i][q]);
|
|
|
|
|
|
if (device->queue_count[i])
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free(&device->vk.alloc, device->queues[i]);
|
2016-11-30 04:30:06 +00:00
|
|
|
|
}
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
2021-01-23 04:23:51 -06:00
|
|
|
|
vk_device_finish(&device->vk);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free(&device->vk.alloc, device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyDevice(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
2017-03-06 15:40:16 +10:00
|
|
|
|
if (!device)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2016-12-23 23:51:18 +01:00
|
|
|
|
if (device->trace_bo)
|
|
|
|
|
|
device->ws->buffer_destroy(device->trace_bo);
|
|
|
|
|
|
|
2017-02-13 04:00:24 +00:00
|
|
|
|
if (device->gfx_init)
|
|
|
|
|
|
device->ws->buffer_destroy(device->gfx_init);
|
|
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
radv_device_finish_border_color(device);
|
|
|
|
|
|
|
2016-11-30 04:30:06 +00:00
|
|
|
|
for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
|
|
|
|
|
|
for (unsigned q = 0; q < device->queue_count[i]; q++)
|
|
|
|
|
|
radv_queue_finish(&device->queues[i][q]);
|
|
|
|
|
|
if (device->queue_count[i])
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free(&device->vk.alloc, device->queues[i]);
|
2017-02-20 02:22:39 +01:00
|
|
|
|
if (device->empty_cs[i])
|
|
|
|
|
|
device->ws->cs_destroy(device->empty_cs[i]);
|
2016-11-30 04:30:06 +00:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
radv_device_finish_meta(device);
|
|
|
|
|
|
|
2017-03-15 14:14:24 +11:00
|
|
|
|
VkPipelineCache pc = radv_pipeline_cache_to_handle(device->mem_cache);
|
|
|
|
|
|
radv_DestroyPipelineCache(radv_device_to_handle(device), pc, NULL);
|
|
|
|
|
|
|
2020-08-18 18:51:46 +02:00
|
|
|
|
radv_trap_handler_finish(device);
|
|
|
|
|
|
|
2017-03-12 22:43:51 +01:00
|
|
|
|
radv_destroy_shader_slabs(device);
|
|
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_destroy(&device->timeline_cond);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
radv_bo_list_finish(&device->bo_list);
|
2020-02-20 13:22:31 +01:00
|
|
|
|
|
2020-12-08 11:06:48 +01:00
|
|
|
|
free(device->thread_trace.trigger_file);
|
2020-02-20 13:22:31 +01:00
|
|
|
|
radv_thread_trace_finish(device);
|
|
|
|
|
|
|
2021-01-23 04:23:51 -06:00
|
|
|
|
vk_device_finish(&device->vk);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free(&device->vk.alloc, device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_EnumerateInstanceLayerProperties(
|
|
|
|
|
|
uint32_t* pPropertyCount,
|
|
|
|
|
|
VkLayerProperties* pProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
|
*pPropertyCount = 0;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* None supported at this time */
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_EnumerateDeviceLayerProperties(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
uint32_t* pPropertyCount,
|
|
|
|
|
|
VkLayerProperties* pProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (pProperties == NULL) {
|
|
|
|
|
|
*pPropertyCount = 0;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* None supported at this time */
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 16:11:48 +01:00
|
|
|
|
void radv_GetDeviceQueue2(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkDeviceQueueInfo2* pQueueInfo,
|
|
|
|
|
|
VkQueue* pQueue)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2018-03-13 21:54:53 +01:00
|
|
|
|
struct radv_queue *queue;
|
|
|
|
|
|
|
|
|
|
|
|
queue = &device->queues[pQueueInfo->queueFamilyIndex][pQueueInfo->queueIndex];
|
|
|
|
|
|
if (pQueueInfo->flags != queue->flags) {
|
|
|
|
|
|
/* From the Vulkan 1.1.70 spec:
|
|
|
|
|
|
*
|
|
|
|
|
|
* "The queue returned by vkGetDeviceQueue2 must have the same
|
|
|
|
|
|
* flags value from this structure as that used at device
|
|
|
|
|
|
* creation time in a VkDeviceQueueCreateInfo instance. If no
|
|
|
|
|
|
* matching flags were specified at device creation time then
|
|
|
|
|
|
* pQueue will return VK_NULL_HANDLE."
|
|
|
|
|
|
*/
|
|
|
|
|
|
*pQueue = VK_NULL_HANDLE;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2018-01-21 16:11:48 +01:00
|
|
|
|
|
2018-03-13 21:54:53 +01:00
|
|
|
|
*pQueue = radv_queue_to_handle(queue);
|
2018-01-21 16:11:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_GetDeviceQueue(
|
|
|
|
|
|
VkDevice _device,
|
2016-11-30 04:30:06 +00:00
|
|
|
|
uint32_t queueFamilyIndex,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
uint32_t queueIndex,
|
|
|
|
|
|
VkQueue* pQueue)
|
|
|
|
|
|
{
|
2018-01-21 16:11:48 +01:00
|
|
|
|
const VkDeviceQueueInfo2 info = (VkDeviceQueueInfo2) {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,
|
|
|
|
|
|
.queueFamilyIndex = queueFamilyIndex,
|
|
|
|
|
|
.queueIndex = queueIndex
|
|
|
|
|
|
};
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2018-01-21 16:11:48 +01:00
|
|
|
|
radv_GetDeviceQueue2(_device, &info, pQueue);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-20 11:06:52 +10:00
|
|
|
|
static void
|
2017-03-30 08:02:14 +01:00
|
|
|
|
fill_geom_tess_rings(struct radv_queue *queue,
|
|
|
|
|
|
uint32_t *map,
|
2017-04-03 04:38:12 +01:00
|
|
|
|
bool add_sample_positions,
|
2017-03-30 08:02:14 +01:00
|
|
|
|
uint32_t esgs_ring_size,
|
|
|
|
|
|
struct radeon_winsys_bo *esgs_ring_bo,
|
|
|
|
|
|
uint32_t gsvs_ring_size,
|
|
|
|
|
|
struct radeon_winsys_bo *gsvs_ring_bo,
|
|
|
|
|
|
uint32_t tess_factor_ring_size,
|
2018-02-25 23:23:45 +00:00
|
|
|
|
uint32_t tess_offchip_ring_offset,
|
2017-03-30 08:02:14 +01:00
|
|
|
|
uint32_t tess_offchip_ring_size,
|
2018-02-25 23:23:45 +00:00
|
|
|
|
struct radeon_winsys_bo *tess_rings_bo)
|
2017-01-20 11:06:52 +10:00
|
|
|
|
{
|
|
|
|
|
|
uint32_t *desc = &map[4];
|
|
|
|
|
|
|
2019-01-17 18:11:09 +01:00
|
|
|
|
if (esgs_ring_bo) {
|
|
|
|
|
|
uint64_t esgs_va = radv_buffer_get_va(esgs_ring_bo);
|
|
|
|
|
|
|
|
|
|
|
|
/* stride 0, num records - size, add tid, swizzle, elsize4,
|
|
|
|
|
|
index stride 64 */
|
|
|
|
|
|
desc[0] = esgs_va;
|
|
|
|
|
|
desc[1] = S_008F04_BASE_ADDRESS_HI(esgs_va >> 32) |
|
|
|
|
|
|
S_008F04_SWIZZLE_ENABLE(true);
|
|
|
|
|
|
desc[2] = esgs_ring_size;
|
|
|
|
|
|
desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
|
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
|
|
|
|
|
|
S_008F0C_INDEX_STRIDE(3) |
|
2019-07-18 15:51:29 +02:00
|
|
|
|
S_008F0C_ADD_TID_ENABLE(1);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
|
2019-06-25 14:10:42 +02:00
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[3] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
2019-07-18 15:51:30 +02:00
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
|
|
|
|
|
|
S_008F0C_ELEMENT_SIZE(1);
|
2019-06-25 14:10:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-17 18:11:09 +01:00
|
|
|
|
/* GS entry for ES->GS ring */
|
|
|
|
|
|
/* stride 0, num records - size, elsize0,
|
|
|
|
|
|
index stride 0 */
|
|
|
|
|
|
desc[4] = esgs_va;
|
2019-07-18 15:51:29 +02:00
|
|
|
|
desc[5] = S_008F04_BASE_ADDRESS_HI(esgs_va >> 32);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
desc[6] = esgs_ring_size;
|
|
|
|
|
|
desc[7] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
2019-07-18 15:51:29 +02:00
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
|
2019-06-25 14:10:42 +02:00
|
|
|
|
|
|
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[7] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
|
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
|
|
|
|
|
|
}
|
2019-01-17 18:11:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
desc += 8;
|
|
|
|
|
|
|
|
|
|
|
|
if (gsvs_ring_bo) {
|
|
|
|
|
|
uint64_t gsvs_va = radv_buffer_get_va(gsvs_ring_bo);
|
|
|
|
|
|
|
|
|
|
|
|
/* VS entry for GS->VS ring */
|
|
|
|
|
|
/* stride 0, num records - size, elsize0,
|
|
|
|
|
|
index stride 0 */
|
|
|
|
|
|
desc[0] = gsvs_va;
|
2019-07-18 15:51:29 +02:00
|
|
|
|
desc[1] = S_008F04_BASE_ADDRESS_HI(gsvs_va >> 32);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
desc[2] = gsvs_ring_size;
|
|
|
|
|
|
desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
2019-07-18 15:51:29 +02:00
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
|
2019-06-25 14:10:42 +02:00
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[3] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
|
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-17 18:11:09 +01:00
|
|
|
|
/* stride gsvs_itemsize, num records 64
|
|
|
|
|
|
elsize 4, index stride 16 */
|
|
|
|
|
|
/* shader will patch stride and desc[2] */
|
|
|
|
|
|
desc[4] = gsvs_va;
|
2019-07-18 15:51:29 +02:00
|
|
|
|
desc[5] = S_008F04_BASE_ADDRESS_HI(gsvs_va >> 32) |
|
|
|
|
|
|
S_008F04_SWIZZLE_ENABLE(1);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
desc[6] = 0;
|
|
|
|
|
|
desc[7] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
|
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W) |
|
|
|
|
|
|
S_008F0C_INDEX_STRIDE(1) |
|
|
|
|
|
|
S_008F0C_ADD_TID_ENABLE(true);
|
2019-06-25 14:10:42 +02:00
|
|
|
|
|
|
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[7] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
2019-07-18 15:51:30 +02:00
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32) |
|
|
|
|
|
|
S_008F0C_ELEMENT_SIZE(1);
|
2019-06-25 14:10:42 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-17 18:11:09 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
desc += 8;
|
|
|
|
|
|
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (tess_rings_bo) {
|
2019-01-17 18:11:09 +01:00
|
|
|
|
uint64_t tess_va = radv_buffer_get_va(tess_rings_bo);
|
|
|
|
|
|
uint64_t tess_offchip_va = tess_va + tess_offchip_ring_offset;
|
|
|
|
|
|
|
|
|
|
|
|
desc[0] = tess_va;
|
2019-07-18 15:51:29 +02:00
|
|
|
|
desc[1] = S_008F04_BASE_ADDRESS_HI(tess_va >> 32);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
desc[2] = tess_factor_ring_size;
|
|
|
|
|
|
desc[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
|
|
|
|
|
|
|
|
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[3] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
|
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
|
|
|
|
|
|
}
|
2019-01-17 18:11:09 +01:00
|
|
|
|
|
|
|
|
|
|
desc[4] = tess_offchip_va;
|
2019-07-18 15:51:29 +02:00
|
|
|
|
desc[5] = S_008F04_BASE_ADDRESS_HI(tess_offchip_va >> 32);
|
2019-01-17 18:11:09 +01:00
|
|
|
|
desc[6] = tess_offchip_ring_size;
|
|
|
|
|
|
desc[7] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
|
|
|
|
|
|
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_DST_SEL_W(V_008F0C_SQ_SEL_W);
|
|
|
|
|
|
|
|
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
desc[7] |= S_008F0C_FORMAT(V_008F0C_IMG_FORMAT_32_FLOAT) |
|
2019-12-18 14:23:26 +01:00
|
|
|
|
S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
|
2019-06-25 14:10:42 +02:00
|
|
|
|
S_008F0C_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
|
|
|
|
|
|
S_008F0C_DATA_FORMAT(V_008F0C_BUF_DATA_FORMAT_32);
|
|
|
|
|
|
}
|
2018-02-25 23:23:45 +00:00
|
|
|
|
}
|
2017-01-31 10:37:25 +10:00
|
|
|
|
|
2017-04-03 04:38:12 +01:00
|
|
|
|
desc += 8;
|
2019-01-17 18:11:09 +01:00
|
|
|
|
|
|
|
|
|
|
if (add_sample_positions) {
|
|
|
|
|
|
/* add sample positions after all rings */
|
|
|
|
|
|
memcpy(desc, queue->device->sample_locations_1x, 8);
|
|
|
|
|
|
desc += 2;
|
|
|
|
|
|
memcpy(desc, queue->device->sample_locations_2x, 16);
|
|
|
|
|
|
desc += 4;
|
|
|
|
|
|
memcpy(desc, queue->device->sample_locations_4x, 32);
|
|
|
|
|
|
desc += 8;
|
|
|
|
|
|
memcpy(desc, queue->device->sample_locations_8x, 64);
|
|
|
|
|
|
}
|
2017-03-30 08:02:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_get_hs_offchip_param(struct radv_device *device, uint32_t *max_offchip_buffers_p)
|
|
|
|
|
|
{
|
2019-05-14 22:16:20 -04:00
|
|
|
|
bool double_offchip_buffers = device->physical_device->rad_info.chip_class >= GFX7 &&
|
2017-03-30 08:02:14 +01:00
|
|
|
|
device->physical_device->rad_info.family != CHIP_CARRIZO &&
|
|
|
|
|
|
device->physical_device->rad_info.family != CHIP_STONEY;
|
|
|
|
|
|
unsigned max_offchip_buffers_per_se = double_offchip_buffers ? 128 : 64;
|
2018-09-03 02:30:48 +02:00
|
|
|
|
unsigned max_offchip_buffers;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
unsigned offchip_granularity;
|
|
|
|
|
|
unsigned hs_offchip_param;
|
2018-09-03 02:30:48 +02:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* Per RadeonSI:
|
|
|
|
|
|
* This must be one less than the maximum number due to a hw limitation.
|
2019-05-14 22:16:20 -04:00
|
|
|
|
* Various hardware bugs need thGFX7
|
2018-09-03 02:30:48 +02:00
|
|
|
|
*
|
|
|
|
|
|
* Per AMDVLK:
|
|
|
|
|
|
* Vega10 should limit max_offchip_buffers to 508 (4 * 127).
|
|
|
|
|
|
* Gfx7 should limit max_offchip_buffers to 508
|
|
|
|
|
|
* Gfx6 should limit max_offchip_buffers to 126 (2 * 63)
|
|
|
|
|
|
*
|
|
|
|
|
|
* Follow AMDVLK here.
|
|
|
|
|
|
*/
|
2019-06-26 09:09:33 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
max_offchip_buffers_per_se = 256;
|
|
|
|
|
|
} else if (device->physical_device->rad_info.family == CHIP_VEGA10 ||
|
|
|
|
|
|
device->physical_device->rad_info.chip_class == GFX7 ||
|
|
|
|
|
|
device->physical_device->rad_info.chip_class == GFX6)
|
2018-09-03 02:30:48 +02:00
|
|
|
|
--max_offchip_buffers_per_se;
|
|
|
|
|
|
|
|
|
|
|
|
max_offchip_buffers = max_offchip_buffers_per_se *
|
|
|
|
|
|
device->physical_device->rad_info.max_se;
|
|
|
|
|
|
|
2018-11-08 14:00:35 +01:00
|
|
|
|
/* Hawaii has a bug with offchip buffers > 256 that can be worked
|
|
|
|
|
|
* around by setting 4K granularity.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (device->tess_offchip_block_dw_size == 4096) {
|
|
|
|
|
|
assert(device->physical_device->rad_info.family == CHIP_HAWAII);
|
2017-03-30 08:02:14 +01:00
|
|
|
|
offchip_granularity = V_03093C_X_4K_DWORDS;
|
2018-11-08 14:00:35 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
assert(device->tess_offchip_block_dw_size == 8192);
|
|
|
|
|
|
offchip_granularity = V_03093C_X_8K_DWORDS;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (device->physical_device->rad_info.chip_class) {
|
2019-05-14 22:16:20 -04:00
|
|
|
|
case GFX6:
|
2017-03-30 08:02:14 +01:00
|
|
|
|
max_offchip_buffers = MIN2(max_offchip_buffers, 126);
|
|
|
|
|
|
break;
|
2019-05-14 22:16:20 -04:00
|
|
|
|
case GFX7:
|
|
|
|
|
|
case GFX8:
|
2017-06-06 08:33:53 +10:00
|
|
|
|
case GFX9:
|
2017-06-06 08:36:24 +10:00
|
|
|
|
max_offchip_buffers = MIN2(max_offchip_buffers, 508);
|
2017-03-30 08:02:14 +01:00
|
|
|
|
break;
|
2019-07-08 23:18:28 +02:00
|
|
|
|
case GFX10:
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*max_offchip_buffers_p = max_offchip_buffers;
|
2020-06-08 18:16:13 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10_3) {
|
|
|
|
|
|
hs_offchip_param = S_03093C_OFFCHIP_BUFFERING_GFX103(max_offchip_buffers - 1) |
|
|
|
|
|
|
S_03093C_OFFCHIP_GRANULARITY_GFX103(offchip_granularity);
|
|
|
|
|
|
} else if (device->physical_device->rad_info.chip_class >= GFX7) {
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX8)
|
2017-03-30 08:02:14 +01:00
|
|
|
|
--max_offchip_buffers;
|
|
|
|
|
|
hs_offchip_param =
|
2020-08-21 08:09:58 -04:00
|
|
|
|
S_03093C_OFFCHIP_BUFFERING_GFX7(max_offchip_buffers) |
|
|
|
|
|
|
S_03093C_OFFCHIP_GRANULARITY_GFX7(offchip_granularity);
|
2017-03-30 08:02:14 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
hs_offchip_param =
|
|
|
|
|
|
S_0089B0_OFFCHIP_BUFFERING(max_offchip_buffers);
|
|
|
|
|
|
}
|
|
|
|
|
|
return hs_offchip_param;
|
2017-01-20 11:06:52 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-17 10:11:44 +02:00
|
|
|
|
static void
|
2018-06-18 21:07:10 -04:00
|
|
|
|
radv_emit_gs_ring_sizes(struct radv_queue *queue, struct radeon_cmdbuf *cs,
|
2018-05-17 10:11:44 +02:00
|
|
|
|
struct radeon_winsys_bo *esgs_ring_bo,
|
|
|
|
|
|
uint32_t esgs_ring_size,
|
|
|
|
|
|
struct radeon_winsys_bo *gsvs_ring_bo,
|
|
|
|
|
|
uint32_t gsvs_ring_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!esgs_ring_bo && !gsvs_ring_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (esgs_ring_bo)
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, esgs_ring_bo);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
|
|
|
|
|
|
if (gsvs_ring_bo)
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, gsvs_ring_bo);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX7) {
|
2018-05-17 10:11:44 +02:00
|
|
|
|
radeon_set_uconfig_reg_seq(cs, R_030900_VGT_ESGS_RING_SIZE, 2);
|
|
|
|
|
|
radeon_emit(cs, esgs_ring_size >> 8);
|
|
|
|
|
|
radeon_emit(cs, gsvs_ring_size >> 8);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
radeon_set_config_reg_seq(cs, R_0088C8_VGT_ESGS_RING_SIZE, 2);
|
|
|
|
|
|
radeon_emit(cs, esgs_ring_size >> 8);
|
|
|
|
|
|
radeon_emit(cs, gsvs_ring_size >> 8);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2018-06-18 21:07:10 -04:00
|
|
|
|
radv_emit_tess_factor_ring(struct radv_queue *queue, struct radeon_cmdbuf *cs,
|
2018-05-17 10:11:44 +02:00
|
|
|
|
unsigned hs_offchip_param, unsigned tf_ring_size,
|
|
|
|
|
|
struct radeon_winsys_bo *tess_rings_bo)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint64_t tf_va;
|
|
|
|
|
|
|
|
|
|
|
|
if (!tess_rings_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
tf_va = radv_buffer_get_va(tess_rings_bo);
|
|
|
|
|
|
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, tess_rings_bo);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX7) {
|
2018-05-17 10:11:44 +02:00
|
|
|
|
radeon_set_uconfig_reg(cs, R_030938_VGT_TF_RING_SIZE,
|
|
|
|
|
|
S_030938_SIZE(tf_ring_size / 4));
|
|
|
|
|
|
radeon_set_uconfig_reg(cs, R_030940_VGT_TF_MEMORY_BASE,
|
|
|
|
|
|
tf_va >> 8);
|
2019-06-25 11:32:53 +02:00
|
|
|
|
|
|
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
radeon_set_uconfig_reg(cs, R_030984_VGT_TF_MEMORY_BASE_HI_UMD,
|
|
|
|
|
|
S_030984_BASE_HI(tf_va >> 40));
|
|
|
|
|
|
} else if (queue->device->physical_device->rad_info.chip_class == GFX9) {
|
2018-05-17 10:11:44 +02:00
|
|
|
|
radeon_set_uconfig_reg(cs, R_030944_VGT_TF_MEMORY_BASE_HI,
|
|
|
|
|
|
S_030944_BASE_HI(tf_va >> 40));
|
|
|
|
|
|
}
|
|
|
|
|
|
radeon_set_uconfig_reg(cs, R_03093C_VGT_HS_OFFCHIP_PARAM,
|
|
|
|
|
|
hs_offchip_param);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
radeon_set_config_reg(cs, R_008988_VGT_TF_RING_SIZE,
|
|
|
|
|
|
S_008988_SIZE(tf_ring_size / 4));
|
|
|
|
|
|
radeon_set_config_reg(cs, R_0089B8_VGT_TF_MEMORY_BASE,
|
|
|
|
|
|
tf_va >> 8);
|
|
|
|
|
|
radeon_set_config_reg(cs, R_0089B0_VGT_HS_OFFCHIP_PARAM,
|
|
|
|
|
|
hs_offchip_param);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_emit_graphics_scratch(struct radv_queue *queue, struct radeon_cmdbuf *cs,
|
|
|
|
|
|
uint32_t size_per_wave, uint32_t waves,
|
|
|
|
|
|
struct radeon_winsys_bo *scratch_bo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (queue->queue_family_index != RADV_QUEUE_GENERAL)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (!scratch_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, scratch_bo);
|
|
|
|
|
|
|
|
|
|
|
|
radeon_set_context_reg(cs, R_0286E8_SPI_TMPRING_SIZE,
|
|
|
|
|
|
S_0286E8_WAVES(waves) |
|
|
|
|
|
|
S_0286E8_WAVESIZE(round_up_u32(size_per_wave, 1024)));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-17 10:11:44 +02:00
|
|
|
|
static void
|
2018-06-18 21:07:10 -04:00
|
|
|
|
radv_emit_compute_scratch(struct radv_queue *queue, struct radeon_cmdbuf *cs,
|
2019-10-31 22:53:30 +01:00
|
|
|
|
uint32_t size_per_wave, uint32_t waves,
|
|
|
|
|
|
struct radeon_winsys_bo *compute_scratch_bo)
|
2018-05-17 10:11:44 +02:00
|
|
|
|
{
|
|
|
|
|
|
uint64_t scratch_va;
|
|
|
|
|
|
|
|
|
|
|
|
if (!compute_scratch_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
scratch_va = radv_buffer_get_va(compute_scratch_bo);
|
|
|
|
|
|
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, compute_scratch_bo);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
|
|
|
|
|
|
radeon_set_sh_reg_seq(cs, R_00B900_COMPUTE_USER_DATA_0, 2);
|
|
|
|
|
|
radeon_emit(cs, scratch_va);
|
|
|
|
|
|
radeon_emit(cs, S_008F04_BASE_ADDRESS_HI(scratch_va >> 32) |
|
|
|
|
|
|
S_008F04_SWIZZLE_ENABLE(1));
|
2019-10-31 22:53:30 +01:00
|
|
|
|
|
|
|
|
|
|
radeon_set_sh_reg(cs, R_00B860_COMPUTE_TMPRING_SIZE,
|
|
|
|
|
|
S_00B860_WAVES(waves) |
|
|
|
|
|
|
S_00B860_WAVESIZE(round_up_u32(size_per_wave, 1024)));
|
2018-05-17 10:11:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_emit_global_shader_pointers(struct radv_queue *queue,
|
2018-06-18 21:07:10 -04:00
|
|
|
|
struct radeon_cmdbuf *cs,
|
2018-05-17 10:11:44 +02:00
|
|
|
|
struct radeon_winsys_bo *descriptor_bo)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint64_t va;
|
|
|
|
|
|
|
|
|
|
|
|
if (!descriptor_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
va = radv_buffer_get_va(descriptor_bo);
|
|
|
|
|
|
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, descriptor_bo);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
|
2019-06-25 11:40:02 +02:00
|
|
|
|
if (queue->device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
uint32_t regs[] = {R_00B030_SPI_SHADER_USER_DATA_PS_0,
|
|
|
|
|
|
R_00B130_SPI_SHADER_USER_DATA_VS_0,
|
2019-07-09 02:56:10 +02:00
|
|
|
|
R_00B208_SPI_SHADER_USER_DATA_ADDR_LO_GS,
|
|
|
|
|
|
R_00B408_SPI_SHADER_USER_DATA_ADDR_LO_HS};
|
2019-06-25 11:40:02 +02:00
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(regs); ++i) {
|
|
|
|
|
|
radv_emit_shader_pointer(queue->device, cs, regs[i],
|
|
|
|
|
|
va, true);
|
|
|
|
|
|
}
|
2019-07-18 15:51:28 +02:00
|
|
|
|
} else if (queue->device->physical_device->rad_info.chip_class == GFX9) {
|
2018-05-17 10:11:44 +02:00
|
|
|
|
uint32_t regs[] = {R_00B030_SPI_SHADER_USER_DATA_PS_0,
|
|
|
|
|
|
R_00B130_SPI_SHADER_USER_DATA_VS_0,
|
|
|
|
|
|
R_00B208_SPI_SHADER_USER_DATA_ADDR_LO_GS,
|
|
|
|
|
|
R_00B408_SPI_SHADER_USER_DATA_ADDR_LO_HS};
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(regs); ++i) {
|
2018-05-16 17:40:47 +02:00
|
|
|
|
radv_emit_shader_pointer(queue->device, cs, regs[i],
|
|
|
|
|
|
va, true);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uint32_t regs[] = {R_00B030_SPI_SHADER_USER_DATA_PS_0,
|
|
|
|
|
|
R_00B130_SPI_SHADER_USER_DATA_VS_0,
|
|
|
|
|
|
R_00B230_SPI_SHADER_USER_DATA_GS_0,
|
|
|
|
|
|
R_00B330_SPI_SHADER_USER_DATA_ES_0,
|
|
|
|
|
|
R_00B430_SPI_SHADER_USER_DATA_HS_0,
|
|
|
|
|
|
R_00B530_SPI_SHADER_USER_DATA_LS_0};
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(regs); ++i) {
|
2018-05-16 17:40:47 +02:00
|
|
|
|
radv_emit_shader_pointer(queue->device, cs, regs[i],
|
|
|
|
|
|
va, true);
|
2018-05-17 10:11:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-18 18:51:46 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_emit_trap_handler(struct radv_queue *queue,
|
|
|
|
|
|
struct radeon_cmdbuf *cs,
|
|
|
|
|
|
struct radeon_winsys_bo *tma_bo)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_device *device = queue->device;
|
|
|
|
|
|
struct radeon_winsys_bo *tba_bo;
|
|
|
|
|
|
uint64_t tba_va, tma_va;
|
|
|
|
|
|
|
|
|
|
|
|
if (!device->trap_handler_shader || !tma_bo)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
tba_bo = device->trap_handler_shader->bo;
|
|
|
|
|
|
|
|
|
|
|
|
tba_va = radv_buffer_get_va(tba_bo) + device->trap_handler_shader->bo_offset;
|
|
|
|
|
|
tma_va = radv_buffer_get_va(tma_bo);
|
|
|
|
|
|
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, tba_bo);
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, tma_bo);
|
|
|
|
|
|
|
|
|
|
|
|
if (queue->queue_family_index == RADV_QUEUE_GENERAL) {
|
|
|
|
|
|
uint32_t regs[] = {R_00B000_SPI_SHADER_TBA_LO_PS,
|
|
|
|
|
|
R_00B100_SPI_SHADER_TBA_LO_VS,
|
|
|
|
|
|
R_00B200_SPI_SHADER_TBA_LO_GS,
|
|
|
|
|
|
R_00B300_SPI_SHADER_TBA_LO_ES,
|
|
|
|
|
|
R_00B400_SPI_SHADER_TBA_LO_HS,
|
|
|
|
|
|
R_00B500_SPI_SHADER_TBA_LO_LS};
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(regs); ++i) {
|
|
|
|
|
|
radeon_set_sh_reg_seq(cs, regs[i], 4);
|
|
|
|
|
|
radeon_emit(cs, tba_va >> 8);
|
|
|
|
|
|
radeon_emit(cs, tba_va >> 40);
|
|
|
|
|
|
radeon_emit(cs, tma_va >> 8);
|
|
|
|
|
|
radeon_emit(cs, tma_va >> 40);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
radeon_set_sh_reg_seq(cs, R_00B838_COMPUTE_TBA_LO, 4);
|
|
|
|
|
|
radeon_emit(cs, tba_va >> 8);
|
|
|
|
|
|
radeon_emit(cs, tba_va >> 40);
|
|
|
|
|
|
radeon_emit(cs, tma_va >> 8);
|
|
|
|
|
|
radeon_emit(cs, tma_va >> 40);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-13 12:30:21 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_init_graphics_state(struct radeon_cmdbuf *cs, struct radv_queue *queue)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_device *device = queue->device;
|
|
|
|
|
|
|
|
|
|
|
|
if (device->gfx_init) {
|
|
|
|
|
|
uint64_t va = radv_buffer_get_va(device->gfx_init);
|
|
|
|
|
|
|
|
|
|
|
|
radeon_emit(cs, PKT3(PKT3_INDIRECT_BUFFER_CIK, 2, 0));
|
|
|
|
|
|
radeon_emit(cs, va);
|
|
|
|
|
|
radeon_emit(cs, va >> 32);
|
|
|
|
|
|
radeon_emit(cs, device->gfx_init_size_dw & 0xffff);
|
|
|
|
|
|
|
|
|
|
|
|
radv_cs_add_buffer(device->ws, cs, device->gfx_init);
|
|
|
|
|
|
} else {
|
2020-04-24 11:13:51 +01:00
|
|
|
|
si_emit_graphics(device, cs);
|
2018-09-13 12:30:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_init_compute_state(struct radeon_cmdbuf *cs, struct radv_queue *queue)
|
|
|
|
|
|
{
|
2020-08-11 10:00:42 +02:00
|
|
|
|
si_emit_compute(queue->device, cs);
|
2018-09-13 12:30:21 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-29 13:53:05 +01:00
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_get_preamble_cs(struct radv_queue *queue,
|
2019-10-31 22:53:30 +01:00
|
|
|
|
uint32_t scratch_size_per_wave,
|
|
|
|
|
|
uint32_t scratch_waves,
|
|
|
|
|
|
uint32_t compute_scratch_size_per_wave,
|
|
|
|
|
|
uint32_t compute_scratch_waves,
|
2017-01-20 11:06:52 +10:00
|
|
|
|
uint32_t esgs_ring_size,
|
|
|
|
|
|
uint32_t gsvs_ring_size,
|
2017-03-30 08:02:14 +01:00
|
|
|
|
bool needs_tess_rings,
|
2019-09-09 10:26:54 +02:00
|
|
|
|
bool needs_gds,
|
2020-01-14 09:14:07 +01:00
|
|
|
|
bool needs_gds_oa,
|
2017-04-03 04:38:12 +01:00
|
|
|
|
bool needs_sample_positions,
|
2018-06-18 21:07:10 -04:00
|
|
|
|
struct radeon_cmdbuf **initial_full_flush_preamble_cs,
|
|
|
|
|
|
struct radeon_cmdbuf **initial_preamble_cs,
|
|
|
|
|
|
struct radeon_cmdbuf **continue_preamble_cs)
|
2017-01-29 13:53:05 +01:00
|
|
|
|
{
|
|
|
|
|
|
struct radeon_winsys_bo *scratch_bo = NULL;
|
|
|
|
|
|
struct radeon_winsys_bo *descriptor_bo = NULL;
|
|
|
|
|
|
struct radeon_winsys_bo *compute_scratch_bo = NULL;
|
2017-01-20 11:06:52 +10:00
|
|
|
|
struct radeon_winsys_bo *esgs_ring_bo = NULL;
|
|
|
|
|
|
struct radeon_winsys_bo *gsvs_ring_bo = NULL;
|
2018-02-25 23:23:45 +00:00
|
|
|
|
struct radeon_winsys_bo *tess_rings_bo = NULL;
|
2019-09-09 10:26:54 +02:00
|
|
|
|
struct radeon_winsys_bo *gds_bo = NULL;
|
|
|
|
|
|
struct radeon_winsys_bo *gds_oa_bo = NULL;
|
2018-06-18 21:07:10 -04:00
|
|
|
|
struct radeon_cmdbuf *dest_cs[3] = {0};
|
2020-01-14 09:14:07 +01:00
|
|
|
|
bool add_tess_rings = false, add_gds = false, add_gds_oa = false, add_sample_positions = false;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
unsigned tess_factor_ring_size = 0, tess_offchip_ring_size = 0;
|
|
|
|
|
|
unsigned max_offchip_buffers;
|
|
|
|
|
|
unsigned hs_offchip_param = 0;
|
2018-02-25 23:23:45 +00:00
|
|
|
|
unsigned tess_offchip_ring_offset;
|
2017-10-25 07:12:13 +01:00
|
|
|
|
uint32_t ring_bo_flags = RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
if (!queue->has_tess_rings) {
|
|
|
|
|
|
if (needs_tess_rings)
|
|
|
|
|
|
add_tess_rings = true;
|
|
|
|
|
|
}
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (!queue->has_gds) {
|
|
|
|
|
|
if (needs_gds)
|
|
|
|
|
|
add_gds = true;
|
|
|
|
|
|
}
|
2020-01-14 09:14:07 +01:00
|
|
|
|
if (!queue->has_gds_oa) {
|
|
|
|
|
|
if (needs_gds_oa)
|
|
|
|
|
|
add_gds_oa = true;
|
|
|
|
|
|
}
|
2017-04-03 04:38:12 +01:00
|
|
|
|
if (!queue->has_sample_positions) {
|
|
|
|
|
|
if (needs_sample_positions)
|
|
|
|
|
|
add_sample_positions = true;
|
|
|
|
|
|
}
|
2017-03-30 08:02:14 +01:00
|
|
|
|
tess_factor_ring_size = 32768 * queue->device->physical_device->rad_info.max_se;
|
|
|
|
|
|
hs_offchip_param = radv_get_hs_offchip_param(queue->device,
|
|
|
|
|
|
&max_offchip_buffers);
|
2018-02-25 23:23:45 +00:00
|
|
|
|
tess_offchip_ring_offset = align(tess_factor_ring_size, 64 * 1024);
|
2017-03-30 08:02:14 +01:00
|
|
|
|
tess_offchip_ring_size = max_offchip_buffers *
|
|
|
|
|
|
queue->device->tess_offchip_block_dw_size * 4;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
scratch_size_per_wave = MAX2(scratch_size_per_wave, queue->scratch_size_per_wave);
|
|
|
|
|
|
if (scratch_size_per_wave)
|
|
|
|
|
|
scratch_waves = MIN2(scratch_waves, UINT32_MAX / scratch_size_per_wave);
|
|
|
|
|
|
else
|
|
|
|
|
|
scratch_waves = 0;
|
|
|
|
|
|
|
|
|
|
|
|
compute_scratch_size_per_wave = MAX2(compute_scratch_size_per_wave, queue->compute_scratch_size_per_wave);
|
|
|
|
|
|
if (compute_scratch_size_per_wave)
|
|
|
|
|
|
compute_scratch_waves = MIN2(compute_scratch_waves, UINT32_MAX / compute_scratch_size_per_wave);
|
|
|
|
|
|
else
|
|
|
|
|
|
compute_scratch_waves = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (scratch_size_per_wave <= queue->scratch_size_per_wave &&
|
|
|
|
|
|
scratch_waves <= queue->scratch_waves &&
|
|
|
|
|
|
compute_scratch_size_per_wave <= queue->compute_scratch_size_per_wave &&
|
|
|
|
|
|
compute_scratch_waves <= queue->compute_scratch_waves &&
|
2017-01-20 11:06:52 +10:00
|
|
|
|
esgs_ring_size <= queue->esgs_ring_size &&
|
2017-02-20 09:26:00 +01:00
|
|
|
|
gsvs_ring_size <= queue->gsvs_ring_size &&
|
2020-01-14 09:14:07 +01:00
|
|
|
|
!add_tess_rings && !add_gds && !add_gds_oa && !add_sample_positions &&
|
2017-02-20 09:26:00 +01:00
|
|
|
|
queue->initial_preamble_cs) {
|
2017-09-02 12:59:55 +02:00
|
|
|
|
*initial_full_flush_preamble_cs = queue->initial_full_flush_preamble_cs;
|
2017-02-20 09:26:00 +01:00
|
|
|
|
*initial_preamble_cs = queue->initial_preamble_cs;
|
|
|
|
|
|
*continue_preamble_cs = queue->continue_preamble_cs;
|
2019-10-31 22:53:30 +01:00
|
|
|
|
if (!scratch_size_per_wave && !compute_scratch_size_per_wave &&
|
|
|
|
|
|
!esgs_ring_size && !gsvs_ring_size && !needs_tess_rings &&
|
2020-01-14 09:14:07 +01:00
|
|
|
|
!needs_gds && !needs_gds_oa && !needs_sample_positions)
|
2017-02-20 09:26:00 +01:00
|
|
|
|
*continue_preamble_cs = NULL;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
uint32_t scratch_size = scratch_size_per_wave * scratch_waves;
|
|
|
|
|
|
uint32_t queue_scratch_size = queue->scratch_size_per_wave * queue->scratch_waves;
|
|
|
|
|
|
if (scratch_size > queue_scratch_size) {
|
2017-01-29 13:53:05 +01:00
|
|
|
|
scratch_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
scratch_size,
|
|
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (!scratch_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else
|
|
|
|
|
|
scratch_bo = queue->scratch_bo;
|
|
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
uint32_t compute_scratch_size = compute_scratch_size_per_wave * compute_scratch_waves;
|
|
|
|
|
|
uint32_t compute_queue_scratch_size = queue->compute_scratch_size_per_wave * queue->compute_scratch_waves;
|
|
|
|
|
|
if (compute_scratch_size > compute_queue_scratch_size) {
|
2017-01-29 13:53:05 +01:00
|
|
|
|
compute_scratch_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
compute_scratch_size,
|
|
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (!compute_scratch_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
compute_scratch_bo = queue->compute_scratch_bo;
|
|
|
|
|
|
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (esgs_ring_size > queue->esgs_ring_size) {
|
|
|
|
|
|
esgs_ring_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
esgs_ring_size,
|
|
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (!esgs_ring_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
esgs_ring_bo = queue->esgs_ring_bo;
|
|
|
|
|
|
esgs_ring_size = queue->esgs_ring_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (gsvs_ring_size > queue->gsvs_ring_size) {
|
|
|
|
|
|
gsvs_ring_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
gsvs_ring_size,
|
|
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (!gsvs_ring_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
gsvs_ring_bo = queue->gsvs_ring_bo;
|
|
|
|
|
|
gsvs_ring_size = queue->gsvs_ring_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-03-30 08:02:14 +01:00
|
|
|
|
if (add_tess_rings) {
|
2018-02-25 23:23:45 +00:00
|
|
|
|
tess_rings_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
tess_offchip_ring_offset + tess_offchip_ring_size,
|
|
|
|
|
|
256,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (!tess_rings_bo)
|
2017-03-30 08:02:14 +01:00
|
|
|
|
goto fail;
|
|
|
|
|
|
} else {
|
2018-02-25 23:23:45 +00:00
|
|
|
|
tess_rings_bo = queue->tess_rings_bo;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (add_gds) {
|
|
|
|
|
|
assert(queue->device->physical_device->rad_info.chip_class >= GFX10);
|
|
|
|
|
|
|
|
|
|
|
|
/* 4 streamout GDS counters.
|
|
|
|
|
|
* We need 256B (64 dw) of GDS, otherwise streamout hangs.
|
|
|
|
|
|
*/
|
|
|
|
|
|
gds_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
256, 4,
|
|
|
|
|
|
RADEON_DOMAIN_GDS,
|
|
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
|
|
|
|
|
if (!gds_bo)
|
|
|
|
|
|
goto fail;
|
2020-01-14 09:14:07 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
gds_bo = queue->gds_bo;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (add_gds_oa) {
|
|
|
|
|
|
assert(queue->device->physical_device->rad_info.chip_class >= GFX10);
|
2019-09-09 10:26:54 +02:00
|
|
|
|
|
|
|
|
|
|
gds_oa_bo = queue->device->ws->buffer_create(queue->device->ws,
|
|
|
|
|
|
4, 1,
|
|
|
|
|
|
RADEON_DOMAIN_OA,
|
|
|
|
|
|
ring_bo_flags,
|
|
|
|
|
|
RADV_BO_PRIORITY_SCRATCH);
|
|
|
|
|
|
if (!gds_oa_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
gds_oa_bo = queue->gds_oa_bo;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (scratch_bo != queue->scratch_bo ||
|
|
|
|
|
|
esgs_ring_bo != queue->esgs_ring_bo ||
|
2017-03-30 08:02:14 +01:00
|
|
|
|
gsvs_ring_bo != queue->gsvs_ring_bo ||
|
2018-02-25 23:23:45 +00:00
|
|
|
|
tess_rings_bo != queue->tess_rings_bo ||
|
|
|
|
|
|
add_sample_positions) {
|
2017-01-20 11:06:52 +10:00
|
|
|
|
uint32_t size = 0;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
if (gsvs_ring_bo || esgs_ring_bo ||
|
2018-02-25 23:23:45 +00:00
|
|
|
|
tess_rings_bo || add_sample_positions) {
|
2017-03-30 08:02:14 +01:00
|
|
|
|
size = 112; /* 2 dword + 2 padding + 4 dword * 6 */
|
2017-04-03 04:38:12 +01:00
|
|
|
|
if (add_sample_positions)
|
2019-01-17 18:11:08 +01:00
|
|
|
|
size += 128; /* 64+32+16+8 = 120 bytes */
|
2017-04-03 04:38:12 +01:00
|
|
|
|
}
|
2017-01-20 11:06:52 +10:00
|
|
|
|
else if (scratch_bo)
|
|
|
|
|
|
size = 8; /* 2 dword */
|
|
|
|
|
|
|
2017-01-29 13:53:05 +01:00
|
|
|
|
descriptor_bo = queue->device->ws->buffer_create(queue->device->ws,
|
2017-01-20 11:06:52 +10:00
|
|
|
|
size,
|
2017-01-29 13:53:05 +01:00
|
|
|
|
4096,
|
|
|
|
|
|
RADEON_DOMAIN_VRAM,
|
2017-12-05 14:22:17 +01:00
|
|
|
|
RADEON_FLAG_CPU_ACCESS |
|
|
|
|
|
|
RADEON_FLAG_NO_INTERPROCESS_SHARING |
|
2019-01-28 00:28:05 +01:00
|
|
|
|
RADEON_FLAG_READ_ONLY,
|
|
|
|
|
|
RADV_BO_PRIORITY_DESCRIPTOR);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (!descriptor_bo)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else
|
|
|
|
|
|
descriptor_bo = queue->descriptor_bo;
|
|
|
|
|
|
|
2019-01-17 18:11:10 +01:00
|
|
|
|
if (descriptor_bo != queue->descriptor_bo) {
|
|
|
|
|
|
uint32_t *map = (uint32_t*)queue->device->ws->buffer_map(descriptor_bo);
|
2020-06-20 21:12:01 +02:00
|
|
|
|
if (!map)
|
|
|
|
|
|
goto fail;
|
2019-01-17 18:11:10 +01:00
|
|
|
|
|
|
|
|
|
|
if (scratch_bo) {
|
|
|
|
|
|
uint64_t scratch_va = radv_buffer_get_va(scratch_bo);
|
|
|
|
|
|
uint32_t rsrc1 = S_008F04_BASE_ADDRESS_HI(scratch_va >> 32) |
|
|
|
|
|
|
S_008F04_SWIZZLE_ENABLE(1);
|
|
|
|
|
|
map[0] = scratch_va;
|
|
|
|
|
|
map[1] = rsrc1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (esgs_ring_bo || gsvs_ring_bo || tess_rings_bo || add_sample_positions)
|
|
|
|
|
|
fill_geom_tess_rings(queue, map, add_sample_positions,
|
|
|
|
|
|
esgs_ring_size, esgs_ring_bo,
|
|
|
|
|
|
gsvs_ring_size, gsvs_ring_bo,
|
|
|
|
|
|
tess_factor_ring_size,
|
|
|
|
|
|
tess_offchip_ring_offset,
|
|
|
|
|
|
tess_offchip_ring_size,
|
|
|
|
|
|
tess_rings_bo);
|
|
|
|
|
|
|
|
|
|
|
|
queue->device->ws->buffer_unmap(descriptor_bo);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
for(int i = 0; i < 3; ++i) {
|
2020-09-01 21:28:16 +02:00
|
|
|
|
enum rgp_flush_bits sqtt_flush_bits = 0;
|
2018-06-18 21:07:10 -04:00
|
|
|
|
struct radeon_cmdbuf *cs = NULL;
|
2017-02-20 09:26:00 +01:00
|
|
|
|
cs = queue->device->ws->cs_create(queue->device->ws,
|
|
|
|
|
|
queue->queue_family_index ? RING_COMPUTE : RING_GFX);
|
|
|
|
|
|
if (!cs)
|
|
|
|
|
|
goto fail;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-02-20 09:26:00 +01:00
|
|
|
|
dest_cs[i] = cs;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-02-20 09:26:00 +01:00
|
|
|
|
if (scratch_bo)
|
2018-07-10 16:13:38 +02:00
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, scratch_bo);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2018-09-13 12:30:21 +02:00
|
|
|
|
/* Emit initial configuration. */
|
|
|
|
|
|
switch (queue->queue_family_index) {
|
|
|
|
|
|
case RADV_QUEUE_GENERAL:
|
|
|
|
|
|
radv_init_graphics_state(cs, queue);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_QUEUE_COMPUTE:
|
|
|
|
|
|
radv_init_compute_state(cs, queue);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_QUEUE_TRANSFER:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (esgs_ring_bo || gsvs_ring_bo || tess_rings_bo) {
|
2017-02-20 09:26:00 +01:00
|
|
|
|
radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
|
|
|
|
|
|
radeon_emit(cs, EVENT_TYPE(V_028A90_VS_PARTIAL_FLUSH) | EVENT_INDEX(4));
|
2019-07-08 13:45:08 +02:00
|
|
|
|
|
2019-07-18 16:12:53 +10:00
|
|
|
|
radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0));
|
|
|
|
|
|
radeon_emit(cs, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0));
|
2017-03-30 08:02:14 +01:00
|
|
|
|
}
|
2017-02-20 09:26:00 +01:00
|
|
|
|
|
2018-05-17 10:11:44 +02:00
|
|
|
|
radv_emit_gs_ring_sizes(queue, cs, esgs_ring_bo, esgs_ring_size,
|
|
|
|
|
|
gsvs_ring_bo, gsvs_ring_size);
|
|
|
|
|
|
radv_emit_tess_factor_ring(queue, cs, hs_offchip_param,
|
|
|
|
|
|
tess_factor_ring_size, tess_rings_bo);
|
|
|
|
|
|
radv_emit_global_shader_pointers(queue, cs, descriptor_bo);
|
2019-10-31 22:53:30 +01:00
|
|
|
|
radv_emit_compute_scratch(queue, cs, compute_scratch_size_per_wave,
|
|
|
|
|
|
compute_scratch_waves, compute_scratch_bo);
|
|
|
|
|
|
radv_emit_graphics_scratch(queue, cs, scratch_size_per_wave,
|
|
|
|
|
|
scratch_waves, scratch_bo);
|
2020-08-18 18:51:46 +02:00
|
|
|
|
radv_emit_trap_handler(queue, cs, queue->device->tma_bo);
|
2017-02-20 09:26:00 +01:00
|
|
|
|
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (gds_bo)
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, gds_bo);
|
|
|
|
|
|
if (gds_oa_bo)
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, gds_oa_bo);
|
2020-02-20 13:19:41 +01:00
|
|
|
|
|
|
|
|
|
|
if (queue->device->trace_bo)
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs, queue->device->trace_bo);
|
2019-09-09 10:26:54 +02:00
|
|
|
|
|
2020-07-13 20:09:15 +02:00
|
|
|
|
if (queue->device->border_color_data.bo)
|
|
|
|
|
|
radv_cs_add_buffer(queue->device->ws, cs,
|
|
|
|
|
|
queue->device->border_color_data.bo);
|
|
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
if (i == 0) {
|
|
|
|
|
|
si_cs_emit_cache_flush(cs,
|
|
|
|
|
|
queue->device->physical_device->rad_info.chip_class,
|
|
|
|
|
|
NULL, 0,
|
|
|
|
|
|
queue->queue_family_index == RING_COMPUTE &&
|
2019-05-14 22:16:20 -04:00
|
|
|
|
queue->device->physical_device->rad_info.chip_class >= GFX7,
|
2017-09-02 12:59:55 +02:00
|
|
|
|
(queue->queue_family_index == RADV_QUEUE_COMPUTE ? RADV_CMD_FLAG_CS_PARTIAL_FLUSH : (RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_PS_PARTIAL_FLUSH)) |
|
|
|
|
|
|
RADV_CMD_FLAG_INV_ICACHE |
|
2019-06-25 17:57:45 +02:00
|
|
|
|
RADV_CMD_FLAG_INV_SCACHE |
|
|
|
|
|
|
RADV_CMD_FLAG_INV_VCACHE |
|
|
|
|
|
|
RADV_CMD_FLAG_INV_L2 |
|
2020-09-01 21:28:16 +02:00
|
|
|
|
RADV_CMD_FLAG_START_PIPELINE_STATS, &sqtt_flush_bits, 0);
|
2017-09-02 12:59:55 +02:00
|
|
|
|
} else if (i == 1) {
|
2017-02-20 09:26:00 +01:00
|
|
|
|
si_cs_emit_cache_flush(cs,
|
|
|
|
|
|
queue->device->physical_device->rad_info.chip_class,
|
2017-06-06 09:01:48 +10:00
|
|
|
|
NULL, 0,
|
2017-02-20 09:26:00 +01:00
|
|
|
|
queue->queue_family_index == RING_COMPUTE &&
|
2019-05-14 22:16:20 -04:00
|
|
|
|
queue->device->physical_device->rad_info.chip_class >= GFX7,
|
2017-02-20 09:26:00 +01:00
|
|
|
|
RADV_CMD_FLAG_INV_ICACHE |
|
2019-06-25 17:57:45 +02:00
|
|
|
|
RADV_CMD_FLAG_INV_SCACHE |
|
|
|
|
|
|
RADV_CMD_FLAG_INV_VCACHE |
|
|
|
|
|
|
RADV_CMD_FLAG_INV_L2 |
|
2020-09-01 21:28:16 +02:00
|
|
|
|
RADV_CMD_FLAG_START_PIPELINE_STATS, &sqtt_flush_bits, 0);
|
2017-02-20 09:26:00 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-24 15:38:19 +02:00
|
|
|
|
if (queue->device->ws->cs_finalize(cs) != VK_SUCCESS)
|
2017-02-20 09:26:00 +01:00
|
|
|
|
goto fail;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
if (queue->initial_full_flush_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->initial_full_flush_preamble_cs);
|
|
|
|
|
|
|
2017-02-20 09:26:00 +01:00
|
|
|
|
if (queue->initial_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->initial_preamble_cs);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-02-20 09:26:00 +01:00
|
|
|
|
if (queue->continue_preamble_cs)
|
|
|
|
|
|
queue->device->ws->cs_destroy(queue->continue_preamble_cs);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
queue->initial_full_flush_preamble_cs = dest_cs[0];
|
|
|
|
|
|
queue->initial_preamble_cs = dest_cs[1];
|
|
|
|
|
|
queue->continue_preamble_cs = dest_cs[2];
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
|
|
|
|
|
if (scratch_bo != queue->scratch_bo) {
|
|
|
|
|
|
if (queue->scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->scratch_bo);
|
|
|
|
|
|
queue->scratch_bo = scratch_bo;
|
|
|
|
|
|
}
|
2019-10-31 22:53:30 +01:00
|
|
|
|
queue->scratch_size_per_wave = scratch_size_per_wave;
|
|
|
|
|
|
queue->scratch_waves = scratch_waves;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
|
|
|
|
|
if (compute_scratch_bo != queue->compute_scratch_bo) {
|
|
|
|
|
|
if (queue->compute_scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->compute_scratch_bo);
|
|
|
|
|
|
queue->compute_scratch_bo = compute_scratch_bo;
|
|
|
|
|
|
}
|
2019-10-31 22:53:30 +01:00
|
|
|
|
queue->compute_scratch_size_per_wave = compute_scratch_size_per_wave;
|
|
|
|
|
|
queue->compute_scratch_waves = compute_scratch_waves;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (esgs_ring_bo != queue->esgs_ring_bo) {
|
|
|
|
|
|
if (queue->esgs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->esgs_ring_bo);
|
|
|
|
|
|
queue->esgs_ring_bo = esgs_ring_bo;
|
|
|
|
|
|
queue->esgs_ring_size = esgs_ring_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (gsvs_ring_bo != queue->gsvs_ring_bo) {
|
|
|
|
|
|
if (queue->gsvs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->gsvs_ring_bo);
|
|
|
|
|
|
queue->gsvs_ring_bo = gsvs_ring_bo;
|
|
|
|
|
|
queue->gsvs_ring_size = gsvs_ring_size;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (tess_rings_bo != queue->tess_rings_bo) {
|
|
|
|
|
|
queue->tess_rings_bo = tess_rings_bo;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
queue->has_tess_rings = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (gds_bo != queue->gds_bo) {
|
|
|
|
|
|
queue->gds_bo = gds_bo;
|
|
|
|
|
|
queue->has_gds = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-01-14 09:14:07 +01:00
|
|
|
|
if (gds_oa_bo != queue->gds_oa_bo) {
|
2019-09-09 10:26:54 +02:00
|
|
|
|
queue->gds_oa_bo = gds_oa_bo;
|
2020-01-14 09:14:07 +01:00
|
|
|
|
queue->has_gds_oa = true;
|
|
|
|
|
|
}
|
2019-09-09 10:26:54 +02:00
|
|
|
|
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (descriptor_bo != queue->descriptor_bo) {
|
|
|
|
|
|
if (queue->descriptor_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->descriptor_bo);
|
|
|
|
|
|
|
|
|
|
|
|
queue->descriptor_bo = descriptor_bo;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-04-03 04:38:12 +01:00
|
|
|
|
if (add_sample_positions)
|
|
|
|
|
|
queue->has_sample_positions = true;
|
|
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
|
*initial_full_flush_preamble_cs = queue->initial_full_flush_preamble_cs;
|
2017-02-20 09:26:00 +01:00
|
|
|
|
*initial_preamble_cs = queue->initial_preamble_cs;
|
|
|
|
|
|
*continue_preamble_cs = queue->continue_preamble_cs;
|
|
|
|
|
|
if (!scratch_size && !compute_scratch_size && !esgs_ring_size && !gsvs_ring_size)
|
|
|
|
|
|
*continue_preamble_cs = NULL;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
fail:
|
2017-02-20 09:26:00 +01:00
|
|
|
|
for (int i = 0; i < ARRAY_SIZE(dest_cs); ++i)
|
|
|
|
|
|
if (dest_cs[i])
|
|
|
|
|
|
queue->device->ws->cs_destroy(dest_cs[i]);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (descriptor_bo && descriptor_bo != queue->descriptor_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(descriptor_bo);
|
|
|
|
|
|
if (scratch_bo && scratch_bo != queue->scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(scratch_bo);
|
|
|
|
|
|
if (compute_scratch_bo && compute_scratch_bo != queue->compute_scratch_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(compute_scratch_bo);
|
2017-01-20 11:06:52 +10:00
|
|
|
|
if (esgs_ring_bo && esgs_ring_bo != queue->esgs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(esgs_ring_bo);
|
|
|
|
|
|
if (gsvs_ring_bo && gsvs_ring_bo != queue->gsvs_ring_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(gsvs_ring_bo);
|
2018-02-25 23:23:45 +00:00
|
|
|
|
if (tess_rings_bo && tess_rings_bo != queue->tess_rings_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(tess_rings_bo);
|
2019-09-09 10:26:54 +02:00
|
|
|
|
if (gds_bo && gds_bo != queue->gds_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(gds_bo);
|
|
|
|
|
|
if (gds_oa_bo && gds_oa_bo != queue->gds_oa_bo)
|
|
|
|
|
|
queue->device->ws->buffer_destroy(gds_oa_bo);
|
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(queue->device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
static VkResult radv_alloc_sem_counts(struct radv_device *device,
|
2018-05-31 01:06:41 +02:00
|
|
|
|
struct radv_winsys_sem_counts *counts,
|
2017-02-27 19:14:00 +00:00
|
|
|
|
int num_sems,
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_semaphore_part **sems,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
const uint64_t *timeline_values,
|
|
|
|
|
|
VkFence _fence,
|
|
|
|
|
|
bool is_signal)
|
2017-02-27 19:14:00 +00:00
|
|
|
|
{
|
2020-07-16 02:44:22 +02:00
|
|
|
|
int syncobj_idx = 0, non_reset_idx = 0, sem_idx = 0, timeline_idx = 0;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
|
if (num_sems == 0 && _fence == VK_NULL_HANDLE)
|
2017-02-27 19:14:00 +00:00
|
|
|
|
return VK_SUCCESS;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
|
for (uint32_t i = 0; i < num_sems; i++) {
|
2019-10-22 10:18:06 +02:00
|
|
|
|
switch(sems[i]->kind) {
|
|
|
|
|
|
case RADV_SEMAPHORE_SYNCOBJ:
|
2017-02-27 19:14:00 +00:00
|
|
|
|
counts->syncobj_count++;
|
2020-06-22 01:11:03 +02:00
|
|
|
|
counts->syncobj_reset_count++;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_WINSYS:
|
2017-02-27 19:14:00 +00:00
|
|
|
|
counts->sem_count++;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_NONE:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_TIMELINE:
|
|
|
|
|
|
counts->syncobj_count++;
|
|
|
|
|
|
break;
|
2020-07-16 02:44:22 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE_SYNCOBJ:
|
|
|
|
|
|
counts->timeline_syncobj_count++;
|
|
|
|
|
|
break;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
|
if (_fence != VK_NULL_HANDLE) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
if (part->kind == RADV_FENCE_SYNCOBJ)
|
2017-11-27 23:58:35 +01:00
|
|
|
|
counts->syncobj_count++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-16 02:44:22 +02:00
|
|
|
|
if (counts->syncobj_count || counts->timeline_syncobj_count) {
|
|
|
|
|
|
counts->points = (uint64_t *)malloc(
|
|
|
|
|
|
sizeof(*counts->syncobj) * counts->syncobj_count +
|
|
|
|
|
|
(sizeof(*counts->syncobj) + sizeof(*counts->points)) * counts->timeline_syncobj_count);
|
|
|
|
|
|
if (!counts->points)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2020-07-16 02:44:22 +02:00
|
|
|
|
counts->syncobj = (uint32_t*)(counts->points + counts->timeline_syncobj_count);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (counts->sem_count) {
|
|
|
|
|
|
counts->sem = (struct radeon_winsys_sem **)malloc(sizeof(struct radeon_winsys_sem *) * counts->sem_count);
|
|
|
|
|
|
if (!counts->sem) {
|
|
|
|
|
|
free(counts->syncobj);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-22 01:11:03 +02:00
|
|
|
|
non_reset_idx = counts->syncobj_reset_count;
|
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
|
for (uint32_t i = 0; i < num_sems; i++) {
|
2019-10-23 15:31:43 +02:00
|
|
|
|
switch(sems[i]->kind) {
|
2019-10-20 22:50:58 +02:00
|
|
|
|
case RADV_SEMAPHORE_NONE:
|
|
|
|
|
|
unreachable("Empty semaphore");
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_SYNCOBJ:
|
2019-10-23 15:31:43 +02:00
|
|
|
|
counts->syncobj[syncobj_idx++] = sems[i]->syncobj;
|
2019-10-20 22:50:58 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_WINSYS:
|
2019-10-23 15:31:43 +02:00
|
|
|
|
counts->sem[sem_idx++] = sems[i]->ws_sem;
|
2019-10-20 22:50:58 +02:00
|
|
|
|
break;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE: {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&sems[i]->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
struct radv_timeline_point *point = NULL;
|
|
|
|
|
|
if (is_signal) {
|
|
|
|
|
|
point = radv_timeline_add_point_locked(device, &sems[i]->timeline, timeline_values[i]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
point = radv_timeline_find_point_at_least_locked(device, &sems[i]->timeline, timeline_values[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&sems[i]->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (point) {
|
2020-06-22 01:11:03 +02:00
|
|
|
|
counts->syncobj[non_reset_idx++] = point->syncobj;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
/* Explicitly remove the semaphore so we might not find
|
|
|
|
|
|
* a point later post-submit. */
|
|
|
|
|
|
sems[i] = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-16 02:44:22 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE_SYNCOBJ:
|
|
|
|
|
|
counts->syncobj[counts->syncobj_count + timeline_idx] = sems[i]->syncobj;
|
|
|
|
|
|
counts->points[timeline_idx] = timeline_values[i];
|
|
|
|
|
|
++timeline_idx;
|
|
|
|
|
|
break;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
|
if (_fence != VK_NULL_HANDLE) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
if (part->kind == RADV_FENCE_SYNCOBJ)
|
2020-06-22 01:11:03 +02:00
|
|
|
|
counts->syncobj[non_reset_idx++] = part->syncobj;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-22 01:11:03 +02:00
|
|
|
|
assert(MAX2(syncobj_idx, non_reset_idx) <= counts->syncobj_count);
|
|
|
|
|
|
counts->syncobj_count = MAX2(syncobj_idx, non_reset_idx);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-31 00:57:55 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_free_sem_info(struct radv_winsys_sem_info *sem_info)
|
2017-02-27 19:14:00 +00:00
|
|
|
|
{
|
2020-07-16 02:44:22 +02:00
|
|
|
|
free(sem_info->wait.points);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
free(sem_info->wait.sem);
|
2020-07-16 02:44:22 +02:00
|
|
|
|
free(sem_info->signal.points);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
free(sem_info->signal.sem);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-13 23:26:32 +01:00
|
|
|
|
|
|
|
|
|
|
static void radv_free_temp_syncobjs(struct radv_device *device,
|
|
|
|
|
|
int num_sems,
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_semaphore_part *sems)
|
2017-11-13 23:26:32 +01:00
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < num_sems; i++) {
|
2019-10-23 15:31:43 +02:00
|
|
|
|
radv_destroy_semaphore_part(device, sems + i);
|
2017-11-13 23:26:32 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-31 00:57:55 +02:00
|
|
|
|
static VkResult
|
2019-10-22 10:18:06 +02:00
|
|
|
|
radv_alloc_sem_info(struct radv_device *device,
|
2018-05-31 01:06:41 +02:00
|
|
|
|
struct radv_winsys_sem_info *sem_info,
|
2018-05-31 00:57:55 +02:00
|
|
|
|
int num_wait_sems,
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_semaphore_part **wait_sems,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
const uint64_t *wait_values,
|
2018-05-31 00:57:55 +02:00
|
|
|
|
int num_signal_sems,
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_semaphore_part **signal_sems,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
const uint64_t *signal_values,
|
2018-05-31 00:57:55 +02:00
|
|
|
|
VkFence fence)
|
2017-02-27 19:14:00 +00:00
|
|
|
|
{
|
|
|
|
|
|
VkResult ret;
|
|
|
|
|
|
memset(sem_info, 0, sizeof(*sem_info));
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
ret = radv_alloc_sem_counts(device, &sem_info->wait, num_wait_sems, wait_sems, wait_values, VK_NULL_HANDLE, false);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return ret;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
ret = radv_alloc_sem_counts(device, &sem_info->signal, num_signal_sems, signal_sems, signal_values, fence, true);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
if (ret)
|
|
|
|
|
|
radv_free_sem_info(sem_info);
|
|
|
|
|
|
|
|
|
|
|
|
/* caller can override these */
|
|
|
|
|
|
sem_info->cs_emit_wait = true;
|
|
|
|
|
|
sem_info->cs_emit_signal = true;
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_finalize_timelines(struct radv_device *device,
|
|
|
|
|
|
uint32_t num_wait_sems,
|
|
|
|
|
|
struct radv_semaphore_part **wait_sems,
|
|
|
|
|
|
const uint64_t *wait_values,
|
|
|
|
|
|
uint32_t num_signal_sems,
|
|
|
|
|
|
struct radv_semaphore_part **signal_sems,
|
2019-10-28 02:44:54 +01:00
|
|
|
|
const uint64_t *signal_values,
|
|
|
|
|
|
struct list_head *processing_list)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < num_wait_sems; ++i) {
|
|
|
|
|
|
if (wait_sems[i] && wait_sems[i]->kind == RADV_SEMAPHORE_TIMELINE) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&wait_sems[i]->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
struct radv_timeline_point *point =
|
|
|
|
|
|
radv_timeline_find_point_at_least_locked(device, &wait_sems[i]->timeline, wait_values[i]);
|
2019-11-22 01:51:36 +01:00
|
|
|
|
point->wait_count -= 2;
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&wait_sems[i]->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
for (uint32_t i = 0; i < num_signal_sems; ++i) {
|
|
|
|
|
|
if (signal_sems[i] && signal_sems[i]->kind == RADV_SEMAPHORE_TIMELINE) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&signal_sems[i]->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
struct radv_timeline_point *point =
|
|
|
|
|
|
radv_timeline_find_point_at_least_locked(device, &signal_sems[i]->timeline, signal_values[i]);
|
2019-11-22 01:51:36 +01:00
|
|
|
|
signal_sems[i]->timeline.highest_submitted =
|
|
|
|
|
|
MAX2(signal_sems[i]->timeline.highest_submitted, point->value);
|
|
|
|
|
|
point->wait_count -= 2;
|
2019-10-28 02:44:54 +01:00
|
|
|
|
radv_timeline_trigger_waiters_locked(&signal_sems[i]->timeline, processing_list);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&signal_sems[i]->timeline.mutex);
|
2020-07-16 02:44:22 +02:00
|
|
|
|
} else if (signal_sems[i] && signal_sems[i]->kind == RADV_SEMAPHORE_TIMELINE_SYNCOBJ) {
|
|
|
|
|
|
signal_sems[i]->timeline_syncobj.max_point =
|
|
|
|
|
|
MAX2(signal_sems[i]->timeline_syncobj.max_point, signal_values[i]);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-21 15:55:38 +02:00
|
|
|
|
static VkResult
|
2019-10-19 17:05:22 +02:00
|
|
|
|
radv_sparse_buffer_bind_memory(struct radv_device *device,
|
|
|
|
|
|
const VkSparseBufferMemoryBindInfo *bind)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, bind->buffer);
|
2020-07-21 15:55:38 +02:00
|
|
|
|
VkResult result;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bind->bindCount; ++i) {
|
|
|
|
|
|
struct radv_device_memory *mem = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (bind->pBinds[i].memory != VK_NULL_HANDLE)
|
|
|
|
|
|
mem = radv_device_memory_from_handle(bind->pBinds[i].memory);
|
|
|
|
|
|
|
2020-07-21 15:55:38 +02:00
|
|
|
|
result = device->ws->buffer_virtual_bind(buffer->bo,
|
|
|
|
|
|
bind->pBinds[i].resourceOffset,
|
|
|
|
|
|
bind->pBinds[i].size,
|
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
|
bind->pBinds[i].memoryOffset);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
2020-07-21 15:55:38 +02:00
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-21 15:55:38 +02:00
|
|
|
|
static VkResult
|
2019-10-19 17:05:22 +02:00
|
|
|
|
radv_sparse_image_opaque_bind_memory(struct radv_device *device,
|
|
|
|
|
|
const VkSparseImageOpaqueMemoryBindInfo *bind)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, bind->image);
|
2020-07-21 15:55:38 +02:00
|
|
|
|
VkResult result;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bind->bindCount; ++i) {
|
|
|
|
|
|
struct radv_device_memory *mem = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (bind->pBinds[i].memory != VK_NULL_HANDLE)
|
|
|
|
|
|
mem = radv_device_memory_from_handle(bind->pBinds[i].memory);
|
|
|
|
|
|
|
2020-07-21 15:55:38 +02:00
|
|
|
|
result = device->ws->buffer_virtual_bind(image->bo,
|
|
|
|
|
|
bind->pBinds[i].resourceOffset,
|
|
|
|
|
|
bind->pBinds[i].size,
|
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
|
bind->pBinds[i].memoryOffset);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
2020-07-21 15:55:38 +02:00
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-06 19:17:03 +01:00
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_sparse_image_bind_memory(struct radv_device *device,
|
|
|
|
|
|
const VkSparseImageMemoryBindInfo *bind)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, bind->image);
|
|
|
|
|
|
struct radeon_surf *surface = &image->planes[0].surface;
|
|
|
|
|
|
uint32_t bs = vk_format_get_blocksize(image->vk_format);
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bind->bindCount; ++i) {
|
|
|
|
|
|
struct radv_device_memory *mem = NULL;
|
|
|
|
|
|
uint32_t offset, pitch;
|
|
|
|
|
|
uint32_t mem_offset = bind->pBinds[i].memoryOffset;
|
|
|
|
|
|
const uint32_t layer = bind->pBinds[i].subresource.arrayLayer;
|
|
|
|
|
|
const uint32_t level = bind->pBinds[i].subresource.mipLevel;
|
|
|
|
|
|
|
|
|
|
|
|
VkExtent3D bind_extent = bind->pBinds[i].extent;
|
|
|
|
|
|
bind_extent.width = DIV_ROUND_UP(bind_extent.width, vk_format_get_blockwidth(image->vk_format));
|
|
|
|
|
|
bind_extent.height = DIV_ROUND_UP(bind_extent.height, vk_format_get_blockheight(image->vk_format));
|
|
|
|
|
|
|
|
|
|
|
|
VkOffset3D bind_offset = bind->pBinds[i].offset;
|
|
|
|
|
|
bind_offset.x /= vk_format_get_blockwidth(image->vk_format);
|
|
|
|
|
|
bind_offset.y /= vk_format_get_blockheight(image->vk_format);
|
|
|
|
|
|
|
|
|
|
|
|
if (bind->pBinds[i].memory != VK_NULL_HANDLE)
|
|
|
|
|
|
mem = radv_device_memory_from_handle(bind->pBinds[i].memory);
|
|
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
|
|
|
|
|
offset = surface->u.gfx9.surf_slice_size * layer +
|
|
|
|
|
|
surface->u.gfx9.prt_level_offset[level];
|
|
|
|
|
|
pitch = surface->u.gfx9.prt_level_pitch[level];
|
|
|
|
|
|
} else {
|
|
|
|
|
|
offset = surface->u.legacy.level[level].offset +
|
|
|
|
|
|
surface->u.legacy.level[level].slice_size_dw * 4 * layer;
|
|
|
|
|
|
pitch = surface->u.legacy.level[level].nblk_x;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
offset += (bind_offset.y * pitch * bs) +
|
|
|
|
|
|
(bind_offset.x * surface->prt_tile_height * bs);
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t aligned_extent_width = ALIGN(bind_extent.width,
|
|
|
|
|
|
surface->prt_tile_width);
|
|
|
|
|
|
|
|
|
|
|
|
bool whole_subres = bind_offset.x == 0 &&
|
|
|
|
|
|
aligned_extent_width == pitch;
|
|
|
|
|
|
|
|
|
|
|
|
if (whole_subres) {
|
|
|
|
|
|
uint32_t aligned_extent_height = ALIGN(bind_extent.height,
|
|
|
|
|
|
surface->prt_tile_height);
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t size = aligned_extent_width * aligned_extent_height * bs;
|
|
|
|
|
|
result = device->ws->buffer_virtual_bind(image->bo,
|
|
|
|
|
|
offset,
|
|
|
|
|
|
size,
|
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
|
mem_offset);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uint32_t img_increment = pitch * bs;
|
|
|
|
|
|
uint32_t mem_increment = aligned_extent_width * bs;
|
|
|
|
|
|
uint32_t size = mem_increment * surface->prt_tile_height;
|
|
|
|
|
|
for (unsigned y = 0; y < bind_extent.height; y += surface->prt_tile_height) {
|
|
|
|
|
|
result = device->ws->buffer_virtual_bind(image->bo,
|
|
|
|
|
|
offset + img_increment * y,
|
|
|
|
|
|
size,
|
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
|
mem_offset + mem_increment * y);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_get_preambles(struct radv_queue *queue,
|
|
|
|
|
|
const VkCommandBuffer *cmd_buffers,
|
|
|
|
|
|
uint32_t cmd_buffer_count,
|
|
|
|
|
|
struct radeon_cmdbuf **initial_full_flush_preamble_cs,
|
|
|
|
|
|
struct radeon_cmdbuf **initial_preamble_cs,
|
|
|
|
|
|
struct radeon_cmdbuf **continue_preamble_cs)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
2019-10-31 22:53:30 +01:00
|
|
|
|
uint32_t scratch_size_per_wave = 0, waves_wanted = 0;
|
|
|
|
|
|
uint32_t compute_scratch_size_per_wave = 0, compute_waves_wanted = 0;
|
2017-01-20 11:06:52 +10:00
|
|
|
|
uint32_t esgs_ring_size = 0, gsvs_ring_size = 0;
|
2017-03-30 08:02:14 +01:00
|
|
|
|
bool tess_rings_needed = false;
|
2019-09-09 10:26:54 +02:00
|
|
|
|
bool gds_needed = false;
|
2020-01-14 09:14:07 +01:00
|
|
|
|
bool gds_oa_needed = false;
|
2017-04-03 04:38:12 +01:00
|
|
|
|
bool sample_positions_needed = false;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
for (uint32_t j = 0; j < cmd_buffer_count; j++) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer,
|
|
|
|
|
|
cmd_buffers[j]);
|
|
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
scratch_size_per_wave = MAX2(scratch_size_per_wave, cmd_buffer->scratch_size_per_wave_needed);
|
|
|
|
|
|
waves_wanted = MAX2(waves_wanted, cmd_buffer->scratch_waves_wanted);
|
|
|
|
|
|
compute_scratch_size_per_wave = MAX2(compute_scratch_size_per_wave,
|
|
|
|
|
|
cmd_buffer->compute_scratch_size_per_wave_needed);
|
|
|
|
|
|
compute_waves_wanted = MAX2(compute_waves_wanted,
|
|
|
|
|
|
cmd_buffer->compute_scratch_waves_wanted);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
esgs_ring_size = MAX2(esgs_ring_size, cmd_buffer->esgs_ring_size_needed);
|
|
|
|
|
|
gsvs_ring_size = MAX2(gsvs_ring_size, cmd_buffer->gsvs_ring_size_needed);
|
|
|
|
|
|
tess_rings_needed |= cmd_buffer->tess_rings_needed;
|
|
|
|
|
|
gds_needed |= cmd_buffer->gds_needed;
|
2020-01-14 09:14:07 +01:00
|
|
|
|
gds_oa_needed |= cmd_buffer->gds_oa_needed;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
sample_positions_needed |= cmd_buffer->sample_positions_needed;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-31 22:53:30 +01:00
|
|
|
|
return radv_get_preamble_cs(queue, scratch_size_per_wave, waves_wanted,
|
|
|
|
|
|
compute_scratch_size_per_wave, compute_waves_wanted,
|
|
|
|
|
|
esgs_ring_size, gsvs_ring_size, tess_rings_needed,
|
2020-01-14 09:14:07 +01:00
|
|
|
|
gds_needed, gds_oa_needed, sample_positions_needed,
|
2019-10-31 22:53:30 +01:00
|
|
|
|
initial_full_flush_preamble_cs,
|
|
|
|
|
|
initial_preamble_cs, continue_preamble_cs);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_deferred_queue_submission {
|
|
|
|
|
|
struct radv_queue *queue;
|
|
|
|
|
|
VkCommandBuffer *cmd_buffers;
|
|
|
|
|
|
uint32_t cmd_buffer_count;
|
|
|
|
|
|
|
|
|
|
|
|
/* Sparse bindings that happen on a queue. */
|
|
|
|
|
|
VkSparseBufferMemoryBindInfo *buffer_binds;
|
|
|
|
|
|
uint32_t buffer_bind_count;
|
|
|
|
|
|
VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
|
|
|
|
|
|
uint32_t image_opaque_bind_count;
|
2020-12-06 19:17:03 +01:00
|
|
|
|
VkSparseImageMemoryBindInfo *image_binds;
|
|
|
|
|
|
uint32_t image_bind_count;
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
|
|
|
|
|
bool flush_caches;
|
|
|
|
|
|
VkShaderStageFlags wait_dst_stage_mask;
|
|
|
|
|
|
struct radv_semaphore_part **wait_semaphores;
|
|
|
|
|
|
uint32_t wait_semaphore_count;
|
|
|
|
|
|
struct radv_semaphore_part **signal_semaphores;
|
|
|
|
|
|
uint32_t signal_semaphore_count;
|
|
|
|
|
|
VkFence fence;
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
uint64_t *wait_values;
|
|
|
|
|
|
uint64_t *signal_values;
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_semaphore_part *temporary_semaphore_parts;
|
|
|
|
|
|
uint32_t temporary_semaphore_part_count;
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
|
|
|
|
|
struct list_head queue_pending_list;
|
|
|
|
|
|
uint32_t submission_wait_count;
|
|
|
|
|
|
struct radv_timeline_waiter *wait_nodes;
|
|
|
|
|
|
|
|
|
|
|
|
struct list_head processing_list;
|
2019-10-23 15:31:43 +02:00
|
|
|
|
};
|
2019-10-03 21:08:29 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_queue_submission {
|
|
|
|
|
|
const VkCommandBuffer *cmd_buffers;
|
|
|
|
|
|
uint32_t cmd_buffer_count;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
|
|
|
|
|
|
/* Sparse bindings that happen on a queue. */
|
|
|
|
|
|
const VkSparseBufferMemoryBindInfo *buffer_binds;
|
|
|
|
|
|
uint32_t buffer_bind_count;
|
|
|
|
|
|
const VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
|
|
|
|
|
|
uint32_t image_opaque_bind_count;
|
2020-12-06 19:17:03 +01:00
|
|
|
|
const VkSparseImageMemoryBindInfo *image_binds;
|
|
|
|
|
|
uint32_t image_bind_count;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
bool flush_caches;
|
|
|
|
|
|
VkPipelineStageFlags wait_dst_stage_mask;
|
|
|
|
|
|
const VkSemaphore *wait_semaphores;
|
|
|
|
|
|
uint32_t wait_semaphore_count;
|
|
|
|
|
|
const VkSemaphore *signal_semaphores;
|
|
|
|
|
|
uint32_t signal_semaphore_count;
|
|
|
|
|
|
VkFence fence;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
const uint64_t *wait_values;
|
|
|
|
|
|
uint32_t wait_value_count;
|
|
|
|
|
|
const uint64_t *signal_values;
|
|
|
|
|
|
uint32_t signal_value_count;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_queue_trigger_submission(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
uint32_t decrement,
|
|
|
|
|
|
struct list_head *processing_list);
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
static VkResult
|
2019-10-23 15:31:43 +02:00
|
|
|
|
radv_create_deferred_submission(struct radv_queue *queue,
|
|
|
|
|
|
const struct radv_queue_submission *submission,
|
|
|
|
|
|
struct radv_deferred_queue_submission **out)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_deferred_queue_submission *deferred = NULL;
|
|
|
|
|
|
size_t size = sizeof(struct radv_deferred_queue_submission);
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t temporary_count = 0;
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->wait_semaphore_count; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, submission->wait_semaphores[i]);
|
|
|
|
|
|
if (semaphore->temporary.kind != RADV_SEMAPHORE_NONE)
|
|
|
|
|
|
++temporary_count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
size += submission->cmd_buffer_count * sizeof(VkCommandBuffer);
|
|
|
|
|
|
size += submission->buffer_bind_count * sizeof(VkSparseBufferMemoryBindInfo);
|
|
|
|
|
|
size += submission->image_opaque_bind_count * sizeof(VkSparseImageOpaqueMemoryBindInfo);
|
2020-12-06 19:17:03 +01:00
|
|
|
|
size += submission->image_bind_count * sizeof(VkSparseImageMemoryBindInfo);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->image_bind_count; ++i)
|
|
|
|
|
|
size += submission->image_binds[i].bindCount * sizeof(VkSparseImageMemoryBind);
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
size += submission->wait_semaphore_count * sizeof(struct radv_semaphore_part *);
|
2019-10-30 19:52:51 +01:00
|
|
|
|
size += temporary_count * sizeof(struct radv_semaphore_part);
|
2019-10-23 15:31:43 +02:00
|
|
|
|
size += submission->signal_semaphore_count * sizeof(struct radv_semaphore_part *);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
size += submission->wait_value_count * sizeof(uint64_t);
|
|
|
|
|
|
size += submission->signal_value_count * sizeof(uint64_t);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
size += submission->wait_semaphore_count * sizeof(struct radv_timeline_waiter);
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
|
|
|
|
|
deferred = calloc(1, size);
|
|
|
|
|
|
if (!deferred)
|
|
|
|
|
|
return VK_ERROR_OUT_OF_HOST_MEMORY;
|
|
|
|
|
|
|
|
|
|
|
|
deferred->queue = queue;
|
|
|
|
|
|
|
|
|
|
|
|
deferred->cmd_buffers = (void*)(deferred + 1);
|
|
|
|
|
|
deferred->cmd_buffer_count = submission->cmd_buffer_count;
|
2020-09-15 13:07:16 +02:00
|
|
|
|
if (submission->cmd_buffer_count) {
|
|
|
|
|
|
memcpy(deferred->cmd_buffers, submission->cmd_buffers,
|
|
|
|
|
|
submission->cmd_buffer_count * sizeof(*deferred->cmd_buffers));
|
|
|
|
|
|
}
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
|
|
|
|
|
deferred->buffer_binds = (void*)(deferred->cmd_buffers + submission->cmd_buffer_count);
|
|
|
|
|
|
deferred->buffer_bind_count = submission->buffer_bind_count;
|
2020-09-15 13:07:16 +02:00
|
|
|
|
if (submission->buffer_bind_count) {
|
|
|
|
|
|
memcpy(deferred->buffer_binds, submission->buffer_binds,
|
|
|
|
|
|
submission->buffer_bind_count * sizeof(*deferred->buffer_binds));
|
|
|
|
|
|
}
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
|
|
|
|
|
deferred->image_opaque_binds = (void*)(deferred->buffer_binds + submission->buffer_bind_count);
|
|
|
|
|
|
deferred->image_opaque_bind_count = submission->image_opaque_bind_count;
|
2020-09-15 13:07:16 +02:00
|
|
|
|
if (submission->image_opaque_bind_count) {
|
|
|
|
|
|
memcpy(deferred->image_opaque_binds, submission->image_opaque_binds,
|
|
|
|
|
|
submission->image_opaque_bind_count * sizeof(*deferred->image_opaque_binds));
|
|
|
|
|
|
}
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
2020-12-06 19:17:03 +01:00
|
|
|
|
deferred->image_binds = (void*)(deferred->image_opaque_binds + deferred->image_opaque_bind_count);
|
|
|
|
|
|
deferred->image_bind_count = submission->image_bind_count;
|
|
|
|
|
|
|
|
|
|
|
|
VkSparseImageMemoryBind *sparse_image_binds = (void*)(deferred->image_binds + deferred->image_bind_count);
|
|
|
|
|
|
for (uint32_t i = 0; i < deferred->image_bind_count; ++i) {
|
|
|
|
|
|
deferred->image_binds[i] = submission->image_binds[i];
|
|
|
|
|
|
deferred->image_binds[i].pBinds = sparse_image_binds;
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < deferred->image_binds[i].bindCount; ++j)
|
|
|
|
|
|
*sparse_image_binds++ = submission->image_binds[i].pBinds[j];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
deferred->flush_caches = submission->flush_caches;
|
|
|
|
|
|
deferred->wait_dst_stage_mask = submission->wait_dst_stage_mask;
|
|
|
|
|
|
|
2020-12-06 19:17:03 +01:00
|
|
|
|
deferred->wait_semaphores = (void*)sparse_image_binds;
|
2019-10-23 15:31:43 +02:00
|
|
|
|
deferred->wait_semaphore_count = submission->wait_semaphore_count;
|
|
|
|
|
|
|
|
|
|
|
|
deferred->signal_semaphores = (void*)(deferred->wait_semaphores + deferred->wait_semaphore_count);
|
|
|
|
|
|
deferred->signal_semaphore_count = submission->signal_semaphore_count;
|
|
|
|
|
|
|
|
|
|
|
|
deferred->fence = submission->fence;
|
|
|
|
|
|
|
|
|
|
|
|
deferred->temporary_semaphore_parts = (void*)(deferred->signal_semaphores + deferred->signal_semaphore_count);
|
|
|
|
|
|
deferred->temporary_semaphore_part_count = temporary_count;
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t temporary_idx = 0;
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->wait_semaphore_count; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, submission->wait_semaphores[i]);
|
|
|
|
|
|
if (semaphore->temporary.kind != RADV_SEMAPHORE_NONE) {
|
|
|
|
|
|
deferred->wait_semaphores[i] = &deferred->temporary_semaphore_parts[temporary_idx];
|
|
|
|
|
|
deferred->temporary_semaphore_parts[temporary_idx] = semaphore->temporary;
|
|
|
|
|
|
semaphore->temporary.kind = RADV_SEMAPHORE_NONE;
|
|
|
|
|
|
++temporary_idx;
|
|
|
|
|
|
} else
|
|
|
|
|
|
deferred->wait_semaphores[i] = &semaphore->permanent;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->signal_semaphore_count; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, submission->signal_semaphores[i]);
|
|
|
|
|
|
if (semaphore->temporary.kind != RADV_SEMAPHORE_NONE) {
|
|
|
|
|
|
deferred->signal_semaphores[i] = &semaphore->temporary;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
deferred->signal_semaphores[i] = &semaphore->permanent;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
deferred->wait_values = (void*)(deferred->temporary_semaphore_parts + temporary_count);
|
2020-09-15 13:07:16 +02:00
|
|
|
|
if (submission->wait_value_count) {
|
|
|
|
|
|
memcpy(deferred->wait_values, submission->wait_values, submission->wait_value_count * sizeof(uint64_t));
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
deferred->signal_values = deferred->wait_values + submission->wait_value_count;
|
2020-09-15 13:07:16 +02:00
|
|
|
|
if (submission->signal_value_count) {
|
|
|
|
|
|
memcpy(deferred->signal_values, submission->signal_values, submission->signal_value_count * sizeof(uint64_t));
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
deferred->wait_nodes = (void*)(deferred->signal_values + submission->signal_value_count);
|
|
|
|
|
|
/* This is worst-case. radv_queue_enqueue_submission will fill in further, but this
|
|
|
|
|
|
* ensure the submission is not accidentally triggered early when adding wait timelines. */
|
|
|
|
|
|
deferred->submission_wait_count = 1 + submission->wait_semaphore_count;
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
*out = deferred;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
static VkResult
|
2019-10-28 02:44:54 +01:00
|
|
|
|
radv_queue_enqueue_submission(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
struct list_head *processing_list)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t wait_cnt = 0;
|
|
|
|
|
|
struct radv_timeline_waiter *waiter = submission->wait_nodes;
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->wait_semaphore_count; ++i) {
|
|
|
|
|
|
if (submission->wait_semaphores[i]->kind == RADV_SEMAPHORE_TIMELINE) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&submission->wait_semaphores[i]->timeline.mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
if (submission->wait_semaphores[i]->timeline.highest_submitted < submission->wait_values[i]) {
|
|
|
|
|
|
++wait_cnt;
|
|
|
|
|
|
waiter->value = submission->wait_values[i];
|
|
|
|
|
|
waiter->submission = submission;
|
|
|
|
|
|
list_addtail(&waiter->list, &submission->wait_semaphores[i]->timeline.waiters);
|
|
|
|
|
|
++waiter;
|
|
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&submission->wait_semaphores[i]->timeline.mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&submission->queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
|
|
|
|
|
bool is_first = list_is_empty(&submission->queue->pending_submissions);
|
|
|
|
|
|
list_addtail(&submission->queue_pending_list, &submission->queue->pending_submissions);
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&submission->queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
|
|
|
|
|
/* If there is already a submission in the queue, that will decrement the counter by 1 when
|
|
|
|
|
|
* submitted, but if the queue was empty, we decrement ourselves as there is no previous
|
|
|
|
|
|
* submission. */
|
|
|
|
|
|
uint32_t decrement = submission->wait_semaphore_count - wait_cnt + (is_first ? 1 : 0);
|
2020-08-29 03:25:02 +02:00
|
|
|
|
|
|
|
|
|
|
/* if decrement is zero, then we don't have a refcounted reference to the
|
|
|
|
|
|
* submission anymore, so it is not safe to access the submission. */
|
|
|
|
|
|
if (!decrement)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
return radv_queue_trigger_submission(submission, decrement, processing_list);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_queue_submission_update_queue(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
struct list_head *processing_list)
|
|
|
|
|
|
{
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&submission->queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
list_del(&submission->queue_pending_list);
|
|
|
|
|
|
|
|
|
|
|
|
/* trigger the next submission in the queue. */
|
|
|
|
|
|
if (!list_is_empty(&submission->queue->pending_submissions)) {
|
|
|
|
|
|
struct radv_deferred_queue_submission *next_submission =
|
|
|
|
|
|
list_first_entry(&submission->queue->pending_submissions,
|
|
|
|
|
|
struct radv_deferred_queue_submission,
|
|
|
|
|
|
queue_pending_list);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
radv_queue_trigger_submission(next_submission, 1, processing_list);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&submission->queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_broadcast(&submission->queue->device->timeline_cond);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
static VkResult
|
2019-10-28 02:44:54 +01:00
|
|
|
|
radv_queue_submit_deferred(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
struct list_head *processing_list)
|
2019-10-03 21:08:29 +02:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, submission->fence);
|
2019-10-23 15:31:43 +02:00
|
|
|
|
struct radv_queue *queue = submission->queue;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
struct radeon_winsys_ctx *ctx = queue->hw_ctx;
|
|
|
|
|
|
uint32_t max_cs_submission = queue->device->trace_bo ? 1 : RADV_MAX_IBS_PER_SUBMIT;
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radeon_winsys_fence *base_fence = NULL;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
bool do_flush = submission->flush_caches || submission->wait_dst_stage_mask;
|
|
|
|
|
|
bool can_patch = true;
|
|
|
|
|
|
uint32_t advance;
|
|
|
|
|
|
struct radv_winsys_sem_info sem_info;
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
struct radeon_cmdbuf *initial_preamble_cs = NULL;
|
|
|
|
|
|
struct radeon_cmdbuf *initial_flush_preamble_cs = NULL;
|
|
|
|
|
|
struct radeon_cmdbuf *continue_preamble_cs = NULL;
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
if (fence) {
|
|
|
|
|
|
/* Under most circumstances, out fences won't be temporary.
|
|
|
|
|
|
* However, the spec does allow it for opaque_fd.
|
|
|
|
|
|
*
|
|
|
|
|
|
* From the Vulkan 1.0.53 spec:
|
|
|
|
|
|
*
|
|
|
|
|
|
* "If the import is temporary, the implementation must
|
|
|
|
|
|
* restore the semaphore to its prior permanent state after
|
|
|
|
|
|
* submitting the next semaphore wait operation."
|
|
|
|
|
|
*/
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
if (part->kind == RADV_FENCE_WINSYS)
|
|
|
|
|
|
base_fence = part->fence;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
result = radv_get_preambles(queue, submission->cmd_buffers,
|
|
|
|
|
|
submission->cmd_buffer_count,
|
|
|
|
|
|
&initial_preamble_cs,
|
|
|
|
|
|
&initial_flush_preamble_cs,
|
|
|
|
|
|
&continue_preamble_cs);
|
2017-01-29 13:53:05 +01:00
|
|
|
|
if (result != VK_SUCCESS)
|
2019-10-23 15:31:43 +02:00
|
|
|
|
goto fail;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
result = radv_alloc_sem_info(queue->device,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
&sem_info,
|
|
|
|
|
|
submission->wait_semaphore_count,
|
|
|
|
|
|
submission->wait_semaphores,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
submission->wait_values,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
submission->signal_semaphore_count,
|
|
|
|
|
|
submission->signal_semaphores,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
submission->signal_values,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
submission->fence);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
2019-10-23 15:31:43 +02:00
|
|
|
|
goto fail;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-10-19 17:05:22 +02:00
|
|
|
|
for (uint32_t i = 0; i < submission->buffer_bind_count; ++i) {
|
2020-07-21 15:55:38 +02:00
|
|
|
|
result = radv_sparse_buffer_bind_memory(queue->device,
|
|
|
|
|
|
submission->buffer_binds + i);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->image_opaque_bind_count; ++i) {
|
2020-07-21 15:55:38 +02:00
|
|
|
|
result = radv_sparse_image_opaque_bind_memory(queue->device,
|
|
|
|
|
|
submission->image_opaque_binds + i);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
2019-10-19 17:05:22 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-06 19:17:03 +01:00
|
|
|
|
for (uint32_t i = 0; i < submission->image_bind_count; ++i) {
|
|
|
|
|
|
result = radv_sparse_image_bind_memory(queue->device,
|
|
|
|
|
|
submission->image_binds + i);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
if (!submission->cmd_buffer_count) {
|
2020-07-13 10:35:56 +02:00
|
|
|
|
result = queue->device->ws->cs_submit(ctx, queue->queue_idx,
|
|
|
|
|
|
&queue->device->empty_cs[queue->queue_family_index],
|
|
|
|
|
|
1, NULL, NULL,
|
|
|
|
|
|
&sem_info, NULL,
|
|
|
|
|
|
false, base_fence);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
struct radeon_cmdbuf **cs_array = malloc(sizeof(struct radeon_cmdbuf *) *
|
|
|
|
|
|
(submission->cmd_buffer_count));
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
for (uint32_t j = 0; j < submission->cmd_buffer_count; j++) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, submission->cmd_buffers[j]);
|
|
|
|
|
|
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
cs_array[j] = cmd_buffer->cs;
|
|
|
|
|
|
if ((cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT))
|
|
|
|
|
|
can_patch = false;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
cmd_buffer->status = RADV_CMD_BUFFER_STATUS_PENDING;
|
|
|
|
|
|
}
|
2017-12-06 17:48:40 +01:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
for (uint32_t j = 0; j < submission->cmd_buffer_count; j += advance) {
|
|
|
|
|
|
struct radeon_cmdbuf *initial_preamble = (do_flush && !j) ? initial_flush_preamble_cs : initial_preamble_cs;
|
|
|
|
|
|
const struct radv_winsys_bo_list *bo_list = NULL;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
advance = MIN2(max_cs_submission,
|
|
|
|
|
|
submission->cmd_buffer_count - j);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
if (queue->device->trace_bo)
|
|
|
|
|
|
*queue->device->trace_id_ptr = 0;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
sem_info.cs_emit_wait = j == 0;
|
|
|
|
|
|
sem_info.cs_emit_signal = j + advance == submission->cmd_buffer_count;
|
2019-10-03 21:08:29 +02:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
if (unlikely(queue->device->use_global_bo_list)) {
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_rdlock(&queue->device->bo_list.rwlock);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
bo_list = &queue->device->bo_list.list;
|
|
|
|
|
|
}
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
2020-07-13 10:35:56 +02:00
|
|
|
|
result = queue->device->ws->cs_submit(ctx, queue->queue_idx, cs_array + j,
|
|
|
|
|
|
advance, initial_preamble, continue_preamble_cs,
|
|
|
|
|
|
&sem_info, bo_list,
|
|
|
|
|
|
can_patch, base_fence);
|
2018-05-17 11:36:09 +02:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
if (unlikely(queue->device->use_global_bo_list))
|
2020-10-13 21:06:21 -07:00
|
|
|
|
u_rwlock_rdunlock(&queue->device->bo_list.rwlock);
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
2020-07-13 10:35:56 +02:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
if (queue->device->trace_bo) {
|
|
|
|
|
|
radv_check_gpu_hangs(queue, cs_array[j]);
|
|
|
|
|
|
}
|
2020-08-18 18:52:35 +02:00
|
|
|
|
|
|
|
|
|
|
if (queue->device->tma_bo) {
|
|
|
|
|
|
radv_check_trap_handler(queue);
|
|
|
|
|
|
}
|
2019-10-03 21:08:29 +02:00
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
free(cs_array);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
}
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
radv_free_temp_syncobjs(queue->device,
|
2019-10-23 15:31:43 +02:00
|
|
|
|
submission->temporary_semaphore_part_count,
|
|
|
|
|
|
submission->temporary_semaphore_parts);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
radv_finalize_timelines(queue->device,
|
|
|
|
|
|
submission->wait_semaphore_count,
|
|
|
|
|
|
submission->wait_semaphores,
|
|
|
|
|
|
submission->wait_values,
|
|
|
|
|
|
submission->signal_semaphore_count,
|
|
|
|
|
|
submission->signal_semaphores,
|
2019-10-28 02:44:54 +01:00
|
|
|
|
submission->signal_values,
|
|
|
|
|
|
processing_list);
|
|
|
|
|
|
/* Has to happen after timeline finalization to make sure the
|
|
|
|
|
|
* condition variable is only triggered when timelines and queue have
|
|
|
|
|
|
* been updated. */
|
|
|
|
|
|
radv_queue_submission_update_queue(submission, processing_list);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
radv_free_sem_info(&sem_info);
|
2019-10-23 15:31:43 +02:00
|
|
|
|
free(submission);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
return VK_SUCCESS;
|
2019-10-23 15:31:43 +02:00
|
|
|
|
|
|
|
|
|
|
fail:
|
2020-07-13 10:35:56 +02:00
|
|
|
|
if (result != VK_SUCCESS && result != VK_ERROR_DEVICE_LOST) {
|
|
|
|
|
|
/* When something bad happened during the submission, such as
|
|
|
|
|
|
* an out of memory issue, it might be hard to recover from
|
|
|
|
|
|
* this inconsistent state. To avoid this sort of problem, we
|
|
|
|
|
|
* assume that we are in a really bad situation and return
|
|
|
|
|
|
* VK_ERROR_DEVICE_LOST to ensure the clients do not attempt
|
|
|
|
|
|
* to submit the same job again to this device.
|
|
|
|
|
|
*/
|
2020-07-13 13:59:48 +02:00
|
|
|
|
result = radv_device_set_lost(queue->device, "vkQueueSubmit() failed");
|
2020-07-13 10:35:56 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
radv_free_temp_syncobjs(queue->device,
|
|
|
|
|
|
submission->temporary_semaphore_part_count,
|
|
|
|
|
|
submission->temporary_semaphore_parts);
|
|
|
|
|
|
free(submission);
|
2020-07-13 10:35:56 +02:00
|
|
|
|
return result;
|
2019-10-23 15:31:43 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_process_submissions(struct list_head *processing_list)
|
|
|
|
|
|
{
|
|
|
|
|
|
while(!list_is_empty(processing_list)) {
|
|
|
|
|
|
struct radv_deferred_queue_submission *submission =
|
|
|
|
|
|
list_first_entry(processing_list, struct radv_deferred_queue_submission, processing_list);
|
|
|
|
|
|
list_del(&submission->processing_list);
|
|
|
|
|
|
|
|
|
|
|
|
VkResult result = radv_queue_submit_deferred(submission, processing_list);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
static VkResult
|
|
|
|
|
|
wait_for_submission_timelines_available(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
uint64_t timeout)
|
|
|
|
|
|
{
|
2020-07-16 02:44:22 +02:00
|
|
|
|
struct radv_device *device = submission->queue->device;
|
|
|
|
|
|
uint32_t syncobj_count = 0;
|
|
|
|
|
|
uint32_t syncobj_idx = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->wait_semaphore_count; ++i) {
|
|
|
|
|
|
if (submission->wait_semaphores[i]->kind != RADV_SEMAPHORE_TIMELINE_SYNCOBJ)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (submission->wait_semaphores[i]->timeline_syncobj.max_point >= submission->wait_values[i])
|
|
|
|
|
|
continue;
|
|
|
|
|
|
++syncobj_count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!syncobj_count)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t *points = malloc((sizeof(uint64_t) + sizeof(uint32_t)) * syncobj_count);
|
|
|
|
|
|
if (!points)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t *syncobj = (uint32_t*)(points + syncobj_count);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submission->wait_semaphore_count; ++i) {
|
|
|
|
|
|
if (submission->wait_semaphores[i]->kind != RADV_SEMAPHORE_TIMELINE_SYNCOBJ)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (submission->wait_semaphores[i]->timeline_syncobj.max_point >= submission->wait_values[i])
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
syncobj[syncobj_idx] = submission->wait_semaphores[i]->syncobj;
|
|
|
|
|
|
points[syncobj_idx] = submission->wait_values[i];
|
|
|
|
|
|
++syncobj_idx;
|
|
|
|
|
|
}
|
|
|
|
|
|
bool success = device->ws->wait_timeline_syncobj(device->ws, syncobj, points, syncobj_idx, true, true, timeout);
|
|
|
|
|
|
|
|
|
|
|
|
free(points);
|
|
|
|
|
|
return success ? VK_SUCCESS : VK_TIMEOUT;
|
2020-06-22 22:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:31:42 -08:00
|
|
|
|
static int radv_queue_submission_thread_run(void *q)
|
2020-06-22 22:07:46 +02:00
|
|
|
|
{
|
|
|
|
|
|
struct radv_queue *queue = q;
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
while (!p_atomic_read(&queue->thread_exit)) {
|
|
|
|
|
|
struct radv_deferred_queue_submission *submission = queue->thread_submission;
|
|
|
|
|
|
struct list_head processing_list;
|
|
|
|
|
|
VkResult result = VK_SUCCESS;
|
|
|
|
|
|
if (!submission) {
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_wait(&queue->thread_cond, &queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
|
|
|
|
|
|
/* Wait at most 5 seconds so we have a chance to notice shutdown when
|
|
|
|
|
|
* a semaphore never gets signaled. If it takes longer we just retry
|
|
|
|
|
|
* the wait next iteration. */
|
|
|
|
|
|
result = wait_for_submission_timelines_available(submission,
|
|
|
|
|
|
radv_get_absolute_timeout(5000000000));
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* The lock isn't held but nobody will add one until we finish
|
|
|
|
|
|
* the current submission. */
|
|
|
|
|
|
p_atomic_set(&queue->thread_submission, NULL);
|
|
|
|
|
|
|
|
|
|
|
|
list_inithead(&processing_list);
|
|
|
|
|
|
list_addtail(&submission->processing_list, &processing_list);
|
|
|
|
|
|
result = radv_process_submissions(&processing_list);
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&queue->thread_mutex);
|
2020-11-26 19:31:42 -08:00
|
|
|
|
return 0;
|
2020-06-22 22:07:46 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_queue_trigger_submission(struct radv_deferred_queue_submission *submission,
|
|
|
|
|
|
uint32_t decrement,
|
|
|
|
|
|
struct list_head *processing_list)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_queue *queue = submission->queue;
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
if (p_atomic_add_return(&submission->submission_wait_count, -decrement))
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
if (wait_for_submission_timelines_available(submission, radv_get_absolute_timeout(0)) == VK_SUCCESS) {
|
|
|
|
|
|
list_addtail(&submission->processing_list, processing_list);
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
|
|
|
|
|
|
/* A submission can only be ready for the thread if it doesn't have
|
|
|
|
|
|
* any predecessors in the same queue, so there can only be one such
|
|
|
|
|
|
* submission at a time. */
|
|
|
|
|
|
assert(queue->thread_submission == NULL);
|
|
|
|
|
|
|
|
|
|
|
|
/* Only start the thread on demand to save resources for the many games
|
|
|
|
|
|
* which only use binary semaphores. */
|
|
|
|
|
|
if (!queue->thread_running) {
|
2020-11-26 19:31:42 -08:00
|
|
|
|
ret = thrd_create(&queue->submission_thread,
|
|
|
|
|
|
radv_queue_submission_thread_run, queue);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
if (ret) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
return vk_errorf(queue->device->instance,
|
|
|
|
|
|
VK_ERROR_DEVICE_LOST,
|
|
|
|
|
|
"Failed to start submission thread");
|
|
|
|
|
|
}
|
|
|
|
|
|
queue->thread_running = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
queue->thread_submission = submission;
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&queue->thread_mutex);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_signal(&queue->thread_cond);
|
2020-06-22 22:07:46 +02:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-23 15:31:43 +02:00
|
|
|
|
static VkResult radv_queue_submit(struct radv_queue *queue,
|
|
|
|
|
|
const struct radv_queue_submission *submission)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radv_deferred_queue_submission *deferred = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
VkResult result = radv_create_deferred_submission(queue, submission, &deferred);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
struct list_head processing_list;
|
|
|
|
|
|
list_inithead(&processing_list);
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
result = radv_queue_enqueue_submission(deferred, &processing_list);
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
|
/* If anything is in the list we leak. */
|
|
|
|
|
|
assert(list_is_empty(&processing_list));
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
2019-10-28 02:44:54 +01:00
|
|
|
|
return radv_process_submissions(&processing_list);
|
2019-10-03 21:08:29 +02:00
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2020-02-21 09:35:46 +01:00
|
|
|
|
bool
|
|
|
|
|
|
radv_queue_internal_submit(struct radv_queue *queue, struct radeon_cmdbuf *cs)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct radeon_winsys_ctx *ctx = queue->hw_ctx;
|
|
|
|
|
|
struct radv_winsys_sem_info sem_info;
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
|
|
result = radv_alloc_sem_info(queue->device, &sem_info, 0, NULL, 0, 0,
|
2020-02-28 14:23:16 +01:00
|
|
|
|
0, NULL, VK_NULL_HANDLE);
|
2020-02-21 09:35:46 +01:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
2020-07-13 10:35:56 +02:00
|
|
|
|
result = queue->device->ws->cs_submit(ctx, queue->queue_idx, &cs, 1,
|
|
|
|
|
|
NULL, NULL, &sem_info, NULL,
|
|
|
|
|
|
false, NULL);
|
2020-02-21 09:35:46 +01:00
|
|
|
|
radv_free_sem_info(&sem_info);
|
2020-07-13 10:35:56 +02:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
2020-02-21 09:35:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
/* Signals fence as soon as all the work currently put on queue is done. */
|
|
|
|
|
|
static VkResult radv_signal_fence(struct radv_queue *queue,
|
|
|
|
|
|
VkFence fence)
|
|
|
|
|
|
{
|
|
|
|
|
|
return radv_queue_submit(queue, &(struct radv_queue_submission) {
|
|
|
|
|
|
.fence = fence
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
|
2019-10-20 19:12:24 +02:00
|
|
|
|
static bool radv_submit_has_effects(const VkSubmitInfo *info)
|
|
|
|
|
|
{
|
|
|
|
|
|
return info->commandBufferCount ||
|
|
|
|
|
|
info->waitSemaphoreCount ||
|
|
|
|
|
|
info->signalSemaphoreCount;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
VkResult radv_QueueSubmit(
|
|
|
|
|
|
VkQueue _queue,
|
|
|
|
|
|
uint32_t submitCount,
|
|
|
|
|
|
const VkSubmitInfo* pSubmits,
|
|
|
|
|
|
VkFence fence)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
|
|
|
|
|
VkResult result;
|
2019-10-20 19:12:24 +02:00
|
|
|
|
uint32_t fence_idx = 0;
|
|
|
|
|
|
bool flushed_caches = false;
|
|
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(queue->device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2019-10-20 19:12:24 +02:00
|
|
|
|
if (fence != VK_NULL_HANDLE) {
|
|
|
|
|
|
for (uint32_t i = 0; i < submitCount; ++i)
|
|
|
|
|
|
if (radv_submit_has_effects(pSubmits + i))
|
|
|
|
|
|
fence_idx = i;
|
|
|
|
|
|
} else
|
|
|
|
|
|
fence_idx = UINT32_MAX;
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
for (uint32_t i = 0; i < submitCount; i++) {
|
2019-10-20 19:12:24 +02:00
|
|
|
|
if (!radv_submit_has_effects(pSubmits + i) && fence_idx != i)
|
2019-10-03 21:08:29 +02:00
|
|
|
|
continue;
|
2018-04-09 12:46:49 +02:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
VkPipelineStageFlags wait_dst_stage_mask = 0;
|
|
|
|
|
|
for (unsigned j = 0; j < pSubmits[i].waitSemaphoreCount; ++j) {
|
|
|
|
|
|
wait_dst_stage_mask |= pSubmits[i].pWaitDstStageMask[j];
|
2016-12-23 23:51:18 +01:00
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2019-11-25 20:50:12 +01:00
|
|
|
|
const VkTimelineSemaphoreSubmitInfo *timeline_info =
|
|
|
|
|
|
vk_find_struct_const(pSubmits[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
result = radv_queue_submit(queue, &(struct radv_queue_submission) {
|
|
|
|
|
|
.cmd_buffers = pSubmits[i].pCommandBuffers,
|
|
|
|
|
|
.cmd_buffer_count = pSubmits[i].commandBufferCount,
|
|
|
|
|
|
.wait_dst_stage_mask = wait_dst_stage_mask,
|
2019-10-20 19:12:24 +02:00
|
|
|
|
.flush_caches = !flushed_caches,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
.wait_semaphores = pSubmits[i].pWaitSemaphores,
|
|
|
|
|
|
.wait_semaphore_count = pSubmits[i].waitSemaphoreCount,
|
|
|
|
|
|
.signal_semaphores = pSubmits[i].pSignalSemaphores,
|
|
|
|
|
|
.signal_semaphore_count = pSubmits[i].signalSemaphoreCount,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
.fence = i == fence_idx ? fence : VK_NULL_HANDLE,
|
|
|
|
|
|
.wait_values = timeline_info ? timeline_info->pWaitSemaphoreValues : NULL,
|
|
|
|
|
|
.wait_value_count = timeline_info && timeline_info->pWaitSemaphoreValues ? timeline_info->waitSemaphoreValueCount : 0,
|
|
|
|
|
|
.signal_values = timeline_info ? timeline_info->pSignalSemaphoreValues : NULL,
|
|
|
|
|
|
.signal_value_count = timeline_info && timeline_info->pSignalSemaphoreValues ? timeline_info->signalSemaphoreValueCount : 0,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
});
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
2019-10-20 19:12:24 +02:00
|
|
|
|
flushed_caches = true;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-20 19:12:24 +02:00
|
|
|
|
if (fence != VK_NULL_HANDLE && !submitCount) {
|
|
|
|
|
|
result = radv_signal_fence(queue, fence);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-08-07 17:18:41 +02:00
|
|
|
|
static const char *
|
|
|
|
|
|
radv_get_queue_family_name(struct radv_queue *queue)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (queue->queue_family_index) {
|
|
|
|
|
|
case RADV_QUEUE_GENERAL:
|
|
|
|
|
|
return "graphics";
|
|
|
|
|
|
case RADV_QUEUE_COMPUTE:
|
|
|
|
|
|
return "compute";
|
|
|
|
|
|
case RADV_QUEUE_TRANSFER:
|
|
|
|
|
|
return "transfer";
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Unknown queue family");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_QueueWaitIdle(
|
|
|
|
|
|
VkQueue _queue)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
|
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(queue->device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
while (!list_is_empty(&queue->pending_submissions)) {
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_wait(&queue->device->timeline_cond, &queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&queue->pending_mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
2020-07-10 14:45:19 +02:00
|
|
|
|
if (!queue->device->ws->ctx_wait_idle(queue->hw_ctx,
|
|
|
|
|
|
radv_queue_family_to_ring(queue->queue_family_index),
|
2020-08-07 17:18:41 +02:00
|
|
|
|
queue->queue_idx)) {
|
2020-07-13 13:59:48 +02:00
|
|
|
|
return radv_device_set_lost(queue->device,
|
|
|
|
|
|
"Failed to wait for a '%s' queue "
|
|
|
|
|
|
"to be idle. GPU hang ?",
|
|
|
|
|
|
radv_get_queue_family_name(queue));
|
2020-08-07 17:18:41 +02:00
|
|
|
|
}
|
2020-07-10 14:45:19 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_DeviceWaitIdle(
|
|
|
|
|
|
VkDevice _device)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
2016-12-17 19:10:35 +01:00
|
|
|
|
for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
|
|
|
|
|
|
for (unsigned q = 0; q < device->queue_count[i]; q++) {
|
2020-07-10 14:45:19 +02:00
|
|
|
|
VkResult result =
|
|
|
|
|
|
radv_QueueWaitIdle(radv_queue_to_handle(&device->queues[i][q]));
|
|
|
|
|
|
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2016-12-17 19:10:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-10 21:43:55 +01:00
|
|
|
|
VkResult radv_EnumerateInstanceExtensionProperties(
|
|
|
|
|
|
const char* pLayerName,
|
|
|
|
|
|
uint32_t* pPropertyCount,
|
|
|
|
|
|
VkExtensionProperties* pProperties)
|
|
|
|
|
|
{
|
2020-08-06 20:57:10 -07:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties,
|
|
|
|
|
|
pPropertyCount);
|
2018-02-10 21:43:55 +01:00
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < RADV_INSTANCE_EXTENSION_COUNT; i++) {
|
2020-05-11 11:33:00 +02:00
|
|
|
|
if (radv_instance_extensions_supported.extensions[i]) {
|
2020-08-06 20:57:10 -07:00
|
|
|
|
vk_outarray_append_typed(VkExtensionProperties, &out, prop) {
|
2018-02-10 21:43:55 +01:00
|
|
|
|
*prop = radv_instance_extensions[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_EnumerateDeviceExtensionProperties(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
const char* pLayerName,
|
|
|
|
|
|
uint32_t* pPropertyCount,
|
|
|
|
|
|
VkExtensionProperties* pProperties)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice);
|
2020-08-06 20:57:10 -07:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkExtensionProperties, out, pProperties,
|
|
|
|
|
|
pPropertyCount);
|
2018-02-10 21:43:55 +01:00
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < RADV_DEVICE_EXTENSION_COUNT; i++) {
|
|
|
|
|
|
if (device->supported_extensions.extensions[i]) {
|
2020-08-06 20:57:10 -07:00
|
|
|
|
vk_outarray_append_typed(VkExtensionProperties, &out, prop) {
|
2018-02-10 21:43:55 +01:00
|
|
|
|
*prop = radv_device_extensions[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
PFN_vkVoidFunction radv_GetInstanceProcAddr(
|
2018-02-11 14:38:42 +01:00
|
|
|
|
VkInstance _instance,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
const char* pName)
|
|
|
|
|
|
{
|
2018-02-11 14:38:42 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
/* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
|
|
|
|
|
|
* when we have to return valid function pointers, NULL, or it's left
|
|
|
|
|
|
* undefined. See the table for exact details.
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (pName == NULL)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
#define LOOKUP_RADV_ENTRYPOINT(entrypoint) \
|
|
|
|
|
|
if (strcmp(pName, "vk" #entrypoint) == 0) \
|
|
|
|
|
|
return (PFN_vkVoidFunction)radv_##entrypoint
|
|
|
|
|
|
|
|
|
|
|
|
LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceExtensionProperties);
|
|
|
|
|
|
LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceLayerProperties);
|
|
|
|
|
|
LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceVersion);
|
|
|
|
|
|
LOOKUP_RADV_ENTRYPOINT(CreateInstance);
|
|
|
|
|
|
|
2020-03-21 20:18:56 +01:00
|
|
|
|
/* GetInstanceProcAddr() can also be called with a NULL instance.
|
|
|
|
|
|
* See https://gitlab.khronos.org/vulkan/vulkan/issues/2057
|
|
|
|
|
|
*/
|
|
|
|
|
|
LOOKUP_RADV_ENTRYPOINT(GetInstanceProcAddr);
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
#undef LOOKUP_RADV_ENTRYPOINT
|
|
|
|
|
|
|
|
|
|
|
|
if (instance == NULL)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int idx = radv_get_instance_entrypoint_index(pName);
|
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
|
return instance->dispatch.entrypoints[idx];
|
|
|
|
|
|
|
|
|
|
|
|
idx = radv_get_physical_device_entrypoint_index(pName);
|
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
|
return instance->physical_device_dispatch.entrypoints[idx];
|
|
|
|
|
|
|
|
|
|
|
|
idx = radv_get_device_entrypoint_index(pName);
|
|
|
|
|
|
if (idx >= 0)
|
|
|
|
|
|
return instance->device_dispatch.entrypoints[idx];
|
|
|
|
|
|
|
|
|
|
|
|
return NULL;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* The loader wants us to expose a second GetInstanceProcAddr function
|
|
|
|
|
|
* to work around certain LD_PRELOAD issues seen in apps.
|
|
|
|
|
|
*/
|
|
|
|
|
|
PUBLIC
|
|
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(
|
|
|
|
|
|
VkInstance instance,
|
|
|
|
|
|
const char* pName)
|
|
|
|
|
|
{
|
|
|
|
|
|
return radv_GetInstanceProcAddr(instance, pName);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-05 13:46:53 +01:00
|
|
|
|
PUBLIC
|
|
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
|
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
|
const char* pName)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
if (!pName || !instance)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int idx = radv_get_physical_device_entrypoint_index(pName);
|
|
|
|
|
|
if (idx < 0)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
return instance->physical_device_dispatch.entrypoints[idx];
|
2019-01-05 13:46:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
PFN_vkVoidFunction radv_GetDeviceProcAddr(
|
2018-02-11 14:38:42 +01:00
|
|
|
|
VkDevice _device,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
const char* pName)
|
|
|
|
|
|
{
|
2018-02-11 14:38:42 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
2020-02-24 17:24:03 +01:00
|
|
|
|
if (!device || !pName)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
int idx = radv_get_device_entrypoint_index(pName);
|
|
|
|
|
|
if (idx < 0)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
return device->dispatch.entrypoints[idx];
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-26 23:52:08 +00:00
|
|
|
|
bool radv_get_memory_fd(struct radv_device *device,
|
|
|
|
|
|
struct radv_device_memory *memory,
|
|
|
|
|
|
int *pFD)
|
|
|
|
|
|
{
|
2020-12-11 12:56:28 +01:00
|
|
|
|
/* Only set BO metadata for the first plane */
|
|
|
|
|
|
if (memory->image && memory->image->offset == 0) {
|
|
|
|
|
|
struct radeon_bo_metadata metadata;
|
2020-12-03 16:03:15 +01:00
|
|
|
|
radv_init_metadata(device, memory->image, &metadata);
|
2017-02-26 23:52:08 +00:00
|
|
|
|
device->ws->buffer_set_metadata(memory->bo, &metadata);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return device->ws->buffer_get_fd(device->ws, memory->bo,
|
|
|
|
|
|
pFD);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-10 14:21:11 +02:00
|
|
|
|
|
2020-07-10 16:18:37 +02:00
|
|
|
|
void
|
|
|
|
|
|
radv_free_memory(struct radv_device *device,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
struct radv_device_memory *mem)
|
2019-07-10 14:21:11 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (mem == NULL)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2019-07-10 14:27:37 +02:00
|
|
|
|
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
|
|
|
|
|
|
if (mem->android_hardware_buffer)
|
|
|
|
|
|
AHardwareBuffer_release(mem->android_hardware_buffer);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2019-07-10 14:21:11 +02:00
|
|
|
|
if (mem->bo) {
|
2020-04-28 13:10:56 +02:00
|
|
|
|
if (device->overallocation_disallowed) {
|
|
|
|
|
|
mtx_lock(&device->overallocation_mutex);
|
|
|
|
|
|
device->allocated_memory_size[mem->heap_index] -= mem->alloc_size;
|
|
|
|
|
|
mtx_unlock(&device->overallocation_mutex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-10 14:21:11 +02:00
|
|
|
|
radv_bo_list_remove(device, mem->bo);
|
|
|
|
|
|
device->ws->buffer_destroy(mem->bo);
|
|
|
|
|
|
mem->bo = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_finish(&mem->base);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, mem);
|
2019-07-10 14:21:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-16 11:03:22 +10:00
|
|
|
|
static VkResult radv_alloc_memory(struct radv_device *device,
|
|
|
|
|
|
const VkMemoryAllocateInfo* pAllocateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkDeviceMemory* pMem)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
struct radv_device_memory *mem;
|
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
enum radeon_bo_domain domain;
|
|
|
|
|
|
uint32_t flags = 0;
|
2016-11-03 04:16:43 +00:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
|
|
|
|
|
|
|
2017-07-15 02:08:01 +02:00
|
|
|
|
const VkImportMemoryFdInfoKHR *import_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkMemoryDedicatedAllocateInfo *dedicate_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
|
|
|
|
|
|
const VkExportMemoryAllocateInfo *export_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO);
|
2019-07-10 14:45:01 +02:00
|
|
|
|
const struct VkImportAndroidHardwareBufferInfoANDROID *ahb_import_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext,
|
|
|
|
|
|
IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
|
2018-01-25 18:12:14 +01:00
|
|
|
|
const VkImportMemoryHostPointerInfoEXT *host_ptr_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_HOST_POINTER_INFO_EXT);
|
2017-02-26 23:52:08 +00:00
|
|
|
|
|
2017-11-16 08:27:01 -08:00
|
|
|
|
const struct wsi_memory_allocate_info *wsi_info =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA);
|
|
|
|
|
|
|
2019-07-10 14:45:01 +02:00
|
|
|
|
if (pAllocateInfo->allocationSize == 0 && !ahb_import_info &&
|
|
|
|
|
|
!(export_info && (export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))) {
|
|
|
|
|
|
/* Apparently, this is allowed */
|
|
|
|
|
|
*pMem = VK_NULL_HANDLE;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 10:16:32 +02:00
|
|
|
|
mem = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
if (mem == NULL)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &mem->base,
|
|
|
|
|
|
VK_OBJECT_TYPE_DEVICE_MEMORY);
|
|
|
|
|
|
|
2017-11-16 08:27:01 -08:00
|
|
|
|
if (wsi_info && wsi_info->implicit_sync)
|
|
|
|
|
|
flags |= RADEON_FLAG_IMPLICIT_SYNC;
|
|
|
|
|
|
|
2017-02-26 23:52:08 +00:00
|
|
|
|
if (dedicate_info) {
|
|
|
|
|
|
mem->image = radv_image_from_handle(dedicate_info->image);
|
|
|
|
|
|
mem->buffer = radv_buffer_from_handle(dedicate_info->buffer);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
mem->image = NULL;
|
|
|
|
|
|
mem->buffer = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-28 02:09:07 +01:00
|
|
|
|
float priority_float = 0.5;
|
|
|
|
|
|
const struct VkMemoryPriorityAllocateInfoEXT *priority_ext =
|
|
|
|
|
|
vk_find_struct_const(pAllocateInfo->pNext,
|
|
|
|
|
|
MEMORY_PRIORITY_ALLOCATE_INFO_EXT);
|
|
|
|
|
|
if (priority_ext)
|
|
|
|
|
|
priority_float = priority_ext->priority;
|
|
|
|
|
|
|
|
|
|
|
|
unsigned priority = MIN2(RADV_BO_PRIORITY_APPLICATION_MAX - 1,
|
|
|
|
|
|
(int)(priority_float * RADV_BO_PRIORITY_APPLICATION_MAX));
|
|
|
|
|
|
|
2018-01-25 18:12:14 +01:00
|
|
|
|
mem->user_ptr = NULL;
|
2019-07-10 14:21:11 +02:00
|
|
|
|
mem->bo = NULL;
|
2018-01-25 18:12:14 +01:00
|
|
|
|
|
2019-07-10 14:27:37 +02:00
|
|
|
|
#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
|
|
|
|
|
|
mem->android_hardware_buffer = NULL;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
2019-07-10 14:45:01 +02:00
|
|
|
|
if (ahb_import_info) {
|
|
|
|
|
|
result = radv_import_ahb_memory(device, mem, priority, ahb_import_info);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else if(export_info && (export_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) {
|
|
|
|
|
|
result = radv_create_ahb_memory(device, mem, priority, pAllocateInfo);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
} else if (import_info) {
|
2017-07-15 02:08:01 +02:00
|
|
|
|
assert(import_info->handleType ==
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2017-11-27 18:43:43 -08:00
|
|
|
|
import_info->handleType ==
|
|
|
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
2017-07-15 02:08:01 +02:00
|
|
|
|
mem->bo = device->ws->buffer_from_fd(device->ws, import_info->fd,
|
2019-10-08 23:24:02 +02:00
|
|
|
|
priority, NULL);
|
2017-07-15 02:08:01 +02:00
|
|
|
|
if (!mem->bo) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
2017-07-15 02:08:01 +02:00
|
|
|
|
goto fail;
|
2017-07-24 03:45:03 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
close(import_info->fd);
|
|
|
|
|
|
}
|
2020-05-04 17:04:00 +02:00
|
|
|
|
|
|
|
|
|
|
if (mem->image && mem->image->plane_count == 1 &&
|
2020-10-29 02:33:31 +01:00
|
|
|
|
!vk_format_is_depth_or_stencil(mem->image->vk_format) &&
|
|
|
|
|
|
mem->image->info.samples == 1) {
|
2020-05-04 17:04:00 +02:00
|
|
|
|
struct radeon_bo_metadata metadata;
|
|
|
|
|
|
device->ws->buffer_get_metadata(mem->bo, &metadata);
|
|
|
|
|
|
|
|
|
|
|
|
struct radv_image_create_info create_info = {
|
|
|
|
|
|
.no_metadata_planes = true,
|
|
|
|
|
|
.bo_metadata = &metadata
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* This gives a basic ability to import radeonsi images
|
|
|
|
|
|
* that don't have DCC. This is not guaranteed by any
|
|
|
|
|
|
* spec and can be removed after we support modifiers. */
|
|
|
|
|
|
result = radv_image_create_layout(device, create_info, mem->image);
|
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
|
device->ws->buffer_destroy(mem->bo);
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
} else if (host_ptr_info) {
|
2018-01-25 18:12:14 +01:00
|
|
|
|
assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
|
|
|
|
|
|
mem->bo = device->ws->buffer_from_ptr(device->ws, host_ptr_info->pHostPointer,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
pAllocateInfo->allocationSize,
|
2019-01-28 02:09:07 +01:00
|
|
|
|
priority);
|
2018-01-25 18:12:14 +01:00
|
|
|
|
if (!mem->bo) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
|
2018-01-25 18:12:14 +01:00
|
|
|
|
goto fail;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
mem->user_ptr = host_ptr_info->pHostPointer;
|
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
|
2020-04-28 13:10:56 +02:00
|
|
|
|
uint32_t heap_index;
|
|
|
|
|
|
|
|
|
|
|
|
heap_index = device->physical_device->memory_properties.memoryTypes[pAllocateInfo->memoryTypeIndex].heapIndex;
|
2020-04-25 23:52:44 +02:00
|
|
|
|
domain = device->physical_device->memory_domains[pAllocateInfo->memoryTypeIndex];
|
2020-04-29 22:35:54 +02:00
|
|
|
|
flags |= device->physical_device->memory_flags[pAllocateInfo->memoryTypeIndex];
|
2016-10-26 02:57:19 +02:00
|
|
|
|
|
2019-04-10 01:42:31 +02:00
|
|
|
|
if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes)) {
|
2018-04-09 12:46:49 +02:00
|
|
|
|
flags |= RADEON_FLAG_NO_INTERPROCESS_SHARING;
|
2019-04-10 01:42:31 +02:00
|
|
|
|
if (device->use_global_bo_list) {
|
|
|
|
|
|
flags |= RADEON_FLAG_PREFER_LOCAL_BO;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-10-25 07:12:13 +01:00
|
|
|
|
|
2020-04-28 13:10:56 +02:00
|
|
|
|
if (device->overallocation_disallowed) {
|
|
|
|
|
|
uint64_t total_size =
|
|
|
|
|
|
device->physical_device->memory_properties.memoryHeaps[heap_index].size;
|
|
|
|
|
|
|
|
|
|
|
|
mtx_lock(&device->overallocation_mutex);
|
|
|
|
|
|
if (device->allocated_memory_size[heap_index] + alloc_size > total_size) {
|
|
|
|
|
|
mtx_unlock(&device->overallocation_mutex);
|
|
|
|
|
|
result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
|
|
|
|
|
device->allocated_memory_size[heap_index] += alloc_size;
|
|
|
|
|
|
mtx_unlock(&device->overallocation_mutex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
|
mem->bo = device->ws->buffer_create(device->ws, alloc_size, device->physical_device->rad_info.max_alignment,
|
2019-01-28 02:09:07 +01:00
|
|
|
|
domain, flags, priority);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
|
if (!mem->bo) {
|
2020-04-28 13:10:56 +02:00
|
|
|
|
if (device->overallocation_disallowed) {
|
|
|
|
|
|
mtx_lock(&device->overallocation_mutex);
|
|
|
|
|
|
device->allocated_memory_size[heap_index] -= alloc_size;
|
|
|
|
|
|
mtx_unlock(&device->overallocation_mutex);
|
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
2020-04-28 13:10:56 +02:00
|
|
|
|
|
|
|
|
|
|
mem->heap_index = heap_index;
|
|
|
|
|
|
mem->alloc_size = alloc_size;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
|
2020-03-24 17:59:26 +01:00
|
|
|
|
if (!wsi_info) {
|
|
|
|
|
|
result = radv_bo_list_add(device, mem->bo);
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
goto fail;
|
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
*pMem = radv_device_memory_to_handle(mem);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
fail:
|
2019-07-10 14:21:11 +02:00
|
|
|
|
radv_free_memory(device, pAllocator,mem);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-20 18:42:12 -04:00
|
|
|
|
VkResult radv_AllocateMemory(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkMemoryAllocateInfo* pAllocateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkDeviceMemory* pMem)
|
|
|
|
|
|
{
|
2017-11-16 11:03:22 +10:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return radv_alloc_memory(device, pAllocateInfo, pAllocator, pMem);
|
2017-10-20 18:42:12 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_FreeMemory(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkDeviceMemory _mem,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, mem, _mem);
|
|
|
|
|
|
|
2019-07-10 14:21:11 +02:00
|
|
|
|
radv_free_memory(device, pAllocator, mem);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_MapMemory(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkDeviceMemory _memory,
|
|
|
|
|
|
VkDeviceSize offset,
|
|
|
|
|
|
VkDeviceSize size,
|
|
|
|
|
|
VkMemoryMapFlags flags,
|
|
|
|
|
|
void** ppData)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, mem, _memory);
|
|
|
|
|
|
|
|
|
|
|
|
if (mem == NULL) {
|
|
|
|
|
|
*ppData = NULL;
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-25 18:12:14 +01:00
|
|
|
|
if (mem->user_ptr)
|
|
|
|
|
|
*ppData = mem->user_ptr;
|
|
|
|
|
|
else
|
|
|
|
|
|
*ppData = device->ws->buffer_map(mem->bo);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (*ppData) {
|
2020-11-26 19:32:48 -08:00
|
|
|
|
*ppData = (uint8_t*)*ppData + offset;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_MEMORY_MAP_FAILED);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_UnmapMemory(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkDeviceMemory _memory)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, mem, _memory);
|
|
|
|
|
|
|
|
|
|
|
|
if (mem == NULL)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2018-01-25 18:12:14 +01:00
|
|
|
|
if (mem->user_ptr == NULL)
|
|
|
|
|
|
device->ws->buffer_unmap(mem->bo);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_FlushMappedMemoryRanges(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
uint32_t memoryRangeCount,
|
|
|
|
|
|
const VkMappedMemoryRange* pMemoryRanges)
|
|
|
|
|
|
{
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_InvalidateMappedMemoryRanges(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
uint32_t memoryRangeCount,
|
|
|
|
|
|
const VkMappedMemoryRange* pMemoryRanges)
|
|
|
|
|
|
{
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_GetBufferMemoryRequirements(
|
2017-11-01 09:26:48 +01:00
|
|
|
|
VkDevice _device,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkBuffer _buffer,
|
|
|
|
|
|
VkMemoryRequirements* pMemoryRequirements)
|
|
|
|
|
|
{
|
2017-11-01 09:26:48 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
pMemoryRequirements->memoryTypeBits = (1u << device->physical_device->memory_properties.memoryTypeCount) - 1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-02-04 11:15:59 +01:00
|
|
|
|
if (buffer->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
|
|
|
|
|
|
pMemoryRequirements->alignment = 4096;
|
|
|
|
|
|
else
|
|
|
|
|
|
pMemoryRequirements->alignment = 16;
|
|
|
|
|
|
|
|
|
|
|
|
pMemoryRequirements->size = align64(buffer->size, pMemoryRequirements->alignment);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetBufferMemoryRequirements2(
|
2017-07-15 02:07:59 +02:00
|
|
|
|
VkDevice device,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkBufferMemoryRequirementsInfo2 *pInfo,
|
|
|
|
|
|
VkMemoryRequirements2 *pMemoryRequirements)
|
2017-07-15 02:07:59 +02:00
|
|
|
|
{
|
|
|
|
|
|
radv_GetBufferMemoryRequirements(device, pInfo->buffer,
|
|
|
|
|
|
&pMemoryRequirements->memoryRequirements);
|
2017-07-15 02:08:00 +02:00
|
|
|
|
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
|
|
|
|
|
|
switch (ext->sType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
|
|
|
|
|
VkMemoryDedicatedRequirements *req =
|
|
|
|
|
|
(VkMemoryDedicatedRequirements *) ext;
|
2020-01-27 16:50:23 +01:00
|
|
|
|
req->requiresDedicatedAllocation = false;
|
2017-07-15 02:08:00 +02:00
|
|
|
|
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-07-15 02:07:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_GetImageMemoryRequirements(
|
2017-11-01 09:26:48 +01:00
|
|
|
|
VkDevice _device,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkImage _image,
|
|
|
|
|
|
VkMemoryRequirements* pMemoryRequirements)
|
|
|
|
|
|
{
|
2017-11-01 09:26:48 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, _image);
|
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
|
pMemoryRequirements->memoryTypeBits = (1u << device->physical_device->memory_properties.memoryTypeCount) - 1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
pMemoryRequirements->size = image->size;
|
|
|
|
|
|
pMemoryRequirements->alignment = image->alignment;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetImageMemoryRequirements2(
|
2017-07-15 02:07:59 +02:00
|
|
|
|
VkDevice device,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkImageMemoryRequirementsInfo2 *pInfo,
|
|
|
|
|
|
VkMemoryRequirements2 *pMemoryRequirements)
|
2017-07-15 02:07:59 +02:00
|
|
|
|
{
|
|
|
|
|
|
radv_GetImageMemoryRequirements(device, pInfo->image,
|
|
|
|
|
|
&pMemoryRequirements->memoryRequirements);
|
2017-07-15 02:08:00 +02:00
|
|
|
|
|
2017-07-15 02:08:01 +02:00
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, pInfo->image);
|
|
|
|
|
|
|
2017-07-15 02:08:00 +02:00
|
|
|
|
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
|
|
|
|
|
|
switch (ext->sType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
|
|
|
|
|
|
VkMemoryDedicatedRequirements *req =
|
|
|
|
|
|
(VkMemoryDedicatedRequirements *) ext;
|
2020-01-27 16:50:23 +01:00
|
|
|
|
req->requiresDedicatedAllocation = image->shareable &&
|
|
|
|
|
|
image->tiling != VK_IMAGE_TILING_LINEAR;
|
2017-07-15 02:08:00 +02:00
|
|
|
|
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2017-07-15 02:07:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_GetDeviceMemoryCommitment(
|
|
|
|
|
|
VkDevice device,
|
|
|
|
|
|
VkDeviceMemory memory,
|
|
|
|
|
|
VkDeviceSize* pCommittedMemoryInBytes)
|
|
|
|
|
|
{
|
|
|
|
|
|
*pCommittedMemoryInBytes = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
VkResult radv_BindBufferMemory2(VkDevice device,
|
|
|
|
|
|
uint32_t bindInfoCount,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkBindBufferMemoryInfo *pBindInfos)
|
2017-09-17 13:55:16 +02:00
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, mem, pBindInfos[i].memory);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, pBindInfos[i].buffer);
|
|
|
|
|
|
|
|
|
|
|
|
if (mem) {
|
|
|
|
|
|
buffer->bo = mem->bo;
|
|
|
|
|
|
buffer->offset = pBindInfos[i].memoryOffset;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
buffer->bo = NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_BindBufferMemory(
|
|
|
|
|
|
VkDevice device,
|
2017-09-17 13:55:16 +02:00
|
|
|
|
VkBuffer buffer,
|
|
|
|
|
|
VkDeviceMemory memory,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkDeviceSize memoryOffset)
|
|
|
|
|
|
{
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkBindBufferMemoryInfo info = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
|
2017-09-17 13:55:16 +02:00
|
|
|
|
.buffer = buffer,
|
|
|
|
|
|
.memory = memory,
|
|
|
|
|
|
.memoryOffset = memoryOffset
|
|
|
|
|
|
};
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
return radv_BindBufferMemory2(device, 1, &info);
|
2017-09-17 13:55:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
VkResult radv_BindImageMemory2(VkDevice device,
|
|
|
|
|
|
uint32_t bindInfoCount,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkBindImageMemoryInfo *pBindInfos)
|
2017-09-17 13:55:16 +02:00
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, mem, pBindInfos[i].memory);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, pBindInfos[i].image);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-09-17 13:55:16 +02:00
|
|
|
|
if (mem) {
|
|
|
|
|
|
image->bo = mem->bo;
|
|
|
|
|
|
image->offset = pBindInfos[i].memoryOffset;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
image->bo = NULL;
|
|
|
|
|
|
image->offset = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-17 13:55:16 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_BindImageMemory(
|
|
|
|
|
|
VkDevice device,
|
2017-09-17 13:55:16 +02:00
|
|
|
|
VkImage image,
|
|
|
|
|
|
VkDeviceMemory memory,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkDeviceSize memoryOffset)
|
|
|
|
|
|
{
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkBindImageMemoryInfo info = {
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
|
2017-09-17 13:55:16 +02:00
|
|
|
|
.image = image,
|
|
|
|
|
|
.memory = memory,
|
|
|
|
|
|
.memoryOffset = memoryOffset
|
|
|
|
|
|
};
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
return radv_BindImageMemory2(device, 1, &info);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-19 17:05:22 +02:00
|
|
|
|
static bool radv_sparse_bind_has_effects(const VkBindSparseInfo *info)
|
2017-02-04 15:58:39 +01:00
|
|
|
|
{
|
2019-10-19 17:05:22 +02:00
|
|
|
|
return info->bufferBindCount ||
|
|
|
|
|
|
info->imageOpaqueBindCount ||
|
|
|
|
|
|
info->imageBindCount ||
|
|
|
|
|
|
info->waitSemaphoreCount ||
|
|
|
|
|
|
info->signalSemaphoreCount;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_QueueBindSparse(
|
|
|
|
|
|
VkQueue _queue,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
uint32_t bindInfoCount,
|
|
|
|
|
|
const VkBindSparseInfo* pBindInfo,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
VkFence fence)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
2017-02-04 15:58:39 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
2019-10-19 17:05:22 +02:00
|
|
|
|
uint32_t fence_idx = 0;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(queue->device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2019-10-19 17:05:22 +02:00
|
|
|
|
if (fence != VK_NULL_HANDLE) {
|
|
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i)
|
|
|
|
|
|
if (radv_sparse_bind_has_effects(pBindInfo + i))
|
|
|
|
|
|
fence_idx = i;
|
|
|
|
|
|
} else
|
|
|
|
|
|
fence_idx = UINT32_MAX;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
|
2019-10-19 17:05:22 +02:00
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
|
|
|
|
|
if (i != fence_idx && !radv_sparse_bind_has_effects(pBindInfo + i))
|
2019-10-03 21:08:29 +02:00
|
|
|
|
continue;
|
2018-06-21 14:39:30 +02:00
|
|
|
|
|
2019-11-25 20:50:12 +01:00
|
|
|
|
const VkTimelineSemaphoreSubmitInfo *timeline_info =
|
|
|
|
|
|
vk_find_struct_const(pBindInfo[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
VkResult result = radv_queue_submit(queue, &(struct radv_queue_submission) {
|
2019-10-19 17:05:22 +02:00
|
|
|
|
.buffer_binds = pBindInfo[i].pBufferBinds,
|
|
|
|
|
|
.buffer_bind_count = pBindInfo[i].bufferBindCount,
|
|
|
|
|
|
.image_opaque_binds = pBindInfo[i].pImageOpaqueBinds,
|
|
|
|
|
|
.image_opaque_bind_count = pBindInfo[i].imageOpaqueBindCount,
|
2020-12-06 19:17:03 +01:00
|
|
|
|
.image_binds = pBindInfo[i].pImageBinds,
|
|
|
|
|
|
.image_bind_count = pBindInfo[i].imageBindCount,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
.wait_semaphores = pBindInfo[i].pWaitSemaphores,
|
|
|
|
|
|
.wait_semaphore_count = pBindInfo[i].waitSemaphoreCount,
|
|
|
|
|
|
.signal_semaphores = pBindInfo[i].pSignalSemaphores,
|
|
|
|
|
|
.signal_semaphore_count = pBindInfo[i].signalSemaphoreCount,
|
2019-10-19 17:05:22 +02:00
|
|
|
|
.fence = i == fence_idx ? fence : VK_NULL_HANDLE,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
.wait_values = timeline_info ? timeline_info->pWaitSemaphoreValues : NULL,
|
|
|
|
|
|
.wait_value_count = timeline_info && timeline_info->pWaitSemaphoreValues ? timeline_info->waitSemaphoreValueCount : 0,
|
|
|
|
|
|
.signal_values = timeline_info ? timeline_info->pSignalSemaphoreValues : NULL,
|
|
|
|
|
|
.signal_value_count = timeline_info && timeline_info->pSignalSemaphoreValues ? timeline_info->signalSemaphoreValueCount : 0,
|
2019-10-03 21:08:29 +02:00
|
|
|
|
});
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2019-10-03 21:08:29 +02:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-19 17:05:22 +02:00
|
|
|
|
if (fence != VK_NULL_HANDLE && !bindInfoCount) {
|
2020-11-03 17:20:36 +01:00
|
|
|
|
VkResult result = radv_signal_fence(queue, fence);
|
2019-10-19 17:05:22 +02:00
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_destroy_fence_part(struct radv_device *device,
|
|
|
|
|
|
struct radv_fence_part *part)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (part->kind) {
|
|
|
|
|
|
case RADV_FENCE_NONE:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_WINSYS:
|
|
|
|
|
|
device->ws->destroy_fence(part->fence);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_SYNCOBJ:
|
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, part->syncobj);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Invalid fence type");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
part->kind = RADV_FENCE_NONE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-10 17:29:21 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_destroy_fence(struct radv_device *device,
|
|
|
|
|
|
const VkAllocationCallbacks *pAllocator,
|
|
|
|
|
|
struct radv_fence *fence)
|
|
|
|
|
|
{
|
2020-07-14 21:46:17 +02:00
|
|
|
|
radv_destroy_fence_part(device, &fence->temporary);
|
|
|
|
|
|
radv_destroy_fence_part(device, &fence->permanent);
|
2020-07-10 17:29:21 +02:00
|
|
|
|
|
|
|
|
|
|
vk_object_base_finish(&fence->base);
|
|
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, fence);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateFence(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkFenceCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkFence* pFence)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkExportFenceCreateInfo *export =
|
|
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext, EXPORT_FENCE_CREATE_INFO);
|
|
|
|
|
|
VkExternalFenceHandleTypeFlags handleTypes =
|
2017-11-27 23:58:35 +01:00
|
|
|
|
export ? export->handleTypes : 0;
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence *fence;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
fence = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*fence), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!fence)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &fence->base, VK_OBJECT_TYPE_FENCE);
|
|
|
|
|
|
|
2018-01-04 18:38:32 +01:00
|
|
|
|
if (device->always_use_syncobj || handleTypes) {
|
2020-07-14 21:46:17 +02:00
|
|
|
|
fence->permanent.kind = RADV_FENCE_SYNCOBJ;
|
|
|
|
|
|
|
2020-07-14 21:23:17 +02:00
|
|
|
|
bool create_signaled = false;
|
|
|
|
|
|
if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
|
|
|
|
|
|
create_signaled = true;
|
|
|
|
|
|
|
|
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, create_signaled,
|
2020-07-14 21:46:17 +02:00
|
|
|
|
&fence->permanent.syncobj);
|
2017-11-27 23:58:35 +01:00
|
|
|
|
if (ret) {
|
2020-07-10 17:29:21 +02:00
|
|
|
|
radv_destroy_fence(device, pAllocator, fence);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-11-27 23:58:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2020-07-14 21:46:17 +02:00
|
|
|
|
fence->permanent.kind = RADV_FENCE_WINSYS;
|
|
|
|
|
|
|
|
|
|
|
|
fence->permanent.fence = device->ws->create_fence();
|
|
|
|
|
|
if (!fence->permanent.fence) {
|
|
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, fence);
|
2020-07-10 17:29:21 +02:00
|
|
|
|
radv_destroy_fence(device, pAllocator, fence);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-11-27 23:58:35 +01:00
|
|
|
|
}
|
2019-05-12 00:30:06 +02:00
|
|
|
|
if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
|
2020-07-14 21:46:17 +02:00
|
|
|
|
device->ws->signal_fence(fence->permanent.fence);
|
2016-12-01 00:44:45 +00:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
*pFence = radv_fence_to_handle(fence);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
void radv_DestroyFence(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkFence _fence,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
|
|
|
|
|
|
|
if (!fence)
|
|
|
|
|
|
return;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-10 17:29:21 +02:00
|
|
|
|
radv_destroy_fence(device, pAllocator, fence);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-12 00:30:06 +02:00
|
|
|
|
static bool radv_all_fences_plain_and_submitted(struct radv_device *device,
|
|
|
|
|
|
uint32_t fenceCount, const VkFence *pFences)
|
2018-02-26 23:48:27 +01:00
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
if (part->kind != RADV_FENCE_WINSYS ||
|
|
|
|
|
|
!device->ws->is_fence_waitable(part->fence))
|
2017-06-15 21:00:56 -07:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool radv_all_fences_syncobj(uint32_t fenceCount, const VkFence *pFences)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
if (part->kind != RADV_FENCE_SYNCOBJ)
|
2018-02-26 23:48:27 +01:00
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_WaitForFences(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
uint32_t fenceCount,
|
|
|
|
|
|
const VkFence* pFences,
|
|
|
|
|
|
VkBool32 waitAll,
|
|
|
|
|
|
uint64_t timeout)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2020-07-13 13:59:48 +02:00
|
|
|
|
|
|
|
|
|
|
if (radv_device_is_lost(device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
timeout = radv_get_absolute_timeout(timeout);
|
|
|
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
|
if (device->always_use_syncobj &&
|
|
|
|
|
|
radv_all_fences_syncobj(fenceCount, pFences))
|
|
|
|
|
|
{
|
2018-02-26 21:52:49 +01:00
|
|
|
|
uint32_t *handles = malloc(sizeof(uint32_t) * fenceCount);
|
|
|
|
|
|
if (!handles)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2018-02-26 21:52:49 +01:00
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
|
|
|
|
|
|
assert(part->kind == RADV_FENCE_SYNCOBJ);
|
|
|
|
|
|
handles[i] = part->syncobj;
|
2018-02-26 21:52:49 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool success = device->ws->wait_syncobj(device->ws, handles, fenceCount, waitAll, timeout);
|
|
|
|
|
|
|
|
|
|
|
|
free(handles);
|
|
|
|
|
|
return success ? VK_SUCCESS : VK_TIMEOUT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!waitAll && fenceCount > 1) {
|
2018-02-26 23:48:27 +01:00
|
|
|
|
/* Not doing this by default for waitAll, due to needing to allocate twice. */
|
2019-05-12 00:30:06 +02:00
|
|
|
|
if (device->physical_device->rad_info.drm_minor >= 10 && radv_all_fences_plain_and_submitted(device, fenceCount, pFences)) {
|
2018-02-26 23:48:27 +01:00
|
|
|
|
uint32_t wait_count = 0;
|
|
|
|
|
|
struct radeon_winsys_fence **fences = malloc(sizeof(struct radeon_winsys_fence *) * fenceCount);
|
|
|
|
|
|
if (!fences)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2018-02-26 23:48:27 +01:00
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
|
|
|
|
|
assert(part->kind == RADV_FENCE_WINSYS);
|
|
|
|
|
|
|
|
|
|
|
|
if (device->ws->fence_wait(device->ws, part->fence, false, 0)) {
|
2018-02-26 23:48:27 +01:00
|
|
|
|
free(fences);
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
fences[wait_count++] = part->fence;
|
2018-02-26 23:48:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool success = device->ws->fences_wait(device->ws, fences, wait_count,
|
|
|
|
|
|
waitAll, timeout - radv_get_current_time());
|
|
|
|
|
|
|
|
|
|
|
|
free(fences);
|
|
|
|
|
|
return success ? VK_SUCCESS : VK_TIMEOUT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-02-26 22:50:41 +01:00
|
|
|
|
while(radv_get_current_time() <= timeout) {
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
if (radv_GetFenceStatus(_device, pFences[i]) == VK_SUCCESS)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return VK_TIMEOUT;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
|
|
|
|
|
bool expired = false;
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
switch (part->kind) {
|
|
|
|
|
|
case RADV_FENCE_NONE:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_WINSYS:
|
|
|
|
|
|
if (!device->ws->is_fence_waitable(part->fence)) {
|
|
|
|
|
|
while (!device->ws->is_fence_waitable(part->fence) &&
|
2019-05-12 00:30:06 +02:00
|
|
|
|
radv_get_current_time() <= timeout)
|
2017-06-15 21:00:56 -07:00
|
|
|
|
/* Do nothing */;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
expired = device->ws->fence_wait(device->ws,
|
2020-07-14 21:46:17 +02:00
|
|
|
|
part->fence,
|
2017-06-15 21:00:56 -07:00
|
|
|
|
true, timeout);
|
|
|
|
|
|
if (!expired)
|
|
|
|
|
|
return VK_TIMEOUT;
|
2020-07-14 21:46:17 +02:00
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_SYNCOBJ:
|
|
|
|
|
|
if (!device->ws->wait_syncobj(device->ws,
|
|
|
|
|
|
&part->syncobj, 1, true,
|
|
|
|
|
|
timeout))
|
|
|
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Invalid fence type");
|
2017-06-15 21:00:56 -07:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
|
VkResult radv_ResetFences(VkDevice _device,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
uint32_t fenceCount,
|
|
|
|
|
|
const VkFence *pFences)
|
|
|
|
|
|
{
|
2017-11-27 23:58:35 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
for (unsigned i = 0; i < fenceCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
/* From the Vulkan 1.0.53 spec:
|
|
|
|
|
|
*
|
|
|
|
|
|
* "If any member of pFences currently has its payload
|
|
|
|
|
|
* imported with temporary permanence, that fence’s prior
|
|
|
|
|
|
* permanent payload is irst restored. The remaining
|
|
|
|
|
|
* operations described therefore operate on the restored
|
|
|
|
|
|
* payload."
|
|
|
|
|
|
*/
|
|
|
|
|
|
if (fence->temporary.kind != RADV_FENCE_NONE)
|
|
|
|
|
|
radv_destroy_fence_part(device, &fence->temporary);
|
|
|
|
|
|
|
|
|
|
|
|
struct radv_fence_part *part = &fence->permanent;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
switch (part->kind) {
|
2020-09-23 12:46:46 -04:00
|
|
|
|
case RADV_FENCE_WINSYS:
|
2020-07-14 21:46:17 +02:00
|
|
|
|
device->ws->reset_fence(part->fence);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_SYNCOBJ:
|
|
|
|
|
|
device->ws->reset_syncobj(device->ws, part->syncobj);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Invalid fence type");
|
2017-11-27 23:58:35 +01:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
switch (part->kind) {
|
|
|
|
|
|
case RADV_FENCE_NONE:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_WINSYS:
|
|
|
|
|
|
if (!device->ws->fence_wait(device->ws, part->fence, false, 0))
|
|
|
|
|
|
return VK_NOT_READY;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_FENCE_SYNCOBJ: {
|
|
|
|
|
|
bool success = device->ws->wait_syncobj(device->ws,
|
|
|
|
|
|
&part->syncobj, 1, true, 0);
|
|
|
|
|
|
if (!success)
|
2017-06-15 21:00:56 -07:00
|
|
|
|
return VK_NOT_READY;
|
2020-07-14 21:46:17 +02:00
|
|
|
|
break;
|
2017-06-15 21:00:56 -07:00
|
|
|
|
}
|
2020-07-14 21:46:17 +02:00
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Invalid fence type");
|
2017-06-15 21:00:56 -07:00
|
|
|
|
}
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Queue semaphore functions
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_create_timeline(struct radv_timeline *timeline, uint64_t value)
|
|
|
|
|
|
{
|
|
|
|
|
|
timeline->highest_signaled = value;
|
|
|
|
|
|
timeline->highest_submitted = value;
|
|
|
|
|
|
list_inithead(&timeline->points);
|
|
|
|
|
|
list_inithead(&timeline->free_points);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
list_inithead(&timeline->waiters);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_init(&timeline->mutex, mtx_plain);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_destroy_timeline(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline)
|
|
|
|
|
|
{
|
|
|
|
|
|
list_for_each_entry_safe(struct radv_timeline_point, point,
|
|
|
|
|
|
&timeline->free_points, list) {
|
|
|
|
|
|
list_del(&point->list);
|
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, point->syncobj);
|
|
|
|
|
|
free(point);
|
|
|
|
|
|
}
|
|
|
|
|
|
list_for_each_entry_safe(struct radv_timeline_point, point,
|
|
|
|
|
|
&timeline->points, list) {
|
|
|
|
|
|
list_del(&point->list);
|
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, point->syncobj);
|
|
|
|
|
|
free(point);
|
|
|
|
|
|
}
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_destroy(&timeline->mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|
radv_timeline_gc_locked(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline)
|
|
|
|
|
|
{
|
|
|
|
|
|
list_for_each_entry_safe(struct radv_timeline_point, point,
|
|
|
|
|
|
&timeline->points, list) {
|
|
|
|
|
|
if (point->wait_count || point->value > timeline->highest_submitted)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (device->ws->wait_syncobj(device->ws, &point->syncobj, 1, true, 0)) {
|
|
|
|
|
|
timeline->highest_signaled = point->value;
|
|
|
|
|
|
list_del(&point->list);
|
|
|
|
|
|
list_add(&point->list, &timeline->free_points);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct radv_timeline_point *
|
|
|
|
|
|
radv_timeline_find_point_at_least_locked(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline,
|
|
|
|
|
|
uint64_t p)
|
|
|
|
|
|
{
|
|
|
|
|
|
radv_timeline_gc_locked(device, timeline);
|
|
|
|
|
|
|
|
|
|
|
|
if (p <= timeline->highest_signaled)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(struct radv_timeline_point, point,
|
|
|
|
|
|
&timeline->points, list) {
|
|
|
|
|
|
if (point->value >= p) {
|
|
|
|
|
|
++point->wait_count;
|
|
|
|
|
|
return point;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static struct radv_timeline_point *
|
|
|
|
|
|
radv_timeline_add_point_locked(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline,
|
|
|
|
|
|
uint64_t p)
|
|
|
|
|
|
{
|
|
|
|
|
|
radv_timeline_gc_locked(device, timeline);
|
|
|
|
|
|
|
|
|
|
|
|
struct radv_timeline_point *ret = NULL;
|
|
|
|
|
|
struct radv_timeline_point *prev = NULL;
|
2020-07-12 18:35:25 +02:00
|
|
|
|
int r;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (p <= timeline->highest_signaled)
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(struct radv_timeline_point, point,
|
|
|
|
|
|
&timeline->points, list) {
|
|
|
|
|
|
if (point->value == p) {
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (point->value < p)
|
|
|
|
|
|
prev = point;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (list_is_empty(&timeline->free_points)) {
|
|
|
|
|
|
ret = malloc(sizeof(struct radv_timeline_point));
|
2020-07-12 18:35:25 +02:00
|
|
|
|
r = device->ws->create_syncobj(device->ws, false, &ret->syncobj);
|
|
|
|
|
|
if (r) {
|
|
|
|
|
|
free(ret);
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
ret = list_first_entry(&timeline->free_points, struct radv_timeline_point, list);
|
|
|
|
|
|
list_del(&ret->list);
|
|
|
|
|
|
|
|
|
|
|
|
device->ws->reset_syncobj(device->ws, ret->syncobj);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ret->value = p;
|
|
|
|
|
|
ret->wait_count = 1;
|
|
|
|
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
|
|
list_add(&ret->list, &prev->list);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
list_addtail(&ret->list, &timeline->points);
|
|
|
|
|
|
}
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static VkResult
|
2020-07-28 12:27:05 +10:00
|
|
|
|
radv_timeline_wait(struct radv_device *device,
|
|
|
|
|
|
struct radv_timeline *timeline,
|
|
|
|
|
|
uint64_t value,
|
|
|
|
|
|
uint64_t abs_timeout)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
{
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&timeline->mutex);
|
2020-07-28 12:27:05 +10:00
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
while(timeline->highest_submitted < value) {
|
|
|
|
|
|
struct timespec abstime;
|
|
|
|
|
|
timespec_from_nsec(&abstime, abs_timeout);
|
|
|
|
|
|
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_timedwait(&device->timeline_cond, &timeline->mutex, &abstime);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2020-07-28 12:27:05 +10:00
|
|
|
|
if (radv_get_current_time() >= abs_timeout && timeline->highest_submitted < value) {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&timeline->mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
return VK_TIMEOUT;
|
2020-07-28 12:27:05 +10:00
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct radv_timeline_point *point = radv_timeline_find_point_at_least_locked(device, timeline, value);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&timeline->mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
if (!point)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
|
|
bool success = device->ws->wait_syncobj(device->ws, &point->syncobj, 1, true, abs_timeout);
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&timeline->mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
point->wait_count--;
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&timeline->mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
return success ? VK_SUCCESS : VK_TIMEOUT;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-28 02:44:54 +01:00
|
|
|
|
static void
|
|
|
|
|
|
radv_timeline_trigger_waiters_locked(struct radv_timeline *timeline,
|
|
|
|
|
|
struct list_head *processing_list)
|
|
|
|
|
|
{
|
|
|
|
|
|
list_for_each_entry_safe(struct radv_timeline_waiter, waiter,
|
|
|
|
|
|
&timeline->waiters, list) {
|
|
|
|
|
|
if (waiter->value > timeline->highest_submitted)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2020-06-22 22:07:46 +02:00
|
|
|
|
radv_queue_trigger_submission(waiter->submission, 1, processing_list);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
list_del(&waiter->list);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-20 22:50:58 +02:00
|
|
|
|
static
|
|
|
|
|
|
void radv_destroy_semaphore_part(struct radv_device *device,
|
|
|
|
|
|
struct radv_semaphore_part *part)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch(part->kind) {
|
|
|
|
|
|
case RADV_SEMAPHORE_NONE:
|
|
|
|
|
|
break;
|
|
|
|
|
|
case RADV_SEMAPHORE_WINSYS:
|
|
|
|
|
|
device->ws->destroy_sem(part->ws_sem);
|
|
|
|
|
|
break;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE:
|
|
|
|
|
|
radv_destroy_timeline(device, &part->timeline);
|
|
|
|
|
|
break;
|
2019-10-20 22:50:58 +02:00
|
|
|
|
case RADV_SEMAPHORE_SYNCOBJ:
|
2020-07-16 02:44:22 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE_SYNCOBJ:
|
2019-10-20 22:50:58 +02:00
|
|
|
|
device->ws->destroy_syncobj(device->ws, part->syncobj);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
part->kind = RADV_SEMAPHORE_NONE;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
static VkSemaphoreTypeKHR
|
|
|
|
|
|
radv_get_semaphore_type(const void *pNext, uint64_t *initial_value)
|
|
|
|
|
|
{
|
2019-11-25 20:50:12 +01:00
|
|
|
|
const VkSemaphoreTypeCreateInfo *type_info =
|
|
|
|
|
|
vk_find_struct_const(pNext, SEMAPHORE_TYPE_CREATE_INFO);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (!type_info)
|
2019-11-25 20:50:12 +01:00
|
|
|
|
return VK_SEMAPHORE_TYPE_BINARY;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (initial_value)
|
|
|
|
|
|
*initial_value = type_info->initialValue;
|
|
|
|
|
|
return type_info->semaphoreType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-10 17:25:00 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_destroy_semaphore(struct radv_device *device,
|
|
|
|
|
|
const VkAllocationCallbacks *pAllocator,
|
|
|
|
|
|
struct radv_semaphore *sem)
|
|
|
|
|
|
{
|
|
|
|
|
|
radv_destroy_semaphore_part(device, &sem->temporary);
|
|
|
|
|
|
radv_destroy_semaphore_part(device, &sem->permanent);
|
|
|
|
|
|
vk_object_base_finish(&sem->base);
|
|
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, sem);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateSemaphore(
|
2016-12-01 01:52:31 +00:00
|
|
|
|
VkDevice _device,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
const VkSemaphoreCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkSemaphore* pSemaphore)
|
|
|
|
|
|
{
|
2016-12-01 01:52:31 +00:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkExportSemaphoreCreateInfo *export =
|
|
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext, EXPORT_SEMAPHORE_CREATE_INFO);
|
|
|
|
|
|
VkExternalSemaphoreHandleTypeFlags handleTypes =
|
2017-02-27 19:14:00 +00:00
|
|
|
|
export ? export->handleTypes : 0;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
uint64_t initial_value = 0;
|
|
|
|
|
|
VkSemaphoreTypeKHR type = radv_get_semaphore_type(pCreateInfo->pNext, &initial_value);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 10:16:32 +02:00
|
|
|
|
struct radv_semaphore *sem = vk_alloc2(&device->vk.alloc, pAllocator,
|
2017-02-27 19:14:00 +00:00
|
|
|
|
sizeof(*sem), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
2016-12-01 01:52:31 +00:00
|
|
|
|
if (!sem)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &sem->base,
|
|
|
|
|
|
VK_OBJECT_TYPE_SEMAPHORE);
|
|
|
|
|
|
|
2019-10-20 22:50:58 +02:00
|
|
|
|
sem->temporary.kind = RADV_SEMAPHORE_NONE;
|
|
|
|
|
|
sem->permanent.kind = RADV_SEMAPHORE_NONE;
|
|
|
|
|
|
|
2020-07-16 02:44:22 +02:00
|
|
|
|
if (type == VK_SEMAPHORE_TYPE_TIMELINE &&
|
|
|
|
|
|
device->physical_device->rad_info.has_timeline_syncobj) {
|
|
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, false, &sem->permanent.syncobj);
|
|
|
|
|
|
if (ret) {
|
|
|
|
|
|
radv_destroy_semaphore(device, pAllocator, sem);
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
}
|
|
|
|
|
|
device->ws->signal_syncobj(device->ws, sem->permanent.syncobj, initial_value);
|
|
|
|
|
|
sem->permanent.timeline_syncobj.max_point = initial_value;
|
|
|
|
|
|
sem->permanent.kind = RADV_SEMAPHORE_TIMELINE_SYNCOBJ;
|
|
|
|
|
|
} else if (type == VK_SEMAPHORE_TYPE_TIMELINE) {
|
2019-10-22 10:18:06 +02:00
|
|
|
|
radv_create_timeline(&sem->permanent.timeline, initial_value);
|
|
|
|
|
|
sem->permanent.kind = RADV_SEMAPHORE_TIMELINE;
|
|
|
|
|
|
} else if (device->always_use_syncobj || handleTypes) {
|
2017-02-27 19:14:00 +00:00
|
|
|
|
assert (device->physical_device->rad_info.has_syncobj);
|
2020-07-14 21:23:17 +02:00
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, false,
|
|
|
|
|
|
&sem->permanent.syncobj);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
if (ret) {
|
2020-07-10 17:25:00 +02:00
|
|
|
|
radv_destroy_semaphore(device, pAllocator, sem);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
2019-10-20 22:50:58 +02:00
|
|
|
|
sem->permanent.kind = RADV_SEMAPHORE_SYNCOBJ;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
} else {
|
2019-10-20 22:50:58 +02:00
|
|
|
|
sem->permanent.ws_sem = device->ws->create_sem(device->ws);
|
|
|
|
|
|
if (!sem->permanent.ws_sem) {
|
2020-07-10 17:25:00 +02:00
|
|
|
|
radv_destroy_semaphore(device, pAllocator, sem);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
2019-10-20 22:50:58 +02:00
|
|
|
|
sem->permanent.kind = RADV_SEMAPHORE_WINSYS;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*pSemaphore = radv_semaphore_to_handle(sem);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroySemaphore(
|
2016-12-01 01:52:31 +00:00
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkSemaphore _semaphore,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
2016-12-01 01:52:31 +00:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2017-02-27 19:14:00 +00:00
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, _semaphore);
|
2016-12-01 01:52:31 +00:00
|
|
|
|
if (!_semaphore)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2020-07-10 17:25:00 +02:00
|
|
|
|
radv_destroy_semaphore(device, pAllocator, sem);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
VkResult
|
2019-11-25 20:50:12 +01:00
|
|
|
|
radv_GetSemaphoreCounterValue(VkDevice _device,
|
|
|
|
|
|
VkSemaphore _semaphore,
|
|
|
|
|
|
uint64_t* pValue)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, _semaphore);
|
|
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
struct radv_semaphore_part *part =
|
|
|
|
|
|
semaphore->temporary.kind != RADV_SEMAPHORE_NONE ? &semaphore->temporary : &semaphore->permanent;
|
|
|
|
|
|
|
|
|
|
|
|
switch (part->kind) {
|
|
|
|
|
|
case RADV_SEMAPHORE_TIMELINE: {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&part->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
radv_timeline_gc_locked(device, &part->timeline);
|
|
|
|
|
|
*pValue = part->timeline.highest_signaled;
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&part->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
2020-07-16 02:44:22 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE_SYNCOBJ: {
|
|
|
|
|
|
return device->ws->query_syncobj(device->ws, part->syncobj, pValue);
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
case RADV_SEMAPHORE_NONE:
|
|
|
|
|
|
case RADV_SEMAPHORE_SYNCOBJ:
|
|
|
|
|
|
case RADV_SEMAPHORE_WINSYS:
|
|
|
|
|
|
unreachable("Invalid semaphore type");
|
|
|
|
|
|
}
|
|
|
|
|
|
unreachable("Unhandled semaphore type");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static VkResult
|
|
|
|
|
|
radv_wait_timelines(struct radv_device *device,
|
2019-11-25 20:50:12 +01:00
|
|
|
|
const VkSemaphoreWaitInfo* pWaitInfo,
|
2019-10-22 10:18:06 +02:00
|
|
|
|
uint64_t abs_timeout)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT_KHR) && pWaitInfo->semaphoreCount > 1) {
|
|
|
|
|
|
for (;;) {
|
|
|
|
|
|
for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, pWaitInfo->pSemaphores[i]);
|
2020-07-28 12:27:05 +10:00
|
|
|
|
VkResult result = radv_timeline_wait(device, &semaphore->permanent.timeline, pWaitInfo->pValues[i], 0);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (result == VK_SUCCESS)
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (radv_get_current_time() > abs_timeout)
|
|
|
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for(uint32_t i = 0; i < pWaitInfo->semaphoreCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, pWaitInfo->pSemaphores[i]);
|
2020-07-28 12:27:05 +10:00
|
|
|
|
VkResult result = radv_timeline_wait(device, &semaphore->permanent.timeline, pWaitInfo->pValues[i], abs_timeout);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
VkResult
|
2019-11-25 20:50:12 +01:00
|
|
|
|
radv_WaitSemaphores(VkDevice _device,
|
|
|
|
|
|
const VkSemaphoreWaitInfo* pWaitInfo,
|
|
|
|
|
|
uint64_t timeout)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2020-07-13 13:59:48 +02:00
|
|
|
|
|
|
|
|
|
|
if (radv_device_is_lost(device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2019-10-22 10:18:06 +02:00
|
|
|
|
uint64_t abs_timeout = radv_get_absolute_timeout(timeout);
|
2020-07-16 02:44:22 +02:00
|
|
|
|
|
|
|
|
|
|
if (radv_semaphore_from_handle(pWaitInfo->pSemaphores[0])->permanent.kind == RADV_SEMAPHORE_TIMELINE)
|
|
|
|
|
|
return radv_wait_timelines(device, pWaitInfo, abs_timeout);
|
|
|
|
|
|
|
|
|
|
|
|
if (pWaitInfo->semaphoreCount > UINT32_MAX / sizeof(uint32_t))
|
|
|
|
|
|
return vk_errorf(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY, "semaphoreCount integer overflow");
|
|
|
|
|
|
|
|
|
|
|
|
bool wait_all = !(pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT_KHR);
|
|
|
|
|
|
uint32_t *handles = malloc(sizeof(*handles) * pWaitInfo->semaphoreCount);
|
|
|
|
|
|
if (!handles)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < pWaitInfo->semaphoreCount; ++i) {
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, pWaitInfo->pSemaphores[i]);
|
|
|
|
|
|
handles[i] = semaphore->permanent.syncobj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool success = device->ws->wait_timeline_syncobj(device->ws, handles, pWaitInfo->pValues,
|
|
|
|
|
|
pWaitInfo->semaphoreCount, wait_all, false,
|
|
|
|
|
|
abs_timeout);
|
|
|
|
|
|
free(handles);
|
|
|
|
|
|
return success ? VK_SUCCESS : VK_TIMEOUT;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult
|
2019-11-25 20:50:12 +01:00
|
|
|
|
radv_SignalSemaphore(VkDevice _device,
|
|
|
|
|
|
const VkSemaphoreSignalInfo* pSignalInfo)
|
2019-10-22 10:18:06 +02:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, semaphore, pSignalInfo->semaphore);
|
|
|
|
|
|
|
|
|
|
|
|
struct radv_semaphore_part *part =
|
|
|
|
|
|
semaphore->temporary.kind != RADV_SEMAPHORE_NONE ? &semaphore->temporary : &semaphore->permanent;
|
|
|
|
|
|
|
|
|
|
|
|
switch(part->kind) {
|
|
|
|
|
|
case RADV_SEMAPHORE_TIMELINE: {
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&part->timeline.mutex);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
radv_timeline_gc_locked(device, &part->timeline);
|
|
|
|
|
|
part->timeline.highest_submitted = MAX2(part->timeline.highest_submitted, pSignalInfo->value);
|
|
|
|
|
|
part->timeline.highest_signaled = MAX2(part->timeline.highest_signaled, pSignalInfo->value);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
|
|
|
|
|
struct list_head processing_list;
|
|
|
|
|
|
list_inithead(&processing_list);
|
|
|
|
|
|
radv_timeline_trigger_waiters_locked(&part->timeline, &processing_list);
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&part->timeline.mutex);
|
2019-10-28 02:44:54 +01:00
|
|
|
|
|
2020-07-28 04:14:23 +02:00
|
|
|
|
VkResult result = radv_process_submissions(&processing_list);
|
|
|
|
|
|
|
|
|
|
|
|
/* This needs to happen after radv_process_submissions, so
|
|
|
|
|
|
* that any submitted submissions that are now unblocked get
|
|
|
|
|
|
* processed before we wake the application. This way we
|
|
|
|
|
|
* ensure that any binary semaphores that are now unblocked
|
|
|
|
|
|
* are usable by the application. */
|
2020-10-31 16:18:34 -07:00
|
|
|
|
u_cnd_monotonic_broadcast(&device->timeline_cond);
|
2020-07-28 04:14:23 +02:00
|
|
|
|
|
|
|
|
|
|
return result;
|
2019-10-22 10:18:06 +02:00
|
|
|
|
}
|
2020-07-16 02:44:22 +02:00
|
|
|
|
case RADV_SEMAPHORE_TIMELINE_SYNCOBJ: {
|
|
|
|
|
|
part->timeline_syncobj.max_point = MAX2(part->timeline_syncobj.max_point, pSignalInfo->value);
|
|
|
|
|
|
device->ws->signal_syncobj(device->ws, part->syncobj, pSignalInfo->value);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
case RADV_SEMAPHORE_NONE:
|
|
|
|
|
|
case RADV_SEMAPHORE_SYNCOBJ:
|
|
|
|
|
|
case RADV_SEMAPHORE_WINSYS:
|
|
|
|
|
|
unreachable("Invalid semaphore type");
|
|
|
|
|
|
}
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-20 21:12:01 +02:00
|
|
|
|
static void radv_destroy_event(struct radv_device *device,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
struct radv_event *event)
|
|
|
|
|
|
{
|
2020-07-10 17:14:30 +02:00
|
|
|
|
if (event->bo)
|
|
|
|
|
|
device->ws->buffer_destroy(event->bo);
|
|
|
|
|
|
|
2020-06-20 21:12:01 +02:00
|
|
|
|
vk_object_base_finish(&event->base);
|
|
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, event);
|
|
|
|
|
|
}
|
2019-10-22 10:18:06 +02:00
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateEvent(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkEventCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkEvent* pEvent)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
struct radv_event *event = vk_alloc2(&device->vk.alloc, pAllocator,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
sizeof(*event), 8,
|
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
|
|
if (!event)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &event->base, VK_OBJECT_TYPE_EVENT);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
event->bo = device->ws->buffer_create(device->ws, 8, 8,
|
|
|
|
|
|
RADEON_DOMAIN_GTT,
|
2019-01-28 00:28:05 +01:00
|
|
|
|
RADEON_FLAG_VA_UNCACHED | RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING,
|
|
|
|
|
|
RADV_BO_PRIORITY_FENCE);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (!event->bo) {
|
2020-07-10 17:14:30 +02:00
|
|
|
|
radv_destroy_event(device, pAllocator, event);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
event->map = (uint64_t*)device->ws->buffer_map(event->bo);
|
2020-06-20 21:12:01 +02:00
|
|
|
|
if (!event->map) {
|
|
|
|
|
|
radv_destroy_event(device, pAllocator, event);
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
*pEvent = radv_event_to_handle(event);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyEvent(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkEvent _event,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_event, event, _event);
|
|
|
|
|
|
|
|
|
|
|
|
if (!event)
|
|
|
|
|
|
return;
|
2020-06-20 21:12:01 +02:00
|
|
|
|
|
|
|
|
|
|
radv_destroy_event(device, pAllocator, event);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetEventStatus(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkEvent _event)
|
|
|
|
|
|
{
|
2020-07-13 13:59:48 +02:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
RADV_FROM_HANDLE(radv_event, event, _event);
|
|
|
|
|
|
|
2020-07-13 13:59:48 +02:00
|
|
|
|
if (radv_device_is_lost(device))
|
|
|
|
|
|
return VK_ERROR_DEVICE_LOST;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
if (*event->map == 1)
|
|
|
|
|
|
return VK_EVENT_SET;
|
|
|
|
|
|
return VK_EVENT_RESET;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_SetEvent(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkEvent _event)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_event, event, _event);
|
|
|
|
|
|
*event->map = 1;
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_ResetEvent(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkEvent _event)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_event, event, _event);
|
|
|
|
|
|
*event->map = 0;
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-10 17:11:10 +02:00
|
|
|
|
static void
|
|
|
|
|
|
radv_destroy_buffer(struct radv_device *device,
|
|
|
|
|
|
const VkAllocationCallbacks *pAllocator,
|
|
|
|
|
|
struct radv_buffer *buffer)
|
|
|
|
|
|
{
|
|
|
|
|
|
if ((buffer->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && buffer->bo)
|
|
|
|
|
|
device->ws->buffer_destroy(buffer->bo);
|
|
|
|
|
|
|
|
|
|
|
|
vk_object_base_finish(&buffer->base);
|
|
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, buffer);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VkResult radv_CreateBuffer(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkBufferCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkBuffer* pBuffer)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
struct radv_buffer *buffer;
|
|
|
|
|
|
|
2020-04-08 10:55:37 +02:00
|
|
|
|
if (pCreateInfo->size > RADV_MAX_MEMORY_ALLOCATION_SIZE)
|
|
|
|
|
|
return VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
|
|
|
|
|
|
|
2020-04-29 10:16:32 +02:00
|
|
|
|
buffer = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*buffer), 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
if (buffer == NULL)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
buffer->size = pCreateInfo->size;
|
|
|
|
|
|
buffer->usage = pCreateInfo->usage;
|
|
|
|
|
|
buffer->bo = NULL;
|
|
|
|
|
|
buffer->offset = 0;
|
2017-02-04 11:15:59 +01:00
|
|
|
|
buffer->flags = pCreateInfo->flags;
|
|
|
|
|
|
|
2017-11-01 23:54:56 +00:00
|
|
|
|
buffer->shareable = vk_find_struct_const(pCreateInfo->pNext,
|
2019-01-09 12:11:48 +00:00
|
|
|
|
EXTERNAL_MEMORY_BUFFER_CREATE_INFO) != NULL;
|
2017-11-01 23:54:56 +00:00
|
|
|
|
|
2017-02-04 11:15:59 +01:00
|
|
|
|
if (pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
|
|
|
|
|
|
buffer->bo = device->ws->buffer_create(device->ws,
|
|
|
|
|
|
align64(buffer->size, 4096),
|
2019-01-28 00:28:05 +01:00
|
|
|
|
4096, 0, RADEON_FLAG_VIRTUAL,
|
|
|
|
|
|
RADV_BO_PRIORITY_VIRTUAL);
|
2017-02-04 11:15:59 +01:00
|
|
|
|
if (!buffer->bo) {
|
2020-07-10 17:11:10 +02:00
|
|
|
|
radv_destroy_buffer(device, pAllocator, buffer);
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2017-02-04 11:15:59 +01:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
*pBuffer = radv_buffer_to_handle(buffer);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyBuffer(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkBuffer _buffer,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
|
|
|
|
|
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
2020-07-10 17:11:10 +02:00
|
|
|
|
radv_destroy_buffer(device, pAllocator, buffer);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-26 09:59:27 +01:00
|
|
|
|
VkDeviceAddress radv_GetBufferDeviceAddress(
|
2019-01-24 02:06:27 +01:00
|
|
|
|
VkDevice device,
|
2019-11-26 09:59:27 +01:00
|
|
|
|
const VkBufferDeviceAddressInfo* pInfo)
|
2019-01-24 02:06:27 +01:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
|
|
|
|
|
|
return radv_buffer_get_va(buffer->bo) + buffer->offset;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-11-26 09:59:27 +01:00
|
|
|
|
uint64_t radv_GetBufferOpaqueCaptureAddress(VkDevice device,
|
|
|
|
|
|
const VkBufferDeviceAddressInfo* pInfo)
|
2019-11-26 01:00:20 +01:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-11-26 09:59:27 +01:00
|
|
|
|
uint64_t radv_GetDeviceMemoryOpaqueCaptureAddress(VkDevice device,
|
|
|
|
|
|
const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo)
|
2019-11-26 01:00:20 +01:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
static inline unsigned
|
2018-07-16 20:51:26 +02:00
|
|
|
|
si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
|
2016-10-07 09:16:09 +10:00
|
|
|
|
{
|
|
|
|
|
|
if (stencil)
|
2018-07-16 20:51:26 +02:00
|
|
|
|
return plane->surface.u.legacy.stencil_tiling_index[level];
|
2016-10-07 09:16:09 +10:00
|
|
|
|
else
|
2018-07-16 20:51:26 +02:00
|
|
|
|
return plane->surface.u.legacy.tiling_index[level];
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-19 15:41:42 +10:00
|
|
|
|
static uint32_t radv_surface_max_layer_count(struct radv_image_view *iview)
|
2017-02-19 01:16:19 +01:00
|
|
|
|
{
|
2017-12-19 15:41:42 +10:00
|
|
|
|
return iview->type == VK_IMAGE_VIEW_TYPE_3D ? iview->extent.depth : (iview->base_layer + iview->layer_count);
|
2017-02-19 01:16:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-11 14:09:15 +02:00
|
|
|
|
static uint32_t
|
|
|
|
|
|
radv_init_dcc_control_reg(struct radv_device *device,
|
|
|
|
|
|
struct radv_image_view *iview)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_256B;
|
|
|
|
|
|
unsigned min_compressed_block_size = V_028C78_MIN_BLOCK_SIZE_32B;
|
|
|
|
|
|
unsigned max_compressed_block_size;
|
2019-06-25 10:09:58 +02:00
|
|
|
|
unsigned independent_128b_blocks;
|
2018-04-11 14:09:15 +02:00
|
|
|
|
unsigned independent_64b_blocks;
|
|
|
|
|
|
|
2019-06-18 10:30:43 +02:00
|
|
|
|
if (!radv_dcc_enabled(iview->image, iview->base_mip))
|
2018-04-11 14:09:15 +02:00
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (!device->physical_device->rad_info.has_dedicated_vram) {
|
|
|
|
|
|
/* amdvlk: [min-compressed-block-size] should be set to 32 for
|
|
|
|
|
|
* dGPU and 64 for APU because all of our APUs to date use
|
|
|
|
|
|
* DIMMs which have a request granularity size of 64B while all
|
|
|
|
|
|
* other chips have a 32B request size.
|
|
|
|
|
|
*/
|
|
|
|
|
|
min_compressed_block_size = V_028C78_MIN_BLOCK_SIZE_64B;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-06-25 10:09:58 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B;
|
2018-04-11 14:09:15 +02:00
|
|
|
|
independent_64b_blocks = 0;
|
2019-06-25 10:09:58 +02:00
|
|
|
|
independent_128b_blocks = 1;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
independent_128b_blocks = 0;
|
|
|
|
|
|
|
|
|
|
|
|
if (iview->image->info.samples > 1) {
|
|
|
|
|
|
if (iview->image->planes[0].surface.bpe == 1)
|
|
|
|
|
|
max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
|
|
|
|
|
else if (iview->image->planes[0].surface.bpe == 2)
|
|
|
|
|
|
max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_128B;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (iview->image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
|
|
|
|
|
|
VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
|
|
|
|
|
|
VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
|
|
|
|
|
|
/* If this DCC image is potentially going to be used in texture
|
|
|
|
|
|
* fetches, we need some special settings.
|
|
|
|
|
|
*/
|
|
|
|
|
|
independent_64b_blocks = 1;
|
|
|
|
|
|
max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
/* MAX_UNCOMPRESSED_BLOCK_SIZE must be >=
|
|
|
|
|
|
* MAX_COMPRESSED_BLOCK_SIZE. Set MAX_COMPRESSED_BLOCK_SIZE as
|
|
|
|
|
|
* big as possible for better compression state.
|
|
|
|
|
|
*/
|
|
|
|
|
|
independent_64b_blocks = 0;
|
|
|
|
|
|
max_compressed_block_size = max_uncompressed_block_size;
|
|
|
|
|
|
}
|
2018-04-11 14:09:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
|
|
|
|
|
|
S_028C78_MAX_COMPRESSED_BLOCK_SIZE(max_compressed_block_size) |
|
|
|
|
|
|
S_028C78_MIN_COMPRESSED_BLOCK_SIZE(min_compressed_block_size) |
|
2019-06-25 10:09:58 +02:00
|
|
|
|
S_028C78_INDEPENDENT_64B_BLOCKS(independent_64b_blocks) |
|
|
|
|
|
|
S_028C78_INDEPENDENT_128B_BLOCKS(independent_128b_blocks);
|
2018-04-11 14:09:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-22 02:31:27 +02:00
|
|
|
|
void
|
2016-10-07 09:16:09 +10:00
|
|
|
|
radv_initialise_color_surface(struct radv_device *device,
|
|
|
|
|
|
struct radv_color_buffer_info *cb,
|
|
|
|
|
|
struct radv_image_view *iview)
|
|
|
|
|
|
{
|
|
|
|
|
|
const struct vk_format_description *desc;
|
|
|
|
|
|
unsigned ntype, format, swap, endian;
|
|
|
|
|
|
unsigned blend_clamp = 0, blend_bypass = 0;
|
|
|
|
|
|
uint64_t va;
|
2018-07-18 00:53:52 +02:00
|
|
|
|
const struct radv_image_plane *plane = &iview->image->planes[iview->plane_id];
|
2018-07-16 20:51:26 +02:00
|
|
|
|
const struct radeon_surf *surf = &plane->surface;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
desc = vk_format_description(iview->vk_format);
|
|
|
|
|
|
|
|
|
|
|
|
memset(cb, 0, sizeof(*cb));
|
|
|
|
|
|
|
2017-06-05 02:05:59 +01:00
|
|
|
|
/* Intensity is implemented as Red, so treat it that way. */
|
|
|
|
|
|
cb->cb_color_attrib = S_028C74_FORCE_DST_ALPHA_1(desc->swizzle[3] == VK_SWIZZLE_1);
|
|
|
|
|
|
|
2018-07-16 20:51:26 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset + plane->offset;
|
2017-06-05 02:05:59 +01:00
|
|
|
|
|
2017-08-04 06:43:26 +01:00
|
|
|
|
cb->cb_color_base = va >> 8;
|
|
|
|
|
|
|
2017-06-06 08:38:36 +10:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
2019-06-25 10:20:33 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
cb->cb_color_attrib3 |= S_028EE0_COLOR_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
|
|
|
|
|
|
S_028EE0_FMASK_SW_MODE(surf->u.gfx9.fmask.swizzle_mode) |
|
2020-05-02 09:19:18 -04:00
|
|
|
|
S_028EE0_CMASK_PIPE_ALIGNED(1) |
|
2019-06-25 10:20:33 +02:00
|
|
|
|
S_028EE0_DCC_PIPE_ALIGNED(surf->u.gfx9.dcc.pipe_aligned);
|
|
|
|
|
|
} else {
|
2020-05-02 09:19:18 -04:00
|
|
|
|
struct gfx9_surf_meta_flags meta = {
|
|
|
|
|
|
.rb_aligned = 1,
|
|
|
|
|
|
.pipe_aligned = 1,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2020-05-24 13:47:20 +02:00
|
|
|
|
if (surf->dcc_offset)
|
2020-05-02 09:19:18 -04:00
|
|
|
|
meta = surf->u.gfx9.dcc;
|
|
|
|
|
|
|
2019-06-25 10:20:33 +02:00
|
|
|
|
cb->cb_color_attrib |= S_028C74_COLOR_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
|
|
|
|
|
|
S_028C74_FMASK_SW_MODE(surf->u.gfx9.fmask.swizzle_mode) |
|
|
|
|
|
|
S_028C74_RB_ALIGNED(meta.rb_aligned) |
|
|
|
|
|
|
S_028C74_PIPE_ALIGNED(meta.pipe_aligned);
|
|
|
|
|
|
cb->cb_mrt_epitch = S_0287A0_EPITCH(surf->u.gfx9.surf.epitch);
|
|
|
|
|
|
}
|
2017-06-06 08:38:36 +10:00
|
|
|
|
|
2018-07-16 20:51:26 +02:00
|
|
|
|
cb->cb_color_base += surf->u.gfx9.surf_offset >> 8;
|
|
|
|
|
|
cb->cb_color_base |= surf->tile_swizzle;
|
2017-06-06 08:38:36 +10:00
|
|
|
|
} else {
|
2017-06-05 02:05:59 +01:00
|
|
|
|
const struct legacy_surf_level *level_info = &surf->u.legacy.level[iview->base_mip];
|
|
|
|
|
|
unsigned pitch_tile_max, slice_tile_max, tile_mode_index;
|
|
|
|
|
|
|
2017-08-04 06:43:26 +01:00
|
|
|
|
cb->cb_color_base += level_info->offset >> 8;
|
|
|
|
|
|
if (level_info->mode == RADEON_SURF_MODE_2D)
|
2018-07-16 20:51:26 +02:00
|
|
|
|
cb->cb_color_base |= surf->tile_swizzle;
|
2017-06-05 02:05:59 +01:00
|
|
|
|
|
|
|
|
|
|
pitch_tile_max = level_info->nblk_x / 8 - 1;
|
|
|
|
|
|
slice_tile_max = (level_info->nblk_x * level_info->nblk_y) / 64 - 1;
|
2018-07-16 20:51:26 +02:00
|
|
|
|
tile_mode_index = si_tile_mode_index(plane, iview->base_mip, false);
|
2017-06-05 02:05:59 +01:00
|
|
|
|
|
|
|
|
|
|
cb->cb_color_pitch = S_028C64_TILE_MAX(pitch_tile_max);
|
|
|
|
|
|
cb->cb_color_slice = S_028C68_TILE_MAX(slice_tile_max);
|
2019-08-01 17:59:55 +02:00
|
|
|
|
cb->cb_color_cmask_slice = surf->u.legacy.cmask_slice_tile_max;
|
2017-06-05 02:05:59 +01:00
|
|
|
|
|
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_TILE_MODE_INDEX(tile_mode_index);
|
|
|
|
|
|
|
2018-04-06 15:37:28 +02:00
|
|
|
|
if (radv_image_has_fmask(iview->image)) {
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7)
|
2019-08-01 17:59:56 +02:00
|
|
|
|
cb->cb_color_pitch |= S_028C64_FMASK_TILE_MAX(surf->u.legacy.fmask.pitch_in_pixels / 8 - 1);
|
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(surf->u.legacy.fmask.tiling_index);
|
|
|
|
|
|
cb->cb_color_fmask_slice = S_028C88_TILE_MAX(surf->u.legacy.fmask.slice_tile_max);
|
2017-06-05 02:05:59 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
/* This must be set for fast clear to work without FMASK. */
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7)
|
2017-06-05 02:05:59 +01:00
|
|
|
|
cb->cb_color_pitch |= S_028C64_FMASK_TILE_MAX(pitch_tile_max);
|
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(tile_mode_index);
|
|
|
|
|
|
cb->cb_color_fmask_slice = S_028C88_TILE_MAX(slice_tile_max);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
/* CMASK variables */
|
2017-09-17 12:15:02 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset;
|
2020-05-24 13:47:20 +02:00
|
|
|
|
va += surf->cmask_offset;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_cmask = va >> 8;
|
|
|
|
|
|
|
2017-09-17 12:15:02 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset;
|
2020-05-24 13:47:20 +02:00
|
|
|
|
va += surf->dcc_offset;
|
2019-06-18 11:51:31 +02:00
|
|
|
|
|
|
|
|
|
|
if (radv_dcc_enabled(iview->image, iview->base_mip) &&
|
|
|
|
|
|
device->physical_device->rad_info.chip_class <= GFX8)
|
|
|
|
|
|
va += plane->surface.u.legacy.level[iview->base_mip].dcc_offset;
|
|
|
|
|
|
|
2019-06-25 14:28:10 +02:00
|
|
|
|
unsigned dcc_tile_swizzle = surf->tile_swizzle;
|
|
|
|
|
|
dcc_tile_swizzle &= (surf->dcc_alignment - 1) >> 8;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_dcc_base = va >> 8;
|
2019-06-25 14:28:10 +02:00
|
|
|
|
cb->cb_dcc_base |= dcc_tile_swizzle;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2019-06-25 10:20:33 +02:00
|
|
|
|
/* GFX10 field has the same base shift as the GFX6 field. */
|
2017-12-19 15:41:42 +10:00
|
|
|
|
uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_view = S_028C6C_SLICE_START(iview->base_layer) |
|
2019-06-25 10:20:33 +02:00
|
|
|
|
S_028C6C_SLICE_MAX_GFX10(max_slice);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-05-02 09:49:14 +10:00
|
|
|
|
if (iview->image->info.samples > 1) {
|
|
|
|
|
|
unsigned log_samples = util_logbase2(iview->image->info.samples);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_NUM_SAMPLES(log_samples) |
|
|
|
|
|
|
S_028C74_NUM_FRAGMENTS(log_samples);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-04-06 15:37:28 +02:00
|
|
|
|
if (radv_image_has_fmask(iview->image)) {
|
2020-05-24 13:47:20 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset + surf->fmask_offset;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_fmask = va >> 8;
|
2019-08-01 17:59:56 +02:00
|
|
|
|
cb->cb_color_fmask |= surf->fmask_tile_swizzle;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
} else {
|
|
|
|
|
|
cb->cb_color_fmask = cb->cb_color_base;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ntype = radv_translate_color_numformat(iview->vk_format,
|
|
|
|
|
|
desc,
|
|
|
|
|
|
vk_format_get_first_non_void_channel(iview->vk_format));
|
|
|
|
|
|
format = radv_translate_colorformat(iview->vk_format);
|
|
|
|
|
|
if (format == V_028C70_COLOR_INVALID || ntype == ~0u)
|
|
|
|
|
|
radv_finishme("Illegal color\n");
|
2019-08-09 16:01:04 +03:00
|
|
|
|
swap = radv_translate_colorswap(iview->vk_format, false);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
endian = radv_colorformat_endian_swap(format);
|
|
|
|
|
|
|
|
|
|
|
|
/* blend clamp should be set for all NORM/SRGB types */
|
|
|
|
|
|
if (ntype == V_028C70_NUMBER_UNORM ||
|
|
|
|
|
|
ntype == V_028C70_NUMBER_SNORM ||
|
|
|
|
|
|
ntype == V_028C70_NUMBER_SRGB)
|
|
|
|
|
|
blend_clamp = 1;
|
|
|
|
|
|
|
|
|
|
|
|
/* set blend bypass according to docs if SINT/UINT or
|
|
|
|
|
|
8/24 COLOR variants */
|
|
|
|
|
|
if (ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT ||
|
|
|
|
|
|
format == V_028C70_COLOR_8_24 || format == V_028C70_COLOR_24_8 ||
|
|
|
|
|
|
format == V_028C70_COLOR_X24_8_32_FLOAT) {
|
|
|
|
|
|
blend_clamp = 0;
|
|
|
|
|
|
blend_bypass = 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
#if 0
|
|
|
|
|
|
if ((ntype == V_028C70_NUMBER_UINT || ntype == V_028C70_NUMBER_SINT) &&
|
|
|
|
|
|
(format == V_028C70_COLOR_8 ||
|
|
|
|
|
|
format == V_028C70_COLOR_8_8 ||
|
|
|
|
|
|
format == V_028C70_COLOR_8_8_8_8))
|
|
|
|
|
|
->color_is_int8 = true;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
cb->cb_color_info = S_028C70_FORMAT(format) |
|
|
|
|
|
|
S_028C70_COMP_SWAP(swap) |
|
|
|
|
|
|
S_028C70_BLEND_CLAMP(blend_clamp) |
|
|
|
|
|
|
S_028C70_BLEND_BYPASS(blend_bypass) |
|
|
|
|
|
|
S_028C70_SIMPLE_FLOAT(1) |
|
|
|
|
|
|
S_028C70_ROUND_MODE(ntype != V_028C70_NUMBER_UNORM &&
|
|
|
|
|
|
ntype != V_028C70_NUMBER_SNORM &&
|
|
|
|
|
|
ntype != V_028C70_NUMBER_SRGB &&
|
|
|
|
|
|
format != V_028C70_COLOR_8_24 &&
|
|
|
|
|
|
format != V_028C70_COLOR_24_8) |
|
|
|
|
|
|
S_028C70_NUMBER_TYPE(ntype) |
|
|
|
|
|
|
S_028C70_ENDIAN(endian);
|
2018-04-06 16:02:16 +02:00
|
|
|
|
if (radv_image_has_fmask(iview->image)) {
|
2017-08-07 07:39:41 +01:00
|
|
|
|
cb->cb_color_info |= S_028C70_COMPRESSION(1);
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class == GFX6) {
|
2019-08-01 17:59:56 +02:00
|
|
|
|
unsigned fmask_bankh = util_logbase2(surf->u.legacy.fmask.bankh);
|
2017-08-07 07:39:41 +01:00
|
|
|
|
cb->cb_color_attrib |= S_028C74_FMASK_BANK_HEIGHT(fmask_bankh);
|
|
|
|
|
|
}
|
2018-11-14 16:24:02 +01:00
|
|
|
|
|
|
|
|
|
|
if (radv_image_is_tc_compat_cmask(iview->image)) {
|
|
|
|
|
|
/* Allow the texture block to read FMASK directly
|
|
|
|
|
|
* without decompressing it. This bit must be cleared
|
|
|
|
|
|
* when performing FMASK_DECOMPRESS or DCC_COMPRESS,
|
|
|
|
|
|
* otherwise the operation doesn't happen.
|
|
|
|
|
|
*/
|
|
|
|
|
|
cb->cb_color_info |= S_028C70_FMASK_COMPRESS_1FRAG_ONLY(1);
|
|
|
|
|
|
|
|
|
|
|
|
/* Set CMASK into a tiling format that allows the
|
|
|
|
|
|
* texture block to read it.
|
|
|
|
|
|
*/
|
|
|
|
|
|
cb->cb_color_info |= S_028C70_CMASK_ADDR_TYPE(2);
|
|
|
|
|
|
}
|
2017-08-07 07:39:41 +01:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2018-04-06 15:37:28 +02:00
|
|
|
|
if (radv_image_has_cmask(iview->image) &&
|
2017-10-11 11:59:20 +11:00
|
|
|
|
!(device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS))
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_info |= S_028C70_FAST_CLEAR(1);
|
|
|
|
|
|
|
2018-04-06 16:00:08 +02:00
|
|
|
|
if (radv_dcc_enabled(iview->image, iview->base_mip))
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_info |= S_028C70_DCC_ENABLE(1);
|
|
|
|
|
|
|
2018-04-11 14:09:15 +02:00
|
|
|
|
cb->cb_dcc_control = radv_init_dcc_control_reg(device, iview);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
/* This must be set for fast clear to work without FMASK. */
|
2018-04-06 15:37:28 +02:00
|
|
|
|
if (!radv_image_has_fmask(iview->image) &&
|
2019-05-14 22:16:20 -04:00
|
|
|
|
device->physical_device->rad_info.chip_class == GFX6) {
|
2018-07-16 20:51:26 +02:00
|
|
|
|
unsigned bankh = util_logbase2(surf->u.legacy.bankh);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
cb->cb_color_attrib |= S_028C74_FMASK_BANK_HEIGHT(bankh);
|
|
|
|
|
|
}
|
2017-06-06 08:38:36 +10:00
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
2019-04-29 21:34:28 +02:00
|
|
|
|
const struct vk_format_description *format_desc = vk_format_description(iview->image->vk_format);
|
|
|
|
|
|
|
2017-08-21 21:02:03 +01:00
|
|
|
|
unsigned mip0_depth = iview->image->type == VK_IMAGE_TYPE_3D ?
|
|
|
|
|
|
(iview->extent.depth - 1) : (iview->image->info.array_size - 1);
|
2019-04-29 21:34:28 +02:00
|
|
|
|
unsigned width = iview->extent.width / (iview->plane_id ? format_desc->width_divisor : 1);
|
|
|
|
|
|
unsigned height = iview->extent.height / (iview->plane_id ? format_desc->height_divisor : 1);
|
2017-06-06 08:38:36 +10:00
|
|
|
|
|
2019-06-25 10:20:33 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
cb->cb_color_view |= S_028C6C_MIP_LEVEL_GFX10(iview->base_mip);
|
|
|
|
|
|
|
|
|
|
|
|
cb->cb_color_attrib3 |= S_028EE0_MIP0_DEPTH(mip0_depth) |
|
|
|
|
|
|
S_028EE0_RESOURCE_TYPE(surf->u.gfx9.resource_type) |
|
|
|
|
|
|
S_028EE0_RESOURCE_LEVEL(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
cb->cb_color_view |= S_028C6C_MIP_LEVEL_GFX9(iview->base_mip);
|
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_MIP0_DEPTH(mip0_depth) |
|
|
|
|
|
|
S_028C74_RESOURCE_TYPE(surf->u.gfx9.resource_type);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-04-29 21:34:28 +02:00
|
|
|
|
cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(width - 1) |
|
|
|
|
|
|
S_028C68_MIP0_HEIGHT(height - 1) |
|
2017-08-21 08:28:27 +01:00
|
|
|
|
S_028C68_MAX_MIP(iview->image->info.levels - 1);
|
2017-06-06 08:38:36 +10:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-21 21:30:41 +01:00
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_calc_decompress_on_z_planes(struct radv_device *device,
|
|
|
|
|
|
struct radv_image_view *iview)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned max_zplanes = 0;
|
|
|
|
|
|
|
2018-04-06 16:17:26 +02:00
|
|
|
|
assert(radv_image_is_tc_compat_htile(iview->image));
|
2018-03-21 21:30:41 +01:00
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
|
|
|
|
|
/* Default value for 32-bit depth surfaces. */
|
|
|
|
|
|
max_zplanes = 4;
|
|
|
|
|
|
|
|
|
|
|
|
if (iview->vk_format == VK_FORMAT_D16_UNORM &&
|
|
|
|
|
|
iview->image->info.samples > 1)
|
|
|
|
|
|
max_zplanes = 2;
|
|
|
|
|
|
|
|
|
|
|
|
max_zplanes = max_zplanes + 1;
|
|
|
|
|
|
} else {
|
2018-03-21 21:30:42 +01:00
|
|
|
|
if (iview->vk_format == VK_FORMAT_D16_UNORM) {
|
|
|
|
|
|
/* Do not enable Z plane compression for 16-bit depth
|
|
|
|
|
|
* surfaces because isn't supported on GFX8. Only
|
|
|
|
|
|
* 32-bit depth surfaces are supported by the hardware.
|
|
|
|
|
|
* This allows to maintain shader compatibility and to
|
|
|
|
|
|
* reduce the number of depth decompressions.
|
|
|
|
|
|
*/
|
|
|
|
|
|
max_zplanes = 1;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (iview->image->info.samples <= 1)
|
|
|
|
|
|
max_zplanes = 5;
|
|
|
|
|
|
else if (iview->image->info.samples <= 4)
|
|
|
|
|
|
max_zplanes = 3;
|
|
|
|
|
|
else
|
|
|
|
|
|
max_zplanes = 2;
|
|
|
|
|
|
}
|
2018-03-21 21:30:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return max_zplanes;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-07-22 02:31:27 +02:00
|
|
|
|
void
|
2016-10-07 09:16:09 +10:00
|
|
|
|
radv_initialise_ds_surface(struct radv_device *device,
|
|
|
|
|
|
struct radv_ds_buffer_info *ds,
|
|
|
|
|
|
struct radv_image_view *iview)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned level = iview->base_mip;
|
2017-06-05 02:01:10 +01:00
|
|
|
|
unsigned format, stencil_format;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
uint64_t va, s_offs, z_offs;
|
2017-04-13 14:36:26 +10:00
|
|
|
|
bool stencil_only = false;
|
2018-07-16 20:51:26 +02:00
|
|
|
|
const struct radv_image_plane *plane = &iview->image->planes[0];
|
|
|
|
|
|
const struct radeon_surf *surf = &plane->surface;
|
|
|
|
|
|
|
|
|
|
|
|
assert(vk_format_get_plane_count(iview->image->vk_format) == 1);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
memset(ds, 0, sizeof(*ds));
|
2017-06-26 01:27:02 +02:00
|
|
|
|
switch (iview->image->vk_format) {
|
2016-10-07 09:16:09 +10:00
|
|
|
|
case VK_FORMAT_D24_UNORM_S8_UINT:
|
|
|
|
|
|
case VK_FORMAT_X8_D24_UNORM_PACK32:
|
|
|
|
|
|
ds->pa_su_poly_offset_db_fmt_cntl = S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(-24);
|
|
|
|
|
|
ds->offset_scale = 2.0f;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VK_FORMAT_D16_UNORM:
|
|
|
|
|
|
case VK_FORMAT_D16_UNORM_S8_UINT:
|
|
|
|
|
|
ds->pa_su_poly_offset_db_fmt_cntl = S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(-16);
|
|
|
|
|
|
ds->offset_scale = 4.0f;
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VK_FORMAT_D32_SFLOAT:
|
|
|
|
|
|
case VK_FORMAT_D32_SFLOAT_S8_UINT:
|
|
|
|
|
|
ds->pa_su_poly_offset_db_fmt_cntl = S_028B78_POLY_OFFSET_NEG_NUM_DB_BITS(-23) |
|
|
|
|
|
|
S_028B78_POLY_OFFSET_DB_IS_FLOAT_FMT(1);
|
|
|
|
|
|
ds->offset_scale = 1.0f;
|
|
|
|
|
|
break;
|
2017-04-13 14:36:26 +10:00
|
|
|
|
case VK_FORMAT_S8_UINT:
|
|
|
|
|
|
stencil_only = true;
|
|
|
|
|
|
break;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-06-26 01:27:02 +02:00
|
|
|
|
format = radv_translate_dbformat(iview->image->vk_format);
|
2018-07-16 20:51:26 +02:00
|
|
|
|
stencil_format = surf->has_stencil ?
|
2017-06-05 02:01:10 +01:00
|
|
|
|
V_028044_STENCIL_8 : V_028044_STENCIL_INVALID;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-12-19 15:41:42 +10:00
|
|
|
|
uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
ds->db_depth_view = S_028008_SLICE_START(iview->base_layer) |
|
2017-12-19 15:41:42 +10:00
|
|
|
|
S_028008_SLICE_MAX(max_slice);
|
2019-06-25 10:42:49 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
ds->db_depth_view |= S_028008_SLICE_START_HI(iview->base_layer >> 11) |
|
|
|
|
|
|
S_028008_SLICE_MAX_HI(max_slice >> 11);
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_htile_data_base = 0;
|
|
|
|
|
|
ds->db_htile_surface = 0;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-09-17 12:15:02 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset;
|
2017-06-05 02:01:10 +01:00
|
|
|
|
s_offs = z_offs = va;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-06-06 08:39:44 +10:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX9) {
|
2018-07-16 20:51:26 +02:00
|
|
|
|
assert(surf->u.gfx9.surf_offset == 0);
|
|
|
|
|
|
s_offs += surf->u.gfx9.stencil_offset;
|
2017-06-06 08:39:44 +10:00
|
|
|
|
|
|
|
|
|
|
ds->db_z_info = S_028038_FORMAT(format) |
|
|
|
|
|
|
S_028038_NUM_SAMPLES(util_logbase2(iview->image->info.samples)) |
|
2018-07-16 20:51:26 +02:00
|
|
|
|
S_028038_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
|
2018-06-08 17:59:49 +02:00
|
|
|
|
S_028038_MAXMIP(iview->image->info.levels - 1) |
|
|
|
|
|
|
S_028038_ZRANGE_PRECISION(1);
|
2017-06-06 08:39:44 +10:00
|
|
|
|
ds->db_stencil_info = S_02803C_FORMAT(stencil_format) |
|
2018-07-16 20:51:26 +02:00
|
|
|
|
S_02803C_SW_MODE(surf->u.gfx9.stencil.swizzle_mode);
|
2017-06-06 08:39:44 +10:00
|
|
|
|
|
2019-06-25 10:42:49 +02:00
|
|
|
|
if (device->physical_device->rad_info.chip_class == GFX9) {
|
|
|
|
|
|
ds->db_z_info2 = S_028068_EPITCH(surf->u.gfx9.surf.epitch);
|
|
|
|
|
|
ds->db_stencil_info2 = S_02806C_EPITCH(surf->u.gfx9.stencil.epitch);
|
|
|
|
|
|
}
|
2017-06-06 08:39:44 +10:00
|
|
|
|
|
2019-06-25 10:42:49 +02:00
|
|
|
|
ds->db_depth_view |= S_028008_MIPID(level);
|
2017-06-06 08:39:44 +10:00
|
|
|
|
ds->db_depth_size = S_02801C_X_MAX(iview->image->info.width - 1) |
|
|
|
|
|
|
S_02801C_Y_MAX(iview->image->info.height - 1);
|
|
|
|
|
|
|
2017-10-03 10:48:42 +02:00
|
|
|
|
if (radv_htile_enabled(iview->image, level)) {
|
2017-06-06 08:39:44 +10:00
|
|
|
|
ds->db_z_info |= S_028038_TILE_SURFACE_ENABLE(1);
|
|
|
|
|
|
|
2018-04-06 16:17:26 +02:00
|
|
|
|
if (radv_image_is_tc_compat_htile(iview->image)) {
|
2018-03-21 21:30:41 +01:00
|
|
|
|
unsigned max_zplanes =
|
|
|
|
|
|
radv_calc_decompress_on_z_planes(device, iview);
|
2017-05-09 08:26:07 +02:00
|
|
|
|
|
2019-06-25 10:42:49 +02:00
|
|
|
|
ds->db_z_info |= S_028038_DECOMPRESS_ON_N_ZPLANES(max_zplanes);
|
|
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
ds->db_z_info |= S_028040_ITERATE_FLUSH(1);
|
|
|
|
|
|
ds->db_stencil_info |= S_028044_ITERATE_FLUSH(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ds->db_z_info |= S_028038_ITERATE_FLUSH(1);
|
|
|
|
|
|
ds->db_stencil_info |= S_02803C_ITERATE_FLUSH(1);
|
|
|
|
|
|
}
|
2017-05-09 08:26:07 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-09 17:48:56 +01:00
|
|
|
|
if (radv_image_tile_stencil_disabled(device, iview->image)) {
|
2017-06-06 08:39:44 +10:00
|
|
|
|
ds->db_stencil_info |= S_02803C_TILE_STENCIL_DISABLE(1);
|
2020-12-09 17:48:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-17 12:15:02 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset +
|
2020-05-24 13:47:20 +02:00
|
|
|
|
surf->htile_offset;
|
2017-06-06 08:39:44 +10:00
|
|
|
|
ds->db_htile_data_base = va >> 8;
|
|
|
|
|
|
ds->db_htile_surface = S_028ABC_FULL_CACHE(1) |
|
2020-05-02 09:19:18 -04:00
|
|
|
|
S_028ABC_PIPE_ALIGNED(1);
|
2019-06-25 10:42:49 +02:00
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class == GFX9) {
|
2020-05-02 09:19:18 -04:00
|
|
|
|
ds->db_htile_surface |= S_028ABC_RB_ALIGNED(1);
|
2019-06-25 10:42:49 +02:00
|
|
|
|
}
|
2017-06-06 08:39:44 +10:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2018-07-16 20:51:26 +02:00
|
|
|
|
const struct legacy_surf_level *level_info = &surf->u.legacy.level[level];
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-04-13 14:36:26 +10:00
|
|
|
|
if (stencil_only)
|
2018-07-16 20:51:26 +02:00
|
|
|
|
level_info = &surf->u.legacy.stencil_level[level];
|
2017-06-05 02:01:10 +01:00
|
|
|
|
|
2018-07-16 20:51:26 +02:00
|
|
|
|
z_offs += surf->u.legacy.level[level].offset;
|
|
|
|
|
|
s_offs += surf->u.legacy.stencil_level[level].offset;
|
2017-06-05 02:01:10 +01:00
|
|
|
|
|
2018-04-06 16:17:26 +02:00
|
|
|
|
ds->db_depth_info = S_02803C_ADDR5_SWIZZLE_MASK(!radv_image_is_tc_compat_htile(iview->image));
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_z_info = S_028040_FORMAT(format) | S_028040_ZRANGE_PRECISION(1);
|
|
|
|
|
|
ds->db_stencil_info = S_028044_FORMAT(stencil_format);
|
|
|
|
|
|
|
|
|
|
|
|
if (iview->image->info.samples > 1)
|
|
|
|
|
|
ds->db_z_info |= S_028040_NUM_SAMPLES(util_logbase2(iview->image->info.samples));
|
|
|
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7) {
|
2017-06-05 02:01:10 +01:00
|
|
|
|
struct radeon_info *info = &device->physical_device->rad_info;
|
2018-07-16 20:51:26 +02:00
|
|
|
|
unsigned tiling_index = surf->u.legacy.tiling_index[level];
|
|
|
|
|
|
unsigned stencil_index = surf->u.legacy.stencil_tiling_index[level];
|
|
|
|
|
|
unsigned macro_index = surf->u.legacy.macro_tile_index;
|
2017-06-05 02:01:10 +01:00
|
|
|
|
unsigned tile_mode = info->si_tile_mode_array[tiling_index];
|
|
|
|
|
|
unsigned stencil_tile_mode = info->si_tile_mode_array[stencil_index];
|
|
|
|
|
|
unsigned macro_mode = info->cik_macrotile_mode_array[macro_index];
|
|
|
|
|
|
|
|
|
|
|
|
if (stencil_only)
|
|
|
|
|
|
tile_mode = stencil_tile_mode;
|
|
|
|
|
|
|
|
|
|
|
|
ds->db_depth_info |=
|
|
|
|
|
|
S_02803C_ARRAY_MODE(G_009910_ARRAY_MODE(tile_mode)) |
|
|
|
|
|
|
S_02803C_PIPE_CONFIG(G_009910_PIPE_CONFIG(tile_mode)) |
|
|
|
|
|
|
S_02803C_BANK_WIDTH(G_009990_BANK_WIDTH(macro_mode)) |
|
|
|
|
|
|
S_02803C_BANK_HEIGHT(G_009990_BANK_HEIGHT(macro_mode)) |
|
|
|
|
|
|
S_02803C_MACRO_TILE_ASPECT(G_009990_MACRO_TILE_ASPECT(macro_mode)) |
|
|
|
|
|
|
S_02803C_NUM_BANKS(G_009990_NUM_BANKS(macro_mode));
|
|
|
|
|
|
ds->db_z_info |= S_028040_TILE_SPLIT(G_009910_TILE_SPLIT(tile_mode));
|
|
|
|
|
|
ds->db_stencil_info |= S_028044_TILE_SPLIT(G_009910_TILE_SPLIT(stencil_tile_mode));
|
|
|
|
|
|
} else {
|
2018-07-16 20:51:26 +02:00
|
|
|
|
unsigned tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, false);
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index);
|
2018-07-16 20:51:26 +02:00
|
|
|
|
tile_mode_index = si_tile_mode_index(&iview->image->planes[0], level, true);
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_stencil_info |= S_028044_TILE_MODE_INDEX(tile_mode_index);
|
2017-07-27 04:51:48 +01:00
|
|
|
|
if (stencil_only)
|
|
|
|
|
|
ds->db_z_info |= S_028040_TILE_MODE_INDEX(tile_mode_index);
|
2017-06-05 02:01:10 +01:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_depth_size = S_028058_PITCH_TILE_MAX((level_info->nblk_x / 8) - 1) |
|
|
|
|
|
|
S_028058_HEIGHT_TILE_MAX((level_info->nblk_y / 8) - 1);
|
|
|
|
|
|
ds->db_depth_slice = S_02805C_SLICE_TILE_MAX((level_info->nblk_x * level_info->nblk_y) / 64 - 1);
|
2017-05-09 00:44:57 +02:00
|
|
|
|
|
2017-10-03 10:48:42 +02:00
|
|
|
|
if (radv_htile_enabled(iview->image, level)) {
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_z_info |= S_028040_TILE_SURFACE_ENABLE(1);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-12-09 17:48:56 +01:00
|
|
|
|
if (radv_image_tile_stencil_disabled(device, iview->image)) {
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_stencil_info |= S_028044_TILE_STENCIL_DISABLE(1);
|
2020-12-09 17:48:56 +01:00
|
|
|
|
}
|
2017-06-05 02:01:10 +01:00
|
|
|
|
|
2017-09-17 12:15:02 +02:00
|
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset +
|
2020-05-24 13:47:20 +02:00
|
|
|
|
surf->htile_offset;
|
2017-06-05 02:01:10 +01:00
|
|
|
|
ds->db_htile_data_base = va >> 8;
|
|
|
|
|
|
ds->db_htile_surface = S_028ABC_FULL_CACHE(1);
|
2017-05-09 08:26:07 +02:00
|
|
|
|
|
2018-04-06 16:17:26 +02:00
|
|
|
|
if (radv_image_is_tc_compat_htile(iview->image)) {
|
2018-03-21 21:30:41 +01:00
|
|
|
|
unsigned max_zplanes =
|
|
|
|
|
|
radv_calc_decompress_on_z_planes(device, iview);
|
2017-05-09 08:26:07 +02:00
|
|
|
|
|
2018-03-21 21:30:41 +01:00
|
|
|
|
ds->db_htile_surface |= S_028ABC_TC_COMPATIBLE(1);
|
|
|
|
|
|
ds->db_z_info |= S_028040_DECOMPRESS_ON_N_ZPLANES(max_zplanes);
|
2017-05-09 08:26:07 +02:00
|
|
|
|
}
|
2017-06-05 02:01:10 +01:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ds->db_z_read_base = ds->db_z_write_base = z_offs >> 8;
|
|
|
|
|
|
ds->db_stencil_read_base = ds->db_stencil_write_base = s_offs >> 8;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_CreateFramebuffer(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkFramebufferCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkFramebuffer* pFramebuffer)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
struct radv_framebuffer *framebuffer;
|
2019-10-15 10:15:04 +02:00
|
|
|
|
const VkFramebufferAttachmentsCreateInfo *imageless_create_info =
|
2019-08-02 14:42:50 +02:00
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
2019-10-15 10:15:04 +02:00
|
|
|
|
FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
|
|
|
|
|
|
|
2019-08-02 14:42:50 +02:00
|
|
|
|
size_t size = sizeof(*framebuffer);
|
|
|
|
|
|
if (!imageless_create_info)
|
|
|
|
|
|
size += sizeof(struct radv_image_view*) * pCreateInfo->attachmentCount;
|
2020-04-29 10:16:32 +02:00
|
|
|
|
framebuffer = vk_alloc2(&device->vk.alloc, pAllocator, size, 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
if (framebuffer == NULL)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &framebuffer->base,
|
|
|
|
|
|
VK_OBJECT_TYPE_FRAMEBUFFER);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
framebuffer->attachment_count = pCreateInfo->attachmentCount;
|
2017-02-19 01:16:19 +01:00
|
|
|
|
framebuffer->width = pCreateInfo->width;
|
|
|
|
|
|
framebuffer->height = pCreateInfo->height;
|
|
|
|
|
|
framebuffer->layers = pCreateInfo->layers;
|
2021-01-18 11:19:20 +01:00
|
|
|
|
framebuffer->imageless = !!imageless_create_info;
|
|
|
|
|
|
|
2019-08-02 14:42:50 +02:00
|
|
|
|
if (imageless_create_info) {
|
|
|
|
|
|
for (unsigned i = 0; i < imageless_create_info->attachmentImageInfoCount; ++i) {
|
2019-10-15 10:15:04 +02:00
|
|
|
|
const VkFramebufferAttachmentImageInfo *attachment =
|
2019-08-02 14:42:50 +02:00
|
|
|
|
imageless_create_info->pAttachmentImageInfos + i;
|
|
|
|
|
|
framebuffer->width = MIN2(framebuffer->width, attachment->width);
|
|
|
|
|
|
framebuffer->height = MIN2(framebuffer->height, attachment->height);
|
|
|
|
|
|
framebuffer->layers = MIN2(framebuffer->layers, attachment->layerCount);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
|
|
|
|
|
|
VkImageView _iview = pCreateInfo->pAttachments[i];
|
|
|
|
|
|
struct radv_image_view *iview = radv_image_view_from_handle(_iview);
|
|
|
|
|
|
framebuffer->attachments[i] = iview;
|
|
|
|
|
|
framebuffer->width = MIN2(framebuffer->width, iview->extent.width);
|
|
|
|
|
|
framebuffer->height = MIN2(framebuffer->height, iview->extent.height);
|
|
|
|
|
|
framebuffer->layers = MIN2(framebuffer->layers, radv_surface_max_layer_count(iview));
|
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*pFramebuffer = radv_framebuffer_to_handle(framebuffer);
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyFramebuffer(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkFramebuffer _fb,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_framebuffer, fb, _fb);
|
|
|
|
|
|
|
|
|
|
|
|
if (!fb)
|
|
|
|
|
|
return;
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_finish(&fb->base);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, fb);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned radv_tex_wrap(VkSamplerAddressMode address_mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (address_mode) {
|
|
|
|
|
|
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
|
|
|
|
|
|
return V_008F30_SQ_TEX_WRAP;
|
|
|
|
|
|
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
|
|
|
|
|
|
return V_008F30_SQ_TEX_MIRROR;
|
|
|
|
|
|
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
|
|
|
|
|
|
return V_008F30_SQ_TEX_CLAMP_LAST_TEXEL;
|
|
|
|
|
|
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
|
|
|
|
|
|
return V_008F30_SQ_TEX_CLAMP_BORDER;
|
|
|
|
|
|
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
|
|
|
|
|
|
return V_008F30_SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("illegal tex wrap mode");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_tex_compare(VkCompareOp op)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (op) {
|
|
|
|
|
|
case VK_COMPARE_OP_NEVER:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER;
|
|
|
|
|
|
case VK_COMPARE_OP_LESS:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_LESS;
|
|
|
|
|
|
case VK_COMPARE_OP_EQUAL:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_EQUAL;
|
|
|
|
|
|
case VK_COMPARE_OP_LESS_OR_EQUAL:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
|
|
|
|
|
|
case VK_COMPARE_OP_GREATER:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_GREATER;
|
|
|
|
|
|
case VK_COMPARE_OP_NOT_EQUAL:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
|
|
|
|
|
|
case VK_COMPARE_OP_GREATER_OR_EQUAL:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
|
|
|
|
|
|
case VK_COMPARE_OP_ALWAYS:
|
|
|
|
|
|
return V_008F30_SQ_TEX_DEPTH_COMPARE_ALWAYS;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("illegal compare mode");
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_tex_filter(VkFilter filter, unsigned max_ansio)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (filter) {
|
|
|
|
|
|
case VK_FILTER_NEAREST:
|
|
|
|
|
|
return (max_ansio > 1 ? V_008F38_SQ_TEX_XY_FILTER_ANISO_POINT :
|
|
|
|
|
|
V_008F38_SQ_TEX_XY_FILTER_POINT);
|
|
|
|
|
|
case VK_FILTER_LINEAR:
|
|
|
|
|
|
return (max_ansio > 1 ? V_008F38_SQ_TEX_XY_FILTER_ANISO_BILINEAR :
|
|
|
|
|
|
V_008F38_SQ_TEX_XY_FILTER_BILINEAR);
|
|
|
|
|
|
case VK_FILTER_CUBIC_IMG:
|
|
|
|
|
|
default:
|
|
|
|
|
|
fprintf(stderr, "illegal texture filter");
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_tex_mipfilter(VkSamplerMipmapMode mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (mode) {
|
|
|
|
|
|
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
|
|
|
|
|
|
return V_008F38_SQ_TEX_Z_FILTER_POINT;
|
|
|
|
|
|
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
|
|
|
|
|
|
return V_008F38_SQ_TEX_Z_FILTER_LINEAR;
|
|
|
|
|
|
default:
|
|
|
|
|
|
return V_008F38_SQ_TEX_Z_FILTER_NONE;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_tex_bordercolor(VkBorderColor bcolor)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (bcolor) {
|
|
|
|
|
|
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
|
|
|
|
|
|
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
|
|
|
|
|
|
return V_008F3C_SQ_TEX_BORDER_COLOR_TRANS_BLACK;
|
|
|
|
|
|
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
|
|
|
|
|
|
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
|
|
|
|
|
|
return V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_BLACK;
|
|
|
|
|
|
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
|
|
|
|
|
|
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
|
|
|
|
|
|
return V_008F3C_SQ_TEX_BORDER_COLOR_OPAQUE_WHITE;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
case VK_BORDER_COLOR_FLOAT_CUSTOM_EXT:
|
|
|
|
|
|
case VK_BORDER_COLOR_INT_CUSTOM_EXT:
|
|
|
|
|
|
return V_008F3C_SQ_TEX_BORDER_COLOR_REGISTER;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-27 03:02:14 +02:00
|
|
|
|
static unsigned
|
|
|
|
|
|
radv_tex_aniso_filter(unsigned filter)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (filter < 2)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
if (filter < 4)
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
if (filter < 8)
|
|
|
|
|
|
return 2;
|
|
|
|
|
|
if (filter < 16)
|
|
|
|
|
|
return 3;
|
|
|
|
|
|
return 4;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-03-25 20:05:42 +02:00
|
|
|
|
static unsigned
|
2019-10-15 08:58:55 +02:00
|
|
|
|
radv_tex_filter_mode(VkSamplerReductionMode mode)
|
2018-03-25 20:05:42 +02:00
|
|
|
|
{
|
|
|
|
|
|
switch (mode) {
|
|
|
|
|
|
case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT:
|
2018-11-19 18:23:40 +01:00
|
|
|
|
return V_008F30_SQ_IMG_FILTER_MODE_BLEND;
|
2018-03-25 20:05:42 +02:00
|
|
|
|
case VK_SAMPLER_REDUCTION_MODE_MIN_EXT:
|
2018-11-19 18:23:40 +01:00
|
|
|
|
return V_008F30_SQ_IMG_FILTER_MODE_MIN;
|
2018-03-25 20:05:42 +02:00
|
|
|
|
case VK_SAMPLER_REDUCTION_MODE_MAX_EXT:
|
2018-11-19 18:23:40 +01:00
|
|
|
|
return V_008F30_SQ_IMG_FILTER_MODE_MAX;
|
2018-03-25 20:05:42 +02:00
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-17 22:23:19 +02:00
|
|
|
|
static uint32_t
|
|
|
|
|
|
radv_get_max_anisotropy(struct radv_device *device,
|
|
|
|
|
|
const VkSamplerCreateInfo *pCreateInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (device->force_aniso >= 0)
|
|
|
|
|
|
return device->force_aniso;
|
|
|
|
|
|
|
|
|
|
|
|
if (pCreateInfo->anisotropyEnable &&
|
|
|
|
|
|
pCreateInfo->maxAnisotropy > 1.0f)
|
|
|
|
|
|
return (uint32_t)pCreateInfo->maxAnisotropy;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-03-25 21:30:55 -04:00
|
|
|
|
static inline int S_FIXED(float value, unsigned frac_bits)
|
|
|
|
|
|
{
|
|
|
|
|
|
return value * (1 << frac_bits);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
static uint32_t radv_register_border_color(struct radv_device *device,
|
|
|
|
|
|
VkClearColorValue value)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t slot;
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&device->border_color_data.mutex);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
|
|
|
|
|
|
for (slot = 0; slot < RADV_BORDER_COLOR_COUNT; slot++) {
|
|
|
|
|
|
if (!device->border_color_data.used[slot]) {
|
|
|
|
|
|
/* Copy to the GPU wrt endian-ness. */
|
|
|
|
|
|
util_memcpy_cpu_to_le32(&device->border_color_data.colors_gpu_ptr[slot],
|
|
|
|
|
|
&value,
|
|
|
|
|
|
sizeof(VkClearColorValue));
|
|
|
|
|
|
|
|
|
|
|
|
device->border_color_data.used[slot] = true;
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&device->border_color_data.mutex);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
|
|
|
|
|
|
return slot;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void radv_unregister_border_color(struct radv_device *device,
|
|
|
|
|
|
uint32_t slot)
|
|
|
|
|
|
{
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_lock(&device->border_color_data.mutex);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
|
|
|
|
|
|
device->border_color_data.used[slot] = false;
|
|
|
|
|
|
|
2020-11-26 19:30:47 -08:00
|
|
|
|
mtx_unlock(&device->border_color_data.mutex);
|
2020-04-07 06:11:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
static void
|
|
|
|
|
|
radv_init_sampler(struct radv_device *device,
|
|
|
|
|
|
struct radv_sampler *sampler,
|
|
|
|
|
|
const VkSamplerCreateInfo *pCreateInfo)
|
|
|
|
|
|
{
|
2018-09-17 22:23:19 +02:00
|
|
|
|
uint32_t max_aniso = radv_get_max_anisotropy(device, pCreateInfo);
|
2016-10-27 03:02:14 +02:00
|
|
|
|
uint32_t max_aniso_ratio = radv_tex_aniso_filter(max_aniso);
|
2019-06-25 12:32:01 +02:00
|
|
|
|
bool compat_mode = device->physical_device->rad_info.chip_class == GFX8 ||
|
|
|
|
|
|
device->physical_device->rad_info.chip_class == GFX9;
|
2018-11-19 18:23:40 +01:00
|
|
|
|
unsigned filter_mode = V_008F30_SQ_IMG_FILTER_MODE_BLEND;
|
2020-01-14 18:03:29 +01:00
|
|
|
|
unsigned depth_compare_func = V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER;
|
2020-02-25 19:24:15 +00:00
|
|
|
|
bool trunc_coord = pCreateInfo->minFilter == VK_FILTER_NEAREST && pCreateInfo->magFilter == VK_FILTER_NEAREST;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
bool uses_border_color = pCreateInfo->addressModeU == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
|
|
|
|
|
|
pCreateInfo->addressModeV == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER ||
|
|
|
|
|
|
pCreateInfo->addressModeW == VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
|
|
|
|
|
VkBorderColor border_color = uses_border_color ? pCreateInfo->borderColor : VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
|
|
|
|
|
uint32_t border_color_ptr;
|
2018-03-25 20:05:42 +02:00
|
|
|
|
|
2019-10-15 08:58:55 +02:00
|
|
|
|
const struct VkSamplerReductionModeCreateInfo *sampler_reduction =
|
2018-03-25 20:05:42 +02:00
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
2019-10-15 08:58:55 +02:00
|
|
|
|
SAMPLER_REDUCTION_MODE_CREATE_INFO);
|
2018-03-25 20:05:42 +02:00
|
|
|
|
if (sampler_reduction)
|
|
|
|
|
|
filter_mode = radv_tex_filter_mode(sampler_reduction->reductionMode);
|
2016-10-27 03:02:14 +02:00
|
|
|
|
|
2020-01-14 18:03:29 +01:00
|
|
|
|
if (pCreateInfo->compareEnable)
|
|
|
|
|
|
depth_compare_func = radv_tex_compare(pCreateInfo->compareOp);
|
|
|
|
|
|
|
2020-04-07 06:11:24 +01:00
|
|
|
|
sampler->border_color_slot = RADV_BORDER_COLOR_COUNT;
|
|
|
|
|
|
|
|
|
|
|
|
if (border_color == VK_BORDER_COLOR_FLOAT_CUSTOM_EXT || border_color == VK_BORDER_COLOR_INT_CUSTOM_EXT) {
|
|
|
|
|
|
const VkSamplerCustomBorderColorCreateInfoEXT *custom_border_color =
|
|
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
|
|
|
|
|
SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT);
|
|
|
|
|
|
|
|
|
|
|
|
assert(custom_border_color);
|
|
|
|
|
|
|
|
|
|
|
|
sampler->border_color_slot =
|
|
|
|
|
|
radv_register_border_color(device, custom_border_color->customBorderColor);
|
|
|
|
|
|
|
|
|
|
|
|
/* Did we fail to find a slot? */
|
|
|
|
|
|
if (sampler->border_color_slot == RADV_BORDER_COLOR_COUNT) {
|
|
|
|
|
|
fprintf(stderr, "WARNING: no free border color slots, defaulting to TRANS_BLACK.\n");
|
|
|
|
|
|
border_color = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If we don't have a custom color, set the ptr to 0 */
|
|
|
|
|
|
border_color_ptr = sampler->border_color_slot != RADV_BORDER_COLOR_COUNT
|
|
|
|
|
|
? sampler->border_color_slot
|
|
|
|
|
|
: 0;
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
sampler->state[0] = (S_008F30_CLAMP_X(radv_tex_wrap(pCreateInfo->addressModeU)) |
|
|
|
|
|
|
S_008F30_CLAMP_Y(radv_tex_wrap(pCreateInfo->addressModeV)) |
|
|
|
|
|
|
S_008F30_CLAMP_Z(radv_tex_wrap(pCreateInfo->addressModeW)) |
|
|
|
|
|
|
S_008F30_MAX_ANISO_RATIO(max_aniso_ratio) |
|
2020-01-14 18:03:29 +01:00
|
|
|
|
S_008F30_DEPTH_COMPARE_FUNC(depth_compare_func) |
|
2016-10-07 09:16:09 +10:00
|
|
|
|
S_008F30_FORCE_UNNORMALIZED(pCreateInfo->unnormalizedCoordinates ? 1 : 0) |
|
2016-10-27 03:02:14 +02:00
|
|
|
|
S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) |
|
|
|
|
|
|
S_008F30_ANISO_BIAS(max_aniso_ratio) |
|
2016-10-07 09:16:09 +10:00
|
|
|
|
S_008F30_DISABLE_CUBE_WRAP(0) |
|
2019-06-25 12:32:01 +02:00
|
|
|
|
S_008F30_COMPAT_MODE(compat_mode) |
|
2020-02-25 19:24:15 +00:00
|
|
|
|
S_008F30_FILTER_MODE(filter_mode) |
|
|
|
|
|
|
S_008F30_TRUNC_COORD(trunc_coord));
|
2016-10-07 09:16:09 +10:00
|
|
|
|
sampler->state[1] = (S_008F34_MIN_LOD(S_FIXED(CLAMP(pCreateInfo->minLod, 0, 15), 8)) |
|
2016-10-27 03:02:14 +02:00
|
|
|
|
S_008F34_MAX_LOD(S_FIXED(CLAMP(pCreateInfo->maxLod, 0, 15), 8)) |
|
|
|
|
|
|
S_008F34_PERF_MIP(max_aniso_ratio ? max_aniso_ratio + 6 : 0));
|
2016-10-07 09:16:09 +10:00
|
|
|
|
sampler->state[2] = (S_008F38_LOD_BIAS(S_FIXED(CLAMP(pCreateInfo->mipLodBias, -16, 16), 8)) |
|
|
|
|
|
|
S_008F38_XY_MAG_FILTER(radv_tex_filter(pCreateInfo->magFilter, max_aniso)) |
|
|
|
|
|
|
S_008F38_XY_MIN_FILTER(radv_tex_filter(pCreateInfo->minFilter, max_aniso)) |
|
|
|
|
|
|
S_008F38_MIP_FILTER(radv_tex_mipfilter(pCreateInfo->mipmapMode)) |
|
2019-06-25 12:32:01 +02:00
|
|
|
|
S_008F38_MIP_POINT_PRECLAMP(0));
|
2020-04-07 06:11:24 +01:00
|
|
|
|
sampler->state[3] = (S_008F3C_BORDER_COLOR_PTR(border_color_ptr) |
|
|
|
|
|
|
S_008F3C_BORDER_COLOR_TYPE(radv_tex_bordercolor(border_color)));
|
2019-06-25 12:32:01 +02:00
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX10) {
|
|
|
|
|
|
sampler->state[2] |= S_008F38_ANISO_OVERRIDE_GFX10(1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
sampler->state[2] |=
|
|
|
|
|
|
S_008F38_DISABLE_LSB_CEIL(device->physical_device->rad_info.chip_class <= GFX8) |
|
|
|
|
|
|
S_008F38_FILTER_PREC_FIX(1) |
|
2020-08-21 08:09:58 -04:00
|
|
|
|
S_008F38_ANISO_OVERRIDE_GFX8(device->physical_device->rad_info.chip_class >= GFX8);
|
2019-06-25 12:32:01 +02:00
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_CreateSampler(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkSamplerCreateInfo* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkSampler* pSampler)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
struct radv_sampler *sampler;
|
|
|
|
|
|
|
2018-12-02 23:58:58 +01:00
|
|
|
|
const struct VkSamplerYcbcrConversionInfo *ycbcr_conversion =
|
|
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
|
|
|
|
|
SAMPLER_YCBCR_CONVERSION_INFO);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
|
|
|
|
|
|
|
2020-04-29 10:16:32 +02:00
|
|
|
|
sampler = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*sampler), 8,
|
2016-10-07 09:16:09 +10:00
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
if (!sampler)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_init(&device->vk, &sampler->base,
|
|
|
|
|
|
VK_OBJECT_TYPE_SAMPLER);
|
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
|
radv_init_sampler(device, sampler, pCreateInfo);
|
2018-12-02 23:58:58 +01:00
|
|
|
|
|
|
|
|
|
|
sampler->ycbcr_sampler = ycbcr_conversion ? radv_sampler_ycbcr_conversion_from_handle(ycbcr_conversion->conversion): NULL;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
*pSampler = radv_sampler_to_handle(sampler);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroySampler(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkSampler _sampler,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_sampler, sampler, _sampler);
|
|
|
|
|
|
|
|
|
|
|
|
if (!sampler)
|
|
|
|
|
|
return;
|
2020-04-07 06:11:24 +01:00
|
|
|
|
|
|
|
|
|
|
if (sampler->border_color_slot != RADV_BORDER_COLOR_COUNT)
|
|
|
|
|
|
radv_unregister_border_color(device, sampler->border_color_slot);
|
|
|
|
|
|
|
2020-04-29 14:57:20 +02:00
|
|
|
|
vk_object_base_finish(&sampler->base);
|
2020-04-29 10:16:32 +02:00
|
|
|
|
vk_free2(&device->vk.alloc, pAllocator, sampler);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
}
|
2017-01-13 08:55:59 +01:00
|
|
|
|
|
|
|
|
|
|
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-01-05 13:46:53 +01:00
|
|
|
|
*pSupportedVersion = MIN2(*pSupportedVersion, 4u);
|
2017-01-13 08:55:59 +01:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
2017-07-15 02:08:01 +02:00
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetMemoryFdKHR(VkDevice _device,
|
|
|
|
|
|
const VkMemoryGetFdInfoKHR *pGetFdInfo,
|
|
|
|
|
|
int *pFD)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device_memory, memory, pGetFdInfo->memory);
|
|
|
|
|
|
|
|
|
|
|
|
assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
|
|
|
|
|
|
|
2017-11-27 18:43:43 -08:00
|
|
|
|
/* At the moment, we support only the below handle types. */
|
2017-07-15 02:08:01 +02:00
|
|
|
|
assert(pGetFdInfo->handleType ==
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2017-11-27 18:43:43 -08:00
|
|
|
|
pGetFdInfo->handleType ==
|
|
|
|
|
|
VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
|
2017-07-15 02:08:01 +02:00
|
|
|
|
|
|
|
|
|
|
bool ret = radv_get_memory_fd(device, memory, pFD);
|
|
|
|
|
|
if (ret == false)
|
2018-05-31 01:06:41 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
2017-07-15 02:08:01 +02:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-26 01:52:44 +02:00
|
|
|
|
static uint32_t radv_compute_valid_memory_types_attempt(struct radv_physical_device *dev,
|
|
|
|
|
|
enum radeon_bo_domain domains,
|
|
|
|
|
|
enum radeon_bo_flag flags,
|
|
|
|
|
|
enum radeon_bo_flag ignore_flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* Don't count GTT/CPU as relevant:
|
2020-10-07 10:59:36 +01:00
|
|
|
|
*
|
2020-04-26 01:52:44 +02:00
|
|
|
|
* - We're not fully consistent between the two.
|
|
|
|
|
|
* - Sometimes VRAM gets VRAM|GTT.
|
|
|
|
|
|
*/
|
2020-10-07 10:59:36 +01:00
|
|
|
|
const enum radeon_bo_domain relevant_domains = RADEON_DOMAIN_VRAM |
|
2020-04-26 01:52:44 +02:00
|
|
|
|
RADEON_DOMAIN_GDS |
|
|
|
|
|
|
RADEON_DOMAIN_OA;
|
|
|
|
|
|
uint32_t bits = 0;
|
|
|
|
|
|
for (unsigned i = 0; i < dev->memory_properties.memoryTypeCount; ++i) {
|
|
|
|
|
|
if ((domains & relevant_domains) != (dev->memory_domains[i] & relevant_domains))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if ((flags & ~ignore_flags) != (dev->memory_flags[i] & ~ignore_flags))
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
bits |= 1u << i;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bits;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static uint32_t radv_compute_valid_memory_types(struct radv_physical_device *dev,
|
|
|
|
|
|
enum radeon_bo_domain domains,
|
|
|
|
|
|
enum radeon_bo_flag flags)
|
|
|
|
|
|
{
|
|
|
|
|
|
enum radeon_bo_flag ignore_flags = ~(RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_GTT_WC);
|
|
|
|
|
|
uint32_t bits = radv_compute_valid_memory_types_attempt(dev, domains, flags, ignore_flags);
|
|
|
|
|
|
|
|
|
|
|
|
if (!bits) {
|
|
|
|
|
|
ignore_flags |= RADEON_FLAG_NO_CPU_ACCESS;
|
|
|
|
|
|
bits = radv_compute_valid_memory_types_attempt(dev, domains, flags, ignore_flags);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return bits;
|
|
|
|
|
|
}
|
2017-07-15 02:08:01 +02:00
|
|
|
|
VkResult radv_GetMemoryFdPropertiesKHR(VkDevice _device,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
VkExternalMemoryHandleTypeFlagBits handleType,
|
2017-07-15 02:08:01 +02:00
|
|
|
|
int fd,
|
|
|
|
|
|
VkMemoryFdPropertiesKHR *pMemoryFdProperties)
|
|
|
|
|
|
{
|
2020-04-26 01:52:44 +02:00
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
|
|
|
|
|
|
switch (handleType) {
|
|
|
|
|
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: {
|
|
|
|
|
|
enum radeon_bo_domain domains;
|
|
|
|
|
|
enum radeon_bo_flag flags;
|
|
|
|
|
|
if (!device->ws->buffer_get_flags_from_fd(device->ws, fd, &domains, &flags))
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
|
|
|
|
|
|
|
|
|
|
|
pMemoryFdProperties->memoryTypeBits = radv_compute_valid_memory_types(device->physical_device, domains, flags);
|
|
|
|
|
|
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.
|
|
|
|
|
|
*/
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
|
|
|
|
|
}
|
2017-07-15 02:08:01 +02:00
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2017-12-18 21:02:05 +01:00
|
|
|
|
static VkResult radv_import_opaque_fd(struct radv_device *device,
|
|
|
|
|
|
int fd,
|
|
|
|
|
|
uint32_t *syncobj)
|
|
|
|
|
|
{
|
|
|
|
|
|
uint32_t syncobj_handle = 0;
|
|
|
|
|
|
int ret = device->ws->import_syncobj(device->ws, fd, &syncobj_handle);
|
|
|
|
|
|
if (ret != 0)
|
2019-01-08 14:30:32 +01:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
|
|
|
|
|
|
if (*syncobj)
|
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, *syncobj);
|
|
|
|
|
|
|
|
|
|
|
|
*syncobj = syncobj_handle;
|
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VkResult radv_import_sync_fd(struct radv_device *device,
|
|
|
|
|
|
int fd,
|
|
|
|
|
|
uint32_t *syncobj)
|
|
|
|
|
|
{
|
|
|
|
|
|
/* If we create a syncobj we do it locally so that if we have an error, we don't
|
|
|
|
|
|
* leave a syncobj in an undetermined state in the fence. */
|
|
|
|
|
|
uint32_t syncobj_handle = *syncobj;
|
|
|
|
|
|
if (!syncobj_handle) {
|
2020-07-14 21:23:17 +02:00
|
|
|
|
bool create_signaled = fd == -1 ? true : false;
|
|
|
|
|
|
|
|
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, create_signaled,
|
|
|
|
|
|
&syncobj_handle);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
if (ret) {
|
2020-07-14 23:15:55 +02:00
|
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
}
|
2020-07-14 21:23:17 +02:00
|
|
|
|
} else {
|
|
|
|
|
|
if (fd == -1)
|
2020-07-16 02:43:32 +02:00
|
|
|
|
device->ws->signal_syncobj(device->ws, syncobj_handle, 0);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-14 21:23:17 +02:00
|
|
|
|
if (fd != -1) {
|
2017-12-18 21:02:05 +01:00
|
|
|
|
int ret = device->ws->import_syncobj_from_sync_file(device->ws, syncobj_handle, fd);
|
2020-07-14 21:23:17 +02:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
|
|
|
|
|
close(fd);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*syncobj = syncobj_handle;
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
|
VkResult radv_ImportSemaphoreFdKHR(VkDevice _device,
|
|
|
|
|
|
const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, pImportSemaphoreFdInfo->semaphore);
|
2019-10-20 22:50:58 +02:00
|
|
|
|
VkResult result;
|
|
|
|
|
|
struct radv_semaphore_part *dst = NULL;
|
2020-07-16 02:44:22 +02:00
|
|
|
|
bool timeline = sem->permanent.kind == RADV_SEMAPHORE_TIMELINE_SYNCOBJ;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
2019-01-08 14:30:32 +01:00
|
|
|
|
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) {
|
2020-07-16 02:44:22 +02:00
|
|
|
|
assert(!timeline);
|
2019-10-20 22:50:58 +02:00
|
|
|
|
dst = &sem->temporary;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
} else {
|
2019-10-20 22:50:58 +02:00
|
|
|
|
dst = &sem->permanent;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
2017-11-13 23:18:19 +01:00
|
|
|
|
|
2020-07-16 02:44:22 +02:00
|
|
|
|
uint32_t syncobj = (dst->kind == RADV_SEMAPHORE_SYNCOBJ ||
|
|
|
|
|
|
dst->kind == RADV_SEMAPHORE_TIMELINE_SYNCOBJ) ? dst->syncobj : 0;
|
2019-10-20 22:50:58 +02:00
|
|
|
|
|
2017-12-18 21:02:05 +01:00
|
|
|
|
switch(pImportSemaphoreFdInfo->handleType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
|
2019-10-20 22:50:58 +02:00
|
|
|
|
result = radv_import_opaque_fd(device, pImportSemaphoreFdInfo->fd, &syncobj);
|
|
|
|
|
|
break;
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
|
2020-07-16 02:44:22 +02:00
|
|
|
|
assert(!timeline);
|
2019-10-20 22:50:58 +02:00
|
|
|
|
result = radv_import_sync_fd(device, pImportSemaphoreFdInfo->fd, &syncobj);
|
|
|
|
|
|
break;
|
2017-12-18 21:02:05 +01:00
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Unhandled semaphore handle type");
|
|
|
|
|
|
}
|
2019-10-20 22:50:58 +02:00
|
|
|
|
|
|
|
|
|
|
if (result == VK_SUCCESS) {
|
|
|
|
|
|
dst->syncobj = syncobj;
|
|
|
|
|
|
dst->kind = RADV_SEMAPHORE_SYNCOBJ;
|
2020-07-16 02:44:22 +02:00
|
|
|
|
if (timeline) {
|
|
|
|
|
|
dst->kind = RADV_SEMAPHORE_TIMELINE_SYNCOBJ;
|
|
|
|
|
|
dst->timeline_syncobj.max_point = 0;
|
|
|
|
|
|
}
|
2019-10-20 22:50:58 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetSemaphoreFdKHR(VkDevice _device,
|
|
|
|
|
|
const VkSemaphoreGetFdInfoKHR *pGetFdInfo,
|
|
|
|
|
|
int *pFd)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, pGetFdInfo->semaphore);
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
uint32_t syncobj_handle;
|
|
|
|
|
|
|
2019-10-20 22:50:58 +02:00
|
|
|
|
if (sem->temporary.kind != RADV_SEMAPHORE_NONE) {
|
2020-07-16 02:44:22 +02:00
|
|
|
|
assert(sem->temporary.kind == RADV_SEMAPHORE_SYNCOBJ ||
|
|
|
|
|
|
sem->temporary.kind == RADV_SEMAPHORE_TIMELINE_SYNCOBJ);
|
2019-10-20 22:50:58 +02:00
|
|
|
|
syncobj_handle = sem->temporary.syncobj;
|
|
|
|
|
|
} else {
|
2020-07-16 02:44:22 +02:00
|
|
|
|
assert(sem->permanent.kind == RADV_SEMAPHORE_SYNCOBJ ||
|
|
|
|
|
|
sem->permanent.kind == RADV_SEMAPHORE_TIMELINE_SYNCOBJ);
|
2019-10-20 22:50:58 +02:00
|
|
|
|
syncobj_handle = sem->permanent.syncobj;
|
|
|
|
|
|
}
|
2017-12-18 21:02:05 +01:00
|
|
|
|
|
|
|
|
|
|
switch(pGetFdInfo->handleType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT:
|
2017-12-18 21:02:05 +01:00
|
|
|
|
ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd);
|
2020-07-14 22:59:58 +02:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_TOO_MANY_OBJECTS);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
break;
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
|
2017-12-18 21:02:05 +01:00
|
|
|
|
ret = device->ws->export_syncobj_to_sync_file(device->ws, syncobj_handle, pFd);
|
2020-07-14 22:59:58 +02:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_TOO_MANY_OBJECTS);
|
|
|
|
|
|
|
|
|
|
|
|
if (sem->temporary.kind != RADV_SEMAPHORE_NONE) {
|
|
|
|
|
|
radv_destroy_semaphore_part(device, &sem->temporary);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
device->ws->reset_syncobj(device->ws, syncobj_handle);
|
2018-01-04 02:55:39 +01:00
|
|
|
|
}
|
2017-12-18 21:02:05 +01:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Unhandled semaphore handle type");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceExternalSemaphoreProperties(
|
2017-02-27 19:14:00 +00:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkPhysicalDeviceExternalSemaphoreInfo *pExternalSemaphoreInfo,
|
|
|
|
|
|
VkExternalSemaphoreProperties *pExternalSemaphoreProperties)
|
2017-02-27 19:14:00 +00:00
|
|
|
|
{
|
2017-12-18 21:09:19 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
2019-10-22 10:18:06 +02:00
|
|
|
|
VkSemaphoreTypeKHR type = radv_get_semaphore_type(pExternalSemaphoreInfo->pNext, NULL);
|
2020-10-07 10:59:36 +01:00
|
|
|
|
|
2020-07-16 02:44:22 +02:00
|
|
|
|
if (type == VK_SEMAPHORE_TYPE_TIMELINE && pdevice->rad_info.has_timeline_syncobj &&
|
|
|
|
|
|
pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
|
|
|
|
|
|
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
|
|
|
|
|
|
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
|
|
|
|
|
|
} else if (type == VK_SEMAPHORE_TYPE_TIMELINE) {
|
2019-10-22 10:18:06 +02:00
|
|
|
|
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
|
|
|
|
|
|
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
|
|
|
|
|
|
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
|
2017-12-18 21:09:19 +01:00
|
|
|
|
|
2017-12-28 15:59:19 +01:00
|
|
|
|
/* Require has_syncobj_wait_for_submit for the syncobj signal ioctl introduced at virtually the same time */
|
2019-10-22 10:18:06 +02:00
|
|
|
|
} else if (pdevice->rad_info.has_syncobj_wait_for_submit &&
|
2020-10-07 10:59:36 +01:00
|
|
|
|
(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2019-10-22 10:18:06 +02:00
|
|
|
|
pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
|
|
|
|
|
|
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
|
|
|
|
|
|
} else if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT) {
|
|
|
|
|
|
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
|
|
|
|
|
|
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT |
|
|
|
|
|
|
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
|
2017-07-25 10:19:21 +10:00
|
|
|
|
} else {
|
|
|
|
|
|
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
|
|
|
|
|
|
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
|
|
|
|
|
|
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
|
|
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
}
|
2017-11-28 00:21:12 +01:00
|
|
|
|
|
|
|
|
|
|
VkResult radv_ImportFenceFdKHR(VkDevice _device,
|
|
|
|
|
|
const VkImportFenceFdInfoKHR *pImportFenceFdInfo)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pImportFenceFdInfo->fence);
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence_part *dst = NULL;
|
|
|
|
|
|
VkResult result;
|
2017-11-28 00:21:12 +01:00
|
|
|
|
|
2019-01-08 14:30:32 +01:00
|
|
|
|
if (pImportFenceFdInfo->flags & VK_FENCE_IMPORT_TEMPORARY_BIT) {
|
2020-07-14 21:46:17 +02:00
|
|
|
|
dst = &fence->temporary;
|
2017-11-28 00:21:12 +01:00
|
|
|
|
} else {
|
2020-07-14 21:46:17 +02:00
|
|
|
|
dst = &fence->permanent;
|
2017-11-28 00:21:12 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
uint32_t syncobj = dst->kind == RADV_FENCE_SYNCOBJ ? dst->syncobj : 0;
|
|
|
|
|
|
|
2017-12-18 21:02:05 +01:00
|
|
|
|
switch(pImportFenceFdInfo->handleType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
|
2020-07-14 21:46:17 +02:00
|
|
|
|
result = radv_import_opaque_fd(device, pImportFenceFdInfo->fd, &syncobj);
|
|
|
|
|
|
break;
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
|
2020-07-14 21:46:17 +02:00
|
|
|
|
result = radv_import_sync_fd(device, pImportFenceFdInfo->fd, &syncobj);
|
|
|
|
|
|
break;
|
2017-12-18 21:02:05 +01:00
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Unhandled fence handle type");
|
|
|
|
|
|
}
|
2020-07-14 21:46:17 +02:00
|
|
|
|
|
|
|
|
|
|
if (result == VK_SUCCESS) {
|
|
|
|
|
|
dst->syncobj = syncobj;
|
|
|
|
|
|
dst->kind = RADV_FENCE_SYNCOBJ;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
2017-11-28 00:21:12 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetFenceFdKHR(VkDevice _device,
|
|
|
|
|
|
const VkFenceGetFdInfoKHR *pGetFdInfo,
|
|
|
|
|
|
int *pFd)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, pGetFdInfo->fence);
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
struct radv_fence_part *part =
|
|
|
|
|
|
fence->temporary.kind != RADV_FENCE_NONE ?
|
|
|
|
|
|
&fence->temporary : &fence->permanent;
|
2017-12-18 21:02:05 +01:00
|
|
|
|
|
|
|
|
|
|
switch(pGetFdInfo->handleType) {
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT:
|
2020-07-14 21:46:17 +02:00
|
|
|
|
ret = device->ws->export_syncobj(device->ws, part->syncobj, pFd);
|
2020-07-14 22:59:58 +02:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_TOO_MANY_OBJECTS);
|
2017-12-18 21:02:05 +01:00
|
|
|
|
break;
|
2019-01-08 14:30:32 +01:00
|
|
|
|
case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
|
2020-07-14 21:46:17 +02:00
|
|
|
|
ret = device->ws->export_syncobj_to_sync_file(device->ws,
|
|
|
|
|
|
part->syncobj, pFd);
|
2020-07-14 22:59:58 +02:00
|
|
|
|
if (ret)
|
|
|
|
|
|
return vk_error(device->instance, VK_ERROR_TOO_MANY_OBJECTS);
|
|
|
|
|
|
|
2020-07-14 21:46:17 +02:00
|
|
|
|
if (part == &fence->temporary) {
|
|
|
|
|
|
radv_destroy_fence_part(device, part);
|
2020-07-14 22:59:58 +02:00
|
|
|
|
} else {
|
2020-07-14 21:46:17 +02:00
|
|
|
|
device->ws->reset_syncobj(device->ws, part->syncobj);
|
2018-01-04 02:55:39 +01:00
|
|
|
|
}
|
2017-12-18 21:02:05 +01:00
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
unreachable("Unhandled fence handle type");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-28 00:21:12 +01:00
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
2017-11-28 00:28:14 +01:00
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
|
void radv_GetPhysicalDeviceExternalFenceProperties(
|
2017-11-28 00:28:14 +01:00
|
|
|
|
VkPhysicalDevice physicalDevice,
|
2019-01-08 14:30:32 +01:00
|
|
|
|
const VkPhysicalDeviceExternalFenceInfo *pExternalFenceInfo,
|
|
|
|
|
|
VkExternalFenceProperties *pExternalFenceProperties)
|
2017-11-28 00:28:14 +01:00
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
|
|
2017-12-28 15:59:19 +01:00
|
|
|
|
if (pdevice->rad_info.has_syncobj_wait_for_submit &&
|
2020-10-07 10:59:36 +01:00
|
|
|
|
(pExternalFenceInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
2019-01-08 14:30:32 +01:00
|
|
|
|
pExternalFenceInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT)) {
|
|
|
|
|
|
pExternalFenceProperties->exportFromImportedHandleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
|
|
|
|
|
|
pExternalFenceProperties->compatibleHandleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT;
|
|
|
|
|
|
pExternalFenceProperties->externalFenceFeatures = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT |
|
|
|
|
|
|
VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT;
|
2017-11-28 00:28:14 +01:00
|
|
|
|
} else {
|
|
|
|
|
|
pExternalFenceProperties->exportFromImportedHandleTypes = 0;
|
|
|
|
|
|
pExternalFenceProperties->compatibleHandleTypes = 0;
|
|
|
|
|
|
pExternalFenceProperties->externalFenceFeatures = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-01-09 03:35:53 +01:00
|
|
|
|
|
|
|
|
|
|
VkResult
|
|
|
|
|
|
radv_CreateDebugReportCallbackEXT(VkInstance _instance,
|
|
|
|
|
|
const VkDebugReportCallbackCreateInfoEXT* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkDebugReportCallbackEXT* pCallback)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
return vk_create_debug_report_callback(&instance->debug_report_callbacks,
|
|
|
|
|
|
pCreateInfo, pAllocator, &instance->alloc,
|
|
|
|
|
|
pCallback);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
radv_DestroyDebugReportCallbackEXT(VkInstance _instance,
|
|
|
|
|
|
VkDebugReportCallbackEXT _callback,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
vk_destroy_debug_report_callback(&instance->debug_report_callbacks,
|
|
|
|
|
|
_callback, pAllocator, &instance->alloc);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
radv_DebugReportMessageEXT(VkInstance _instance,
|
|
|
|
|
|
VkDebugReportFlagsEXT flags,
|
|
|
|
|
|
VkDebugReportObjectTypeEXT objectType,
|
|
|
|
|
|
uint64_t object,
|
|
|
|
|
|
size_t location,
|
|
|
|
|
|
int32_t messageCode,
|
|
|
|
|
|
const char* pLayerPrefix,
|
|
|
|
|
|
const char* pMessage)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
vk_debug_report(&instance->debug_report_callbacks, flags, objectType,
|
|
|
|
|
|
object, location, messageCode, pLayerPrefix, pMessage);
|
|
|
|
|
|
}
|
2018-01-21 17:13:26 +01:00
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
radv_GetDeviceGroupPeerMemoryFeatures(
|
|
|
|
|
|
VkDevice device,
|
|
|
|
|
|
uint32_t heapIndex,
|
|
|
|
|
|
uint32_t localDeviceIndex,
|
|
|
|
|
|
uint32_t remoteDeviceIndex,
|
|
|
|
|
|
VkPeerMemoryFeatureFlags* pPeerMemoryFeatures)
|
|
|
|
|
|
{
|
|
|
|
|
|
assert(localDeviceIndex == remoteDeviceIndex);
|
|
|
|
|
|
|
|
|
|
|
|
*pPeerMemoryFeatures = VK_PEER_MEMORY_FEATURE_COPY_SRC_BIT |
|
|
|
|
|
|
VK_PEER_MEMORY_FEATURE_COPY_DST_BIT |
|
|
|
|
|
|
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
|
|
|
|
|
|
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
|
|
|
|
|
|
}
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
static const VkTimeDomainEXT radv_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 radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
uint32_t *pTimeDomainCount,
|
|
|
|
|
|
VkTimeDomainEXT *pTimeDomains)
|
|
|
|
|
|
{
|
|
|
|
|
|
int d;
|
2020-08-06 20:57:10 -07:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkTimeDomainEXT, out, pTimeDomains,
|
|
|
|
|
|
pTimeDomainCount);
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
|
2020-08-06 20:57:10 -07:00
|
|
|
|
vk_outarray_append_typed(VkTimeDomainEXT, &out, i) {
|
2018-10-11 16:05:18 -07:00
|
|
|
|
*i = radv_time_domains[d];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-03 21:27:42 -08:00
|
|
|
|
#ifndef _WIN32
|
2018-10-11 16:05:18 -07:00
|
|
|
|
static uint64_t
|
|
|
|
|
|
radv_clock_gettime(clockid_t clock_id)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct timespec current;
|
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
ret = clock_gettime(clock_id, ¤t);
|
2020-09-01 12:13:43 +10:00
|
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2018-10-11 16:05:18 -07:00
|
|
|
|
if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
|
|
|
|
|
|
ret = clock_gettime(CLOCK_MONOTONIC, ¤t);
|
2020-09-01 12:13:43 +10:00
|
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
|
if (ret < 0)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetCalibratedTimestampsEXT(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
uint32_t timestampCount,
|
|
|
|
|
|
const VkCalibratedTimestampInfoEXT *pTimestampInfos,
|
|
|
|
|
|
uint64_t *pTimestamps,
|
|
|
|
|
|
uint64_t *pMaxDeviation)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
|
|
|
|
|
|
int d;
|
|
|
|
|
|
uint64_t begin, end;
|
|
|
|
|
|
uint64_t max_clock_period = 0;
|
|
|
|
|
|
|
2020-09-01 12:13:43 +10:00
|
|
|
|
#ifdef CLOCK_MONOTONIC_RAW
|
2018-10-11 16:05:18 -07:00
|
|
|
|
begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
|
2020-09-01 12:13:43 +10:00
|
|
|
|
#else
|
|
|
|
|
|
begin = radv_clock_gettime(CLOCK_MONOTONIC);
|
|
|
|
|
|
#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:
|
|
|
|
|
|
pTimestamps[d] = device->ws->query_value(device->ws,
|
|
|
|
|
|
RADEON_TIMESTAMP);
|
|
|
|
|
|
uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
|
|
|
|
|
|
max_clock_period = MAX2(max_clock_period, device_period);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
|
|
|
|
|
|
pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
|
|
|
|
|
|
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
|
2018-10-11 16:05:18 -07:00
|
|
|
|
end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
|
2020-09-01 12:13:43 +10:00
|
|
|
|
#else
|
|
|
|
|
|
end = radv_clock_gettime(CLOCK_MONOTONIC);
|
|
|
|
|
|
#endif
|
2018-10-11 16:05:18 -07:00
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
* The maximum deviation is the sum of the interval over which we
|
|
|
|
|
|
* perform the sampling and the maximum period of any sampled
|
|
|
|
|
|
* clock. That's because the maximum skew between any two sampled
|
|
|
|
|
|
* clock edges is when the sampled clock with the largest period is
|
|
|
|
|
|
* sampled at the end of that period but right at the beginning of the
|
|
|
|
|
|
* sampling interval and some other clock is sampled right at the
|
|
|
|
|
|
* begining of its sampling period and right at the end of the
|
|
|
|
|
|
* sampling interval. Let's assume the GPU has the longest clock
|
|
|
|
|
|
* period and that the application is sampling GPU and monotonic:
|
|
|
|
|
|
*
|
|
|
|
|
|
* s e
|
|
|
|
|
|
* w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
|
|
|
|
|
|
* Raw -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
|
|
|
|
|
*
|
|
|
|
|
|
* g
|
|
|
|
|
|
* 0 1 2 3
|
|
|
|
|
|
* GPU -----_____-----_____-----_____-----_____
|
|
|
|
|
|
*
|
|
|
|
|
|
* m
|
|
|
|
|
|
* x y z 0 1 2 3 4 5 6 7 8 9 a b c
|
|
|
|
|
|
* Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
|
|
|
|
|
*
|
|
|
|
|
|
* Interval <----------------->
|
|
|
|
|
|
* Deviation <-------------------------->
|
|
|
|
|
|
*
|
|
|
|
|
|
* s = read(raw) 2
|
|
|
|
|
|
* g = read(GPU) 1
|
|
|
|
|
|
* m = read(monotonic) 2
|
|
|
|
|
|
* e = read(raw) b
|
|
|
|
|
|
*
|
|
|
|
|
|
* We round the sample interval up by one tick to cover sampling error
|
|
|
|
|
|
* in the interval clock
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t sample_interval = end - begin + 1;
|
|
|
|
|
|
|
|
|
|
|
|
*pMaxDeviation = sample_interval + max_clock_period;
|
|
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
}
|
2020-12-03 21:27:42 -08:00
|
|
|
|
#endif
|
2019-05-16 11:55:02 +02:00
|
|
|
|
|
|
|
|
|
|
void radv_GetPhysicalDeviceMultisamplePropertiesEXT(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
VkSampleCountFlagBits samples,
|
|
|
|
|
|
VkMultisamplePropertiesEXT* pMultisampleProperties)
|
|
|
|
|
|
{
|
2020-12-01 12:33:05 +01:00
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
|
|
|
|
|
|
VkSampleCountFlagBits supported_samples = VK_SAMPLE_COUNT_2_BIT |
|
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT;
|
|
|
|
|
|
|
|
|
|
|
|
if (physical_device->rad_info.chip_class < GFX10)
|
|
|
|
|
|
supported_samples |= VK_SAMPLE_COUNT_8_BIT;
|
|
|
|
|
|
|
|
|
|
|
|
if (samples & supported_samples) {
|
2019-05-16 11:55:02 +02:00
|
|
|
|
pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 2, 2 };
|
|
|
|
|
|
} else {
|
|
|
|
|
|
pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 0, 0 };
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-04-29 10:19:11 +02:00
|
|
|
|
|
2020-11-26 17:39:53 +01:00
|
|
|
|
VkResult radv_GetPhysicalDeviceFragmentShadingRatesKHR(
|
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
|
uint32_t* pFragmentShadingRateCount,
|
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRateKHR* pFragmentShadingRates)
|
|
|
|
|
|
{
|
2020-12-14 10:33:03 -08:00
|
|
|
|
VK_OUTARRAY_MAKE_TYPED(VkPhysicalDeviceFragmentShadingRateKHR, out, pFragmentShadingRates, pFragmentShadingRateCount);
|
2020-11-26 17:39:53 +01:00
|
|
|
|
|
|
|
|
|
|
#define append_rate(w, h, s) { \
|
|
|
|
|
|
VkPhysicalDeviceFragmentShadingRateKHR rate = { \
|
|
|
|
|
|
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_PROPERTIES_KHR,\
|
|
|
|
|
|
.sampleCounts = s, \
|
|
|
|
|
|
.fragmentSize = { .width = w, .height = h }, \
|
|
|
|
|
|
}; \
|
2020-12-14 10:33:03 -08:00
|
|
|
|
vk_outarray_append_typed(VkPhysicalDeviceFragmentShadingRateKHR, &out, r) *r = rate; \
|
2020-11-26 17:39:53 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (uint32_t x = 2; x >= 1; x--) {
|
|
|
|
|
|
for (uint32_t y = 2; y >= 1; y--) {
|
|
|
|
|
|
append_rate(x, y, VK_SAMPLE_COUNT_1_BIT |
|
|
|
|
|
|
VK_SAMPLE_COUNT_2_BIT |
|
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT |
|
|
|
|
|
|
VK_SAMPLE_COUNT_8_BIT);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#undef append_rate
|
|
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-04-29 10:19:11 +02:00
|
|
|
|
VkResult radv_CreatePrivateDataSlotEXT(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
const VkPrivateDataSlotCreateInfoEXT* pCreateInfo,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkPrivateDataSlotEXT* pPrivateDataSlot)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_private_data_slot_create(&device->vk, pCreateInfo, pAllocator,
|
|
|
|
|
|
pPrivateDataSlot);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyPrivateDataSlotEXT(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkPrivateDataSlotEXT privateDataSlot,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
vk_private_data_slot_destroy(&device->vk, privateDataSlot, pAllocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_SetPrivateDataEXT(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkObjectType objectType,
|
|
|
|
|
|
uint64_t objectHandle,
|
|
|
|
|
|
VkPrivateDataSlotEXT privateDataSlot,
|
|
|
|
|
|
uint64_t data)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_object_base_set_private_data(&device->vk, objectType,
|
|
|
|
|
|
objectHandle, privateDataSlot,
|
|
|
|
|
|
data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_GetPrivateDataEXT(
|
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
|
VkObjectType objectType,
|
|
|
|
|
|
uint64_t objectHandle,
|
|
|
|
|
|
VkPrivateDataSlotEXT privateDataSlot,
|
|
|
|
|
|
uint64_t* pData)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
vk_object_base_get_private_data(&device->vk, objectType, objectHandle,
|
|
|
|
|
|
privateDataSlot, pData);
|
|
|
|
|
|
}
|
2021-01-17 13:37:50 +01:00
|
|
|
|
|
|
|
|
|
|
VkResult radv_CreateDeferredOperationKHR(VkDevice _device,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
|
VkDeferredOperationKHR* pDeferredOperation)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_create_deferred_operation(&device->vk, pAllocator,
|
|
|
|
|
|
pDeferredOperation);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void radv_DestroyDeferredOperationKHR(VkDevice _device,
|
|
|
|
|
|
VkDeferredOperationKHR operation,
|
|
|
|
|
|
const VkAllocationCallbacks* pAllocator)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
vk_destroy_deferred_operation(&device->vk, operation, pAllocator);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint32_t radv_GetDeferredOperationMaxConcurrencyKHR(VkDevice _device,
|
|
|
|
|
|
VkDeferredOperationKHR operation)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_get_deferred_operation_max_concurrency(&device->vk, operation);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetDeferredOperationResultKHR(VkDevice _device,
|
|
|
|
|
|
VkDeferredOperationKHR operation)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_get_deferred_operation_result(&device->vk, operation);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkResult radv_DeferredOperationJoinKHR(VkDevice _device,
|
|
|
|
|
|
VkDeferredOperationKHR operation)
|
|
|
|
|
|
{
|
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
return vk_deferred_operation_join(&device->vk, operation);
|
|
|
|
|
|
}
|
|
|
|
|
|
|