• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 Intel Corporation
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "blorp_priv.h"
7 #include "blorp_nir_builder.h"
8 #include "compiler/brw_compiler.h"
9 #include "compiler/brw_nir.h"
10 #include "dev/intel_debug.h"
11 
12 static struct blorp_program
blorp_compile_fs_brw(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir,bool multisample_fbo,bool use_repclear)13 blorp_compile_fs_brw(struct blorp_context *blorp, void *mem_ctx,
14                      struct nir_shader *nir,
15                      bool multisample_fbo,
16                      bool use_repclear)
17 {
18    const struct brw_compiler *compiler = blorp->compiler->brw;
19    nir->options = compiler->nir_options[MESA_SHADER_FRAGMENT];
20 
21    struct brw_wm_prog_data *wm_prog_data = rzalloc(mem_ctx, struct brw_wm_prog_data);
22    wm_prog_data->base.nr_params = 0;
23    wm_prog_data->base.param = NULL;
24 
25    struct brw_nir_compiler_opts opts = {};
26    brw_preprocess_nir(compiler, nir, &opts);
27    nir_remove_dead_variables(nir, nir_var_shader_in, NULL);
28    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
29 
30    struct brw_wm_prog_key wm_key;
31    memset(&wm_key, 0, sizeof(wm_key));
32    wm_key.multisample_fbo = multisample_fbo ? BRW_ALWAYS : BRW_NEVER;
33    wm_key.nr_color_regions = 1;
34 
35    struct brw_compile_fs_params params = {
36       .base = {
37          .mem_ctx = mem_ctx,
38          .nir = nir,
39          .log_data = blorp->driver_ctx,
40          .debug_flag = DEBUG_BLORP,
41       },
42       .key = &wm_key,
43       .prog_data = wm_prog_data,
44 
45       .use_rep_send = use_repclear,
46       .max_polygons = 1,
47    };
48 
49    const unsigned *kernel = brw_compile_fs(compiler, &params);
50    return (struct blorp_program){
51       .kernel         = kernel,
52       .kernel_size    = wm_prog_data->base.program_size,
53       .prog_data      = wm_prog_data,
54       .prog_data_size = sizeof(*wm_prog_data),
55    };
56 }
57 
58 static struct blorp_program
blorp_compile_vs_brw(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)59 blorp_compile_vs_brw(struct blorp_context *blorp, void *mem_ctx,
60                      struct nir_shader *nir)
61 {
62    const struct brw_compiler *compiler = blorp->compiler->brw;
63 
64    nir->options = compiler->nir_options[MESA_SHADER_VERTEX];
65 
66    struct brw_nir_compiler_opts opts = {};
67    brw_preprocess_nir(compiler, nir, &opts);
68    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
69 
70    struct brw_vs_prog_data *vs_prog_data = rzalloc(mem_ctx, struct brw_vs_prog_data);
71    vs_prog_data->inputs_read = nir->info.inputs_read;
72 
73    brw_compute_vue_map(compiler->devinfo,
74                        &vs_prog_data->base.vue_map,
75                        nir->info.outputs_written,
76                        nir->info.separate_shader,
77                        1);
78 
79    struct brw_vs_prog_key vs_key = { 0, };
80 
81    struct brw_compile_vs_params params = {
82       .base = {
83          .mem_ctx = mem_ctx,
84          .nir = nir,
85          .log_data = blorp->driver_ctx,
86          .debug_flag = DEBUG_BLORP,
87       },
88       .key = &vs_key,
89       .prog_data = vs_prog_data,
90    };
91 
92    const unsigned *kernel = brw_compile_vs(compiler, &params);
93    return (struct blorp_program) {
94       .kernel         = kernel,
95       .kernel_size    = vs_prog_data->base.base.program_size,
96       .prog_data      = vs_prog_data,
97       .prog_data_size = sizeof(*vs_prog_data),
98    };
99 }
100 
101 static bool
lower_base_workgroup_id(nir_builder * b,nir_intrinsic_instr * intrin,UNUSED void * data)102 lower_base_workgroup_id(nir_builder *b, nir_intrinsic_instr *intrin,
103                         UNUSED void *data)
104 {
105    if (intrin->intrinsic != nir_intrinsic_load_base_workgroup_id)
106       return false;
107 
108    b->cursor = nir_instr_remove(&intrin->instr);
109    nir_def_rewrite_uses(&intrin->def, nir_imm_zero(b, 3, 32));
110    return true;
111 }
112 
113 static struct blorp_program
blorp_compile_cs_brw(struct blorp_context * blorp,void * mem_ctx,struct nir_shader * nir)114 blorp_compile_cs_brw(struct blorp_context *blorp, void *mem_ctx,
115                      struct nir_shader *nir)
116 {
117    const struct brw_compiler *compiler = blorp->compiler->brw;
118 
119    nir->options = compiler->nir_options[MESA_SHADER_COMPUTE];
120 
121    struct brw_nir_compiler_opts opts = {};
122    brw_preprocess_nir(compiler, nir, &opts);
123    nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
124 
125    NIR_PASS_V(nir, nir_lower_io, nir_var_uniform, type_size_scalar_bytes,
126               (nir_lower_io_options)0);
127 
128    STATIC_ASSERT(offsetof(struct blorp_wm_inputs, subgroup_id) + 4 ==
129                  sizeof(struct blorp_wm_inputs));
130    nir->num_uniforms = offsetof(struct blorp_wm_inputs, subgroup_id);
131    unsigned nr_params = nir->num_uniforms / 4;
132 
133    struct brw_cs_prog_data *cs_prog_data = rzalloc(mem_ctx, struct brw_cs_prog_data);
134    cs_prog_data->base.nr_params = nr_params;
135    cs_prog_data->base.param = rzalloc_array(NULL, uint32_t, nr_params);
136 
137    NIR_PASS_V(nir, brw_nir_lower_cs_intrinsics, compiler->devinfo,
138               cs_prog_data);
139    NIR_PASS_V(nir, nir_shader_intrinsics_pass, lower_base_workgroup_id,
140               nir_metadata_block_index | nir_metadata_dominance, NULL);
141 
142    struct brw_cs_prog_key cs_key;
143    memset(&cs_key, 0, sizeof(cs_key));
144 
145    struct brw_compile_cs_params params = {
146       .base = {
147          .mem_ctx = mem_ctx,
148          .nir = nir,
149          .log_data = blorp->driver_ctx,
150          .debug_flag = DEBUG_BLORP,
151       },
152       .key = &cs_key,
153       .prog_data = cs_prog_data,
154    };
155 
156    const unsigned *kernel = brw_compile_cs(compiler, &params);
157 
158    ralloc_free(cs_prog_data->base.param);
159    cs_prog_data->base.param = NULL;
160 
161    return (struct blorp_program) {
162       .kernel         = kernel,
163       .kernel_size    = cs_prog_data->base.program_size,
164       .prog_data      = cs_prog_data,
165       .prog_data_size = sizeof(*cs_prog_data),
166    };
167 }
168 
169 #pragma pack(push, 1)
170 struct layer_offset_vs_key {
171    struct blorp_base_key base;
172    unsigned num_inputs;
173 };
174 #pragma pack(pop)
175 
176 /* In the case of doing attachment clears, we are using a surface state that
177  * is handed to us so we can't set (and don't even know) the base array layer.
178  * In order to do a layered clear in this scenario, we need some way of adding
179  * the base array layer to the instance id.  Unfortunately, our hardware has
180  * no real concept of "base instance", so we have to do it manually in a
181  * vertex shader.
182  */
183 static bool
blorp_params_get_layer_offset_vs_brw(struct blorp_batch * batch,struct blorp_params * params)184 blorp_params_get_layer_offset_vs_brw(struct blorp_batch *batch,
185                                      struct blorp_params *params)
186 {
187    struct blorp_context *blorp = batch->blorp;
188    struct layer_offset_vs_key blorp_key = {
189       .base = BLORP_BASE_KEY_INIT(BLORP_SHADER_TYPE_LAYER_OFFSET_VS),
190    };
191 
192    struct brw_wm_prog_data *wm_prog_data = params->wm_prog_data;
193    if (wm_prog_data)
194       blorp_key.num_inputs = wm_prog_data->num_varying_inputs;
195 
196    if (blorp->lookup_shader(batch, &blorp_key, sizeof(blorp_key),
197                             &params->vs_prog_kernel, &params->vs_prog_data))
198       return true;
199 
200    void *mem_ctx = ralloc_context(NULL);
201 
202    nir_builder b;
203    blorp_nir_init_shader(&b, mem_ctx, MESA_SHADER_VERTEX,
204                          blorp_shader_type_to_name(blorp_key.base.shader_type));
205 
206    const struct glsl_type *uvec4_type = glsl_vector_type(GLSL_TYPE_UINT, 4);
207 
208    /* First we deal with the header which has instance and base instance */
209    nir_variable *a_header = nir_variable_create(b.shader, nir_var_shader_in,
210                                                 uvec4_type, "header");
211    a_header->data.location = VERT_ATTRIB_GENERIC0;
212 
213    nir_variable *v_layer = nir_variable_create(b.shader, nir_var_shader_out,
214                                                glsl_int_type(), "layer_id");
215    v_layer->data.location = VARYING_SLOT_LAYER;
216 
217    /* Compute the layer id */
218    nir_def *header = nir_load_var(&b, a_header);
219    nir_def *base_layer = nir_channel(&b, header, 0);
220    nir_def *instance = nir_channel(&b, header, 1);
221    nir_store_var(&b, v_layer, nir_iadd(&b, instance, base_layer), 0x1);
222 
223    /* Then we copy the vertex from the next slot to VARYING_SLOT_POS */
224    nir_variable *a_vertex = nir_variable_create(b.shader, nir_var_shader_in,
225                                                 glsl_vec4_type(), "a_vertex");
226    a_vertex->data.location = VERT_ATTRIB_GENERIC1;
227 
228    nir_variable *v_pos = nir_variable_create(b.shader, nir_var_shader_out,
229                                              glsl_vec4_type(), "v_pos");
230    v_pos->data.location = VARYING_SLOT_POS;
231 
232    nir_copy_var(&b, v_pos, a_vertex);
233 
234    /* Then we copy everything else */
235    for (unsigned i = 0; i < blorp_key.num_inputs; i++) {
236       nir_variable *a_in = nir_variable_create(b.shader, nir_var_shader_in,
237                                                uvec4_type, "input");
238       a_in->data.location = VERT_ATTRIB_GENERIC2 + i;
239 
240       nir_variable *v_out = nir_variable_create(b.shader, nir_var_shader_out,
241                                                 uvec4_type, "output");
242       v_out->data.location = VARYING_SLOT_VAR0 + i;
243 
244       nir_copy_var(&b, v_out, a_in);
245    }
246 
247    const struct blorp_program p =
248       blorp_compile_vs(blorp, mem_ctx, b.shader);
249 
250    bool result =
251       blorp->upload_shader(batch, MESA_SHADER_VERTEX,
252                            &blorp_key, sizeof(blorp_key),
253                            p.kernel, p.kernel_size,
254                            p.prog_data, p.prog_data_size,
255                            &params->vs_prog_kernel, &params->vs_prog_data);
256 
257    ralloc_free(mem_ctx);
258    return result;
259 }
260 
261 void
blorp_init_brw(struct blorp_context * blorp,void * driver_ctx,struct isl_device * isl_dev,const struct brw_compiler * brw,const struct blorp_config * config)262 blorp_init_brw(struct blorp_context *blorp, void *driver_ctx,
263                struct isl_device *isl_dev, const struct brw_compiler *brw,
264                const struct blorp_config *config)
265 {
266    blorp_init(blorp, driver_ctx, isl_dev, config);
267    assert(brw);
268 
269    blorp->compiler->brw = brw;
270    blorp->compiler->compile_fs = blorp_compile_fs_brw;
271    blorp->compiler->compile_vs = blorp_compile_vs_brw;
272    blorp->compiler->compile_cs = blorp_compile_cs_brw;
273    blorp->compiler->params_get_layer_offset_vs =
274       blorp_params_get_layer_offset_vs_brw;
275 }
276