* IN THE SOFTWARE.
*/
+#include "dirent.h"
#include <errno.h>
#include <fcntl.h>
#include <linux/audit.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
-#include <llvm/Config/llvm-config.h>
#include "radv_debug.h"
#include "radv_private.h"
#include "radv_shader.h"
#include "radv_cs.h"
#include "util/disk_cache.h"
-#include "util/strtod.h"
#include "vk_util.h"
#include <xf86drm.h>
#include <amdgpu.h>
#include <amdgpu_drm.h>
#include "winsys/amdgpu/radv_amdgpu_winsys_public.h"
+#include "winsys/null/radv_null_winsys_public.h"
#include "ac_llvm_util.h"
#include "vk_format.h"
#include "sid.h"
return device->rad_info.vram_size - radv_get_visible_vram_size(device);
}
+static bool
+radv_is_mem_type_vram(enum radv_mem_type type)
+{
+ return type == RADV_MEM_TYPE_VRAM ||
+ type == RADV_MEM_TYPE_VRAM_UNCACHED;
+}
+
+static bool
+radv_is_mem_type_vram_visible(enum radv_mem_type type)
+{
+ return type == RADV_MEM_TYPE_VRAM_CPU_ACCESS ||
+ type == RADV_MEM_TYPE_VRAM_CPU_ACCESS_UNCACHED;
+}
+static bool
+radv_is_mem_type_gtt_wc(enum radv_mem_type type)
+{
+ return type == RADV_MEM_TYPE_GTT_WRITE_COMBINE ||
+ type == RADV_MEM_TYPE_GTT_WRITE_COMBINE_VRAM_UNCACHED;
+}
+
+static bool
+radv_is_mem_type_gtt_cached(enum radv_mem_type type)
+{
+ return type == RADV_MEM_TYPE_GTT_CACHED ||
+ type == RADV_MEM_TYPE_GTT_CACHED_VRAM_UNCACHED;
+}
+
+static bool
+radv_is_mem_type_uncached(enum radv_mem_type type)
+{
+ return type == RADV_MEM_TYPE_VRAM_UNCACHED ||
+ type == RADV_MEM_TYPE_VRAM_CPU_ACCESS_UNCACHED ||
+ type == RADV_MEM_TYPE_GTT_WRITE_COMBINE_VRAM_UNCACHED ||
+ type == RADV_MEM_TYPE_GTT_CACHED_VRAM_UNCACHED;
+}
+
static void
radv_physical_device_init_mem_types(struct radv_physical_device *device)
{
};
}
device->memory_properties.memoryTypeCount = type_count;
-}
-
-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;
+ if (device->rad_info.has_l2_uncached) {
+ for (int i = 0; i < device->memory_properties.memoryTypeCount; i++) {
+ VkMemoryType mem_type = device->memory_properties.memoryTypes[i];
+
+ if ((mem_type.propertyFlags & (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) ||
+ mem_type.propertyFlags == VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+ enum radv_mem_type mem_type_id;
+
+ switch (device->mem_type_indices[i]) {
+ case RADV_MEM_TYPE_VRAM:
+ mem_type_id = RADV_MEM_TYPE_VRAM_UNCACHED;
+ break;
+ case RADV_MEM_TYPE_VRAM_CPU_ACCESS:
+ mem_type_id = RADV_MEM_TYPE_VRAM_CPU_ACCESS_UNCACHED;
+ break;
+ case RADV_MEM_TYPE_GTT_WRITE_COMBINE:
+ mem_type_id = RADV_MEM_TYPE_GTT_WRITE_COMBINE_VRAM_UNCACHED;
+ break;
+ case RADV_MEM_TYPE_GTT_CACHED:
+ mem_type_id = RADV_MEM_TYPE_GTT_CACHED_VRAM_UNCACHED;
+ break;
+ default:
+ unreachable("invalid memory type");
+ }
- 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;
-
- if (i >= CHIP_NAVI10)
- device->rad_info.chip_class = GFX10;
- else if (i >= CHIP_VEGA10)
- device->rad_info.chip_class = GFX9;
- else if (i >= CHIP_TONGA)
- device->rad_info.chip_class = GFX8;
- else if (i >= CHIP_BONAIRE)
- device->rad_info.chip_class = GFX7;
- else
- device->rad_info.chip_class = GFX6;
+ VkMemoryPropertyFlags property_flags = mem_type.propertyFlags |
+ VK_MEMORY_PROPERTY_DEVICE_COHERENT_BIT_AMD |
+ VK_MEMORY_PROPERTY_DEVICE_UNCACHED_BIT_AMD;
- return;
+ device->mem_type_indices[type_count] = mem_type_id;
+ device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
+ .propertyFlags = property_flags,
+ .heapIndex = mem_type.heapIndex,
+ };
+ }
}
+ device->memory_properties.memoryTypeCount = type_count;
}
-
- fprintf(stderr, "radv: Unknown family: %s\n", family);
- exit(1);
}
static VkResult
struct radv_instance *instance,
drmDevicePtr drm_device)
{
- const char *path = drm_device->nodes[DRM_NODE_RENDER];
VkResult result;
- drmVersionPtr version;
- int fd;
+ int fd = -1;
int master_fd = -1;
- fd = open(path, O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- if (instance->debug_flags & RADV_DEBUG_STARTUP)
- radv_logi("Could not open device '%s'", path);
+ if (drm_device) {
+ const char *path = drm_device->nodes[DRM_NODE_RENDER];
+ drmVersionPtr version;
- return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
- }
+ fd = open(path, O_RDWR | O_CLOEXEC);
+ if (fd < 0) {
+ if (instance->debug_flags & RADV_DEBUG_STARTUP)
+ radv_logi("Could not open device '%s'", path);
- version = drmGetVersion(fd);
- if (!version) {
- close(fd);
+ return vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
+ }
- if (instance->debug_flags & RADV_DEBUG_STARTUP)
- radv_logi("Could not get the kernel driver version for device '%s'", path);
+ version = drmGetVersion(fd);
+ if (!version) {
+ close(fd);
- return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
- "failed to get version %s: %m", path);
- }
+ if (instance->debug_flags & RADV_DEBUG_STARTUP)
+ radv_logi("Could not get the kernel driver version for device '%s'", path);
+
+ return vk_errorf(instance, VK_ERROR_INCOMPATIBLE_DRIVER,
+ "failed to get version %s: %m", path);
+ }
+
+ if (strcmp(version->name, "amdgpu")) {
+ drmFreeVersion(version);
+ close(fd);
- if (strcmp(version->name, "amdgpu")) {
+ if (instance->debug_flags & RADV_DEBUG_STARTUP)
+ radv_logi("Device '%s' is not using the amdgpu kernel driver.", path);
+
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
drmFreeVersion(version);
- close(fd);
if (instance->debug_flags & RADV_DEBUG_STARTUP)
- radv_logi("Device '%s' is not using the amdgpu kernel driver.", path);
-
- return VK_ERROR_INCOMPATIBLE_DRIVER;
+ radv_logi("Found compatible device '%s'.", path);
}
- drmFreeVersion(version);
-
- if (instance->debug_flags & RADV_DEBUG_STARTUP)
- radv_logi("Found compatible device '%s'.", path);
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = instance;
- device->ws = radv_amdgpu_winsys_create(fd, instance->debug_flags,
- instance->perftest_flags);
+ if (drm_device) {
+ device->ws = radv_amdgpu_winsys_create(fd, instance->debug_flags,
+ instance->perftest_flags);
+ } else {
+ device->ws = radv_null_winsys_create();
+ }
+
if (!device->ws) {
result = vk_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
goto fail;
}
- if (instance->enabled_extensions.KHR_display) {
+ if (drm_device && 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;
device->local_fd = fd;
device->ws->query_info(device->ws, &device->rad_info);
- radv_handle_env_var_force_family(device);
-
device->use_aco = instance->perftest_flags & RADV_PERFTEST_ACO;
- if (device->rad_info.chip_class < GFX8 && device->use_aco) {
- fprintf(stderr, "WARNING: disabling ACO on unsupported GPUs.\n");
- device->use_aco = false;
- }
snprintf(device->name, sizeof(device->name),
"AMD RADV%s %s (LLVM " MESA_LLVM_VERSION_STRING ")", device->use_aco ? "/ACO" : "",
}
/* 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) |
- (device->use_aco ? 0x4 : 0);
+ uint64_t shader_env_flags = (device->use_aco ? 0x2 : 0);
/* The gpu id is already embedded in the uuid so we just pass "radv"
* when creating the cache.
disk_cache_format_hex_id(buf, device->cache_uuid, VK_UUID_SIZE * 2);
device->disk_cache = disk_cache_create(device->name, buf, shader_env_flags);
- if (device->rad_info.chip_class < GFX8 ||
- device->rad_info.chip_class > GFX9)
+ if (device->rad_info.chip_class < GFX8)
fprintf(stderr, "WARNING: radv is not a conformant vulkan implementation, testing use only.\n");
radv_get_driver_uuid(&device->driver_uuid);
device->dcc_msaa_allowed =
(device->instance->perftest_flags & RADV_PERFTEST_DCC_MSAA);
- device->use_shader_ballot = device->rad_info.chip_class >= GFX8 &&
- (device->use_aco || device->instance->perftest_flags & RADV_PERFTEST_SHADER_BALLOT);
+ device->use_shader_ballot = (device->use_aco && device->rad_info.chip_class >= GFX8) ||
+ (device->instance->perftest_flags & RADV_PERFTEST_SHADER_BALLOT);
device->use_ngg = device->rad_info.chip_class >= GFX10 &&
device->rad_info.family != CHIP_NAVI14 &&
!(device->instance->debug_flags & RADV_DEBUG_NO_NGG);
- if (device->use_aco && device->use_ngg) {
- fprintf(stderr, "WARNING: disabling NGG because ACO is used.\n");
- device->use_ngg = false;
- }
device->use_ngg_streamout = false;
radv_physical_device_init_mem_types(device);
radv_fill_device_extension_table(device, &device->supported_extensions);
- device->bus_info = *drm_device->businfo.pci;
+ if (drm_device)
+ device->bus_info = *drm_device->businfo.pci;
if ((device->instance->debug_flags & RADV_DEBUG_INFO))
ac_print_gpu_info(&device->rad_info);
{"shaderstats", RADV_DEBUG_DUMP_SHADER_STATS},
{"nohiz", RADV_DEBUG_NO_HIZ},
{"nocompute", RADV_DEBUG_NO_COMPUTE_QUEUE},
- {"unsafemath", RADV_DEBUG_UNSAFE_MATH},
{"allbos", RADV_DEBUG_ALL_BOS},
{"noibs", RADV_DEBUG_NO_IBS},
{"spirv", RADV_DEBUG_DUMP_SPIRV},
{"vmfaults", RADV_DEBUG_VM_FAULTS},
{"zerovram", RADV_DEBUG_ZERO_VRAM},
{"syncshaders", RADV_DEBUG_SYNC_SHADERS},
- {"nosisched", RADV_DEBUG_NO_SISCHED},
{"preoptir", RADV_DEBUG_PREOPTIR},
{"nodynamicbounds", RADV_DEBUG_NO_DYNAMIC_BOUNDS},
{"nooutoforder", RADV_DEBUG_NO_OUT_OF_ORDER},
}
static const struct debug_control radv_perftest_options[] = {
- {"nobatchchain", RADV_PERFTEST_NO_BATCHCHAIN},
- {"sisched", RADV_PERFTEST_SISCHED},
{"localbos", RADV_PERFTEST_LOCAL_BOS},
{"dccmsaa", RADV_PERFTEST_DCC_MSAA},
{"bolist", RADV_PERFTEST_BO_LIST},
if (!name)
return;
- if (!strcmp(name, "Talos - Linux - 32bit") ||
- !strcmp(name, "Talos - Linux - 64bit")) {
- 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;
- }
- } else if (!strcmp(name, "DOOM_VFR")) {
+ if (!strcmp(name, "DOOM_VFR")) {
/* Work around a Doom VFR game bug */
instance->debug_flags |= RADV_DEBUG_NO_DYNAMIC_BOUNDS;
} else if (!strcmp(name, "MonsterHunterWorld.exe")) {
if (LLVM_VERSION_MAJOR < 9)
instance->debug_flags |= RADV_DEBUG_NO_LOAD_STORE_OPT;
} else if (!strcmp(name, "Wolfenstein: Youngblood")) {
- if (!(instance->debug_flags & RADV_DEBUG_NO_SHADER_BALLOT)) {
+ if (!(instance->debug_flags & RADV_DEBUG_NO_SHADER_BALLOT) &&
+ !(instance->perftest_flags & RADV_PERFTEST_ACO)) {
/* Force enable VK_AMD_shader_ballot because it looks
* safe and it gives a nice boost (+20% on Vega 56 at
- * this time).
+ * this time). It also prevents corruption on LLVM.
*/
instance->perftest_flags |= RADV_PERFTEST_SHADER_BALLOT;
}
* uninitialized data in an indirect draw.
*/
instance->debug_flags |= RADV_DEBUG_ZERO_VRAM;
+ } else if (!strcmp(name, "No Man's Sky")) {
+ /* Work around a NMS game bug */
+ instance->debug_flags |= RADV_DEBUG_DISCARD_TO_DEMOTE;
}
}
DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
DRI_CONF_SECTION_END
+
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST("false")
+ DRI_CONF_SECTION_END
DRI_CONF_END;
static void radv_init_dri_options(struct radv_instance *instance)
instance->enabled_extensions.extensions[index] = true;
}
+ bool unchecked = instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS;
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_instance_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions)) {
+ instance->dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->dispatch.entrypoints[i] =
+ radv_instance_dispatch_table.entrypoints[i];
+ }
+ }
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->physical_device_dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_physical_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions)) {
+ instance->physical_device_dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->physical_device_dispatch.entrypoints[i] =
+ radv_physical_device_dispatch_table.entrypoints[i];
+ }
+ }
+
+ for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have
+ * not been enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions, NULL)) {
+ instance->device_dispatch.entrypoints[i] = NULL;
+ } else {
+ instance->device_dispatch.entrypoints[i] =
+ radv_device_dispatch_table.entrypoints[i];
+ }
+ }
+
result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
if (result != VK_SUCCESS) {
vk_free2(&default_alloc, pAllocator, instance);
VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
instance->engineVersion = engine_version;
- _mesa_locale_init();
glsl_type_singleton_init_or_ref();
VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
VG(VALGRIND_DESTROY_MEMPOOL(instance));
glsl_type_singleton_decref();
- _mesa_locale_fini();
driDestroyOptionCache(&instance->dri_options);
driDestroyOptionInfo(&instance->available_dri_options);
instance->physicalDeviceCount = 0;
+ if (getenv("RADV_FORCE_FAMILY")) {
+ /* When RADV_FORCE_FAMILY is set, the driver creates a nul
+ * device that allows to test the compiler without having an
+ * AMDGPU instance.
+ */
+ result = radv_physical_device_init(instance->physicalDevices +
+ instance->physicalDeviceCount,
+ instance, NULL);
+
+ ++instance->physicalDeviceCount;
+ return VK_SUCCESS;
+ }
+
max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
if (instance->debug_flags & RADV_DEBUG_STARTUP)
.shaderTessellationAndGeometryPointSize = true,
.shaderImageGatherExtended = true,
.shaderStorageImageExtendedFormats = true,
- .shaderStorageImageMultisample = pdevice->rad_info.chip_class >= GFX8,
+ .shaderStorageImageMultisample = true,
.shaderUniformBufferArrayDynamicIndexing = true,
.shaderSampledImageArrayDynamicIndexing = true,
.shaderStorageBufferArrayDynamicIndexing = true,
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
VkPhysicalDevice16BitStorageFeatures *features =
(VkPhysicalDevice16BitStorageFeatures*)ext;
- bool enabled = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
- features->storageBuffer16BitAccess = enabled;
- features->uniformAndStorageBuffer16BitAccess = enabled;
- features->storagePushConstant16 = enabled;
- features->storageInputOutput16 = enabled && LLVM_VERSION_MAJOR >= 9;
+ features->storageBuffer16BitAccess = !pdevice->use_aco;
+ features->uniformAndStorageBuffer16BitAccess = !pdevice->use_aco;
+ features->storagePushConstant16 = !pdevice->use_aco;
+ features->storageInputOutput16 = pdevice->rad_info.has_double_rate_fp16 && !pdevice->use_aco && LLVM_VERSION_MAJOR >= 9;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES: {
features->samplerYcbcrConversion = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT: {
- VkPhysicalDeviceDescriptorIndexingFeaturesEXT *features =
- (VkPhysicalDeviceDescriptorIndexingFeaturesEXT*)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES: {
+ VkPhysicalDeviceDescriptorIndexingFeatures *features =
+ (VkPhysicalDeviceDescriptorIndexingFeatures*)ext;
features->shaderInputAttachmentArrayDynamicIndexing = true;
features->shaderUniformTexelBufferArrayDynamicIndexing = true;
features->shaderStorageTexelBufferArrayDynamicIndexing = true;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *features =
(VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT *)ext;
- features->vertexAttributeInstanceRateDivisor = VK_TRUE;
- features->vertexAttributeInstanceRateZeroDivisor = VK_TRUE;
+ features->vertexAttributeInstanceRateDivisor = true;
+ features->vertexAttributeInstanceRateZeroDivisor = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
features->geometryStreams = !pdevice->use_ngg_streamout;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT: {
- VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *features =
- (VkPhysicalDeviceScalarBlockLayoutFeaturesEXT *)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES: {
+ VkPhysicalDeviceScalarBlockLayoutFeatures *features =
+ (VkPhysicalDeviceScalarBlockLayoutFeatures *)ext;
features->scalarBlockLayout = pdevice->rad_info.chip_class >= GFX7;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT: {
VkPhysicalDeviceMemoryPriorityFeaturesEXT *features =
(VkPhysicalDeviceMemoryPriorityFeaturesEXT *)ext;
- features->memoryPriority = VK_TRUE;
+ features->memoryPriority = true;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES_EXT: {
features->bufferDeviceAddressMultiDevice = false;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_DEVICE_ADDRESS_FEATURES: {
+ VkPhysicalDeviceBufferDeviceAddressFeatures *features =
+ (VkPhysicalDeviceBufferDeviceAddressFeatures *)ext;
+ features->bufferDeviceAddress = true;
+ features->bufferDeviceAddressCaptureReplay = false;
+ features->bufferDeviceAddressMultiDevice = false;
+ break;
+ }
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
(VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
features->depthClipEnable = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT: {
- VkPhysicalDeviceHostQueryResetFeaturesEXT *features =
- (VkPhysicalDeviceHostQueryResetFeaturesEXT *)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES: {
+ VkPhysicalDeviceHostQueryResetFeatures *features =
+ (VkPhysicalDeviceHostQueryResetFeatures *)ext;
features->hostQueryReset = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
- VkPhysicalDevice8BitStorageFeaturesKHR *features =
- (VkPhysicalDevice8BitStorageFeaturesKHR*)ext;
- bool enabled = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
- features->storageBuffer8BitAccess = enabled;
- features->uniformAndStorageBuffer8BitAccess = enabled;
- features->storagePushConstant8 = enabled;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES: {
+ VkPhysicalDevice8BitStorageFeatures *features =
+ (VkPhysicalDevice8BitStorageFeatures *)ext;
+ features->storageBuffer8BitAccess = !pdevice->use_aco;
+ features->uniformAndStorageBuffer8BitAccess = !pdevice->use_aco;
+ features->storagePushConstant8 = !pdevice->use_aco;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES_KHR: {
- VkPhysicalDeviceShaderFloat16Int8FeaturesKHR *features =
- (VkPhysicalDeviceShaderFloat16Int8FeaturesKHR*)ext;
- features->shaderFloat16 = pdevice->rad_info.chip_class >= GFX8 && !pdevice->use_aco;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_FLOAT16_INT8_FEATURES: {
+ VkPhysicalDeviceShaderFloat16Int8Features *features =
+ (VkPhysicalDeviceShaderFloat16Int8Features*)ext;
+ features->shaderFloat16 = pdevice->rad_info.has_double_rate_fp16 && !pdevice->use_aco;
features->shaderInt8 = !pdevice->use_aco;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR: {
- VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *features =
- (VkPhysicalDeviceShaderAtomicInt64FeaturesKHR *)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES: {
+ VkPhysicalDeviceShaderAtomicInt64Features *features =
+ (VkPhysicalDeviceShaderAtomicInt64Features *)ext;
features->shaderBufferInt64Atomics = LLVM_VERSION_MAJOR >= 9;
features->shaderSharedInt64Atomics = LLVM_VERSION_MAJOR >= 9;
break;
features->ycbcrImageArrays = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR: {
- VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *features =
- (VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR *)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES: {
+ VkPhysicalDeviceUniformBufferStandardLayoutFeatures *features =
+ (VkPhysicalDeviceUniformBufferStandardLayoutFeatures *)ext;
features->uniformBufferStandardLayout = true;
break;
}
features->indexTypeUint8 = pdevice->rad_info.chip_class >= GFX8;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES_KHR: {
- VkPhysicalDeviceImagelessFramebufferFeaturesKHR *features =
- (VkPhysicalDeviceImagelessFramebufferFeaturesKHR *)ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGELESS_FRAMEBUFFER_FEATURES: {
+ VkPhysicalDeviceImagelessFramebufferFeatures *features =
+ (VkPhysicalDeviceImagelessFramebufferFeatures *)ext;
features->imagelessFramebuffer = true;
break;
}
features->texelBufferAlignment = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR: {
- VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *features =
- (VkPhysicalDeviceTimelineSemaphoreFeaturesKHR *) ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES: {
+ VkPhysicalDeviceTimelineSemaphoreFeatures *features =
+ (VkPhysicalDeviceTimelineSemaphoreFeatures *) ext;
features->timelineSemaphore = true;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_FEATURES_EXT: {
+ VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *features =
+ (VkPhysicalDeviceSubgroupSizeControlFeaturesEXT *)ext;
+ features->subgroupSizeControl = true;
+ features->computeFullSubgroups = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COHERENT_MEMORY_FEATURES_AMD: {
+ VkPhysicalDeviceCoherentMemoryFeaturesAMD *features =
+ (VkPhysicalDeviceCoherentMemoryFeaturesAMD *)ext;
+ features->deviceCoherentMemory = pdevice->rad_info.has_l2_uncached;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_EXTENDED_TYPES_FEATURES: {
+ VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *features =
+ (VkPhysicalDeviceShaderSubgroupExtendedTypesFeatures *)ext;
+ features->shaderSubgroupExtendedTypes = !pdevice->use_aco;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SEPARATE_DEPTH_STENCIL_LAYOUTS_FEATURES_KHR: {
+ VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *features =
+ (VkPhysicalDeviceSeparateDepthStencilLayoutsFeaturesKHR *)ext;
+ features->separateDepthStencilLayouts = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES: {
+ VkPhysicalDeviceVulkan11Features *features =
+ (VkPhysicalDeviceVulkan11Features *)ext;
+ features->storageBuffer16BitAccess = !pdevice->use_aco;
+ features->uniformAndStorageBuffer16BitAccess = !pdevice->use_aco;
+ features->storagePushConstant16 = !pdevice->use_aco;
+ features->storageInputOutput16 = pdevice->rad_info.has_double_rate_fp16 && !pdevice->use_aco && LLVM_VERSION_MAJOR >= 9;
+ features->multiview = true;
+ features->multiviewGeometryShader = true;
+ features->multiviewTessellationShader = true;
+ features->variablePointersStorageBuffer = true;
+ features->variablePointers = true;
+ features->protectedMemory = false;
+ features->samplerYcbcrConversion = true;
+ features->shaderDrawParameters = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES: {
+ VkPhysicalDeviceVulkan12Features *features =
+ (VkPhysicalDeviceVulkan12Features *)ext;
+ features->samplerMirrorClampToEdge = true;
+ features->drawIndirectCount = true;
+ features->storageBuffer8BitAccess = !pdevice->use_aco;
+ features->uniformAndStorageBuffer8BitAccess = !pdevice->use_aco;
+ features->storagePushConstant8 = !pdevice->use_aco;
+ features->shaderBufferInt64Atomics = LLVM_VERSION_MAJOR >= 9;
+ features->shaderSharedInt64Atomics = LLVM_VERSION_MAJOR >= 9;
+ features->shaderFloat16 = pdevice->rad_info.has_double_rate_fp16 && !pdevice->use_aco;
+ features->shaderInt8 = !pdevice->use_aco;
+ features->descriptorIndexing = true;
+ features->shaderInputAttachmentArrayDynamicIndexing = true;
+ features->shaderUniformTexelBufferArrayDynamicIndexing = true;
+ features->shaderStorageTexelBufferArrayDynamicIndexing = true;
+ features->shaderUniformBufferArrayNonUniformIndexing = true;
+ features->shaderSampledImageArrayNonUniformIndexing = true;
+ features->shaderStorageBufferArrayNonUniformIndexing = true;
+ features->shaderStorageImageArrayNonUniformIndexing = true;
+ features->shaderInputAttachmentArrayNonUniformIndexing = true;
+ features->shaderUniformTexelBufferArrayNonUniformIndexing = true;
+ features->shaderStorageTexelBufferArrayNonUniformIndexing = true;
+ 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;
+ features->samplerFilterMinmax = true;
+ features->scalarBlockLayout = pdevice->rad_info.chip_class >= GFX7;
+ features->imagelessFramebuffer = true;
+ features->uniformBufferStandardLayout = true;
+ features->shaderSubgroupExtendedTypes = !pdevice->use_aco;
+ features->separateDepthStencilLayouts = true;
+ features->hostQueryReset = true;
+ features->timelineSemaphore = pdevice->rad_info.has_syncobj_wait_for_submit;
+ features->bufferDeviceAddress = true;
+ features->bufferDeviceAddressCaptureReplay = false;
+ features->bufferDeviceAddressMultiDevice = false;
+ features->vulkanMemoryModel = false;
+ features->vulkanMemoryModelDeviceScope = false;
+ features->vulkanMemoryModelAvailabilityVisibilityChains = false;
+ features->shaderOutputViewportIndex = true;
+ features->shaderOutputLayer = true;
+ features->subgroupBroadcastDynamicId = true;
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT: {
+ VkPhysicalDeviceLineRasterizationFeaturesEXT *features =
+ (VkPhysicalDeviceLineRasterizationFeaturesEXT *)ext;
+ features->rectangularLines = false;
+ features->bresenhamLines = true;
+ features->smoothLines = false;
+ features->stippledRectangularLines = false;
+ features->stippledBresenhamLines = true;
+ features->stippledSmoothLines = false;
+ break;
+ }
default:
break;
}
return radv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
}
-void radv_GetPhysicalDeviceProperties(
- VkPhysicalDevice physicalDevice,
- VkPhysicalDeviceProperties* pProperties)
+static size_t
+radv_max_descriptor_set_size()
{
- RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
- VkSampleCountFlags sample_counts = 0xf;
-
/* 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) /
+ return ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS
+ - MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
(32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
32 /* storage buffer, 32 due to potential space wasted on alignment */ +
32 /* sampler, largest when combined with image */ +
64 /* sampled image */ +
64 /* storage image */);
+}
+
+void radv_GetPhysicalDeviceProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties* pProperties)
+{
+ RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
+ VkSampleCountFlags sample_counts = 0xf;
+
+ size_t max_descriptor_set_size = radv_max_descriptor_set_size();
VkPhysicalDeviceLimits limits = {
.maxImageDimension1D = (1 << 14),
.maxMemoryAllocationCount = UINT32_MAX,
.maxSamplerAllocationCount = 64 * 1024,
.bufferImageGranularity = 64, /* A cache line */
- .sparseAddressSpaceSize = 0xffffffffu, /* buffer max size */
+ .sparseAddressSpaceSize = RADV_MAX_MEMORY_ALLOCATION_SIZE, /* buffer max size */
.maxBoundDescriptorSets = MAX_SETS,
.maxPerStageDescriptorSamplers = max_descriptor_set_size,
.maxPerStageDescriptorUniformBuffers = max_descriptor_set_size,
.maxFragmentCombinedOutputResources = 8,
.maxComputeSharedMemorySize = 32768,
.maxComputeWorkGroupCount = { 65535, 65535, 65535 },
- .maxComputeWorkGroupInvocations = 2048,
+ .maxComputeWorkGroupInvocations = 1024,
.maxComputeWorkGroupSize = {
- 2048,
- 2048,
- 2048
+ 1024,
+ 1024,
+ 1024
},
.subPixelPrecisionBits = 8,
.subTexelPrecisionBits = 8,
.framebufferNoAttachmentsSampleCounts = sample_counts,
.maxColorAttachments = MAX_RTS,
.sampledImageColorSampleCounts = sample_counts,
- .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
+ .sampledImageIntegerSampleCounts = sample_counts,
.sampledImageDepthSampleCounts = sample_counts,
.sampledImageStencilSampleCounts = sample_counts,
- .storageImageSampleCounts = pdevice->rad_info.chip_class >= GFX8 ? sample_counts : VK_SAMPLE_COUNT_1_BIT,
+ .storageImageSampleCounts = sample_counts,
.maxSampleMaskWords = 1,
.timestampComputeAndGraphics = true,
.timestampPeriod = 1000000.0 / pdevice->rad_info.clock_crystal_freq,
.maxCombinedClipAndCullDistances = 8,
.discreteQueuePriorities = 2,
.pointSizeRange = { 0.0, 8192.0 },
- .lineWidthRange = { 0.0, 7.9921875 },
+ .lineWidthRange = { 0.0, 8192.0 },
.pointSizeGranularity = (1.0 / 8.0),
- .lineWidthGranularity = (1.0 / 128.0),
+ .lineWidthGranularity = (1.0 / 8.0),
.strictLines = false, /* FINISHME */
.standardSampleLocations = true,
.optimalBufferCopyOffsetAlignment = 128,
memcpy(pProperties->pipelineCacheUUID, pdevice->cache_uuid, VK_UUID_SIZE);
}
+static void
+radv_get_physical_device_properties_1_1(struct radv_physical_device *pdevice,
+ VkPhysicalDeviceVulkan11Properties *p)
+{
+ assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES);
+
+ memcpy(p->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
+ memcpy(p->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
+ memset(p->deviceLUID, 0, VK_LUID_SIZE);
+ /* The LUID is for Windows. */
+ p->deviceLUIDValid = false;
+ p->deviceNodeMask = 0;
+
+ p->subgroupSize = RADV_SUBGROUP_SIZE;
+ p->subgroupSupportedStages = VK_SHADER_STAGE_ALL;
+ p->subgroupSupportedOperations = VK_SUBGROUP_FEATURE_BASIC_BIT |
+ VK_SUBGROUP_FEATURE_VOTE_BIT |
+ VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
+ VK_SUBGROUP_FEATURE_BALLOT_BIT |
+ VK_SUBGROUP_FEATURE_CLUSTERED_BIT |
+ VK_SUBGROUP_FEATURE_QUAD_BIT;
+
+ if (((pdevice->rad_info.chip_class == GFX6 ||
+ pdevice->rad_info.chip_class == GFX7) && !pdevice->use_aco) ||
+ pdevice->rad_info.chip_class >= GFX8) {
+ p->subgroupSupportedOperations |= VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
+ VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
+ }
+ p->subgroupQuadOperationsInAllStages = true;
+
+ p->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
+ p->maxMultiviewViewCount = MAX_VIEWS;
+ p->maxMultiviewInstanceIndex = INT_MAX;
+ p->protectedNoFault = false;
+ p->maxPerSetDescriptors = RADV_MAX_PER_SET_DESCRIPTORS;
+ p->maxMemoryAllocationSize = RADV_MAX_MEMORY_ALLOCATION_SIZE;
+}
+
+static void
+radv_get_physical_device_properties_1_2(struct radv_physical_device *pdevice,
+ VkPhysicalDeviceVulkan12Properties *p)
+{
+ assert(p->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES);
+
+ p->driverID = VK_DRIVER_ID_MESA_RADV;
+ snprintf(p->driverName, VK_MAX_DRIVER_NAME_SIZE, "radv");
+ snprintf(p->driverInfo, VK_MAX_DRIVER_INFO_SIZE,
+ "Mesa " PACKAGE_VERSION MESA_GIT_SHA1
+ " (LLVM " MESA_LLVM_VERSION_STRING ")");
+ p->conformanceVersion = (VkConformanceVersion) {
+ .major = 1,
+ .minor = 2,
+ .subminor = 0,
+ .patch = 0,
+ };
+
+ /* On AMD hardware, denormals and rounding modes for fp16/fp64 are
+ * controlled by the same config register.
+ */
+ if (pdevice->rad_info.has_double_rate_fp16) {
+ p->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
+ p->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
+ } else {
+ p->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
+ p->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
+ }
+
+ /* Do not allow both preserving and flushing denorms because different
+ * shaders in the same pipeline can have different settings and this
+ * won't work for merged shaders. To make it work, this requires LLVM
+ * support for changing the register. The same logic applies for the
+ * rounding modes because they are configured with the same config
+ * register. TODO: we can enable a lot of these for ACO when it
+ * supports all stages.
+ */
+ p->shaderDenormFlushToZeroFloat32 = true;
+ p->shaderDenormPreserveFloat32 = false;
+ p->shaderRoundingModeRTEFloat32 = true;
+ p->shaderRoundingModeRTZFloat32 = false;
+ p->shaderSignedZeroInfNanPreserveFloat32 = true;
+
+ p->shaderDenormFlushToZeroFloat16 = false;
+ p->shaderDenormPreserveFloat16 = pdevice->rad_info.has_double_rate_fp16;
+ p->shaderRoundingModeRTEFloat16 = pdevice->rad_info.has_double_rate_fp16;
+ p->shaderRoundingModeRTZFloat16 = false;
+ p->shaderSignedZeroInfNanPreserveFloat16 = pdevice->rad_info.has_double_rate_fp16;
+
+ p->shaderDenormFlushToZeroFloat64 = false;
+ p->shaderDenormPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
+ p->shaderRoundingModeRTEFloat64 = pdevice->rad_info.chip_class >= GFX8;
+ p->shaderRoundingModeRTZFloat64 = false;
+ p->shaderSignedZeroInfNanPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
+
+ p->maxUpdateAfterBindDescriptorsInAllPools = UINT32_MAX / 64;
+ p->shaderUniformBufferArrayNonUniformIndexingNative = false;
+ p->shaderSampledImageArrayNonUniformIndexingNative = false;
+ p->shaderStorageBufferArrayNonUniformIndexingNative = false;
+ p->shaderStorageImageArrayNonUniformIndexingNative = false;
+ p->shaderInputAttachmentArrayNonUniformIndexingNative = false;
+ p->robustBufferAccessUpdateAfterBind = false;
+ p->quadDivergentImplicitLod = false;
+
+ size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS -
+ MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
+ (32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
+ 32 /* storage buffer, 32 due to potential space wasted on alignment */ +
+ 32 /* sampler, largest when combined with image */ +
+ 64 /* sampled image */ +
+ 64 /* storage image */);
+ p->maxPerStageDescriptorUpdateAfterBindSamplers = max_descriptor_set_size;
+ p->maxPerStageDescriptorUpdateAfterBindUniformBuffers = max_descriptor_set_size;
+ p->maxPerStageDescriptorUpdateAfterBindStorageBuffers = max_descriptor_set_size;
+ p->maxPerStageDescriptorUpdateAfterBindSampledImages = max_descriptor_set_size;
+ p->maxPerStageDescriptorUpdateAfterBindStorageImages = max_descriptor_set_size;
+ p->maxPerStageDescriptorUpdateAfterBindInputAttachments = max_descriptor_set_size;
+ p->maxPerStageUpdateAfterBindResources = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindSamplers = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindUniformBuffers = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindUniformBuffersDynamic = MAX_DYNAMIC_UNIFORM_BUFFERS;
+ p->maxDescriptorSetUpdateAfterBindStorageBuffers = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindStorageBuffersDynamic = MAX_DYNAMIC_STORAGE_BUFFERS;
+ p->maxDescriptorSetUpdateAfterBindSampledImages = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindStorageImages = max_descriptor_set_size;
+ p->maxDescriptorSetUpdateAfterBindInputAttachments = max_descriptor_set_size;
+
+ /* We support all of the depth resolve modes */
+ p->supportedDepthResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |
+ VK_RESOLVE_MODE_AVERAGE_BIT_KHR |
+ VK_RESOLVE_MODE_MIN_BIT_KHR |
+ VK_RESOLVE_MODE_MAX_BIT_KHR;
+
+ /* Average doesn't make sense for stencil so we don't support that */
+ p->supportedStencilResolveModes = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR |
+ VK_RESOLVE_MODE_MIN_BIT_KHR |
+ VK_RESOLVE_MODE_MAX_BIT_KHR;
+
+ p->independentResolveNone = true;
+ p->independentResolve = true;
+
+ /* GFX6-8 only support single channel min/max filter. */
+ p->filterMinmaxImageComponentMapping = pdevice->rad_info.chip_class >= GFX9;
+ p->filterMinmaxSingleComponentFormats = true;
+
+ p->maxTimelineSemaphoreValueDifference = UINT64_MAX;
+
+ p->framebufferIntegerColorSampleCounts = VK_SAMPLE_COUNT_1_BIT;
+}
+
void radv_GetPhysicalDeviceProperties2(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceProperties2 *pProperties)
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
radv_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
+ VkPhysicalDeviceVulkan11Properties core_1_1 = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES,
+ };
+ radv_get_physical_device_properties_1_1(pdevice, &core_1_1);
+
+ VkPhysicalDeviceVulkan12Properties core_1_2 = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES,
+ };
+ radv_get_physical_device_properties_1_2(pdevice, &core_1_2);
+
+#define CORE_RENAMED_PROPERTY(major, minor, ext_property, core_property) \
+ memcpy(&properties->ext_property, &core_##major##_##minor.core_property, \
+ sizeof(core_##major##_##minor.core_property))
+
+#define CORE_PROPERTY(major, minor, property) \
+ CORE_RENAMED_PROPERTY(major, minor, property, property)
+
vk_foreach_struct(ext, pProperties->pNext) {
switch (ext->sType) {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
VkPhysicalDeviceIDProperties *properties = (VkPhysicalDeviceIDProperties*)ext;
- memcpy(properties->driverUUID, pdevice->driver_uuid, VK_UUID_SIZE);
- memcpy(properties->deviceUUID, pdevice->device_uuid, VK_UUID_SIZE);
- properties->deviceLUIDValid = false;
+ CORE_PROPERTY(1, 1, deviceUUID);
+ CORE_PROPERTY(1, 1, driverUUID);
+ CORE_PROPERTY(1, 1, deviceLUID);
+ CORE_PROPERTY(1, 1, deviceLUIDValid);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES: {
VkPhysicalDeviceMultiviewProperties *properties = (VkPhysicalDeviceMultiviewProperties*)ext;
- properties->maxMultiviewViewCount = MAX_VIEWS;
- properties->maxMultiviewInstanceIndex = INT_MAX;
+ CORE_PROPERTY(1, 1, maxMultiviewViewCount);
+ CORE_PROPERTY(1, 1, maxMultiviewInstanceIndex);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES: {
VkPhysicalDevicePointClippingProperties *properties =
(VkPhysicalDevicePointClippingProperties*)ext;
- properties->pointClippingBehavior = VK_POINT_CLIPPING_BEHAVIOR_ALL_CLIP_PLANES;
+ CORE_PROPERTY(1, 1, pointClippingBehavior);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT: {
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES: {
VkPhysicalDeviceSubgroupProperties *properties =
(VkPhysicalDeviceSubgroupProperties*)ext;
- properties->subgroupSize = 64;
- properties->supportedStages = VK_SHADER_STAGE_ALL;
- properties->supportedOperations =
- VK_SUBGROUP_FEATURE_BASIC_BIT |
- VK_SUBGROUP_FEATURE_BALLOT_BIT |
- VK_SUBGROUP_FEATURE_QUAD_BIT |
- VK_SUBGROUP_FEATURE_VOTE_BIT;
- if (pdevice->rad_info.chip_class >= GFX8) {
- properties->supportedOperations |=
- VK_SUBGROUP_FEATURE_ARITHMETIC_BIT |
- VK_SUBGROUP_FEATURE_CLUSTERED_BIT |
- VK_SUBGROUP_FEATURE_SHUFFLE_BIT |
- VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT;
- }
- properties->quadOperationsInAllStages = true;
+ CORE_PROPERTY(1, 1, subgroupSize);
+ CORE_RENAMED_PROPERTY(1, 1, supportedStages,
+ subgroupSupportedStages);
+ CORE_RENAMED_PROPERTY(1, 1, supportedOperations,
+ subgroupSupportedOperations);
+ CORE_RENAMED_PROPERTY(1, 1, quadOperationsInAllStages,
+ subgroupQuadOperationsInAllStages);
break;
}
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;
+ CORE_PROPERTY(1, 1, maxPerSetDescriptors);
+ CORE_PROPERTY(1, 1, maxMemoryAllocationSize);
break;
}
- 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;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES: {
+ VkPhysicalDeviceSamplerFilterMinmaxProperties *properties =
+ (VkPhysicalDeviceSamplerFilterMinmaxProperties *)ext;
+ CORE_PROPERTY(1, 2, filterMinmaxImageComponentMapping);
+ CORE_PROPERTY(1, 2, filterMinmaxSingleComponentFormats);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD: {
pdevice->rad_info.max_sh_per_se;
properties->computeUnitsPerShaderArray =
pdevice->rad_info.num_good_cu_per_sh;
- properties->simdPerComputeUnit = 4;
+ properties->simdPerComputeUnit =
+ pdevice->rad_info.num_simd_per_compute_unit;
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 ||
- pdevice->rad_info.family == CHIP_POLARIS12 ||
- pdevice->rad_info.family == CHIP_VEGAM ? 8 : 10;
+ pdevice->rad_info.max_wave64_per_simd;
properties->wavefrontSize = 64;
/* SGPR. */
properties->sgprsPerSimd =
pdevice->rad_info.num_physical_sgprs_per_simd;
properties->minSgprAllocation =
- pdevice->rad_info.chip_class >= GFX8 ? 16 : 8;
+ pdevice->rad_info.min_sgpr_alloc;
properties->maxSgprAllocation =
- pdevice->rad_info.family == CHIP_TONGA ||
- pdevice->rad_info.family == CHIP_ICELAND ? 96 : 104;
+ pdevice->rad_info.max_sgpr_alloc;
properties->sgprAllocationGranularity =
- pdevice->rad_info.chip_class >= GFX8 ? 16 : 8;
+ pdevice->rad_info.sgpr_alloc_granularity;
/* VGPR. */
- properties->vgprsPerSimd = RADV_NUM_PHYSICAL_VGPRS;
- properties->minVgprAllocation = 4;
- properties->maxVgprAllocation = 256;
- properties->vgprAllocationGranularity = 4;
+ properties->vgprsPerSimd =
+ pdevice->rad_info.num_physical_wave64_vgprs_per_simd;
+ properties->minVgprAllocation =
+ pdevice->rad_info.min_wave64_vgpr_alloc;
+ properties->maxVgprAllocation =
+ pdevice->rad_info.max_vgpr_alloc;
+ properties->vgprAllocationGranularity =
+ pdevice->rad_info.wave64_vgpr_alloc_granularity;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_2_AMD: {
properties->maxVertexAttribDivisor = UINT32_MAX;
break;
}
- 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;
-
- size_t max_descriptor_set_size = ((1ull << 31) - 16 * MAX_DYNAMIC_BUFFERS -
- MAX_INLINE_UNIFORM_BLOCK_SIZE * MAX_INLINE_UNIFORM_BLOCK_COUNT) /
- (32 /* uniform buffer, 32 due to potential space wasted on alignment */ +
- 32 /* storage buffer, 32 due to potential space wasted on alignment */ +
- 32 /* sampler, largest when combined with image */ +
- 64 /* sampled image */ +
- 64 /* storage image */);
- 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;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES: {
+ VkPhysicalDeviceDescriptorIndexingProperties *properties =
+ (VkPhysicalDeviceDescriptorIndexingProperties*)ext;
+ CORE_PROPERTY(1, 2, maxUpdateAfterBindDescriptorsInAllPools);
+ CORE_PROPERTY(1, 2, shaderUniformBufferArrayNonUniformIndexingNative);
+ CORE_PROPERTY(1, 2, shaderSampledImageArrayNonUniformIndexingNative);
+ CORE_PROPERTY(1, 2, shaderStorageBufferArrayNonUniformIndexingNative);
+ CORE_PROPERTY(1, 2, shaderStorageImageArrayNonUniformIndexingNative);
+ CORE_PROPERTY(1, 2, shaderInputAttachmentArrayNonUniformIndexingNative);
+ CORE_PROPERTY(1, 2, robustBufferAccessUpdateAfterBind);
+ CORE_PROPERTY(1, 2, quadDivergentImplicitLod);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSamplers);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindUniformBuffers);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageBuffers);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindSampledImages);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindStorageImages);
+ CORE_PROPERTY(1, 2, maxPerStageDescriptorUpdateAfterBindInputAttachments);
+ CORE_PROPERTY(1, 2, maxPerStageUpdateAfterBindResources);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSamplers);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffers);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindUniformBuffersDynamic);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffers);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageBuffersDynamic);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindSampledImages);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindStorageImages);
+ CORE_PROPERTY(1, 2, maxDescriptorSetUpdateAfterBindInputAttachments);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
VkPhysicalDeviceProtectedMemoryProperties *properties =
(VkPhysicalDeviceProtectedMemoryProperties *)ext;
- properties->protectedNoFault = false;
+ CORE_PROPERTY(1, 1, protectedNoFault);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_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;
+ properties->primitiveUnderestimation = false;
+ properties->conservativePointAndLineRasterization = false;
+ properties->degenerateTrianglesRasterized = false;
+ properties->degenerateLinesRasterized = false;
+ properties->fullyCoveredFragmentShaderInputVariable = false;
+ properties->conservativeRasterizationPostDepthCoverage = false;
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT: {
properties->pciFunction = pdevice->bus_info.func;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR: {
- VkPhysicalDeviceDriverPropertiesKHR *driver_props =
- (VkPhysicalDeviceDriverPropertiesKHR *) ext;
-
- driver_props->driverID = VK_DRIVER_ID_MESA_RADV_KHR;
- snprintf(driver_props->driverName, VK_MAX_DRIVER_NAME_SIZE_KHR, "radv");
- snprintf(driver_props->driverInfo, VK_MAX_DRIVER_INFO_SIZE_KHR,
- "Mesa " PACKAGE_VERSION MESA_GIT_SHA1
- " (LLVM " MESA_LLVM_VERSION_STRING ")");
-
- driver_props->conformanceVersion = (VkConformanceVersionKHR) {
- .major = 1,
- .minor = 1,
- .subminor = 2,
- .patch = 0,
- };
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES: {
+ VkPhysicalDeviceDriverProperties *properties =
+ (VkPhysicalDeviceDriverProperties *) ext;
+ CORE_PROPERTY(1, 2, driverID);
+ CORE_PROPERTY(1, 2, driverName);
+ CORE_PROPERTY(1, 2, driverInfo);
+ CORE_PROPERTY(1, 2, conformanceVersion);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
properties->sampleLocationCoordinateRange[0] = 0.0f;
properties->sampleLocationCoordinateRange[1] = 0.9375f;
properties->sampleLocationSubPixelBits = 4;
- properties->variableSampleLocations = VK_FALSE;
+ properties->variableSampleLocations = false;
break;
}
- 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;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES: {
+ VkPhysicalDeviceDepthStencilResolveProperties *properties =
+ (VkPhysicalDeviceDepthStencilResolveProperties *)ext;
+ CORE_PROPERTY(1, 2, supportedDepthResolveModes);
+ CORE_PROPERTY(1, 2, supportedStencilResolveModes);
+ CORE_PROPERTY(1, 2, independentResolveNone);
+ CORE_PROPERTY(1, 2, independentResolve);
break;
}
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT: {
properties->uniformTexelBufferOffsetSingleTexelAlignment = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR : {
- VkPhysicalDeviceFloatControlsPropertiesKHR *properties =
- (VkPhysicalDeviceFloatControlsPropertiesKHR *)ext;
-
- /* On AMD hardware, denormals and rounding modes for
- * fp16/fp64 are controlled by the same config
- * register.
- */
- properties->denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
- properties->roundingModeIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
-
- /* Do not allow both preserving and flushing denorms
- * because different shaders in the same pipeline can
- * have different settings and this won't work for
- * merged shaders. To make it work, this requires LLVM
- * support for changing the register. The same logic
- * applies for the rounding modes because they are
- * configured with the same config register.
- */
- properties->shaderDenormFlushToZeroFloat32 = true;
- properties->shaderDenormPreserveFloat32 = false;
- properties->shaderRoundingModeRTEFloat32 = true;
- properties->shaderRoundingModeRTZFloat32 = false;
- properties->shaderSignedZeroInfNanPreserveFloat32 = true;
-
- properties->shaderDenormFlushToZeroFloat16 = false;
- properties->shaderDenormPreserveFloat16 = pdevice->rad_info.chip_class >= GFX8;
- properties->shaderRoundingModeRTEFloat16 = pdevice->rad_info.chip_class >= GFX8;
- properties->shaderRoundingModeRTZFloat16 = false;
- properties->shaderSignedZeroInfNanPreserveFloat16 = pdevice->rad_info.chip_class >= GFX8;
-
- properties->shaderDenormFlushToZeroFloat64 = false;
- properties->shaderDenormPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
- properties->shaderRoundingModeRTEFloat64 = pdevice->rad_info.chip_class >= GFX8;
- properties->shaderRoundingModeRTZFloat64 = false;
- properties->shaderSignedZeroInfNanPreserveFloat64 = pdevice->rad_info.chip_class >= GFX8;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES : {
+ VkPhysicalDeviceFloatControlsProperties *properties =
+ (VkPhysicalDeviceFloatControlsProperties *)ext;
+ CORE_PROPERTY(1, 2, denormBehaviorIndependence);
+ CORE_PROPERTY(1, 2, roundingModeIndependence);
+ CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat16);
+ CORE_PROPERTY(1, 2, shaderDenormPreserveFloat16);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat16);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat16);
+ CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat16);
+ CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat32);
+ CORE_PROPERTY(1, 2, shaderDenormPreserveFloat32);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat32);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat32);
+ CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat32);
+ CORE_PROPERTY(1, 2, shaderDenormFlushToZeroFloat64);
+ CORE_PROPERTY(1, 2, shaderDenormPreserveFloat64);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTEFloat64);
+ CORE_PROPERTY(1, 2, shaderRoundingModeRTZFloat64);
+ CORE_PROPERTY(1, 2, shaderSignedZeroInfNanPreserveFloat64);
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES: {
+ VkPhysicalDeviceTimelineSemaphoreProperties *properties =
+ (VkPhysicalDeviceTimelineSemaphoreProperties *) ext;
+ CORE_PROPERTY(1, 2, maxTimelineSemaphoreValueDifference);
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_PROPERTIES_KHR: {
- VkPhysicalDeviceTimelineSemaphorePropertiesKHR *props =
- (VkPhysicalDeviceTimelineSemaphorePropertiesKHR *) ext;
- props->maxTimelineSemaphoreValueDifference = UINT64_MAX;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_SIZE_CONTROL_PROPERTIES_EXT: {
+ VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *props =
+ (VkPhysicalDeviceSubgroupSizeControlPropertiesEXT *)ext;
+ props->minSubgroupSize = 64;
+ props->maxSubgroupSize = 64;
+ props->maxComputeWorkgroupSubgroups = UINT32_MAX;
+ props->requiredSubgroupSizeStages = 0;
+
+ if (pdevice->rad_info.chip_class >= GFX10) {
+ /* Only GFX10+ supports wave32. */
+ props->minSubgroupSize = 32;
+ props->requiredSubgroupSizeStages = VK_SHADER_STAGE_COMPUTE_BIT;
+ }
+ break;
+ }
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_PROPERTIES:
+ radv_get_physical_device_properties_1_1(pdevice, (void *)ext);
+ break;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES:
+ radv_get_physical_device_properties_1_2(pdevice, (void *)ext);
+ break;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_PROPERTIES_EXT: {
+ VkPhysicalDeviceLineRasterizationPropertiesEXT *props =
+ (VkPhysicalDeviceLineRasterizationPropertiesEXT *)ext;
+ props->lineSubPixelPrecisionBits = 4;
break;
}
default:
{
int num_queue_families = 1;
int idx;
- if (pdevice->rad_info.num_compute_rings > 0 &&
+ if (pdevice->rad_info.num_rings[RING_COMPUTE] > 0 &&
!(pdevice->instance->debug_flags & RADV_DEBUG_NO_COMPUTE_QUEUE))
num_queue_families++;
idx++;
}
- if (pdevice->rad_info.num_compute_rings > 0 &&
+ if (pdevice->rad_info.num_rings[RING_COMPUTE] > 0 &&
!(pdevice->instance->debug_flags & RADV_DEBUG_NO_COMPUTE_QUEUE)) {
if (*pCount > idx) {
*pQueueFamilyProperties[idx] = (VkQueueFamilyProperties) {
.queueFlags = VK_QUEUE_COMPUTE_BIT |
VK_QUEUE_TRANSFER_BIT |
VK_QUEUE_SPARSE_BINDING_BIT,
- .queueCount = pdevice->rad_info.num_compute_rings,
+ .queueCount = pdevice->rad_info.num_rings[RING_COMPUTE],
.timestampValidBits = 64,
.minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
};
for (int i = 0; i < device->memory_properties.memoryTypeCount; i++) {
uint32_t heap_index = device->memory_properties.memoryTypes[i].heapIndex;
- switch (device->mem_type_indices[i]) {
- case RADV_MEM_TYPE_VRAM:
+ if (radv_is_mem_type_vram(device->mem_type_indices[i])) {
heap_usage = device->ws->query_value(device->ws,
RADEON_ALLOCATED_VRAM);
memoryBudget->heapBudget[heap_index] = heap_budget;
memoryBudget->heapUsage[heap_index] = heap_usage;
- break;
- case RADV_MEM_TYPE_VRAM_CPU_ACCESS:
+ } else if (radv_is_mem_type_vram_visible(device->mem_type_indices[i])) {
heap_usage = device->ws->query_value(device->ws,
RADEON_ALLOCATED_VRAM_VIS);
memoryBudget->heapBudget[heap_index] = heap_budget;
memoryBudget->heapUsage[heap_index] = heap_usage;
- break;
- case RADV_MEM_TYPE_GTT_WRITE_COMBINE:
+ } else if (radv_is_mem_type_gtt_wc(device->mem_type_indices[i])) {
heap_usage = device->ws->query_value(device->ws,
RADEON_ALLOCATED_GTT);
memoryBudget->heapBudget[heap_index] = heap_budget;
memoryBudget->heapUsage[heap_index] = heap_usage;
- break;
- default:
- break;
}
}
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) {
+ if (radv_is_mem_type_gtt_cached(physical_device->mem_type_indices[i])) {
memoryTypeBits = (1 << i);
break;
}
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, AUDIT_ARCH_X86_64, 0, 12),
/* Futex is required for mutex locks */
+ #if defined __NR__newselect
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR__newselect, 11, 0),
+ #elif defined __NR_select
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_select, 11, 0),
+ #else
+ BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
+ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_pselect6, 11, 0),
+ #endif
/* Allow system exit calls for the forked process */
BPF_STMT(BPF_LD + BPF_W + BPF_ABS, (offsetof(struct seccomp_data, nr))),
}
}
+static bool radv_close_all_fds(const int *keep_fds, int keep_fd_count)
+{
+ DIR *d;
+ struct dirent *dir;
+ d = opendir("/proc/self/fd");
+ if (!d)
+ return false;
+ int dir_fd = dirfd(d);
+
+ while ((dir = readdir(d)) != NULL) {
+ if (dir->d_name[0] == '.')
+ continue;
+
+ int fd = atoi(dir->d_name);
+ if (fd == dir_fd)
+ continue;
+
+ bool keep = false;
+ for (int i = 0; !keep && i < keep_fd_count; ++i)
+ if (keep_fds[i] == fd)
+ keep = true;
+
+ if (keep)
+ continue;
+
+ close(fd);
+ }
+ closedir(d);
+ return true;
+}
+
+static bool secure_compile_open_fifo_fds(struct radv_secure_compile_state *sc,
+ int *fd_server, int *fd_client,
+ unsigned process, bool make_fifo)
+{
+ bool result = false;
+ char *fifo_server_path = NULL;
+ char *fifo_client_path = NULL;
+
+ if (asprintf(&fifo_server_path, "/tmp/radv_server_%s_%u", sc->uid, process) == -1)
+ goto open_fifo_exit;
+
+ if (asprintf(&fifo_client_path, "/tmp/radv_client_%s_%u", sc->uid, process) == -1)
+ goto open_fifo_exit;
+
+ if (make_fifo) {
+ int file1 = mkfifo(fifo_server_path, 0666);
+ if(file1 < 0)
+ goto open_fifo_exit;
+
+ int file2 = mkfifo(fifo_client_path, 0666);
+ if(file2 < 0)
+ goto open_fifo_exit;
+ }
+
+ *fd_server = open(fifo_server_path, O_RDWR);
+ if(*fd_server < 1)
+ goto open_fifo_exit;
+
+ *fd_client = open(fifo_client_path, O_RDWR);
+ if(*fd_client < 1) {
+ close(*fd_server);
+ goto open_fifo_exit;
+ }
+
+ result = true;
+
+open_fifo_exit:
+ free(fifo_server_path);
+ free(fifo_client_path);
+
+ return result;
+}
+
static void run_secure_compile_device(struct radv_device *device, unsigned process,
- int *fd_secure_input, int *fd_secure_output)
+ int fd_idle_device_output)
{
+ int fd_secure_input;
+ int fd_secure_output;
+ bool fifo_result = secure_compile_open_fifo_fds(device->sc_state,
+ &fd_secure_input,
+ &fd_secure_output,
+ process, false);
+
enum radv_secure_compile_type sc_type;
- if (install_seccomp_filter() == -1) {
+
+ const int needed_fds[] = {
+ fd_secure_input,
+ fd_secure_output,
+ fd_idle_device_output,
+ };
+
+ if (!fifo_result || !radv_close_all_fds(needed_fds, ARRAY_SIZE(needed_fds)) ||
+ install_seccomp_filter() == -1) {
sc_type = RADV_SC_TYPE_INIT_FAILURE;
} else {
sc_type = RADV_SC_TYPE_INIT_SUCCESS;
- device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input[0];
- device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output[1];
+ device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input;
+ device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output;
}
- write(fd_secure_output[1], &sc_type, sizeof(sc_type));
+ write(fd_idle_device_output, &sc_type, sizeof(sc_type));
if (sc_type == RADV_SC_TYPE_INIT_FAILURE)
goto secure_compile_exit;
while (true) {
- radv_sc_read(fd_secure_input[0], &sc_type, sizeof(sc_type), false);
+ radv_sc_read(fd_secure_input, &sc_type, sizeof(sc_type), false);
if (sc_type == RADV_SC_TYPE_COMPILE_PIPELINE) {
struct radv_pipeline *pipeline;
/* Read pipeline layout */
struct radv_pipeline_layout layout;
- sc_read = radv_sc_read(fd_secure_input[0], &layout, sizeof(struct radv_pipeline_layout), true);
- sc_read &= radv_sc_read(fd_secure_input[0], &layout.num_sets, sizeof(uint32_t), true);
+ sc_read = radv_sc_read(fd_secure_input, &layout, sizeof(struct radv_pipeline_layout), true);
+ sc_read &= radv_sc_read(fd_secure_input, &layout.num_sets, sizeof(uint32_t), true);
if (!sc_read)
goto secure_compile_exit;
for (uint32_t set = 0; set < layout.num_sets; set++) {
uint32_t layout_size;
- sc_read &= radv_sc_read(fd_secure_input[0], &layout_size, sizeof(uint32_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &layout_size, sizeof(uint32_t), true);
if (!sc_read)
goto secure_compile_exit;
layout.set[set].layout = malloc(layout_size);
layout.set[set].layout->layout_size = layout_size;
- sc_read &= radv_sc_read(fd_secure_input[0], layout.set[set].layout,
+ sc_read &= radv_sc_read(fd_secure_input, layout.set[set].layout,
layout.set[set].layout->layout_size, true);
}
/* Read pipeline key */
struct radv_pipeline_key key;
- sc_read &= radv_sc_read(fd_secure_input[0], &key, sizeof(struct radv_pipeline_key), true);
+ sc_read &= radv_sc_read(fd_secure_input, &key, sizeof(struct radv_pipeline_key), true);
/* Read pipeline create flags */
VkPipelineCreateFlags flags;
- sc_read &= radv_sc_read(fd_secure_input[0], &flags, sizeof(VkPipelineCreateFlags), true);
+ sc_read &= radv_sc_read(fd_secure_input, &flags, sizeof(VkPipelineCreateFlags), true);
/* Read stage and shader information */
uint32_t num_stages;
const VkPipelineShaderStageCreateInfo *pStages[MESA_SHADER_STAGES] = { 0, };
- sc_read &= radv_sc_read(fd_secure_input[0], &num_stages, sizeof(uint32_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &num_stages, sizeof(uint32_t), true);
if (!sc_read)
goto secure_compile_exit;
/* Read stage */
gl_shader_stage stage;
- sc_read &= radv_sc_read(fd_secure_input[0], &stage, sizeof(gl_shader_stage), true);
+ sc_read &= radv_sc_read(fd_secure_input, &stage, sizeof(gl_shader_stage), true);
VkPipelineShaderStageCreateInfo *pStage = calloc(1, sizeof(VkPipelineShaderStageCreateInfo));
/* Read entry point name */
size_t name_size;
- sc_read &= radv_sc_read(fd_secure_input[0], &name_size, sizeof(size_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &name_size, sizeof(size_t), true);
if (!sc_read)
goto secure_compile_exit;
char *ep_name = malloc(name_size);
- sc_read &= radv_sc_read(fd_secure_input[0], ep_name, name_size, true);
+ sc_read &= radv_sc_read(fd_secure_input, ep_name, name_size, true);
pStage->pName = ep_name;
/* Read shader module */
size_t module_size;
- sc_read &= radv_sc_read(fd_secure_input[0], &module_size, sizeof(size_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &module_size, sizeof(size_t), true);
if (!sc_read)
goto secure_compile_exit;
struct radv_shader_module *module = malloc(module_size);
- sc_read &= radv_sc_read(fd_secure_input[0], module, module_size, true);
+ sc_read &= radv_sc_read(fd_secure_input, module, module_size, true);
pStage->module = radv_shader_module_to_handle(module);
/* Read specialization info */
bool has_spec_info;
- sc_read &= radv_sc_read(fd_secure_input[0], &has_spec_info, sizeof(bool), true);
+ sc_read &= radv_sc_read(fd_secure_input, &has_spec_info, sizeof(bool), true);
if (!sc_read)
goto secure_compile_exit;
VkSpecializationInfo *specInfo = malloc(sizeof(VkSpecializationInfo));
pStage->pSpecializationInfo = specInfo;
- sc_read &= radv_sc_read(fd_secure_input[0], &specInfo->dataSize, sizeof(size_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &specInfo->dataSize, sizeof(size_t), true);
if (!sc_read)
goto secure_compile_exit;
void *si_data = malloc(specInfo->dataSize);
- sc_read &= radv_sc_read(fd_secure_input[0], si_data, specInfo->dataSize, true);
+ sc_read &= radv_sc_read(fd_secure_input, si_data, specInfo->dataSize, true);
specInfo->pData = si_data;
- sc_read &= radv_sc_read(fd_secure_input[0], &specInfo->mapEntryCount, sizeof(uint32_t), true);
+ sc_read &= radv_sc_read(fd_secure_input, &specInfo->mapEntryCount, sizeof(uint32_t), true);
if (!sc_read)
goto secure_compile_exit;
VkSpecializationMapEntry *mapEntries = malloc(sizeof(VkSpecializationMapEntry) * specInfo->mapEntryCount);
for (uint32_t j = 0; j < specInfo->mapEntryCount; j++) {
- sc_read &= radv_sc_read(fd_secure_input[0], &mapEntries[j], sizeof(VkSpecializationMapEntry), true);
+ sc_read &= radv_sc_read(fd_secure_input, &mapEntries[j], sizeof(VkSpecializationMapEntry), true);
if (!sc_read)
goto secure_compile_exit;
}
vk_free(&device->alloc, pipeline);
sc_type = RADV_SC_TYPE_COMPILE_PIPELINE_FINISHED;
- write(fd_secure_output[1], &sc_type, sizeof(sc_type));
+ write(fd_secure_output, &sc_type, sizeof(sc_type));
+
+ } else if (sc_type == RADV_SC_TYPE_DESTROY_DEVICE) {
+ goto secure_compile_exit;
+ }
+ }
+
+secure_compile_exit:
+ close(fd_secure_input);
+ close(fd_secure_output);
+ close(fd_idle_device_output);
+ _exit(0);
+}
+
+static enum radv_secure_compile_type fork_secure_compile_device(struct radv_device *device, unsigned process)
+{
+ int fd_secure_input[2];
+ int fd_secure_output[2];
+
+ /* create pipe descriptors (used to communicate between processes) */
+ if (pipe(fd_secure_input) == -1 || pipe(fd_secure_output) == -1)
+ return RADV_SC_TYPE_INIT_FAILURE;
+
+
+ int sc_pid;
+ if ((sc_pid = fork()) == 0) {
+ device->sc_state->secure_compile_thread_counter = process;
+ run_secure_compile_device(device, process, fd_secure_output[1]);
+ } else {
+ if (sc_pid == -1)
+ return RADV_SC_TYPE_INIT_FAILURE;
+
+ /* Read the init result returned from the secure process */
+ enum radv_secure_compile_type sc_type;
+ bool sc_read = radv_sc_read(fd_secure_output[0], &sc_type, sizeof(sc_type), true);
+
+ if (sc_type == RADV_SC_TYPE_INIT_FAILURE || !sc_read) {
+ close(fd_secure_input[0]);
+ close(fd_secure_input[1]);
+ close(fd_secure_output[1]);
+ close(fd_secure_output[0]);
+ int status;
+ waitpid(sc_pid, &status, 0);
+
+ return RADV_SC_TYPE_INIT_FAILURE;
+ } else {
+ assert(sc_type == RADV_SC_TYPE_INIT_SUCCESS);
+ write(device->sc_state->secure_compile_processes[process].fd_secure_output, &sc_type, sizeof(sc_type));
+
+ close(fd_secure_input[0]);
+ close(fd_secure_input[1]);
+ close(fd_secure_output[1]);
+ close(fd_secure_output[0]);
+
+ int status;
+ waitpid(sc_pid, &status, 0);
+ }
+ }
+
+ return RADV_SC_TYPE_INIT_SUCCESS;
+}
+
+/* Run a bare bones fork of a device that was forked right after its creation.
+ * This device will have low overhead when it is forked again before each
+ * pipeline compilation. This device sits idle and its only job is to fork
+ * itself.
+ */
+static void run_secure_compile_idle_device(struct radv_device *device, unsigned process,
+ int fd_secure_input, int fd_secure_output)
+{
+ enum radv_secure_compile_type sc_type = RADV_SC_TYPE_INIT_SUCCESS;
+ device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input;
+ device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output;
+
+ write(fd_secure_output, &sc_type, sizeof(sc_type));
+
+ while (true) {
+ radv_sc_read(fd_secure_input, &sc_type, sizeof(sc_type), false);
+
+ if (sc_type == RADV_SC_TYPE_FORK_DEVICE) {
+ sc_type = fork_secure_compile_device(device, process);
+
+ if (sc_type == RADV_SC_TYPE_INIT_FAILURE)
+ goto secure_compile_exit;
} else if (sc_type == RADV_SC_TYPE_DESTROY_DEVICE) {
goto secure_compile_exit;
}
secure_compile_exit:
- close(fd_secure_input[1]);
- close(fd_secure_input[0]);
- close(fd_secure_output[1]);
- close(fd_secure_output[0]);
+ close(fd_secure_input);
+ close(fd_secure_output);
_exit(0);
}
waitpid(device->sc_state->secure_compile_processes[process].sc_pid, &status, 0);
}
-static VkResult fork_secure_compile_device(struct radv_device *device)
+static VkResult fork_secure_compile_idle_device(struct radv_device *device)
{
device->sc_state = vk_zalloc(&device->alloc,
sizeof(struct radv_secure_compile_state),
mtx_init(&device->sc_state->secure_compile_mutex, mtx_plain);
+ pid_t upid = getpid();
+ time_t seconds = time(NULL);
+
+ char *uid;
+ if (asprintf(&uid, "%ld_%ld", (long) upid, (long) seconds) == -1)
+ return VK_ERROR_INITIALIZATION_FAILED;
+
+ device->sc_state->uid = uid;
+
uint8_t sc_threads = device->instance->num_sc_threads;
int fd_secure_input[MAX_SC_PROCS][2];
int fd_secure_output[MAX_SC_PROCS][2];
for (unsigned process = 0; process < sc_threads; process++) {
if ((device->sc_state->secure_compile_processes[process].sc_pid = fork()) == 0) {
device->sc_state->secure_compile_thread_counter = process;
- run_secure_compile_device(device, process, fd_secure_input[process], fd_secure_output[process]);
+ run_secure_compile_idle_device(device, process, fd_secure_input[process][0], fd_secure_output[process][1]);
} else {
if (device->sc_state->secure_compile_processes[process].sc_pid == -1)
return VK_ERROR_INITIALIZATION_FAILED;
enum radv_secure_compile_type sc_type;
bool sc_read = radv_sc_read(fd_secure_output[process][0], &sc_type, sizeof(sc_type), true);
- if (sc_type == RADV_SC_TYPE_INIT_FAILURE || !sc_read) {
+ bool fifo_result;
+ if (sc_read && sc_type == RADV_SC_TYPE_INIT_SUCCESS) {
+ fifo_result = secure_compile_open_fifo_fds(device->sc_state,
+ &device->sc_state->secure_compile_processes[process].fd_server,
+ &device->sc_state->secure_compile_processes[process].fd_client,
+ process, true);
+
+ device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input[process][1];
+ device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output[process][0];
+ }
+
+ if (sc_type == RADV_SC_TYPE_INIT_FAILURE || !sc_read || !fifo_result) {
close(fd_secure_input[process][0]);
close(fd_secure_input[process][1]);
close(fd_secure_output[process][1]);
}
return VK_ERROR_INITIALIZATION_FAILED;
- } else {
- assert(sc_type == RADV_SC_TYPE_INIT_SUCCESS);
- device->sc_state->secure_compile_processes[process].fd_secure_input = fd_secure_input[process][1];
- device->sc_state->secure_compile_processes[process].fd_secure_output = fd_secure_output[process][0];
}
}
}
return VK_SUCCESS;
}
+static void
+radv_device_init_dispatch(struct radv_device *device)
+{
+ const struct radv_instance *instance = device->physical_device->instance;
+ const struct radv_device_dispatch_table *dispatch_table_layer = NULL;
+ bool unchecked = instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS;
+ int radv_thread_trace = radv_get_int_debug_option("RADV_THREAD_TRACE", -1);
+
+ if (radv_thread_trace >= 0) {
+ /* Use device entrypoints from the SQTT layer if enabled. */
+ dispatch_table_layer = &sqtt_device_dispatch_table;
+ }
+
+ for (unsigned i = 0; i < ARRAY_SIZE(device->dispatch.entrypoints); i++) {
+ /* Vulkan requires that entrypoints for extensions which have not been
+ * enabled must not be advertised.
+ */
+ if (!unchecked &&
+ !radv_device_entrypoint_is_enabled(i, instance->apiVersion,
+ &instance->enabled_extensions,
+ &device->enabled_extensions)) {
+ device->dispatch.entrypoints[i] = NULL;
+ } else if (dispatch_table_layer &&
+ dispatch_table_layer->entrypoints[i]) {
+ device->dispatch.entrypoints[i] =
+ dispatch_table_layer->entrypoints[i];
+ } else {
+ device->dispatch.entrypoints[i] =
+ radv_device_dispatch_table.entrypoints[i];
+ }
+ }
+}
+
static VkResult
radv_create_pthread_cond(pthread_cond_t *cond)
{
device->enabled_extensions.extensions[index] = true;
}
+ radv_device_init_dispatch(device);
+
keep_shader_info = device->enabled_extensions.AMD_shader_info;
/* With update after bind we can't attach bo's to the command buffer
device->use_global_bo_list =
(device->instance->perftest_flags & RADV_PERFTEST_BO_LIST) ||
device->enabled_extensions.EXT_descriptor_indexing ||
- device->enabled_extensions.EXT_buffer_device_address;
+ device->enabled_extensions.EXT_buffer_device_address ||
+ device->enabled_extensions.KHR_buffer_device_address;
device->robust_buffer_access = pCreateInfo->pEnabledFeatures &&
pCreateInfo->pEnabledFeatures->robustBufferAccess;
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_CS_W32_EN(device->physical_device->cs_wave_size == 32);
+ device->dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1);
if (device->physical_device->rad_info.chip_class >= GFX7) {
/* If the KMD allows it (there is a KMD hw register for it),
radv_dump_enabled_options(device, stderr);
}
+ int radv_thread_trace = radv_get_int_debug_option("RADV_THREAD_TRACE", -1);
+ if (radv_thread_trace >= 0) {
+ fprintf(stderr, "*************************************************\n");
+ fprintf(stderr, "* WARNING: Thread trace support is experimental *\n");
+ fprintf(stderr, "*************************************************\n");
+
+ if (device->physical_device->rad_info.chip_class < GFX8) {
+ fprintf(stderr, "GPU hardware not supported: refer to "
+ "the RGP documentation for the list of "
+ "supported GPUs!\n");
+ abort();
+ }
+
+ /* Default buffer size set to 1MB per SE. */
+ device->thread_trace_buffer_size =
+ radv_get_int_debug_option("RADV_THREAD_TRACE_BUFFER_SIZE", 1024 * 1024);
+ device->thread_trace_start_frame = radv_thread_trace;
+
+ if (!radv_thread_trace_init(device))
+ goto fail;
+ }
+
/* Temporarily disable secure compile while we create meta shaders, etc */
uint8_t sc_threads = device->instance->num_sc_threads;
if (sc_threads)
/* Fork device for secure compile as required */
device->instance->num_sc_threads = sc_threads;
if (radv_device_use_secure_compile(device->instance)) {
- result = fork_secure_compile_device(device);
+
+ result = fork_secure_compile_idle_device(device);
if (result != VK_SUCCESS)
goto fail_meta;
}
fail:
radv_bo_list_finish(&device->bo_list);
+ radv_thread_trace_finish(device);
+
if (device->trace_bo)
device->ws->buffer_destroy(device->trace_bo);
pthread_cond_destroy(&device->timeline_cond);
radv_bo_list_finish(&device->bo_list);
+ radv_thread_trace_finish(device);
+
if (radv_device_use_secure_compile(device->instance)) {
for (unsigned i = 0; i < device->instance->num_sc_threads; i++ ) {
destroy_secure_compile_device(device, i);
}
}
- if (device->sc_state)
+ if (device->sc_state) {
+ free(device->sc_state->uid);
vk_free(&device->alloc, device->sc_state->secure_compile_processes);
+ }
vk_free(&device->alloc, device->sc_state);
vk_free(&device->alloc, device);
}
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_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
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_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
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_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
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_OOB_SELECT(V_008F0C_OOB_SELECT_DISABLED) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
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_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[3] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
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_OOB_SELECT(V_008F0C_OOB_SELECT_RAW) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
desc[7] |= S_008F0C_NUM_FORMAT(V_008F0C_BUF_NUM_FORMAT_FLOAT) |
}
}
+static void
+radv_emit_graphics_scratch(struct radv_queue *queue, struct radeon_cmdbuf *cs,
+ uint32_t size_per_wave, uint32_t waves,
+ struct radeon_winsys_bo *scratch_bo)
+{
+ if (queue->queue_family_index != RADV_QUEUE_GENERAL)
+ return;
+
+ if (!scratch_bo)
+ return;
+
+ radv_cs_add_buffer(queue->device->ws, cs, scratch_bo);
+
+ radeon_set_context_reg(cs, R_0286E8_SPI_TMPRING_SIZE,
+ S_0286E8_WAVES(waves) |
+ S_0286E8_WAVESIZE(round_up_u32(size_per_wave, 1024)));
+}
+
static void
radv_emit_compute_scratch(struct radv_queue *queue, struct radeon_cmdbuf *cs,
- struct radeon_winsys_bo *compute_scratch_bo)
+ uint32_t size_per_wave, uint32_t waves,
+ struct radeon_winsys_bo *compute_scratch_bo)
{
uint64_t scratch_va;
radeon_emit(cs, scratch_va);
radeon_emit(cs, S_008F04_BASE_ADDRESS_HI(scratch_va >> 32) |
S_008F04_SWIZZLE_ENABLE(1));
+
+ radeon_set_sh_reg(cs, R_00B860_COMPUTE_TMPRING_SIZE,
+ S_00B860_WAVES(waves) |
+ S_00B860_WAVESIZE(round_up_u32(size_per_wave, 1024)));
}
static void
static VkResult
radv_get_preamble_cs(struct radv_queue *queue,
- uint32_t scratch_size,
- uint32_t compute_scratch_size,
+ uint32_t scratch_size_per_wave,
+ uint32_t scratch_waves,
+ uint32_t compute_scratch_size_per_wave,
+ uint32_t compute_scratch_waves,
uint32_t esgs_ring_size,
uint32_t gsvs_ring_size,
bool needs_tess_rings,
bool needs_gds,
+ bool needs_gds_oa,
bool needs_sample_positions,
struct radeon_cmdbuf **initial_full_flush_preamble_cs,
struct radeon_cmdbuf **initial_preamble_cs,
struct radeon_winsys_bo *gds_bo = NULL;
struct radeon_winsys_bo *gds_oa_bo = NULL;
struct radeon_cmdbuf *dest_cs[3] = {0};
- bool add_tess_rings = false, add_gds = false, add_sample_positions = false;
+ bool add_tess_rings = false, add_gds = false, add_gds_oa = false, add_sample_positions = false;
unsigned tess_factor_ring_size = 0, tess_offchip_ring_size = 0;
unsigned max_offchip_buffers;
unsigned hs_offchip_param = 0;
if (needs_gds)
add_gds = true;
}
+ if (!queue->has_gds_oa) {
+ if (needs_gds_oa)
+ add_gds_oa = true;
+ }
if (!queue->has_sample_positions) {
if (needs_sample_positions)
add_sample_positions = true;
tess_offchip_ring_size = max_offchip_buffers *
queue->device->tess_offchip_block_dw_size * 4;
- if (scratch_size <= queue->scratch_size &&
- compute_scratch_size <= queue->compute_scratch_size &&
+ scratch_size_per_wave = MAX2(scratch_size_per_wave, queue->scratch_size_per_wave);
+ if (scratch_size_per_wave)
+ scratch_waves = MIN2(scratch_waves, UINT32_MAX / scratch_size_per_wave);
+ else
+ scratch_waves = 0;
+
+ compute_scratch_size_per_wave = MAX2(compute_scratch_size_per_wave, queue->compute_scratch_size_per_wave);
+ if (compute_scratch_size_per_wave)
+ compute_scratch_waves = MIN2(compute_scratch_waves, UINT32_MAX / compute_scratch_size_per_wave);
+ else
+ compute_scratch_waves = 0;
+
+ if (scratch_size_per_wave <= queue->scratch_size_per_wave &&
+ scratch_waves <= queue->scratch_waves &&
+ compute_scratch_size_per_wave <= queue->compute_scratch_size_per_wave &&
+ compute_scratch_waves <= queue->compute_scratch_waves &&
esgs_ring_size <= queue->esgs_ring_size &&
gsvs_ring_size <= queue->gsvs_ring_size &&
- !add_tess_rings && !add_gds && !add_sample_positions &&
+ !add_tess_rings && !add_gds && !add_gds_oa && !add_sample_positions &&
queue->initial_preamble_cs) {
*initial_full_flush_preamble_cs = queue->initial_full_flush_preamble_cs;
*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 &&
- !needs_tess_rings && !needs_gds && !needs_sample_positions)
+ if (!scratch_size_per_wave && !compute_scratch_size_per_wave &&
+ !esgs_ring_size && !gsvs_ring_size && !needs_tess_rings &&
+ !needs_gds && !needs_gds_oa && !needs_sample_positions)
*continue_preamble_cs = NULL;
return VK_SUCCESS;
}
- if (scratch_size > queue->scratch_size) {
+ uint32_t scratch_size = scratch_size_per_wave * scratch_waves;
+ uint32_t queue_scratch_size = queue->scratch_size_per_wave * queue->scratch_waves;
+ if (scratch_size > queue_scratch_size) {
scratch_bo = queue->device->ws->buffer_create(queue->device->ws,
scratch_size,
4096,
} else
scratch_bo = queue->scratch_bo;
- if (compute_scratch_size > queue->compute_scratch_size) {
+ uint32_t compute_scratch_size = compute_scratch_size_per_wave * compute_scratch_waves;
+ uint32_t compute_queue_scratch_size = queue->compute_scratch_size_per_wave * queue->compute_scratch_waves;
+ if (compute_scratch_size > compute_queue_scratch_size) {
compute_scratch_bo = queue->device->ws->buffer_create(queue->device->ws,
compute_scratch_size,
4096,
RADV_BO_PRIORITY_SCRATCH);
if (!gds_bo)
goto fail;
+ } else {
+ gds_bo = queue->gds_bo;
+ }
+
+ if (add_gds_oa) {
+ assert(queue->device->physical_device->rad_info.chip_class >= GFX10);
gds_oa_bo = queue->device->ws->buffer_create(queue->device->ws,
4, 1,
if (!gds_oa_bo)
goto fail;
} else {
- gds_bo = queue->gds_bo;
gds_oa_bo = queue->gds_oa_bo;
}
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);
+ radv_emit_compute_scratch(queue, cs, compute_scratch_size_per_wave,
+ compute_scratch_waves, compute_scratch_bo);
+ radv_emit_graphics_scratch(queue, cs, scratch_size_per_wave,
+ scratch_waves, scratch_bo);
if (gds_bo)
radv_cs_add_buffer(queue->device->ws, cs, gds_bo);
if (gds_oa_bo)
radv_cs_add_buffer(queue->device->ws, cs, gds_oa_bo);
+ if (queue->device->trace_bo)
+ radv_cs_add_buffer(queue->device->ws, cs, queue->device->trace_bo);
+
if (i == 0) {
si_cs_emit_cache_flush(cs,
queue->device->physical_device->rad_info.chip_class,
if (queue->scratch_bo)
queue->device->ws->buffer_destroy(queue->scratch_bo);
queue->scratch_bo = scratch_bo;
- queue->scratch_size = scratch_size;
}
+ queue->scratch_size_per_wave = scratch_size_per_wave;
+ queue->scratch_waves = scratch_waves;
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;
}
+ queue->compute_scratch_size_per_wave = compute_scratch_size_per_wave;
+ queue->compute_scratch_waves = compute_scratch_waves;
if (esgs_ring_bo != queue->esgs_ring_bo) {
if (queue->esgs_ring_bo)
queue->has_gds = true;
}
- if (gds_oa_bo != queue->gds_oa_bo)
+ if (gds_oa_bo != queue->gds_oa_bo) {
queue->gds_oa_bo = gds_oa_bo;
+ queue->has_gds_oa = true;
+ }
if (descriptor_bo != queue->descriptor_bo) {
if (queue->descriptor_bo)
pthread_mutex_lock(&wait_sems[i]->timeline.mutex);
struct radv_timeline_point *point =
radv_timeline_find_point_at_least_locked(device, &wait_sems[i]->timeline, wait_values[i]);
- if (point)
- --point->wait_count;
+ point->wait_count -= 2;
pthread_mutex_unlock(&wait_sems[i]->timeline.mutex);
}
}
pthread_mutex_lock(&signal_sems[i]->timeline.mutex);
struct radv_timeline_point *point =
radv_timeline_find_point_at_least_locked(device, &signal_sems[i]->timeline, signal_values[i]);
- if (point) {
- signal_sems[i]->timeline.highest_submitted =
- MAX2(signal_sems[i]->timeline.highest_submitted, point->value);
- point->wait_count--;
- }
+ signal_sems[i]->timeline.highest_submitted =
+ MAX2(signal_sems[i]->timeline.highest_submitted, point->value);
+ point->wait_count -= 2;
radv_timeline_trigger_waiters_locked(&signal_sems[i]->timeline, processing_list);
pthread_mutex_unlock(&signal_sems[i]->timeline.mutex);
}
struct radeon_cmdbuf **initial_preamble_cs,
struct radeon_cmdbuf **continue_preamble_cs)
{
- uint32_t scratch_size = 0;
- uint32_t compute_scratch_size = 0;
+ uint32_t scratch_size_per_wave = 0, waves_wanted = 0;
+ uint32_t compute_scratch_size_per_wave = 0, compute_waves_wanted = 0;
uint32_t esgs_ring_size = 0, gsvs_ring_size = 0;
bool tess_rings_needed = false;
bool gds_needed = false;
+ bool gds_oa_needed = false;
bool sample_positions_needed = false;
for (uint32_t j = 0; j < cmd_buffer_count; j++) {
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer,
cmd_buffers[j]);
- scratch_size = MAX2(scratch_size, cmd_buffer->scratch_size_needed);
- compute_scratch_size = MAX2(compute_scratch_size,
- cmd_buffer->compute_scratch_size_needed);
+ scratch_size_per_wave = MAX2(scratch_size_per_wave, cmd_buffer->scratch_size_per_wave_needed);
+ waves_wanted = MAX2(waves_wanted, cmd_buffer->scratch_waves_wanted);
+ compute_scratch_size_per_wave = MAX2(compute_scratch_size_per_wave,
+ cmd_buffer->compute_scratch_size_per_wave_needed);
+ compute_waves_wanted = MAX2(compute_waves_wanted,
+ cmd_buffer->compute_scratch_waves_wanted);
esgs_ring_size = MAX2(esgs_ring_size, cmd_buffer->esgs_ring_size_needed);
gsvs_ring_size = MAX2(gsvs_ring_size, cmd_buffer->gsvs_ring_size_needed);
tess_rings_needed |= cmd_buffer->tess_rings_needed;
gds_needed |= cmd_buffer->gds_needed;
+ gds_oa_needed |= cmd_buffer->gds_oa_needed;
sample_positions_needed |= cmd_buffer->sample_positions_needed;
}
- return radv_get_preamble_cs(queue, scratch_size, compute_scratch_size,
- esgs_ring_size, gsvs_ring_size, tess_rings_needed,
- gds_needed, sample_positions_needed,
- initial_full_flush_preamble_cs,
- initial_preamble_cs, continue_preamble_cs);
+ return radv_get_preamble_cs(queue, scratch_size_per_wave, waves_wanted,
+ compute_scratch_size_per_wave, compute_waves_wanted,
+ esgs_ring_size, gsvs_ring_size, tess_rings_needed,
+ gds_needed, gds_oa_needed, sample_positions_needed,
+ initial_full_flush_preamble_cs,
+ initial_preamble_cs, continue_preamble_cs);
}
struct radv_deferred_queue_submission {
return radv_process_submissions(&processing_list);
}
+bool
+radv_queue_internal_submit(struct radv_queue *queue, struct radeon_cmdbuf *cs)
+{
+ struct radeon_winsys_ctx *ctx = queue->hw_ctx;
+ struct radv_winsys_sem_info sem_info;
+ VkResult result;
+ int ret;
+
+ result = radv_alloc_sem_info(queue->device, &sem_info, 0, NULL, 0, 0,
+ 0, NULL, VK_NULL_HANDLE);
+ if (result != VK_SUCCESS)
+ return false;
+
+ ret = queue->device->ws->cs_submit(ctx, queue->queue_idx, &cs, 1, NULL,
+ NULL, &sem_info, NULL, false, NULL);
+ radv_free_sem_info(&sem_info);
+ return !ret;
+}
+
/* Signals fence as soon as all the work currently put on queue is done. */
static VkResult radv_signal_fence(struct radv_queue *queue,
VkFence fence)
wait_dst_stage_mask |= pSubmits[i].pWaitDstStageMask[j];
}
- const VkTimelineSemaphoreSubmitInfoKHR *timeline_info =
- vk_find_struct_const(pSubmits[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR);
+ const VkTimelineSemaphoreSubmitInfo *timeline_info =
+ vk_find_struct_const(pSubmits[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
result = radv_queue_submit(queue, &(struct radv_queue_submission) {
.cmd_buffers = pSubmits[i].pCommandBuffers,
const char* pName)
{
RADV_FROM_HANDLE(radv_instance, instance, _instance);
- bool unchecked = instance ? instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS : false;
- if (unchecked) {
- return radv_lookup_entrypoint_unchecked(pName);
- } else {
- return radv_lookup_entrypoint_checked(pName,
- instance ? instance->apiVersion : 0,
- instance ? &instance->enabled_extensions : NULL,
- NULL);
- }
+ /* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
+ * when we have to return valid function pointers, NULL, or it's left
+ * undefined. See the table for exact details.
+ */
+ if (pName == NULL)
+ return NULL;
+
+#define LOOKUP_RADV_ENTRYPOINT(entrypoint) \
+ if (strcmp(pName, "vk" #entrypoint) == 0) \
+ return (PFN_vkVoidFunction)radv_##entrypoint
+
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceExtensionProperties);
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceLayerProperties);
+ LOOKUP_RADV_ENTRYPOINT(EnumerateInstanceVersion);
+ LOOKUP_RADV_ENTRYPOINT(CreateInstance);
+
+#undef LOOKUP_RADV_ENTRYPOINT
+
+ if (instance == NULL)
+ return NULL;
+
+ int idx = radv_get_instance_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->dispatch.entrypoints[idx];
+
+ idx = radv_get_physical_device_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->physical_device_dispatch.entrypoints[idx];
+
+ idx = radv_get_device_entrypoint_index(pName);
+ if (idx >= 0)
+ return instance->device_dispatch.entrypoints[idx];
+
+ return NULL;
}
/* The loader wants us to expose a second GetInstanceProcAddr function
{
RADV_FROM_HANDLE(radv_instance, instance, _instance);
- return radv_lookup_physical_device_entrypoint_checked(pName,
- instance ? instance->apiVersion : 0,
- instance ? &instance->enabled_extensions : NULL);
+ if (!pName || !instance)
+ return NULL;
+
+ int idx = radv_get_physical_device_entrypoint_index(pName);
+ if (idx < 0)
+ return NULL;
+
+ return instance->physical_device_dispatch.entrypoints[idx];
}
PFN_vkVoidFunction radv_GetDeviceProcAddr(
const char* pName)
{
RADV_FROM_HANDLE(radv_device, device, _device);
- bool unchecked = device ? device->instance->debug_flags & RADV_DEBUG_ALL_ENTRYPOINTS : false;
- if (unchecked) {
- return radv_lookup_entrypoint_unchecked(pName);
- } else {
- return radv_lookup_entrypoint_checked(pName,
- device->instance->apiVersion,
- &device->instance->enabled_extensions,
- &device->enabled_extensions);
- }
+ if (!device || !pName)
+ return NULL;
+
+ int idx = radv_get_device_entrypoint_index(pName);
+ if (idx < 0)
+ return NULL;
+
+ return device->dispatch.entrypoints[idx];
}
bool radv_get_memory_fd(struct radv_device *device,
struct radeon_bo_metadata metadata;
if (memory->image) {
- radv_init_metadata(device, memory->image, &metadata);
+ if (memory->image->tiling != VK_IMAGE_TILING_LINEAR)
+ radv_init_metadata(device, memory->image, &metadata);
device->ws->buffer_set_metadata(memory->bo, &metadata);
}
}
} else if (host_ptr_info) {
assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
- assert(mem_type_index == RADV_MEM_TYPE_GTT_CACHED);
+ assert(radv_is_mem_type_gtt_cached(mem_type_index));
mem->bo = device->ws->buffer_from_ptr(device->ws, host_ptr_info->pHostPointer,
pAllocateInfo->allocationSize,
priority);
}
} 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)
+ if (radv_is_mem_type_gtt_wc(mem_type_index) ||
+ radv_is_mem_type_gtt_cached(mem_type_index))
domain = RADEON_DOMAIN_GTT;
else
domain = RADEON_DOMAIN_VRAM;
- if (mem_type_index == RADV_MEM_TYPE_VRAM)
+ if (radv_is_mem_type_vram(mem_type_index))
flags |= RADEON_FLAG_NO_CPU_ACCESS;
else
flags |= RADEON_FLAG_CPU_ACCESS;
- if (mem_type_index == RADV_MEM_TYPE_GTT_WRITE_COMBINE)
+ if (radv_is_mem_type_gtt_wc(mem_type_index))
flags |= RADEON_FLAG_GTT_WC;
if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes)) {
}
}
+ if (radv_is_mem_type_uncached(mem_type_index)) {
+ assert(device->physical_device->rad_info.has_l2_uncached);
+ flags |= RADEON_FLAG_VA_UNCACHED;
+ }
+
mem->bo = device->ws->buffer_create(device->ws, alloc_size, device->physical_device->rad_info.max_alignment,
domain, flags, priority);
fail:
radv_free_memory(device, pAllocator,mem);
- vk_free2(&device->alloc, pAllocator, mem);
return result;
}
{
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: {
VkMemoryDedicatedRequirements *req =
(VkMemoryDedicatedRequirements *) ext;
- req->requiresDedicatedAllocation = buffer->shareable;
+ req->requiresDedicatedAllocation = false;
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
break;
}
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *req =
(VkMemoryDedicatedRequirements *) ext;
- req->requiresDedicatedAllocation = image->shareable;
+ req->requiresDedicatedAllocation = image->shareable &&
+ image->tiling != VK_IMAGE_TILING_LINEAR;
req->prefersDedicatedAllocation = req->requiresDedicatedAllocation;
break;
}
if (i != fence_idx && !radv_sparse_bind_has_effects(pBindInfo + i))
continue;
- const VkTimelineSemaphoreSubmitInfoKHR *timeline_info =
- vk_find_struct_const(pBindInfo[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO_KHR);
+ const VkTimelineSemaphoreSubmitInfo *timeline_info =
+ vk_find_struct_const(pBindInfo[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
VkResult result = radv_queue_submit(queue, &(struct radv_queue_submission) {
.buffer_binds = pBindInfo[i].pBufferBinds,
if (!point)
return VK_SUCCESS;
- point->wait_count++;
-
pthread_mutex_unlock(&timeline->mutex);
bool success = device->ws->wait_syncobj(device->ws, &point->syncobj, 1, true, abs_timeout);
static VkSemaphoreTypeKHR
radv_get_semaphore_type(const void *pNext, uint64_t *initial_value)
{
- const VkSemaphoreTypeCreateInfoKHR *type_info =
- vk_find_struct_const(pNext, SEMAPHORE_TYPE_CREATE_INFO_KHR);
+ const VkSemaphoreTypeCreateInfo *type_info =
+ vk_find_struct_const(pNext, SEMAPHORE_TYPE_CREATE_INFO);
if (!type_info)
- return VK_SEMAPHORE_TYPE_BINARY_KHR;
+ return VK_SEMAPHORE_TYPE_BINARY;
if (initial_value)
*initial_value = type_info->initialValue;
sem->temporary.kind = RADV_SEMAPHORE_NONE;
sem->permanent.kind = RADV_SEMAPHORE_NONE;
- if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR) {
+ if (type == VK_SEMAPHORE_TYPE_TIMELINE) {
radv_create_timeline(&sem->permanent.timeline, initial_value);
sem->permanent.kind = RADV_SEMAPHORE_TIMELINE;
} else if (device->always_use_syncobj || handleTypes) {
}
VkResult
-radv_GetSemaphoreCounterValueKHR(VkDevice _device,
- VkSemaphore _semaphore,
- uint64_t* pValue)
+radv_GetSemaphoreCounterValue(VkDevice _device,
+ VkSemaphore _semaphore,
+ uint64_t* pValue)
{
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_semaphore, semaphore, _semaphore);
static VkResult
radv_wait_timelines(struct radv_device *device,
- const VkSemaphoreWaitInfoKHR* pWaitInfo,
+ const VkSemaphoreWaitInfo* pWaitInfo,
uint64_t abs_timeout)
{
if ((pWaitInfo->flags & VK_SEMAPHORE_WAIT_ANY_BIT_KHR) && pWaitInfo->semaphoreCount > 1) {
return VK_SUCCESS;
}
VkResult
-radv_WaitSemaphoresKHR(VkDevice _device,
- const VkSemaphoreWaitInfoKHR* pWaitInfo,
- uint64_t timeout)
+radv_WaitSemaphores(VkDevice _device,
+ const VkSemaphoreWaitInfo* pWaitInfo,
+ uint64_t timeout)
{
RADV_FROM_HANDLE(radv_device, device, _device);
uint64_t abs_timeout = radv_get_absolute_timeout(timeout);
}
VkResult
-radv_SignalSemaphoreKHR(VkDevice _device,
- const VkSemaphoreSignalInfoKHR* pSignalInfo)
+radv_SignalSemaphore(VkDevice _device,
+ const VkSemaphoreSignalInfo* pSignalInfo)
{
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_semaphore, semaphore, pSignalInfo->semaphore);
RADV_FROM_HANDLE(radv_device, device, _device);
struct radv_buffer *buffer;
+ if (pCreateInfo->size > RADV_MAX_MEMORY_ALLOCATION_SIZE)
+ return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
vk_free2(&device->alloc, pAllocator, buffer);
}
-VkDeviceAddress radv_GetBufferDeviceAddressEXT(
+VkDeviceAddress radv_GetBufferDeviceAddress(
VkDevice device,
- const VkBufferDeviceAddressInfoEXT* pInfo)
+ const VkBufferDeviceAddressInfo* pInfo)
{
RADV_FROM_HANDLE(radv_buffer, buffer, pInfo->buffer);
return radv_buffer_get_va(buffer->bo) + buffer->offset;
}
+uint64_t radv_GetBufferOpaqueCaptureAddress(VkDevice device,
+ const VkBufferDeviceAddressInfo* pInfo)
+{
+ return 0;
+}
+
+uint64_t radv_GetDeviceMemoryOpaqueCaptureAddress(VkDevice device,
+ const VkDeviceMemoryOpaqueCaptureAddressInfo* pInfo)
+{
+ return 0;
+}
+
static inline unsigned
si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
{
{
RADV_FROM_HANDLE(radv_device, device, _device);
struct radv_framebuffer *framebuffer;
- const VkFramebufferAttachmentsCreateInfoKHR *imageless_create_info =
+ const VkFramebufferAttachmentsCreateInfo *imageless_create_info =
vk_find_struct_const(pCreateInfo->pNext,
- FRAMEBUFFER_ATTACHMENTS_CREATE_INFO_KHR);
+ FRAMEBUFFER_ATTACHMENTS_CREATE_INFO);
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
framebuffer->layers = pCreateInfo->layers;
if (imageless_create_info) {
for (unsigned i = 0; i < imageless_create_info->attachmentImageInfoCount; ++i) {
- const VkFramebufferAttachmentImageInfoKHR *attachment =
+ const VkFramebufferAttachmentImageInfo *attachment =
imageless_create_info->pAttachmentImageInfos + i;
framebuffer->width = MIN2(framebuffer->width, attachment->width);
framebuffer->height = MIN2(framebuffer->height, attachment->height);
}
static unsigned
-radv_tex_filter_mode(VkSamplerReductionModeEXT mode)
+radv_tex_filter_mode(VkSamplerReductionMode mode)
{
switch (mode) {
case VK_SAMPLER_REDUCTION_MODE_WEIGHTED_AVERAGE_EXT:
return 0;
}
+static inline int S_FIXED(float value, unsigned frac_bits)
+{
+ return value * (1 << frac_bits);
+}
+
static void
radv_init_sampler(struct radv_device *device,
struct radv_sampler *sampler,
bool compat_mode = device->physical_device->rad_info.chip_class == GFX8 ||
device->physical_device->rad_info.chip_class == GFX9;
unsigned filter_mode = V_008F30_SQ_IMG_FILTER_MODE_BLEND;
+ unsigned depth_compare_func = V_008F30_SQ_TEX_DEPTH_COMPARE_NEVER;
- const struct VkSamplerReductionModeCreateInfoEXT *sampler_reduction =
+ const struct VkSamplerReductionModeCreateInfo *sampler_reduction =
vk_find_struct_const(pCreateInfo->pNext,
- SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT);
+ SAMPLER_REDUCTION_MODE_CREATE_INFO);
if (sampler_reduction)
filter_mode = radv_tex_filter_mode(sampler_reduction->reductionMode);
+ if (pCreateInfo->compareEnable)
+ depth_compare_func = radv_tex_compare(pCreateInfo->compareOp);
+
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_DEPTH_COMPARE_FUNC(depth_compare_func) |
S_008F30_FORCE_UNNORMALIZED(pCreateInfo->unnormalizedCoordinates ? 1 : 0) |
S_008F30_ANISO_THRESHOLD(max_aniso_ratio >> 1) |
S_008F30_ANISO_BIAS(max_aniso_ratio) |
RADV_FROM_HANDLE(radv_physical_device, pdevice, physicalDevice);
VkSemaphoreTypeKHR type = radv_get_semaphore_type(pExternalSemaphoreInfo->pNext, NULL);
- if (type == VK_SEMAPHORE_TYPE_TIMELINE_KHR) {
+ if (type == VK_SEMAPHORE_TYPE_TIMELINE) {
pExternalSemaphoreProperties->exportFromImportedHandleTypes = 0;
pExternalSemaphoreProperties->compatibleHandleTypes = 0;
pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;