nir: Add options to nir_lower_compute_system_values to control compute ID base lowering
[mesa.git] / src / gallium / frontends / vallium / val_cmd_buffer.c
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 "val_private.h"
25 #include "pipe/p_context.h"
26
27 static VkResult val_create_cmd_buffer(
28 struct val_device * device,
29 struct val_cmd_pool * pool,
30 VkCommandBufferLevel level,
31 VkCommandBuffer* pCommandBuffer)
32 {
33 struct val_cmd_buffer *cmd_buffer;
34
35 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
36 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
37 if (cmd_buffer == NULL)
38 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
39
40 vk_object_base_init(&device->vk, &cmd_buffer->base,
41 VK_OBJECT_TYPE_COMMAND_BUFFER);
42 cmd_buffer->device = device;
43 cmd_buffer->pool = pool;
44 list_inithead(&cmd_buffer->cmds);
45 cmd_buffer->status = VAL_CMD_BUFFER_STATUS_INITIAL;
46 if (pool) {
47 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
48 } else {
49 /* Init the pool_link so we can safefly call list_del when we destroy
50 * the command buffer
51 */
52 list_inithead(&cmd_buffer->pool_link);
53 }
54 *pCommandBuffer = val_cmd_buffer_to_handle(cmd_buffer);
55
56 return VK_SUCCESS;
57 }
58
59 static void
60 val_cmd_buffer_free_all_cmds(struct val_cmd_buffer *cmd_buffer)
61 {
62 struct val_cmd_buffer_entry *tmp, *cmd;
63 LIST_FOR_EACH_ENTRY_SAFE(cmd, tmp, &cmd_buffer->cmds, cmd_link) {
64 list_del(&cmd->cmd_link);
65 vk_free(&cmd_buffer->pool->alloc, cmd);
66 }
67 }
68
69 static VkResult val_reset_cmd_buffer(struct val_cmd_buffer *cmd_buffer)
70 {
71 val_cmd_buffer_free_all_cmds(cmd_buffer);
72 list_inithead(&cmd_buffer->cmds);
73 cmd_buffer->status = VAL_CMD_BUFFER_STATUS_INITIAL;
74 return VK_SUCCESS;
75 }
76
77 VkResult val_AllocateCommandBuffers(
78 VkDevice _device,
79 const VkCommandBufferAllocateInfo* pAllocateInfo,
80 VkCommandBuffer* pCommandBuffers)
81 {
82 VAL_FROM_HANDLE(val_device, device, _device);
83 VAL_FROM_HANDLE(val_cmd_pool, pool, pAllocateInfo->commandPool);
84
85 VkResult result = VK_SUCCESS;
86 uint32_t i;
87
88 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
89
90 if (!list_is_empty(&pool->free_cmd_buffers)) {
91 struct val_cmd_buffer *cmd_buffer = list_first_entry(&pool->free_cmd_buffers, struct val_cmd_buffer, pool_link);
92
93 list_del(&cmd_buffer->pool_link);
94 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
95
96 result = val_reset_cmd_buffer(cmd_buffer);
97 cmd_buffer->level = pAllocateInfo->level;
98
99 pCommandBuffers[i] = val_cmd_buffer_to_handle(cmd_buffer);
100 } else {
101 result = val_create_cmd_buffer(device, pool, pAllocateInfo->level,
102 &pCommandBuffers[i]);
103 if (result != VK_SUCCESS)
104 break;
105 }
106 }
107
108 if (result != VK_SUCCESS) {
109 val_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
110 i, pCommandBuffers);
111 memset(pCommandBuffers, 0,
112 sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
113 }
114
115 return result;
116 }
117
118 static void
119 val_cmd_buffer_destroy(struct val_cmd_buffer *cmd_buffer)
120 {
121 val_cmd_buffer_free_all_cmds(cmd_buffer);
122 list_del(&cmd_buffer->pool_link);
123 vk_object_base_finish(&cmd_buffer->base);
124 vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
125 }
126
127 void val_FreeCommandBuffers(
128 VkDevice device,
129 VkCommandPool commandPool,
130 uint32_t commandBufferCount,
131 const VkCommandBuffer* pCommandBuffers)
132 {
133 for (uint32_t i = 0; i < commandBufferCount; i++) {
134 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
135
136 if (cmd_buffer) {
137 if (cmd_buffer->pool) {
138 list_del(&cmd_buffer->pool_link);
139 list_addtail(&cmd_buffer->pool_link, &cmd_buffer->pool->free_cmd_buffers);
140 } else
141 val_cmd_buffer_destroy(cmd_buffer);
142 }
143 }
144 }
145
146 VkResult val_ResetCommandBuffer(
147 VkCommandBuffer commandBuffer,
148 VkCommandBufferResetFlags flags)
149 {
150 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
151
152 return val_reset_cmd_buffer(cmd_buffer);
153 }
154
155 VkResult val_BeginCommandBuffer(
156 VkCommandBuffer commandBuffer,
157 const VkCommandBufferBeginInfo* pBeginInfo)
158 {
159 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
160 VkResult result;
161 if (cmd_buffer->status != VAL_CMD_BUFFER_STATUS_INITIAL) {
162 result = val_reset_cmd_buffer(cmd_buffer);
163 if (result != VK_SUCCESS)
164 return result;
165 }
166 cmd_buffer->status = VAL_CMD_BUFFER_STATUS_RECORDING;
167 return VK_SUCCESS;
168 }
169
170 VkResult val_EndCommandBuffer(
171 VkCommandBuffer commandBuffer)
172 {
173 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
174 cmd_buffer->status = VAL_CMD_BUFFER_STATUS_EXECUTABLE;
175 return VK_SUCCESS;
176 }
177
178 VkResult val_CreateCommandPool(
179 VkDevice _device,
180 const VkCommandPoolCreateInfo* pCreateInfo,
181 const VkAllocationCallbacks* pAllocator,
182 VkCommandPool* pCmdPool)
183 {
184 VAL_FROM_HANDLE(val_device, device, _device);
185 struct val_cmd_pool *pool;
186
187 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
188 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
189 if (pool == NULL)
190 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
191
192 vk_object_base_init(&device->vk, &pool->base,
193 VK_OBJECT_TYPE_COMMAND_POOL);
194 if (pAllocator)
195 pool->alloc = *pAllocator;
196 else
197 pool->alloc = device->alloc;
198
199 list_inithead(&pool->cmd_buffers);
200 list_inithead(&pool->free_cmd_buffers);
201
202 *pCmdPool = val_cmd_pool_to_handle(pool);
203
204 return VK_SUCCESS;
205 }
206
207 void val_DestroyCommandPool(
208 VkDevice _device,
209 VkCommandPool commandPool,
210 const VkAllocationCallbacks* pAllocator)
211 {
212 VAL_FROM_HANDLE(val_device, device, _device);
213 VAL_FROM_HANDLE(val_cmd_pool, pool, commandPool);
214
215 if (!pool)
216 return;
217
218 list_for_each_entry_safe(struct val_cmd_buffer, cmd_buffer,
219 &pool->cmd_buffers, pool_link) {
220 val_cmd_buffer_destroy(cmd_buffer);
221 }
222
223 list_for_each_entry_safe(struct val_cmd_buffer, cmd_buffer,
224 &pool->free_cmd_buffers, pool_link) {
225 val_cmd_buffer_destroy(cmd_buffer);
226 }
227
228 vk_object_base_finish(&pool->base);
229 vk_free2(&device->alloc, pAllocator, pool);
230 }
231
232 VkResult val_ResetCommandPool(
233 VkDevice device,
234 VkCommandPool commandPool,
235 VkCommandPoolResetFlags flags)
236 {
237 VAL_FROM_HANDLE(val_cmd_pool, pool, commandPool);
238 VkResult result;
239
240 list_for_each_entry(struct val_cmd_buffer, cmd_buffer,
241 &pool->cmd_buffers, pool_link) {
242 result = val_reset_cmd_buffer(cmd_buffer);
243 if (result != VK_SUCCESS)
244 return result;
245 }
246 return VK_SUCCESS;
247 }
248
249 void val_TrimCommandPool(
250 VkDevice device,
251 VkCommandPool commandPool,
252 VkCommandPoolTrimFlags flags)
253 {
254 VAL_FROM_HANDLE(val_cmd_pool, pool, commandPool);
255
256 if (!pool)
257 return;
258
259 list_for_each_entry_safe(struct val_cmd_buffer, cmd_buffer,
260 &pool->free_cmd_buffers, pool_link) {
261 val_cmd_buffer_destroy(cmd_buffer);
262 }
263 }
264
265 static struct val_cmd_buffer_entry *cmd_buf_entry_alloc_size(struct val_cmd_buffer *cmd_buffer,
266 uint32_t extra_size,
267 enum val_cmds type)
268 {
269 struct val_cmd_buffer_entry *cmd;
270 uint32_t cmd_size = sizeof(*cmd) + extra_size;
271 cmd = vk_alloc(&cmd_buffer->pool->alloc,
272 cmd_size,
273 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
274 if (!cmd)
275 return NULL;
276
277 cmd->cmd_type = type;
278 return cmd;
279 }
280
281 static struct val_cmd_buffer_entry *cmd_buf_entry_alloc(struct val_cmd_buffer *cmd_buffer,
282 enum val_cmds type)
283 {
284 return cmd_buf_entry_alloc_size(cmd_buffer, 0, type);
285 }
286
287 static void cmd_buf_queue(struct val_cmd_buffer *cmd_buffer,
288 struct val_cmd_buffer_entry *cmd)
289 {
290 list_addtail(&cmd->cmd_link, &cmd_buffer->cmds);
291 }
292
293 static void
294 state_setup_attachments(struct val_attachment_state *attachments,
295 struct val_render_pass *pass,
296 const VkClearValue *clear_values)
297 {
298 for (uint32_t i = 0; i < pass->attachment_count; ++i) {
299 struct val_render_pass_attachment *att = &pass->attachments[i];
300 VkImageAspectFlags att_aspects = vk_format_aspects(att->format);
301 VkImageAspectFlags clear_aspects = 0;
302 if (att_aspects == VK_IMAGE_ASPECT_COLOR_BIT) {
303 /* color attachment */
304 if (att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
305 clear_aspects |= VK_IMAGE_ASPECT_COLOR_BIT;
306 }
307 } else {
308 /* depthstencil attachment */
309 if ((att_aspects & VK_IMAGE_ASPECT_DEPTH_BIT) &&
310 att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
311 clear_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT;
312 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
313 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_DONT_CARE)
314 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
315 }
316 if ((att_aspects & VK_IMAGE_ASPECT_STENCIL_BIT) &&
317 att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) {
318 clear_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT;
319 }
320 }
321 attachments[i].pending_clear_aspects = clear_aspects;
322 if (clear_values)
323 attachments[i].clear_value = clear_values[i];
324 }
325 }
326
327 void val_CmdBeginRenderPass(
328 VkCommandBuffer commandBuffer,
329 const VkRenderPassBeginInfo* pRenderPassBegin,
330 VkSubpassContents contents)
331 {
332 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
333 VAL_FROM_HANDLE(val_render_pass, pass, pRenderPassBegin->renderPass);
334 VAL_FROM_HANDLE(val_framebuffer, framebuffer, pRenderPassBegin->framebuffer);
335 struct val_cmd_buffer_entry *cmd;
336 uint32_t cmd_size = pass->attachment_count * sizeof(struct val_attachment_state);
337
338 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_BEGIN_RENDER_PASS);
339 if (!cmd)
340 return;
341
342 cmd->u.begin_render_pass.render_pass = pass;
343 cmd->u.begin_render_pass.framebuffer = framebuffer;
344 cmd->u.begin_render_pass.render_area = pRenderPassBegin->renderArea;
345
346 cmd->u.begin_render_pass.attachments = (struct val_attachment_state *)(cmd + 1);
347 state_setup_attachments(cmd->u.begin_render_pass.attachments, pass, pRenderPassBegin->pClearValues);
348
349 cmd_buf_queue(cmd_buffer, cmd);
350 }
351
352 void val_CmdNextSubpass(
353 VkCommandBuffer commandBuffer,
354 VkSubpassContents contents)
355 {
356 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
357 struct val_cmd_buffer_entry *cmd;
358
359 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_NEXT_SUBPASS);
360 if (!cmd)
361 return;
362
363 cmd->u.next_subpass.contents = contents;
364
365 cmd_buf_queue(cmd_buffer, cmd);
366 }
367
368 void val_CmdBindVertexBuffers(
369 VkCommandBuffer commandBuffer,
370 uint32_t firstBinding,
371 uint32_t bindingCount,
372 const VkBuffer* pBuffers,
373 const VkDeviceSize* pOffsets)
374 {
375 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
376 struct val_cmd_buffer_entry *cmd;
377 struct val_buffer **buffers;
378 VkDeviceSize *offsets;
379 int i;
380 uint32_t cmd_size = bindingCount * sizeof(struct val_buffer *) + bindingCount * sizeof(VkDeviceSize);
381
382 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_BIND_VERTEX_BUFFERS);
383 if (!cmd)
384 return;
385
386 cmd->u.vertex_buffers.first = firstBinding;
387 cmd->u.vertex_buffers.binding_count = bindingCount;
388
389 buffers = (struct val_buffer **)(cmd + 1);
390 offsets = (VkDeviceSize *)(buffers + bindingCount);
391 for (i = 0; i < bindingCount; i++) {
392 buffers[i] = val_buffer_from_handle(pBuffers[i]);
393 offsets[i] = pOffsets[i];
394 }
395 cmd->u.vertex_buffers.buffers = buffers;
396 cmd->u.vertex_buffers.offsets = offsets;
397
398 cmd_buf_queue(cmd_buffer, cmd);
399 }
400
401 void val_CmdBindPipeline(
402 VkCommandBuffer commandBuffer,
403 VkPipelineBindPoint pipelineBindPoint,
404 VkPipeline _pipeline)
405 {
406 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
407 VAL_FROM_HANDLE(val_pipeline, pipeline, _pipeline);
408 struct val_cmd_buffer_entry *cmd;
409
410 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_BIND_PIPELINE);
411 if (!cmd)
412 return;
413
414 cmd->u.pipeline.bind_point = pipelineBindPoint;
415 cmd->u.pipeline.pipeline = pipeline;
416
417 cmd_buf_queue(cmd_buffer, cmd);
418 }
419
420 void val_CmdBindDescriptorSets(
421 VkCommandBuffer commandBuffer,
422 VkPipelineBindPoint pipelineBindPoint,
423 VkPipelineLayout _layout,
424 uint32_t firstSet,
425 uint32_t descriptorSetCount,
426 const VkDescriptorSet* pDescriptorSets,
427 uint32_t dynamicOffsetCount,
428 const uint32_t* pDynamicOffsets)
429 {
430 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
431 VAL_FROM_HANDLE(val_pipeline_layout, layout, _layout);
432 struct val_cmd_buffer_entry *cmd;
433 struct val_descriptor_set **sets;
434 uint32_t *offsets;
435 int i;
436 uint32_t cmd_size = descriptorSetCount * sizeof(struct val_descriptor_set *) + dynamicOffsetCount * sizeof(uint32_t);
437
438 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_BIND_DESCRIPTOR_SETS);
439 if (!cmd)
440 return;
441
442 cmd->u.descriptor_sets.bind_point = pipelineBindPoint;
443 cmd->u.descriptor_sets.layout = layout;
444 cmd->u.descriptor_sets.first = firstSet;
445 cmd->u.descriptor_sets.count = descriptorSetCount;
446
447 sets = (struct val_descriptor_set **)(cmd + 1);
448 for (i = 0; i < descriptorSetCount; i++) {
449 sets[i] = val_descriptor_set_from_handle(pDescriptorSets[i]);
450 }
451 cmd->u.descriptor_sets.sets = sets;
452
453 cmd->u.descriptor_sets.dynamic_offset_count = dynamicOffsetCount;
454 offsets = (uint32_t *)(sets + descriptorSetCount);
455 for (i = 0; i < dynamicOffsetCount; i++)
456 offsets[i] = pDynamicOffsets[i];
457 cmd->u.descriptor_sets.dynamic_offsets = offsets;
458
459 cmd_buf_queue(cmd_buffer, cmd);
460 }
461
462 void val_CmdDraw(
463 VkCommandBuffer commandBuffer,
464 uint32_t vertexCount,
465 uint32_t instanceCount,
466 uint32_t firstVertex,
467 uint32_t firstInstance)
468 {
469 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
470 struct val_cmd_buffer_entry *cmd;
471
472 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DRAW);
473 if (!cmd)
474 return;
475
476 cmd->u.draw.vertex_count = vertexCount;
477 cmd->u.draw.instance_count = instanceCount;
478 cmd->u.draw.first_vertex = firstVertex;
479 cmd->u.draw.first_instance = firstInstance;
480
481 cmd_buf_queue(cmd_buffer, cmd);
482 }
483
484 void val_CmdEndRenderPass(
485 VkCommandBuffer commandBuffer)
486 {
487 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
488 struct val_cmd_buffer_entry *cmd;
489
490 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_END_RENDER_PASS);
491 if (!cmd)
492 return;
493
494 cmd_buf_queue(cmd_buffer, cmd);
495 }
496
497 void val_CmdSetViewport(
498 VkCommandBuffer commandBuffer,
499 uint32_t firstViewport,
500 uint32_t viewportCount,
501 const VkViewport* pViewports)
502 {
503 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
504 struct val_cmd_buffer_entry *cmd;
505 int i;
506
507 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_VIEWPORT);
508 if (!cmd)
509 return;
510
511 cmd->u.set_viewport.first_viewport = firstViewport;
512 cmd->u.set_viewport.viewport_count = viewportCount;
513 for (i = 0; i < viewportCount; i++)
514 cmd->u.set_viewport.viewports[i] = pViewports[i];
515
516 cmd_buf_queue(cmd_buffer, cmd);
517 }
518
519 void val_CmdSetScissor(
520 VkCommandBuffer commandBuffer,
521 uint32_t firstScissor,
522 uint32_t scissorCount,
523 const VkRect2D* pScissors)
524 {
525 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
526 struct val_cmd_buffer_entry *cmd;
527 int i;
528
529 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_SCISSOR);
530 if (!cmd)
531 return;
532
533 cmd->u.set_scissor.first_scissor = firstScissor;
534 cmd->u.set_scissor.scissor_count = scissorCount;
535 for (i = 0; i < scissorCount; i++)
536 cmd->u.set_scissor.scissors[i] = pScissors[i];
537
538 cmd_buf_queue(cmd_buffer, cmd);
539 }
540
541 void val_CmdSetLineWidth(
542 VkCommandBuffer commandBuffer,
543 float lineWidth)
544 {
545 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
546 struct val_cmd_buffer_entry *cmd;
547
548 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_LINE_WIDTH);
549 if (!cmd)
550 return;
551
552 cmd->u.set_line_width.line_width = lineWidth;
553
554 cmd_buf_queue(cmd_buffer, cmd);
555 }
556
557 void val_CmdSetDepthBias(
558 VkCommandBuffer commandBuffer,
559 float depthBiasConstantFactor,
560 float depthBiasClamp,
561 float depthBiasSlopeFactor)
562 {
563 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
564 struct val_cmd_buffer_entry *cmd;
565
566 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_DEPTH_BIAS);
567 if (!cmd)
568 return;
569
570 cmd->u.set_depth_bias.constant_factor = depthBiasConstantFactor;
571 cmd->u.set_depth_bias.clamp = depthBiasClamp;
572 cmd->u.set_depth_bias.slope_factor = depthBiasSlopeFactor;
573
574 cmd_buf_queue(cmd_buffer, cmd);
575 }
576
577 void val_CmdSetBlendConstants(
578 VkCommandBuffer commandBuffer,
579 const float blendConstants[4])
580 {
581 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
582 struct val_cmd_buffer_entry *cmd;
583
584 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_BLEND_CONSTANTS);
585 if (!cmd)
586 return;
587
588 memcpy(cmd->u.set_blend_constants.blend_constants, blendConstants, 4 * sizeof(float));
589
590 cmd_buf_queue(cmd_buffer, cmd);
591 }
592
593 void val_CmdSetDepthBounds(
594 VkCommandBuffer commandBuffer,
595 float minDepthBounds,
596 float maxDepthBounds)
597 {
598 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
599 struct val_cmd_buffer_entry *cmd;
600
601 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_DEPTH_BOUNDS);
602 if (!cmd)
603 return;
604
605 cmd->u.set_depth_bounds.min_depth = minDepthBounds;
606 cmd->u.set_depth_bounds.max_depth = maxDepthBounds;
607
608 cmd_buf_queue(cmd_buffer, cmd);
609 }
610
611 void val_CmdSetStencilCompareMask(
612 VkCommandBuffer commandBuffer,
613 VkStencilFaceFlags faceMask,
614 uint32_t compareMask)
615 {
616 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
617 struct val_cmd_buffer_entry *cmd;
618
619 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_STENCIL_COMPARE_MASK);
620 if (!cmd)
621 return;
622
623 cmd->u.stencil_vals.face_mask = faceMask;
624 cmd->u.stencil_vals.value = compareMask;
625
626 cmd_buf_queue(cmd_buffer, cmd);
627 }
628
629 void val_CmdSetStencilWriteMask(
630 VkCommandBuffer commandBuffer,
631 VkStencilFaceFlags faceMask,
632 uint32_t writeMask)
633 {
634 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
635 struct val_cmd_buffer_entry *cmd;
636
637 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_STENCIL_WRITE_MASK);
638 if (!cmd)
639 return;
640
641 cmd->u.stencil_vals.face_mask = faceMask;
642 cmd->u.stencil_vals.value = writeMask;
643
644 cmd_buf_queue(cmd_buffer, cmd);
645 }
646
647
648 void val_CmdSetStencilReference(
649 VkCommandBuffer commandBuffer,
650 VkStencilFaceFlags faceMask,
651 uint32_t reference)
652 {
653 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
654 struct val_cmd_buffer_entry *cmd;
655
656 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_STENCIL_REFERENCE);
657 if (!cmd)
658 return;
659
660 cmd->u.stencil_vals.face_mask = faceMask;
661 cmd->u.stencil_vals.value = reference;
662
663 cmd_buf_queue(cmd_buffer, cmd);
664 }
665
666 void val_CmdPushConstants(
667 VkCommandBuffer commandBuffer,
668 VkPipelineLayout layout,
669 VkShaderStageFlags stageFlags,
670 uint32_t offset,
671 uint32_t size,
672 const void* pValues)
673 {
674 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
675 struct val_cmd_buffer_entry *cmd;
676
677 cmd = cmd_buf_entry_alloc_size(cmd_buffer, (size - 4), VAL_CMD_PUSH_CONSTANTS);
678 if (!cmd)
679 return;
680
681 cmd->u.push_constants.stage = stageFlags;
682 cmd->u.push_constants.offset = offset;
683 cmd->u.push_constants.size = size;
684 memcpy(cmd->u.push_constants.val, pValues, size);
685
686 cmd_buf_queue(cmd_buffer, cmd);
687 }
688
689 void val_CmdBindIndexBuffer(
690 VkCommandBuffer commandBuffer,
691 VkBuffer _buffer,
692 VkDeviceSize offset,
693 VkIndexType indexType)
694 {
695 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
696 VAL_FROM_HANDLE(val_buffer, buffer, _buffer);
697 struct val_cmd_buffer_entry *cmd;
698
699 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_BIND_INDEX_BUFFER);
700 if (!cmd)
701 return;
702
703 cmd->u.index_buffer.buffer = buffer;
704 cmd->u.index_buffer.offset = offset;
705 cmd->u.index_buffer.index_type = indexType;
706
707 cmd_buf_queue(cmd_buffer, cmd);
708 }
709
710 void val_CmdDrawIndexed(
711 VkCommandBuffer commandBuffer,
712 uint32_t indexCount,
713 uint32_t instanceCount,
714 uint32_t firstIndex,
715 int32_t vertexOffset,
716 uint32_t firstInstance)
717 {
718 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
719 struct val_cmd_buffer_entry *cmd;
720
721 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DRAW_INDEXED);
722 if (!cmd)
723 return;
724
725 cmd->u.draw_indexed.index_count = indexCount;
726 cmd->u.draw_indexed.instance_count = instanceCount;
727 cmd->u.draw_indexed.first_index = firstIndex;
728 cmd->u.draw_indexed.vertex_offset = vertexOffset;
729 cmd->u.draw_indexed.first_instance = firstInstance;
730
731 cmd_buf_queue(cmd_buffer, cmd);
732 }
733
734 void val_CmdDrawIndirect(
735 VkCommandBuffer commandBuffer,
736 VkBuffer _buffer,
737 VkDeviceSize offset,
738 uint32_t drawCount,
739 uint32_t stride)
740 {
741 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
742 VAL_FROM_HANDLE(val_buffer, buf, _buffer);
743 struct val_cmd_buffer_entry *cmd;
744
745 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DRAW_INDIRECT);
746 if (!cmd)
747 return;
748
749 cmd->u.draw_indirect.offset = offset;
750 cmd->u.draw_indirect.buffer = buf;
751 cmd->u.draw_indirect.draw_count = drawCount;
752 cmd->u.draw_indirect.stride = stride;
753
754 cmd_buf_queue(cmd_buffer, cmd);
755 }
756
757 void val_CmdDrawIndexedIndirect(
758 VkCommandBuffer commandBuffer,
759 VkBuffer _buffer,
760 VkDeviceSize offset,
761 uint32_t drawCount,
762 uint32_t stride)
763 {
764 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
765 VAL_FROM_HANDLE(val_buffer, buf, _buffer);
766 struct val_cmd_buffer_entry *cmd;
767
768 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DRAW_INDEXED_INDIRECT);
769 if (!cmd)
770 return;
771
772 cmd->u.draw_indirect.offset = offset;
773 cmd->u.draw_indirect.buffer = buf;
774 cmd->u.draw_indirect.draw_count = drawCount;
775 cmd->u.draw_indirect.stride = stride;
776
777 cmd_buf_queue(cmd_buffer, cmd);
778 }
779
780 void val_CmdDispatch(
781 VkCommandBuffer commandBuffer,
782 uint32_t x,
783 uint32_t y,
784 uint32_t z)
785 {
786 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
787 struct val_cmd_buffer_entry *cmd;
788
789 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DISPATCH);
790 if (!cmd)
791 return;
792
793 cmd->u.dispatch.x = x;
794 cmd->u.dispatch.y = y;
795 cmd->u.dispatch.z = z;
796
797 cmd_buf_queue(cmd_buffer, cmd);
798 }
799
800 void val_CmdDispatchIndirect(
801 VkCommandBuffer commandBuffer,
802 VkBuffer _buffer,
803 VkDeviceSize offset)
804 {
805 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
806 struct val_cmd_buffer_entry *cmd;
807
808 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_DISPATCH_INDIRECT);
809 if (!cmd)
810 return;
811
812 cmd->u.dispatch_indirect.buffer = val_buffer_from_handle(_buffer);
813 cmd->u.dispatch_indirect.offset = offset;
814
815 cmd_buf_queue(cmd_buffer, cmd);
816 }
817
818 void val_CmdExecuteCommands(
819 VkCommandBuffer commandBuffer,
820 uint32_t commandBufferCount,
821 const VkCommandBuffer* pCmdBuffers)
822 {
823 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
824 struct val_cmd_buffer_entry *cmd;
825 uint32_t cmd_size = commandBufferCount * sizeof(struct val_cmd_buffer *);
826
827 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_EXECUTE_COMMANDS);
828 if (!cmd)
829 return;
830
831 cmd->u.execute_commands.command_buffer_count = commandBufferCount;
832 for (unsigned i = 0; i < commandBufferCount; i++)
833 cmd->u.execute_commands.cmd_buffers[i] = val_cmd_buffer_from_handle(pCmdBuffers[i]);
834
835 cmd_buf_queue(cmd_buffer, cmd);
836 }
837
838 void val_CmdSetEvent(VkCommandBuffer commandBuffer,
839 VkEvent _event,
840 VkPipelineStageFlags stageMask)
841 {
842 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
843 VAL_FROM_HANDLE(val_event, event, _event);
844 struct val_cmd_buffer_entry *cmd;
845
846 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_EVENT);
847 if (!cmd)
848 return;
849
850 cmd->u.event_set.event = event;
851 cmd->u.event_set.value = true;
852 cmd->u.event_set.flush = !!(stageMask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
853
854 cmd_buf_queue(cmd_buffer, cmd);
855 }
856
857 void val_CmdResetEvent(VkCommandBuffer commandBuffer,
858 VkEvent _event,
859 VkPipelineStageFlags stageMask)
860 {
861 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
862 VAL_FROM_HANDLE(val_event, event, _event);
863 struct val_cmd_buffer_entry *cmd;
864
865 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_SET_EVENT);
866 if (!cmd)
867 return;
868
869 cmd->u.event_set.event = event;
870 cmd->u.event_set.value = false;
871 cmd->u.event_set.flush = !!(stageMask == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
872
873 cmd_buf_queue(cmd_buffer, cmd);
874
875 }
876
877 void val_CmdWaitEvents(VkCommandBuffer commandBuffer,
878 uint32_t eventCount,
879 const VkEvent* pEvents,
880 VkPipelineStageFlags srcStageMask,
881 VkPipelineStageFlags dstStageMask,
882 uint32_t memoryBarrierCount,
883 const VkMemoryBarrier* pMemoryBarriers,
884 uint32_t bufferMemoryBarrierCount,
885 const VkBufferMemoryBarrier* pBufferMemoryBarriers,
886 uint32_t imageMemoryBarrierCount,
887 const VkImageMemoryBarrier* pImageMemoryBarriers)
888 {
889 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
890 struct val_cmd_buffer_entry *cmd;
891 uint32_t cmd_size = 0;
892
893 cmd_size += eventCount * sizeof(struct val_event *);
894 cmd_size += memoryBarrierCount * sizeof(VkMemoryBarrier);
895 cmd_size += bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
896 cmd_size += imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
897
898 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_WAIT_EVENTS);
899 if (!cmd)
900 return;
901
902 cmd->u.wait_events.src_stage_mask = srcStageMask;
903 cmd->u.wait_events.dst_stage_mask = dstStageMask;
904 cmd->u.wait_events.event_count = eventCount;
905 cmd->u.wait_events.events = (struct val_event **)(cmd + 1);
906 for (unsigned i = 0; i < eventCount; i++)
907 cmd->u.wait_events.events[i] = val_event_from_handle(pEvents[i]);
908 cmd->u.wait_events.memory_barrier_count = memoryBarrierCount;
909 cmd->u.wait_events.buffer_memory_barrier_count = bufferMemoryBarrierCount;
910 cmd->u.wait_events.image_memory_barrier_count = imageMemoryBarrierCount;
911
912 /* TODO finish off this */
913 cmd_buf_queue(cmd_buffer, cmd);
914 }
915
916
917 void val_CmdCopyBufferToImage(
918 VkCommandBuffer commandBuffer,
919 VkBuffer srcBuffer,
920 VkImage destImage,
921 VkImageLayout destImageLayout,
922 uint32_t regionCount,
923 const VkBufferImageCopy* pRegions)
924 {
925 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
926 VAL_FROM_HANDLE(val_buffer, src_buffer, srcBuffer);
927 VAL_FROM_HANDLE(val_image, dst_image, destImage);
928 struct val_cmd_buffer_entry *cmd;
929 uint32_t cmd_size = regionCount * sizeof(VkBufferImageCopy);
930
931 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_COPY_BUFFER_TO_IMAGE);
932 if (!cmd)
933 return;
934
935 cmd->u.buffer_to_img.src = src_buffer;
936 cmd->u.buffer_to_img.dst = dst_image;
937 cmd->u.buffer_to_img.dst_layout = destImageLayout;
938 cmd->u.buffer_to_img.region_count = regionCount;
939
940 {
941 VkBufferImageCopy *regions;
942
943 regions = (VkBufferImageCopy *)(cmd + 1);
944 memcpy(regions, pRegions, regionCount * sizeof(VkBufferImageCopy));
945 cmd->u.buffer_to_img.regions = regions;
946 }
947
948 cmd_buf_queue(cmd_buffer, cmd);
949 }
950
951 void val_CmdCopyImageToBuffer(
952 VkCommandBuffer commandBuffer,
953 VkImage srcImage,
954 VkImageLayout srcImageLayout,
955 VkBuffer destBuffer,
956 uint32_t regionCount,
957 const VkBufferImageCopy* pRegions)
958 {
959 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
960 VAL_FROM_HANDLE(val_image, src_image, srcImage);
961 VAL_FROM_HANDLE(val_buffer, dst_buffer, destBuffer);
962 struct val_cmd_buffer_entry *cmd;
963 uint32_t cmd_size = regionCount * sizeof(VkBufferImageCopy);
964
965 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_COPY_IMAGE_TO_BUFFER);
966 if (!cmd)
967 return;
968
969 cmd->u.img_to_buffer.src = src_image;
970 cmd->u.img_to_buffer.dst = dst_buffer;
971 cmd->u.img_to_buffer.src_layout = srcImageLayout;
972 cmd->u.img_to_buffer.region_count = regionCount;
973
974 {
975 VkBufferImageCopy *regions;
976
977 regions = (VkBufferImageCopy *)(cmd + 1);
978 memcpy(regions, pRegions, regionCount * sizeof(VkBufferImageCopy));
979 cmd->u.img_to_buffer.regions = regions;
980 }
981
982 cmd_buf_queue(cmd_buffer, cmd);
983 }
984
985 void val_CmdCopyImage(
986 VkCommandBuffer commandBuffer,
987 VkImage srcImage,
988 VkImageLayout srcImageLayout,
989 VkImage destImage,
990 VkImageLayout destImageLayout,
991 uint32_t regionCount,
992 const VkImageCopy* pRegions)
993 {
994 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
995 VAL_FROM_HANDLE(val_image, src_image, srcImage);
996 VAL_FROM_HANDLE(val_image, dest_image, destImage);
997 struct val_cmd_buffer_entry *cmd;
998 uint32_t cmd_size = regionCount * sizeof(VkImageCopy);
999
1000 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_COPY_IMAGE);
1001 if (!cmd)
1002 return;
1003
1004 cmd->u.copy_image.src = src_image;
1005 cmd->u.copy_image.dst = dest_image;
1006 cmd->u.copy_image.src_layout = srcImageLayout;
1007 cmd->u.copy_image.dst_layout = destImageLayout;
1008 cmd->u.copy_image.region_count = regionCount;
1009
1010 {
1011 VkImageCopy *regions;
1012
1013 regions = (VkImageCopy *)(cmd + 1);
1014 memcpy(regions, pRegions, regionCount * sizeof(VkImageCopy));
1015 cmd->u.copy_image.regions = regions;
1016 }
1017
1018 cmd_buf_queue(cmd_buffer, cmd);
1019 }
1020
1021
1022 void val_CmdCopyBuffer(
1023 VkCommandBuffer commandBuffer,
1024 VkBuffer srcBuffer,
1025 VkBuffer destBuffer,
1026 uint32_t regionCount,
1027 const VkBufferCopy* pRegions)
1028 {
1029 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1030 VAL_FROM_HANDLE(val_buffer, src_buffer, srcBuffer);
1031 VAL_FROM_HANDLE(val_buffer, dest_buffer, destBuffer);
1032 struct val_cmd_buffer_entry *cmd;
1033 uint32_t cmd_size = regionCount * sizeof(VkBufferCopy);
1034
1035 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_COPY_BUFFER);
1036 if (!cmd)
1037 return;
1038
1039 cmd->u.copy_buffer.src = src_buffer;
1040 cmd->u.copy_buffer.dst = dest_buffer;
1041 cmd->u.copy_buffer.region_count = regionCount;
1042
1043 {
1044 VkBufferCopy *regions;
1045
1046 regions = (VkBufferCopy *)(cmd + 1);
1047 memcpy(regions, pRegions, regionCount * sizeof(VkBufferCopy));
1048 cmd->u.copy_buffer.regions = regions;
1049 }
1050
1051 cmd_buf_queue(cmd_buffer, cmd);
1052 }
1053
1054 void val_CmdBlitImage(
1055 VkCommandBuffer commandBuffer,
1056 VkImage srcImage,
1057 VkImageLayout srcImageLayout,
1058 VkImage destImage,
1059 VkImageLayout destImageLayout,
1060 uint32_t regionCount,
1061 const VkImageBlit* pRegions,
1062 VkFilter filter)
1063 {
1064 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1065 VAL_FROM_HANDLE(val_image, src_image, srcImage);
1066 VAL_FROM_HANDLE(val_image, dest_image, destImage);
1067 struct val_cmd_buffer_entry *cmd;
1068 uint32_t cmd_size = regionCount * sizeof(VkImageBlit);
1069
1070 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_BLIT_IMAGE);
1071 if (!cmd)
1072 return;
1073
1074 cmd->u.blit_image.src = src_image;
1075 cmd->u.blit_image.dst = dest_image;
1076 cmd->u.blit_image.src_layout = srcImageLayout;
1077 cmd->u.blit_image.dst_layout = destImageLayout;
1078 cmd->u.blit_image.filter = filter;
1079 cmd->u.blit_image.region_count = regionCount;
1080
1081 {
1082 VkImageBlit *regions;
1083
1084 regions = (VkImageBlit *)(cmd + 1);
1085 memcpy(regions, pRegions, regionCount * sizeof(VkImageBlit));
1086 cmd->u.blit_image.regions = regions;
1087 }
1088
1089 cmd_buf_queue(cmd_buffer, cmd);
1090 }
1091
1092 void val_CmdClearAttachments(
1093 VkCommandBuffer commandBuffer,
1094 uint32_t attachmentCount,
1095 const VkClearAttachment* pAttachments,
1096 uint32_t rectCount,
1097 const VkClearRect* pRects)
1098 {
1099 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1100 struct val_cmd_buffer_entry *cmd;
1101 uint32_t cmd_size = attachmentCount * sizeof(VkClearAttachment) + rectCount * sizeof(VkClearRect);
1102
1103 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_CLEAR_ATTACHMENTS);
1104 if (!cmd)
1105 return;
1106
1107 cmd->u.clear_attachments.attachment_count = attachmentCount;
1108 cmd->u.clear_attachments.attachments = (VkClearAttachment *)(cmd + 1);
1109 for (unsigned i = 0; i < attachmentCount; i++)
1110 cmd->u.clear_attachments.attachments[i] = pAttachments[i];
1111 cmd->u.clear_attachments.rect_count = rectCount;
1112 cmd->u.clear_attachments.rects = (VkClearRect *)(cmd->u.clear_attachments.attachments + attachmentCount);
1113 for (unsigned i = 0; i < rectCount; i++)
1114 cmd->u.clear_attachments.rects[i] = pRects[i];
1115
1116 cmd_buf_queue(cmd_buffer, cmd);
1117 }
1118
1119 void val_CmdFillBuffer(
1120 VkCommandBuffer commandBuffer,
1121 VkBuffer dstBuffer,
1122 VkDeviceSize dstOffset,
1123 VkDeviceSize fillSize,
1124 uint32_t data)
1125 {
1126 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1127 VAL_FROM_HANDLE(val_buffer, dst_buffer, dstBuffer);
1128 struct val_cmd_buffer_entry *cmd;
1129
1130 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_FILL_BUFFER);
1131 if (!cmd)
1132 return;
1133
1134 cmd->u.fill_buffer.buffer = dst_buffer;
1135 cmd->u.fill_buffer.offset = dstOffset;
1136 cmd->u.fill_buffer.fill_size = fillSize;
1137 cmd->u.fill_buffer.data = data;
1138
1139 cmd_buf_queue(cmd_buffer, cmd);
1140 }
1141
1142 void val_CmdUpdateBuffer(
1143 VkCommandBuffer commandBuffer,
1144 VkBuffer dstBuffer,
1145 VkDeviceSize dstOffset,
1146 VkDeviceSize dataSize,
1147 const void* pData)
1148 {
1149 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1150 VAL_FROM_HANDLE(val_buffer, dst_buffer, dstBuffer);
1151 struct val_cmd_buffer_entry *cmd;
1152
1153 cmd = cmd_buf_entry_alloc_size(cmd_buffer, dataSize, VAL_CMD_UPDATE_BUFFER);
1154 if (!cmd)
1155 return;
1156
1157 cmd->u.update_buffer.buffer = dst_buffer;
1158 cmd->u.update_buffer.offset = dstOffset;
1159 cmd->u.update_buffer.data_size = dataSize;
1160 memcpy(cmd->u.update_buffer.data, pData, dataSize);
1161
1162 cmd_buf_queue(cmd_buffer, cmd);
1163 }
1164
1165 void val_CmdClearColorImage(
1166 VkCommandBuffer commandBuffer,
1167 VkImage image_h,
1168 VkImageLayout imageLayout,
1169 const VkClearColorValue* pColor,
1170 uint32_t rangeCount,
1171 const VkImageSubresourceRange* pRanges)
1172 {
1173 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1174 VAL_FROM_HANDLE(val_image, image, image_h);
1175 struct val_cmd_buffer_entry *cmd;
1176 uint32_t cmd_size = rangeCount * sizeof(VkImageSubresourceRange);
1177
1178 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_CLEAR_COLOR_IMAGE);
1179 if (!cmd)
1180 return;
1181
1182 cmd->u.clear_color_image.image = image;
1183 cmd->u.clear_color_image.layout = imageLayout;
1184 cmd->u.clear_color_image.clear_val = *pColor;
1185 cmd->u.clear_color_image.range_count = rangeCount;
1186 cmd->u.clear_color_image.ranges = (VkImageSubresourceRange *)(cmd + 1);
1187 for (unsigned i = 0; i < rangeCount; i++)
1188 cmd->u.clear_color_image.ranges[i] = pRanges[i];
1189
1190 cmd_buf_queue(cmd_buffer, cmd);
1191 }
1192
1193 void val_CmdClearDepthStencilImage(
1194 VkCommandBuffer commandBuffer,
1195 VkImage image_h,
1196 VkImageLayout imageLayout,
1197 const VkClearDepthStencilValue* pDepthStencil,
1198 uint32_t rangeCount,
1199 const VkImageSubresourceRange* pRanges)
1200 {
1201 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1202 VAL_FROM_HANDLE(val_image, image, image_h);
1203 struct val_cmd_buffer_entry *cmd;
1204 uint32_t cmd_size = rangeCount * sizeof(VkImageSubresourceRange);
1205
1206 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_CLEAR_DEPTH_STENCIL_IMAGE);
1207 if (!cmd)
1208 return;
1209
1210 cmd->u.clear_ds_image.image = image;
1211 cmd->u.clear_ds_image.layout = imageLayout;
1212 cmd->u.clear_ds_image.clear_val = *pDepthStencil;
1213 cmd->u.clear_ds_image.range_count = rangeCount;
1214 cmd->u.clear_ds_image.ranges = (VkImageSubresourceRange *)(cmd + 1);
1215 for (unsigned i = 0; i < rangeCount; i++)
1216 cmd->u.clear_ds_image.ranges[i] = pRanges[i];
1217
1218 cmd_buf_queue(cmd_buffer, cmd);
1219 }
1220
1221
1222 void val_CmdResolveImage(
1223 VkCommandBuffer commandBuffer,
1224 VkImage srcImage,
1225 VkImageLayout srcImageLayout,
1226 VkImage destImage,
1227 VkImageLayout destImageLayout,
1228 uint32_t regionCount,
1229 const VkImageResolve* regions)
1230 {
1231 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1232 VAL_FROM_HANDLE(val_image, src_image, srcImage);
1233 VAL_FROM_HANDLE(val_image, dst_image, destImage);
1234 struct val_cmd_buffer_entry *cmd;
1235 uint32_t cmd_size = regionCount * sizeof(VkImageResolve);
1236
1237 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_RESOLVE_IMAGE);
1238 if (!cmd)
1239 return;
1240
1241 cmd->u.resolve_image.src = src_image;
1242 cmd->u.resolve_image.dst = dst_image;
1243 cmd->u.resolve_image.src_layout = srcImageLayout;
1244 cmd->u.resolve_image.dst_layout = destImageLayout;
1245 cmd->u.resolve_image.region_count = regionCount;
1246 cmd->u.resolve_image.regions = (VkImageResolve *)(cmd + 1);
1247 for (unsigned i = 0; i < regionCount; i++)
1248 cmd->u.resolve_image.regions[i] = regions[i];
1249
1250 cmd_buf_queue(cmd_buffer, cmd);
1251 }
1252
1253 void val_CmdResetQueryPool(
1254 VkCommandBuffer commandBuffer,
1255 VkQueryPool queryPool,
1256 uint32_t firstQuery,
1257 uint32_t queryCount)
1258 {
1259 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1260 VAL_FROM_HANDLE(val_query_pool, query_pool, queryPool);
1261 struct val_cmd_buffer_entry *cmd;
1262
1263 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_RESET_QUERY_POOL);
1264 if (!cmd)
1265 return;
1266
1267 cmd->u.query.pool = query_pool;
1268 cmd->u.query.query = firstQuery;
1269 cmd->u.query.index = queryCount;
1270
1271 cmd_buf_queue(cmd_buffer, cmd);
1272 }
1273
1274 void val_CmdBeginQueryIndexedEXT(
1275 VkCommandBuffer commandBuffer,
1276 VkQueryPool queryPool,
1277 uint32_t query,
1278 VkQueryControlFlags flags,
1279 uint32_t index)
1280 {
1281 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1282 VAL_FROM_HANDLE(val_query_pool, query_pool, queryPool);
1283 struct val_cmd_buffer_entry *cmd;
1284
1285 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_BEGIN_QUERY);
1286 if (!cmd)
1287 return;
1288
1289 cmd->u.query.pool = query_pool;
1290 cmd->u.query.query = query;
1291 cmd->u.query.index = index;
1292 cmd->u.query.precise = true;
1293
1294 cmd_buf_queue(cmd_buffer, cmd);
1295 }
1296
1297 void val_CmdBeginQuery(
1298 VkCommandBuffer commandBuffer,
1299 VkQueryPool queryPool,
1300 uint32_t query,
1301 VkQueryControlFlags flags)
1302 {
1303 val_CmdBeginQueryIndexedEXT(commandBuffer, queryPool, query, flags, 0);
1304 }
1305
1306 void val_CmdEndQueryIndexedEXT(
1307 VkCommandBuffer commandBuffer,
1308 VkQueryPool queryPool,
1309 uint32_t query,
1310 uint32_t index)
1311 {
1312 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1313 VAL_FROM_HANDLE(val_query_pool, query_pool, queryPool);
1314 struct val_cmd_buffer_entry *cmd;
1315
1316 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_END_QUERY);
1317 if (!cmd)
1318 return;
1319
1320 cmd->u.query.pool = query_pool;
1321 cmd->u.query.query = query;
1322 cmd->u.query.index = index;
1323
1324 cmd_buf_queue(cmd_buffer, cmd);
1325 }
1326
1327 void val_CmdEndQuery(
1328 VkCommandBuffer commandBuffer,
1329 VkQueryPool queryPool,
1330 uint32_t query)
1331 {
1332 val_CmdEndQueryIndexedEXT(commandBuffer, queryPool, query, 0);
1333 }
1334
1335 void val_CmdWriteTimestamp(
1336 VkCommandBuffer commandBuffer,
1337 VkPipelineStageFlagBits pipelineStage,
1338 VkQueryPool queryPool,
1339 uint32_t query)
1340 {
1341 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1342 VAL_FROM_HANDLE(val_query_pool, query_pool, queryPool);
1343 struct val_cmd_buffer_entry *cmd;
1344
1345 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_WRITE_TIMESTAMP);
1346 if (!cmd)
1347 return;
1348
1349 cmd->u.query.pool = query_pool;
1350 cmd->u.query.query = query;
1351 cmd->u.query.flush = !(pipelineStage == VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
1352
1353 cmd_buf_queue(cmd_buffer, cmd);
1354 }
1355
1356 void val_CmdCopyQueryPoolResults(
1357 VkCommandBuffer commandBuffer,
1358 VkQueryPool queryPool,
1359 uint32_t firstQuery,
1360 uint32_t queryCount,
1361 VkBuffer dstBuffer,
1362 VkDeviceSize dstOffset,
1363 VkDeviceSize stride,
1364 VkQueryResultFlags flags)
1365 {
1366 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1367 VAL_FROM_HANDLE(val_query_pool, query_pool, queryPool);
1368 VAL_FROM_HANDLE(val_buffer, buffer, dstBuffer);
1369 struct val_cmd_buffer_entry *cmd;
1370
1371 cmd = cmd_buf_entry_alloc(cmd_buffer, VAL_CMD_COPY_QUERY_POOL_RESULTS);
1372 if (!cmd)
1373 return;
1374
1375 cmd->u.copy_query_pool_results.pool = query_pool;
1376 cmd->u.copy_query_pool_results.first_query = firstQuery;
1377 cmd->u.copy_query_pool_results.query_count = queryCount;
1378 cmd->u.copy_query_pool_results.dst = buffer;
1379 cmd->u.copy_query_pool_results.dst_offset = dstOffset;
1380 cmd->u.copy_query_pool_results.stride = stride;
1381 cmd->u.copy_query_pool_results.flags = flags;
1382
1383 cmd_buf_queue(cmd_buffer, cmd);
1384 }
1385
1386 void val_CmdPipelineBarrier(
1387 VkCommandBuffer commandBuffer,
1388 VkPipelineStageFlags srcStageMask,
1389 VkPipelineStageFlags destStageMask,
1390 VkBool32 byRegion,
1391 uint32_t memoryBarrierCount,
1392 const VkMemoryBarrier* pMemoryBarriers,
1393 uint32_t bufferMemoryBarrierCount,
1394 const VkBufferMemoryBarrier* pBufferMemoryBarriers,
1395 uint32_t imageMemoryBarrierCount,
1396 const VkImageMemoryBarrier* pImageMemoryBarriers)
1397 {
1398 VAL_FROM_HANDLE(val_cmd_buffer, cmd_buffer, commandBuffer);
1399 struct val_cmd_buffer_entry *cmd;
1400 uint32_t cmd_size = 0;
1401
1402 cmd_size += memoryBarrierCount * sizeof(VkMemoryBarrier);
1403 cmd_size += bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1404 cmd_size += imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1405
1406 cmd = cmd_buf_entry_alloc_size(cmd_buffer, cmd_size, VAL_CMD_PIPELINE_BARRIER);
1407 if (!cmd)
1408 return;
1409
1410 cmd->u.pipeline_barrier.src_stage_mask = srcStageMask;
1411 cmd->u.pipeline_barrier.dst_stage_mask = destStageMask;
1412 cmd->u.pipeline_barrier.by_region = byRegion;
1413 cmd->u.pipeline_barrier.memory_barrier_count = memoryBarrierCount;
1414 cmd->u.pipeline_barrier.buffer_memory_barrier_count = bufferMemoryBarrierCount;
1415 cmd->u.pipeline_barrier.image_memory_barrier_count = imageMemoryBarrierCount;
1416
1417 /* TODO finish off this */
1418 cmd_buf_queue(cmd_buffer, cmd);
1419 }