+/* Geometry shader:
+ */
+static void update_gs_constants(struct st_context *st )
+{
+ struct st_geometry_program *gp = st->gp;
+ struct gl_program_parameter_list *params;
+
+ if (gp) {
+ params = gp->Base.Parameters;
+ st_upload_constants( st, params, MESA_SHADER_GEOMETRY );
+ }
+}
+
+const struct st_tracked_state st_update_gs_constants = {
+ update_gs_constants /* update */
+};
+
+/* Tessellation control shader:
+ */
+static void update_tcs_constants(struct st_context *st )
+{
+ struct st_tessctrl_program *tcp = st->tcp;
+ struct gl_program_parameter_list *params;
+
+ if (tcp) {
+ params = tcp->Base.Parameters;
+ st_upload_constants( st, params, MESA_SHADER_TESS_CTRL );
+ }
+}
+
+const struct st_tracked_state st_update_tcs_constants = {
+ update_tcs_constants /* update */
+};
+
+/* Tessellation evaluation shader:
+ */
+static void update_tes_constants(struct st_context *st )
+{
+ struct st_tesseval_program *tep = st->tep;
+ struct gl_program_parameter_list *params;
+
+ if (tep) {
+ params = tep->Base.Parameters;
+ st_upload_constants( st, params, MESA_SHADER_TESS_EVAL );
+ }
+}
+
+const struct st_tracked_state st_update_tes_constants = {
+ update_tes_constants /* update */
+};
+
+/* Compute shader:
+ */
+static void update_cs_constants(struct st_context *st )
+{
+ struct st_compute_program *cp = st->cp;
+ struct gl_program_parameter_list *params;
+
+ if (cp) {
+ params = cp->Base.Parameters;
+ st_upload_constants( st, params, MESA_SHADER_COMPUTE );
+ }
+}
+
+const struct st_tracked_state st_update_cs_constants = {
+ update_cs_constants /* update */
+};
+
+static void st_bind_ubos(struct st_context *st,
+ struct gl_linked_shader *shader,
+ unsigned shader_type)
+{
+ unsigned i;
+ struct pipe_constant_buffer cb = { 0 };
+
+ if (!shader)
+ return;
+
+ for (i = 0; i < shader->Program->info.num_ubos; i++) {
+ struct gl_uniform_buffer_binding *binding;
+ struct st_buffer_object *st_obj;
+
+ binding = &st->ctx->UniformBufferBindings[shader->Program->sh.UniformBlocks[i]->Binding];
+ st_obj = st_buffer_object(binding->BufferObject);
+
+ cb.buffer = st_obj->buffer;
+
+ if (cb.buffer) {
+ cb.buffer_offset = binding->Offset;
+ cb.buffer_size = cb.buffer->width0 - binding->Offset;
+
+ /* AutomaticSize is FALSE if the buffer was set with BindBufferRange.
+ * Take the minimum just to be sure.
+ */
+ if (!binding->AutomaticSize)
+ cb.buffer_size = MIN2(cb.buffer_size, (unsigned) binding->Size);
+ }
+ else {
+ cb.buffer_offset = 0;
+ cb.buffer_size = 0;
+ }
+
+ cso_set_constant_buffer(st->cso_context, shader_type, 1 + i, &cb);
+ }
+}
+
+static void bind_vs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_VERTEX], PIPE_SHADER_VERTEX);
+}
+
+const struct st_tracked_state st_bind_vs_ubos = {
+ bind_vs_ubos
+};
+
+static void bind_fs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_FRAGMENT], PIPE_SHADER_FRAGMENT);
+}
+
+const struct st_tracked_state st_bind_fs_ubos = {
+ bind_fs_ubos
+};
+
+static void bind_gs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_GEOMETRY], PIPE_SHADER_GEOMETRY);
+}
+
+const struct st_tracked_state st_bind_gs_ubos = {
+ bind_gs_ubos
+};
+
+static void bind_tcs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_TESS_CTRL], PIPE_SHADER_TESS_CTRL);
+}
+
+const struct st_tracked_state st_bind_tcs_ubos = {
+ bind_tcs_ubos
+};
+
+static void bind_tes_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_TESS_EVAL], PIPE_SHADER_TESS_EVAL);
+}
+
+const struct st_tracked_state st_bind_tes_ubos = {
+ bind_tes_ubos
+};
+
+static void bind_cs_ubos(struct st_context *st)
+{
+ struct gl_shader_program *prog =
+ st->ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+
+ if (!prog)
+ return;
+
+ st_bind_ubos(st, prog->_LinkedShaders[MESA_SHADER_COMPUTE],
+ PIPE_SHADER_COMPUTE);
+}
+
+const struct st_tracked_state st_bind_cs_ubos = {
+ bind_cs_ubos
+};