v3dv: implement vk{Create,Destroy}Framebuffer

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index ba55585..a7b3a24 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -1381,3 +1381,49 @@
 
    vk_free2(&device->alloc, pAllocator, buffer);
 }
+
+VkResult
+v3dv_CreateFramebuffer(VkDevice _device,
+                       const VkFramebufferCreateInfo *pCreateInfo,
+                       const VkAllocationCallbacks *pAllocator,
+                       VkFramebuffer *pFramebuffer)
+{
+   V3DV_FROM_HANDLE(v3dv_device, device, _device);
+   struct v3dv_framebuffer *framebuffer;
+
+   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
+
+   size_t size = sizeof(*framebuffer) +
+                 sizeof(struct v3dv_image_view *) * pCreateInfo->attachmentCount;
+   framebuffer = vk_alloc2(&device->alloc, pAllocator, size, 8,
+                           VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+   if (framebuffer == NULL)
+      return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+   framebuffer->width = pCreateInfo->width;
+   framebuffer->height = pCreateInfo->height;
+   framebuffer->layers = pCreateInfo->layers;
+   framebuffer->attachment_count = pCreateInfo->attachmentCount;
+   for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
+      framebuffer->attachments[i] =
+         v3dv_image_view_from_handle(pCreateInfo->pAttachments[i]);
+   }
+
+   *pFramebuffer = v3dv_framebuffer_to_handle(framebuffer);
+
+   return VK_SUCCESS;
+}
+
+void
+v3dv_DestroyFramebuffer(VkDevice _device,
+                        VkFramebuffer _fb,
+                        const VkAllocationCallbacks *pAllocator)
+{
+   V3DV_FROM_HANDLE(v3dv_device, device, _device);
+   V3DV_FROM_HANDLE(v3dv_framebuffer, fb, _fb);
+
+   if (!fb)
+      return;
+
+   vk_free2(&device->alloc, pAllocator, fb);
+}
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 7abc252..42e10f3 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -334,6 +334,15 @@
    struct v3dv_subpass_attachment *subpass_attachments;
 };
 
+struct v3dv_framebuffer {
+   uint32_t width;
+   uint32_t height;
+   uint32_t layers;
+
+   uint32_t attachment_count;
+   struct v3dv_image_view *attachments[0];
+};
+
 struct v3dv_shader_module {
    unsigned char sha1[20];
    uint32_t size;
@@ -433,6 +442,7 @@
 
 V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_buffer, VkBuffer)
 V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_device_memory, VkDeviceMemory)
+V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_framebuffer, VkFramebuffer)
 V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image, VkImage)
 V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_image_view, VkImageView)
 V3DV_DEFINE_NONDISP_HANDLE_CASTS(v3dv_render_pass, VkRenderPass)