1/* 2 * © Copyright 2018 Alyssa Rosenzweig 3 * Copyright (C) 2019-2020 Collabora, Ltd. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 * 24 */ 25 26#include <stdio.h> 27#include <stdlib.h> 28#include <string.h> 29#include "pan_bo.h" 30#include "pan_context.h" 31#include "pan_shader.h" 32#include "pan_util.h" 33#include "panfrost-quirks.h" 34 35#include "compiler/nir/nir.h" 36#include "nir/tgsi_to_nir.h" 37#include "util/u_dynarray.h" 38#include "util/u_upload_mgr.h" 39 40#include "tgsi/tgsi_dump.h" 41 42void 43panfrost_shader_compile(struct pipe_screen *pscreen, 44 struct panfrost_pool *shader_pool, 45 struct panfrost_pool *desc_pool, 46 enum pipe_shader_ir ir_type, 47 const void *ir, 48 gl_shader_stage stage, 49 struct panfrost_shader_state *state) 50{ 51 struct panfrost_screen *screen = pan_screen(pscreen); 52 struct panfrost_device *dev = pan_device(pscreen); 53 54 nir_shader *s; 55 56 if (ir_type == PIPE_SHADER_IR_NIR) { 57 s = nir_shader_clone(NULL, ir); 58 } else { 59 assert (ir_type == PIPE_SHADER_IR_TGSI); 60 s = tgsi_to_nir(ir, pscreen, false); 61 } 62 63 /* Lower this early so the backends don't have to worry about it */ 64 if (stage == MESA_SHADER_FRAGMENT) 65 NIR_PASS_V(s, nir_lower_fragcolor, state->nr_cbufs); 66 67 s->info.stage = stage; 68 69 /* Call out to Midgard compiler given the above NIR */ 70 struct panfrost_compile_inputs inputs = { 71 .gpu_id = dev->gpu_id, 72 .shaderdb = !!(dev->debug & PAN_DBG_PRECOMPILE), 73 }; 74 75 memcpy(inputs.rt_formats, state->rt_formats, sizeof(inputs.rt_formats)); 76 77 struct util_dynarray binary; 78 79 util_dynarray_init(&binary, NULL); 80 screen->vtbl.compile_shader(s, &inputs, &binary, &state->info); 81 82 if (binary.size) { 83 state->bin = panfrost_pool_take_ref(shader_pool, 84 pan_pool_upload_aligned(&shader_pool->base, 85 binary.data, binary.size, 128)); 86 } 87 88 89 /* Don't upload RSD for fragment shaders since they need draw-time 90 * merging for e.g. depth/stencil/alpha */ 91 bool upload = stage != MESA_SHADER_FRAGMENT; 92 screen->vtbl.prepare_rsd(state, desc_pool, upload); 93 94 panfrost_analyze_sysvals(state); 95 96 util_dynarray_fini(&binary); 97 98 /* In both clone and tgsi_to_nir paths, the shader is ralloc'd against 99 * a NULL context */ 100 ralloc_free(s); 101} 102