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