#include <xf86drm.h>
#include <amdgpu.h>
#include <amdgpu_drm.h>
-#include "amdgpu_id.h"
#include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
#include "ac_llvm_util.h"
#include "vk_format.h"
ac_compute_device_uuid(info, uuid, VK_UUID_SIZE);
}
-static const char *
-get_chip_name(enum radeon_family family)
+static void
+radv_get_device_name(enum radeon_family family, char *name, size_t name_len)
{
+ const char *chip_string;
+ char llvm_string[32] = {};
+
switch (family) {
- case CHIP_TAHITI: return "AMD RADV TAHITI";
- case CHIP_PITCAIRN: return "AMD RADV PITCAIRN";
- case CHIP_VERDE: return "AMD RADV CAPE VERDE";
- case CHIP_OLAND: return "AMD RADV OLAND";
- case CHIP_HAINAN: return "AMD RADV HAINAN";
- case CHIP_BONAIRE: return "AMD RADV BONAIRE";
- case CHIP_KAVERI: return "AMD RADV KAVERI";
- case CHIP_KABINI: return "AMD RADV KABINI";
- case CHIP_HAWAII: return "AMD RADV HAWAII";
- case CHIP_MULLINS: return "AMD RADV MULLINS";
- case CHIP_TONGA: return "AMD RADV TONGA";
- case CHIP_ICELAND: return "AMD RADV ICELAND";
- case CHIP_CARRIZO: return "AMD RADV CARRIZO";
- case CHIP_FIJI: return "AMD RADV FIJI";
- case CHIP_POLARIS10: return "AMD RADV POLARIS10";
- case CHIP_POLARIS11: return "AMD RADV POLARIS11";
- case CHIP_POLARIS12: return "AMD RADV POLARIS12";
- case CHIP_STONEY: return "AMD RADV STONEY";
- case CHIP_VEGA10: return "AMD RADV VEGA";
- case CHIP_RAVEN: return "AMD RADV RAVEN";
- default: return "AMD RADV unknown";
+ 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_MULLINS: chip_string = "AMD RADV MULLINS"; 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;
+ case CHIP_VEGA10: chip_string = "AMD RADV VEGA"; break;
+ case CHIP_RAVEN: chip_string = "AMD RADV RAVEN"; break;
+ default: chip_string = "AMD RADV unknown"; break;
+ }
+
+ if (HAVE_LLVM > 0) {
+ snprintf(llvm_string, sizeof(llvm_string),
+ " (LLVM %i.%i.%i)", (HAVE_LLVM >> 8) & 0xff,
+ HAVE_LLVM & 0xff, MESA_LLVM_VERSION_PATCH);
+ }
+
+ snprintf(name, name_len, "%s%s", chip_string, llvm_string);
+}
+
+static void
+radv_physical_device_init_mem_types(struct radv_physical_device *device)
+{
+ STATIC_ASSERT(RADV_MEM_HEAP_COUNT <= VK_MAX_MEMORY_HEAPS);
+ uint64_t visible_vram_size = MIN2(device->rad_info.vram_size,
+ device->rad_info.vram_vis_size);
+
+ int vram_index = -1, visible_vram_index = -1, gart_index = -1;
+ device->memory_properties.memoryHeapCount = 0;
+ if (device->rad_info.vram_size - visible_vram_size > 0) {
+ vram_index = device->memory_properties.memoryHeapCount++;
+ device->memory_properties.memoryHeaps[vram_index] = (VkMemoryHeap) {
+ .size = device->rad_info.vram_size - visible_vram_size,
+ .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,
+ .flags = 0,
+ };
+ }
+
+ 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 |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+ .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 |
+ VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+ .heapIndex = gart_index,
+ };
+ }
+ device->memory_properties.memoryTypeCount = type_count;
}
static VkResult
fd = open(path, O_RDWR | O_CLOEXEC);
if (fd < 0)
- return VK_ERROR_INCOMPATIBLE_DRIVER;
+ return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
version = drmGetVersion(fd);
if (!version) {
device->local_fd = fd;
device->ws->query_info(device->ws, &device->rad_info);
- result = radv_init_wsi(device);
- if (result != VK_SUCCESS) {
- device->ws->destroy(device->ws);
- goto fail;
- }
- device->name = get_chip_name(device->rad_info.family);
+ radv_get_device_name(device->rad_info.family, device->name, sizeof(device->name));
if (radv_device_get_cache_uuid(device->rad_info.family, device->cache_uuid)) {
- radv_finish_wsi(device);
device->ws->destroy(device->ws);
result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
"cannot generate UUID");
*/
device->has_clear_state = device->rad_info.chip_class >= CIK;
+ device->cpdma_prefetch_writes_memory = device->rad_info.chip_class <= VI;
+
+ /* 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;
+
+ radv_physical_device_init_mem_types(device);
+
+ result = radv_init_wsi(device);
+ if (result != VK_SUCCESS) {
+ device->ws->destroy(device->ws);
+ goto fail;
+ }
+
return VK_SUCCESS;
fail:
{"vmfaults", RADV_DEBUG_VM_FAULTS},
{"zerovram", RADV_DEBUG_ZERO_VRAM},
{"syncshaders", RADV_DEBUG_SYNC_SHADERS},
+ {"nosisched", RADV_DEBUG_NO_SISCHED},
{NULL, 0}
};
static const struct debug_control radv_perftest_options[] = {
{"nobatchchain", RADV_PERFTEST_NO_BATCHCHAIN},
{"sisched", RADV_PERFTEST_SISCHED},
+ {"localbos", RADV_PERFTEST_LOCAL_BOS},
+ {"binning", RADV_PERFTEST_BINNING},
{NULL, 0}
};
return radv_perftest_options[id].string;
}
+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")) {
+ /* Force enable LLVM sisched for Talos because it looks safe
+ * and it gives few more FPS.
+ */
+ instance->perftest_flags |= RADV_PERFTEST_SISCHED;
+ }
+}
+
VkResult radv_CreateInstance(
const VkInstanceCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
}
- instance = vk_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ instance = vk_zalloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
if (!instance)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- memset(instance, 0, sizeof(*instance));
-
instance->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
if (pAllocator)
instance->perftest_flags = parse_debug_string(getenv("RADV_PERFTEST"),
radv_perftest_options);
+ radv_handle_per_app_options(instance, pCreateInfo->pApplicationInfo);
+
+ if (instance->debug_flags & RADV_DEBUG_NO_SISCHED) {
+ /* Disable sisched when the user requests it, this is mostly
+ * useful when the driver force-enable sisched for the given
+ * application.
+ */
+ instance->perftest_flags &= ~RADV_PERFTEST_SISCHED;
+ }
+
*pInstance = radv_instance_to_handle(instance);
return VK_SUCCESS;
max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
if (max_devices < 1)
- return VK_ERROR_INCOMPATIBLE_DRIVER;
+ return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
for (unsigned i = 0; i < (unsigned)max_devices; i++) {
if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES_KHR;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: {
+ VkPhysicalDeviceDiscardRectanglePropertiesEXT *properties =
+ (VkPhysicalDeviceDiscardRectanglePropertiesEXT*)ext;
+ properties->maxDiscardRectangles = MAX_DISCARD_RECTANGLES;
+ break;
+ }
default:
break;
}
{
RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
- STATIC_ASSERT(RADV_MEM_TYPE_COUNT <= VK_MAX_MEMORY_TYPES);
-
- pMemoryProperties->memoryTypeCount = RADV_MEM_TYPE_COUNT;
- pMemoryProperties->memoryTypes[RADV_MEM_TYPE_VRAM] = (VkMemoryType) {
- .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- .heapIndex = RADV_MEM_HEAP_VRAM,
- };
- pMemoryProperties->memoryTypes[RADV_MEM_TYPE_GTT_WRITE_COMBINE] = (VkMemoryType) {
- .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- .heapIndex = RADV_MEM_HEAP_GTT,
- };
- pMemoryProperties->memoryTypes[RADV_MEM_TYPE_VRAM_CPU_ACCESS] = (VkMemoryType) {
- .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
- VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
- .heapIndex = RADV_MEM_HEAP_VRAM_CPU_ACCESS,
- };
- pMemoryProperties->memoryTypes[RADV_MEM_TYPE_GTT_CACHED] = (VkMemoryType) {
- .propertyFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
- VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
- VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
- .heapIndex = RADV_MEM_HEAP_GTT,
- };
-
- STATIC_ASSERT(RADV_MEM_HEAP_COUNT <= VK_MAX_MEMORY_HEAPS);
- uint64_t visible_vram_size = MIN2(physical_device->rad_info.vram_size,
- physical_device->rad_info.vram_vis_size);
-
- pMemoryProperties->memoryHeapCount = RADV_MEM_HEAP_COUNT;
- pMemoryProperties->memoryHeaps[RADV_MEM_HEAP_VRAM] = (VkMemoryHeap) {
- .size = physical_device->rad_info.vram_size -
- visible_vram_size,
- .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
- };
- pMemoryProperties->memoryHeaps[RADV_MEM_HEAP_VRAM_CPU_ACCESS] = (VkMemoryHeap) {
- .size = visible_vram_size,
- .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
- };
- pMemoryProperties->memoryHeaps[RADV_MEM_HEAP_GTT] = (VkMemoryHeap) {
- .size = physical_device->rad_info.gart_size,
- .flags = 0,
- };
+ *pMemoryProperties = physical_device->memory_properties;
}
void radv_GetPhysicalDeviceMemoryProperties2KHR(
return RADEON_CTX_PRIORITY_MEDIUM;
switch(pObj->globalPriority) {
- case VK_QUEUE_GLOBAL_PRIORITY_REALTIME:
+ case VK_QUEUE_GLOBAL_PRIORITY_REALTIME_EXT:
return RADEON_CTX_PRIORITY_REALTIME;
- case VK_QUEUE_GLOBAL_PRIORITY_HIGH:
+ case VK_QUEUE_GLOBAL_PRIORITY_HIGH_EXT:
return RADEON_CTX_PRIORITY_HIGH;
- case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM:
+ case VK_QUEUE_GLOBAL_PRIORITY_MEDIUM_EXT:
return RADEON_CTX_PRIORITY_MEDIUM;
- case VK_QUEUE_GLOBAL_PRIORITY_LOW:
+ case VK_QUEUE_GLOBAL_PRIORITY_LOW_EXT:
return RADEON_CTX_PRIORITY_LOW;
default:
unreachable("Illegal global priority value");
static int
radv_queue_init(struct radv_device *device, struct radv_queue *queue,
- int queue_family_index, int idx,
+ uint32_t queue_family_index, int idx,
const VkDeviceQueueGlobalPriorityCreateInfoEXT *global_priority)
{
queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
queue->hw_ctx = device->ws->ctx_create(device->ws, queue->priority);
if (!queue->hw_ctx)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
return VK_SUCCESS;
}
VkResult result;
struct radv_device *device;
+ bool keep_shader_info = false;
+
for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
const char *ext_name = pCreateInfo->ppEnabledExtensionNames[i];
if (!radv_physical_device_extension_supported(physical_device, ext_name))
return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
+
+ if (strcmp(ext_name, VK_AMD_SHADER_INFO_EXTENSION_NAME) == 0)
+ keep_shader_info = true;
}
/* Check enabled features */
}
}
- device = vk_alloc2(&physical_device->instance->alloc, pAllocator,
- sizeof(*device), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
+ device = vk_zalloc2(&physical_device->instance->alloc, pAllocator,
+ sizeof(*device), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
if (!device)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- memset(device, 0, sizeof(*device));
-
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = physical_device->instance;
device->physical_device = physical_device;
}
}
+ device->pbb_allowed = device->physical_device->rad_info.chip_class >= GFX9 &&
+ (device->instance->perftest_flags & RADV_PERFTEST_BINNING);
+
+ /* Disabled and not implemented for now. */
+ device->dfsm_allowed = device->pbb_allowed && false;
+
+
#if HAVE_LLVM < 0x0400
device->llvm_supports_spill = false;
#else
device->scratch_waves = MAX2(32 * physical_device->rad_info.num_good_compute_units,
max_threads_per_block / 64);
+ device->dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1) |
+ S_00B800_FORCE_START_AT_000(1);
+
+ if (device->physical_device->rad_info.chip_class >= CIK) {
+ /* 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);
+ }
+
radv_device_init_gs_info(device);
device->tess_offchip_block_dw_size =
device->physical_device->rad_info.max_se >= 2;
if (getenv("RADV_TRACE_FILE")) {
+ keep_shader_info = true;
+
if (!radv_init_trace(device))
goto fail;
}
+ device->keep_shader_info = keep_shader_info;
+
result = radv_device_init_meta(device);
if (result != VK_SUCCESS)
goto fail;
unsigned tess_factor_ring_size = 0, tess_offchip_ring_size = 0;
unsigned max_offchip_buffers;
unsigned hs_offchip_param = 0;
+ uint32_t ring_bo_flags = RADEON_FLAG_NO_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING;
if (!queue->has_tess_rings) {
if (needs_tess_rings)
add_tess_rings = true;
scratch_size,
4096,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!scratch_bo)
goto fail;
} else
compute_scratch_size,
4096,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!compute_scratch_bo)
goto fail;
esgs_ring_size,
4096,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!esgs_ring_bo)
goto fail;
} else {
gsvs_ring_size,
4096,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!gsvs_ring_bo)
goto fail;
} else {
tess_factor_ring_size,
256,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!tess_factor_ring_bo)
goto fail;
tess_offchip_ring_bo = queue->device->ws->buffer_create(queue->device->ws,
tess_offchip_ring_size,
256,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_NO_CPU_ACCESS);
+ ring_bo_flags);
if (!tess_offchip_ring_bo)
goto fail;
} else {
size,
4096,
RADEON_DOMAIN_VRAM,
- RADEON_FLAG_CPU_ACCESS);
+ RADEON_FLAG_CPU_ACCESS |
+ RADEON_FLAG_NO_INTERPROCESS_SHARING |
+ RADEON_FLAG_READ_ONLY);
if (!descriptor_bo)
goto fail;
} else
dest_cs[i] = cs;
if (scratch_bo)
- queue->device->ws->cs_add_buffer(cs, scratch_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, scratch_bo, 8);
if (esgs_ring_bo)
- queue->device->ws->cs_add_buffer(cs, esgs_ring_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, esgs_ring_bo, 8);
if (gsvs_ring_bo)
- queue->device->ws->cs_add_buffer(cs, gsvs_ring_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, gsvs_ring_bo, 8);
if (tess_factor_ring_bo)
- queue->device->ws->cs_add_buffer(cs, tess_factor_ring_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, tess_factor_ring_bo, 8);
if (tess_offchip_ring_bo)
- queue->device->ws->cs_add_buffer(cs, tess_offchip_ring_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, tess_offchip_ring_bo, 8);
if (descriptor_bo)
- queue->device->ws->cs_add_buffer(cs, descriptor_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, descriptor_bo, 8);
if (descriptor_bo != queue->descriptor_bo) {
uint32_t *map = (uint32_t*)queue->device->ws->buffer_map(descriptor_bo);
uint32_t rsrc1 = S_008F04_BASE_ADDRESS_HI(scratch_va >> 32) |
S_008F04_SWIZZLE_ENABLE(1);
- queue->device->ws->cs_add_buffer(cs, compute_scratch_bo, 8);
+ radv_cs_add_buffer(queue->device->ws, cs, compute_scratch_bo, 8);
radeon_set_sh_reg_seq(cs, R_00B900_COMPUTE_USER_DATA_0, 2);
radeon_emit(cs, scratch_va);
queue->device->ws->buffer_destroy(tess_factor_ring_bo);
if (tess_offchip_ring_bo && tess_offchip_ring_bo != queue->tess_offchip_ring_bo)
queue->device->ws->buffer_destroy(tess_offchip_ring_bo);
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
}
static VkResult radv_alloc_sem_counts(struct radv_winsys_sem_counts *counts,
int num_sems,
const VkSemaphore *sems,
+ VkFence _fence,
bool reset_temp)
{
int syncobj_idx = 0, sem_idx = 0;
- if (num_sems == 0)
+ if (num_sems == 0 && _fence == VK_NULL_HANDLE)
return VK_SUCCESS;
+
for (uint32_t i = 0; i < num_sems; i++) {
RADV_FROM_HANDLE(radv_semaphore, sem, sems[i]);
counts->sem_count++;
}
+ if (_fence != VK_NULL_HANDLE) {
+ RADV_FROM_HANDLE(radv_fence, fence, _fence);
+ if (fence->temp_syncobj || fence->syncobj)
+ counts->syncobj_count++;
+ }
+
if (counts->syncobj_count) {
counts->syncobj = (uint32_t *)malloc(sizeof(uint32_t) * counts->syncobj_count);
if (!counts->syncobj)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
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);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
}
if (sem->temp_syncobj) {
counts->syncobj[syncobj_idx++] = sem->temp_syncobj;
- if (reset_temp) {
- /* after we wait on a temp import - drop it */
- sem->temp_syncobj = 0;
- }
}
else if (sem->syncobj)
counts->syncobj[syncobj_idx++] = sem->syncobj;
}
}
+ 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;
+ }
+
return VK_SUCCESS;
}
free(sem_info->signal.sem);
}
+
+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;
+ }
+ }
+}
+
VkResult radv_alloc_sem_info(struct radv_winsys_sem_info *sem_info,
int num_wait_sems,
const VkSemaphore *wait_sems,
int num_signal_sems,
- const VkSemaphore *signal_sems)
+ const VkSemaphore *signal_sems,
+ VkFence fence)
{
VkResult ret;
memset(sem_info, 0, sizeof(*sem_info));
- ret = radv_alloc_sem_counts(&sem_info->wait, num_wait_sems, wait_sems, true);
+ ret = radv_alloc_sem_counts(&sem_info->wait, num_wait_sems, wait_sems, VK_NULL_HANDLE, true);
if (ret)
return ret;
- ret = radv_alloc_sem_counts(&sem_info->signal, num_signal_sems, signal_sems, false);
+ ret = radv_alloc_sem_counts(&sem_info->signal, num_signal_sems, signal_sems, fence, false);
if (ret)
radv_free_sem_info(sem_info);
pSubmits[i].waitSemaphoreCount,
pSubmits[i].pWaitSemaphores,
pSubmits[i].signalSemaphoreCount,
- pSubmits[i].pSignalSemaphores);
+ pSubmits[i].pSignalSemaphores,
+ _fence);
if (result != VK_SUCCESS)
return result;
cs_array[j] = cmd_buffer->cs;
if ((cmd_buffer->usage_flags & VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT))
can_patch = false;
+
+ cmd_buffer->status = RADV_CMD_BUFFER_STATUS_PENDING;
}
for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j += advance) {
}
}
+ radv_free_temp_syncobjs(queue->device,
+ pSubmits[i].waitSemaphoreCount,
+ pSubmits[i].pWaitSemaphores);
radv_free_sem_info(&sem_info);
free(cs_array);
}
if (fence) {
if (!fence_emitted) {
- struct radv_winsys_sem_info sem_info = {0};
+ struct radv_winsys_sem_info sem_info;
+
+ result = radv_alloc_sem_info(&sem_info, 0, NULL, 0, NULL,
+ _fence);
+ if (result != VK_SUCCESS)
+ return result;
+
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx,
&queue->device->empty_cs[queue->queue_family_index],
1, NULL, NULL, &sem_info,
false, base_fence);
+ radv_free_sem_info(&sem_info);
}
fence->submitted = true;
}
pFD);
}
-VkResult radv_alloc_memory(VkDevice _device,
- const VkMemoryAllocateInfo* pAllocateInfo,
- const VkAllocationCallbacks* pAllocator,
- enum radv_mem_flags_bits mem_flags,
- VkDeviceMemory* pMem)
+static VkResult radv_alloc_memory(struct radv_device *device,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeviceMemory* pMem)
{
- RADV_FROM_HANDLE(radv_device, device, _device);
struct radv_device_memory *mem;
VkResult result;
enum radeon_bo_domain domain;
uint32_t flags = 0;
+ enum radv_mem_type mem_type_index = device->physical_device->mem_type_indices[pAllocateInfo->memoryTypeIndex];
assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
const VkMemoryDedicatedAllocateInfoKHR *dedicate_info =
vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO_KHR);
+ const VkExportMemoryAllocateInfoKHR *export_info =
+ vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO_KHR);
+
+ const struct wsi_memory_allocate_info *wsi_info =
+ vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA);
mem = vk_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (mem == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ if (wsi_info && wsi_info->implicit_sync)
+ flags |= RADEON_FLAG_IMPLICIT_SYNC;
+
if (dedicate_info) {
mem->image = radv_image_from_handle(dedicate_info->image);
mem->buffer = radv_buffer_from_handle(dedicate_info->buffer);
if (import_info) {
assert(import_info->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
+ import_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
mem->bo = device->ws->buffer_from_fd(device->ws, import_info->fd,
NULL, NULL);
if (!mem->bo) {
}
uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
- if (pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_GTT_WRITE_COMBINE ||
- pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_GTT_CACHED)
+ 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;
- if (pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_VRAM)
+ if (mem_type_index == RADV_MEM_TYPE_VRAM)
flags |= RADEON_FLAG_NO_CPU_ACCESS;
else
flags |= RADEON_FLAG_CPU_ACCESS;
- if (pAllocateInfo->memoryTypeIndex == RADV_MEM_TYPE_GTT_WRITE_COMBINE)
+ if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE)
flags |= RADEON_FLAG_GTT_WC;
- if (mem_flags & RADV_MEM_IMPLICIT_SYNC)
- flags |= RADEON_FLAG_IMPLICIT_SYNC;
+ if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes))
+ flags |= RADEON_FLAG_NO_INTERPROCESS_SHARING;
mem->bo = device->ws->buffer_create(device->ws, alloc_size, device->physical_device->rad_info.max_alignment,
domain, flags);
result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
goto fail;
}
- mem->type_index = pAllocateInfo->memoryTypeIndex;
+ mem->type_index = mem_type_index;
out_success:
*pMem = radv_device_memory_to_handle(mem);
const VkAllocationCallbacks* pAllocator,
VkDeviceMemory* pMem)
{
- return radv_alloc_memory(_device, pAllocateInfo, pAllocator, 0, pMem);
+ RADV_FROM_HANDLE(radv_device, device, _device);
+ return radv_alloc_memory(device, pAllocateInfo, pAllocator, pMem);
}
void radv_FreeMemory(
return VK_SUCCESS;
}
- return VK_ERROR_MEMORY_MAP_FAILED;
+ return vk_error(VK_ERROR_MEMORY_MAP_FAILED);
}
void radv_UnmapMemory(
}
void radv_GetBufferMemoryRequirements(
- VkDevice device,
+ VkDevice _device,
VkBuffer _buffer,
VkMemoryRequirements* pMemoryRequirements)
{
+ RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_buffer, buffer, _buffer);
- pMemoryRequirements->memoryTypeBits = (1u << RADV_MEM_TYPE_COUNT) - 1;
+ pMemoryRequirements->memoryTypeBits = (1u << device->physical_device->memory_properties.memoryTypeCount) - 1;
if (buffer->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
pMemoryRequirements->alignment = 4096;
{
radv_GetBufferMemoryRequirements(device, pInfo->buffer,
&pMemoryRequirements->memoryRequirements);
-
+ RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
vk_foreach_struct(ext, pMemoryRequirements->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR: {
VkMemoryDedicatedRequirementsKHR *req =
(VkMemoryDedicatedRequirementsKHR *) ext;
- req->requiresDedicatedAllocation = false;
+ req->requiresDedicatedAllocation = buffer->shareable;
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
break;
}
}
void radv_GetImageMemoryRequirements(
- VkDevice device,
+ VkDevice _device,
VkImage _image,
VkMemoryRequirements* pMemoryRequirements)
{
+ RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_image, image, _image);
- pMemoryRequirements->memoryTypeBits = (1u << RADV_MEM_TYPE_COUNT) - 1;
+ pMemoryRequirements->memoryTypeBits = (1u << device->physical_device->memory_properties.memoryTypeCount) - 1;
pMemoryRequirements->size = image->size;
pMemoryRequirements->alignment = image->alignment;
pBindInfo[i].waitSemaphoreCount,
pBindInfo[i].pWaitSemaphores,
pBindInfo[i].signalSemaphoreCount,
- pBindInfo[i].pSignalSemaphores);
+ pBindInfo[i].pSignalSemaphores,
+ _fence);
if (result != VK_SUCCESS)
return result;
VkFence* pFence)
{
RADV_FROM_HANDLE(radv_device, device, _device);
+ const VkExportFenceCreateInfoKHR *export =
+ vk_find_struct_const(pCreateInfo->pNext, EXPORT_FENCE_CREATE_INFO_KHR);
+ VkExternalFenceHandleTypeFlagsKHR handleTypes =
+ export ? export->handleTypes : 0;
+
struct radv_fence *fence = vk_alloc2(&device->alloc, pAllocator,
sizeof(*fence), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!fence)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- memset(fence, 0, sizeof(*fence));
fence->submitted = false;
fence->signalled = !!(pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT);
- fence->fence = device->ws->create_fence();
- if (!fence->fence) {
- vk_free2(&device->alloc, pAllocator, fence);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ fence->temp_syncobj = 0;
+ if (handleTypes) {
+ int ret = device->ws->create_syncobj(device->ws, &fence->syncobj);
+ if (ret) {
+ vk_free2(&device->alloc, pAllocator, fence);
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+ 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);
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ }
+ fence->syncobj = 0;
}
*pFence = radv_fence_to_handle(fence);
if (!fence)
return;
- device->ws->destroy_fence(fence->fence);
+
+ 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);
vk_free2(&device->alloc, pAllocator, fence);
}
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
bool expired = false;
+ if (fence->temp_syncobj) {
+ if (!device->ws->wait_syncobj(device->ws, fence->temp_syncobj, timeout))
+ return VK_TIMEOUT;
+ continue;
+ }
+
+ if (fence->syncobj) {
+ if (!device->ws->wait_syncobj(device->ws, fence->syncobj, timeout))
+ return VK_TIMEOUT;
+ continue;
+ }
+
if (fence->signalled)
continue;
return VK_SUCCESS;
}
-VkResult radv_ResetFences(VkDevice device,
+VkResult radv_ResetFences(VkDevice _device,
uint32_t fenceCount,
const VkFence *pFences)
{
+ RADV_FROM_HANDLE(radv_device, device, _device);
+
for (unsigned i = 0; i < fenceCount; ++i) {
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
fence->submitted = fence->signalled = false;
+
+ /* 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);
+ }
}
return VK_SUCCESS;
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_fence, fence, _fence);
+ if (fence->temp_syncobj) {
+ bool success = device->ws->wait_syncobj(device->ws, fence->temp_syncobj, 0);
+ return success ? VK_SUCCESS : VK_NOT_READY;
+ }
+
+ if (fence->syncobj) {
+ bool success = device->ws->wait_syncobj(device->ws, fence->syncobj, 0);
+ return success ? VK_SUCCESS : VK_NOT_READY;
+ }
+
if (fence->signalled)
return VK_SUCCESS;
if (!fence->submitted)
return VK_NOT_READY;
-
if (!device->ws->fence_wait(device->ws, fence->fence, false, 0))
return VK_NOT_READY;
sizeof(*sem), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!sem)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
sem->temp_syncobj = 0;
/* create a syncobject if we are going to export this semaphore */
if (handleTypes) {
assert (device->physical_device->rad_info.has_syncobj);
- assert (handleTypes == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
int ret = device->ws->create_syncobj(device->ws, &sem->syncobj);
if (ret) {
vk_free2(&device->alloc, pAllocator, sem);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
sem->sem = NULL;
} else {
sem->sem = device->ws->create_sem(device->ws);
if (!sem->sem) {
vk_free2(&device->alloc, pAllocator, sem);
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
sem->syncobj = 0;
}
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!event)
- return VK_ERROR_OUT_OF_HOST_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
event->bo = device->ws->buffer_create(device->ws, 8, 8,
RADEON_DOMAIN_GTT,
- RADEON_FLAG_VA_UNCACHED | RADEON_FLAG_CPU_ACCESS);
+ RADEON_FLAG_VA_UNCACHED | RADEON_FLAG_CPU_ACCESS | RADEON_FLAG_NO_INTERPROCESS_SHARING);
if (!event->bo) {
vk_free2(&device->alloc, pAllocator, event);
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
}
event->map = (uint64_t*)device->ws->buffer_map(event->bo);
buffer->offset = 0;
buffer->flags = pCreateInfo->flags;
+ buffer->shareable = vk_find_struct_const(pCreateInfo->pNext,
+ EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR) != NULL;
+
if (pCreateInfo->flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) {
buffer->bo = device->ws->buffer_create(device->ws,
align64(buffer->size, 4096),
return image->surface.u.legacy.tiling_index[level];
}
-static uint32_t radv_surface_layer_count(struct radv_image_view *iview)
+static uint32_t radv_surface_max_layer_count(struct radv_image_view *iview)
{
- return iview->type == VK_IMAGE_VIEW_TYPE_3D ? iview->extent.depth : iview->layer_count;
+ return iview->type == VK_IMAGE_VIEW_TYPE_3D ? iview->extent.depth : (iview->base_layer + iview->layer_count);
}
static void
cb->cb_color_cmask_slice = iview->image->cmask.slice_tile_max;
cb->cb_color_attrib |= S_028C74_TILE_MODE_INDEX(tile_mode_index);
- cb->micro_tile_mode = iview->image->surface.micro_tile_mode;
if (iview->image->fmask.size) {
if (device->physical_device->rad_info.chip_class >= CIK)
cb->cb_dcc_base = va >> 8;
cb->cb_dcc_base |= iview->image->surface.tile_swizzle;
- uint32_t max_slice = radv_surface_layer_count(iview);
+ uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
cb->cb_color_view = S_028C6C_SLICE_START(iview->base_layer) |
- S_028C6C_SLICE_MAX(iview->base_layer + max_slice - 1);
+ S_028C6C_SLICE_MAX(max_slice);
if (iview->image->info.samples > 1) {
unsigned log_samples = util_logbase2(iview->image->info.samples);
cb->cb_color_info |= S_028C70_DCC_ENABLE(1);
if (device->physical_device->rad_info.chip_class >= VI) {
- unsigned max_uncompressed_block_size = 2;
+ unsigned max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_256B;
+ unsigned min_compressed_block_size = V_028C78_MIN_BLOCK_SIZE_32B;
+ unsigned independent_64b_blocks = 0;
+ unsigned max_compressed_block_size;
+
+ /* 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 */
+ if (!device->physical_device->rad_info.has_dedicated_vram)
+ min_compressed_block_size = V_028C78_MIN_BLOCK_SIZE_64B;
+
if (iview->image->info.samples > 1) {
if (iview->image->surface.bpe == 1)
- max_uncompressed_block_size = 0;
+ max_uncompressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
else if (iview->image->surface.bpe == 2)
- max_uncompressed_block_size = 1;
+ 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)) {
+ independent_64b_blocks = 1;
+ max_compressed_block_size = V_028C78_MAX_BLOCK_SIZE_64B;
+ } else
+ max_compressed_block_size = max_uncompressed_block_size;
+
cb->cb_dcc_control = S_028C78_MAX_UNCOMPRESSED_BLOCK_SIZE(max_uncompressed_block_size) |
- S_028C78_INDEPENDENT_64B_BLOCKS(1);
+ S_028C78_MAX_COMPRESSED_BLOCK_SIZE(max_compressed_block_size) |
+ S_028C78_MIN_COMPRESSED_BLOCK_SIZE(min_compressed_block_size) |
+ S_028C78_INDEPENDENT_64B_BLOCKS(independent_64b_blocks);
}
/* This must be set for fast clear to work without FMASK. */
cb->cb_color_attrib2 = S_028C68_MIP0_WIDTH(iview->extent.width - 1) |
S_028C68_MIP0_HEIGHT(iview->extent.height - 1) |
S_028C68_MAX_MIP(iview->image->info.levels - 1);
-
- cb->gfx9_epitch = S_0287A0_EPITCH(iview->image->surface.u.gfx9.surf.epitch);
-
}
}
stencil_format = iview->image->surface.has_stencil ?
V_028044_STENCIL_8 : V_028044_STENCIL_INVALID;
- uint32_t max_slice = radv_surface_layer_count(iview);
+ uint32_t max_slice = radv_surface_max_layer_count(iview) - 1;
ds->db_depth_view = S_028008_SLICE_START(iview->base_layer) |
- S_028008_SLICE_MAX(iview->base_layer + max_slice - 1);
+ S_028008_SLICE_MAX(max_slice);
ds->db_htile_data_base = 0;
ds->db_htile_surface = 0;
}
framebuffer->width = MIN2(framebuffer->width, iview->extent.width);
framebuffer->height = MIN2(framebuffer->height, iview->extent.height);
- framebuffer->layers = MIN2(framebuffer->layers, radv_surface_layer_count(iview));
+ framebuffer->layers = MIN2(framebuffer->layers, radv_surface_max_layer_count(iview));
}
*pFramebuffer = radv_framebuffer_to_handle(framebuffer);
S_008F38_XY_MIN_FILTER(radv_tex_filter(pCreateInfo->minFilter, max_aniso)) |
S_008F38_MIP_FILTER(radv_tex_mipfilter(pCreateInfo->mipmapMode)) |
S_008F38_MIP_POINT_PRECLAMP(0) |
- S_008F38_DISABLE_LSB_CEIL(1) |
+ S_008F38_DISABLE_LSB_CEIL(device->physical_device->rad_info.chip_class <= VI) |
S_008F38_FILTER_PREC_FIX(1) |
S_008F38_ANISO_OVERRIDE(is_vi));
sampler->state[3] = (S_008F3C_BORDER_COLOR_PTR(0) |
assert(pGetFdInfo->sType == VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR);
- /* We support only one handle type. */
+ /* At the moment, we support only the below handle types. */
assert(pGetFdInfo->handleType ==
- VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
+ pGetFdInfo->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
bool ret = radv_get_memory_fd(device, memory, pFD);
if (ret == false)
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
return VK_SUCCESS;
}
int fd,
VkMemoryFdPropertiesKHR *pMemoryFdProperties)
{
- /* The valid usage section for this function says:
- *
- * "handleType must not be one of the handle types defined as opaque."
- *
- * Since we only handle opaque handles for now, there are no FD properties.
- */
- return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
+ switch (handleType) {
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
+ 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.
+ */
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+ }
+}
+
+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)
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+
+ 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) {
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+ }
+ }
+
+ 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)
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+ }
+
+ *syncobj = syncobj_handle;
+ if (fd != -1)
+ close(fd);
+
+ return VK_SUCCESS;
}
VkResult radv_ImportSemaphoreFdKHR(VkDevice _device,
{
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_semaphore, sem, pImportSemaphoreFdInfo->semaphore);
- uint32_t syncobj_handle = 0;
- assert(pImportSemaphoreFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
-
- int ret = device->ws->import_syncobj(device->ws, pImportSemaphoreFdInfo->fd, &syncobj_handle);
- if (ret != 0)
- return VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR;
+ uint32_t *syncobj_dst = NULL;
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT_KHR) {
- sem->temp_syncobj = syncobj_handle;
+ syncobj_dst = &sem->temp_syncobj;
} else {
- sem->syncobj = syncobj_handle;
+ syncobj_dst = &sem->syncobj;
+ }
+
+ switch(pImportSemaphoreFdInfo->handleType) {
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
+ return radv_import_opaque_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst);
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
+ return radv_import_sync_fd(device, pImportSemaphoreFdInfo->fd, syncobj_dst);
+ default:
+ unreachable("Unhandled semaphore handle type");
}
- close(pImportSemaphoreFdInfo->fd);
- return VK_SUCCESS;
}
VkResult radv_GetSemaphoreFdKHR(VkDevice _device,
int ret;
uint32_t syncobj_handle;
- assert(pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR);
if (sem->temp_syncobj)
syncobj_handle = sem->temp_syncobj;
else
syncobj_handle = sem->syncobj;
- ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd);
+
+ switch(pGetFdInfo->handleType) {
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
+ ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd);
+ break;
+ case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
+ ret = device->ws->export_syncobj_to_sync_file(device->ws, syncobj_handle, pFd);
+ break;
+ default:
+ unreachable("Unhandled semaphore handle type");
+ }
+
if (ret)
return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
return VK_SUCCESS;
const VkPhysicalDeviceExternalSemaphoreInfoKHR* pExternalSemaphoreInfo,
VkExternalSemaphorePropertiesKHR* pExternalSemaphoreProperties)
{
- if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) {
+ RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
+
+ /* 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 &&
+ (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
+ pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR)) {
+ pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
+ pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
+ pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR;
+ } else if (pExternalSemaphoreInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR) {
pExternalSemaphoreProperties->exportFromImportedHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
pExternalSemaphoreProperties->compatibleHandleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;
pExternalSemaphoreProperties->externalSemaphoreFeatures = VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT_KHR |
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
}
}
+
+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;
+
+
+ if (pImportFenceFdInfo->flags & VK_FENCE_IMPORT_TEMPORARY_BIT_KHR) {
+ syncobj_dst = &fence->temp_syncobj;
+ } else {
+ syncobj_dst = &fence->syncobj;
+ }
+
+ switch(pImportFenceFdInfo->handleType) {
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
+ return radv_import_opaque_fd(device, pImportFenceFdInfo->fd, syncobj_dst);
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
+ return radv_import_sync_fd(device, pImportFenceFdInfo->fd, syncobj_dst);
+ default:
+ unreachable("Unhandled fence handle type");
+ }
+}
+
+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;
+
+ switch(pGetFdInfo->handleType) {
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
+ ret = device->ws->export_syncobj(device->ws, syncobj_handle, pFd);
+ break;
+ case VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR:
+ ret = device->ws->export_syncobj_to_sync_file(device->ws, syncobj_handle, pFd);
+ break;
+ default:
+ unreachable("Unhandled fence handle type");
+ }
+
+ if (ret)
+ return vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR);
+ return VK_SUCCESS;
+}
+
+void radv_GetPhysicalDeviceExternalFencePropertiesKHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceExternalFenceInfoKHR* pExternalFenceInfo,
+ VkExternalFencePropertiesKHR* pExternalFenceProperties)
+{
+ RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
+
+ if (pdevice->rad_info.has_syncobj_wait_for_submit &&
+ (pExternalFenceInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR ||
+ pExternalFenceInfo->handleType == VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR)) {
+ pExternalFenceProperties->exportFromImportedHandleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
+ pExternalFenceProperties->compatibleHandleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT_KHR;
+ pExternalFenceProperties->externalFenceFeatures = VK_EXTERNAL_FENCE_FEATURE_EXPORTABLE_BIT_KHR |
+ VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT_KHR;
+ } else {
+ pExternalFenceProperties->exportFromImportedHandleTypes = 0;
+ pExternalFenceProperties->compatibleHandleTypes = 0;
+ pExternalFenceProperties->externalFenceFeatures = 0;
+ }
+}