101e04c3fSmrg/* 201e04c3fSmrg * Copyright © 2015 Intel Corporation 301e04c3fSmrg * 401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a 501e04c3fSmrg * copy of this software and associated documentation files (the "Software"), 601e04c3fSmrg * to deal in the Software without restriction, including without limitation 701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the 901e04c3fSmrg * Software is furnished to do so, subject to the following conditions: 1001e04c3fSmrg * 1101e04c3fSmrg * The above copyright notice and this permission notice (including the next 1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the 1301e04c3fSmrg * Software. 1401e04c3fSmrg * 1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 2101e04c3fSmrg * IN THE SOFTWARE. 2201e04c3fSmrg */ 2301e04c3fSmrg 2401e04c3fSmrg#include <assert.h> 2501e04c3fSmrg#include <stdbool.h> 2601e04c3fSmrg#include <string.h> 2701e04c3fSmrg#include <unistd.h> 2801e04c3fSmrg#include <fcntl.h> 2901e04c3fSmrg 3001e04c3fSmrg#include "anv_private.h" 317ec681f3Smrg#include "anv_measure.h" 3201e04c3fSmrg 339f464c52Smaya#include "vk_util.h" 3401e04c3fSmrg 3501e04c3fSmrg/** \file anv_cmd_buffer.c 3601e04c3fSmrg * 3701e04c3fSmrg * This file contains all of the stuff for emitting commands into a command 3801e04c3fSmrg * buffer. This includes implementations of most of the vkCmd* 3901e04c3fSmrg * entrypoints. This file is concerned entirely with state emission and 4001e04c3fSmrg * not with the command buffer data structure itself. As far as this file 4101e04c3fSmrg * is concerned, most of anv_cmd_buffer is magic. 4201e04c3fSmrg */ 4301e04c3fSmrg 4401e04c3fSmrg/* TODO: These are taken from GLES. We should check the Vulkan spec */ 4501e04c3fSmrgconst struct anv_dynamic_state default_dynamic_state = { 4601e04c3fSmrg .viewport = { 4701e04c3fSmrg .count = 0, 4801e04c3fSmrg }, 4901e04c3fSmrg .scissor = { 5001e04c3fSmrg .count = 0, 5101e04c3fSmrg }, 5201e04c3fSmrg .line_width = 1.0f, 5301e04c3fSmrg .depth_bias = { 5401e04c3fSmrg .bias = 0.0f, 5501e04c3fSmrg .clamp = 0.0f, 5601e04c3fSmrg .slope = 0.0f, 5701e04c3fSmrg }, 5801e04c3fSmrg .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f }, 5901e04c3fSmrg .depth_bounds = { 6001e04c3fSmrg .min = 0.0f, 6101e04c3fSmrg .max = 1.0f, 6201e04c3fSmrg }, 6301e04c3fSmrg .stencil_compare_mask = { 6401e04c3fSmrg .front = ~0u, 6501e04c3fSmrg .back = ~0u, 6601e04c3fSmrg }, 6701e04c3fSmrg .stencil_write_mask = { 6801e04c3fSmrg .front = ~0u, 6901e04c3fSmrg .back = ~0u, 7001e04c3fSmrg }, 7101e04c3fSmrg .stencil_reference = { 7201e04c3fSmrg .front = 0u, 7301e04c3fSmrg .back = 0u, 7401e04c3fSmrg }, 757ec681f3Smrg .stencil_op = { 767ec681f3Smrg .front = { 777ec681f3Smrg .fail_op = 0, 787ec681f3Smrg .pass_op = 0, 797ec681f3Smrg .depth_fail_op = 0, 807ec681f3Smrg .compare_op = 0, 817ec681f3Smrg }, 827ec681f3Smrg .back = { 837ec681f3Smrg .fail_op = 0, 847ec681f3Smrg .pass_op = 0, 857ec681f3Smrg .depth_fail_op = 0, 867ec681f3Smrg .compare_op = 0, 877ec681f3Smrg }, 887ec681f3Smrg }, 897ec681f3Smrg .line_stipple = { 907ec681f3Smrg .factor = 0u, 917ec681f3Smrg .pattern = 0u, 927ec681f3Smrg }, 937ec681f3Smrg .cull_mode = 0, 947ec681f3Smrg .front_face = 0, 957ec681f3Smrg .primitive_topology = 0, 967ec681f3Smrg .depth_test_enable = 0, 977ec681f3Smrg .depth_write_enable = 0, 987ec681f3Smrg .depth_compare_op = 0, 997ec681f3Smrg .depth_bounds_test_enable = 0, 1007ec681f3Smrg .stencil_test_enable = 0, 1017ec681f3Smrg .dyn_vbo_stride = 0, 1027ec681f3Smrg .dyn_vbo_size = 0, 1037ec681f3Smrg .color_writes = 0xff, 1047ec681f3Smrg .raster_discard = 0, 1057ec681f3Smrg .depth_bias_enable = 0, 1067ec681f3Smrg .primitive_restart_enable = 0, 1077ec681f3Smrg .logic_op = 0, 10801e04c3fSmrg}; 10901e04c3fSmrg 1107ec681f3Smrg/** 1117ec681f3Smrg * Copy the dynamic state from src to dest based on the copy_mask. 1127ec681f3Smrg * 1137ec681f3Smrg * Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and 1147ec681f3Smrg * BLEND_CONSTANTS (always copy them if they are in the copy_mask). 1157ec681f3Smrg * 1167ec681f3Smrg * Returns a mask of the states which changed. 1177ec681f3Smrg */ 1187ec681f3Smrganv_cmd_dirty_mask_t 11901e04c3fSmrganv_dynamic_state_copy(struct anv_dynamic_state *dest, 12001e04c3fSmrg const struct anv_dynamic_state *src, 1217ec681f3Smrg anv_cmd_dirty_mask_t copy_mask) 12201e04c3fSmrg{ 1237ec681f3Smrg anv_cmd_dirty_mask_t changed = 0; 1247ec681f3Smrg 1257ec681f3Smrg if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) { 12601e04c3fSmrg dest->viewport.count = src->viewport.count; 12701e04c3fSmrg typed_memcpy(dest->viewport.viewports, src->viewport.viewports, 12801e04c3fSmrg src->viewport.count); 1297ec681f3Smrg changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; 13001e04c3fSmrg } 13101e04c3fSmrg 1327ec681f3Smrg if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) { 13301e04c3fSmrg dest->scissor.count = src->scissor.count; 13401e04c3fSmrg typed_memcpy(dest->scissor.scissors, src->scissor.scissors, 13501e04c3fSmrg src->scissor.count); 1367ec681f3Smrg changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; 13701e04c3fSmrg } 13801e04c3fSmrg 1397ec681f3Smrg if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) { 1407ec681f3Smrg typed_memcpy(dest->blend_constants, src->blend_constants, 4); 1417ec681f3Smrg changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; 1427ec681f3Smrg } 14301e04c3fSmrg 1447ec681f3Smrg#define ANV_CMP_COPY(field, flag) \ 1457ec681f3Smrg if (copy_mask & flag) { \ 1467ec681f3Smrg if (dest->field != src->field) { \ 1477ec681f3Smrg dest->field = src->field; \ 1487ec681f3Smrg changed |= flag; \ 1497ec681f3Smrg } \ 1507ec681f3Smrg } 15101e04c3fSmrg 1527ec681f3Smrg ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH); 1537ec681f3Smrg 1547ec681f3Smrg ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); 1557ec681f3Smrg ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); 1567ec681f3Smrg ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS); 1577ec681f3Smrg 1587ec681f3Smrg ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS); 1597ec681f3Smrg ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS); 1607ec681f3Smrg 1617ec681f3Smrg ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK); 1627ec681f3Smrg ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK); 1637ec681f3Smrg 1647ec681f3Smrg ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK); 1657ec681f3Smrg ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK); 1667ec681f3Smrg 1677ec681f3Smrg ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE); 1687ec681f3Smrg ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE); 1697ec681f3Smrg 1707ec681f3Smrg ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE); 1717ec681f3Smrg ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE); 1727ec681f3Smrg 1737ec681f3Smrg ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE); 1747ec681f3Smrg ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE); 1757ec681f3Smrg ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY); 1767ec681f3Smrg ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE); 1777ec681f3Smrg ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE); 1787ec681f3Smrg ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP); 1797ec681f3Smrg ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE); 1807ec681f3Smrg ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE); 1817ec681f3Smrg 1827ec681f3Smrg if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP_EXT) { 1837ec681f3Smrg ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1847ec681f3Smrg ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1857ec681f3Smrg ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1867ec681f3Smrg ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1877ec681f3Smrg ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1887ec681f3Smrg ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1897ec681f3Smrg ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1907ec681f3Smrg ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP); 1917ec681f3Smrg } 19201e04c3fSmrg 1937ec681f3Smrg ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE); 1947ec681f3Smrg ANV_CMP_COPY(dyn_vbo_size, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE); 19501e04c3fSmrg 1967ec681f3Smrg ANV_CMP_COPY(raster_discard, ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE); 1977ec681f3Smrg ANV_CMP_COPY(depth_bias_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE); 1987ec681f3Smrg ANV_CMP_COPY(primitive_restart_enable, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE); 1997ec681f3Smrg ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP); 2007ec681f3Smrg 2017ec681f3Smrg if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) { 2027ec681f3Smrg dest->sample_locations.samples = src->sample_locations.samples; 2037ec681f3Smrg typed_memcpy(dest->sample_locations.locations, 2047ec681f3Smrg src->sample_locations.locations, 2057ec681f3Smrg dest->sample_locations.samples); 2067ec681f3Smrg changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS; 2077ec681f3Smrg } 20801e04c3fSmrg 2097ec681f3Smrg ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE); 21001e04c3fSmrg 2117ec681f3Smrg ANV_CMP_COPY(fragment_shading_rate.width, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE); 2127ec681f3Smrg ANV_CMP_COPY(fragment_shading_rate.height, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE); 2137ec681f3Smrg 2147ec681f3Smrg#undef ANV_CMP_COPY 2157ec681f3Smrg 2167ec681f3Smrg return changed; 21701e04c3fSmrg} 21801e04c3fSmrg 21901e04c3fSmrgstatic void 22001e04c3fSmrganv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer) 22101e04c3fSmrg{ 22201e04c3fSmrg struct anv_cmd_state *state = &cmd_buffer->state; 22301e04c3fSmrg 22401e04c3fSmrg memset(state, 0, sizeof(*state)); 22501e04c3fSmrg 22601e04c3fSmrg state->current_pipeline = UINT32_MAX; 22701e04c3fSmrg state->restart_index = UINT32_MAX; 22801e04c3fSmrg state->gfx.dynamic = default_dynamic_state; 22901e04c3fSmrg} 23001e04c3fSmrg 23101e04c3fSmrgstatic void 23201e04c3fSmrganv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer, 23301e04c3fSmrg struct anv_cmd_pipeline_state *pipe_state) 23401e04c3fSmrg{ 2359f464c52Smaya for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) { 2369f464c52Smaya if (pipe_state->push_descriptors[i]) { 2379f464c52Smaya anv_descriptor_set_layout_unref(cmd_buffer->device, 2389f464c52Smaya pipe_state->push_descriptors[i]->set.layout); 2399f464c52Smaya vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]); 2409f464c52Smaya } 2419f464c52Smaya } 24201e04c3fSmrg} 24301e04c3fSmrg 24401e04c3fSmrgstatic void 24501e04c3fSmrganv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer) 24601e04c3fSmrg{ 24701e04c3fSmrg struct anv_cmd_state *state = &cmd_buffer->state; 24801e04c3fSmrg 24901e04c3fSmrg anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base); 25001e04c3fSmrg anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base); 25101e04c3fSmrg 25201e04c3fSmrg vk_free(&cmd_buffer->pool->alloc, state->attachments); 25301e04c3fSmrg} 25401e04c3fSmrg 25501e04c3fSmrgstatic void 25601e04c3fSmrganv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer) 25701e04c3fSmrg{ 25801e04c3fSmrg anv_cmd_state_finish(cmd_buffer); 25901e04c3fSmrg anv_cmd_state_init(cmd_buffer); 26001e04c3fSmrg} 26101e04c3fSmrg 26201e04c3fSmrgstatic VkResult anv_create_cmd_buffer( 26301e04c3fSmrg struct anv_device * device, 26401e04c3fSmrg struct anv_cmd_pool * pool, 26501e04c3fSmrg VkCommandBufferLevel level, 26601e04c3fSmrg VkCommandBuffer* pCommandBuffer) 26701e04c3fSmrg{ 26801e04c3fSmrg struct anv_cmd_buffer *cmd_buffer; 26901e04c3fSmrg VkResult result; 27001e04c3fSmrg 2717ec681f3Smrg cmd_buffer = vk_alloc2(&device->vk.alloc, &pool->alloc, sizeof(*cmd_buffer), 2727ec681f3Smrg 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 27301e04c3fSmrg if (cmd_buffer == NULL) 2747ec681f3Smrg return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY); 2757ec681f3Smrg 2767ec681f3Smrg result = vk_command_buffer_init(&cmd_buffer->vk, &device->vk); 2777ec681f3Smrg if (result != VK_SUCCESS) 2787ec681f3Smrg goto fail_alloc; 27901e04c3fSmrg 28001e04c3fSmrg cmd_buffer->batch.status = VK_SUCCESS; 28101e04c3fSmrg 28201e04c3fSmrg cmd_buffer->device = device; 28301e04c3fSmrg cmd_buffer->pool = pool; 28401e04c3fSmrg cmd_buffer->level = level; 28501e04c3fSmrg 28601e04c3fSmrg result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer); 28701e04c3fSmrg if (result != VK_SUCCESS) 2887ec681f3Smrg goto fail_vk; 28901e04c3fSmrg 29001e04c3fSmrg anv_state_stream_init(&cmd_buffer->surface_state_stream, 29101e04c3fSmrg &device->surface_state_pool, 4096); 29201e04c3fSmrg anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 29301e04c3fSmrg &device->dynamic_state_pool, 16384); 2947ec681f3Smrg anv_state_stream_init(&cmd_buffer->general_state_stream, 2957ec681f3Smrg &device->general_state_pool, 16384); 2967ec681f3Smrg 2977ec681f3Smrg cmd_buffer->self_mod_locations = NULL; 29801e04c3fSmrg 29901e04c3fSmrg anv_cmd_state_init(cmd_buffer); 30001e04c3fSmrg 3017ec681f3Smrg list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers); 3027ec681f3Smrg 3037ec681f3Smrg anv_measure_init(cmd_buffer); 30401e04c3fSmrg 30501e04c3fSmrg *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer); 30601e04c3fSmrg 30701e04c3fSmrg return VK_SUCCESS; 30801e04c3fSmrg 3097ec681f3Smrg fail_vk: 3107ec681f3Smrg vk_command_buffer_finish(&cmd_buffer->vk); 3117ec681f3Smrg fail_alloc: 3127ec681f3Smrg vk_free2(&device->vk.alloc, &pool->alloc, cmd_buffer); 31301e04c3fSmrg 31401e04c3fSmrg return result; 31501e04c3fSmrg} 31601e04c3fSmrg 31701e04c3fSmrgVkResult anv_AllocateCommandBuffers( 31801e04c3fSmrg VkDevice _device, 31901e04c3fSmrg const VkCommandBufferAllocateInfo* pAllocateInfo, 32001e04c3fSmrg VkCommandBuffer* pCommandBuffers) 32101e04c3fSmrg{ 32201e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 32301e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool); 32401e04c3fSmrg 32501e04c3fSmrg VkResult result = VK_SUCCESS; 32601e04c3fSmrg uint32_t i; 32701e04c3fSmrg 32801e04c3fSmrg for (i = 0; i < pAllocateInfo->commandBufferCount; i++) { 32901e04c3fSmrg result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level, 33001e04c3fSmrg &pCommandBuffers[i]); 33101e04c3fSmrg if (result != VK_SUCCESS) 33201e04c3fSmrg break; 33301e04c3fSmrg } 33401e04c3fSmrg 33501e04c3fSmrg if (result != VK_SUCCESS) { 33601e04c3fSmrg anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool, 33701e04c3fSmrg i, pCommandBuffers); 33801e04c3fSmrg for (i = 0; i < pAllocateInfo->commandBufferCount; i++) 33901e04c3fSmrg pCommandBuffers[i] = VK_NULL_HANDLE; 34001e04c3fSmrg } 34101e04c3fSmrg 34201e04c3fSmrg return result; 34301e04c3fSmrg} 34401e04c3fSmrg 34501e04c3fSmrgstatic void 34601e04c3fSmrganv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer) 34701e04c3fSmrg{ 3487ec681f3Smrg anv_measure_destroy(cmd_buffer); 3497ec681f3Smrg 35001e04c3fSmrg list_del(&cmd_buffer->pool_link); 35101e04c3fSmrg 35201e04c3fSmrg anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer); 35301e04c3fSmrg 35401e04c3fSmrg anv_state_stream_finish(&cmd_buffer->surface_state_stream); 35501e04c3fSmrg anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 3567ec681f3Smrg anv_state_stream_finish(&cmd_buffer->general_state_stream); 35701e04c3fSmrg 35801e04c3fSmrg anv_cmd_state_finish(cmd_buffer); 35901e04c3fSmrg 3607ec681f3Smrg vk_free(&cmd_buffer->pool->alloc, cmd_buffer->self_mod_locations); 3617ec681f3Smrg 3627ec681f3Smrg vk_command_buffer_finish(&cmd_buffer->vk); 3637ec681f3Smrg vk_free2(&cmd_buffer->device->vk.alloc, &cmd_buffer->pool->alloc, 3647ec681f3Smrg cmd_buffer); 36501e04c3fSmrg} 36601e04c3fSmrg 36701e04c3fSmrgvoid anv_FreeCommandBuffers( 36801e04c3fSmrg VkDevice device, 36901e04c3fSmrg VkCommandPool commandPool, 37001e04c3fSmrg uint32_t commandBufferCount, 37101e04c3fSmrg const VkCommandBuffer* pCommandBuffers) 37201e04c3fSmrg{ 37301e04c3fSmrg for (uint32_t i = 0; i < commandBufferCount; i++) { 37401e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]); 37501e04c3fSmrg 37601e04c3fSmrg if (!cmd_buffer) 37701e04c3fSmrg continue; 37801e04c3fSmrg 37901e04c3fSmrg anv_cmd_buffer_destroy(cmd_buffer); 38001e04c3fSmrg } 38101e04c3fSmrg} 38201e04c3fSmrg 38301e04c3fSmrgVkResult 38401e04c3fSmrganv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer) 38501e04c3fSmrg{ 3867ec681f3Smrg vk_command_buffer_reset(&cmd_buffer->vk); 3877ec681f3Smrg 38801e04c3fSmrg cmd_buffer->usage_flags = 0; 3897ec681f3Smrg cmd_buffer->perf_query_pool = NULL; 39001e04c3fSmrg anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer); 39101e04c3fSmrg anv_cmd_state_reset(cmd_buffer); 39201e04c3fSmrg 39301e04c3fSmrg anv_state_stream_finish(&cmd_buffer->surface_state_stream); 39401e04c3fSmrg anv_state_stream_init(&cmd_buffer->surface_state_stream, 39501e04c3fSmrg &cmd_buffer->device->surface_state_pool, 4096); 39601e04c3fSmrg 39701e04c3fSmrg anv_state_stream_finish(&cmd_buffer->dynamic_state_stream); 39801e04c3fSmrg anv_state_stream_init(&cmd_buffer->dynamic_state_stream, 39901e04c3fSmrg &cmd_buffer->device->dynamic_state_pool, 16384); 4007ec681f3Smrg 4017ec681f3Smrg anv_state_stream_finish(&cmd_buffer->general_state_stream); 4027ec681f3Smrg anv_state_stream_init(&cmd_buffer->general_state_stream, 4037ec681f3Smrg &cmd_buffer->device->general_state_pool, 16384); 4047ec681f3Smrg 4057ec681f3Smrg anv_measure_reset(cmd_buffer); 40601e04c3fSmrg return VK_SUCCESS; 40701e04c3fSmrg} 40801e04c3fSmrg 40901e04c3fSmrgVkResult anv_ResetCommandBuffer( 41001e04c3fSmrg VkCommandBuffer commandBuffer, 41101e04c3fSmrg VkCommandBufferResetFlags flags) 41201e04c3fSmrg{ 41301e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 41401e04c3fSmrg return anv_cmd_buffer_reset(cmd_buffer); 41501e04c3fSmrg} 41601e04c3fSmrg 41701e04c3fSmrgvoid 41801e04c3fSmrganv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer) 41901e04c3fSmrg{ 4207ec681f3Smrg const struct intel_device_info *devinfo = &cmd_buffer->device->info; 4217ec681f3Smrg anv_genX(devinfo, cmd_buffer_emit_state_base_address)(cmd_buffer); 42201e04c3fSmrg} 42301e04c3fSmrg 42401e04c3fSmrgvoid 42501e04c3fSmrganv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer, 42601e04c3fSmrg const struct anv_image *image, 42701e04c3fSmrg VkImageAspectFlagBits aspect, 42801e04c3fSmrg enum isl_aux_usage aux_usage, 42901e04c3fSmrg uint32_t level, 43001e04c3fSmrg uint32_t base_layer, 43101e04c3fSmrg uint32_t layer_count) 43201e04c3fSmrg{ 4337ec681f3Smrg const struct intel_device_info *devinfo = &cmd_buffer->device->info; 4347ec681f3Smrg anv_genX(devinfo, cmd_buffer_mark_image_written)(cmd_buffer, image, 4357ec681f3Smrg aspect, aux_usage, 4367ec681f3Smrg level, base_layer, 4377ec681f3Smrg layer_count); 43801e04c3fSmrg} 43901e04c3fSmrg 4409f464c52Smayavoid 4419f464c52Smayaanv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer) 4429f464c52Smaya{ 4437ec681f3Smrg const struct intel_device_info *devinfo = &cmd_buffer->device->info; 4447ec681f3Smrg anv_genX(devinfo, cmd_emit_conditional_render_predicate)(cmd_buffer); 4457ec681f3Smrg} 4467ec681f3Smrg 4477ec681f3Smrgstatic bool 4487ec681f3Smrgmem_update(void *dst, const void *src, size_t size) 4497ec681f3Smrg{ 4507ec681f3Smrg if (memcmp(dst, src, size) == 0) 4517ec681f3Smrg return false; 4527ec681f3Smrg 4537ec681f3Smrg memcpy(dst, src, size); 4547ec681f3Smrg return true; 4557ec681f3Smrg} 4567ec681f3Smrg 4577ec681f3Smrgstatic void 4587ec681f3Smrgset_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer, 4597ec681f3Smrg gl_shader_stage stage, 4607ec681f3Smrg const struct anv_pipeline_bind_map *map) 4617ec681f3Smrg{ 4627ec681f3Smrg assert(stage < ARRAY_SIZE(cmd_buffer->state.surface_sha1s)); 4637ec681f3Smrg if (mem_update(cmd_buffer->state.surface_sha1s[stage], 4647ec681f3Smrg map->surface_sha1, sizeof(map->surface_sha1))) 4657ec681f3Smrg cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage); 4667ec681f3Smrg 4677ec681f3Smrg assert(stage < ARRAY_SIZE(cmd_buffer->state.sampler_sha1s)); 4687ec681f3Smrg if (mem_update(cmd_buffer->state.sampler_sha1s[stage], 4697ec681f3Smrg map->sampler_sha1, sizeof(map->sampler_sha1))) 4707ec681f3Smrg cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage); 4717ec681f3Smrg 4727ec681f3Smrg assert(stage < ARRAY_SIZE(cmd_buffer->state.push_sha1s)); 4737ec681f3Smrg if (mem_update(cmd_buffer->state.push_sha1s[stage], 4747ec681f3Smrg map->push_sha1, sizeof(map->push_sha1))) 4757ec681f3Smrg cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage); 4769f464c52Smaya} 4779f464c52Smaya 47801e04c3fSmrgvoid anv_CmdBindPipeline( 47901e04c3fSmrg VkCommandBuffer commandBuffer, 48001e04c3fSmrg VkPipelineBindPoint pipelineBindPoint, 48101e04c3fSmrg VkPipeline _pipeline) 48201e04c3fSmrg{ 48301e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 48401e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline); 48501e04c3fSmrg 48601e04c3fSmrg switch (pipelineBindPoint) { 4877ec681f3Smrg case VK_PIPELINE_BIND_POINT_COMPUTE: { 4887ec681f3Smrg struct anv_compute_pipeline *compute_pipeline = 4897ec681f3Smrg anv_pipeline_to_compute(pipeline); 4907ec681f3Smrg if (cmd_buffer->state.compute.pipeline == compute_pipeline) 4917ec681f3Smrg return; 4927ec681f3Smrg 4937ec681f3Smrg cmd_buffer->state.compute.pipeline = compute_pipeline; 49401e04c3fSmrg cmd_buffer->state.compute.pipeline_dirty = true; 4957ec681f3Smrg set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE, 4967ec681f3Smrg &compute_pipeline->cs->bind_map); 49701e04c3fSmrg break; 4987ec681f3Smrg } 49901e04c3fSmrg 5007ec681f3Smrg case VK_PIPELINE_BIND_POINT_GRAPHICS: { 5017ec681f3Smrg struct anv_graphics_pipeline *gfx_pipeline = 5027ec681f3Smrg anv_pipeline_to_graphics(pipeline); 5037ec681f3Smrg if (cmd_buffer->state.gfx.pipeline == gfx_pipeline) 5047ec681f3Smrg return; 5057ec681f3Smrg 5067ec681f3Smrg cmd_buffer->state.gfx.pipeline = gfx_pipeline; 5077ec681f3Smrg cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used; 50801e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE; 5097ec681f3Smrg 5107ec681f3Smrg anv_foreach_stage(stage, gfx_pipeline->active_stages) { 5117ec681f3Smrg set_dirty_for_bind_map(cmd_buffer, stage, 5127ec681f3Smrg &gfx_pipeline->shaders[stage]->bind_map); 5137ec681f3Smrg } 51401e04c3fSmrg 51501e04c3fSmrg /* Apply the dynamic state from the pipeline */ 5167ec681f3Smrg cmd_buffer->state.gfx.dirty |= 5177ec681f3Smrg anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic, 5187ec681f3Smrg &gfx_pipeline->dynamic_state, 5197ec681f3Smrg gfx_pipeline->dynamic_state_mask); 52001e04c3fSmrg break; 5217ec681f3Smrg } 5227ec681f3Smrg 5237ec681f3Smrg case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: { 5247ec681f3Smrg struct anv_ray_tracing_pipeline *rt_pipeline = 5257ec681f3Smrg anv_pipeline_to_ray_tracing(pipeline); 5267ec681f3Smrg if (cmd_buffer->state.rt.pipeline == rt_pipeline) 5277ec681f3Smrg return; 5287ec681f3Smrg 5297ec681f3Smrg cmd_buffer->state.rt.pipeline = rt_pipeline; 5307ec681f3Smrg cmd_buffer->state.rt.pipeline_dirty = true; 5317ec681f3Smrg 5327ec681f3Smrg if (rt_pipeline->stack_size > 0) { 5337ec681f3Smrg anv_CmdSetRayTracingPipelineStackSizeKHR(commandBuffer, 5347ec681f3Smrg rt_pipeline->stack_size); 5357ec681f3Smrg } 5367ec681f3Smrg break; 5377ec681f3Smrg } 53801e04c3fSmrg 53901e04c3fSmrg default: 54001e04c3fSmrg assert(!"invalid bind point"); 54101e04c3fSmrg break; 54201e04c3fSmrg } 54301e04c3fSmrg} 54401e04c3fSmrg 5457ec681f3Smrgvoid anv_CmdSetRasterizerDiscardEnableEXT( 5467ec681f3Smrg VkCommandBuffer commandBuffer, 5477ec681f3Smrg VkBool32 rasterizerDiscardEnable) 5487ec681f3Smrg{ 5497ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 5507ec681f3Smrg 5517ec681f3Smrg cmd_buffer->state.gfx.dynamic.raster_discard = rasterizerDiscardEnable; 5527ec681f3Smrg 5537ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE; 5547ec681f3Smrg} 5557ec681f3Smrg 5567ec681f3Smrgvoid anv_CmdSetDepthBiasEnableEXT( 5577ec681f3Smrg VkCommandBuffer commandBuffer, 5587ec681f3Smrg VkBool32 depthBiasEnable) 5597ec681f3Smrg{ 5607ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 5617ec681f3Smrg 5627ec681f3Smrg cmd_buffer->state.gfx.dynamic.depth_bias_enable = depthBiasEnable; 5637ec681f3Smrg 5647ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE; 5657ec681f3Smrg} 5667ec681f3Smrg 5677ec681f3Smrgvoid anv_CmdSetPrimitiveRestartEnableEXT( 5687ec681f3Smrg VkCommandBuffer commandBuffer, 5697ec681f3Smrg VkBool32 primitiveRestartEnable) 5707ec681f3Smrg{ 5717ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 5727ec681f3Smrg 5737ec681f3Smrg cmd_buffer->state.gfx.dynamic.primitive_restart_enable = primitiveRestartEnable; 5747ec681f3Smrg 5757ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE; 5767ec681f3Smrg} 5777ec681f3Smrg 5787ec681f3Smrgvoid anv_CmdSetLogicOpEXT( 5797ec681f3Smrg VkCommandBuffer commandBuffer, 5807ec681f3Smrg VkLogicOp logicOp) 5817ec681f3Smrg{ 5827ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 5837ec681f3Smrg 5847ec681f3Smrg cmd_buffer->state.gfx.dynamic.logic_op = logicOp; 5857ec681f3Smrg 5867ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP; 5877ec681f3Smrg} 5887ec681f3Smrg 5897ec681f3Smrgvoid anv_CmdSetPatchControlPointsEXT( 5907ec681f3Smrg VkCommandBuffer commandBuffer, 5917ec681f3Smrg uint32_t patchControlPoints) 5927ec681f3Smrg{ 5937ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 5947ec681f3Smrg anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_FEATURE_NOT_PRESENT); 5957ec681f3Smrg} 5967ec681f3Smrg 59701e04c3fSmrgvoid anv_CmdSetViewport( 59801e04c3fSmrg VkCommandBuffer commandBuffer, 59901e04c3fSmrg uint32_t firstViewport, 60001e04c3fSmrg uint32_t viewportCount, 60101e04c3fSmrg const VkViewport* pViewports) 60201e04c3fSmrg{ 60301e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 60401e04c3fSmrg 60501e04c3fSmrg const uint32_t total_count = firstViewport + viewportCount; 60601e04c3fSmrg if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count) 60701e04c3fSmrg cmd_buffer->state.gfx.dynamic.viewport.count = total_count; 60801e04c3fSmrg 60901e04c3fSmrg memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport, 61001e04c3fSmrg pViewports, viewportCount * sizeof(*pViewports)); 61101e04c3fSmrg 61201e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; 61301e04c3fSmrg} 61401e04c3fSmrg 6157ec681f3Smrgvoid anv_CmdSetViewportWithCountEXT( 6167ec681f3Smrg VkCommandBuffer commandBuffer, 6177ec681f3Smrg uint32_t viewportCount, 6187ec681f3Smrg const VkViewport* pViewports) 6197ec681f3Smrg{ 6207ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 6217ec681f3Smrg 6227ec681f3Smrg cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount; 6237ec681f3Smrg 6247ec681f3Smrg memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports, 6257ec681f3Smrg pViewports, viewportCount * sizeof(*pViewports)); 6267ec681f3Smrg 6277ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT; 6287ec681f3Smrg} 6297ec681f3Smrg 63001e04c3fSmrgvoid anv_CmdSetScissor( 63101e04c3fSmrg VkCommandBuffer commandBuffer, 63201e04c3fSmrg uint32_t firstScissor, 63301e04c3fSmrg uint32_t scissorCount, 63401e04c3fSmrg const VkRect2D* pScissors) 63501e04c3fSmrg{ 63601e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 63701e04c3fSmrg 63801e04c3fSmrg const uint32_t total_count = firstScissor + scissorCount; 63901e04c3fSmrg if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count) 64001e04c3fSmrg cmd_buffer->state.gfx.dynamic.scissor.count = total_count; 64101e04c3fSmrg 64201e04c3fSmrg memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor, 64301e04c3fSmrg pScissors, scissorCount * sizeof(*pScissors)); 64401e04c3fSmrg 64501e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; 64601e04c3fSmrg} 64701e04c3fSmrg 6487ec681f3Smrgvoid anv_CmdSetScissorWithCountEXT( 6497ec681f3Smrg VkCommandBuffer commandBuffer, 6507ec681f3Smrg uint32_t scissorCount, 6517ec681f3Smrg const VkRect2D* pScissors) 6527ec681f3Smrg{ 6537ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 6547ec681f3Smrg 6557ec681f3Smrg cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount; 6567ec681f3Smrg 6577ec681f3Smrg memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors, 6587ec681f3Smrg pScissors, scissorCount * sizeof(*pScissors)); 6597ec681f3Smrg 6607ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR; 6617ec681f3Smrg} 6627ec681f3Smrg 6637ec681f3Smrgvoid anv_CmdSetPrimitiveTopologyEXT( 6647ec681f3Smrg VkCommandBuffer commandBuffer, 6657ec681f3Smrg VkPrimitiveTopology primitiveTopology) 6667ec681f3Smrg{ 6677ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 6687ec681f3Smrg 6697ec681f3Smrg cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology; 6707ec681f3Smrg 6717ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY; 6727ec681f3Smrg} 6737ec681f3Smrg 67401e04c3fSmrgvoid anv_CmdSetLineWidth( 67501e04c3fSmrg VkCommandBuffer commandBuffer, 67601e04c3fSmrg float lineWidth) 67701e04c3fSmrg{ 67801e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 67901e04c3fSmrg 68001e04c3fSmrg cmd_buffer->state.gfx.dynamic.line_width = lineWidth; 68101e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH; 68201e04c3fSmrg} 68301e04c3fSmrg 68401e04c3fSmrgvoid anv_CmdSetDepthBias( 68501e04c3fSmrg VkCommandBuffer commandBuffer, 68601e04c3fSmrg float depthBiasConstantFactor, 68701e04c3fSmrg float depthBiasClamp, 68801e04c3fSmrg float depthBiasSlopeFactor) 68901e04c3fSmrg{ 69001e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 69101e04c3fSmrg 69201e04c3fSmrg cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor; 69301e04c3fSmrg cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp; 69401e04c3fSmrg cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor; 69501e04c3fSmrg 69601e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS; 69701e04c3fSmrg} 69801e04c3fSmrg 69901e04c3fSmrgvoid anv_CmdSetBlendConstants( 70001e04c3fSmrg VkCommandBuffer commandBuffer, 70101e04c3fSmrg const float blendConstants[4]) 70201e04c3fSmrg{ 70301e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 70401e04c3fSmrg 70501e04c3fSmrg memcpy(cmd_buffer->state.gfx.dynamic.blend_constants, 70601e04c3fSmrg blendConstants, sizeof(float) * 4); 70701e04c3fSmrg 70801e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS; 70901e04c3fSmrg} 71001e04c3fSmrg 71101e04c3fSmrgvoid anv_CmdSetDepthBounds( 71201e04c3fSmrg VkCommandBuffer commandBuffer, 71301e04c3fSmrg float minDepthBounds, 71401e04c3fSmrg float maxDepthBounds) 71501e04c3fSmrg{ 71601e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 71701e04c3fSmrg 71801e04c3fSmrg cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds; 71901e04c3fSmrg cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds; 72001e04c3fSmrg 72101e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS; 72201e04c3fSmrg} 72301e04c3fSmrg 72401e04c3fSmrgvoid anv_CmdSetStencilCompareMask( 72501e04c3fSmrg VkCommandBuffer commandBuffer, 72601e04c3fSmrg VkStencilFaceFlags faceMask, 72701e04c3fSmrg uint32_t compareMask) 72801e04c3fSmrg{ 72901e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 73001e04c3fSmrg 73101e04c3fSmrg if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 73201e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask; 73301e04c3fSmrg if (faceMask & VK_STENCIL_FACE_BACK_BIT) 73401e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask; 73501e04c3fSmrg 73601e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK; 73701e04c3fSmrg} 73801e04c3fSmrg 73901e04c3fSmrgvoid anv_CmdSetStencilWriteMask( 74001e04c3fSmrg VkCommandBuffer commandBuffer, 74101e04c3fSmrg VkStencilFaceFlags faceMask, 74201e04c3fSmrg uint32_t writeMask) 74301e04c3fSmrg{ 74401e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 74501e04c3fSmrg 74601e04c3fSmrg if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 74701e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask; 74801e04c3fSmrg if (faceMask & VK_STENCIL_FACE_BACK_BIT) 74901e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask; 75001e04c3fSmrg 75101e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK; 75201e04c3fSmrg} 75301e04c3fSmrg 75401e04c3fSmrgvoid anv_CmdSetStencilReference( 75501e04c3fSmrg VkCommandBuffer commandBuffer, 75601e04c3fSmrg VkStencilFaceFlags faceMask, 75701e04c3fSmrg uint32_t reference) 75801e04c3fSmrg{ 75901e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 76001e04c3fSmrg 76101e04c3fSmrg if (faceMask & VK_STENCIL_FACE_FRONT_BIT) 76201e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference; 76301e04c3fSmrg if (faceMask & VK_STENCIL_FACE_BACK_BIT) 76401e04c3fSmrg cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference; 76501e04c3fSmrg 76601e04c3fSmrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE; 76701e04c3fSmrg} 76801e04c3fSmrg 7697ec681f3Smrgvoid anv_CmdSetSampleLocationsEXT( 7707ec681f3Smrg VkCommandBuffer commandBuffer, 7717ec681f3Smrg const VkSampleLocationsInfoEXT* pSampleLocationsInfo) 7727ec681f3Smrg{ 7737ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 7747ec681f3Smrg 7757ec681f3Smrg struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic; 7767ec681f3Smrg uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel; 7777ec681f3Smrg 7787ec681f3Smrg dyn_state->sample_locations.samples = samples; 7797ec681f3Smrg typed_memcpy(dyn_state->sample_locations.locations, 7807ec681f3Smrg pSampleLocationsInfo->pSampleLocations, samples); 7817ec681f3Smrg 7827ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS; 7837ec681f3Smrg} 7847ec681f3Smrg 7857ec681f3Smrgvoid anv_CmdSetLineStippleEXT( 7867ec681f3Smrg VkCommandBuffer commandBuffer, 7877ec681f3Smrg uint32_t lineStippleFactor, 7887ec681f3Smrg uint16_t lineStipplePattern) 7897ec681f3Smrg{ 7907ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 7917ec681f3Smrg 7927ec681f3Smrg cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor; 7937ec681f3Smrg cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern; 7947ec681f3Smrg 7957ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE; 7967ec681f3Smrg} 7977ec681f3Smrg 7987ec681f3Smrgvoid anv_CmdSetCullModeEXT( 7997ec681f3Smrg VkCommandBuffer commandBuffer, 8007ec681f3Smrg VkCullModeFlags cullMode) 8017ec681f3Smrg{ 8027ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8037ec681f3Smrg 8047ec681f3Smrg cmd_buffer->state.gfx.dynamic.cull_mode = cullMode; 8057ec681f3Smrg 8067ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE; 8077ec681f3Smrg} 8087ec681f3Smrg 8097ec681f3Smrgvoid anv_CmdSetFrontFaceEXT( 8107ec681f3Smrg VkCommandBuffer commandBuffer, 8117ec681f3Smrg VkFrontFace frontFace) 8127ec681f3Smrg{ 8137ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8147ec681f3Smrg 8157ec681f3Smrg cmd_buffer->state.gfx.dynamic.front_face = frontFace; 8167ec681f3Smrg 8177ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE; 8187ec681f3Smrg} 8197ec681f3Smrg 8207ec681f3Smrgvoid anv_CmdSetDepthTestEnableEXT( 8217ec681f3Smrg VkCommandBuffer commandBuffer, 8227ec681f3Smrg VkBool32 depthTestEnable) 8237ec681f3Smrg 8247ec681f3Smrg{ 8257ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8267ec681f3Smrg 8277ec681f3Smrg cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable; 8287ec681f3Smrg 8297ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE; 8307ec681f3Smrg} 8317ec681f3Smrg 8327ec681f3Smrgvoid anv_CmdSetDepthWriteEnableEXT( 8337ec681f3Smrg VkCommandBuffer commandBuffer, 8347ec681f3Smrg VkBool32 depthWriteEnable) 8357ec681f3Smrg{ 8367ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8377ec681f3Smrg 8387ec681f3Smrg cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable; 8397ec681f3Smrg 8407ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE; 8417ec681f3Smrg} 8427ec681f3Smrg 8437ec681f3Smrgvoid anv_CmdSetDepthCompareOpEXT( 8447ec681f3Smrg VkCommandBuffer commandBuffer, 8457ec681f3Smrg VkCompareOp depthCompareOp) 8467ec681f3Smrg{ 8477ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8487ec681f3Smrg 8497ec681f3Smrg cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp; 8507ec681f3Smrg 8517ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP; 8527ec681f3Smrg} 8537ec681f3Smrg 8547ec681f3Smrgvoid anv_CmdSetDepthBoundsTestEnableEXT( 8557ec681f3Smrg VkCommandBuffer commandBuffer, 8567ec681f3Smrg VkBool32 depthBoundsTestEnable) 8577ec681f3Smrg{ 8587ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8597ec681f3Smrg 8607ec681f3Smrg cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable; 8617ec681f3Smrg 8627ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE; 8637ec681f3Smrg} 8647ec681f3Smrg 8657ec681f3Smrgvoid anv_CmdSetStencilTestEnableEXT( 8667ec681f3Smrg VkCommandBuffer commandBuffer, 8677ec681f3Smrg VkBool32 stencilTestEnable) 8687ec681f3Smrg{ 8697ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8707ec681f3Smrg 8717ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable; 8727ec681f3Smrg 8737ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE; 8747ec681f3Smrg} 8757ec681f3Smrg 8767ec681f3Smrgvoid anv_CmdSetStencilOpEXT( 8777ec681f3Smrg VkCommandBuffer commandBuffer, 8787ec681f3Smrg VkStencilFaceFlags faceMask, 8797ec681f3Smrg VkStencilOp failOp, 8807ec681f3Smrg VkStencilOp passOp, 8817ec681f3Smrg VkStencilOp depthFailOp, 8827ec681f3Smrg VkCompareOp compareOp) 8837ec681f3Smrg{ 8847ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 8857ec681f3Smrg 8867ec681f3Smrg if (faceMask & VK_STENCIL_FACE_FRONT_BIT) { 8877ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp; 8887ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp; 8897ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp; 8907ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp; 8917ec681f3Smrg } 8927ec681f3Smrg 8937ec681f3Smrg if (faceMask & VK_STENCIL_FACE_BACK_BIT) { 8947ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp; 8957ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp; 8967ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp; 8977ec681f3Smrg cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp; 8987ec681f3Smrg } 8997ec681f3Smrg 9007ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP; 9017ec681f3Smrg} 9027ec681f3Smrg 90301e04c3fSmrgstatic void 90401e04c3fSmrganv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer, 90501e04c3fSmrg VkPipelineBindPoint bind_point, 90601e04c3fSmrg struct anv_pipeline_layout *layout, 90701e04c3fSmrg uint32_t set_index, 90801e04c3fSmrg struct anv_descriptor_set *set, 90901e04c3fSmrg uint32_t *dynamic_offset_count, 91001e04c3fSmrg const uint32_t **dynamic_offsets) 91101e04c3fSmrg{ 91201e04c3fSmrg struct anv_descriptor_set_layout *set_layout = 91301e04c3fSmrg layout->set[set_index].layout; 91401e04c3fSmrg 9157ec681f3Smrg VkShaderStageFlags stages = set_layout->shader_stages; 91601e04c3fSmrg struct anv_cmd_pipeline_state *pipe_state; 9177ec681f3Smrg 9187ec681f3Smrg switch (bind_point) { 9197ec681f3Smrg case VK_PIPELINE_BIND_POINT_GRAPHICS: 9207ec681f3Smrg stages &= VK_SHADER_STAGE_ALL_GRAPHICS; 92101e04c3fSmrg pipe_state = &cmd_buffer->state.gfx.base; 9227ec681f3Smrg break; 9237ec681f3Smrg 9247ec681f3Smrg case VK_PIPELINE_BIND_POINT_COMPUTE: 9257ec681f3Smrg stages &= VK_SHADER_STAGE_COMPUTE_BIT; 9267ec681f3Smrg pipe_state = &cmd_buffer->state.compute.base; 9277ec681f3Smrg break; 9287ec681f3Smrg 9297ec681f3Smrg case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: 9307ec681f3Smrg stages &= VK_SHADER_STAGE_RAYGEN_BIT_KHR | 9317ec681f3Smrg VK_SHADER_STAGE_ANY_HIT_BIT_KHR | 9327ec681f3Smrg VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | 9337ec681f3Smrg VK_SHADER_STAGE_MISS_BIT_KHR | 9347ec681f3Smrg VK_SHADER_STAGE_INTERSECTION_BIT_KHR | 9357ec681f3Smrg VK_SHADER_STAGE_CALLABLE_BIT_KHR; 9367ec681f3Smrg pipe_state = &cmd_buffer->state.rt.base; 9377ec681f3Smrg break; 9387ec681f3Smrg 9397ec681f3Smrg default: 9407ec681f3Smrg unreachable("invalid bind point"); 9417ec681f3Smrg } 9427ec681f3Smrg 9437ec681f3Smrg VkShaderStageFlags dirty_stages = 0; 9447ec681f3Smrg /* If it's a push descriptor set, we have to flag things as dirty 9457ec681f3Smrg * regardless of whether or not the CPU-side data structure changed as we 9467ec681f3Smrg * may have edited in-place. 9477ec681f3Smrg */ 9487ec681f3Smrg if (pipe_state->descriptors[set_index] != set || 9497ec681f3Smrg anv_descriptor_set_is_push(set)) { 9507ec681f3Smrg pipe_state->descriptors[set_index] = set; 9517ec681f3Smrg 9527ec681f3Smrg /* Ray-tracing shaders are entirely bindless and so they don't have 9537ec681f3Smrg * access to HW binding tables. This means that we have to upload the 9547ec681f3Smrg * descriptor set as an 64-bit address in the push constants. 9557ec681f3Smrg */ 9567ec681f3Smrg if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) { 9577ec681f3Smrg struct anv_push_constants *push = &pipe_state->push_constants; 9587ec681f3Smrg 9597ec681f3Smrg struct anv_address addr = anv_descriptor_set_address(set); 9607ec681f3Smrg push->desc_sets[set_index] = anv_address_physical(addr); 9617ec681f3Smrg 9627ec681f3Smrg if (addr.bo) { 9637ec681f3Smrg anv_reloc_list_add_bo(cmd_buffer->batch.relocs, 9647ec681f3Smrg cmd_buffer->batch.alloc, 9657ec681f3Smrg addr.bo); 9667ec681f3Smrg } 9677ec681f3Smrg } 9687ec681f3Smrg 9697ec681f3Smrg dirty_stages |= stages; 97001e04c3fSmrg } 97101e04c3fSmrg 97201e04c3fSmrg if (dynamic_offsets) { 97301e04c3fSmrg if (set_layout->dynamic_offset_count > 0) { 9747ec681f3Smrg struct anv_push_constants *push = &pipe_state->push_constants; 97501e04c3fSmrg uint32_t dynamic_offset_start = 97601e04c3fSmrg layout->set[set_index].dynamic_offset_start; 9777ec681f3Smrg uint32_t *push_offsets = 9787ec681f3Smrg &push->dynamic_offsets[dynamic_offset_start]; 97901e04c3fSmrg 98001e04c3fSmrg /* Assert that everything is in range */ 98101e04c3fSmrg assert(set_layout->dynamic_offset_count <= *dynamic_offset_count); 98201e04c3fSmrg assert(dynamic_offset_start + set_layout->dynamic_offset_count <= 9837ec681f3Smrg ARRAY_SIZE(push->dynamic_offsets)); 9847ec681f3Smrg 9857ec681f3Smrg for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) { 9867ec681f3Smrg if (push_offsets[i] != (*dynamic_offsets)[i]) { 9877ec681f3Smrg push_offsets[i] = (*dynamic_offsets)[i]; 9887ec681f3Smrg /* dynamic_offset_stages[] elements could contain blanket 9897ec681f3Smrg * values like VK_SHADER_STAGE_ALL, so limit this to the 9907ec681f3Smrg * binding point's bits. 9917ec681f3Smrg */ 9927ec681f3Smrg dirty_stages |= set_layout->dynamic_offset_stages[i] & stages; 9937ec681f3Smrg } 9947ec681f3Smrg } 99501e04c3fSmrg 99601e04c3fSmrg *dynamic_offsets += set_layout->dynamic_offset_count; 99701e04c3fSmrg *dynamic_offset_count -= set_layout->dynamic_offset_count; 99801e04c3fSmrg } 99901e04c3fSmrg } 100001e04c3fSmrg 10017ec681f3Smrg cmd_buffer->state.descriptors_dirty |= dirty_stages; 10027ec681f3Smrg cmd_buffer->state.push_constants_dirty |= dirty_stages; 100301e04c3fSmrg} 100401e04c3fSmrg 100501e04c3fSmrgvoid anv_CmdBindDescriptorSets( 100601e04c3fSmrg VkCommandBuffer commandBuffer, 100701e04c3fSmrg VkPipelineBindPoint pipelineBindPoint, 100801e04c3fSmrg VkPipelineLayout _layout, 100901e04c3fSmrg uint32_t firstSet, 101001e04c3fSmrg uint32_t descriptorSetCount, 101101e04c3fSmrg const VkDescriptorSet* pDescriptorSets, 101201e04c3fSmrg uint32_t dynamicOffsetCount, 101301e04c3fSmrg const uint32_t* pDynamicOffsets) 101401e04c3fSmrg{ 101501e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 101601e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 101701e04c3fSmrg 101801e04c3fSmrg assert(firstSet + descriptorSetCount <= MAX_SETS); 101901e04c3fSmrg 102001e04c3fSmrg for (uint32_t i = 0; i < descriptorSetCount; i++) { 102101e04c3fSmrg ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]); 102201e04c3fSmrg anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, 102301e04c3fSmrg layout, firstSet + i, set, 102401e04c3fSmrg &dynamicOffsetCount, 102501e04c3fSmrg &pDynamicOffsets); 102601e04c3fSmrg } 102701e04c3fSmrg} 102801e04c3fSmrg 10297ec681f3Smrgvoid anv_CmdBindVertexBuffers2EXT( 10307ec681f3Smrg VkCommandBuffer commandBuffer, 10317ec681f3Smrg uint32_t firstBinding, 10327ec681f3Smrg uint32_t bindingCount, 10337ec681f3Smrg const VkBuffer* pBuffers, 10347ec681f3Smrg const VkDeviceSize* pOffsets, 10357ec681f3Smrg const VkDeviceSize* pSizes, 10367ec681f3Smrg const VkDeviceSize* pStrides) 103701e04c3fSmrg{ 103801e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 103901e04c3fSmrg struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings; 104001e04c3fSmrg 104101e04c3fSmrg /* We have to defer setting up vertex buffer since we need the buffer 104201e04c3fSmrg * stride from the pipeline. */ 104301e04c3fSmrg 10447ec681f3Smrg if (pSizes) 10457ec681f3Smrg cmd_buffer->state.gfx.dynamic.dyn_vbo_size = true; 10467ec681f3Smrg if (pStrides) 10477ec681f3Smrg cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true; 10487ec681f3Smrg 104901e04c3fSmrg assert(firstBinding + bindingCount <= MAX_VBS); 105001e04c3fSmrg for (uint32_t i = 0; i < bindingCount; i++) { 105101e04c3fSmrg vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]); 105201e04c3fSmrg vb[firstBinding + i].offset = pOffsets[i]; 10537ec681f3Smrg vb[firstBinding + i].size = pSizes ? pSizes[i] : 0; 10547ec681f3Smrg vb[firstBinding + i].stride = pStrides ? pStrides[i] : 0; 105501e04c3fSmrg cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i); 105601e04c3fSmrg } 105701e04c3fSmrg} 105801e04c3fSmrg 10597ec681f3Smrgvoid anv_CmdBindVertexBuffers( 10607ec681f3Smrg VkCommandBuffer commandBuffer, 10617ec681f3Smrg uint32_t firstBinding, 10627ec681f3Smrg uint32_t bindingCount, 10637ec681f3Smrg const VkBuffer* pBuffers, 10647ec681f3Smrg const VkDeviceSize* pOffsets) 10657ec681f3Smrg{ 10667ec681f3Smrg return anv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding, 10677ec681f3Smrg bindingCount, pBuffers, pOffsets, 10687ec681f3Smrg NULL, NULL); 10697ec681f3Smrg} 10707ec681f3Smrg 10719f464c52Smayavoid anv_CmdBindTransformFeedbackBuffersEXT( 10729f464c52Smaya VkCommandBuffer commandBuffer, 10739f464c52Smaya uint32_t firstBinding, 10749f464c52Smaya uint32_t bindingCount, 10759f464c52Smaya const VkBuffer* pBuffers, 10769f464c52Smaya const VkDeviceSize* pOffsets, 10779f464c52Smaya const VkDeviceSize* pSizes) 10789f464c52Smaya{ 10799f464c52Smaya ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 10809f464c52Smaya struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings; 10819f464c52Smaya 10829f464c52Smaya /* We have to defer setting up vertex buffer since we need the buffer 10839f464c52Smaya * stride from the pipeline. */ 10849f464c52Smaya 10859f464c52Smaya assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS); 10869f464c52Smaya for (uint32_t i = 0; i < bindingCount; i++) { 10879f464c52Smaya if (pBuffers[i] == VK_NULL_HANDLE) { 10889f464c52Smaya xfb[firstBinding + i].buffer = NULL; 10899f464c52Smaya } else { 10909f464c52Smaya ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]); 10919f464c52Smaya xfb[firstBinding + i].buffer = buffer; 10929f464c52Smaya xfb[firstBinding + i].offset = pOffsets[i]; 10939f464c52Smaya xfb[firstBinding + i].size = 10949f464c52Smaya anv_buffer_get_range(buffer, pOffsets[i], 10959f464c52Smaya pSizes ? pSizes[i] : VK_WHOLE_SIZE); 10969f464c52Smaya } 10979f464c52Smaya } 10989f464c52Smaya} 10999f464c52Smaya 110001e04c3fSmrgenum isl_format 11017ec681f3Smrganv_isl_format_for_descriptor_type(const struct anv_device *device, 11027ec681f3Smrg VkDescriptorType type) 110301e04c3fSmrg{ 110401e04c3fSmrg switch (type) { 110501e04c3fSmrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 110601e04c3fSmrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 11077ec681f3Smrg return device->physical->compiler->indirect_ubos_use_sampler ? 11087ec681f3Smrg ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW; 110901e04c3fSmrg 111001e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 111101e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 111201e04c3fSmrg return ISL_FORMAT_RAW; 111301e04c3fSmrg 111401e04c3fSmrg default: 111501e04c3fSmrg unreachable("Invalid descriptor type"); 111601e04c3fSmrg } 111701e04c3fSmrg} 111801e04c3fSmrg 111901e04c3fSmrgstruct anv_state 112001e04c3fSmrganv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer, 112101e04c3fSmrg const void *data, uint32_t size, uint32_t alignment) 112201e04c3fSmrg{ 112301e04c3fSmrg struct anv_state state; 112401e04c3fSmrg 112501e04c3fSmrg state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment); 112601e04c3fSmrg memcpy(state.map, data, size); 112701e04c3fSmrg 112801e04c3fSmrg VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size)); 112901e04c3fSmrg 113001e04c3fSmrg return state; 113101e04c3fSmrg} 113201e04c3fSmrg 113301e04c3fSmrgstruct anv_state 113401e04c3fSmrganv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer, 113501e04c3fSmrg uint32_t *a, uint32_t *b, 113601e04c3fSmrg uint32_t dwords, uint32_t alignment) 113701e04c3fSmrg{ 113801e04c3fSmrg struct anv_state state; 113901e04c3fSmrg uint32_t *p; 114001e04c3fSmrg 114101e04c3fSmrg state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 114201e04c3fSmrg dwords * 4, alignment); 114301e04c3fSmrg p = state.map; 114401e04c3fSmrg for (uint32_t i = 0; i < dwords; i++) 114501e04c3fSmrg p[i] = a[i] | b[i]; 114601e04c3fSmrg 114701e04c3fSmrg VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4)); 114801e04c3fSmrg 114901e04c3fSmrg return state; 115001e04c3fSmrg} 115101e04c3fSmrg 115201e04c3fSmrgstruct anv_state 11537ec681f3Smrganv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer) 115401e04c3fSmrg{ 115501e04c3fSmrg struct anv_push_constants *data = 11567ec681f3Smrg &cmd_buffer->state.gfx.base.push_constants; 115701e04c3fSmrg 115801e04c3fSmrg struct anv_state state = 115901e04c3fSmrg anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 11607ec681f3Smrg sizeof(struct anv_push_constants), 116101e04c3fSmrg 32 /* bottom 5 bits MBZ */); 11627ec681f3Smrg memcpy(state.map, data, sizeof(struct anv_push_constants)); 116301e04c3fSmrg 116401e04c3fSmrg return state; 116501e04c3fSmrg} 116601e04c3fSmrg 116701e04c3fSmrgstruct anv_state 116801e04c3fSmrganv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer) 116901e04c3fSmrg{ 11707ec681f3Smrg const struct intel_device_info *devinfo = &cmd_buffer->device->info; 117101e04c3fSmrg struct anv_push_constants *data = 11727ec681f3Smrg &cmd_buffer->state.compute.base.push_constants; 11737ec681f3Smrg struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline; 117401e04c3fSmrg const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline); 11757ec681f3Smrg const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0]; 117601e04c3fSmrg 11777ec681f3Smrg const struct brw_cs_dispatch_info dispatch = 11787ec681f3Smrg brw_cs_get_dispatch_info(devinfo, cs_prog_data, NULL); 11797ec681f3Smrg const unsigned total_push_constants_size = 11807ec681f3Smrg brw_cs_push_const_total_size(cs_prog_data, dispatch.threads); 11817ec681f3Smrg if (total_push_constants_size == 0) 118201e04c3fSmrg return (struct anv_state) { .offset = 0 }; 118301e04c3fSmrg 118401e04c3fSmrg const unsigned push_constant_alignment = 11857ec681f3Smrg cmd_buffer->device->info.ver < 8 ? 32 : 64; 118601e04c3fSmrg const unsigned aligned_total_push_constants_size = 11877ec681f3Smrg ALIGN(total_push_constants_size, push_constant_alignment); 11887ec681f3Smrg struct anv_state state; 11897ec681f3Smrg if (devinfo->verx10 >= 125) { 11907ec681f3Smrg state = anv_state_stream_alloc(&cmd_buffer->general_state_stream, 11917ec681f3Smrg aligned_total_push_constants_size, 11927ec681f3Smrg push_constant_alignment); 11937ec681f3Smrg } else { 11947ec681f3Smrg state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, 11957ec681f3Smrg aligned_total_push_constants_size, 11967ec681f3Smrg push_constant_alignment); 11977ec681f3Smrg } 119801e04c3fSmrg 11997ec681f3Smrg void *dst = state.map; 12007ec681f3Smrg const void *src = (char *)data + (range->start * 32); 120101e04c3fSmrg 120201e04c3fSmrg if (cs_prog_data->push.cross_thread.size > 0) { 12037ec681f3Smrg memcpy(dst, src, cs_prog_data->push.cross_thread.size); 12047ec681f3Smrg dst += cs_prog_data->push.cross_thread.size; 12057ec681f3Smrg src += cs_prog_data->push.cross_thread.size; 120601e04c3fSmrg } 120701e04c3fSmrg 120801e04c3fSmrg if (cs_prog_data->push.per_thread.size > 0) { 12097ec681f3Smrg for (unsigned t = 0; t < dispatch.threads; t++) { 12107ec681f3Smrg memcpy(dst, src, cs_prog_data->push.per_thread.size); 12117ec681f3Smrg 12127ec681f3Smrg uint32_t *subgroup_id = dst + 12137ec681f3Smrg offsetof(struct anv_push_constants, cs.subgroup_id) - 12147ec681f3Smrg (range->start * 32 + cs_prog_data->push.cross_thread.size); 12157ec681f3Smrg *subgroup_id = t; 12167ec681f3Smrg 12177ec681f3Smrg dst += cs_prog_data->push.per_thread.size; 121801e04c3fSmrg } 121901e04c3fSmrg } 122001e04c3fSmrg 122101e04c3fSmrg return state; 122201e04c3fSmrg} 122301e04c3fSmrg 122401e04c3fSmrgvoid anv_CmdPushConstants( 122501e04c3fSmrg VkCommandBuffer commandBuffer, 122601e04c3fSmrg VkPipelineLayout layout, 122701e04c3fSmrg VkShaderStageFlags stageFlags, 122801e04c3fSmrg uint32_t offset, 122901e04c3fSmrg uint32_t size, 123001e04c3fSmrg const void* pValues) 123101e04c3fSmrg{ 123201e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 123301e04c3fSmrg 12347ec681f3Smrg if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) { 12357ec681f3Smrg struct anv_cmd_pipeline_state *pipe_state = 12367ec681f3Smrg &cmd_buffer->state.gfx.base; 12377ec681f3Smrg 12387ec681f3Smrg memcpy(pipe_state->push_constants.client_data + offset, pValues, size); 12397ec681f3Smrg } 12407ec681f3Smrg if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) { 12417ec681f3Smrg struct anv_cmd_pipeline_state *pipe_state = 12427ec681f3Smrg &cmd_buffer->state.compute.base; 12437ec681f3Smrg 12447ec681f3Smrg memcpy(pipe_state->push_constants.client_data + offset, pValues, size); 12457ec681f3Smrg } 12467ec681f3Smrg if (stageFlags & (VK_SHADER_STAGE_RAYGEN_BIT_KHR | 12477ec681f3Smrg VK_SHADER_STAGE_ANY_HIT_BIT_KHR | 12487ec681f3Smrg VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR | 12497ec681f3Smrg VK_SHADER_STAGE_MISS_BIT_KHR | 12507ec681f3Smrg VK_SHADER_STAGE_INTERSECTION_BIT_KHR | 12517ec681f3Smrg VK_SHADER_STAGE_CALLABLE_BIT_KHR)) { 12527ec681f3Smrg struct anv_cmd_pipeline_state *pipe_state = 12537ec681f3Smrg &cmd_buffer->state.rt.base; 12547ec681f3Smrg 12557ec681f3Smrg memcpy(pipe_state->push_constants.client_data + offset, pValues, size); 125601e04c3fSmrg } 125701e04c3fSmrg 125801e04c3fSmrg cmd_buffer->state.push_constants_dirty |= stageFlags; 125901e04c3fSmrg} 126001e04c3fSmrg 126101e04c3fSmrgVkResult anv_CreateCommandPool( 126201e04c3fSmrg VkDevice _device, 126301e04c3fSmrg const VkCommandPoolCreateInfo* pCreateInfo, 126401e04c3fSmrg const VkAllocationCallbacks* pAllocator, 126501e04c3fSmrg VkCommandPool* pCmdPool) 126601e04c3fSmrg{ 126701e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 126801e04c3fSmrg struct anv_cmd_pool *pool; 126901e04c3fSmrg 12707ec681f3Smrg pool = vk_object_alloc(&device->vk, pAllocator, sizeof(*pool), 12717ec681f3Smrg VK_OBJECT_TYPE_COMMAND_POOL); 127201e04c3fSmrg if (pool == NULL) 12737ec681f3Smrg return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 12747ec681f3Smrg 12757ec681f3Smrg assert(pCreateInfo->queueFamilyIndex < device->physical->queue.family_count); 12767ec681f3Smrg pool->queue_family = 12777ec681f3Smrg &device->physical->queue.families[pCreateInfo->queueFamilyIndex]; 127801e04c3fSmrg 127901e04c3fSmrg if (pAllocator) 128001e04c3fSmrg pool->alloc = *pAllocator; 128101e04c3fSmrg else 12827ec681f3Smrg pool->alloc = device->vk.alloc; 128301e04c3fSmrg 128401e04c3fSmrg list_inithead(&pool->cmd_buffers); 128501e04c3fSmrg 12867ec681f3Smrg pool->flags = pCreateInfo->flags; 12877ec681f3Smrg 128801e04c3fSmrg *pCmdPool = anv_cmd_pool_to_handle(pool); 128901e04c3fSmrg 129001e04c3fSmrg return VK_SUCCESS; 129101e04c3fSmrg} 129201e04c3fSmrg 129301e04c3fSmrgvoid anv_DestroyCommandPool( 129401e04c3fSmrg VkDevice _device, 129501e04c3fSmrg VkCommandPool commandPool, 129601e04c3fSmrg const VkAllocationCallbacks* pAllocator) 129701e04c3fSmrg{ 129801e04c3fSmrg ANV_FROM_HANDLE(anv_device, device, _device); 129901e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 130001e04c3fSmrg 130101e04c3fSmrg if (!pool) 130201e04c3fSmrg return; 130301e04c3fSmrg 130401e04c3fSmrg list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer, 130501e04c3fSmrg &pool->cmd_buffers, pool_link) { 130601e04c3fSmrg anv_cmd_buffer_destroy(cmd_buffer); 130701e04c3fSmrg } 130801e04c3fSmrg 13097ec681f3Smrg vk_object_free(&device->vk, pAllocator, pool); 131001e04c3fSmrg} 131101e04c3fSmrg 131201e04c3fSmrgVkResult anv_ResetCommandPool( 131301e04c3fSmrg VkDevice device, 131401e04c3fSmrg VkCommandPool commandPool, 131501e04c3fSmrg VkCommandPoolResetFlags flags) 131601e04c3fSmrg{ 131701e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool); 131801e04c3fSmrg 131901e04c3fSmrg list_for_each_entry(struct anv_cmd_buffer, cmd_buffer, 132001e04c3fSmrg &pool->cmd_buffers, pool_link) { 132101e04c3fSmrg anv_cmd_buffer_reset(cmd_buffer); 132201e04c3fSmrg } 132301e04c3fSmrg 132401e04c3fSmrg return VK_SUCCESS; 132501e04c3fSmrg} 132601e04c3fSmrg 132701e04c3fSmrgvoid anv_TrimCommandPool( 132801e04c3fSmrg VkDevice device, 132901e04c3fSmrg VkCommandPool commandPool, 133001e04c3fSmrg VkCommandPoolTrimFlags flags) 133101e04c3fSmrg{ 133201e04c3fSmrg /* Nothing for us to do here. Our pools stay pretty tidy. */ 133301e04c3fSmrg} 133401e04c3fSmrg 133501e04c3fSmrg/** 133601e04c3fSmrg * Return NULL if the current subpass has no depthstencil attachment. 133701e04c3fSmrg */ 133801e04c3fSmrgconst struct anv_image_view * 133901e04c3fSmrganv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer) 134001e04c3fSmrg{ 134101e04c3fSmrg const struct anv_subpass *subpass = cmd_buffer->state.subpass; 134201e04c3fSmrg 134301e04c3fSmrg if (subpass->depth_stencil_attachment == NULL) 134401e04c3fSmrg return NULL; 134501e04c3fSmrg 134601e04c3fSmrg const struct anv_image_view *iview = 13477ec681f3Smrg cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view; 134801e04c3fSmrg 13497ec681f3Smrg assert(iview->vk.aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | 13507ec681f3Smrg VK_IMAGE_ASPECT_STENCIL_BIT)); 135101e04c3fSmrg 135201e04c3fSmrg return iview; 135301e04c3fSmrg} 135401e04c3fSmrg 13559f464c52Smayastatic struct anv_descriptor_set * 13569f464c52Smayaanv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer, 13579f464c52Smaya VkPipelineBindPoint bind_point, 13589f464c52Smaya struct anv_descriptor_set_layout *layout, 13599f464c52Smaya uint32_t _set) 136001e04c3fSmrg{ 136101e04c3fSmrg struct anv_cmd_pipeline_state *pipe_state; 13627ec681f3Smrg 13637ec681f3Smrg switch (bind_point) { 13647ec681f3Smrg case VK_PIPELINE_BIND_POINT_GRAPHICS: 136501e04c3fSmrg pipe_state = &cmd_buffer->state.gfx.base; 13667ec681f3Smrg break; 13677ec681f3Smrg 13687ec681f3Smrg case VK_PIPELINE_BIND_POINT_COMPUTE: 13697ec681f3Smrg pipe_state = &cmd_buffer->state.compute.base; 13707ec681f3Smrg break; 13717ec681f3Smrg 13727ec681f3Smrg case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: 13737ec681f3Smrg pipe_state = &cmd_buffer->state.rt.base; 13747ec681f3Smrg break; 13757ec681f3Smrg 13767ec681f3Smrg default: 13777ec681f3Smrg unreachable("invalid bind point"); 137801e04c3fSmrg } 137901e04c3fSmrg 138001e04c3fSmrg struct anv_push_descriptor_set **push_set = 13819f464c52Smaya &pipe_state->push_descriptors[_set]; 138201e04c3fSmrg 138301e04c3fSmrg if (*push_set == NULL) { 13849f464c52Smaya *push_set = vk_zalloc(&cmd_buffer->pool->alloc, 13859f464c52Smaya sizeof(struct anv_push_descriptor_set), 8, 13869f464c52Smaya VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 138701e04c3fSmrg if (*push_set == NULL) { 138801e04c3fSmrg anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY); 138901e04c3fSmrg return NULL; 139001e04c3fSmrg } 139101e04c3fSmrg } 139201e04c3fSmrg 13939f464c52Smaya struct anv_descriptor_set *set = &(*push_set)->set; 13949f464c52Smaya 13959f464c52Smaya if (set->layout != layout) { 13969f464c52Smaya if (set->layout) 13979f464c52Smaya anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout); 13989f464c52Smaya anv_descriptor_set_layout_ref(layout); 13999f464c52Smaya set->layout = layout; 14009f464c52Smaya } 14017ec681f3Smrg set->size = anv_descriptor_set_layout_size(layout, 0); 14029f464c52Smaya set->buffer_view_count = layout->buffer_view_count; 14037ec681f3Smrg set->descriptor_count = layout->descriptor_count; 14049f464c52Smaya set->buffer_views = (*push_set)->buffer_views; 14059f464c52Smaya 14069f464c52Smaya if (layout->descriptor_buffer_size && 14079f464c52Smaya ((*push_set)->set_used_on_gpu || 14089f464c52Smaya set->desc_mem.alloc_size < layout->descriptor_buffer_size)) { 14099f464c52Smaya /* The previous buffer is either actively used by some GPU command (so 14109f464c52Smaya * we can't modify it) or is too small. Allocate a new one. 14119f464c52Smaya */ 14129f464c52Smaya struct anv_state desc_mem = 14139f464c52Smaya anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, 14147ec681f3Smrg anv_descriptor_set_layout_descriptor_buffer_size(layout, 0), 14157ec681f3Smrg ANV_UBO_ALIGNMENT); 14169f464c52Smaya if (set->desc_mem.alloc_size) { 14179f464c52Smaya /* TODO: Do we really need to copy all the time? */ 14189f464c52Smaya memcpy(desc_mem.map, set->desc_mem.map, 14199f464c52Smaya MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size)); 14209f464c52Smaya } 14219f464c52Smaya set->desc_mem = desc_mem; 14229f464c52Smaya 14237ec681f3Smrg set->desc_addr = (struct anv_address) { 14249f464c52Smaya .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo, 14259f464c52Smaya .offset = set->desc_mem.offset, 14269f464c52Smaya }; 14279f464c52Smaya 14287ec681f3Smrg enum isl_format format = 14297ec681f3Smrg anv_isl_format_for_descriptor_type(cmd_buffer->device, 14307ec681f3Smrg VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); 14317ec681f3Smrg 14329f464c52Smaya const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev; 14339f464c52Smaya set->desc_surface_state = 14349f464c52Smaya anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 14359f464c52Smaya isl_dev->ss.size, isl_dev->ss.align); 14369f464c52Smaya anv_fill_buffer_surface_state(cmd_buffer->device, 14377ec681f3Smrg set->desc_surface_state, format, 14387ec681f3Smrg ISL_SURF_USAGE_CONSTANT_BUFFER_BIT, 14397ec681f3Smrg set->desc_addr, 14407ec681f3Smrg layout->descriptor_buffer_size, 1); 14419f464c52Smaya } 14429f464c52Smaya 14439f464c52Smaya return set; 144401e04c3fSmrg} 144501e04c3fSmrg 144601e04c3fSmrgvoid anv_CmdPushDescriptorSetKHR( 144701e04c3fSmrg VkCommandBuffer commandBuffer, 144801e04c3fSmrg VkPipelineBindPoint pipelineBindPoint, 144901e04c3fSmrg VkPipelineLayout _layout, 145001e04c3fSmrg uint32_t _set, 145101e04c3fSmrg uint32_t descriptorWriteCount, 145201e04c3fSmrg const VkWriteDescriptorSet* pDescriptorWrites) 145301e04c3fSmrg{ 145401e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 145501e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 145601e04c3fSmrg 145701e04c3fSmrg assert(_set < MAX_SETS); 145801e04c3fSmrg 145901e04c3fSmrg struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; 146001e04c3fSmrg 14619f464c52Smaya struct anv_descriptor_set *set = 14629f464c52Smaya anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint, 14639f464c52Smaya set_layout, _set); 14649f464c52Smaya if (!set) 146501e04c3fSmrg return; 146601e04c3fSmrg 146701e04c3fSmrg /* Go through the user supplied descriptors. */ 146801e04c3fSmrg for (uint32_t i = 0; i < descriptorWriteCount; i++) { 146901e04c3fSmrg const VkWriteDescriptorSet *write = &pDescriptorWrites[i]; 147001e04c3fSmrg 147101e04c3fSmrg switch (write->descriptorType) { 147201e04c3fSmrg case VK_DESCRIPTOR_TYPE_SAMPLER: 147301e04c3fSmrg case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 147401e04c3fSmrg case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 147501e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 147601e04c3fSmrg case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 147701e04c3fSmrg for (uint32_t j = 0; j < write->descriptorCount; j++) { 14789f464c52Smaya anv_descriptor_set_write_image_view(cmd_buffer->device, set, 147901e04c3fSmrg write->pImageInfo + j, 148001e04c3fSmrg write->descriptorType, 148101e04c3fSmrg write->dstBinding, 148201e04c3fSmrg write->dstArrayElement + j); 148301e04c3fSmrg } 148401e04c3fSmrg break; 148501e04c3fSmrg 148601e04c3fSmrg case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 148701e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 148801e04c3fSmrg for (uint32_t j = 0; j < write->descriptorCount; j++) { 148901e04c3fSmrg ANV_FROM_HANDLE(anv_buffer_view, bview, 149001e04c3fSmrg write->pTexelBufferView[j]); 149101e04c3fSmrg 14929f464c52Smaya anv_descriptor_set_write_buffer_view(cmd_buffer->device, set, 149301e04c3fSmrg write->descriptorType, 149401e04c3fSmrg bview, 149501e04c3fSmrg write->dstBinding, 149601e04c3fSmrg write->dstArrayElement + j); 149701e04c3fSmrg } 149801e04c3fSmrg break; 149901e04c3fSmrg 150001e04c3fSmrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 150101e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 150201e04c3fSmrg case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 150301e04c3fSmrg case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 150401e04c3fSmrg for (uint32_t j = 0; j < write->descriptorCount; j++) { 150501e04c3fSmrg ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer); 150601e04c3fSmrg 15079f464c52Smaya anv_descriptor_set_write_buffer(cmd_buffer->device, set, 150801e04c3fSmrg &cmd_buffer->surface_state_stream, 150901e04c3fSmrg write->descriptorType, 151001e04c3fSmrg buffer, 151101e04c3fSmrg write->dstBinding, 151201e04c3fSmrg write->dstArrayElement + j, 151301e04c3fSmrg write->pBufferInfo[j].offset, 151401e04c3fSmrg write->pBufferInfo[j].range); 151501e04c3fSmrg } 151601e04c3fSmrg break; 151701e04c3fSmrg 15187ec681f3Smrg case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: { 15197ec681f3Smrg const VkWriteDescriptorSetAccelerationStructureKHR *accel_write = 15207ec681f3Smrg vk_find_struct_const(write, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR); 15217ec681f3Smrg assert(accel_write->accelerationStructureCount == 15227ec681f3Smrg write->descriptorCount); 15237ec681f3Smrg for (uint32_t j = 0; j < write->descriptorCount; j++) { 15247ec681f3Smrg ANV_FROM_HANDLE(anv_acceleration_structure, accel, 15257ec681f3Smrg accel_write->pAccelerationStructures[j]); 15267ec681f3Smrg anv_descriptor_set_write_acceleration_structure(cmd_buffer->device, 15277ec681f3Smrg set, accel, 15287ec681f3Smrg write->dstBinding, 15297ec681f3Smrg write->dstArrayElement + j); 15307ec681f3Smrg } 15319f464c52Smaya break; 15329f464c52Smaya } 15339f464c52Smaya 153401e04c3fSmrg default: 153501e04c3fSmrg break; 153601e04c3fSmrg } 153701e04c3fSmrg } 153801e04c3fSmrg 153901e04c3fSmrg anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint, 154001e04c3fSmrg layout, _set, set, NULL, NULL); 154101e04c3fSmrg} 154201e04c3fSmrg 154301e04c3fSmrgvoid anv_CmdPushDescriptorSetWithTemplateKHR( 154401e04c3fSmrg VkCommandBuffer commandBuffer, 154501e04c3fSmrg VkDescriptorUpdateTemplate descriptorUpdateTemplate, 154601e04c3fSmrg VkPipelineLayout _layout, 154701e04c3fSmrg uint32_t _set, 154801e04c3fSmrg const void* pData) 154901e04c3fSmrg{ 155001e04c3fSmrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 155101e04c3fSmrg ANV_FROM_HANDLE(anv_descriptor_update_template, template, 155201e04c3fSmrg descriptorUpdateTemplate); 155301e04c3fSmrg ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout); 155401e04c3fSmrg 155501e04c3fSmrg assert(_set < MAX_PUSH_DESCRIPTORS); 155601e04c3fSmrg 155701e04c3fSmrg struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout; 155801e04c3fSmrg 15599f464c52Smaya struct anv_descriptor_set *set = 15609f464c52Smaya anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point, 15619f464c52Smaya set_layout, _set); 15629f464c52Smaya if (!set) 156301e04c3fSmrg return; 156401e04c3fSmrg 15659f464c52Smaya anv_descriptor_set_write_template(cmd_buffer->device, set, 156601e04c3fSmrg &cmd_buffer->surface_state_stream, 156701e04c3fSmrg template, 156801e04c3fSmrg pData); 156901e04c3fSmrg 157001e04c3fSmrg anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point, 157101e04c3fSmrg layout, _set, set, NULL, NULL); 157201e04c3fSmrg} 157301e04c3fSmrg 157401e04c3fSmrgvoid anv_CmdSetDeviceMask( 157501e04c3fSmrg VkCommandBuffer commandBuffer, 157601e04c3fSmrg uint32_t deviceMask) 157701e04c3fSmrg{ 157801e04c3fSmrg /* No-op */ 157901e04c3fSmrg} 15807ec681f3Smrg 15817ec681f3Smrgvoid anv_CmdSetColorWriteEnableEXT( 15827ec681f3Smrg VkCommandBuffer commandBuffer, 15837ec681f3Smrg uint32_t attachmentCount, 15847ec681f3Smrg const VkBool32* pColorWriteEnables) 15857ec681f3Smrg{ 15867ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 15877ec681f3Smrg 15887ec681f3Smrg assert(attachmentCount < MAX_RTS); 15897ec681f3Smrg 15907ec681f3Smrg uint8_t color_writes = 0; 15917ec681f3Smrg for (uint32_t i = 0; i < attachmentCount; i++) 15927ec681f3Smrg color_writes |= pColorWriteEnables[i] ? (1 << i) : 0; 15937ec681f3Smrg 15947ec681f3Smrg if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) { 15957ec681f3Smrg cmd_buffer->state.gfx.dynamic.color_writes = color_writes; 15967ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE; 15977ec681f3Smrg } 15987ec681f3Smrg} 15997ec681f3Smrg 16007ec681f3Smrgvoid anv_CmdSetFragmentShadingRateKHR( 16017ec681f3Smrg VkCommandBuffer commandBuffer, 16027ec681f3Smrg const VkExtent2D* pFragmentSize, 16037ec681f3Smrg const VkFragmentShadingRateCombinerOpKHR combinerOps[2]) 16047ec681f3Smrg{ 16057ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 16067ec681f3Smrg 16077ec681f3Smrg cmd_buffer->state.gfx.dynamic.fragment_shading_rate = *pFragmentSize; 16087ec681f3Smrg cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE; 16097ec681f3Smrg} 16107ec681f3Smrg 16117ec681f3Smrgstatic inline uint32_t 16127ec681f3Smrgilog2_round_up(uint32_t value) 16137ec681f3Smrg{ 16147ec681f3Smrg assert(value != 0); 16157ec681f3Smrg return 32 - __builtin_clz(value - 1); 16167ec681f3Smrg} 16177ec681f3Smrg 16187ec681f3Smrgvoid anv_CmdSetRayTracingPipelineStackSizeKHR( 16197ec681f3Smrg VkCommandBuffer commandBuffer, 16207ec681f3Smrg uint32_t pipelineStackSize) 16217ec681f3Smrg{ 16227ec681f3Smrg ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); 16237ec681f3Smrg struct anv_cmd_ray_tracing_state *rt = &cmd_buffer->state.rt; 16247ec681f3Smrg struct anv_device *device = cmd_buffer->device; 16257ec681f3Smrg 16267ec681f3Smrg if (anv_batch_has_error(&cmd_buffer->batch)) 16277ec681f3Smrg return; 16287ec681f3Smrg 16297ec681f3Smrg uint32_t stack_ids_per_dss = 2048; /* TODO */ 16307ec681f3Smrg 16317ec681f3Smrg unsigned stack_size_log2 = ilog2_round_up(pipelineStackSize); 16327ec681f3Smrg if (stack_size_log2 < 10) 16337ec681f3Smrg stack_size_log2 = 10; 16347ec681f3Smrg 16357ec681f3Smrg if (rt->scratch.layout.total_size == 1 << stack_size_log2) 16367ec681f3Smrg return; 16377ec681f3Smrg 16387ec681f3Smrg brw_rt_compute_scratch_layout(&rt->scratch.layout, &device->info, 16397ec681f3Smrg stack_ids_per_dss, 1 << stack_size_log2); 16407ec681f3Smrg 16417ec681f3Smrg unsigned bucket = stack_size_log2 - 10; 16427ec681f3Smrg assert(bucket < ARRAY_SIZE(device->rt_scratch_bos)); 16437ec681f3Smrg 16447ec681f3Smrg struct anv_bo *bo = p_atomic_read(&device->rt_scratch_bos[bucket]); 16457ec681f3Smrg if (bo == NULL) { 16467ec681f3Smrg struct anv_bo *new_bo; 16477ec681f3Smrg VkResult result = anv_device_alloc_bo(device, "RT scratch", 16487ec681f3Smrg rt->scratch.layout.total_size, 16497ec681f3Smrg 0, /* alloc_flags */ 16507ec681f3Smrg 0, /* explicit_address */ 16517ec681f3Smrg &new_bo); 16527ec681f3Smrg if (result != VK_SUCCESS) { 16537ec681f3Smrg rt->scratch.layout.total_size = 0; 16547ec681f3Smrg anv_batch_set_error(&cmd_buffer->batch, result); 16557ec681f3Smrg return; 16567ec681f3Smrg } 16577ec681f3Smrg 16587ec681f3Smrg bo = p_atomic_cmpxchg(&device->rt_scratch_bos[bucket], NULL, new_bo); 16597ec681f3Smrg if (bo != NULL) { 16607ec681f3Smrg anv_device_release_bo(device, bo); 16617ec681f3Smrg } else { 16627ec681f3Smrg bo = new_bo; 16637ec681f3Smrg } 16647ec681f3Smrg } 16657ec681f3Smrg 16667ec681f3Smrg rt->scratch.bo = bo; 16677ec681f3Smrg} 1668