Updated code generation so that for vertex shader output position is written at last...
[mesa.git] / src / libre-soc / vulkan / libresoc_cmd_buffer.c
1
2 /*
3 * Copyright © 2016 Red Hat.
4 * Copyright © 2016 Bas Nieuwenhuizen
5 *
6 * based in part on anv driver which is:
7 * Copyright © 2015 Intel Corporation
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 * IN THE SOFTWARE.
27 */
28
29 #include "libresoc_private.h"
30
31 void libresoc_CmdEndRenderPass(
32 VkCommandBuffer commandBuffer)
33 {
34 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
35 struct libresoc_cmd *cmd;
36 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
37 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
38 cmd->command.endRenderPass.commandId = EndRenderPassID;
39 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
40 }
41
42 void libresoc_CmdSetScissor(
43 VkCommandBuffer commandBuffer,
44 uint32_t firstScissor,
45 uint32_t scissorCount,
46 const VkRect2D* pScissors)
47 {
48 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
49 struct libresoc_cmd *cmd;
50 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
51 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
52 cmd->command.setScissors.commandId = SetScissorsID;
53 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
54 }
55
56 void libresoc_CmdPushConstants(VkCommandBuffer commandBuffer,
57 VkPipelineLayout layout,
58 VkShaderStageFlags stageFlags,
59 uint32_t offset,
60 uint32_t size,
61 const void* pValues)
62 {
63 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
64 struct libresoc_cmd *cmd;
65 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
66 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
67 cmd->command.pushConstants.commandId = PushConstantsID;
68 cmd->command.pushConstants.offset = offset;
69 cmd->command.pushConstants.size = size;
70 memcpy(cmd->command.pushConstants.values, pValues, size);
71 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
72 }
73
74 void libresoc_CmdDraw(
75 VkCommandBuffer commandBuffer,
76 uint32_t vertexCount,
77 uint32_t instanceCount,
78 uint32_t firstVertex,
79 uint32_t firstInstance)
80 {
81 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
82 struct libresoc_cmd *cmd;
83 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
84 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
85 cmd->command.draw.commandId = DrawID;
86 cmd->command.draw.vertexCount = vertexCount;
87 cmd->command.draw.instanceCount = instanceCount;
88 cmd->command.draw.firstVertex = firstVertex;
89 cmd->command.draw.firstInstance = firstInstance;
90 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
91 }
92
93 void libresoc_CmdDrawIndexed(
94 VkCommandBuffer commandBuffer,
95 uint32_t indexCount,
96 uint32_t instanceCount,
97 uint32_t firstIndex,
98 int32_t vertexOffset,
99 uint32_t firstInstance)
100 {
101 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
102 struct libresoc_cmd *cmd;
103 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
104 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
105 cmd->command.drawIndexed.commandId = DrawIndexedID;
106 cmd->command.drawIndexed.indexCount = indexCount;
107 cmd->command.drawIndexed.instanceCount = instanceCount;
108 cmd->command.drawIndexed.firstIndex = firstIndex;
109 cmd->command.drawIndexed.vertexOffset = vertexOffset;
110 cmd->command.drawIndexed.firstInstance = firstInstance;
111 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
112 }
113
114 void libresoc_CmdCopyBufferToImage(
115 VkCommandBuffer commandBuffer,
116 VkBuffer srcBuffer,
117 VkImage destImage,
118 VkImageLayout destImageLayout,
119 uint32_t regionCount,
120 const VkBufferImageCopy* pRegions)
121 {
122 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
123 for(uint32_t r = 0; r < regionCount; r++)
124 {
125 struct libresoc_cmd *cmd;
126 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
127 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
128 cmd->command.copyBuf2Img.commandId = CopyBuf2ImgID;
129 cmd->command.copyBuf2Img.srcBuffer = srcBuffer;
130 cmd->command.copyBuf2Img.dstImage = destImage;
131 cmd->command.copyBuf2Img.region = pRegions[r];
132 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
133 }
134 }
135
136 void libresoc_CmdCopyBuffer(
137 VkCommandBuffer commandBuffer,
138 VkBuffer srcBuffer,
139 VkBuffer destBuffer,
140 uint32_t regionCount,
141 const VkBufferCopy* pRegions)
142 {
143 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
144 for(uint32_t r = 0; r < regionCount; r++)
145 {
146 struct libresoc_cmd *cmd;
147 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
148 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
149 cmd->command.copyBuf.commandId = CopyBufID;
150 cmd->command.copyBuf.srcBuffer = srcBuffer;
151 cmd->command.copyBuf.dstBuffer = destBuffer;
152 cmd->command.copyBuf.region = pRegions[r];
153 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
154 }
155 }
156
157 void libresoc_CmdBindPipeline(
158 VkCommandBuffer commandBuffer,
159 VkPipelineBindPoint pipelineBindPoint,
160 VkPipeline _pipeline)
161 {
162 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
163 struct libresoc_cmd *cmd;
164 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
165 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
166 cmd->command.bindPipeline.commandId = BindPipelineID;
167 cmd->command.bindPipeline.pipeline = _pipeline;
168 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
169 }
170
171 void libresoc_CmdBindDescriptorSets(
172 VkCommandBuffer commandBuffer,
173 VkPipelineBindPoint pipelineBindPoint,
174 VkPipelineLayout _layout,
175 uint32_t firstSet,
176 uint32_t descriptorSetCount,
177 const VkDescriptorSet* pDescriptorSets,
178 uint32_t dynamicOffsetCount,
179 const uint32_t* pDynamicOffsets)
180 {
181 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
182 for(int i=0; i < descriptorSetCount; ++i)
183 {
184 struct libresoc_cmd *cmd;
185 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
186 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
187 cmd->command.bindDescriptorSets.commandId = BindDescriptorSetsID;
188 cmd->command.bindDescriptorSets.idx = firstSet + i;
189 cmd->command.bindDescriptorSets.set = pDescriptorSets[i];
190 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
191 }
192 }
193
194 void libresoc_CmdBindVertexBuffers(
195 VkCommandBuffer commandBuffer,
196 uint32_t firstBinding,
197 uint32_t bindingCount,
198 const VkBuffer* pBuffers,
199 const VkDeviceSize* pOffsets)
200 {
201 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
202 for(int i=0; i < bindingCount; ++i)
203 {
204 struct libresoc_cmd *cmd;
205 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
206 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
207 cmd->command.bindVB.commandId = BindVBID;
208 cmd->command.bindVB.slot = firstBinding + i;
209 cmd->command.bindVB.buffer = pBuffers[i];
210 cmd->command.bindVB.offset = pOffsets[i];
211 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
212 }
213 }
214
215 void libresoc_CmdBindIndexBuffer(
216 VkCommandBuffer commandBuffer,
217 VkBuffer buffer,
218 VkDeviceSize offset,
219 VkIndexType indexType)
220 {
221 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
222 struct libresoc_cmd *cmd;
223 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
224 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
225 cmd->command.bindIB.commandId = BindIBID;
226 cmd->command.bindIB.buffer = buffer;
227 cmd->command.bindIB.offset = offset;
228 cmd->command.bindIB.indexType = indexType;
229 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
230 }
231
232 void libresoc_CmdBeginRenderPass(
233 VkCommandBuffer commandBuffer,
234 const VkRenderPassBeginInfo* pRenderPassBegin,
235 VkSubpassContents contents)
236 {
237
238 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
239 struct libresoc_cmd *cmd;
240 cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct libresoc_cmd), 8,
241 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
242 cmd->command.beginRenderPass.commandId = BeginRenderPassID;
243 cmd->command.beginRenderPass.renderPass = pRenderPassBegin->renderPass;
244 cmd->command.beginRenderPass.framebuffer = pRenderPassBegin->framebuffer;
245 size_t count = (pRenderPassBegin->clearValueCount < 8U) ? pRenderPassBegin->clearValueCount : 8U;
246 memcpy(&cmd->command.beginRenderPass.clearval, pRenderPassBegin->pClearValues,
247 sizeof(VkClearValue) * count);
248 list_addtail(&cmd->link, &cmd_buffer->cmd.link);
249 }
250
251 void libresoc_FreeCommandBuffers(
252 VkDevice device,
253 VkCommandPool commandPool,
254 uint32_t commandBufferCount,
255 const VkCommandBuffer *pCommandBuffers)
256 {
257 //TODO: stub
258 }
259
260 VkResult libresoc_CreateCommandPool(
261 VkDevice _device,
262 const VkCommandPoolCreateInfo* pCreateInfo,
263 const VkAllocationCallbacks* pAllocator,
264 VkCommandPool* pCmdPool)
265 {
266 LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
267 struct libresoc_cmd_pool *pool;
268
269 pool = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*pool), 8,
270 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
271 if (pool == NULL)
272 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
273
274 vk_object_base_init(&device->vk, &pool->base,
275 VK_OBJECT_TYPE_COMMAND_POOL);
276
277 if (pAllocator)
278 pool->alloc = *pAllocator;
279 else
280 pool->alloc = device->vk.alloc;
281
282 list_inithead(&pool->cmd_buffers);
283 list_inithead(&pool->free_cmd_buffers);
284
285 pool->queue_family_index = pCreateInfo->queueFamilyIndex;
286
287 *pCmdPool = libresoc_cmd_pool_to_handle(pool);
288
289 return VK_SUCCESS;
290
291 }
292
293 void libresoc_DestroyCommandPool(
294 VkDevice _device,
295 VkCommandPool commandPool,
296 const VkAllocationCallbacks* pAllocator)
297 {
298 LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
299 LIBRESOC_FROM_HANDLE(libresoc_cmd_pool, pool, commandPool);
300
301 if (!pool)
302 return;
303
304 // list_for_each_entry_safe(struct libresoc_cmd_buffer, cmd_buffer,
305 // &pool->cmd_buffers, pool_link) {
306 // libresoc_destroy_cmd_buffer(cmd_buffer);
307 // }
308
309 // list_for_each_entry_safe(struct libresoc_cmd_buffer, cmd_buffer,
310 // &pool->free_cmd_buffers, pool_link) {
311 // libresoc_destroy_cmd_buffer(cmd_buffer);
312 // }
313
314 vk_object_base_finish(&pool->base);
315 vk_free2(&device->vk.alloc, pAllocator, pool);
316 }
317
318 static VkResult libresoc_create_cmd_buffer(
319 struct libresoc_device * device,
320 struct libresoc_cmd_pool * pool,
321 VkCommandBufferLevel level,
322 VkCommandBuffer* pCommandBuffer)
323 {
324 struct libresoc_cmd_buffer *cmd_buffer;
325 unsigned ring;
326 cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
327 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
328 if (cmd_buffer == NULL)
329 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
330
331 vk_object_base_init(&device->vk, &cmd_buffer->base,
332 VK_OBJECT_TYPE_COMMAND_BUFFER);
333 cmd_buffer->device = device;
334 cmd_buffer->size = 0;
335 list_inithead(&cmd_buffer->cmd.link);
336 *pCommandBuffer = libresoc_cmd_buffer_to_handle(cmd_buffer);
337
338 return VK_SUCCESS;
339 }
340
341 VkResult libresoc_AllocateCommandBuffers(
342 VkDevice _device,
343 const VkCommandBufferAllocateInfo *pAllocateInfo,
344 VkCommandBuffer *pCommandBuffers)
345 {
346 LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
347 LIBRESOC_FROM_HANDLE(libresoc_cmd_pool, pool, pAllocateInfo->commandPool);
348
349 VkResult result = VK_SUCCESS;
350 uint32_t i;
351
352 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
353 result = libresoc_create_cmd_buffer(device, pool, pAllocateInfo->level,
354 &pCommandBuffers[i]);
355 if (result != VK_SUCCESS)
356 break;
357 }
358
359 // if (result != VK_SUCCESS) {
360 // libresoc_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
361 // i, pCommandBuffers);
362
363 // /* From the Vulkan 1.0.66 spec:
364 // *
365 // * "vkAllocateCommandBuffers can be used to create multiple
366 // * command buffers. If the creation of any of those command
367 // * buffers fails, the implementation must destroy all
368 // * successfully created command buffer objects from this
369 // * command, set all entries of the pCommandBuffers array to
370 // * NULL and return the error."
371 // */
372 // memset(pCommandBuffers, 0,
373 // sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount);
374 // }
375
376 return result;
377 }
378
379 VkResult libresoc_BeginCommandBuffer(
380 VkCommandBuffer commandBuffer,
381 const VkCommandBufferBeginInfo *pBeginInfo)
382 {
383 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
384 VkResult result = VK_SUCCESS;
385
386
387 return result;
388 }
389
390 void libresoc_CmdPipelineBarrier(
391 VkCommandBuffer commandBuffer,
392 VkPipelineStageFlags srcStageMask,
393 VkPipelineStageFlags destStageMask,
394 VkBool32 byRegion,
395 uint32_t memoryBarrierCount,
396 const VkMemoryBarrier* pMemoryBarriers,
397 uint32_t bufferMemoryBarrierCount,
398 const VkBufferMemoryBarrier* pBufferMemoryBarriers,
399 uint32_t imageMemoryBarrierCount,
400 const VkImageMemoryBarrier* pImageMemoryBarriers)
401 {
402 // LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
403 // struct PipelineBarrier *cmd;
404 // cmd = vk_alloc(&cmd_buffer->device->vk.alloc, sizeof(struct PipelineBarrier), 8,
405 // VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
406 // cmd->commandId = PipelineBarrierID;
407 // if (list_is_empty(&cmd_buffer->list)) {
408 // list_inithead(&cmd);
409 // } else {
410 // list_addtail(&cmd, &cmd_buffer->list);
411 // }
412 // cmd_buffer->size += sizeof(struct PipelineBarrier);
413 }
414
415 VkResult libresoc_EndCommandBuffer(
416 VkCommandBuffer commandBuffer)
417 {
418
419 LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, cmd_buffer, commandBuffer);
420
421 // if (cmd_buffer->queue_family_index != LIBRESOC_QUEUE_TRANSFER) {
422 // if (cmd_buffer->device->physical_device->rad_info.chip_class == GFX6)
423 // cmd_buffer->state.flush_bits |= LIBRESOC_CMD_FLAG_CS_PARTIAL_FLUSH | LIBRESOC_CMD_FLAG_PS_PARTIAL_FLUSH | LIBRESOC_CMD_FLAG_WB_L2;
424
425 // /* Make sure to sync all pending active queries at the end of
426 // * command buffer.
427 // */
428 // cmd_buffer->state.flush_bits |= cmd_buffer->active_query_flush_bits;
429
430 // /* Since NGG streamout uses GDS, we need to make GDS idle when
431 // * we leave the IB, otherwise another process might overwrite
432 // * it while our shaders are busy.
433 // */
434 // if (cmd_buffer->gds_needed)
435 // cmd_buffer->state.flush_bits |= LIBRESOC_CMD_FLAG_PS_PARTIAL_FLUSH;
436
437 // si_emit_cache_flush(cmd_buffer);
438 // }
439
440 // /* Make sure CP DMA is idle at the end of IBs because the kernel
441 // * doesn't wait for it.
442 // */
443 // si_cp_dma_wait_for_idle(cmd_buffer);
444
445 // libresoc_describe_end_cmd_buffer(cmd_buffer);
446
447 // vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
448 // vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.subpass_sample_locs);
449
450 // VkResult result = cmd_buffer->device->ws->cs_finalize(cmd_buffer->cs);
451 // if (result != VK_SUCCESS)
452 // return vk_error(cmd_buffer->device->instance, result);
453
454 // cmd_buffer->status = LIBRESOC_CMD_BUFFER_STATUS_EXECUTABLE;
455
456 return VK_SUCCESS;
457 }