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 <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
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"
|
2016-10-07 09:16:09 +10:00
|
|
|
#include "util/strtod.h"
|
2017-06-06 12:31:05 +01:00
|
|
|
#include "vk_util.h"
|
2016-10-11 15:21:25 +10:00
|
|
|
#include <xf86drm.h>
|
2016-10-07 09:16:09 +10:00
|
|
|
#include <amdgpu.h>
|
|
|
|
|
#include <amdgpu_drm.h>
|
|
|
|
|
#include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
|
|
|
|
|
#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-03-15 09:47:49 +02:00
|
|
|
#include "compiler/glsl_types.h"
|
2019-04-15 00:32:27 +02:00
|
|
|
#include "util/xmlpool.h"
|
2018-09-16 02:50:34 +02:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2017-12-06 10:28:14 +00:00
|
|
|
static void
|
|
|
|
|
radv_get_device_name(enum radeon_family family, char *name, size_t name_len)
|
2017-05-12 00:56:06 +02:00
|
|
|
{
|
2017-12-06 10:28:14 +00:00
|
|
|
const char *chip_string;
|
|
|
|
|
|
2017-05-12 00:56:06 +02:00
|
|
|
switch (family) {
|
2017-12-06 10:28:14 +00:00
|
|
|
case CHIP_TAHITI: chip_string = "AMD RADV TAHITI"; break;
|
|
|
|
|
case CHIP_PITCAIRN: chip_string = "AMD RADV PITCAIRN"; break;
|
|
|
|
|
case CHIP_VERDE: chip_string = "AMD RADV CAPE VERDE"; break;
|
|
|
|
|
case CHIP_OLAND: chip_string = "AMD RADV OLAND"; break;
|
|
|
|
|
case CHIP_HAINAN: chip_string = "AMD RADV HAINAN"; break;
|
|
|
|
|
case CHIP_BONAIRE: chip_string = "AMD RADV BONAIRE"; break;
|
|
|
|
|
case CHIP_KAVERI: chip_string = "AMD RADV KAVERI"; break;
|
|
|
|
|
case CHIP_KABINI: chip_string = "AMD RADV KABINI"; break;
|
|
|
|
|
case CHIP_HAWAII: chip_string = "AMD RADV HAWAII"; break;
|
|
|
|
|
case CHIP_TONGA: chip_string = "AMD RADV TONGA"; break;
|
|
|
|
|
case CHIP_ICELAND: chip_string = "AMD RADV ICELAND"; break;
|
|
|
|
|
case CHIP_CARRIZO: chip_string = "AMD RADV CARRIZO"; break;
|
|
|
|
|
case CHIP_FIJI: chip_string = "AMD RADV FIJI"; break;
|
|
|
|
|
case CHIP_POLARIS10: chip_string = "AMD RADV POLARIS10"; break;
|
|
|
|
|
case CHIP_POLARIS11: chip_string = "AMD RADV POLARIS11"; break;
|
|
|
|
|
case CHIP_POLARIS12: chip_string = "AMD RADV POLARIS12"; break;
|
|
|
|
|
case CHIP_STONEY: chip_string = "AMD RADV STONEY"; break;
|
2018-04-19 06:35:08 +02:00
|
|
|
case CHIP_VEGAM: chip_string = "AMD RADV VEGA M"; break;
|
2018-03-22 16:41:43 +01:00
|
|
|
case CHIP_VEGA10: chip_string = "AMD RADV VEGA10"; break;
|
2018-03-22 16:41:42 +01:00
|
|
|
case CHIP_VEGA12: chip_string = "AMD RADV VEGA12"; break;
|
2019-04-27 12:07:51 +02:00
|
|
|
case CHIP_VEGA20: chip_string = "AMD RADV VEGA20"; break;
|
2017-12-06 10:28:14 +00:00
|
|
|
case CHIP_RAVEN: chip_string = "AMD RADV RAVEN"; break;
|
2018-10-30 11:52:37 +01:00
|
|
|
case CHIP_RAVEN2: chip_string = "AMD RADV RAVEN2"; break;
|
2019-06-25 12:11:42 +02:00
|
|
|
case CHIP_NAVI10: chip_string = "AMD RADV NAVI10"; break;
|
|
|
|
|
case CHIP_NAVI12: chip_string = "AMD RADV NAVI12"; break;
|
|
|
|
|
case CHIP_NAVI14: chip_string = "AMD RADV NAVI14"; break;
|
2017-12-06 10:28:14 +00:00
|
|
|
default: chip_string = "AMD RADV unknown"; break;
|
2017-05-12 00:56:06 +02:00
|
|
|
}
|
2017-12-06 10:28:14 +00:00
|
|
|
|
2019-03-14 13:58:54 +00:00
|
|
|
snprintf(name, name_len, "%s (LLVM " MESA_LLVM_VERSION_STRING ")", chip_string);
|
2017-05-12 00:56:06 +02:00
|
|
|
}
|
|
|
|
|
|
2019-01-07 17:38:08 +01:00
|
|
|
static uint64_t
|
|
|
|
|
radv_get_visible_vram_size(struct radv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
return MIN2(device->rad_info.vram_size, device->rad_info.vram_vis_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint64_t
|
|
|
|
|
radv_get_vram_size(struct radv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
return device->rad_info.vram_size - radv_get_visible_vram_size(device);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-01 09:26:48 +01:00
|
|
|
static void
|
|
|
|
|
radv_physical_device_init_mem_types(struct radv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
STATIC_ASSERT(RADV_MEM_HEAP_COUNT <= VK_MAX_MEMORY_HEAPS);
|
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;
|
2019-01-07 17:38:08 +01:00
|
|
|
if (vram_size > 0) {
|
2017-11-01 09:26:48 +01:00
|
|
|
vram_index = device->memory_properties.memoryHeapCount++;
|
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (visible_vram_size) {
|
|
|
|
|
visible_vram_index = device->memory_properties.memoryHeapCount++;
|
|
|
|
|
device->memory_properties.memoryHeaps[visible_vram_index] = (VkMemoryHeap) {
|
|
|
|
|
.size = visible_vram_size,
|
|
|
|
|
.flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (device->rad_info.gart_size > 0) {
|
|
|
|
|
gart_index = device->memory_properties.memoryHeapCount++;
|
|
|
|
|
device->memory_properties.memoryHeaps[gart_index] = (VkMemoryHeap) {
|
|
|
|
|
.size = device->rad_info.gart_size,
|
2018-04-20 18:16:02 +02:00
|
|
|
.flags = device->rad_info.has_dedicated_vram ? 0 : VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
|
2017-11-01 09:26:48 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STATIC_ASSERT(RADV_MEM_TYPE_COUNT <= VK_MAX_MEMORY_TYPES);
|
|
|
|
|
unsigned type_count = 0;
|
|
|
|
|
if (vram_index >= 0) {
|
|
|
|
|
device->mem_type_indices[type_count] = RADV_MEM_TYPE_VRAM;
|
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
|
|
|
|
.heapIndex = vram_index,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (gart_index >= 0) {
|
|
|
|
|
device->mem_type_indices[type_count] = RADV_MEM_TYPE_GTT_WRITE_COMBINE;
|
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
2018-04-20 18:16:02 +02:00
|
|
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
|
|
|
|
(device->rad_info.has_dedicated_vram ? 0 : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
2017-11-01 09:26:48 +01:00
|
|
|
.heapIndex = gart_index,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (visible_vram_index >= 0) {
|
|
|
|
|
device->mem_type_indices[type_count] = RADV_MEM_TYPE_VRAM_CPU_ACCESS;
|
|
|
|
|
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,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
if (gart_index >= 0) {
|
|
|
|
|
device->mem_type_indices[type_count] = RADV_MEM_TYPE_GTT_CACHED;
|
|
|
|
|
device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
|
|
|
|
|
.propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
|
|
|
|
|
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
|
2018-04-20 18:16:02 +02:00
|
|
|
VK_MEMORY_PROPERTY_HOST_CACHED_BIT |
|
|
|
|
|
(device->rad_info.has_dedicated_vram ? 0 : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT),
|
2017-11-01 09:26:48 +01:00
|
|
|
.heapIndex = gart_index,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
device->memory_properties.memoryTypeCount = type_count;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-16 11:00:14 +01:00
|
|
|
static void
|
|
|
|
|
radv_handle_env_var_force_family(struct radv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
const char *family = getenv("RADV_FORCE_FAMILY");
|
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
|
|
if (!family)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (i = CHIP_TAHITI; i < CHIP_LAST; i++) {
|
|
|
|
|
if (!strcmp(family, ac_get_llvm_processor_name(i))) {
|
|
|
|
|
/* Override family and chip_class. */
|
|
|
|
|
device->rad_info.family = i;
|
|
|
|
|
|
2019-06-25 12:09:41 +02:00
|
|
|
if (i >= CHIP_NAVI10)
|
|
|
|
|
device->rad_info.chip_class = GFX10;
|
|
|
|
|
else if (i >= CHIP_VEGA10)
|
2018-02-16 11:00:14 +01:00
|
|
|
device->rad_info.chip_class = GFX9;
|
|
|
|
|
else if (i >= CHIP_TONGA)
|
2019-05-14 22:16:20 -04:00
|
|
|
device->rad_info.chip_class = GFX8;
|
2018-02-16 11:00:14 +01:00
|
|
|
else if (i >= CHIP_BONAIRE)
|
2019-05-14 22:16:20 -04:00
|
|
|
device->rad_info.chip_class = GFX7;
|
2018-02-16 11:00:14 +01:00
|
|
|
else
|
2019-05-14 22:16:20 -04:00
|
|
|
device->rad_info.chip_class = GFX6;
|
2018-02-16 11:00:14 +01:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(stderr, "radv: Unknown family: %s\n", family);
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
static VkResult
|
|
|
|
|
radv_physical_device_init(struct radv_physical_device *device,
|
|
|
|
|
struct radv_instance *instance,
|
2017-05-23 09:22:09 +02:00
|
|
|
drmDevicePtr drm_device)
|
2016-10-07 09:16:09 +10:00
|
|
|
{
|
2017-05-23 09:22:09 +02:00
|
|
|
const char *path = drm_device->nodes[DRM_NODE_RENDER];
|
2016-10-07 09:16:09 +10:00
|
|
|
VkResult result;
|
2016-10-11 15:21:25 +10:00
|
|
|
drmVersionPtr version;
|
2016-10-07 09:16:09 +10:00
|
|
|
int 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
|
|
|
int master_fd = -1;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
fd = open(path, O_RDWR | O_CLOEXEC);
|
2018-05-31 01:49:38 +02:00
|
|
|
if (fd < 0) {
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
radv_logi("Could not open device '%s'", path);
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
|
2018-05-31 01:49:38 +02:00
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2016-10-11 15:21:25 +10:00
|
|
|
version = drmGetVersion(fd);
|
|
|
|
|
if (!version) {
|
|
|
|
|
close(fd);
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
radv_logi("Could not get the kernel driver version for device '%s'", path);
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
|
2016-10-11 15:21:25 +10:00
|
|
|
"failed to get version %s: %m", path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (strcmp(version->name, "amdgpu")) {
|
|
|
|
|
drmFreeVersion(version);
|
|
|
|
|
close(fd);
|
2018-05-31 01:49:38 +02:00
|
|
|
|
|
|
|
|
if (instance->debug_flags & RADV_DEBUG_STARTUP)
|
|
|
|
|
radv_logi("Device '%s' is not using the amdgpu kernel driver.", path);
|
|
|
|
|
|
2017-11-14 13:23:00 +10:00
|
|
|
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)
|
|
|
|
|
radv_logi("Found compatible device '%s'.", path);
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
|
|
|
|
|
device->instance = instance;
|
|
|
|
|
|
2017-05-09 04:17:30 +01:00
|
|
|
device->ws = radv_amdgpu_winsys_create(fd, instance->debug_flags,
|
|
|
|
|
instance->perftest_flags);
|
2016-10-07 09:16:09 +10:00
|
|
|
if (!device->ws) {
|
2018-05-31 01:49:38 +02:00
|
|
|
result = vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
|
2016-10-07 09:16:09 +10:00
|
|
|
goto fail;
|
|
|
|
|
}
|
2017-02-19 15:27:47 +10:00
|
|
|
|
2018-02-07 10:31:44 -08:00
|
|
|
if (instance->enabled_extensions.KHR_display) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
2018-02-16 11:00:14 +01:00
|
|
|
radv_handle_env_var_force_family(device);
|
|
|
|
|
|
2017-12-06 10:28:14 +00:00
|
|
|
radv_get_device_name(device->rad_info.family, device->name, sizeof(device->name));
|
2017-10-25 02:23:08 +01:00
|
|
|
|
2017-07-12 18:45:29 -04:00
|
|
|
if (radv_device_get_cache_uuid(device->rad_info.family, device->cache_uuid)) {
|
2016-11-22 00:19:30 +01:00
|
|
|
device->ws->destroy(device->ws);
|
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");
|
2016-11-22 00:19:30 +01:00
|
|
|
goto fail;
|
|
|
|
|
}
|
2016-11-22 00:31:44 +01:00
|
|
|
|
2017-10-11 12:00:27 +11:00
|
|
|
/* These flags affect shader compilation. */
|
|
|
|
|
uint64_t shader_env_flags =
|
|
|
|
|
(device->instance->perftest_flags & RADV_PERFTEST_SISCHED ? 0x1 : 0) |
|
|
|
|
|
(device->instance->debug_flags & RADV_DEBUG_UNSAFE_MATH ? 0x2 : 0);
|
|
|
|
|
|
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);
|
2017-10-11 12:00:27 +11:00
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
if (device->rad_info.chip_class < GFX8 ||
|
2018-03-07 16:38:32 +01:00
|
|
|
device->rad_info.chip_class > GFX9)
|
|
|
|
|
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
|
|
|
|
2017-06-06 09:03:55 +10:00
|
|
|
if (device->rad_info.family == CHIP_STONEY ||
|
|
|
|
|
device->rad_info.chip_class >= GFX9) {
|
|
|
|
|
device->has_rbplus = true;
|
2018-03-22 16:41:42 +01:00
|
|
|
device->rbplus_allowed = device->rad_info.family == CHIP_STONEY ||
|
2018-04-11 01:35:38 +02:00
|
|
|
device->rad_info.family == CHIP_VEGA12 ||
|
2018-10-30 11:52:37 +01:00
|
|
|
device->rad_info.family == CHIP_RAVEN ||
|
|
|
|
|
device->rad_info.family == CHIP_RAVEN2;
|
2017-06-06 09:03:55 +10:00
|
|
|
}
|
|
|
|
|
|
2018-05-10 00:26:21 +03:00
|
|
|
/* The mere presence of CLEAR_STATE in the IB causes random GPU hangs
|
2019-05-14 22:16:20 -04:00
|
|
|
* on GFX6.
|
2017-10-05 14:55:24 +02:00
|
|
|
*/
|
2019-07-23 08:41:15 +02:00
|
|
|
device->has_clear_state = device->rad_info.chip_class >= GFX7;
|
2017-10-05 14:55:24 +02:00
|
|
|
|
2019-05-14 22:16:20 -04:00
|
|
|
device->cpdma_prefetch_writes_memory = device->rad_info.chip_class <= GFX8;
|
2018-01-04 15:19:47 +01:00
|
|
|
|
2018-01-05 18:00:31 +01:00
|
|
|
/* Vega10/Raven need a special workaround for a hardware bug. */
|
|
|
|
|
device->has_scissor_bug = device->rad_info.family == CHIP_VEGA10 ||
|
|
|
|
|
device->rad_info.family == CHIP_RAVEN;
|
|
|
|
|
|
2019-07-16 17:35:00 +02:00
|
|
|
device->has_tc_compat_zrange_bug = device->rad_info.chip_class < GFX10;
|
|
|
|
|
|
2018-03-28 19:03:00 +02:00
|
|
|
/* Out-of-order primitive rasterization. */
|
2019-05-14 22:16:20 -04:00
|
|
|
device->has_out_of_order_rast = device->rad_info.chip_class >= GFX8 &&
|
2018-03-28 19:03:00 +02:00
|
|
|
device->rad_info.max_se >= 2;
|
|
|
|
|
device->out_of_order_rast_allowed = device->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-05-14 22:16:20 -04:00
|
|
|
/* TODO: Figure out how to use LOAD_CONTEXT_REG on GFX6-GFX7. */
|
2019-02-12 09:01:50 +01:00
|
|
|
device->has_load_ctx_reg_pkt = device->rad_info.chip_class >= GFX9 ||
|
2019-05-14 22:16:20 -04:00
|
|
|
(device->rad_info.chip_class >= GFX8 &&
|
2019-02-12 09:01:50 +01:00
|
|
|
device->rad_info.me_fw_feature >= 41);
|
|
|
|
|
|
2019-06-25 16:18:40 +02:00
|
|
|
device->has_dcc_constant_encode = device->rad_info.family == CHIP_RAVEN2 ||
|
|
|
|
|
device->rad_info.chip_class >= GFX10;
|
2019-06-25 16:17:17 +02:00
|
|
|
|
2018-05-09 20:43:16 +02:00
|
|
|
device->use_shader_ballot = device->instance->perftest_flags & RADV_PERFTEST_SHADER_BALLOT;
|
|
|
|
|
|
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);
|
2018-02-10 21:43:55 +01:00
|
|
|
radv_fill_device_extension_table(device, &device->supported_extensions);
|
2017-11-18 15:30:34 -08:00
|
|
|
|
2018-10-19 11:51:47 +02:00
|
|
|
device->bus_info = *drm_device->businfo.pci;
|
|
|
|
|
|
|
|
|
|
if ((device->instance->debug_flags & RADV_DEBUG_INFO))
|
|
|
|
|
ac_print_gpu_info(&device->rad_info);
|
|
|
|
|
|
|
|
|
|
/* 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) {
|
|
|
|
|
device->ws->destroy(device->ws);
|
2018-05-31 01:49:38 +02:00
|
|
|
vk_error(instance, result);
|
2017-11-18 15:30:34 -08:00
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
|
|
|
|
fail:
|
|
|
|
|
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
|
|
|
|
|
radv_physical_device_finish(struct radv_physical_device *device)
|
|
|
|
|
{
|
|
|
|
|
radv_finish_wsi(device);
|
|
|
|
|
device->ws->destroy(device->ws);
|
2017-10-11 12:00:27 +11:00
|
|
|
disk_cache_destroy(device->disk_cache);
|
2017-02-19 15:27:47 +10:00
|
|
|
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);
|
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},
|
|
|
|
|
{"unsafemath", RADV_DEBUG_UNSAFE_MATH},
|
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},
|
2017-11-10 09:34:46 +01:00
|
|
|
{"nosisched", RADV_DEBUG_NO_SISCHED},
|
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-05-07 16:09:46 +02:00
|
|
|
{"noloadstoreopt", RADV_DEBUG_NO_LOAD_STORE_OPT},
|
2019-07-17 14:19:10 +02:00
|
|
|
{"nongg", RADV_DEBUG_NO_NGG},
|
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-09-02 21:47:11 +02:00
|
|
|
{"nobatchchain", RADV_PERFTEST_NO_BATCHCHAIN},
|
2017-07-06 03:06:01 +01:00
|
|
|
{"sisched", RADV_PERFTEST_SISCHED},
|
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-05-09 20:43:16 +02:00
|
|
|
{"shader_ballot", RADV_PERFTEST_SHADER_BALLOT},
|
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},
|
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;
|
|
|
|
|
|
|
|
|
|
if (!name)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!strcmp(name, "Talos - Linux - 32bit") ||
|
|
|
|
|
!strcmp(name, "Talos - Linux - 64bit")) {
|
2018-05-09 23:52:53 +02:00
|
|
|
if (!(instance->debug_flags & RADV_DEBUG_NO_SISCHED)) {
|
|
|
|
|
/* Force enable LLVM sisched for Talos because it looks
|
|
|
|
|
* safe and it gives few more FPS.
|
|
|
|
|
*/
|
|
|
|
|
instance->perftest_flags |= RADV_PERFTEST_SISCHED;
|
|
|
|
|
}
|
2018-08-15 21:12:13 +10:00
|
|
|
} else if (!strcmp(name, "DOOM_VFR")) {
|
|
|
|
|
/* Work around a Doom VFR game bug */
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_NO_DYNAMIC_BOUNDS;
|
2019-05-07 16:09:46 +02:00
|
|
|
} else if (!strcmp(name, "MonsterHunterWorld.exe")) {
|
|
|
|
|
/* Workaround for a WaW hazard when LLVM moves/merges
|
|
|
|
|
* load/store memory operations.
|
|
|
|
|
* See https://reviews.llvm.org/D61313
|
|
|
|
|
*/
|
|
|
|
|
if (HAVE_LLVM < 0x900)
|
|
|
|
|
instance->debug_flags |= RADV_DEBUG_NO_LOAD_STORE_OPT;
|
2017-11-07 10:02:32 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-11 00:32:34 +01:00
|
|
|
static int radv_get_instance_extension_index(const char *name)
|
|
|
|
|
{
|
|
|
|
|
for (unsigned i = 0; i < RADV_INSTANCE_EXTENSION_COUNT; ++i) {
|
|
|
|
|
if (strcmp(name, radv_instance_extensions[i].extensionName) == 0)
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-15 00:32:27 +02:00
|
|
|
static const char radv_dri_options_xml[] =
|
|
|
|
|
DRI_CONF_BEGIN
|
2019-04-17 01:51:10 +02:00
|
|
|
DRI_CONF_SECTION_QUALITY
|
|
|
|
|
DRI_CONF_ADAPTIVE_SYNC("true")
|
|
|
|
|
DRI_CONF_SECTION_END
|
2019-04-15 00:32:27 +02:00
|
|
|
DRI_CONF_END;
|
|
|
|
|
|
|
|
|
|
static void radv_init_dri_options(struct radv_instance *instance)
|
|
|
|
|
{
|
|
|
|
|
driParseOptionInfo(&instance->available_dri_options, radv_dri_options_xml);
|
|
|
|
|
driParseConfigFiles(&instance->dri_options,
|
|
|
|
|
&instance->available_dri_options,
|
|
|
|
|
0, "radv", NULL);
|
|
|
|
|
}
|
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
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
|
|
|
|
|
|
|
|
|
|
uint32_t client_version;
|
|
|
|
|
if (pCreateInfo->pApplicationInfo &&
|
|
|
|
|
pCreateInfo->pApplicationInfo->apiVersion != 0) {
|
|
|
|
|
client_version = pCreateInfo->pApplicationInfo->apiVersion;
|
|
|
|
|
} else {
|
2018-11-23 00:32:29 +01:00
|
|
|
client_version = VK_API_VERSION_1_0;
|
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
|
|
|
|
|
|
|
|
instance->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
|
|
|
|
|
|
|
|
|
|
if (pAllocator)
|
|
|
|
|
instance->alloc = *pAllocator;
|
|
|
|
|
else
|
|
|
|
|
instance->alloc = default_alloc;
|
|
|
|
|
|
|
|
|
|
instance->apiVersion = client_version;
|
|
|
|
|
instance->physicalDeviceCount = -1;
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
instance->debug_flags = parse_debug_string(getenv("RADV_DEBUG"),
|
|
|
|
|
radv_debug_options);
|
|
|
|
|
|
|
|
|
|
instance->perftest_flags = parse_debug_string(getenv("RADV_PERFTEST"),
|
|
|
|
|
radv_perftest_options);
|
|
|
|
|
|
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++) {
|
|
|
|
|
const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
|
|
|
|
|
int index = radv_get_instance_extension_index(ext_name);
|
|
|
|
|
|
|
|
|
|
if (index < 0 || !radv_supported_instance_extensions.extensions[index]) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
instance->enabled_extensions.extensions[index] = true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-09 03:35:53 +01:00
|
|
|
result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
|
|
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
_mesa_locale_init();
|
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;
|
|
|
|
|
|
2017-01-16 21:25:10 +01:00
|
|
|
for (int i = 0; i < instance->physicalDeviceCount; ++i) {
|
|
|
|
|
radv_physical_device_finish(instance->physicalDevices + i);
|
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
|
|
|
_mesa_locale_fini();
|
|
|
|
|
|
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);
|
|
|
|
|
|
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
|
|
|
|
|
radv_enumerate_devices(struct radv_instance *instance)
|
2016-10-07 09:16:09 +10:00
|
|
|
{
|
2016-12-01 20:58:20 +00:00
|
|
|
/* TODO: Check for more devices ? */
|
|
|
|
|
drmDevicePtr devices[8];
|
|
|
|
|
VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
|
|
|
|
|
int max_devices;
|
|
|
|
|
|
|
|
|
|
instance->physicalDeviceCount = 0;
|
|
|
|
|
|
2017-05-02 19:41:13 +03:00
|
|
|
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)
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
|
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
|
|
|
|
2017-01-16 21:25:10 +01:00
|
|
|
result = radv_physical_device_init(instance->physicalDevices +
|
|
|
|
|
instance->physicalDeviceCount,
|
2016-12-01 20:58:20 +00:00
|
|
|
instance,
|
2017-05-23 09:22:09 +02:00
|
|
|
devices[i]);
|
2017-01-16 21:25:10 +01:00
|
|
|
if (result == VK_SUCCESS)
|
|
|
|
|
++instance->physicalDeviceCount;
|
|
|
|
|
else if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
|
2017-05-02 20:05:07 +03:00
|
|
|
break;
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
}
|
2017-05-02 20:05:07 +03:00
|
|
|
drmFreeDevices(devices, max_devices);
|
|
|
|
|
|
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);
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
if (instance->physicalDeviceCount < 0) {
|
|
|
|
|
result = radv_enumerate_devices(instance);
|
|
|
|
|
if (result != VK_SUCCESS &&
|
|
|
|
|
result != VK_ERROR_INCOMPATIBLE_DRIVER)
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
if (!pPhysicalDevices) {
|
|
|
|
|
*pPhysicalDeviceCount = instance->physicalDeviceCount;
|
|
|
|
|
} else {
|
2017-01-16 21:25:10 +01:00
|
|
|
*pPhysicalDeviceCount = MIN2(*pPhysicalDeviceCount, instance->physicalDeviceCount);
|
|
|
|
|
for (unsigned i = 0; i < *pPhysicalDeviceCount; ++i)
|
|
|
|
|
pPhysicalDevices[i] = radv_physical_device_to_handle(instance->physicalDevices + i);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
|
2017-01-16 21:25:10 +01:00
|
|
|
return *pPhysicalDeviceCount < instance->physicalDeviceCount ? VK_INCOMPLETE
|
|
|
|
|
: VK_SUCCESS;
|
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);
|
|
|
|
|
VkResult result;
|
|
|
|
|
|
|
|
|
|
if (instance->physicalDeviceCount < 0) {
|
|
|
|
|
result = radv_enumerate_devices(instance);
|
|
|
|
|
if (result != VK_SUCCESS &&
|
|
|
|
|
result != VK_ERROR_INCOMPATIBLE_DRIVER)
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!pPhysicalDeviceGroupProperties) {
|
|
|
|
|
*pPhysicalDeviceGroupCount = instance->physicalDeviceCount;
|
|
|
|
|
} else {
|
|
|
|
|
*pPhysicalDeviceGroupCount = MIN2(*pPhysicalDeviceGroupCount, instance->physicalDeviceCount);
|
|
|
|
|
for (unsigned i = 0; i < *pPhysicalDeviceGroupCount; ++i) {
|
|
|
|
|
pPhysicalDeviceGroupProperties[i].physicalDeviceCount = 1;
|
|
|
|
|
pPhysicalDeviceGroupProperties[i].physicalDevices[0] = radv_physical_device_to_handle(instance->physicalDevices + i);
|
|
|
|
|
pPhysicalDeviceGroupProperties[i].subsetAllocation = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return *pPhysicalDeviceGroupCount < instance->physicalDeviceCount ? VK_INCOMPLETE
|
|
|
|
|
: VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
|
|
.alphaToOne = true,
|
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,
|
2019-05-14 22:16:20 -04:00
|
|
|
.shaderStorageImageMultisample = pdevice->rad_info.chip_class >= GFX8,
|
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,
|
2018-11-02 09:50:32 +01:00
|
|
|
.shaderInt16 = pdevice->rad_info.chip_class >= GFX9,
|
2017-01-31 23:59:02 +01:00
|
|
|
.sparseBinding = true,
|
2017-04-12 23:29:58 +02:00
|
|
|
.variableMultisampleRate = true,
|
2017-04-12 23:17:14 +02:00
|
|
|
.inheritedQueries = true,
|
2016-10-07 09:16:09 +10:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
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;
|
2017-07-19 23:55:58 +02:00
|
|
|
features->variablePointersStorageBuffer = true;
|
2019-01-09 12:31:48 +01:00
|
|
|
features->variablePointers = true;
|
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;
|
2017-08-16 09:20:53 +02:00
|
|
|
features->multiview = true;
|
|
|
|
|
features->multiviewGeometryShader = true;
|
|
|
|
|
features->multiviewTessellationShader = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-23 13:47:10 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETERS_FEATURES: {
|
|
|
|
|
VkPhysicalDeviceShaderDrawParametersFeatures *features =
|
|
|
|
|
(VkPhysicalDeviceShaderDrawParametersFeatures*)ext;
|
2018-01-21 15:57:59 +01:00
|
|
|
features->shaderDrawParameters = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-01-21 15:59:45 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
|
|
|
|
|
VkPhysicalDeviceProtectedMemoryFeatures *features =
|
|
|
|
|
(VkPhysicalDeviceProtectedMemoryFeatures*)ext;
|
|
|
|
|
features->protectedMemory = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-01-22 00:34:08 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
|
|
|
|
|
VkPhysicalDevice16BitStorageFeatures *features =
|
|
|
|
|
(VkPhysicalDevice16BitStorageFeatures*)ext;
|
2019-05-14 22:16:20 -04:00
|
|
|
bool enabled = pdevice->rad_info.chip_class >= GFX8;
|
2018-05-15 17:10:12 +02:00
|
|
|
features->storageBuffer16BitAccess = enabled;
|
|
|
|
|
features->uniformAndStorageBuffer16BitAccess = enabled;
|
|
|
|
|
features->storagePushConstant16 = enabled;
|
2019-02-22 14:16:08 +01:00
|
|
|
features->storageInputOutput16 = enabled && HAVE_LLVM >= 0x900;
|
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;
|
2019-04-01 17:43:29 +02:00
|
|
|
features->samplerYcbcrConversion = true;
|
2018-01-22 22:22:41 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2018-04-11 19:08:30 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
|
|
|
|
|
VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =
|
2018-05-20 13:21:13 +02:00
|
|
|
(VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)ext;
|
2018-04-11 19:08:30 +02:00
|
|
|
features->shaderInputAttachmentArrayDynamicIndexing = true;
|
|
|
|
|
features->shaderUniformTexelBufferArrayDynamicIndexing = true;
|
|
|
|
|
features->shaderStorageTexelBufferArrayDynamicIndexing = true;
|
2019-04-07 23:57:58 +02:00
|
|
|
features->shaderUniformBufferArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderSampledImageArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderStorageBufferArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderStorageImageArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderInputAttachmentArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderUniformTexelBufferArrayNonUniformIndexing = true;
|
|
|
|
|
features->shaderStorageTexelBufferArrayNonUniformIndexing = true;
|
2018-04-11 19:08:30 +02:00
|
|
|
features->descriptorBindingUniformBufferUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingSampledImageUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingStorageImageUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingStorageBufferUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingUniformTexelBufferUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingStorageTexelBufferUpdateAfterBind = true;
|
|
|
|
|
features->descriptorBindingUpdateUnusedWhilePending = true;
|
|
|
|
|
features->descriptorBindingPartiallyBound = true;
|
|
|
|
|
features->descriptorBindingVariableDescriptorCount = true;
|
|
|
|
|
features->runtimeDescriptorArray = true;
|
|
|
|
|
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;
|
|
|
|
|
features->vertexAttributeInstanceRateDivisor = VK_TRUE;
|
|
|
|
|
features->vertexAttributeInstanceRateZeroDivisor = VK_TRUE;
|
|
|
|
|
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;
|
|
|
|
|
features->geometryStreams = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-12-05 13:48:36 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
|
|
|
|
|
VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =
|
|
|
|
|
(VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)ext;
|
2019-05-14 22:16:20 -04:00
|
|
|
features->scalarBlockLayout = pdevice->rad_info.chip_class >= GFX7;
|
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;
|
|
|
|
|
features->memoryPriority = VK_TRUE;
|
|
|
|
|
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-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;
|
|
|
|
|
}
|
2018-11-17 18:39:24 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
|
|
|
|
|
VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
|
|
|
|
|
(VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
|
|
|
|
|
features->hostQueryReset = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-12-06 13:33:48 +00:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
|
|
|
|
|
VkPhysicalDevice8BitStorageFeaturesKHR *features =
|
|
|
|
|
(VkPhysicalDevice8BitStorageFeaturesKHR*)ext;
|
2019-05-14 22:16:20 -04:00
|
|
|
bool enabled = pdevice->rad_info.chip_class >= GFX8;
|
2018-12-06 13:33:48 +00:00
|
|
|
features->storageBuffer8BitAccess = enabled;
|
|
|
|
|
features->uniformAndStorageBuffer8BitAccess = enabled;
|
|
|
|
|
features->storagePushConstant8 = enabled;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-04-01 16:18:11 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR: {
|
|
|
|
|
VkPhysicalDeviceFloat16Int8FeaturesKHR *features =
|
|
|
|
|
(VkPhysicalDeviceFloat16Int8FeaturesKHR*)ext;
|
2019-05-14 22:16:20 -04:00
|
|
|
features->shaderFloat16 = pdevice->rad_info.chip_class >= GFX8 && HAVE_LLVM >= 0x0800;
|
2019-04-15 17:42:20 +02:00
|
|
|
features->shaderInt8 = true;
|
2019-04-01 16:18:11 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2019-04-16 10:38:24 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
|
|
|
|
|
VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features =
|
|
|
|
|
(VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)ext;
|
2019-08-02 02:16:23 +02:00
|
|
|
features->shaderBufferInt64Atomics = HAVE_LLVM >= 0x0900;
|
|
|
|
|
features->shaderSharedInt64Atomics = HAVE_LLVM >= 0x0900;
|
2019-04-16 10:38:24 +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-05-13 18:43:55 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
|
|
|
|
|
VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
|
|
|
|
|
(VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
|
|
|
|
|
features->uniformBufferStandardLayout = true;
|
|
|
|
|
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;
|
|
|
|
|
}
|
2017-07-19 23:55:58 +02:00
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-11 02:27:21 +00:00
|
|
|
return radv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
void radv_GetPhysicalDeviceProperties(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkPhysicalDeviceProperties* pProperties)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
|
|
|
|
|
VkSampleCountFlags sample_counts = 0xf;
|
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. */
|
|
|
|
|
size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS) /
|
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 */);
|
|
|
|
|
|
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),
|
|
|
|
|
.maxTexelBufferElements = 128 * 1024 * 1024,
|
|
|
|
|
.maxUniformBufferRange = UINT32_MAX,
|
|
|
|
|
.maxStorageBufferRange = UINT32_MAX,
|
|
|
|
|
.maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
|
|
|
|
|
.maxMemoryAllocationCount = UINT32_MAX,
|
|
|
|
|
.maxSamplerAllocationCount = 64 * 1024,
|
|
|
|
|
.bufferImageGranularity = 64, /* A cache line */
|
2017-01-31 23:59:02 +01:00
|
|
|
.sparseAddressSpaceSize = 0xffffffffu, /* 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 },
|
2016-12-18 21:09:28 +01:00
|
|
|
.maxComputeWorkGroupInvocations = 2048,
|
2016-10-07 09:16:09 +10:00
|
|
|
.maxComputeWorkGroupSize = {
|
2016-12-18 21:09:28 +01:00
|
|
|
2048,
|
|
|
|
|
2048,
|
|
|
|
|
2048
|
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 */
|
|
|
|
|
.minTexelBufferOffsetAlignment = 1,
|
|
|
|
|
.minUniformBufferOffsetAlignment = 4,
|
|
|
|
|
.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,
|
|
|
|
|
.sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
|
|
|
|
|
.sampledImageDepthSampleCounts = sample_counts,
|
|
|
|
|
.sampledImageStencilSampleCounts = sample_counts,
|
2019-05-14 22:16:20 -04:00
|
|
|
.storageImageSampleCounts = pdevice->rad_info.chip_class >= GFX8 ? sample_counts : VK_SAMPLE_COUNT_1_BIT,
|
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,
|
2019-03-11 10:25:53 +01:00
|
|
|
.pointSizeRange = { 0.0, 8192.0 },
|
2016-10-07 09:16:09 +10:00
|
|
|
.lineWidthRange = { 0.0, 7.9921875 },
|
|
|
|
|
.pointSizeGranularity = (1.0 / 8.0),
|
|
|
|
|
.lineWidthGranularity = (1.0 / 128.0),
|
|
|
|
|
.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,
|
2017-04-14 19:54:35 +03:00
|
|
|
.sparseProperties = {0},
|
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
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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;
|
2017-07-12 18:45:31 -04:00
|
|
|
memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
|
2017-07-15 02:08:01 +02:00
|
|
|
memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
|
|
|
|
|
properties->deviceLUIDValid = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
|
|
|
|
|
VkPhysicalDeviceMultiviewProperties *properties = (VkPhysicalDeviceMultiviewProperties*)ext;
|
2017-08-16 09:20:53 +02:00
|
|
|
properties->maxMultiviewViewCount = MAX_VIEWS;
|
|
|
|
|
properties->maxMultiviewInstanceIndex = INT_MAX;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-01-08 14:30:32 +01:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
|
|
|
|
|
VkPhysicalDevicePointClippingProperties *properties =
|
|
|
|
|
(VkPhysicalDevicePointClippingProperties*)ext;
|
|
|
|
|
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
|
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;
|
|
|
|
|
properties->subgroupSize = 64;
|
|
|
|
|
properties->supportedStages = VK_SHADER_STAGE_ALL;
|
2018-03-06 15:05:13 +01:00
|
|
|
properties->supportedOperations =
|
|
|
|
|
VK_SUBGROUP_FEATURE_BASIC_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_BALLOT_BIT |
|
2018-10-17 16:57:01 +02:00
|
|
|
VK_SUBGROUP_FEATURE_QUAD_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_VOTE_BIT;
|
2019-05-14 22:16:20 -04:00
|
|
|
if (pdevice->rad_info.chip_class >= GFX8) {
|
2018-05-30 08:50:03 +02:00
|
|
|
properties->supportedOperations |=
|
2018-11-07 17:06:27 +01:00
|
|
|
VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
|
2018-05-30 08:50:03 +02:00
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
|
|
|
|
|
VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
|
|
|
|
|
}
|
2018-03-06 15:05:13 +01:00
|
|
|
properties->quadOperationsInAllStages = true;
|
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;
|
|
|
|
|
/* Make sure everything is addressable by a signed 32-bit int, and
|
|
|
|
|
* our largest descriptors are 96 bytes. */
|
|
|
|
|
properties->maxPerSetDescriptors = (1ull << 31) / 96;
|
|
|
|
|
/* Our buffer size fields allow only this much */
|
|
|
|
|
properties->maxMemoryAllocationSize = 0xFFFFFFFFull;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-03-25 20:05:42 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;
|
|
|
|
|
/* GFX6-8 only support single channel min/max filter. */
|
|
|
|
|
properties->filterMinmaxImageComponentMapping = pdevice->rad_info.chip_class >= GFX9;
|
|
|
|
|
properties->filterMinmaxSingleComponentFormats = true;
|
|
|
|
|
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 =
|
|
|
|
|
pdevice->rad_info.max_sh_per_se;
|
|
|
|
|
properties->computeUnitsPerShaderArray =
|
2018-10-29 11:37:01 +01:00
|
|
|
pdevice->rad_info.num_good_cu_per_sh;
|
2018-04-06 12:40:33 +02:00
|
|
|
properties->simdPerComputeUnit = 4;
|
|
|
|
|
properties->wavefrontsPerSimd =
|
|
|
|
|
pdevice->rad_info.family == CHIP_TONGA ||
|
|
|
|
|
pdevice->rad_info.family == CHIP_ICELAND ||
|
|
|
|
|
pdevice->rad_info.family == CHIP_POLARIS10 ||
|
|
|
|
|
pdevice->rad_info.family == CHIP_POLARIS11 ||
|
2018-04-19 06:35:08 +02:00
|
|
|
pdevice->rad_info.family == CHIP_POLARIS12 ||
|
|
|
|
|
pdevice->rad_info.family == CHIP_VEGAM ? 8 : 10;
|
2018-04-06 12:40:33 +02:00
|
|
|
properties->wavefrontSize = 64;
|
|
|
|
|
|
|
|
|
|
/* SGPR. */
|
|
|
|
|
properties->sgprsPerSimd =
|
2019-02-01 21:16:54 +11:00
|
|
|
ac_get_num_physical_sgprs(pdevice->rad_info.chip_class);
|
2018-04-06 12:40:33 +02:00
|
|
|
properties->minSgprAllocation =
|
2019-05-14 22:16:20 -04:00
|
|
|
pdevice->rad_info.chip_class >= GFX8 ? 16 : 8;
|
2018-04-06 12:40:33 +02:00
|
|
|
properties->maxSgprAllocation =
|
|
|
|
|
pdevice->rad_info.family == CHIP_TONGA ||
|
|
|
|
|
pdevice->rad_info.family == CHIP_ICELAND ? 96 : 104;
|
|
|
|
|
properties->sgprAllocationGranularity =
|
2019-05-14 22:16:20 -04:00
|
|
|
pdevice->rad_info.chip_class >= GFX8 ? 16 : 8;
|
2018-04-06 12:40:33 +02:00
|
|
|
|
|
|
|
|
/* VGPR. */
|
|
|
|
|
properties->vgprsPerSimd = RADV_NUM_PHYSICAL_VGPRS;
|
|
|
|
|
properties->minVgprAllocation = 4;
|
|
|
|
|
properties->maxVgprAllocation = 256;
|
|
|
|
|
properties->vgprAllocationGranularity = 4;
|
|
|
|
|
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;
|
|
|
|
|
}
|
2018-04-11 19:08:30 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT: {
|
|
|
|
|
VkPhysicalDeviceDescriptorIndexingPropertiesEXT *properties =
|
|
|
|
|
(VkPhysicalDeviceDescriptorIndexingPropertiesEXT*)ext;
|
|
|
|
|
properties->maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX / 64;
|
|
|
|
|
properties->shaderUniformBufferArrayNonUniformIndexingNative = false;
|
|
|
|
|
properties->shaderSampledImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
properties->shaderStorageBufferArrayNonUniformIndexingNative = false;
|
|
|
|
|
properties->shaderStorageImageArrayNonUniformIndexingNative = false;
|
|
|
|
|
properties->shaderInputAttachmentArrayNonUniformIndexingNative = false;
|
|
|
|
|
properties->robustBufferAccessUpdateAfterBind = false;
|
|
|
|
|
properties->quadDivergentImplicitLod = false;
|
|
|
|
|
|
2019-03-14 11:20:53 +01:00
|
|
|
size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS -
|
|
|
|
|
MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
|
2018-04-11 19:08:30 +02:00
|
|
|
(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 */);
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindSamplers = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindSampledImages = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindStorageImages = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
|
|
|
|
|
properties->maxPerStageUpdateAfterBindResources = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindSamplers = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindUniformBuffers = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindStorageBuffers = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindSampledImages = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
|
|
|
|
|
properties->maxDescriptorSetUpdateAfterBindInputAttachments = max_descriptor_set_size;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2018-08-30 11:43:47 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
|
|
|
|
|
VkPhysicalDeviceProtectedMemoryProperties *properties =
|
|
|
|
|
(VkPhysicalDeviceProtectedMemoryProperties *)ext;
|
|
|
|
|
properties->protectedNoFault = false;
|
|
|
|
|
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;
|
|
|
|
|
properties->primitiveUnderestimation = VK_FALSE;
|
|
|
|
|
properties->conservativePointAndLineRasterization = VK_FALSE;
|
|
|
|
|
properties->degenerateTrianglesRasterized = VK_FALSE;
|
|
|
|
|
properties->degenerateLinesRasterized = VK_FALSE;
|
|
|
|
|
properties->fullyCoveredFragmentShaderInputVariable = VK_FALSE;
|
|
|
|
|
properties->conservativeRasterizationPostDepthCoverage = VK_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
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;
|
|
|
|
|
}
|
2018-09-30 20:02:04 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDeviceDriverPropertiesKHR *driver_props =
|
|
|
|
|
(VkPhysicalDeviceDriverPropertiesKHR *) ext;
|
|
|
|
|
|
|
|
|
|
driver_props->driverID = VK_DRIVER_ID_MESA_RADV_KHR;
|
2019-07-08 17:14:28 +01:00
|
|
|
snprintf(driver_props->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR, "radv");
|
2018-09-30 20:02:04 +02:00
|
|
|
snprintf(driver_props->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,
|
2018-10-25 17:36:30 +01:00
|
|
|
"Mesa " PACKAGE_VERSION MESA_GIT_SHA1
|
2019-03-14 13:58:54 +00:00
|
|
|
" (LLVM " MESA_LLVM_VERSION_STRING ")");
|
2018-09-30 20:02:04 +02:00
|
|
|
|
|
|
|
|
driver_props->conformanceVersion = (VkConformanceVersionKHR) {
|
|
|
|
|
.major = 1,
|
|
|
|
|
.minor = 1,
|
|
|
|
|
.subminor = 2,
|
|
|
|
|
.patch = 0,
|
|
|
|
|
};
|
|
|
|
|
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;
|
|
|
|
|
properties->maxTransformFeedbackBufferDataSize = UINT32_MAX;
|
|
|
|
|
properties->maxTransformFeedbackBufferDataStride = 512;
|
|
|
|
|
properties->transformFeedbackQueries = true;
|
2019-05-30 10:08:48 +02:00
|
|
|
properties->transformFeedbackStreamsLinesTriangles = true;
|
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;
|
|
|
|
|
properties->sampleLocationSampleCounts = VK_SAMPLE_COUNT_2_BIT |
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT |
|
|
|
|
|
VK_SAMPLE_COUNT_8_BIT;
|
|
|
|
|
properties->maxSampleLocationGridSize = (VkExtent2D){ 2 , 2 };
|
|
|
|
|
properties->sampleLocationCoordinateRange[0] = 0.0f;
|
|
|
|
|
properties->sampleLocationCoordinateRange[1] = 0.9375f;
|
|
|
|
|
properties->sampleLocationSubPixelBits = 4;
|
|
|
|
|
properties->variableSampleLocations = VK_FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2019-05-20 11:46:33 +02:00
|
|
|
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR: {
|
|
|
|
|
VkPhysicalDeviceDepthStencilResolvePropertiesKHR *properties =
|
|
|
|
|
(VkPhysicalDeviceDepthStencilResolvePropertiesKHR *)ext;
|
|
|
|
|
|
|
|
|
|
/* We support all of the depth resolve modes */
|
|
|
|
|
properties->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 */
|
|
|
|
|
properties->supportedStencilResolveModes =
|
|
|
|
|
VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |
|
|
|
|
|
VK_RESOLVE_MODE_MIN_BIT_KHR |
|
|
|
|
|
VK_RESOLVE_MODE_MAX_BIT_KHR;
|
|
|
|
|
|
|
|
|
|
properties->independentResolveNone = VK_TRUE;
|
|
|
|
|
properties->independentResolve = VK_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;
|
2017-05-12 01:11:27 +02:00
|
|
|
if (pdevice->rad_info.num_compute_rings > 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++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-12 01:11:27 +02:00
|
|
|
if (pdevice->rad_info.num_compute_rings > 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,
|
2017-05-12 01:11:27 +02:00
|
|
|
.queueCount = pdevice->rad_info.num_compute_rings,
|
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;
|
|
|
|
|
uint64_t visible_vram_size = radv_get_visible_vram_size(device);
|
|
|
|
|
uint64_t vram_size = radv_get_vram_size(device);
|
|
|
|
|
uint64_t gtt_size = device->rad_info.gart_size;
|
|
|
|
|
uint64_t heap_budget, heap_usage;
|
|
|
|
|
|
|
|
|
|
/* 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).
|
|
|
|
|
*/
|
2019-06-12 09:44:29 +02:00
|
|
|
for (int i = 0; i < device->memory_properties.memoryTypeCount; i++) {
|
|
|
|
|
uint32_t heap_index = device->memory_properties.memoryTypes[i].heapIndex;
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
switch (device->mem_type_indices[i]) {
|
|
|
|
|
case RADV_MEM_TYPE_VRAM:
|
|
|
|
|
heap_usage = device->ws->query_value(device->ws,
|
|
|
|
|
RADEON_ALLOCATED_VRAM);
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
heap_budget = vram_size -
|
|
|
|
|
device->ws->query_value(device->ws, RADEON_VRAM_USAGE) +
|
|
|
|
|
heap_usage;
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
memoryBudget->heapBudget[heap_index] = heap_budget;
|
|
|
|
|
memoryBudget->heapUsage[heap_index] = heap_usage;
|
|
|
|
|
break;
|
|
|
|
|
case RADV_MEM_TYPE_VRAM_CPU_ACCESS:
|
|
|
|
|
heap_usage = device->ws->query_value(device->ws,
|
|
|
|
|
RADEON_ALLOCATED_VRAM_VIS);
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
heap_budget = visible_vram_size -
|
|
|
|
|
device->ws->query_value(device->ws, RADEON_VRAM_VIS_USAGE) +
|
|
|
|
|
heap_usage;
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
memoryBudget->heapBudget[heap_index] = heap_budget;
|
|
|
|
|
memoryBudget->heapUsage[heap_index] = heap_usage;
|
|
|
|
|
break;
|
|
|
|
|
case RADV_MEM_TYPE_GTT_WRITE_COMBINE:
|
|
|
|
|
heap_usage = device->ws->query_value(device->ws,
|
|
|
|
|
RADEON_ALLOCATED_GTT);
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
heap_budget = gtt_size -
|
|
|
|
|
device->ws->query_value(device->ws, RADEON_GTT_USAGE) +
|
|
|
|
|
heap_usage;
|
2019-01-09 14:40:00 +01:00
|
|
|
|
2019-06-12 09:44:29 +02:00
|
|
|
memoryBudget->heapBudget[heap_index] = heap_budget;
|
|
|
|
|
memoryBudget->heapUsage[heap_index] = heap_usage;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
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++) {
|
|
|
|
|
if (physical_device->mem_type_indices[i] == RADV_MEM_TYPE_GTT_CACHED) {
|
|
|
|
|
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->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
|
|
|
|
|
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
|
|
|
|
2017-10-20 18:02:14 -04:00
|
|
|
queue->hw_ctx = device->ws->ctx_create(device->ws, queue->priority);
|
2017-01-13 18:44:15 -05:00
|
|
|
if (!queue->hw_ctx)
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
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)
|
|
|
|
|
{
|
2017-01-13 18:44:15 -05:00
|
|
|
if (queue->hw_ctx)
|
|
|
|
|
queue->device->ws->ctx_destroy(queue->hw_ctx);
|
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);
|
2017-01-29 13:53:05 +01:00
|
|
|
if (queue->compute_scratch_bo)
|
|
|
|
|
queue->device->ws->buffer_destroy(queue->compute_scratch_bo);
|
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)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_init(&bo_list->mutex, NULL);
|
|
|
|
|
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);
|
|
|
|
|
pthread_mutex_destroy(&bo_list->mutex);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
static 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;
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
pthread_mutex_lock(&bo_list->mutex);
|
|
|
|
|
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) {
|
|
|
|
|
pthread_mutex_unlock(&bo_list->mutex);
|
|
|
|
|
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;
|
|
|
|
|
pthread_mutex_unlock(&bo_list->mutex);
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
static 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;
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
pthread_mutex_lock(&bo_list->mutex);
|
|
|
|
|
for(unsigned i = 0; i < bo_list->list.count; ++i) {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&bo_list->mutex);
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
|
2017-07-24 07:16:40 +01:00
|
|
|
/* Check enabled features */
|
|
|
|
|
if (pCreateInfo->pEnabledFeatures) {
|
|
|
|
|
VkPhysicalDeviceFeatures supported_features;
|
|
|
|
|
radv_GetPhysicalDeviceFeatures(physicalDevice, &supported_features);
|
|
|
|
|
VkBool32 *supported_feature = (VkBool32 *)&supported_features;
|
|
|
|
|
VkBool32 *enabled_feature = (VkBool32 *)pCreateInfo->pEnabledFeatures;
|
|
|
|
|
unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
|
|
|
|
|
for (uint32_t i = 0; i < num_features; i++) {
|
|
|
|
|
if (enabled_feature[i] && !supported_feature[i])
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(physical_device->instance, VK_ERROR_FEATURE_NOT_PRESENT);
|
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
|
|
|
|
|
|
|
|
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
|
|
|
|
|
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;
|
|
|
|
|
if (pAllocator)
|
|
|
|
|
device->alloc = *pAllocator;
|
|
|
|
|
else
|
|
|
|
|
device->alloc = physical_device->instance->alloc;
|
|
|
|
|
|
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]) {
|
|
|
|
|
vk_free(&device->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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 ||
|
|
|
|
|
device->enabled_extensions.EXT_buffer_device_address;
|
2018-04-19 13:48:33 +02:00
|
|
|
|
2017-03-12 22:43:51 +01:00
|
|
|
mtx_init(&device->shader_slab_mutex, mtx_plain);
|
|
|
|
|
list_inithead(&device->shader_slabs);
|
|
|
|
|
|
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);
|
|
|
|
|
|
2016-11-30 04:30:06 +00:00
|
|
|
device->queues[qfi] = vk_alloc(&device->alloc,
|
|
|
|
|
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
|
|
|
|
|
|
|
|
/* Disabled and not implemented for now. */
|
2018-07-14 14:28:23 +02:00
|
|
|
device->dfsm_allowed = device->pbb_allowed &&
|
2018-10-30 11:52:37 +01:00
|
|
|
(device->physical_device->rad_info.family == CHIP_RAVEN ||
|
|
|
|
|
device->physical_device->rad_info.family == CHIP_RAVEN2);
|
2017-12-30 17:31:15 +01:00
|
|
|
|
2018-01-04 18:38:32 +01:00
|
|
|
#ifdef ANDROID
|
|
|
|
|
device->always_use_syncobj = device->physical_device->rad_info.has_syncobj_wait_for_submit;
|
|
|
|
|
#endif
|
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-07-30 18:32:42 +02:00
|
|
|
device->dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1) |
|
|
|
|
|
S_00B800_CS_W32_EN(device->physical_device->cs_wave_size == 32);
|
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;
|
|
|
|
|
device->has_distributed_tess =
|
2019-05-14 22:16:20 -04:00
|
|
|
device->physical_device->rad_info.chip_class >= GFX8 &&
|
2017-03-30 07:58:22 +01:00
|
|
|
device->physical_device->rad_info.max_se >= 2;
|
|
|
|
|
|
2017-09-22 15:16:22 +02:00
|
|
|
if (getenv("RADV_TRACE_FILE")) {
|
2018-03-14 12:02:13 +01:00
|
|
|
const char *filename = getenv("RADV_TRACE_FILE");
|
|
|
|
|
|
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");
|
|
|
|
|
fprintf(stderr, "* WARNING: RADV_TRACE_FILE is costly and should only be used for debugging! *\n");
|
|
|
|
|
fprintf(stderr, "*****************************************************************************\n");
|
|
|
|
|
|
2018-03-14 12:02:13 +01:00
|
|
|
fprintf(stderr, "Trace file will be dumped to %s\n", filename);
|
|
|
|
|
radv_dump_enabled_options(device, stderr);
|
2017-09-22 15:16:22 +02:00
|
|
|
}
|
|
|
|
|
|
2017-10-27 14:25:05 +01: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
|
|
|
|
|
|
|
|
for (int family = 0; family < RADV_MAX_QUEUE_FAMILIES; ++family) {
|
|
|
|
|
device->empty_cs[family] = device->ws->cs_create(device->ws, family);
|
|
|
|
|
switch (family) {
|
|
|
|
|
case RADV_QUEUE_GENERAL:
|
|
|
|
|
radeon_emit(device->empty_cs[family], PKT3(PKT3_CONTEXT_CONTROL, 1, 0));
|
|
|
|
|
radeon_emit(device->empty_cs[family], CONTEXT_CONTROL_LOAD_ENABLE(1));
|
|
|
|
|
radeon_emit(device->empty_cs[family], CONTEXT_CONTROL_SHADOW_ENABLE(1));
|
|
|
|
|
break;
|
|
|
|
|
case RADV_QUEUE_COMPUTE:
|
|
|
|
|
radeon_emit(device->empty_cs[family], PKT3(PKT3_NOP, 0, 0));
|
|
|
|
|
radeon_emit(device->empty_cs[family], 0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
device->ws->cs_finalize(device->empty_cs[family]);
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
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
|
|
|
|
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);
|
|
|
|
|
|
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);
|
|
|
|
|
|
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])
|
|
|
|
|
vk_free(&device->alloc, device->queues[i]);
|
|
|
|
|
}
|
2016-12-23 23:51:18 +01:00
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free(&device->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);
|
|
|
|
|
|
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])
|
|
|
|
|
vk_free(&device->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);
|
|
|
|
|
|
2017-03-12 22:43:51 +01:00
|
|
|
radv_destroy_shader_slabs(device);
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
radv_bo_list_finish(&device->bo_list);
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free(&device->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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(2) |
|
|
|
|
|
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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(2) |
|
|
|
|
|
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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(2) |
|
|
|
|
|
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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(2) |
|
|
|
|
|
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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(3) |
|
|
|
|
|
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) |
|
|
|
|
|
S_008F0C_OOB_SELECT(3) |
|
|
|
|
|
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;
|
2019-05-14 22:16:20 -04:00
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX7) {
|
|
|
|
|
if (device->physical_device->rad_info.chip_class >= GFX8)
|
2017-03-30 08:02:14 +01:00
|
|
|
--max_offchip_buffers;
|
|
|
|
|
hs_offchip_param =
|
|
|
|
|
S_03093C_OFFCHIP_BUFFERING(max_offchip_buffers) |
|
|
|
|
|
S_03093C_OFFCHIP_GRANULARITY(offchip_granularity);
|
|
|
|
|
} 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2018-06-18 21:07:10 -04:00
|
|
|
radv_emit_compute_scratch(struct radv_queue *queue, struct radeon_cmdbuf *cs,
|
2018-05-17 10:11:44 +02:00
|
|
|
struct radeon_winsys_bo *compute_scratch_bo)
|
|
|
|
|
{
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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 {
|
|
|
|
|
struct radv_physical_device *physical_device = device->physical_device;
|
|
|
|
|
si_emit_graphics(physical_device, cs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
radv_init_compute_state(struct radeon_cmdbuf *cs, struct radv_queue *queue)
|
|
|
|
|
{
|
|
|
|
|
struct radv_physical_device *physical_device = queue->device->physical_device;
|
|
|
|
|
si_emit_compute(physical_device, cs);
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-29 13:53:05 +01:00
|
|
|
static VkResult
|
|
|
|
|
radv_get_preamble_cs(struct radv_queue *queue,
|
|
|
|
|
uint32_t scratch_size,
|
|
|
|
|
uint32_t compute_scratch_size,
|
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,
|
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;
|
2018-06-18 21:07:10 -04:00
|
|
|
struct radeon_cmdbuf *dest_cs[3] = {0};
|
2017-04-03 04:38:12 +01:00
|
|
|
bool add_tess_rings = 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;
|
|
|
|
|
}
|
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
|
|
|
|
|
|
|
|
if (scratch_size <= queue->scratch_size &&
|
2017-01-20 11:06:52 +10:00
|
|
|
compute_scratch_size <= queue->compute_scratch_size &&
|
|
|
|
|
esgs_ring_size <= queue->esgs_ring_size &&
|
2017-02-20 09:26:00 +01:00
|
|
|
gsvs_ring_size <= queue->gsvs_ring_size &&
|
2017-04-03 04:38:12 +01:00
|
|
|
!add_tess_rings && !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;
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (scratch_size > queue->scratch_size) {
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (compute_scratch_size > queue->compute_scratch_size) {
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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) {
|
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);
|
|
|
|
|
radv_emit_compute_scratch(queue, cs, compute_scratch_bo);
|
2017-02-20 09:26:00 +01:00
|
|
|
|
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 |
|
2018-07-11 11:55:55 +02:00
|
|
|
RADV_CMD_FLAG_START_PIPELINE_STATS, 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 |
|
2018-07-11 11:55:55 +02:00
|
|
|
RADV_CMD_FLAG_START_PIPELINE_STATS, 0);
|
2017-02-20 09:26:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!queue->device->ws->cs_finalize(cs))
|
|
|
|
|
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;
|
|
|
|
|
queue->scratch_size = scratch_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
queue->compute_scratch_size = compute_scratch_size;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
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
|
|
|
}
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
static VkResult radv_alloc_sem_counts(struct radv_instance *instance,
|
|
|
|
|
struct radv_winsys_sem_counts *counts,
|
2017-02-27 19:14:00 +00:00
|
|
|
int num_sems,
|
|
|
|
|
const VkSemaphore *sems,
|
2017-11-27 23:58:35 +01:00
|
|
|
VkFence _fence,
|
2017-02-27 19:14:00 +00:00
|
|
|
bool reset_temp)
|
|
|
|
|
{
|
|
|
|
|
int syncobj_idx = 0, sem_idx = 0;
|
|
|
|
|
|
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++) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, sems[i]);
|
|
|
|
|
|
|
|
|
|
if (sem->temp_syncobj || sem->syncobj)
|
|
|
|
|
counts->syncobj_count++;
|
|
|
|
|
else
|
|
|
|
|
counts->sem_count++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
if (_fence != VK_NULL_HANDLE) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
if (fence->temp_syncobj || fence->syncobj)
|
|
|
|
|
counts->syncobj_count++;
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
if (counts->syncobj_count) {
|
|
|
|
|
counts->syncobj = (uint32_t *)malloc(sizeof(uint32_t) * counts->syncobj_count);
|
|
|
|
|
if (!counts->syncobj)
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
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);
|
2018-05-31 01:06:41 +02:00
|
|
|
return vk_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY);
|
2017-02-27 19:14:00 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < num_sems; i++) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, sems[i]);
|
|
|
|
|
|
|
|
|
|
if (sem->temp_syncobj) {
|
|
|
|
|
counts->syncobj[syncobj_idx++] = sem->temp_syncobj;
|
|
|
|
|
}
|
|
|
|
|
else if (sem->syncobj)
|
|
|
|
|
counts->syncobj[syncobj_idx++] = sem->syncobj;
|
|
|
|
|
else {
|
|
|
|
|
assert(sem->sem);
|
|
|
|
|
counts->sem[sem_idx++] = sem->sem;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
if (_fence != VK_NULL_HANDLE) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
if (fence->temp_syncobj)
|
|
|
|
|
counts->syncobj[syncobj_idx++] = fence->temp_syncobj;
|
|
|
|
|
else if (fence->syncobj)
|
|
|
|
|
counts->syncobj[syncobj_idx++] = fence->syncobj;
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
{
|
|
|
|
|
free(sem_info->wait.syncobj);
|
|
|
|
|
free(sem_info->wait.sem);
|
|
|
|
|
free(sem_info->signal.syncobj);
|
|
|
|
|
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,
|
|
|
|
|
const VkSemaphore *sems)
|
|
|
|
|
{
|
|
|
|
|
for (uint32_t i = 0; i < num_sems; i++) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_semaphore, sem, sems[i]);
|
|
|
|
|
|
|
|
|
|
if (sem->temp_syncobj) {
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, sem->temp_syncobj);
|
|
|
|
|
sem->temp_syncobj = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-31 00:57:55 +02:00
|
|
|
static VkResult
|
2018-05-31 01:06:41 +02:00
|
|
|
radv_alloc_sem_info(struct radv_instance *instance,
|
|
|
|
|
struct radv_winsys_sem_info *sem_info,
|
2018-05-31 00:57:55 +02:00
|
|
|
int num_wait_sems,
|
|
|
|
|
const VkSemaphore *wait_sems,
|
|
|
|
|
int num_signal_sems,
|
|
|
|
|
const VkSemaphore *signal_sems,
|
|
|
|
|
VkFence fence)
|
2017-02-27 19:14:00 +00:00
|
|
|
{
|
|
|
|
|
VkResult ret;
|
|
|
|
|
memset(sem_info, 0, sizeof(*sem_info));
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
ret = radv_alloc_sem_counts(instance, &sem_info->wait, num_wait_sems, wait_sems, VK_NULL_HANDLE, true);
|
2017-02-27 19:14:00 +00:00
|
|
|
if (ret)
|
|
|
|
|
return ret;
|
2018-05-31 01:06:41 +02:00
|
|
|
ret = radv_alloc_sem_counts(instance, &sem_info->signal, num_signal_sems, signal_sems, fence, false);
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-27 14:51:12 +01:00
|
|
|
/* Signals fence as soon as all the work currently put on queue is done. */
|
|
|
|
|
static VkResult radv_signal_fence(struct radv_queue *queue,
|
|
|
|
|
struct radv_fence *fence)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
VkResult result;
|
|
|
|
|
struct radv_winsys_sem_info sem_info;
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
result = radv_alloc_sem_info(queue->device->instance, &sem_info, 0, NULL, 0, NULL,
|
2018-01-27 14:51:12 +01:00
|
|
|
radv_fence_to_handle(fence));
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
ret = queue->device->ws->cs_submit(queue->hw_ctx, queue->queue_idx,
|
|
|
|
|
&queue->device->empty_cs[queue->queue_family_index],
|
2018-04-09 12:46:49 +02:00
|
|
|
1, NULL, NULL, &sem_info, NULL,
|
2018-01-27 14:51:12 +01:00
|
|
|
false, fence->fence);
|
|
|
|
|
radv_free_sem_info(&sem_info);
|
|
|
|
|
|
|
|
|
|
if (ret)
|
2018-06-21 14:39:28 +02:00
|
|
|
return vk_error(queue->device->instance, VK_ERROR_DEVICE_LOST);
|
2018-01-27 14:51:12 +01:00
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
VkResult radv_QueueSubmit(
|
|
|
|
|
VkQueue _queue,
|
|
|
|
|
uint32_t submitCount,
|
|
|
|
|
const VkSubmitInfo* pSubmits,
|
|
|
|
|
VkFence _fence)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
|
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
struct radeon_winsys_fence *base_fence = fence ? fence->fence : NULL;
|
2017-01-13 18:44:15 -05:00
|
|
|
struct radeon_winsys_ctx *ctx = queue->hw_ctx;
|
2016-10-07 09:16:09 +10:00
|
|
|
int ret;
|
2019-03-12 21:49:42 +01:00
|
|
|
uint32_t max_cs_submission = queue->device->trace_bo ? 1 : RADV_MAX_IBS_PER_SUBMIT;
|
2017-01-29 13:53:05 +01:00
|
|
|
uint32_t scratch_size = 0;
|
|
|
|
|
uint32_t compute_scratch_size = 0;
|
2017-01-20 11:06:52 +10:00
|
|
|
uint32_t esgs_ring_size = 0, gsvs_ring_size = 0;
|
2018-06-18 21:07:10 -04:00
|
|
|
struct radeon_cmdbuf *initial_preamble_cs = NULL, *initial_flush_preamble_cs = NULL, *continue_preamble_cs = NULL;
|
2017-01-29 13:53:05 +01:00
|
|
|
VkResult result;
|
2017-02-09 03:24:05 +00:00
|
|
|
bool fence_emitted = false;
|
2017-03-30 08:02:14 +01:00
|
|
|
bool tess_rings_needed = false;
|
2017-04-03 04:38:12 +01:00
|
|
|
bool sample_positions_needed = false;
|
2017-01-29 13:53:05 +01:00
|
|
|
|
|
|
|
|
/* Do this first so failing to allocate scratch buffers can't result in
|
|
|
|
|
* partially executed submissions. */
|
|
|
|
|
for (uint32_t i = 0; i < submitCount; i++) {
|
|
|
|
|
for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer,
|
|
|
|
|
pSubmits[i].pCommandBuffers[j]);
|
|
|
|
|
|
|
|
|
|
scratch_size = MAX2(scratch_size, cmd_buffer->scratch_size_needed);
|
|
|
|
|
compute_scratch_size = MAX2(compute_scratch_size,
|
|
|
|
|
cmd_buffer->compute_scratch_size_needed);
|
2017-01-20 11:06:52 +10: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);
|
2017-03-30 08:02:14 +01:00
|
|
|
tess_rings_needed |= cmd_buffer->tess_rings_needed;
|
2017-04-03 04:38:12 +01:00
|
|
|
sample_positions_needed |= cmd_buffer->sample_positions_needed;
|
2017-01-29 13:53:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-20 09:26:00 +01:00
|
|
|
result = radv_get_preamble_cs(queue, scratch_size, compute_scratch_size,
|
2017-03-30 08:02:14 +01:00
|
|
|
esgs_ring_size, gsvs_ring_size, tess_rings_needed,
|
2017-09-02 12:59:55 +02:00
|
|
|
sample_positions_needed, &initial_flush_preamble_cs,
|
2017-02-20 09:26:00 +01:00
|
|
|
&initial_preamble_cs, &continue_preamble_cs);
|
2017-01-29 13:53:05 +01:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < submitCount; i++) {
|
2018-06-18 21:07:10 -04:00
|
|
|
struct radeon_cmdbuf **cs_array;
|
2017-05-03 07:13:21 +10:00
|
|
|
bool do_flush = !i || pSubmits[i].pWaitDstStageMask;
|
2017-09-02 12:59:55 +02:00
|
|
|
bool can_patch = true;
|
2016-12-23 23:51:18 +01:00
|
|
|
uint32_t advance;
|
2017-02-27 19:14:00 +00:00
|
|
|
struct radv_winsys_sem_info sem_info;
|
|
|
|
|
|
2018-05-31 01:06:41 +02:00
|
|
|
result = radv_alloc_sem_info(queue->device->instance,
|
|
|
|
|
&sem_info,
|
2017-02-27 19:14:00 +00:00
|
|
|
pSubmits[i].waitSemaphoreCount,
|
|
|
|
|
pSubmits[i].pWaitSemaphores,
|
|
|
|
|
pSubmits[i].signalSemaphoreCount,
|
2017-11-27 23:58:35 +01:00
|
|
|
pSubmits[i].pSignalSemaphores,
|
|
|
|
|
_fence);
|
2017-02-27 19:14:00 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2017-02-20 08:44:58 +10:00
|
|
|
if (!pSubmits[i].commandBufferCount) {
|
2017-02-09 03:24:05 +00:00
|
|
|
if (pSubmits[i].waitSemaphoreCount || pSubmits[i].signalSemaphoreCount) {
|
|
|
|
|
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx,
|
|
|
|
|
&queue->device->empty_cs[queue->queue_family_index],
|
2017-02-20 09:08:31 +01:00
|
|
|
1, NULL, NULL,
|
2018-04-09 12:46:49 +02:00
|
|
|
&sem_info, NULL,
|
2017-02-09 03:24:05 +00:00
|
|
|
false, base_fence);
|
|
|
|
|
if (ret) {
|
|
|
|
|
radv_loge("failed to submit CS %d\n", i);
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
fence_emitted = true;
|
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
radv_free_sem_info(&sem_info);
|
2016-10-07 09:16:09 +10:00
|
|
|
continue;
|
2017-02-09 03:24:05 +00:00
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2018-06-18 21:07:10 -04:00
|
|
|
cs_array = malloc(sizeof(struct radeon_cmdbuf *) *
|
2017-09-02 12:59:55 +02:00
|
|
|
(pSubmits[i].commandBufferCount));
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {
|
|
|
|
|
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer,
|
|
|
|
|
pSubmits[i].pCommandBuffers[j]);
|
|
|
|
|
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
|
|
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
cs_array[j] = cmd_buffer->cs;
|
2016-10-07 09:16:09 +10:00
|
|
|
if ((cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT))
|
|
|
|
|
can_patch = false;
|
2017-12-06 17:48:40 +01:00
|
|
|
|
|
|
|
|
cmd_buffer->status = RADV_CMD_BUFFER_STATUS_PENDING;
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
2016-12-23 23:51:18 +01:00
|
|
|
|
2017-09-02 12:59:55 +02:00
|
|
|
for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j += advance) {
|
2018-06-18 21:07:10 -04:00
|
|
|
struct radeon_cmdbuf *initial_preamble = (do_flush && !j) ? initial_flush_preamble_cs : initial_preamble_cs;
|
2018-05-17 11:36:09 +02:00
|
|
|
const struct radv_winsys_bo_list *bo_list = NULL;
|
|
|
|
|
|
2016-12-23 23:51:18 +01:00
|
|
|
advance = MIN2(max_cs_submission,
|
2017-09-02 12:59:55 +02:00
|
|
|
pSubmits[i].commandBufferCount - j);
|
2016-12-23 23:51:18 +01:00
|
|
|
|
|
|
|
|
if (queue->device->trace_bo)
|
|
|
|
|
*queue->device->trace_id_ptr = 0;
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
sem_info.cs_emit_wait = j == 0;
|
2017-09-02 12:59:55 +02:00
|
|
|
sem_info.cs_emit_signal = j + advance == pSubmits[i].commandBufferCount;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
2018-05-17 11:36:09 +02:00
|
|
|
if (unlikely(queue->device->use_global_bo_list)) {
|
2018-04-19 13:48:33 +02:00
|
|
|
pthread_mutex_lock(&queue->device->bo_list.mutex);
|
2018-05-17 11:36:09 +02:00
|
|
|
bo_list = &queue->device->bo_list.list;
|
|
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
2017-01-27 00:19:52 +01:00
|
|
|
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, cs_array + j,
|
2017-09-02 12:59:55 +02:00
|
|
|
advance, initial_preamble, continue_preamble_cs,
|
2018-05-17 11:36:09 +02:00
|
|
|
&sem_info, bo_list,
|
2016-12-23 23:51:18 +01:00
|
|
|
can_patch, base_fence);
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
if (unlikely(queue->device->use_global_bo_list))
|
|
|
|
|
pthread_mutex_unlock(&queue->device->bo_list.mutex);
|
2018-04-09 12:46:49 +02:00
|
|
|
|
2016-12-23 23:51:18 +01:00
|
|
|
if (ret) {
|
|
|
|
|
radv_loge("failed to submit CS %d\n", i);
|
|
|
|
|
abort();
|
|
|
|
|
}
|
2017-02-09 03:24:05 +00:00
|
|
|
fence_emitted = true;
|
2016-12-23 23:51:18 +01:00
|
|
|
if (queue->device->trace_bo) {
|
2017-09-01 09:44:45 +02:00
|
|
|
radv_check_gpu_hangs(queue, cs_array[j]);
|
2016-12-23 23:51:18 +01:00
|
|
|
}
|
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
2017-11-13 23:26:32 +01:00
|
|
|
radv_free_temp_syncobjs(queue->device,
|
|
|
|
|
pSubmits[i].waitSemaphoreCount,
|
|
|
|
|
pSubmits[i].pWaitSemaphores);
|
2017-02-27 19:14:00 +00:00
|
|
|
radv_free_sem_info(&sem_info);
|
2016-10-07 09:16:09 +10:00
|
|
|
free(cs_array);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fence) {
|
2017-02-27 19:14:00 +00:00
|
|
|
if (!fence_emitted) {
|
2018-06-21 14:39:29 +02:00
|
|
|
result = radv_signal_fence(queue, fence);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2017-02-27 19:14:00 +00:00
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult radv_QueueWaitIdle(
|
|
|
|
|
VkQueue _queue)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
|
|
|
|
|
2017-01-13 18:44:15 -05:00
|
|
|
queue->device->ws->ctx_wait_idle(queue->hw_ctx,
|
2016-12-17 19:10:35 +01:00
|
|
|
radv_queue_family_to_ring(queue->queue_family_index),
|
|
|
|
|
queue->queue_idx);
|
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++) {
|
|
|
|
|
radv_QueueWaitIdle(radv_queue_to_handle(&device->queues[i][q]));
|
|
|
|
|
}
|
|
|
|
|
}
|
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)
|
|
|
|
|
{
|
|
|
|
|
VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < RADV_INSTANCE_EXTENSION_COUNT; i++) {
|
|
|
|
|
if (radv_supported_instance_extensions.extensions[i]) {
|
|
|
|
|
vk_outarray_append(&out, prop) {
|
|
|
|
|
*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);
|
|
|
|
|
VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < RADV_DEVICE_EXTENSION_COUNT; i++) {
|
|
|
|
|
if (device->supported_extensions.extensions[i]) {
|
|
|
|
|
vk_outarray_append(&out, prop) {
|
|
|
|
|
*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);
|
|
|
|
|
|
|
|
|
|
return radv_lookup_entrypoint_checked(pName,
|
|
|
|
|
instance ? instance->apiVersion : 0,
|
|
|
|
|
instance ? &instance->enabled_extensions : NULL,
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
PUBLIC
|
|
|
|
|
VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vk_icdGetPhysicalDeviceProcAddr(
|
|
|
|
|
VkInstance _instance,
|
|
|
|
|
const char* pName)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_instance, instance, _instance);
|
|
|
|
|
|
|
|
|
|
return radv_lookup_physical_device_entrypoint_checked(pName,
|
|
|
|
|
instance ? instance->apiVersion : 0,
|
|
|
|
|
instance ? &instance->enabled_extensions : NULL);
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
return radv_lookup_entrypoint_checked(pName,
|
|
|
|
|
device->instance->apiVersion,
|
|
|
|
|
&device->instance->enabled_extensions,
|
|
|
|
|
&device->enabled_extensions);
|
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)
|
|
|
|
|
{
|
|
|
|
|
struct radeon_bo_metadata metadata;
|
|
|
|
|
|
|
|
|
|
if (memory->image) {
|
|
|
|
|
radv_init_metadata(device, memory->image, &metadata);
|
|
|
|
|
device->ws->buffer_set_metadata(memory->bo, &metadata);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return device->ws->buffer_get_fd(device->ws, memory->bo,
|
|
|
|
|
pFD);
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2017-11-01 09:26:48 +01:00
|
|
|
enum radv_mem_type mem_type_index = device->physical_device->mem_type_indices[pAllocateInfo->memoryTypeIndex];
|
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);
|
|
|
|
|
|
|
|
|
|
if (pAllocateInfo->allocationSize == 0) {
|
|
|
|
|
/* Apparently, this is allowed */
|
|
|
|
|
*pMem = VK_NULL_HANDLE;
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
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);
|
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);
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
mem = vk_alloc2(&device->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
|
|
|
|
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;
|
|
|
|
|
|
2017-07-15 02:08:01 +02:00
|
|
|
if (import_info) {
|
|
|
|
|
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-01-28 02:09:07 +01:00
|
|
|
priority, NULL, 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);
|
|
|
|
|
}
|
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);
|
|
|
|
|
assert(mem_type_index == RADV_MEM_TYPE_GTT_CACHED);
|
|
|
|
|
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);
|
|
|
|
|
if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE ||
|
|
|
|
|
mem_type_index == RADV_MEM_TYPE_GTT_CACHED)
|
|
|
|
|
domain = RADEON_DOMAIN_GTT;
|
|
|
|
|
else
|
|
|
|
|
domain = RADEON_DOMAIN_VRAM;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
if (mem_type_index == RADV_MEM_TYPE_VRAM)
|
|
|
|
|
flags |= RADEON_FLAG_NO_CPU_ACCESS;
|
|
|
|
|
else
|
|
|
|
|
flags |= RADEON_FLAG_CPU_ACCESS;
|
2016-10-26 02:57:19 +02:00
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE)
|
|
|
|
|
flags |= RADEON_FLAG_GTT_WC;
|
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
|
|
|
|
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) {
|
|
|
|
|
result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
|
|
|
|
|
goto fail;
|
|
|
|
|
}
|
|
|
|
|
mem->type_index = mem_type_index;
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
2018-04-09 12:46:49 +02:00
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
result = radv_bo_list_add(device, mem->bo);
|
2018-04-09 12:46:49 +02:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
goto fail_bo;
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
*pMem = radv_device_memory_to_handle(mem);
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
|
2018-04-09 12:46:49 +02:00
|
|
|
fail_bo:
|
|
|
|
|
device->ws->buffer_destroy(mem->bo);
|
2016-10-07 09:16:09 +10:00
|
|
|
fail:
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, 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);
|
|
|
|
|
|
|
|
|
|
if (mem == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2018-04-19 13:48:33 +02:00
|
|
|
radv_bo_list_remove(device, mem->bo);
|
2016-10-07 09:16:09 +10:00
|
|
|
device->ws->buffer_destroy(mem->bo);
|
|
|
|
|
mem->bo = NULL;
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, 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) {
|
|
|
|
|
*ppData += offset;
|
|
|
|
|
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-11-01 23:54:56 +00:00
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
|
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;
|
2017-11-01 23:54:56 +00:00
|
|
|
req->requiresDedicatedAllocation = buffer->shareable;
|
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;
|
2017-07-15 02:08:01 +02:00
|
|
|
req->requiresDedicatedAllocation = image->shareable;
|
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_GetImageSparseMemoryRequirements(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
VkImage image,
|
|
|
|
|
uint32_t* pSparseMemoryRequirementCount,
|
|
|
|
|
VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
|
|
|
|
|
{
|
|
|
|
|
stub();
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-21 13:39:22 +01:00
|
|
|
void radv_GetImageSparseMemoryRequirements2(
|
2017-07-15 02:07:59 +02:00
|
|
|
VkDevice device,
|
2019-01-08 14:30:32 +01:00
|
|
|
const VkImageSparseMemoryRequirementsInfo2 *pInfo,
|
2017-07-15 02:07:59 +02:00
|
|
|
uint32_t* pSparseMemoryRequirementCount,
|
2019-01-08 14:30:32 +01:00
|
|
|
VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
|
2017-07-15 02:07:59 +02:00
|
|
|
{
|
|
|
|
|
stub();
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2017-02-04 15:58:39 +01:00
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
radv_sparse_buffer_bind_memory(struct radv_device *device,
|
|
|
|
|
const VkSparseBufferMemoryBindInfo *bind)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, bind->buffer);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
device->ws->buffer_virtual_bind(buffer->bo,
|
|
|
|
|
bind->pBinds[i].resourceOffset,
|
|
|
|
|
bind->pBinds[i].size,
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
bind->pBinds[i].memoryOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
radv_sparse_image_opaque_bind_memory(struct radv_device *device,
|
|
|
|
|
const VkSparseImageOpaqueMemoryBindInfo *bind)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_image, image, bind->image);
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
device->ws->buffer_virtual_bind(image->bo,
|
|
|
|
|
bind->pBinds[i].resourceOffset,
|
|
|
|
|
bind->pBinds[i].size,
|
|
|
|
|
mem ? mem->bo : NULL,
|
|
|
|
|
bind->pBinds[i].memoryOffset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult radv_QueueBindSparse(
|
|
|
|
|
VkQueue _queue,
|
2016-10-07 09:16:09 +10:00
|
|
|
uint32_t bindInfoCount,
|
|
|
|
|
const VkBindSparseInfo* pBindInfo,
|
2017-02-04 15:58:39 +01:00
|
|
|
VkFence _fence)
|
2016-10-07 09:16:09 +10:00
|
|
|
{
|
2017-02-04 15:58:39 +01:00
|
|
|
RADV_FROM_HANDLE(radv_fence, fence, _fence);
|
|
|
|
|
RADV_FROM_HANDLE(radv_queue, queue, _queue);
|
|
|
|
|
struct radeon_winsys_fence *base_fence = fence ? fence->fence : NULL;
|
|
|
|
|
bool fence_emitted = false;
|
2018-06-21 14:39:29 +02:00
|
|
|
VkResult result;
|
2018-06-21 14:39:30 +02:00
|
|
|
int ret;
|
2017-02-04 15:58:39 +01:00
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < bindInfoCount; ++i) {
|
2017-02-27 19:14:00 +00:00
|
|
|
struct radv_winsys_sem_info sem_info;
|
2017-02-04 15:58:39 +01:00
|
|
|
for (uint32_t j = 0; j < pBindInfo[i].bufferBindCount; ++j) {
|
|
|
|
|
radv_sparse_buffer_bind_memory(queue->device,
|
|
|
|
|
pBindInfo[i].pBufferBinds + j);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (uint32_t j = 0; j < pBindInfo[i].imageOpaqueBindCount; ++j) {
|
|
|
|
|
radv_sparse_image_opaque_bind_memory(queue->device,
|
|
|
|
|
pBindInfo[i].pImageOpaqueBinds + j);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
VkResult result;
|
2018-05-31 01:06:41 +02:00
|
|
|
result = radv_alloc_sem_info(queue->device->instance,
|
|
|
|
|
&sem_info,
|
2017-02-27 19:14:00 +00:00
|
|
|
pBindInfo[i].waitSemaphoreCount,
|
|
|
|
|
pBindInfo[i].pWaitSemaphores,
|
|
|
|
|
pBindInfo[i].signalSemaphoreCount,
|
2017-11-27 23:58:35 +01:00
|
|
|
pBindInfo[i].pSignalSemaphores,
|
|
|
|
|
_fence);
|
2017-02-27 19:14:00 +00:00
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
|
2017-02-04 15:58:39 +01:00
|
|
|
if (pBindInfo[i].waitSemaphoreCount || pBindInfo[i].signalSemaphoreCount) {
|
2018-06-21 14:39:30 +02:00
|
|
|
ret = queue->device->ws->cs_submit(queue->hw_ctx, queue->queue_idx,
|
|
|
|
|
&queue->device->empty_cs[queue->queue_family_index],
|
|
|
|
|
1, NULL, NULL,
|
|
|
|
|
&sem_info, NULL,
|
|
|
|
|
false, base_fence);
|
|
|
|
|
if (ret) {
|
|
|
|
|
radv_loge("failed to submit CS %d\n", i);
|
|
|
|
|
abort();
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-04 15:58:39 +01:00
|
|
|
fence_emitted = true;
|
|
|
|
|
}
|
2017-02-27 19:14:00 +00:00
|
|
|
|
|
|
|
|
radv_free_sem_info(&sem_info);
|
|
|
|
|
|
2017-02-04 15:58:39 +01:00
|
|
|
}
|
|
|
|
|
|
2018-01-27 14:51:12 +01:00
|
|
|
if (fence) {
|
|
|
|
|
if (!fence_emitted) {
|
2018-06-21 14:39:29 +02:00
|
|
|
result = radv_signal_fence(queue, fence);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
2018-01-27 14:51:12 +01:00
|
|
|
}
|
2017-02-04 15:58:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return VK_SUCCESS;
|
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;
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
struct radv_fence *fence = vk_alloc2(&device->alloc, pAllocator,
|
2016-10-07 09:16:09 +10:00
|
|
|
sizeof(*fence), 8,
|
|
|
|
|
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
fence->fence_wsi = NULL;
|
2017-11-27 23:58:35 +01:00
|
|
|
fence->temp_syncobj = 0;
|
2018-01-04 18:38:32 +01:00
|
|
|
if (device->always_use_syncobj || handleTypes) {
|
2017-11-27 23:58:35 +01:00
|
|
|
int ret = device->ws->create_syncobj(device->ws, &fence->syncobj);
|
|
|
|
|
if (ret) {
|
|
|
|
|
vk_free2(&device->alloc, 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
|
|
|
}
|
|
|
|
|
if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
|
|
|
|
|
device->ws->signal_syncobj(device->ws, fence->syncobj);
|
|
|
|
|
}
|
|
|
|
|
fence->fence = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
fence->fence = device->ws->create_fence();
|
|
|
|
|
if (!fence->fence) {
|
|
|
|
|
vk_free2(&device->alloc, 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
|
|
|
}
|
|
|
|
|
fence->syncobj = 0;
|
2019-05-12 00:30:06 +02:00
|
|
|
if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
|
|
|
|
|
device->ws->signal_fence(fence->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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
if (fence->temp_syncobj)
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, fence->temp_syncobj);
|
|
|
|
|
if (fence->syncobj)
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, fence->syncobj);
|
|
|
|
|
if (fence->fence)
|
|
|
|
|
device->ws->destroy_fence(fence->fence);
|
2017-06-15 21:00:56 -07:00
|
|
|
if (fence->fence_wsi)
|
|
|
|
|
fence->fence_wsi->destroy(fence->fence_wsi);
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, pAllocator, fence);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
|
2018-02-26 22:50:41 +01:00
|
|
|
|
2019-03-19 02:30:33 +01:00
|
|
|
uint64_t radv_get_current_time(void)
|
2016-10-07 09:16:09 +10:00
|
|
|
{
|
|
|
|
|
struct timespec tv;
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &tv);
|
2018-02-26 22:50:41 +01:00
|
|
|
return tv.tv_nsec + tv.tv_sec*1000000000ull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint64_t radv_get_absolute_timeout(uint64_t timeout)
|
|
|
|
|
{
|
|
|
|
|
uint64_t current_time = radv_get_current_time();
|
2016-10-07 09:16:09 +10:00
|
|
|
|
|
|
|
|
timeout = MIN2(UINT64_MAX - current_time, timeout);
|
|
|
|
|
|
|
|
|
|
return current_time + timeout;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-26 23:48:27 +01: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]);
|
2017-06-15 21:00:56 -07:00
|
|
|
if (fence->fence == NULL || fence->syncobj ||
|
2019-05-12 00:30:06 +02:00
|
|
|
fence->temp_syncobj || fence->fence_wsi ||
|
|
|
|
|
(!device->ws->is_fence_waitable(fence->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]);
|
|
|
|
|
if (fence->syncobj == 0 && fence->temp_syncobj == 0)
|
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);
|
|
|
|
|
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]);
|
|
|
|
|
handles[i] = fence->temp_syncobj ? fence->temp_syncobj : fence->syncobj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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]);
|
|
|
|
|
|
2019-05-12 00:30:06 +02:00
|
|
|
if (device->ws->fence_wait(device->ws, fence->fence, false, 0)) {
|
2018-02-26 23:48:27 +01:00
|
|
|
free(fences);
|
|
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fences[wait_count++] = fence->fence;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
if (fence->temp_syncobj) {
|
2018-02-26 21:52:49 +01:00
|
|
|
if (!device->ws->wait_syncobj(device->ws, &fence->temp_syncobj, 1, true, timeout))
|
2017-11-27 23:58:35 +01:00
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fence->syncobj) {
|
2018-02-26 21:52:49 +01:00
|
|
|
if (!device->ws->wait_syncobj(device->ws, &fence->syncobj, 1, true, timeout))
|
2017-11-27 23:58:35 +01:00
|
|
|
return VK_TIMEOUT;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
if (fence->fence) {
|
2019-05-12 00:30:06 +02:00
|
|
|
if (!device->ws->is_fence_waitable(fence->fence)) {
|
|
|
|
|
while(!device->ws->is_fence_waitable(fence->fence) &&
|
|
|
|
|
radv_get_current_time() <= timeout)
|
2017-06-15 21:00:56 -07:00
|
|
|
/* Do nothing */;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
expired = device->ws->fence_wait(device->ws,
|
|
|
|
|
fence->fence,
|
|
|
|
|
true, timeout);
|
|
|
|
|
if (!expired)
|
|
|
|
|
return VK_TIMEOUT;
|
2018-02-26 22:54:06 +01:00
|
|
|
}
|
2016-10-06 01:09:54 +02:00
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
if (fence->fence_wsi) {
|
|
|
|
|
VkResult result = fence->fence_wsi->wait(fence->fence_wsi, timeout);
|
|
|
|
|
if (result != VK_SUCCESS)
|
|
|
|
|
return result;
|
|
|
|
|
}
|
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]);
|
2019-05-12 00:30:06 +02:00
|
|
|
if (fence->fence)
|
|
|
|
|
device->ws->reset_fence(fence->fence);
|
2017-11-27 23:58:35 +01:00
|
|
|
|
|
|
|
|
/* Per spec, we first restore the permanent payload, and then reset, so
|
|
|
|
|
* having a temp syncobj should not skip resetting the permanent syncobj. */
|
|
|
|
|
if (fence->temp_syncobj) {
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, fence->temp_syncobj);
|
|
|
|
|
fence->temp_syncobj = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fence->syncobj) {
|
|
|
|
|
device->ws->reset_syncobj(device->ws, fence->syncobj);
|
|
|
|
|
}
|
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);
|
|
|
|
|
|
2017-11-27 23:58:35 +01:00
|
|
|
if (fence->temp_syncobj) {
|
2018-02-26 21:52:49 +01:00
|
|
|
bool success = device->ws->wait_syncobj(device->ws, &fence->temp_syncobj, 1, true, 0);
|
2017-11-27 23:58:35 +01:00
|
|
|
return success ? VK_SUCCESS : VK_NOT_READY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fence->syncobj) {
|
2018-02-26 21:52:49 +01:00
|
|
|
bool success = device->ws->wait_syncobj(device->ws, &fence->syncobj, 1, true, 0);
|
2017-11-27 23:58:35 +01:00
|
|
|
return success ? VK_SUCCESS : VK_NOT_READY;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
if (fence->fence) {
|
|
|
|
|
if (!device->ws->fence_wait(device->ws, fence->fence, false, 0))
|
|
|
|
|
return VK_NOT_READY;
|
|
|
|
|
}
|
|
|
|
|
if (fence->fence_wsi) {
|
|
|
|
|
VkResult result = fence->fence_wsi->wait(fence->fence_wsi, 0);
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2017-06-15 21:00:56 -07:00
|
|
|
if (result != VK_SUCCESS) {
|
|
|
|
|
if (result == VK_TIMEOUT)
|
|
|
|
|
return VK_NOT_READY;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-07 09:16:09 +10:00
|
|
|
return VK_SUCCESS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Queue semaphore functions
|
|
|
|
|
|
|
|
|
|
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;
|
2016-10-07 09:16:09 +10:00
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
struct radv_semaphore *sem = vk_alloc2(&device->alloc, pAllocator,
|
|
|
|
|
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
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
sem->temp_syncobj = 0;
|
|
|
|
|
/* create a syncobject if we are going to export this semaphore */
|
2018-01-04 18:38:32 +01:00
|
|
|
if (device->always_use_syncobj || handleTypes) {
|
2017-02-27 19:14:00 +00:00
|
|
|
assert (device->physical_device->rad_info.has_syncobj);
|
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, &sem->syncobj);
|
|
|
|
|
if (ret) {
|
|
|
|
|
vk_free2(&device->alloc, 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
|
|
|
}
|
|
|
|
|
sem->sem = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
sem->sem = device->ws->create_sem(device->ws);
|
|
|
|
|
if (!sem->sem) {
|
|
|
|
|
vk_free2(&device->alloc, 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
|
|
|
}
|
|
|
|
|
sem->syncobj = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*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;
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
if (sem->syncobj)
|
|
|
|
|
device->ws->destroy_syncobj(device->ws, sem->syncobj);
|
|
|
|
|
else
|
|
|
|
|
device->ws->destroy_sem(sem->sem);
|
|
|
|
|
vk_free2(&device->alloc, pAllocator, sem);
|
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);
|
2016-10-14 13:36:45 +10:00
|
|
|
struct radv_event *event = vk_alloc2(&device->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
|
|
|
|
|
|
|
|
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) {
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, 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);
|
|
|
|
|
|
|
|
|
|
*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;
|
|
|
|
|
device->ws->buffer_destroy(event->bo);
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, pAllocator, event);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetEventStatus(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
VkEvent _event)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_event, event, _event);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkResult radv_CreateBuffer(
|
|
|
|
|
VkDevice _device,
|
|
|
|
|
const VkBufferCreateInfo* pCreateInfo,
|
|
|
|
|
const VkAllocationCallbacks* pAllocator,
|
|
|
|
|
VkBuffer* pBuffer)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
struct radv_buffer *buffer;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
buffer = vk_alloc2(&device->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
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
vk_free2(&device->alloc, 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;
|
|
|
|
|
|
2017-02-04 11:15:59 +01:00
|
|
|
if (buffer->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
|
|
|
|
|
device->ws->buffer_destroy(buffer->bo);
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, pAllocator, buffer);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
|
|
|
|
|
2019-01-24 02:06:27 +01:00
|
|
|
VkDeviceAddress radv_GetBufferDeviceAddressEXT(
|
|
|
|
|
VkDevice device,
|
|
|
|
|
const VkBufferDeviceAddressInfoEXT* pInfo)
|
|
|
|
|
{
|
|
|
|
|
RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
|
|
|
|
|
return radv_buffer_get_va(buffer->bo) + buffer->offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
static void
|
|
|
|
|
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) {
|
|
|
|
|
struct gfx9_surf_meta_flags meta;
|
|
|
|
|
if (iview->image->dcc_offset)
|
2018-07-16 20:51:26 +02:00
|
|
|
meta = surf->u.gfx9.dcc;
|
2017-06-06 08:38:36 +10:00
|
|
|
else
|
2018-07-16 20:51:26 +02:00
|
|
|
meta = surf->u.gfx9.cmask;
|
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_attrib3 |= S_028EE0_COLOR_SW_MODE(surf->u.gfx9.surf.swizzle_mode) |
|
|
|
|
|
S_028EE0_FMASK_SW_MODE(surf->u.gfx9.fmask.swizzle_mode) |
|
|
|
|
|
S_028EE0_CMASK_PIPE_ALIGNED(surf->u.gfx9.cmask.pipe_aligned) |
|
|
|
|
|
S_028EE0_DCC_PIPE_ALIGNED(surf->u.gfx9.dcc.pipe_aligned);
|
|
|
|
|
} else {
|
|
|
|
|
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);
|
|
|
|
|
cb->cb_color_cmask_slice = iview->image->cmask.slice_tile_max;
|
|
|
|
|
|
|
|
|
|
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)
|
2017-06-05 02:05:59 +01:00
|
|
|
cb->cb_color_pitch |= S_028C64_FMASK_TILE_MAX(iview->image->fmask.pitch_in_pixels / 8 - 1);
|
|
|
|
|
cb->cb_color_attrib |= S_028C74_FMASK_TILE_MODE_INDEX(iview->image->fmask.tile_mode_index);
|
|
|
|
|
cb->cb_color_fmask_slice = S_028C88_TILE_MAX(iview->image->fmask.slice_tile_max);
|
|
|
|
|
} 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;
|
2016-10-07 09:16:09 +10:00
|
|
|
va += iview->image->cmask.offset;
|
|
|
|
|
cb->cb_color_cmask = va >> 8;
|
|
|
|
|
|
2017-09-17 12:15:02 +02:00
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset;
|
2016-10-07 09:16:09 +10:00
|
|
|
va += iview->image->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)) {
|
2017-09-17 12:15:02 +02:00
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset + iview->image->fmask.offset;
|
2016-10-07 09:16:09 +10:00
|
|
|
cb->cb_color_fmask = va >> 8;
|
2017-08-15 12:40:41 +10:00
|
|
|
cb->cb_color_fmask |= iview->image->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");
|
|
|
|
|
swap = radv_translate_colorswap(iview->vk_format, FALSE);
|
|
|
|
|
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) {
|
2017-08-07 07:39:41 +01:00
|
|
|
unsigned fmask_bankh = util_logbase2(iview->image->fmask.bank_height);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 09:16:09 +10:00
|
|
|
static void
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
2018-07-16 20:51:26 +02:00
|
|
|
if (!surf->has_stencil)
|
2017-06-06 08:39:44 +10:00
|
|
|
/* Use all of the htile_buffer for depth if there's no stencil. */
|
|
|
|
|
ds->db_stencil_info |= S_02803C_TILE_STENCIL_DISABLE(1);
|
2017-09-17 12:15:02 +02:00
|
|
|
va = radv_buffer_get_va(iview->bo) + iview->image->offset +
|
2017-06-06 08:39:44 +10:00
|
|
|
iview->image->htile_offset;
|
|
|
|
|
ds->db_htile_data_base = va >> 8;
|
|
|
|
|
ds->db_htile_surface = S_028ABC_FULL_CACHE(1) |
|
2019-06-25 10:42:49 +02:00
|
|
|
S_028ABC_PIPE_ALIGNED(surf->u.gfx9.htile.pipe_aligned);
|
|
|
|
|
|
|
|
|
|
if (device->physical_device->rad_info.chip_class == GFX9) {
|
|
|
|
|
ds->db_htile_surface |= S_028ABC_RB_ALIGNED(surf->u.gfx9.htile.rb_aligned);
|
|
|
|
|
}
|
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
|
|
|
|
2018-07-16 20:51:26 +02:00
|
|
|
if (!surf->has_stencil &&
|
2018-04-06 16:17:26 +02:00
|
|
|
!radv_image_is_tc_compat_htile(iview->image))
|
2017-06-05 02:01:10 +01:00
|
|
|
/* Use all of the htile_buffer for depth if there's no stencil. */
|
|
|
|
|
ds->db_stencil_info |= S_028044_TILE_STENCIL_DISABLE(1);
|
|
|
|
|
|
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
|
|
|
iview->image->htile_offset;
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
|
|
|
|
|
|
|
|
|
|
size_t size = sizeof(*framebuffer) +
|
|
|
|
|
sizeof(struct radv_attachment_info) * pCreateInfo->attachmentCount;
|
2016-10-14 13:36:45 +10:00
|
|
|
framebuffer = vk_alloc2(&device->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
|
|
|
|
|
|
|
|
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;
|
2016-10-07 09:16:09 +10:00
|
|
|
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].attachment = iview;
|
2018-07-16 20:51:26 +02:00
|
|
|
if (iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
|
2016-10-07 09:16:09 +10:00
|
|
|
radv_initialise_ds_surface(device, &framebuffer->attachments[i].ds, iview);
|
2018-07-16 20:51:26 +02:00
|
|
|
} else {
|
|
|
|
|
radv_initialise_color_surface(device, &framebuffer->attachments[i].cb, iview);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
2017-02-19 01:16:19 +01:00
|
|
|
framebuffer->width = MIN2(framebuffer->width, iview->extent.width);
|
|
|
|
|
framebuffer->height = MIN2(framebuffer->height, iview->extent.height);
|
2017-12-19 15:41:42 +10:00
|
|
|
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;
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->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;
|
|
|
|
|
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
|
|
|
|
|
radv_tex_filter_mode(VkSamplerReductionModeEXT mode)
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
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;
|
2018-03-25 20:05:42 +02:00
|
|
|
|
|
|
|
|
const struct VkSamplerReductionModeCreateInfoEXT *sampler_reduction =
|
|
|
|
|
vk_find_struct_const(pCreateInfo->pNext,
|
|
|
|
|
SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT);
|
|
|
|
|
if (sampler_reduction)
|
|
|
|
|
filter_mode = radv_tex_filter_mode(sampler_reduction->reductionMode);
|
2016-10-27 03:02:14 +02:00
|
|
|
|
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) |
|
|
|
|
|
S_008F30_DEPTH_COMPARE_FUNC(radv_tex_compare(pCreateInfo->compareOp)) |
|
|
|
|
|
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) |
|
2018-03-25 20:05:42 +02:00
|
|
|
S_008F30_FILTER_MODE(filter_mode));
|
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));
|
2016-10-07 09:16:09 +10:00
|
|
|
sampler->state[3] = (S_008F3C_BORDER_COLOR_PTR(0) |
|
|
|
|
|
S_008F3C_BORDER_COLOR_TYPE(radv_tex_bordercolor(pCreateInfo->borderColor)));
|
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) |
|
|
|
|
|
S_008F38_ANISO_OVERRIDE_GFX6(device->physical_device->rad_info.chip_class >= GFX8);
|
|
|
|
|
}
|
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);
|
|
|
|
|
|
2016-10-14 13:36:45 +10:00
|
|
|
sampler = vk_alloc2(&device->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
|
|
|
|
|
|
|
|
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;
|
2016-10-14 13:36:45 +10:00
|
|
|
vk_free2(&device->alloc, pAllocator, sampler);
|
2016-10-07 09:16:09 +10:00
|
|
|
}
|
2017-01-13 08:55:59 +01:00
|
|
|
|
|
|
|
|
/* vk_icd.h does not declare this function, so we declare it here to
|
|
|
|
|
* suppress Wmissing-prototypes.
|
|
|
|
|
*/
|
|
|
|
|
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
|
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
|
|
|
|
|
|
|
|
|
|
PUBLIC VKAPI_ATTR VkResult VKAPI_CALL
|
|
|
|
|
vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
|
|
|
|
|
{
|
|
|
|
|
/* For the full details on loader interface versioning, see
|
|
|
|
|
* <https://github.com/KhronosGroup/Vulkan-LoaderAndValidationLayers/blob/master/loader/LoaderAndLayerInterface.md>.
|
|
|
|
|
* What follows is a condensed summary, to help you navigate the large and
|
|
|
|
|
* confusing official doc.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v0 is incompatible with later versions. We don't
|
|
|
|
|
* support it.
|
|
|
|
|
*
|
|
|
|
|
* - In loader interface v1:
|
|
|
|
|
* - The first ICD entrypoint called by the loader is
|
|
|
|
|
* vk_icdGetInstanceProcAddr(). The ICD must statically expose this
|
|
|
|
|
* entrypoint.
|
|
|
|
|
* - The ICD must statically expose no other Vulkan symbol unless it is
|
|
|
|
|
* linked with -Bsymbolic.
|
|
|
|
|
* - Each dispatchable Vulkan handle created by the ICD must be
|
|
|
|
|
* a pointer to a struct whose first member is VK_LOADER_DATA. The
|
|
|
|
|
* ICD must initialize VK_LOADER_DATA.loadMagic to ICD_LOADER_MAGIC.
|
|
|
|
|
* - The loader implements vkCreate{PLATFORM}SurfaceKHR() and
|
|
|
|
|
* vkDestroySurfaceKHR(). The ICD must be capable of working with
|
|
|
|
|
* such loader-managed surfaces.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v2 differs from v1 in:
|
|
|
|
|
* - The first ICD entrypoint called by the loader is
|
|
|
|
|
* vk_icdNegotiateLoaderICDInterfaceVersion(). The ICD must
|
|
|
|
|
* statically expose this entrypoint.
|
|
|
|
|
*
|
|
|
|
|
* - Loader interface v3 differs from v2 in:
|
|
|
|
|
* - The ICD must implement vkCreate{PLATFORM}SurfaceKHR(),
|
|
|
|
|
* vkDestroySurfaceKHR(), and other API which uses VKSurfaceKHR,
|
|
|
|
|
* because the loader no longer does so.
|
|
|
|
|
*/
|
2019-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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2018-05-31 01:06:41 +02:00
|
|
|
RADV_FROM_HANDLE(radv_device, device, _device);
|
|
|
|
|
|
2017-11-27 18:43:43 -08:00
|
|
|
switch (handleType) {
|
2017-12-05 21:15:25 +01:00
|
|
|
case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
|
2017-11-27 18:43:43 -08:00
|
|
|
pMemoryFdProperties->memoryTypeBits = (1 << RADV_MEM_TYPE_COUNT) - 1;
|
|
|
|
|
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.
|
|
|
|
|
*/
|
2019-01-08 14:30:32 +01:00
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
2017-11-27 18:43:43 -08:00
|
|
|
}
|
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) {
|
|
|
|
|
int ret = device->ws->create_syncobj(device->ws, &syncobj_handle);
|
|
|
|
|
if (ret) {
|
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 (fd == -1) {
|
|
|
|
|
device->ws->signal_syncobj(device->ws, syncobj_handle);
|
|
|
|
|
} else {
|
|
|
|
|
int ret = device->ws->import_syncobj_from_sync_file(device->ws, syncobj_handle, fd);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*syncobj = syncobj_handle;
|
|
|
|
|
if (fd != -1)
|
|
|
|
|
close(fd);
|
|
|
|
|
|
|
|
|
|
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);
|
2017-11-13 23:18:19 +01:00
|
|
|
uint32_t *syncobj_dst = NULL;
|
2017-02-27 19:14:00 +00:00
|
|
|
|
2019-01-08 14:30:32 +01:00
|
|
|
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) {
|
2017-11-13 23:18:19 +01:00
|
|
|
syncobj_dst = &sem->temp_syncobj;
|
2017-02-27 19:14:00 +00:00
|
|
|
} else {
|
2017-11-13 23:18:19 +01:00
|
|
|
syncobj_dst = &sem->syncobj;
|
2017-02-27 19:14:00 +00:00
|
|
|
}
|
2017-11-13 23:18:19 +01: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:
|
2017-12-18 21:02:05 +01:00
|
|
|
return radv_import_opaque_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst);
|
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
|
|
|
return radv_import_sync_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Unhandled semaphore handle type");
|
|
|
|
|
}
|
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;
|
|
|
|
|
|
|
|
|
|
if (sem->temp_syncobj)
|
|
|
|
|
syncobj_handle = sem->temp_syncobj;
|
|
|
|
|
else
|
|
|
|
|
syncobj_handle = sem->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);
|
|
|
|
|
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);
|
2018-01-04 02:55:39 +01:00
|
|
|
if (!ret) {
|
|
|
|
|
if (sem->temp_syncobj) {
|
|
|
|
|
close (sem->temp_syncobj);
|
|
|
|
|
sem->temp_syncobj = 0;
|
|
|
|
|
} else {
|
|
|
|
|
device->ws->reset_syncobj(device->ws, syncobj_handle);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-18 21:02:05 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Unhandled semaphore handle type");
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-27 19:14:00 +00:00
|
|
|
if (ret)
|
2019-01-08 14:30:32 +01:00
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
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);
|
|
|
|
|
|
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 */
|
|
|
|
|
if (pdevice->rad_info.has_syncobj_wait_for_submit &&
|
2019-01-08 14:30:32 +01:00
|
|
|
(pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
|
|
|
|
pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)) {
|
|
|
|
|
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);
|
|
|
|
|
uint32_t *syncobj_dst = NULL;
|
|
|
|
|
|
|
|
|
|
|
2019-01-08 14:30:32 +01:00
|
|
|
if (pImportFenceFdInfo->flags & VK_FENCE_IMPORT_TEMPORARY_BIT) {
|
2017-11-28 00:21:12 +01:00
|
|
|
syncobj_dst = &fence->temp_syncobj;
|
|
|
|
|
} else {
|
|
|
|
|
syncobj_dst = &fence->syncobj;
|
|
|
|
|
}
|
|
|
|
|
|
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:
|
2017-12-18 21:02:05 +01:00
|
|
|
return radv_import_opaque_fd(device, pImportFenceFdInfo->fd, syncobj_dst);
|
2019-01-08 14:30:32 +01:00
|
|
|
case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT:
|
2017-12-18 21:02:05 +01:00
|
|
|
return radv_import_sync_fd(device, pImportFenceFdInfo->fd, syncobj_dst);
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Unhandled fence handle type");
|
|
|
|
|
}
|
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;
|
|
|
|
|
uint32_t syncobj_handle;
|
|
|
|
|
|
|
|
|
|
if (fence->temp_syncobj)
|
|
|
|
|
syncobj_handle = fence->temp_syncobj;
|
|
|
|
|
else
|
|
|
|
|
syncobj_handle = fence->syncobj;
|
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:
|
2017-12-18 21:02:05 +01:00
|
|
|
ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd);
|
|
|
|
|
break;
|
2019-01-08 14:30:32 +01:00
|
|
|
case VK_EXTERNAL_FENCE_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);
|
2018-01-04 02:55:39 +01:00
|
|
|
if (!ret) {
|
|
|
|
|
if (fence->temp_syncobj) {
|
|
|
|
|
close (fence->temp_syncobj);
|
|
|
|
|
fence->temp_syncobj = 0;
|
|
|
|
|
} else {
|
|
|
|
|
device->ws->reset_syncobj(device->ws, syncobj_handle);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-18 21:02:05 +01:00
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
unreachable("Unhandled fence handle type");
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-28 00:21:12 +01:00
|
|
|
if (ret)
|
2019-01-08 14:30:32 +01:00
|
|
|
return vk_error(device->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
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 &&
|
2019-01-08 14:30:32 +01:00
|
|
|
(pExternalFenceInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT ||
|
|
|
|
|
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,
|
|
|
|
|
VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
uint32_t *pTimeDomainCount,
|
|
|
|
|
VkTimeDomainEXT *pTimeDomains)
|
|
|
|
|
{
|
|
|
|
|
int d;
|
|
|
|
|
VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
|
|
|
|
|
|
|
|
|
|
for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
|
|
|
|
|
vk_outarray_append(&out, i) {
|
|
|
|
|
*i = radv_time_domains[d];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return vk_outarray_status(&out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static uint64_t
|
|
|
|
|
radv_clock_gettime(clockid_t clock_id)
|
|
|
|
|
{
|
|
|
|
|
struct timespec current;
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
ret = clock_gettime(clock_id, ¤t);
|
|
|
|
|
if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
|
|
|
|
|
ret = clock_gettime(CLOCK_MONOTONIC, ¤t);
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
|
|
|
|
|
pTimestamps[d] = begin;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
pTimestamps[d] = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
2019-05-16 11:55:02 +02:00
|
|
|
|
|
|
|
|
void radv_GetPhysicalDeviceMultisamplePropertiesEXT(
|
|
|
|
|
VkPhysicalDevice physicalDevice,
|
|
|
|
|
VkSampleCountFlagBits samples,
|
|
|
|
|
VkMultisamplePropertiesEXT* pMultisampleProperties)
|
|
|
|
|
{
|
|
|
|
|
if (samples & (VK_SAMPLE_COUNT_2_BIT |
|
|
|
|
|
VK_SAMPLE_COUNT_4_BIT |
|
|
|
|
|
VK_SAMPLE_COUNT_8_BIT)) {
|
|
|
|
|
pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 2, 2 };
|
|
|
|
|
} else {
|
|
|
|
|
pMultisampleProperties->maxSampleLocationGridSize = (VkExtent2D){ 0, 0 };
|
|
|
|
|
}
|
|
|
|
|
}
|