We will use this to send updates for an individual wave.

Signed-off-by: Nicolai Hähnle <nicolai.haeh...@amd.com>
---
 src/app/gui/commands.c | 299 +++++++++++++++++++++--------------------
 1 file changed, 153 insertions(+), 146 deletions(-)

diff --git a/src/app/gui/commands.c b/src/app/gui/commands.c
index fbb11fa..38ae44d 100644
--- a/src/app/gui/commands.c
+++ b/src/app/gui/commands.c
@@ -1537,175 +1537,182 @@ void init_asics() {
                        }
 
                        index++;
                } else {
                        fclose(opt.test_log_fd);
                        free(ip_discovery_dump);
                }
        }
 }
 
-static void wave_to_json(struct umr_asic *asic, int ring_is_halted, int 
include_shaders, JSON_Object *out) {
-       // TODO: This is using the deprecated API ...
-       struct umr_pm4_stream *stream = NULL; // umr_pm4_decode_ring(asic, 
asic->options.ring_name, 1, -1, -1);
-
-       struct umr_wave_data *wd = umr_scan_wave_data(asic);
-
-       JSON_Value *shaders = json_value_init_object();
+static JSON_Value *wave_to_json(struct umr_asic *asic, struct umr_wave_data 
*wd, int include_shaders,
+                               struct umr_pm4_stream *stream, JSON_Value 
*shaders) {
+       uint64_t pgm_addr = (((uint64_t)wd->ws.pc_hi << 32) | wd->ws.pc_lo);
+       unsigned vmid;
+
+       JSON_Value *wave = json_value_init_object();
+       json_object_set_number(json_object(wave), "se", wd->se);
+       json_object_set_number(json_object(wave), "sh", wd->sh);
+       json_object_set_number(json_object(wave), asic->family < FAMILY_NV ? 
"cu" : "wgp", wd->cu);
+       json_object_set_number(json_object(wave), "simd_id", 
wd->ws.hw_id1.simd_id);
+       json_object_set_number(json_object(wave), "wave_id", 
wd->ws.hw_id1.wave_id);
+       json_object_set_number(json_object(wave), "PC", pgm_addr);
+       json_object_set_number(json_object(wave), "wave_inst_dw0", 
wd->ws.wave_inst_dw0);
+       if (asic->family < FAMILY_NV)
+               json_object_set_number(json_object(wave), "wave_inst_dw1", 
wd->ws.wave_inst_dw1);
+
+       JSON_Value *status = json_value_init_object();
+       json_object_set_number(json_object(status), "value", 
wd->ws.wave_status.value);
+       json_object_set_number(json_object(status), "scc", 
wd->ws.wave_status.scc);
+       json_object_set_number(json_object(status), "execz", 
wd->ws.wave_status.execz);
+       json_object_set_number(json_object(status), "vccz", 
wd->ws.wave_status.vccz);
+       json_object_set_number(json_object(status), "in_tg", 
wd->ws.wave_status.in_tg);
+       json_object_set_number(json_object(status), "halt", 
wd->ws.wave_status.halt);
+       json_object_set_number(json_object(status), "valid", 
wd->ws.wave_status.valid);
+       json_object_set_number(json_object(status), "spi_prio", 
wd->ws.wave_status.spi_prio);
+       json_object_set_number(json_object(status), "wave_prio", 
wd->ws.wave_status.wave_prio);
+       json_object_set_number(json_object(status), "priv", 
wd->ws.wave_status.priv);
+       json_object_set_number(json_object(status), "trap_en", 
wd->ws.wave_status.trap_en);
+       json_object_set_number(json_object(status), "trap", 
wd->ws.wave_status.trap);
+       json_object_set_number(json_object(status), "ttrace_en", 
wd->ws.wave_status.ttrace_en);
+       json_object_set_number(json_object(status), "export_rdy", 
wd->ws.wave_status.export_rdy);
+       json_object_set_number(json_object(status), "in_barrier", 
wd->ws.wave_status.in_barrier);
+       json_object_set_number(json_object(status), "ecc_err", 
wd->ws.wave_status.ecc_err);
+       json_object_set_number(json_object(status), "skip_export", 
wd->ws.wave_status.skip_export);
+       json_object_set_number(json_object(status), "perf_en", 
wd->ws.wave_status.perf_en);
+       json_object_set_number(json_object(status), "cond_dbg_user", 
wd->ws.wave_status.cond_dbg_user);
+       json_object_set_number(json_object(status), "cond_dbg_sys", 
wd->ws.wave_status.cond_dbg_sys);
+       json_object_set_number(json_object(status), "allow_replay", 
wd->ws.wave_status.allow_replay);
+       json_object_set_number(json_object(status), "fatal_halt", asic->family 
>= FAMILY_AI && wd->ws.wave_status.fatal_halt);
+       json_object_set_number(json_object(status), "must_export", 
wd->ws.wave_status.must_export);
+
+       json_object_set_value(json_object(wave), "status", status);
+
+       JSON_Value *hw_id = json_value_init_object();
+       if (asic->family < FAMILY_NV) {
+               json_object_set_number(json_object(hw_id), "value", 
wd->ws.hw_id.value);
+               json_object_set_number(json_object(hw_id), "wave_id", 
wd->ws.hw_id.wave_id);
+               json_object_set_number(json_object(hw_id), "simd_id", 
wd->ws.hw_id.simd_id);
+               json_object_set_number(json_object(hw_id), "pipe_id", 
wd->ws.hw_id.pipe_id);
+               json_object_set_number(json_object(hw_id), "cu_id", 
wd->ws.hw_id.cu_id);
+               json_object_set_number(json_object(hw_id), "sh_id", 
wd->ws.hw_id.sh_id);
+               json_object_set_number(json_object(hw_id), "tg_id", 
wd->ws.hw_id.tg_id);
+               json_object_set_number(json_object(hw_id), "state_id", 
wd->ws.hw_id.state_id);
+               json_object_set_number(json_object(hw_id), "vm_id", 
wd->ws.hw_id.vm_id);
+               vmid = wd->ws.hw_id.vm_id;
+       } else {
+               json_object_set_number(json_object(hw_id), "value", 
wd->ws.hw_id1.value);
+               json_object_set_number(json_object(hw_id), "wave_id", 
wd->ws.hw_id1.wave_id);
+               json_object_set_number(json_object(hw_id), "simd_id", 
wd->ws.hw_id1.simd_id);
+               json_object_set_number(json_object(hw_id), "wgp_id", 
wd->ws.hw_id1.wgp_id);
+               json_object_set_number(json_object(hw_id), "se_id", 
wd->ws.hw_id1.se_id);
+               json_object_set_number(json_object(hw_id), "sa_id", 
wd->ws.hw_id1.sa_id);
+               json_object_set_number(json_object(hw_id), "queue_id", 
wd->ws.hw_id2.queue_id);
+               json_object_set_number(json_object(hw_id), "pipe_id", 
wd->ws.hw_id2.pipe_id);
+               json_object_set_number(json_object(hw_id), "me_id", 
wd->ws.hw_id2.me_id);
+               json_object_set_number(json_object(hw_id), "state_id", 
wd->ws.hw_id2.state_id);
+               json_object_set_number(json_object(hw_id), "wg_id", 
wd->ws.hw_id2.wg_id);
+               json_object_set_number(json_object(hw_id), "compat_level", 
wd->ws.hw_id2.compat_level);
+               json_object_set_number(json_object(hw_id), "vm_id", 
wd->ws.hw_id2.vm_id);
+               vmid = wd->ws.hw_id2.vm_id;
+       }
+       json_object_set_value(json_object(wave), "hw_id", hw_id);
 
-       JSON_Value *waves = json_value_init_array();
-       while (wd) {
-               uint64_t pgm_addr = (((uint64_t)wd->ws.pc_hi << 32) | 
wd->ws.pc_lo);
-               unsigned vmid;
-
-               JSON_Value *wave = json_value_init_object();
-               json_object_set_number(json_object(wave), "se", wd->se);
-               json_object_set_number(json_object(wave), "sh", wd->sh);
-               json_object_set_number(json_object(wave), asic->family < 
FAMILY_NV ? "cu" : "wgp", wd->cu);
-               json_object_set_number(json_object(wave), "simd_id", 
wd->ws.hw_id1.simd_id);
-               json_object_set_number(json_object(wave), "wave_id", 
wd->ws.hw_id1.wave_id);
-               json_object_set_number(json_object(wave), "PC", pgm_addr);
-               json_object_set_number(json_object(wave), "wave_inst_dw0", 
wd->ws.wave_inst_dw0);
-               if (asic->family < FAMILY_NV)
-                       json_object_set_number(json_object(wave), 
"wave_inst_dw1", wd->ws.wave_inst_dw1);
-
-               JSON_Value *status = json_value_init_object();
-               json_object_set_number(json_object(status), "value", 
wd->ws.wave_status.value);
-               json_object_set_number(json_object(status), "scc", 
wd->ws.wave_status.scc);
-               json_object_set_number(json_object(status), "execz", 
wd->ws.wave_status.execz);
-               json_object_set_number(json_object(status), "vccz", 
wd->ws.wave_status.vccz);
-               json_object_set_number(json_object(status), "in_tg", 
wd->ws.wave_status.in_tg);
-               json_object_set_number(json_object(status), "halt", 
wd->ws.wave_status.halt);
-               json_object_set_number(json_object(status), "valid", 
wd->ws.wave_status.valid);
-               json_object_set_number(json_object(status), "spi_prio", 
wd->ws.wave_status.spi_prio);
-               json_object_set_number(json_object(status), "wave_prio", 
wd->ws.wave_status.wave_prio);
-               json_object_set_number(json_object(status), "priv", 
wd->ws.wave_status.priv);
-               json_object_set_number(json_object(status), "trap_en", 
wd->ws.wave_status.trap_en);
-               json_object_set_number(json_object(status), "trap", 
wd->ws.wave_status.trap);
-               json_object_set_number(json_object(status), "ttrace_en", 
wd->ws.wave_status.ttrace_en);
-               json_object_set_number(json_object(status), "export_rdy", 
wd->ws.wave_status.export_rdy);
-               json_object_set_number(json_object(status), "in_barrier", 
wd->ws.wave_status.in_barrier);
-               json_object_set_number(json_object(status), "ecc_err", 
wd->ws.wave_status.ecc_err);
-               json_object_set_number(json_object(status), "skip_export", 
wd->ws.wave_status.skip_export);
-               json_object_set_number(json_object(status), "perf_en", 
wd->ws.wave_status.perf_en);
-               json_object_set_number(json_object(status), "cond_dbg_user", 
wd->ws.wave_status.cond_dbg_user);
-               json_object_set_number(json_object(status), "cond_dbg_sys", 
wd->ws.wave_status.cond_dbg_sys);
-               json_object_set_number(json_object(status), "allow_replay", 
wd->ws.wave_status.allow_replay);
-               json_object_set_number(json_object(status), "fatal_halt", 
asic->family >= FAMILY_AI && wd->ws.wave_status.fatal_halt);
-               json_object_set_number(json_object(status), "must_export", 
wd->ws.wave_status.must_export);
-
-               json_object_set_value(json_object(wave), "status", status);
-
-               JSON_Value *hw_id = json_value_init_object();
-               if (asic->family < FAMILY_NV) {
-                       json_object_set_number(json_object(hw_id), "value", 
wd->ws.hw_id.value);
-                       json_object_set_number(json_object(hw_id), "wave_id", 
wd->ws.hw_id.wave_id);
-                       json_object_set_number(json_object(hw_id), "simd_id", 
wd->ws.hw_id.simd_id);
-                       json_object_set_number(json_object(hw_id), "pipe_id", 
wd->ws.hw_id.pipe_id);
-                       json_object_set_number(json_object(hw_id), "cu_id", 
wd->ws.hw_id.cu_id);
-                       json_object_set_number(json_object(hw_id), "sh_id", 
wd->ws.hw_id.sh_id);
-                       json_object_set_number(json_object(hw_id), "tg_id", 
wd->ws.hw_id.tg_id);
-                       json_object_set_number(json_object(hw_id), "state_id", 
wd->ws.hw_id.state_id);
-                       json_object_set_number(json_object(hw_id), "vm_id", 
wd->ws.hw_id.vm_id);
-                       vmid = wd->ws.hw_id.vm_id;
+       JSON_Value *threads = json_value_init_array();
+       int num_threads = wd->num_threads;
+       for (int thread = 0; thread < num_threads; thread++) {
+               unsigned live = thread < 32 ? (wd->ws.exec_lo & (1u << thread)) 
: (wd->ws.exec_hi & (1u << (thread - 32)));
+               json_array_append_boolean(json_array(threads), live ? 1 : 0);
+       }
+       json_object_set_value(json_object(wave), "threads", threads);
+
+       JSON_Value *gpr_alloc = json_value_init_object();
+       json_object_set_number(json_object(gpr_alloc), "vgpr_base", 
wd->ws.gpr_alloc.vgpr_base);
+       json_object_set_number(json_object(gpr_alloc), "vgpr_size", 
wd->ws.gpr_alloc.vgpr_size);
+       json_object_set_number(json_object(gpr_alloc), "sgpr_base", 
wd->ws.gpr_alloc.sgpr_base);
+       json_object_set_number(json_object(gpr_alloc), "sgpr_size", 
wd->ws.gpr_alloc.sgpr_size);
+       json_object_set_value(json_object(wave), "gpr_alloc", gpr_alloc);
+
+       if (wd->ws.gpr_alloc.value != 0xbebebeef) {
+               int sgpr_count;
+               if (asic->family <= FAMILY_AI) {
+                       int shift = asic->family <= FAMILY_CIK ? 3 : 4;
+                       sgpr_count = (wd->ws.gpr_alloc.sgpr_size + 1) << shift;
                } else {
-                       json_object_set_number(json_object(hw_id), "value", 
wd->ws.hw_id1.value);
-                       json_object_set_number(json_object(hw_id), "wave_id", 
wd->ws.hw_id1.wave_id);
-                       json_object_set_number(json_object(hw_id), "simd_id", 
wd->ws.hw_id1.simd_id);
-                       json_object_set_number(json_object(hw_id), "wgp_id", 
wd->ws.hw_id1.wgp_id);
-                       json_object_set_number(json_object(hw_id), "se_id", 
wd->ws.hw_id1.se_id);
-                       json_object_set_number(json_object(hw_id), "sa_id", 
wd->ws.hw_id1.sa_id);
-                       json_object_set_number(json_object(hw_id), "queue_id", 
wd->ws.hw_id2.queue_id);
-                       json_object_set_number(json_object(hw_id), "pipe_id", 
wd->ws.hw_id2.pipe_id);
-                       json_object_set_number(json_object(hw_id), "me_id", 
wd->ws.hw_id2.me_id);
-                       json_object_set_number(json_object(hw_id), "state_id", 
wd->ws.hw_id2.state_id);
-                       json_object_set_number(json_object(hw_id), "wg_id", 
wd->ws.hw_id2.wg_id);
-                       json_object_set_number(json_object(hw_id), 
"compat_level", wd->ws.hw_id2.compat_level);
-                       json_object_set_number(json_object(hw_id), "vm_id", 
wd->ws.hw_id2.vm_id);
-                       vmid = wd->ws.hw_id2.vm_id;
-               }
-               json_object_set_value(json_object(wave), "hw_id", hw_id);
-
-               JSON_Value *threads = json_value_init_array();
-               int num_threads = wd->num_threads;
-               for (int thread = 0; thread < num_threads; thread++) {
-                       unsigned live = thread < 32 ? (wd->ws.exec_lo & (1u << 
thread)) : (wd->ws.exec_hi & (1u << (thread - 32)));
-                       json_array_append_boolean(json_array(threads), live ? 1 
: 0);
-               }
-               json_object_set_value(json_object(wave), "threads", threads);
-
-               JSON_Value *gpr_alloc = json_value_init_object();
-               json_object_set_number(json_object(gpr_alloc), "vgpr_base", 
wd->ws.gpr_alloc.vgpr_base);
-               json_object_set_number(json_object(gpr_alloc), "vgpr_size", 
wd->ws.gpr_alloc.vgpr_size);
-               json_object_set_number(json_object(gpr_alloc), "sgpr_base", 
wd->ws.gpr_alloc.sgpr_base);
-               json_object_set_number(json_object(gpr_alloc), "sgpr_size", 
wd->ws.gpr_alloc.sgpr_size);
-               json_object_set_value(json_object(wave), "gpr_alloc", 
gpr_alloc);
-
-               if (wd->ws.gpr_alloc.value != 0xbebebeef) {
-                       int sgpr_count;
-                       if (asic->family <= FAMILY_AI) {
-                               int shift = asic->family <= FAMILY_CIK ? 3 : 4;
-                               sgpr_count = (wd->ws.gpr_alloc.sgpr_size + 1) 
<< shift;
-                       } else {
-                               sgpr_count = 108; // regular SGPRs and VCC
-                       }
-                       JSON_Value *sgpr = json_value_init_array();
-                       for (int x = 0; x < sgpr_count; x++) {
-                               json_array_append_number(json_array(sgpr), 
wd->sgprs[x]);
-                       }
-                       json_object_set_value(json_object(wave), "sgpr", sgpr);
-
-                       if (wd->have_vgprs) {
-                               unsigned granularity = 
asic->parameters.vgpr_granularity;
-                               unsigned vpgr_count = 
(wd->ws.gpr_alloc.vgpr_size + 1) << granularity;
-                               JSON_Value *vgpr = json_value_init_array();
-                               for (int x = 0; x < (int) vpgr_count; x++) {
-                                       JSON_Value *v = json_value_init_array();
-                                       for (int thread = 0; thread < 
num_threads; thread++) {
-                                               
json_array_append_number(json_array(v), wd->vgprs[thread * 256 + x]);
-                                       }
-                                       
json_array_append_value(json_array(vgpr), v);
+                       sgpr_count = 108; // regular SGPRs and VCC
+               }
+               JSON_Value *sgpr = json_value_init_array();
+               for (int x = 0; x < sgpr_count; x++) {
+                       json_array_append_number(json_array(sgpr), 
wd->sgprs[x]);
+               }
+               json_object_set_value(json_object(wave), "sgpr", sgpr);
+
+               if (wd->have_vgprs) {
+                       unsigned granularity = 
asic->parameters.vgpr_granularity;
+                       unsigned vpgr_count = (wd->ws.gpr_alloc.vgpr_size + 1) 
<< granularity;
+                       JSON_Value *vgpr = json_value_init_array();
+                       for (int x = 0; x < (int) vpgr_count; x++) {
+                               JSON_Value *v = json_value_init_array();
+                               for (int thread = 0; thread < num_threads; 
thread++) {
+                                       json_array_append_number(json_array(v), 
wd->vgprs[thread * 256 + x]);
                                }
-                               json_object_set_value(json_object(wave), 
"vgpr", vgpr);
+                               json_array_append_value(json_array(vgpr), v);
                        }
+                       json_object_set_value(json_object(wave), "vgpr", vgpr);
+               }
 
-                       /* */
-                       if (include_shaders && (wd->ws.wave_status.halt || 
wd->ws.wave_status.fatal_halt)) {
-                               struct umr_shaders_pgm *shader = NULL;
-                               uint32_t shader_size;
-                               uint64_t shader_addr;
+               /* */
+               if (include_shaders && (wd->ws.wave_status.halt || 
wd->ws.wave_status.fatal_halt)) {
+                       struct umr_shaders_pgm *shader = NULL;
+                       uint32_t shader_size;
+                       uint64_t shader_addr;
 
-                               if (ring_is_halted)
-                                       shader = 
umr_find_shader_in_stream(stream, vmid, pgm_addr);
+                       if (stream)
+                               shader = umr_find_shader_in_stream(stream, 
vmid, pgm_addr);
 
-                               if (shader) {
-                                       shader_size = shader->size;
-                                       shader_addr = shader->addr;
-                               } else {
-                                       #define NUM_OPCODE_WORDS 16
-                                       pgm_addr -= (NUM_OPCODE_WORDS*4)/2;
-                                       shader_addr = pgm_addr;
-                                       shader_size = NUM_OPCODE_WORDS * 4;
-                                       #undef NUM_OPCODE_WORDS
-                               }
+                       if (shader) {
+                               shader_size = shader->size;
+                               shader_addr = shader->addr;
+                       } else {
+                               #define NUM_OPCODE_WORDS 16
+                               pgm_addr -= (NUM_OPCODE_WORDS*4)/2;
+                               shader_addr = pgm_addr;
+                               shader_size = NUM_OPCODE_WORDS * 4;
+                               #undef NUM_OPCODE_WORDS
+                       }
 
-                               char tmp[128];
-                               sprintf(tmp, "%lx", shader_addr);
-                               /* This given shader isn't there, so read it. */
-                               if (json_object_get_value(json_object(shaders), 
tmp) == NULL) {
-                                       JSON_Value *shader = 
shader_pgm_to_json(asic, vmid, shader_addr, shader_size);
-                                       if (shader)
-                                               
json_object_set_value(json_object(shaders), tmp, shader);
-                               }
-                               json_object_set_string(json_object(wave), 
"shader", tmp);
+                       char tmp[128];
+                       sprintf(tmp, "%lx", shader_addr);
+                       /* This given shader isn't there, so read it. */
+                       if (json_object_get_value(json_object(shaders), tmp) == 
NULL) {
+                               JSON_Value *shader = shader_pgm_to_json(asic, 
vmid, shader_addr, shader_size);
+                               if (shader)
+                                       
json_object_set_value(json_object(shaders), tmp, shader);
                        }
+                       json_object_set_string(json_object(wave), "shader", 
tmp);
                }
+       }
+
+       return wave;
+}
+
+static void waves_to_json(struct umr_asic *asic, int ring_is_halted, int 
include_shaders, JSON_Object *out) {
+       // TODO: This is using the deprecated API ...
+       struct umr_pm4_stream *stream = NULL; // umr_pm4_decode_ring(asic, 
asic->options.ring_name, 1, -1, -1);
+
+       struct umr_wave_data *wd = umr_scan_wave_data(asic);
+
+       JSON_Value *shaders = json_value_init_object();
+
+       JSON_Value *waves = json_value_init_array();
+       while (wd) {
+               JSON_Value *wave = wave_to_json(asic, wd, include_shaders, 
ring_is_halted ? stream : NULL, shaders);
 
                json_array_append_value(json_array(waves), wave);
 
                struct umr_wave_data *old = wd;
                wd = wd->next;
                free(old);
        }
 
        json_object_set_value(out, "waves", waves);
        if (include_shaders)
@@ -2021,21 +2028,21 @@ JSON_Value *umr_process_json_request(JSON_Object 
*request, void **raw_data, unsi
                }
 
                asic->options.skip_gprs = 0;
                asic->options.halt_waves = halt_waves;
                asic->options.verbose = 0;
 
                int ring_is_halted = umr_ring_is_halted(asic, 
asic->options.ring_name);
 
                answer = json_value_init_object();
 
-               wave_to_json(asic, ring_is_halted, 1, json_object(answer));
+               waves_to_json(asic, ring_is_halted, 1, json_object(answer));
 
                if (disable_gfxoff && asic->fd.gfxoff >= 0) {
                        uint32_t value = 1;
                        write(asic->fd.gfxoff, &value, sizeof(value));
                }
                if (resume_waves)
                        umr_sq_cmd_halt_waves(asic, UMR_SQ_CMD_RESUME);
        } else if (strcmp(command, "resume-waves") == 0) {
                strcpy(asic->options.ring_name, json_object_get_string(request, 
"ring"));
                umr_sq_cmd_halt_waves(asic, UMR_SQ_CMD_RESUME);
-- 
2.40.0

Reply via email to