Making SWAPChain exntesions work.
[mesa.git] / src / libre-soc / vulkan / libresoc_cmd_buffer.c
diff --git a/src/libre-soc/vulkan/libresoc_cmd_buffer.c b/src/libre-soc/vulkan/libresoc_cmd_buffer.c
new file mode 100644 (file)
index 0000000..a865f5b
--- /dev/null
@@ -0,0 +1,306 @@
+
+/*
+ * 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;
+}