There is lots of commented code.
--- /dev/null
+
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "libresoc_private.h"
+
+void libresoc_FreeCommandBuffers(
+ VkDevice device,
+ VkCommandPool commandPool,
+ uint32_t commandBufferCount,
+ const VkCommandBuffer *pCommandBuffers)
+{
+ //TODO: stub
+}
+
+VkResult libresoc_CreateCommandPool(
+ VkDevice _device,
+ const VkCommandPoolCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkCommandPool* pCmdPool)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ struct libresoc_cmd_pool *pool;
+
+ pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (pool == NULL)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &pool->base,
+ VK_OBJECT_TYPE_COMMAND_POOL);
+
+ if (pAllocator)
+ pool->alloc = *pAllocator;
+ else
+ pool->alloc = device->vk.alloc;
+
+ list_inithead(&pool->cmd_buffers);
+ list_inithead(&pool->free_cmd_buffers);
+
+ pool->queue_family_index = pCreateInfo->queueFamilyIndex;
+
+ *pCmdPool = libresoc_cmd_pool_to_handle(pool);
+
+ return VK_SUCCESS;
+
+}
+
+void libresoc_DestroyCommandPool(
+ VkDevice _device,
+ VkCommandPool commandPool,
+ const VkAllocationCallbacks* pAllocator)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_cmd_pool, pool, commandPool);
+
+ if (!pool)
+ return;
+
+ // list_for_each_entry_safe(struct libresoc_cmd_buffer, cmd_buffer,
+ // &pool->cmd_buffers, pool_link) {
+ // libresoc_destroy_cmd_buffer(cmd_buffer);
+ // }
+
+ // list_for_each_entry_safe(struct libresoc_cmd_buffer, cmd_buffer,
+ // &pool->free_cmd_buffers, pool_link) {
+ // libresoc_destroy_cmd_buffer(cmd_buffer);
+ // }
+
+ vk_object_base_finish(&pool->base);
+ vk_free2(&device->vk.alloc, pAllocator, pool);
+}
+
+static VkResult libresoc_create_cmd_buffer(
+ struct libresoc_device * device,
+ struct libresoc_cmd_pool * pool,
+ VkCommandBufferLevel level,
+ VkCommandBuffer* pCommandBuffer)
+{
+ struct libresoc_cmd_buffer *cmd_buffer;
+ unsigned ring;
+ cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (cmd_buffer == NULL)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &cmd_buffer->base,
+ VK_OBJECT_TYPE_COMMAND_BUFFER);
+
+ cmd_buffer->device = device;
+ cmd_buffer->pool = pool;
+ cmd_buffer->level = level;
+
+ list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
+ cmd_buffer->queue_family_index = pool->queue_family_index;
+
+ // ring = libresoc_queue_family_to_ring(cmd_buffer->queue_family_index);
+
+ // cmd_buffer->cs = device->ws->cs_create(device->ws, ring);
+ // if (!cmd_buffer->cs) {
+ // libresoc_destroy_cmd_buffer(cmd_buffer);
+ // return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+ // }
+
+ *pCommandBuffer = libresoc_cmd_buffer_to_handle(cmd_buffer);
+
+ list_inithead(&cmd_buffer->upload.list);
+
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_AllocateCommandBuffers(
+ VkDevice _device,
+ const VkCommandBufferAllocateInfo *pAllocateInfo,
+ VkCommandBuffer *pCommandBuffers)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_cmd_pool, pool, pAllocateInfo->commandPool);
+
+ VkResult result = VK_SUCCESS;
+ uint32_t i;
+
+ for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
+
+ if (!list_is_empty(&pool->free_cmd_buffers)) {
+ struct libresoc_cmd_buffer *cmd_buffer = list_first_entry(&pool->free_cmd_buffers, struct libresoc_cmd_buffer, pool_link);
+
+ list_del(&cmd_buffer->pool_link);
+ list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
+
+ //result = libresoc_reset_cmd_buffer(cmd_buffer);
+ cmd_buffer->level = pAllocateInfo->level;
+
+ pCommandBuffers[i] = libresoc_cmd_buffer_to_handle(cmd_buffer);
+ } else {
+ result = libresoc_create_cmd_buffer(device, pool, pAllocateInfo->level,
+ &pCommandBuffers[i]);
+ }
+ if (result != VK_SUCCESS)
+ break;
+ }
+
+ // if (result != VK_SUCCESS) {
+ // libresoc_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
+ // i, pCommandBuffers);
+
+ // /* From the Vulkan 1.0.66 spec:
+ // *
+ // * "vkAllocateCommandBuffers can be used to create multiple
+ // * command buffers. If the creation of any of those command
+ // * buffers fails, the implementation must destroy all
+ // * successfully created command buffer objects from this
+ // * command, set all entries of the pCommandBuffers array to
+ // * NULL and return the error."
+ // */
+ // memset(pCommandBuffers, 0,
+ // sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
+ // }
+
+ return result;
+}
+
+VkResult libresoc_BeginCommandBuffer(
+ VkCommandBuffer commandBuffer,
+ const VkCommandBufferBeginInfo *pBeginInfo)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
+ VkResult result = VK_SUCCESS;
+
+
+ // memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
+ // cmd_buffer->state.last_primitive_reset_en = -1;
+ // cmd_buffer->state.last_index_type = -1;
+ // cmd_buffer->state.last_num_instances = -1;
+ // cmd_buffer->state.last_vertex_offset = -1;
+ // cmd_buffer->state.last_first_instance = -1;
+ // cmd_buffer->state.predication_type = -1;
+ // cmd_buffer->state.last_sx_ps_downconvert = -1;
+ // cmd_buffer->state.last_sx_blend_opt_epsilon = -1;
+ // cmd_buffer->state.last_sx_blend_opt_control = -1;
+ cmd_buffer->usage_flags = pBeginInfo->flags;
+
+ // if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
+ // (pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) {
+ // assert(pBeginInfo->pInheritanceInfo);
+ // cmd_buffer->state.framebuffer = libresoc_framebuffer_from_handle(pBeginInfo->pInheritanceInfo->framebuffer);
+ // cmd_buffer->state.pass = libresoc_render_pass_from_handle(pBeginInfo->pInheritanceInfo->renderPass);
+
+ // struct libresoc_subpass *subpass =
+ // &cmd_buffer->state.pass->subpasses[pBeginInfo->pInheritanceInfo->subpass];
+
+ // if (cmd_buffer->state.framebuffer) {
+ // result = libresoc_cmd_state_setup_attachments(cmd_buffer, cmd_buffer->state.pass, NULL);
+ // if (result != VK_SUCCESS)
+ // return result;
+ // }
+
+ // cmd_buffer->state.inherited_pipeline_statistics =
+ // pBeginInfo->pInheritanceInfo->pipelineStatistics;
+
+ // libresoc_cmd_buffer_set_subpass(cmd_buffer, subpass);
+ // }
+
+ // if (unlikely(cmd_buffer->device->trace_bo))
+ // libresoc_cmd_buffer_trace_emit(cmd_buffer);
+
+// libresoc_describe_begin_cmd_buffer(cmd_buffer);
+
+ //cmd_buffer->status = LIBRESOC_CMD_BUFFER_STATUS_RECORDING;
+
+ return result;
+}
+
+void libresoc_CmdPipelineBarrier(
+ VkCommandBuffer commandBuffer,
+ VkPipelineStageFlags srcStageMask,
+ VkPipelineStageFlags destStageMask,
+ VkBool32 byRegion,
+ uint32_t memoryBarrierCount,
+ const VkMemoryBarrier* pMemoryBarriers,
+ uint32_t bufferMemoryBarrierCount,
+ const VkBufferMemoryBarrier* pBufferMemoryBarriers,
+ uint32_t imageMemoryBarrierCount,
+ const VkImageMemoryBarrier* pImageMemoryBarriers)
+{
+ // LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
+ // struct libresoc_barrier_info info;
+
+ // info.reason = RGP_BARRIER_EXTERNAL_CMD_PIPELINE_BARRIER;
+ // info.eventCount = 0;
+ // info.pEvents = NULL;
+ // info.srcStageMask = srcStageMask;
+ // info.dstStageMask = destStageMask;
+
+ // libresoc_barrier(cmd_buffer, memoryBarrierCount, pMemoryBarriers,
+ // bufferMemoryBarrierCount, pBufferMemoryBarriers,
+ // imageMemoryBarrierCount, pImageMemoryBarriers, &info);
+}
+
+VkResult libresoc_EndCommandBuffer(
+ VkCommandBuffer commandBuffer)
+{
+
+ LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
+
+ // if (cmd_buffer->queue_family_index != LIBRESOC_QUEUE_TRANSFER) {
+ // if (cmd_buffer->device->physical_device->rad_info.chip_class == GFX6)
+ // cmd_buffer->state.flush_bits |= LIBRESOC_CMD_FLAG_CS_PARTIAL_FLUSH | LIBRESOC_CMD_FLAG_PS_PARTIAL_FLUSH | LIBRESOC_CMD_FLAG_WB_L2;
+
+ // /* Make sure to sync all pending active queries at the end of
+ // * command buffer.
+ // */
+ // cmd_buffer->state.flush_bits |= cmd_buffer->active_query_flush_bits;
+
+ // /* Since NGG streamout uses GDS, we need to make GDS idle when
+ // * we leave the IB, otherwise another process might overwrite
+ // * it while our shaders are busy.
+ // */
+ // if (cmd_buffer->gds_needed)
+ // cmd_buffer->state.flush_bits |= LIBRESOC_CMD_FLAG_PS_PARTIAL_FLUSH;
+
+ // si_emit_cache_flush(cmd_buffer);
+ // }
+
+ // /* Make sure CP DMA is idle at the end of IBs because the kernel
+ // * doesn't wait for it.
+ // */
+ // si_cp_dma_wait_for_idle(cmd_buffer);
+
+ // libresoc_describe_end_cmd_buffer(cmd_buffer);
+
+ // vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
+ // vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.subpass_sample_locs);
+
+ // VkResult result = cmd_buffer->device->ws->cs_finalize(cmd_buffer->cs);
+ // if (result != VK_SUCCESS)
+ // return vk_error(cmd_buffer->device->instance, result);
+
+ // cmd_buffer->status = LIBRESOC_CMD_BUFFER_STATUS_EXECUTABLE;
+
+ return cmd_buffer->record_result;
+}
#include <unistd.h>
#include "util/debug.h"
+#include "util/driconf.h"
#include "libresoc_private.h"
#include "vk_util.h"
#include "vk_alloc.h"
+struct libresoc_deferred_queue_submission {
+ struct libresoc_queue *queue;
+ VkCommandBuffer *cmd_buffers;
+ uint32_t cmd_buffer_count;
+
+ /* Sparse bindings that happen on a queue. */
+ VkSparseBufferMemoryBindInfo *buffer_binds;
+ uint32_t buffer_bind_count;
+ VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
+ uint32_t image_opaque_bind_count;
+
+ bool flush_caches;
+ VkShaderStageFlags wait_dst_stage_mask;
+ struct libresoc_semaphore_part **wait_semaphores;
+ uint32_t wait_semaphore_count;
+ struct libresoc_semaphore_part **signal_semaphores;
+ uint32_t signal_semaphore_count;
+ VkFence fence;
+
+ uint64_t *wait_values;
+ uint64_t *signal_values;
+
+ struct libresoc_semaphore_part *temporary_semaphore_parts;
+ uint32_t temporary_semaphore_part_count;
+
+ struct list_head queue_pending_list;
+ uint32_t submission_wait_count;
+ struct libresoc_timeline_waiter *wait_nodes;
+
+ struct list_head processing_list;
+};
+
+struct libresoc_queue_submission {
+ const VkCommandBuffer *cmd_buffers;
+ uint32_t cmd_buffer_count;
+
+ /* Sparse bindings that happen on a queue. */
+ const VkSparseBufferMemoryBindInfo *buffer_binds;
+ uint32_t buffer_bind_count;
+ const VkSparseImageOpaqueMemoryBindInfo *image_opaque_binds;
+ uint32_t image_opaque_bind_count;
+
+ bool flush_caches;
+ VkPipelineStageFlags wait_dst_stage_mask;
+ const VkSemaphore *wait_semaphores;
+ uint32_t wait_semaphore_count;
+ const VkSemaphore *signal_semaphores;
+ uint32_t signal_semaphore_count;
+ VkFence fence;
+
+ const uint64_t *wait_values;
+ uint32_t wait_value_count;
+ const uint64_t *signal_values;
+ uint32_t signal_value_count;
+};
+
+void
+libresoc_free_memory(struct libresoc_device *device,
+ const VkAllocationCallbacks* pAllocator,
+ struct libresoc_device_memory *mem)
+{
+ if (mem == NULL)
+ return;
+
+ vk_object_base_finish(&mem->base);
+ vk_free2(&device->vk.alloc, pAllocator, mem);
+}
+
+static VkResult libresoc_alloc_memory(struct libresoc_device *device,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeviceMemory* pMem)
+{
+ struct libresoc_device_memory *mem;
+ VkResult result;
+ uint32_t flags = 0;
+
+ assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
+
+ const VkImportMemoryFdInfoKHR *import_info =
+ vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_FD_INFO_KHR);
+ const VkMemoryDedicatedAllocateInfo *dedicate_info =
+ vk_find_struct_const(pAllocateInfo->pNext, MEMORY_DEDICATED_ALLOCATE_INFO);
+ const VkExportMemoryAllocateInfo *export_info =
+ vk_find_struct_const(pAllocateInfo->pNext, EXPORT_MEMORY_ALLOCATE_INFO);
+ const VkImportMemoryHostPointerInfoEXT *host_ptr_info =
+ vk_find_struct_const(pAllocateInfo->pNext, IMPORT_MEMORY_HOST_POINTER_INFO_EXT);
+
+ const struct wsi_memory_allocate_info *wsi_info =
+ vk_find_struct_const(pAllocateInfo->pNext, WSI_MEMORY_ALLOCATE_INFO_MESA);
+
+
+ mem = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*mem), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (mem == NULL)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &mem->base,
+ VK_OBJECT_TYPE_DEVICE_MEMORY);
+
+ if (dedicate_info) {
+ mem->image = libresoc_image_from_handle(dedicate_info->image);
+ //mem->buffer = libresoc_buffer_from_handle(dedicate_info->buffer);
+ } else {
+ mem->image = NULL;
+ //mem->buffer = NULL;
+ }
+
+ // float priority_float = 0.5;
+ // const struct VkMemoryPriorityAllocateInfoEXT *priority_ext =
+ // vk_find_struct_const(pAllocateInfo->pNext,
+ // MEMORY_PRIORITY_ALLOCATE_INFO_EXT);
+ // if (priority_ext)
+ // priority_float = priority_ext->priority;
+
+ // unsigned priority = MIN2(LIBRESOC_BO_PRIORITY_APPLICATION_MAX - 1,
+ // (int)(priority_float * LIBRESOC_BO_PRIORITY_APPLICATION_MAX));
+
+ mem->user_ptr = NULL;
+ //mem->bo = NULL;
+
+
+ if (import_info) {
+ assert(import_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ||
+ import_info->handleType ==
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT);
+ // mem->bo = device->ws->buffer_from_fd(device->ws, import_info->fd,
+ // priority, NULL);
+ // if (!mem->bo) {
+ // result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ // goto fail;
+ // } else {
+ // close(import_info->fd);
+ // }
+
+ // if (mem->image && mem->image->plane_count == 1 &&
+ // !vk_format_is_depth_or_stencil(mem->image->vk_format)) {
+ // struct radeon_bo_metadata metadata;
+ // device->ws->buffer_get_metadata(mem->bo, &metadata);
+
+ // struct libresoc_image_create_info create_info = {
+ // .no_metadata_planes = true,
+ // .bo_metadata = &metadata
+ // };
+
+ // /* This gives a basic ability to import radeonsi images
+ // * that don't have DCC. This is not guaranteed by any
+ // * spec and can be removed after we support modifiers. */
+ // result = libresoc_image_create_layout(device, create_info, mem->image);
+ // if (result != VK_SUCCESS) {
+ // device->ws->buffer_destroy(mem->bo);
+ // goto fail;
+ // }
+ // }
+ } else if (host_ptr_info) {
+ // assert(host_ptr_info->handleType == VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT);
+ // mem->bo = device->ws->buffer_from_ptr(device->ws, host_ptr_info->pHostPointer,
+ // pAllocateInfo->allocationSize,
+ // priority);
+ // if (!mem->bo) {
+ // result = VK_ERROR_INVALID_EXTERNAL_HANDLE;
+ // goto fail;
+ // } else {
+ // mem->user_ptr = host_ptr_info->pHostPointer;
+ // }
+ } else {
+ uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
+ uint32_t heap_index;
+
+ heap_index = device->physical_device->memory_properties.memoryTypes[pAllocateInfo->memoryTypeIndex].heapIndex;
+ // domain = device->physical_device->memory_domains[pAllocateInfo->memoryTypeIndex];
+ // flags |= device->physical_device->memory_flags[pAllocateInfo->memoryTypeIndex];
+
+ // if (!dedicate_info && !import_info && (!export_info || !export_info->handleTypes)) {
+ // flags |= RADEON_FLAG_NO_INTERPROCESS_SHARING;
+ // if (device->use_global_bo_list) {
+ // flags |= RADEON_FLAG_PREFER_LOCAL_BO;
+ // }
+ // }
+
+ if (device->overallocation_disallowed) {
+ uint64_t total_size =
+ device->physical_device->memory_properties.memoryHeaps[heap_index].size;
+
+ mtx_lock(&device->overallocation_mutex);
+ if (device->allocated_memory_size[heap_index] + alloc_size > total_size) {
+ mtx_unlock(&device->overallocation_mutex);
+ result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ goto fail;
+ }
+ device->allocated_memory_size[heap_index] += alloc_size;
+ mtx_unlock(&device->overallocation_mutex);
+ }
+
+ // mem->bo = device->ws->buffer_create(device->ws, alloc_size, device->physical_device->rad_info.max_alignment,
+ // domain, flags, priority);
+
+ // if (!mem->bo) {
+ // if (device->overallocation_disallowed) {
+ // mtx_lock(&device->overallocation_mutex);
+ // device->allocated_memory_size[heap_index] -= alloc_size;
+ // mtx_unlock(&device->overallocation_mutex);
+ // }
+ // result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ // goto fail;
+ // }
+
+ mem->heap_index = heap_index;
+ mem->alloc_size = alloc_size;
+ }
+
+ // if (!wsi_info) {
+ // result = libresoc_bo_list_add(device, mem->bo);
+ // if (result != VK_SUCCESS)
+ // goto fail;
+ // }
+
+ *pMem = libresoc_device_memory_to_handle(mem);
+
+ return VK_SUCCESS;
+
+fail:
+ libresoc_free_memory(device, pAllocator,mem);
+
+ return result;
+}
+
+VkResult libresoc_AllocateMemory(
+ VkDevice _device,
+ const VkMemoryAllocateInfo* pAllocateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkDeviceMemory* pMem)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ return libresoc_alloc_memory(device, pAllocateInfo, pAllocator, pMem);
+}
+
+void libresoc_FreeMemory(
+ VkDevice _device,
+ VkDeviceMemory _mem,
+ const VkAllocationCallbacks* pAllocator)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_device_memory, mem, _mem);
+
+ libresoc_free_memory(device, pAllocator, mem);
+}
+static VkResult
+libresoc_create_pthread_cond(pthread_cond_t *cond)
+{
+ pthread_condattr_t condattr;
+ if (pthread_condattr_init(&condattr)) {
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+
+ if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
+ pthread_condattr_destroy(&condattr);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ if (pthread_cond_init(cond, &condattr)) {
+ pthread_condattr_destroy(&condattr);
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ pthread_condattr_destroy(&condattr);
+ return VK_SUCCESS;
+}
+
VkResult
libresoc_EnumerateInstanceExtensionProperties(const char *pLayerName,
uint32_t *pPropertyCount,
assert(id < ARRAY_SIZE(libresoc_debug_options) - 1);
return libresoc_debug_options[id].string;
}
+
+static const char libresoc_dri_options_xml[] =
+DRI_CONF_BEGIN
+ DRI_CONF_SECTION_PERFORMANCE
+ DRI_CONF_ADAPTIVE_SYNC("true")
+ DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
+ DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
+ DRI_CONF_VK_X11_ENSURE_MIN_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 libresoc_init_dri_options(struct libresoc_instance *instance)
+{
+ driParseOptionInfo(&instance->available_dri_options, libresoc_dri_options_xml);
+ driParseConfigFiles(&instance->dri_options,
+ &instance->available_dri_options,
+ 0, "libresoc", NULL,
+ instance->app_info.app_name,
+ instance->app_info.app_version,
+ instance->engineName,
+ instance->engineVersion);
+}
+
VkResult
libresoc_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
const VkAllocationCallbacks *pAllocator,
}
instance->physical_devices_enumerated = false;
list_inithead(&instance->physical_devices);
+ libresoc_init_dri_options(instance);
*pInstance = libresoc_instance_to_handle(instance);
return VK_SUCCESS;
/* FIXME: stub */
}
+static void
+libresoc_physical_device_init_mem_types(struct libresoc_physical_device *device)
+{
+ uint64_t visible_vram_size = 65536; //TODO: some dummy value
+ uint64_t vram_size = 65536; //TODO: some dummy value
+ int vram_index = -1, visible_vram_index = -1;
+ device->memory_properties.memoryHeapCount = 0;
+ if (vram_size > 0) {
+ vram_index = device->memory_properties.memoryHeapCount++;
+ device->memory_properties.memoryHeaps[vram_index] = (VkMemoryHeap) {
+ .size = vram_size,
+ .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+ };
+ }
+
+ if (visible_vram_size) {
+ visible_vram_index = device->memory_properties.memoryHeapCount++;
+ device->memory_properties.memoryHeaps[visible_vram_index] = (VkMemoryHeap) {
+ .size = visible_vram_size,
+ .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+ };
+ }
+ unsigned type_count = 0;
+
+ if (vram_index >= 0 || visible_vram_index >= 0) {
+ device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
+ .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ .heapIndex = vram_index >= 0 ? vram_index : visible_vram_index,
+ };
+ }
+
+ if (visible_vram_index >= 0) {
+ device->memory_properties.memoryTypes[type_count++] = (VkMemoryType) {
+ .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
+ VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
+ VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
+ .heapIndex = visible_vram_index,
+ };
+ }
+
+ device->memory_properties.memoryTypeCount = type_count;
+
+
+}
static VkResult
libresoc_physical_device_try_create(struct libresoc_instance *instance,
struct libresoc_physical_device **device_out)
{
VkResult result;
+ int fd = -1;
+ int master_fd = -1;
struct libresoc_physical_device *device =
vk_zalloc2(&instance->alloc, NULL, sizeof(*device), 8,
device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
device->instance = instance;
+ device->master_fd = master_fd;
+ device->local_fd = fd;
+ libresoc_physical_device_init_mem_types(device);
+
+ libresoc_physical_device_get_supported_extensions(device,
+ &device->supported_extensions);
+ result = libresoc_init_wsi(device);
+ if (result != VK_SUCCESS) {
+ return result;
+ }
snprintf(device->name, sizeof(device->name),
"LIBRE-SOC DEVICE");
*device_out = device;
-
+//TODO: incase of failures need to deallocate and cleanup various allocation properly.
return VK_SUCCESS;
}
.apiVersion = libresoc_physical_device_api_version(pdevice),
.driverVersion = vk_get_driver_version(),
.vendorID = 1, //TODO: some dummy value
- .deviceID = 1, //TODO: dome dummay value
+ .deviceID = 1, //TODO: dome dummy value
.deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
.limits = limits,
.sparseProperties = {0},
if (getenv("LIBRESOC_TRACE")) {
fprintf(stderr, "GetPhysicalDEviceMemoryProperties called. \n");
}
- /* FIXME: stub */
-}
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, physical_device, physicalDevice);
-void
-libresoc_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
-
- if (getenv("LIBRESOC_TRACE")) {
- fprintf(stderr, "GetPhysicalDeviceFormatProperties called. \n");
- }
+ *pMemoryProperties = physical_device->memory_properties;
/* FIXME: stub */
}
-VkResult
- libresoc_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
-{
- if (getenv("LIBRESOC_TRACE")) {
- fprintf(stderr, "GetPhysicalDEviceImageFormatProperties called. \n");
- }
-
- /* FIXME: stub */
- return VK_SUCCESS;
-}
- void
- libresoc_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
- {
- if (getenv("LIBRESOC_TRACE")) {
- fprintf(stderr, "GetPhysicalDeviceSparseImageFormatProperties called. \n");
- }
- /* FIXME: stub */
- }
+//void
+//libresoc_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
+//
+// if (getenv("LIBRESOC_TRACE")) {
+// fprintf(stderr, "GetPhysicalDeviceFormatProperties called. \n");
+// }
+// /* FIXME: stub */
+//}
+
+//VkResult
+// libresoc_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
+//{
+// if (getenv("LIBRESOC_TRACE")) {
+// fprintf(stderr, "GetPhysicalDEviceImageFormatProperties called. \n");
+// }
+//
+// /* FIXME: stub */
+// return VK_SUCCESS;
+//}
+// void
+// libresoc_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
+// {
+// if (getenv("LIBRESOC_TRACE")) {
+// fprintf(stderr, "GetPhysicalDeviceSparseImageFormatProperties called. \n");
+// }
+// /* FIXME: stub */
+// }
PFN_vkVoidFunction
libresoc_GetInstanceProcAddr(VkInstance _instance,
const char *pName)
}
}
-/*
-static VkResult
-libresoc_create_pthread_cond(pthread_cond_t *cond)
-{
- pthread_condattr_t condattr;
- if (pthread_condattr_init(&condattr)) {
- return VK_ERROR_INITIALIZATION_FAILED;
- }
-
- if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
- pthread_condattr_destroy(&condattr);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- if (pthread_cond_init(cond, &condattr)) {
- pthread_condattr_destroy(&condattr);
- return VK_ERROR_INITIALIZATION_FAILED;
- }
- pthread_condattr_destroy(&condattr);
- return VK_SUCCESS;
-}
-*/
static VkResult
check_physical_device_features(VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceFeatures *features)
queue->queue_family_index = queue_family_index;
queue->queue_idx = idx;
queue->flags = flags;
+ list_inithead(&queue->pending_submissions);
+ pthread_mutex_init(&queue->pending_mutex, NULL);
+
+ pthread_mutex_init(&queue->thread_mutex, NULL);
+ //queue->thread_submission = NULL;
+ queue->thread_running = queue->thread_exit = false;
+ VkResult result = libresoc_create_pthread_cond(&queue->thread_cond);
+ if (result != VK_SUCCESS)
+ return vk_error(device->instance, result);
+
return VK_SUCCESS;
}
}
return VK_SUCCESS;
}
+
+void libresoc_GetPhysicalDeviceProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties2 *pProperties)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, pdevice, physicalDevice);
+ libresoc_GetPhysicalDeviceProperties(physicalDevice, &pProperties->properties);
+ //TODO: add more stuffs when required
+}
+
+void libresoc_GetPhysicalDeviceFeatures2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures2 *pFeatures)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, pdevice, physicalDevice);
+ libresoc_GetPhysicalDeviceFeatures(physicalDevice, &pFeatures->features);
+}
+
+void libresoc_GetPhysicalDeviceQueueFamilyProperties2(
+ VkPhysicalDevice physicalDevice,
+ uint32_t* pCount,
+ VkQueueFamilyProperties2 *pQueueFamilyProperties)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, pdevice, physicalDevice);
+ if (!pQueueFamilyProperties) {
+ libresoc_get_physical_device_queue_family_properties(pdevice, pCount, NULL);
+ return;
+ }
+ VkQueueFamilyProperties *properties[] = {
+ &pQueueFamilyProperties[0].queueFamilyProperties,
+ &pQueueFamilyProperties[1].queueFamilyProperties,
+ &pQueueFamilyProperties[2].queueFamilyProperties,
+ };
+ libresoc_get_physical_device_queue_family_properties(pdevice, pCount, properties);
+ assert(*pCount <= 3);
+}
+
+static void
+libresoc_get_memory_budget_properties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryBudgetPropertiesEXT *memoryBudget)
+{
+//TODO: stub
+}
+
+void libresoc_GetPhysicalDeviceMemoryProperties2(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties2 *pMemoryProperties)
+{
+ libresoc_GetPhysicalDeviceMemoryProperties(physicalDevice,
+ &pMemoryProperties->memoryProperties);
+
+ VkPhysicalDeviceMemoryBudgetPropertiesEXT *memory_budget =
+ vk_find_struct(pMemoryProperties->pNext,
+ PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT);
+ if (memory_budget)
+ libresoc_get_memory_budget_properties(physicalDevice, memory_budget);
+}
+
+VkResult libresoc_CreateSemaphore(
+ VkDevice _device,
+ const VkSemaphoreCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSemaphore* pSemaphore)
+{
+ //TODO: minimal things as of now, add more complex code as required
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ struct libresoc_semaphore *sem = vk_alloc2(&device->vk.alloc, pAllocator,
+ sizeof(*sem), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!sem)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &sem->base,
+ VK_OBJECT_TYPE_SEMAPHORE);
+
+ *pSemaphore = libresoc_semaphore_to_handle(sem);
+ return VK_SUCCESS;
+}
+
+void libresoc_GetImageMemoryRequirements(
+ VkDevice _device,
+ VkImage _image,
+ VkMemoryRequirements* pMemoryRequirements)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_image, image, _image);
+
+ pMemoryRequirements->memoryTypeBits = (1u << device->physical_device->memory_properties.memoryTypeCount) - 1;
+
+ pMemoryRequirements->size = image->size;
+ pMemoryRequirements->alignment = image->alignment;
+}
+
+void libresoc_GetImageMemoryRequirements2(
+ VkDevice device,
+ const VkImageMemoryRequirementsInfo2 *pInfo,
+ VkMemoryRequirements2 *pMemoryRequirements)
+{
+ libresoc_GetImageMemoryRequirements(device, pInfo->image,
+ &pMemoryRequirements->memoryRequirements);
+}
+
+VkResult libresoc_BindImageMemory2(VkDevice device,
+ uint32_t bindInfoCount,
+ const VkBindImageMemoryInfo *pBindInfos)
+{
+ for (uint32_t i = 0; i < bindInfoCount; ++i) {
+ LIBRESOC_FROM_HANDLE(libresoc_device_memory, mem, pBindInfos[i].memory);
+ LIBRESOC_FROM_HANDLE(libresoc_image, image, pBindInfos[i].image);
+
+ if (mem) {
+ // image->bo = mem->bo;
+ // image->offset = pBindInfos[i].memoryOffset;
+ } else {
+ // image->bo = NULL;
+ // image->offset = 0;
+ }
+ }
+ return VK_SUCCESS;
+}
+
+
+VkResult libresoc_BindImageMemory(
+ VkDevice device,
+ VkImage image,
+ VkDeviceMemory memory,
+ VkDeviceSize memoryOffset)
+{
+ const VkBindImageMemoryInfo info = {
+ .sType = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
+ .image = image,
+ .memory = memory,
+ .memoryOffset = memoryOffset
+ };
+
+ return libresoc_BindImageMemory2(device, 1, &info);
+}
+
+static VkResult libresoc_queue_submit(struct libresoc_queue *queue,
+ const struct libresoc_queue_submission *submission)
+{
+ return VK_SUCCESS;
+ // struct libresoc_deferred_queue_submission *deferred = NULL;
+
+ // VkResult result = libresoc_create_deferred_submission(queue, submission, &deferred);
+ // if (result != VK_SUCCESS)
+ // return result;
+
+ // struct list_head processing_list;
+ // list_inithead(&processing_list);
+
+ // result = libresoc_queue_enqueue_submission(deferred, &processing_list);
+ // if (result != VK_SUCCESS) {
+ // /* If anything is in the list we leak. */
+ // assert(list_is_empty(&processing_list));
+ // return result;
+ // }
+ // return libresoc_process_submissions(&processing_list);
+}
+
+/* Signals fence as soon as all the work currently put on queue is done. */
+static VkResult libresoc_signal_fence(struct libresoc_queue *queue,
+ VkFence fence)
+{
+ return libresoc_queue_submit(queue, &(struct libresoc_queue_submission) {
+ .fence = fence
+ });
+}
+
+static bool libresoc_submit_has_effects(const VkSubmitInfo *info)
+{
+ return info->commandBufferCount ||
+ info->waitSemaphoreCount ||
+ info->signalSemaphoreCount;
+}
+
+VkResult libresoc_QueueSubmit(
+ VkQueue _queue,
+ uint32_t submitCount,
+ const VkSubmitInfo* pSubmits,
+ VkFence fence)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_queue, queue, _queue);
+ VkResult result;
+ uint32_t fence_idx = 0;
+ bool flushed_caches = false;
+
+ if (fence != VK_NULL_HANDLE) {
+ for (uint32_t i = 0; i < submitCount; ++i)
+ if (libresoc_submit_has_effects(pSubmits + i))
+ fence_idx = i;
+ } else
+ fence_idx = UINT32_MAX;
+
+ for (uint32_t i = 0; i < submitCount; i++) {
+ if (!libresoc_submit_has_effects(pSubmits + i) && fence_idx != i)
+ continue;
+
+ VkPipelineStageFlags wait_dst_stage_mask = 0;
+ for (unsigned j = 0; j < pSubmits[i].waitSemaphoreCount; ++j) {
+ wait_dst_stage_mask |= pSubmits[i].pWaitDstStageMask[j];
+ }
+
+ const VkTimelineSemaphoreSubmitInfo *timeline_info =
+ vk_find_struct_const(pSubmits[i].pNext, TIMELINE_SEMAPHORE_SUBMIT_INFO);
+
+ result = libresoc_queue_submit(queue, &(struct libresoc_queue_submission) {
+ .cmd_buffers = pSubmits[i].pCommandBuffers,
+ .cmd_buffer_count = pSubmits[i].commandBufferCount,
+ .wait_dst_stage_mask = wait_dst_stage_mask,
+ .flush_caches = !flushed_caches,
+ .wait_semaphores = pSubmits[i].pWaitSemaphores,
+ .wait_semaphore_count = pSubmits[i].waitSemaphoreCount,
+ .signal_semaphores = pSubmits[i].pSignalSemaphores,
+ .signal_semaphore_count = pSubmits[i].signalSemaphoreCount,
+ .fence = i == fence_idx ? fence : VK_NULL_HANDLE,
+ .wait_values = timeline_info ? timeline_info->pWaitSemaphoreValues : NULL,
+ .wait_value_count = timeline_info && timeline_info->pWaitSemaphoreValues ? timeline_info->waitSemaphoreValueCount : 0,
+ .signal_values = timeline_info ? timeline_info->pSignalSemaphoreValues : NULL,
+ .signal_value_count = timeline_info && timeline_info->pSignalSemaphoreValues ? timeline_info->signalSemaphoreValueCount : 0,
+ });
+ if (result != VK_SUCCESS)
+ return result;
+
+ flushed_caches = true;
+ }
+
+ if (fence != VK_NULL_HANDLE && !submitCount) {
+ result = libresoc_signal_fence(queue, fence);
+ if (result != VK_SUCCESS)
+ return result;
+ }
+
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_CreateFence(
+ VkDevice _device,
+ const VkFenceCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkFence* pFence)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ const VkExportFenceCreateInfo *export =
+ vk_find_struct_const(pCreateInfo->pNext, EXPORT_FENCE_CREATE_INFO);
+ VkExternalFenceHandleTypeFlags handleTypes =
+ export ? export->handleTypes : 0;
+ struct libresoc_fence *fence;
+
+ fence = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*fence), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!fence)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &fence->base, VK_OBJECT_TYPE_FENCE);
+
+ // if (device->always_use_syncobj || handleTypes) {
+ // fence->permanent.kind = LIBRESOC_FENCE_SYNCOBJ;
+
+ // bool create_signaled = false;
+ // if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
+ // create_signaled = true;
+
+ // int ret = device->ws->create_syncobj(device->ws, create_signaled,
+ // &fence->permanent.syncobj);
+ // if (ret) {
+ // libresoc_destroy_fence(device, pAllocator, fence);
+ // return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+ // }
+ // } else {
+ // fence->permanent.kind = LIBRESOC_FENCE_WINSYS;
+
+ // fence->permanent.fence = device->ws->create_fence();
+ // if (!fence->permanent.fence) {
+ // vk_free2(&device->vk.alloc, pAllocator, fence);
+ // libresoc_destroy_fence(device, pAllocator, fence);
+ // return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+ // }
+ // if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT)
+ // device->ws->signal_fence(fence->permanent.fence);
+ // }
+
+ *pFence = libresoc_fence_to_handle(fence);
+
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_MapMemory(
+ VkDevice _device,
+ VkDeviceMemory _memory,
+ VkDeviceSize offset,
+ VkDeviceSize size,
+ VkMemoryMapFlags flags,
+ void** ppData)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_device_memory, mem, _memory);
+
+ if (mem == NULL) {
+ *ppData = NULL;
+ return VK_SUCCESS;
+ }
+
+ if (mem->user_ptr)
+ *ppData = mem->user_ptr;
+ // else
+ // *ppData = device->ws->buffer_map(mem->bo);
+
+ if (*ppData) {
+ *ppData += offset;
+ return VK_SUCCESS;
+ }
+
+ return vk_error(device->instance, VK_ERROR_MEMORY_MAP_FAILED);
+}
+
+void libresoc_UnmapMemory(
+ VkDevice _device,
+ VkDeviceMemory _memory)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_device_memory, mem, _memory);
+
+ if (mem == NULL)
+ return;
+
+ // if (mem->user_ptr == NULL)
+ // device->ws->buffer_unmap(mem->bo);
+}
+
+VkResult libresoc_WaitForFences(
+ VkDevice _device,
+ uint32_t fenceCount,
+ const VkFence* pFences,
+ VkBool32 waitAll,
+ uint64_t timeout)
+{
+ //TODO: stub
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_ResetFences(VkDevice _device,
+ uint32_t fenceCount,
+ const VkFence *pFences)
+{
+
+ //TODO: stub
+ return VK_SUCCESS;
+}
# available.
API_VERSIONS = [
ApiVersion('1.0', True),
+ ApiVersion('1.1', False),
- # FIXME: for now we only support 1.0. We maintain this support from anv just in case in
- # the future we support more that one version supported.
- # ApiVersion('1.1', <condition> ),
]
MAX_API_VERSION = None # Computed later
EXTENSIONS = [
- #FIXME: for now we don't support additional extensions beyond 1.0. Revisit later
+ #Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
+ #Extension('VK_KHR_external_memory', 1, True),
+ #TODO: enabling following extension creates compilation problem
+ #Extension('VK_KHR_external_memory_capabilities', 1, True),
+ #Extension('VK_KHR_external_memory_fd', 1, True),
+ Extension('VK_KHR_get_physical_device_properties2', 1, True),
+ #Extension('VK_KHR_get_surface_capabilities2', 1, 'LIBRESOC_HAS_SURFACE'),
+ Extension('VK_KHR_surface', 25, 'LIBRESOC_HAS_SURFACE'),
+ Extension('VK_KHR_swapchain', 68, 'LIBRESOC_HAS_SURFACE'),
+ # Extension('VK_KHR_wayland_surface', 6, 'VK_USE_PLATFORM_WAYLAND_KHR'),
+ Extension('VK_KHR_xcb_surface', 6, 'VK_USE_PLATFORM_XCB_KHR'),
+ Extension('VK_KHR_xlib_surface', 6, 'VK_USE_PLATFORM_XLIB_KHR'),
+ # Extension('VK_EXT_debug_report', 9, True),
+ # Extension('VK_EXT_external_memory_dma_buf', 1, True),
+ # Extension('VK_EXT_image_drm_format_modifier', 1, False),
+
]
# Sort the extension list the way we expect: KHR, then EXT, then vendors
--- /dev/null
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "libresoc_private.h"
+
+#include "vk_format.h"
+
+#include "vk_util.h"
+
+#include "util/u_half.h"
+#include "util/format_srgb.h"
+#include "util/format_r11g11b10f.h"
+
+//uint32_t libresoc_translate_buffer_dataformat(const struct vk_format_description *desc,
+// int first_non_void)
+//{
+// unsigned type;
+// int i;
+//
+// assert(desc->layout != VK_FORMAT_LAYOUT_MULTIPLANE);
+//
+// if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
+// return V_008F0C_BUF_DATA_FORMAT_10_11_11;
+//
+// if (first_non_void < 0)
+// return V_008F0C_BUF_DATA_FORMAT_INVALID;
+// type = desc->channel[first_non_void].type;
+//
+// if (type == VK_FORMAT_TYPE_FIXED)
+// return V_008F0C_BUF_DATA_FORMAT_INVALID;
+// if (desc->nr_channels == 4 &&
+// desc->channel[0].size == 10 &&
+// desc->channel[1].size == 10 &&
+// desc->channel[2].size == 10 &&
+// desc->channel[3].size == 2)
+// return V_008F0C_BUF_DATA_FORMAT_2_10_10_10;
+//
+// /* See whether the components are of the same size. */
+// for (i = 0; i < desc->nr_channels; i++) {
+// if (desc->channel[first_non_void].size != desc->channel[i].size)
+// return V_008F0C_BUF_DATA_FORMAT_INVALID;
+// }
+//
+// switch (desc->channel[first_non_void].size) {
+// case 8:
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F0C_BUF_DATA_FORMAT_8;
+// case 2:
+// return V_008F0C_BUF_DATA_FORMAT_8_8;
+// case 4:
+// return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
+// }
+// break;
+// case 16:
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F0C_BUF_DATA_FORMAT_16;
+// case 2:
+// return V_008F0C_BUF_DATA_FORMAT_16_16;
+// case 4:
+// return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
+// }
+// break;
+// case 32:
+// /* From the Southern Islands ISA documentation about MTBUF:
+// * 'Memory reads of data in memory that is 32 or 64 bits do not
+// * undergo any format conversion.'
+// */
+// if (type != VK_FORMAT_TYPE_FLOAT &&
+// !desc->channel[first_non_void].pure_integer)
+// return V_008F0C_BUF_DATA_FORMAT_INVALID;
+//
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F0C_BUF_DATA_FORMAT_32;
+// case 2:
+// return V_008F0C_BUF_DATA_FORMAT_32_32;
+// case 3:
+// return V_008F0C_BUF_DATA_FORMAT_32_32_32;
+// case 4:
+// return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
+// }
+// break;
+// }
+//
+// return V_008F0C_BUF_DATA_FORMAT_INVALID;
+//}
+
+//uint32_t libresoc_translate_buffer_numformat(const struct vk_format_description *desc,
+// int first_non_void)
+//{
+// assert(desc->layout != VK_FORMAT_LAYOUT_MULTIPLANE);
+//
+// if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
+// return V_008F0C_BUF_NUM_FORMAT_FLOAT;
+//
+// if (first_non_void < 0)
+// return ~0;
+//
+// switch (desc->channel[first_non_void].type) {
+// case VK_FORMAT_TYPE_SIGNED:
+// if (desc->channel[first_non_void].normalized)
+// return V_008F0C_BUF_NUM_FORMAT_SNORM;
+// else if (desc->channel[first_non_void].pure_integer)
+// return V_008F0C_BUF_NUM_FORMAT_SINT;
+// else
+// return V_008F0C_BUF_NUM_FORMAT_SSCALED;
+// break;
+// case VK_FORMAT_TYPE_UNSIGNED:
+// if (desc->channel[first_non_void].normalized)
+// return V_008F0C_BUF_NUM_FORMAT_UNORM;
+// else if (desc->channel[first_non_void].pure_integer)
+// return V_008F0C_BUF_NUM_FORMAT_UINT;
+// else
+// return V_008F0C_BUF_NUM_FORMAT_USCALED;
+// break;
+// case VK_FORMAT_TYPE_FLOAT:
+// default:
+// return V_008F0C_BUF_NUM_FORMAT_FLOAT;
+// }
+//}
+
+//uint32_t libresoc_translate_tex_dataformat(VkFormat format,
+// const struct vk_format_description *desc,
+// int first_non_void)
+//{
+// bool uniform = true;
+// int i;
+//
+// assert(vk_format_get_plane_count(format) == 1);
+//
+// if (!desc)
+// return ~0;
+// /* Colorspace (return non-RGB formats directly). */
+// switch (desc->colorspace) {
+// /* Depth stencil formats */
+// case VK_FORMAT_COLORSPACE_ZS:
+// switch (format) {
+// case VK_FORMAT_D16_UNORM:
+// return V_008F14_IMG_DATA_FORMAT_16;
+// case VK_FORMAT_D24_UNORM_S8_UINT:
+// case VK_FORMAT_X8_D24_UNORM_PACK32:
+// return V_008F14_IMG_DATA_FORMAT_8_24;
+// case VK_FORMAT_S8_UINT:
+// return V_008F14_IMG_DATA_FORMAT_8;
+// case VK_FORMAT_D32_SFLOAT:
+// return V_008F14_IMG_DATA_FORMAT_32;
+// case VK_FORMAT_D32_SFLOAT_S8_UINT:
+// return V_008F14_IMG_DATA_FORMAT_X24_8_32;
+// default:
+// goto out_unknown;
+// }
+//
+// case VK_FORMAT_COLORSPACE_YUV:
+// goto out_unknown; /* TODO */
+//
+// case VK_FORMAT_COLORSPACE_SRGB:
+// if (desc->nr_channels != 4 && desc->nr_channels != 1)
+// goto out_unknown;
+// break;
+//
+// default:
+// break;
+// }
+//
+// if (desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
+// switch(format) {
+// /* Don't ask me why this looks inverted. PAL does the same. */
+// case VK_FORMAT_G8B8G8R8_422_UNORM:
+// return V_008F14_IMG_DATA_FORMAT_BG_RG;
+// case VK_FORMAT_B8G8R8G8_422_UNORM:
+// return V_008F14_IMG_DATA_FORMAT_GB_GR;
+// default:
+// goto out_unknown;
+// }
+// }
+//
+// if (desc->layout == VK_FORMAT_LAYOUT_RGTC) {
+// switch(format) {
+// case VK_FORMAT_BC4_UNORM_BLOCK:
+// case VK_FORMAT_BC4_SNORM_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC4;
+// case VK_FORMAT_BC5_UNORM_BLOCK:
+// case VK_FORMAT_BC5_SNORM_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC5;
+// default:
+// break;
+// }
+// }
+//
+// if (desc->layout == VK_FORMAT_LAYOUT_S3TC) {
+// switch(format) {
+// case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
+// case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
+// case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
+// case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC1;
+// case VK_FORMAT_BC2_UNORM_BLOCK:
+// case VK_FORMAT_BC2_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC2;
+// case VK_FORMAT_BC3_UNORM_BLOCK:
+// case VK_FORMAT_BC3_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC3;
+// default:
+// break;
+// }
+// }
+//
+// if (desc->layout == VK_FORMAT_LAYOUT_BPTC) {
+// switch(format) {
+// case VK_FORMAT_BC6H_UFLOAT_BLOCK:
+// case VK_FORMAT_BC6H_SFLOAT_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC6;
+// case VK_FORMAT_BC7_UNORM_BLOCK:
+// case VK_FORMAT_BC7_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_BC7;
+// default:
+// break;
+// }
+// }
+//
+// if (desc->layout == VK_FORMAT_LAYOUT_ETC) {
+// switch (format) {
+// case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_ETC2_RGB;
+// case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1;
+// case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA;
+// case VK_FORMAT_EAC_R11_UNORM_BLOCK:
+// case VK_FORMAT_EAC_R11_SNORM_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_ETC2_R;
+// case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
+// case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
+// return V_008F14_IMG_DATA_FORMAT_ETC2_RG;
+// default:
+// break;
+// }
+// }
+//
+// if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
+// return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
+// } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
+// return V_008F14_IMG_DATA_FORMAT_10_11_11;
+// }
+//
+// /* R8G8Bx_SNORM - TODO CxV8U8 */
+//
+// /* hw cannot support mixed formats (except depth/stencil, since only
+// * depth is read).*/
+// if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS)
+// goto out_unknown;
+//
+// /* See whether the components are of the same size. */
+// for (i = 1; i < desc->nr_channels; i++) {
+// uniform = uniform && desc->channel[0].size == desc->channel[i].size;
+// }
+//
+// /* Non-uniform formats. */
+// if (!uniform) {
+// switch(desc->nr_channels) {
+// case 3:
+// if (desc->channel[0].size == 5 &&
+// desc->channel[1].size == 6 &&
+// desc->channel[2].size == 5) {
+// return V_008F14_IMG_DATA_FORMAT_5_6_5;
+// }
+// goto out_unknown;
+// case 4:
+// if (desc->channel[0].size == 5 &&
+// desc->channel[1].size == 5 &&
+// desc->channel[2].size == 5 &&
+// desc->channel[3].size == 1) {
+// return V_008F14_IMG_DATA_FORMAT_1_5_5_5;
+// }
+// if (desc->channel[0].size == 1 &&
+// desc->channel[1].size == 5 &&
+// desc->channel[2].size == 5 &&
+// desc->channel[3].size == 5) {
+// return V_008F14_IMG_DATA_FORMAT_5_5_5_1;
+// }
+// if (desc->channel[0].size == 10 &&
+// desc->channel[1].size == 10 &&
+// desc->channel[2].size == 10 &&
+// desc->channel[3].size == 2) {
+// /* Closed VK driver does this also no 2/10/10/10 snorm */
+// if (desc->channel[0].type == VK_FORMAT_TYPE_SIGNED &&
+// desc->channel[0].normalized)
+// goto out_unknown;
+// return V_008F14_IMG_DATA_FORMAT_2_10_10_10;
+// }
+// goto out_unknown;
+// }
+// goto out_unknown;
+// }
+//
+// if (first_non_void < 0 || first_non_void > 3)
+// goto out_unknown;
+//
+// /* uniform formats */
+// switch (desc->channel[first_non_void].size) {
+// case 4:
+// switch (desc->nr_channels) {
+//#if 0 /* Not supported for render targets */
+// case 2:
+// return V_008F14_IMG_DATA_FORMAT_4_4;
+//#endif
+// case 4:
+// return V_008F14_IMG_DATA_FORMAT_4_4_4_4;
+// }
+// break;
+// case 8:
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F14_IMG_DATA_FORMAT_8;
+// case 2:
+// return V_008F14_IMG_DATA_FORMAT_8_8;
+// case 4:
+// return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
+// }
+// break;
+// case 16:
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F14_IMG_DATA_FORMAT_16;
+// case 2:
+// return V_008F14_IMG_DATA_FORMAT_16_16;
+// case 4:
+// return V_008F14_IMG_DATA_FORMAT_16_16_16_16;
+// }
+// break;
+// case 32:
+// switch (desc->nr_channels) {
+// case 1:
+// return V_008F14_IMG_DATA_FORMAT_32;
+// case 2:
+// return V_008F14_IMG_DATA_FORMAT_32_32;
+// case 3:
+// return V_008F14_IMG_DATA_FORMAT_32_32_32;
+// case 4:
+// return V_008F14_IMG_DATA_FORMAT_32_32_32_32;
+// }
+// }
+//
+//out_unknown:
+// /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */
+// return ~0;
+//}
+
+//uint32_t libresoc_translate_tex_numformat(VkFormat format,
+// const struct vk_format_description *desc,
+// int first_non_void)
+//{
+// assert(vk_format_get_plane_count(format) == 1);
+//
+// switch (format) {
+// case VK_FORMAT_D24_UNORM_S8_UINT:
+// return V_008F14_IMG_NUM_FORMAT_UNORM;
+// default:
+// if (first_non_void < 0) {
+// if (vk_format_is_compressed(format)) {
+// switch (format) {
+// case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
+// case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
+// case VK_FORMAT_BC2_SRGB_BLOCK:
+// case VK_FORMAT_BC3_SRGB_BLOCK:
+// case VK_FORMAT_BC7_SRGB_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
+// case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+// return V_008F14_IMG_NUM_FORMAT_SRGB;
+// case VK_FORMAT_BC4_SNORM_BLOCK:
+// case VK_FORMAT_BC5_SNORM_BLOCK:
+// case VK_FORMAT_BC6H_SFLOAT_BLOCK:
+// case VK_FORMAT_EAC_R11_SNORM_BLOCK:
+// case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
+// return V_008F14_IMG_NUM_FORMAT_SNORM;
+// default:
+// return V_008F14_IMG_NUM_FORMAT_UNORM;
+// }
+// } else if (desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
+// return V_008F14_IMG_NUM_FORMAT_UNORM;
+// } else {
+// return V_008F14_IMG_NUM_FORMAT_FLOAT;
+// }
+// } else if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
+// return V_008F14_IMG_NUM_FORMAT_SRGB;
+// } else {
+// switch (desc->channel[first_non_void].type) {
+// case VK_FORMAT_TYPE_FLOAT:
+// return V_008F14_IMG_NUM_FORMAT_FLOAT;
+// case VK_FORMAT_TYPE_SIGNED:
+// if (desc->channel[first_non_void].normalized)
+// return V_008F14_IMG_NUM_FORMAT_SNORM;
+// else if (desc->channel[first_non_void].pure_integer)
+// return V_008F14_IMG_NUM_FORMAT_SINT;
+// else
+// return V_008F14_IMG_NUM_FORMAT_SSCALED;
+// case VK_FORMAT_TYPE_UNSIGNED:
+// if (desc->channel[first_non_void].normalized)
+// return V_008F14_IMG_NUM_FORMAT_UNORM;
+// else if (desc->channel[first_non_void].pure_integer)
+// return V_008F14_IMG_NUM_FORMAT_UINT;
+// else
+// return V_008F14_IMG_NUM_FORMAT_USCALED;
+// default:
+// return V_008F14_IMG_NUM_FORMAT_UNORM;
+// }
+// }
+// }
+//}
+
+//uint32_t libresoc_translate_color_numformat(VkFormat format,
+// const struct vk_format_description *desc,
+// int first_non_void)
+//{
+// unsigned ntype;
+//
+// assert(vk_format_get_plane_count(format) == 1);
+//
+// if (first_non_void == -1 || desc->channel[first_non_void].type == VK_FORMAT_TYPE_FLOAT)
+// ntype = V_028C70_NUMBER_FLOAT;
+// else {
+// ntype = V_028C70_NUMBER_UNORM;
+// if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB)
+// ntype = V_028C70_NUMBER_SRGB;
+// else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_SIGNED) {
+// if (desc->channel[first_non_void].pure_integer) {
+// ntype = V_028C70_NUMBER_SINT;
+// } else if (desc->channel[first_non_void].normalized) {
+// ntype = V_028C70_NUMBER_SNORM;
+// } else
+// ntype = ~0u;
+// } else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_UNSIGNED) {
+// if (desc->channel[first_non_void].pure_integer) {
+// ntype = V_028C70_NUMBER_UINT;
+// } else if (desc->channel[first_non_void].normalized) {
+// ntype = V_028C70_NUMBER_UNORM;
+// } else
+// ntype = ~0u;
+// }
+// }
+// return ntype;
+//}
+
+static bool libresoc_is_sampler_format_supported(VkFormat format, bool *linear_sampling)
+{
+ const struct vk_format_description *desc = vk_format_description(format);
+ uint32_t num_format;
+ if (!desc || format == VK_FORMAT_UNDEFINED)
+ return false;
+
+ //TODO: stub, enables everything
+ return true;
+}
+
+
+static bool libresoc_is_storage_image_format_supported(struct libresoc_physical_device *physical_device,
+ VkFormat format)
+{
+ const struct vk_format_description *desc = vk_format_description(format);
+ unsigned data_format, num_format;
+ if (!desc || format == VK_FORMAT_UNDEFINED)
+ return false;
+ //TODO: stub, enables everything
+ return true;
+}
+
+bool libresoc_is_buffer_format_supported(VkFormat format, bool *scaled)
+{
+ const struct vk_format_description *desc = vk_format_description(format);
+ unsigned data_format, num_format;
+ if (!desc || format == VK_FORMAT_UNDEFINED)
+ return false;
+
+ //TODO: stub, enables everything
+ return true;
+}
+
+bool libresoc_is_colorbuffer_format_supported(VkFormat format, bool *blendable)
+{
+ //TODO: stub, enables everything
+ return true;
+}
+
+static bool libresoc_is_zs_format_supported(VkFormat format)
+{
+ //TODO: stub, enables everything
+ return true;
+}
+
+static bool libresoc_is_filter_minmax_format_supported(VkFormat format)
+{
+ /* From the Vulkan spec 1.1.71:
+ *
+ * "The following formats must support the
+ * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
+ * VK_IMAGE_TILING_OPTIMAL, if they support
+ * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT."
+ */
+ /* TODO: enable more formats. */
+ switch (format) {
+ case VK_FORMAT_R8_UNORM:
+ case VK_FORMAT_R8_SNORM:
+ case VK_FORMAT_R16_UNORM:
+ case VK_FORMAT_R16_SNORM:
+ case VK_FORMAT_R16_SFLOAT:
+ case VK_FORMAT_R32_SFLOAT:
+ case VK_FORMAT_D16_UNORM:
+ case VK_FORMAT_X8_D24_UNORM_PACK32:
+ case VK_FORMAT_D32_SFLOAT:
+ case VK_FORMAT_D16_UNORM_S8_UINT:
+ case VK_FORMAT_D24_UNORM_S8_UINT:
+ case VK_FORMAT_D32_SFLOAT_S8_UINT:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool
+libresoc_device_supports_etc(struct libresoc_physical_device *physical_device)
+{
+ //TODO: stub, enables everything
+ return true;
+}
+
+static void
+libresoc_physical_device_get_format_properties(struct libresoc_physical_device *physical_device,
+ VkFormat format,
+ VkFormatProperties *out_properties)
+{
+ VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0;
+ const struct vk_format_description *desc = vk_format_description(format);
+ bool blendable;
+ bool scaled = false;
+ /* TODO: implement some software emulation of SUBSAMPLED formats. */
+ if (!desc || desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
+ out_properties->linearTilingFeatures = linear;
+ out_properties->optimalTilingFeatures = tiled;
+ out_properties->bufferFeatures = buffer;
+ return;
+ }
+
+ if (desc->layout == VK_FORMAT_LAYOUT_ETC &&
+ !libresoc_device_supports_etc(physical_device)) {
+ out_properties->linearTilingFeatures = linear;
+ out_properties->optimalTilingFeatures = tiled;
+ out_properties->bufferFeatures = buffer;
+ return;
+ }
+
+ if (desc->layout == VK_FORMAT_LAYOUT_MULTIPLANE ||
+ desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
+ uint32_t tiling = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT |
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT |
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT;
+
+ /* The subsampled formats have no support for linear filters. */
+ if (desc->layout != VK_FORMAT_LAYOUT_SUBSAMPLED) {
+ tiling |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
+ }
+
+ /* Fails for unknown reasons with linear tiling & subsampled formats. */
+ out_properties->linearTilingFeatures = desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED ? 0 : tiling;
+ out_properties->optimalTilingFeatures = tiling;
+ out_properties->bufferFeatures = 0;
+ return;
+ }
+
+ if (libresoc_is_storage_image_format_supported(physical_device, format)) {
+ tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+ linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+ }
+
+ if (libresoc_is_buffer_format_supported(format, &scaled)) {
+ buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
+ if (!scaled)
+ buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
+ VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
+ }
+
+ if (vk_format_is_depth_or_stencil(format)) {
+ if (libresoc_is_zs_format_supported(format)) {
+ tiled |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
+ tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT |
+ VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
+
+ if (libresoc_is_filter_minmax_format_supported(format))
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
+
+ /* Don't support blitting surfaces with depth/stencil. */
+ if (vk_format_is_depth(format) && vk_format_is_stencil(format))
+ tiled &= ~VK_FORMAT_FEATURE_BLIT_DST_BIT;
+
+ /* Don't support linear depth surfaces */
+ linear = 0;
+ }
+ } else {
+ bool linear_sampling;
+ if (libresoc_is_sampler_format_supported(format, &linear_sampling)) {
+ linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT;
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT;
+
+ if (libresoc_is_filter_minmax_format_supported(format))
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
+
+ if (linear_sampling) {
+ linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+ tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
+ }
+
+ /* Don't support blitting for R32G32B32 formats. */
+ if (format == VK_FORMAT_R32G32B32_SFLOAT ||
+ format == VK_FORMAT_R32G32B32_UINT ||
+ format == VK_FORMAT_R32G32B32_SINT) {
+ linear &= ~VK_FORMAT_FEATURE_BLIT_SRC_BIT;
+ }
+ }
+ if (libresoc_is_colorbuffer_format_supported(format, &blendable)) {
+ linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ if (blendable) {
+ linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+ tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
+ }
+ }
+ if (tiled && !scaled) {
+ tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
+ }
+
+ /* Tiled formatting does not support NPOT pixel sizes */
+ if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format)))
+ tiled = 0;
+ }
+
+ if (linear && !scaled) {
+ linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT |
+ VK_FORMAT_FEATURE_TRANSFER_DST_BIT;
+ }
+
+ if (format == VK_FORMAT_R32_UINT ||
+ format == VK_FORMAT_R32_SINT ||
+ format == VK_FORMAT_R32_SFLOAT) {
+ buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
+ linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
+ tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
+ }
+
+
+ out_properties->linearTilingFeatures = linear;
+ out_properties->optimalTilingFeatures = tiled;
+ out_properties->bufferFeatures = buffer;
+}
+
+//uint32_t libresoc_translate_colorformat(VkFormat format)
+//{
+// const struct vk_format_description *desc = vk_format_description(format);
+//
+//#define HAS_SIZE(x,y,z,w) \
+// (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
+// desc->channel[2].size == (z) && desc->channel[3].size == (w))
+//
+// if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
+// return V_028C70_COLOR_10_11_11;
+//
+// if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
+// return V_028C70_COLOR_INVALID;
+//
+// /* hw cannot support mixed formats (except depth/stencil, since
+// * stencil is not written to). */
+// if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS)
+// return V_028C70_COLOR_INVALID;
+//
+// switch (desc->nr_channels) {
+// case 1:
+// switch (desc->channel[0].size) {
+// case 8:
+// return V_028C70_COLOR_8;
+// case 16:
+// return V_028C70_COLOR_16;
+// case 32:
+// return V_028C70_COLOR_32;
+// }
+// break;
+// case 2:
+// if (desc->channel[0].size == desc->channel[1].size) {
+// switch (desc->channel[0].size) {
+// case 8:
+// return V_028C70_COLOR_8_8;
+// case 16:
+// return V_028C70_COLOR_16_16;
+// case 32:
+// return V_028C70_COLOR_32_32;
+// }
+// } else if (HAS_SIZE(8,24,0,0)) {
+// return V_028C70_COLOR_24_8;
+// } else if (HAS_SIZE(24,8,0,0)) {
+// return V_028C70_COLOR_8_24;
+// }
+// break;
+// case 3:
+// if (HAS_SIZE(5,6,5,0)) {
+// return V_028C70_COLOR_5_6_5;
+// } else if (HAS_SIZE(32,8,24,0)) {
+// return V_028C70_COLOR_X24_8_32_FLOAT;
+// }
+// break;
+// case 4:
+// if (desc->channel[0].size == desc->channel[1].size &&
+// desc->channel[0].size == desc->channel[2].size &&
+// desc->channel[0].size == desc->channel[3].size) {
+// switch (desc->channel[0].size) {
+// case 4:
+// return V_028C70_COLOR_4_4_4_4;
+// case 8:
+// return V_028C70_COLOR_8_8_8_8;
+// case 16:
+// return V_028C70_COLOR_16_16_16_16;
+// case 32:
+// return V_028C70_COLOR_32_32_32_32;
+// }
+// } else if (HAS_SIZE(5,5,5,1)) {
+// return V_028C70_COLOR_1_5_5_5;
+// } else if (HAS_SIZE(1,5,5,5)) {
+// return V_028C70_COLOR_5_5_5_1;
+// } else if (HAS_SIZE(10,10,10,2)) {
+// return V_028C70_COLOR_2_10_10_10;
+// }
+// break;
+// }
+// return V_028C70_COLOR_INVALID;
+//}
+
+//uint32_t libresoc_colorformat_endian_swap(uint32_t colorformat)
+//{
+// if (0/*SI_BIG_ENDIAN*/) {
+// switch(colorformat) {
+// /* 8-bit buffers. */
+// case V_028C70_COLOR_8:
+// return V_028C70_ENDIAN_NONE;
+//
+// /* 16-bit buffers. */
+// case V_028C70_COLOR_5_6_5:
+// case V_028C70_COLOR_1_5_5_5:
+// case V_028C70_COLOR_4_4_4_4:
+// case V_028C70_COLOR_16:
+// case V_028C70_COLOR_8_8:
+// return V_028C70_ENDIAN_8IN16;
+//
+// /* 32-bit buffers. */
+// case V_028C70_COLOR_8_8_8_8:
+// case V_028C70_COLOR_2_10_10_10:
+// case V_028C70_COLOR_8_24:
+// case V_028C70_COLOR_24_8:
+// case V_028C70_COLOR_16_16:
+// return V_028C70_ENDIAN_8IN32;
+//
+// /* 64-bit buffers. */
+// case V_028C70_COLOR_16_16_16_16:
+// return V_028C70_ENDIAN_8IN16;
+//
+// case V_028C70_COLOR_32_32:
+// return V_028C70_ENDIAN_8IN32;
+//
+// /* 128-bit buffers. */
+// case V_028C70_COLOR_32_32_32_32:
+// return V_028C70_ENDIAN_8IN32;
+// default:
+// return V_028C70_ENDIAN_NONE; /* Unsupported. */
+// }
+// } else {
+// return V_028C70_ENDIAN_NONE;
+// }
+//}
+
+//uint32_t libresoc_translate_dbformat(VkFormat format)
+//{
+// switch (format) {
+// case VK_FORMAT_D16_UNORM:
+// case VK_FORMAT_D16_UNORM_S8_UINT:
+// return V_028040_Z_16;
+// case VK_FORMAT_D32_SFLOAT:
+// case VK_FORMAT_D32_SFLOAT_S8_UINT:
+// return V_028040_Z_32_FLOAT;
+// default:
+// return V_028040_Z_INVALID;
+// }
+//}
+
+//unsigned libresoc_translate_colorswap(VkFormat format, bool do_endian_swap)
+//{
+// const struct vk_format_description *desc = vk_format_description(format);
+//
+//#define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == VK_SWIZZLE_##swz)
+//
+// if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
+// return V_028C70_SWAP_STD;
+//
+// if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
+// return ~0U;
+//
+// switch (desc->nr_channels) {
+// case 1:
+// if (HAS_SWIZZLE(0,X))
+// return V_028C70_SWAP_STD; /* X___ */
+// else if (HAS_SWIZZLE(3,X))
+// return V_028C70_SWAP_ALT_REV; /* ___X */
+// break;
+// case 2:
+// if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) ||
+// (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) ||
+// (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y)))
+// return V_028C70_SWAP_STD; /* XY__ */
+// else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) ||
+// (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) ||
+// (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X)))
+// /* YX__ */
+// return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
+// else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y))
+// return V_028C70_SWAP_ALT; /* X__Y */
+// else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X))
+// return V_028C70_SWAP_ALT_REV; /* Y__X */
+// break;
+// case 3:
+// if (HAS_SWIZZLE(0,X))
+// return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
+// else if (HAS_SWIZZLE(0,Z))
+// return V_028C70_SWAP_STD_REV; /* ZYX */
+// break;
+// case 4:
+// /* check the middle channels, the 1st and 4th channel can be NONE */
+// if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z)) {
+// return V_028C70_SWAP_STD; /* XYZW */
+// } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y)) {
+// return V_028C70_SWAP_STD_REV; /* WZYX */
+// } else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X)) {
+// return V_028C70_SWAP_ALT; /* ZYXW */
+// } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,W)) {
+// /* YZWX */
+// if (desc->is_array)
+// return V_028C70_SWAP_ALT_REV;
+// else
+// return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
+// }
+// break;
+// }
+// return ~0U;
+//}
+
+//bool libresoc_format_pack_clear_color(VkFormat format,
+// uint32_t clear_vals[2],
+// VkClearColorValue *value)
+//{
+// const struct vk_format_description *desc = vk_format_description(format);
+//
+// if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
+// clear_vals[0] = float3_to_r11g11b10f(value->float32);
+// clear_vals[1] = 0;
+// return true;
+// }
+//
+// if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) {
+// fprintf(stderr, "failed to fast clear for non-plain format %d\n", format);
+// return false;
+// }
+//
+// if (!util_is_power_of_two_or_zero(desc->block.bits)) {
+// fprintf(stderr, "failed to fast clear for NPOT format %d\n", format);
+// return false;
+// }
+//
+// if (desc->block.bits > 64) {
+// /*
+// * We have a 128 bits format, check if the first 3 components are the same.
+// * Every elements has to be 32 bits since we don't support 64-bit formats,
+// * and we can skip swizzling checks as alpha always comes last for these and
+// * we do not care about the rest as they have to be the same.
+// */
+// if (desc->channel[0].type == VK_FORMAT_TYPE_FLOAT) {
+// if (value->float32[0] != value->float32[1] ||
+// value->float32[0] != value->float32[2])
+// return false;
+// } else {
+// if (value->uint32[0] != value->uint32[1] ||
+// value->uint32[0] != value->uint32[2])
+// return false;
+// }
+// clear_vals[0] = value->uint32[0];
+// clear_vals[1] = value->uint32[3];
+// return true;
+// }
+// uint64_t clear_val = 0;
+//
+// for (unsigned c = 0; c < 4; ++c) {
+// if (desc->swizzle[c] >= 4)
+// continue;
+//
+// const struct vk_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
+// assert(channel->size);
+//
+// uint64_t v = 0;
+// if (channel->pure_integer) {
+// v = value->uint32[c] & ((1ULL << channel->size) - 1);
+// } else if (channel->normalized) {
+// if (channel->type == VK_FORMAT_TYPE_UNSIGNED &&
+// desc->swizzle[c] < 3 &&
+// desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
+// assert(channel->size == 8);
+//
+// v = util_format_linear_float_to_srgb_8unorm(value->float32[c]);
+// } else {
+// float f = MIN2(value->float32[c], 1.0f);
+//
+// if (channel->type == VK_FORMAT_TYPE_UNSIGNED) {
+// f = MAX2(f, 0.0f) * ((1ULL << channel->size) - 1);
+// } else {
+// f = MAX2(f, -1.0f) * ((1ULL << (channel->size - 1)) - 1);
+// }
+//
+// /* The hardware rounds before conversion. */
+// if (f > 0)
+// f += 0.5f;
+// else
+// f -= 0.5f;
+//
+// v = (uint64_t)f;
+// }
+// } else if (channel->type == VK_FORMAT_TYPE_FLOAT) {
+// if (channel->size == 32) {
+// memcpy(&v, &value->float32[c], 4);
+// } else if(channel->size == 16) {
+// v = util_float_to_half_rtz(value->float32[c]);
+// } else {
+// fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format);
+// return false;
+// }
+// } else {
+// fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n", format);
+// return false;
+// }
+// clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift;
+// }
+//
+// clear_vals[0] = clear_val;
+// clear_vals[1] = clear_val >> 32;
+//
+// return true;
+//}
+
+void libresoc_GetPhysicalDeviceFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties* pFormatProperties)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, physical_device, physicalDevice);
+
+ libresoc_physical_device_get_format_properties(physical_device,
+ format,
+ pFormatProperties);
+}
+
+//void libresoc_GetPhysicalDeviceFormatProperties2(
+// VkPhysicalDevice physicalDevice,
+// VkFormat format,
+// VkFormatProperties2* pFormatProperties)
+//{
+// LIBRESOC_FROM_HANDLE(libresoc_physical_device, physical_device, physicalDevice);
+//
+// libresoc_physical_device_get_format_properties(physical_device,
+// format,
+// &pFormatProperties->formatProperties);
+//}
+
+static VkResult libresoc_get_image_format_properties(struct libresoc_physical_device *physical_device,
+ const VkPhysicalDeviceImageFormatInfo2 *info,
+ VkFormat format,
+ VkImageFormatProperties *pImageFormatProperties)
+
+{
+ VkFormatProperties format_props;
+ VkFormatFeatureFlags format_feature_flags;
+ VkExtent3D maxExtent;
+ uint32_t maxMipLevels;
+ uint32_t maxArraySize;
+ VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
+ const struct vk_format_description *desc = vk_format_description(format);
+
+ libresoc_physical_device_get_format_properties(physical_device, format,
+ &format_props);
+ if (info->tiling == VK_IMAGE_TILING_LINEAR) {
+ format_feature_flags = format_props.linearTilingFeatures;
+ } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
+ format_feature_flags = format_props.optimalTilingFeatures;
+ } else {
+ unreachable("bad VkImageTiling");
+ }
+
+ if (format_feature_flags == 0)
+ goto unsupported;
+
+ if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format))
+ goto unsupported;
+
+ switch (info->type) {
+ default:
+ unreachable("bad vkimage type\n");
+ case VK_IMAGE_TYPE_1D:
+ maxExtent.width = 16384;
+ maxExtent.height = 1;
+ maxExtent.depth = 1;
+ maxMipLevels = 15; /* log2(maxWidth) + 1 */
+ maxArraySize = 2048;
+ break;
+ case VK_IMAGE_TYPE_2D:
+ maxExtent.width = 16384;
+ maxExtent.height = 16384;
+ maxExtent.depth = 1;
+ maxMipLevels = 15; /* log2(maxWidth) + 1 */
+ maxArraySize = 2048;
+ break;
+ case VK_IMAGE_TYPE_3D:
+ maxExtent.width = 2048;
+ maxExtent.height = 2048;
+ maxExtent.depth = 2048;
+ maxMipLevels = util_logbase2(maxExtent.width) + 1;
+ maxArraySize = 1;
+ break;
+ }
+
+ if (desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
+ /* Might be able to support but the entire format support is
+ * messy, so taking the lazy way out. */
+ maxArraySize = 1;
+ }
+
+ if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
+ info->type == VK_IMAGE_TYPE_2D &&
+ (format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
+ !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)) {
+ sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
+ }
+
+ if (info->tiling == VK_IMAGE_TILING_LINEAR &&
+ (format == VK_FORMAT_R32G32B32_SFLOAT ||
+ format == VK_FORMAT_R32G32B32_SINT ||
+ format == VK_FORMAT_R32G32B32_UINT)) {
+ /* R32G32B32 is a weird format and the driver currently only
+ * supports the barely minimum.
+ * TODO: Implement more if we really need to.
+ */
+ maxArraySize = 1;
+ maxMipLevels = 1;
+ }
+
+
+
+ *pImageFormatProperties = (VkImageFormatProperties) {
+ .maxExtent = maxExtent,
+ .maxMipLevels = maxMipLevels,
+ .maxArrayLayers = maxArraySize,
+ .sampleCounts = sampleCounts,
+
+ /* FINISHME: Accurately calculate
+ * VkImageFormatProperties::maxResourceSize.
+ */
+ .maxResourceSize = UINT32_MAX,
+ };
+
+ return VK_SUCCESS;
+//TODO: for now we support everything
+unsupported:
+ *pImageFormatProperties = (VkImageFormatProperties) {
+ .maxExtent = { 0, 0, 0 },
+ .maxMipLevels = 0,
+ .maxArrayLayers = 0,
+ .sampleCounts = 0,
+ .maxResourceSize = 0,
+ };
+
+ return VK_ERROR_FORMAT_NOT_SUPPORTED;
+}
+
+VkResult libresoc_GetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags createFlags,
+ VkImageFormatProperties* pImageFormatProperties)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, physical_device, physicalDevice);
+
+ const VkPhysicalDeviceImageFormatInfo2 info = {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
+ .pNext = NULL,
+ .format = format,
+ .type = type,
+ .tiling = tiling,
+ .usage = usage,
+ .flags = createFlags,
+ };
+
+ return libresoc_get_image_format_properties(physical_device, &info, format,
+ pImageFormatProperties);
+}
+
+static void
+get_external_image_format_properties(struct libresoc_physical_device *physical_device,
+ const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
+ VkExternalMemoryHandleTypeFlagBits handleType,
+ VkExternalMemoryProperties *external_properties,
+ VkImageFormatProperties *format_properties)
+{
+ VkExternalMemoryFeatureFlagBits flags = 0;
+ VkExternalMemoryHandleTypeFlags export_flags = 0;
+ VkExternalMemoryHandleTypeFlags compat_flags = 0;
+
+ if (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
+ return;
+
+ switch (handleType) {
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
+ switch (pImageFormatInfo->type) {
+ case VK_IMAGE_TYPE_2D:
+ flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+ if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
+ flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
+
+ compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+ VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+ break;
+ default:
+ break;
+ }
+ break;
+ case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
+ flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+ compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
+ break;
+ default:
+ break;
+ }
+
+ *external_properties = (VkExternalMemoryProperties) {
+ .externalMemoryFeatures = flags,
+ .exportFromImportedHandleTypes = export_flags,
+ .compatibleHandleTypes = compat_flags,
+ };
+}
+
+//VkResult libresoc_GetPhysicalDeviceImageFormatProperties2(
+// VkPhysicalDevice physicalDevice,
+// const VkPhysicalDeviceImageFormatInfo2 *base_info,
+// VkImageFormatProperties2 *base_props)
+//{
+// LIBRESOC_FROM_HANDLE(libresoc_physical_device, physical_device, physicalDevice);
+// const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
+// VkExternalImageFormatProperties *external_props = NULL;
+// struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
+// VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
+// VkTextureLODGatherFormatPropertiesAMD *texture_lod_props = NULL;
+// VkResult result;
+// VkFormat format = libresoc_select_android_external_format(base_info->pNext, base_info->format);
+//
+// result = libresoc_get_image_format_properties(physical_device, base_info, format,
+// &base_props->imageFormatProperties);
+// if (result != VK_SUCCESS)
+// return result;
+//
+// /* Extract input structs */
+// vk_foreach_struct_const(s, base_info->pNext) {
+// switch (s->sType) {
+// case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
+// external_info = (const void *) s;
+// break;
+// default:
+// break;
+// }
+// }
+//
+// /* Extract output structs */
+// vk_foreach_struct(s, base_props->pNext) {
+// switch (s->sType) {
+// case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
+// external_props = (void *) s;
+// break;
+// case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
+// ycbcr_props = (void *) s;
+// break;
+// case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID:
+// android_usage = (void *) s;
+// break;
+// case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD:
+// texture_lod_props = (void *) s;
+// break;
+// default:
+// break;
+// }
+// }
+//
+// bool ahb_supported = physical_device->supported_extensions.ANDROID_external_memory_android_hardware_buffer;
+// if (android_usage && ahb_supported) {
+//#if LIBRESOC_SUPPORT_ANDROID_HARDWARE_BUFFER
+// android_usage->androidHardwareBufferUsage =
+// libresoc_ahb_usage_from_vk_usage(base_info->flags,
+// base_info->usage);
+//#endif
+// }
+//
+// /* From the Vulkan 1.0.97 spec:
+// *
+// * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
+// * behave as if VkPhysicalDeviceExternalImageFormatInfo was not
+// * present and VkExternalImageFormatProperties will be ignored.
+// */
+// if (external_info && external_info->handleType != 0) {
+// get_external_image_format_properties(physical_device, base_info, external_info->handleType,
+// &external_props->externalMemoryProperties,
+// &base_props->imageFormatProperties);
+// if (!external_props->externalMemoryProperties.externalMemoryFeatures) {
+// /* From the Vulkan 1.0.97 spec:
+// *
+// * If handleType is not compatible with the [parameters] specified
+// * in VkPhysicalDeviceImageFormatInfo2, then
+// * vkGetPhysicalDeviceImageFormatProperties2 returns
+// * VK_ERROR_FORMAT_NOT_SUPPORTED.
+// */
+// result = vk_errorf(physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
+// "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
+// external_info->handleType);
+// goto fail;
+// }
+// }
+//
+// if (ycbcr_props) {
+// ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
+// }
+//
+// if (texture_lod_props) {
+// if (physical_device->rad_info.chip_class >= GFX9) {
+// texture_lod_props->supportsTextureGatherLODBiasAMD = true;
+// } else {
+// texture_lod_props->supportsTextureGatherLODBiasAMD = !vk_format_is_int(format);
+// }
+// }
+//
+// return VK_SUCCESS;
+//
+//fail:
+// if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
+// /* From the Vulkan 1.0.97 spec:
+// *
+// * If the combination of parameters to
+// * vkGetPhysicalDeviceImageFormatProperties2 is not supported by
+// * the implementation for use in vkCreateImage, then all members of
+// * imageFormatProperties will be filled with zero.
+// */
+// base_props->imageFormatProperties = (VkImageFormatProperties) {0};
+// }
+//
+// return result;
+//}
+
+void libresoc_GetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ uint32_t samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t* pNumProperties,
+ VkSparseImageFormatProperties* pProperties)
+{
+ /* Sparse images are not yet supported. */
+ *pNumProperties = 0;
+}
+
+//void libresoc_GetPhysicalDeviceSparseImageFormatProperties2(
+// VkPhysicalDevice physicalDevice,
+// const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
+// uint32_t *pPropertyCount,
+// VkSparseImageFormatProperties2 *pProperties)
+//{
+// /* Sparse images are not yet supported. */
+// *pPropertyCount = 0;
+//}
+
+
+//void libresoc_GetPhysicalDeviceExternalBufferProperties(
+// VkPhysicalDevice physicalDevice,
+// const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
+// VkExternalBufferProperties *pExternalBufferProperties)
+//{
+// VkExternalMemoryFeatureFlagBits flags = 0;
+// VkExternalMemoryHandleTypeFlags export_flags = 0;
+// VkExternalMemoryHandleTypeFlags compat_flags = 0;
+// switch(pExternalBufferInfo->handleType) {
+// case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
+// case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
+// flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT |
+// VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+// compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
+// VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+// break;
+// case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
+// flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
+// compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
+// break;
+// default:
+// break;
+// }
+// pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties) {
+// .externalMemoryFeatures = flags,
+// .exportFromImportedHandleTypes = export_flags,
+// .compatibleHandleTypes = compat_flags,
+// };
+//}
+
--- /dev/null
+
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "vk_util.h"
+#include "libresoc_private.h"
+
+
+VkResult
+libresoc_image_create(VkDevice _device,
+ const struct libresoc_image_create_info *create_info,
+ const VkAllocationCallbacks* alloc,
+ VkImage *pImage)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
+ struct libresoc_image *image = NULL;
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
+
+ // const unsigned plane_count = vk_format_get_plane_count(format);
+ // const size_t image_struct_size = sizeof(*image) + sizeof(struct libresoc_image_plane) * plane_count;
+
+ const size_t image_struct_size = sizeof(*image);
+ // libresoc_assert(pCreateInfo->mipLevels > 0);
+ // libresoc_assert(pCreateInfo->arrayLayers > 0);
+ // libresoc_assert(pCreateInfo->samples > 0);
+ // libresoc_assert(pCreateInfo->extent.width > 0);
+ // libresoc_assert(pCreateInfo->extent.height > 0);
+ // libresoc_assert(pCreateInfo->extent.depth > 0);
+
+ image = vk_zalloc2(&device->vk.alloc, alloc, image_struct_size, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (!image)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);
+
+ image->type = pCreateInfo->imageType;
+ // image->info.width = pCreateInfo->extent.width;
+ // image->info.height = pCreateInfo->extent.height;
+ // image->info.depth = pCreateInfo->extent.depth;
+ // image->info.samples = pCreateInfo->samples;
+ // image->info.storage_samples = pCreateInfo->samples;
+ // image->info.array_size = pCreateInfo->arrayLayers;
+ // image->info.levels = pCreateInfo->mipLevels;
+ // image->info.num_channels = vk_format_get_nr_components(format);
+
+ //image->vk_format = format;
+ image->tiling = pCreateInfo->tiling;
+ image->usage = pCreateInfo->usage;
+ image->flags = pCreateInfo->flags;
+ //image->plane_count = plane_count;
+
+ image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
+ // if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
+ // for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
+ // if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL ||
+ // pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT)
+ // image->queue_family_mask |= (1u << LIBRESOC_MAX_QUEUE_FAMILIES) - 1u;
+ // else
+ // image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i];
+ // }
+
+ // const VkExternalMemoryImageCreateInfo *external_info =
+ // vk_find_struct_const(pCreateInfo->pNext,
+ // EXTERNAL_MEMORY_IMAGE_CREATE_INFO) ;
+
+ // image->shareable = external_info;
+ // if (!vk_format_is_depth_or_stencil(format) && !image->shareable) {
+ // image->info.surf_index = &device->image_mrt_offset_counter;
+ // }
+
+ // for (unsigned plane = 0; plane < image->plane_count; ++plane) {
+ // image->planes[plane].surface.flags =
+ // libresoc_get_surface_flags(device, image, plane, pCreateInfo, format);
+ // }
+
+ // bool delay_layout = external_info &&
+ // (external_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
+
+ // if (delay_layout) {
+ // *pImage = libresoc_image_to_handle(image);
+ // assert (!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT));
+ // return VK_SUCCESS;
+ // }
+
+ // ASSERTED VkResult result = libresoc_image_create_layout(device, *create_info, image);
+ // assert(result == VK_SUCCESS);
+
+ // if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
+ // image->alignment = MAX2(image->alignment, 4096);
+ // image->size = align64(image->size, image->alignment);
+ // image->offset = 0;
+
+ // image->bo = device->ws->buffer_create(device->ws, image->size, image->alignment,
+ // 0, RADEON_FLAG_VIRTUAL, LIBRESOC_BO_PRIORITY_VIRTUAL);
+ // if (!image->bo) {
+ // libresoc_destroy_image(device, alloc, image);
+ // return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+ // }
+ // }
+
+ *pImage = libresoc_image_to_handle(image);
+
+ return VK_SUCCESS;
+}
+
+
+VkResult
+libresoc_CreateImage(VkDevice device,
+ const VkImageCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkImage *pImage)
+{
+
+ const struct wsi_image_create_info *wsi_info =
+ vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
+ bool scanout = wsi_info && wsi_info->scanout;
+
+ return libresoc_image_create(device,
+ &(struct libresoc_image_create_info) {
+ .vk_info = pCreateInfo,
+ .scanout = scanout,
+ },
+ pAllocator,
+ pImage);
+}
+void libresoc_GetImageSubresourceLayout(
+ VkDevice _device,
+ VkImage _image,
+ const VkImageSubresource* pSubresource,
+ VkSubresourceLayout* pLayout)
+{
+//TODO: stub
+}
--- /dev/null
+
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "libresoc_private.h"
+
+void libresoc_CmdClearColorImage(
+ VkCommandBuffer commandBuffer,
+ VkImage image_h,
+ VkImageLayout imageLayout,
+ const VkClearColorValue* pColor,
+ uint32_t rangeCount,
+ const VkImageSubresourceRange* pRanges)
+{
+//TODO: stub
+}
--- /dev/null
+/*
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "util/mesa-sha1.h"
+#include "util/debug.h"
+#include "util/disk_cache.h"
+#include "util/u_atomic.h"
+#include "libresoc_debug.h"
+#include "libresoc_private.h"
+//#include "libresoc_shader.h"
+#include "vulkan/util/vk_util.h"
+
+//#include "ac_nir_to_llvm.h"
+
+struct cache_entry {
+ union {
+ unsigned char sha1[20];
+ uint32_t sha1_dw[5];
+ };
+ uint32_t binary_sizes[MESA_SHADER_STAGES];
+ struct libresoc_shader_variant *variants[MESA_SHADER_STAGES];
+ char code[0];
+};
+
+static void
+libresoc_pipeline_cache_lock(struct libresoc_pipeline_cache *cache)
+{
+ if (cache->flags & VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT)
+ return;
+
+ pthread_mutex_lock(&cache->mutex);
+}
+
+static void
+libresoc_pipeline_cache_unlock(struct libresoc_pipeline_cache *cache)
+{
+ if (cache->flags & VK_PIPELINE_CACHE_CREATE_EXTERNALLY_SYNCHRONIZED_BIT_EXT)
+ return;
+
+ pthread_mutex_unlock(&cache->mutex);
+}
+
+void
+libresoc_pipeline_cache_init(struct libresoc_pipeline_cache *cache,
+ struct libresoc_device *device)
+{
+ cache->device = device;
+ pthread_mutex_init(&cache->mutex, NULL);
+ cache->flags = 0;
+
+ cache->modified = false;
+ cache->kernel_count = 0;
+ cache->total_size = 0;
+ cache->table_size = 1024;
+ const size_t byte_size = cache->table_size * sizeof(cache->hash_table[0]);
+ cache->hash_table = malloc(byte_size);
+
+ /* We don't consider allocation failure fatal, we just start with a 0-sized
+ * cache. Disable caching when we want to keep shader debug info, since
+ * we don't get the debug info on cached shaders. */
+ if (cache->hash_table == NULL ||
+ (device->instance->debug_flags & LIBRESOC_DEBUG_NO_CACHE))
+ cache->table_size = 0;
+ else
+ memset(cache->hash_table, 0, byte_size);
+}
+
+void
+libresoc_pipeline_cache_finish(struct libresoc_pipeline_cache *cache)
+{
+ for (unsigned i = 0; i < cache->table_size; ++i)
+ if (cache->hash_table[i]) {
+ for(int j = 0; j < MESA_SHADER_STAGES; ++j) {
+ // TODO: uncomment following lines
+ //if (cache->hash_table[i]->variants[j])
+ // libresoc_shader_variant_destroy(cache->device,
+ // cache->hash_table[i]->variants[j]);
+ }
+ vk_free(&cache->alloc, cache->hash_table[i]);
+ }
+ pthread_mutex_destroy(&cache->mutex);
+ free(cache->hash_table);
+}
+
+static uint32_t
+entry_size(struct cache_entry *entry)
+{
+ size_t ret = sizeof(*entry);
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i)
+ if (entry->binary_sizes[i])
+ ret += entry->binary_sizes[i];
+ return ret;
+}
+
+/*
+void
+libresoc_hash_shaders(unsigned char *hash,
+ const VkPipelineShaderStageCreateInfo **stages,
+ const struct libresoc_pipeline_layout *layout,
+ const struct libresoc_pipeline_key *key,
+ uint32_t flags)
+{
+ struct mesa_sha1 ctx;
+
+ _mesa_sha1_init(&ctx);
+ if (key)
+ _mesa_sha1_update(&ctx, key, sizeof(*key));
+ if (layout)
+ _mesa_sha1_update(&ctx, layout->sha1, sizeof(layout->sha1));
+
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
+ if (stages[i]) {
+ LIBRESOC_FROM_HANDLE(libresoc_shader_module, module, stages[i]->module);
+ const VkSpecializationInfo *spec_info = stages[i]->pSpecializationInfo;
+
+ _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+ _mesa_sha1_update(&ctx, stages[i]->pName, strlen(stages[i]->pName));
+ if (spec_info) {
+ _mesa_sha1_update(&ctx, spec_info->pMapEntries,
+ spec_info->mapEntryCount * sizeof spec_info->pMapEntries[0]);
+ _mesa_sha1_update(&ctx, spec_info->pData, spec_info->dataSize);
+ }
+ }
+ }
+ _mesa_sha1_update(&ctx, &flags, 4);
+ _mesa_sha1_final(&ctx, hash);
+}*/
+
+
+static struct cache_entry *
+libresoc_pipeline_cache_search_unlocked(struct libresoc_pipeline_cache *cache,
+ const unsigned char *sha1)
+{
+ const uint32_t mask = cache->table_size - 1;
+ const uint32_t start = (*(uint32_t *) sha1);
+
+ if (cache->table_size == 0)
+ return NULL;
+
+ for (uint32_t i = 0; i < cache->table_size; i++) {
+ const uint32_t index = (start + i) & mask;
+ struct cache_entry *entry = cache->hash_table[index];
+
+ if (!entry)
+ return NULL;
+
+ if (memcmp(entry->sha1, sha1, sizeof(entry->sha1)) == 0) {
+ return entry;
+ }
+ }
+
+ unreachable("hash table should never be full");
+}
+
+static struct cache_entry *
+libresoc_pipeline_cache_search(struct libresoc_pipeline_cache *cache,
+ const unsigned char *sha1)
+{
+ struct cache_entry *entry;
+
+ libresoc_pipeline_cache_lock(cache);
+
+ entry = libresoc_pipeline_cache_search_unlocked(cache, sha1);
+
+ libresoc_pipeline_cache_unlock(cache);
+
+ return entry;
+}
+
+static void
+libresoc_pipeline_cache_set_entry(struct libresoc_pipeline_cache *cache,
+ struct cache_entry *entry)
+{
+ const uint32_t mask = cache->table_size - 1;
+ const uint32_t start = entry->sha1_dw[0];
+
+ /* We'll always be able to insert when we get here. */
+ assert(cache->kernel_count < cache->table_size / 2);
+
+ for (uint32_t i = 0; i < cache->table_size; i++) {
+ const uint32_t index = (start + i) & mask;
+ if (!cache->hash_table[index]) {
+ cache->hash_table[index] = entry;
+ break;
+ }
+ }
+
+ cache->total_size += entry_size(entry);
+ cache->kernel_count++;
+}
+
+
+static VkResult
+libresoc_pipeline_cache_grow(struct libresoc_pipeline_cache *cache)
+{
+ const uint32_t table_size = cache->table_size * 2;
+ const uint32_t old_table_size = cache->table_size;
+ const size_t byte_size = table_size * sizeof(cache->hash_table[0]);
+ struct cache_entry **table;
+ struct cache_entry **old_table = cache->hash_table;
+
+ table = malloc(byte_size);
+ if (table == NULL)
+ return vk_error(cache->device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ cache->hash_table = table;
+ cache->table_size = table_size;
+ cache->kernel_count = 0;
+ cache->total_size = 0;
+
+ memset(cache->hash_table, 0, byte_size);
+ for (uint32_t i = 0; i < old_table_size; i++) {
+ struct cache_entry *entry = old_table[i];
+ if (!entry)
+ continue;
+
+ libresoc_pipeline_cache_set_entry(cache, entry);
+ }
+
+ free(old_table);
+
+ return VK_SUCCESS;
+}
+
+static void
+libresoc_pipeline_cache_add_entry(struct libresoc_pipeline_cache *cache,
+ struct cache_entry *entry)
+{
+ if (cache->kernel_count == cache->table_size / 2)
+ libresoc_pipeline_cache_grow(cache);
+
+ /* Failing to grow that hash table isn't fatal, but may mean we don't
+ * have enough space to add this new kernel. Only add it if there's room.
+ */
+ if (cache->kernel_count < cache->table_size / 2)
+ libresoc_pipeline_cache_set_entry(cache, entry);
+}
+
+static bool
+libresoc_is_cache_disabled(struct libresoc_device *device)
+{
+ /* Pipeline caches can be disabled with LIBRESOC_DEBUG=nocache, with
+ * MESA_GLSL_CACHE_DISABLE=1, and when VK_AMD_shader_info is requested.
+ */
+ return (device->instance->debug_flags & LIBRESOC_DEBUG_NO_CACHE);
+}
+
+/*
+bool
+libresoc_create_shader_variants_from_pipeline_cache(struct libresoc_device *device,
+ struct libresoc_pipeline_cache *cache,
+ const unsigned char *sha1,
+ struct libresoc_shader_variant **variants,
+ bool *found_in_application_cache)
+{
+ struct cache_entry *entry;
+
+ if (!cache) {
+ cache = device->mem_cache;
+ *found_in_application_cache = false;
+ }
+
+ libresoc_pipeline_cache_lock(cache);
+
+ entry = libresoc_pipeline_cache_search_unlocked(cache, sha1);
+
+ if (!entry) {
+ *found_in_application_cache = false;
+
+*/ /* Don't cache when we want debug info, since this isn't
+ * present in the cache.
+ */
+/* if (libresoc_is_cache_disabled(device) || !device->physical_device->disk_cache) {
+ libresoc_pipeline_cache_unlock(cache);
+ return false;
+ }
+
+ uint8_t disk_sha1[20];
+ disk_cache_compute_key(device->physical_device->disk_cache,
+ sha1, 20, disk_sha1);
+
+ entry = (struct cache_entry *)
+ disk_cache_get(device->physical_device->disk_cache,
+ disk_sha1, NULL);
+ if (!entry) {
+ libresoc_pipeline_cache_unlock(cache);
+ return false;
+ } else {
+ size_t size = entry_size(entry);
+ struct cache_entry *new_entry = vk_alloc(&cache->alloc, size, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_CACHE);
+ if (!new_entry) {
+ free(entry);
+ libresoc_pipeline_cache_unlock(cache);
+ return false;
+ }
+
+ memcpy(new_entry, entry, entry_size(entry));
+ free(entry);
+ entry = new_entry;
+
+ if (!(device->instance->debug_flags & LIBRESOC_DEBUG_NO_MEMORY_CACHE) ||
+ cache != device->mem_cache)
+ libresoc_pipeline_cache_add_entry(cache, new_entry);
+ }
+ }
+
+ char *p = entry->code;
+ for(int i = 0; i < MESA_SHADER_STAGES; ++i) {
+ if (!entry->variants[i] && entry->binary_sizes[i]) {
+ struct libresoc_shader_binary *binary = calloc(1, entry->binary_sizes[i]);
+ memcpy(binary, p, entry->binary_sizes[i]);
+ p += entry->binary_sizes[i];
+
+ entry->variants[i] = libresoc_shader_variant_create(device, binary, false);
+ free(binary);
+ } else if (entry->binary_sizes[i]) {
+ p += entry->binary_sizes[i];
+ }
+
+ }
+
+ memcpy(variants, entry->variants, sizeof(entry->variants));
+
+ if (device->instance->debug_flags & LIBRESOC_DEBUG_NO_MEMORY_CACHE &&
+ cache == device->mem_cache)
+ vk_free(&cache->alloc, entry);
+ else {
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i)
+ if (entry->variants[i])
+ p_atomic_inc(&entry->variants[i]->ref_count);
+ }
+
+ libresoc_pipeline_cache_unlock(cache);
+ return true;
+}*/
+
+/*
+void
+libresoc_pipeline_cache_insert_shaders(struct libresoc_device *device,
+ struct libresoc_pipeline_cache *cache,
+ const unsigned char *sha1,
+ struct libresoc_shader_variant **variants,
+ struct libresoc_shader_binary *const *binaries)
+{
+ if (!cache)
+ cache = device->mem_cache;
+
+ libresoc_pipeline_cache_lock(cache);
+ struct cache_entry *entry = libresoc_pipeline_cache_search_unlocked(cache, sha1);
+ if (entry) {
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
+ if (entry->variants[i]) {
+ libresoc_shader_variant_destroy(cache->device, variants[i]);
+ variants[i] = entry->variants[i];
+ } else {
+ entry->variants[i] = variants[i];
+ }
+ if (variants[i])
+ p_atomic_inc(&variants[i]->ref_count);
+ }
+ libresoc_pipeline_cache_unlock(cache);
+ return;
+ }
+
+*/ /* Don't cache when we want debug info, since this isn't
+ * present in the cache.
+ */
+/* if (libresoc_is_cache_disabled(device)) {
+ libresoc_pipeline_cache_unlock(cache);
+ return;
+ }
+
+ size_t size = sizeof(*entry);
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i)
+ if (variants[i])
+ size += binaries[i]->total_size;
+
+
+ entry = vk_alloc(&cache->alloc, size, 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_CACHE);
+ if (!entry) {
+ libresoc_pipeline_cache_unlock(cache);
+ return;
+ }
+
+ memset(entry, 0, sizeof(*entry));
+ memcpy(entry->sha1, sha1, 20);
+
+ char* p = entry->code;
+
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
+ if (!variants[i])
+ continue;
+
+ entry->binary_sizes[i] = binaries[i]->total_size;
+
+ memcpy(p, binaries[i], binaries[i]->total_size);
+ p += binaries[i]->total_size;
+ }
+
+*/ /* Always add cache items to disk. This will allow collection of
+ * compiled shaders by third parties such as steam, even if the app
+ * implements its own pipeline cache.
+ */
+/* if (device->physical_device->disk_cache) {
+ uint8_t disk_sha1[20];
+ disk_cache_compute_key(device->physical_device->disk_cache, sha1, 20,
+ disk_sha1);
+
+ disk_cache_put(device->physical_device->disk_cache, disk_sha1,
+ entry, entry_size(entry), NULL);
+ }
+
+ if (device->instance->debug_flags & LIBRESOC_DEBUG_NO_MEMORY_CACHE &&
+ cache == device->mem_cache) {
+ vk_free2(&cache->alloc, NULL, entry);
+ libresoc_pipeline_cache_unlock(cache);
+ return;
+ }
+
+*/ /* We delay setting the variant so we have reproducible disk cache
+ * items.
+ */
+/* for (int i = 0; i < MESA_SHADER_STAGES; ++i) {
+ if (!variants[i])
+ continue;
+
+ entry->variants[i] = variants[i];
+ p_atomic_inc(&variants[i]->ref_count);
+ }
+
+ libresoc_pipeline_cache_add_entry(cache, entry);
+
+ cache->modified = true;
+ libresoc_pipeline_cache_unlock(cache);
+ return;
+}*/
+
+bool
+libresoc_pipeline_cache_load(struct libresoc_pipeline_cache *cache,
+ const void *data, size_t size)
+{
+ struct libresoc_device *device = cache->device;
+ struct vk_pipeline_cache_header header;
+
+ if (size < sizeof(header))
+ return false;
+ memcpy(&header, data, sizeof(header));
+ if (header.header_size < sizeof(header))
+ return false;
+ if (header.header_version != VK_PIPELINE_CACHE_HEADER_VERSION_ONE)
+ return false;
+ if (header.vendor_id != 1) //TODO: just dummy value
+ return false;
+ if (header.device_id != 1) //TODO: just dummy value
+ return false;
+ if (memcmp(header.uuid, device->physical_device->cache_uuid, VK_UUID_SIZE) != 0)
+ return false;
+
+ char *end = (void *) data + size;
+ char *p = (void *) data + header.header_size;
+
+ while (end - p >= sizeof(struct cache_entry)) {
+ struct cache_entry *entry = (struct cache_entry*)p;
+ struct cache_entry *dest_entry;
+ size_t size = entry_size(entry);
+ if(end - p < size)
+ break;
+
+ dest_entry = vk_alloc(&cache->alloc, size,
+ 8, VK_SYSTEM_ALLOCATION_SCOPE_CACHE);
+ if (dest_entry) {
+ memcpy(dest_entry, entry, size);
+ for (int i = 0; i < MESA_SHADER_STAGES; ++i)
+ dest_entry->variants[i] = NULL;
+ libresoc_pipeline_cache_add_entry(cache, dest_entry);
+ }
+ p += size;
+ }
+
+ return true;
+}
+
+VkResult libresoc_CreatePipelineCache(
+ VkDevice _device,
+ const VkPipelineCacheCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkPipelineCache* pPipelineCache)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ struct libresoc_pipeline_cache *cache;
+
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO);
+ assert(pCreateInfo->flags == 0);
+
+ cache = vk_alloc2(&device->vk.alloc, pAllocator,
+ sizeof(*cache), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ if (cache == NULL)
+ return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ vk_object_base_init(&device->vk, &cache->base,
+ VK_OBJECT_TYPE_PIPELINE_CACHE);
+
+ if (pAllocator)
+ cache->alloc = *pAllocator;
+ else
+ cache->alloc = device->vk.alloc;
+
+ libresoc_pipeline_cache_init(cache, device);
+ cache->flags = pCreateInfo->flags;
+
+ /*if (pCreateInfo->initialDataSize > 0) {
+ libresoc_pipeline_cache_load(cache,
+ pCreateInfo->pInitialData,
+ pCreateInfo->initialDataSize);
+ }*/
+
+ *pPipelineCache = libresoc_pipeline_cache_to_handle(cache);
+
+ return VK_SUCCESS;
+}
+
+void libresoc_DestroyPipelineCache(
+ VkDevice _device,
+ VkPipelineCache _cache,
+ const VkAllocationCallbacks* pAllocator)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_pipeline_cache, cache, _cache);
+
+ if (!cache)
+ return;
+ libresoc_pipeline_cache_finish(cache);
+
+ vk_object_base_finish(&cache->base);
+ vk_free2(&device->vk.alloc, pAllocator, cache);
+}
+
+VkResult libresoc_GetPipelineCacheData(
+ VkDevice _device,
+ VkPipelineCache _cache,
+ size_t* pDataSize,
+ void* pData)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ LIBRESOC_FROM_HANDLE(libresoc_pipeline_cache, cache, _cache);
+ struct vk_pipeline_cache_header *header;
+ VkResult result = VK_SUCCESS;
+
+ libresoc_pipeline_cache_lock(cache);
+
+ const size_t size = sizeof(*header) + cache->total_size;
+ if (pData == NULL) {
+ libresoc_pipeline_cache_unlock(cache);
+ *pDataSize = size;
+ return VK_SUCCESS;
+ }
+ if (*pDataSize < sizeof(*header)) {
+ libresoc_pipeline_cache_unlock(cache);
+ *pDataSize = 0;
+ return VK_INCOMPLETE;
+ }
+ void *p = pData, *end = pData + *pDataSize;
+ header = p;
+ header->header_size = sizeof(*header);
+ header->header_version = VK_PIPELINE_CACHE_HEADER_VERSION_ONE;
+ header->vendor_id = 1; //TODO: some dummy value
+ header->device_id = 1; //TODO: some dummy value
+ memcpy(header->uuid, device->physical_device->cache_uuid, VK_UUID_SIZE);
+ p += header->header_size;
+
+ struct cache_entry *entry;
+ for (uint32_t i = 0; i < cache->table_size; i++) {
+ if (!cache->hash_table[i])
+ continue;
+ entry = cache->hash_table[i];
+ const uint32_t size = entry_size(entry);
+ if (end < p + size) {
+ result = VK_INCOMPLETE;
+ break;
+ }
+
+ memcpy(p, entry, size);
+ for(int j = 0; j < MESA_SHADER_STAGES; ++j)
+ ((struct cache_entry*)p)->variants[j] = NULL;
+ p += size;
+ }
+ *pDataSize = p - pData;
+
+ libresoc_pipeline_cache_unlock(cache);
+ return result;
+}
+
+static void
+libresoc_pipeline_cache_merge(struct libresoc_pipeline_cache *dst,
+ struct libresoc_pipeline_cache *src)
+{
+ for (uint32_t i = 0; i < src->table_size; i++) {
+ struct cache_entry *entry = src->hash_table[i];
+ if (!entry || libresoc_pipeline_cache_search(dst, entry->sha1))
+ continue;
+
+ libresoc_pipeline_cache_add_entry(dst, entry);
+
+ src->hash_table[i] = NULL;
+ }
+}
+
+VkResult libresoc_MergePipelineCaches(
+ VkDevice _device,
+ VkPipelineCache destCache,
+ uint32_t srcCacheCount,
+ const VkPipelineCache* pSrcCaches)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_pipeline_cache, dst, destCache);
+
+ for (uint32_t i = 0; i < srcCacheCount; i++) {
+ LIBRESOC_FROM_HANDLE(libresoc_pipeline_cache, src, pSrcCaches[i]);
+
+ libresoc_pipeline_cache_merge(dst, src);
+ }
+
+ return VK_SUCCESS;
+}
#include "libresoc_constants.h"
#include "libresoc_debug.h"
+#include "wsi_common.h"
#define LIBRESOC_MAX_QUEUE_FAMILIES 1
+
+static inline uint32_t
+align_u32(uint32_t v, uint32_t a)
+{
+ assert(a != 0 && a == (a & -a));
+ return (v + a - 1) & ~(a - 1);
+}
+
+static inline uint32_t
+align_u32_npot(uint32_t v, uint32_t a)
+{
+ return (v + a - 1) / a * a;
+}
+
+static inline uint64_t
+align_u64(uint64_t v, uint64_t a)
+{
+ assert(a != 0 && a == (a & -a));
+ return (v + a - 1) & ~(a - 1);
+}
+
+static inline int32_t
+align_i32(int32_t v, int32_t a)
+{
+ assert(a != 0 && a == (a & -a));
+ return (v + a - 1) & ~(a - 1);
+}
+
+/** Alignment must be a power of 2. */
+static inline bool
+libresoc_is_aligned(uintmax_t n, uintmax_t a)
+{
+ assert(a == (a & -a));
+ return (n & (a - 1)) == 0;
+}
+
+static inline uint32_t
+round_up_u32(uint32_t v, uint32_t a)
+{
+ return (v + a - 1) / a;
+}
+
+static inline uint64_t
+round_up_u64(uint64_t v, uint64_t a)
+{
+ return (v + a - 1) / a;
+}
+
+static inline uint32_t
+libresoc_minify(uint32_t n, uint32_t levels)
+{
+ if (unlikely(n == 0))
+ return 0;
+ else
+ return MAX2(n >> levels, 1);
+}
+static inline float
+libresoc_clamp_f(float f, float min, float max)
+{
+ assert(min < max);
+
+ if (f > max)
+ return max;
+ else if (f < min)
+ return min;
+ else
+ return f;
+}
+
+static inline bool
+libresoc_clear_mask(uint32_t *inout_mask, uint32_t clear_mask)
+{
+ if (*inout_mask & clear_mask) {
+ *inout_mask &= ~clear_mask;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+struct libresoc_fence {
+ struct vk_object_base base;
+};
+
+struct libresoc_image_create_info {
+ const VkImageCreateInfo *vk_info;
+ bool scanout;
+ bool no_metadata_planes;
+};
+
+struct libresoc_image {
+ struct vk_object_base base;
+ VkImageType type;
+ /* The original VkFormat provided by the client. This may not match any
+ * of the actual surface formats.
+ */
+ VkFormat vk_format;
+ VkImageAspectFlags aspects;
+ VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
+ VkImageTiling tiling; /** VkImageCreateInfo::tiling */
+ VkImageCreateFlags flags; /** VkImageCreateInfo::flags */
+
+ VkDeviceSize size;
+ uint32_t alignment;
+
+ unsigned queue_family_mask;
+ bool exclusive;
+ bool shareable;
+
+};
+
+VkResult libresoc_image_create(VkDevice _device,
+ const struct libresoc_image_create_info *info,
+ const VkAllocationCallbacks* alloc,
+ VkImage *pImage);
+
+struct libresoc_cmd_pool {
+ struct vk_object_base base;
+ VkAllocationCallbacks alloc;
+ struct list_head cmd_buffers;
+ struct list_head free_cmd_buffers;
+ uint32_t queue_family_index;
+};
+
+struct libresoc_semaphore {
+ struct vk_object_base base;
+};
+
struct libresoc_instance;
struct libresoc_device;
struct cache_entry;
const unsigned char *sha1,
struct libresoc_shader_variant **variants,
struct libresoc_shader_binary *const *binaries);
+
+VkResult libresoc_init_wsi(struct libresoc_physical_device *physical_device);
+void libresoc_finish_wsi(struct libresoc_physical_device *physical_device);
+
struct libresoc_device {
struct vk_device vk;
/* Condition variable for legacy timelines, to notify waiters when a
* new point gets submitted. */
pthread_cond_t timeline_cond;
+ /* Overallocation. */
+ bool overallocation_disallowed;
+ uint64_t allocated_memory_size[VK_MAX_MEMORY_HEAPS];
+ mtx_t overallocation_mutex;
/* FIXME: stub */
};
struct list_head link;
struct libresoc_instance *instance;
-
+ struct wsi_device wsi_device;
struct libresoc_device_extension_table supported_extensions;
struct libresoc_physical_device_dispatch_table dispatch;
uint8_t driver_uuid[VK_UUID_SIZE];
uint8_t device_uuid[VK_UUID_SIZE];
uint8_t cache_uuid[VK_UUID_SIZE];
+ int local_fd;
+ int master_fd;
+ VkPhysicalDeviceMemoryProperties memory_properties;
/* FIXME: stub */
};
int physical_device_count;
struct list_head physical_devices;
+ struct driOptionCache dri_options;
+ struct driOptionCache available_dri_options;
struct vk_debug_report_instance debug_report_callbacks;
};
+struct libresoc_deferred_queue_submission;
struct libresoc_queue {
VK_LOADER_DATA _loader_data;
struct list_head pending_submissions;
pthread_mutex_t pending_mutex;
+ pthread_mutex_t thread_mutex;
+ pthread_cond_t thread_cond;
+ //struct libresoc_deferred_queue_submission *thread_submission;
+ pthread_t submission_thread;
+ bool thread_exit;
+ bool thread_running;
/* FIXME: stub */
};
+struct libresoc_cmd_buffer_upload {
+ uint8_t *map;
+ unsigned offset;
+ uint64_t size;
+ struct list_head list;
+};
+
+enum libresoc_cmd_buffer_status {
+ LIBRESOC_CMD_BUFFER_STATUS_INVALID,
+ LIBRESOC_CMD_BUFFER_STATUS_INITIAL,
+ LIBRESOC_CMD_BUFFER_STATUS_RECORDING,
+ LIBRESOC_CMD_BUFFER_STATUS_EXECUTABLE,
+ LIBRESOC_CMD_BUFFER_STATUS_PENDING,
+};
+
struct libresoc_cmd_buffer {
+ struct vk_object_base base;
- struct libresoc_device *device;
+ struct libresoc_device * device;
+
+ struct libresoc_cmd_pool * pool;
+ struct list_head pool_link;
+
+ VkCommandBufferUsageFlags usage_flags;
+ VkCommandBufferLevel level;
+ enum libresoc_cmd_buffer_status status;
+ //struct radeon_cmdbuf *cs;
+ // struct libresoc_cmd_state state;
+ // struct libresoc_vertex_binding vertex_bindings[MAX_VBS];
+ // struct libresoc_streamout_binding streamout_bindings[MAX_SO_BUFFERS];
+ uint32_t queue_family_index;
+
+ uint8_t push_constants[MAX_PUSH_CONSTANTS_SIZE];
+ VkShaderStageFlags push_constant_stages;
+ // struct libresoc_descriptor_set meta_push_descriptors;
+
+ // struct libresoc_descriptor_state descriptors[MAX_BIND_POINTS];
+
+ struct libresoc_cmd_buffer_upload upload;
+
+ uint32_t scratch_size_per_wave_needed;
+ uint32_t scratch_waves_wanted;
+ uint32_t compute_scratch_size_per_wave_needed;
+ uint32_t compute_scratch_waves_wanted;
+ uint32_t esgs_ring_size_needed;
+ uint32_t gsvs_ring_size_needed;
+ bool tess_rings_needed;
+ bool sample_positions_needed;
+
+ VkResult record_result;
- /* FIXME: stub */
};
+struct libresoc_device_memory {
+ struct vk_object_base base;
+ /* for dedicated allocations */
+ struct libresoc_image *image;
+ //struct libresoc_buffer *buffer;
+ uint32_t heap_index;
+ uint64_t alloc_size;
+ void * map;
+ void * user_ptr;
+};
+
+void libresoc_free_memory(struct libresoc_device *device,
+ const VkAllocationCallbacks* pAllocator,
+ struct libresoc_device_memory *mem);
+
uint32_t libresoc_physical_device_api_version(struct libresoc_physical_device *dev);
int libresoc_get_instance_entrypoint_index(const char *name);
const char *
libresoc_get_debug_option_name(int id);
+struct libresoc_binning_settings {
+ unsigned context_states_per_bin; /* allowed range: [1, 6] */
+ unsigned persistent_states_per_bin; /* allowed range: [1, 32] */
+ unsigned fpovs_per_batch; /* allowed range: [0, 255], 0 = unlimited */
+};
+
+struct libresoc_binning_settings
+libresoc_get_binning_settings(const struct libresoc_physical_device *pdev);
+
+struct vk_format_description;
+uint32_t libresoc_translate_buffer_dataformat(const struct vk_format_description *desc,
+ int first_non_void);
+uint32_t libresoc_translate_buffer_numformat(const struct vk_format_description *desc,
+ int first_non_void);
+bool libresoc_is_buffer_format_supported(VkFormat format, bool *scaled);
+uint32_t libresoc_translate_colorformat(VkFormat format);
+uint32_t libresoc_translate_color_numformat(VkFormat format,
+ const struct vk_format_description *desc,
+ int first_non_void);
+uint32_t libresoc_colorformat_endian_swap(uint32_t colorformat);
+unsigned libresoc_translate_colorswap(VkFormat format, bool do_endian_swap);
+uint32_t libresoc_translate_dbformat(VkFormat format);
+uint32_t libresoc_translate_tex_dataformat(VkFormat format,
+ const struct vk_format_description *desc,
+ int first_non_void);
+uint32_t libresoc_translate_tex_numformat(VkFormat format,
+ const struct vk_format_description *desc,
+ int first_non_void);
+bool libresoc_format_pack_clear_color(VkFormat format,
+ uint32_t clear_vals[2],
+ VkClearColorValue *value);
+bool libresoc_is_colorbuffer_format_supported(VkFormat format, bool *blendable);
+bool libresoc_dcc_formats_compatible(VkFormat format1,
+ VkFormat format2);
+bool libresoc_device_supports_etc(struct libresoc_physical_device *physical_device);
+
+
+/* Whether the image has a htile that is known consistent with the contents of
+ * the image and is allowed to be in compressed form.
+ *
+ * If this is false reads that don't use the htile should be able to return
+ * correct results.
+ */
+bool libresoc_layout_is_htile_compressed(const struct libresoc_image *image,
+ VkImageLayout layout,
+ bool in_render_loop,
+ unsigned queue_mask);
+
+bool libresoc_layout_can_fast_clear(const struct libresoc_image *image,
+ VkImageLayout layout,
+ bool in_render_loop,
+ unsigned queue_mask);
+
+bool libresoc_layout_dcc_compressed(const struct libresoc_device *device,
+ const struct libresoc_image *image,
+ VkImageLayout layout,
+ bool in_render_loop,
+ unsigned queue_mask);
+
#define libresoc_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
VkResult __vk_errorf(struct libresoc_instance *instance, VkResult error,
LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_physical_device, VkPhysicalDevice)
LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_queue, VkQueue)
-//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_cmd_pool, VkCommandPool)
+LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_cmd_pool, VkCommandPool)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_buffer, VkBuffer)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_buffer_view, VkBufferView)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_pool, VkDescriptorPool)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_set, VkDescriptorSet)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_set_layout, VkDescriptorSetLayout)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_descriptor_update_template, VkDescriptorUpdateTemplate)
-//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_device_memory, VkDeviceMemory)
-//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_fence, VkFence)
+LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_device_memory, VkDeviceMemory)
+LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_fence, VkFence)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_event, VkEvent)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_framebuffer, VkFramebuffer)
-//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_image, VkImage)
+LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_image, VkImage)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_image_view, VkImageView);
LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_pipeline_cache, VkPipelineCache)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_pipeline, VkPipeline)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_sampler, VkSampler)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_sampler_ycbcr_conversion, VkSamplerYcbcrConversion)
//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_shader_module, VkShaderModule)
-//LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_semaphore, VkSemaphore)
+LIBRESOC_DEFINE_NONDISP_HANDLE_CASTS(libresoc_semaphore, VkSemaphore)
#endif /* LIBRESOC_PRIVATE_H */
--- /dev/null
+/*
+ * Copyright © 2016 Red Hat
+ * based on intel anv code:
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "libresoc_private.h"
+//#include "libresoc_meta.h"
+#include "wsi_common.h"
+#include "vk_util.h"
+#include "util/macros.h"
+
+static PFN_vkVoidFunction
+libresoc_wsi_proc_addr(VkPhysicalDevice physicalDevice, const char *pName)
+{
+ return libresoc_lookup_entrypoint(pName);
+}
+
+static void
+libresoc_wsi_set_memory_ownership(VkDevice _device,
+ VkDeviceMemory _mem,
+ VkBool32 ownership)
+{
+ //TODO: enable when required
+ //LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ //LIBRESOC_FROM_HANDLE(libresoc_device_memory, mem, _mem);
+
+ //if (ownership)
+ // libresoc_bo_list_add(device, mem->bo);
+ //else
+ // libresoc_bo_list_remove(device, mem->bo);
+}
+
+VkResult
+libresoc_init_wsi(struct libresoc_physical_device *physical_device)
+{
+ //TODO: stub
+ //return VK_SUCCESS;
+ VkResult result = wsi_device_init(&physical_device->wsi_device,
+ libresoc_physical_device_to_handle(physical_device),
+ libresoc_wsi_proc_addr,
+ &physical_device->instance->alloc,
+ physical_device->master_fd,
+ &physical_device->instance->dri_options,
+ true); //TODO: for now this is sw_device
+ if (result != VK_SUCCESS)
+ return result;
+
+ physical_device->wsi_device.set_memory_ownership = libresoc_wsi_set_memory_ownership;
+ return VK_SUCCESS;
+}
+
+void
+libresoc_finish_wsi(struct libresoc_physical_device *physical_device)
+{
+ wsi_device_finish(&physical_device->wsi_device,
+ &physical_device->instance->alloc);
+}
+
+void libresoc_DestroySurfaceKHR(
+ VkInstance _instance,
+ VkSurfaceKHR _surface,
+ const VkAllocationCallbacks* pAllocator)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
+ ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface);
+
+ vk_free2(&instance->alloc, pAllocator, surface);
+}
+
+VkResult libresoc_GetPhysicalDeviceSurfaceSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ VkSurfaceKHR surface,
+ VkBool32* pSupported)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return wsi_common_get_surface_support(&device->wsi_device,
+ queueFamilyIndex,
+ surface,
+ pSupported);
+}
+
+VkResult libresoc_GetPhysicalDeviceSurfaceCapabilitiesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilitiesKHR* pSurfaceCapabilities)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return wsi_common_get_surface_capabilities(&device->wsi_device,
+ surface,
+ pSurfaceCapabilities);
+}
+
+// VkResult libresoc_GetPhysicalDeviceSurfaceCapabilities2KHR(
+// VkPhysicalDevice physicalDevice,
+// const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+// VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
+// {
+// LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+// return wsi_common_get_surface_capabilities2(&device->wsi_device,
+// pSurfaceInfo,
+// pSurfaceCapabilities);
+// }
+
+// VkResult libresoc_GetPhysicalDeviceSurfaceCapabilities2EXT(
+// VkPhysicalDevice physicalDevice,
+// VkSurfaceKHR surface,
+// VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
+// {
+// LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+// return wsi_common_get_surface_capabilities2ext(&device->wsi_device,
+// surface,
+// pSurfaceCapabilities);
+// }
+
+VkResult libresoc_GetPhysicalDeviceSurfaceFormatsKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormatKHR* pSurfaceFormats)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return wsi_common_get_surface_formats(&device->wsi_device,
+ surface,
+ pSurfaceFormatCount,
+ pSurfaceFormats);
+}
+
+// VkResult libresoc_GetPhysicalDeviceSurfaceFormats2KHR(
+// VkPhysicalDevice physicalDevice,
+// const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+// uint32_t* pSurfaceFormatCount,
+// VkSurfaceFormat2KHR* pSurfaceFormats)
+// {
+// LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+// return wsi_common_get_surface_formats2(&device->wsi_device,
+// pSurfaceInfo,
+// pSurfaceFormatCount,
+// pSurfaceFormats);
+// }
+
+VkResult libresoc_GetPhysicalDeviceSurfacePresentModesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pPresentModeCount,
+ VkPresentModeKHR* pPresentModes)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return wsi_common_get_surface_present_modes(&device->wsi_device,
+ surface,
+ pPresentModeCount,
+ pPresentModes);
+}
+
+VkResult libresoc_CreateSwapchainKHR(
+ VkDevice _device,
+ const VkSwapchainCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSwapchainKHR* pSwapchain)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ const VkAllocationCallbacks *alloc;
+ if (pAllocator)
+ alloc = pAllocator;
+ else
+ alloc = &device->vk.alloc;
+
+ return wsi_common_create_swapchain(&device->physical_device->wsi_device,
+ libresoc_device_to_handle(device),
+ pCreateInfo,
+ alloc,
+ pSwapchain);
+}
+
+void libresoc_DestroySwapchainKHR(
+ VkDevice _device,
+ VkSwapchainKHR swapchain,
+ const VkAllocationCallbacks* pAllocator)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ const VkAllocationCallbacks *alloc;
+
+ if (pAllocator)
+ alloc = pAllocator;
+ else
+ alloc = &device->vk.alloc;
+
+ wsi_common_destroy_swapchain(_device, swapchain, alloc);
+}
+
+VkResult libresoc_GetSwapchainImagesKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint32_t* pSwapchainImageCount,
+ VkImage* pSwapchainImages)
+{
+ return wsi_common_get_images(swapchain,
+ pSwapchainImageCount,
+ pSwapchainImages);
+}
+
+VkResult libresoc_AcquireNextImageKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain,
+ uint64_t timeout,
+ VkSemaphore semaphore,
+ VkFence fence,
+ uint32_t* pImageIndex)
+{
+ VkAcquireNextImageInfoKHR acquire_info = {
+ .sType = VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR,
+ .swapchain = swapchain,
+ .timeout = timeout,
+ .semaphore = semaphore,
+ .fence = fence,
+ .deviceMask = 0,
+ };
+
+ return libresoc_AcquireNextImage2KHR(device, &acquire_info, pImageIndex);
+}
+
+VkResult libresoc_AcquireNextImage2KHR(
+ VkDevice _device,
+ const VkAcquireNextImageInfoKHR* pAcquireInfo,
+ uint32_t* pImageIndex)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+ struct libresoc_physical_device *pdevice = device->physical_device;
+ //LIBRESOC_FROM_HANDLE(libresoc_fence, fence, pAcquireInfo->fence);
+ //LIBRESOC_FROM_HANDLE(libresoc_semaphore, semaphore, pAcquireInfo->semaphore);
+
+ VkResult result = wsi_common_acquire_next_image2(&pdevice->wsi_device,
+ _device,
+ pAcquireInfo,
+ pImageIndex);
+ //TODO: enable if required
+ // if (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR) {
+ // if (fence) {
+ // struct libresoc_fence_part *part =
+ // fence->temporary.kind != LIBRESOC_FENCE_NONE ?
+ // &fence->temporary : &fence->permanent;
+
+ // switch (part->kind) {
+ // case LIBRESOC_FENCE_NONE:
+ // break;
+ // case LIBRESOC_FENCE_WINSYS:
+ // device->ws->signal_fence(part->fence);
+ // break;
+ // case LIBRESOC_FENCE_SYNCOBJ:
+ // device->ws->signal_syncobj(device->ws, part->syncobj, 0);
+ // break;
+ // default:
+ // unreachable("Invalid WSI fence type");
+ // }
+ // }
+ // if (semaphore) {
+ // struct libresoc_semaphore_part *part =
+ // semaphore->temporary.kind != LIBRESOC_SEMAPHORE_NONE ?
+ // &semaphore->temporary : &semaphore->permanent;
+
+ // switch (part->kind) {
+ // case LIBRESOC_SEMAPHORE_NONE:
+ // case LIBRESOC_SEMAPHORE_WINSYS:
+ // /* Do not need to do anything. */
+ // break;
+ // case LIBRESOC_SEMAPHORE_TIMELINE:
+ // case LIBRESOC_SEMAPHORE_TIMELINE_SYNCOBJ:
+ // unreachable("WSI only allows binary semaphores.");
+ // case LIBRESOC_SEMAPHORE_SYNCOBJ:
+ // device->ws->signal_syncobj(device->ws, part->syncobj, 0);
+ // break;
+ // }
+ // }
+ // }
+ return result;
+}
+
+VkResult libresoc_QueuePresentKHR(
+ VkQueue _queue,
+ const VkPresentInfoKHR* pPresentInfo)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_queue, queue, _queue);
+ return wsi_common_queue_present(&queue->device->physical_device->wsi_device,
+ libresoc_device_to_handle(queue->device),
+ _queue,
+ queue->queue_family_index,
+ pPresentInfo);
+}
+
+
+VkResult libresoc_GetDeviceGroupPresentCapabilitiesKHR(
+ VkDevice device,
+ VkDeviceGroupPresentCapabilitiesKHR* pCapabilities)
+{
+ memset(pCapabilities->presentMask, 0,
+ sizeof(pCapabilities->presentMask));
+ pCapabilities->presentMask[0] = 0x1;
+ pCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
+
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_GetDeviceGroupSurfacePresentModesKHR(
+ VkDevice device,
+ VkSurfaceKHR surface,
+ VkDeviceGroupPresentModeFlagsKHR* pModes)
+{
+ *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
+
+ return VK_SUCCESS;
+}
+
+VkResult libresoc_GetPhysicalDevicePresentRectanglesKHR(
+ VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ uint32_t* pRectCount,
+ VkRect2D* pRects)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return wsi_common_get_present_rectangles(&device->wsi_device,
+ surface,
+ pRectCount, pRects);
+}
--- /dev/null
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based mostly on anv driver which is:
+ * Copyright © 2015 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <X11/Xlib-xcb.h>
+#include <X11/xshmfence.h>
+#include <xcb/xcb.h>
+#include <xcb/dri3.h>
+#include <xcb/present.h>
+
+#include "wsi_common_x11.h"
+#include "libresoc_private.h"
+
+
+VkBool32 libresoc_GetPhysicalDeviceXcbPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ xcb_connection_t* connection,
+ xcb_visualid_t visual_id)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return true;
+ //TODO: for now always allow
+/* return wsi_get_physical_device_xcb_presentation_support(
+ &device->wsi_device,
+ queueFamilyIndex,
+ connection, visual_id);*/
+}
+
+VkBool32 libresoc_GetPhysicalDeviceXlibPresentationSupportKHR(
+ VkPhysicalDevice physicalDevice,
+ uint32_t queueFamilyIndex,
+ Display* dpy,
+ VisualID visualID)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_physical_device, device, physicalDevice);
+
+ return true;
+ //TODO: for now always allow
+/* return wsi_get_physical_device_xcb_presentation_support(
+ &device->wsi_device,
+ queueFamilyIndex,
+ XGetXCBConnection(dpy), visualID);*/
+}
+
+VkResult libresoc_CreateXcbSurfaceKHR(
+ VkInstance _instance,
+ const VkXcbSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
+ const VkAllocationCallbacks *alloc;
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR);
+
+ if (pAllocator)
+ alloc = pAllocator;
+ else
+ alloc = &instance->alloc;
+
+ return wsi_create_xcb_surface(alloc, pCreateInfo, pSurface);
+}
+
+VkResult libresoc_CreateXlibSurfaceKHR(
+ VkInstance _instance,
+ const VkXlibSurfaceCreateInfoKHR* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSurfaceKHR* pSurface)
+{
+ LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
+ const VkAllocationCallbacks *alloc;
+
+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR);
+
+ if (pAllocator)
+ alloc = pAllocator;
+ else
+ alloc = &instance->alloc;
+
+ return wsi_create_xlib_surface(alloc, pCreateInfo, pSurface);
+}
],
depend_files : files('libresoc_extensions.py'),
)
-#libresoc_entrypoints = custom_target(
-# 'libresoc_entrypoints.[ch]',
-# input : ['libresoc_entrypoints_gen.py', vk_api_xml],
-# output : ['libresoc_entrypoints.h', 'libresoc_entrypoints.c'],
-# command : [
-# prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
-# meson.current_build_dir()
-# ],
-# depend_files : files('libresoc_extensions.py'),
-#)
-#
-#libresoc_extensions_c = custom_target(
-# 'libresoc_extensions.c',
-# input : ['libresoc_extensions.py', vk_api_xml],
-# output : ['libresoc_extensions.c', 'libresoc_extensions.h'],
-# command : [
-# prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--out-c', '@OUTPUT0@',
-# '--out-h', '@OUTPUT1@'
-# ],
-#)
libresoc_vk_format_table_c = custom_target(
'libresoc_vk_format_table.c',
liblibresoc_files = files(
'libresoc_device.c',
+ 'libresoc_meta_clear.c',
+ 'libresoc_image.c',
+ 'libresoc_cmd_buffer.c',
+ 'libresoc_formats.c',
'libresoc_pipeline.c',
'libresoc_pipeline_cache.c',
'libresoc_util.c',
+ 'libresoc_wsi.c',
+ 'libresoc_private.h',
+ 'vk_format.h',
)
libresoc_deps = []
libresoc_flags = []
-
libresoc_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR'
+libresoc_flags += '-DVK_USE_PLATFORM_XLIB_KHR'
+libresoc_flags += '-DVK_USE_PLATFORM_XCB_KHR'
if with_platform_x11
- #libresoc_deps += dep_xcb_dri3
- #libresoc_flags += [
- # '-DVK_USE_PLATFORM_XCB_KHR',
- # '-DVK_USE_PLATFORM_XLIB_KHR',
- #]
- #liblibresoc_files += files('libresoc_wsi_x11.c')
-endif
-
-if with_platform_wayland
- #libresoc_deps += dep_wayland_client
- #libresoc_flags += '-DVK_USE_PLATFORM_WAYLAND_KHR'
- #liblibresoc_files += files('libresoc_wsi_wayland.c')
-endif
-
-if system_has_kms_drm and not with_platform_android
- #libresoc_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR'
- #liblibresoc_files += files('libresoc_wsi_display.c')
-endif
-
-if with_xlib_lease
- #libresoc_deps += [dep_xcb_xrandr, dep_xlib_xrandr]
- #libresoc_flags += '-DVK_USE_PLATFORM_XLIB_XRANDR_EXT'
-endif
-
-if with_platform_android
- #libresoc_deps += dep_android
- #libresoc_flags += [
- # '-DVK_USE_PLATFORM_ANDROID_KHR'
- #]
+ libresoc_deps += dep_xcb_dri3
+ libresoc_flags += [
+ '-DVK_USE_PLATFORM_XCB_KHR',
+ '-DVK_USE_PLATFORM_XLIB_KHR',
+ ]
+ liblibresoc_files += files('libresoc_wsi_x11.c')
endif
libvulkan_libresoc = shared_library(
'vulkan_libresoc',
[liblibresoc_files, libresoc_entrypoints, libresoc_extensions_c, libresoc_extensions_h, libresoc_vk_format_table_c, sha1_h],
include_directories : [
- inc_include, inc_src, inc_mapi, inc_mesa, inc_compiler, inc_util, inc_vulkan_wsi, #inc_gallium, inc_gallium_aux, inc_amd, inc_amd_common, inc_amd_common_llvm,
+ inc_include, inc_src, inc_mapi, inc_mesa, inc_compiler, inc_util, inc_vulkan_wsi, inc_gallium_aux, inc_gallium, #inc_amd, inc_amd_common, inc_amd_common_llvm,
],
link_with : [
libvulkan_wsi, #libamd_common, libamd_common_llvm, libamdgpu_addrlib,
],
dependencies : [idep_vulkan_util, libresoc_deps,idep_xmlconfig, dep_libdrm,
dep_llvm, dep_thread, dep_elf, dep_dl, dep_m,dep_valgrind, idep_mesautil, idep_nir,
- # libresoc_deps, idep_aco, dep_libdrm_amdgpu,
+ libresoc_deps, #idep_aco, dep_libdrm_amdgpu,
# idep_amdgfxregs_h,
],
c_args : [no_override_init_args, libresoc_flags],