struct pipe_constant_buffer cb;
const uint paramBytes = params->NumParameterValues * sizeof(GLfloat);
- /* Update the constants which come from fixed-function state, such as
- * transformation matrices, fog factors, etc. The rest of the values in
- * the parameters list are explicitly set by the user with glUniform,
- * glProgramParameter(), etc.
- */
- if (params->StateFlags)
- _mesa_load_state_parameters(st->ctx, params);
-
_mesa_shader_write_subroutine_indices(st->ctx, stage);
- cb.buffer = NULL;
- cb.user_buffer = params->ParameterValues;
- cb.buffer_offset = 0;
- cb.buffer_size = paramBytes;
-
if (ST_DEBUG & DEBUG_CONSTANTS) {
debug_printf("%s(shader=%d, numParams=%d, stateFlags=0x%x)\n",
__func__, shader_type, params->NumParameters,
_mesa_print_parameter_list(params);
}
- cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
- pipe_resource_reference(&cb.buffer, NULL);
+ cb.buffer = NULL;
+ cb.user_buffer = NULL;
+ cb.buffer_offset = 0;
+ cb.buffer_size = paramBytes;
+
+ if (st->prefer_real_buffer_in_constbuf0) {
+ uint32_t *ptr;
+ /* fetch_state always stores 4 components (16 bytes) per matrix row,
+ * but matrix rows are sometimes allocated partially, so add 12
+ * to compensate for the fetch_state defect.
+ */
+ u_upload_alloc(st->pipe->const_uploader, 0, paramBytes + 12, 64,
+ &cb.buffer_offset, &cb.buffer, (void**)&ptr);
+
+ int uniform_bytes = params->UniformBytes;
+ if (uniform_bytes)
+ memcpy(ptr, params->ParameterValues, uniform_bytes);
+
+ /* Upload the constants which come from fixed-function state, such as
+ * transformation matrices, fog factors, etc.
+ */
+ if (params->StateFlags)
+ _mesa_upload_state_parameters(st->ctx, params, ptr);
+
+ u_upload_unmap(st->pipe->const_uploader);
+ cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
+ pipe_resource_reference(&cb.buffer, NULL);
+
+ /* Set inlinable constants. This is more involved because state
+ * parameters are uploaded directly above instead of being loaded
+ * into gl_program_parameter_list. The easiest way to get their values
+ * is to load them.
+ */
+ unsigned num_inlinable_uniforms = prog->info.num_inlinable_uniforms;
+ if (num_inlinable_uniforms) {
+ struct pipe_context *pipe = st->pipe;
+ uint32_t values[MAX_INLINABLE_UNIFORMS];
+ gl_constant_value *constbuf = params->ParameterValues;
+ bool loaded_state_vars = false;
+
+ for (unsigned i = 0; i < num_inlinable_uniforms; i++) {
+ unsigned dw_offset = prog->info.inlinable_uniform_dw_offsets[i];
+
+ if (dw_offset * 4 >= uniform_bytes && !loaded_state_vars) {
+ _mesa_load_state_parameters(st->ctx, params);
+ loaded_state_vars = true;
+ }
+
+ values[i] = constbuf[prog->info.inlinable_uniform_dw_offsets[i]].u;
+ }
+
+ pipe->set_inlinable_constants(pipe, shader_type,
+ prog->info.num_inlinable_uniforms,
+ values);
+ }
+ } else {
+ cb.user_buffer = params->ParameterValues;
+
+ /* Update the constants which come from fixed-function state, such as
+ * transformation matrices, fog factors, etc.
+ */
+ if (params->StateFlags)
+ _mesa_load_state_parameters(st->ctx, params);
+
+ cso_set_constant_buffer(st->cso_context, shader_type, 0, &cb);
- /* Set inlinable constants. */
- unsigned num_inlinable_uniforms = prog->info.num_inlinable_uniforms;
- if (num_inlinable_uniforms) {
- struct pipe_context *pipe = st->pipe;
- uint32_t values[MAX_INLINABLE_UNIFORMS];
- gl_constant_value *constbuf = params->ParameterValues;
+ /* Set inlinable constants. */
+ unsigned num_inlinable_uniforms = prog->info.num_inlinable_uniforms;
+ if (num_inlinable_uniforms) {
+ struct pipe_context *pipe = st->pipe;
+ uint32_t values[MAX_INLINABLE_UNIFORMS];
+ gl_constant_value *constbuf = params->ParameterValues;
- for (unsigned i = 0; i < num_inlinable_uniforms; i++)
- values[i] = constbuf[prog->info.inlinable_uniform_dw_offsets[i]].u;
+ for (unsigned i = 0; i < num_inlinable_uniforms; i++)
+ values[i] = constbuf[prog->info.inlinable_uniform_dw_offsets[i]].u;
- pipe->set_inlinable_constants(pipe, shader_type,
- prog->info.num_inlinable_uniforms,
- values);
+ pipe->set_inlinable_constants(pipe, shader_type,
+ prog->info.num_inlinable_uniforms,
+ values);
+ }
}
st->state.constants[shader_type].ptr = params->ParameterValues;
info.has_user_indices = false;
}
- /* set constant buffers */
+ /* set constant buffer 0 */
+ struct gl_program_parameter_list *params = st->vp->Base.Parameters;
+
+ /* Update the constants which come from fixed-function state, such as
+ * transformation matrices, fog factors, etc.
+ *
+ * It must be done here if the state tracker doesn't update state vars
+ * in gl_program_parameter_list because allow_constbuf0_as_real_buffer
+ * is set.
+ */
+ if (st->prefer_real_buffer_in_constbuf0 && params->StateFlags)
+ _mesa_load_state_parameters(st->ctx, params);
+
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
st->state.constants[PIPE_SHADER_VERTEX].ptr,
st->state.constants[PIPE_SHADER_VERTEX].size);
+ /* set uniform buffers */
const struct gl_program *prog = &vp->Base.Base;
struct pipe_transfer *ubo_transfer[PIPE_MAX_CONSTANT_BUFFERS] = {0};
assert(prog->info.num_ubos <= ARRAY_SIZE(ubo_transfer));