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