1 /* 2 * Copyright (c) 2012-2015 Etnaviv Project 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sub license, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the 12 * next paragraph) shall be included in all copies or substantial portions 13 * of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Wladimir J. van der Laan <laanwj (at) gmail.com> 25 */ 26 27 #include "etnaviv_shader.h" 28 29 #include "etnaviv_compiler.h" 30 #include "etnaviv_context.h" 31 #include "etnaviv_debug.h" 32 #include "etnaviv_util.h" 33 34 #include "util/u_math.h" 35 #include "util/u_memory.h" 36 37 /* Link vs and fs together: fill in shader_state from vs and fs 38 * as this function is called every time a new fs or vs is bound, the goal is to 39 * do little processing as possible here, and to precompute as much as possible in 40 * the vs/fs shader_object. 41 * 42 * XXX we could cache the link result for a certain set of VS/PS; usually a pair 43 * of VS and PS will be used together anyway. 44 */ 45 static bool 46 etna_link_shaders(struct etna_context *ctx, struct compiled_shader_state *cs, 47 const struct etna_shader *vs, const struct etna_shader *fs) 48 { 49 struct etna_shader_link_info link = { }; 50 51 assert(vs->processor == PIPE_SHADER_VERTEX); 52 assert(fs->processor == PIPE_SHADER_FRAGMENT); 53 54 #ifdef DEBUG 55 if (DBG_ENABLED(ETNA_DBG_DUMP_SHADERS)) { 56 etna_dump_shader(vs); 57 etna_dump_shader(fs); 58 } 59 #endif 60 61 if (etna_link_shader(&link, vs, fs)) { 62 /* linking failed: some fs inputs do not have corresponding 63 * vs outputs */ 64 assert(0); 65 66 return false; 67 } 68 69 if (DBG_ENABLED(ETNA_DBG_LINKER_MSGS)) { 70 debug_printf("link result:\n"); 71 debug_printf(" vs -> fs comps use pa_attr\n"); 72 73 for (int idx = 0; idx < link.num_varyings; ++idx) 74 debug_printf(" t%-2u -> t%-2u %-5.*s %u,%u,%u,%u 0x%08x\n", 75 link.varyings[idx].reg, idx + 1, 76 link.varyings[idx].num_components, "xyzw", 77 link.varyings[idx].use[0], link.varyings[idx].use[1], 78 link.varyings[idx].use[2], link.varyings[idx].use[3], 79 link.varyings[idx].pa_attributes); 80 } 81 82 /* set last_varying_2x flag if the last varying has 1 or 2 components */ 83 bool last_varying_2x = false; 84 if (link.num_varyings > 0 && link.varyings[link.num_varyings - 1].num_components <= 2) 85 last_varying_2x = true; 86 87 cs->RA_CONTROL = VIVS_RA_CONTROL_UNK0 | 88 COND(last_varying_2x, VIVS_RA_CONTROL_LAST_VARYING_2X); 89 90 cs->PA_ATTRIBUTE_ELEMENT_COUNT = VIVS_PA_ATTRIBUTE_ELEMENT_COUNT_COUNT(link.num_varyings); 91 for (int idx = 0; idx < link.num_varyings; ++idx) 92 cs->PA_SHADER_ATTRIBUTES[idx] = link.varyings[idx].pa_attributes; 93 94 cs->VS_END_PC = vs->code_size / 4; 95 cs->VS_OUTPUT_COUNT = 1 + link.num_varyings; /* position + varyings */ 96 97 /* vs outputs (varyings) */ 98 DEFINE_ETNA_BITARRAY(vs_output, 16, 8) = {0}; 99 int varid = 0; 100 etna_bitarray_set(vs_output, 8, varid++, vs->vs_pos_out_reg); 101 for (int idx = 0; idx < link.num_varyings; ++idx) 102 etna_bitarray_set(vs_output, 8, varid++, link.varyings[idx].reg); 103 if (vs->vs_pointsize_out_reg >= 0) 104 etna_bitarray_set(vs_output, 8, varid++, vs->vs_pointsize_out_reg); /* pointsize is last */ 105 106 for (int idx = 0; idx < ARRAY_SIZE(cs->VS_OUTPUT); ++idx) 107 cs->VS_OUTPUT[idx] = vs_output[idx]; 108 109 if (vs->vs_pointsize_out_reg != -1) { 110 /* vertex shader outputs point coordinate, provide extra output and make 111 * sure PA config is 112 * not masked */ 113 cs->PA_CONFIG = ~0; 114 cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT + 1; 115 } else { 116 /* vertex shader does not output point coordinate, make sure thate 117 * POINT_SIZE_ENABLE is masked 118 * and no extra output is given */ 119 cs->PA_CONFIG = ~VIVS_PA_CONFIG_POINT_SIZE_ENABLE; 120 cs->VS_OUTPUT_COUNT_PSIZE = cs->VS_OUTPUT_COUNT; 121 } 122 123 cs->VS_LOAD_BALANCING = vs->vs_load_balancing; 124 cs->VS_START_PC = 0; 125 126 cs->PS_END_PC = fs->code_size / 4; 127 cs->PS_OUTPUT_REG = fs->ps_color_out_reg; 128 cs->PS_INPUT_COUNT = 129 VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 1) | /* Number of inputs plus position */ 130 VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8); 131 cs->PS_TEMP_REGISTER_CONTROL = 132 VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 1)); 133 cs->PS_CONTROL = VIVS_PS_CONTROL_UNK1; /* XXX when can we set BYPASS? */ 134 cs->PS_START_PC = 0; 135 136 /* Precompute PS_INPUT_COUNT and TEMP_REGISTER_CONTROL in the case of MSAA 137 * mode, avoids some fumbling in sync_context. */ 138 cs->PS_INPUT_COUNT_MSAA = 139 VIVS_PS_INPUT_COUNT_COUNT(link.num_varyings + 2) | /* MSAA adds another input */ 140 VIVS_PS_INPUT_COUNT_UNK8(fs->input_count_unk8); 141 cs->PS_TEMP_REGISTER_CONTROL_MSAA = 142 VIVS_PS_TEMP_REGISTER_CONTROL_NUM_TEMPS(MAX2(fs->num_temps, link.num_varyings + 2)); 143 144 uint32_t total_components = 0; 145 DEFINE_ETNA_BITARRAY(num_components, ETNA_NUM_VARYINGS, 4) = {0}; 146 DEFINE_ETNA_BITARRAY(component_use, 4 * ETNA_NUM_VARYINGS, 2) = {0}; 147 for (int idx = 0; idx < link.num_varyings; ++idx) { 148 const struct etna_varying *varying = &link.varyings[idx]; 149 150 etna_bitarray_set(num_components, 4, idx, varying->num_components); 151 for (int comp = 0; comp < varying->num_components; ++comp) { 152 etna_bitarray_set(component_use, 2, total_components, varying->use[comp]); 153 total_components += 1; 154 } 155 } 156 157 cs->GL_VARYING_TOTAL_COMPONENTS = 158 VIVS_GL_VARYING_TOTAL_COMPONENTS_NUM(align(total_components, 2)); 159 cs->GL_VARYING_NUM_COMPONENTS = num_components[0]; 160 cs->GL_VARYING_COMPONENT_USE[0] = component_use[0]; 161 cs->GL_VARYING_COMPONENT_USE[1] = component_use[1]; 162 163 /* reference instruction memory */ 164 cs->vs_inst_mem_size = vs->code_size; 165 cs->VS_INST_MEM = vs->code; 166 cs->ps_inst_mem_size = fs->code_size; 167 cs->PS_INST_MEM = fs->code; 168 169 return true; 170 } 171 172 bool 173 etna_shader_link(struct etna_context *ctx) 174 { 175 if (!ctx->vs || !ctx->fs) 176 return false; 177 178 /* re-link vs and fs if needed */ 179 return etna_link_shaders(ctx, &ctx->shader_state, ctx->vs, ctx->fs); 180 } 181 182 static bool 183 etna_shader_update_vs_inputs(struct etna_context *ctx, 184 struct compiled_shader_state *cs, 185 const struct etna_shader *vs, 186 const struct compiled_vertex_elements_state *ves) 187 { 188 unsigned num_temps, cur_temp, num_vs_inputs; 189 190 if (!vs) 191 return false; 192 193 /* Number of vertex elements determines number of VS inputs. Otherwise, 194 * the GPU crashes. Allocate any unused vertex elements to VS temporary 195 * registers. */ 196 num_vs_inputs = MAX2(ves->num_elements, vs->infile.num_reg); 197 if (num_vs_inputs != ves->num_elements) { 198 BUG("Number of elements %u does not match the number of VS inputs %zu", 199 ctx->vertex_elements->num_elements, ctx->vs->infile.num_reg); 200 return false; 201 } 202 203 cur_temp = vs->num_temps; 204 num_temps = num_vs_inputs - vs->infile.num_reg + cur_temp; 205 206 cs->VS_INPUT_COUNT = VIVS_VS_INPUT_COUNT_COUNT(num_vs_inputs) | 207 VIVS_VS_INPUT_COUNT_UNK8(vs->input_count_unk8); 208 cs->VS_TEMP_REGISTER_CONTROL = 209 VIVS_VS_TEMP_REGISTER_CONTROL_NUM_TEMPS(num_temps); 210 211 /* vs inputs (attributes) */ 212 DEFINE_ETNA_BITARRAY(vs_input, 16, 8) = {0}; 213 for (int idx = 0; idx < num_vs_inputs; ++idx) { 214 if (idx < vs->infile.num_reg) 215 etna_bitarray_set(vs_input, 8, idx, vs->infile.reg[idx].reg); 216 else 217 etna_bitarray_set(vs_input, 8, idx, cur_temp++); 218 } 219 220 for (int idx = 0; idx < ARRAY_SIZE(cs->VS_INPUT); ++idx) 221 cs->VS_INPUT[idx] = vs_input[idx]; 222 223 return true; 224 } 225 226 bool 227 etna_shader_update_vertex(struct etna_context *ctx) 228 { 229 return etna_shader_update_vs_inputs(ctx, &ctx->shader_state, ctx->vs, 230 ctx->vertex_elements); 231 } 232 233 static void * 234 etna_create_shader_state(struct pipe_context *pctx, 235 const struct pipe_shader_state *pss) 236 { 237 struct etna_context *ctx = etna_context(pctx); 238 239 return etna_compile_shader(&ctx->specs, pss->tokens); 240 } 241 242 static void 243 etna_delete_shader_state(struct pipe_context *pctx, void *ss) 244 { 245 etna_destroy_shader(ss); 246 } 247 248 static void 249 etna_bind_fs_state(struct pipe_context *pctx, void *fss_) 250 { 251 struct etna_context *ctx = etna_context(pctx); 252 struct etna_shader *fss = fss_; 253 254 if (ctx->fs == fss) /* skip if already bound */ 255 return; 256 257 assert(fss == NULL || fss->processor == PIPE_SHADER_FRAGMENT); 258 ctx->fs = fss; 259 ctx->dirty |= ETNA_DIRTY_SHADER; 260 } 261 262 static void 263 etna_bind_vs_state(struct pipe_context *pctx, void *vss_) 264 { 265 struct etna_context *ctx = etna_context(pctx); 266 struct etna_shader *vss = vss_; 267 268 if (ctx->vs == vss) /* skip if already bound */ 269 return; 270 271 assert(vss == NULL || vss->processor == PIPE_SHADER_VERTEX); 272 ctx->vs = vss; 273 ctx->dirty |= ETNA_DIRTY_SHADER; 274 } 275 276 void 277 etna_shader_init(struct pipe_context *pctx) 278 { 279 pctx->create_fs_state = etna_create_shader_state; 280 pctx->bind_fs_state = etna_bind_fs_state; 281 pctx->delete_fs_state = etna_delete_shader_state; 282 pctx->create_vs_state = etna_create_shader_state; 283 pctx->bind_vs_state = etna_bind_vs_state; 284 pctx->delete_vs_state = etna_delete_shader_state; 285 } 286