1/* Copyright © 2023 Intel Corporation 2 * SPDX-License-Identifier: MIT 3 */ 4 5#include "libintel_shaders.h" 6#include "dev/intel_wa.h" 7 8static void end_generated_draws(global void *dst_ptr, 9 uint32_t item_idx, 10 uint32_t draw_id, uint32_t draw_count, 11 uint32_t ring_count, uint32_t max_draw_count, 12 uint32_t flags, uint32_t _3dprim_size_B, 13 uint64_t gen_addr, uint64_t end_addr) 14{ 15 bool indirect_count = (flags & ANV_GENERATED_FLAG_COUNT) != 0; 16 bool ring_mode = (flags & ANV_GENERATED_FLAG_RING_MODE) != 0; 17 /* We can have an indirect draw count = 0. */ 18 uint32_t last_draw_id = draw_count == 0 ? 0 : (min(draw_count, max_draw_count) - 1); 19 global void *jump_dst = draw_count == 0 ? dst_ptr : (dst_ptr + _3dprim_size_B); 20 21 if (ring_mode) { 22 if (draw_id == last_draw_id) { 23 /* Exit the ring buffer to the next user commands */ 24 genX(write_MI_BATCH_BUFFER_START)(jump_dst, end_addr); 25 } else if (item_idx == (ring_count - 1)) { 26 /* Jump back to the generation shader to generate mode draws */ 27 genX(write_MI_BATCH_BUFFER_START)(jump_dst, gen_addr); 28 } 29 } else { 30 if (draw_id == last_draw_id && draw_count < max_draw_count) { 31 /* Skip forward to the end of the generated draws */ 32 genX(write_MI_BATCH_BUFFER_START)(jump_dst, end_addr); 33 } 34 } 35} 36 37void 38genX(libanv_write_draw)(global void *dst_base, 39 global void *wa_insts_ptr, 40 global void *indirect_base, 41 global void *draw_id_base, 42 uint32_t indirect_stride, 43 global uint32_t *_draw_count, 44 uint32_t draw_base, 45 uint32_t instance_multiplier, 46 uint32_t max_draw_count, 47 uint32_t flags, 48 uint32_t mocs, 49 uint32_t _3dprim_size_B, 50 uint32_t ring_count, 51 uint64_t gen_addr, 52 uint64_t end_addr, 53 uint32_t item_idx) 54{ 55 uint32_t draw_id = draw_base + item_idx; 56 uint32_t draw_count = *_draw_count; 57 global void *dst_ptr = dst_base + item_idx * _3dprim_size_B; 58 global void *indirect_ptr = indirect_base + draw_id * indirect_stride; 59 global void *draw_id_ptr = draw_id_base + item_idx * 4; 60 61 if (draw_id < min(draw_count, max_draw_count)) { 62 bool is_indexed = (flags & ANV_GENERATED_FLAG_INDEXED) != 0; 63 bool is_predicated = (flags & ANV_GENERATED_FLAG_PREDICATED) != 0; 64 bool uses_tbimr = (flags & ANV_GENERATED_FLAG_TBIMR) != 0; 65 bool uses_base = (flags & ANV_GENERATED_FLAG_BASE) != 0; 66 bool uses_drawid = (flags & ANV_GENERATED_FLAG_DRAWID) != 0; 67 uint32_t inst_offset_B = 0; 68 69#if INTEL_WA_16011107343_GFX_VER 70 if (flags & ANV_GENERATED_FLAG_WA_16011107343) { 71 genX(copy_data)(dst_ptr + inst_offset_B, 72 wa_insts_ptr + inst_offset_B, 73 GENX(3DSTATE_HS_length) * 4); 74 inst_offset_B += GENX(3DSTATE_HS_length) * 4; 75 } 76#endif 77 78#if INTEL_WA_22018402687_GFX_VER 79 if (flags & ANV_GENERATED_FLAG_WA_22018402687) { 80 genX(copy_data)(dst_ptr + inst_offset_B, 81 wa_insts_ptr + inst_offset_B, 82 GENX(3DSTATE_DS_length) * 4); 83 inst_offset_B += GENX(3DSTATE_DS_length) * 4; 84 } 85#endif 86 87 genX(write_draw)(dst_ptr + inst_offset_B, 88 indirect_ptr, draw_id_ptr, 89 draw_id, instance_multiplier, 90 is_indexed, is_predicated, 91 uses_tbimr, uses_base, uses_drawid, 92 mocs); 93 } 94 95 end_generated_draws(dst_ptr, item_idx, draw_id, draw_count, 96 ring_count, max_draw_count, 97 flags, _3dprim_size_B, 98 gen_addr, end_addr); 99} 100