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_reset(struct anv_cmd_buffer *cmd_buffer) 117 { 118 struct anv_cmd_state *state = &cmd_buffer->state; 119 120 memset(&state->descriptors, 0, sizeof(state->descriptors)); 121 for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { 122 if (state->push_constants[i] != NULL) { 123 vk_free(&cmd_buffer->pool->alloc, state->push_constants[i]); 124 state->push_constants[i] = NULL; 125 } 126 } 127 memset(state->binding_tables, 0, sizeof(state->binding_tables)); 128 memset(state->samplers, 0, sizeof(state->samplers)); 129 130 /* 0 isn't a valid config. This ensures that we always configure L3$. */ 131 cmd_buffer->state.current_l3_config = 0; 132 133 state->dirty = 0; 134 state->vb_dirty = 0; 135 state->pending_pipe_bits = 0; 136 state->descriptors_dirty = 0; 137 state->push_constants_dirty = 0; 138 state->pipeline = NULL; 139 state->push_constant_stages = 0; 140 state->restart_index = UINT32_MAX; 141 state->dynamic = default_dynamic_state; 142 state->need_query_wa = true; 143 144 if (state->attachments != NULL) { 145 vk_free(&cmd_buffer->pool->alloc, state->attachments); 146 state->attachments = NULL; 147 } 148 149 state->gen7.index_buffer = NULL; 150 } 151 152 VkResult 153 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer, 154 gl_shader_stage stage, uint32_t size) 155 { 156 struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage]; 157 158 if (*ptr == NULL) { 159 *ptr = vk_alloc(&cmd_buffer->pool->alloc, size, 8, 160 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 161 if (*ptr == NULL) 162 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 163 } else if ((*ptr)->size < size) { 164 *ptr = vk_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8, 165 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 166 if (*ptr == NULL) 167 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 168 } 169 (*ptr)->size = size; 170 171 return VK_SUCCESS; 172 } 173 174 static VkResult anv_create_cmd_buffer( 175 struct anv_device * device, 176 struct anv_cmd_pool * pool, 177 VkCommandBufferLevel level, 178 VkCommandBuffer* pCommandBuffer) 179 { 180 struct anv_cmd_buffer *cmd_buffer; 181 VkResult result; 182 183 cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8, 184 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 185 if (cmd_buffer == NULL) 186 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 187 188 for (uint32_t i = 0; i < MESA_SHADER_STAGES; i++) { 189 cmd_buffer->state.push_constants[i] = NULL; 190 } 191 cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC; 192 cmd_buffer->device = device; 193 cmd_buffer->pool = pool; 194 cmd_buffer->level = level; 195 cmd_buffer->state.attachments = NULL; 196 197 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer); 198 if (result != VK_SUCCESS) 199 goto fail; 200 201 anv_state_stream_init(&cmd_buffer->surface_state_stream, 202 &device->surface_state_block_pool); 203 anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 204 &device->dynamic_state_block_pool); 205 206 if (pool) { 207 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); 208 } else { 209 /* Init the pool_link so we can safefly call list_del when we destroy 210 * the command buffer 211 */ 212 list_inithead(&cmd_buffer->pool_link); 213 } 214 215 *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer); 216 217 return VK_SUCCESS; 218 219 fail: 220 vk_free(&cmd_buffer->pool->alloc, cmd_buffer); 221 222 return result; 223 } 224 225 VkResult anv_AllocateCommandBuffers( 226 VkDevice _device, 227 const VkCommandBufferAllocateInfo* pAllocateInfo, 228 VkCommandBuffer* pCommandBuffers) 229 { 230 ANV_FROM_HANDLE(anv_device, device, _device); 231 ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool); 232 233 VkResult result = VK_SUCCESS; 234 uint32_t i; 235 236 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) { 237 result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level, 238 &pCommandBuffers[i]); 239 if (result != VK_SUCCESS) 240 break; 241 } 242 243 if (result != VK_SUCCESS) { 244 anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool, 245 i, pCommandBuffers); 246 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) 247 pCommandBuffers[i] = VK_NULL_HANDLE; 248 } 249 250 return result; 251 } 252 253 static void 254 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer) 255 { 256 list_del(&cmd_buffer->pool_link); 257 258 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer); 259 260 anv_state_stream_finish(&cmd_buffer->surface_state_stream); 261 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 262 263 vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments); 264 vk_free(&cmd_buffer->pool->alloc, cmd_buffer); 265 } 266 267 void anv_FreeCommandBuffers( 268 VkDevice device, 269 VkCommandPool commandPool, 270 uint32_t commandBufferCount, 271 const VkCommandBuffer* pCommandBuffers) 272 { 273 for (uint32_t i = 0; i < commandBufferCount; i++) { 274 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]); 275 276 if (!cmd_buffer) 277 continue; 278 279 anv_cmd_buffer_destroy(cmd_buffer); 280 } 281 } 282 283 VkResult 284 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer) 285 { 286 cmd_buffer->usage_flags = 0; 287 cmd_buffer->state.current_pipeline = UINT32_MAX; 288 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer); 289 anv_cmd_state_reset(cmd_buffer); 290 291 anv_state_stream_finish(&cmd_buffer->surface_state_stream); 292 anv_state_stream_init(&cmd_buffer->surface_state_stream, 293 &cmd_buffer->device->surface_state_block_pool); 294 295 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 296 anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 297 &cmd_buffer->device->dynamic_state_block_pool); 298 return VK_SUCCESS; 299 } 300 301 VkResult anv_ResetCommandBuffer( 302 VkCommandBuffer commandBuffer, 303 VkCommandBufferResetFlags flags) 304 { 305 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 306 return anv_cmd_buffer_reset(cmd_buffer); 307 } 308 309 void 310 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer) 311 { 312 switch (cmd_buffer->device->info.gen) { 313 case 7: 314 if (cmd_buffer->device->info.is_haswell) 315 return gen75_cmd_buffer_emit_state_base_address(cmd_buffer); 316 else 317 return gen7_cmd_buffer_emit_state_base_address(cmd_buffer); 318 case 8: 319 return gen8_cmd_buffer_emit_state_base_address(cmd_buffer); 320 case 9: 321 return gen9_cmd_buffer_emit_state_base_address(cmd_buffer); 322 default: 323 unreachable("unsupported gen\n"); 324 } 325 } 326 327 void anv_CmdBindPipeline( 328 VkCommandBuffer commandBuffer, 329 VkPipelineBindPoint pipelineBindPoint, 330 VkPipeline _pipeline) 331 { 332 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 333 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline); 334 335 switch (pipelineBindPoint) { 336 case VK_PIPELINE_BIND_POINT_COMPUTE: 337 cmd_buffer->state.compute_pipeline = pipeline; 338 cmd_buffer->state.compute_dirty |= ANV_CMD_DIRTY_PIPELINE; 339 cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; 340 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT; 341 break; 342 343 case VK_PIPELINE_BIND_POINT_GRAPHICS: 344 cmd_buffer->state.pipeline = pipeline; 345 cmd_buffer->state.vb_dirty |= pipeline->vb_used; 346 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE; 347 cmd_buffer->state.push_constants_dirty |= pipeline->active_stages; 348 cmd_buffer->state.descriptors_dirty |= pipeline->active_stages; 349 350 /* Apply the dynamic state from the pipeline */ 351 cmd_buffer->state.dirty |= pipeline->dynamic_state_mask; 352 anv_dynamic_state_copy(&cmd_buffer->state.dynamic, 353 &pipeline->dynamic_state, 354 pipeline->dynamic_state_mask); 355 break; 356 357 default: 358 assert(!"invalid bind point"); 359 break; 360 } 361 } 362 363 void anv_CmdSetViewport( 364 VkCommandBuffer commandBuffer, 365 uint32_t firstViewport, 366 uint32_t viewportCount, 367 const VkViewport* pViewports) 368 { 369 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 370 371 const uint32_t total_count = firstViewport + viewportCount; 372 if (cmd_buffer->state.dynamic.viewport.count < total_count) 373 cmd_buffer->state.dynamic.viewport.count = total_count; 374 375 memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport, 376 pViewports, viewportCount * sizeof(*pViewports)); 377 378 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; 379 } 380 381 void anv_CmdSetScissor( 382 VkCommandBuffer commandBuffer, 383 uint32_t firstScissor, 384 uint32_t scissorCount, 385 const VkRect2D* pScissors) 386 { 387 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 388 389 const uint32_t total_count = firstScissor + scissorCount; 390 if (cmd_buffer->state.dynamic.scissor.count < total_count) 391 cmd_buffer->state.dynamic.scissor.count = total_count; 392 393 memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor, 394 pScissors, scissorCount * sizeof(*pScissors)); 395 396 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; 397 } 398 399 void anv_CmdSetLineWidth( 400 VkCommandBuffer commandBuffer, 401 float lineWidth) 402 { 403 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 404 405 cmd_buffer->state.dynamic.line_width = lineWidth; 406 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; 407 } 408 409 void anv_CmdSetDepthBias( 410 VkCommandBuffer commandBuffer, 411 float depthBiasConstantFactor, 412 float depthBiasClamp, 413 float depthBiasSlopeFactor) 414 { 415 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 416 417 cmd_buffer->state.dynamic.depth_bias.bias = depthBiasConstantFactor; 418 cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp; 419 cmd_buffer->state.dynamic.depth_bias.slope = depthBiasSlopeFactor; 420 421 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; 422 } 423 424 void anv_CmdSetBlendConstants( 425 VkCommandBuffer commandBuffer, 426 const float blendConstants[4]) 427 { 428 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 429 430 memcpy(cmd_buffer->state.dynamic.blend_constants, 431 blendConstants, sizeof(float) * 4); 432 433 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; 434 } 435 436 void anv_CmdSetDepthBounds( 437 VkCommandBuffer commandBuffer, 438 float minDepthBounds, 439 float maxDepthBounds) 440 { 441 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 442 443 cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds; 444 cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds; 445 446 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; 447 } 448 449 void anv_CmdSetStencilCompareMask( 450 VkCommandBuffer commandBuffer, 451 VkStencilFaceFlags faceMask, 452 uint32_t compareMask) 453 { 454 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 455 456 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 457 cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask; 458 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 459 cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask; 460 461 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; 462 } 463 464 void anv_CmdSetStencilWriteMask( 465 VkCommandBuffer commandBuffer, 466 VkStencilFaceFlags faceMask, 467 uint32_t writeMask) 468 { 469 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 470 471 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 472 cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask; 473 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 474 cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask; 475 476 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; 477 } 478 479 void anv_CmdSetStencilReference( 480 VkCommandBuffer commandBuffer, 481 VkStencilFaceFlags faceMask, 482 uint32_t reference) 483 { 484 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 485 486 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 487 cmd_buffer->state.dynamic.stencil_reference.front = reference; 488 if (faceMask & VK_STENCIL_FACE_BACK_BIT) 489 cmd_buffer->state.dynamic.stencil_reference.back = reference; 490 491 cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; 492 } 493 494 void anv_CmdBindDescriptorSets( 495 VkCommandBuffer commandBuffer, 496 VkPipelineBindPoint pipelineBindPoint, 497 VkPipelineLayout _layout, 498 uint32_t firstSet, 499 uint32_t descriptorSetCount, 500 const VkDescriptorSet* pDescriptorSets, 501 uint32_t dynamicOffsetCount, 502 const uint32_t* pDynamicOffsets) 503 { 504 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 505 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 506 struct anv_descriptor_set_layout *set_layout; 507 508 assert(firstSet + descriptorSetCount < MAX_SETS); 509 510 for (uint32_t i = 0; i < descriptorSetCount; i++) { 511 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]); 512 set_layout = layout->set[firstSet + i].layout; 513 514 if (cmd_buffer->state.descriptors[firstSet + i] != set) { 515 cmd_buffer->state.descriptors[firstSet + i] = set; 516 cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages; 517 } 518 519 if (set_layout->dynamic_offset_count > 0) { 520 anv_foreach_stage(s, set_layout->shader_stages) { 521 anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, s, dynamic); 522 523 struct anv_push_constants *push = 524 cmd_buffer->state.push_constants[s]; 525 526 unsigned d = layout->set[firstSet + i].dynamic_offset_start; 527 const uint32_t *offsets = pDynamicOffsets; 528 struct anv_descriptor *desc = set->descriptors; 529 530 for (unsigned b = 0; b < set_layout->binding_count; b++) { 531 if (set_layout->binding[b].dynamic_offset_index < 0) 532 continue; 533 534 unsigned array_size = set_layout->binding[b].array_size; 535 for (unsigned j = 0; j < array_size; j++) { 536 push->dynamic[d].offset = *(offsets++); 537 push->dynamic[d].range = (desc->buffer_view) ? 538 desc->buffer_view->range : 0; 539 desc++; 540 d++; 541 } 542 } 543 } 544 cmd_buffer->state.push_constants_dirty |= set_layout->shader_stages; 545 } 546 } 547 } 548 549 void anv_CmdBindVertexBuffers( 550 VkCommandBuffer commandBuffer, 551 uint32_t firstBinding, 552 uint32_t bindingCount, 553 const VkBuffer* pBuffers, 554 const VkDeviceSize* pOffsets) 555 { 556 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 557 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings; 558 559 /* We have to defer setting up vertex buffer since we need the buffer 560 * stride from the pipeline. */ 561 562 assert(firstBinding + bindingCount < MAX_VBS); 563 for (uint32_t i = 0; i < bindingCount; i++) { 564 vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]); 565 vb[firstBinding + i].offset = pOffsets[i]; 566 cmd_buffer->state.vb_dirty |= 1 << (firstBinding + i); 567 } 568 } 569 570 enum isl_format 571 anv_isl_format_for_descriptor_type(VkDescriptorType type) 572 { 573 switch (type) { 574 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 575 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 576 return ISL_FORMAT_R32G32B32A32_FLOAT; 577 578 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 579 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 580 return ISL_FORMAT_RAW; 581 582 default: 583 unreachable("Invalid descriptor type"); 584 } 585 } 586 587 struct anv_state 588 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer, 589 const void *data, uint32_t size, uint32_t alignment) 590 { 591 struct anv_state state; 592 593 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment); 594 memcpy(state.map, data, size); 595 596 if (!cmd_buffer->device->info.has_llc) 597 anv_state_clflush(state); 598 599 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size)); 600 601 return state; 602 } 603 604 struct anv_state 605 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer, 606 uint32_t *a, uint32_t *b, 607 uint32_t dwords, uint32_t alignment) 608 { 609 struct anv_state state; 610 uint32_t *p; 611 612 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 613 dwords * 4, alignment); 614 p = state.map; 615 for (uint32_t i = 0; i < dwords; i++) 616 p[i] = a[i] | b[i]; 617 618 if (!cmd_buffer->device->info.has_llc) 619 anv_state_clflush(state); 620 621 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4)); 622 623 return state; 624 } 625 626 struct anv_state 627 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer, 628 gl_shader_stage stage) 629 { 630 /* If we don't have this stage, bail. */ 631 if (!anv_pipeline_has_stage(cmd_buffer->state.pipeline, stage)) 632 return (struct anv_state) { .offset = 0 }; 633 634 struct anv_push_constants *data = 635 cmd_buffer->state.push_constants[stage]; 636 const struct brw_stage_prog_data *prog_data = 637 cmd_buffer->state.pipeline->shaders[stage]->prog_data; 638 639 /* If we don't actually have any push constants, bail. */ 640 if (data == NULL || prog_data == NULL || prog_data->nr_params == 0) 641 return (struct anv_state) { .offset = 0 }; 642 643 struct anv_state state = 644 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 645 prog_data->nr_params * sizeof(float), 646 32 /* bottom 5 bits MBZ */); 647 648 /* Walk through the param array and fill the buffer with data */ 649 uint32_t *u32_map = state.map; 650 for (unsigned i = 0; i < prog_data->nr_params; i++) { 651 uint32_t offset = (uintptr_t)prog_data->param[i]; 652 u32_map[i] = *(uint32_t *)((uint8_t *)data + offset); 653 } 654 655 if (!cmd_buffer->device->info.has_llc) 656 anv_state_clflush(state); 657 658 return state; 659 } 660 661 struct anv_state 662 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) 663 { 664 struct anv_push_constants *data = 665 cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE]; 666 struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline; 667 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline); 668 const struct brw_stage_prog_data *prog_data = &cs_prog_data->base; 669 670 /* If we don't actually have any push constants, bail. */ 671 if (cs_prog_data->push.total.size == 0) 672 return (struct anv_state) { .offset = 0 }; 673 674 const unsigned push_constant_alignment = 675 cmd_buffer->device->info.gen < 8 ? 32 : 64; 676 const unsigned aligned_total_push_constants_size = 677 ALIGN(cs_prog_data->push.total.size, push_constant_alignment); 678 struct anv_state state = 679 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 680 aligned_total_push_constants_size, 681 push_constant_alignment); 682 683 /* Walk through the param array and fill the buffer with data */ 684 uint32_t *u32_map = state.map; 685 686 if (cs_prog_data->push.cross_thread.size > 0) { 687 assert(cs_prog_data->thread_local_id_index < 0 || 688 cs_prog_data->thread_local_id_index >= 689 cs_prog_data->push.cross_thread.dwords); 690 for (unsigned i = 0; 691 i < cs_prog_data->push.cross_thread.dwords; 692 i++) { 693 uint32_t offset = (uintptr_t)prog_data->param[i]; 694 u32_map[i] = *(uint32_t *)((uint8_t *)data + offset); 695 } 696 } 697 698 if (cs_prog_data->push.per_thread.size > 0) { 699 for (unsigned t = 0; t < cs_prog_data->threads; t++) { 700 unsigned dst = 701 8 * (cs_prog_data->push.per_thread.regs * t + 702 cs_prog_data->push.cross_thread.regs); 703 unsigned src = cs_prog_data->push.cross_thread.dwords; 704 for ( ; src < prog_data->nr_params; src++, dst++) { 705 if (src != cs_prog_data->thread_local_id_index) { 706 uint32_t offset = (uintptr_t)prog_data->param[src]; 707 u32_map[dst] = *(uint32_t *)((uint8_t *)data + offset); 708 } else { 709 u32_map[dst] = t * cs_prog_data->simd_size; 710 } 711 } 712 } 713 } 714 715 if (!cmd_buffer->device->info.has_llc) 716 anv_state_clflush(state); 717 718 return state; 719 } 720 721 void anv_CmdPushConstants( 722 VkCommandBuffer commandBuffer, 723 VkPipelineLayout layout, 724 VkShaderStageFlags stageFlags, 725 uint32_t offset, 726 uint32_t size, 727 const void* pValues) 728 { 729 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 730 731 anv_foreach_stage(stage, stageFlags) { 732 anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data); 733 734 memcpy(cmd_buffer->state.push_constants[stage]->client_data + offset, 735 pValues, size); 736 } 737 738 cmd_buffer->state.push_constants_dirty |= stageFlags; 739 } 740 741 VkResult anv_CreateCommandPool( 742 VkDevice _device, 743 const VkCommandPoolCreateInfo* pCreateInfo, 744 const VkAllocationCallbacks* pAllocator, 745 VkCommandPool* pCmdPool) 746 { 747 ANV_FROM_HANDLE(anv_device, device, _device); 748 struct anv_cmd_pool *pool; 749 750 pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8, 751 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 752 if (pool == NULL) 753 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 754 755 if (pAllocator) 756 pool->alloc = *pAllocator; 757 else 758 pool->alloc = device->alloc; 759 760 list_inithead(&pool->cmd_buffers); 761 762 *pCmdPool = anv_cmd_pool_to_handle(pool); 763 764 return VK_SUCCESS; 765 } 766 767 void anv_DestroyCommandPool( 768 VkDevice _device, 769 VkCommandPool commandPool, 770 const VkAllocationCallbacks* pAllocator) 771 { 772 ANV_FROM_HANDLE(anv_device, device, _device); 773 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 774 775 if (!pool) 776 return; 777 778 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer, 779 &pool->cmd_buffers, pool_link) { 780 anv_cmd_buffer_destroy(cmd_buffer); 781 } 782 783 vk_free2(&device->alloc, pAllocator, pool); 784 } 785 786 VkResult anv_ResetCommandPool( 787 VkDevice device, 788 VkCommandPool commandPool, 789 VkCommandPoolResetFlags flags) 790 { 791 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 792 793 list_for_each_entry(struct anv_cmd_buffer, cmd_buffer, 794 &pool->cmd_buffers, pool_link) { 795 anv_cmd_buffer_reset(cmd_buffer); 796 } 797 798 return VK_SUCCESS; 799 } 800 801 /** 802 * Return NULL if the current subpass has no depthstencil attachment. 803 */ 804 const struct anv_image_view * 805 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) 806 { 807 const struct anv_subpass *subpass = cmd_buffer->state.subpass; 808 const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer; 809 810 if (subpass->depth_stencil_attachment == VK_ATTACHMENT_UNUSED) 811 return NULL; 812 813 const struct anv_image_view *iview = 814 fb->attachments[subpass->depth_stencil_attachment]; 815 816 assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | 817 VK_IMAGE_ASPECT_STENCIL_BIT)); 818 819 return iview; 820 } 821