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)11CallStack::CallStack(r600_bytecode& bc): 12 m_bc(bc) 13 { 14 } 15 ~CallStack()16CallStack::~CallStack() {} 17 18 int push(unsigned type)19CallStack::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)39CallStack::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)61CallStack::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