1 /*
2 * Copyright © 2019 Red Hat.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is 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
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "lvp_private.h"
25 #include "pipe/p_context.h"
26 #include "vk_util.h"
27
28 #include "vk_common_entrypoints.h"
29
30 static void
lvp_cmd_buffer_destroy(struct vk_command_buffer * cmd_buffer)31 lvp_cmd_buffer_destroy(struct vk_command_buffer *cmd_buffer)
32 {
33 vk_command_buffer_finish(cmd_buffer);
34 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
35 }
36
37 static VkResult
lvp_create_cmd_buffer(struct vk_command_pool * pool,struct vk_command_buffer ** cmd_buffer_out)38 lvp_create_cmd_buffer(struct vk_command_pool *pool,
39 struct vk_command_buffer **cmd_buffer_out)
40 {
41 struct lvp_device *device =
42 container_of(pool->base.device, struct lvp_device, vk);
43 struct lvp_cmd_buffer *cmd_buffer;
44
45 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
46 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
47 if (cmd_buffer == NULL)
48 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
49
50 VkResult result = vk_command_buffer_init(pool, &cmd_buffer->vk,
51 &lvp_cmd_buffer_ops, 0);
52 if (result != VK_SUCCESS) {
53 vk_free(&pool->alloc, cmd_buffer);
54 return result;
55 }
56
57 cmd_buffer->device = device;
58
59 *cmd_buffer_out = &cmd_buffer->vk;
60
61 return VK_SUCCESS;
62 }
63
64 static void
lvp_reset_cmd_buffer(struct vk_command_buffer * vk_cmd_buffer,UNUSED VkCommandBufferResetFlags flags)65 lvp_reset_cmd_buffer(struct vk_command_buffer *vk_cmd_buffer,
66 UNUSED VkCommandBufferResetFlags flags)
67 {
68 vk_command_buffer_reset(vk_cmd_buffer);
69 }
70
71 const struct vk_command_buffer_ops lvp_cmd_buffer_ops = {
72 .create = lvp_create_cmd_buffer,
73 .reset = lvp_reset_cmd_buffer,
74 .destroy = lvp_cmd_buffer_destroy,
75 };
76
lvp_BeginCommandBuffer(VkCommandBuffer commandBuffer,const VkCommandBufferBeginInfo * pBeginInfo)77 VKAPI_ATTR VkResult VKAPI_CALL lvp_BeginCommandBuffer(
78 VkCommandBuffer commandBuffer,
79 const VkCommandBufferBeginInfo* pBeginInfo)
80 {
81 LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
82
83 vk_command_buffer_begin(&cmd_buffer->vk, pBeginInfo);
84
85 return VK_SUCCESS;
86 }
87
lvp_EndCommandBuffer(VkCommandBuffer commandBuffer)88 VKAPI_ATTR VkResult VKAPI_CALL lvp_EndCommandBuffer(
89 VkCommandBuffer commandBuffer)
90 {
91 LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
92
93 return vk_command_buffer_end(&cmd_buffer->vk);
94 }
95
96 static void
lvp_free_CmdPushDescriptorSetWithTemplate2KHR(struct vk_cmd_queue * queue,struct vk_cmd_queue_entry * cmd)97 lvp_free_CmdPushDescriptorSetWithTemplate2KHR(struct vk_cmd_queue *queue, struct vk_cmd_queue_entry *cmd)
98 {
99 struct lvp_device *device = cmd->driver_data;
100 LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, cmd->u.push_descriptor_set_with_template2_khr.push_descriptor_set_with_template_info->descriptorUpdateTemplate);
101 lvp_descriptor_template_templ_unref(device, templ);
102 }
103
lvp_CmdPushDescriptorSetWithTemplate2KHR(VkCommandBuffer commandBuffer,const VkPushDescriptorSetWithTemplateInfoKHR * pPushDescriptorSetWithTemplateInfo)104 VKAPI_ATTR void VKAPI_CALL lvp_CmdPushDescriptorSetWithTemplate2KHR(
105 VkCommandBuffer commandBuffer,
106 const VkPushDescriptorSetWithTemplateInfoKHR* pPushDescriptorSetWithTemplateInfo)
107 {
108 LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
109 LVP_FROM_HANDLE(lvp_descriptor_update_template, templ, pPushDescriptorSetWithTemplateInfo->descriptorUpdateTemplate);
110 size_t info_size = 0;
111 struct vk_cmd_queue_entry *cmd = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc,
112 vk_cmd_queue_type_sizes[VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE2_KHR], 8,
113 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
114 if (!cmd)
115 return;
116
117 cmd->type = VK_CMD_PUSH_DESCRIPTOR_SET_WITH_TEMPLATE2_KHR;
118
119 list_addtail(&cmd->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
120 cmd->driver_free_cb = lvp_free_CmdPushDescriptorSetWithTemplate2KHR;
121 cmd->driver_data = cmd_buffer->device;
122 lvp_descriptor_template_templ_ref(templ);
123 cmd->u.push_descriptor_set_with_template2_khr.push_descriptor_set_with_template_info = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(VkPushDescriptorSetWithTemplateInfoKHR), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
124 memcpy(cmd->u.push_descriptor_set_with_template2_khr.push_descriptor_set_with_template_info, pPushDescriptorSetWithTemplateInfo, sizeof(VkPushDescriptorSetWithTemplateInfoKHR));
125
126 for (unsigned i = 0; i < templ->entry_count; i++) {
127 VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
128
129 switch (entry->descriptorType) {
130 case VK_DESCRIPTOR_TYPE_SAMPLER:
131 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
132 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
133 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
134 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
135 info_size += sizeof(VkDescriptorImageInfo) * entry->descriptorCount;
136 break;
137 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
138 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
139 info_size += sizeof(VkBufferView) * entry->descriptorCount;
140 break;
141 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
142 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
143 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
144 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
145 default:
146 info_size += sizeof(VkDescriptorBufferInfo) * entry->descriptorCount;
147 break;
148 }
149 }
150
151 cmd->u.push_descriptor_set_with_template2_khr.push_descriptor_set_with_template_info->pData = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, info_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
152
153 uint64_t offset = 0;
154 for (unsigned i = 0; i < templ->entry_count; i++) {
155 VkDescriptorUpdateTemplateEntry *entry = &templ->entry[i];
156
157 unsigned size = lvp_descriptor_update_template_entry_size(entry->descriptorType);
158
159 for (unsigned i = 0; i < entry->descriptorCount; i++) {
160 memcpy((uint8_t*)cmd->u.push_descriptor_set_with_template2_khr.push_descriptor_set_with_template_info->pData + offset, (const uint8_t*)pPushDescriptorSetWithTemplateInfo->pData + entry->offset + i * entry->stride, size);
161 offset += size;
162 }
163 }
164 }
165
166
167 static void
vk_free_cmd_push_constants2_khr(struct vk_cmd_queue * queue,struct vk_cmd_queue_entry * cmd)168 vk_free_cmd_push_constants2_khr(struct vk_cmd_queue *queue,
169 struct vk_cmd_queue_entry *cmd)
170 {
171 vk_free(queue->alloc, (void*)cmd->u.push_constants2_khr.push_constants_info->pValues);
172 vk_free(queue->alloc, (VkPushConstantsInfoKHR*)cmd->u.push_constants2_khr.push_constants_info);
173 vk_free(queue->alloc, cmd);
174 }
175
lvp_CmdPushConstants2KHR(VkCommandBuffer commandBuffer,const VkPushConstantsInfoKHR * pPushConstantsInfo)176 VKAPI_ATTR void VKAPI_CALL lvp_CmdPushConstants2KHR(
177 VkCommandBuffer commandBuffer,
178 const VkPushConstantsInfoKHR* pPushConstantsInfo)
179 {
180 LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
181 struct vk_cmd_queue_entry *cmd = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, vk_cmd_queue_type_sizes[VK_CMD_PUSH_CONSTANTS2_KHR], 8,
182 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
183 if (!cmd)
184 return;
185
186 cmd->type = VK_CMD_PUSH_CONSTANTS2_KHR;
187
188 cmd->u.push_constants2_khr.push_constants_info = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(VkPushConstantsInfoKHR), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
189 memcpy((void*)cmd->u.push_constants2_khr.push_constants_info, pPushConstantsInfo, sizeof(VkPushConstantsInfoKHR));
190
191 cmd->u.push_constants2_khr.push_constants_info->pValues = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, pPushConstantsInfo->size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
192 memcpy((void*)cmd->u.push_constants2_khr.push_constants_info->pValues, pPushConstantsInfo->pValues, pPushConstantsInfo->size);
193
194 list_addtail(&cmd->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
195 }
196
197
198 static void
lvp_free_cmd_push_descriptor_set2_khr(struct vk_cmd_queue * queue,struct vk_cmd_queue_entry * cmd)199 lvp_free_cmd_push_descriptor_set2_khr(struct vk_cmd_queue *queue,
200 struct vk_cmd_queue_entry *cmd)
201 {
202 ralloc_free(cmd->driver_data);
203 }
204
lvp_CmdPushDescriptorSet2KHR(VkCommandBuffer commandBuffer,const VkPushDescriptorSetInfoKHR * pPushDescriptorSetInfo)205 VKAPI_ATTR void VKAPI_CALL lvp_CmdPushDescriptorSet2KHR(
206 VkCommandBuffer commandBuffer,
207 const VkPushDescriptorSetInfoKHR* pPushDescriptorSetInfo)
208 {
209 LVP_FROM_HANDLE(lvp_cmd_buffer, cmd_buffer, commandBuffer);
210 struct vk_cmd_queue_entry *cmd = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, vk_cmd_queue_type_sizes[VK_CMD_PUSH_DESCRIPTOR_SET2_KHR], 8,
211 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
212
213 cmd->type = VK_CMD_PUSH_DESCRIPTOR_SET2_KHR;
214 cmd->driver_free_cb = lvp_free_cmd_push_descriptor_set2_khr;
215
216 void *ctx = cmd->driver_data = ralloc_context(NULL);
217 if (pPushDescriptorSetInfo) {
218 cmd->u.push_descriptor_set2_khr.push_descriptor_set_info = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(VkPushDescriptorSetInfoKHR), 8,
219 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
220
221 memcpy((void*)cmd->u.push_descriptor_set2_khr.push_descriptor_set_info, pPushDescriptorSetInfo, sizeof(VkPushDescriptorSetInfoKHR));
222 VkPushDescriptorSetInfoKHR *tmp_dst1 = (void *) cmd->u.push_descriptor_set2_khr.push_descriptor_set_info; (void) tmp_dst1;
223 VkPushDescriptorSetInfoKHR *tmp_src1 = (void *) pPushDescriptorSetInfo; (void) tmp_src1;
224
225 const VkBaseInStructure *pnext = tmp_dst1->pNext;
226 if (pnext) {
227 switch ((int32_t)pnext->sType) {
228 case VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO:
229 if (pnext) {
230 tmp_dst1->pNext = rzalloc(ctx, VkPipelineLayoutCreateInfo);
231
232 memcpy((void*)tmp_dst1->pNext, pnext, sizeof(VkPipelineLayoutCreateInfo));
233 VkPipelineLayoutCreateInfo *tmp_dst2 = (void *) tmp_dst1->pNext; (void) tmp_dst2;
234 VkPipelineLayoutCreateInfo *tmp_src2 = (void *) pnext; (void) tmp_src2;
235 if (tmp_src2->pSetLayouts) {
236 tmp_dst2->pSetLayouts = rzalloc_array_size(ctx, sizeof(*tmp_dst2->pSetLayouts), tmp_dst2->setLayoutCount);
237
238 memcpy((void*)tmp_dst2->pSetLayouts, tmp_src2->pSetLayouts, sizeof(*tmp_dst2->pSetLayouts) * tmp_dst2->setLayoutCount);
239 }
240 if (tmp_src2->pPushConstantRanges) {
241 tmp_dst2->pPushConstantRanges = rzalloc_array_size(ctx, sizeof(*tmp_dst2->pPushConstantRanges), tmp_dst2->pushConstantRangeCount);
242
243 memcpy((void*)tmp_dst2->pPushConstantRanges, tmp_src2->pPushConstantRanges, sizeof(*tmp_dst2->pPushConstantRanges) * tmp_dst2->pushConstantRangeCount);
244 }
245
246 } else {
247 tmp_dst1->pNext = NULL;
248 }
249 break;
250 }
251 }
252 if (tmp_src1->pDescriptorWrites) {
253 tmp_dst1->pDescriptorWrites = vk_zalloc(cmd_buffer->vk.cmd_queue.alloc, sizeof(*tmp_dst1->pDescriptorWrites) * tmp_dst1->descriptorWriteCount, 8,
254 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
255
256 memcpy((void*)tmp_dst1->pDescriptorWrites, tmp_src1->pDescriptorWrites, sizeof(*tmp_dst1->pDescriptorWrites) * tmp_dst1->descriptorWriteCount);
257 for (unsigned i = 0; i < tmp_src1->descriptorWriteCount; i++) {
258 VkWriteDescriptorSet *dstwrite = (void*)&tmp_dst1->pDescriptorWrites[i];
259 const VkWriteDescriptorSet *write = &tmp_src1->pDescriptorWrites[i];
260 switch (write->descriptorType) {
261 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK: {
262 const VkWriteDescriptorSetInlineUniformBlock *uniform_data = vk_find_struct_const(write->pNext, WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK);
263 assert(uniform_data);
264 VkWriteDescriptorSetInlineUniformBlock *dst = rzalloc(ctx, VkWriteDescriptorSetInlineUniformBlock);
265 memcpy((void*)dst, uniform_data, sizeof(*uniform_data));
266 dst->pData = ralloc_size(ctx, uniform_data->dataSize);
267 memcpy((void*)dst->pData, uniform_data->pData, uniform_data->dataSize);
268 dstwrite->pNext = dst;
269 break;
270 }
271
272 case VK_DESCRIPTOR_TYPE_SAMPLER:
273 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
274 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
275 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
276 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
277 dstwrite->pImageInfo = rzalloc_array(ctx, VkDescriptorImageInfo, write->descriptorCount);
278 {
279 VkDescriptorImageInfo *arr = (void*)dstwrite->pImageInfo;
280 typed_memcpy(arr, write->pImageInfo, write->descriptorCount);
281 }
282 break;
283
284 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
285 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
286 dstwrite->pTexelBufferView = rzalloc_array(ctx, VkBufferView, write->descriptorCount);
287 {
288 VkBufferView *arr = (void*)dstwrite->pTexelBufferView;
289 typed_memcpy(arr, write->pTexelBufferView, write->descriptorCount);
290 }
291 break;
292
293 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
294 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
295 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
296 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
297 dstwrite->pBufferInfo = rzalloc_array(ctx, VkDescriptorBufferInfo, write->descriptorCount);
298 {
299 VkDescriptorBufferInfo *arr = (void*)dstwrite->pBufferInfo;
300 typed_memcpy(arr, write->pBufferInfo, write->descriptorCount);
301 }
302 break;
303
304 default:
305 break;
306 }
307 }
308 }
309
310 } else {
311 cmd->u.push_descriptor_set2_khr.push_descriptor_set_info = NULL;
312 }
313
314 list_addtail(&cmd->cmd_link, &cmd_buffer->vk.cmd_queue.cmds);
315 }
316