xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/sfn/sfn_callstack.cpp (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* -*- mesa-c++  -*-
2  * Copyright 2019 Collabora LTD
3  * Author: Gert Wollny <[email protected]>
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "sfn_callstack.h"
8 
9 namespace r600 {
10 
CallStack(r600_bytecode & bc)11 CallStack::CallStack(r600_bytecode& bc):
12     m_bc(bc)
13 {
14 }
15 
~CallStack()16 CallStack::~CallStack() {}
17 
18 int
push(unsigned type)19 CallStack::push(unsigned type)
20 {
21    switch (type) {
22    case FC_PUSH_VPM:
23       ++m_bc.stack.push;
24       break;
25    case FC_PUSH_WQM:
26       ++m_bc.stack.push_wqm;
27       break;
28    case FC_LOOP:
29       ++m_bc.stack.loop;
30       break;
31    default:
32       assert(0);
33    }
34 
35    return update_max_depth(type);
36 }
37 
38 void
pop(unsigned type)39 CallStack::pop(unsigned type)
40 {
41    switch (type) {
42    case FC_PUSH_VPM:
43       --m_bc.stack.push;
44       assert(m_bc.stack.push >= 0);
45       break;
46    case FC_PUSH_WQM:
47       --m_bc.stack.push_wqm;
48       assert(m_bc.stack.push_wqm >= 0);
49       break;
50    case FC_LOOP:
51       --m_bc.stack.loop;
52       assert(m_bc.stack.loop >= 0);
53       break;
54    default:
55       assert(0);
56       break;
57    }
58 }
59 
60 int
update_max_depth(unsigned type)61 CallStack::update_max_depth(unsigned type)
62 {
63 
64    r600_stack_info& stack = m_bc.stack;
65    int elements;
66    int entries;
67 
68    int entry_size = stack.entry_size;
69 
70    elements = (stack.loop + stack.push_wqm) * entry_size;
71    elements += stack.push;
72 
73    switch (m_bc.gfx_level) {
74    case R600:
75    case R700:
76       /* pre-r8xx: if any non-WQM PUSH instruction is invoked, 2 elements on
77        * the stack must be reserved to hold the current active/continue
78        * masks */
79       if (type == FC_PUSH_VPM || stack.push > 0) {
80          elements += 2;
81       }
82       break;
83    case CAYMAN:
84       /* r9xx: any stack operation on empty stack consumes 2 additional
85        * elements */
86       elements += 2;
87       break;
88    case EVERGREEN:
89       /* r8xx+: 2 extra elements are not always required, but one extra
90        * element must be added for each of the following cases:
91        * 1. There is an ALU_ELSE_AFTER instruction at the point of greatest
92        *    stack usage.
93        *    (Currently we don't use ALU_ELSE_AFTER.)
94        * 2. There are LOOP/WQM frames on the stack when any flavor of non-WQM
95        *    PUSH instruction executed.
96        *
97        *    NOTE: it seems we also need to reserve additional element in some
98        *    other cases, e.g. when we have 4 levels of PUSH_VPM in the shader,
99        *    then STACK_SIZE should be 2 instead of 1 */
100       if (type == FC_PUSH_VPM || stack.push > 0) {
101          elements += 1;
102       }
103       break;
104    default:
105       assert(0);
106       break;
107    }
108 
109    entry_size = 4;
110 
111    entries = (elements + (entry_size - 1)) / entry_size;
112 
113    if (entries > stack.max_entries)
114       stack.max_entries = entries;
115 
116    return elements;
117 }
118 
119 } // namespace r600
120