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