xref: /aosp_15_r20/external/mesa3d/src/amd/vulkan/radv_printf.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © 2024 Valve Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * SPDX-License-Identifier: MIT
5*61046927SAndroid Build Coastguard Worker  */
6*61046927SAndroid Build Coastguard Worker 
7*61046927SAndroid Build Coastguard Worker #include "radv_printf.h"
8*61046927SAndroid Build Coastguard Worker #include "radv_device.h"
9*61046927SAndroid Build Coastguard Worker #include "radv_physical_device.h"
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #include "util/hash_table.h"
12*61046927SAndroid Build Coastguard Worker #include "util/strndup.h"
13*61046927SAndroid Build Coastguard Worker #include "util/u_printf.h"
14*61046927SAndroid Build Coastguard Worker 
15*61046927SAndroid Build Coastguard Worker #include "nir.h"
16*61046927SAndroid Build Coastguard Worker #include "nir_builder.h"
17*61046927SAndroid Build Coastguard Worker 
18*61046927SAndroid Build Coastguard Worker static struct hash_table *device_ht = NULL;
19*61046927SAndroid Build Coastguard Worker 
20*61046927SAndroid Build Coastguard Worker VkResult
radv_printf_data_init(struct radv_device * device)21*61046927SAndroid Build Coastguard Worker radv_printf_data_init(struct radv_device *device)
22*61046927SAndroid Build Coastguard Worker {
23*61046927SAndroid Build Coastguard Worker    const struct radv_physical_device *pdev = radv_device_physical(device);
24*61046927SAndroid Build Coastguard Worker 
25*61046927SAndroid Build Coastguard Worker    util_dynarray_init(&device->printf.formats, NULL);
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker    device->printf.buffer_size = debug_get_num_option("RADV_PRINTF_BUFFER_SIZE", 0);
28*61046927SAndroid Build Coastguard Worker    if (device->printf.buffer_size < sizeof(struct radv_printf_buffer_header))
29*61046927SAndroid Build Coastguard Worker       return VK_SUCCESS;
30*61046927SAndroid Build Coastguard Worker 
31*61046927SAndroid Build Coastguard Worker    VkBufferCreateInfo buffer_create_info = {
32*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
33*61046927SAndroid Build Coastguard Worker       .pNext =
34*61046927SAndroid Build Coastguard Worker          &(VkBufferUsageFlags2CreateInfoKHR){
35*61046927SAndroid Build Coastguard Worker             .sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR,
36*61046927SAndroid Build Coastguard Worker             .usage = VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT_KHR | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT_KHR,
37*61046927SAndroid Build Coastguard Worker          },
38*61046927SAndroid Build Coastguard Worker       .size = device->printf.buffer_size,
39*61046927SAndroid Build Coastguard Worker    };
40*61046927SAndroid Build Coastguard Worker 
41*61046927SAndroid Build Coastguard Worker    VkDevice _device = radv_device_to_handle(device);
42*61046927SAndroid Build Coastguard Worker    VkResult result = device->vk.dispatch_table.CreateBuffer(_device, &buffer_create_info, NULL, &device->printf.buffer);
43*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
44*61046927SAndroid Build Coastguard Worker       return result;
45*61046927SAndroid Build Coastguard Worker 
46*61046927SAndroid Build Coastguard Worker    VkMemoryRequirements requirements;
47*61046927SAndroid Build Coastguard Worker    device->vk.dispatch_table.GetBufferMemoryRequirements(_device, device->printf.buffer, &requirements);
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker    VkMemoryAllocateInfo alloc_info = {
50*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
51*61046927SAndroid Build Coastguard Worker       .allocationSize = requirements.size,
52*61046927SAndroid Build Coastguard Worker       .memoryTypeIndex =
53*61046927SAndroid Build Coastguard Worker          radv_find_memory_index(pdev, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
54*61046927SAndroid Build Coastguard Worker                                          VK_MEMORY_PROPERTY_HOST_COHERENT_BIT),
55*61046927SAndroid Build Coastguard Worker    };
56*61046927SAndroid Build Coastguard Worker 
57*61046927SAndroid Build Coastguard Worker    result = device->vk.dispatch_table.AllocateMemory(_device, &alloc_info, NULL, &device->printf.memory);
58*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
59*61046927SAndroid Build Coastguard Worker       return result;
60*61046927SAndroid Build Coastguard Worker 
61*61046927SAndroid Build Coastguard Worker    result = device->vk.dispatch_table.MapMemory(_device, device->printf.memory, 0, VK_WHOLE_SIZE, 0,
62*61046927SAndroid Build Coastguard Worker                                                 (void **)&device->printf.data);
63*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
64*61046927SAndroid Build Coastguard Worker       return result;
65*61046927SAndroid Build Coastguard Worker 
66*61046927SAndroid Build Coastguard Worker    result = device->vk.dispatch_table.BindBufferMemory(_device, device->printf.buffer, device->printf.memory, 0);
67*61046927SAndroid Build Coastguard Worker    if (result != VK_SUCCESS)
68*61046927SAndroid Build Coastguard Worker       return result;
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    struct radv_printf_buffer_header *header = device->printf.data;
71*61046927SAndroid Build Coastguard Worker    header->offset = sizeof(struct radv_printf_buffer_header);
72*61046927SAndroid Build Coastguard Worker    header->size = device->printf.buffer_size;
73*61046927SAndroid Build Coastguard Worker 
74*61046927SAndroid Build Coastguard Worker    VkBufferDeviceAddressInfo addr_info = {
75*61046927SAndroid Build Coastguard Worker       .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO,
76*61046927SAndroid Build Coastguard Worker       .buffer = device->printf.buffer,
77*61046927SAndroid Build Coastguard Worker    };
78*61046927SAndroid Build Coastguard Worker    device->printf.buffer_addr = device->vk.dispatch_table.GetBufferDeviceAddress(_device, &addr_info);
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    return VK_SUCCESS;
81*61046927SAndroid Build Coastguard Worker }
82*61046927SAndroid Build Coastguard Worker 
83*61046927SAndroid Build Coastguard Worker void
radv_printf_data_finish(struct radv_device * device)84*61046927SAndroid Build Coastguard Worker radv_printf_data_finish(struct radv_device *device)
85*61046927SAndroid Build Coastguard Worker {
86*61046927SAndroid Build Coastguard Worker    VkDevice _device = radv_device_to_handle(device);
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker    device->vk.dispatch_table.DestroyBuffer(_device, device->printf.buffer, NULL);
89*61046927SAndroid Build Coastguard Worker    if (device->printf.memory)
90*61046927SAndroid Build Coastguard Worker       device->vk.dispatch_table.UnmapMemory(_device, device->printf.memory);
91*61046927SAndroid Build Coastguard Worker    device->vk.dispatch_table.FreeMemory(_device, device->printf.memory, NULL);
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker    util_dynarray_foreach (&device->printf.formats, struct radv_printf_format, format)
94*61046927SAndroid Build Coastguard Worker       free(format->string);
95*61046927SAndroid Build Coastguard Worker 
96*61046927SAndroid Build Coastguard Worker    util_dynarray_fini(&device->printf.formats);
97*61046927SAndroid Build Coastguard Worker }
98*61046927SAndroid Build Coastguard Worker 
99*61046927SAndroid Build Coastguard Worker void
radv_build_printf(nir_builder * b,nir_def * cond,const char * format_string,...)100*61046927SAndroid Build Coastguard Worker radv_build_printf(nir_builder *b, nir_def *cond, const char *format_string, ...)
101*61046927SAndroid Build Coastguard Worker {
102*61046927SAndroid Build Coastguard Worker    if (!device_ht)
103*61046927SAndroid Build Coastguard Worker       return;
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    struct radv_device *device = _mesa_hash_table_search(device_ht, b->shader)->data;
106*61046927SAndroid Build Coastguard Worker    if (!device->printf.buffer_addr)
107*61046927SAndroid Build Coastguard Worker       return;
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    struct radv_printf_format format = {0};
110*61046927SAndroid Build Coastguard Worker    format.string = strdup(format_string);
111*61046927SAndroid Build Coastguard Worker    if (!format.string)
112*61046927SAndroid Build Coastguard Worker       return;
113*61046927SAndroid Build Coastguard Worker 
114*61046927SAndroid Build Coastguard Worker    uint32_t format_index = util_dynarray_num_elements(&device->printf.formats, struct radv_printf_format);
115*61046927SAndroid Build Coastguard Worker 
116*61046927SAndroid Build Coastguard Worker    if (cond)
117*61046927SAndroid Build Coastguard Worker       nir_push_if(b, cond);
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    nir_def *size = nir_imm_int(b, 4);
120*61046927SAndroid Build Coastguard Worker 
121*61046927SAndroid Build Coastguard Worker    va_list arg_list;
122*61046927SAndroid Build Coastguard Worker    va_start(arg_list, format_string);
123*61046927SAndroid Build Coastguard Worker 
124*61046927SAndroid Build Coastguard Worker    uint32_t num_args = 0;
125*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < strlen(format_string); i++)
126*61046927SAndroid Build Coastguard Worker       if (format_string[i] == '%')
127*61046927SAndroid Build Coastguard Worker          num_args++;
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker    nir_def **args = malloc(num_args * sizeof(nir_def *));
130*61046927SAndroid Build Coastguard Worker    nir_def **strides = malloc(num_args * sizeof(nir_def *));
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker    nir_def *ballot = nir_ballot(b, 1, 64, nir_imm_true(b));
133*61046927SAndroid Build Coastguard Worker    nir_def *active_invocation_count = nir_bit_count(b, ballot);
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    for (uint32_t i = 0; i < num_args; i++) {
136*61046927SAndroid Build Coastguard Worker       nir_def *arg = va_arg(arg_list, nir_def *);
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker       if (arg->bit_size == 1)
139*61046927SAndroid Build Coastguard Worker          arg = nir_b2i32(b, arg);
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker       args[i] = arg;
142*61046927SAndroid Build Coastguard Worker 
143*61046927SAndroid Build Coastguard Worker       uint32_t arg_size = arg->bit_size == 1 ? 32 : arg->bit_size / 8;
144*61046927SAndroid Build Coastguard Worker       format.element_sizes[i] = arg_size;
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker       nir_update_instr_divergence(b->shader, arg->parent_instr);
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker       if (arg->divergent) {
149*61046927SAndroid Build Coastguard Worker          strides[i] = nir_imul_imm(b, active_invocation_count, arg_size);
150*61046927SAndroid Build Coastguard Worker          format.divergence_mask |= BITFIELD_BIT(i);
151*61046927SAndroid Build Coastguard Worker       } else {
152*61046927SAndroid Build Coastguard Worker          strides[i] = nir_imm_int(b, arg_size);
153*61046927SAndroid Build Coastguard Worker       }
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker       size = nir_iadd(b, size, strides[i]);
156*61046927SAndroid Build Coastguard Worker    }
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    va_end(arg_list);
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker    nir_def *offset;
161*61046927SAndroid Build Coastguard Worker    nir_def *undef;
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    nir_push_if(b, nir_elect(b, 1));
164*61046927SAndroid Build Coastguard Worker    {
165*61046927SAndroid Build Coastguard Worker       offset = nir_global_atomic(
166*61046927SAndroid Build Coastguard Worker          b, 32, nir_imm_int64(b, device->printf.buffer_addr + offsetof(struct radv_printf_buffer_header, offset)), size,
167*61046927SAndroid Build Coastguard Worker          .atomic_op = nir_atomic_op_iadd);
168*61046927SAndroid Build Coastguard Worker    }
169*61046927SAndroid Build Coastguard Worker    nir_push_else(b, NULL);
170*61046927SAndroid Build Coastguard Worker    {
171*61046927SAndroid Build Coastguard Worker       undef = nir_undef(b, 1, 32);
172*61046927SAndroid Build Coastguard Worker    }
173*61046927SAndroid Build Coastguard Worker    nir_pop_if(b, NULL);
174*61046927SAndroid Build Coastguard Worker 
175*61046927SAndroid Build Coastguard Worker    offset = nir_read_first_invocation(b, nir_if_phi(b, offset, undef));
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker    nir_def *buffer_size = nir_load_global(
178*61046927SAndroid Build Coastguard Worker       b, nir_imm_int64(b, device->printf.buffer_addr + offsetof(struct radv_printf_buffer_header, size)), 4, 1, 32);
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    nir_push_if(b, nir_ige(b, buffer_size, nir_iadd(b, offset, size)));
181*61046927SAndroid Build Coastguard Worker    {
182*61046927SAndroid Build Coastguard Worker       nir_def *addr = nir_iadd_imm(b, nir_u2u64(b, offset), device->printf.buffer_addr);
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker       /* header */
185*61046927SAndroid Build Coastguard Worker       nir_store_global(b, addr, 4, nir_ior_imm(b, active_invocation_count, format_index << 16), 1);
186*61046927SAndroid Build Coastguard Worker       addr = nir_iadd_imm(b, addr, 4);
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < num_args; i++) {
189*61046927SAndroid Build Coastguard Worker          nir_def *arg = args[i];
190*61046927SAndroid Build Coastguard Worker 
191*61046927SAndroid Build Coastguard Worker          if (arg->divergent) {
192*61046927SAndroid Build Coastguard Worker             nir_def *invocation_index = nir_mbcnt_amd(b, ballot, nir_imm_int(b, 0));
193*61046927SAndroid Build Coastguard Worker             nir_store_global(
194*61046927SAndroid Build Coastguard Worker                b, nir_iadd(b, addr, nir_u2u64(b, nir_imul_imm(b, invocation_index, format.element_sizes[i]))), 4, arg,
195*61046927SAndroid Build Coastguard Worker                1);
196*61046927SAndroid Build Coastguard Worker          } else {
197*61046927SAndroid Build Coastguard Worker             nir_store_global(b, addr, 4, arg, 1);
198*61046927SAndroid Build Coastguard Worker          }
199*61046927SAndroid Build Coastguard Worker 
200*61046927SAndroid Build Coastguard Worker          addr = nir_iadd(b, addr, nir_u2u64(b, strides[i]));
201*61046927SAndroid Build Coastguard Worker       }
202*61046927SAndroid Build Coastguard Worker    }
203*61046927SAndroid Build Coastguard Worker    nir_pop_if(b, NULL);
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker    if (cond)
206*61046927SAndroid Build Coastguard Worker       nir_pop_if(b, NULL);
207*61046927SAndroid Build Coastguard Worker 
208*61046927SAndroid Build Coastguard Worker    free(args);
209*61046927SAndroid Build Coastguard Worker    free(strides);
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker    util_dynarray_append(&device->printf.formats, struct radv_printf_format, format);
212*61046927SAndroid Build Coastguard Worker }
213*61046927SAndroid Build Coastguard Worker 
214*61046927SAndroid Build Coastguard Worker void
radv_dump_printf_data(struct radv_device * device,FILE * out)215*61046927SAndroid Build Coastguard Worker radv_dump_printf_data(struct radv_device *device, FILE *out)
216*61046927SAndroid Build Coastguard Worker {
217*61046927SAndroid Build Coastguard Worker    if (!device->printf.data)
218*61046927SAndroid Build Coastguard Worker       return;
219*61046927SAndroid Build Coastguard Worker 
220*61046927SAndroid Build Coastguard Worker    device->vk.dispatch_table.DeviceWaitIdle(radv_device_to_handle(device));
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    struct radv_printf_buffer_header *header = device->printf.data;
223*61046927SAndroid Build Coastguard Worker    uint8_t *data = device->printf.data;
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker    for (uint32_t offset = sizeof(struct radv_printf_buffer_header); offset < header->offset;) {
226*61046927SAndroid Build Coastguard Worker       uint32_t printf_header = *(uint32_t *)&data[offset];
227*61046927SAndroid Build Coastguard Worker       offset += sizeof(uint32_t);
228*61046927SAndroid Build Coastguard Worker 
229*61046927SAndroid Build Coastguard Worker       uint32_t format_index = printf_header >> 16;
230*61046927SAndroid Build Coastguard Worker       struct radv_printf_format *printf_format =
231*61046927SAndroid Build Coastguard Worker          util_dynarray_element(&device->printf.formats, struct radv_printf_format, format_index);
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker       uint32_t invocation_count = printf_header & 0xFFFF;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker       uint32_t num_args = 0;
236*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i < strlen(printf_format->string); i++)
237*61046927SAndroid Build Coastguard Worker          if (printf_format->string[i] == '%')
238*61046927SAndroid Build Coastguard Worker             num_args++;
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker       char *format = printf_format->string;
241*61046927SAndroid Build Coastguard Worker 
242*61046927SAndroid Build Coastguard Worker       for (uint32_t i = 0; i <= num_args; i++) {
243*61046927SAndroid Build Coastguard Worker          size_t spec_pos = util_printf_next_spec_pos(format, 0);
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker          if (spec_pos == -1) {
246*61046927SAndroid Build Coastguard Worker             fprintf(out, "%s", format);
247*61046927SAndroid Build Coastguard Worker             continue;
248*61046927SAndroid Build Coastguard Worker          }
249*61046927SAndroid Build Coastguard Worker 
250*61046927SAndroid Build Coastguard Worker          const char *token = util_printf_prev_tok(&format[spec_pos]);
251*61046927SAndroid Build Coastguard Worker          char *next_format = &format[spec_pos + 1];
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker          /* print the part before the format token */
254*61046927SAndroid Build Coastguard Worker          if (token != format)
255*61046927SAndroid Build Coastguard Worker             fwrite(format, token - format, 1, out);
256*61046927SAndroid Build Coastguard Worker 
257*61046927SAndroid Build Coastguard Worker          char *print_str = strndup(token, next_format - token);
258*61046927SAndroid Build Coastguard Worker          /* rebase spec_pos so we can use it with print_str */
259*61046927SAndroid Build Coastguard Worker          spec_pos += format - token;
260*61046927SAndroid Build Coastguard Worker 
261*61046927SAndroid Build Coastguard Worker          size_t element_size = printf_format->element_sizes[i];
262*61046927SAndroid Build Coastguard Worker          bool is_float = strpbrk(print_str, "fFeEgGaA") != NULL;
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker          uint32_t lane_count = (printf_format->divergence_mask & BITFIELD_BIT(i)) ? invocation_count : 1;
265*61046927SAndroid Build Coastguard Worker          for (uint32_t lane = 0; lane < lane_count; lane++) {
266*61046927SAndroid Build Coastguard Worker             switch (element_size) {
267*61046927SAndroid Build Coastguard Worker             case 1: {
268*61046927SAndroid Build Coastguard Worker                uint8_t v;
269*61046927SAndroid Build Coastguard Worker                memcpy(&v, &data[offset], element_size);
270*61046927SAndroid Build Coastguard Worker                fprintf(out, print_str, v);
271*61046927SAndroid Build Coastguard Worker                break;
272*61046927SAndroid Build Coastguard Worker             }
273*61046927SAndroid Build Coastguard Worker             case 2: {
274*61046927SAndroid Build Coastguard Worker                uint16_t v;
275*61046927SAndroid Build Coastguard Worker                memcpy(&v, &data[offset], element_size);
276*61046927SAndroid Build Coastguard Worker                fprintf(out, print_str, v);
277*61046927SAndroid Build Coastguard Worker                break;
278*61046927SAndroid Build Coastguard Worker             }
279*61046927SAndroid Build Coastguard Worker             case 4: {
280*61046927SAndroid Build Coastguard Worker                if (is_float) {
281*61046927SAndroid Build Coastguard Worker                   float v;
282*61046927SAndroid Build Coastguard Worker                   memcpy(&v, &data[offset], element_size);
283*61046927SAndroid Build Coastguard Worker                   fprintf(out, print_str, v);
284*61046927SAndroid Build Coastguard Worker                } else {
285*61046927SAndroid Build Coastguard Worker                   uint32_t v;
286*61046927SAndroid Build Coastguard Worker                   memcpy(&v, &data[offset], element_size);
287*61046927SAndroid Build Coastguard Worker                   fprintf(out, print_str, v);
288*61046927SAndroid Build Coastguard Worker                }
289*61046927SAndroid Build Coastguard Worker                break;
290*61046927SAndroid Build Coastguard Worker             }
291*61046927SAndroid Build Coastguard Worker             case 8: {
292*61046927SAndroid Build Coastguard Worker                if (is_float) {
293*61046927SAndroid Build Coastguard Worker                   double v;
294*61046927SAndroid Build Coastguard Worker                   memcpy(&v, &data[offset], element_size);
295*61046927SAndroid Build Coastguard Worker                   fprintf(out, print_str, v);
296*61046927SAndroid Build Coastguard Worker                } else {
297*61046927SAndroid Build Coastguard Worker                   uint64_t v;
298*61046927SAndroid Build Coastguard Worker                   memcpy(&v, &data[offset], element_size);
299*61046927SAndroid Build Coastguard Worker                   fprintf(out, print_str, v);
300*61046927SAndroid Build Coastguard Worker                }
301*61046927SAndroid Build Coastguard Worker                break;
302*61046927SAndroid Build Coastguard Worker             }
303*61046927SAndroid Build Coastguard Worker             default:
304*61046927SAndroid Build Coastguard Worker                unreachable("Unsupported data type");
305*61046927SAndroid Build Coastguard Worker             }
306*61046927SAndroid Build Coastguard Worker 
307*61046927SAndroid Build Coastguard Worker             if (lane != lane_count - 1)
308*61046927SAndroid Build Coastguard Worker                fprintf(out, " ");
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker             offset += element_size;
311*61046927SAndroid Build Coastguard Worker          }
312*61046927SAndroid Build Coastguard Worker 
313*61046927SAndroid Build Coastguard Worker          /* rebase format */
314*61046927SAndroid Build Coastguard Worker          format = next_format;
315*61046927SAndroid Build Coastguard Worker          free(print_str);
316*61046927SAndroid Build Coastguard Worker       }
317*61046927SAndroid Build Coastguard Worker    }
318*61046927SAndroid Build Coastguard Worker 
319*61046927SAndroid Build Coastguard Worker    fflush(out);
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker    header->offset = sizeof(struct radv_printf_buffer_header);
322*61046927SAndroid Build Coastguard Worker }
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker void
radv_device_associate_nir(struct radv_device * device,nir_shader * nir)325*61046927SAndroid Build Coastguard Worker radv_device_associate_nir(struct radv_device *device, nir_shader *nir)
326*61046927SAndroid Build Coastguard Worker {
327*61046927SAndroid Build Coastguard Worker    if (!device->printf.buffer_addr)
328*61046927SAndroid Build Coastguard Worker       return;
329*61046927SAndroid Build Coastguard Worker 
330*61046927SAndroid Build Coastguard Worker    if (!device_ht)
331*61046927SAndroid Build Coastguard Worker       device_ht = _mesa_pointer_hash_table_create(NULL);
332*61046927SAndroid Build Coastguard Worker 
333*61046927SAndroid Build Coastguard Worker    _mesa_hash_table_insert(device_ht, nir, device);
334*61046927SAndroid Build Coastguard Worker }
335