1/* 2 * Copyright © 2015 Intel Corporation 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 <assert.h> 25#include <stdbool.h> 26#include <string.h> 27#include <unistd.h> 28#include <fcntl.h> 29 30#include "anv_private.h" 31 32#include "vk_format_info.h" 33#include "vk_util.h" 34 35/** \file anv_cmd_buffer.c 36 * 37 * This file contains all of the stuff for emitting commands into a command 38 * buffer. This includes implementations of most of the vkCmd* 39 * entrypoints. This file is concerned entirely with state emission and 40 * not with the command buffer data structure itself. As far as this file 41 * is concerned, most of anv_cmd_buffer is magic. 42 */ 43 44/* TODO: These are taken from GLES. We should check the Vulkan spec */ 45const struct anv_dynamic_state default_dynamic_state = { 46 .viewport = { 47 .count = 0, 48 }, 49 .scissor = { 50 .count = 0, 51 }, 52 .line_width = 1.0f, 53 .depth_bias = { 54 .bias = 0.0f, 55 .clamp = 0.0f, 56 .slope = 0.0f, 57 }, 58 .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f }, 59 .depth_bounds = { 60 .min = 0.0f, 61 .max = 1.0f, 62 }, 63 .stencil_compare_mask = { 64 .front = ~0u, 65 .back = ~0u, 66 }, 67 .stencil_write_mask = { 68 .front = ~0u, 69 .back = ~0u, 70 }, 71 .stencil_reference = { 72 .front = 0u, 73 .back = 0u, 74 }, 75}; 76 77void 78anv_dynamic_state_copy(struct anv_dynamic_state *dest, 79 const struct anv_dynamic_state *src, 80 uint32_t copy_mask) 81{ 82 if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) { 83 dest->viewport.count = src->viewport.count; 84 typed_memcpy(dest->viewport.viewports, src->viewport.viewports, 85 src->viewport.count); 86 } 87 88 if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) { 89 dest->scissor.count = src->scissor.count; 90 typed_memcpy(dest->scissor.scissors, src->scissor.scissors, 91 src->scissor.count); 92 } 93 94 if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH)) 95 dest->line_width = src->line_width; 96 97 if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS)) 98 dest->depth_bias = src->depth_bias; 99 100 if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS)) 101 typed_memcpy(dest->blend_constants, src->blend_constants, 4); 102 103 if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS)) 104 dest->depth_bounds = src->depth_bounds; 105 106 if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK)) 107 dest->stencil_compare_mask = src->stencil_compare_mask; 108 109 if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK)) 110 dest->stencil_write_mask = src->stencil_write_mask; 111 112 if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE)) 113 dest->stencil_reference = src->stencil_reference; 114} 115 116static void 117anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer) 118{ 119 struct anv_cmd_state *state = &cmd_buffer->state; 120 121 memset(state, 0, sizeof(*state)); 122 123 state->current_pipeline = UINT32_MAX; 124 state->restart_index = UINT32_MAX; 125 state->gfx.dynamic = default_dynamic_state; 126} 127 128static void 129anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer, 130 struct anv_cmd_pipeline_state *pipe_state) 131{ 132 for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) { 133 if (pipe_state->push_descriptors[i]) { 134 anv_descriptor_set_layout_unref(cmd_buffer->device, 135 pipe_state->push_descriptors[i]->set.layout); 136 vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]); 137 } 138 } 139} 140 141static void 142anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer) 143{ 144 struct anv_cmd_state *state = &cmd_buffer->state; 145 146 anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base); 147 anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base); 148 149 vk_free(&cmd_buffer->pool->alloc, state->attachments); 150} 151 152static void 153anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer) 154{ 155 anv_cmd_state_finish(cmd_buffer); 156 anv_cmd_state_init(cmd_buffer); 157} 158 159static VkResult anv_create_cmd_buffer( 160 struct anv_device * device, 161 struct anv_cmd_pool * pool, 162 VkCommandBufferLevel level, 163 VkCommandBuffer* pCommandBuffer) 164{ 165 struct anv_cmd_buffer *cmd_buffer; 166 VkResult result; 167 168 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8, 169 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 170 if (cmd_buffer == NULL) 171 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 172 173 cmd_buffer->batch.status = VK_SUCCESS; 174 175 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC; 176 cmd_buffer->device = device; 177 cmd_buffer->pool = pool; 178 cmd_buffer->level = level; 179 180 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer); 181 if (result != VK_SUCCESS) 182 goto fail; 183 184 anv_state_stream_init(&cmd_buffer->surface_state_stream, 185 &device->surface_state_pool, 4096); 186 anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 187 &device->dynamic_state_pool, 16384); 188 189 anv_cmd_state_init(cmd_buffer); 190 191 if (pool) { 192 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); 193 } else { 194 /* Init the pool_link so we can safefly call list_del when we destroy 195 * the command buffer 196 */ 197 list_inithead(&cmd_buffer->pool_link); 198 } 199 200 *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer); 201 202 return VK_SUCCESS; 203 204 fail: 205 vk_free(&cmd_buffer->pool->alloc, cmd_buffer); 206 207 return result; 208} 209 210VkResult anv_AllocateCommandBuffers( 211 VkDevice _device, 212 const VkCommandBufferAllocateInfo* pAllocateInfo, 213 VkCommandBuffer* pCommandBuffers) 214{ 215 ANV_FROM_HANDLE(anv_device, device, _device); 216 ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool); 217 218 VkResult result = VK_SUCCESS; 219 uint32_t i; 220 221 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) { 222 result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level, 223 &pCommandBuffers[i]); 224 if (result != VK_SUCCESS) 225 break; 226 } 227 228 if (result != VK_SUCCESS) { 229 anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool, 230 i, pCommandBuffers); 231 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) 232 pCommandBuffers[i] = VK_NULL_HANDLE; 233 } 234 235 return result; 236} 237 238static void 239anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer) 240{ 241 list_del(&cmd_buffer->pool_link); 242 243 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer); 244 245 anv_state_stream_finish(&cmd_buffer->surface_state_stream); 246 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 247 248 anv_cmd_state_finish(cmd_buffer); 249 250 vk_free(&cmd_buffer->pool->alloc, cmd_buffer); 251} 252 253void anv_FreeCommandBuffers( 254 VkDevice device, 255 VkCommandPool commandPool, 256 uint32_t commandBufferCount, 257 const VkCommandBuffer* pCommandBuffers) 258{ 259 for (uint32_t i = 0; i < commandBufferCount; i++) { 260 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]); 261 262 if (!cmd_buffer) 263 continue; 264 265 anv_cmd_buffer_destroy(cmd_buffer); 266 } 267} 268 269VkResult 270anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer) 271{ 272 cmd_buffer->usage_flags = 0; 273 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer); 274 anv_cmd_state_reset(cmd_buffer); 275 276 anv_state_stream_finish(&cmd_buffer->surface_state_stream); 277 anv_state_stream_init(&cmd_buffer->surface_state_stream, 278 &cmd_buffer->device->surface_state_pool, 4096); 279 280 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 281 anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 282 &cmd_buffer->device->dynamic_state_pool, 16384); 283 return VK_SUCCESS; 284} 285 286VkResult anv_ResetCommandBuffer( 287 VkCommandBuffer commandBuffer, 288 VkCommandBufferResetFlags flags) 289{ 290 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 291 return anv_cmd_buffer_reset(cmd_buffer); 292} 293 294#define anv_genX_call(devinfo, func, ...) \ 295 switch ((devinfo)->gen) { \ 296 case 7: \ 297 if ((devinfo)->is_haswell) { \ 298 gen75_##func(__VA_ARGS__); \ 299 } else { \ 300 gen7_##func(__VA_ARGS__); \ 301 } \ 302 break; \ 303 case 8: \ 304 gen8_##func(__VA_ARGS__); \ 305 break; \ 306 case 9: \ 307 gen9_##func(__VA_ARGS__); \ 308 break; \ 309 case 10: \ 310 gen10_##func(__VA_ARGS__); \ 311 break; \ 312 case 11: \ 313 gen11_##func(__VA_ARGS__); \ 314 break; \ 315 default: \ 316 assert(!"Unknown hardware generation"); \ 317 } 318 319void 320anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer) 321{ 322 anv_genX_call(&cmd_buffer->device->info, 323 cmd_buffer_emit_state_base_address, 324 cmd_buffer); 325} 326 327void 328anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer, 329 const struct anv_image *image, 330 VkImageAspectFlagBits aspect, 331 enum isl_aux_usage aux_usage, 332 uint32_t level, 333 uint32_t base_layer, 334 uint32_t layer_count) 335{ 336 anv_genX_call(&cmd_buffer->device->info, 337 cmd_buffer_mark_image_written, 338 cmd_buffer, image, aspect, aux_usage, 339 level, base_layer, layer_count); 340} 341 342void 343anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer) 344{ 345 anv_genX_call(&cmd_buffer->device->info, 346 cmd_emit_conditional_render_predicate, 347 cmd_buffer); 348} 349 350void anv_CmdBindPipeline( 351 VkCommandBuffer commandBuffer, 352 VkPipelineBindPoint pipelineBindPoint, 353 VkPipeline _pipeline) 354{ 355 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 356 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline); 357 358 switch (pipelineBindPoint) { 359 case VK_PIPELINE_BIND_POINT_COMPUTE: 360 cmd_buffer->state.compute.base.pipeline = pipeline; 361 cmd_buffer->state.compute.pipeline_dirty = true; 362 cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; 363 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; 364 break; 365 366 case VK_PIPELINE_BIND_POINT_GRAPHICS: 367 cmd_buffer->state.gfx.base.pipeline = pipeline; 368 cmd_buffer->state.gfx.vb_dirty |= pipeline->vb_used; 369 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE; 370 cmd_buffer->state.push_constants_dirty |= pipeline->active_stages; 371 cmd_buffer->state.descriptors_dirty |= pipeline->active_stages; 372 373 /* Apply the dynamic state from the pipeline */ 374 cmd_buffer->state.gfx.dirty |= pipeline->dynamic_state_mask; 375 anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic, 376 &pipeline->dynamic_state, 377 pipeline->dynamic_state_mask); 378 break; 379 380 default: 381 assert(!"invalid bind point"); 382 break; 383 } 384} 385 386void anv_CmdSetViewport( 387 VkCommandBuffer commandBuffer, 388 uint32_t firstViewport, 389 uint32_t viewportCount, 390 const VkViewport* pViewports) 391{ 392 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 393 394 const uint32_t total_count = firstViewport + viewportCount; 395 if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count) 396 cmd_buffer->state.gfx.dynamic.viewport.count = total_count; 397 398 memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport, 399 pViewports, viewportCount * sizeof(*pViewports)); 400 401 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; 402} 403 404void anv_CmdSetScissor( 405 VkCommandBuffer commandBuffer, 406 uint32_t firstScissor, 407 uint32_t scissorCount, 408 const VkRect2D* pScissors) 409{ 410 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 411 412 const uint32_t total_count = firstScissor + scissorCount; 413 if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count) 414 cmd_buffer->state.gfx.dynamic.scissor.count = total_count; 415 416 memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor, 417 pScissors, scissorCount * sizeof(*pScissors)); 418 419 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; 420} 421 422void anv_CmdSetLineWidth( 423 VkCommandBuffer commandBuffer, 424 float lineWidth) 425{ 426 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 427 428 cmd_buffer->state.gfx.dynamic.line_width = lineWidth; 429 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; 430} 431 432void anv_CmdSetDepthBias( 433 VkCommandBuffer commandBuffer, 434 float depthBiasConstantFactor, 435 float depthBiasClamp, 436 float depthBiasSlopeFactor) 437{ 438 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 439 440 cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor; 441 cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp; 442 cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor; 443 444 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; 445} 446 447void anv_CmdSetBlendConstants( 448 VkCommandBuffer commandBuffer, 449 const float blendConstants[4]) 450{ 451 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 452 453 memcpy(cmd_buffer->state.gfx.dynamic.blend_constants, 454 blendConstants, sizeof(float) * 4); 455 456 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; 457} 458 459void anv_CmdSetDepthBounds( 460 VkCommandBuffer commandBuffer, 461 float minDepthBounds, 462 float maxDepthBounds) 463{ 464 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 465 466 cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds; 467 cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds; 468 469 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; 470} 471 472void anv_CmdSetStencilCompareMask( 473 VkCommandBuffer commandBuffer, 474 VkStencilFaceFlags faceMask, 475 uint32_t compareMask) 476{ 477 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 478 479 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 480 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask; 481 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 482 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask; 483 484 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; 485} 486 487void anv_CmdSetStencilWriteMask( 488 VkCommandBuffer commandBuffer, 489 VkStencilFaceFlags faceMask, 490 uint32_t writeMask) 491{ 492 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 493 494 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 495 cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask; 496 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 497 cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask; 498 499 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; 500} 501 502void anv_CmdSetStencilReference( 503 VkCommandBuffer commandBuffer, 504 VkStencilFaceFlags faceMask, 505 uint32_t reference) 506{ 507 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 508 509 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 510 cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference; 511 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 512 cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference; 513 514 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; 515} 516 517static void 518anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, 519 VkPipelineBindPoint bind_point, 520 struct anv_pipeline_layout *layout, 521 uint32_t set_index, 522 struct anv_descriptor_set *set, 523 uint32_t *dynamic_offset_count, 524 const uint32_t **dynamic_offsets) 525{ 526 struct anv_descriptor_set_layout *set_layout = 527 layout->set[set_index].layout; 528 529 struct anv_cmd_pipeline_state *pipe_state; 530 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 531 pipe_state = &cmd_buffer->state.compute.base; 532 } else { 533 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); 534 pipe_state = &cmd_buffer->state.gfx.base; 535 } 536 pipe_state->descriptors[set_index] = set; 537 538 if (dynamic_offsets) { 539 if (set_layout->dynamic_offset_count > 0) { 540 uint32_t dynamic_offset_start = 541 layout->set[set_index].dynamic_offset_start; 542 543 /* Assert that everything is in range */ 544 assert(set_layout->dynamic_offset_count <= *dynamic_offset_count); 545 assert(dynamic_offset_start + set_layout->dynamic_offset_count <= 546 ARRAY_SIZE(pipe_state->dynamic_offsets)); 547 548 typed_memcpy(&pipe_state->dynamic_offsets[dynamic_offset_start], 549 *dynamic_offsets, set_layout->dynamic_offset_count); 550 551 *dynamic_offsets += set_layout->dynamic_offset_count; 552 *dynamic_offset_count -= set_layout->dynamic_offset_count; 553 554 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 555 cmd_buffer->state.push_constants_dirty |= 556 VK_SHADER_STAGE_COMPUTE_BIT; 557 } else { 558 cmd_buffer->state.push_constants_dirty |= 559 VK_SHADER_STAGE_ALL_GRAPHICS; 560 } 561 } 562 } 563 564 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 565 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; 566 } else { 567 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); 568 cmd_buffer->state.descriptors_dirty |= 569 set_layout->shader_stages & VK_SHADER_STAGE_ALL_GRAPHICS; 570 } 571 572 /* Pipeline layout objects are required to live at least while any command 573 * buffers that use them are in recording state. We need to grab a reference 574 * to the pipeline layout being bound here so we can compute correct dynamic 575 * offsets for VK_DESCRIPTOR_TYPE_*_DYNAMIC in dynamic_offset_for_binding() 576 * when we record draw commands that come after this. 577 */ 578 pipe_state->layout = layout; 579} 580 581void anv_CmdBindDescriptorSets( 582 VkCommandBuffer commandBuffer, 583 VkPipelineBindPoint pipelineBindPoint, 584 VkPipelineLayout _layout, 585 uint32_t firstSet, 586 uint32_t descriptorSetCount, 587 const VkDescriptorSet* pDescriptorSets, 588 uint32_t dynamicOffsetCount, 589 const uint32_t* pDynamicOffsets) 590{ 591 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 592 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 593 594 assert(firstSet + descriptorSetCount <= MAX_SETS); 595 596 for (uint32_t i = 0; i < descriptorSetCount; i++) { 597 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]); 598 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, 599 layout, firstSet + i, set, 600 &dynamicOffsetCount, 601 &pDynamicOffsets); 602 } 603} 604 605void anv_CmdBindVertexBuffers( 606 VkCommandBuffer commandBuffer, 607 uint32_t firstBinding, 608 uint32_t bindingCount, 609 const VkBuffer* pBuffers, 610 const VkDeviceSize* pOffsets) 611{ 612 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 613 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings; 614 615 /* We have to defer setting up vertex buffer since we need the buffer 616 * stride from the pipeline. */ 617 618 assert(firstBinding + bindingCount <= MAX_VBS); 619 for (uint32_t i = 0; i < bindingCount; i++) { 620 vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]); 621 vb[firstBinding + i].offset = pOffsets[i]; 622 cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i); 623 } 624} 625 626void anv_CmdBindTransformFeedbackBuffersEXT( 627 VkCommandBuffer commandBuffer, 628 uint32_t firstBinding, 629 uint32_t bindingCount, 630 const VkBuffer* pBuffers, 631 const VkDeviceSize* pOffsets, 632 const VkDeviceSize* pSizes) 633{ 634 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 635 struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings; 636 637 /* We have to defer setting up vertex buffer since we need the buffer 638 * stride from the pipeline. */ 639 640 assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS); 641 for (uint32_t i = 0; i < bindingCount; i++) { 642 if (pBuffers[i] == VK_NULL_HANDLE) { 643 xfb[firstBinding + i].buffer = NULL; 644 } else { 645 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]); 646 xfb[firstBinding + i].buffer = buffer; 647 xfb[firstBinding + i].offset = pOffsets[i]; 648 xfb[firstBinding + i].size = 649 anv_buffer_get_range(buffer, pOffsets[i], 650 pSizes ? pSizes[i] : VK_WHOLE_SIZE); 651 } 652 } 653} 654 655enum isl_format 656anv_isl_format_for_descriptor_type(VkDescriptorType type) 657{ 658 switch (type) { 659 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 660 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 661 return ISL_FORMAT_R32G32B32A32_FLOAT; 662 663 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 664 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 665 return ISL_FORMAT_RAW; 666 667 default: 668 unreachable("Invalid descriptor type"); 669 } 670} 671 672struct anv_state 673anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer, 674 const void *data, uint32_t size, uint32_t alignment) 675{ 676 struct anv_state state; 677 678 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment); 679 memcpy(state.map, data, size); 680 681 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size)); 682 683 return state; 684} 685 686struct anv_state 687anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer, 688 uint32_t *a, uint32_t *b, 689 uint32_t dwords, uint32_t alignment) 690{ 691 struct anv_state state; 692 uint32_t *p; 693 694 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 695 dwords * 4, alignment); 696 p = state.map; 697 for (uint32_t i = 0; i < dwords; i++) 698 p[i] = a[i] | b[i]; 699 700 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4)); 701 702 return state; 703} 704 705static uint32_t 706anv_push_constant_value(const struct anv_cmd_pipeline_state *state, 707 const struct anv_push_constants *data, uint32_t param) 708{ 709 if (BRW_PARAM_IS_BUILTIN(param)) { 710 switch (param) { 711 case BRW_PARAM_BUILTIN_ZERO: 712 return 0; 713 case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_X: 714 return data->base_work_group_id[0]; 715 case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_Y: 716 return data->base_work_group_id[1]; 717 case BRW_PARAM_BUILTIN_BASE_WORK_GROUP_ID_Z: 718 return data->base_work_group_id[2]; 719 default: 720 unreachable("Invalid param builtin"); 721 } 722 } else if (ANV_PARAM_IS_PUSH(param)) { 723 uint32_t offset = ANV_PARAM_PUSH_OFFSET(param); 724 assert(offset % sizeof(uint32_t) == 0); 725 if (offset < sizeof(data->client_data)) 726 return *(uint32_t *)((uint8_t *)data + offset); 727 else 728 return 0; 729 } else if (ANV_PARAM_IS_DYN_OFFSET(param)) { 730 unsigned idx = ANV_PARAM_DYN_OFFSET_IDX(param); 731 assert(idx < MAX_DYNAMIC_BUFFERS); 732 return state->dynamic_offsets[idx]; 733 } 734 735 assert(!"Invalid param"); 736 return 0; 737} 738 739struct anv_state 740anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer, 741 gl_shader_stage stage) 742{ 743 struct anv_cmd_pipeline_state *pipeline_state = &cmd_buffer->state.gfx.base; 744 struct anv_pipeline *pipeline = cmd_buffer->state.gfx.base.pipeline; 745 746 /* If we don't have this stage, bail. */ 747 if (!anv_pipeline_has_stage(pipeline, stage)) 748 return (struct anv_state) { .offset = 0 }; 749 750 struct anv_push_constants *data = 751 &cmd_buffer->state.push_constants[stage]; 752 const struct brw_stage_prog_data *prog_data = 753 pipeline->shaders[stage]->prog_data; 754 755 /* If we don't actually have any push constants, bail. */ 756 if (prog_data == NULL || prog_data->nr_params == 0) 757 return (struct anv_state) { .offset = 0 }; 758 759 struct anv_state state = 760 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 761 prog_data->nr_params * sizeof(float), 762 32 /* bottom 5 bits MBZ */); 763 764 /* Walk through the param array and fill the buffer with data */ 765 uint32_t *u32_map = state.map; 766 for (unsigned i = 0; i < prog_data->nr_params; i++) { 767 u32_map[i] = anv_push_constant_value(pipeline_state, data, 768 prog_data->param[i]); 769 } 770 771 return state; 772} 773 774struct anv_state 775anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) 776{ 777 struct anv_cmd_pipeline_state *pipeline_state = &cmd_buffer->state.compute.base; 778 struct anv_push_constants *data = 779 &cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE]; 780 struct anv_pipeline *pipeline = cmd_buffer->state.compute.base.pipeline; 781 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline); 782 const struct brw_stage_prog_data *prog_data = &cs_prog_data->base; 783 784 /* If we don't actually have any push constants, bail. */ 785 if (cs_prog_data->push.total.size == 0) 786 return (struct anv_state) { .offset = 0 }; 787 788 const unsigned push_constant_alignment = 789 cmd_buffer->device->info.gen < 8 ? 32 : 64; 790 const unsigned aligned_total_push_constants_size = 791 ALIGN(cs_prog_data->push.total.size, push_constant_alignment); 792 struct anv_state state = 793 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 794 aligned_total_push_constants_size, 795 push_constant_alignment); 796 797 /* Walk through the param array and fill the buffer with data */ 798 uint32_t *u32_map = state.map; 799 800 if (cs_prog_data->push.cross_thread.size > 0) { 801 for (unsigned i = 0; 802 i < cs_prog_data->push.cross_thread.dwords; 803 i++) { 804 assert(prog_data->param[i] != BRW_PARAM_BUILTIN_SUBGROUP_ID); 805 u32_map[i] = anv_push_constant_value(pipeline_state, data, 806 prog_data->param[i]); 807 } 808 } 809 810 if (cs_prog_data->push.per_thread.size > 0) { 811 for (unsigned t = 0; t < cs_prog_data->threads; t++) { 812 unsigned dst = 813 8 * (cs_prog_data->push.per_thread.regs * t + 814 cs_prog_data->push.cross_thread.regs); 815 unsigned src = cs_prog_data->push.cross_thread.dwords; 816 for ( ; src < prog_data->nr_params; src++, dst++) { 817 if (prog_data->param[src] == BRW_PARAM_BUILTIN_SUBGROUP_ID) { 818 u32_map[dst] = t; 819 } else { 820 u32_map[dst] = anv_push_constant_value(pipeline_state, data, 821 prog_data->param[src]); 822 } 823 } 824 } 825 } 826 827 return state; 828} 829 830void anv_CmdPushConstants( 831 VkCommandBuffer commandBuffer, 832 VkPipelineLayout layout, 833 VkShaderStageFlags stageFlags, 834 uint32_t offset, 835 uint32_t size, 836 const void* pValues) 837{ 838 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 839 840 anv_foreach_stage(stage, stageFlags) { 841 memcpy(cmd_buffer->state.push_constants[stage].client_data + offset, 842 pValues, size); 843 } 844 845 cmd_buffer->state.push_constants_dirty |= stageFlags; 846} 847 848VkResult anv_CreateCommandPool( 849 VkDevice _device, 850 const VkCommandPoolCreateInfo* pCreateInfo, 851 const VkAllocationCallbacks* pAllocator, 852 VkCommandPool* pCmdPool) 853{ 854 ANV_FROM_HANDLE(anv_device, device, _device); 855 struct anv_cmd_pool *pool; 856 857 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8, 858 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 859 if (pool == NULL) 860 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 861 862 if (pAllocator) 863 pool->alloc = *pAllocator; 864 else 865 pool->alloc = device->alloc; 866 867 list_inithead(&pool->cmd_buffers); 868 869 *pCmdPool = anv_cmd_pool_to_handle(pool); 870 871 return VK_SUCCESS; 872} 873 874void anv_DestroyCommandPool( 875 VkDevice _device, 876 VkCommandPool commandPool, 877 const VkAllocationCallbacks* pAllocator) 878{ 879 ANV_FROM_HANDLE(anv_device, device, _device); 880 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 881 882 if (!pool) 883 return; 884 885 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer, 886 &pool->cmd_buffers, pool_link) { 887 anv_cmd_buffer_destroy(cmd_buffer); 888 } 889 890 vk_free2(&device->alloc, pAllocator, pool); 891} 892 893VkResult anv_ResetCommandPool( 894 VkDevice device, 895 VkCommandPool commandPool, 896 VkCommandPoolResetFlags flags) 897{ 898 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 899 900 list_for_each_entry(struct anv_cmd_buffer, cmd_buffer, 901 &pool->cmd_buffers, pool_link) { 902 anv_cmd_buffer_reset(cmd_buffer); 903 } 904 905 return VK_SUCCESS; 906} 907 908void anv_TrimCommandPool( 909 VkDevice device, 910 VkCommandPool commandPool, 911 VkCommandPoolTrimFlags flags) 912{ 913 /* Nothing for us to do here. Our pools stay pretty tidy. */ 914} 915 916/** 917 * Return NULL if the current subpass has no depthstencil attachment. 918 */ 919const struct anv_image_view * 920anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) 921{ 922 const struct anv_subpass *subpass = cmd_buffer->state.subpass; 923 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; 924 925 if (subpass->depth_stencil_attachment == NULL) 926 return NULL; 927 928 const struct anv_image_view *iview = 929 fb->attachments[subpass->depth_stencil_attachment->attachment]; 930 931 assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | 932 VK_IMAGE_ASPECT_STENCIL_BIT)); 933 934 return iview; 935} 936 937static struct anv_descriptor_set * 938anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer, 939 VkPipelineBindPoint bind_point, 940 struct anv_descriptor_set_layout *layout, 941 uint32_t _set) 942{ 943 struct anv_cmd_pipeline_state *pipe_state; 944 if (bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) { 945 pipe_state = &cmd_buffer->state.compute.base; 946 } else { 947 assert(bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS); 948 pipe_state = &cmd_buffer->state.gfx.base; 949 } 950 951 struct anv_push_descriptor_set **push_set = 952 &pipe_state->push_descriptors[_set]; 953 954 if (*push_set == NULL) { 955 *push_set = vk_zalloc(&cmd_buffer->pool->alloc, 956 sizeof(struct anv_push_descriptor_set), 8, 957 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 958 if (*push_set == NULL) { 959 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); 960 return NULL; 961 } 962 } 963 964 struct anv_descriptor_set *set = &(*push_set)->set; 965 966 if (set->layout != layout) { 967 if (set->layout) 968 anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout); 969 anv_descriptor_set_layout_ref(layout); 970 set->layout = layout; 971 } 972 set->size = anv_descriptor_set_layout_size(layout); 973 set->buffer_view_count = layout->buffer_view_count; 974 set->buffer_views = (*push_set)->buffer_views; 975 976 if (layout->descriptor_buffer_size && 977 ((*push_set)->set_used_on_gpu || 978 set->desc_mem.alloc_size < layout->descriptor_buffer_size)) { 979 /* The previous buffer is either actively used by some GPU command (so 980 * we can't modify it) or is too small. Allocate a new one. 981 */ 982 struct anv_state desc_mem = 983 anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, 984 layout->descriptor_buffer_size, 32); 985 if (set->desc_mem.alloc_size) { 986 /* TODO: Do we really need to copy all the time? */ 987 memcpy(desc_mem.map, set->desc_mem.map, 988 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size)); 989 } 990 set->desc_mem = desc_mem; 991 992 struct anv_address addr = { 993 .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo, 994 .offset = set->desc_mem.offset, 995 }; 996 997 const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; 998 set->desc_surface_state = 999 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 1000 isl_dev->ss.size, isl_dev->ss.align); 1001 anv_fill_buffer_surface_state(cmd_buffer->device, 1002 set->desc_surface_state, 1003 ISL_FORMAT_R32G32B32A32_FLOAT, 1004 addr, layout->descriptor_buffer_size, 1); 1005 } 1006 1007 return set; 1008} 1009 1010void anv_CmdPushDescriptorSetKHR( 1011 VkCommandBuffer commandBuffer, 1012 VkPipelineBindPoint pipelineBindPoint, 1013 VkPipelineLayout _layout, 1014 uint32_t _set, 1015 uint32_t descriptorWriteCount, 1016 const VkWriteDescriptorSet* pDescriptorWrites) 1017{ 1018 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 1019 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 1020 1021 assert(_set < MAX_SETS); 1022 1023 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; 1024 1025 struct anv_descriptor_set *set = 1026 anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint, 1027 set_layout, _set); 1028 if (!set) 1029 return; 1030 1031 /* Go through the user supplied descriptors. */ 1032 for (uint32_t i = 0; i < descriptorWriteCount; i++) { 1033 const VkWriteDescriptorSet *write = &pDescriptorWrites[i]; 1034 1035 switch (write->descriptorType) { 1036 case VK_DESCRIPTOR_TYPE_SAMPLER: 1037 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 1038 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 1039 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 1040 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 1041 for (uint32_t j = 0; j < write->descriptorCount; j++) { 1042 anv_descriptor_set_write_image_view(cmd_buffer->device, set, 1043 write->pImageInfo + j, 1044 write->descriptorType, 1045 write->dstBinding, 1046 write->dstArrayElement + j); 1047 } 1048 break; 1049 1050 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 1051 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 1052 for (uint32_t j = 0; j < write->descriptorCount; j++) { 1053 ANV_FROM_HANDLE(anv_buffer_view, bview, 1054 write->pTexelBufferView[j]); 1055 1056 anv_descriptor_set_write_buffer_view(cmd_buffer->device, set, 1057 write->descriptorType, 1058 bview, 1059 write->dstBinding, 1060 write->dstArrayElement + j); 1061 } 1062 break; 1063 1064 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 1065 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 1066 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 1067 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 1068 for (uint32_t j = 0; j < write->descriptorCount; j++) { 1069 assert(write->pBufferInfo[j].buffer); 1070 ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer); 1071 assert(buffer); 1072 1073 anv_descriptor_set_write_buffer(cmd_buffer->device, set, 1074 &cmd_buffer->surface_state_stream, 1075 write->descriptorType, 1076 buffer, 1077 write->dstBinding, 1078 write->dstArrayElement + j, 1079 write->pBufferInfo[j].offset, 1080 write->pBufferInfo[j].range); 1081 } 1082 break; 1083 1084 case VK_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT: { 1085 const VkWriteDescriptorSetInlineUniformBlockEXT *inline_write = 1086 vk_find_struct_const(write->pNext, 1087 WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT); 1088 assert(inline_write->dataSize == write->descriptorCount); 1089 anv_descriptor_set_write_inline_uniform_data(cmd_buffer->device, set, 1090 write->dstBinding, 1091 inline_write->pData, 1092 write->dstArrayElement, 1093 inline_write->dataSize); 1094 break; 1095 } 1096 1097 default: 1098 break; 1099 } 1100 } 1101 1102 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, 1103 layout, _set, set, NULL, NULL); 1104} 1105 1106void anv_CmdPushDescriptorSetWithTemplateKHR( 1107 VkCommandBuffer commandBuffer, 1108 VkDescriptorUpdateTemplate descriptorUpdateTemplate, 1109 VkPipelineLayout _layout, 1110 uint32_t _set, 1111 const void* pData) 1112{ 1113 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 1114 ANV_FROM_HANDLE(anv_descriptor_update_template, template, 1115 descriptorUpdateTemplate); 1116 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 1117 1118 assert(_set < MAX_PUSH_DESCRIPTORS); 1119 1120 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; 1121 1122 struct anv_descriptor_set *set = 1123 anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point, 1124 set_layout, _set); 1125 if (!set) 1126 return; 1127 1128 anv_descriptor_set_write_template(cmd_buffer->device, set, 1129 &cmd_buffer->surface_state_stream, 1130 template, 1131 pData); 1132 1133 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point, 1134 layout, _set, set, NULL, NULL); 1135} 1136 1137void anv_CmdSetDeviceMask( 1138 VkCommandBuffer commandBuffer, 1139 uint32_t deviceMask) 1140{ 1141 /* No-op */ 1142} 1143