xref: /aosp_15_r20/external/mesa3d/src/freedreno/afuc/emu-ds.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2021 Google, Inc.
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include <assert.h>
7 #include <ctype.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include "emu.h"
12 #include "util.h"
13 
14 /*
15  * Emulation for draw-state (ie. CP_SET_DRAW_STATE) related control registers:
16  */
17 
18 EMU_CONTROL_REG(DRAW_STATE_SET_HDR);
19 EMU_CONTROL_REG(DRAW_STATE_SEL);
20 EMU_CONTROL_REG(DRAW_STATE_ACTIVE_BITMASK);
21 EMU_CONTROL_REG(DRAW_STATE_HDR);
22 EMU_CONTROL_REG(DRAW_STATE_BASE);
23 EMU_CONTROL_REG(SDS_BASE);
24 EMU_CONTROL_REG(SDS_DWORDS);
25 
26 uint32_t
emu_get_draw_state_reg(struct emu * emu,unsigned n)27 emu_get_draw_state_reg(struct emu *emu, unsigned n)
28 {
29    // TODO maybe we don't need to do anything here
30    return emu->control_regs.val[n];
31 }
32 
33 void
emu_set_draw_state_base(struct emu * emu,unsigned n,uint32_t val)34 emu_set_draw_state_base(struct emu *emu, unsigned n, uint32_t val)
35 {
36    struct emu_draw_state *ds = &emu->draw_state;
37 
38    unsigned cur_idx = (emu_get_reg32(emu, &DRAW_STATE_SET_HDR) >> 24) & 0x1f;
39    ds->state[cur_idx].base_lohi[n] = val;
40 }
41 
42 void
emu_set_draw_state_reg(struct emu * emu,unsigned n,uint32_t val)43 emu_set_draw_state_reg(struct emu *emu, unsigned n, uint32_t val)
44 {
45    struct emu_draw_state *ds = &emu->draw_state;
46    unsigned cur_idx = emu_get_reg32(emu, &DRAW_STATE_SEL);
47 
48    if (n == emu_reg_offset(&DRAW_STATE_SET_HDR)) {
49       cur_idx = (val >> 24) & 0x1f;
50       ds->state[cur_idx].count = val & 0xffff;
51       ds->state[cur_idx].mode_mask = (val >> 20) & 0x7;
52 
53       unsigned active_mask = emu_get_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK);
54       active_mask |= (1 << cur_idx);
55 
56       emu_set_reg32(emu, &DRAW_STATE_ACTIVE_BITMASK, active_mask);
57    } else if (n == emu_reg_offset(&DRAW_STATE_SEL)) {
58       emu_set_reg32(emu, &DRAW_STATE_HDR, ds->state[val].hdr);
59       emu_set_reg64(emu, &DRAW_STATE_BASE, ds->state[val].base);
60 
61       /* It seems that SDS_BASE/SDS_DWORDS is also per draw-state group,
62        * and that when a new state-group is selected, SQE compares to
63        * the previous values to new DRAW_STATE_BASE & count to detect
64        * that new state has been appended to existing draw-state group:
65        */
66       unsigned prev_idx = ds->prev_draw_state_sel;
67       ds->state[prev_idx].sds_base = emu_get_reg64(emu, &SDS_BASE);
68       ds->state[prev_idx].sds_dwords = emu_get_reg32(emu, &SDS_DWORDS);
69 
70       emu_set_reg64(emu, &SDS_BASE, ds->state[val].sds_base);
71       emu_set_reg32(emu, &SDS_DWORDS, ds->state[val].sds_dwords);
72 
73       ds->prev_draw_state_sel = val;
74    }
75 }
76