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