#include <unistd.h>
#include <fcntl.h>
#include <xf86drm.h>
-#include <drm_fourcc.h>
+#include "drm-uapi/drm_fourcc.h"
#include "anv_private.h"
#include "util/strtod.h"
va_end(args);
}
-static VkResult
-anv_compute_heap_size(int fd, uint64_t gtt_size, uint64_t *heap_size)
+static uint64_t
+anv_compute_heap_size(int fd, uint64_t gtt_size)
{
/* Query the total ram from the system */
struct sysinfo info;
*/
uint64_t available_gtt = gtt_size * 3 / 4;
- *heap_size = MIN2(available_ram, available_gtt);
-
- return VK_SUCCESS;
+ return MIN2(available_ram, available_gtt);
}
static VkResult
device->supports_48bit_addresses = (device->info.gen >= 8) &&
gtt_size > (4ULL << 30 /* GiB */);
- uint64_t heap_size = 0;
- VkResult result = anv_compute_heap_size(fd, gtt_size, &heap_size);
- if (result != VK_SUCCESS)
- return result;
+ uint64_t heap_size = anv_compute_heap_size(fd, gtt_size);
if (heap_size > (2ull << 30) && !device->supports_48bit_addresses) {
/* When running with an overridden PCI ID, we may get a GTT size from
device->has_context_isolation =
anv_gem_get_param(fd, I915_PARAM_HAS_CONTEXT_ISOLATION);
- bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
-
/* Starting with Gen10, the timestamp frequency of the command streamer may
* vary from one part to another. We can query the value from the kernel.
*/
device->info.gen < 8 || !device->has_context_isolation;
device->compiler->supports_shader_constants = true;
+ /* Broadwell PRM says:
+ *
+ * "Before Gen8, there was a historical configuration control field to
+ * swizzle address bit[6] for in X/Y tiling modes. This was set in three
+ * different places: TILECTL[1:0], ARB_MODE[5:4], and
+ * DISP_ARB_CTL[14:13].
+ *
+ * For Gen8 and subsequent generations, the swizzle fields are all
+ * reserved, and the CPU's memory controller performs all address
+ * swizzling modifications."
+ */
+ bool swizzled =
+ device->info.gen < 8 && anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
+
isl_device_init(&device->isl_dev, &device->info, swizzled);
result = anv_physical_device_init_uuids(device);
.shaderInt64 = pdevice->info.gen >= 8 &&
pdevice->info.has_64bit_types,
.shaderInt16 = pdevice->info.gen >= 8,
- .shaderResourceMinLod = false,
+ .shaderResourceMinLod = pdevice->info.gen >= 9,
.variableMultisampleRate = true,
.inheritedQueries = true,
};
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2* pFeatures)
{
+ ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
anv_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
vk_foreach_struct(ext, pFeatures->pNext) {
switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
- VkPhysicalDeviceProtectedMemoryFeatures *features = (void *)ext;
- features->protectedMemory = VK_FALSE;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
+ VkPhysicalDevice8BitStorageFeaturesKHR *features =
+ (VkPhysicalDevice8BitStorageFeaturesKHR *)ext;
+ ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
+
+ features->storageBuffer8BitAccess = pdevice->info.gen >= 8;
+ features->uniformAndStorageBuffer8BitAccess = pdevice->info.gen >= 8;
+ features->storagePushConstant8 = pdevice->info.gen >= 8;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES: {
+ VkPhysicalDevice16BitStorageFeatures *features =
+ (VkPhysicalDevice16BitStorageFeatures *)ext;
+ features->storageBuffer16BitAccess = pdevice->info.gen >= 8;
+ features->uniformAndStorageBuffer16BitAccess = pdevice->info.gen >= 8;
+ features->storagePushConstant16 = pdevice->info.gen >= 8;
+ features->storageInputOutput16 = false;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT: {
+ VkPhysicalDeviceBufferAddressFeaturesEXT *features = (void *)ext;
+ features->bufferDeviceAddress = pdevice->use_softpin &&
+ pdevice->info.gen >= 8;
+ features->bufferDeviceAddressCaptureReplay = false;
+ features->bufferDeviceAddressMultiDevice = false;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT: {
+ VkPhysicalDeviceConditionalRenderingFeaturesEXT *features =
+ (VkPhysicalDeviceConditionalRenderingFeaturesEXT*)ext;
+ ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
+
+ features->conditionalRendering = pdevice->info.gen >= 8 ||
+ pdevice->info.is_haswell;
+ features->inheritedConditionalRendering = pdevice->info.gen >= 8 ||
+ pdevice->info.is_haswell;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_CLIP_ENABLE_FEATURES_EXT: {
+ VkPhysicalDeviceDepthClipEnableFeaturesEXT *features =
+ (VkPhysicalDeviceDepthClipEnableFeaturesEXT *)ext;
+ features->depthClipEnable = VK_TRUE;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT: {
+ VkPhysicalDeviceInlineUniformBlockFeaturesEXT *features =
+ (VkPhysicalDeviceInlineUniformBlockFeaturesEXT *)ext;
+ features->inlineUniformBlock = true;
+ features->descriptorBindingInlineUniformBlockUpdateAfterBind = false;
break;
}
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
- VkPhysicalDeviceVariablePointerFeatures *features = (void *)ext;
- features->variablePointersStorageBuffer = true;
- features->variablePointers = true;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES: {
+ VkPhysicalDeviceProtectedMemoryFeatures *features = (void *)ext;
+ features->protectedMemory = VK_FALSE;
break;
}
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR: {
- VkPhysicalDevice16BitStorageFeaturesKHR *features =
- (VkPhysicalDevice16BitStorageFeaturesKHR *)ext;
- ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
-
- features->storageBuffer16BitAccess = pdevice->info.gen >= 8;
- features->uniformAndStorageBuffer16BitAccess = pdevice->info.gen >= 8;
- features->storagePushConstant16 = pdevice->info.gen >= 8;
- features->storageInputOutput16 = false;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES: {
+ VkPhysicalDeviceVariablePointerFeatures *features = (void *)ext;
+ features->variablePointersStorageBuffer = true;
+ features->variablePointers = true;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR: {
- VkPhysicalDevice8BitStorageFeaturesKHR *features =
- (VkPhysicalDevice8BitStorageFeaturesKHR *)ext;
- ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
-
- features->storageBuffer8BitAccess = pdevice->info.gen >= 8;
- features->uniformAndStorageBuffer8BitAccess = pdevice->info.gen >= 8;
- features->storagePushConstant8 = pdevice->info.gen >= 8;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: {
+ VkPhysicalDeviceTransformFeedbackFeaturesEXT *features =
+ (VkPhysicalDeviceTransformFeedbackFeaturesEXT *)ext;
+ features->transformFeedback = VK_TRUE;
+ features->geometryStreams = VK_TRUE;
break;
}
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_YCBCR_IMAGE_ARRAYS_FEATURES_EXT: {
+ VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *features =
+ (VkPhysicalDeviceYcbcrImageArraysFeaturesEXT *)ext;
+ features->ycbcrImageArrays = VK_TRUE;
+ break;
+ }
+
default:
anv_debug_ignored_stype(ext->sType);
break;
const uint32_t max_samplers = (devinfo->gen >= 8 || devinfo->is_haswell) ?
128 : 16;
+ const uint32_t max_images = devinfo->gen < 9 ? MAX_GEN8_IMAGES : MAX_IMAGES;
+
VkSampleCountFlags sample_counts =
isl_device_get_sample_counts(&pdevice->isl_dev);
+
VkPhysicalDeviceLimits limits = {
.maxImageDimension1D = (1 << 14),
.maxImageDimension2D = (1 << 14),
.maxPerStageDescriptorUniformBuffers = 64,
.maxPerStageDescriptorStorageBuffers = 64,
.maxPerStageDescriptorSampledImages = max_samplers,
- .maxPerStageDescriptorStorageImages = 64,
+ .maxPerStageDescriptorStorageImages = max_images,
.maxPerStageDescriptorInputAttachments = 64,
.maxPerStageResources = 250,
.maxDescriptorSetSamplers = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSamplers */
.maxDescriptorSetStorageBuffers = 6 * 64, /* number of stages * maxPerStageDescriptorStorageBuffers */
.maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
.maxDescriptorSetSampledImages = 6 * max_samplers, /* number of stages * maxPerStageDescriptorSampledImages */
- .maxDescriptorSetStorageImages = 6 * 64, /* number of stages * maxPerStageDescriptorStorageImages */
+ .maxDescriptorSetStorageImages = 6 * max_images, /* number of stages * maxPerStageDescriptorStorageImages */
.maxDescriptorSetInputAttachments = 256,
.maxVertexInputAttributes = MAX_VBS,
.maxVertexInputBindings = MAX_VBS,
16 * devinfo->max_cs_threads,
16 * devinfo->max_cs_threads,
},
- .subPixelPrecisionBits = 4 /* FIXME */,
+ .subPixelPrecisionBits = 8,
.subTexelPrecisionBits = 4 /* FIXME */,
.mipmapPrecisionBits = 4 /* FIXME */,
.maxDrawIndexedIndexValue = UINT32_MAX,
vk_foreach_struct(ext, pProperties->pNext) {
switch (ext->sType) {
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
- VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
- (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR: {
+ VkPhysicalDeviceDepthStencilResolvePropertiesKHR *props =
+ (VkPhysicalDeviceDepthStencilResolvePropertiesKHR *)ext;
+
+ /* We support all of the depth resolve modes */
+ props->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 */
+ props->supportedStencilResolveModes =
+ VK_RESOLVE_MODE_SAMPLE_ZERO_BIT_KHR;
+ if (pdevice->info.gen >= 8) {
+ /* The advanced stencil resolve modes currently require stencil
+ * sampling be supported by the hardware.
+ */
+ props->supportedStencilResolveModes |=
+ VK_RESOLVE_MODE_MIN_BIT_KHR |
+ VK_RESOLVE_MODE_MAX_BIT_KHR;
+ }
- properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
+ props->independentResolveNone = VK_TRUE;
+ props->independentResolve = VK_TRUE;
break;
}
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT: {
+ VkPhysicalDeviceExternalMemoryHostPropertiesEXT *props =
+ (VkPhysicalDeviceExternalMemoryHostPropertiesEXT *) ext;
+ /* Userptr needs page aligned memory. */
+ props->minImportedHostPointerAlignment = 4096;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES: {
VkPhysicalDeviceIDProperties *id_props =
(VkPhysicalDeviceIDProperties *)ext;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT: {
+ VkPhysicalDeviceInlineUniformBlockPropertiesEXT *props =
+ (VkPhysicalDeviceInlineUniformBlockPropertiesEXT *)ext;
+ props->maxInlineUniformBlockSize = MAX_INLINE_UNIFORM_BLOCK_SIZE;
+ props->maxPerStageDescriptorInlineUniformBlocks =
+ MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
+ props->maxPerStageDescriptorUpdateAfterBindInlineUniformBlocks =
+ MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
+ props->maxDescriptorSetInlineUniformBlocks =
+ MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
+ props->maxDescriptorSetUpdateAfterBindInlineUniformBlocks =
+ MAX_INLINE_UNIFORM_BLOCK_DESCRIPTORS;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES: {
VkPhysicalDeviceMaintenance3Properties *props =
(VkPhysicalDeviceMaintenance3Properties *)ext;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
+ VkPhysicalDeviceProtectedMemoryProperties *props =
+ (VkPhysicalDeviceProtectedMemoryProperties *)ext;
+ props->protectedNoFault = false;
+ break;
+ }
+
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR: {
+ VkPhysicalDevicePushDescriptorPropertiesKHR *properties =
+ (VkPhysicalDevicePushDescriptorPropertiesKHR *) ext;
+
+ properties->maxPushDescriptors = MAX_PUSH_DESCRIPTORS;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT: {
VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *properties =
(VkPhysicalDeviceSamplerFilterMinmaxPropertiesEXT *)ext;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT: {
+ VkPhysicalDeviceTransformFeedbackPropertiesEXT *props =
+ (VkPhysicalDeviceTransformFeedbackPropertiesEXT *)ext;
+
+ props->maxTransformFeedbackStreams = MAX_XFB_STREAMS;
+ props->maxTransformFeedbackBuffers = MAX_XFB_BUFFERS;
+ props->maxTransformFeedbackBufferSize = (1ull << 32);
+ props->maxTransformFeedbackStreamDataSize = 128 * 4;
+ props->maxTransformFeedbackBufferDataSize = 128 * 4;
+ props->maxTransformFeedbackBufferDataStride = 2048;
+ props->transformFeedbackQueries = VK_TRUE;
+ props->transformFeedbackStreamsLinesTriangles = VK_FALSE;
+ props->transformFeedbackRasterizationStreamSelect = VK_FALSE;
+ props->transformFeedbackDraw = VK_TRUE;
+ break;
+ }
+
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: {
VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *props =
(VkPhysicalDeviceVertexAttributeDivisorPropertiesEXT *)ext;
break;
}
- case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES: {
- VkPhysicalDeviceProtectedMemoryProperties *props =
- (VkPhysicalDeviceProtectedMemoryProperties *)ext;
- props->protectedNoFault = false;
- break;
- }
-
default:
anv_debug_ignored_stype(ext->sType);
break;
state = anv_state_pool_alloc(pool, size, align);
memcpy(state.map, p, size);
- anv_state_flush(pool->block_pool.device, state);
-
return state;
}
anv_gem_munmap(map, device->hiz_clear_bo.size);
}
+static bool
+get_bo_from_pool(struct gen_batch_decode_bo *ret,
+ struct anv_block_pool *pool,
+ uint64_t address)
+{
+ for (uint32_t i = 0; i < pool->nbos; i++) {
+ uint64_t bo_address = pool->bos[i].offset & (~0ull >> 16);
+ uint32_t bo_size = pool->bos[i].size;
+ if (address >= bo_address && address < (bo_address + bo_size)) {
+ *ret = (struct gen_batch_decode_bo) {
+ .addr = bo_address,
+ .size = bo_size,
+ .map = pool->bos[i].map,
+ };
+ return true;
+ }
+ }
+ return false;
+}
+
+/* Finding a buffer for batch decoding */
+static struct gen_batch_decode_bo
+decode_get_bo(void *v_batch, bool ppgtt, uint64_t address)
+{
+ struct anv_device *device = v_batch;
+ struct gen_batch_decode_bo ret_bo = {};
+
+ assert(ppgtt);
+
+ if (get_bo_from_pool(&ret_bo, &device->dynamic_state_pool.block_pool, address))
+ return ret_bo;
+ if (get_bo_from_pool(&ret_bo, &device->instruction_state_pool.block_pool, address))
+ return ret_bo;
+ if (get_bo_from_pool(&ret_bo, &device->binding_table_pool.block_pool, address))
+ return ret_bo;
+ if (get_bo_from_pool(&ret_bo, &device->surface_state_pool.block_pool, address))
+ return ret_bo;
+
+ if (!device->cmd_buffer_being_decoded)
+ return (struct gen_batch_decode_bo) { };
+
+ struct anv_batch_bo **bo;
+
+ u_vector_foreach(bo, &device->cmd_buffer_being_decoded->seen_bbos) {
+ /* The decoder zeroes out the top 16 bits, so we need to as well */
+ uint64_t bo_address = (*bo)->bo.offset & (~0ull >> 16);
+
+ if (address >= bo_address && address < bo_address + (*bo)->bo.size) {
+ return (struct gen_batch_decode_bo) {
+ .addr = bo_address,
+ .size = (*bo)->bo.size,
+ .map = (*bo)->bo.map,
+ };
+ }
+ }
+
+ return (struct gen_batch_decode_bo) { };
+}
+
VkResult anv_CreateDevice(
VkPhysicalDevice physicalDevice,
const VkDeviceCreateInfo* pCreateInfo,
if (!device)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ const unsigned decode_flags =
+ GEN_BATCH_DECODE_FULL |
+ ((INTEL_DEBUG & DEBUG_COLOR) ? GEN_BATCH_DECODE_IN_COLOR : 0) |
+ GEN_BATCH_DECODE_OFFSETS |
+ GEN_BATCH_DECODE_FLOATS;
+
+ gen_batch_decode_ctx_init(&device->decoder_ctx,
+ &physical_device->info,
+ stderr, decode_flags, NULL,
+ decode_get_bo, NULL, device);
+
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = physical_device->instance;
device->chipset_id = physical_device->chipset_id;
if (device->info.gen >= 10)
anv_device_init_hiz_clear_value_bo(device);
+ if (physical_device->use_softpin)
+ device->pinned_buffers = _mesa_pointer_set_create(NULL);
+
anv_scratch_pool_init(device, &device->scratch_pool);
anv_queue_init(device, &device->queue);
anv_queue_finish(&device->queue);
+ if (physical_device->use_softpin)
+ _mesa_set_destroy(device->pinned_buffers, NULL);
+
#ifdef HAVE_VALGRIND
/* We only need to free these to prevent valgrind errors. The backing
* BO will go away in a couple of lines so we don't actually leak.
anv_gem_destroy_context(device, device->context_id);
+ gen_batch_decode_ctx_finish(&device->decoder_ctx);
+
close(device->fd);
vk_free(&device->alloc, device);
mem->type = &pdevice->memory.types[pAllocateInfo->memoryTypeIndex];
mem->map = NULL;
mem->map_size = 0;
+ mem->ahw = NULL;
+ mem->host_ptr = NULL;
uint64_t bo_flags = 0;
if (pdevice->use_softpin)
bo_flags |= EXEC_OBJECT_PINNED;
+ const VkExportMemoryAllocateInfo *export_info =
+ vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO);
+
+ /* Check if we need to support Android HW buffer export. If so,
+ * create AHardwareBuffer and import memory from it.
+ */
+ bool android_export = false;
+ if (export_info && export_info->handleTypes &
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
+ android_export = true;
+
+ /* Android memory import. */
+ const struct VkImportAndroidHardwareBufferInfoANDROID *ahw_import_info =
+ vk_find_struct_const(pAllocateInfo->pNext,
+ IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID);
+
+ if (ahw_import_info) {
+ result = anv_import_ahw_memory(_device, mem, ahw_import_info);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ goto success;
+ } else if (android_export) {
+ result = anv_create_ahw_memory(_device, mem, pAllocateInfo);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ const struct VkImportAndroidHardwareBufferInfoANDROID import_info = {
+ .buffer = mem->ahw,
+ };
+ result = anv_import_ahw_memory(_device, mem, &import_info);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ goto success;
+ }
+
const VkImportMemoryFdInfoKHR *fd_info =
vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
*/
if (mem->bo->size < aligned_alloc_size) {
result = vk_errorf(device->instance, device,
- VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR,
+ VK_ERROR_INVALID_EXTERNAL_HANDLE,
"aligned allocationSize too large for "
- "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: "
+ "VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: "
"%"PRIu64"B > %"PRIu64"B",
aligned_alloc_size, mem->bo->size);
anv_bo_cache_release(device, &device->bo_cache, mem->bo);
* If the import fails, we leave the file descriptor open.
*/
close(fd_info->fd);
- } else {
- const VkExportMemoryAllocateInfoKHR *fd_info =
- vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO_KHR);
- if (fd_info && fd_info->handleTypes)
- bo_flags |= ANV_BO_EXTERNAL;
-
- result = anv_bo_cache_alloc(device, &device->bo_cache,
- pAllocateInfo->allocationSize, bo_flags,
- &mem->bo);
+ goto success;
+ }
+
+ const VkImportMemoryHostPointerInfoEXT *host_ptr_info =
+ vk_find_struct_const(pAllocateInfo->pNext,
+ IMPORT_MEMORY_HOST_POINTER_INFO_EXT);
+ if (host_ptr_info && host_ptr_info->handleType) {
+ if (host_ptr_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_MAPPED_FOREIGN_MEMORY_BIT_EXT) {
+ result = vk_error(VK_ERROR_INVALID_EXTERNAL_HANDLE);
+ goto fail;
+ }
+
+ assert(host_ptr_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
+
+ result = anv_bo_cache_import_host_ptr(
+ device, &device->bo_cache, host_ptr_info->pHostPointer,
+ pAllocateInfo->allocationSize, bo_flags, &mem->bo);
+
if (result != VK_SUCCESS)
goto fail;
- const VkMemoryDedicatedAllocateInfoKHR *dedicated_info =
- vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO_KHR);
- if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
- ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);
+ mem->host_ptr = host_ptr_info->pHostPointer;
+ goto success;
+ }
- /* Some legacy (non-modifiers) consumers need the tiling to be set on
- * the BO. In this case, we have a dedicated allocation.
- */
- if (image->needs_set_tiling) {
- const uint32_t i915_tiling =
- isl_tiling_to_i915_tiling(image->planes[0].surface.isl.tiling);
- int ret = anv_gem_set_tiling(device, mem->bo->gem_handle,
- image->planes[0].surface.isl.row_pitch_B,
- i915_tiling);
- if (ret) {
- anv_bo_cache_release(device, &device->bo_cache, mem->bo);
- return vk_errorf(device->instance, NULL,
- VK_ERROR_OUT_OF_DEVICE_MEMORY,
- "failed to set BO tiling: %m");
- }
+ /* Regular allocate (not importing memory). */
+
+ if (export_info && export_info->handleTypes)
+ bo_flags |= ANV_BO_EXTERNAL;
+
+ result = anv_bo_cache_alloc(device, &device->bo_cache,
+ pAllocateInfo->allocationSize, bo_flags,
+ &mem->bo);
+ if (result != VK_SUCCESS)
+ goto fail;
+
+ const VkMemoryDedicatedAllocateInfo *dedicated_info =
+ vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
+ if (dedicated_info && dedicated_info->image != VK_NULL_HANDLE) {
+ ANV_FROM_HANDLE(anv_image, image, dedicated_info->image);
+
+ /* Some legacy (non-modifiers) consumers need the tiling to be set on
+ * the BO. In this case, we have a dedicated allocation.
+ */
+ if (image->needs_set_tiling) {
+ const uint32_t i915_tiling =
+ isl_tiling_to_i915_tiling(image->planes[0].surface.isl.tiling);
+ int ret = anv_gem_set_tiling(device, mem->bo->gem_handle,
+ image->planes[0].surface.isl.row_pitch_B,
+ i915_tiling);
+ if (ret) {
+ anv_bo_cache_release(device, &device->bo_cache, mem->bo);
+ return vk_errorf(device->instance, NULL,
+ VK_ERROR_OUT_OF_DEVICE_MEMORY,
+ "failed to set BO tiling: %m");
}
}
}
+ success:
*pMem = anv_device_memory_to_handle(mem);
return VK_SUCCESS;
VkResult anv_GetMemoryFdPropertiesKHR(
VkDevice _device,
- VkExternalMemoryHandleTypeFlagBitsKHR handleType,
+ VkExternalMemoryHandleTypeFlagBits handleType,
int fd,
VkMemoryFdPropertiesKHR* pMemoryFdProperties)
{
}
}
+VkResult anv_GetMemoryHostPointerPropertiesEXT(
+ VkDevice _device,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ const void* pHostPointer,
+ VkMemoryHostPointerPropertiesEXT* pMemoryHostPointerProperties)
+{
+ ANV_FROM_HANDLE(anv_device, device, _device);
+
+ assert(pMemoryHostPointerProperties->sType ==
+ VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT);
+
+ switch (handleType) {
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: {
+ struct anv_physical_device *pdevice = &device->instance->physicalDevice;
+
+ /* Host memory can be imported as any memory type. */
+ pMemoryHostPointerProperties->memoryTypeBits =
+ (1ull << pdevice->memory.type_count) - 1;
+
+ return VK_SUCCESS;
+ }
+ default:
+ return VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ }
+}
+
void anv_FreeMemory(
VkDevice _device,
VkDeviceMemory _mem,
anv_bo_cache_release(device, &device->bo_cache, mem->bo);
+#ifdef ANDROID
+ if (mem->ahw)
+ AHardwareBuffer_release(mem->ahw);
+#endif
+
vk_free2(&device->alloc, pAllocator, mem);
}
return VK_SUCCESS;
}
+ if (mem->host_ptr) {
+ *ppData = mem->host_ptr + offset;
+ return VK_SUCCESS;
+ }
+
if (size == VK_WHOLE_SIZE)
size = mem->bo->size - offset;
{
ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
- if (mem == NULL)
+ if (mem == NULL || mem->host_ptr)
return;
anv_gem_munmap(mem->map, mem->map_size);
*/
uint32_t memory_types = (1ull << pdevice->memory.type_count) - 1;
+ /* We must have image allocated or imported at this point. According to the
+ * specification, external images must have been bound to memory before
+ * calling GetImageMemoryRequirements.
+ */
+ assert(image->size > 0);
+
pMemoryRequirements->size = image->size;
pMemoryRequirements->alignment = image->alignment;
pMemoryRequirements->memoryTypeBits = memory_types;
switch (ext->sType) {
case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO: {
struct anv_physical_device *pdevice = &device->instance->physicalDevice;
- const VkImagePlaneMemoryRequirementsInfoKHR *plane_reqs =
- (const VkImagePlaneMemoryRequirementsInfoKHR *) ext;
+ const VkImagePlaneMemoryRequirementsInfo *plane_reqs =
+ (const VkImagePlaneMemoryRequirementsInfo *) ext;
uint32_t plane = anv_image_aspect_to_plane(image->aspects,
plane_reqs->planeAspect);
pMemoryRequirements->memoryRequirements.memoryTypeBits =
(1ull << pdevice->memory.type_count) - 1;
+ /* We must have image allocated or imported at this point. According to the
+ * specification, external images must have been bound to memory before
+ * calling GetImageMemoryRequirements.
+ */
+ assert(image->planes[plane].size > 0);
+
pMemoryRequirements->memoryRequirements.size = image->planes[plane].size;
pMemoryRequirements->memoryRequirements.alignment =
image->planes[plane].alignment;
switch (ext->sType) {
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {
VkMemoryDedicatedRequirements *requirements = (void *)ext;
- if (image->needs_set_tiling) {
+ if (image->needs_set_tiling || image->external_format) {
/* If we need to set the tiling for external consumers, we need a
* dedicated allocation.
*
buffer->usage = pCreateInfo->usage;
buffer->address = ANV_NULL_ADDRESS;
+ if (buffer->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) {
+ pthread_mutex_lock(&device->mutex);
+ _mesa_set_add(device->pinned_buffers, buffer);
+ pthread_mutex_unlock(&device->mutex);
+ }
+
*pBuffer = anv_buffer_to_handle(buffer);
return VK_SUCCESS;
if (!buffer)
return;
+ if (buffer->usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT) {
+ pthread_mutex_lock(&device->mutex);
+ _mesa_set_remove_key(device->pinned_buffers, buffer);
+ pthread_mutex_unlock(&device->mutex);
+ }
+
vk_free2(&device->alloc, pAllocator, buffer);
}
+VkDeviceAddress anv_GetBufferDeviceAddressEXT(
+ VkDevice device,
+ const VkBufferDeviceAddressInfoEXT* pInfo)
+{
+ ANV_FROM_HANDLE(anv_buffer, buffer, pInfo->buffer);
+
+ assert(buffer->address.bo->flags & EXEC_OBJECT_PINNED);
+
+ return anv_address_physical(buffer->address);
+}
+
void
anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state,
enum isl_format format,
.size_B = range,
.format = format,
.stride_B = stride);
-
- anv_state_flush(device, state);
}
void anv_DestroySampler(