~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/imagination/vulkan/pvr_bo.c

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2022 Imagination Technologies Ltd.
3
 
 *
4
 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
5
 
 * of this software and associated documentation files (the "Software"), to deal
6
 
 * in the Software without restriction, including without limitation the rights
7
 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
 
 * copies of the Software, and to permit persons to whom the Software is
9
 
 * furnished to do so, subject to the following conditions:
10
 
 *
11
 
 * The above copyright notice and this permission notice (including the next
12
 
 * paragraph) shall be included in all copies or substantial portions of the
13
 
 * Software.
14
 
 *
15
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
 
 * SOFTWARE.
22
 
 */
23
 
 
24
 
#include <assert.h>
25
 
#include <stddef.h>
26
 
#include <stdint.h>
27
 
#include <vulkan/vulkan.h>
28
 
 
29
 
#include "pvr_bo.h"
30
 
#include "pvr_private.h"
31
 
#include "pvr_winsys.h"
32
 
#include "vk_alloc.h"
33
 
#include "vk_log.h"
34
 
 
35
 
static uint32_t pvr_bo_alloc_to_winsys_flags(uint64_t flags)
36
 
{
37
 
   uint32_t ws_flags = 0;
38
 
 
39
 
   if (flags & PVR_BO_ALLOC_FLAG_CPU_ACCESS)
40
 
      ws_flags |= PVR_WINSYS_BO_FLAG_CPU_ACCESS;
41
 
 
42
 
   if (flags & PVR_BO_ALLOC_FLAG_GPU_UNCACHED)
43
 
      ws_flags |= PVR_WINSYS_BO_FLAG_GPU_UNCACHED;
44
 
 
45
 
   if (flags & PVR_BO_ALLOC_FLAG_PM_FW_PROTECT)
46
 
      ws_flags |= PVR_WINSYS_BO_FLAG_PM_FW_PROTECT;
47
 
 
48
 
   if (flags & PVR_BO_ALLOC_FLAG_ZERO_ON_ALLOC)
49
 
      ws_flags |= PVR_WINSYS_BO_FLAG_ZERO_ON_ALLOC;
50
 
 
51
 
   return ws_flags;
52
 
}
53
 
 
54
 
/**
55
 
 * \brief Helper interface to allocate a GPU buffer and map it to both host and
56
 
 * device virtual memory. Host mapping is conditional and is controlled by
57
 
 * flags.
58
 
 *
59
 
 * \param[in] device      Logical device pointer.
60
 
 * \param[in] heap        Heap to allocate device virtual address from.
61
 
 * \param[in] size        Size of buffer to allocate.
62
 
 * \param[in] alignment   Required alignment of the allocation. Must be a power
63
 
 *                        of two.
64
 
 * \param[in] flags       Controls allocation, CPU and GPU mapping behavior
65
 
 *                        using PVR_BO_ALLOC_FLAG_*.
66
 
 * \param[out] pvr_bo_out On success output buffer is returned in this pointer.
67
 
 * \return VK_SUCCESS on success, or error code otherwise.
68
 
 *
69
 
 * \sa #pvr_bo_free()
70
 
 */
71
 
VkResult pvr_bo_alloc(struct pvr_device *device,
72
 
                      struct pvr_winsys_heap *heap,
73
 
                      uint64_t size,
74
 
                      uint64_t alignment,
75
 
                      uint64_t flags,
76
 
                      struct pvr_bo **const pvr_bo_out)
77
 
