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