1 /**************************************************************************
2 *
3 * Copyright 2007 VMware, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keithw@vmware.com>
31 * Brian Paul
32 */
33
34 #include "main/imports.h"
35 #include "program/prog_parameter.h"
36 #include "program/prog_print.h"
37 #include "main/shaderapi.h"
38 #include "pipe/p_context.h"
39 #include "pipe/p_defines.h"
40 #include "util/u_inlines.h"
41 #include "util/u_upload_mgr.h"
42 #include "cso_cache/cso_context.h"
43
44 #include "st_debug.h"
45 #include "st_context.h"
46 #include "st_atom.h"
47 #include "st_atom_constbuf.h"
48 #include "st_program.h"
49 #include "st_cb_bufferobjects.h"
50
51 /**
52 * Pass the given program parameters to the graphics pipe as a
53 * constant buffer.
54 * \param shader_type either PIPE_SHADER_VERTEX or PIPE_SHADER_FRAGMENT
55 */
st_upload_constants(struct st_context * st,struct gl_program_parameter_list * params,gl_shader_stage stage)56 void st_upload_constants( struct st_context *st,
57 struct gl_program_parameter_list *params,
58 gl_shader_stage stage)
59 {
60 enum pipe_shader_type shader_type = st_shader_stage_to_ptarget(stage);
61
62 assert(shader_type == PIPE_SHADER_VERTEX ||
63 shader_type == PIPE_SHADER_FRAGMENT ||
64 shader_type == PIPE_SHADER_GEOMETRY ||
65 shader_type == PIPE_SHADER_TESS_CTRL ||
66 shader_type == PIPE_SHADER_TESS_EVAL ||
67 shader_type == PIPE_SHADER_COMPUTE);
68
69 /* update the ATI constants before rendering */
70 if (shader_type == PIPE_SHADER_FRAGMENT && st->fp->ati_fs) {
71 struct ati_fragment_shader *ati_fs = st->fp->ati_fs;
72 unsigned c;
73
74 for (c = 0; c < MAX_NUM_FRAGMENT_CONSTANTS_ATI; c++) {
75 if (ati_fs->LocalConstDef & (1 << c))
76 memcpy(params->ParameterValues[c],
77 ati_fs->Constants[c], sizeof(GLfloat) * 4);
78 else
79 memcpy(params->ParameterValues[c],
80 st->ctx->ATIFragmentShader.GlobalConstants[c], sizeof(GLfloat) * 4);
81 }
82 }
83
84 /* update constants */
85 if (params && params->NumParameters) {
86 struct pipe_constant_buffer cb;
87 const uint paramBytes = params->NumParameters * sizeof(GLfloat) * 4;
88
89 /* Update the constants which come from fixed-function state, such as
90 * transformation matrices, fog factors, etc. The rest of the values in
91 * the parameters list are explicitly set by the user with glUniform,
92 * glProgramParameter(), etc.
93 */
94 if (params->StateFlags)
95 _mesa_load_state_parameters(st->ctx, params);
96
97 _mesa_shader_write_subroutine_indices(st->ctx, stage);
98
99 /* We always need to get a new buffer, to keep the drivers simple and
100 * avoid gratuitous rendering synchronization.
101 * Let's use a user buffer to avoid an unnecessary copy.
102 */
103 if (st->constbuf_uploader) {
104 cb.buffer = NULL;
105 cb.user_buffer = NULL;
106 u_upload_data(st->constbuf_uploader, 0, paramBytes,
107 st->ctx->Const.UniformBufferOffsetAlignment,
108 params->ParameterValues, &cb.buffer_offset, &cb.buffer);
109 u_upload_unmap(st->constbuf_uploader);
110 } else {
111 cb.buffer = NULL;
112 cb.user_buffer = params->ParameterValues;
113 cb.buffer_offset = 0;
114 }
115 cb.buffer_size = paramBytes;
116
117 if (ST_DEBUG & DEBUG_CONSTANTS) {
118 debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
119 __func__, shader_type, params->NumParameters,
120 params->StateFlags);
121 _mesa_print_parameter_list(params);
122 }
123
124 cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
125 pipe_resource_reference(&cb.buffer, NULL);
126
127 st->state.constants[shader_type].ptr = params->ParameterValues;
128 st->state.constants[shader_type].size = paramBytes;
129 }
130 else if (st->state.constants[shader_type].ptr) {
131 /* Unbind. */
132 st->state.constants[shader_type].ptr = NULL;
133 st->state.constants[shader_type].size = 0;
134 cso_set_constant_buffer(st->cso_context, shader_type, 0, NULL);
135 }
136 }
137
138
139 /**
140 * Vertex shader:
141 */
update_vs_constants(struct st_context * st)142 static void update_vs_constants(struct st_context *st )
143 {
144 struct st_vertex_program *vp = st->vp;
145 struct gl_program_parameter_list *params = vp->Base.Parameters;
146
147 st_upload_constants( st, params, MESA_SHADER_VERTEX );
148 }
149
150
151 const struct st_tracked_state st_update_vs_constants = {
152 update_vs_constants /* update */
153 };
154
155
156
157 /**
158 * Fragment shader:
159 */
update_fs_constants(struct st_context * st)160 static void update_fs_constants(struct st_context *st )
161 {
162 struct st_fragment_program *fp = st->fp;
163 struct gl_program_parameter_list *params = fp->Base.Parameters;
164
165 st_upload_constants( st, params, MESA_SHADER_FRAGMENT );
166 }
167
168
169 const struct st_tracked_state st_update_fs_constants = {
170 update_fs_constants /* update */
171 };
172
173 /* Geometry shader:
174 */
update_gs_constants(struct st_context * st)175 static void update_gs_constants(struct st_context *st )
176 {
177 struct st_geometry_program *gp = st->gp;
178 struct gl_program_parameter_list *params;
179
180 if (gp) {
181 params = gp->Base.Parameters;
182 st_upload_constants( st, params, MESA_SHADER_GEOMETRY );
183 }
184 }
185
186 const struct st_tracked_state st_update_gs_constants = {
187 update_gs_constants /* update */
188 };
189
190 /* Tessellation control shader:
191 */
update_tcs_constants(struct st_context * st)192 static void update_tcs_constants(struct st_context *st )
193 {
194 struct st_tessctrl_program *tcp = st->tcp;
195 struct gl_program_parameter_list *params;
196
197 if (tcp) {
198 params = tcp->Base.Parameters;
199 st_upload_constants( st, params, MESA_SHADER_TESS_CTRL );
200 }
201 }
202
203 const struct st_tracked_state st_update_tcs_constants = {
204 update_tcs_constants /* update */
205 };
206
207 /* Tessellation evaluation shader:
208 */
update_tes_constants(struct st_context * st)209 static void update_tes_constants(struct st_context *st )
210 {
211 struct st_tesseval_program *tep = st->tep;
212 struct gl_program_parameter_list *params;
213
214 if (tep) {
215 params = tep->Base.Parameters;
216 st_upload_constants( st, params, MESA_SHADER_TESS_EVAL );
217 }
218 }
219
220 const struct st_tracked_state st_update_tes_constants = {
221 update_tes_constants /* update */
222 };
223
224 /* Compute shader:
225 */
update_cs_constants(struct st_context * st)226 static void update_cs_constants(struct st_context *st )
227 {
228 struct st_compute_program *cp = st->cp;
229 struct gl_program_parameter_list *params;
230
231 if (cp) {
232 params = cp->Base.Parameters;
233 st_upload_constants( st, params, MESA_SHADER_COMPUTE );
234 }
235 }
236
237 const struct st_tracked_state st_update_cs_constants = {
238 update_cs_constants /* update */
239 };
240
st_bind_ubos(struct st_context * st,struct gl_program * prog,unsigned shader_type)241 static void st_bind_ubos(struct st_context *st, struct gl_program *prog,
242 unsigned shader_type)
243 {
244 unsigned i;
245 struct pipe_constant_buffer cb = { 0 };
246
247 if (!prog)
248 return;
249
250 for (i = 0; i < prog->info.num_ubos; i++) {
251 struct gl_uniform_buffer_binding *binding;
252 struct st_buffer_object *st_obj;
253
254 binding =
255 &st->ctx->UniformBufferBindings[prog->sh.UniformBlocks[i]->Binding];
256 st_obj = st_buffer_object(binding->BufferObject);
257
258 cb.buffer = st_obj->buffer;
259
260 if (cb.buffer) {
261 cb.buffer_offset = binding->Offset;
262 cb.buffer_size = cb.buffer->width0 - binding->Offset;
263
264 /* AutomaticSize is FALSE if the buffer was set with BindBufferRange.
265 * Take the minimum just to be sure.
266 */
267 if (!binding->AutomaticSize)
268 cb.buffer_size = MIN2(cb.buffer_size, (unsigned) binding->Size);
269 }
270 else {
271 cb.buffer_offset = 0;
272 cb.buffer_size = 0;
273 }
274
275 cso_set_constant_buffer(st->cso_context, shader_type, 1 + i, &cb);
276 }
277 }
278
bind_vs_ubos(struct st_context * st)279 static void bind_vs_ubos(struct st_context *st)
280 {
281 struct gl_shader_program *prog =
282 st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
283
284 if (!prog || !prog->_LinkedShaders[MESA_SHADER_VERTEX])
285 return;
286
287 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_VERTEX]->Program, PIPE_SHADER_VERTEX);
288 }
289
290 const struct st_tracked_state st_bind_vs_ubos = {
291 bind_vs_ubos
292 };
293
bind_fs_ubos(struct st_context * st)294 static void bind_fs_ubos(struct st_context *st)
295 {
296 struct gl_shader_program *prog =
297 st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
298
299 if (!prog || !prog->_LinkedShaders[MESA_SHADER_FRAGMENT])
300 return;
301
302 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program, PIPE_SHADER_FRAGMENT);
303 }
304
305 const struct st_tracked_state st_bind_fs_ubos = {
306 bind_fs_ubos
307 };
308
bind_gs_ubos(struct st_context * st)309 static void bind_gs_ubos(struct st_context *st)
310 {
311 struct gl_shader_program *prog =
312 st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
313
314 if (!prog || !prog->_LinkedShaders[MESA_SHADER_GEOMETRY])
315 return;
316
317 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program, PIPE_SHADER_GEOMETRY);
318 }
319
320 const struct st_tracked_state st_bind_gs_ubos = {
321 bind_gs_ubos
322 };
323
bind_tcs_ubos(struct st_context * st)324 static void bind_tcs_ubos(struct st_context *st)
325 {
326 struct gl_shader_program *prog =
327 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
328
329 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_CTRL])
330 return;
331
332 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]->Program, PIPE_SHADER_TESS_CTRL);
333 }
334
335 const struct st_tracked_state st_bind_tcs_ubos = {
336 bind_tcs_ubos
337 };
338
bind_tes_ubos(struct st_context * st)339 static void bind_tes_ubos(struct st_context *st)
340 {
341 struct gl_shader_program *prog =
342 st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
343
344 if (!prog || !prog->_LinkedShaders[MESA_SHADER_TESS_EVAL])
345 return;
346
347 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]->Program, PIPE_SHADER_TESS_EVAL);
348 }
349
350 const struct st_tracked_state st_bind_tes_ubos = {
351 bind_tes_ubos
352 };
353
bind_cs_ubos(struct st_context * st)354 static void bind_cs_ubos(struct st_context *st)
355 {
356 struct gl_shader_program *prog =
357 st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
358
359 if (!prog || !prog->_LinkedShaders[MESA_SHADER_COMPUTE])
360 return;
361
362 st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE]->Program,
363 PIPE_SHADER_COMPUTE);
364 }
365
366 const struct st_tracked_state st_bind_cs_ubos = {
367 bind_cs_ubos
368 };
369