{
78
 
   const uint32_t ws_flags = pvr_bo_alloc_to_winsys_flags(flags);
79
 
   struct pvr_bo *pvr_bo;
80
 
   pvr_dev_addr_t addr;
81
 
   VkResult result;
82
 
 
83
 
   pvr_bo = vk_alloc(&device->vk.alloc,
84
 
                     sizeof(*pvr_bo),
85
 
                     8,
86
 
                     VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
87
 
   if (!pvr_bo)
88
 
      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
89
 
 
90
 
   result = device->ws->ops->buffer_create(device->ws,
91
 
                                           size,
92
 
                                           alignment,
93
 
                                           PVR_WINSYS_BO_TYPE_GPU,
94
 
                                           ws_flags,
95
 
                                           &pvr_bo->bo);
96
 
   if (result != VK_SUCCESS)
97
 
      goto err_vk_free;
98
 
 
99
 
   if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED) {
100
 
      void *map = device->ws->ops->buffer_map(pvr_bo->bo);
101
 
      if (!map) {
102
 
         result = VK_ERROR_MEMORY_MAP_FAILED;
103
 
         goto err_buffer_destroy;
104
 
      }
105
 
   }
106
 
 
107
 
   pvr_bo->vma = device->ws->ops->heap_alloc(heap, size, alignment);
108
 
   if (!pvr_bo->vma) {
109
 
      result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
110
 
      goto err_buffer_unmap;
111
 
   }
112
 
 
113
 
   addr = device->ws->ops->vma_map(pvr_bo->vma, pvr_bo->bo, 0, size);
114
 
   if (!addr.addr) {
115
 
      result = VK_ERROR_MEMORY_MAP_FAILED;
116
 
      goto err_heap_free;
117
 
   }
118
 
 
119
 
   *pvr_bo_out = pvr_bo;
120
 
 
121
 
   return VK_SUCCESS;
122
 
 
123
 
err_heap_free:
124
 
   device->ws->ops->heap_free(pvr_bo->vma);
125
 
 
126
 
err_buffer_unmap:
127
 
   if (flags & PVR_BO_ALLOC_FLAG_CPU_MAPPED)
128
 
      device->ws->ops->buffer_unmap(pvr_bo->bo);
129
 
 
130
 
err_buffer_destroy:
131
 
   device->ws->ops->buffer_destroy(pvr_bo->bo);
132
 
 
133
 
err_vk_free:
134
 
   vk_free(&device->vk.alloc, pvr_bo);
135
 
 
136
 
   return result;
137
 
}
138
 
 
139
 
/**
140
 
 * \brief Interface to map the buffer into host virtual address space.
141
 
 *
142
 
 * Buffer should have been created with the #PVR_BO_ALLOC_FLAG_CPU_ACCESS
143
 
 * flag. It should also not already be mapped or it should have been unmapped
144
 
 * using #pvr_bo_cpu_unmap() before mapping again.
145
 
 *
146
 
 * \param[in] device Logical device pointer.
147
 
 * \param[in] pvr_bo Buffer to map.
148
 
 * \return Valid host virtual address on success, or NULL otherwise.
149
 
 *
150
 
 * \sa #pvr_bo_alloc(), #PVR_BO_ALLOC_FLAG_CPU_MAPPED
151
 
 */
152
 
void *pvr_bo_cpu_map(struct pvr_device *device, struct pvr_bo *pvr_bo)
153
 
{
154
 
   assert(!pvr_bo->bo->map);
155
 
 
156
 
   return device->ws->ops->buffer_map(pvr_bo->bo);
157
 
}
158
 
 
159
 
/**
160
 
 * \brief Interface to unmap the buffer from host virtual address space.
161
 
 *
162
 
 * Buffer should have a valid mapping, created either using #pvr_bo_cpu_map() or
163
 
 * by passing #PVR_BO_ALLOC_FLAG_CPU_MAPPED flag to #pvr_bo_alloc() at
164
 
 * allocation time.
165
 
 *
166
 
 * Buffer can be remapped using #pvr_bo_cpu_map().
167
 
 *
168
 
 * \param[in] device Logical device pointer.
169
 
 * \param[in] pvr_bo Buffer to unmap.
170
 
 */
171
 
void pvr_bo_cpu_unmap(struct pvr_device *device, struct pvr_bo *pvr_bo)
172
 
{
173
 
   assert(pvr_bo->bo->map);
174
 
   device->ws->ops->buffer_unmap(pvr_bo->bo);
175
 
}
176
 
 
177
 
/**
178
 
 * \brief Interface to free the buffer object.
179
 
 *
180
 
 * \param[in] device Logical device pointer.
181
 
 * \param[in] pvr_bo Buffer to free.
182
 
 *
183
 
 * \sa #pvr_bo_alloc()
184
 
 */
185
 
void pvr_bo_free(struct pvr_device *device, struct pvr_bo *pvr_bo)
186
 
{
187
 
   if (!pvr_bo)
188
 
      return;
189
 
 
190
 
   device->ws->ops->vma_unmap(pvr_bo->vma);
191
 
   device->ws->ops->heap_free(pvr_bo->vma);
192
 
 
193
 
   if (pvr_bo->bo->map)
194
 
      device->ws->ops->buffer_unmap(pvr_bo->bo);
195
 
 
196
 
   device->ws->ops->buffer_destroy(pvr_bo->bo);
197
 
 
198
 
   vk_free(&device->vk.alloc, pvr_bo);
199
 
}