1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * © Copyright 2018 Alyssa Rosenzweig 3bf215546Sopenharmony_ci * Copyright (C) 2019-2020 Collabora, Ltd. 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22bf215546Sopenharmony_ci * SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci#include <stdio.h> 27bf215546Sopenharmony_ci#include <stdlib.h> 28bf215546Sopenharmony_ci#include <string.h> 29bf215546Sopenharmony_ci#include "pan_bo.h" 30bf215546Sopenharmony_ci#include "pan_context.h" 31bf215546Sopenharmony_ci#include "pan_shader.h" 32bf215546Sopenharmony_ci#include "pan_util.h" 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "compiler/nir/nir.h" 35bf215546Sopenharmony_ci#include "util/u_dynarray.h" 36bf215546Sopenharmony_ci#include "util/u_upload_mgr.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_civoid 39bf215546Sopenharmony_cipanfrost_shader_compile(struct pipe_screen *pscreen, 40bf215546Sopenharmony_ci struct panfrost_pool *shader_pool, 41bf215546Sopenharmony_ci struct panfrost_pool *desc_pool, 42bf215546Sopenharmony_ci const nir_shader *ir, 43bf215546Sopenharmony_ci struct panfrost_shader_state *state) 44bf215546Sopenharmony_ci{ 45bf215546Sopenharmony_ci struct panfrost_screen *screen = pan_screen(pscreen); 46bf215546Sopenharmony_ci struct panfrost_device *dev = pan_device(pscreen); 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci nir_shader *s = nir_shader_clone(NULL, ir); 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci if (s->xfb_info && !s->info.internal) { 51bf215546Sopenharmony_ci /* Create compute shader doing transform feedback */ 52bf215546Sopenharmony_ci nir_shader *xfb = nir_shader_clone(NULL, s); 53bf215546Sopenharmony_ci xfb->info.name = ralloc_asprintf(xfb, "%s@xfb", xfb->info.name); 54bf215546Sopenharmony_ci xfb->info.internal = true; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci state->xfb = calloc(1, sizeof(struct panfrost_shader_state)); 57bf215546Sopenharmony_ci panfrost_shader_compile(pscreen, shader_pool, desc_pool, xfb, state->xfb); 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci /* Main shader no longer uses XFB */ 60bf215546Sopenharmony_ci s->info.has_transform_feedback_varyings = false; 61bf215546Sopenharmony_ci } 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci /* Lower this early so the backends don't have to worry about it */ 64bf215546Sopenharmony_ci if (s->info.stage == MESA_SHADER_FRAGMENT) { 65bf215546Sopenharmony_ci NIR_PASS_V(s, nir_lower_fragcolor, state->key.fs.nr_cbufs); 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci if (state->key.fs.sprite_coord_enable) { 68bf215546Sopenharmony_ci NIR_PASS_V(s, nir_lower_texcoord_replace, 69bf215546Sopenharmony_ci state->key.fs.sprite_coord_enable, 70bf215546Sopenharmony_ci true /* point coord is sysval */, 71bf215546Sopenharmony_ci false /* Y-invert */); 72bf215546Sopenharmony_ci } 73bf215546Sopenharmony_ci 74bf215546Sopenharmony_ci if (state->key.fs.clip_plane_enable) { 75bf215546Sopenharmony_ci NIR_PASS_V(s, nir_lower_clip_fs, 76bf215546Sopenharmony_ci state->key.fs.clip_plane_enable, 77bf215546Sopenharmony_ci false); 78bf215546Sopenharmony_ci } 79bf215546Sopenharmony_ci } 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci /* Call out to Midgard compiler given the above NIR */ 82bf215546Sopenharmony_ci struct panfrost_compile_inputs inputs = { 83bf215546Sopenharmony_ci .gpu_id = dev->gpu_id, 84bf215546Sopenharmony_ci .shaderdb = !!(dev->debug & PAN_DBG_PRECOMPILE), 85bf215546Sopenharmony_ci .fixed_sysval_ubo = -1, 86bf215546Sopenharmony_ci .fixed_varying_mask = state->key.fixed_varying_mask 87bf215546Sopenharmony_ci }; 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci /* No IDVS for internal XFB shaders */ 90bf215546Sopenharmony_ci if (s->info.stage == MESA_SHADER_VERTEX && s->info.has_transform_feedback_varyings) 91bf215546Sopenharmony_ci inputs.no_idvs = true; 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci memcpy(inputs.rt_formats, state->key.fs.rt_formats, sizeof(inputs.rt_formats)); 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci struct util_dynarray binary; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci util_dynarray_init(&binary, NULL); 98bf215546Sopenharmony_ci screen->vtbl.compile_shader(s, &inputs, &binary, &state->info); 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci if (binary.size) { 101bf215546Sopenharmony_ci state->bin = panfrost_pool_take_ref(shader_pool, 102bf215546Sopenharmony_ci pan_pool_upload_aligned(&shader_pool->base, 103bf215546Sopenharmony_ci binary.data, binary.size, 128)); 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci 107bf215546Sopenharmony_ci /* Don't upload RSD for fragment shaders since they need draw-time 108bf215546Sopenharmony_ci * merging for e.g. depth/stencil/alpha. RSDs are replaced by simpler 109bf215546Sopenharmony_ci * shader program descriptors on Valhall, which can be preuploaded even 110bf215546Sopenharmony_ci * for fragment shaders. */ 111bf215546Sopenharmony_ci bool upload = !(s->info.stage == MESA_SHADER_FRAGMENT && dev->arch <= 7); 112bf215546Sopenharmony_ci screen->vtbl.prepare_shader(state, desc_pool, upload); 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci panfrost_analyze_sysvals(state); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci util_dynarray_fini(&binary); 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci /* In both clone and tgsi_to_nir paths, the shader is ralloc'd against 119bf215546Sopenharmony_ci * a NULL context */ 120bf215546Sopenharmony_ci ralloc_free(s); 121bf215546Sopenharmony_ci} 122