xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/r600_sfn.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 "r600_sfn.h"
8 
9 #include "compiler/nir/nir.h"
10 #include "compiler/shader_enums.h"
11 #include "sfn/sfn_assembler.h"
12 #include "sfn/sfn_debug.h"
13 #include "sfn/sfn_memorypool.h"
14 #include "sfn/sfn_nir.h"
15 #include "sfn/sfn_shader.h"
16 #include "r600_asm.h"
17 #include "r600_pipe.h"
18 #include "util/macros.h"
19 #include "util/ralloc.h"
20 
21 #include <cassert>
22 #include <cstdio>
23 #include <cstring>
24 #include <iostream>
25 
26 char *
r600_finalize_nir(pipe_screen * screen,void * shader)27 r600_finalize_nir(pipe_screen *screen, void *shader)
28 {
29    auto rs = container_of(screen, r600_screen, b.b);
30    auto nir = static_cast<nir_shader *>(shader);
31    r600_finalize_nir_common(nir, rs->b.gfx_level);
32    return nullptr;
33 }
34 
35 class MallocPoolRelease {
36 public:
MallocPoolRelease()37    MallocPoolRelease() { r600::init_pool(); }
~MallocPoolRelease()38    ~MallocPoolRelease() { r600::release_pool(); }
39 };
40 
41 int
r600_shader_from_nir(struct r600_context * rctx,struct r600_pipe_shader * pipeshader,r600_shader_key * key)42 r600_shader_from_nir(struct r600_context *rctx,
43                      struct r600_pipe_shader *pipeshader,
44                      r600_shader_key *key)
45 {
46 
47    MallocPoolRelease pool_release;
48 
49    struct r600_pipe_shader_selector *sel = pipeshader->selector;
50 
51    if (rctx->screen->b.debug_flags & DBG_PREOPT_IR) {
52       fprintf(stderr, "PRE-OPT-NIR-----------.------------------------------\n");
53       nir_print_shader(sel->nir, stderr);
54       fprintf(stderr, "END PRE-OPT-NIR--------------------------------------\n\n");
55    }
56 
57    auto sh = nir_shader_clone(sel->nir, sel->nir);
58 
59    r600_lower_and_optimize_nir(sh, key, rctx->b.gfx_level, &sel->so);
60 
61    if (rctx->screen->b.debug_flags & DBG_ALL_SHADERS) {
62       fprintf(stderr,
63               "-- NIR --------------------------------------------------------\n");
64       struct nir_function *func =
65          (struct nir_function *)exec_list_get_head(&sh->functions);
66       nir_index_ssa_defs(func->impl);
67       nir_print_shader(sh, stderr);
68       fprintf(stderr,
69               "-- END --------------------------------------------------------\n");
70    }
71 
72    memset(&pipeshader->shader, 0, sizeof(r600_shader));
73    pipeshader->scratch_space_needed = sh->scratch_size;
74 
75    if (sh->info.stage == MESA_SHADER_TESS_EVAL || sh->info.stage == MESA_SHADER_VERTEX ||
76        sh->info.stage == MESA_SHADER_GEOMETRY) {
77       pipeshader->shader.clip_dist_write |=
78          ((1 << sh->info.clip_distance_array_size) - 1);
79       pipeshader->shader.cull_dist_write = ((1 << sh->info.cull_distance_array_size) - 1)
80                                            << sh->info.clip_distance_array_size;
81       pipeshader->shader.cc_dist_mask =
82          (1 << (sh->info.cull_distance_array_size + sh->info.clip_distance_array_size)) -
83          1;
84    }
85    struct r600_shader *gs_shader = nullptr;
86    if (rctx->gs_shader)
87       gs_shader = &rctx->gs_shader->current->shader;
88    r600_screen *rscreen = rctx->screen;
89 
90    r600::Shader *shader =
91       r600::Shader::translate_from_nir(sh, &sel->so, gs_shader, *key,
92                                        rctx->isa->hw_class, rscreen->b.family);
93 
94    assert(shader);
95    if (!shader)
96       return -2;
97 
98    pipeshader->enabled_stream_buffers_mask = shader->enabled_stream_buffers_mask();
99    pipeshader->selector->info.file_count[TGSI_FILE_HW_ATOMIC] +=
100       shader->atomic_file_count();
101    pipeshader->selector->info.writes_memory =
102       shader->has_flag(r600::Shader::sh_writes_memory);
103 
104    r600_finalize_and_optimize_shader(shader);
105 
106    auto scheduled_shader = r600_schedule_shader(shader);
107    if (!scheduled_shader) {
108       return -1;
109    }
110 
111    scheduled_shader->get_shader_info(&pipeshader->shader);
112    pipeshader->shader.uses_doubles = sh->info.bit_sizes_float & 64 ? 1 : 0;
113 
114    r600_bytecode_init(&pipeshader->shader.bc,
115                       rscreen->b.gfx_level,
116                       rscreen->b.family,
117                       rscreen->has_compressed_msaa_texturing);
118 
119    /* We already schedule the code with this in mind, no need to handle this
120     * in the backend assembler */
121    pipeshader->shader.bc.ar_handling = AR_HANDLE_NORMAL;
122    pipeshader->shader.bc.r6xx_nop_after_rel_dst = 0;
123 
124    r600::sfn_log << r600::SfnLog::shader_info << "pipeshader->shader.processor_type = "
125                  << pipeshader->shader.processor_type << "\n";
126 
127    pipeshader->shader.bc.type = pipeshader->shader.processor_type;
128    pipeshader->shader.bc.isa = rctx->isa;
129    pipeshader->shader.bc.ngpr = scheduled_shader->required_registers();
130 
131    r600::Assembler afs(&pipeshader->shader, *key);
132    if (!afs.lower(scheduled_shader)) {
133       R600_ERR("%s: Lowering to assembly failed\n", __func__);
134 
135       scheduled_shader->print(std::cerr);
136       /* For now crash if the shader could not be generated */
137       assert(0);
138       return -1;
139    }
140 
141    if (sh->info.stage == MESA_SHADER_VERTEX) {
142       pipeshader->shader.vs_position_window_space =
143             sh->info.vs.window_space_position;
144    }
145 
146    if (sh->info.stage == MESA_SHADER_FRAGMENT)
147       pipeshader->shader.ps_conservative_z =
148             sh->info.fs.depth_layout;
149 
150    if (sh->info.stage == MESA_SHADER_GEOMETRY) {
151       r600::sfn_log << r600::SfnLog::shader_info
152                     << "Geometry shader, create copy shader\n";
153       generate_gs_copy_shader(rctx, pipeshader, &sel->so);
154       assert(pipeshader->gs_copy_shader);
155    } else {
156       r600::sfn_log << r600::SfnLog::shader_info << "This is not a Geometry shader\n";
157    }
158    ralloc_free(sh);
159 
160    return 0;
161 }
162