1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2018-2019 Lima Project
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
12bf215546Sopenharmony_ci * all copies or substantial portions of the Software.
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bf215546Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
21bf215546Sopenharmony_ci *
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include <stdio.h>
25bf215546Sopenharmony_ci#include <stdarg.h>
26bf215546Sopenharmony_ci#include <time.h>
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include <pipe/p_defines.h>
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include "util/u_debug.h"
31bf215546Sopenharmony_ci#include "util/u_memory.h"
32bf215546Sopenharmony_ci#include "util/u_box.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "lima_util.h"
35bf215546Sopenharmony_ci#include "lima_parser.h"
36bf215546Sopenharmony_ci#include "lima_screen.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistruct lima_dump {
39bf215546Sopenharmony_ci   FILE *fp;
40bf215546Sopenharmony_ci   int id;
41bf215546Sopenharmony_ci};
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_cibool lima_get_absolute_timeout(uint64_t *timeout)
44bf215546Sopenharmony_ci{
45bf215546Sopenharmony_ci   struct timespec current;
46bf215546Sopenharmony_ci   uint64_t current_ns;
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ci   if (*timeout == PIPE_TIMEOUT_INFINITE)
49bf215546Sopenharmony_ci      return true;
50bf215546Sopenharmony_ci
51bf215546Sopenharmony_ci   if (clock_gettime(CLOCK_MONOTONIC, &current))
52bf215546Sopenharmony_ci      return false;
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   current_ns = ((uint64_t)current.tv_sec) * 1000000000ull;
55bf215546Sopenharmony_ci   current_ns += current.tv_nsec;
56bf215546Sopenharmony_ci   *timeout += current_ns;
57bf215546Sopenharmony_ci
58bf215546Sopenharmony_ci   return true;
59bf215546Sopenharmony_ci}
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_cistatic void
62bf215546Sopenharmony_cilima_dump_blob(FILE *fp, void *data, int size, bool is_float)
63bf215546Sopenharmony_ci{
64bf215546Sopenharmony_ci   fprintf(fp, "{\n");
65bf215546Sopenharmony_ci   for (int i = 0; i * 4 < size; i++) {
66bf215546Sopenharmony_ci      if (i % 4 == 0)
67bf215546Sopenharmony_ci         fprintf(fp, "\t");
68bf215546Sopenharmony_ci
69bf215546Sopenharmony_ci      if (is_float)
70bf215546Sopenharmony_ci         fprintf(fp, "%f, ", ((float *)data)[i]);
71bf215546Sopenharmony_ci      else
72bf215546Sopenharmony_ci         fprintf(fp, "0x%08x, ", ((uint32_t *)data)[i]);
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ci      if ((i % 4 == 3) || (i == size / 4 - 1)) {
75bf215546Sopenharmony_ci         fprintf(fp, "/* 0x%08x */", MAX2((i - 3) * 4, 0));
76bf215546Sopenharmony_ci         if (i) fprintf(fp, "\n");
77bf215546Sopenharmony_ci      }
78bf215546Sopenharmony_ci   }
79bf215546Sopenharmony_ci   fprintf(fp, "}\n");
80bf215546Sopenharmony_ci}
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_civoid
83bf215546Sopenharmony_cilima_dump_shader(struct lima_dump *dump, void *data, int size, bool is_frag)
84bf215546Sopenharmony_ci{
85bf215546Sopenharmony_ci   if (dump)
86bf215546Sopenharmony_ci      lima_parse_shader(dump->fp, (uint32_t *)data, size, is_frag);
87bf215546Sopenharmony_ci}
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_civoid
90bf215546Sopenharmony_cilima_dump_vs_command_stream_print(struct lima_dump *dump, void *data,
91bf215546Sopenharmony_ci                                  int size, uint32_t start)
92bf215546Sopenharmony_ci{
93bf215546Sopenharmony_ci   if (dump)
94bf215546Sopenharmony_ci      lima_parse_vs(dump->fp, (uint32_t *)data, size, start);
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_civoid
98bf215546Sopenharmony_cilima_dump_plbu_command_stream_print(struct lima_dump *dump, void *data,
99bf215546Sopenharmony_ci                                    int size, uint32_t start)
100bf215546Sopenharmony_ci{
101bf215546Sopenharmony_ci   if (dump)
102bf215546Sopenharmony_ci      lima_parse_plbu(dump->fp, (uint32_t *)data, size, start);
103bf215546Sopenharmony_ci}
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_civoid
106bf215546Sopenharmony_cilima_dump_rsw_command_stream_print(struct lima_dump *dump, void *data,
107bf215546Sopenharmony_ci                                   int size, uint32_t start)
108bf215546Sopenharmony_ci{
109bf215546Sopenharmony_ci   if (dump)
110bf215546Sopenharmony_ci      lima_parse_render_state(dump->fp, (uint32_t *)data, size, start);
111bf215546Sopenharmony_ci}
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_civoid
114bf215546Sopenharmony_cilima_dump_texture_descriptor(struct lima_dump *dump, void *data,
115bf215546Sopenharmony_ci                             int size, uint32_t start, uint32_t offset)
116bf215546Sopenharmony_ci{
117bf215546Sopenharmony_ci   if (dump)
118bf215546Sopenharmony_ci      lima_parse_texture_descriptor(dump->fp, (uint32_t *)data, size, start, offset);
119bf215546Sopenharmony_ci}
120bf215546Sopenharmony_ci
121bf215546Sopenharmony_cistruct lima_dump *
122bf215546Sopenharmony_cilima_dump_create(void)
123bf215546Sopenharmony_ci{
124bf215546Sopenharmony_ci   static int dump_id = 0;
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   if (!(lima_debug & LIMA_DEBUG_DUMP))
127bf215546Sopenharmony_ci      return NULL;
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci   struct lima_dump *ret = MALLOC_STRUCT(lima_dump);
130bf215546Sopenharmony_ci   if (!ret)
131bf215546Sopenharmony_ci      return NULL;
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   ret->id = dump_id++;
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ci   char buffer[PATH_MAX];
136bf215546Sopenharmony_ci   const char *dump_command = debug_get_option("LIMA_DUMP_FILE", "lima.dump");
137bf215546Sopenharmony_ci   snprintf(buffer, sizeof(buffer), "%s.staging.%04d", dump_command, ret->id);
138bf215546Sopenharmony_ci
139bf215546Sopenharmony_ci   ret->fp = fopen(buffer, "w");
140bf215546Sopenharmony_ci   if (!ret->fp) {
141bf215546Sopenharmony_ci      fprintf(stderr, "lima: failed to open command stream log file %s\n", buffer);
142bf215546Sopenharmony_ci      FREE(ret);
143bf215546Sopenharmony_ci      return NULL;
144bf215546Sopenharmony_ci   }
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci   return ret;
147bf215546Sopenharmony_ci}
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_civoid
150bf215546Sopenharmony_cilima_dump_free(struct lima_dump *dump)
151bf215546Sopenharmony_ci{
152bf215546Sopenharmony_ci   static int frame_count = 0;
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci   if (!dump)
155bf215546Sopenharmony_ci      return;
156bf215546Sopenharmony_ci
157bf215546Sopenharmony_ci   fclose(dump->fp);
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   /* we only know the frame count when flush, not on dump create, so first dump to a
160bf215546Sopenharmony_ci    * stage file, then move to the final file with frame count as surfix when flush.
161bf215546Sopenharmony_ci    */
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci   char stage_name[PATH_MAX];
164bf215546Sopenharmony_ci   char final_name[PATH_MAX];
165bf215546Sopenharmony_ci   const char *dump_command = debug_get_option("LIMA_DUMP_FILE", "lima.dump");
166bf215546Sopenharmony_ci   snprintf(stage_name, sizeof(stage_name), "%s.staging.%04d", dump_command, dump->id);
167bf215546Sopenharmony_ci   snprintf(final_name, sizeof(final_name), "%s.%04d", dump_command, frame_count++);
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci   if (rename(stage_name, final_name))
170bf215546Sopenharmony_ci      fprintf(stderr, "lima: failed to rename log %s to %s\n", stage_name, final_name);
171bf215546Sopenharmony_ci
172bf215546Sopenharmony_ci   FREE(dump);
173bf215546Sopenharmony_ci}
174bf215546Sopenharmony_ci
175bf215546Sopenharmony_civoid
176bf215546Sopenharmony_ci_lima_dump_command_stream_print(struct lima_dump *dump, void *data,
177bf215546Sopenharmony_ci                                int size, bool is_float, const char *fmt, ...)
178bf215546Sopenharmony_ci{
179bf215546Sopenharmony_ci   va_list ap;
180bf215546Sopenharmony_ci   va_start(ap, fmt);
181bf215546Sopenharmony_ci   vfprintf(dump->fp, fmt, ap);
182bf215546Sopenharmony_ci   va_end(ap);
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ci   lima_dump_blob(dump->fp, data, size, is_float);
185bf215546Sopenharmony_ci}
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_civoid
188bf215546Sopenharmony_cilima_damage_rect_union(struct pipe_scissor_state *rect,
189bf215546Sopenharmony_ci                       unsigned minx, unsigned maxx,
190bf215546Sopenharmony_ci                       unsigned miny, unsigned maxy)
191bf215546Sopenharmony_ci{
192bf215546Sopenharmony_ci   rect->minx = MIN2(rect->minx, minx);
193bf215546Sopenharmony_ci   rect->miny = MIN2(rect->miny, miny);
194bf215546Sopenharmony_ci   rect->maxx = MAX2(rect->maxx, maxx);
195bf215546Sopenharmony_ci   rect->maxy = MAX2(rect->maxy, maxy);
196bf215546Sopenharmony_ci}
197