vallium: initial import of the vulkan frontend
[mesa.git] / src / gallium / frontends / vallium / val_image.c
diff --git a/src/gallium/frontends/vallium/val_image.c b/src/gallium/frontends/vallium/val_image.c
new file mode 100644 (file)
index 0000000..29a493e
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * Copyright © 2019 Red Hat.
+ *
+ * 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 "val_private.h"
+#include "util/format/u_format.h"
+#include "util/u_inlines.h"
+#include "pipe/p_state.h"
+
+VkResult
+val_image_create(VkDevice _device,
+                 const struct val_image_create_info *create_info,
+                 const VkAllocationCallbacks* alloc,
+                 VkImage *pImage)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
+   struct val_image *image;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
+
+   image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
+                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (image == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);
+   image->alignment = 16;
+   image->type = pCreateInfo->imageType;
+   {
+      struct pipe_resource template;
+
+      memset(&template, 0, sizeof(template));
+
+      template.screen = device->pscreen;
+      switch (pCreateInfo->imageType) {
+      case VK_IMAGE_TYPE_1D:
+         template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_1D_ARRAY : PIPE_TEXTURE_1D;
+         break;
+      default:
+      case VK_IMAGE_TYPE_2D:
+         template.target = pCreateInfo->arrayLayers > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
+         if (pCreateInfo->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
+            template.target = pCreateInfo->arrayLayers == 6 ? PIPE_TEXTURE_CUBE : PIPE_TEXTURE_CUBE_ARRAY;
+         break;
+      case VK_IMAGE_TYPE_3D:
+         template.target = PIPE_TEXTURE_3D;
+         break;
+      }
+
+      template.format = vk_format_to_pipe(pCreateInfo->format);
+      template.width0 = pCreateInfo->extent.width;
+      template.height0 = pCreateInfo->extent.height;
+      template.depth0 = pCreateInfo->extent.depth;
+      template.array_size = pCreateInfo->arrayLayers;
+      template.last_level = pCreateInfo->mipLevels - 1;
+      template.nr_samples = pCreateInfo->samples;
+      template.nr_storage_samples = pCreateInfo->samples;
+      if (create_info->bind_flags)
+         template.bind = create_info->bind_flags;
+      image->bo = device->pscreen->resource_create_unbacked(device->pscreen,
+                                                            &template,
+                                                            &image->size);
+   }
+   *pImage = val_image_to_handle(image);
+
+   return VK_SUCCESS;
+}
+
+VkResult
+val_CreateImage(VkDevice device,
+                const VkImageCreateInfo *pCreateInfo,
+                const VkAllocationCallbacks *pAllocator,
+                VkImage *pImage)
+{
+   return val_image_create(device,
+      &(struct val_image_create_info) {
+         .vk_info = pCreateInfo,
+         .bind_flags = 0,
+      },
+      pAllocator,
+      pImage);
+}
+
+void
+val_DestroyImage(VkDevice _device, VkImage _image,
+                 const VkAllocationCallbacks *pAllocator)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_image, image, _image);
+
+   if (!_image)
+     return;
+   pipe_resource_reference(&image->bo, NULL);
+   vk_object_base_finish(&image->base);
+   vk_free2(&device->alloc, pAllocator, image);
+}
+
+VkResult
+val_CreateImageView(VkDevice _device,
+                    const VkImageViewCreateInfo *pCreateInfo,
+                    const VkAllocationCallbacks *pAllocator,
+                    VkImageView *pView)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_image, image, pCreateInfo->image);
+   struct val_image_view *view;
+
+   view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
+                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (view == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   vk_object_base_init(&device->vk, &view->base,
+                       VK_OBJECT_TYPE_IMAGE_VIEW);
+   view->view_type = pCreateInfo->viewType;
+   view->format = pCreateInfo->format;
+   view->pformat = vk_format_to_pipe(pCreateInfo->format);
+   view->components = pCreateInfo->components;
+   view->subresourceRange = pCreateInfo->subresourceRange;
+   view->image = image;
+   view->surface = NULL;
+   *pView = val_image_view_to_handle(view);
+
+   return VK_SUCCESS;
+}
+
+void
+val_DestroyImageView(VkDevice _device, VkImageView _iview,
+                     const VkAllocationCallbacks *pAllocator)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_image_view, iview, _iview);
+
+   if (!_iview)
+     return;
+
+   pipe_surface_reference(&iview->surface, NULL);
+   vk_object_base_finish(&iview->base);
+   vk_free2(&device->alloc, pAllocator, iview);
+}
+
+void val_GetImageSubresourceLayout(
+    VkDevice                                    _device,
+    VkImage                                     _image,
+    const VkImageSubresource*                   pSubresource,
+    VkSubresourceLayout*                        pLayout)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_image, image, _image);
+   uint32_t stride, offset;
+   device->pscreen->resource_get_info(device->pscreen,
+                                      image->bo,
+                                      &stride, &offset);
+   pLayout->offset = offset;
+   pLayout->rowPitch = stride;
+   pLayout->arrayPitch = 0;
+   pLayout->size = image->size;
+   switch (pSubresource->aspectMask) {
+   case VK_IMAGE_ASPECT_COLOR_BIT:
+      break;
+   case VK_IMAGE_ASPECT_DEPTH_BIT:
+      break;
+   case VK_IMAGE_ASPECT_STENCIL_BIT:
+      break;
+   default:
+      assert(!"Invalid image aspect");
+   }
+}
+
+VkResult val_CreateBuffer(
+    VkDevice                                    _device,
+    const VkBufferCreateInfo*                   pCreateInfo,
+    const VkAllocationCallbacks*                pAllocator,
+    VkBuffer*                                   pBuffer)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   struct val_buffer *buffer;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
+
+   buffer = vk_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
+                       VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (buffer == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   vk_object_base_init(&device->vk, &buffer->base, VK_OBJECT_TYPE_BUFFER);
+   buffer->size = pCreateInfo->size;
+   buffer->usage = pCreateInfo->usage;
+   buffer->offset = 0;
+
+   {
+      struct pipe_resource template;
+      memset(&template, 0, sizeof(struct pipe_resource));
+      template.screen = device->pscreen;
+      template.target = PIPE_BUFFER;
+      template.format = PIPE_FORMAT_R8_UNORM;
+      template.width0 = buffer->size;
+      template.height0 = 1;
+      template.depth0 = 1;
+      template.array_size = 1;
+      template.flags = PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE;
+      buffer->bo = device->pscreen->resource_create_unbacked(device->pscreen,
+                                                             &template,
+                                                             &buffer->total_size);
+      if (!buffer->bo) {
+         vk_free2(&device->alloc, pAllocator, buffer);
+         return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
+      }
+   }
+   *pBuffer = val_buffer_to_handle(buffer);
+
+   return VK_SUCCESS;
+}
+
+void val_DestroyBuffer(
+    VkDevice                                    _device,
+    VkBuffer                                    _buffer,
+    const VkAllocationCallbacks*                pAllocator)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_buffer, buffer, _buffer);
+
+   if (!_buffer)
+     return;
+
+   pipe_resource_reference(&buffer->bo, NULL);
+   vk_object_base_finish(&buffer->base);
+   vk_free2(&device->alloc, pAllocator, buffer);
+}
+
+VkResult
+val_CreateBufferView(VkDevice _device,
+                     const VkBufferViewCreateInfo *pCreateInfo,
+                     const VkAllocationCallbacks *pAllocator,
+                     VkBufferView *pView)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_buffer, buffer, pCreateInfo->buffer);
+   struct val_buffer_view *view;
+   view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
+                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (!view)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   vk_object_base_init(&device->vk, &view->base,
+                       VK_OBJECT_TYPE_BUFFER_VIEW);
+   view->buffer = buffer;
+   view->format = pCreateInfo->format;
+   view->pformat = vk_format_to_pipe(pCreateInfo->format);
+   view->offset = pCreateInfo->offset;
+   view->range = pCreateInfo->range;
+   *pView = val_buffer_view_to_handle(view);
+
+   return VK_SUCCESS;
+}
+
+void
+val_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
+                      const VkAllocationCallbacks *pAllocator)
+{
+   VAL_FROM_HANDLE(val_device, device, _device);
+   VAL_FROM_HANDLE(val_buffer_view, view, bufferView);
+
+   if (!bufferView)
+     return;
+   vk_object_base_finish(&view->base);
+   vk_free2(&device->alloc, pAllocator, view);
+}