#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
+#include <xf86drm.h>
#include "anv_private.h"
#include "util/strtod.h"
vk_free(&instance->alloc, instance);
}
+static VkResult
+anv_enumerate_devices(struct anv_instance *instance)
+{
+ /* TODO: Check for more devices ? */
+ drmDevicePtr devices[8];
+ VkResult result = VK_ERROR_INCOMPATIBLE_DRIVER;
+ int max_devices;
+
+ instance->physicalDeviceCount = 0;
+
+ max_devices = drmGetDevices2(0, devices, sizeof(devices));
+ if (max_devices < 1)
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+
+ for (unsigned i = 0; i < (unsigned)max_devices; i++) {
+ if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
+ devices[i]->bustype == DRM_BUS_PCI &&
+ devices[i]->deviceinfo.pci->vendor_id == 0x8086) {
+
+ result = anv_physical_device_init(&instance->physicalDevice,
+ instance,
+ devices[i]->nodes[DRM_NODE_RENDER]);
+ if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
+ break;
+ }
+ }
+
+ if (result == VK_SUCCESS)
+ instance->physicalDeviceCount = 1;
+
+ return result;
+}
+
+
VkResult anv_EnumeratePhysicalDevices(
VkInstance _instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices)
{
ANV_FROM_HANDLE(anv_instance, instance, _instance);
+ VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
VkResult result;
if (instance->physicalDeviceCount < 0) {
- char path[20];
- for (unsigned i = 0; i < 8; i++) {
- snprintf(path, sizeof(path), "/dev/dri/renderD%d", 128 + i);
- result = anv_physical_device_init(&instance->physicalDevice,
- instance, path);
- if (result != VK_ERROR_INCOMPATIBLE_DRIVER)
- break;
- }
-
- if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
- instance->physicalDeviceCount = 0;
- } else if (result == VK_SUCCESS) {
- instance->physicalDeviceCount = 1;
- } else {
+ result = anv_enumerate_devices(instance);
+ if (result != VK_SUCCESS &&
+ result != VK_ERROR_INCOMPATIBLE_DRIVER)
return result;
- }
}
- /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
- * otherwise it's an inout parameter.
- *
- * The Vulkan spec (git aaed022) says:
- *
- * pPhysicalDeviceCount is a pointer to an unsigned integer variable
- * that is initialized with the number of devices the application is
- * prepared to receive handles to. pname:pPhysicalDevices is pointer to
- * an array of at least this many VkPhysicalDevice handles [...].
- *
- * Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
- * overwrites the contents of the variable pointed to by
- * pPhysicalDeviceCount with the number of physical devices in in the
- * instance; otherwise, vkEnumeratePhysicalDevices overwrites
- * pPhysicalDeviceCount with the number of physical handles written to
- * pPhysicalDevices.
- */
- if (!pPhysicalDevices) {
- *pPhysicalDeviceCount = instance->physicalDeviceCount;
- } else if (*pPhysicalDeviceCount >= 1) {
- pPhysicalDevices[0] = anv_physical_device_to_handle(&instance->physicalDevice);
- *pPhysicalDeviceCount = 1;
- } else if (*pPhysicalDeviceCount < instance->physicalDeviceCount) {
- return VK_INCOMPLETE;
- } else {
- *pPhysicalDeviceCount = 0;
+ if (instance->physicalDeviceCount > 0) {
+ assert(instance->physicalDeviceCount == 1);
+ vk_outarray_append(&out, i) {
+ *i = anv_physical_device_to_handle(&instance->physicalDevice);
+ }
}
- return VK_SUCCESS;
+ return vk_outarray_status(&out);
}
void anv_GetPhysicalDeviceFeatures(
.maxPerStageResources = 128,
.maxDescriptorSetSamplers = 256,
.maxDescriptorSetUniformBuffers = 256,
- .maxDescriptorSetUniformBuffersDynamic = 256,
+ .maxDescriptorSetUniformBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
.maxDescriptorSetStorageBuffers = 256,
- .maxDescriptorSetStorageBuffersDynamic = 256,
+ .maxDescriptorSetStorageBuffersDynamic = MAX_DYNAMIC_BUFFERS / 2,
.maxDescriptorSetSampledImages = 256,
.maxDescriptorSetStorageImages = 256,
.maxDescriptorSetInputAttachments = 256,
}
}
-static void
-anv_get_queue_family_properties(struct anv_physical_device *phys_dev,
- VkQueueFamilyProperties *props)
-{
- *props = (VkQueueFamilyProperties) {
- .queueFlags = VK_QUEUE_GRAPHICS_BIT |
- VK_QUEUE_COMPUTE_BIT |
- VK_QUEUE_TRANSFER_BIT,
- .queueCount = 1,
- .timestampValidBits = 36, /* XXX: Real value here */
- .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
- };
-}
+/* We support exactly one queue family. */
+static const VkQueueFamilyProperties
+anv_queue_family_properties = {
+ .queueFlags = VK_QUEUE_GRAPHICS_BIT |
+ VK_QUEUE_COMPUTE_BIT |
+ VK_QUEUE_TRANSFER_BIT,
+ .queueCount = 1,
+ .timestampValidBits = 36, /* XXX: Real value here */
+ .minImageTransferGranularity = { 1, 1, 1 },
+};
void anv_GetPhysicalDeviceQueueFamilyProperties(
VkPhysicalDevice physicalDevice,
uint32_t* pCount,
VkQueueFamilyProperties* pQueueFamilyProperties)
{
- ANV_FROM_HANDLE(anv_physical_device, phys_dev, physicalDevice);
+ VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pCount);
- if (pQueueFamilyProperties == NULL) {
- *pCount = 1;
- return;
+ vk_outarray_append(&out, p) {
+ *p = anv_queue_family_properties;
}
-
- /* The spec implicitly allows the incoming count to be 0. From the Vulkan
- * 1.0.38 spec, Section 4.1 Physical Devices:
- *
- * If the value referenced by pQueueFamilyPropertyCount is not 0 [then
- * do stuff].
- */
- if (*pCount == 0)
- return;
-
- *pCount = 1;
- anv_get_queue_family_properties(phys_dev, pQueueFamilyProperties);
}
void anv_GetPhysicalDeviceQueueFamilyProperties2KHR(
VkQueueFamilyProperties2KHR* pQueueFamilyProperties)
{
- ANV_FROM_HANDLE(anv_physical_device, phys_dev, physicalDevice);
+ VK_OUTARRAY_MAKE(out, pQueueFamilyProperties, pQueueFamilyPropertyCount);
- if (pQueueFamilyProperties == NULL) {
- *pQueueFamilyPropertyCount = 1;
- return;
- }
+ vk_outarray_append(&out, p) {
+ p->queueFamilyProperties = anv_queue_family_properties;
- /* The spec implicitly allows the incoming count to be 0. From the Vulkan
- * 1.0.38 spec, Section 4.1 Physical Devices:
- *
- * If the value referenced by pQueueFamilyPropertyCount is not 0 [then
- * do stuff].
- */
- if (*pQueueFamilyPropertyCount == 0)
- return;
-
- /* We support exactly one queue family. So need to traverse only the first
- * array element's pNext chain.
- */
- *pQueueFamilyPropertyCount = 1;
- anv_get_queue_family_properties(phys_dev,
- &pQueueFamilyProperties->queueFamilyProperties);
-
- vk_foreach_struct(ext, pQueueFamilyProperties->pNext) {
- switch (ext->sType) {
- default:
- anv_debug_ignored_stype(ext->sType);
- break;
+ vk_foreach_struct(s, p->pNext) {
+ anv_debug_ignored_stype(s->sType);
}
}
}
device->robust_buffer_access = pCreateInfo->pEnabledFeatures &&
pCreateInfo->pEnabledFeatures->robustBufferAccess;
- pthread_mutex_init(&device->mutex, NULL);
+ if (pthread_mutex_init(&device->mutex, NULL) != 0) {
+ result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
+ goto fail_context_id;
+ }
pthread_condattr_t condattr;
- pthread_condattr_init(&condattr);
- pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
- pthread_cond_init(&device->queue_submit, NULL);
+ if (pthread_condattr_init(&condattr) != 0) {
+ result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
+ goto fail_mutex;
+ }
+ if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC) != 0) {
+ pthread_condattr_destroy(&condattr);
+ result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
+ goto fail_mutex;
+ }
+ if (pthread_cond_init(&device->queue_submit, NULL) != 0) {
+ pthread_condattr_destroy(&condattr);
+ result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
+ goto fail_mutex;
+ }
pthread_condattr_destroy(&condattr);
anv_bo_pool_init(&device->batch_bo_pool, device);
- anv_block_pool_init(&device->dynamic_state_block_pool, device, 16384);
+ result = anv_block_pool_init(&device->dynamic_state_block_pool, device,
+ 16384);
+ if (result != VK_SUCCESS)
+ goto fail_batch_bo_pool;
anv_state_pool_init(&device->dynamic_state_pool,
&device->dynamic_state_block_pool);
- anv_block_pool_init(&device->instruction_block_pool, device, 1024 * 1024);
+ result = anv_block_pool_init(&device->instruction_block_pool, device,
+ 1024 * 1024);
+ if (result != VK_SUCCESS)
+ goto fail_dynamic_state_pool;
+
anv_state_pool_init(&device->instruction_state_pool,
&device->instruction_block_pool);
- anv_block_pool_init(&device->surface_state_block_pool, device, 4096);
+ result = anv_block_pool_init(&device->surface_state_block_pool, device,
+ 4096);
+ if (result != VK_SUCCESS)
+ goto fail_instruction_state_pool;
anv_state_pool_init(&device->surface_state_pool,
&device->surface_state_block_pool);
- anv_bo_init_new(&device->workaround_bo, device, 1024);
+ result = anv_bo_init_new(&device->workaround_bo, device, 1024);
+ if (result != VK_SUCCESS)
+ goto fail_surface_state_pool;
anv_scratch_pool_init(device, &device->scratch_pool);
unreachable("unhandled gen");
}
if (result != VK_SUCCESS)
- goto fail_fd;
+ goto fail_workaround_bo;
anv_device_init_blorp(device);
return VK_SUCCESS;
+ fail_workaround_bo:
+ anv_queue_finish(&device->queue);
+ anv_scratch_pool_finish(device, &device->scratch_pool);
+ anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
+ anv_gem_close(device, device->workaround_bo.gem_handle);
+ fail_surface_state_pool:
+ anv_state_pool_finish(&device->surface_state_pool);
+ anv_block_pool_finish(&device->surface_state_block_pool);
+ fail_instruction_state_pool:
+ anv_state_pool_finish(&device->instruction_state_pool);
+ anv_block_pool_finish(&device->instruction_block_pool);
+ fail_dynamic_state_pool:
+ anv_state_pool_finish(&device->dynamic_state_pool);
+ anv_block_pool_finish(&device->dynamic_state_block_pool);
+ fail_batch_bo_pool:
+ anv_bo_pool_finish(&device->batch_bo_pool);
+ pthread_cond_destroy(&device->queue_submit);
+ fail_mutex:
+ pthread_mutex_destroy(&device->mutex);
+ fail_context_id:
+ anv_gem_destroy_context(device, device->context_id);
fail_fd:
close(device->fd);
fail_device:
ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer,
pSubmits[i].pCommandBuffers[j]);
assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
+ assert(!anv_batch_has_error(&cmd_buffer->batch));
result = anv_cmd_buffer_execbuf(device, cmd_buffer);
if (result != VK_SUCCESS)
uint32_t* pSparseMemoryRequirementCount,
VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
{
- stub();
+ *pSparseMemoryRequirementCount = 0;
}
void anv_GetDeviceMemoryCommitment(
const VkBindSparseInfo* pBindInfo,
VkFence fence)
{
- stub_return(VK_ERROR_INCOMPATIBLE_DRIVER);
+ return vk_error(VK_ERROR_FEATURE_NOT_PRESENT);
}
VkResult anv_CreateFence(