--- /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;
+}