i965: drop brw->gen in favor of devinfo->gen
[mesa.git] / src / mesa / drivers / dri / i965 / brw_nir_uniforms.cpp
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
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:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "compiler/brw_nir.h"
25 #include "compiler/glsl/ir_uniform.h"
26
27 static void
28 brw_nir_setup_glsl_builtin_uniform(nir_variable *var,
29 const struct gl_program *prog,
30 struct brw_stage_prog_data *stage_prog_data,
31 bool is_scalar)
32 {
33 const nir_state_slot *const slots = var->state_slots;
34 assert(var->state_slots != NULL);
35
36 unsigned uniform_index = var->data.driver_location / 4;
37 for (unsigned int i = 0; i < var->num_state_slots; i++) {
38 /* This state reference has already been setup by ir_to_mesa, but we'll
39 * get the same index back here.
40 */
41 int index = _mesa_add_state_reference(prog->Parameters,
42 (gl_state_index *)slots[i].tokens);
43
44 /* Add each of the unique swizzles of the element as a parameter.
45 * This'll end up matching the expected layout of the
46 * array/matrix/structure we're trying to fill in.
47 */
48 int last_swiz = -1;
49 for (unsigned j = 0; j < 4; j++) {
50 int swiz = GET_SWZ(slots[i].swizzle, j);
51
52 /* If we hit a pair of identical swizzles, this means we've hit the
53 * end of the builtin variable. In scalar mode, we should just quit
54 * and move on to the next one. In vec4, we need to continue and pad
55 * it out to 4 components.
56 */
57 if (swiz == last_swiz && is_scalar)
58 break;
59
60 last_swiz = swiz;
61
62 stage_prog_data->param[uniform_index++] =
63 &prog->Parameters->ParameterValues[index][swiz];
64 }
65 }
66 }
67
68 static void
69 setup_vec4_uniform_value(const gl_constant_value **params,
70 const gl_constant_value *values,
71 unsigned n)
72 {
73 static const gl_constant_value zero = { 0 };
74
75 for (unsigned i = 0; i < n; ++i)
76 params[i] = &values[i];
77
78 for (unsigned i = n; i < 4; ++i)
79 params[i] = &zero;
80 }
81
82 static void
83 brw_setup_image_uniform_values(gl_shader_stage stage,
84 struct brw_stage_prog_data *stage_prog_data,
85 unsigned param_start_index,
86 const gl_uniform_storage *storage)
87 {
88 const gl_constant_value **param =
89 &stage_prog_data->param[param_start_index];
90
91 for (unsigned i = 0; i < MAX2(storage->array_elements, 1); i++) {
92 const unsigned image_idx = storage->opaque[stage].index + i;
93 const brw_image_param *image_param =
94 &stage_prog_data->image_param[image_idx];
95
96 /* Upload the brw_image_param structure. The order is expected to match
97 * the BRW_IMAGE_PARAM_*_OFFSET defines.
98 */
99 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SURFACE_IDX_OFFSET,
100 (const gl_constant_value *)&image_param->surface_idx, 1);
101 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_OFFSET_OFFSET,
102 (const gl_constant_value *)image_param->offset, 2);
103 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SIZE_OFFSET,
104 (const gl_constant_value *)image_param->size, 3);
105 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_STRIDE_OFFSET,
106 (const gl_constant_value *)image_param->stride, 4);
107 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_TILING_OFFSET,
108 (const gl_constant_value *)image_param->tiling, 3);
109 setup_vec4_uniform_value(param + BRW_IMAGE_PARAM_SWIZZLING_OFFSET,
110 (const gl_constant_value *)image_param->swizzling, 2);
111 param += BRW_IMAGE_PARAM_SIZE;
112
113 brw_mark_surface_used(
114 stage_prog_data,
115 stage_prog_data->binding_table.image_start + image_idx);
116 }
117 }
118
119 static void
120 brw_nir_setup_glsl_uniform(gl_shader_stage stage, nir_variable *var,
121 const struct gl_program *prog,
122 struct brw_stage_prog_data *stage_prog_data,
123 bool is_scalar)
124 {
125 int namelen = strlen(var->name);
126
127 /* The data for our (non-builtin) uniforms is stored in a series of
128 * gl_uniform_storage structs for each subcomponent that
129 * glGetUniformLocation() could name. We know it's been set up in the same
130 * order we'd walk the type, so walk the list of storage and find anything
131 * with our name, or the prefix of a component that starts with our name.
132 */
133 unsigned uniform_index = var->data.driver_location / 4;
134 for (unsigned u = 0; u < prog->sh.data->NumUniformStorage; u++) {
135 struct gl_uniform_storage *storage =
136 &prog->sh.data->UniformStorage[u];
137
138 if (storage->builtin || storage->type->is_sampler())
139 continue;
140
141 if (strncmp(var->name, storage->name, namelen) != 0 ||
142 (storage->name[namelen] != 0 &&
143 storage->name[namelen] != '.' &&
144 storage->name[namelen] != '[')) {
145 continue;
146 }
147
148 if (storage->type->is_image()) {
149 brw_setup_image_uniform_values(stage, stage_prog_data,
150 uniform_index, storage);
151 uniform_index +=
152 BRW_IMAGE_PARAM_SIZE * MAX2(storage->array_elements, 1);
153 } else {
154 gl_constant_value *components = storage->storage;
155 unsigned vector_count = (MAX2(storage->array_elements, 1) *
156 storage->type->matrix_columns);
157 unsigned vector_size = storage->type->vector_elements;
158 unsigned max_vector_size = 4;
159 if (storage->type->base_type == GLSL_TYPE_DOUBLE ||
160 storage->type->base_type == GLSL_TYPE_UINT64 ||
161 storage->type->base_type == GLSL_TYPE_INT64) {
162 vector_size *= 2;
163 if (vector_size > 4)
164 max_vector_size = 8;
165 }
166
167 for (unsigned s = 0; s < vector_count; s++) {
168 unsigned i;
169 for (i = 0; i < vector_size; i++) {
170 stage_prog_data->param[uniform_index++] = components++;
171 }
172
173 if (!is_scalar) {
174 /* Pad out with zeros if needed (only needed for vec4) */
175 for (; i < max_vector_size; i++) {
176 static const gl_constant_value zero = { 0.0 };
177 stage_prog_data->param[uniform_index++] = &zero;
178 }
179 }
180 }
181 }
182 }
183 }
184
185 void
186 brw_nir_setup_glsl_uniforms(nir_shader *shader, const struct gl_program *prog,
187 struct brw_stage_prog_data *stage_prog_data,
188 bool is_scalar)
189 {
190 nir_foreach_variable(var, &shader->uniforms) {
191 /* UBO's, atomics and samplers don't take up space in the
192 uniform file */
193 if (var->interface_type != NULL || var->type->contains_atomic())
194 continue;
195
196 if (strncmp(var->name, "gl_", 3) == 0) {
197 brw_nir_setup_glsl_builtin_uniform(var, prog, stage_prog_data,
198 is_scalar);
199 } else {
200 brw_nir_setup_glsl_uniform(shader->stage, var, prog, stage_prog_data,
201 is_scalar);
202 }
203 }
204 }
205
206 void
207 brw_nir_setup_arb_uniforms(nir_shader *shader, struct gl_program *prog,
208 struct brw_stage_prog_data *stage_prog_data)
209 {
210 struct gl_program_parameter_list *plist = prog->Parameters;
211
212 /* For ARB programs, prog_to_nir generates a single "parameters" variable
213 * for all uniform data. nir_lower_wpos_ytransform may also create an
214 * additional variable.
215 */
216 assert(shader->uniforms.length() <= 2);
217
218 for (unsigned p = 0; p < plist->NumParameters; p++) {
219 /* Parameters should be either vec4 uniforms or single component
220 * constants; matrices and other larger types should have been broken
221 * down earlier.
222 */
223 assert(plist->Parameters[p].Size <= 4);
224
225 unsigned i;
226 for (i = 0; i < plist->Parameters[p].Size; i++) {
227 stage_prog_data->param[4 * p + i] = &plist->ParameterValues[p][i];
228 }
229 for (; i < 4; i++) {
230 static const gl_constant_value zero = { 0.0 };
231 stage_prog_data->param[4 * p + i] = &zero;
232 }
233 }
234 }