1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31 #include "anv_measure.h"
32
33 #include "vk_util.h"
34
35 /** \file anv_cmd_buffer.c
36 *
37 * This file contains all of the stuff for emitting commands into a command
38 * buffer. This includes implementations of most of the vkCmd*
39 * entrypoints. This file is concerned entirely with state emission and
40 * not with the command buffer data structure itself. As far as this file
41 * is concerned, most of anv_cmd_buffer is magic.
42 */
43
44 /* TODO: These are taken from GLES. We should check the Vulkan spec */
45 const struct anv_dynamic_state default_dynamic_state = {
46 .viewport = {
47 .count = 0,
48 },
49 .scissor = {
50 .count = 0,
51 },
52 .line_width = 1.0f,
53 .depth_bias = {
54 .bias = 0.0f,
55 .clamp = 0.0f,
56 .slope = 0.0f,
57 },
58 .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
59 .depth_bounds = {
60 .min = 0.0f,
61 .max = 1.0f,
62 },
63 .stencil_compare_mask = {
64 .front = ~0u,
65 .back = ~0u,
66 },
67 .stencil_write_mask = {
68 .front = ~0u,
69 .back = ~0u,
70 },
71 .stencil_reference = {
72 .front = 0u,
73 .back = 0u,
74 },
75 .stencil_op = {
76 .front = {
77 .fail_op = 0,
78 .pass_op = 0,
79 .depth_fail_op = 0,
80 .compare_op = 0,
81 },
82 .back = {
83 .fail_op = 0,
84 .pass_op = 0,
85 .depth_fail_op = 0,
86 .compare_op = 0,
87 },
88 },
89 .line_stipple = {
90 .factor = 0u,
91 .pattern = 0u,
92 },
93 .cull_mode = 0,
94 .front_face = 0,
95 .primitive_topology = 0,
96 .depth_test_enable = 0,
97 .depth_write_enable = 0,
98 .depth_compare_op = 0,
99 .depth_bounds_test_enable = 0,
100 .stencil_test_enable = 0,
101 .dyn_vbo_stride = 0,
102 .dyn_vbo_size = 0,
103 .color_writes = 0xff,
104 .raster_discard = 0,
105 .depth_bias_enable = 0,
106 .primitive_restart_enable = 0,
107 .logic_op = 0,
108 };
109
110 /**
111 * Copy the dynamic state from src to dest based on the copy_mask.
112 *
113 * Avoid copying states that have not changed, except for VIEWPORT, SCISSOR and
114 * BLEND_CONSTANTS (always copy them if they are in the copy_mask).
115 *
116 * Returns a mask of the states which changed.
117 */
118 anv_cmd_dirty_mask_t
anv_dynamic_state_copy(struct anv_dynamic_state * dest,const struct anv_dynamic_state * src,anv_cmd_dirty_mask_t copy_mask)119 anv_dynamic_state_copy(struct anv_dynamic_state *dest,
120 const struct anv_dynamic_state *src,
121 anv_cmd_dirty_mask_t copy_mask)
122 {
123 anv_cmd_dirty_mask_t changed = 0;
124
125 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_VIEWPORT) {
126 dest->viewport.count = src->viewport.count;
127 typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
128 src->viewport.count);
129 changed |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
130 }
131
132 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SCISSOR) {
133 dest->scissor.count = src->scissor.count;
134 typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
135 src->scissor.count);
136 changed |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
137 }
138
139 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS) {
140 typed_memcpy(dest->blend_constants, src->blend_constants, 4);
141 changed |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
142 }
143
144 #define ANV_CMP_COPY(field, flag) \
145 if (copy_mask & flag) { \
146 if (dest->field != src->field) { \
147 dest->field = src->field; \
148 changed |= flag; \
149 } \
150 }
151
152 ANV_CMP_COPY(line_width, ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH);
153
154 ANV_CMP_COPY(depth_bias.bias, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
155 ANV_CMP_COPY(depth_bias.clamp, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
156 ANV_CMP_COPY(depth_bias.slope, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS);
157
158 ANV_CMP_COPY(depth_bounds.min, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
159 ANV_CMP_COPY(depth_bounds.max, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS);
160
161 ANV_CMP_COPY(stencil_compare_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
162 ANV_CMP_COPY(stencil_compare_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK);
163
164 ANV_CMP_COPY(stencil_write_mask.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
165 ANV_CMP_COPY(stencil_write_mask.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK);
166
167 ANV_CMP_COPY(stencil_reference.front, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
168 ANV_CMP_COPY(stencil_reference.back, ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE);
169
170 ANV_CMP_COPY(line_stipple.factor, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
171 ANV_CMP_COPY(line_stipple.pattern, ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE);
172
173 ANV_CMP_COPY(cull_mode, ANV_CMD_DIRTY_DYNAMIC_CULL_MODE);
174 ANV_CMP_COPY(front_face, ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE);
175 ANV_CMP_COPY(primitive_topology, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY);
176 ANV_CMP_COPY(depth_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE);
177 ANV_CMP_COPY(depth_write_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE);
178 ANV_CMP_COPY(depth_compare_op, ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP);
179 ANV_CMP_COPY(depth_bounds_test_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE);
180 ANV_CMP_COPY(stencil_test_enable, ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE);
181
182 if (copy_mask & VK_DYNAMIC_STATE_STENCIL_OP_EXT) {
183 ANV_CMP_COPY(stencil_op.front.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
184 ANV_CMP_COPY(stencil_op.front.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
185 ANV_CMP_COPY(stencil_op.front.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
186 ANV_CMP_COPY(stencil_op.front.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
187 ANV_CMP_COPY(stencil_op.back.fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
188 ANV_CMP_COPY(stencil_op.back.pass_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
189 ANV_CMP_COPY(stencil_op.back.depth_fail_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
190 ANV_CMP_COPY(stencil_op.back.compare_op, ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP);
191 }
192
193 ANV_CMP_COPY(dyn_vbo_stride, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
194 ANV_CMP_COPY(dyn_vbo_size, ANV_CMD_DIRTY_DYNAMIC_VERTEX_INPUT_BINDING_STRIDE);
195
196 ANV_CMP_COPY(raster_discard, ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE);
197 ANV_CMP_COPY(depth_bias_enable, ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE);
198 ANV_CMP_COPY(primitive_restart_enable, ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE);
199 ANV_CMP_COPY(logic_op, ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP);
200
201 if (copy_mask & ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS) {
202 dest->sample_locations.samples = src->sample_locations.samples;
203 typed_memcpy(dest->sample_locations.locations,
204 src->sample_locations.locations,
205 dest->sample_locations.samples);
206 changed |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
207 }
208
209 ANV_CMP_COPY(color_writes, ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE);
210
211 ANV_CMP_COPY(fragment_shading_rate.width, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
212 ANV_CMP_COPY(fragment_shading_rate.height, ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE);
213
214 #undef ANV_CMP_COPY
215
216 return changed;
217 }
218
219 static void
anv_cmd_state_init(struct anv_cmd_buffer * cmd_buffer)220 anv_cmd_state_init(struct anv_cmd_buffer *cmd_buffer)
221 {
222 struct anv_cmd_state *state = &cmd_buffer->state;
223
224 memset(state, 0, sizeof(*state));
225
226 state->current_pipeline = UINT32_MAX;
227 state->restart_index = UINT32_MAX;
228 state->gfx.dynamic = default_dynamic_state;
229 }
230
231 static void
anv_cmd_pipeline_state_finish(struct anv_cmd_buffer * cmd_buffer,struct anv_cmd_pipeline_state * pipe_state)232 anv_cmd_pipeline_state_finish(struct anv_cmd_buffer *cmd_buffer,
233 struct anv_cmd_pipeline_state *pipe_state)
234 {
235 for (uint32_t i = 0; i < ARRAY_SIZE(pipe_state->push_descriptors); i++) {
236 if (pipe_state->push_descriptors[i]) {
237 anv_descriptor_set_layout_unref(cmd_buffer->device,
238 pipe_state->push_descriptors[i]->set.layout);
239 vk_free(&cmd_buffer->pool->alloc, pipe_state->push_descriptors[i]);
240 }
241 }
242 }
243
244 static void
anv_cmd_state_finish(struct anv_cmd_buffer * cmd_buffer)245 anv_cmd_state_finish(struct anv_cmd_buffer *cmd_buffer)
246 {
247 struct anv_cmd_state *state = &cmd_buffer->state;
248
249 anv_cmd_pipeline_state_finish(cmd_buffer, &state->gfx.base);
250 anv_cmd_pipeline_state_finish(cmd_buffer, &state->compute.base);
251
252 vk_free(&cmd_buffer->pool->alloc, state->attachments);
253 }
254
255 static void
anv_cmd_state_reset(struct anv_cmd_buffer * cmd_buffer)256 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
257 {
258 anv_cmd_state_finish(cmd_buffer);
259 anv_cmd_state_init(cmd_buffer);
260 }
261
anv_create_cmd_buffer(struct anv_device * device,struct anv_cmd_pool * pool,VkCommandBufferLevel level,VkCommandBuffer * pCommandBuffer)262 static VkResult anv_create_cmd_buffer(
263 struct anv_device * device,
264 struct anv_cmd_pool * pool,
265 VkCommandBufferLevel level,
266 VkCommandBuffer* pCommandBuffer)
267 {
268 struct anv_cmd_buffer *cmd_buffer;
269 VkResult result;
270
271 cmd_buffer = vk_alloc2(&device->vk.alloc, &pool->alloc, sizeof(*cmd_buffer),
272 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
273 if (cmd_buffer == NULL)
274 return vk_error(pool, VK_ERROR_OUT_OF_HOST_MEMORY);
275
276 result = vk_command_buffer_init(&cmd_buffer->vk, &device->vk);
277 if (result != VK_SUCCESS)
278 goto fail;
279
280 cmd_buffer->batch.status = VK_SUCCESS;
281
282 cmd_buffer->device = device;
283 cmd_buffer->pool = pool;
284 cmd_buffer->level = level;
285
286 result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
287 if (result != VK_SUCCESS)
288 goto fail;
289
290 anv_state_stream_init(&cmd_buffer->surface_state_stream,
291 &device->surface_state_pool, 4096);
292 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
293 &device->dynamic_state_pool, 16384);
294 anv_state_stream_init(&cmd_buffer->general_state_stream,
295 &device->general_state_pool, 16384);
296
297 cmd_buffer->self_mod_locations = NULL;
298
299 anv_cmd_state_init(cmd_buffer);
300
301 list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
302
303 anv_measure_init(cmd_buffer);
304
305 *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
306
307 return VK_SUCCESS;
308
309 fail:
310 vk_free2(&device->vk.alloc, &pool->alloc, cmd_buffer);
311
312 return result;
313 }
314
anv_AllocateCommandBuffers(VkDevice _device,const VkCommandBufferAllocateInfo * pAllocateInfo,VkCommandBuffer * pCommandBuffers)315 VkResult anv_AllocateCommandBuffers(
316 VkDevice _device,
317 const VkCommandBufferAllocateInfo* pAllocateInfo,
318 VkCommandBuffer* pCommandBuffers)
319 {
320 ANV_FROM_HANDLE(anv_device, device, _device);
321 ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
322
323 VkResult result = VK_SUCCESS;
324 uint32_t i;
325
326 for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
327 result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
328 &pCommandBuffers[i]);
329 if (result != VK_SUCCESS)
330 break;
331 }
332
333 if (result != VK_SUCCESS) {
334 anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
335 i, pCommandBuffers);
336 for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
337 pCommandBuffers[i] = VK_NULL_HANDLE;
338 }
339
340 return result;
341 }
342
343 static void
anv_cmd_buffer_destroy(struct anv_cmd_buffer * cmd_buffer)344 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
345 {
346 anv_measure_destroy(cmd_buffer);
347
348 list_del(&cmd_buffer->pool_link);
349
350 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
351
352 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
353 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
354 anv_state_stream_finish(&cmd_buffer->general_state_stream);
355
356 anv_cmd_state_finish(cmd_buffer);
357
358 vk_free(&cmd_buffer->pool->alloc, cmd_buffer->self_mod_locations);
359
360 vk_command_buffer_finish(&cmd_buffer->vk);
361 vk_free2(&cmd_buffer->device->vk.alloc, &cmd_buffer->pool->alloc,
362 cmd_buffer);
363 }
364
anv_FreeCommandBuffers(VkDevice device,VkCommandPool commandPool,uint32_t commandBufferCount,const VkCommandBuffer * pCommandBuffers)365 void anv_FreeCommandBuffers(
366 VkDevice device,
367 VkCommandPool commandPool,
368 uint32_t commandBufferCount,
369 const VkCommandBuffer* pCommandBuffers)
370 {
371 for (uint32_t i = 0; i < commandBufferCount; i++) {
372 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
373
374 if (!cmd_buffer)
375 continue;
376
377 anv_cmd_buffer_destroy(cmd_buffer);
378 }
379 }
380
381 VkResult
anv_cmd_buffer_reset(struct anv_cmd_buffer * cmd_buffer)382 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
383 {
384 vk_command_buffer_reset(&cmd_buffer->vk);
385
386 cmd_buffer->usage_flags = 0;
387 cmd_buffer->perf_query_pool = NULL;
388 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
389 anv_cmd_state_reset(cmd_buffer);
390
391 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
392 anv_state_stream_init(&cmd_buffer->surface_state_stream,
393 &cmd_buffer->device->surface_state_pool, 4096);
394
395 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
396 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
397 &cmd_buffer->device->dynamic_state_pool, 16384);
398
399 anv_state_stream_finish(&cmd_buffer->general_state_stream);
400 anv_state_stream_init(&cmd_buffer->general_state_stream,
401 &cmd_buffer->device->general_state_pool, 16384);
402
403 anv_measure_reset(cmd_buffer);
404 return VK_SUCCESS;
405 }
406
anv_ResetCommandBuffer(VkCommandBuffer commandBuffer,VkCommandBufferResetFlags flags)407 VkResult anv_ResetCommandBuffer(
408 VkCommandBuffer commandBuffer,
409 VkCommandBufferResetFlags flags)
410 {
411 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
412 return anv_cmd_buffer_reset(cmd_buffer);
413 }
414
415 void
anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer * cmd_buffer)416 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
417 {
418 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
419 anv_genX(devinfo, cmd_buffer_emit_state_base_address)(cmd_buffer);
420 }
421
422 void
anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer * cmd_buffer,const struct anv_image * image,VkImageAspectFlagBits aspect,enum isl_aux_usage aux_usage,uint32_t level,uint32_t base_layer,uint32_t layer_count)423 anv_cmd_buffer_mark_image_written(struct anv_cmd_buffer *cmd_buffer,
424 const struct anv_image *image,
425 VkImageAspectFlagBits aspect,
426 enum isl_aux_usage aux_usage,
427 uint32_t level,
428 uint32_t base_layer,
429 uint32_t layer_count)
430 {
431 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
432 anv_genX(devinfo, cmd_buffer_mark_image_written)(cmd_buffer, image,
433 aspect, aux_usage,
434 level, base_layer,
435 layer_count);
436 }
437
438 void
anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer * cmd_buffer)439 anv_cmd_emit_conditional_render_predicate(struct anv_cmd_buffer *cmd_buffer)
440 {
441 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
442 anv_genX(devinfo, cmd_emit_conditional_render_predicate)(cmd_buffer);
443 }
444
445 static bool
mem_update(void * dst,const void * src,size_t size)446 mem_update(void *dst, const void *src, size_t size)
447 {
448 if (memcmp(dst, src, size) == 0)
449 return false;
450
451 memcpy(dst, src, size);
452 return true;
453 }
454
455 static void
set_dirty_for_bind_map(struct anv_cmd_buffer * cmd_buffer,gl_shader_stage stage,const struct anv_pipeline_bind_map * map)456 set_dirty_for_bind_map(struct anv_cmd_buffer *cmd_buffer,
457 gl_shader_stage stage,
458 const struct anv_pipeline_bind_map *map)
459 {
460 assert(stage < ARRAY_SIZE(cmd_buffer->state.surface_sha1s));
461 if (mem_update(cmd_buffer->state.surface_sha1s[stage],
462 map->surface_sha1, sizeof(map->surface_sha1)))
463 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
464
465 assert(stage < ARRAY_SIZE(cmd_buffer->state.sampler_sha1s));
466 if (mem_update(cmd_buffer->state.sampler_sha1s[stage],
467 map->sampler_sha1, sizeof(map->sampler_sha1)))
468 cmd_buffer->state.descriptors_dirty |= mesa_to_vk_shader_stage(stage);
469
470 assert(stage < ARRAY_SIZE(cmd_buffer->state.push_sha1s));
471 if (mem_update(cmd_buffer->state.push_sha1s[stage],
472 map->push_sha1, sizeof(map->push_sha1)))
473 cmd_buffer->state.push_constants_dirty |= mesa_to_vk_shader_stage(stage);
474 }
475
anv_CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline _pipeline)476 void anv_CmdBindPipeline(
477 VkCommandBuffer commandBuffer,
478 VkPipelineBindPoint pipelineBindPoint,
479 VkPipeline _pipeline)
480 {
481 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
482 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
483
484 switch (pipelineBindPoint) {
485 case VK_PIPELINE_BIND_POINT_COMPUTE: {
486 struct anv_compute_pipeline *compute_pipeline =
487 anv_pipeline_to_compute(pipeline);
488 if (cmd_buffer->state.compute.pipeline == compute_pipeline)
489 return;
490
491 cmd_buffer->state.compute.pipeline = compute_pipeline;
492 cmd_buffer->state.compute.pipeline_dirty = true;
493 set_dirty_for_bind_map(cmd_buffer, MESA_SHADER_COMPUTE,
494 &compute_pipeline->cs->bind_map);
495 break;
496 }
497
498 case VK_PIPELINE_BIND_POINT_GRAPHICS: {
499 struct anv_graphics_pipeline *gfx_pipeline =
500 anv_pipeline_to_graphics(pipeline);
501 if (cmd_buffer->state.gfx.pipeline == gfx_pipeline)
502 return;
503
504 cmd_buffer->state.gfx.pipeline = gfx_pipeline;
505 cmd_buffer->state.gfx.vb_dirty |= gfx_pipeline->vb_used;
506 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_PIPELINE;
507
508 anv_foreach_stage(stage, gfx_pipeline->active_stages) {
509 set_dirty_for_bind_map(cmd_buffer, stage,
510 &gfx_pipeline->shaders[stage]->bind_map);
511 }
512
513 /* Apply the dynamic state from the pipeline */
514 cmd_buffer->state.gfx.dirty |=
515 anv_dynamic_state_copy(&cmd_buffer->state.gfx.dynamic,
516 &gfx_pipeline->dynamic_state,
517 gfx_pipeline->dynamic_state_mask);
518 break;
519 }
520
521 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR: {
522 struct anv_ray_tracing_pipeline *rt_pipeline =
523 anv_pipeline_to_ray_tracing(pipeline);
524 if (cmd_buffer->state.rt.pipeline == rt_pipeline)
525 return;
526
527 cmd_buffer->state.rt.pipeline = rt_pipeline;
528 cmd_buffer->state.rt.pipeline_dirty = true;
529
530 if (rt_pipeline->stack_size > 0) {
531 anv_CmdSetRayTracingPipelineStackSizeKHR(commandBuffer,
532 rt_pipeline->stack_size);
533 }
534 break;
535 }
536
537 default:
538 assert(!"invalid bind point");
539 break;
540 }
541 }
542
anv_CmdSetRasterizerDiscardEnableEXT(VkCommandBuffer commandBuffer,VkBool32 rasterizerDiscardEnable)543 void anv_CmdSetRasterizerDiscardEnableEXT(
544 VkCommandBuffer commandBuffer,
545 VkBool32 rasterizerDiscardEnable)
546 {
547 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
548
549 cmd_buffer->state.gfx.dynamic.raster_discard = rasterizerDiscardEnable;
550
551 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_RASTERIZER_DISCARD_ENABLE;
552 }
553
anv_CmdSetDepthBiasEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthBiasEnable)554 void anv_CmdSetDepthBiasEnableEXT(
555 VkCommandBuffer commandBuffer,
556 VkBool32 depthBiasEnable)
557 {
558 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
559
560 cmd_buffer->state.gfx.dynamic.depth_bias_enable = depthBiasEnable;
561
562 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS_ENABLE;
563 }
564
anv_CmdSetPrimitiveRestartEnableEXT(VkCommandBuffer commandBuffer,VkBool32 primitiveRestartEnable)565 void anv_CmdSetPrimitiveRestartEnableEXT(
566 VkCommandBuffer commandBuffer,
567 VkBool32 primitiveRestartEnable)
568 {
569 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
570
571 cmd_buffer->state.gfx.dynamic.primitive_restart_enable = primitiveRestartEnable;
572
573 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_RESTART_ENABLE;
574 }
575
anv_CmdSetLogicOpEXT(VkCommandBuffer commandBuffer,VkLogicOp logicOp)576 void anv_CmdSetLogicOpEXT(
577 VkCommandBuffer commandBuffer,
578 VkLogicOp logicOp)
579 {
580 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
581
582 cmd_buffer->state.gfx.dynamic.logic_op = logicOp;
583
584 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LOGIC_OP;
585 }
586
anv_CmdSetPatchControlPointsEXT(VkCommandBuffer commandBuffer,uint32_t patchControlPoints)587 void anv_CmdSetPatchControlPointsEXT(
588 VkCommandBuffer commandBuffer,
589 uint32_t patchControlPoints)
590 {
591 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
592 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_FEATURE_NOT_PRESENT);
593 }
594
anv_CmdSetViewport(VkCommandBuffer commandBuffer,uint32_t firstViewport,uint32_t viewportCount,const VkViewport * pViewports)595 void anv_CmdSetViewport(
596 VkCommandBuffer commandBuffer,
597 uint32_t firstViewport,
598 uint32_t viewportCount,
599 const VkViewport* pViewports)
600 {
601 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
602
603 const uint32_t total_count = firstViewport + viewportCount;
604 if (cmd_buffer->state.gfx.dynamic.viewport.count < total_count)
605 cmd_buffer->state.gfx.dynamic.viewport.count = total_count;
606
607 memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports + firstViewport,
608 pViewports, viewportCount * sizeof(*pViewports));
609
610 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
611 }
612
anv_CmdSetViewportWithCountEXT(VkCommandBuffer commandBuffer,uint32_t viewportCount,const VkViewport * pViewports)613 void anv_CmdSetViewportWithCountEXT(
614 VkCommandBuffer commandBuffer,
615 uint32_t viewportCount,
616 const VkViewport* pViewports)
617 {
618 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
619
620 cmd_buffer->state.gfx.dynamic.viewport.count = viewportCount;
621
622 memcpy(cmd_buffer->state.gfx.dynamic.viewport.viewports,
623 pViewports, viewportCount * sizeof(*pViewports));
624
625 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
626 }
627
anv_CmdSetScissor(VkCommandBuffer commandBuffer,uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * pScissors)628 void anv_CmdSetScissor(
629 VkCommandBuffer commandBuffer,
630 uint32_t firstScissor,
631 uint32_t scissorCount,
632 const VkRect2D* pScissors)
633 {
634 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
635
636 const uint32_t total_count = firstScissor + scissorCount;
637 if (cmd_buffer->state.gfx.dynamic.scissor.count < total_count)
638 cmd_buffer->state.gfx.dynamic.scissor.count = total_count;
639
640 memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors + firstScissor,
641 pScissors, scissorCount * sizeof(*pScissors));
642
643 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
644 }
645
anv_CmdSetScissorWithCountEXT(VkCommandBuffer commandBuffer,uint32_t scissorCount,const VkRect2D * pScissors)646 void anv_CmdSetScissorWithCountEXT(
647 VkCommandBuffer commandBuffer,
648 uint32_t scissorCount,
649 const VkRect2D* pScissors)
650 {
651 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
652
653 cmd_buffer->state.gfx.dynamic.scissor.count = scissorCount;
654
655 memcpy(cmd_buffer->state.gfx.dynamic.scissor.scissors,
656 pScissors, scissorCount * sizeof(*pScissors));
657
658 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
659 }
660
anv_CmdSetPrimitiveTopologyEXT(VkCommandBuffer commandBuffer,VkPrimitiveTopology primitiveTopology)661 void anv_CmdSetPrimitiveTopologyEXT(
662 VkCommandBuffer commandBuffer,
663 VkPrimitiveTopology primitiveTopology)
664 {
665 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
666
667 cmd_buffer->state.gfx.dynamic.primitive_topology = primitiveTopology;
668
669 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_PRIMITIVE_TOPOLOGY;
670 }
671
anv_CmdSetLineWidth(VkCommandBuffer commandBuffer,float lineWidth)672 void anv_CmdSetLineWidth(
673 VkCommandBuffer commandBuffer,
674 float lineWidth)
675 {
676 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
677
678 cmd_buffer->state.gfx.dynamic.line_width = lineWidth;
679 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
680 }
681
anv_CmdSetDepthBias(VkCommandBuffer commandBuffer,float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)682 void anv_CmdSetDepthBias(
683 VkCommandBuffer commandBuffer,
684 float depthBiasConstantFactor,
685 float depthBiasClamp,
686 float depthBiasSlopeFactor)
687 {
688 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
689
690 cmd_buffer->state.gfx.dynamic.depth_bias.bias = depthBiasConstantFactor;
691 cmd_buffer->state.gfx.dynamic.depth_bias.clamp = depthBiasClamp;
692 cmd_buffer->state.gfx.dynamic.depth_bias.slope = depthBiasSlopeFactor;
693
694 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
695 }
696
anv_CmdSetBlendConstants(VkCommandBuffer commandBuffer,const float blendConstants[4])697 void anv_CmdSetBlendConstants(
698 VkCommandBuffer commandBuffer,
699 const float blendConstants[4])
700 {
701 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
702
703 memcpy(cmd_buffer->state.gfx.dynamic.blend_constants,
704 blendConstants, sizeof(float) * 4);
705
706 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
707 }
708
anv_CmdSetDepthBounds(VkCommandBuffer commandBuffer,float minDepthBounds,float maxDepthBounds)709 void anv_CmdSetDepthBounds(
710 VkCommandBuffer commandBuffer,
711 float minDepthBounds,
712 float maxDepthBounds)
713 {
714 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
715
716 cmd_buffer->state.gfx.dynamic.depth_bounds.min = minDepthBounds;
717 cmd_buffer->state.gfx.dynamic.depth_bounds.max = maxDepthBounds;
718
719 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
720 }
721
anv_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t compareMask)722 void anv_CmdSetStencilCompareMask(
723 VkCommandBuffer commandBuffer,
724 VkStencilFaceFlags faceMask,
725 uint32_t compareMask)
726 {
727 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
728
729 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
730 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.front = compareMask;
731 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
732 cmd_buffer->state.gfx.dynamic.stencil_compare_mask.back = compareMask;
733
734 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
735 }
736
anv_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t writeMask)737 void anv_CmdSetStencilWriteMask(
738 VkCommandBuffer commandBuffer,
739 VkStencilFaceFlags faceMask,
740 uint32_t writeMask)
741 {
742 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
743
744 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
745 cmd_buffer->state.gfx.dynamic.stencil_write_mask.front = writeMask;
746 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
747 cmd_buffer->state.gfx.dynamic.stencil_write_mask.back = writeMask;
748
749 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
750 }
751
anv_CmdSetStencilReference(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,uint32_t reference)752 void anv_CmdSetStencilReference(
753 VkCommandBuffer commandBuffer,
754 VkStencilFaceFlags faceMask,
755 uint32_t reference)
756 {
757 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
758
759 if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
760 cmd_buffer->state.gfx.dynamic.stencil_reference.front = reference;
761 if (faceMask & VK_STENCIL_FACE_BACK_BIT)
762 cmd_buffer->state.gfx.dynamic.stencil_reference.back = reference;
763
764 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
765 }
766
anv_CmdSetSampleLocationsEXT(VkCommandBuffer commandBuffer,const VkSampleLocationsInfoEXT * pSampleLocationsInfo)767 void anv_CmdSetSampleLocationsEXT(
768 VkCommandBuffer commandBuffer,
769 const VkSampleLocationsInfoEXT* pSampleLocationsInfo)
770 {
771 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
772
773 struct anv_dynamic_state *dyn_state = &cmd_buffer->state.gfx.dynamic;
774 uint32_t samples = pSampleLocationsInfo->sampleLocationsPerPixel;
775
776 dyn_state->sample_locations.samples = samples;
777 typed_memcpy(dyn_state->sample_locations.locations,
778 pSampleLocationsInfo->pSampleLocations, samples);
779
780 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SAMPLE_LOCATIONS;
781 }
782
anv_CmdSetLineStippleEXT(VkCommandBuffer commandBuffer,uint32_t lineStippleFactor,uint16_t lineStipplePattern)783 void anv_CmdSetLineStippleEXT(
784 VkCommandBuffer commandBuffer,
785 uint32_t lineStippleFactor,
786 uint16_t lineStipplePattern)
787 {
788 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
789
790 cmd_buffer->state.gfx.dynamic.line_stipple.factor = lineStippleFactor;
791 cmd_buffer->state.gfx.dynamic.line_stipple.pattern = lineStipplePattern;
792
793 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_STIPPLE;
794 }
795
anv_CmdSetCullModeEXT(VkCommandBuffer commandBuffer,VkCullModeFlags cullMode)796 void anv_CmdSetCullModeEXT(
797 VkCommandBuffer commandBuffer,
798 VkCullModeFlags cullMode)
799 {
800 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
801
802 cmd_buffer->state.gfx.dynamic.cull_mode = cullMode;
803
804 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_CULL_MODE;
805 }
806
anv_CmdSetFrontFaceEXT(VkCommandBuffer commandBuffer,VkFrontFace frontFace)807 void anv_CmdSetFrontFaceEXT(
808 VkCommandBuffer commandBuffer,
809 VkFrontFace frontFace)
810 {
811 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
812
813 cmd_buffer->state.gfx.dynamic.front_face = frontFace;
814
815 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_FRONT_FACE;
816 }
817
anv_CmdSetDepthTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthTestEnable)818 void anv_CmdSetDepthTestEnableEXT(
819 VkCommandBuffer commandBuffer,
820 VkBool32 depthTestEnable)
821
822 {
823 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
824
825 cmd_buffer->state.gfx.dynamic.depth_test_enable = depthTestEnable;
826
827 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_TEST_ENABLE;
828 }
829
anv_CmdSetDepthWriteEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthWriteEnable)830 void anv_CmdSetDepthWriteEnableEXT(
831 VkCommandBuffer commandBuffer,
832 VkBool32 depthWriteEnable)
833 {
834 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
835
836 cmd_buffer->state.gfx.dynamic.depth_write_enable = depthWriteEnable;
837
838 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_WRITE_ENABLE;
839 }
840
anv_CmdSetDepthCompareOpEXT(VkCommandBuffer commandBuffer,VkCompareOp depthCompareOp)841 void anv_CmdSetDepthCompareOpEXT(
842 VkCommandBuffer commandBuffer,
843 VkCompareOp depthCompareOp)
844 {
845 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
846
847 cmd_buffer->state.gfx.dynamic.depth_compare_op = depthCompareOp;
848
849 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_COMPARE_OP;
850 }
851
anv_CmdSetDepthBoundsTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 depthBoundsTestEnable)852 void anv_CmdSetDepthBoundsTestEnableEXT(
853 VkCommandBuffer commandBuffer,
854 VkBool32 depthBoundsTestEnable)
855 {
856 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
857
858 cmd_buffer->state.gfx.dynamic.depth_bounds_test_enable = depthBoundsTestEnable;
859
860 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS_TEST_ENABLE;
861 }
862
anv_CmdSetStencilTestEnableEXT(VkCommandBuffer commandBuffer,VkBool32 stencilTestEnable)863 void anv_CmdSetStencilTestEnableEXT(
864 VkCommandBuffer commandBuffer,
865 VkBool32 stencilTestEnable)
866 {
867 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
868
869 cmd_buffer->state.gfx.dynamic.stencil_test_enable = stencilTestEnable;
870
871 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_TEST_ENABLE;
872 }
873
anv_CmdSetStencilOpEXT(VkCommandBuffer commandBuffer,VkStencilFaceFlags faceMask,VkStencilOp failOp,VkStencilOp passOp,VkStencilOp depthFailOp,VkCompareOp compareOp)874 void anv_CmdSetStencilOpEXT(
875 VkCommandBuffer commandBuffer,
876 VkStencilFaceFlags faceMask,
877 VkStencilOp failOp,
878 VkStencilOp passOp,
879 VkStencilOp depthFailOp,
880 VkCompareOp compareOp)
881 {
882 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
883
884 if (faceMask & VK_STENCIL_FACE_FRONT_BIT) {
885 cmd_buffer->state.gfx.dynamic.stencil_op.front.fail_op = failOp;
886 cmd_buffer->state.gfx.dynamic.stencil_op.front.pass_op = passOp;
887 cmd_buffer->state.gfx.dynamic.stencil_op.front.depth_fail_op = depthFailOp;
888 cmd_buffer->state.gfx.dynamic.stencil_op.front.compare_op = compareOp;
889 }
890
891 if (faceMask & VK_STENCIL_FACE_BACK_BIT) {
892 cmd_buffer->state.gfx.dynamic.stencil_op.back.fail_op = failOp;
893 cmd_buffer->state.gfx.dynamic.stencil_op.back.pass_op = passOp;
894 cmd_buffer->state.gfx.dynamic.stencil_op.back.depth_fail_op = depthFailOp;
895 cmd_buffer->state.gfx.dynamic.stencil_op.back.compare_op = compareOp;
896 }
897
898 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_OP;
899 }
900
901 static void
anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer * cmd_buffer,VkPipelineBindPoint bind_point,struct anv_pipeline_layout * layout,uint32_t set_index,struct anv_descriptor_set * set,uint32_t * dynamic_offset_count,const uint32_t ** dynamic_offsets)902 anv_cmd_buffer_bind_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
903 VkPipelineBindPoint bind_point,
904 struct anv_pipeline_layout *layout,
905 uint32_t set_index,
906 struct anv_descriptor_set *set,
907 uint32_t *dynamic_offset_count,
908 const uint32_t **dynamic_offsets)
909 {
910 struct anv_descriptor_set_layout *set_layout =
911 layout->set[set_index].layout;
912
913 VkShaderStageFlags stages = set_layout->shader_stages;
914 struct anv_cmd_pipeline_state *pipe_state;
915
916 switch (bind_point) {
917 case VK_PIPELINE_BIND_POINT_GRAPHICS:
918 stages &= VK_SHADER_STAGE_ALL_GRAPHICS;
919 pipe_state = &cmd_buffer->state.gfx.base;
920 break;
921
922 case VK_PIPELINE_BIND_POINT_COMPUTE:
923 stages &= VK_SHADER_STAGE_COMPUTE_BIT;
924 pipe_state = &cmd_buffer->state.compute.base;
925 break;
926
927 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
928 stages &= VK_SHADER_STAGE_RAYGEN_BIT_KHR |
929 VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
930 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
931 VK_SHADER_STAGE_MISS_BIT_KHR |
932 VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
933 VK_SHADER_STAGE_CALLABLE_BIT_KHR;
934 pipe_state = &cmd_buffer->state.rt.base;
935 break;
936
937 default:
938 unreachable("invalid bind point");
939 }
940
941 VkShaderStageFlags dirty_stages = 0;
942 /* If it's a push descriptor set, we have to flag things as dirty
943 * regardless of whether or not the CPU-side data structure changed as we
944 * may have edited in-place.
945 */
946 if (pipe_state->descriptors[set_index] != set ||
947 anv_descriptor_set_is_push(set)) {
948 pipe_state->descriptors[set_index] = set;
949
950 /* Ray-tracing shaders are entirely bindless and so they don't have
951 * access to HW binding tables. This means that we have to upload the
952 * descriptor set as an 64-bit address in the push constants.
953 */
954 if (bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) {
955 struct anv_push_constants *push = &pipe_state->push_constants;
956
957 struct anv_address addr = anv_descriptor_set_address(set);
958 push->desc_sets[set_index] = anv_address_physical(addr);
959
960 if (addr.bo) {
961 anv_reloc_list_add_bo(cmd_buffer->batch.relocs,
962 cmd_buffer->batch.alloc,
963 addr.bo);
964 }
965 }
966
967 dirty_stages |= stages;
968 }
969
970 if (dynamic_offsets) {
971 if (set_layout->dynamic_offset_count > 0) {
972 struct anv_push_constants *push = &pipe_state->push_constants;
973 uint32_t dynamic_offset_start =
974 layout->set[set_index].dynamic_offset_start;
975 uint32_t *push_offsets =
976 &push->dynamic_offsets[dynamic_offset_start];
977
978 /* Assert that everything is in range */
979 assert(set_layout->dynamic_offset_count <= *dynamic_offset_count);
980 assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
981 ARRAY_SIZE(push->dynamic_offsets));
982
983 for (uint32_t i = 0; i < set_layout->dynamic_offset_count; i++) {
984 if (push_offsets[i] != (*dynamic_offsets)[i]) {
985 push_offsets[i] = (*dynamic_offsets)[i];
986 /* dynamic_offset_stages[] elements could contain blanket
987 * values like VK_SHADER_STAGE_ALL, so limit this to the
988 * binding point's bits.
989 */
990 dirty_stages |= set_layout->dynamic_offset_stages[i] & stages;
991 }
992 }
993
994 *dynamic_offsets += set_layout->dynamic_offset_count;
995 *dynamic_offset_count -= set_layout->dynamic_offset_count;
996 }
997 }
998
999 cmd_buffer->state.descriptors_dirty |= dirty_stages;
1000 cmd_buffer->state.push_constants_dirty |= dirty_stages;
1001 }
1002
anv_CmdBindDescriptorSets(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * pDescriptorSets,uint32_t dynamicOffsetCount,const uint32_t * pDynamicOffsets)1003 void anv_CmdBindDescriptorSets(
1004 VkCommandBuffer commandBuffer,
1005 VkPipelineBindPoint pipelineBindPoint,
1006 VkPipelineLayout _layout,
1007 uint32_t firstSet,
1008 uint32_t descriptorSetCount,
1009 const VkDescriptorSet* pDescriptorSets,
1010 uint32_t dynamicOffsetCount,
1011 const uint32_t* pDynamicOffsets)
1012 {
1013 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1014 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1015
1016 assert(firstSet + descriptorSetCount <= MAX_SETS);
1017
1018 for (uint32_t i = 0; i < descriptorSetCount; i++) {
1019 ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
1020 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1021 layout, firstSet + i, set,
1022 &dynamicOffsetCount,
1023 &pDynamicOffsets);
1024 }
1025 }
1026
anv_CmdBindVertexBuffers2EXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes,const VkDeviceSize * pStrides)1027 void anv_CmdBindVertexBuffers2EXT(
1028 VkCommandBuffer commandBuffer,
1029 uint32_t firstBinding,
1030 uint32_t bindingCount,
1031 const VkBuffer* pBuffers,
1032 const VkDeviceSize* pOffsets,
1033 const VkDeviceSize* pSizes,
1034 const VkDeviceSize* pStrides)
1035 {
1036 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1037 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
1038
1039 /* We have to defer setting up vertex buffer since we need the buffer
1040 * stride from the pipeline. */
1041
1042 if (pSizes)
1043 cmd_buffer->state.gfx.dynamic.dyn_vbo_size = true;
1044 if (pStrides)
1045 cmd_buffer->state.gfx.dynamic.dyn_vbo_stride = true;
1046
1047 assert(firstBinding + bindingCount <= MAX_VBS);
1048 for (uint32_t i = 0; i < bindingCount; i++) {
1049 vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
1050 vb[firstBinding + i].offset = pOffsets[i];
1051 vb[firstBinding + i].size = pSizes ? pSizes[i] : 0;
1052 vb[firstBinding + i].stride = pStrides ? pStrides[i] : 0;
1053 cmd_buffer->state.gfx.vb_dirty |= 1 << (firstBinding + i);
1054 }
1055 }
1056
anv_CmdBindVertexBuffers(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets)1057 void anv_CmdBindVertexBuffers(
1058 VkCommandBuffer commandBuffer,
1059 uint32_t firstBinding,
1060 uint32_t bindingCount,
1061 const VkBuffer* pBuffers,
1062 const VkDeviceSize* pOffsets)
1063 {
1064 return anv_CmdBindVertexBuffers2EXT(commandBuffer, firstBinding,
1065 bindingCount, pBuffers, pOffsets,
1066 NULL, NULL);
1067 }
1068
anv_CmdBindTransformFeedbackBuffersEXT(VkCommandBuffer commandBuffer,uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * pBuffers,const VkDeviceSize * pOffsets,const VkDeviceSize * pSizes)1069 void anv_CmdBindTransformFeedbackBuffersEXT(
1070 VkCommandBuffer commandBuffer,
1071 uint32_t firstBinding,
1072 uint32_t bindingCount,
1073 const VkBuffer* pBuffers,
1074 const VkDeviceSize* pOffsets,
1075 const VkDeviceSize* pSizes)
1076 {
1077 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1078 struct anv_xfb_binding *xfb = cmd_buffer->state.xfb_bindings;
1079
1080 /* We have to defer setting up vertex buffer since we need the buffer
1081 * stride from the pipeline. */
1082
1083 assert(firstBinding + bindingCount <= MAX_XFB_BUFFERS);
1084 for (uint32_t i = 0; i < bindingCount; i++) {
1085 if (pBuffers[i] == VK_NULL_HANDLE) {
1086 xfb[firstBinding + i].buffer = NULL;
1087 } else {
1088 ANV_FROM_HANDLE(anv_buffer, buffer, pBuffers[i]);
1089 xfb[firstBinding + i].buffer = buffer;
1090 xfb[firstBinding + i].offset = pOffsets[i];
1091 xfb[firstBinding + i].size =
1092 anv_buffer_get_range(buffer, pOffsets[i],
1093 pSizes ? pSizes[i] : VK_WHOLE_SIZE);
1094 }
1095 }
1096 }
1097
1098 enum isl_format
anv_isl_format_for_descriptor_type(const struct anv_device * device,VkDescriptorType type)1099 anv_isl_format_for_descriptor_type(const struct anv_device *device,
1100 VkDescriptorType type)
1101 {
1102 switch (type) {
1103 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1104 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1105 return device->physical->compiler->indirect_ubos_use_sampler ?
1106 ISL_FORMAT_R32G32B32A32_FLOAT : ISL_FORMAT_RAW;
1107
1108 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1109 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1110 return ISL_FORMAT_RAW;
1111
1112 default:
1113 unreachable("Invalid descriptor type");
1114 }
1115 }
1116
1117 struct anv_state
anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer * cmd_buffer,const void * data,uint32_t size,uint32_t alignment)1118 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
1119 const void *data, uint32_t size, uint32_t alignment)
1120 {
1121 struct anv_state state;
1122
1123 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
1124 memcpy(state.map, data, size);
1125
1126 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
1127
1128 return state;
1129 }
1130
1131 struct anv_state
anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer * cmd_buffer,uint32_t * a,uint32_t * b,uint32_t dwords,uint32_t alignment)1132 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
1133 uint32_t *a, uint32_t *b,
1134 uint32_t dwords, uint32_t alignment)
1135 {
1136 struct anv_state state;
1137 uint32_t *p;
1138
1139 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1140 dwords * 4, alignment);
1141 p = state.map;
1142 for (uint32_t i = 0; i < dwords; i++)
1143 p[i] = a[i] | b[i];
1144
1145 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
1146
1147 return state;
1148 }
1149
1150 struct anv_state
anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer * cmd_buffer)1151 anv_cmd_buffer_gfx_push_constants(struct anv_cmd_buffer *cmd_buffer)
1152 {
1153 struct anv_push_constants *data =
1154 &cmd_buffer->state.gfx.base.push_constants;
1155
1156 struct anv_state state =
1157 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1158 sizeof(struct anv_push_constants),
1159 32 /* bottom 5 bits MBZ */);
1160 memcpy(state.map, data, sizeof(struct anv_push_constants));
1161
1162 return state;
1163 }
1164
1165 struct anv_state
anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer * cmd_buffer)1166 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
1167 {
1168 const struct intel_device_info *devinfo = &cmd_buffer->device->info;
1169 struct anv_push_constants *data =
1170 &cmd_buffer->state.compute.base.push_constants;
1171 struct anv_compute_pipeline *pipeline = cmd_buffer->state.compute.pipeline;
1172 const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
1173 const struct anv_push_range *range = &pipeline->cs->bind_map.push_ranges[0];
1174
1175 const struct brw_cs_dispatch_info dispatch =
1176 brw_cs_get_dispatch_info(devinfo, cs_prog_data, NULL);
1177 const unsigned total_push_constants_size =
1178 brw_cs_push_const_total_size(cs_prog_data, dispatch.threads);
1179 if (total_push_constants_size == 0)
1180 return (struct anv_state) { .offset = 0 };
1181
1182 const unsigned push_constant_alignment =
1183 cmd_buffer->device->info.ver < 8 ? 32 : 64;
1184 const unsigned aligned_total_push_constants_size =
1185 ALIGN(total_push_constants_size, push_constant_alignment);
1186 struct anv_state state;
1187 if (devinfo->verx10 >= 125) {
1188 state = anv_state_stream_alloc(&cmd_buffer->general_state_stream,
1189 aligned_total_push_constants_size,
1190 push_constant_alignment);
1191 } else {
1192 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
1193 aligned_total_push_constants_size,
1194 push_constant_alignment);
1195 }
1196
1197 void *dst = state.map;
1198 const void *src = (char *)data + (range->start * 32);
1199
1200 if (cs_prog_data->push.cross_thread.size > 0) {
1201 memcpy(dst, src, cs_prog_data->push.cross_thread.size);
1202 dst += cs_prog_data->push.cross_thread.size;
1203 src += cs_prog_data->push.cross_thread.size;
1204 }
1205
1206 if (cs_prog_data->push.per_thread.size > 0) {
1207 for (unsigned t = 0; t < dispatch.threads; t++) {
1208 memcpy(dst, src, cs_prog_data->push.per_thread.size);
1209
1210 uint32_t *subgroup_id = dst +
1211 offsetof(struct anv_push_constants, cs.subgroup_id) -
1212 (range->start * 32 + cs_prog_data->push.cross_thread.size);
1213 *subgroup_id = t;
1214
1215 dst += cs_prog_data->push.per_thread.size;
1216 }
1217 }
1218
1219 return state;
1220 }
1221
anv_CmdPushConstants(VkCommandBuffer commandBuffer,VkPipelineLayout layout,VkShaderStageFlags stageFlags,uint32_t offset,uint32_t size,const void * pValues)1222 void anv_CmdPushConstants(
1223 VkCommandBuffer commandBuffer,
1224 VkPipelineLayout layout,
1225 VkShaderStageFlags stageFlags,
1226 uint32_t offset,
1227 uint32_t size,
1228 const void* pValues)
1229 {
1230 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1231
1232 if (stageFlags & VK_SHADER_STAGE_ALL_GRAPHICS) {
1233 struct anv_cmd_pipeline_state *pipe_state =
1234 &cmd_buffer->state.gfx.base;
1235
1236 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1237 }
1238 if (stageFlags & VK_SHADER_STAGE_COMPUTE_BIT) {
1239 struct anv_cmd_pipeline_state *pipe_state =
1240 &cmd_buffer->state.compute.base;
1241
1242 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1243 }
1244 if (stageFlags & (VK_SHADER_STAGE_RAYGEN_BIT_KHR |
1245 VK_SHADER_STAGE_ANY_HIT_BIT_KHR |
1246 VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR |
1247 VK_SHADER_STAGE_MISS_BIT_KHR |
1248 VK_SHADER_STAGE_INTERSECTION_BIT_KHR |
1249 VK_SHADER_STAGE_CALLABLE_BIT_KHR)) {
1250 struct anv_cmd_pipeline_state *pipe_state =
1251 &cmd_buffer->state.rt.base;
1252
1253 memcpy(pipe_state->push_constants.client_data + offset, pValues, size);
1254 }
1255
1256 cmd_buffer->state.push_constants_dirty |= stageFlags;
1257 }
1258
anv_CreateCommandPool(VkDevice _device,const VkCommandPoolCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkCommandPool * pCmdPool)1259 VkResult anv_CreateCommandPool(
1260 VkDevice _device,
1261 const VkCommandPoolCreateInfo* pCreateInfo,
1262 const VkAllocationCallbacks* pAllocator,
1263 VkCommandPool* pCmdPool)
1264 {
1265 ANV_FROM_HANDLE(anv_device, device, _device);
1266 struct anv_cmd_pool *pool;
1267
1268 pool = vk_object_alloc(&device->vk, pAllocator, sizeof(*pool),
1269 VK_OBJECT_TYPE_COMMAND_POOL);
1270 if (pool == NULL)
1271 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1272
1273 assert(pCreateInfo->queueFamilyIndex < device->physical->queue.family_count);
1274 pool->queue_family =
1275 &device->physical->queue.families[pCreateInfo->queueFamilyIndex];
1276
1277 if (pAllocator)
1278 pool->alloc = *pAllocator;
1279 else
1280 pool->alloc = device->vk.alloc;
1281
1282 list_inithead(&pool->cmd_buffers);
1283
1284 pool->flags = pCreateInfo->flags;
1285
1286 *pCmdPool = anv_cmd_pool_to_handle(pool);
1287
1288 return VK_SUCCESS;
1289 }
1290
anv_DestroyCommandPool(VkDevice _device,VkCommandPool commandPool,const VkAllocationCallbacks * pAllocator)1291 void anv_DestroyCommandPool(
1292 VkDevice _device,
1293 VkCommandPool commandPool,
1294 const VkAllocationCallbacks* pAllocator)
1295 {
1296 ANV_FROM_HANDLE(anv_device, device, _device);
1297 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1298
1299 if (!pool)
1300 return;
1301
1302 list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
1303 &pool->cmd_buffers, pool_link) {
1304 anv_cmd_buffer_destroy(cmd_buffer);
1305 }
1306
1307 vk_object_free(&device->vk, pAllocator, pool);
1308 }
1309
anv_ResetCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolResetFlags flags)1310 VkResult anv_ResetCommandPool(
1311 VkDevice device,
1312 VkCommandPool commandPool,
1313 VkCommandPoolResetFlags flags)
1314 {
1315 ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
1316
1317 list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
1318 &pool->cmd_buffers, pool_link) {
1319 anv_cmd_buffer_reset(cmd_buffer);
1320 }
1321
1322 return VK_SUCCESS;
1323 }
1324
anv_TrimCommandPool(VkDevice device,VkCommandPool commandPool,VkCommandPoolTrimFlags flags)1325 void anv_TrimCommandPool(
1326 VkDevice device,
1327 VkCommandPool commandPool,
1328 VkCommandPoolTrimFlags flags)
1329 {
1330 /* Nothing for us to do here. Our pools stay pretty tidy. */
1331 }
1332
1333 /**
1334 * Return NULL if the current subpass has no depthstencil attachment.
1335 */
1336 const struct anv_image_view *
anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer * cmd_buffer)1337 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
1338 {
1339 const struct anv_subpass *subpass = cmd_buffer->state.subpass;
1340
1341 if (subpass->depth_stencil_attachment == NULL)
1342 return NULL;
1343
1344 const struct anv_image_view *iview =
1345 cmd_buffer->state.attachments[subpass->depth_stencil_attachment->attachment].image_view;
1346
1347 assert(iview->vk.aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |
1348 VK_IMAGE_ASPECT_STENCIL_BIT));
1349
1350 return iview;
1351 }
1352
1353 static struct anv_descriptor_set *
anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer * cmd_buffer,VkPipelineBindPoint bind_point,struct anv_descriptor_set_layout * layout,uint32_t _set)1354 anv_cmd_buffer_push_descriptor_set(struct anv_cmd_buffer *cmd_buffer,
1355 VkPipelineBindPoint bind_point,
1356 struct anv_descriptor_set_layout *layout,
1357 uint32_t _set)
1358 {
1359 struct anv_cmd_pipeline_state *pipe_state;
1360
1361 switch (bind_point) {
1362 case VK_PIPELINE_BIND_POINT_GRAPHICS:
1363 pipe_state = &cmd_buffer->state.gfx.base;
1364 break;
1365
1366 case VK_PIPELINE_BIND_POINT_COMPUTE:
1367 pipe_state = &cmd_buffer->state.compute.base;
1368 break;
1369
1370 case VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR:
1371 pipe_state = &cmd_buffer->state.rt.base;
1372 break;
1373
1374 default:
1375 unreachable("invalid bind point");
1376 }
1377
1378 struct anv_push_descriptor_set **push_set =
1379 &pipe_state->push_descriptors[_set];
1380
1381 if (*push_set == NULL) {
1382 *push_set = vk_zalloc(&cmd_buffer->pool->alloc,
1383 sizeof(struct anv_push_descriptor_set), 8,
1384 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1385 if (*push_set == NULL) {
1386 anv_batch_set_error(&cmd_buffer->batch, VK_ERROR_OUT_OF_HOST_MEMORY);
1387 return NULL;
1388 }
1389 }
1390
1391 struct anv_descriptor_set *set = &(*push_set)->set;
1392
1393 if (set->layout != layout) {
1394 if (set->layout)
1395 anv_descriptor_set_layout_unref(cmd_buffer->device, set->layout);
1396 anv_descriptor_set_layout_ref(layout);
1397 set->layout = layout;
1398 }
1399 set->size = anv_descriptor_set_layout_size(layout, 0);
1400 set->buffer_view_count = layout->buffer_view_count;
1401 set->descriptor_count = layout->descriptor_count;
1402 set->buffer_views = (*push_set)->buffer_views;
1403
1404 if (layout->descriptor_buffer_size &&
1405 ((*push_set)->set_used_on_gpu ||
1406 set->desc_mem.alloc_size < layout->descriptor_buffer_size)) {
1407 /* The previous buffer is either actively used by some GPU command (so
1408 * we can't modify it) or is too small. Allocate a new one.
1409 */
1410 struct anv_state desc_mem =
1411 anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
1412 anv_descriptor_set_layout_descriptor_buffer_size(layout, 0),
1413 ANV_UBO_ALIGNMENT);
1414 if (set->desc_mem.alloc_size) {
1415 /* TODO: Do we really need to copy all the time? */
1416 memcpy(desc_mem.map, set->desc_mem.map,
1417 MIN2(desc_mem.alloc_size, set->desc_mem.alloc_size));
1418 }
1419 set->desc_mem = desc_mem;
1420
1421 set->desc_addr = (struct anv_address) {
1422 .bo = cmd_buffer->dynamic_state_stream.state_pool->block_pool.bo,
1423 .offset = set->desc_mem.offset,
1424 };
1425
1426 enum isl_format format =
1427 anv_isl_format_for_descriptor_type(cmd_buffer->device,
1428 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
1429
1430 const struct isl_device *isl_dev = &cmd_buffer->device->isl_dev;
1431 set->desc_surface_state =
1432 anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
1433 isl_dev->ss.size, isl_dev->ss.align);
1434 anv_fill_buffer_surface_state(cmd_buffer->device,
1435 set->desc_surface_state, format,
1436 ISL_SURF_USAGE_CONSTANT_BUFFER_BIT,
1437 set->desc_addr,
1438 layout->descriptor_buffer_size, 1);
1439 }
1440
1441 return set;
1442 }
1443
anv_CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipelineLayout _layout,uint32_t _set,uint32_t descriptorWriteCount,const VkWriteDescriptorSet * pDescriptorWrites)1444 void anv_CmdPushDescriptorSetKHR(
1445 VkCommandBuffer commandBuffer,
1446 VkPipelineBindPoint pipelineBindPoint,
1447 VkPipelineLayout _layout,
1448 uint32_t _set,
1449 uint32_t descriptorWriteCount,
1450 const VkWriteDescriptorSet* pDescriptorWrites)
1451 {
1452 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1453 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1454
1455 assert(_set < MAX_SETS);
1456
1457 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1458
1459 struct anv_descriptor_set *set =
1460 anv_cmd_buffer_push_descriptor_set(cmd_buffer, pipelineBindPoint,
1461 set_layout, _set);
1462 if (!set)
1463 return;
1464
1465 /* Go through the user supplied descriptors. */
1466 for (uint32_t i = 0; i < descriptorWriteCount; i++) {
1467 const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
1468
1469 switch (write->descriptorType) {
1470 case VK_DESCRIPTOR_TYPE_SAMPLER:
1471 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1472 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1473 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1474 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
1475 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1476 anv_descriptor_set_write_image_view(cmd_buffer->device, set,
1477 write->pImageInfo + j,
1478 write->descriptorType,
1479 write->dstBinding,
1480 write->dstArrayElement + j);
1481 }
1482 break;
1483
1484 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1485 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1486 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1487 ANV_FROM_HANDLE(anv_buffer_view, bview,
1488 write->pTexelBufferView[j]);
1489
1490 anv_descriptor_set_write_buffer_view(cmd_buffer->device, set,
1491 write->descriptorType,
1492 bview,
1493 write->dstBinding,
1494 write->dstArrayElement + j);
1495 }
1496 break;
1497
1498 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1499 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1500 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1501 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1502 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1503 ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
1504
1505 anv_descriptor_set_write_buffer(cmd_buffer->device, set,
1506 &cmd_buffer->surface_state_stream,
1507 write->descriptorType,
1508 buffer,
1509 write->dstBinding,
1510 write->dstArrayElement + j,
1511 write->pBufferInfo[j].offset,
1512 write->pBufferInfo[j].range);
1513 }
1514 break;
1515
1516 case VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR: {
1517 const VkWriteDescriptorSetAccelerationStructureKHR *accel_write =
1518 vk_find_struct_const(write, WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_KHR);
1519 assert(accel_write->accelerationStructureCount ==
1520 write->descriptorCount);
1521 for (uint32_t j = 0; j < write->descriptorCount; j++) {
1522 ANV_FROM_HANDLE(anv_acceleration_structure, accel,
1523 accel_write->pAccelerationStructures[j]);
1524 anv_descriptor_set_write_acceleration_structure(cmd_buffer->device,
1525 set, accel,
1526 write->dstBinding,
1527 write->dstArrayElement + j);
1528 }
1529 break;
1530 }
1531
1532 default:
1533 break;
1534 }
1535 }
1536
1537 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, pipelineBindPoint,
1538 layout, _set, set, NULL, NULL);
1539 }
1540
anv_CmdPushDescriptorSetWithTemplateKHR(VkCommandBuffer commandBuffer,VkDescriptorUpdateTemplate descriptorUpdateTemplate,VkPipelineLayout _layout,uint32_t _set,const void * pData)1541 void anv_CmdPushDescriptorSetWithTemplateKHR(
1542 VkCommandBuffer commandBuffer,
1543 VkDescriptorUpdateTemplate descriptorUpdateTemplate,
1544 VkPipelineLayout _layout,
1545 uint32_t _set,
1546 const void* pData)
1547 {
1548 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1549 ANV_FROM_HANDLE(anv_descriptor_update_template, template,
1550 descriptorUpdateTemplate);
1551 ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
1552
1553 assert(_set < MAX_PUSH_DESCRIPTORS);
1554
1555 struct anv_descriptor_set_layout *set_layout = layout->set[_set].layout;
1556
1557 struct anv_descriptor_set *set =
1558 anv_cmd_buffer_push_descriptor_set(cmd_buffer, template->bind_point,
1559 set_layout, _set);
1560 if (!set)
1561 return;
1562
1563 anv_descriptor_set_write_template(cmd_buffer->device, set,
1564 &cmd_buffer->surface_state_stream,
1565 template,
1566 pData);
1567
1568 anv_cmd_buffer_bind_descriptor_set(cmd_buffer, template->bind_point,
1569 layout, _set, set, NULL, NULL);
1570 }
1571
anv_CmdSetDeviceMask(VkCommandBuffer commandBuffer,uint32_t deviceMask)1572 void anv_CmdSetDeviceMask(
1573 VkCommandBuffer commandBuffer,
1574 uint32_t deviceMask)
1575 {
1576 /* No-op */
1577 }
1578
anv_CmdSetColorWriteEnableEXT(VkCommandBuffer commandBuffer,uint32_t attachmentCount,const VkBool32 * pColorWriteEnables)1579 void anv_CmdSetColorWriteEnableEXT(
1580 VkCommandBuffer commandBuffer,
1581 uint32_t attachmentCount,
1582 const VkBool32* pColorWriteEnables)
1583 {
1584 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1585
1586 assert(attachmentCount < MAX_RTS);
1587
1588 uint8_t color_writes = 0;
1589 for (uint32_t i = 0; i < attachmentCount; i++)
1590 color_writes |= pColorWriteEnables[i] ? (1 << i) : 0;
1591
1592 if (cmd_buffer->state.gfx.dynamic.color_writes != color_writes) {
1593 cmd_buffer->state.gfx.dynamic.color_writes = color_writes;
1594 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_STATE;
1595 }
1596 }
1597
anv_CmdSetFragmentShadingRateKHR(VkCommandBuffer commandBuffer,const VkExtent2D * pFragmentSize,const VkFragmentShadingRateCombinerOpKHR combinerOps[2])1598 void anv_CmdSetFragmentShadingRateKHR(
1599 VkCommandBuffer commandBuffer,
1600 const VkExtent2D* pFragmentSize,
1601 const VkFragmentShadingRateCombinerOpKHR combinerOps[2])
1602 {
1603 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1604
1605 cmd_buffer->state.gfx.dynamic.fragment_shading_rate = *pFragmentSize;
1606 cmd_buffer->state.gfx.dirty |= ANV_CMD_DIRTY_DYNAMIC_SHADING_RATE;
1607 }
1608
1609 static inline uint32_t
ilog2_round_up(uint32_t value)1610 ilog2_round_up(uint32_t value)
1611 {
1612 assert(value != 0);
1613 return 32 - __builtin_clz(value - 1);
1614 }
1615
anv_CmdSetRayTracingPipelineStackSizeKHR(VkCommandBuffer commandBuffer,uint32_t pipelineStackSize)1616 void anv_CmdSetRayTracingPipelineStackSizeKHR(
1617 VkCommandBuffer commandBuffer,
1618 uint32_t pipelineStackSize)
1619 {
1620 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
1621 struct anv_cmd_ray_tracing_state *rt = &cmd_buffer->state.rt;
1622 struct anv_device *device = cmd_buffer->device;
1623
1624 if (anv_batch_has_error(&cmd_buffer->batch))
1625 return;
1626
1627 uint32_t stack_ids_per_dss = 2048; /* TODO */
1628
1629 unsigned stack_size_log2 = ilog2_round_up(pipelineStackSize);
1630 if (stack_size_log2 < 10)
1631 stack_size_log2 = 10;
1632
1633 if (rt->scratch.layout.total_size == 1 << stack_size_log2)
1634 return;
1635
1636 brw_rt_compute_scratch_layout(&rt->scratch.layout, &device->info,
1637 stack_ids_per_dss, 1 << stack_size_log2);
1638
1639 unsigned bucket = stack_size_log2 - 10;
1640 assert(bucket < ARRAY_SIZE(device->rt_scratch_bos));
1641
1642 struct anv_bo *bo = p_atomic_read(&device->rt_scratch_bos[bucket]);
1643 if (bo == NULL) {
1644 struct anv_bo *new_bo;
1645 VkResult result = anv_device_alloc_bo(device, "RT scratch",
1646 rt->scratch.layout.total_size,
1647 0, /* alloc_flags */
1648 0, /* explicit_address */
1649 &new_bo);
1650 if (result != VK_SUCCESS) {
1651 rt->scratch.layout.total_size = 0;
1652 anv_batch_set_error(&cmd_buffer->batch, result);
1653 return;
1654 }
1655
1656 bo = p_atomic_cmpxchg(&device->rt_scratch_bos[bucket], NULL, new_bo);
1657 if (bo != NULL) {
1658 anv_device_release_bo(device, bo);
1659 } else {
1660 bo = new_bo;
1661 }
1662 }
1663
1664 rt->scratch.bo = bo;
1665 }
1666