2 * Copyright © 2018 Intel Corporation
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, sublicense,
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:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
23 #include "tgsi/tgsi_from_mesa.h"
26 #include "compiler/nir/nir_builder.h"
27 #include "compiler/glsl/gl_nir.h"
29 struct pipe_shader_state
*
30 st_nir_finish_builtin_shader(struct st_context
*st
,
34 struct pipe_context
*pipe
= st
->pipe
;
35 struct pipe_screen
*screen
= pipe
->screen
;
37 nir
->info
.name
= ralloc_strdup(nir
, name
);
38 nir
->info
.separate_shader
= true;
39 if (nir
->info
.stage
== MESA_SHADER_FRAGMENT
)
40 nir
->info
.fs
.untyped_color_outputs
= true;
42 NIR_PASS_V(nir
, nir_lower_global_vars_to_local
);
43 NIR_PASS_V(nir
, nir_split_var_copies
);
44 NIR_PASS_V(nir
, nir_lower_var_copies
);
45 NIR_PASS_V(nir
, nir_lower_system_values
);
47 if (nir
->options
->lower_to_scalar
) {
48 nir_variable_mode mask
=
49 (nir
->info
.stage
> MESA_SHADER_VERTEX
? nir_var_shader_in
: 0) |
50 (nir
->info
.stage
< MESA_SHADER_FRAGMENT
? nir_var_shader_out
: 0);
52 NIR_PASS_V(nir
, nir_lower_io_to_scalar_early
, mask
);
55 nir_shader_gather_info(nir
, nir_shader_get_entrypoint(nir
));
57 st_nir_assign_vs_in_locations(nir
);
58 st_nir_assign_varying_locations(st
, nir
);
60 st_nir_lower_samplers(screen
, nir
, NULL
, NULL
);
61 st_nir_lower_uniforms(st
, nir
);
62 if (!screen
->get_param(screen
, PIPE_CAP_NIR_IMAGES_AS_DEREF
))
63 NIR_PASS_V(nir
, gl_nir_lower_images
, false);
65 if (screen
->finalize_nir
)
66 screen
->finalize_nir(screen
, nir
, true);
70 struct pipe_shader_state state
= {
71 .type
= PIPE_SHADER_IR_NIR
,
75 switch (nir
->info
.stage
) {
76 case MESA_SHADER_VERTEX
:
77 return pipe
->create_vs_state(pipe
, &state
);
78 case MESA_SHADER_TESS_CTRL
:
79 return pipe
->create_tcs_state(pipe
, &state
);
80 case MESA_SHADER_TESS_EVAL
:
81 return pipe
->create_tes_state(pipe
, &state
);
82 case MESA_SHADER_GEOMETRY
:
83 return pipe
->create_gs_state(pipe
, &state
);
84 case MESA_SHADER_FRAGMENT
:
85 return pipe
->create_fs_state(pipe
, &state
);
87 unreachable("unsupported shader stage");
93 * Make a simple shader that copies inputs to corresponding outputs.
95 struct pipe_shader_state
*
96 st_nir_make_passthrough_shader(struct st_context
*st
,
97 const char *shader_name
,
98 gl_shader_stage stage
,
100 unsigned *input_locations
,
101 unsigned *output_locations
,
102 unsigned *interpolation_modes
,
103 unsigned sysval_mask
)
105 struct nir_builder b
;
106 const struct glsl_type
*vec4
= glsl_vec4_type();
107 const nir_shader_compiler_options
*options
=
108 st
->ctx
->Const
.ShaderCompilerOptions
[stage
].NirOptions
;
110 nir_builder_init_simple_shader(&b
, NULL
, stage
, options
);
114 for (unsigned i
= 0; i
< num_vars
; i
++) {
116 if (sysval_mask
& (1 << i
)) {
117 snprintf(var_name
, sizeof(var_name
), "sys_%u", input_locations
[i
]);
118 in
= nir_variable_create(b
.shader
, nir_var_system_value
,
119 glsl_int_type(), var_name
);
120 in
->data
.interpolation
= INTERP_MODE_FLAT
;
122 snprintf(var_name
, sizeof(var_name
), "in_%u", input_locations
[i
]);
123 in
= nir_variable_create(b
.shader
, nir_var_shader_in
, vec4
, var_name
);
125 in
->data
.location
= input_locations
[i
];
126 if (interpolation_modes
)
127 in
->data
.interpolation
= interpolation_modes
[i
];
129 snprintf(var_name
, sizeof(var_name
), "out_%u", output_locations
[i
]);
131 nir_variable_create(b
.shader
, nir_var_shader_out
, in
->type
, var_name
);
132 out
->data
.location
= output_locations
[i
];
133 out
->data
.interpolation
= in
->data
.interpolation
;
135 nir_copy_var(&b
, out
, in
);
138 return st_nir_finish_builtin_shader(st
, b
.shader
, shader_name
);